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