Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rand_jitter v0.4, platform_ns_time feature, MSRV=1.51, rustfmt #47

Merged
merged 8 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.36.0 # MSRV
- os: ubuntu-latest
deps: sudo apt-get update ; sudo apt install gcc-multilib
target: i686-unknown-linux-gnu
Expand Down Expand Up @@ -85,12 +82,38 @@ 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_isaac / rand_xorshift / rand_xoshiro
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/[email protected] # older versions may work (untested)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 1.36 should work for them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd have to pin older versions of dependencies (see failure). Doesn't seem worth it.

- run: cd rand_isaac && cargo test --all-features
- run: cd rand_xorshift && cargo test --all-features
- run: cd rand_xoshiro && cargo test --all-features

msrv_hc:
name: MSRV for rand_hc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/[email protected]
- run: cd rand_hc && cargo test --all-features

msrv_jitter:
name: MSRV for rand_jitter
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/[email protected]
- run: cd rand_jitter && cargo test --features std

test-cross:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target: [mips-unknown-linux-gnu]
target: [powerpc-unknown-linux-gnu]
toolchain: [stable]

steps:
Expand Down
8 changes: 7 additions & 1 deletion rand_jitter/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion rand_jitter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great to add this to the other Cargo.toml files as well. I'm not sure whether Cargo shipped with Rust 1.36 supports this, but for the other crates it should work.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That can happen when these get updated... they will need an MSRV update for the next rand_core anyway.


[dependencies]
rand_core = { version = "0.6" }
Expand Down
2 changes: 1 addition & 1 deletion rand_jitter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
3 changes: 1 addition & 2 deletions rand_jitter/benches/mod.rs
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -14,4 +14,3 @@ fn bench_add_two(b: &mut Bencher) {
});
b.bytes = buf.len() as u64;
}

11 changes: 6 additions & 5 deletions rand_jitter/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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).
///
Expand Down Expand Up @@ -68,12 +68,13 @@ impl From<TimerError> 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())
}
}
}

81 changes: 51 additions & 30 deletions rand_jitter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +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
Expand All @@ -64,7 +64,7 @@ pub use rand_core;
macro_rules! doc_comment {
($x:expr) => {
#[doc = $x]
extern {}
fn _doc_comment() {}
};
}

Expand Down Expand Up @@ -102,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")]
Expand Down Expand Up @@ -191,7 +191,9 @@ impl<F> fmt::Debug for JitterRng<F> {
}

impl<F> Clone for JitterRng<F>
where F: Clone {
where
F: Clone,
{
fn clone(&self) -> JitterRng<F> {
JitterRng {
data: self.data,
Expand All @@ -209,9 +211,7 @@ where F: Clone {
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
static JITTER_ROUNDS: AtomicUsize = AtomicUsize::new(0);

impl<F> JitterRng<F>
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.
Expand All @@ -220,7 +220,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<JitterRng<fn() -> u64>, TimerError> {
pub fn new() -> Result<JitterRng<impl Fn() -> u64 + Send + Sync>, TimerError> {
if cfg!(target_arch = "wasm32") {
return Err(TimerError::NoTimer);
}
Expand All @@ -239,8 +239,12 @@ where F: Fn() -> u64 + Send + Sync {
state.gen_entropy();
Ok(state)
}
*/
}

impl<F> JitterRng<F>
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.
Expand Down Expand Up @@ -352,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;
Expand Down Expand Up @@ -382,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 {
Expand Down Expand Up @@ -412,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 {
Expand Down Expand Up @@ -454,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
Expand Down Expand Up @@ -599,21 +609,29 @@ 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
// 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;
}

Expand Down Expand Up @@ -674,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])
}
}
Expand Down Expand Up @@ -721,8 +740,10 @@ fn black_box<T>(dummy: T) -> T {
}
}

impl<F> RngCore for JitterRng<F>
where F: Fn() -> u64 + Send + Sync {
impl<F> RngCore for JitterRng<F>
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 {
Expand All @@ -736,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]) {
Expand Down
2 changes: 1 addition & 1 deletion rand_jitter/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading