diff --git a/Cargo.toml b/Cargo.toml index 7db21b5..1973fcd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ exclude = [ ] [dependencies] +rand = "0.3" arrayref = "0.3.2" # The development profile, used for `cargo build`. diff --git a/src/lib.rs b/src/lib.rs index ddb79e6..9253c39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,8 @@ extern crate test; #[macro_use] extern crate arrayref; +extern crate rand; + // Modules for low-level operations directly on field elements and curve points. pub mod field; diff --git a/src/scalar.rs b/src/scalar.rs index 610c563..8a575fd 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -29,6 +29,9 @@ use std::clone::Clone; use std::ops::{Index, IndexMut}; +use rand::OsRng; +use rand::Rng; + use field::{load3, load4}; /// The `Scalar` struct represents an element in ℤ/lℤ, where @@ -60,6 +63,17 @@ impl IndexMut for Scalar { } impl Scalar { + /// Return a `Scalar` chosen uniformly at random using a CSPRNG. + /// Panics if the operating system's CSPRNG is unavailable. + pub fn random() -> Self { + // XXX is there a more efficient way than building + // the rng every time here? + let mut rng = OsRng::new().unwrap(); + let mut scalar_bytes = [0u8; 64]; + rng.fill_bytes(&mut scalar_bytes); + Scalar::reduce(&scalar_bytes) + } + /// Construct the additive identity pub fn zero() -> Self { Scalar([0u8; 32]) @@ -417,6 +431,11 @@ mod test { use super::*; use test::Bencher; + #[bench] + fn bench_scalar_random(b: &mut Bencher) { + b.iter(|| Scalar::random()); + } + #[bench] fn bench_scalar_multiply_add(b: &mut Bencher) { b.iter(|| Scalar::multiply_add(&X, &Y, &Z) );