From 762eb0c4703c0a954961f0aeb31974b60f807e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sat, 5 Jan 2019 15:58:59 +0300 Subject: [PATCH 01/10] use rand_core --- Cargo.toml | 15 ++++++--- src/ed25519.rs | 86 +++++++++++++++++++++++++------------------------- src/lib.rs | 6 +++- 3 files changed, 58 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9e3e300..89b9fea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,13 @@ travis-ci = { repository = "dalek-cryptography/ed25519-dalek", branch = "master" version = "1.0.0-pre.0" default-features = false -[dependencies.rand] -version = "0.5" +[dependencies.rand_core] +version = "0.3" default-features = false -features = ["i128_support"] + +[dependencies.rand] +version = "0.6" +optional = true [dependencies.serde] version = "^1.0" @@ -44,6 +47,8 @@ hex = "^0.3" sha2 = "^0.8" bincode = "^0.9" criterion = "0.2" +rand_os = "0.1.0" +rand_chacha = "0.1.0" [[bench]] name = "ed25519_benchmarks" @@ -52,9 +57,9 @@ harness = false [features] default = ["std", "u64_backend"] # We don't add "rand/std" here because it would enable a bunch of Fuchsia dependencies. -std = ["curve25519-dalek/std"] +std = ["curve25519-dalek/std", "rand"] alloc = ["curve25519-dalek/alloc"] -nightly = ["curve25519-dalek/nightly", "rand/nightly", "clear_on_drop/nightly"] +nightly = ["curve25519-dalek/nightly", "clear_on_drop/nightly"] asm = ["sha2/asm"] yolocrypto = ["curve25519-dalek/yolocrypto"] u64_backend = ["curve25519-dalek/u64_backend"] diff --git a/src/ed25519.rs b/src/ed25519.rs index 0654eb1..829908d 100644 --- a/src/ed25519.rs +++ b/src/ed25519.rs @@ -13,8 +13,7 @@ use core::default::Default; use core::fmt::{Debug}; -use rand::CryptoRng; -use rand::Rng; +use rand_core::{CryptoRng, RngCore}; #[cfg(feature = "serde")] use serde::{Serialize, Deserialize}; @@ -253,15 +252,15 @@ impl SecretKey { /// # Example /// /// ``` - /// extern crate rand; + /// extern crate rand_os; /// extern crate sha2; /// extern crate ed25519_dalek; /// /// # #[cfg(feature = "std")] /// # fn main() { /// # - /// use rand::Rng; - /// use rand::OsRng; + /// use rand_os::OsRng; + /// use sha2::Sha512; /// use ed25519_dalek::PublicKey; /// use ed25519_dalek::SecretKey; @@ -280,15 +279,15 @@ impl SecretKey { /// traits, and which returns 512 bits of output—via: /// /// ``` - /// # extern crate rand; + /// # extern crate rand_chacha; + /// # extern crate rand_core; /// # extern crate sha2; /// # extern crate ed25519_dalek; /// # /// # fn main() { /// # - /// # use rand::Rng; - /// # use rand::ChaChaRng; - /// # use rand::SeedableRng; + /// # use rand_core::SeedableRng; + /// # use rand_chacha::ChaChaRng; /// # use sha2::Sha512; /// # use ed25519_dalek::PublicKey; /// # use ed25519_dalek::SecretKey; @@ -309,7 +308,7 @@ impl SecretKey { /// /// A CSPRNG with a `fill_bytes()` method, e.g. `rand::ChaChaRng` pub fn generate(csprng: &mut T) -> SecretKey - where T: CryptoRng + Rng, + where T: CryptoRng + RngCore, { let mut sk: SecretKey = SecretKey([0u8; 32]); @@ -403,14 +402,14 @@ impl<'a> From<&'a SecretKey> for ExpandedSecretKey { /// # Examples /// /// ``` - /// # extern crate rand; + /// # extern crate rand_os; /// # extern crate sha2; /// # extern crate ed25519_dalek; /// # /// # #[cfg(all(feature = "std", feature = "sha2"))] /// # fn main() { /// # - /// use rand::{Rng, OsRng}; + /// use rand_os::OsRng; /// use sha2::Sha512; /// use ed25519_dalek::{SecretKey, ExpandedSecretKey}; /// @@ -439,14 +438,14 @@ impl ExpandedSecretKey { /// # Examples /// /// ``` - /// # extern crate rand; + /// # extern crate rand_os; /// # extern crate sha2; /// # extern crate ed25519_dalek; /// # /// # #[cfg(all(feature = "sha2", feature = "std"))] /// # fn main() { /// # - /// use rand::{Rng, OsRng}; + /// use rand_os::OsRng; /// use sha2::Sha512; /// use ed25519_dalek::{SecretKey, ExpandedSecretKey}; /// @@ -480,16 +479,17 @@ impl ExpandedSecretKey { /// # Examples /// /// ``` - /// # extern crate rand; + /// # extern crate rand_os; /// # extern crate sha2; /// # extern crate ed25519_dalek; /// # + /// use rand_os::OsRng; + /// use ed25519_dalek::{SecretKey, ExpandedSecretKey}; + /// use ed25519_dalek::SignatureError; + /// # /// # #[cfg(all(feature = "sha2", feature = "std"))] /// # fn do_test() -> Result { /// # - /// use rand::{Rng, OsRng}; - /// use ed25519_dalek::{SecretKey, ExpandedSecretKey}; - /// use ed25519_dalek::SignatureError; /// /// let mut csprng: OsRng = OsRng::new().unwrap(); /// let secret_key: SecretKey = SecretKey::generate(&mut csprng); @@ -530,14 +530,14 @@ impl ExpandedSecretKey { /// # Examples /// /// ``` - /// # extern crate rand; + /// # extern crate rand_os; /// # extern crate sha2; /// # extern crate ed25519_dalek; /// # /// # #[cfg(all(feature = "std", feature = "sha2"))] /// # fn main() { /// # - /// use rand::{Rng, OsRng}; + /// use rand_os::OsRng; /// use sha2::Sha512; /// use ed25519_dalek::{SecretKey, ExpandedSecretKey}; /// @@ -914,7 +914,7 @@ impl From for PublicKey { /// * `messages` is a slice of byte slices, one per signed message. /// * `signatures` is a slice of `Signature`s. /// * `public_keys` is a slice of `PublicKey`s. -/// * `csprng` is an implementation of `Rng + CryptoRng`, such as `rand::ThreadRng`. +/// * `csprng` is an implementation of `Rng + CryptoRng`, such as `rand::rngs::ThreadRng`. /// /// # Panics /// @@ -939,7 +939,7 @@ impl From for PublicKey { /// use ed25519_dalek::PublicKey; /// use ed25519_dalek::Signature; /// use rand::thread_rng; -/// use rand::ThreadRng; +/// use rand::rngs::ThreadRng; /// use sha2::Sha512; /// /// # fn main() { @@ -972,7 +972,7 @@ pub fn verify_batch(messages: &[&[u8]], use std::vec::Vec; use core::iter::once; - use rand::thread_rng; + use rand::{Rng, thread_rng}; use curve25519_dalek::traits::IsIdentity; use curve25519_dalek::traits::VartimeMultiscalarMul; @@ -1111,15 +1111,14 @@ impl Keypair { /// # Example /// /// ``` - /// extern crate rand; + /// extern crate rand_os; /// extern crate sha2; /// extern crate ed25519_dalek; /// /// # #[cfg(all(feature = "std", feature = "sha2"))] /// # fn main() { /// - /// use rand::Rng; - /// use rand::OsRng; + /// use rand_os::OsRng; /// use sha2::Sha512; /// use ed25519_dalek::Keypair; /// use ed25519_dalek::Signature; @@ -1135,7 +1134,7 @@ impl Keypair { /// /// # Input /// - /// A CSPRNG with a `fill_bytes()` method, e.g. `rand::ChaChaRng`. + /// A CSPRNG with a `fill_bytes()` method, e.g. `rand_chacha::ChaChaRng`. /// /// The caller must also supply a hash function which implements the /// `Digest` and `Default` traits, and which returns 512 bits of output. @@ -1144,7 +1143,7 @@ impl Keypair { /// Other suitable hash functions include Keccak-512 and Blake2b-512. pub fn generate(csprng: &mut R) -> Keypair where D: Digest + Default, - R: CryptoRng + Rng, + R: CryptoRng + RngCore, { let sk: SecretKey = SecretKey::generate(csprng); let pk: PublicKey = PublicKey::from_secret::(&sk); @@ -1184,8 +1183,8 @@ impl Keypair { /// use ed25519_dalek::Keypair; /// use ed25519_dalek::Signature; /// use rand::thread_rng; - /// use rand::ThreadRng; - /// use sha2::Sha512; + /// use rand::rngs::ThreadRng; + /// use sha2::{Sha512, Digest}; /// /// # #[cfg(all(feature = "std", feature = "sha2"))] /// # fn main() { @@ -1194,7 +1193,7 @@ impl Keypair { /// let message: &[u8] = b"All I want is to pet all of the dogs."; /// /// // Create a hash digest object which we'll feed the message into: - /// let prehashed: Sha512 = Sha512::default(); + /// let mut prehashed: Sha512 = Sha512::default(); /// /// prehashed.input(message); /// # } @@ -1232,15 +1231,15 @@ impl Keypair { /// # use ed25519_dalek::Keypair; /// # use ed25519_dalek::Signature; /// # use rand::thread_rng; - /// # use rand::ThreadRng; - /// # use sha2::Sha512; + /// # use rand::rngs::ThreadRng; + /// # use sha2::{Sha512, Digest}; /// # /// # #[cfg(all(feature = "std", feature = "sha2"))] /// # fn main() { /// # let mut csprng: ThreadRng = thread_rng(); /// # let keypair: Keypair = Keypair::generate::(&mut csprng); /// # let message: &[u8] = b"All I want is to pet all of the dogs."; - /// # let prehashed: Sha512 = Sha512::default(); + /// # let mut prehashed: Sha512 = Sha512::default(); /// # prehashed.input(message); /// # /// let context: &[u8] = b"Ed25519DalekSignPrehashedDoctest"; @@ -1294,9 +1293,10 @@ impl Keypair { /// /// use ed25519_dalek::Keypair; /// use ed25519_dalek::Signature; + /// use ed25519_dalek::SignatureError; /// use rand::thread_rng; - /// use rand::ThreadRng; - /// use sha2::Sha512; + /// use rand::rngs::ThreadRng; + /// use sha2::{Sha512, Digest}; /// /// # #[cfg(all(feature = "std", feature = "sha2"))] /// # fn main() { @@ -1304,7 +1304,7 @@ impl Keypair { /// let keypair: Keypair = Keypair::generate::(&mut csprng); /// let message: &[u8] = b"All I want is to pet all of the dogs."; /// - /// let prehashed: Sha512 = Sha512::default(); + /// let mut prehashed: Sha512 = Sha512::new(); /// prehashed.input(message); /// /// let context: &[u8] = b"Ed25519DalekSignPrehashedDoctest"; @@ -1312,12 +1312,12 @@ impl Keypair { /// let sig: Signature = keypair.sign_prehashed(prehashed, Some(context)); /// /// // The sha2::Sha512 struct doesn't implement Copy, so we'll have to create a new one: - /// let prehashed_again: Sha512 = Sha512::default(); + /// let mut prehashed_again: Sha512 = Sha512::default(); /// prehashed_again.input(message); /// - /// let valid: bool = keypair.public.verify_prehashed(prehashed_again, context, sig); + /// let res: Result<(), SignatureError> = keypair.public.verify_prehashed(prehashed_again, Some(context), &sig); /// - /// assert!(valid); + /// assert!(res.is_ok()); /// # } /// # /// # #[cfg(any(not(feature = "sha2"), not(feature = "std")))] @@ -1380,9 +1380,9 @@ mod test { use std::string::String; use std::vec::Vec; use rand::thread_rng; - use rand::ChaChaRng; - use rand::SeedableRng; - use rand::ThreadRng; + use rand::rngs::ThreadRng; + use rand_chacha::ChaChaRng; + use rand_core::SeedableRng; use hex::FromHex; use sha2::Sha512; use super::*; diff --git a/src/lib.rs b/src/lib.rs index 488ea5c..f113a47 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -259,8 +259,12 @@ extern crate curve25519_dalek; extern crate failure; -extern crate rand; +extern crate rand_core; extern crate clear_on_drop; +#[cfg(any(feature = "std", test))] +extern crate rand; +#[cfg(test)] +extern crate rand_chacha; #[cfg(any(feature = "std", test))] #[macro_use] From 1dfe00b79d5f4b8ec29cd4b581cd72913c28fd8f Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Sun, 27 Jan 2019 03:06:18 +0100 Subject: [PATCH 02/10] Fix rand dependency, deal with unusedness warnings --- Cargo.toml | 1 + src/ed25519.rs | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index fbf67f8..8298c07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ default-features = false [dependencies.rand] version = "0.6" features = ["i128_support"] +default-features = false [dependencies.serde] version = "^1.0" diff --git a/src/ed25519.rs b/src/ed25519.rs index 2d144ce..7262bee 100644 --- a/src/ed25519.rs +++ b/src/ed25519.rs @@ -9,6 +9,7 @@ //! ed25519 keypairs and batch verification. +#[allow(unused_imports)] use core::default::Default; use rand::CryptoRng; @@ -28,8 +29,11 @@ pub use sha2::Sha512; use curve25519_dalek::digest::generic_array::typenum::U64; pub use curve25519_dalek::digest::Digest; +#[cfg(any(feature = "alloc", feature = "std"))] use curve25519_dalek::constants; +#[cfg(any(feature = "alloc", feature = "std"))] use curve25519_dalek::edwards::EdwardsPoint; +#[cfg(any(feature = "alloc", feature = "std"))] use curve25519_dalek::scalar::Scalar; pub use crate::constants::*; @@ -96,7 +100,7 @@ pub fn verify_batch( assert!(signatures.len() == messages.len(), ASSERT_MESSAGE); assert!(signatures.len() == public_keys.len(), ASSERT_MESSAGE); assert!(public_keys.len() == messages.len(), ASSERT_MESSAGE); - + #[cfg(feature = "alloc")] use alloc::vec::Vec; #[cfg(feature = "std")] From 1edc2965adaf88babf57f28fdc2a4bf2590e2fd5 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Tue, 12 Mar 2019 20:52:34 +0000 Subject: [PATCH 03/10] Fix typo in README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ebe578..9cb233c 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ The numbers after the `/` in the test name refer to the size of the batch: Ed25519 batch signature verification/256 time: [5.0124 ms 5.0290 ms 5.0491 ms] As you can see, there's an optimal batch size for each machine, so you'll likely -want to your the benchmarks on your target CPU to discover the best size. For +want to test the benchmarks on your target CPU to discover the best size. For this machine, around 100 signatures per batch is the optimum: ![](https://github.com/dalek-cryptography/ed25519-dalek/blob/master/res/batch-violin-benchmark.svg) From 43baaaf27940f49f5394d2f27311bf1d887fb6bc Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Tue, 12 Mar 2019 21:12:43 +0000 Subject: [PATCH 04/10] Also test the `alloc` features on Travis. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index f7f92d7..7451b70 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,9 @@ matrix: # the 32-bit backend (this also exercises testing with `no_std`): - rust: nightly env: TEST_COMMAND=build FEATURES='--no-default-features --features=u32_backend' + # Also test the `alloc` feature with `no_std`: + - rust: nightly + env: TEST_COMMAND=build FEATURES='--no-default-features --features="u64_backend alloc"' # Test any nightly gated features on nightly: - rust: nightly env: TEST_COMMAND=test FEATURES='--features=nightly' From d31df0aaa8791e291bcd223e2605fb6e5ba775dd Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Tue, 2 Apr 2019 01:46:23 +0000 Subject: [PATCH 05/10] Remove sha2 dep; limit rand depends; fixes after PR#68 merge. * ADD new "batch" feature for feature-gating ed25519 batch verification; off by default. The "batch" feature is the only thing which depends on all of the `rand` crate, since it requires the functionality of `rand::thread_rng()`. Without batch verification, the rest of ed25519-dalek only depends on `rand_os` and `rand_core`. --- Cargo.toml | 12 +++++--- src/ed25519.rs | 39 +++++++++++++------------- src/lib.rs | 72 +++++++++++++++++++++++++++--------------------- src/secret.rs | 28 ++++++++----------- tests/ed25519.rs | 18 ++++++------ 5 files changed, 89 insertions(+), 80 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7dc63a7..4f46a48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,10 @@ features = ["i128_support"] default-features = false optional = true +[dependencies.rand_os] +version = "0.1" +optional = true + [dependencies.serde] version = "^1.0" optional = true @@ -48,8 +52,7 @@ version = "0.2" hex = "^0.3" bincode = "^0.9" criterion = "0.2" -rand_os = "0.1.0" -rand_chacha = "0.1.0" +rand_os = "0.1" [[bench]] name = "ed25519_benchmarks" @@ -57,9 +60,10 @@ harness = false [features] default = ["std", "u64_backend"] -std = ["curve25519-dalek/std", "rand", "sha2/std"] -alloc = ["curve25519-dalek/alloc"] +std = ["curve25519-dalek/std", "rand_os", "sha2/std"] +alloc = ["curve25519-dalek/alloc", "rand_os"] nightly = ["curve25519-dalek/nightly", "clear_on_drop/nightly"] +batch = ["rand"] asm = ["sha2/asm"] yolocrypto = ["curve25519-dalek/yolocrypto"] u64_backend = ["curve25519-dalek/u64_backend"] diff --git a/src/ed25519.rs b/src/ed25519.rs index f483bd1..1b6334a 100644 --- a/src/ed25519.rs +++ b/src/ed25519.rs @@ -28,11 +28,11 @@ pub use sha2::Sha512; use curve25519_dalek::digest::generic_array::typenum::U64; pub use curve25519_dalek::digest::Digest; -#[cfg(any(feature = "alloc", feature = "std"))] +#[cfg(all(feature = "batch", any(feature = "alloc", feature = "std")))] use curve25519_dalek::constants; -#[cfg(any(feature = "alloc", feature = "std"))] +#[cfg(all(feature = "batch", any(feature = "alloc", feature = "std")))] use curve25519_dalek::edwards::EdwardsPoint; -#[cfg(any(feature = "alloc", feature = "std"))] +#[cfg(all(feature = "batch", any(feature = "alloc", feature = "std")))] use curve25519_dalek::scalar::Scalar; pub use crate::constants::*; @@ -48,7 +48,7 @@ pub use crate::signature::*; /// * `messages` is a slice of byte slices, one per signed message. /// * `signatures` is a slice of `Signature`s. /// * `public_keys` is a slice of `PublicKey`s. -/// * `csprng` is an implementation of `Rng + CryptoRng`, such as `rand::rngs::ThreadRng`. +/// * `csprng` is an implementation of `Rng + CryptoRng`. /// /// # Panics /// @@ -65,17 +65,16 @@ pub use crate::signature::*; /// /// ``` /// extern crate ed25519_dalek; -/// extern crate rand; +/// extern crate rand_os; /// /// use ed25519_dalek::verify_batch; /// use ed25519_dalek::Keypair; /// use ed25519_dalek::PublicKey; /// use ed25519_dalek::Signature; -/// use rand::thread_rng; -/// use rand::rngs::ThreadRng; +/// use rand_os::OsRng; /// /// # fn main() { -/// let mut csprng: ThreadRng = thread_rng(); +/// let mut csprng: OsRng = OsRng::new().unwrap(); /// let keypairs: Vec = (0..64).map(|_| Keypair::generate(&mut csprng)).collect(); /// let msg: &[u8] = b"They're good dogs Brant"; /// let messages: Vec<&[u8]> = (0..64).map(|_| msg).collect(); @@ -86,7 +85,7 @@ pub use crate::signature::*; /// assert!(result.is_ok()); /// # } /// ``` -#[cfg(any(feature = "alloc", feature = "std"))] +#[cfg(all(feature = "batch", any(feature = "alloc", feature = "std")))] #[allow(non_snake_case)] pub fn verify_batch( messages: &[&[u8]], @@ -217,12 +216,14 @@ impl Keypair { /// # Example /// /// ``` + /// extern crate rand_core; /// extern crate rand_os; /// extern crate ed25519_dalek; /// /// # #[cfg(feature = "std")] /// # fn main() { /// + /// use rand_core::{CryptoRng, RngCore}; /// use rand_os::OsRng; /// use ed25519_dalek::Keypair; /// use ed25519_dalek::Signature; @@ -238,7 +239,7 @@ impl Keypair { /// /// # Input /// - /// A CSPRNG with a `fill_bytes()` method, e.g. `rand_chacha::ChaChaRng`. + /// A CSPRNG with a `fill_bytes()` method, e.g. `rand_os::OsRng`. /// /// The caller must also supply a hash function which implements the /// `Digest` and `Default` traits, and which returns 512 bits of output. @@ -282,17 +283,17 @@ impl Keypair { /// /// ``` /// extern crate ed25519_dalek; - /// extern crate rand; + /// extern crate rand_os; /// /// use ed25519_dalek::Digest; /// use ed25519_dalek::Keypair; /// use ed25519_dalek::Sha512; /// use ed25519_dalek::Signature; - /// use rand::thread_rng; + /// use rand_os::OsRng; /// /// # #[cfg(feature = "std")] /// # fn main() { - /// let mut csprng = thread_rng(); + /// let mut csprng = OsRng::new().unwrap(); /// let keypair: Keypair = Keypair::generate(&mut csprng); /// let message: &[u8] = b"All I want is to pet all of the dogs."; /// @@ -329,17 +330,17 @@ impl Keypair { /// /// ``` /// # extern crate ed25519_dalek; - /// # extern crate rand; + /// # extern crate rand_os; /// # /// # use ed25519_dalek::Digest; /// # use ed25519_dalek::Keypair; /// # use ed25519_dalek::Signature; /// # use ed25519_dalek::Sha512; - /// # use rand::thread_rng; + /// # use rand_os::OsRng; /// # /// # #[cfg(feature = "std")] /// # fn main() { - /// # let mut csprng = thread_rng(); + /// # let mut csprng: OsRng = OsRng::new().unwrap(); /// # let keypair: Keypair = Keypair::generate(&mut csprng); /// # let message: &[u8] = b"All I want is to pet all of the dogs."; /// # let mut prehashed: Sha512 = Sha512::new(); @@ -400,17 +401,17 @@ impl Keypair { /// /// ``` /// extern crate ed25519_dalek; - /// extern crate rand; + /// extern crate rand_os; /// /// use ed25519_dalek::Digest; /// use ed25519_dalek::Keypair; /// use ed25519_dalek::Signature; /// use ed25519_dalek::Sha512; - /// use rand::thread_rng; + /// use rand_os::OsRng; /// /// # #[cfg(feature = "std")] /// # fn main() { - /// let mut csprng = thread_rng(); + /// let mut csprng: OsRng = OsRng::new().unwrap(); /// let keypair: Keypair = Keypair::generate(&mut csprng); /// let message: &[u8] = b"All I want is to pet all of the dogs."; /// diff --git a/src/lib.rs b/src/lib.rs index 9b72ac8..1007b6c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,12 +19,13 @@ //! the operating system's builtin PRNG: //! //! ``` +//! extern crate rand_core; //! extern crate rand_os; //! extern crate ed25519_dalek; //! //! # #[cfg(feature = "std")] //! # fn main() { -//! use rand::Rng; +//! use rand_core::RngCore; //! use rand_os::OsRng; //! use ed25519_dalek::Keypair; //! use ed25519_dalek::Signature; @@ -40,14 +41,15 @@ //! We can now use this `keypair` to sign a message: //! //! ``` -//! # extern crate rand; +//! # extern crate rand_core; +//! # extern crate rand_os; //! # extern crate ed25519_dalek; //! # fn main() { -//! # use rand::Rng; -//! # use rand::thread_rng; +//! # use rand_core::RngCore; +//! # use rand_os::OsRng; //! # use ed25519_dalek::Keypair; //! # use ed25519_dalek::Signature; -//! # let mut csprng = thread_rng(); +//! # let mut csprng = OsRng::new().unwrap(); //! # let keypair: Keypair = Keypair::generate(&mut csprng); //! let message: &[u8] = b"This is a test of the tsunami alert system."; //! let signature: Signature = keypair.sign(message); @@ -58,14 +60,15 @@ //! that `message`: //! //! ``` -//! # extern crate rand; +//! # extern crate rand_core; +//! # extern crate rand_os; //! # extern crate ed25519_dalek; //! # fn main() { -//! # use rand::Rng; -//! # use rand::thread_rng; +//! # use rand_core::RngCore; +//! # use rand_os::OsRng; //! # use ed25519_dalek::Keypair; //! # use ed25519_dalek::Signature; -//! # let mut csprng = thread_rng(); +//! # let mut csprng = OsRng::new().unwrap(); //! # let keypair: Keypair = Keypair::generate(&mut csprng); //! # let message: &[u8] = b"This is a test of the tsunami alert system."; //! # let signature: Signature = keypair.sign(message); @@ -77,15 +80,16 @@ //! verify this signature: //! //! ``` -//! # extern crate rand; +//! # extern crate rand_core; +//! # extern crate rand_os; //! # extern crate ed25519_dalek; //! # fn main() { -//! # use rand::Rng; -//! # use rand::thread_rng; +//! # use rand_core::RngCore; +//! # use rand_os::OsRng; //! # use ed25519_dalek::Keypair; //! # use ed25519_dalek::Signature; //! use ed25519_dalek::PublicKey; -//! # let mut csprng = thread_rng(); +//! # let mut csprng = OsRng::new().unwrap(); //! # let keypair: Keypair = Keypair::generate(&mut csprng); //! # let message: &[u8] = b"This is a test of the tsunami alert system."; //! # let signature: Signature = keypair.sign(message); @@ -104,14 +108,15 @@ //! verify your signatures!) //! //! ``` -//! # extern crate rand; +//! # extern crate rand_core; +//! # extern crate rand_os; //! # extern crate ed25519_dalek; //! # fn main() { -//! # use rand::Rng; -//! # use rand::thread_rng; +//! # use rand_core::RngCore; +//! # use rand_os::OsRng; //! # use ed25519_dalek::{Keypair, Signature, PublicKey}; //! use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH}; -//! # let mut csprng = thread_rng(); +//! # let mut csprng = OsRng::new().unwrap(); //! # let keypair: Keypair = Keypair::generate(&mut csprng); //! # let message: &[u8] = b"This is a test of the tsunami alert system."; //! # let signature: Signature = keypair.sign(message); @@ -127,14 +132,15 @@ //! And similarly, decoded from bytes with `::from_bytes()`: //! //! ``` -//! # extern crate rand; +//! # extern crate rand_core; +//! # extern crate rand_os; //! # extern crate ed25519_dalek; -//! # use rand::Rng; -//! # use rand::thread_rng; +//! # use rand_core::RngCore; +//! # use rand_os::OsRng; //! # use ed25519_dalek::{Keypair, Signature, PublicKey, SecretKey, SignatureError}; //! # use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH}; //! # fn do_test() -> Result<(SecretKey, PublicKey, Keypair, Signature), SignatureError> { -//! # let mut csprng = thread_rng(); +//! # let mut csprng = OsRng::new().unwrap(); //! # let keypair_orig: Keypair = Keypair::generate(&mut csprng); //! # let message: &[u8] = b"This is a test of the tsunami alert system."; //! # let signature_orig: Signature = keypair_orig.sign(message); @@ -169,7 +175,8 @@ //! For example, using [bincode](https://github.com/TyOverby/bincode): //! //! ``` -//! # extern crate rand; +//! # extern crate rand_core; +//! # extern crate rand_os; //! # extern crate ed25519_dalek; //! # #[cfg(feature = "serde")] //! extern crate serde; @@ -178,11 +185,11 @@ //! //! # #[cfg(feature = "serde")] //! # fn main() { -//! # use rand::Rng; -//! # use rand::thread_rng; +//! # use rand_core::RngCore; +//! # use rand_os::OsRng; //! # use ed25519_dalek::{Keypair, Signature, PublicKey}; //! use bincode::{serialize, Infinite}; -//! # let mut csprng = thread_rng(); +//! # let mut csprng = OsRng::new().unwrap(); //! # let keypair: Keypair = Keypair::generate(&mut csprng); //! # let message: &[u8] = b"This is a test of the tsunami alert system."; //! # let signature: Signature = keypair.sign(message); @@ -200,7 +207,8 @@ //! recipient may deserialise them and verify: //! //! ``` -//! # extern crate rand; +//! # extern crate rand_core; +//! # extern crate rand_os; //! # extern crate ed25519_dalek; //! # #[cfg(feature = "serde")] //! # extern crate serde; @@ -209,13 +217,13 @@ //! # //! # #[cfg(feature = "serde")] //! # fn main() { -//! # use rand::Rng; -//! # use rand::thread_rng; +//! # use rand_core::RngCore; +//! # use rand_os::OsRng; //! # use ed25519_dalek::{Keypair, Signature, PublicKey}; //! # use bincode::{serialize, Infinite}; //! use bincode::{deserialize}; //! -//! # let mut csprng = thread_rng(); +//! # let mut csprng = OsRng::new().unwrap(); //! # let keypair: Keypair = Keypair::generate(&mut csprng); //! let message: &[u8] = b"This is a test of the tsunami alert system."; //! # let signature: Signature = keypair.sign(message); @@ -250,10 +258,10 @@ extern crate std; extern crate clear_on_drop; extern crate curve25519_dalek; extern crate failure; -#[cfg(any(feature = "std", test))] +#[cfg(all(feature = "batch", any(feature = "std", feature = "alloc", test)))] extern crate rand; -#[cfg(test)] -extern crate rand_chacha; +#[cfg(any(feature = "std", test))] +extern crate rand_os; extern crate rand_core; #[cfg(feature = "serde")] extern crate serde; diff --git a/src/secret.rs b/src/secret.rs index 3e1a5d8..b3c0e0a 100644 --- a/src/secret.rs +++ b/src/secret.rs @@ -126,14 +126,12 @@ impl SecretKey { /// /// ``` /// extern crate rand_os; - /// extern crate sha2; /// extern crate ed25519_dalek; /// /// # #[cfg(feature = "std")] /// # fn main() { /// # /// use rand_os::OsRng; - /// use sha2::Sha512; /// use ed25519_dalek::PublicKey; /// use ed25519_dalek::SecretKey; /// use ed25519_dalek::Signature; @@ -149,18 +147,17 @@ impl SecretKey { /// Afterwards, you can generate the corresponding public: /// /// ``` - /// # extern crate rand; + /// # extern crate rand_os; /// # extern crate ed25519_dalek; /// # /// # fn main() { /// # - /// # use rand::Rng; - /// # use rand::thread_rng; + /// # use rand_os::OsRng; /// # use ed25519_dalek::PublicKey; /// # use ed25519_dalek::SecretKey; /// # use ed25519_dalek::Signature; /// # - /// # let mut csprng = thread_rng(); + /// # let mut csprng = OsRng::new().unwrap(); /// # let secret_key: SecretKey = SecretKey::generate(&mut csprng); /// /// let public_key: PublicKey = (&secret_key).into(); @@ -172,7 +169,7 @@ impl SecretKey { /// A CSPRNG with a `fill_bytes()` method, e.g. `rand::OsRng` pub fn generate(csprng: &mut T) -> SecretKey where - T: CryptoRng + Rng, + T: CryptoRng + RngCore, { let mut sk: SecretKey = SecretKey([0u8; 32]); @@ -273,18 +270,18 @@ impl<'a> From<&'a SecretKey> for ExpandedSecretKey { /// # Examples /// /// ``` - /// # extern crate rand; + /// # extern crate rand_core; + /// # extern crate rand_os; /// # extern crate sha2; /// # extern crate ed25519_dalek; /// # /// # fn main() { /// # - /// use rand::Rng; - /// use rand::thread_rng; - /// use sha2::Sha512; + /// use rand_core::RngCore; + /// use rand_os::OsRng; /// use ed25519_dalek::{SecretKey, ExpandedSecretKey}; /// - /// let mut csprng = thread_rng(); + /// let mut csprng = OsRng::new().unwrap(); /// let secret_key: SecretKey = SecretKey::generate(&mut csprng); /// let expanded_secret_key: ExpandedSecretKey = ExpandedSecretKey::from(&secret_key); /// # } @@ -329,7 +326,6 @@ impl ExpandedSecretKey { /// # fn main() { /// # /// use rand_os::OsRng; - /// use sha2::Sha512; /// use ed25519_dalek::{SecretKey, ExpandedSecretKey}; /// /// let mut csprng: OsRng = OsRng::new().unwrap(); @@ -340,7 +336,7 @@ impl ExpandedSecretKey { /// assert!(&expanded_secret_key_bytes[..] != &[0u8; 64][..]); /// # } /// # - /// # #[cfg(any(not(feature = "sha2"), not(feature = "std")))] + /// # #[cfg(not(feature = "std"))] /// # fn main() { } /// ``` #[inline] @@ -384,13 +380,13 @@ impl ExpandedSecretKey { /// # Ok(expanded_secret_key_again) /// # } /// # - /// # #[cfg(all(feature = "sha2", feature = "std"))] + /// # #[cfg(feature = "std")] /// # fn main() { /// # let result = do_test(); /// # assert!(result.is_ok()); /// # } /// # - /// # #[cfg(any(not(feature = "sha2"), not(feature = "std")))] + /// # #[cfg(not(feature = "std"))] /// # fn main() { } /// ``` #[inline] diff --git a/tests/ed25519.rs b/tests/ed25519.rs index d849e41..555b952 100644 --- a/tests/ed25519.rs +++ b/tests/ed25519.rs @@ -13,15 +13,14 @@ extern crate bincode; extern crate ed25519_dalek; extern crate hex; -extern crate rand; +extern crate rand_os; extern crate sha2; use ed25519_dalek::*; use hex::FromHex; -use rand::thread_rng; -use rand::rngs::ThreadRng; +use rand_os::OsRng; use sha2::Sha512; @@ -117,7 +116,6 @@ mod integrations { #[test] fn sign_verify() { // TestSignVerify - let mut csprng: ThreadRng; let keypair: Keypair; let good_sig: Signature; let bad_sig: Signature; @@ -125,7 +123,8 @@ mod integrations { let good: &[u8] = "test message".as_bytes(); let bad: &[u8] = "wrong message".as_bytes(); - csprng = thread_rng(); + let mut csprng: OsRng = OsRng::new().unwrap(); + keypair = Keypair::generate(&mut csprng); good_sig = keypair.sign(&good); bad_sig = keypair.sign(&bad); @@ -140,7 +139,6 @@ mod integrations { #[test] fn ed25519ph_sign_verify() { - let mut csprng: ThreadRng; let keypair: Keypair; let good_sig: Signature; let bad_sig: Signature; @@ -148,6 +146,8 @@ mod integrations { let good: &[u8] = b"test message"; let bad: &[u8] = b"wrong message"; + let mut csprng: OsRng = OsRng::new().unwrap(); + // ugh… there's no `impl Copy for Sha512`… i hope we can all agree these are the same hashes let mut prehashed_good1: Sha512 = Sha512::default(); prehashed_good1.input(good); @@ -163,7 +163,6 @@ mod integrations { let context: &[u8] = b"testing testing 1 2 3"; - csprng = thread_rng(); keypair = Keypair::generate(&mut csprng); good_sig = keypair.sign_prehashed(prehashed_good1, Some(context)); bad_sig = keypair.sign_prehashed(prehashed_bad1, Some(context)); @@ -176,6 +175,7 @@ mod integrations { "Verification of a signature on a different message passed!"); } + #[cfg(feature = "batch")] #[test] fn verify_batch_seven_signatures() { let messages: [&[u8]; 7] = [ @@ -186,7 +186,7 @@ mod integrations { b"Fuck dumbin' it down, spit ice, skip jewellery: Molotov cocktails on me like accessories.", b"Hey, I never cared about your bucks, so if I run up with a mask on, probably got a gas can too.", b"And I'm not here to fill 'er up. Nope, we came to riot, here to incite, we don't want any of your stuff.", ]; - let mut csprng: ThreadRng = thread_rng(); + let mut csprng: OsRng = OsRng::new().unwrap(); let mut keypairs: Vec = Vec::new(); let mut signatures: Vec = Vec::new(); @@ -204,7 +204,7 @@ mod integrations { #[test] fn pubkey_from_secret_and_expanded_secret() { - let mut csprng = thread_rng(); + let mut csprng = OsRng::new().unwrap(); let secret: SecretKey = SecretKey::generate(&mut csprng); let expanded_secret: ExpandedSecretKey = (&secret).into(); let public_from_secret: PublicKey = (&secret).into(); // XXX eww From dc4b77b55196f0921ea0106084acd7615ca24792 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Thu, 3 Oct 2019 23:14:49 +0000 Subject: [PATCH 06/10] Fix bad import and feature specification in benchmarks. --- Cargo.toml | 4 ++++ benches/ed25519_benchmarks.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4f46a48..a814efe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,11 +52,15 @@ version = "0.2" hex = "^0.3" bincode = "^0.9" criterion = "0.2" +rand = "0.6" rand_os = "0.1" [[bench]] name = "ed25519_benchmarks" harness = false +# This doesn't seem to work with criterion, cf. https://github.com/bheisler/criterion.rs/issues/344 +# For now, we have to bench by doing `cargo bench --features="batch"`. +# required-features = ["batch"] [features] default = ["std", "u64_backend"] diff --git a/benches/ed25519_benchmarks.rs b/benches/ed25519_benchmarks.rs index 52cb597..e07eb61 100644 --- a/benches/ed25519_benchmarks.rs +++ b/benches/ed25519_benchmarks.rs @@ -22,7 +22,7 @@ mod ed25519_benches { use ed25519_dalek::Signature; use ed25519_dalek::verify_batch; use rand::thread_rng; - use rand::rngs::ThreadRng; + use rand::prelude::ThreadRng; fn sign(c: &mut Criterion) { let mut csprng: ThreadRng = thread_rng(); From aa49b4cd8d61ef8d7fb5527f3c4642cd32393715 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Fri, 4 Oct 2019 01:19:23 +0000 Subject: [PATCH 07/10] Fix two failing doctests. --- src/secret.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/secret.rs b/src/secret.rs index b3c0e0a..5393e4d 100644 --- a/src/secret.rs +++ b/src/secret.rs @@ -322,7 +322,7 @@ impl ExpandedSecretKey { /// # extern crate sha2; /// # extern crate ed25519_dalek; /// # - /// # #[cfg(all(feature = "sha2", feature = "std"))] + /// # #[cfg(feature = "std")] /// # fn main() { /// # /// use rand_os::OsRng; @@ -364,7 +364,7 @@ impl ExpandedSecretKey { /// # /// # use ed25519_dalek::{ExpandedSecretKey, SignatureError}; /// # - /// # #[cfg(all(feature = "sha2", feature = "std"))] + /// # #[cfg(feature = "std")] /// # fn do_test() -> Result { /// # /// use rand_os::OsRng; From 52ee8010221089376698713b6d7b1a1721b80e80 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Fri, 4 Oct 2019 01:23:59 +0000 Subject: [PATCH 08/10] Fix Travis CI builds after change in features syntax parsing. cf. https://travis-ci.org/isislovecruft/ed25519-dalek/jobs/593331585#L194 --- .travis.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7451b70..72f94de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,26 +6,26 @@ rust: - nightly env: - - TEST_COMMAND=test FEATURES='' + - TEST_COMMAND=test EXTRA_FLAGS='' FEATURES='' matrix: include: # We use the 64-bit optimised curve backend by default, so also test with # the 32-bit backend (this also exercises testing with `no_std`): - rust: nightly - env: TEST_COMMAND=build FEATURES='--no-default-features --features=u32_backend' - # Also test the `alloc` feature with `no_std`: + env: TEST_COMMAND=build EXTRA_FLAGS='--no-default-features' FEATURES='u32_backend alloc' + # Also test the batch feature: - rust: nightly - env: TEST_COMMAND=build FEATURES='--no-default-features --features="u64_backend alloc"' + env: TEST_COMMAND=build EXTRA_FLAGS='--no-default-features' FEATURES='u64_backend alloc batch' # Test any nightly gated features on nightly: - rust: nightly - env: TEST_COMMAND=test FEATURES='--features=nightly' + env: TEST_COMMAND=test EXTRA_FLAGS='' FEATURES='nightly' # Test serde support on stable, assuming that if it works there it'll work everywhere: - rust: stable - env: TEST_COMMAND=test FEATURE='--features=serde' + env: TEST_COMMAND=test EXTRA_FLAGS='' FEATURES='serde' script: - - cargo $TEST_COMMAND $FEATURES + - cargo $TEST_COMMAND --features="$FEATURES" $EXTRA_FLAGS notifications: slack: From 1342e2a3a4ea916b798a91582d657f3c8b9ca90f Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Fri, 4 Oct 2019 02:05:20 +0000 Subject: [PATCH 09/10] Fix no_std+alloc builds. --- src/ed25519.rs | 2 +- src/lib.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ed25519.rs b/src/ed25519.rs index 1b6334a..a76b091 100644 --- a/src/ed25519.rs +++ b/src/ed25519.rs @@ -93,7 +93,7 @@ pub fn verify_batch( public_keys: &[PublicKey], ) -> Result<(), SignatureError> { - const ASSERT_MESSAGE: &'static [u8] = b"The number of messages, signatures, and public keys must be equal."; + const ASSERT_MESSAGE: &'static str = "The number of messages, signatures, and public keys must be equal."; assert!(signatures.len() == messages.len(), ASSERT_MESSAGE); assert!(signatures.len() == public_keys.len(), ASSERT_MESSAGE); assert!(public_keys.len() == messages.len(), ASSERT_MESSAGE); diff --git a/src/lib.rs b/src/lib.rs index 1007b6c..fcd52af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -255,6 +255,8 @@ #[macro_use] extern crate std; +#[cfg(all(feature = "alloc", not(feature = "std")))] +extern crate alloc; extern crate clear_on_drop; extern crate curve25519_dalek; extern crate failure; From 46811866cc3342fa145d121ae14de34f0a716570 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Fri, 4 Oct 2019 02:16:06 +0000 Subject: [PATCH 10/10] Bump ed25519-dalek version to 1.0.0-pre.2. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a814efe..453d72e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ed25519-dalek" -version = "1.0.0-pre.1" +version = "1.0.0-pre.2" authors = ["isis lovecruft "] readme = "README.md" license = "BSD-3-Clause"