From d81d43e3ae957e4c707560d7aaf9f7326a96eaaa Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Sat, 29 Dec 2018 22:56:16 +0000 Subject: [PATCH] Hardcode use of sha2::Sha512 in most cases. This implements https://github.com/dalek-cryptography/ed25519-dalek/issues/64 You can still choose the "prehash" algorithm, as long as it has 64 bytes of output. Otherwise, everything is hardcoded to use sha2::Sha512. To use a different implementation you'll need a [patch.crates-io] section in cargo config. --- Cargo.toml | 5 +- src/ed25519.rs | 332 ++++++++++++++++++++++--------------------------- src/lib.rs | 80 +++++------- 3 files changed, 179 insertions(+), 238 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5b04835..5d5cc94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ optional = true [dependencies.sha2] version = "^0.8" -optional = true +default-features = false [dependencies.failure] version = "^0.1.1" @@ -40,7 +40,6 @@ version = "0.2" [dev-dependencies] hex = "^0.3" -sha2 = "^0.8" bincode = "^0.9" criterion = "0.2" @@ -51,7 +50,7 @@ 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", "rand/std"] +std = ["curve25519-dalek/std", "rand/std", "sha2/std"] alloc = ["curve25519-dalek/alloc"] nightly = ["curve25519-dalek/nightly", "rand/nightly", "clear_on_drop/nightly"] asm = ["sha2/asm"] diff --git a/src/ed25519.rs b/src/ed25519.rs index 4d2fabd..fe207df 100644 --- a/src/ed25519.rs +++ b/src/ed25519.rs @@ -7,8 +7,7 @@ // Authors: // - Isis Agora Lovecruft -//! A Rust implementation of ed25519 EdDSA key generation, signing, and -//! verification. +//! A Rust implementation of ed25519 key generation, signing, and verification. use core::default::Default; use core::fmt::{Debug}; @@ -25,12 +24,11 @@ use serde::de::Error as SerdeError; #[cfg(feature = "serde")] use serde::de::Visitor; -#[cfg(feature = "sha2")] -use sha2::Sha512; +pub use sha2::Sha512; use clear_on_drop::clear::Clear; -use curve25519_dalek::digest::Digest; +pub use curve25519_dalek::digest::Digest; use curve25519_dalek::digest::generic_array::typenum::U64; use curve25519_dalek::constants; @@ -188,13 +186,6 @@ impl AsRef<[u8]> for SecretKey { } impl SecretKey { - /// Expand this `SecretKey` into an `ExpandedSecretKey`. - pub fn expand(&self) -> ExpandedSecretKey - where D: Digest + Default - { - ExpandedSecretKey::from_secret_key::(&self) - } - /// Convert this secret key to a byte array. #[inline] pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] { @@ -279,20 +270,16 @@ impl SecretKey { /// # fn main() { } /// ``` /// - /// Afterwards, you can generate the corresponding public—provided you also - /// supply a hash function which implements the `Digest` and `Default` - /// traits, and which returns 512 bits of output—via: + /// Afterwards, you can generate the corresponding public: /// /// ``` /// # extern crate rand; - /// # extern crate sha2; /// # extern crate ed25519_dalek; /// # /// # fn main() { /// # /// # use rand::Rng; /// # use rand::thread_rng; - /// # use sha2::Sha512; /// # use ed25519_dalek::PublicKey; /// # use ed25519_dalek::SecretKey; /// # use ed25519_dalek::Signature; @@ -300,17 +287,13 @@ impl SecretKey { /// # let mut csprng = thread_rng(); /// # let secret_key: SecretKey = SecretKey::generate(&mut csprng); /// - /// let public_key: PublicKey = PublicKey::from_secret::(&secret_key); + /// let public_key: PublicKey = (&secret_key).into(); /// # } /// ``` /// - /// The standard hash function used for most ed25519 libraries is SHA-512, - /// which is available with `use sha2::Sha512` as in the example above. - /// Other suitable hash functions include Keccak-512 and Blake2b-512. - /// /// # Input /// - /// A CSPRNG with a `fill_bytes()` method, e.g. `rand_chacha::ChaChaRng` + /// A CSPRNG with a `fill_bytes()` method, e.g. `rand::OsRng` pub fn generate(csprng: &mut T) -> SecretKey where T: CryptoRng + Rng, { @@ -398,7 +381,6 @@ impl Drop for ExpandedSecretKey { } } -#[cfg(feature = "sha2")] impl<'a> From<&'a SecretKey> for ExpandedSecretKey { /// Construct an `ExpandedSecretKey` from a `SecretKey`. /// @@ -409,24 +391,35 @@ impl<'a> From<&'a SecretKey> for ExpandedSecretKey { /// # extern crate sha2; /// # extern crate ed25519_dalek; /// # - /// # #[cfg(all(feature = "std", feature = "sha2"))] /// # fn main() { /// # /// use rand::Rng; - /// use rand::rngs::OsRng; + /// use rand::thread_rng; /// use sha2::Sha512; /// use ed25519_dalek::{SecretKey, ExpandedSecretKey}; /// - /// let mut csprng: OsRng = OsRng::new().unwrap(); + /// let mut csprng = thread_rng(); /// let secret_key: SecretKey = SecretKey::generate(&mut csprng); /// let expanded_secret_key: ExpandedSecretKey = ExpandedSecretKey::from(&secret_key); /// # } - /// # - /// # #[cfg(any(not(feature = "std"), not(feature = "sha2")))] - /// # fn main() {} /// ``` fn from(secret_key: &'a SecretKey) -> ExpandedSecretKey { - ExpandedSecretKey::from_secret_key::(&secret_key) + let mut h: Sha512 = Sha512::default(); + let mut hash: [u8; 64] = [0u8; 64]; + let mut lower: [u8; 32] = [0u8; 32]; + let mut upper: [u8; 32] = [0u8; 32]; + + h.input(secret_key.as_bytes()); + hash.copy_from_slice(h.result().as_slice()); + + lower.copy_from_slice(&hash[00..32]); + upper.copy_from_slice(&hash[32..64]); + + lower[0] &= 248; + lower[31] &= 63; + lower[31] |= 64; + + ExpandedSecretKey{ key: Scalar::from_bits(lower), nonce: upper, } } } @@ -532,56 +525,10 @@ impl ExpandedSecretKey { nonce: upper }) } - /// Construct an `ExpandedSecretKey` from a `SecretKey`, using hash function `D`. - /// - /// # Examples - /// - /// ``` - /// # extern crate rand; - /// # extern crate sha2; - /// # extern crate ed25519_dalek; - /// # - /// # #[cfg(all(feature = "std", feature = "sha2"))] - /// # fn main() { - /// # - /// use rand::Rng; - /// use rand::rngs::OsRng; - /// use sha2::Sha512; - /// use ed25519_dalek::{SecretKey, ExpandedSecretKey}; - /// - /// let mut csprng: OsRng = OsRng::new().unwrap(); - /// let secret_key: SecretKey = SecretKey::generate(&mut csprng); - /// let expanded_secret_key: ExpandedSecretKey = ExpandedSecretKey::from_secret_key::(&secret_key); - /// # } - /// # - /// # #[cfg(any(not(feature = "sha2"), not(feature = "std")))] - /// # fn main() { } - /// ``` - pub fn from_secret_key(secret_key: &SecretKey) -> ExpandedSecretKey - where D: Digest + Default { - let mut h: D = D::default(); - let mut hash: [u8; 64] = [0u8; 64]; - let mut lower: [u8; 32] = [0u8; 32]; - let mut upper: [u8; 32] = [0u8; 32]; - - h.input(secret_key.as_bytes()); - hash.copy_from_slice(h.result().as_slice()); - - lower.copy_from_slice(&hash[00..32]); - upper.copy_from_slice(&hash[32..64]); - - lower[0] &= 248; - lower[31] &= 63; - lower[31] |= 64; - - ExpandedSecretKey{ key: Scalar::from_bits(lower), nonce: upper, } - } - /// Sign a message with this `ExpandedSecretKey`. #[allow(non_snake_case)] - pub fn sign(&self, message: &[u8], public_key: &PublicKey) -> Signature - where D: Digest + Default { - let mut h: D = D::default(); + pub fn sign(&self, message: &[u8], public_key: &PublicKey) -> Signature { + let mut h: Sha512 = Sha512::new(); let R: CompressedEdwardsY; let r: Scalar; let s: Scalar; @@ -593,7 +540,7 @@ impl ExpandedSecretKey { r = Scalar::from_hash(h); R = (&r * &constants::ED25519_BASEPOINT_TABLE).compress(); - h = D::default(); + h = Sha512::new(); h.input(R.as_bytes()); h.input(public_key.as_bytes()); h.input(&message); @@ -623,13 +570,16 @@ impl ExpandedSecretKey { /// /// [rfc8032]: https://tools.ietf.org/html/rfc8032#section-5.1 #[allow(non_snake_case)] - pub fn sign_prehashed(&self, - prehashed_message: D, - public_key: &PublicKey, - context: Option<&'static [u8]>) -> Signature - where D: Digest + Default + pub fn sign_prehashed( + &self, + prehashed_message: D, + public_key: &PublicKey, + context: Option<&'static [u8]>, + ) -> Signature + where + D: Digest, { - let mut h: D; + let mut h: Sha512; let mut prehash: [u8; 64] = [0u8; 64]; let R: CompressedEdwardsY; let r: Scalar; @@ -657,7 +607,7 @@ impl ExpandedSecretKey { // // This is a really fucking stupid bandaid, and the damned scheme is // still bleeding from malleability, for fuck's sake. - h = D::default() + h = Sha512::new() .chain(b"SigEd25519 no Ed25519 collisions") .chain(&[1]) // Ed25519ph .chain(&[ctx_len]) @@ -668,7 +618,7 @@ impl ExpandedSecretKey { r = Scalar::from_hash(h); R = (&r * &constants::ED25519_BASEPOINT_TABLE).compress(); - h = D::default() + h = Sha512::new() .chain(b"SigEd25519 no Ed25519 collisions") .chain(&[1]) // Ed25519ph .chain(&[ctx_len]) @@ -794,13 +744,12 @@ impl PublicKey { Ok(PublicKey(compressed, point)) } +} +impl<'a> From<&'a SecretKey> for PublicKey { /// Derive this public key from its corresponding `SecretKey`. - #[allow(unused_assignments)] - pub fn from_secret(secret_key: &SecretKey) -> PublicKey - where D: Digest + Default - { - let mut h: D = D::default(); + fn from(secret_key: &SecretKey) -> PublicKey { + let mut h: Sha512 = Sha512::new(); let mut hash: [u8; 64] = [0u8; 64]; let mut digest: [u8; 32] = [0u8; 32]; @@ -811,14 +760,18 @@ impl PublicKey { PublicKey::mangle_scalar_bits_and_multiply_by_basepoint_to_produce_public_key(&mut digest) } +} +impl<'a> From<&'a ExpandedSecretKey> for PublicKey { /// Derive this public key from its corresponding `ExpandedSecretKey`. - pub fn from_expanded_secret(expanded_secret_key: &ExpandedSecretKey) -> PublicKey { + fn from(expanded_secret_key: &ExpandedSecretKey) -> PublicKey { let mut bits: [u8; 32] = expanded_secret_key.key.to_bytes(); PublicKey::mangle_scalar_bits_and_multiply_by_basepoint_to_produce_public_key(&mut bits) } +} +impl PublicKey { /// Internal utility function for mangling the bits of a (formerly /// mathematically well-defined) "scalar" and multiplying it to produce a /// public key. @@ -839,10 +792,13 @@ impl PublicKey { /// /// Returns `Ok(())` if the signature is valid, and `Err` otherwise. #[allow(non_snake_case)] - pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), SignatureError> - where D: Digest + Default + pub fn verify( + &self, + message: &[u8], + signature: &Signature + ) -> Result<(), SignatureError> { - let mut h: D = D::default(); + let mut h: Sha512 = Sha512::new(); let R: EdwardsPoint; let k: Scalar; let minus_A: EdwardsPoint = -self.1; @@ -880,13 +836,16 @@ impl PublicKey { /// /// [rfc8032]: https://tools.ietf.org/html/rfc8032#section-5.1 #[allow(non_snake_case)] - pub fn verify_prehashed(&self, - prehashed_message: D, - context: Option<&[u8]>, - signature: &Signature) -> Result<(), SignatureError> - where D: Digest + Default + pub fn verify_prehashed( + &self, + prehashed_message: D, + context: Option<&[u8]>, + signature: &Signature, + ) -> Result<(), SignatureError> + where + D: Digest, { - let mut h: D = D::default(); + let mut h: Sha512 = Sha512::default(); let R: EdwardsPoint; let k: Scalar; @@ -914,12 +873,6 @@ impl PublicKey { } } -impl From for PublicKey { - fn from(source: ExpandedSecretKey) -> PublicKey { - PublicKey::from_expanded_secret(&source) - } -} - /// Verify a batch of `signatures` on `messages` with their respective `public_keys`. /// /// # Inputs @@ -946,7 +899,6 @@ impl From for PublicKey { /// ``` /// extern crate ed25519_dalek; /// extern crate rand; -/// extern crate sha2; /// /// use ed25519_dalek::verify_batch; /// use ed25519_dalek::Keypair; @@ -954,26 +906,26 @@ impl From for PublicKey { /// use ed25519_dalek::Signature; /// use rand::thread_rng; /// use rand::rngs::ThreadRng; -/// use sha2::Sha512; /// /// # fn main() { /// let mut csprng: ThreadRng = thread_rng(); -/// let keypairs: Vec = (0..64).map(|_| Keypair::generate::(&mut csprng)).collect(); +/// 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(); -/// let signatures: Vec = keypairs.iter().map(|key| key.sign::(&msg)).collect(); +/// let signatures: Vec = keypairs.iter().map(|key| key.sign(&msg)).collect(); /// let public_keys: Vec = keypairs.iter().map(|key| key.public).collect(); /// -/// let result = verify_batch::(&messages[..], &signatures[..], &public_keys[..]); +/// let result = verify_batch(&messages[..], &signatures[..], &public_keys[..]); /// assert!(result.is_ok()); /// # } /// ``` #[cfg(any(feature = "alloc", feature = "std"))] #[allow(non_snake_case)] -pub fn verify_batch(messages: &[&[u8]], - signatures: &[Signature], - public_keys: &[PublicKey]) -> Result<(), SignatureError> - where D: Digest + Default +pub fn verify_batch( + messages: &[&[u8]], + signatures: &[Signature], + public_keys: &[PublicKey], +) -> Result<(), SignatureError> { const ASSERT_MESSAGE: &'static [u8] = b"The number of messages, signatures, and public keys must be equal."; assert!(signatures.len() == messages.len(), ASSERT_MESSAGE); @@ -1007,7 +959,7 @@ pub fn verify_batch(messages: &[&[u8]], // Compute H(R || A || M) for each (signature, public_key, message) triplet let hrams = (0..signatures.len()).map(|i| { - let mut h: D = D::default(); + let mut h: Sha512 = Sha512::default(); h.input(signatures[i].R.as_bytes()); h.input(public_keys[i].as_bytes()); h.input(&messages[i]); @@ -1125,24 +1077,22 @@ impl Keypair { /// /// ``` /// extern crate rand; - /// extern crate sha2; /// extern crate ed25519_dalek; /// - /// # #[cfg(all(feature = "std", feature = "sha2"))] + /// # #[cfg(feature = "std")] /// # fn main() { /// /// use rand::Rng; /// use rand::OsRng; - /// use sha2::Sha512; /// use ed25519_dalek::Keypair; /// use ed25519_dalek::Signature; /// /// let mut csprng: OsRng = OsRng::new().unwrap(); - /// let keypair: Keypair = Keypair::generate::(&mut csprng); + /// let keypair: Keypair = Keypair::generate(&mut csprng); /// /// # } /// # - /// # #[cfg(any(not(feature = "sha2"), not(feature = "std")))] + /// # #[cfg(not(feature = "std"))] /// # fn main() { } /// ``` /// @@ -1155,20 +1105,21 @@ impl Keypair { /// The standard hash function used for most ed25519 libraries is SHA-512, /// which is available with `use sha2::Sha512` as in the example above. /// Other suitable hash functions include Keccak-512 and Blake2b-512. - pub fn generate(csprng: &mut R) -> Keypair - where D: Digest + Default, - R: CryptoRng + Rng, + pub fn generate(csprng: &mut R) -> Keypair + where R: CryptoRng + Rng, { let sk: SecretKey = SecretKey::generate(csprng); - let pk: PublicKey = PublicKey::from_secret::(&sk); + let pk: PublicKey = (&sk).into(); Keypair{ public: pk, secret: sk } } /// Sign a message with this keypair's secret key. - pub fn sign(&self, message: &[u8]) -> Signature - where D: Digest + Default { - self.secret.expand::().sign::(&message, &self.public) + pub fn sign(&self, message: &[u8]) -> Signature + { + let expanded: ExpandedSecretKey = (&self.secret).into(); + + expanded.sign(&message, &self.public) } /// Sign a `prehashed_message` with this `Keypair` using the @@ -1192,27 +1143,26 @@ impl Keypair { /// ``` /// extern crate ed25519_dalek; /// extern crate rand; - /// extern crate sha2; /// + /// use ed25519_dalek::Digest; /// use ed25519_dalek::Keypair; + /// use ed25519_dalek::Sha512; /// use ed25519_dalek::Signature; /// use rand::thread_rng; - /// use sha2::Digest; - /// use sha2::Sha512; /// - /// # #[cfg(all(feature = "std", feature = "sha2"))] + /// # #[cfg(feature = "std")] /// # fn main() { /// let mut csprng = thread_rng(); - /// let keypair: Keypair = Keypair::generate::(&mut csprng); + /// let keypair: Keypair = Keypair::generate(&mut csprng); /// 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 mut prehashed: Sha512 = Sha512::default(); + /// let mut prehashed: Sha512 = Sha512::new(); /// /// prehashed.input(message); /// # } /// # - /// # #[cfg(any(not(feature = "sha2"), not(feature = "std")))] + /// # #[cfg(not(feature = "std"))] /// # fn main() { } /// ``` /// @@ -1240,20 +1190,19 @@ impl Keypair { /// ``` /// # extern crate ed25519_dalek; /// # extern crate rand; - /// # extern crate sha2; /// # + /// # use ed25519_dalek::Digest; /// # use ed25519_dalek::Keypair; /// # use ed25519_dalek::Signature; + /// # use ed25519_dalek::Sha512; /// # use rand::thread_rng; - /// # use sha2::Digest; - /// # use sha2::Sha512; /// # - /// # #[cfg(all(feature = "std", feature = "sha2"))] + /// # #[cfg(feature = "std")] /// # fn main() { /// # let mut csprng = thread_rng(); - /// # let keypair: Keypair = Keypair::generate::(&mut csprng); + /// # 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::default(); + /// # let mut prehashed: Sha512 = Sha512::new(); /// # prehashed.input(message); /// # /// let context: &[u8] = b"Ed25519DalekSignPrehashedDoctest"; @@ -1261,24 +1210,33 @@ impl Keypair { /// let sig: Signature = keypair.sign_prehashed(prehashed, Some(context)); /// # } /// # - /// # #[cfg(any(not(feature = "sha2"), not(feature = "std")))] + /// # #[cfg(not(feature = "std"))] /// # fn main() { } /// ``` /// /// [rfc8032]: https://tools.ietf.org/html/rfc8032#section-5.1 /// [terrible_idea]: https://github.com/isislovecruft/scripts/blob/master/gpgkey2bc.py - pub fn sign_prehashed(&self, - prehashed_message: D, - context: Option<&'static [u8]>) -> Signature - where D: Digest + Default + pub fn sign_prehashed( + &self, + prehashed_message: D, + context: Option<&'static [u8]> + ) -> Signature + where + D: Digest, { - self.secret.expand::().sign_prehashed::(prehashed_message, &self.public, context) + let expanded: ExpandedSecretKey = (&self.secret).into(); // xxx thanks i hate this + + expanded.sign_prehashed(prehashed_message, &self.public, context) } /// Verify a signature on a message with this keypair's public key. - pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), SignatureError> - where D: Digest + Default { - self.public.verify::(message, signature) + pub fn verify( + &self, + message: &[u8], + signature: &Signature + ) -> Result<(), SignatureError> + { + self.public.verify(message, signature) } /// Verify a `signature` on a `prehashed_message` using the Ed25519ph algorithm. @@ -1303,18 +1261,17 @@ impl Keypair { /// ``` /// extern crate ed25519_dalek; /// extern crate rand; - /// extern crate sha2; /// + /// use ed25519_dalek::Digest; /// use ed25519_dalek::Keypair; /// use ed25519_dalek::Signature; + /// use ed25519_dalek::Sha512; /// use rand::thread_rng; - /// use sha2::Digest; - /// use sha2::Sha512; /// - /// # #[cfg(all(feature = "std", feature = "sha2"))] + /// # #[cfg(feature = "std")] /// # fn main() { /// let mut csprng = thread_rng(); - /// let keypair: Keypair = Keypair::generate::(&mut csprng); + /// 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::default(); @@ -1333,18 +1290,21 @@ impl Keypair { /// assert!(verified.is_ok()); /// # } /// # - /// # #[cfg(any(not(feature = "sha2"), not(feature = "std")))] + /// # #[cfg(not(feature = "std"))] /// # fn main() { } /// ``` /// /// [rfc8032]: https://tools.ietf.org/html/rfc8032#section-5.1 - pub fn verify_prehashed(&self, - prehashed_message: D, - context: Option<&[u8]>, - signature: &Signature) -> Result<(), SignatureError> - where D: Digest + Default + pub fn verify_prehashed( + &self, + prehashed_message: D, + context: Option<&[u8]>, + signature: &Signature + ) -> Result<(), SignatureError> + where + D: Digest, { - self.public.verify_prehashed::(prehashed_message, context, signature) + self.public.verify_prehashed(prehashed_message, context, signature) } } @@ -1435,15 +1395,15 @@ mod test { let bad: &[u8] = "wrong message".as_bytes(); csprng = thread_rng(); - keypair = Keypair::generate::(&mut csprng); - good_sig = keypair.sign::(&good); - bad_sig = keypair.sign::(&bad); + keypair = Keypair::generate(&mut csprng); + good_sig = keypair.sign(&good); + bad_sig = keypair.sign(&bad); - assert!(keypair.verify::(&good, &good_sig).is_ok(), + assert!(keypair.verify(&good, &good_sig).is_ok(), "Verification of a valid signature failed!"); - assert!(keypair.verify::(&good, &bad_sig).is_err(), + assert!(keypair.verify(&good, &bad_sig).is_err(), "Verification of a signature on a different message passed!"); - assert!(keypair.verify::(&bad, &good_sig).is_err(), + assert!(keypair.verify(&bad, &good_sig).is_err(), "Verification of a signature on a different message passed!"); } @@ -1485,10 +1445,10 @@ mod test { // The signatures in the test vectors also include the message // at the end, but we just want R and S. let sig1: Signature = Signature::from_bytes(&sig_bytes[..64]).unwrap(); - let sig2: Signature = keypair.sign::(&msg_bytes); + let sig2: Signature = keypair.sign(&msg_bytes); assert!(sig1 == sig2, "Signature bytes not equal on line {}", lineno); - assert!(keypair.verify::(&msg_bytes, &sig2).is_ok(), + assert!(keypair.verify(&msg_bytes, &sig2).is_ok(), "Signature verification failed on line {}", lineno); } } @@ -1552,15 +1512,15 @@ mod test { 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)); + keypair = Keypair::generate(&mut csprng); + good_sig = keypair.sign_prehashed(prehashed_good1, Some(context)); + bad_sig = keypair.sign_prehashed(prehashed_bad1, Some(context)); - assert!(keypair.verify_prehashed::(prehashed_good2, Some(context), &good_sig).is_ok(), + assert!(keypair.verify_prehashed(prehashed_good2, Some(context), &good_sig).is_ok(), "Verification of a valid signature failed!"); - assert!(keypair.verify_prehashed::(prehashed_good3, Some(context), &bad_sig).is_err(), + assert!(keypair.verify_prehashed(prehashed_good3, Some(context), &bad_sig).is_err(), "Verification of a signature on a different message passed!"); - assert!(keypair.verify_prehashed::(prehashed_bad2, Some(context), &good_sig).is_err(), + assert!(keypair.verify_prehashed(prehashed_bad2, Some(context), &good_sig).is_err(), "Verification of a signature on a different message passed!"); } @@ -1579,13 +1539,13 @@ mod test { let mut signatures: Vec = Vec::new(); for i in 0..messages.len() { - let keypair: Keypair = Keypair::generate::(&mut csprng); - signatures.push(keypair.sign::(&messages[i])); + let keypair: Keypair = Keypair::generate(&mut csprng); + signatures.push(keypair.sign(&messages[i])); keypairs.push(keypair); } let public_keys: Vec = keypairs.iter().map(|key| key.public).collect(); - let result = verify_batch::(&messages, &signatures[..], &public_keys[..]); + let result = verify_batch(&messages, &signatures[..], &public_keys[..]); assert!(result.is_ok()); } @@ -1636,10 +1596,10 @@ mod test { #[test] fn pubkey_from_secret_and_expanded_secret() { let mut csprng = thread_rng(); - let secret: SecretKey = SecretKey::generate::<_>(&mut csprng); - let expanded_secret: ExpandedSecretKey = ExpandedSecretKey::from_secret_key::(&secret); - let public_from_secret: PublicKey = PublicKey::from_secret::(&secret); - let public_from_expanded_secret: PublicKey = PublicKey::from_expanded_secret(&expanded_secret); + let secret: SecretKey = SecretKey::generate(&mut csprng); + let expanded_secret: ExpandedSecretKey = (&secret).into(); + let public_from_secret: PublicKey = (&secret).into(); // XXX eww + let public_from_expanded_secret: PublicKey = (&expanded_secret).into(); // XXX eww assert!(public_from_secret == public_from_expanded_secret); } diff --git a/src/lib.rs b/src/lib.rs index ff8ed03..6c92afb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,28 +15,25 @@ //! //! 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 -//! secure pseudorandom number generator (CSPRNG), and a hash function which -//! has 512 bits of output. For this example, we'll use the operating -//! system's builtin PRNG and SHA-512 to generate a keypair: +//! secure pseudorandom number generator (CSPRNG). For this example, we'll use +//! the operating system's builtin PRNG: //! //! ``` //! extern crate rand; -//! extern crate sha2; //! extern crate ed25519_dalek; //! -//! # #[cfg(all(feature = "std", feature = "sha2"))] +//! # #[cfg(feature = "std")] //! # fn main() { //! use rand::Rng; //! use rand::OsRng; -//! use sha2::Sha512; //! use ed25519_dalek::Keypair; //! use ed25519_dalek::Signature; //! //! let mut csprng: OsRng = OsRng::new().unwrap(); -//! let keypair: Keypair = Keypair::generate::(&mut csprng); // The `_` can be the type of `csprng` +//! let keypair: Keypair = Keypair::generate(&mut csprng); //! # } //! # -//! # #[cfg(any(not(feature = "std"), not(feature = "sha2")))] +//! # #[cfg(not(feature = "std"))] //! # fn main() { } //! ``` //! @@ -44,18 +41,16 @@ //! //! ``` //! # extern crate rand; -//! # extern crate sha2; //! # extern crate ed25519_dalek; //! # fn main() { //! # use rand::Rng; //! # use rand::thread_rng; -//! # use sha2::Sha512; //! # use ed25519_dalek::Keypair; //! # use ed25519_dalek::Signature; //! # let mut csprng = thread_rng(); -//! # let keypair: Keypair = Keypair::generate::(&mut csprng); -//! let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); -//! let signature: Signature = keypair.sign::(message); +//! # 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); //! # } //! ``` //! @@ -64,19 +59,17 @@ //! //! ``` //! # extern crate rand; -//! # extern crate sha2; //! # extern crate ed25519_dalek; //! # fn main() { //! # use rand::Rng; //! # use rand::thread_rng; -//! # use sha2::Sha512; //! # use ed25519_dalek::Keypair; //! # use ed25519_dalek::Signature; //! # let mut csprng = thread_rng(); -//! # let keypair: Keypair = Keypair::generate::(&mut csprng); -//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); -//! # let signature: Signature = keypair.sign::(message); -//! assert!(keypair.verify::(message, &signature).is_ok()); +//! # 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); +//! assert!(keypair.verify(message, &signature).is_ok()); //! # } //! ``` //! @@ -85,22 +78,20 @@ //! //! ``` //! # extern crate rand; -//! # extern crate sha2; //! # extern crate ed25519_dalek; //! # fn main() { //! # use rand::Rng; //! # use rand::thread_rng; -//! # use sha2::Sha512; //! # use ed25519_dalek::Keypair; //! # use ed25519_dalek::Signature; //! use ed25519_dalek::PublicKey; //! # let mut csprng = thread_rng(); -//! # let keypair: Keypair = Keypair::generate::(&mut csprng); -//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); -//! # let signature: Signature = keypair.sign::(message); +//! # 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); //! //! let public_key: PublicKey = keypair.public; -//! assert!(public_key.verify::(message, &signature).is_ok()); +//! assert!(public_key.verify(message, &signature).is_ok()); //! # } //! ``` //! @@ -114,18 +105,16 @@ //! //! ``` //! # extern crate rand; -//! # extern crate sha2; //! # extern crate ed25519_dalek; //! # fn main() { //! # use rand::Rng; //! # use rand::thread_rng; -//! # use sha2::Sha512; //! # 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 keypair: Keypair = Keypair::generate::(&mut csprng); -//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); -//! # let signature: Signature = keypair.sign::(message); +//! # 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); //! # let public_key: PublicKey = keypair.public; //! //! let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = public_key.to_bytes(); @@ -139,18 +128,16 @@ //! //! ``` //! # extern crate rand; -//! # extern crate sha2; //! # extern crate ed25519_dalek; //! # use rand::Rng; //! # use rand::thread_rng; -//! # use sha2::Sha512; //! # 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 keypair_orig: Keypair = Keypair::generate::(&mut csprng); -//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); -//! # let signature_orig: Signature = keypair_orig.sign::(message); +//! # 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); //! # let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = keypair_orig.public.to_bytes(); //! # let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = keypair_orig.secret.to_bytes(); //! # let keypair_bytes: [u8; KEYPAIR_LENGTH] = keypair_orig.to_bytes(); @@ -183,7 +170,6 @@ //! //! ``` //! # extern crate rand; -//! # extern crate sha2; //! # extern crate ed25519_dalek; //! # #[cfg(feature = "serde")] //! extern crate serde; @@ -194,15 +180,14 @@ //! # fn main() { //! # use rand::Rng; //! # use rand::thread_rng; -//! # use sha2::Sha512; //! # use ed25519_dalek::{Keypair, Signature, PublicKey}; //! use bincode::{serialize, Infinite}; //! # let mut csprng = thread_rng(); -//! # let keypair: Keypair = Keypair::generate::(&mut csprng); -//! # let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); -//! # let signature: Signature = keypair.sign::(message); +//! # 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); //! # let public_key: PublicKey = keypair.public; -//! # let verified: bool = public_key.verify::(message, &signature).is_ok(); +//! # let verified: bool = public_key.verify(message, &signature).is_ok(); //! //! let encoded_public_key: Vec = serialize(&public_key, Infinite).unwrap(); //! let encoded_signature: Vec = serialize(&signature, Infinite).unwrap(); @@ -216,7 +201,6 @@ //! //! ``` //! # extern crate rand; -//! # extern crate sha2; //! # extern crate ed25519_dalek; //! # #[cfg(feature = "serde")] //! # extern crate serde; @@ -227,17 +211,16 @@ //! # fn main() { //! # use rand::Rng; //! # use rand::thread_rng; -//! # use sha2::Sha512; //! # use ed25519_dalek::{Keypair, Signature, PublicKey}; //! # use bincode::{serialize, Infinite}; //! use bincode::{deserialize}; //! //! # let mut csprng = thread_rng(); -//! # let keypair: Keypair = Keypair::generate::(&mut csprng); -//! let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes(); -//! # let signature: Signature = keypair.sign::(message); +//! # 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); //! # let public_key: PublicKey = keypair.public; -//! # let verified: bool = public_key.verify::(message, &signature).is_ok(); +//! # let verified: bool = public_key.verify(message, &signature).is_ok(); //! # let encoded_public_key: Vec = serialize(&public_key, Infinite).unwrap(); //! # let encoded_signature: Vec = serialize(&signature, Infinite).unwrap(); //! let decoded_public_key: PublicKey = deserialize(&encoded_public_key).unwrap(); @@ -246,7 +229,7 @@ //! # assert_eq!(public_key, decoded_public_key); //! # assert_eq!(signature, decoded_signature); //! # -//! let verified: bool = decoded_public_key.verify::(&message, &decoded_signature).is_ok(); +//! let verified: bool = decoded_public_key.verify(&message, &decoded_signature).is_ok(); //! //! assert!(verified); //! # } @@ -267,7 +250,6 @@ extern crate rand; #[macro_use] extern crate std; -#[cfg(any(test, feature = "sha2"))] extern crate sha2; #[cfg(test)]