diff --git a/Cargo.toml b/Cargo.toml index 49cf64ed..cec30e72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,6 @@ exclude = [ "benches", ] resolver = "2" + +[patch.crates-io] +rand_core = { git = "https://github.com/rust-random/rand_core.git", branch = "reduce-block-code" } diff --git a/rand_hc/src/hc128.rs b/rand_hc/src/hc128.rs index fe6ba269..fe78a8e9 100644 --- a/rand_hc/src/hc128.rs +++ b/rand_hc/src/hc128.rs @@ -15,7 +15,7 @@ //! The HC-128 random number generator. use core::fmt; -use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng}; +use rand_core::block::{BlockRng, CryptoGenerator, Generator}; use rand_core::{CryptoRng, RngCore, SeedableRng, le}; const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv @@ -75,12 +75,12 @@ pub struct Hc128Rng(BlockRng); impl RngCore for Hc128Rng { #[inline] fn next_u32(&mut self) -> u32 { - self.0.next_u32() + self.0.next_word() } #[inline] fn next_u64(&mut self) -> u64 { - self.0.next_u64() + self.0.next_u64_from_u32() } #[inline] @@ -94,7 +94,7 @@ impl SeedableRng for Hc128Rng { #[inline] fn from_seed(seed: Self::Seed) -> Self { - Hc128Rng(BlockRng::::from_seed(seed)) + Hc128Rng(BlockRng::new(Hc128Core::from_seed(seed))) } } @@ -121,11 +121,10 @@ impl fmt::Debug for Hc128Core { } } -impl BlockRngCore for Hc128Core { - type Item = u32; - type Results = [u32; 16]; +impl Generator for Hc128Core { + type Output = [u32; 16]; - fn generate(&mut self, results: &mut Self::Results) { + fn generate(&mut self, results: &mut Self::Output) { assert!(self.counter1024 % 16 == 0); let cc = self.counter1024 % 512; @@ -342,7 +341,7 @@ impl SeedableRng for Hc128Core { } } -impl CryptoBlockRng for Hc128Core {} +impl CryptoGenerator for Hc128Core {} // Custom PartialEq implementation as it can't currently be derived from an array of size 1024 impl PartialEq for Hc128Core { diff --git a/rand_isaac/Cargo.toml b/rand_isaac/Cargo.toml index cf30165d..ee77f415 100644 --- a/rand_isaac/Cargo.toml +++ b/rand_isaac/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.85" all-features = true [features] -serde = ["dep:serde", "rand_core/serde"] +serde = ["dep:serde"] [dependencies] rand_core = "0.10.0-rc-2" diff --git a/rand_isaac/src/isaac.rs b/rand_isaac/src/isaac.rs index 88771beb..fe4a79a9 100644 --- a/rand_isaac/src/isaac.rs +++ b/rand_isaac/src/isaac.rs @@ -9,10 +9,9 @@ //! The ISAAC random number generator. -use crate::isaac_array::IsaacArray; use core::num::Wrapping as w; use core::{fmt, slice}; -use rand_core::block::{BlockRng, BlockRngCore}; +use rand_core::block::{BlockRng, Generator}; use rand_core::{RngCore, SeedableRng, TryRngCore, le}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -96,12 +95,12 @@ pub struct IsaacRng(BlockRng); impl RngCore for IsaacRng { #[inline] fn next_u32(&mut self) -> u32 { - self.0.next_u32() + self.0.next_word() } #[inline] fn next_u64(&mut self) -> u64 { - self.0.next_u64() + self.0.next_u64_from_u32() } #[inline] @@ -115,7 +114,7 @@ impl SeedableRng for IsaacRng { #[inline] fn from_seed(seed: Self::Seed) -> Self { - IsaacRng(BlockRng::::from_seed(seed)) + IsaacRng(BlockRng::new(IsaacCore::from_seed(seed))) } /// Create an ISAAC random number generator using an `u64` as seed. @@ -123,7 +122,7 @@ impl SeedableRng for IsaacRng { /// the reference implementation when used unseeded. #[inline] fn seed_from_u64(seed: u64) -> Self { - IsaacRng(BlockRng::::seed_from_u64(seed)) + IsaacRng(BlockRng::new(IsaacCore::seed_from_u64(seed))) } #[inline] @@ -131,7 +130,7 @@ impl SeedableRng for IsaacRng { where R: RngCore + ?Sized, { - IsaacRng(BlockRng::::from_rng(rng)) + IsaacRng(BlockRng::new(IsaacCore::from_rng(rng))) } #[inline] @@ -139,7 +138,7 @@ impl SeedableRng for IsaacRng { where S: TryRngCore + ?Sized, { - BlockRng::::try_from_rng(rng).map(IsaacRng) + IsaacCore::try_from_rng(rng).map(|core| IsaacRng(BlockRng::new(core))) } } @@ -174,9 +173,8 @@ impl ::core::cmp::PartialEq for IsaacCore { // Custom Eq implementation as it can't currently be derived from an array of size RAND_SIZE impl ::core::cmp::Eq for IsaacCore {} -impl BlockRngCore for IsaacCore { - type Item = u32; - type Results = IsaacArray; +impl Generator for IsaacCore { + type Output = [u32; RAND_SIZE]; /// Refills the output buffer, `results`. See also the pseudocode description /// of the algorithm in the `IsaacRng` documentation. @@ -198,7 +196,7 @@ impl BlockRngCore for IsaacCore { /// make `fill_bytes` a memcopy. To maintain compatibility we fill in /// reverse. #[rustfmt::skip] - fn generate(&mut self, results: &mut IsaacArray) { + fn generate(&mut self, results: &mut [u32; RAND_SIZE]) { self.c += w(1); // abbreviations let mut a = self.a; diff --git a/rand_isaac/src/isaac64.rs b/rand_isaac/src/isaac64.rs index 713cf0df..174c8e5d 100644 --- a/rand_isaac/src/isaac64.rs +++ b/rand_isaac/src/isaac64.rs @@ -9,10 +9,9 @@ //! The ISAAC-64 random number generator. -use crate::isaac_array::IsaacArray; use core::num::Wrapping as w; use core::{fmt, slice}; -use rand_core::block::{BlockRng64, BlockRngCore}; +use rand_core::block::{BlockRng, Generator}; use rand_core::{RngCore, SeedableRng, TryRngCore, le}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -70,7 +69,7 @@ const RAND_SIZE: usize = 1 << RAND_SIZE_LEN; /// } /// ``` /// -/// This implementation uses [`BlockRng64`] to implement the [`RngCore`] methods. +/// This implementation uses [`BlockRng`] to implement the [`RngCore`] methods. /// /// See for more information the documentation of [`IsaacRng`]. /// @@ -79,20 +78,20 @@ const RAND_SIZE: usize = 1 << RAND_SIZE_LEN; /// /// [`IsaacRng`]: crate::isaac::IsaacRng /// [`rand_hc`]: https://docs.rs/rand_hc -/// [`BlockRng64`]: rand_core::block::BlockRng64 +/// [`BlockRng`]: rand_core::block::BlockRng #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Isaac64Rng(BlockRng64); +pub struct Isaac64Rng(BlockRng); impl RngCore for Isaac64Rng { #[inline] fn next_u32(&mut self) -> u32 { - self.0.next_u32() + self.0.next_word() as u32 } #[inline] fn next_u64(&mut self) -> u64 { - self.0.next_u64() + self.0.next_word() } #[inline] @@ -106,7 +105,7 @@ impl SeedableRng for Isaac64Rng { #[inline] fn from_seed(seed: Self::Seed) -> Self { - Isaac64Rng(BlockRng64::::from_seed(seed)) + Isaac64Rng(BlockRng::new(Isaac64Core::from_seed(seed))) } /// Create an ISAAC random number generator using an `u64` as seed. @@ -114,7 +113,7 @@ impl SeedableRng for Isaac64Rng { /// the reference implementation when used unseeded. #[inline] fn seed_from_u64(seed: u64) -> Self { - Isaac64Rng(BlockRng64::::seed_from_u64(seed)) + Isaac64Rng(BlockRng::new(Isaac64Core::seed_from_u64(seed))) } #[inline] @@ -122,7 +121,7 @@ impl SeedableRng for Isaac64Rng { where R: RngCore + ?Sized, { - Isaac64Rng(BlockRng64::::from_rng(rng)) + Isaac64Rng(BlockRng::new(Isaac64Core::from_rng(rng))) } #[inline] @@ -130,7 +129,7 @@ impl SeedableRng for Isaac64Rng { where S: TryRngCore + ?Sized, { - BlockRng64::::try_from_rng(rng).map(Isaac64Rng) + Isaac64Core::try_from_rng(rng).map(|core| Isaac64Rng(BlockRng::new(core))) } } @@ -165,9 +164,8 @@ impl ::core::cmp::PartialEq for Isaac64Core { // Custom Eq implementation as it can't currently be derived from an array of size RAND_SIZE impl ::core::cmp::Eq for Isaac64Core {} -impl BlockRngCore for Isaac64Core { - type Item = u64; - type Results = IsaacArray; +impl Generator for Isaac64Core { + type Output = [u64; RAND_SIZE]; /// Refills the output buffer, `results`. See also the pseudocode description /// of the algorithm in the `Isaac64Rng` documentation. @@ -189,7 +187,7 @@ impl BlockRngCore for Isaac64Core { /// make `fill_bytes` a memcopy. To maintain compatibility we fill in /// reverse. #[rustfmt::skip] - fn generate(&mut self, results: &mut IsaacArray) { + fn generate(&mut self, results: &mut [u64; RAND_SIZE]) { self.c += w(1); // abbreviations let mut a = self.a; @@ -457,8 +455,8 @@ mod test { } // Subset of above values, as an LE u32 sequence let expected = [ - 3477963620, 3509106075, 687845478, 1797495790, 227048253, 2523132918, 4044335064, - 1260557630, 4079741768, 3001306521, 69157722, 3958365844, + 3477963620, 687845478, 227048253, 4044335064, 4079741768, 69157722, 3912394646, + 1204022051, 2459090310, 2151271855, 384864925, 1183723065, ]; assert_eq!(results, expected); } @@ -475,12 +473,12 @@ mod test { // `test_isaac64_true_values_32`. assert_eq!(rng.next_u64(), 15071495833797886820); assert_eq!(rng.next_u32(), 687845478); - assert_eq!(rng.next_u32(), 1797495790); - assert_eq!(rng.next_u64(), 10836773366498097981); - assert_eq!(rng.next_u32(), 4044335064); + assert_eq!(rng.next_u32(), 227048253); + assert_eq!(rng.next_u64(), 5414053799617603544); + assert_eq!(rng.next_u32(), 4079741768); // Skip one u32 - assert_eq!(rng.next_u64(), 12890513357046278984); - assert_eq!(rng.next_u32(), 69157722); + assert_eq!(rng.next_u64(), 17001051845652595546); + assert_eq!(rng.next_u32(), 3912394646); } #[test] diff --git a/rand_isaac/src/isaac_array.rs b/rand_isaac/src/isaac_array.rs deleted file mode 100644 index afa5a160..00000000 --- a/rand_isaac/src/isaac_array.rs +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2018 Developers of the Rand project. -// Copyright 2017-2018 The Rust Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! ISAAC helper functions for 256-element arrays. - -// Terrible workaround because arrays with more than 32 elements do not -// implement `AsRef`, `Default`, `Serialize`, `Deserialize`, or any other -// traits for that matter. - -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - -const RAND_SIZE_LEN: usize = 8; -const RAND_SIZE: usize = 1 << RAND_SIZE_LEN; - -#[derive(Copy, Clone)] -#[allow(missing_debug_implementations)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct IsaacArray { - #[cfg_attr(feature = "serde", serde(with = "isaac_array_serde"))] - #[cfg_attr( - feature = "serde", - serde(bound( - serialize = "T: Serialize", - deserialize = "T: Deserialize<'de> + Copy + Default" - )) - )] - inner: [T; RAND_SIZE], -} - -impl ::core::convert::AsRef<[T]> for IsaacArray { - #[inline(always)] - fn as_ref(&self) -> &[T] { - &self.inner[..] - } -} - -impl ::core::convert::AsMut<[T]> for IsaacArray { - #[inline(always)] - fn as_mut(&mut self) -> &mut [T] { - &mut self.inner[..] - } -} - -impl ::core::ops::Deref for IsaacArray { - type Target = [T; RAND_SIZE]; - #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl ::core::ops::DerefMut for IsaacArray { - #[inline(always)] - fn deref_mut(&mut self) -> &mut [T; RAND_SIZE] { - &mut self.inner - } -} - -impl ::core::default::Default for IsaacArray -where - T: Copy + Default, -{ - fn default() -> IsaacArray { - IsaacArray { - inner: [T::default(); RAND_SIZE], - } - } -} - -// Custom PartialEq implementation as it can't currently be derived from an array of size RAND_SIZE -impl ::core::cmp::PartialEq for IsaacArray -where - T: PartialEq, -{ - fn eq(&self, other: &IsaacArray) -> bool { - self.inner[..] == other.inner[..] - } -} - -// Custom Eq implementation as it can't currently be derived from an array of size RAND_SIZE -impl ::core::cmp::Eq for IsaacArray where T: Eq {} - -#[cfg(feature = "serde")] -pub(super) mod isaac_array_serde { - const RAND_SIZE_LEN: usize = 8; - const RAND_SIZE: usize = 1 << RAND_SIZE_LEN; - - use serde::de; - use serde::de::{SeqAccess, Visitor}; - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - - use core::fmt; - - pub fn serialize(arr: &[T; RAND_SIZE], ser: S) -> Result - where - T: Serialize, - S: Serializer, - { - use serde::ser::SerializeTuple; - - let mut seq = ser.serialize_tuple(RAND_SIZE)?; - - for e in arr.iter() { - seq.serialize_element(&e)?; - } - - seq.end() - } - - #[inline] - pub fn deserialize<'de, T, D>(de: D) -> Result<[T; RAND_SIZE], D::Error> - where - T: Deserialize<'de> + Default + Copy, - D: Deserializer<'de>, - { - use core::marker::PhantomData; - struct ArrayVisitor { - _pd: PhantomData, - } - impl<'de, T> Visitor<'de> for ArrayVisitor - where - T: Deserialize<'de> + Default + Copy, - { - type Value = [T; RAND_SIZE]; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("Isaac state array") - } - - #[inline] - fn visit_seq(self, mut seq: A) -> Result<[T; RAND_SIZE], A::Error> - where - A: SeqAccess<'de>, - { - let mut out = [Default::default(); RAND_SIZE]; - - for i in 0..RAND_SIZE { - match seq.next_element()? { - Some(val) => out[i] = val, - None => return Err(de::Error::invalid_length(i, &self)), - }; - } - - Ok(out) - } - } - - de.deserialize_tuple(RAND_SIZE, ArrayVisitor { _pd: PhantomData }) - } -} diff --git a/rand_isaac/src/lib.rs b/rand_isaac/src/lib.rs index 2f00d608..ca5524e9 100644 --- a/rand_isaac/src/lib.rs +++ b/rand_isaac/src/lib.rs @@ -27,7 +27,5 @@ pub mod isaac; pub mod isaac64; -mod isaac_array; - pub use self::isaac::IsaacRng; pub use self::isaac64::Isaac64Rng;