Update README to explain features and update benches.

This commit is contained in:
Isis Lovecruft 2018-05-30 20:59:44 +00:00
parent 115174df19
commit 196fd24b63
Failed to extract signature

109
README.md
View file

@ -1,4 +1,4 @@
# ed25519-dalek [![](https://img.shields.io/crates/v/ed25519-dalek.svg)](https://crates.io/crates/ed25519-dalek) [![](https://docs.rs/ed25519-dalek/badge.svg)](https://docs.rs/ed25519-dalek) [![](https://travis-ci.org/isislovecruft/ed25519-dalek.svg?branch=master)](https://travis-ci.org/isislovecruft/ed25519-dalek?branch=master)
# ed25519-dalek [![](https://img.shields.io/crates/v/ed25519-dalek.svg)](https://crates.io/crates/ed25519-dalek) [![](https://docs.rs/ed25519-dalek/badge.svg)](https://docs.rs/ed25519-dalek) [![](https://travis-ci.org/isislovecruft/ed25519-dalek.svg?branch=master)](https://travis-ci.org/dalek-cryptography/ed25519-dalek?branch=master)
Fast and efficient Rust implementation of ed25519 key generation, signing, and
verification in Rust.
@ -18,19 +18,23 @@ 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
achieves the following performance benchmarks:
∃!isisⒶwintermute:(develop *$)~/code/rust/ed25519 ∴ cargo bench --features="bench"
Finished release [optimized] target(s) in 0.0 secs
Running target/release/deps/ed25519_dalek-281c2d7a2379edae
∃!isisⒶwintermute:(master *=)~/code/rust/ed25519-dalek ∴ cargo bench --features="nightly bench"
Compiling ed25519-dalek v0.7.0 (file:///home/isis/code/rust/ed25519-dalek)
Finished release [optimized] target(s) in 3.11s
Running target/release/deps/ed25519_dalek-ae92163eefd0cc80
running 6 tests
running 9 tests
test ed25519::test::golden ... ignored
test ed25519::test::public_key_from_bytes ... ignored
test ed25519::test::sign_verify ... ignored
test ed25519::test::unmarshal_marshal ... ignored
test ed25519::bench::key_generation ... bench: 54,571 ns/iter (+/- 7,861)
test ed25519::bench::sign ... bench: 70,009 ns/iter (+/- 22,812)
test ed25519::bench::verify ... bench: 185,619 ns/iter (+/- 24,117)
test ed25519::bench::key_generation ... bench: 30,711 ns/iter (+/- 10,936)
test ed25519::bench::sign ... bench: 39,432 ns/iter (+/- 21,387)
test ed25519::bench::sign_expanded_key ... bench: 45,753 ns/iter (+/- 25,261)
test ed25519::bench::underlying_scalar_mult_basepoint ... bench: 25,455 ns/iter (+/- 10,587)
test ed25519::bench::verify ... bench: 91,408 ns/iter (+/- 31,193)
test result: ok. 0 passed; 0 failed; 3 ignored; 3 measured
test result: ok. 0 passed; 0 failed; 4 ignored; 5 measured; 0 filtered out
In comparison, the equivalent package in Golang performs as follows:
@ -41,37 +45,22 @@ In comparison, the equivalent package in Golang performs as follows:
BenchmarkVerification 10000 212585 ns/op
ok github.com/agl/ed25519 7.500s
Making key generation, signing, and verification a rough average of one third
faster, one fifth faster, and one eighth faster respectively. Of course, this
Making key generation, signing, and verification a rough average of 33%
faster, 44% faster, and 43% faster respectively. Of course, this
is just my machine, and these results—nowhere near rigorous—should be taken
with a handful of salt.
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:
∃!isisⒶwintermute:(develop *$)~/code/rust/ed25519 ∴ cargo bench --features="bench nightly"
Finished release [optimized] target(s) in 0.0 secs
Running target/release/deps/ed25519_dalek-9d7f8674ae11ac39
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).
nanoseconds to cycles per second on a 2591 Mhz CPU, that's 237660 cycles for
verification and 102523 for signing, which for signing is competitive
with optimised assembly versions.
Additionally, if you're on the Rust nightly channel, be sure to build with
`cargo build --features="nightly"` which enables more secure compiler
optimisation protections in the
[subtle](https://github.com/dalek-cryptography/subtle) crate. Additionally, if
you're using a CSPRNG from the `rand` crate, the `nightly` feature will enable
`u128`/`i128` features there, resulting in potentially faster performance.
Additionally, thanks to Rust, this implementation has both type and memory
safety. It's also easily readable by a much larger set of people than those who
@ -118,42 +107,60 @@ eventually support VXEdDSA in curve25519-dalek.
To install, add the following to your project's `Cargo.toml`:
[dependencies.ed25519-dalek]
version = "^0.6"
```toml
[dependencies.ed25519-dalek]
version = "^0.7"
```
Then, in your library or executable source, add:
extern crate ed25519_dalek
```rust
extern crate ed25519_dalek;
```
# Features
To cause your application to build `ed25519-dalek` with the nightly feature
enabled by default, instead do:
[dependencies.ed25519-dalek]
version = "^0.6"
features = ["nightly"]
```toml
[dependencies.ed25519-dalek]
version = "^0.7"
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"]
Using the `nightly` feature will nearly double the latency of signing and
verification.
```toml
[features]
nightly = ["ed25519-dalek/nightly"]
```
To enable [serde](https://serde.rs) support, build `ed25519-dalek` with:
[dependencies.ed25519-dalek]
version = "^0.6"
features = ["serde"]
```toml
[dependencies.ed25519-dalek]
version = "^0.7"
features = ["serde"]
```
By default, `ed25519-dalek` builds against `curve25519-dalek`'s `u64_backend`
feature, which uses Rust's `i128` feature to achieve roughly double the speed as
the `u32_backend` feature. When targetting 32-bit systems, however, you'll
likely want to compile with
`cargo build --no-default-features --features="u32_backend"`.
If you're building for a machine with avx2 instructions, there's also the
experimental `avx2_backend`. To use it, compile with
`RUSTFLAGS="-C target_cpu=native" cargo build --no-default-features --features="avx2_backend"`
# TODO
* Batch signature verification, maybe?
* We can probably make this go even faster if we implement SHA512,
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 bzero it before mutating to store the
digest.
* Incorporate ed25519-dalek into Brian Smith's
[crypto-bench](https://github.com/briansmith/crypto-bench).