Rework CryptoRng (#1273)

This commit is contained in:
Artyom Pavlov 2023-02-20 10:28:23 +00:00 committed by GitHub
parent f2e21db971
commit 7c1e649ea1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 49 deletions

View File

@ -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};
@ -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.
///
@ -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());
}
}
}

View File

@ -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);
@ -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")]
@ -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.
@ -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.
@ -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 {

View File

@ -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
@ -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.
///

View File

@ -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
@ -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,
{
}
@ -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,
{
}