Skip to content
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
18 changes: 0 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tooling/ast_fuzzer/src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn arb_value_from_abi_type(
IntStrategy::new(width as usize)
.prop_map(move |mut int| {
if int < 0 {
int += shift
int += shift;
}
InputValue::Field(int.into())
})
Expand Down
4 changes: 4 additions & 0 deletions tooling/ast_fuzzer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#![forbid(unsafe_code)]
#![warn(clippy::semicolon_if_nothing_returned)]
#![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))]

mod abi;
pub mod compare;
mod input;
Expand Down
2 changes: 1 addition & 1 deletion tooling/ast_fuzzer/src/program/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ impl<'a> FunctionContext<'a> {
if types::is_unit(typ) && u.ratio(4, 5)? {
// ending a unit block with `<stmt>;` looks better than a `()` but both are valid.
// NB the AST printer puts a `;` between all statements, including after `if` and `for`.
stmts.push(Expression::Semi(Box::new(self.gen_stmt(u)?)))
stmts.push(Expression::Semi(Box::new(self.gen_stmt(u)?)));
} else {
stmts.push(self.gen_expr(u, typ, max_depth, Flags::TOP)?);
}
Expand Down
4 changes: 2 additions & 2 deletions tooling/ast_fuzzer/src/program/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ pub fn visit_expr<V>(expr: &Expression, v: &mut V)
where
V: FnMut(&Expression) -> bool,
{
visit_expr_be(expr, &mut |e| (v(e), ()), &mut |_, _| {})
visit_expr_be(expr, &mut |e| (v(e), ()), &mut |_, _| {});
}

/// Visit the contents of an [Expression] representing the AST,
Expand Down Expand Up @@ -293,7 +293,7 @@ where
Expression::Continue => {}
}

e(expr, token)
e(expr, token);
}

fn visit_lvalue<B, E, T>(lvalue: &LValue, b: &mut B, e: &mut E)
Expand Down
4 changes: 3 additions & 1 deletion tooling/greybox_fuzzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ rand.workspace = true
num-traits.workspace = true
fm.workspace=true
rayon.workspace = true
num-bigint.workspace = true

rand_xorshift="0.3.0"
walkdir = "2.5.0"
sha256={ version = "1.5.0", default-features = false }
termcolor = "1.1.2"

[dev-dependencies]
num-bigint.workspace = true
6 changes: 3 additions & 3 deletions tooling/greybox_fuzzer/src/corpus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,12 @@ impl Sequence {

/// Resets the sequence by setting remaining executions to 0
pub fn clear(&mut self) {
self.executions_left = 0
self.executions_left = 0;
}

/// Decrements the number of remaining executions by 1
pub fn decrement(&mut self) {
self.executions_left -= 1
self.executions_left -= 1;
}
}

Expand Down Expand Up @@ -377,7 +377,7 @@ impl Corpus {
self.corpus_file_manager.save_testcase_to_disk(
&serialize_to_json(&new_testcase_value, &self.corpus_file_manager.abi)
.expect("Shouldn't be any issues with serializing input map"),
)?
)?;
}
self.brillig_orchestrator.new_testcase(testcase_id);
self.acir_orchestrator.new_testcase(testcase_id);
Expand Down
2 changes: 1 addition & 1 deletion tooling/greybox_fuzzer/src/dictionary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn build_dictionary_from_circuit<F: AcirField>(circuit: &Circuit<F>) -> HashSet<
}
}
if let Some(predicate) = predicate {
insert_expr(&mut constants, predicate)
insert_expr(&mut constants, predicate);
}
}

Expand Down
8 changes: 6 additions & 2 deletions tooling/greybox_fuzzer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#![forbid(unsafe_code)]
#![warn(clippy::semicolon_if_nothing_returned)]
#![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))]

use core::panic;
use std::{
cmp::max,
Expand Down Expand Up @@ -223,7 +227,7 @@ impl Metrics {
pub fn increase_processed_testcase_count(&mut self, update: &usize) {
self.processed_testcase_count += update;
}
pub fn increment_removed_testcase_count(&mut self) {
fn increment_removed_testcase_count(&mut self) {
self.removed_testcase_count += 1;
self.removed_testcase_last_round = true;
}
Expand Down Expand Up @@ -770,7 +774,7 @@ impl<
.increase_total_brillig_duration_micros(&fast_result.brillig_duration_micros());
self.metrics.increase_total_mutation_time(&fast_result.mutation_time());
if !fast_result.skip_check() {
analysis_queue.push(index)
analysis_queue.push(index);
}
}

Expand Down
78 changes: 38 additions & 40 deletions tooling/greybox_fuzzer/src/mutation/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
//! There are configurations for determining probability of each top-level and low-level mutation
//! Currently, the configurations are constant and "new" methods aren't used, but the architecture is prepared for easier introduction of MOpt (Mutation Optimization) technique in the future

use std::sync::OnceLock;

use super::configurations::{
BASIC_FIELD_ELEMENT_DICTIONARY_UPDATE_CONFIGURATION,
BASIC_FIELD_ELEMENT_POW_2_UPDATE_CONFIGURATION,
Expand All @@ -44,10 +46,25 @@ use rand_xorshift::XorShiftRng;
const SMALL_VALUE_MAX: u64 = 0xff;
const SMALL_VALUE_MIN: u64 = 1;

static mut POWERS_OF_TWO_INITIALIZED: bool = false;
static mut POWERS_OF_TWO: Vec<FieldElement> = Vec::new();
static mut INVERSE_POWERS_OF_TWO: Vec<FieldElement> = Vec::new();
static mut POWERS_OF_TWO_MINUS_ONE: Vec<FieldElement> = Vec::new();
fn powers_of_two() -> &'static Vec<FieldElement> {
static INSTANCE: OnceLock<Vec<FieldElement>> = OnceLock::new();
INSTANCE.get_or_init(|| {
(1..=MAX_POW_2)
.map(|i| FieldElement::from(2i128).pow(&FieldElement::from(i)))
.collect::<Vec<FieldElement>>()
})
}

fn powers_of_two_minus_one() -> &'static Vec<FieldElement> {
static INSTANCE: OnceLock<Vec<FieldElement>> = OnceLock::new();
INSTANCE.get_or_init(|| powers_of_two().iter().map(|x| *x - FieldElement::one()).collect())
}

fn inverse_powers_of_two() -> &'static Vec<FieldElement> {
static INSTANCE: OnceLock<Vec<FieldElement>> = OnceLock::new();
INSTANCE
.get_or_init(|| powers_of_two().iter().map(|p| p.inverse()).collect::<Vec<FieldElement>>())
}

// We are using bn254 scalar field so 254 is enough
const MAX_POW_2: usize = 254;
Expand All @@ -60,22 +77,6 @@ struct FieldMutator<'a> {
impl<'a> FieldMutator<'a> {
pub fn new(dictionary: &'a Vec<FieldElement>, prng: &'a mut XorShiftRng) -> Self {
// Initialize powers of two if we haven't done that yet
unsafe {
if !POWERS_OF_TWO_INITIALIZED {
let powers_of_two = (1..=MAX_POW_2)
.map(|i| FieldElement::from(2i128).pow(&FieldElement::from(i)))
.collect::<Vec<FieldElement>>();
INVERSE_POWERS_OF_TWO =
powers_of_two.iter().map(|p| p.inverse()).collect::<Vec<FieldElement>>();

POWERS_OF_TWO_MINUS_ONE =
powers_of_two.iter().map(|x| *x - FieldElement::from(1i128)).collect();

POWERS_OF_TWO = powers_of_two;
POWERS_OF_TWO_INITIALIZED = true;
}
};

assert!(!dictionary.is_empty());
Self { dictionary, prng }
}
Expand All @@ -89,12 +90,12 @@ impl<'a> FieldMutator<'a> {
FieldElementSubstitutionMutationOptions::Dictionary => {
*self.dictionary.choose(self.prng).unwrap()
}
FieldElementSubstitutionMutationOptions::PowerOfTwo => unsafe {
*POWERS_OF_TWO.choose(self.prng).unwrap()
},
FieldElementSubstitutionMutationOptions::PowerOfTwoMinusOne => unsafe {
*POWERS_OF_TWO_MINUS_ONE.choose(self.prng).unwrap()
},
FieldElementSubstitutionMutationOptions::PowerOfTwo => {
*powers_of_two().choose(self.prng).unwrap()
}
FieldElementSubstitutionMutationOptions::PowerOfTwoMinusOne => {
*powers_of_two_minus_one().choose(self.prng).unwrap()
}
}
}

Expand All @@ -107,9 +108,8 @@ impl<'a> FieldMutator<'a> {

#[allow(static_mut_refs)]
fn apply_pow_2_update(&mut self, element: FieldElement) -> FieldElement {
let chosen_power_of_two = unsafe { POWERS_OF_TWO.choose(self.prng).unwrap() };
let chosen_inverse_power_of_two =
unsafe { INVERSE_POWERS_OF_TWO.choose(self.prng).unwrap() };
let chosen_power_of_two = powers_of_two().choose(self.prng).unwrap();
let chosen_inverse_power_of_two = inverse_powers_of_two().choose(self.prng).unwrap();
match BASIC_FIELD_ELEMENT_POW_2_UPDATE_CONFIGURATION.select(self.prng) {
FieldElementPow2UpdateOptions::Addition => element + *chosen_power_of_two,
FieldElementPow2UpdateOptions::Subtraction => element - *chosen_power_of_two,
Expand Down Expand Up @@ -176,7 +176,7 @@ impl<'a> FieldMutator<'a> {
/// * `previous_input` - The input value to mutate, must be a Field variant
/// * `dictionary` - A vector of interesting field element values to use in mutations
/// * `prng` - Random number generator for selecting mutations
pub fn mutate_field_input_value(
pub(super) fn mutate_field_input_value(
previous_input: &InputValue,
dictionary: &Vec<FieldElement>,
prng: &mut XorShiftRng,
Expand Down Expand Up @@ -209,8 +209,8 @@ mod tests {
|| result == FieldElement::from(1u32)
|| result == -FieldElement::from(1u32)
|| result == FieldElement::from(42u32)
|| unsafe { POWERS_OF_TWO.contains(&result) }
|| unsafe { POWERS_OF_TWO_MINUS_ONE.contains(&result) }
|| powers_of_two().contains(&result)
|| powers_of_two_minus_one().contains(&result)
);
}

Expand Down Expand Up @@ -241,14 +241,12 @@ mod tests {
// Verify result is different from input
assert_ne!(result, element);
// Result should be element combined with a power of 2 via +,-,*,/
assert!(unsafe {
POWERS_OF_TWO.iter().any(|p| {
result == element + *p
|| result == element - *p
|| result == element * *p
|| result == element * p.inverse()
})
});
assert!(powers_of_two().iter().any(|p| {
result == element + *p
|| result == element - *p
|| result == element * *p
|| result == element * p.inverse()
}));
}
}

Expand Down
22 changes: 2 additions & 20 deletions tooling/ssa_fuzzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,14 @@ noirc_driver.workspace = true
noirc_abi.workspace = true
acvm.workspace = true
bn254_blackbox_solver.workspace = true
fxhash.workspace = true
iter-extended.workspace = true
thiserror.workspace = true
num-bigint = "0.4"
im.workspace = true
serde.workspace = true
serde_json.workspace = true
serde_with = "3.2.0"
tracing.workspace = true
chrono = "0.4.37"
rayon.workspace = true
cfg-if.workspace = true
thiserror.workspace = true
nargo = { path = "../nargo", features = ["rpc"] }
smallvec = { version = "1.13.2", features = ["serde"] }
libfuzzer-sys = { version = "0.4.0", features = ["arbitrary-derive"] }
vec-collections = "0.4.3"
env_logger = "0.11.6"
log = "0.4"
rand = "0.8"

[dev-dependencies]
proptest.workspace = true
similar-asserts.workspace = true
tracing-test = "0.2.5"
num-traits.workspace = true
test-case.workspace = true
rand.workspace = true

[features]
bn254 = ["noirc_frontend/bn254"]
Expand Down
6 changes: 5 additions & 1 deletion tooling/ssa_fuzzer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#![allow(dead_code)]
#![forbid(unsafe_code)]
#![warn(unreachable_pub)]
#![warn(clippy::semicolon_if_nothing_returned)]
#![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))]

pub mod builder;
pub mod compiler;
pub mod config;
Expand Down
Loading