Skip to content

Commit

Permalink
Rework CryptoRng (#1273)
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov authored Feb 20, 2023
1 parent f2e21db commit 7c1e649
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 49 deletions.
16 changes: 8 additions & 8 deletions rand_chacha/src/chacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

use self::core::fmt;
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore};
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};

#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer};
Expand Down Expand Up @@ -99,7 +99,7 @@ macro_rules! chacha_impl {
}
}

impl CryptoRng for $ChaChaXCore {}
impl CryptoBlockRng for $ChaChaXCore {}

/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
Expand Down Expand Up @@ -626,12 +626,12 @@ mod test {

#[test]
fn test_trait_objects() {
use rand_core::CryptoRngCore;
use rand_core::CryptoRng;

let rng = &mut ChaChaRng::from_seed(Default::default()) as &mut dyn CryptoRngCore;
let r1 = rng.next_u64();
let rng: &mut dyn RngCore = rng.as_rngcore();
let r2 = rng.next_u64();
assert_ne!(r1, r2);
let mut rng1 = ChaChaRng::from_seed(Default::default());
let rng2 = &mut rng1.clone() as &mut dyn CryptoRng;
for _ in 0..1000 {
assert_eq!(rng1.next_u64(), rng2.next_u64());
}
}
}
14 changes: 11 additions & 3 deletions rand_core/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
//! }
//! }
//!
//! // optionally, also implement CryptoRng for MyRngCore
//! // optionally, also implement CryptoBlockRng for MyRngCore
//!
//! // Final RNG.
//! let mut rng = BlockRng::<MyRngCore>::seed_from_u64(0);
Expand All @@ -54,7 +54,7 @@
//! [`fill_bytes`]: RngCore::fill_bytes

use crate::impls::{fill_via_u32_chunks, fill_via_u64_chunks};
use crate::{CryptoRng, Error, RngCore, SeedableRng};
use crate::{Error, CryptoRng, RngCore, SeedableRng};
use core::convert::AsRef;
use core::fmt;
#[cfg(feature = "serde1")]
Expand All @@ -77,6 +77,12 @@ pub trait BlockRngCore {
fn generate(&mut self, results: &mut Self::Results);
}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to be cryptographically secure.
///
/// See [`CryptoRng`][crate::CryptoRng] docs for more information.
pub trait CryptoBlockRng: BlockRngCore { }

/// A wrapper type implementing [`RngCore`] for some type implementing
/// [`BlockRngCore`] with `u32` array buffer; i.e. this can be used to implement
/// a full RNG from just a `generate` function.
Expand Down Expand Up @@ -256,6 +262,8 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
}
}

impl<R: CryptoBlockRng + BlockRngCore<Item = u32>> CryptoRng for BlockRng<R> {}

/// A wrapper type implementing [`RngCore`] for some type implementing
/// [`BlockRngCore`] with `u64` array buffer; i.e. this can be used to implement
/// a full RNG from just a `generate` function.
Expand Down Expand Up @@ -422,7 +430,7 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng64<R> {
}
}

impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R> {}
impl<R: CryptoBlockRng + BlockRngCore<Item = u64>> CryptoRng for BlockRng64<R> {}

#[cfg(test)]
mod test {
Expand Down
35 changes: 3 additions & 32 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ pub trait RngCore {
}
}

/// A marker trait used to indicate that an [`RngCore`] or [`BlockRngCore`]
/// implementation is supposed to be cryptographically secure.
/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to be cryptographically secure.
///
/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
/// satisfy an additional properties over other generators: given the first
Expand All @@ -213,36 +213,7 @@ pub trait RngCore {
/// weaknesses such as seeding from a weak entropy source or leaking state.
///
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng {}

/// An extension trait that is automatically implemented for any type
/// implementing [`RngCore`] and [`CryptoRng`].
///
/// It may be used as a trait object, and supports upcasting to [`RngCore`] via
/// the [`CryptoRngCore::as_rngcore`] method.
///
/// # Example
///
/// ```
/// use rand_core::CryptoRngCore;
///
/// #[allow(unused)]
/// fn make_token(rng: &mut dyn CryptoRngCore) -> [u8; 32] {
/// let mut buf = [0u8; 32];
/// rng.fill_bytes(&mut buf);
/// buf
/// }
/// ```
pub trait CryptoRngCore: CryptoRng + RngCore {
/// Upcast to an [`RngCore`] trait object.
fn as_rngcore(&mut self) -> &mut dyn RngCore;
}

impl<T: CryptoRng + RngCore> CryptoRngCore for T {
fn as_rngcore(&mut self) -> &mut dyn RngCore {
self
}
}
pub trait CryptoRng: RngCore {}

/// A random number generator that can be explicitly seeded.
///
Expand Down
12 changes: 6 additions & 6 deletions src/rngs/adapter/reseeding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

use core::mem::size_of;

use rand_core::block::{BlockRng, BlockRngCore};
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};

/// A wrapper around any PRNG that implements [`BlockRngCore`], that adds the
Expand Down Expand Up @@ -147,8 +147,8 @@ where

impl<R, Rsdr> CryptoRng for ReseedingRng<R, Rsdr>
where
R: BlockRngCore + SeedableRng + CryptoRng,
Rsdr: RngCore + CryptoRng,
R: BlockRngCore<Item = u32> + SeedableRng + CryptoBlockRng,
Rsdr: CryptoRng,
{
}

Expand Down Expand Up @@ -276,10 +276,10 @@ where
}
}

impl<R, Rsdr> CryptoRng for ReseedingCore<R, Rsdr>
impl<R, Rsdr> CryptoBlockRng for ReseedingCore<R, Rsdr>
where
R: BlockRngCore + SeedableRng + CryptoRng,
Rsdr: RngCore + CryptoRng,
R: BlockRngCore<Item = u32> + SeedableRng + CryptoBlockRng,
Rsdr: CryptoRng,
{
}

Expand Down

0 comments on commit 7c1e649

Please sign in to comment.