From d9999d8e5445e3fc2074416f0576b258069999e4 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Sun, 6 Sep 2020 23:39:51 +0200 Subject: [PATCH] SmallRng: Replace PCG algorithm with xoshiro{128,256}++ Due to close correlations of PCG streams (#907) and lack of right-state propagation (#905), the `SmallRng` algorithm is switched to xoshiro{128,256}++. The implementation is taken from the `rand_xoshiro` crate and slightly simplified. Fixes #910. --- Cargo.toml | 3 +-- src/rngs/mod.rs | 6 ++++++ src/rngs/small.rs | 23 +++++++++++------------ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c0d8cba184a..70713bfff73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ simd_support = ["packed_simd"] std_rng = ["rand_chacha", "rand_hc"] # Option: enable SmallRng -small_rng = ["rand_pcg"] +small_rng = [] [workspace] members = [ @@ -56,7 +56,6 @@ members = [ [dependencies] rand_core = { path = "rand_core", version = "0.5.1" } -rand_pcg = { path = "rand_pcg", version = "0.2.1", optional = true } log = { version = "0.4.4", optional = true } serde = { version = "1.0.103", features = ["derive"], optional = true } diff --git a/src/rngs/mod.rs b/src/rngs/mod.rs index f866409579b..ba2f81b807d 100644 --- a/src/rngs/mod.rs +++ b/src/rngs/mod.rs @@ -101,7 +101,13 @@ pub mod mock; // Public so we don't export `StepRng` directly, making it a bit // more clear it is intended for testing. + +#[cfg(all(feature = "small_rng", target_pointer_width = "64"))] +mod xoshiro256plusplus; +#[cfg(all(feature = "small_rng", not(target_pointer_width = "64")))] +mod xoshiro128plusplus; #[cfg(feature = "small_rng")] mod small; + #[cfg(feature = "std_rng")] mod std; #[cfg(all(feature = "std", feature = "std_rng"))] pub(crate) mod thread; diff --git a/src/rngs/small.rs b/src/rngs/small.rs index e0b56315935..d9373a34081 100644 --- a/src/rngs/small.rs +++ b/src/rngs/small.rs @@ -10,10 +10,10 @@ use rand_core::{Error, RngCore, SeedableRng}; -#[cfg(all(not(target_os = "emscripten"), target_pointer_width = "64"))] -type Rng = rand_pcg::Pcg64Mcg; -#[cfg(not(all(not(target_os = "emscripten"), target_pointer_width = "64")))] -type Rng = rand_pcg::Pcg32; +#[cfg(target_pointer_width = "64")] +type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus; +#[cfg(not(target_pointer_width = "64"))] +type Rng = super::xoshiro128plusplus::Xoshiro128PlusPlus; /// A small-state, fast non-crypto PRNG /// @@ -25,15 +25,14 @@ type Rng = rand_pcg::Pcg32; /// The algorithm is deterministic but should not be considered reproducible /// due to dependence on platform and possible replacement in future /// library versions. For a reproducible generator, use a named PRNG from an -/// external crate, e.g. [rand_pcg] or [rand_chacha]. +/// external crate, e.g. [rand_xoshiro] or [rand_chacha]. /// Refer also to [The Book](https://rust-random.github.io/book/guide-rngs.html). /// -/// The PRNG algorithm in `SmallRng` is chosen to be -/// efficient on the current platform, without consideration for cryptography -/// or security. The size of its state is much smaller than [`StdRng`]. -/// The current algorithm is [`Pcg64Mcg`](rand_pcg::Pcg64Mcg) on 64-bit -/// platforms and [`Pcg32`](rand_pcg::Pcg32) on 32-bit platforms. Both are -/// implemented by the [rand_pcg] crate. +/// The PRNG algorithm in `SmallRng` is chosen to be efficient on the current +/// platform, without consideration for cryptography or security. The size of +/// its state is much smaller than [`StdRng`]. The current algorithm is +/// `Xoshiro256PlusPlus` on 64-bit platforms and `Xoshiro128PlusPlus` on 32-bit +/// platforms. Both are implemented by the [rand_xoshiro] crate. /// /// # Examples /// @@ -69,7 +68,7 @@ type Rng = rand_pcg::Pcg32; /// [`StdRng`]: crate::rngs::StdRng /// [`thread_rng`]: crate::thread_rng /// [rand_chacha]: https://crates.io/crates/rand_chacha -/// [rand_pcg]: https://crates.io/crates/rand_pcg +/// [rand_xoshiro]: https://crates.io/crates/rand_pcg #[cfg_attr(doc_cfg, doc(cfg(feature = "small_rng")))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct SmallRng(Rng);