From c893c053b13165b5d723f9f8a48f6139fce66177 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 9 Dec 2020 22:30:31 +0100 Subject: [PATCH] moved to romu_trio rand --- afl/benches/rand_speeds.rs | 14 ++++- afl/src/engines/mod.rs | 3 +- afl/src/events/mod.rs | 4 +- afl/src/feedbacks/mod.rs | 1 - afl/src/utils.rs | 123 ++++++++++++++++++++++++++++--------- 5 files changed, 107 insertions(+), 38 deletions(-) diff --git a/afl/benches/rand_speeds.rs b/afl/benches/rand_speeds.rs index 087738659f..495d7018e0 100644 --- a/afl/benches/rand_speeds.rs +++ b/afl/benches/rand_speeds.rs @@ -1,14 +1,22 @@ //! Compare the speed of rand implementations -use afl::utils::{Rand, XorShift64Rand, Xoshiro256StarRand}; +use afl::utils::{ + Lehmer64Rand, Rand, RomuDuoJrRand, RomuTrioRand, XorShift64Rand, Xoshiro256StarRand, +}; use criterion::{black_box, criterion_group, criterion_main, Criterion}; fn criterion_benchmark(c: &mut Criterion) { - let mut xorshift = XorShift64Rand::new(0); - let mut xoshiro = Xoshiro256StarRand::new(0); + let mut xorshift = XorShift64Rand::new(1); + let mut xoshiro = Xoshiro256StarRand::new(1); + let mut romu = RomuDuoJrRand::new(1); + let mut lehmer = Lehmer64Rand::new(1); + let mut romu_trio = RomuTrioRand::new(1); c.bench_function("xorshift", |b| b.iter(|| black_box(xorshift.next()))); c.bench_function("xoshiro", |b| b.iter(|| black_box(xoshiro.next()))); + c.bench_function("romu", |b| b.iter(|| black_box(romu.next()))); + c.bench_function("romu_trio", |b| b.iter(|| black_box(romu_trio.next()))); + c.bench_function("lehmer", |b| b.iter(|| black_box(lehmer.next()))); } criterion_group!(benches, criterion_benchmark); diff --git a/afl/src/engines/mod.rs b/afl/src/engines/mod.rs index 426fac6c0b..2f75445217 100644 --- a/afl/src/engines/mod.rs +++ b/afl/src/engines/mod.rs @@ -301,7 +301,8 @@ where let cur = current_milliseconds(); if cur - last > 60 * 100 { last = cur; - manager.fire(Event::update_stats(state.executions(), state.executions_over_seconds()), + manager.fire( + Event::update_stats(state.executions(), state.executions_over_seconds()), state, corpus, )?; // TODO self.new_execs}); diff --git a/afl/src/events/mod.rs b/afl/src/events/mod.rs index 25a0106f7a..cadbe0f1c9 100644 --- a/afl/src/events/mod.rs +++ b/afl/src/events/mod.rs @@ -33,9 +33,7 @@ pub enum BrokerEventResult { Forward, } -pub trait ShowStats { - -} +pub trait ShowStats {} /* diff --git a/afl/src/feedbacks/mod.rs b/afl/src/feedbacks/mod.rs index 9117333c1f..39f2d505dd 100644 --- a/afl/src/feedbacks/mod.rs +++ b/afl/src/feedbacks/mod.rs @@ -300,4 +300,3 @@ where } } */ - diff --git a/afl/src/utils.rs b/afl/src/utils.rs index 21ea1d3d4d..c23aaf81f6 100644 --- a/afl/src/utils.rs +++ b/afl/src/utils.rs @@ -9,14 +9,16 @@ use xxhash_rust::xxh3::xxh3_64_with_seed; #[cfg(feature = "std")] use std::time::{SystemTime, UNIX_EPOCH}; -pub type StdRand = Xoshiro256StarRand; +pub type StdRand = RomuTrioRand; /// Ways to get random around here pub trait Rand: Debug { // Sets the seed of this Rand fn set_seed(&mut self, seed: u64); + // Gets the next 64 bit value fn next(&mut self) -> u64; + // Gets a value below the given 64 bit val (inclusive) fn below(&mut self, upper_bound_excl: u64) -> u64 { if upper_bound_excl <= 1 { @@ -73,6 +75,15 @@ where const HASH_CONST: u64 = 0xa5b35705; +#[cfg(feature = "std")] +/// Gets current nanoseconds since UNIX_EPOCH +pub fn current_nanos() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos() as u64 +} + /// XXH3 Based, hopefully speedy, rnd implementation /// #[derive(Copy, Clone, Debug, Default)] @@ -91,6 +102,7 @@ impl Rand for Xoshiro256StarRand { self.seeded = true; } + #[inline] fn next(&mut self) -> u64 { let ret: u64 = self.rand_seed[0] .wrapping_add(self.rand_seed[3]) @@ -125,19 +137,11 @@ impl Xoshiro256StarRand { ret } - pub fn to_rc_refcell(self) -> Rc> { - self.into() - } - /// Creates a rand instance, pre-seeded with the current time in nanoseconds. /// Needs stdlib timer #[cfg(feature = "std")] pub fn preseeded() -> Self { - let seed = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_nanos() as u64; - Self::new(seed) + Self::new(current_nanos()) } } @@ -155,6 +159,7 @@ impl Rand for XorShift64Rand { self.seeded = true; } + #[inline] fn next(&mut self) -> u64 { let mut x = self.rand_seed; x ^= x << 13; @@ -179,19 +184,11 @@ impl XorShift64Rand { ret } - pub fn to_rc_refcell(self) -> Rc> { - self.into() - } - /// Creates a rand instance, pre-seeded with the current time in nanoseconds. /// Needs stdlib timer #[cfg(feature = "std")] pub fn preseeded() -> Self { - let seed = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_nanos() as u64; - Self::new(seed) + Self::new(current_nanos()) } } @@ -209,6 +206,7 @@ impl Rand for Lehmer64Rand { self.seeded = true; } + #[inline] fn next(&mut self) -> u64 { self.rand_seed *= 0xda942042e4dd58b5; return (self.rand_seed >> 64) as u64; @@ -222,26 +220,91 @@ impl Into>> for Lehmer64Rand { } impl Lehmer64Rand { - /// Creates a new Xoshiro rand with the given seed + /// Creates a new Lehmer rand with the given seed pub fn new(seed: u64) -> Self { let mut ret: Self = Default::default(); - ret.set_seed(seed); // TODO: Proper random seed? + ret.set_seed(seed); ret } - pub fn to_rc_refcell(self) -> Rc> { - self.into() - } - /// Creates a rand instance, pre-seeded with the current time in nanoseconds. /// Needs stdlib timer #[cfg(feature = "std")] pub fn preseeded() -> Self { - let seed = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_nanos() as u64; - Self::new(seed) + Self::new(current_nanos()) + } +} + +/// Extremely quick rand implementation +/// see https://arxiv.org/pdf/2002.11331.pdf +#[derive(Copy, Clone, Debug, Default)] +pub struct RomuTrioRand { + x_state: u64, + y_state: u64, + z_state: u64, +} + +impl RomuTrioRand { + pub fn new(seed: u64) -> Self { + let mut rand = Self::default(); + rand.set_seed(seed); + rand + } + + /// Creates a rand instance, pre-seeded with the current time in nanoseconds. + /// Needs stdlib timer + #[cfg(feature = "std")] + pub fn preseeded() -> Self { + Self::new(current_nanos()) + } +} + +impl Rand for RomuTrioRand { + fn set_seed(&mut self, seed: u64) { + self.x_state = seed ^ 0x12345; + self.y_state = seed ^ 0x6789A; + self.z_state = seed ^ 0xBCDEF; + } + + #[inline] + fn next(&mut self) -> u64 { + let xp = self.x_state; + let yp = self.y_state; + let zp = self.z_state; + self.x_state = 15241094284759029579u64.wrapping_mul(zp); + self.y_state = yp.wrapping_sub(xp).rotate_left(12); + self.z_state = zp.wrapping_sub(yp).rotate_left(44); + xp + } +} + +/// see https://arxiv.org/pdf/2002.11331.pdf +#[derive(Copy, Clone, Debug, Default)] +pub struct RomuDuoJrRand { + x_state: u64, + y_state: u64, +} + +impl RomuDuoJrRand { + pub fn new(seed: u64) -> Self { + let mut rand = Self::default(); + rand.set_seed(seed); + rand + } +} + +impl Rand for RomuDuoJrRand { + fn set_seed(&mut self, seed: u64) { + self.x_state = seed ^ 0x12345; + self.y_state = seed ^ 0x6789A; + } + + #[inline] + fn next(&mut self) -> u64 { + let xp = self.x_state; + self.x_state = 15241094284759029579u64.wrapping_mul(self.y_state); + self.y_state = self.y_state.wrapping_sub(xp).rotate_left(27); + xp } }