Revise README with new benchmarks, warning, and install instructions.

This commit is contained in:
Isis Lovecruft 2017-03-15 21:05:07 +00:00
parent 054e9ce6b8
commit 71c2bc7687
Failed to extract signature
2 changed files with 103 additions and 24 deletions

127
README.md
View file

@ -3,26 +3,36 @@
Fast and efficient Rust implementation of ed25519 key generation, signing, and Fast and efficient Rust implementation of ed25519 key generation, signing, and
verification in Rust. verification in Rust.
# Documentation
Documentation is available [here](https://docs.rs/ed25519-dalek).
# Benchmarks # Benchmarks
You need to pass the `--features="bench"` flag to run the benchmarks. The
reason for feature-gating the benchmarks is that Rust's `test::Bencher` is
unstable, and thus only works on the nightly channel. (We'd like people to be
able to compile and test on the stable and beta channels too!)
On an Intel i5 Sandy Bridge running at 2.6 GHz, with TurboBoost enabled (and On an Intel i5 Sandy Bridge running at 2.6 GHz, with TurboBoost enabled (and
also running in QubesOS with *lots* of other VMs executing), this code also running in QubesOS with *lots* of other VMs executing), this code
achieves the following performance benchmarks: achieves the following performance benchmarks:
∃!isisⒶwintermute:(release/0.1.0 *$)~/code/rust/ed25519 ∴ cargo bench ∃!isisⒶwintermute:(develop *$)~/code/rust/ed25519 ∴ cargo bench --features="bench"
Finished release [optimized] target(s) in 0.0 secs Finished release [optimized] target(s) in 0.0 secs
Running target/release/deps/ed25519-0135748522c518d8 Running target/release/deps/ed25519_dalek-281c2d7a2379edae
running 5 tests running 6 tests
test ed25519::test::test_sign_verify ... ignored test ed25519::test::golden ... ignored
test ed25519::test::test_unmarshal_marshal ... ignored test ed25519::test::sign_verify ... ignored
test ed25519::test::bench_key_generation ... bench: 54,837 ns/iter (+/- 11,613) test ed25519::test::unmarshal_marshal ... ignored
test ed25519::test::bench_sign ... bench: 69,735 ns/iter (+/- 21,902) test ed25519::bench::key_generation ... bench: 54,571 ns/iter (+/- 7,861)
test ed25519::test::bench_verify ... bench: 183,891 ns/iter (+/- 75,304) test ed25519::bench::sign ... bench: 70,009 ns/iter (+/- 22,812)
test ed25519::bench::verify ... bench: 185,619 ns/iter (+/- 24,117)
test result: ok. 0 passed; 0 failed; 2 ignored; 3 measured test result: ok. 0 passed; 0 failed; 3 ignored; 3 measured
In comparision, the equivalent package in Golang performs as follows: In comparison, the equivalent package in Golang performs as follows:
∃!isisⒶwintermute:(master *=)~/code/go/src/github.com/agl/ed25519 ∴ go test -bench . ∃!isisⒶwintermute:(master *=)~/code/go/src/github.com/agl/ed25519 ∴ go test -bench .
PASS PASS
@ -34,36 +44,105 @@ In comparision, the equivalent package in Golang performs as follows:
Making key generation, signing, and verification a rough average of one third Making key generation, signing, and verification a rough average of one third
faster, one fifth faster, and one eighth faster respectively. Of course, this faster, one fifth faster, and one eighth faster respectively. Of course, this
is just my machine, and these results—nowhere near rigorous—should be taken is just my machine, and these results—nowhere near rigorous—should be taken
with a fistful of salt. with a handful of salt.
## Warning Additionally, if you're on the Rust nightly channel, be sure to build with
`cargo build --features="nightly"`, which uses Rust's experimental support for
the `u128` type in curve25519-dalek to speed up field arithmetic by roughly a
factor of two. The benchmarks using nightly (on the same machine as above)
are:
[Our elliptic curve library](https://github.com/isislovecruft/curve25519-dalek) ∃!isisⒶwintermute:(develop *$)~/code/rust/ed25519 ∴ cargo bench --features="bench nightly"
(which this code uses) has **not** yet received sufficient peer review by Finished release [optimized] target(s) in 0.0 secs
other qualified cryptographers to be considered in any way, shape, or form, Running target/release/deps/ed25519_dalek-9d7f8674ae11ac39
safe.
running 6 tests
test ed25519::test::golden ... ignored
test ed25519::test::sign_verify ... ignored
test ed25519::test::unmarshal_marshal ... ignored
test ed25519::bench::key_generation ... bench: 31,160 ns/iter (+/- 8,597)
test ed25519::bench::sign ... bench: 40,565 ns/iter (+/- 4,758)
test ed25519::bench::verify ... bench: 106,146 ns/iter (+/- 2,796)
test result: ok. 0 passed; 0 failed; 3 ignored; 3 measured
Translating to a rough cycle count: we multiply by a factor of 2.6 to convert
nanoseconds to cycles per second on a 2.6 GHz CPU, that's 275979 cycles for
verification and 105469 for signing, which is
[competitive with the optimised assembly version](https://ed25519.cr.yp.to/)
included in the SUPERCOP benchmarking suite (albeit their numbers are for the
older Nehalem microarchitecture).
Additionally, thanks to Rust, this implementation has both type and memory
safety. Not to mention that it's readable for everyone, making ours arguable
more readily auditable. We're of the opinion that these features—combined
with speed—are ultimately more valuable than sole cycle count.
# Warnings
ed25519-dalek and
[our elliptic curve library](https://github.com/isislovecruft/curve25519-dalek)
(which this code uses) have received *one* formal cryptographic and security
review. Neither have yet received what we would consider *sufficient* peer
review by other qualified cryptographers to be considered in any way, shape,
or form, safe.
**USE AT YOUR OWN RISK** **USE AT YOUR OWN RISK**
# Documentation ## A Note on Signature Malleability
Documentation is available [here](https://docs.rs/ed25519-dalek). The signatures produced by this library are malleable, as defined in
[the original paper](https://ed25519.cr.yp.to/ed25519-20110926.pdf):
![](https://raw.githubusercontent.com/isislovecruft/ed25519-dalek/develop/ed25519-malleability.png)
We could eliminate the malleability property by multiplying by the curve
cofactor, however, this would cause our implementation to *not* match the
behaviour of every other implementation in existence. While there is, as of
this writing, a
[draft RFC for EdDSA signatures](https://tools.ietf.org/html/rfc8032) which
specifies that the stronger check should be done (and while we agree that the
stronger check should be done), it is our opinion that one doesn't get to
change the definition of "ed25519 verification" a decade after the fact,
declaring every implementation (including one's own) to be non-conformant.
In short, if malleable signatures are bad for your protocol, don't use them.
Consider using a curve25519-based Verifiable Random Function (VRF), such as
[Trevor Perrin's VXEdDSA](https://www.whispersystems.org/docs/specifications/xeddsa/),
instead. We
[plan](https://github.com/isislovecruft/curve25519-dalek/issues/9) to
eventually support VXEdDSA in curve25519-dalek.
# Installation # Installation
To install, add the following to the dependencies section of your project's To install, add the following to your project's `Cargo.toml`:
`Cargo.toml`:
ed25519-dalek = "^0.2" [dependencies.ed25519-dalek]
version = "^0.3"
Then, in your library or executable source, add: Then, in your library or executable source, add:
extern crate ed25519_dalek extern crate ed25519_dalek
To cause your application to build `ed25519-dalek` with the nightly feature
enabled by default, instead do:
[dependencies.ed25519-dalek]
version = "^0.3"
features = ["nightly"]
To cause your application to instead build with the nightly feature enabled
when someone builds with `cargo build --features="nightly"` add the following
to the `Cargo.toml`:
[features]
nightly = ["ed25519-dalek/nightly"]
# TODO # TODO
* Maybe add methods to make exporting keys for backup easier. * Maybe add methods to make exporting keys for backup easier. Maybe using
* Benchmark in comparison to the ed25519_ref10 code. serde?
* We can probably make this go even faster if we implement SHA512, * We can probably make this go even faster if we implement SHA512,
rather than using the rust-crypto implementation whose API requires rather than using the rust-crypto implementation whose API requires
that we allocate memory and memzero it before mutating to store the that we allocate memory and memzero it before mutating to store the

BIN
ed25519-malleability.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB