diff --git a/Cargo.toml b/Cargo.toml index 05104ef288..097b2956ae 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,7 @@ rand_pcg = { path = "rand_pcg", version = "0.10.0-rc.1" } postcard = {version = "1.1.3", default-features = false, features = ["alloc"]} rayon = "1.7" serde_json = "1.0.140" + +[patch.crates-io.rand_core] +git = "https://github.com/rust-random/rand_core.git" +rev = "29b1630b" diff --git a/benches/Cargo.toml b/benches/Cargo.toml index 699186b26f..bb4c554bf6 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -56,3 +56,7 @@ harness = false [[bench]] name = "weighted" harness = false + +[patch.crates-io.rand_core] +git = "https://github.com/rust-random/rand_core.git" +rev = "29b1630b" 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/rand_pcg/src/pcg128.rs b/rand_pcg/src/pcg128.rs index f7dbada8cb..e6c4e02bf6 100644 --- a/rand_pcg/src/pcg128.rs +++ b/rand_pcg/src/pcg128.rs @@ -14,7 +14,7 @@ const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645; use core::fmt; -use rand_core::{RngCore, SeedableRng, le}; +use rand_core::{RngCore, SeedableRng, utils}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -126,8 +126,7 @@ impl SeedableRng for Lcg128Xsl64 { /// We use a single 255-bit seed to initialise the state and select a stream. /// One `seed` bit (lowest bit of `seed[8]`) is ignored. fn from_seed(seed: Self::Seed) -> Self { - let mut seed_u64 = [0u64; 4]; - le::read_u64_into(&seed, &mut seed_u64); + let seed_u64: [u64; 4] = utils::read_words(&seed); let state = u128::from(seed_u64[0]) | (u128::from(seed_u64[1]) << 64); let incr = u128::from(seed_u64[2]) | (u128::from(seed_u64[3]) << 64); @@ -150,7 +149,7 @@ impl RngCore for Lcg128Xsl64 { #[inline] fn fill_bytes(&mut self, dest: &mut [u8]) { - le::fill_bytes_via_next(self, dest) + utils::fill_bytes_via_next_word(dest, || self.next_u64()); } } @@ -232,8 +231,7 @@ impl SeedableRng for Mcg128Xsl64 { fn from_seed(seed: Self::Seed) -> Self { // Read as if a little-endian u128 value: - let mut seed_u64 = [0u64; 2]; - le::read_u64_into(&seed, &mut seed_u64); + let seed_u64: [u64; 2] = utils::read_words(&seed); let state = u128::from(seed_u64[0]) | (u128::from(seed_u64[1]) << 64); Mcg128Xsl64::new(state) } @@ -253,7 +251,7 @@ impl RngCore for Mcg128Xsl64 { #[inline] fn fill_bytes(&mut self, dest: &mut [u8]) { - le::fill_bytes_via_next(self, dest) + utils::fill_bytes_via_next_word(dest, || self.next_u64()); } } diff --git a/rand_pcg/src/pcg128cm.rs b/rand_pcg/src/pcg128cm.rs index 681ca639b4..e9ce218f36 100644 --- a/rand_pcg/src/pcg128cm.rs +++ b/rand_pcg/src/pcg128cm.rs @@ -14,7 +14,7 @@ const MULTIPLIER: u64 = 15750249268501108917; use core::fmt; -use rand_core::{RngCore, SeedableRng, le}; +use rand_core::{RngCore, SeedableRng, utils}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -131,8 +131,7 @@ impl SeedableRng for Lcg128CmDxsm64 { /// We use a single 255-bit seed to initialise the state and select a stream. /// One `seed` bit (lowest bit of `seed[8]`) is ignored. fn from_seed(seed: Self::Seed) -> Self { - let mut seed_u64 = [0u64; 4]; - le::read_u64_into(&seed, &mut seed_u64); + let seed_u64: [u64; 4] = utils::read_words(&seed); let state = u128::from(seed_u64[0]) | (u128::from(seed_u64[1]) << 64); let incr = u128::from(seed_u64[2]) | (u128::from(seed_u64[3]) << 64); @@ -156,7 +155,7 @@ impl RngCore for Lcg128CmDxsm64 { #[inline] fn fill_bytes(&mut self, dest: &mut [u8]) { - le::fill_bytes_via_next(self, dest) + utils::fill_bytes_via_next_word(dest, || self.next_u64()); } } diff --git a/rand_pcg/src/pcg64.rs b/rand_pcg/src/pcg64.rs index 967299fdcb..4eeabfd0be 100644 --- a/rand_pcg/src/pcg64.rs +++ b/rand_pcg/src/pcg64.rs @@ -11,7 +11,7 @@ //! PCG random number generators use core::fmt; -use rand_core::{RngCore, SeedableRng, le}; +use rand_core::{RngCore, SeedableRng, utils}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -127,8 +127,7 @@ impl SeedableRng for Lcg64Xsh32 { /// We use a single 127-bit seed to initialise the state and select a stream. /// One `seed` bit (lowest bit of `seed[8]`) is ignored. fn from_seed(seed: Self::Seed) -> Self { - let mut seed_u64 = [0u64; 2]; - le::read_u64_into(&seed, &mut seed_u64); + let seed_u64: [u64; 2] = utils::read_words(&seed); // The increment must be odd, hence we discard one bit: Lcg64Xsh32::from_state_incr(seed_u64[0], seed_u64[1] | 1) @@ -154,11 +153,11 @@ impl RngCore for Lcg64Xsh32 { #[inline] fn next_u64(&mut self) -> u64 { - le::next_u64_via_u32(self) + utils::next_u64_via_u32(self) } #[inline] fn fill_bytes(&mut self, dest: &mut [u8]) { - le::fill_bytes_via_next(self, dest) + utils::fill_bytes_via_next_word(dest, || self.next_u32()); } } diff --git a/src/distr/integer.rs b/src/distr/integer.rs index b715d443de..f2bfdc5602 100644 --- a/src/distr/integer.rs +++ b/src/distr/integer.rs @@ -112,8 +112,7 @@ impl Distribution<__m128i> for StandardUniform { fn sample(&self, rng: &mut R) -> __m128i { // NOTE: It's tempting to use the u128 impl here, but confusingly this // results in different code (return via rdx, r10 instead of rax, rdx - // with u128 impl) and is much slower (+130 time). This version calls - // le::fill_bytes_via_next but performs well. + // with u128 impl) and is much slower (+130 time). let mut buf = [0_u8; core::mem::size_of::<__m128i>()]; rng.fill_bytes(&mut buf); diff --git a/src/lib.rs b/src/lib.rs index a42838d52d..4a68bebded 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -367,7 +367,7 @@ mod test { } fn fill_bytes(&mut self, dst: &mut [u8]) { - rand_core::le::fill_bytes_via_next(self, dst) + rand_core::utils::fill_bytes_via_next_word(dst, || self.next_u64()); } } 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, { } diff --git a/src/rngs/xoshiro128plusplus.rs b/src/rngs/xoshiro128plusplus.rs index 5d6b9318c5..1e8713db2e 100644 --- a/src/rngs/xoshiro128plusplus.rs +++ b/src/rngs/xoshiro128plusplus.rs @@ -6,7 +6,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rand_core::{RngCore, SeedableRng, le}; +use rand_core::{RngCore, SeedableRng, utils}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -31,8 +31,7 @@ impl SeedableRng for Xoshiro128PlusPlus { /// mapped to a different seed. #[inline] fn from_seed(seed: [u8; 16]) -> Xoshiro128PlusPlus { - let mut state = [0; 4]; - le::read_u32_into(&seed, &mut state); + let state = utils::read_words(&seed); // Check for zero on aligned integers for better code generation. // Furtermore, seed_from_u64(0) will expand to a constant when optimized. if state.iter().all(|&x| x == 0) { @@ -88,12 +87,12 @@ impl RngCore for Xoshiro128PlusPlus { #[inline] fn next_u64(&mut self) -> u64 { - le::next_u64_via_u32(self) + utils::next_u64_via_u32(self) } #[inline] fn fill_bytes(&mut self, dst: &mut [u8]) { - le::fill_bytes_via_next(self, dst) + utils::fill_bytes_via_next_word(dst, || self.next_u32()); } } diff --git a/src/rngs/xoshiro256plusplus.rs b/src/rngs/xoshiro256plusplus.rs index 4ef433abe1..b961574150 100644 --- a/src/rngs/xoshiro256plusplus.rs +++ b/src/rngs/xoshiro256plusplus.rs @@ -6,7 +6,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rand_core::{RngCore, SeedableRng, le}; +use rand_core::{RngCore, SeedableRng, utils}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -31,8 +31,7 @@ impl SeedableRng for Xoshiro256PlusPlus { /// mapped to a different seed. #[inline] fn from_seed(seed: [u8; 32]) -> Xoshiro256PlusPlus { - let mut state = [0; 4]; - le::read_u64_into(&seed, &mut state); + let state = utils::read_words(&seed); // Check for zero on aligned integers for better code generation. // Furtermore, seed_from_u64(0) will expand to a constant when optimized. if state.iter().all(|&x| x == 0) { @@ -95,7 +94,7 @@ impl RngCore for Xoshiro256PlusPlus { #[inline] fn fill_bytes(&mut self, dst: &mut [u8]) { - le::fill_bytes_via_next(self, dst) + utils::fill_bytes_via_next_word(dst, || self.next_u64()); } }