From 83061f63e1d1064976a954a9aa0b0c0b0c46a09c Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Tue, 4 Jun 2024 11:15:12 +0100 Subject: [PATCH] Update to rand master (#53) Temporarily, we patch this repo to use rand from git. Not ideal, but: - It lets us get this code (mostly) ready for the next rand version now - Lets us test the rand_core changes - Allows us to move rand_pcg here, if we want to (possibly not; it is used by benches in the rand repo) --- .github/workflows/benches.yml | 4 +- Cargo.toml | 4 + benches/Cargo.toml | 6 +- benches/mod.rs | 94 ++++++++++++------------ rand_hc/Cargo.toml | 2 +- rand_hc/src/hc128.rs | 22 +++--- rand_isaac/Cargo.toml | 2 +- rand_isaac/src/isaac.rs | 39 +++++++--- rand_isaac/src/isaac64.rs | 38 +++++++--- rand_jitter/Cargo.toml | 2 +- rand_jitter/src/error.rs | 16 ---- rand_jitter/src/lib.rs | 64 +++++++++------- rand_xorshift/Cargo.toml | 2 +- rand_xorshift/src/lib.rs | 30 ++++++-- rand_xorshift/tests/mod.rs | 2 +- rand_xoshiro/Cargo.toml | 2 +- rand_xoshiro/src/common.rs | 2 +- rand_xoshiro/src/splitmix64.rs | 10 +-- rand_xoshiro/src/xoroshiro128plus.rs | 8 +- rand_xoshiro/src/xoroshiro128plusplus.rs | 8 +- rand_xoshiro/src/xoroshiro128starstar.rs | 8 +- rand_xoshiro/src/xoroshiro64star.rs | 8 +- rand_xoshiro/src/xoroshiro64starstar.rs | 8 +- rand_xoshiro/src/xoshiro128plus.rs | 10 +-- rand_xoshiro/src/xoshiro128plusplus.rs | 10 +-- rand_xoshiro/src/xoshiro128starstar.rs | 10 +-- rand_xoshiro/src/xoshiro256plus.rs | 10 +-- rand_xoshiro/src/xoshiro256plusplus.rs | 10 +-- rand_xoshiro/src/xoshiro256starstar.rs | 10 +-- rand_xoshiro/src/xoshiro512plus.rs | 10 +-- rand_xoshiro/src/xoshiro512plusplus.rs | 10 +-- rand_xoshiro/src/xoshiro512starstar.rs | 10 +-- 32 files changed, 233 insertions(+), 238 deletions(-) diff --git a/.github/workflows/benches.yml b/.github/workflows/benches.yml index f0112ec8..7ef65c21 100644 --- a/.github/workflows/benches.yml +++ b/.github/workflows/benches.yml @@ -18,9 +18,9 @@ jobs: with: toolchain: nightly components: clippy, rustfmt + - name: Build + run: RUSTFLAGS=-Dwarnings cargo build --all-targets - name: Rustfmt run: cargo fmt -- --check - name: Clippy run: cargo clippy --all-targets -- -D warnings - - name: Build - run: RUSTFLAGS=-Dwarnings cargo build --all-targets diff --git a/Cargo.toml b/Cargo.toml index f9cc4350..6f553265 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,7 @@ exclude = [ "benches", ] resolver = "2" + +[patch.crates-io.rand_core] +git = "https://github.com/rust-random/rand.git" +branch = "master" diff --git a/benches/Cargo.toml b/benches/Cargo.toml index a9909689..27a95696 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dev-dependencies] criterion = "0.5.0" criterion-cycles-per-byte = "0.6" -rand_core = { version = "0.6.4", features = ["getrandom"] } +rand_core = { version = "=0.9.0-alpha.1", features = ["getrandom"] } rand_xoshiro = { path = "../rand_xoshiro", version = "0.6" } rand_isaac = { path = "../rand_isaac", version = "0.3" } rand_xorshift = { path = "../rand_xorshift", version = "0.3" } @@ -18,3 +18,7 @@ rand_hc = { path = "../rand_hc", version = "0.3" } name = "mod" path = "mod.rs" harness = false + +[patch.crates-io.rand_core] +git = "https://github.com/rust-random/rand.git" +branch = "master" diff --git a/benches/mod.rs b/benches/mod.rs index 216224ae..7a4ce084 100644 --- a/benches/mod.rs +++ b/benches/mod.rs @@ -49,21 +49,21 @@ fn gen_bytes(c: &mut Criterion) { }; } - gen_bytes!("xorshift", XorShiftRng::from_entropy()); - gen_bytes!("xoshiro256starstar", Xoshiro256StarStar::from_entropy()); - gen_bytes!("xoshiro256plus", Xoshiro256Plus::from_entropy()); - gen_bytes!("xoshiro256plusplus", Xoshiro256PlusPlus::from_entropy()); - gen_bytes!("xoshiro128starstar", Xoshiro128StarStar::from_entropy()); - gen_bytes!("xoshiro128plus", Xoshiro128Plus::from_entropy()); - gen_bytes!("xoshiro128plusplus", Xoshiro128PlusPlus::from_entropy()); - gen_bytes!("xoroshiro128starstar", Xoroshiro128StarStar::from_entropy()); - gen_bytes!("xoroshiro128plus", Xoroshiro128Plus::from_entropy()); - gen_bytes!("xoroshiro64starstar", Xoroshiro64StarStar::from_entropy()); - gen_bytes!("xoroshiro64star", Xoroshiro64Star::from_entropy()); - gen_bytes!("splitmix64", SplitMix64::from_entropy()); - gen_bytes!("hc128", Hc128Rng::from_entropy()); - gen_bytes!("isaac", IsaacRng::from_entropy()); - gen_bytes!("isaac64", Isaac64Rng::from_entropy()); + gen_bytes!("xorshift", XorShiftRng::from_os_rng()); + gen_bytes!("xoshiro256starstar", Xoshiro256StarStar::from_os_rng()); + gen_bytes!("xoshiro256plus", Xoshiro256Plus::from_os_rng()); + gen_bytes!("xoshiro256plusplus", Xoshiro256PlusPlus::from_os_rng()); + gen_bytes!("xoshiro128starstar", Xoshiro128StarStar::from_os_rng()); + gen_bytes!("xoshiro128plus", Xoshiro128Plus::from_os_rng()); + gen_bytes!("xoshiro128plusplus", Xoshiro128PlusPlus::from_os_rng()); + gen_bytes!("xoroshiro128starstar", Xoroshiro128StarStar::from_os_rng()); + gen_bytes!("xoroshiro128plus", Xoroshiro128Plus::from_os_rng()); + gen_bytes!("xoroshiro64starstar", Xoroshiro64StarStar::from_os_rng()); + gen_bytes!("xoroshiro64star", Xoroshiro64Star::from_os_rng()); + gen_bytes!("splitmix64", SplitMix64::from_os_rng()); + gen_bytes!("hc128", Hc128Rng::from_os_rng()); + gen_bytes!("isaac", IsaacRng::from_os_rng()); + gen_bytes!("isaac64", Isaac64Rng::from_os_rng()); } // Save a dependency on Rand: @@ -105,102 +105,102 @@ fn gen_uint(c: &mut Criterion) { let mut g = c.benchmark_group("gen_u32"); g.throughput(Throughput::Bytes(size_of::() as u64 * RAND_BENCH_N)); - gen_uint!(g, "xorshift", u32, XorShiftRng::from_entropy()); + gen_uint!(g, "xorshift", u32, XorShiftRng::from_os_rng()); gen_uint!( g, "xoshiro256starstar", u32, - Xoshiro256StarStar::from_entropy() + Xoshiro256StarStar::from_os_rng() ); - gen_uint!(g, "xoshiro256plus", u32, Xoshiro256Plus::from_entropy()); + gen_uint!(g, "xoshiro256plus", u32, Xoshiro256Plus::from_os_rng()); gen_uint!( g, "xoshiro256plusplus", u32, - Xoshiro256PlusPlus::from_entropy() + Xoshiro256PlusPlus::from_os_rng() ); gen_uint!( g, "xoshiro128starstar", u32, - Xoshiro128StarStar::from_entropy() + Xoshiro128StarStar::from_os_rng() ); - gen_uint!(g, "xoshiro128plus", u32, Xoshiro128Plus::from_entropy()); + gen_uint!(g, "xoshiro128plus", u32, Xoshiro128Plus::from_os_rng()); gen_uint!( g, "xoshiro128plusplus", u32, - Xoshiro128PlusPlus::from_entropy() + Xoshiro128PlusPlus::from_os_rng() ); gen_uint!( g, "xoroshiro128starstar", u32, - Xoroshiro128StarStar::from_entropy() + Xoroshiro128StarStar::from_os_rng() ); - gen_uint!(g, "xoroshiro128plus", u32, Xoroshiro128Plus::from_entropy()); + gen_uint!(g, "xoroshiro128plus", u32, Xoroshiro128Plus::from_os_rng()); gen_uint!( g, "xoroshiro64starstar", u32, - Xoroshiro64StarStar::from_entropy() + Xoroshiro64StarStar::from_os_rng() ); - gen_uint!(g, "xoroshiro64star", u32, Xoroshiro64Star::from_entropy()); - gen_uint!(g, "splitmix64", u32, SplitMix64::from_entropy()); - gen_uint!(g, "hc128", u32, Hc128Rng::from_entropy()); - gen_uint!(g, "isaac", u32, IsaacRng::from_entropy()); - gen_uint!(g, "isaac64", u32, Isaac64Rng::from_entropy()); + gen_uint!(g, "xoroshiro64star", u32, Xoroshiro64Star::from_os_rng()); + gen_uint!(g, "splitmix64", u32, SplitMix64::from_os_rng()); + gen_uint!(g, "hc128", u32, Hc128Rng::from_os_rng()); + gen_uint!(g, "isaac", u32, IsaacRng::from_os_rng()); + gen_uint!(g, "isaac64", u32, Isaac64Rng::from_os_rng()); } { let mut g = c.benchmark_group("gen_u64"); g.throughput(Throughput::Bytes(size_of::() as u64 * RAND_BENCH_N)); - gen_uint!(g, "xorshift", u64, XorShiftRng::from_entropy()); + gen_uint!(g, "xorshift", u64, XorShiftRng::from_os_rng()); gen_uint!( g, "xoshiro256starstar", u64, - Xoshiro256StarStar::from_entropy() + Xoshiro256StarStar::from_os_rng() ); - gen_uint!(g, "xoshiro256plus", u64, Xoshiro256Plus::from_entropy()); + gen_uint!(g, "xoshiro256plus", u64, Xoshiro256Plus::from_os_rng()); gen_uint!( g, "xoshiro256plusplus", u64, - Xoshiro256PlusPlus::from_entropy() + Xoshiro256PlusPlus::from_os_rng() ); gen_uint!( g, "xoshiro128starstar", u64, - Xoshiro128StarStar::from_entropy() + Xoshiro128StarStar::from_os_rng() ); - gen_uint!(g, "xoshiro128plus", u64, Xoshiro128Plus::from_entropy()); + gen_uint!(g, "xoshiro128plus", u64, Xoshiro128Plus::from_os_rng()); gen_uint!( g, "xoshiro128plusplus", u64, - Xoshiro128PlusPlus::from_entropy() + Xoshiro128PlusPlus::from_os_rng() ); gen_uint!( g, "xoroshiro128starstar", u64, - Xoroshiro128StarStar::from_entropy() + Xoroshiro128StarStar::from_os_rng() ); - gen_uint!(g, "xoroshiro128plus", u64, Xoroshiro128Plus::from_entropy()); + gen_uint!(g, "xoroshiro128plus", u64, Xoroshiro128Plus::from_os_rng()); gen_uint!( g, "xoroshiro64starstar", u64, - Xoroshiro64StarStar::from_entropy() + Xoroshiro64StarStar::from_os_rng() ); - gen_uint!(g, "xoroshiro64star", u64, Xoroshiro64Star::from_entropy()); - gen_uint!(g, "splitmix64", u64, SplitMix64::from_entropy()); - gen_uint!(g, "hc128", u64, Hc128Rng::from_entropy()); - gen_uint!(g, "isaac", u64, IsaacRng::from_entropy()); - gen_uint!(g, "isaac64", u64, Isaac64Rng::from_entropy()); + gen_uint!(g, "xoroshiro64star", u64, Xoroshiro64Star::from_os_rng()); + gen_uint!(g, "splitmix64", u64, SplitMix64::from_os_rng()); + gen_uint!(g, "hc128", u64, Hc128Rng::from_os_rng()); + gen_uint!(g, "isaac", u64, IsaacRng::from_os_rng()); + gen_uint!(g, "isaac64", u64, Isaac64Rng::from_os_rng()); } } @@ -210,8 +210,8 @@ fn init(c: &mut Criterion) { macro_rules! init_gen { ($fnn:expr, $gen:ident) => { g.bench_function($fnn, |b| { - let mut rng = XorShiftRng::from_entropy(); - b.iter(|| $gen::from_rng(black_box(&mut rng)).unwrap()) + let mut rng = XorShiftRng::from_os_rng(); + b.iter(|| $gen::from_rng(black_box(&mut rng))) }); }; } diff --git a/rand_hc/Cargo.toml b/rand_hc/Cargo.toml index 299af921..6b5420b5 100644 --- a/rand_hc/Cargo.toml +++ b/rand_hc/Cargo.toml @@ -16,4 +16,4 @@ edition = "2021" rust-version = "1.61" [dependencies] -rand_core = "0.6" +rand_core = "=0.9.0-alpha.1" diff --git a/rand_hc/src/hc128.rs b/rand_hc/src/hc128.rs index 3fed9484..6438ad22 100644 --- a/rand_hc/src/hc128.rs +++ b/rand_hc/src/hc128.rs @@ -15,8 +15,8 @@ //! The HC-128 random number generator. use core::fmt; -use rand_core::block::{BlockRng, BlockRngCore}; -use rand_core::{le, CryptoRng, Error, RngCore, SeedableRng}; +use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng}; +use rand_core::{le, CryptoRng, RngCore, SeedableRng, TryRngCore}; const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv @@ -87,13 +87,10 @@ impl RngCore for Hc128Rng { fn fill_bytes(&mut self, dest: &mut [u8]) { self.0.fill_bytes(dest) } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.0.try_fill_bytes(dest) - } } +rand_core::impl_try_crypto_rng_from_crypto_rng!(Hc128Rng); + impl SeedableRng for Hc128Rng { type Seed = ::Seed; @@ -103,8 +100,13 @@ impl SeedableRng for Hc128Rng { } #[inline] - fn from_rng(rng: R) -> Result { - BlockRng::::from_rng(rng).map(Hc128Rng) + fn from_rng(rng: impl RngCore) -> Self { + Hc128Rng(BlockRng::::from_rng(rng)) + } + + #[inline] + fn try_from_rng(rng: R) -> Result { + BlockRng::::try_from_rng(rng).map(Hc128Rng) } } @@ -352,7 +354,7 @@ impl SeedableRng for Hc128Core { } } -impl CryptoRng for Hc128Core {} +impl CryptoBlockRng 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 1db5307b..8e5688e0 100644 --- a/rand_isaac/Cargo.toml +++ b/rand_isaac/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.61" serde1 = ["serde", "rand_core/serde1"] [dependencies] -rand_core = { version = "0.6" } +rand_core = { version = "=0.9.0-alpha.1" } serde = { version = "1.0.103", features = ["derive"], optional = true } # Not a direct dependency but required to boost the minimum version: serde_derive = { version = "1.0.103", optional = true } diff --git a/rand_isaac/src/isaac.rs b/rand_isaac/src/isaac.rs index 4e51e8ab..5ed0a967 100644 --- a/rand_isaac/src/isaac.rs +++ b/rand_isaac/src/isaac.rs @@ -13,7 +13,7 @@ use crate::isaac_array::IsaacArray; use core::num::Wrapping as w; use core::{fmt, slice}; use rand_core::block::{BlockRng, BlockRngCore}; -use rand_core::{le, Error, RngCore, SeedableRng}; +use rand_core::{le, RngCore, SeedableRng, TryRngCore}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -108,13 +108,10 @@ impl RngCore for IsaacRng { fn fill_bytes(&mut self, dest: &mut [u8]) { self.0.fill_bytes(dest) } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.0.try_fill_bytes(dest) - } } +rand_core::impl_try_rng_from_rng_core!(IsaacRng); + impl SeedableRng for IsaacRng { type Seed = ::Seed; @@ -132,8 +129,13 @@ impl SeedableRng for IsaacRng { } #[inline] - fn from_rng(rng: S) -> Result { - BlockRng::::from_rng(rng).map(IsaacRng) + fn from_rng(rng: impl RngCore) -> Self { + IsaacRng(BlockRng::::from_rng(rng)) + } + + #[inline] + fn try_from_rng(rng: S) -> Result { + BlockRng::::try_from_rng(rng).map(IsaacRng) } } @@ -365,7 +367,24 @@ impl SeedableRng for IsaacCore { Self::init(key, 1) } - fn from_rng(mut rng: R) -> Result { + fn from_rng(mut rng: impl RngCore) -> Self { + // Custom `from_rng` implementation that fills a seed with the same size + // as the entire state. + let mut seed = [w(0u32); RAND_SIZE]; + unsafe { + let ptr = seed.as_mut_ptr() as *mut u8; + + let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE * 4); + rng.fill_bytes(slice); + } + for i in seed.iter_mut() { + *i = w(i.0.to_le()); + } + + Self::init(seed, 2) + } + + fn try_from_rng(mut rng: R) -> Result { // Custom `from_rng` implementation that fills a seed with the same size // as the entire state. let mut seed = [w(0u32); RAND_SIZE]; @@ -398,7 +417,7 @@ mod test { let mut rng1 = IsaacRng::from_seed(seed); assert_eq!(rng1.next_u32(), 2869442790); - let mut rng2 = IsaacRng::from_rng(rng1).unwrap(); + let mut rng2 = IsaacRng::from_rng(rng1); assert_eq!(rng2.next_u32(), 3094074039); } diff --git a/rand_isaac/src/isaac64.rs b/rand_isaac/src/isaac64.rs index e5511e79..3cb59e4c 100644 --- a/rand_isaac/src/isaac64.rs +++ b/rand_isaac/src/isaac64.rs @@ -13,7 +13,7 @@ use crate::isaac_array::IsaacArray; use core::num::Wrapping as w; use core::{fmt, slice}; use rand_core::block::{BlockRng64, BlockRngCore}; -use rand_core::{le, Error, RngCore, SeedableRng}; +use rand_core::{le, RngCore, SeedableRng, TryRngCore}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -99,13 +99,10 @@ impl RngCore for Isaac64Rng { fn fill_bytes(&mut self, dest: &mut [u8]) { self.0.fill_bytes(dest) } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.0.try_fill_bytes(dest) - } } +rand_core::impl_try_rng_from_rng_core!(Isaac64Rng); + impl SeedableRng for Isaac64Rng { type Seed = ::Seed; @@ -123,8 +120,13 @@ impl SeedableRng for Isaac64Rng { } #[inline] - fn from_rng(rng: S) -> Result { - BlockRng64::::from_rng(rng).map(Isaac64Rng) + fn from_rng(rng: impl RngCore) -> Self { + Isaac64Rng(BlockRng64::::from_rng(rng)) + } + + #[inline] + fn try_from_rng(rng: S) -> Result { + BlockRng64::::try_from_rng(rng).map(Isaac64Rng) } } @@ -327,7 +329,23 @@ impl SeedableRng for Isaac64Core { Self::init(key, 1) } - fn from_rng(mut rng: R) -> Result { + fn from_rng(mut rng: impl RngCore) -> Self { + // Custom `from_rng` implementation that fills a seed with the same size + // as the entire state. + let mut seed = [w(0u64); RAND_SIZE]; + unsafe { + let ptr = seed.as_mut_ptr() as *mut u8; + let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE * 8); + rng.fill_bytes(slice); + } + for i in seed.iter_mut() { + *i = w(i.0.to_le()); + } + + Self::init(seed, 2) + } + + fn try_from_rng(mut rng: R) -> Result { // Custom `from_rng` implementation that fills a seed with the same size // as the entire state. let mut seed = [w(0u64); RAND_SIZE]; @@ -359,7 +377,7 @@ mod test { let mut rng1 = Isaac64Rng::from_seed(seed); assert_eq!(rng1.next_u64(), 14964555543728284049); - let mut rng2 = Isaac64Rng::from_rng(rng1).unwrap(); + let mut rng2 = Isaac64Rng::from_rng(rng1); assert_eq!(rng2.next_u64(), 919595328260451758); } diff --git a/rand_jitter/Cargo.toml b/rand_jitter/Cargo.toml index 2fae4412..22c9b83d 100644 --- a/rand_jitter/Cargo.toml +++ b/rand_jitter/Cargo.toml @@ -16,7 +16,7 @@ std = ["rand_core/std"] log = ["dep:log"] [dependencies] -rand_core = { version = "0.6" } +rand_core = { version = "=0.9.0-alpha.1" } log = { version = "0.4.4", optional = true } [target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] diff --git a/rand_jitter/src/error.rs b/rand_jitter/src/error.rs index 3b1267cf..883cc648 100644 --- a/rand_jitter/src/error.rs +++ b/rand_jitter/src/error.rs @@ -8,7 +8,6 @@ // except according to those terms. use core::fmt; -use rand_core::Error; /// Base code for all `JitterRng` errors const ERROR_BASE: u32 = 0xAE53_0400; @@ -63,18 +62,3 @@ impl ::std::error::Error for TimerError { self.description() } } - -impl From for Error { - fn from(err: TimerError) -> Error { - // Timer check is already quite permissive of failures so we don't - // expect false-positive failures, i.e. any error is irrecoverable. - #[cfg(feature = "std")] - { - Error::new(err) - } - #[cfg(not(feature = "std"))] - { - Error::from(core::num::NonZeroU32::new(err as u32).unwrap()) - } - } -} diff --git a/rand_jitter/src/lib.rs b/rand_jitter/src/lib.rs index 6c80b531..21ce9e9e 100644 --- a/rand_jitter/src/lib.rs +++ b/rand_jitter/src/lib.rs @@ -107,7 +107,7 @@ mod error; mod platform; pub use crate::error::TimerError; -use rand_core::{impls, Error, RngCore}; +use rand_core::{impls, RngCore}; use core::{fmt, mem, ptr}; #[cfg(feature = "std")] @@ -260,32 +260,26 @@ where /// # Example /// /// ``` - /// # use rand_jitter::rand_core::{RngCore, Error}; - /// use rand_jitter::JitterRng; + /// use rand_jitter::{JitterRng, TimerError}; /// - /// # fn try_inner() -> Result<(), Error> { - /// fn get_nstime() -> u64 { - /// use std::time::{SystemTime, UNIX_EPOCH}; + /// fn make_jitter_rng() -> Result u64 + Send + Sync>, TimerError> { + /// fn get_nstime() -> u64 { + /// use std::time::{SystemTime, UNIX_EPOCH}; /// - /// let dur = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); - /// // The correct way to calculate the current time is - /// // `dur.as_secs() * 1_000_000_000 + dur.subsec_nanos() as u64` - /// // But this is faster, and the difference in terms of entropy is - /// // negligible (log2(10^9) == 29.9). - /// dur.as_secs() << 30 | dur.subsec_nanos() as u64 - /// } - /// - /// let mut rng = JitterRng::new_with_timer(get_nstime); - /// let rounds = rng.test_timer()?; - /// rng.set_rounds(rounds); // optional - /// let _ = rng.next_u64(); + /// let dur = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + /// // The correct way to calculate the current time is + /// // `dur.as_secs() * 1_000_000_000 + dur.subsec_nanos() as u64` + /// // But this is faster, and the difference in terms of entropy is + /// // negligible (log2(10^9) == 29.9). + /// dur.as_secs() << 30 | dur.subsec_nanos() as u64 + /// } /// - /// // Ready for use - /// let v: u64 = rng.next_u64(); - /// # Ok(()) - /// # } - /// - /// # let _ = try_inner(); + /// let mut rng = JitterRng::new_with_timer(get_nstime); + /// let rounds = rng.test_timer()?; + /// rng.set_rounds(rounds); // optional + /// Ok(rng) + /// } + /// # let _rng = make_jitter_rng(); /// ``` /// /// [`test_timer`]: JitterRng::test_timer @@ -769,9 +763,27 @@ where // themselves via `fill_bytes`. impls::fill_bytes_via_next(self, dest) } +} + +impl rand_core::TryRngCore for JitterRng +where + F: Fn() -> u64 + Send + Sync, +{ + type Error = core::convert::Infallible; + + #[inline] + fn try_next_u32(&mut self) -> Result { + Ok(rand_core::RngCore::next_u32(self)) + } + + #[inline] + fn try_next_u64(&mut self) -> Result { + Ok(rand_core::RngCore::next_u64(self)) + } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); + #[inline] + fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Self::Error> { + rand_core::RngCore::fill_bytes(self, dst); Ok(()) } } diff --git a/rand_xorshift/Cargo.toml b/rand_xorshift/Cargo.toml index aeccd7c0..ae26996e 100644 --- a/rand_xorshift/Cargo.toml +++ b/rand_xorshift/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.61" serde1 = ["serde"] [dependencies] -rand_core = { version = "0.6" } +rand_core = { version = "=0.9.0-alpha.1" } serde = { version = "1.0.118", default-features = false, features = ["derive"], optional = true } [dev-dependencies] diff --git a/rand_xorshift/src/lib.rs b/rand_xorshift/src/lib.rs index b240d1bc..e725db06 100644 --- a/rand_xorshift/src/lib.rs +++ b/rand_xorshift/src/lib.rs @@ -32,7 +32,7 @@ use core::fmt; use core::num::Wrapping as w; -use rand_core::{impls, le, Error, RngCore, SeedableRng}; +use rand_core::{impls, le, RngCore, SeedableRng, TryRngCore}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -90,13 +90,10 @@ impl RngCore for XorShiftRng { fn fill_bytes(&mut self, dest: &mut [u8]) { impls::fill_bytes_via_next(self, dest) } - - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(XorShiftRng); + impl SeedableRng for XorShiftRng { type Seed = [u8; 16]; @@ -119,10 +116,27 @@ impl SeedableRng for XorShiftRng { } } - fn from_rng(mut rng: R) -> Result { + fn from_rng(mut rng: impl RngCore) -> Self { + let mut b = [0u8; 16]; + loop { + rng.fill_bytes(b.as_mut()); + if b != [0; 16] { + break; + } + } + + XorShiftRng { + x: w(u32::from_le_bytes([b[0], b[1], b[2], b[3]])), + y: w(u32::from_le_bytes([b[4], b[5], b[6], b[7]])), + z: w(u32::from_le_bytes([b[8], b[9], b[10], b[11]])), + w: w(u32::from_le_bytes([b[12], b[13], b[14], b[15]])), + } + } + + fn try_from_rng(mut rng: R) -> Result { let mut b = [0u8; 16]; loop { - rng.try_fill_bytes(&mut b[..])?; + rng.try_fill_bytes(b.as_mut())?; if b != [0; 16] { break; } diff --git a/rand_xorshift/tests/mod.rs b/rand_xorshift/tests/mod.rs index ba57d052..881e982e 100644 --- a/rand_xorshift/tests/mod.rs +++ b/rand_xorshift/tests/mod.rs @@ -8,7 +8,7 @@ fn test_xorshift_construction() { let mut rng1 = XorShiftRng::from_seed(seed); assert_eq!(rng1.next_u64(), 4325440999699518727); - let mut rng2 = XorShiftRng::from_rng(&mut rng1).unwrap(); + let mut rng2 = XorShiftRng::from_rng(&mut rng1); // Yes, this makes rng2 a clone of rng1! assert_eq!(rng1.next_u64(), 15614385950550801700); assert_eq!(rng2.next_u64(), 15614385950550801700); diff --git a/rand_xoshiro/Cargo.toml b/rand_xoshiro/Cargo.toml index 3d13fc3c..980799a8 100644 --- a/rand_xoshiro/Cargo.toml +++ b/rand_xoshiro/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.61" serde1 = ["serde"] [dependencies] -rand_core = { version = "0.6" } +rand_core = { version = "=0.9.0-alpha.1" } serde = { version = "1", features = ["derive"], optional=true } [dev-dependencies] diff --git a/rand_xoshiro/src/common.rs b/rand_xoshiro/src/common.rs index 5e9d8eaa..e5c63f4f 100644 --- a/rand_xoshiro/src/common.rs +++ b/rand_xoshiro/src/common.rs @@ -10,7 +10,7 @@ macro_rules! from_splitmix { ($seed:expr) => {{ let mut rng = crate::SplitMix64::seed_from_u64($seed); - Self::from_rng(&mut rng).unwrap() + Self::from_rng(&mut rng) }}; } diff --git a/rand_xoshiro/src/splitmix64.rs b/rand_xoshiro/src/splitmix64.rs index 2fdc9f21..88130c74 100644 --- a/rand_xoshiro/src/splitmix64.rs +++ b/rand_xoshiro/src/splitmix64.rs @@ -8,7 +8,7 @@ use rand_core::impls::fill_bytes_via_next; use rand_core::le::read_u64_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -57,14 +57,10 @@ impl RngCore for SplitMix64 { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(SplitMix64); + impl SeedableRng for SplitMix64 { type Seed = [u8; 8]; diff --git a/rand_xoshiro/src/xoroshiro128plus.rs b/rand_xoshiro/src/xoroshiro128plus.rs index 73a0a047..6655d3cc 100644 --- a/rand_xoshiro/src/xoroshiro128plus.rs +++ b/rand_xoshiro/src/xoroshiro128plus.rs @@ -78,14 +78,10 @@ impl RngCore for Xoroshiro128Plus { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoroshiro128Plus); + impl SeedableRng for Xoroshiro128Plus { type Seed = [u8; 16]; diff --git a/rand_xoshiro/src/xoroshiro128plusplus.rs b/rand_xoshiro/src/xoroshiro128plusplus.rs index 03d0ef4d..e90f3291 100644 --- a/rand_xoshiro/src/xoroshiro128plusplus.rs +++ b/rand_xoshiro/src/xoroshiro128plusplus.rs @@ -75,14 +75,10 @@ impl RngCore for Xoroshiro128PlusPlus { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoroshiro128PlusPlus); + impl SeedableRng for Xoroshiro128PlusPlus { type Seed = [u8; 16]; diff --git a/rand_xoshiro/src/xoroshiro128starstar.rs b/rand_xoshiro/src/xoroshiro128starstar.rs index eedae6e3..8c9e59fe 100644 --- a/rand_xoshiro/src/xoroshiro128starstar.rs +++ b/rand_xoshiro/src/xoroshiro128starstar.rs @@ -75,14 +75,10 @@ impl RngCore for Xoroshiro128StarStar { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoroshiro128StarStar); + impl SeedableRng for Xoroshiro128StarStar { type Seed = [u8; 16]; diff --git a/rand_xoshiro/src/xoroshiro64star.rs b/rand_xoshiro/src/xoroshiro64star.rs index 5cf557c5..99411420 100644 --- a/rand_xoshiro/src/xoroshiro64star.rs +++ b/rand_xoshiro/src/xoroshiro64star.rs @@ -46,14 +46,10 @@ impl RngCore for Xoroshiro64Star { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoroshiro64Star); + impl SeedableRng for Xoroshiro64Star { type Seed = [u8; 8]; diff --git a/rand_xoshiro/src/xoroshiro64starstar.rs b/rand_xoshiro/src/xoroshiro64starstar.rs index c5e87cf0..9e47fb41 100644 --- a/rand_xoshiro/src/xoroshiro64starstar.rs +++ b/rand_xoshiro/src/xoroshiro64starstar.rs @@ -45,14 +45,10 @@ impl RngCore for Xoroshiro64StarStar { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoroshiro64StarStar); + impl SeedableRng for Xoroshiro64StarStar { type Seed = [u8; 8]; diff --git a/rand_xoshiro/src/xoshiro128plus.rs b/rand_xoshiro/src/xoshiro128plus.rs index c5a92943..50e41617 100644 --- a/rand_xoshiro/src/xoshiro128plus.rs +++ b/rand_xoshiro/src/xoshiro128plus.rs @@ -8,7 +8,7 @@ use rand_core::impls::{fill_bytes_via_next, next_u64_via_u32}; use rand_core::le::read_u32_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -93,14 +93,8 @@ impl RngCore for Xoshiro128Plus { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } - +rand_core::impl_try_rng_from_rng_core!(Xoshiro128Plus); #[cfg(test)] mod tests { use super::*; diff --git a/rand_xoshiro/src/xoshiro128plusplus.rs b/rand_xoshiro/src/xoshiro128plusplus.rs index 28cb684f..eb222701 100644 --- a/rand_xoshiro/src/xoshiro128plusplus.rs +++ b/rand_xoshiro/src/xoshiro128plusplus.rs @@ -8,7 +8,7 @@ use rand_core::impls::{fill_bytes_via_next, next_u64_via_u32}; use rand_core::le::read_u32_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -92,14 +92,10 @@ impl RngCore for Xoshiro128PlusPlus { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoshiro128PlusPlus); + #[cfg(test)] mod tests { use super::*; diff --git a/rand_xoshiro/src/xoshiro128starstar.rs b/rand_xoshiro/src/xoshiro128starstar.rs index 10cc529f..f22d81b4 100644 --- a/rand_xoshiro/src/xoshiro128starstar.rs +++ b/rand_xoshiro/src/xoshiro128starstar.rs @@ -8,7 +8,7 @@ use rand_core::impls::{fill_bytes_via_next, next_u64_via_u32}; use rand_core::le::read_u32_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -92,14 +92,10 @@ impl RngCore for Xoshiro128StarStar { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoshiro128StarStar); + #[cfg(test)] mod tests { use super::*; diff --git a/rand_xoshiro/src/xoshiro256plus.rs b/rand_xoshiro/src/xoshiro256plus.rs index 124d1b2f..27cd0bca 100644 --- a/rand_xoshiro/src/xoshiro256plus.rs +++ b/rand_xoshiro/src/xoshiro256plus.rs @@ -8,7 +8,7 @@ use rand_core::impls::fill_bytes_via_next; use rand_core::le::read_u64_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -113,14 +113,10 @@ impl RngCore for Xoshiro256Plus { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoshiro256Plus); + #[cfg(test)] mod tests { use super::*; diff --git a/rand_xoshiro/src/xoshiro256plusplus.rs b/rand_xoshiro/src/xoshiro256plusplus.rs index d9b988bf..bc30e31c 100644 --- a/rand_xoshiro/src/xoshiro256plusplus.rs +++ b/rand_xoshiro/src/xoshiro256plusplus.rs @@ -8,7 +8,7 @@ use rand_core::impls::fill_bytes_via_next; use rand_core::le::read_u64_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -112,14 +112,10 @@ impl RngCore for Xoshiro256PlusPlus { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoshiro256PlusPlus); + #[cfg(test)] mod tests { use super::*; diff --git a/rand_xoshiro/src/xoshiro256starstar.rs b/rand_xoshiro/src/xoshiro256starstar.rs index 983bda4b..fb427977 100644 --- a/rand_xoshiro/src/xoshiro256starstar.rs +++ b/rand_xoshiro/src/xoshiro256starstar.rs @@ -8,7 +8,7 @@ use rand_core::impls::fill_bytes_via_next; use rand_core::le::read_u64_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -112,14 +112,10 @@ impl RngCore for Xoshiro256StarStar { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoshiro256StarStar); + #[cfg(test)] mod tests { use super::*; diff --git a/rand_xoshiro/src/xoshiro512plus.rs b/rand_xoshiro/src/xoshiro512plus.rs index cb83c705..c3e0a059 100644 --- a/rand_xoshiro/src/xoshiro512plus.rs +++ b/rand_xoshiro/src/xoshiro512plus.rs @@ -8,7 +8,7 @@ use rand_core::impls::fill_bytes_via_next; use rand_core::le::read_u64_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -123,14 +123,10 @@ impl RngCore for Xoshiro512Plus { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoshiro512Plus); + #[cfg(test)] mod tests { use super::*; diff --git a/rand_xoshiro/src/xoshiro512plusplus.rs b/rand_xoshiro/src/xoshiro512plusplus.rs index 3e5049a2..f546844a 100644 --- a/rand_xoshiro/src/xoshiro512plusplus.rs +++ b/rand_xoshiro/src/xoshiro512plusplus.rs @@ -8,7 +8,7 @@ use rand_core::impls::fill_bytes_via_next; use rand_core::le::read_u64_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -122,14 +122,10 @@ impl RngCore for Xoshiro512PlusPlus { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoshiro512PlusPlus); + #[cfg(test)] mod tests { use super::*; diff --git a/rand_xoshiro/src/xoshiro512starstar.rs b/rand_xoshiro/src/xoshiro512starstar.rs index 0e508602..ac98a0f9 100644 --- a/rand_xoshiro/src/xoshiro512starstar.rs +++ b/rand_xoshiro/src/xoshiro512starstar.rs @@ -8,7 +8,7 @@ use rand_core::impls::fill_bytes_via_next; use rand_core::le::read_u64_into; -use rand_core::{Error, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; @@ -122,14 +122,10 @@ impl RngCore for Xoshiro512StarStar { fn fill_bytes(&mut self, dest: &mut [u8]) { fill_bytes_via_next(self, dest); } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } } +rand_core::impl_try_rng_from_rng_core!(Xoshiro512StarStar); + #[cfg(test)] mod tests { use super::*;