From a93798d209294e3ea018a8960518523e7eb0e4b6 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Mon, 27 Feb 2017 11:19:06 -0800 Subject: [PATCH 1/2] Add a function to hash a byte slice to a scalar. --- Cargo.toml | 10 ++++++++++ src/lib.rs | 5 +++++ src/scalar.rs | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index da90912..691f464 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,16 @@ version = "0.3.3" optional = true version = "0.3" +[dependencies.digest] +version = "0.4" + +[dependencies.generic-array] +# same version that digest depends on +version = "^0.6" + +[dev-dependencies.sha2] +version = "0.4" + [features] default = ["std"] std = ["rand"] diff --git a/src/lib.rs b/src/lib.rs index fe26b70..13fec92 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,10 +38,15 @@ extern crate std; #[cfg(test)] extern crate test; +#[cfg(test)] +extern crate sha2; #[macro_use] extern crate arrayref; +extern crate generic_array; +extern crate digest; + #[cfg(feature = "std")] extern crate rand; diff --git a/src/scalar.rs b/src/scalar.rs index 85c77be..db19a9e 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -36,6 +36,10 @@ use core::ops::{Neg}; #[cfg(feature = "std")] use rand::Rng; +use digest::Digest; +use generic_array::GenericArray; +use generic_array::typenum::U64; + use constants; use utils::{load3, load4}; use subtle::CTAssignable; @@ -159,6 +163,35 @@ impl Scalar { Scalar::reduce(&scalar_bytes) } + /// Hash a slice of bytes into a scalar. + /// + /// Takes a type parameter `D`, which is any `Digest` producing 64 + /// bytes (512 bits) of output. + /// + /// # Example + /// + /// ``` + /// # extern crate curve25519_dalek; + /// # use curve25519_dalek::scalar::Scalar; + /// extern crate sha2; + /// use sha2::Sha512; + /// + /// # fn main() { + /// let msg = "To really appreciate architecture, you may even need to commit a murder"; + /// let s = Scalar::hash_from_bytes::(msg.as_bytes()); + /// # } + /// ``` + /// + pub fn hash_from_bytes(input: &[u8]) -> Scalar + where D: Digest + Default { + let mut hash = D::default(); + hash.input(input); + // XXX this seems clumsy + let mut output = [0u8;64]; + output.copy_from_slice(hash.result().as_slice()); + Scalar::reduce(&output) + } + /// Construct the additive identity pub fn zero() -> Self { Scalar([0u8; 32]) From fe15bc1d0b676f3b3d3ae21d2a41edcf1fc6276d Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Mon, 27 Feb 2017 11:22:07 -0800 Subject: [PATCH 2/2] Add note on fn main() in doctest --- src/scalar.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/scalar.rs b/src/scalar.rs index db19a9e..60d92ba 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -176,6 +176,8 @@ impl Scalar { /// extern crate sha2; /// use sha2::Sha512; /// + /// # // Need fn main() here in comment so the doctest compiles + /// # // See https://doc.rust-lang.org/book/documentation.html#documentation-as-tests /// # fn main() { /// let msg = "To really appreciate architecture, you may even need to commit a murder"; /// let s = Scalar::hash_from_bytes::(msg.as_bytes());