From 2af1e7dc5138dc93cfbf5150eebefcbc9a6a1438 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 20 Nov 2023 11:39:15 +0000 Subject: [PATCH 1/8] rand_jitter: fix unused doc comment warning --- rand_jitter/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rand_jitter/src/lib.rs b/rand_jitter/src/lib.rs index 5ead1e13..0211344c 100644 --- a/rand_jitter/src/lib.rs +++ b/rand_jitter/src/lib.rs @@ -64,7 +64,7 @@ pub use rand_core; macro_rules! doc_comment { ($x:expr) => { #[doc = $x] - extern {} + fn _doc_comment() {} }; } From 2b86ba1d607fa9daee19c0faee23e9f29c600e52 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 20 Nov 2023 11:50:38 +0000 Subject: [PATCH 2/8] Use RPIT to fix #16 --- rand_jitter/src/lib.rs | 11 ++++++----- rand_jitter/tests/mod.rs | 8 +++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/rand_jitter/src/lib.rs b/rand_jitter/src/lib.rs index 0211344c..7eb88b0a 100644 --- a/rand_jitter/src/lib.rs +++ b/rand_jitter/src/lib.rs @@ -49,6 +49,7 @@ #![deny(missing_debug_implementations)] #![doc(test(attr(allow(unused_variables), deny(warnings))))] + // Note: the C implementation of `Jitterentropy` relies on being compiled // without optimizations. This implementation goes through lengths to make the // compiler not optimize out code which does influence timing jitter, but is @@ -209,9 +210,7 @@ where F: Clone { #[cfg(all(feature = "std", not(target_arch = "wasm32")))] static JITTER_ROUNDS: AtomicUsize = AtomicUsize::new(0); -impl JitterRng -where F: Fn() -> u64 + Send + Sync { - /* FIXME: this method is broken - see #16 +impl JitterRng<()> { /// Create a new `JitterRng`. Makes use of `std::time` for a timer, or a /// platform-specific function with higher accuracy if necessary and /// available. @@ -220,7 +219,7 @@ where F: Fn() -> u64 + Send + Sync { /// hundred times. If this does not pass basic quality tests, an error is /// returned. The test result is cached to make subsequent calls faster. #[cfg(all(feature = "std", not(target_arch = "wasm32")))] - pub fn new() -> Result u64>, TimerError> { + pub fn new() -> Result u64 + Send + Sync>, TimerError> { if cfg!(target_arch = "wasm32") { return Err(TimerError::NoTimer); } @@ -239,8 +238,10 @@ where F: Fn() -> u64 + Send + Sync { state.gen_entropy(); Ok(state) } - */ +} +impl JitterRng +where F: Fn() -> u64 + Send + Sync { /// Create a new `JitterRng`. /// A custom timer can be supplied, making it possible to use `JitterRng` in /// `no_std` environments. diff --git a/rand_jitter/tests/mod.rs b/rand_jitter/tests/mod.rs index ba3ca5d5..ccb85732 100644 --- a/rand_jitter/tests/mod.rs +++ b/rand_jitter/tests/mod.rs @@ -1,11 +1,10 @@ use rand_jitter::JitterRng; -#[cfg(feature = "std")] -use rand_core::RngCore; -/* FIXME #16 -#[cfg(feature = "std")] +#[cfg(all(feature = "std", not(target_arch = "wasm32")))] #[test] fn test_jitter_init() { + use rand_core::RngCore; + // Because this is a debug build, measurements here are not representive // of the final release build. // Don't fail this test if initializing `JitterRng` fails because of a @@ -19,7 +18,6 @@ fn test_jitter_init() { Err(_) => {}, } } -*/ #[test] fn test_jitter_bad_timer() { From 5a5cdf5521266599745e61e25eb77e8485d7e955 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 20 Nov 2023 11:52:00 +0000 Subject: [PATCH 3/8] rand_jitter: apply rustfmt --- rand_jitter/benches/mod.rs | 3 +- rand_jitter/src/error.rs | 11 +++--- rand_jitter/src/lib.rs | 70 ++++++++++++++++++++++++------------- rand_jitter/src/platform.rs | 2 +- rand_jitter/tests/mod.rs | 14 +++++--- 5 files changed, 62 insertions(+), 38 deletions(-) diff --git a/rand_jitter/benches/mod.rs b/rand_jitter/benches/mod.rs index bf7c8a27..b62d90f1 100644 --- a/rand_jitter/benches/mod.rs +++ b/rand_jitter/benches/mod.rs @@ -1,8 +1,8 @@ #![feature(test)] #![cfg(std)] -use test::Bencher; use rand_jitter::rand_core::RngCore; +use test::Bencher; #[bench] fn bench_add_two(b: &mut Bencher) { @@ -14,4 +14,3 @@ fn bench_add_two(b: &mut Bencher) { }); b.bytes = buf.len() as u64; } - diff --git a/rand_jitter/src/error.rs b/rand_jitter/src/error.rs index c59d0fdf..3b1267cf 100644 --- a/rand_jitter/src/error.rs +++ b/rand_jitter/src/error.rs @@ -7,14 +7,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rand_core::Error; use core::fmt; +use rand_core::Error; /// Base code for all `JitterRng` errors const ERROR_BASE: u32 = 0xAE53_0400; /// An error that can occur when [`JitterRng::test_timer`] fails. -/// +/// /// All variants have a value of 0xAE530400 = 2924676096 plus a small /// increment (1 through 5). /// @@ -68,12 +68,13 @@ 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")] { + #[cfg(feature = "std")] + { Error::new(err) } - #[cfg(not(feature = "std"))] { + #[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 7eb88b0a..6125d105 100644 --- a/rand_jitter/src/lib.rs +++ b/rand_jitter/src/lib.rs @@ -41,15 +41,14 @@ //! [Jitterentropy]: http://www.chronox.de/jent.html //! [discussion]: https://github.com/rust-random/rand/issues/699 -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", - html_favicon_url = "https://www.rust-lang.org/favicon.ico", - html_root_url = "https://rust-random.github.io/rand/")] - +#![doc( + html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", + html_favicon_url = "https://www.rust-lang.org/favicon.ico", + html_root_url = "https://rust-random.github.io/rand/" +)] #![deny(missing_docs)] #![deny(missing_debug_implementations)] #![doc(test(attr(allow(unused_variables), deny(warnings))))] - - // Note: the C implementation of `Jitterentropy` relies on being compiled // without optimizations. This implementation goes through lengths to make the // compiler not optimize out code which does influence timing jitter, but is @@ -103,12 +102,12 @@ macro_rules! error { ($($x:tt)*) => ( } ) } +mod error; #[cfg(feature = "std")] mod platform; -mod error; -use rand_core::{RngCore, Error, impls}; pub use crate::error::TimerError; +use rand_core::{impls, Error, RngCore}; use core::{fmt, mem, ptr}; #[cfg(feature = "std")] @@ -192,7 +191,9 @@ impl fmt::Debug for JitterRng { } impl Clone for JitterRng -where F: Clone { +where + F: Clone, +{ fn clone(&self) -> JitterRng { JitterRng { data: self.data, @@ -241,7 +242,9 @@ impl JitterRng<()> { } impl JitterRng -where F: Fn() -> u64 + Send + Sync { +where + F: Fn() -> u64 + Send + Sync, +{ /// Create a new `JitterRng`. /// A custom timer can be supplied, making it possible to use `JitterRng` in /// `no_std` environments. @@ -353,7 +356,7 @@ where F: Fn() -> u64 + Send + Sync { // the loop in this function implies that careful retesting must be done. #[inline(never)] fn lfsr_time(&mut self, time: u64, var_rounds: bool) { - fn lfsr(mut data: u64, time: u64) -> u64{ + fn lfsr(mut data: u64, time: u64) -> u64 { for i in 1..65 { let mut tmp = time << (64 - i); tmp >>= 64 - 1; @@ -383,7 +386,9 @@ where F: Fn() -> u64 + Send + Sync { // other rounds are not optimised out, we first run all but the last // round on a throw-away value instead of the real `self.data`. let mut lfsr_loop_cnt = 0; - if var_rounds { lfsr_loop_cnt = self.random_loop_cnt(4) }; + if var_rounds { + lfsr_loop_cnt = self.random_loop_cnt(4) + }; let mut throw_away: u64 = 0; for _ in 0..lfsr_loop_cnt { @@ -413,7 +418,9 @@ where F: Fn() -> u64 + Send + Sync { #[inline(never)] fn memaccess(&mut self, mem: &mut [u8; MEMORY_SIZE], var_rounds: bool) { let mut acc_loop_cnt = 128; - if var_rounds { acc_loop_cnt += self.random_loop_cnt(4) }; + if var_rounds { + acc_loop_cnt += self.random_loop_cnt(4) + }; let mut index = self.mem_prev_index as usize; for _ in 0..acc_loop_cnt { @@ -455,7 +462,9 @@ where F: Fn() -> u64 + Send + Sync { // Check whether we have a stuck measurement (i.e. does the last // measurement holds entropy?). - if ec.stuck(current_delta) { return None }; + if ec.stuck(current_delta) { + return None; + }; // Rotate the data buffer by a prime number (any odd number would // do) to ensure that every bit position of the input time stamp @@ -600,16 +609,24 @@ where F: Fn() -> u64 + Send + Sync { // already have had an impact on the caches, branch prediction, // etc. with the goal to clear it to get the worst case // measurements. - if i < CLEARCACHE { continue; } + if i < CLEARCACHE { + continue; + } - if ec.stuck(delta) { count_stuck += 1; } + if ec.stuck(delta) { + count_stuck += 1; + } // Test whether we have an increasing timer. - if time2 <= time { time_backwards += 1; } + if time2 <= time { + time_backwards += 1; + } // Count the number of times the counter increases in steps of 100ns // or greater. - if (delta % 100) == 0 { count_mod += 1; } + if (delta % 100) == 0 { + count_mod += 1; + } // Ensure that we have a varying delta timer which is necessary for // the calculation of entropy -- perform this check only after the @@ -675,14 +692,15 @@ where F: Fn() -> u64 + Send + Sync { if delta_average >= 16 { let log2 = 64 - delta_average.leading_zeros(); // Do something similar to roundup(64/(log2/2)): - Ok( ((64u32 * 2 + log2 - 1) / log2) as u8) + Ok(((64u32 * 2 + log2 - 1) / log2) as u8) } else { // For values < 16 the rounding error becomes too large, use a // lookup table. // Values 0 and 1 are invalid, and filtered out by the // `delta_sum < TESTLOOPCOUNT` test above. - let log2_lookup = [0, 0, 128, 81, 64, 56, 50, 46, - 43, 41, 39, 38, 36, 35, 34, 33]; + let log2_lookup = [ + 0, 0, 128, 81, 64, 56, 50, 46, 43, 41, 39, 38, 36, 35, 34, 33, + ]; Ok(log2_lookup[delta_average as usize]) } } @@ -722,8 +740,10 @@ fn black_box(dummy: T) -> T { } } -impl RngCore for JitterRng -where F: Fn() -> u64 + Send + Sync { +impl RngCore for JitterRng +where + F: Fn() -> u64 + Send + Sync, +{ fn next_u32(&mut self) -> u32 { // We want to use both parts of the generated entropy if self.data_half_used { @@ -737,8 +757,8 @@ where F: Fn() -> u64 + Send + Sync { } fn next_u64(&mut self) -> u64 { - self.data_half_used = false; - self.gen_entropy() + self.data_half_used = false; + self.gen_entropy() } fn fill_bytes(&mut self, dest: &mut [u8]) { diff --git a/rand_jitter/src/platform.rs b/rand_jitter/src/platform.rs index 8e3d0fb2..cc286839 100644 --- a/rand_jitter/src/platform.rs +++ b/rand_jitter/src/platform.rs @@ -22,7 +22,7 @@ pub fn get_nstime() -> u64 { #[cfg(any(target_os = "macos", target_os = "ios"))] pub fn get_nstime() -> u64 { use libc; - + // On Mac OS and iOS std::time::SystemTime only has 1000ns resolution. // We use `mach_absolute_time` instead. This provides a CPU dependent // unit, to get real nanoseconds the result should by multiplied by diff --git a/rand_jitter/tests/mod.rs b/rand_jitter/tests/mod.rs index ccb85732..58ff8dac 100644 --- a/rand_jitter/tests/mod.rs +++ b/rand_jitter/tests/mod.rs @@ -14,21 +14,25 @@ fn test_jitter_init() { Ok(ref mut rng) => { // false positives are possible, but extremely unlikely assert!(rng.next_u32() | rng.next_u32() != 0); - }, - Err(_) => {}, + } + Err(_) => {} } } #[test] fn test_jitter_bad_timer() { - fn bad_timer() -> u64 { 0 } + fn bad_timer() -> u64 { + 0 + } let mut rng = JitterRng::new_with_timer(bad_timer); assert!(rng.test_timer().is_err()); } #[test] fn test_jitter_closure() { - fn bad_timer() -> u64 { 0 } + fn bad_timer() -> u64 { + 0 + } let at_start = bad_timer(); - let _ = JitterRng::new_with_timer(move || { bad_timer() - at_start }); + let _ = JitterRng::new_with_timer(move || bad_timer() - at_start); } From 0aa171557f14dbeeaf7ac6792ed048c5f429ab72 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 20 Nov 2023 12:04:06 +0000 Subject: [PATCH 4/8] Bump MSRV to 1.51 and use unsigned_abs --- .github/workflows/test.yml | 2 +- rand_jitter/Cargo.toml | 1 + rand_jitter/README.md | 2 +- rand_jitter/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c8788a28..2b91b0c4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,7 +50,7 @@ jobs: # Test both windows-gnu and windows-msvc; use beta rust on one - os: ubuntu-latest target: x86_64-unknown-linux-gnu - toolchain: 1.36.0 # MSRV + toolchain: 1.51.0 # temporary MSRV of rand_jitter - os: ubuntu-latest deps: sudo apt-get update ; sudo apt install gcc-multilib target: i686-unknown-linux-gnu diff --git a/rand_jitter/Cargo.toml b/rand_jitter/Cargo.toml index d6eff875..63808506 100644 --- a/rand_jitter/Cargo.toml +++ b/rand_jitter/Cargo.toml @@ -9,6 +9,7 @@ documentation = "https://docs.rs/rand_jitter" description = "Random number generator based on timing jitter" keywords = ["random", "rng", "os"] edition = "2018" +rust-version = "1.51" [dependencies] rand_core = { version = "0.6" } diff --git a/rand_jitter/README.md b/rand_jitter/README.md index 149b590a..e84e41f6 100644 --- a/rand_jitter/README.md +++ b/rand_jitter/README.md @@ -5,7 +5,7 @@ [![Book](https://img.shields.io/badge/book-master-yellow.svg)](https://rust-random.github.io/book/) [![API](https://img.shields.io/badge/api-master-yellow.svg)](https://rust-random.github.io/rand/rand_jitter) [![API](https://docs.rs/rand_jitter/badge.svg)](https://docs.rs/rand_jitter) -[![Minimum rustc version](https://img.shields.io/badge/rustc-1.36+-lightgray.svg)](https://github.com/rust-random/rngs#rust-version-requirements) +[![Minimum rustc version](https://img.shields.io/badge/rustc-1.51-lightgray.svg)](https://github.com/rust-random/rngs#rust-version-requirements) Non-physical true random number generator based on timing jitter. diff --git a/rand_jitter/src/lib.rs b/rand_jitter/src/lib.rs index 6125d105..6c80b531 100644 --- a/rand_jitter/src/lib.rs +++ b/rand_jitter/src/lib.rs @@ -631,7 +631,7 @@ where // Ensure that we have a varying delta timer which is necessary for // the calculation of entropy -- perform this check only after the // first loop is executed as we need to prime the old_delta value - delta_sum += (delta - old_delta).abs() as u64; + delta_sum += (delta - old_delta).unsigned_abs() as u64; old_delta = delta; } From 218a632884552840444eea0ccb4dbbc9885f5960 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 20 Nov 2023 12:08:12 +0000 Subject: [PATCH 5/8] Prepare 0.4.0 --- rand_jitter/CHANGELOG.md | 8 +++++++- rand_jitter/Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/rand_jitter/CHANGELOG.md b/rand_jitter/CHANGELOG.md index fbcc4499..b72a9b7d 100644 --- a/rand_jitter/CHANGELOG.md +++ b/rand_jitter/CHANGELOG.md @@ -4,9 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.4.0] - 2023-11-20 +### Changed +- Update to `rand_core` v0.6 +- Bump MSRV to 1.51 +- Use return-position impl trait to fix `JitterRng::new` (#16) + ## [0.3.0] - 2020-09-07 ### Changed -- `JitterRng::new_with_timer` accepts closures +- `JitterRng::new_with_timer` accepts closures (this breaks `JitterRng::new`) ## [0.2.1] - 2019-08-16 ### Changed diff --git a/rand_jitter/Cargo.toml b/rand_jitter/Cargo.toml index 63808506..00ae8839 100644 --- a/rand_jitter/Cargo.toml +++ b/rand_jitter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rand_jitter" -version = "0.3.0" +version = "0.4.0" authors = ["The Rand Project Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 4b4d361e2c3419b86e6caf86c0b65d0463de2d98 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 20 Nov 2023 16:15:21 +0000 Subject: [PATCH 6/8] CI: run cross test on powerpc, not mips --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2b91b0c4..9593525c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -90,7 +90,7 @@ jobs: strategy: fail-fast: false matrix: - target: [mips-unknown-linux-gnu] + target: [powerpc-unknown-linux-gnu] toolchain: [stable] steps: From 153d42fc17977e7799679e4341a40ecc1e922433 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 20 Nov 2023 16:21:31 +0000 Subject: [PATCH 7/8] CI: separated MSRV tests --- .github/workflows/test.yml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9593525c..34957d33 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,9 +48,6 @@ jobs: target: x86_64-pc-windows-msvc toolchain: beta # Test both windows-gnu and windows-msvc; use beta rust on one - - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - toolchain: 1.51.0 # temporary MSRV of rand_jitter - os: ubuntu-latest deps: sudo apt-get update ; sudo apt install gcc-multilib target: i686-unknown-linux-gnu @@ -85,6 +82,25 @@ jobs: cargo test --target ${{ matrix.target }} --manifest-path rand_xoshiro/Cargo.toml --all-features cargo test --target ${{ matrix.target }} --manifest-path rand_jitter/Cargo.toml --all-features + msrv: + name: MSRV for rand_hc / rand_isaac / rand_xorshift / rand_xoshiro + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@1.36.0 + - run: cd rand_hc && cargo test --all-features + - run: cd rand_isaac && cargo test --all-features + - run: cd rand_xorshift && cargo test --all-features + - run: cd rand_xoshiro && cargo test --all-features + + jitter: + name: MSRV for rand_jitter + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@1.51.0 + - run: cd rand_jitter && cargo test --features std + test-cross: runs-on: ubuntu-latest strategy: From 8b94537f2208e0d8d6d8b45bb3c8c4c6d363b9e3 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 20 Nov 2023 17:06:21 +0000 Subject: [PATCH 8/8] CI: use 1.56 for isaac/xoshiro/xorshift --- .github/workflows/test.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 34957d33..e11be4c7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -83,17 +83,24 @@ jobs: cargo test --target ${{ matrix.target }} --manifest-path rand_jitter/Cargo.toml --all-features msrv: - name: MSRV for rand_hc / rand_isaac / rand_xorshift / rand_xoshiro + name: MSRV for rand_isaac / rand_xorshift / rand_xoshiro runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@1.36.0 - - run: cd rand_hc && cargo test --all-features + - uses: dtolnay/rust-toolchain@1.56.0 # older versions may work (untested) - run: cd rand_isaac && cargo test --all-features - run: cd rand_xorshift && cargo test --all-features - run: cd rand_xoshiro && cargo test --all-features - jitter: + msrv_hc: + name: MSRV for rand_hc + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@1.36.0 + - run: cd rand_hc && cargo test --all-features + + msrv_jitter: name: MSRV for rand_jitter runs-on: ubuntu-latest steps: