README.md in x25519-0.0.0 vs README.md in x25519-0.1.0

- old
+ new

@@ -1,25 +1,37 @@ -# x25519.rb +# x25519.rb [![Latest Version][gem-shield]][gem-link] [![Build Status][build-image]][build-link] [![License: LGPL v3][license-image]][license-link] +[gem-shield]: https://badge.fury.io/rb/x25519.svg +[gem-link]: https://rubygems.org/gems/x25519 +[build-image]: https://travis-ci.org/cryptosphere/x25519.svg?branch=master +[build-link]: https://travis-ci.org/cryptosphere/x25519 +[license-image]: https://img.shields.io/badge/License-LGPL%20v3-blue.svg +[license-link]: https://www.gnu.org/licenses/lgpl-3.0 + An efficient public key cryptography library for Ruby providing key exchange/agreement. This gem implements X25519 (a.k.a. Curve25519) Elliptic Curve Diffie-Hellman function as described in [RFC7748] as a C extension using the -high performance [rfc7748-precomputed] implementation based on the paper -[How to (pre-)compute a ladder]. +high performance [rfc7748_precomputed] implementation based on the paper +[How to (pre-)compute a ladder] +(with fallback to the ref10 C implementation). [RFC7748]: https://tools.ietf.org/html/rfc7748 [How to (pre-)compute a ladder]: https://eprint.iacr.org/2017/264 [rfc7748_precomputed]: https://github.com/armfazh/rfc7748_precomputed +## Requirements + +* MRI 2.2+ + ## Installation Add this line to your application's Gemfile: ```ruby -gem 'x25519' +gem "x25519" ``` And then execute: $ bundle @@ -28,40 +40,219 @@ $ gem install x25519 ## Usage -Coming soon! +The example below shows how to perform a full Diffie-Hellman key exchange: +```ruby +require "x25519" + +# Alice generates random scalar (private key) +alice_sk = X25519::Scalar.generate + +# Alice obtains public key for her private key/scalar +alice_pk = alice_sk.public_key + +# Bob generates random scalar (private key) +# Ostensibly this would be on a different computer somewhere +bob_sk = X25519::Scalar.generate +bob_pk = bob_sk.public_key + +# Alice can perform Diffie-Hellman with Bob's public key +alice_secret = alice_sk.diffie_hellman(bob_pk).to_bytes + +# Bob can perform Diffie-Hellman with Alice's public key +bob_secret = bob_sk.diffie_hellman(alice_pk).to_bytes + +# The resulting secrets should be the same +alice_secret == bob_secret # true +``` + +## API + +### `X25519::Scalar`: private keys + +The `X25519::Scalar` class represents secret integers used as X25519 private +keys. These secret integers are multiplied by a well-known base point to +obtain X25519 public keys (`X25519::MontgomeryU`). + +#### `X25519::Scalar.generate()`: make a random private key + +Generate a random private scalar (using `SecureRandom`) + +##### Example + +```ruby +secret_key = X25519::Scalar.generate +``` + +#### `X25519::Scalar.new(bytes)`: load existing private key + +* `bytes`: a 32-byte `String` value containing the private key + +##### Example + +```ruby +secret_key = X25519::Scalar.new(File.read("alice.key")) +``` + +#### `X25519::Scalar#public_key()`: obtain public key for this scalar + +NOTE: The `#multiply_base` method is an alias of this one. + +Performs fixed-base scalar multiplication (i.e. calculates public key) + +##### Return Value + +Returns a `X25519::MontgomeryU` object which represents the public key for this private key/scalar. + +##### Example + +```ruby +secret_key = X25519::Scalar.generate +public_key = secret_key.public_key +``` + +#### `X25519::Scalar#diffie_hellman(other_public_key)`: obtain public key for this scalar + +NOTE: The `#multiply` method is an alias of this one. + +Performs variable-base scalar multiplication, computing a shared secret between +our private scalar and someone else's public key/point. + +##### Return Value + +Returns a `X25519::MontgomeryU` object which represents the shared secret. + +##### Arguments + +* `other_public_key`: a `X25519::MontgomeryU` object containing the public key + with which we'd like to compute a shared secret. + +##### Example + +```ruby +secret_key = X25519::Scalar.generate +public_key = X25519::MontgomeryU.new(File.read("bob.pub")) + +# Returns an X25519::MontgomeryU +shared_secret = secret_key.multiply(public_key) + +# Obtain the shared secret as a serialized byte representation +shared_secret_bytes = shared_secret.to_bytes +``` + +#### `X25519::Scalar#to_bytes`: serialize a scalar as a `String` + +##### Return Value + +Returns a `String` containing a byte representation of this scalar: + +##### Example + +```ruby +secret_key = X25519::Scalar.new(...) +File.write("alice.key", secret_key.to_bytes) +``` + +### `X25519::MontgomeryU`: public keys and shared secrets + +The `X25519::MontgomeryU` class represents a coordinate (specifically a +Montgomery-u coordinate) on the elliptic curve. In the X25519 Diffie-Hellman +function, these serve both as public keys and as shared secrets. + +#### `X25519::MontgomeryU.new(bytes)`: load existing public key + +##### Arguments + +* `bytes`: a 32-byte `String` value containing the public key + +##### Example + +```ruby +public_key = X25519::MontgomeryU.new(File.read("bob.pub")) +``` + +#### `X25519::MontgomeryU#to_bytes`: serialize a Montgomery-u coordinate as a `String` + +##### Return Value + +Returns a `String` containing a byte representation of a compressed Montgomery-u coordinate: + +##### Example + +```ruby +public_key = X25519::MontgomeryU..new(...) +File.write("bob.pub", public_key.to_bytes) +``` + +### `X25519`: module-level functionality + +#### `X25519.diffie_hellman(secret_key, public_key)`: shorthand `String`-oriented API + +If you'd like to avoid the object-oriented API, you can use a simplified API which +acts entirely on bytestrings. + +##### Arguments + +* `secret_key`: a 32-byte `String` containing a private scalar +* `public_key`: a 32-byte `String` containing a compressed Montgomery-u coordinate + +##### Return Value + +Returns a `String` containing a 32-byte compressed Montgomery-u coordinate + ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/cryptosphere/x25519. This project is intended to be a safe, welcoming space for collaboration, and contributors areexpected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. ## Implementation Details +This gem contains two implementations of X25519: an optimized assembly +implementation and a portable C implementation. Implementations are selected +based on available CPU features. + +### [rfc7748_precomputed]: optimized assembly implementation + * Prime field arithmetic is optimized for the 4th and 6th generation of Intel Core processors (Haswell and Skylake micro-architectures). * Efficient integer multiplication using MULX instruction. * Integer additions accelerated with ADCX/ADOX instructions. -* Key generation uses a read-only table of 8 KB (25 KB) for X25519 (X448). +* Key generation uses a read-only table of 8 KB for X25519. +### ref10: portable C implementation + +* Taken from the [SUPERCOP] cryptographic benchmarking suite (supercop-20171020) +* Portable C code which should compile on any architecture + +[SUPERCOP]: https://bench.cr.yp.to/supercop.html + ## Designers -Thomaz Oliveira, Computer Science Department, Cinvestav-IPN, Mexico. -Julio López, University of Campinas, Brazil. -Hüseyin Hisil, Yasar University, Turkey. -Armando Faz-Hernández, University of Campinas, Brazil. -Francisco Rodríguez-Henríquez, Computer Science Department, Cinvestav-IPN, Mexico. +The X25519 Diffie-Hellman function was originally designed by Dan Bernstein: -## License +https://cr.yp.to/ecdh.html -The gem is available as open source under the terms of the +The optimized [rfc7748_precomputed] implementation was designed by: + +* Thomaz Oliveira, Computer Science Department, Cinvestav-IPN, Mexico. +* Julio López, University of Campinas, Brazil. +* Hüseyin Hisil, Yasar University, Turkey. +* Armando Faz-Hernández, University of Campinas, Brazil. +* Francisco Rodríguez-Henríquez, Computer Science Department, Cinvestav-IPN, Mexico. + +## Copyright and License + +Copyright (c) 2017 Armando Faz, Tony Arcieri + +This gem is available as open source under the terms of the GNU Lesser General Public License v3.0 ([LICENSE](https://www.gnu.org/licenses/lgpl-3.0.txt)) ## Code of Conduct -Everyone interacting in the X25519 project’s codebases, issue trackers, chat +Everyone interacting in the x25519.rb project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct]. [code of conduct]: https://github.com/cryptosphere/x25519/blob/master/CODE_OF_CONDUCT.md