From d8476fe6cfcd422a0a7a2b588b93eb9e1897df01 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Fri, 9 Dec 2016 17:24:43 -0800 Subject: [PATCH 1/2] Add a Scalar::random() constructor This adds a dependency on the `rand` crate, used to construct an OS-backed CSPRNG. The implementation in this commit is somewhat inefficient as it constructs a new OsRng object every time; it might be better to construct it once. (Seems like a lot of overhead for a few getrandom(2) calls...) --- Cargo.toml | 1 + src/lib.rs | 2 ++ src/scalar.rs | 14 ++++++++++++++ 3 files changed, 17 insertions(+) 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..7f0adf0 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]) From c6b1b497b05e7270c773a35e168e80686e01fbfa Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Fri, 9 Dec 2016 17:45:54 -0800 Subject: [PATCH 2/2] Add benchmark for Scalar::random() --- src/scalar.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/scalar.rs b/src/scalar.rs index 7f0adf0..8a575fd 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -431,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) );