Merge branch 'release/0.7.0'

This commit is contained in:
Isis Lovecruft 2018-07-15 23:24:51 +00:00
commit e6f224616d
Failed to extract signature
7 changed files with 701 additions and 369 deletions

View file

@ -7,23 +7,14 @@ rust:
env: env:
- TEST_COMMAND=test FEATURES='' - TEST_COMMAND=test FEATURES=''
- TEST_COMMAND=test FEATURES=--features="serde"
matrix: matrix:
include: include:
- rust: stable
env: TEST_COMMAND=test FEATURES=--features="serde"
- rust: beta
env: TEST_COMMAND=test FEATURES=--features="serde"
- rust: nightly - rust: nightly
env: TEST_COMMAND=test FEATURES=--features="serde" env: TEST_COMMAND=build FEATURES="--no-default-features --features=u32_backend"
- rust: nightly
env: TEST_COMMAND=build FEATURES=--no-default-features
- rust: nightly - rust: nightly
env: TEST_COMMAND=test FEATURES=--features="nightly" env: TEST_COMMAND=test FEATURES=--features="nightly"
- rust: nightly
env: TEST_COMMAND=bench FEATURES=--features="bench"
- rust: nightly
env: TEST_COMMAND=bench FEATURES=--features="nightly bench"
script: script:
- cargo $TEST_COMMAND $FEATURES - cargo $TEST_COMMAND $FEATURES

View file

@ -1,6 +1,6 @@
[package] [package]
name = "ed25519-dalek" name = "ed25519-dalek"
version = "0.6.2" version = "0.7.0"
authors = ["Isis Lovecruft <isis@patternsinthevoid.net>"] authors = ["Isis Lovecruft <isis@patternsinthevoid.net>"]
readme = "README.md" readme = "README.md"
license = "BSD-3-Clause" license = "BSD-3-Clause"
@ -16,16 +16,12 @@ exclude = [ ".gitignore", "TESTVECTORS", "res/*" ]
travis-ci = { repository = "dalek-cryptography/ed25519-dalek", branch = "master"} travis-ci = { repository = "dalek-cryptography/ed25519-dalek", branch = "master"}
[dependencies.curve25519-dalek] [dependencies.curve25519-dalek]
version = "0.16" version = "0.18"
default-features = false
[dependencies.subtle]
version = "0.6"
default-features = false default-features = false
[dependencies.rand] [dependencies.rand]
optional = true version = "0.5"
version = "0.4" default-features = false
[dependencies.digest] [dependencies.digest]
version = "^0.7" version = "^0.7"
@ -50,11 +46,19 @@ default-features = false
hex = "^0.3" hex = "^0.3"
sha2 = "^0.7" sha2 = "^0.7"
bincode = "^0.9" bincode = "^0.9"
criterion = "0.2"
[[bench]]
name = "ed25519_benchmarks"
harness = false
[features] [features]
default = ["std"] default = ["std", "u64_backend"]
std = ["rand", "subtle/std", "curve25519-dalek/std", "failure/std"] # We don't add "rand/std" here because it would enable a bunch of Fuchsia dependencies.
bench = [] std = ["curve25519-dalek/std"]
nightly = ["curve25519-dalek/nightly", "subtle/nightly"] nightly = ["curve25519-dalek/nightly", "rand/nightly"]
asm = ["sha2/asm"] asm = ["sha2/asm"]
yolocrypto = ["curve25519-dalek/yolocrypto"] yolocrypto = ["curve25519-dalek/yolocrypto"]
u64_backend = ["curve25519-dalek/u64_backend"]
u32_backend = ["curve25519-dalek/u32_backend"]
avx2_backend = ["curve25519-dalek/avx2_backend"]

135
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/dalek-cryptography/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 Fast and efficient Rust implementation of ed25519 key generation, signing, and
verification in Rust. verification in Rust.
@ -14,64 +14,51 @@ 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 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!) 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 i9-7900X running at 3.30 GHz, without TurboBoost, this code achieves
also running in QubesOS with *lots* of other VMs executing), this code the following performance benchmarks:
achieves the following performance benchmarks:
∃!isisⒶwintermute:(develop *$)~/code/rust/ed25519 ∴ cargo bench --features="bench" ∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ cargo bench
Finished release [optimized] target(s) in 0.0 secs Compiling ed25519-dalek v0.7.0 (file:///home/isis/code/rust/ed25519-dalek)
Running target/release/deps/ed25519_dalek-281c2d7a2379edae Finished release [optimized] target(s) in 3.11s
Running target/release/deps/ed25519_benchmarks-721332beed423bce
running 6 tests Ed25519 signing time: [15.617 us 15.630 us 15.647 us]
test ed25519::test::golden ... ignored Ed25519 signature verification time: [45.930 us 45.968 us 46.011 us]
test ed25519::test::sign_verify ... ignored Ed25519 keypair generation time: [15.440 us 15.465 us 15.492 us]
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 result: ok. 0 passed; 0 failed; 3 ignored; 3 measured By enabling the avx2 backend (on machines with compatible microarchitectures),
the performance for signature verification is greatly improved:
∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ export RUSTFLAGS="-C target_cpu=native"
∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ cargo bench --no-default-features --features "std avx2_backend"
Compiling ed25519-dalek v0.7.0 (file:///home/isis/code/rust/ed25519-dalek)
Finished release [optimized] target(s) in 4.28s
Running target/release/deps/ed25519_benchmarks-e4866664de39c84d
Ed25519 signing time: [15.923 us 15.945 us 15.967 us]
Ed25519 signature verification time: [33.382 us 33.411 us 33.445 us]
Ed25519 keypair generation time: [15.246 us 15.260 us 15.275 us]
In comparison, 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 BenchmarkKeyGeneration 30000 47007 ns/op
BenchmarkKeyGeneration 20000 85880 ns/op BenchmarkSigning 30000 48820 ns/op
BenchmarkSigning 20000 89115 ns/op BenchmarkVerification 10000 119701 ns/op
BenchmarkVerification 10000 212585 ns/op ok github.com/agl/ed25519 5.775s
ok github.com/agl/ed25519 7.500s
Making key generation, signing, and verification a rough average of one third Making key generation and signing a rough average of 2x faster, and
faster, one fifth faster, and one eighth faster respectively. Of course, this verification 2.5-3x faster depending on the availability of avx2. 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 handful of salt. with a handful of salt.
Additionally, if you're on the Rust nightly channel, be sure to build with Translating to a rough cycle count: we multiply by a factor of 3.3 to convert
`cargo build --features="nightly"`, which uses Rust's experimental support for nanoseconds to cycles per second on a 3300 Mhz CPU, that's 110256 cycles for
the `u128` type in curve25519-dalek to speed up field arithmetic by roughly a verification and 52618 for signing, which is competitive with hand-optimised
factor of two. The benchmarks using nightly (on the same machine as above) assembly implementations.
are:
∃!isisⒶwintermute:(develop *$)~/code/rust/ed25519 ∴ cargo bench --features="bench nightly" Additionally, if you're using a CSPRNG from the `rand` crate, the `nightly`
Finished release [optimized] target(s) in 0.0 secs feature will enable `u128`/`i128` features there, resulting in potentially
Running target/release/deps/ed25519_dalek-9d7f8674ae11ac39 faster performance.
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 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 safety. It's also easily readable by a much larger set of people than those who
@ -82,7 +69,7 @@ valuable than simply cycle counts alone.
# Warnings # Warnings
ed25519-dalek and ed25519-dalek and
[our elliptic curve library](https://github.com/isislovecruft/curve25519-dalek) [our elliptic curve library](https://github.com/dalek-cryptography/curve25519-dalek)
(which this code uses) have received *one* formal cryptographic and security (which this code uses) have received *one* formal cryptographic and security
review. Neither have yet received what we would consider *sufficient* peer review. Neither have yet received what we would consider *sufficient* peer
review by other qualified cryptographers to be considered in any way, shape, review by other qualified cryptographers to be considered in any way, shape,
@ -96,7 +83,7 @@ or form, safe.
The signatures produced by this library are malleable, as discussed in The signatures produced by this library are malleable, as discussed in
[the original paper](https://ed25519.cr.yp.to/ed25519-20110926.pdf): [the original paper](https://ed25519.cr.yp.to/ed25519-20110926.pdf):
![](https://github.com/isislovecruft/ed25519-dalek/blob/develop/res/ed25519-malleability.png) ![](https://github.com/dalek-cryptography/ed25519-dalek/blob/master/res/ed25519-malleability.png)
We could eliminate the malleability property by multiplying by the curve We could eliminate the malleability property by multiplying by the curve
cofactor, however, this would cause our implementation to *not* match the cofactor, however, this would cause our implementation to *not* match the
@ -111,49 +98,67 @@ 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 Consider using a curve25519-based Verifiable Random Function (VRF), such as
[Trevor Perrin's VXEdDSA](https://www.whispersystems.org/docs/specifications/xeddsa/), [Trevor Perrin's VXEdDSA](https://www.whispersystems.org/docs/specifications/xeddsa/),
instead. We instead. We
[plan](https://github.com/isislovecruft/curve25519-dalek/issues/9) to [plan](https://github.com/dalek-cryptography/curve25519-dalek/issues/9) to
eventually support VXEdDSA in curve25519-dalek. eventually support VXEdDSA in curve25519-dalek.
# Installation # Installation
To install, add the following to your project's `Cargo.toml`: To install, add the following to your project's `Cargo.toml`:
[dependencies.ed25519-dalek] ```toml
version = "^0.6" [dependencies.ed25519-dalek]
version = "^0.7"
```
Then, in your library or executable source, add: 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 To cause your application to build `ed25519-dalek` with the nightly feature
enabled by default, instead do: enabled by default, instead do:
[dependencies.ed25519-dalek] ```toml
version = "^0.6" [dependencies.ed25519-dalek]
features = ["nightly"] version = "^0.7"
features = ["nightly"]
```
To cause your application to instead build with the nightly feature enabled To cause your application to instead build with the nightly feature enabled
when someone builds with `cargo build --features="nightly"` add the following when someone builds with `cargo build --features="nightly"` add the following
to the `Cargo.toml`: to the `Cargo.toml`:
[features] ```toml
nightly = ["ed25519-dalek/nightly"] [features]
nightly = ["ed25519-dalek/nightly"]
Using the `nightly` feature will nearly double the latency of signing and ```
verification.
To enable [serde](https://serde.rs) support, build `ed25519-dalek` with: To enable [serde](https://serde.rs) support, build `ed25519-dalek` with:
[dependencies.ed25519-dalek] ```toml
version = "^0.6" [dependencies.ed25519-dalek]
features = ["serde"] 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 # TODO
* Batch signature verification, maybe?
* 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 bzero it before mutating to store the
digest. digest.
* Incorporate ed25519-dalek into Brian Smith's * Incorporate ed25519-dalek into Brian Smith's
[crypto-bench](https://github.com/briansmith/crypto-bench). [crypto-bench](https://github.com/briansmith/crypto-bench).

View file

@ -0,0 +1,80 @@
// -*- mode: rust; -*-
//
// This file is part of ed25519-dalek.
// Copyright (c) 2018 Isis Lovecruft
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
#[macro_use]
extern crate criterion;
extern crate ed25519_dalek;
extern crate rand;
extern crate sha2;
use criterion::Criterion;
mod ed25519_benches {
use super::*;
use ed25519_dalek::ExpandedSecretKey;
use ed25519_dalek::Keypair;
use ed25519_dalek::Signature;
use rand::thread_rng;
use rand::ThreadRng;
use sha2::Sha512;
fn sign(c: &mut Criterion) {
let mut csprng: ThreadRng = thread_rng();
let keypair: Keypair = Keypair::generate::<Sha512, _>(&mut csprng);
let msg: &[u8] = b"";
c.bench_function("Ed25519 signing", move |b| {
b.iter(| | keypair.sign::<Sha512>(msg))
});
}
fn sign_expanded_key(c: &mut Criterion) {
let mut csprng: ThreadRng = thread_rng();
let keypair: Keypair = Keypair::generate::<Sha512, _>(&mut csprng);
let expanded: ExpandedSecretKey = keypair.secret.expand::<Sha512>();
let msg: &[u8] = b"";
c.bench_function("Ed25519 signing with an expanded secret key", move |b| {
b.iter(| | expanded.sign::<Sha512>(msg, &keypair.public))
});
}
fn verify(c: &mut Criterion) {
let mut csprng: ThreadRng = thread_rng();
let keypair: Keypair = Keypair::generate::<Sha512, _>(&mut csprng);
let msg: &[u8] = b"";
let sig: Signature = keypair.sign::<Sha512>(msg);
c.bench_function("Ed25519 signature verification", move |b| {
b.iter(| | keypair.verify::<Sha512>(msg, &sig))
});
}
fn key_generation(c: &mut Criterion) {
let mut csprng: ThreadRng = thread_rng();
c.bench_function("Ed25519 keypair generation", move |b| {
b.iter(| | Keypair::generate::<Sha512, _>(&mut csprng))
});
}
criterion_group!{
name = ed25519_benches;
config = Criterion::default();
targets =
sign,
sign_expanded_key,
verify,
key_generation,
}
}
criterion_main!(
ed25519_benches::ed25519_benches,
);

File diff suppressed because it is too large Load diff

View file

@ -20,7 +20,6 @@ use core::fmt::Display;
/// need to pay any attention to these. /// need to pay any attention to these.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub (crate) enum InternalError { pub (crate) enum InternalError {
#[allow(dead_code)]
PointDecompressionError, PointDecompressionError,
ScalarFormatError, ScalarFormatError,
/// An error in the length of bytes handed to a constructor. /// An error in the length of bytes handed to a constructor.
@ -29,55 +28,52 @@ pub (crate) enum InternalError {
/// returning the error, and the `length` in bytes which its constructor /// returning the error, and the `length` in bytes which its constructor
/// expects. /// expects.
BytesLengthError{ name: &'static str, length: usize }, BytesLengthError{ name: &'static str, length: usize },
/// The verification equation wasn't satisfied
VerifyError,
} }
impl Display for InternalError { impl Display for InternalError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
InternalError::PointDecompressionError InternalError::PointDecompressionError
=> write!(f, "Cannot decompress extended twisted edwards point"), => write!(f, "Cannot decompress Edwards point"),
InternalError::ScalarFormatError InternalError::ScalarFormatError
=> write!(f, "Cannot use scalar with high-bit set"), => write!(f, "Cannot use scalar with high-bit set"),
InternalError::BytesLengthError{ name: n, length: l} InternalError::BytesLengthError{ name: n, length: l}
=> write!(f, "{} must be {} bytes in length", n, l), => write!(f, "{} must be {} bytes in length", n, l),
InternalError::VerifyError
=> write!(f, "Verification equation was not satisfied"),
} }
} }
} }
impl ::failure::Fail for InternalError {} impl ::failure::Fail for InternalError {}
/// Errors which may occur in the `from_bytes()` constructors of `PublicKey`, /// Errors which may occur while processing signatures and keypairs.
/// `SecretKey`, `ExpandedSecretKey`, `Keypair`, and `Signature`.
///
/// There was an internal problem due to parsing the `Signature`.
/// ///
/// This error may arise due to: /// This error may arise due to:
/// ///
/// * Being given bytes with a length different to what was expected.
///
/// * A problem decompressing `r`, a curve point, in the `Signature`, or the /// * A problem decompressing `r`, a curve point, in the `Signature`, or the
/// curve point for a `PublicKey`. /// curve point for a `PublicKey`.
///
/// * A problem with the format of `s`, a scalar, in the `Signature`. This /// * A problem with the format of `s`, a scalar, in the `Signature`. This
/// is only raised if the high-bit of the scalar was set. (Scalars must /// is only raised if the high-bit of the scalar was set. (Scalars must
/// only be constructed from 255-bit integers.) /// only be constructed from 255-bit integers.)
/// * Being given bytes with a length different to what was expected. ///
/// * Failure of a signature to satisfy the verification equation.
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
pub struct DecodingError(pub (crate) InternalError); pub struct SignatureError(pub (crate) InternalError);
impl Display for DecodingError { impl Display for SignatureError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 { write!(f, "{}", self.0)
InternalError::PointDecompressionError => write!(f, "{}", self.0),
InternalError::ScalarFormatError => write!(f, "{}", self.0),
InternalError::BytesLengthError{ name: _, length: _ } => write!(f, "{}", self.0),
}
} }
} }
impl ::failure::Fail for DecodingError { impl ::failure::Fail for SignatureError {
fn cause(&self) -> Option<&::failure::Fail> { fn cause(&self) -> Option<&::failure::Fail> {
match self.0 { Some(&self.0)
InternalError::PointDecompressionError => Some(&self.0),
InternalError::ScalarFormatError => Some(&self.0),
InternalError::BytesLengthError{ name: _, length: _} => Some(&self.0),
}
} }
} }

View file

@ -15,7 +15,7 @@
//! //!
//! First, we need to generate a `Keypair`, which includes both public and //! First, we need to generate a `Keypair`, which includes both public and
//! secret halves of an asymmetric key. To do so, we need a cryptographically //! secret halves of an asymmetric key. To do so, we need a cryptographically
//! secure pseudorandom number generator (CSPRING), and a hash function which //! secure pseudorandom number generator (CSPRNG), and a hash function which
//! has 512 bits of output. For this example, we'll use the operating //! has 512 bits of output. For this example, we'll use the operating
//! system's builtin PRNG and SHA-512 to generate a keypair: //! system's builtin PRNG and SHA-512 to generate a keypair:
//! //!
@ -24,6 +24,7 @@
//! extern crate sha2; //! extern crate sha2;
//! extern crate ed25519_dalek; //! extern crate ed25519_dalek;
//! //!
//! # #[cfg(all(feature = "std", feature = "sha2"))]
//! # fn main() { //! # fn main() {
//! use rand::Rng; //! use rand::Rng;
//! use rand::OsRng; //! use rand::OsRng;
@ -31,9 +32,12 @@
//! use ed25519_dalek::Keypair; //! use ed25519_dalek::Keypair;
//! use ed25519_dalek::Signature; //! use ed25519_dalek::Signature;
//! //!
//! let mut cspring: OsRng = OsRng::new().unwrap(); //! let mut csprng: OsRng = OsRng::new().unwrap();
//! let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring); //! let keypair: Keypair = Keypair::generate::<Sha512, _>(&mut csprng);
//! # } //! # }
//! #
//! # #[cfg(any(not(feature = "std"), not(feature = "sha2")))]
//! # fn main() { }
//! ``` //! ```
//! //!
//! We can now use this `keypair` to sign a message: //! We can now use this `keypair` to sign a message:
@ -44,12 +48,13 @@
//! # extern crate ed25519_dalek; //! # extern crate ed25519_dalek;
//! # fn main() { //! # fn main() {
//! # use rand::Rng; //! # use rand::Rng;
//! # use rand::OsRng; //! # use rand::ChaChaRng;
//! # use rand::SeedableRng;
//! # use sha2::Sha512; //! # use sha2::Sha512;
//! # use ed25519_dalek::Keypair; //! # use ed25519_dalek::Keypair;
//! # use ed25519_dalek::Signature; //! # use ed25519_dalek::Signature;
//! # let mut cspring: OsRng = OsRng::new().unwrap(); //! # let mut csprng: ChaChaRng = ChaChaRng::from_seed([0u8; 32]);
//! # let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring); //! # let keypair: Keypair = Keypair::generate::<Sha512, _>(&mut csprng);
//! let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); //! let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
//! let signature: Signature = keypair.sign::<Sha512>(message); //! let signature: Signature = keypair.sign::<Sha512>(message);
//! # } //! # }
@ -64,17 +69,16 @@
//! # extern crate ed25519_dalek; //! # extern crate ed25519_dalek;
//! # fn main() { //! # fn main() {
//! # use rand::Rng; //! # use rand::Rng;
//! # use rand::OsRng; //! # use rand::ChaChaRng;
//! # use rand::SeedableRng;
//! # use sha2::Sha512; //! # use sha2::Sha512;
//! # use ed25519_dalek::Keypair; //! # use ed25519_dalek::Keypair;
//! # use ed25519_dalek::Signature; //! # use ed25519_dalek::Signature;
//! # let mut cspring: OsRng = OsRng::new().unwrap(); //! # let mut csprng: ChaChaRng = ChaChaRng::from_seed([0u8; 32]);
//! # let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring); //! # let keypair: Keypair = Keypair::generate::<Sha512, _>(&mut csprng);
//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); //! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
//! # let signature: Signature = keypair.sign::<Sha512>(message); //! # let signature: Signature = keypair.sign::<Sha512>(message);
//! let verified: bool = keypair.verify::<Sha512>(message, &signature); //! assert!(keypair.verify::<Sha512>(message, &signature).is_ok());
//!
//! assert!(verified);
//! # } //! # }
//! ``` //! ```
//! //!
@ -87,20 +91,19 @@
//! # extern crate ed25519_dalek; //! # extern crate ed25519_dalek;
//! # fn main() { //! # fn main() {
//! # use rand::Rng; //! # use rand::Rng;
//! # use rand::OsRng; //! # use rand::ChaChaRng;
//! # use rand::SeedableRng;
//! # use sha2::Sha512; //! # use sha2::Sha512;
//! # use ed25519_dalek::Keypair; //! # use ed25519_dalek::Keypair;
//! # use ed25519_dalek::Signature; //! # use ed25519_dalek::Signature;
//! use ed25519_dalek::PublicKey; //! use ed25519_dalek::PublicKey;
//! # let mut cspring: OsRng = OsRng::new().unwrap(); //! # let mut csprng: ChaChaRng = ChaChaRng::from_seed([0u8; 32]);
//! # let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring); //! # let keypair: Keypair = Keypair::generate::<Sha512, _>(&mut csprng);
//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); //! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
//! # let signature: Signature = keypair.sign::<Sha512>(message); //! # let signature: Signature = keypair.sign::<Sha512>(message);
//! //!
//! let public_key: PublicKey = keypair.public; //! let public_key: PublicKey = keypair.public;
//! let verified: bool = public_key.verify::<Sha512>(message, &signature); //! assert!(public_key.verify::<Sha512>(message, &signature).is_ok());
//!
//! assert!(verified);
//! # } //! # }
//! ``` //! ```
//! //!
@ -117,16 +120,15 @@
//! # extern crate sha2; //! # extern crate sha2;
//! # extern crate ed25519_dalek; //! # extern crate ed25519_dalek;
//! # fn main() { //! # fn main() {
//! # use rand::{Rng, OsRng}; //! # use rand::{Rng, ChaChaRng, SeedableRng};
//! # use sha2::Sha512; //! # use sha2::Sha512;
//! # use ed25519_dalek::{Keypair, Signature, PublicKey}; //! # use ed25519_dalek::{Keypair, Signature, PublicKey};
//! use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH}; //! use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH};
//! # let mut cspring: OsRng = OsRng::new().unwrap(); //! # let mut csprng: ChaChaRng = ChaChaRng::from_seed([0u8; 32]);
//! # let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring); //! # let keypair: Keypair = Keypair::generate::<Sha512, _>(&mut csprng);
//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); //! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
//! # let signature: Signature = keypair.sign::<Sha512>(message); //! # let signature: Signature = keypair.sign::<Sha512>(message);
//! # let public_key: PublicKey = keypair.public; //! # let public_key: PublicKey = keypair.public;
//! # let verified: bool = public_key.verify::<Sha512>(message, &signature);
//! //!
//! let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = public_key.to_bytes(); //! let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = public_key.to_bytes();
//! let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = keypair.secret.to_bytes(); //! let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = keypair.secret.to_bytes();
@ -141,13 +143,13 @@
//! # extern crate rand; //! # extern crate rand;
//! # extern crate sha2; //! # extern crate sha2;
//! # extern crate ed25519_dalek; //! # extern crate ed25519_dalek;
//! # use rand::{Rng, OsRng}; //! # use rand::{Rng, ChaChaRng, SeedableRng};
//! # use sha2::Sha512; //! # use sha2::Sha512;
//! # use ed25519_dalek::{Keypair, Signature, PublicKey, SecretKey, DecodingError}; //! # use ed25519_dalek::{Keypair, Signature, PublicKey, SecretKey, SignatureError};
//! # use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH}; //! # use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH};
//! # fn do_test() -> Result<(SecretKey, PublicKey, Keypair, Signature), DecodingError> { //! # fn do_test() -> Result<(SecretKey, PublicKey, Keypair, Signature), SignatureError> {
//! # let mut cspring: OsRng = OsRng::new().unwrap(); //! # let mut csprng: ChaChaRng = ChaChaRng::from_seed([0u8; 32]);
//! # let keypair_orig: Keypair = Keypair::generate::<Sha512>(&mut cspring); //! # let keypair_orig: Keypair = Keypair::generate::<Sha512, _>(&mut csprng);
//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); //! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
//! # let signature_orig: Signature = keypair_orig.sign::<Sha512>(message); //! # let signature_orig: Signature = keypair_orig.sign::<Sha512>(message);
//! # let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = keypair_orig.public.to_bytes(); //! # let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = keypair_orig.public.to_bytes();
@ -173,7 +175,7 @@
//! types additionally come with built-in [serde](https://serde.rs) support by //! types additionally come with built-in [serde](https://serde.rs) support by
//! building `ed25519-dalek` via: //! building `ed25519-dalek` via:
//! //!
//! ```ignore,bash //! ```bash
//! $ cargo build --features="serde" //! $ cargo build --features="serde"
//! ``` //! ```
//! //!
@ -191,12 +193,12 @@
//! //!
//! # #[cfg(feature = "serde")] //! # #[cfg(feature = "serde")]
//! # fn main() { //! # fn main() {
//! # use rand::{Rng, OsRng}; //! # use rand::{Rng, ChaChaRng, SeedableRng};
//! # use sha2::Sha512; //! # use sha2::Sha512;
//! # use ed25519_dalek::{Keypair, Signature, PublicKey}; //! # use ed25519_dalek::{Keypair, Signature, PublicKey};
//! use bincode::{serialize, Infinite}; //! use bincode::{serialize, Infinite};
//! # let mut cspring: OsRng = OsRng::new().unwrap(); //! # let mut csprng: ChaChaRng = ChaChaRng::from_seed([0u8; 32]);
//! # let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring); //! # let keypair: Keypair = Keypair::generate::<Sha512>(&mut csprng);
//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); //! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
//! # let signature: Signature = keypair.sign::<Sha512>(message); //! # let signature: Signature = keypair.sign::<Sha512>(message);
//! # let public_key: PublicKey = keypair.public; //! # let public_key: PublicKey = keypair.public;
@ -223,14 +225,14 @@
//! # //! #
//! # #[cfg(feature = "serde")] //! # #[cfg(feature = "serde")]
//! # fn main() { //! # fn main() {
//! # use rand::{Rng, OsRng}; //! # use rand::{Rng, ChaChaRng, SeedableRng};
//! # use sha2::Sha512; //! # use sha2::Sha512;
//! # use ed25519_dalek::{Keypair, Signature, PublicKey}; //! # use ed25519_dalek::{Keypair, Signature, PublicKey};
//! # use bincode::{serialize, Infinite}; //! # use bincode::{serialize, Infinite};
//! use bincode::{deserialize}; //! use bincode::{deserialize};
//! //!
//! # let mut cspring: OsRng = OsRng::new().unwrap(); //! # let mut csprng: ChaChaRng = ChaChaRng::from_seed([0u8; 32]);
//! # let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring); //! # let keypair: Keypair = Keypair::generate::<Sha512>(&mut csprng);
//! let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); //! let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
//! # let signature: Signature = keypair.sign::<Sha512>(message); //! # let signature: Signature = keypair.sign::<Sha512>(message);
//! # let public_key: PublicKey = keypair.public; //! # let public_key: PublicKey = keypair.public;
@ -260,10 +262,7 @@
extern crate curve25519_dalek; extern crate curve25519_dalek;
extern crate generic_array; extern crate generic_array;
extern crate digest; extern crate digest;
extern crate subtle;
extern crate failure; extern crate failure;
#[cfg(feature = "std")]
extern crate rand; extern crate rand;
#[cfg(any(feature = "std", test))] #[cfg(any(feature = "std", test))]