diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ad0cf1425cc..25b4b9111e0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -73,7 +73,7 @@ jobs: - os: ubuntu-latest target: x86_64-unknown-linux-gnu variant: MSRV - toolchain: 1.63.0 + toolchain: 1.85.0 - os: ubuntu-latest deps: sudo apt-get update ; sudo apt install gcc-multilib target: i686-unknown-linux-gnu diff --git a/CHANGELOG.md b/CHANGELOG.md index 891db26a9f9..6806b9b7497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ A [separate changelog is kept for rand_core](rand_core/CHANGELOG.md). You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.html) useful. ## [Unreleased] +### Changed +- The dependency on `rand_chacha` has been replaced with a dependency on `chacha20`. This changes the implementation behind `StdRng`, but the output remains the same. There may be some API breakage when using the ChaCha-types directly as these are now the ones in `chacha20` instead of `rand_chacha`. +- Changed MSRV to 1.85 (required by `chacha20`). + ### Deprecated - Deprecate `rand::rngs::mock` module and `StepRng` generator (#1634) diff --git a/Cargo.toml b/Cargo.toml index 523c8d3c867..626f0de557b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["random", "rng"] categories = ["algorithms", "no-std"] autobenches = true edition = "2021" -rust-version = "1.63" +rust-version = "1.85" include = ["src/", "LICENSE-*", "README.md", "CHANGELOG.md", "COPYRIGHT"] [package.metadata.docs.rs] @@ -34,7 +34,7 @@ serde = ["dep:serde", "rand_core/serde"] # Option (enabled by default): without "std" rand uses libcore; this option # enables functionality expected to be available on a standard platform. -std = ["rand_core/std", "rand_chacha?/std", "alloc"] +std = ["rand_core/std", "alloc"] # Option: "alloc" enables support for Vec and Box when not using "std" alloc = [] @@ -46,7 +46,7 @@ os_rng = ["rand_core/os_rng"] simd_support = [] # Option (enabled by default): enable StdRng -std_rng = ["dep:rand_chacha"] +std_rng = ["dep:chacha20"] # Option: enable SmallRng small_rng = [] @@ -70,11 +70,16 @@ members = [ ] exclude = ["benches", "distr_test"] +# Force chacha20 to use the local rand_code to avoid compiling two different "rand_core"s. +# This is necessary even if the specified versions are the same. +[patch.crates-io] +rand_core = { path = "rand_core" } + [dependencies] rand_core = { path = "rand_core", version = "0.9.0", default-features = false } log = { version = "0.4.4", optional = true } serde = { version = "1.0.103", features = ["derive"], optional = true } -rand_chacha = { path = "rand_chacha", version = "0.9.0", default-features = false, optional = true } +chacha20 = { version = "=0.10.0-rc.0", default-features = false, features = ["rng"], optional = true } [dev-dependencies] rand_pcg = { path = "rand_pcg", version = "0.9.0" } diff --git a/benches/Cargo.toml b/benches/Cargo.toml index adb9aadd84b..6cd7a95e706 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -8,6 +8,11 @@ publish = false # Option (requires nightly Rust): experimental SIMD support simd_support = ["rand/simd_support"] +# Force chacha20 to use the local rand_code to avoid compiling two different "rand_core"s. +# This is necessary even if the specified versions are the same. +[patch.crates-io] +rand_core = { path = "../rand_core" } + [dependencies] [dev-dependencies] diff --git a/examples/rayon-monte-carlo.rs b/examples/rayon-monte-carlo.rs index 31d8e681067..25b6ed88698 100644 --- a/examples/rayon-monte-carlo.rs +++ b/examples/rayon-monte-carlo.rs @@ -38,8 +38,9 @@ //! over BATCH_SIZE trials. Manually batching also turns out to be faster //! for the nondeterministic version of this program as well. +use chacha20::ChaCha8Rng; use rand::distr::{Distribution, Uniform}; -use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng}; +use rand_core::SeedableRng; use rayon::prelude::*; static SEED: u64 = 0; @@ -56,7 +57,7 @@ fn main() { // We chose ChaCha because it's fast, has suitable statistical properties for simulation, // and because it supports this set_stream() api, which lets us choose a different stream // per work item. ChaCha supports 2^64 independent streams. - rng.set_stream(i); + rng.set_stream(u128::from(i)); let mut count = 0; for _ in 0..BATCH_SIZE { let a = range.sample(&mut rng); diff --git a/rand_core/src/block.rs b/rand_core/src/block.rs index a17a6666f3f..cf801a3a3b6 100644 --- a/rand_core/src/block.rs +++ b/rand_core/src/block.rs @@ -557,7 +557,7 @@ mod test { } rng.next_u32(); - let result = rng.next_u64(); + let _ = rng.next_u64(); assert_eq!(rng.index(), 1); } } diff --git a/src/rngs/reseeding.rs b/src/rngs/reseeding.rs index 69b9045e0de..9050e14d2cc 100644 --- a/src/rngs/reseeding.rs +++ b/src/rngs/reseeding.rs @@ -53,9 +53,9 @@ use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore}; /// # Example /// /// ``` +/// use chacha20::ChaCha20Core; // Internal part of ChaChaRng that +/// // implements BlockRngCore /// use rand::prelude::*; -/// use rand_chacha::ChaCha20Core; // Internal part of ChaChaRng that -/// // implements BlockRngCore /// use rand::rngs::OsRng; /// use rand::rngs::ReseedingRng; /// diff --git a/src/rngs/std.rs b/src/rngs/std.rs index 6e1658e7453..64313f91405 100644 --- a/src/rngs/std.rs +++ b/src/rngs/std.rs @@ -11,9 +11,9 @@ use rand_core::{CryptoRng, RngCore, SeedableRng}; #[cfg(any(test, feature = "os_rng"))] -pub(crate) use rand_chacha::ChaCha12Core as Core; +pub(crate) use chacha20::ChaCha12Core as Core; -use rand_chacha::ChaCha12Rng as Rng; +use chacha20::ChaCha12Rng as Rng; /// A strong, fast (amortized), non-portable RNG /// @@ -121,4 +121,81 @@ mod test { assert_eq!([x0, x1], target); } + + #[test] + fn test_chacha12_tv1_tv2() { + // Test vectors 1 and 2 from + // https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04 + // but the expected values are replaced with the ones produced + // by Chacha12 (as generated by rand_chacha). + let seed = [0u8; 32]; + let mut rng = StdRng::from_seed(seed); + + let results: [u32; 16] = core::array::from_fn(|_| rng.next_u32()); + let expected = [ + 1788540059, 1408849159, 315498369, 3582142047, 3150129412, 343203913, 2777219198, + 1595256366, 2046321669, 3236133586, 875096108, 2039282348, 748642874, 426368672, + 803736417, 3190166337, + ]; + assert_eq!(results, expected); + + let results = core::array::from_fn(|_| rng.next_u32()); + let expected = [ + 1099486475, 4269030944, 863108230, 1024974988, 3085641926, 3435904281, 562369813, + 3028926540, 3448579394, 301026465, 2545418950, 1137216539, 3393593065, 3226554768, + 2963686439, 378791447, + ]; + assert_eq!(results, expected); + } + + #[test] + fn test_chacha12_tv3() { + // Test vector 3 from + // https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04 + // but the expected values are replaced with the ones produced + // by Chacha12 (as generated by rand_chacha). + let seed = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, + ]; + let mut rng = StdRng::from_seed(seed); + + // Skip block 0 + for _ in 0..16 { + rng.next_u32(); + } + + let results: [u32; 16] = core::array::from_fn(|_| rng.next_u32()); + let expected = [ + 1149489484, 1453872210, 205606722, 2561053166, 4209612569, 2282920975, 2059979989, + 3051314295, 4135011526, 3904759261, 3697107527, 2431012387, 1801979597, 1269452364, + 3197257745, 2154707421, + ]; + assert_eq!(results, expected); + } + + #[test] + fn test_chacha12_tv4() { + // Test vector 4 from + // https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04 + // but the expected values are replaced with the ones produced + // by Chacha12 (as generated by rand_chacha). + let seed = [ + 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ]; + + // Test block 2 by skipping block 0 and 1 + let mut rng = StdRng::from_seed(seed); + for _ in 0..32 { + rng.next_u32(); + } + let results: [u32; 16] = core::array::from_fn(|_| rng.next_u32()); + let expected = [ + 1614024310, 613097064, 193455541, 494774344, 2671734178, 1658534307, 1449802595, + 1853279994, 129091709, 2135285029, 2884964524, 3629948889, 2335941772, 2471549797, + 887756884, 3388159322, + ]; + assert_eq!(results, expected); + } } diff --git a/src/seq/slice.rs b/src/seq/slice.rs index f909418bc48..67615f100b6 100644 --- a/src/seq/slice.rs +++ b/src/seq/slice.rs @@ -87,7 +87,11 @@ pub trait IndexedRandom: Index { /// } /// ``` #[cfg(feature = "alloc")] - fn choose_multiple(&self, rng: &mut R, amount: usize) -> SliceChooseIter + fn choose_multiple( + &self, + rng: &mut R, + amount: usize, + ) -> SliceChooseIter<'_, Self, Self::Output> where Self::Output: Sized, R: Rng + ?Sized, @@ -209,7 +213,7 @@ pub trait IndexedRandom: Index { rng: &mut R, amount: usize, weight: F, - ) -> Result, WeightError> + ) -> Result, WeightError> where Self::Output: Sized, R: Rng + ?Sized,