diff --git a/Cargo.toml b/Cargo.toml index 6442c18945..87b8e71ab3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ exclude = ["benches", "distr_test"] rand_core = { version = "0.10.0-rc-2", default-features = false } log = { version = "0.4.4", optional = true } serde = { version = "1.0.103", features = ["derive"], optional = true } -chacha20 = { version = "=0.10.0-rc.5", default-features = false, features = ["rng"], optional = true } +chacha20 = { path = "rand_chacha", optional = true, package = "rand_chacha" } getrandom = { version = "0.3.0", optional = true } [dev-dependencies] @@ -85,3 +85,6 @@ rand_pcg = { path = "rand_pcg", version = "0.10.0-rc.1" } bincode = "1.2.1" rayon = "1.7" serde_json = "1.0.140" + +[patch.crates-io] +rand_core = { git = "https://github.com/rust-random/rand_core.git", branch = "reduce-block-code" } diff --git a/benches/Cargo.toml b/benches/Cargo.toml index 699186b26f..83d8e0c327 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -56,3 +56,6 @@ harness = false [[bench]] name = "weighted" harness = false + +[patch.crates-io] +rand_core = { git = "https://github.com/rust-random/rand_core.git", branch = "reduce-block-code" } diff --git a/rand_chacha/src/chacha.rs b/rand_chacha/src/chacha.rs index f42232f757..a455f0123c 100644 --- a/rand_chacha/src/chacha.rs +++ b/rand_chacha/src/chacha.rs @@ -10,7 +10,7 @@ use crate::guts::ChaCha; use core::fmt; -use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng}; +use rand_core::block::{BlockRng, CryptoGenerator, Generator}; use rand_core::{CryptoRng, RngCore, SeedableRng}; #[cfg(feature = "serde")] @@ -21,52 +21,6 @@ const BUF_BLOCKS: u8 = 4; // number of 32-bit words per ChaCha block (fixed by algorithm definition) const BLOCK_WORDS: u8 = 16; -#[repr(transparent)] -pub struct Array64([T; 64]); -impl Default for Array64 -where - T: Default, -{ - #[rustfmt::skip] - fn default() -> Self { - Self([ - T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), - T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), - T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), - T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), - T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), - T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), - T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), - T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), - ]) - } -} -impl AsRef<[T]> for Array64 { - fn as_ref(&self) -> &[T] { - &self.0 - } -} -impl AsMut<[T]> for Array64 { - fn as_mut(&mut self) -> &mut [T] { - &mut self.0 - } -} -impl Clone for Array64 -where - T: Copy + Default, -{ - fn clone(&self) -> Self { - let mut new = Self::default(); - new.0.copy_from_slice(&self.0); - new - } -} -impl fmt::Debug for Array64 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Array64 {{}}") - } -} - macro_rules! chacha_impl { ($ChaChaXCore:ident, $ChaChaXRng:ident, $rounds:expr, $doc:expr, $abst:ident,) => { #[doc=$doc] @@ -82,13 +36,12 @@ macro_rules! chacha_impl { } } - impl BlockRngCore for $ChaChaXCore { - type Item = u32; - type Results = Array64; + impl Generator for $ChaChaXCore { + type Output = [u32; 64]; #[inline] - fn generate(&mut self, r: &mut Self::Results) { - self.state.refill4($rounds, &mut r.0); + fn generate(&mut self, output: &mut Self::Output) { + self.state.refill4($rounds, output); } } @@ -103,7 +56,7 @@ macro_rules! chacha_impl { } } - impl CryptoBlockRng for $ChaChaXCore {} + impl CryptoGenerator for $ChaChaXCore {} /// A cryptographically secure random number generator that uses the ChaCha algorithm. /// @@ -163,12 +116,12 @@ macro_rules! chacha_impl { impl RngCore for $ChaChaXRng { #[inline] fn next_u32(&mut self) -> u32 { - self.rng.next_u32() + self.rng.next_word() } #[inline] fn next_u64(&mut self) -> u64 { - self.rng.next_u64() + self.rng.next_u64_from_u32() } #[inline] diff --git a/src/rngs/reseeding.rs b/src/rngs/reseeding.rs index 4a9f107edb..47f449d9be 100644 --- a/src/rngs/reseeding.rs +++ b/src/rngs/reseeding.rs @@ -12,10 +12,10 @@ use core::mem::size_of_val; -use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng}; +use rand_core::block::{BlockRng, CryptoGenerator, Generator}; use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore}; -/// A wrapper around any PRNG that implements [`BlockRngCore`], that adds the +/// A wrapper around any PRNG that implements [`Generator`], that adds the /// ability to reseed it. /// /// `ReseedingRng` reseeds the underlying PRNG in the following cases: @@ -53,7 +53,7 @@ use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore}; /// /// ``` /// use chacha20::ChaCha20Core; // Internal part of ChaChaRng that -/// // implements BlockRngCore +/// // implements Generator /// use rand::prelude::*; /// use rand::rngs::OsRng; /// use rand::rngs::ReseedingRng; @@ -63,18 +63,18 @@ use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore}; /// println!("{}", reseeding_rng.random::()); /// ``` /// -/// [`BlockRngCore`]: rand_core::block::BlockRngCore +/// [`Generator`]: rand_core::block::Generator /// [`ReseedingRng::new`]: ReseedingRng::new /// [`reseed()`]: ReseedingRng::reseed #[derive(Debug)] -pub struct ReseedingRng(BlockRng>) +pub struct ReseedingRng(BlockRng>) where - R: BlockRngCore + SeedableRng, + G: Generator + SeedableRng, Rsdr: TryRngCore; -impl ReseedingRng +impl ReseedingRng where - R: BlockRngCore + SeedableRng, + G: Generator + SeedableRng, Rsdr: TryRngCore, { /// Create a new `ReseedingRng` from an existing PRNG, combined with a RNG @@ -100,19 +100,19 @@ where // TODO: this should be implemented for any type where the inner type // implements RngCore, but we can't specify that because ReseedingCore is private -impl RngCore for ReseedingRng +impl RngCore for ReseedingRng where - R: BlockRngCore + SeedableRng, + G: Generator + SeedableRng, Rsdr: TryRngCore, { #[inline(always)] fn next_u32(&mut self) -> u32 { - self.0.next_u32() + self.0.next_word() } #[inline(always)] fn next_u64(&mut self) -> u64 { - self.0.next_u64() + self.0.next_u64_from_u32() } fn fill_bytes(&mut self, dest: &mut [u8]) { @@ -120,51 +120,50 @@ where } } -impl CryptoRng for ReseedingRng +impl CryptoRng for ReseedingRng where - R: BlockRngCore + SeedableRng + CryptoBlockRng, + G: Generator + SeedableRng + CryptoGenerator, Rsdr: TryCryptoRng, { } #[derive(Debug)] -struct ReseedingCore { - inner: R, +struct ReseedingCore { + inner: G, reseeder: Rsdr, threshold: i64, bytes_until_reseed: i64, } -impl BlockRngCore for ReseedingCore +impl Generator for ReseedingCore where - R: BlockRngCore + SeedableRng, + G: Generator + SeedableRng, Rsdr: TryRngCore, { - type Item = ::Item; - type Results = ::Results; + type Output = ::Output; - fn generate(&mut self, results: &mut Self::Results) { + fn generate(&mut self, results: &mut Self::Output) { if self.bytes_until_reseed <= 0 { // We get better performance by not calling only `reseed` here // and continuing with the rest of the function, but by directly // returning from a non-inlined function. return self.reseed_and_generate(results); } - let num_bytes = size_of_val(results.as_ref()); + let num_bytes = size_of_val(results); self.bytes_until_reseed -= num_bytes as i64; self.inner.generate(results); } } -impl ReseedingCore +impl ReseedingCore where - R: BlockRngCore + SeedableRng, + G: Generator + SeedableRng, Rsdr: TryRngCore, { /// Create a new `ReseedingCore`. /// /// `threshold` is the maximum number of bytes produced by - /// [`BlockRngCore::generate`] before attempting reseeding. + /// [`Generator::generate`] before attempting reseeding. fn new(threshold: u64, mut reseeder: Rsdr) -> Result { // Because generating more values than `i64::MAX` takes centuries on // current hardware, we just clamp to that value. @@ -178,7 +177,7 @@ where i64::MAX }; - let inner = R::try_from_rng(&mut reseeder)?; + let inner = G::try_from_rng(&mut reseeder)?; Ok(ReseedingCore { inner, @@ -190,17 +189,17 @@ where /// Reseed the internal PRNG. fn reseed(&mut self) -> Result<(), Rsdr::Error> { - R::try_from_rng(&mut self.reseeder).map(|result| { + G::try_from_rng(&mut self.reseeder).map(|result| { self.bytes_until_reseed = self.threshold; self.inner = result }) } #[inline(never)] - fn reseed_and_generate(&mut self, results: &mut ::Results) { + fn reseed_and_generate(&mut self, results: &mut G::Output) { trace!("Reseeding RNG (periodic reseed)"); - let num_bytes = size_of_val(results.as_ref()); + let num_bytes = size_of_val(results); if let Err(e) = self.reseed() { warn!("Reseeding RNG failed: {}", e); @@ -212,9 +211,9 @@ where } } -impl CryptoBlockRng for ReseedingCore +impl CryptoGenerator for ReseedingCore where - R: BlockRngCore + SeedableRng + CryptoBlockRng, + G: Generator + SeedableRng + CryptoGenerator, Rsdr: TryCryptoRng, { }