Skip to content

Commit

Permalink
WIP3
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Jan 1, 2018
1 parent 0607517 commit 7e4ffd0
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 79 deletions.
16 changes: 9 additions & 7 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,23 +157,25 @@ pub trait Rng {
/// implemented for well-reviewed code implementing well-regarded algorithms.
pub trait CryptoRng: Rng {}

/// FIXME
pub trait BlockRng<T>: Sized {
/// Trait for RNG's that do not generate random numbers one at a time, but in
/// blocks. Especially for cryptographic RNG's it is common to generate 16 or
/// more results at a time.
pub trait BlockRngCore<T>: Sized {
type Results: AsRef<[T]> + Default;

fn generate(&mut self, results: &mut Self::Results);
}

#[derive(Debug, Clone)]
pub struct BlockRngWrapper<R: BlockRng<u32>> {
pub struct BlockRng<R: BlockRngCore<u32>> {
pub core: R,
pub results: R::Results,
pub index: usize,
pub half_used: bool, // Only used for u64 rng's,
// true if only half of the previous result is used
}

impl<R: BlockRng<u32>> Rng for BlockRngWrapper<R> {
impl<R: BlockRngCore<u32>> Rng for BlockRng<R> {
#[inline]
fn next_u32(&mut self) -> u32 {
if self.index >= self.results.as_ref().len() {
Expand Down Expand Up @@ -285,9 +287,9 @@ impl<R: BlockRng<u32>> Rng for BlockRngWrapper<R> {

/*
// FIXME: failes to build with:
// error[E0119]: conflicting implementations of trait `Rng` for type `BlockRngWrapper<_, _>`
// error[E0119]: conflicting implementations of trait `Rng` for type `BlockRng<_, _>`
impl<R: BlockRng<u64>> Rng for BlockRngWrapper<R> {
impl<R: BlockRngCore<u64>> Rng for BlockRng<R> {
#[inline]
fn next_u32(&mut self) -> u32 {
let len = self.results.as_ref().len();
Expand Down Expand Up @@ -360,7 +362,7 @@ impl<R: BlockRng<u64>> Rng for BlockRngWrapper<R> {
}
*/

impl<R: BlockRng<u32> + SeedableRng> SeedableRng for BlockRngWrapper<R> {
impl<R: BlockRngCore<u32> + SeedableRng> SeedableRng for BlockRng<R> {
type Seed = R::Seed;

fn from_seed(seed: Self::Seed) -> Self {
Expand Down
26 changes: 13 additions & 13 deletions src/prng/chacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! The ChaCha random number generator.

use core::fmt;
use rand_core::{le, BlockRng, BlockRngWrapper};
use rand_core::{le, BlockRngCore, BlockRng};
use {Rng, CryptoRng, SeedableRng, Error};

const SEED_WORDS: usize = 8; // 8 words for the 256-bit key
Expand Down Expand Up @@ -47,7 +47,7 @@ const CHACHA_ROUNDS: u32 = 20; // Cryptographically secure from 8 upwards as of
/// [2]: Daniel J. Bernstein. [*Extending the Salsa20
/// nonce.*](http://cr.yp.to/papers.html#xsalsa)
#[derive(Clone)]
pub struct ChaChaRng(BlockRngWrapper<ChaCha>);
pub struct ChaChaRng(BlockRng<ChaChaCore>);

impl Rng for ChaChaRng {
#[inline]
Expand Down Expand Up @@ -78,14 +78,14 @@ impl Rng for ChaChaRng {
}

impl SeedableRng for ChaChaRng {
type Seed = <ChaCha as SeedableRng>::Seed;
type Seed = <ChaChaCore as SeedableRng>::Seed;

fn from_seed(seed: Self::Seed) -> Self {
ChaChaRng(BlockRngWrapper::<ChaCha>::from_seed(seed))
ChaChaRng(BlockRng::<ChaChaCore>::from_seed(seed))
}

fn from_rng<R: Rng>(rng: R) -> Result<Self, Error> {
BlockRngWrapper::<ChaCha>::from_rng(rng).map(|rng| ChaChaRng(rng))
BlockRng::<ChaChaCore>::from_rng(rng).map(|rng| ChaChaRng(rng))
}
}

Expand Down Expand Up @@ -151,14 +151,14 @@ impl fmt::Debug for ChaChaRng {


#[derive(Clone, Copy)]
pub struct ChaCha {
pub struct ChaChaCore {
state: [u32; STATE_WORDS],
}

// Custom Debug implementation that does not expose the internal state
impl fmt::Debug for ChaCha {
impl fmt::Debug for ChaChaCore {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ChaCha {{}}")
write!(f, "ChaChaCore {{}}")
}
}

Expand Down Expand Up @@ -186,7 +186,7 @@ macro_rules! double_round{
}}
}

impl BlockRng<u32> for ChaCha {
impl BlockRngCore<u32> for ChaChaCore {
type Results = [u32; STATE_WORDS];

fn generate(&mut self, results: &mut Self::Results) {
Expand All @@ -211,9 +211,9 @@ impl BlockRng<u32> for ChaCha {
}
}

impl ChaCha {
impl ChaChaCore {
fn init(seed: [u32; SEED_WORDS]) -> Self {
ChaCha { state:
Self { state:
[0x61707865, 0x3320646E, 0x79622D32, 0x6B206574, // constants
seed[0], seed[1], seed[2], seed[3], // seed
seed[4], seed[5], seed[6], seed[7], // seed
Expand All @@ -231,13 +231,13 @@ impl ChaCha {
}
}

impl SeedableRng for ChaCha {
impl SeedableRng for ChaChaCore {
type Seed = [u8; SEED_WORDS*4];

fn from_seed(seed: Self::Seed) -> Self {
let mut seed_u32 = [0u32; SEED_WORDS];
le::read_u32_into(&seed, &mut seed_u32);
ChaCha::init(seed_u32)
Self::init(seed_u32)
}
}

Expand Down
28 changes: 14 additions & 14 deletions src/prng/hc128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! The HC-128 random number generator.

use core::fmt;
use rand_core::{le, BlockRng, BlockRngWrapper};
use rand_core::{le, BlockRngCore, BlockRng};
use {Rng, CryptoRng, SeedableRng, Error};

const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv
Expand Down Expand Up @@ -54,7 +54,7 @@ const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv
/// ["Some Results On Analysis And Implementation Of HC-128 Stream Cipher"]
/// (http://library.isical.ac.in:8080/jspui/bitstream/123456789/6636/1/TH431.pdf).
#[derive(Clone)]
pub struct Hc128Rng(BlockRngWrapper<Hc128>);
pub struct Hc128Rng(BlockRng<Hc128Core>);

impl Rng for Hc128Rng {
#[inline]
Expand Down Expand Up @@ -85,14 +85,14 @@ impl Rng for Hc128Rng {
}

impl SeedableRng for Hc128Rng {
type Seed = <Hc128 as SeedableRng>::Seed;
type Seed = <Hc128Core as SeedableRng>::Seed;

fn from_seed(seed: Self::Seed) -> Self {
Hc128Rng(BlockRngWrapper::<Hc128>::from_seed(seed))
Hc128Rng(BlockRng::<Hc128Core>::from_seed(seed))
}

fn from_rng<R: Rng>(rng: R) -> Result<Self, Error> {
BlockRngWrapper::<Hc128>::from_rng(rng).map(|rng| Hc128Rng(rng))
BlockRng::<Hc128Core>::from_rng(rng).map(|rng| Hc128Rng(rng))
}
}

Expand All @@ -107,27 +107,27 @@ impl fmt::Debug for Hc128Rng {


#[derive(Copy)]
pub struct Hc128 {
pub struct Hc128Core {
t: [u32; 1024],
counter1024: usize,
}

// Custom Debug implementation that does not expose the internal state
impl fmt::Debug for Hc128 {
impl fmt::Debug for Hc128Core {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Hc128 {{}}")
write!(f, "Hc128Core {{}}")
}
}

// Cannot be derived because [u32; 1024] does not implement Clone in
// Rust < 1.21.0 (since https://github.com/rust-lang/rust/pull/43690)
impl Clone for Hc128 {
impl Clone for Hc128Core {
fn clone(&self) -> Self {
*self
}
}

impl BlockRng<u32> for Hc128 {
impl BlockRngCore<u32> for Hc128Core {
type Results = [u32; 16];

fn generate(&mut self, results: &mut Self::Results) {
Expand Down Expand Up @@ -178,7 +178,7 @@ impl BlockRng<u32> for Hc128 {
}
}

impl Hc128 {
impl Hc128Core {
// One step of HC-128, update P and generate 32 bits keystream
#[inline(always)]
fn step_p(&mut self, i: usize, i511: usize, i3: usize, i10: usize, i12: usize)
Expand Down Expand Up @@ -314,7 +314,7 @@ impl Hc128 {
.wrapping_add(t[i-16]).wrapping_add(256 + i as u32);
}

let mut core = Hc128 { t: t, counter1024: 0 };
let mut core = Self { t: t, counter1024: 0 };

// run the cipher 1024 steps
for _ in 0..64 { core.sixteen_steps() };
Expand All @@ -323,13 +323,13 @@ impl Hc128 {
}
}

impl SeedableRng for Hc128 {
impl SeedableRng for Hc128Core {
type Seed = [u8; SEED_WORDS*4];

fn from_seed(seed_u8: Self::Seed) -> Self {
let mut seed = [0u32; SEED_WORDS];
le::read_u32_into(&seed_u8, &mut seed);
Hc128::init(seed)
Self::init(seed)
}
}

Expand Down
34 changes: 17 additions & 17 deletions src/prng/isaac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

use core::{fmt, slice};
use core::num::Wrapping as w;
use rand_core::{le, BlockRng, BlockRngWrapper};
use rand_core::{le, BlockRngCore, BlockRng};
use {Rng, SeedableRng, Error};

#[allow(non_camel_case_types)]
Expand Down Expand Up @@ -85,7 +85,7 @@ const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
/// [3]: Jean-Philippe Aumasson, [*On the pseudo-random generator ISAAC*]
/// (http://eprint.iacr.org/2006/438)
#[derive(Clone)]
pub struct IsaacRng(BlockRngWrapper<Isaac>);
pub struct IsaacRng(BlockRng<IsaacCore>);

impl Rng for IsaacRng {
#[inline]
Expand Down Expand Up @@ -116,14 +116,14 @@ impl Rng for IsaacRng {
}

impl SeedableRng for IsaacRng {
type Seed = <Isaac as SeedableRng>::Seed;
type Seed = <IsaacCore as SeedableRng>::Seed;

fn from_seed(seed: Self::Seed) -> Self {
IsaacRng(BlockRngWrapper::<Isaac>::from_seed(seed))
IsaacRng(BlockRng::<IsaacCore>::from_seed(seed))
}

fn from_rng<R: Rng>(rng: R) -> Result<Self, Error> {
BlockRngWrapper::<Isaac>::from_rng(rng).map(|rng| IsaacRng(rng))
BlockRng::<IsaacCore>::from_rng(rng).map(|rng| IsaacRng(rng))
}
}

Expand All @@ -135,14 +135,14 @@ impl IsaacRng {
let mut key = [w(0); RAND_SIZE];
key[0] = w(seed as u32);
key[1] = w((seed >> 32) as u32);
IsaacRng(BlockRngWrapper {
IsaacRng(BlockRng {
// Initialize with only one pass.
// A second pass does not improve the quality here, because all of
// the seed was already available in the first round.
// Not doing the second pass has the small advantage that if
// `seed == 0` this method produces exactly the same state as the
// reference implementation when used unseeded.
core: Isaac::init(key, 1),
core: IsaacCore::init(key, 1),
results: IsaacArray([0; RAND_SIZE]),
index: RAND_SIZE, // generate on first use
half_used: false,
Expand All @@ -159,23 +159,23 @@ impl fmt::Debug for IsaacRng {


#[derive(Copy)]
pub struct Isaac {
pub struct IsaacCore {
mem: [w32; RAND_SIZE],
a: w32,
b: w32,
c: w32,
}

// Custom Debug implementation that does not expose the internal state
impl fmt::Debug for Isaac {
impl fmt::Debug for IsaacCore {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Isaac {{}}")
write!(f, "IsaacCore {{}}")
}
}

// Cannot be derived because [u32; 1024] does not implement Clone in
// Rust < 1.21.0 (since https://github.com/rust-lang/rust/pull/43690)
impl Clone for Isaac {
impl Clone for IsaacCore {
fn clone(&self) -> Self {
*self
}
Expand Down Expand Up @@ -209,7 +209,7 @@ impl ::core::default::Default for IsaacArray {
fn default() -> IsaacArray { IsaacArray([0u32; RAND_SIZE]) }
}

impl BlockRng<u32> for Isaac {
impl BlockRngCore<u32> for IsaacCore {
type Results = IsaacArray;

/// Refills the output buffer (`results`)
Expand Down Expand Up @@ -284,7 +284,7 @@ impl BlockRng<u32> for Isaac {
}
}

impl Isaac {
impl IsaacCore {
/// Creates a new ISAAC random number generator.
///
/// The author Bob Jenkins describes how to best initialize ISAAC here:
Expand Down Expand Up @@ -353,11 +353,11 @@ impl Isaac {
}
}

Isaac { mem: mem, a: w(0), b: w(0), c: w(0) }
Self { mem: mem, a: w(0), b: w(0), c: w(0) }
}
}

impl SeedableRng for Isaac {
impl SeedableRng for IsaacCore {
type Seed = [u8; 32];

fn from_seed(seed: Self::Seed) -> Self {
Expand All @@ -367,7 +367,7 @@ impl SeedableRng for Isaac {
for (x, y) in seed_extended.iter_mut().zip(seed_u32.iter()) {
*x = w(*y);
}
Isaac::init(seed_extended, 2)
Self::init(seed_extended, 2)
}

fn from_rng<R: Rng>(mut rng: R) -> Result<Self, Error> {
Expand All @@ -382,7 +382,7 @@ impl SeedableRng for Isaac {
for i in seed.iter_mut() {
*i = w(i.0.to_le());
}
Ok(Isaac::init(seed, 2))
Ok(Self::init(seed, 2))
}
}

Expand Down
Loading

0 comments on commit 7e4ffd0

Please sign in to comment.