diff --git a/src/signature.rs b/src/signature.rs index fca8dfb234da27..15771e280a596f 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -3,6 +3,7 @@ use generic_array::GenericArray; use generic_array::typenum::{U32, U64}; use rand::{ChaChaRng, Rng, SeedableRng}; +use rayon::prelude::*; use ring::error::Unspecified; use ring::rand::SecureRandom; use ring::signature::Ed25519KeyPair; @@ -88,12 +89,85 @@ impl SecureRandom for GenKeys { } } -#[cfg(test)] +pub struct GenKeys2 { + // This is necessary because the rng needs to mutate its state to remain + // deterministic, and the fill trait requires an immuatble reference to self + generator: RefCell, +} + +impl GenKeys2 { + pub fn new(seed_values: &[u8]) -> GenKeys2 { + let seed: &[u8] = &seed_values[..]; + let rng: ChaChaRng = SeedableRng::from_seed(unsafe { mem::transmute(seed) }); + GenKeys2 { + generator: RefCell::new(rng), + } + } + + pub fn new_key(&self) -> Vec { + KeyPair::generate_pkcs8(self).unwrap().to_vec() + } + + pub fn gen_n_seeds(&self, n_seeds: i64) -> Vec<[u8; 16]> { + let mut rng = self.generator.borrow_mut(); + + let seeds = (0..n_seeds) + .into_iter() + .map(|_| { + let seed: [u8; 16] = rng.gen(); + seed + }) + .collect(); + seeds + } + + pub fn gen_n_keys(&self, n_keys: i64, tokens_per_user: i64) -> Vec<(Vec, i64)> { + let keys = self.gen_n_seeds(n_keys); + + let users: Vec<_> = keys + .into_par_iter() + .map(|seed| { + let new: GenKeys2 = GenKeys2::new(&seed[..]); + let pkcs8 = KeyPair::generate_pkcs8(&new).unwrap().to_vec(); + (pkcs8, tokens_per_user) + }) + .collect(); + users + } +} + +impl SecureRandom for GenKeys2 { + fn fill(&self, dest: &mut [u8]) -> Result<(), Unspecified> { + let mut rng = self.generator.borrow_mut(); + rng.fill_bytes(dest); + Ok(()) + } +} + + +#[cfg(all(feature = "unstable", test))] mod tests { + extern crate test; + + use self::test::Bencher; use super::*; use std::collections::HashSet; use std::iter::FromIterator; + #[bench] + fn bench_gen_keys(b: &mut Bencher) { + let seed: &[_] = &[1, 2, 3, 4]; + let rnd = GenKeys::new(seed); + b.iter(|| rnd.gen_n_keys(1000, 1)); + } + + #[bench] + fn bench_gen_keys2(b: &mut Bencher) { + let seed: &[_] = &[1, 2, 3, 4]; + let rnd = GenKeys2::new(seed); + b.iter(|| rnd.gen_n_keys(1000, 1)); + } + #[test] fn test_new_key_is_redundant() { let seed: &[_] = &[1, 2, 3, 4];