From 94d6196e3aaf6803d270f79bd80c82582942b8e6 Mon Sep 17 00:00:00 2001 From: jewelofchaos9 Date: Tue, 30 Sep 2025 08:13:41 +0000 Subject: [PATCH 1/6] fix array get/set --- .../ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs | 6 -- .../fuzzer/src/fuzz_lib/block_context.rs | 79 ++++++------------- tooling/ssa_fuzzer/src/typed_value.rs | 11 +++ 3 files changed, 34 insertions(+), 62 deletions(-) diff --git a/tooling/ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs b/tooling/ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs index bf60a4e424f..4e207d189a3 100644 --- a/tooling/ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs +++ b/tooling/ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs @@ -48,18 +48,12 @@ libfuzzer_sys::fuzz_target!(|data: &[u8]| -> Corpus { // Disable some instructions with bugs that are not fixed yet let instruction_options = InstructionOptions { - // https://github.com/noir-lang/noir/issues/9707 - shr_enabled: false, - shl_enabled: false, // https://github.com/noir-lang/noir/issues/9437 array_get_enabled: false, array_set_enabled: false, // https://github.com/noir-lang/noir/issues/9559 point_add_enabled: false, multi_scalar_mul_enabled: false, - // https://github.com/noir-lang/noir/issues/9619 - ecdsa_secp256k1_enabled: false, - ecdsa_secp256r1_enabled: false, ..InstructionOptions::default() }; let modes = vec![FuzzerMode::NonConstant]; diff --git a/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/block_context.rs b/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/block_context.rs index 4dd14786366..1b94bd53e48 100644 --- a/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/block_context.rs +++ b/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/block_context.rs @@ -355,12 +355,8 @@ impl BlockContext { /*is constant =*/ false, safe_index, ); - if let Some((value, is_references)) = value { - if !is_references { - self.store_variable(&value); - } else { - panic!("References are not supported for array get with dynamic index"); - } + if let Some(value) = value { + self.store_variable(&value); } } Instruction::ArraySet { array_index, index, value_index, safe_index } => { @@ -384,22 +380,16 @@ impl BlockContext { value_index, safe_index, ); - if let Some((new_array, is_references)) = new_array { - if is_references { - panic!("References are not supported for array set with dynamic index"); - } - let element_type = new_array.type_of_variable.unwrap_array_element_type(); - match element_type { - Type::Numeric(_element_type) => { - self.store_variable(&new_array); - } - _ => panic!("Expected NumericType, found {element_type:?}"), - } + if let Some(new_array) = new_array { + self.store_variable(&new_array); } } Instruction::ArrayGetWithConstantIndex { array_index, index, safe_index } => { + // Array index should be limited to 32 bits + // Otherwise it fails at compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs:133:40: + let index_32_bits = index & (u32::MAX as usize); // insert constant index - let index_id = builder.insert_constant(index, NumericType::U32); + let index_id = builder.insert_constant(index_32_bits, NumericType::U32); let value = self.insert_array_get( builder, array_index, @@ -407,7 +397,7 @@ impl BlockContext { /*is constant =*/ true, safe_index, ); - if let Some((value, _is_references)) = value { + if let Some(value) = value { self.store_variable(&value); } } @@ -417,8 +407,11 @@ impl BlockContext { value_index, safe_index, } => { + // Array index should be limited to 32 bits + // Otherwise it fails at compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs:133:40: + let index_32_bits = index & (u32::MAX as usize); // insert constant index - let index_id = builder.insert_constant(index, NumericType::U32); + let index_id = builder.insert_constant(index_32_bits, NumericType::U32); let new_array = self.insert_array_set( builder, array_index, @@ -427,34 +420,8 @@ impl BlockContext { value_index, safe_index, ); - if let Some((new_array, is_references)) = new_array { - let element_type = match new_array.type_of_variable.clone() { - Type::Array(elements_type, _) => elements_type[0].clone(), - _ => panic!("Expected ArrayType, found {:?}", new_array.type_of_variable), - }; - match element_type { - Type::Numeric(_element_type) => { - assert!( - !is_references, - "Encountered numeric element in an array with references" - ); - self.store_variable(&new_array); - } - Type::Reference(type_ref) => { - assert!( - is_references, - "Encountered reference element in an array without references" - ); - assert!( - type_ref.is_numeric(), - "Expected reference to a numeric type, found {type_ref:?}" - ); - self.store_variable(&new_array); - } - _ => { - panic!("Expected NumericType or ReferenceType, found {element_type:?}") - } - } + if let Some(new_array) = new_array { + self.store_variable(&new_array); } } Instruction::FieldToBytesToField { field_idx } => { @@ -769,7 +736,7 @@ impl BlockContext { /// * `safe_index` - If true, the index will be taken modulo the array length /// /// # Returns - /// * (TypedValue, is_references) + /// * TypedValue /// * None if the instruction is not enabled or the array is not stored fn insert_array_get( &mut self, @@ -778,7 +745,7 @@ impl BlockContext { index: TypedValue, index_is_constant: bool, safe_index: bool, - ) -> Option<(TypedValue, bool)> { + ) -> Option { if !self.options.instruction_options.array_get_enabled || !self.options.instruction_options.create_array_enabled { @@ -797,7 +764,7 @@ impl BlockContext { _ => return None, }; // references are not supported for array get with dynamic index - if array.type_of_variable.is_reference() && !index_is_constant { + if array.type_of_variable.type_contains_reference() && !index_is_constant { return None; } // cast the index to u32 @@ -808,7 +775,7 @@ impl BlockContext { array.type_of_variable.unwrap_array_element_type(), safe_index, ); - Some((value, array.type_of_variable.is_reference())) + Some(value) } /// Inserts an array set instruction @@ -821,7 +788,7 @@ impl BlockContext { /// * `safe_index` - If true, the index will be taken modulo the array length /// /// # Returns - /// * (TypedValue referencing the new array, is_references) + /// * TypedValue referencing the new array /// * None if the instruction is not enabled or the array is not stored fn insert_array_set( &mut self, @@ -831,7 +798,7 @@ impl BlockContext { index_is_constant: bool, value_index: usize, safe_index: bool, - ) -> Option<(TypedValue, bool)> { + ) -> Option { if !self.options.instruction_options.array_set_enabled { return None; } @@ -849,7 +816,7 @@ impl BlockContext { }; let is_array_of_references = - array.type_of_variable.unwrap_array_element_type().is_reference(); + array.type_of_variable.unwrap_array_element_type().type_contains_reference(); // get the array from the stored arrays // references are not supported for array set with dynamic index if is_array_of_references && !index_is_constant { @@ -863,7 +830,7 @@ impl BlockContext { }; let new_array = builder.insert_array_set(array.clone(), index.clone(), value.clone(), safe_index); - Some((new_array, is_array_of_references)) + Some(new_array) } pub(crate) fn insert_instructions( diff --git a/tooling/ssa_fuzzer/src/typed_value.rs b/tooling/ssa_fuzzer/src/typed_value.rs index a3b69b67714..9a0017ebae3 100644 --- a/tooling/ssa_fuzzer/src/typed_value.rs +++ b/tooling/ssa_fuzzer/src/typed_value.rs @@ -91,6 +91,17 @@ impl Type { matches!(self, Type::Reference(_)) } + pub fn type_contains_reference(&self) -> bool { + match self { + Type::Reference(_) => true, + Type::Array(element_types, _) => { + element_types.iter().any(|t| t.type_contains_reference()) + } + Type::Slice(element_types) => element_types.iter().any(|t| t.type_contains_reference()), + Type::Numeric(_) => false, + } + } + pub fn is_array(&self) -> bool { matches!(self, Type::Array(_, _)) } From bed25b2407ab393f04a23bf98947b66ccccb8aac Mon Sep 17 00:00:00 2001 From: jewelofchaos9 Date: Tue, 30 Sep 2025 08:43:00 +0000 Subject: [PATCH 2/6] smol fix brillig --- tooling/ssa_fuzzer/fuzzer/src/brillig.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tooling/ssa_fuzzer/fuzzer/src/brillig.rs b/tooling/ssa_fuzzer/fuzzer/src/brillig.rs index fad86062f7e..3fab2fe0f20 100644 --- a/tooling/ssa_fuzzer/fuzzer/src/brillig.rs +++ b/tooling/ssa_fuzzer/fuzzer/src/brillig.rs @@ -238,7 +238,15 @@ impl SimulatorProcess { .map_err(|e| format!("Failed to decode simulator response from base64: {e}")) { Ok(response_line) => response_line, - Err(e) => panic!("Failed to decode simulator response: {e}"), + Err(e) => { + if e.to_string().contains("unexpected end of file") { + log::warn!("Unexpected end of file, recreating simulator"); + recreate_simulator().expect("Failed to recreate simulator"); + return self.execute(bytecode, inputs); + } else { + panic!("Failed to decode simulator response: {e}"); + } + } }; let gz_decode_step = Instant::now(); From e4c8eb884fbacdcbd5185437dc0034ec91a2823b Mon Sep 17 00:00:00 2001 From: jewelofchaos9 Date: Tue, 30 Sep 2025 09:11:30 +0000 Subject: [PATCH 3/6] comment why some brillig ops are disabled --- tooling/ssa_fuzzer/fuzzer/src/brillig.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tooling/ssa_fuzzer/fuzzer/src/brillig.rs b/tooling/ssa_fuzzer/fuzzer/src/brillig.rs index 3fab2fe0f20..c0ae354951a 100644 --- a/tooling/ssa_fuzzer/fuzzer/src/brillig.rs +++ b/tooling/ssa_fuzzer/fuzzer/src/brillig.rs @@ -363,16 +363,18 @@ libfuzzer_sys::fuzz_target!( // You can disable some instructions with bugs that are not fixed yet let modes = vec![FuzzerMode::NonConstant]; let instruction_options = InstructionOptions { - array_get_enabled: false, - array_set_enabled: false, + // https://github.com/AztecProtocol/aztec-packages/issues/17182 + // all of them use to_le_radix ecdsa_secp256k1_enabled: false, ecdsa_secp256r1_enabled: false, blake2s_hash_enabled: false, blake3_hash_enabled: false, aes128_encrypt_enabled: false, field_to_bytes_to_field_enabled: false, + // https://github.com/AztecProtocol/aztec-packages/issues/16948 point_add_enabled: false, multi_scalar_mul_enabled: false, + // https://github.com/AztecProtocol/aztec-packages/issues/16944 shl_enabled: false, shr_enabled: false, ..InstructionOptions::default() From fd6c4de1bb9e19f2e022f42e0b6b406d5918e7de Mon Sep 17 00:00:00 2001 From: jewelofchaos9 Date: Tue, 30 Sep 2025 09:14:44 +0000 Subject: [PATCH 4/6] fixie wixie dixie fix --- tooling/ssa_fuzzer/fuzzer/src/brillig.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tooling/ssa_fuzzer/fuzzer/src/brillig.rs b/tooling/ssa_fuzzer/fuzzer/src/brillig.rs index c0ae354951a..080642612f1 100644 --- a/tooling/ssa_fuzzer/fuzzer/src/brillig.rs +++ b/tooling/ssa_fuzzer/fuzzer/src/brillig.rs @@ -252,12 +252,21 @@ impl SimulatorProcess { let gz_decode_step = Instant::now(); let mut gz_decoder = GzDecoder::new(response_line_gzip.as_slice()); let mut response_line = Vec::new(); - let result = gz_decoder + match gz_decoder .read_to_end(&mut response_line) - .map_err(|e| format!("Failed to read simulator response: {e}")); - if result.is_err() { - panic!("Failed to read simulator response, gzip decoder: {}", result.err().unwrap()); - } + .map_err(|e| format!("Failed to read simulator response: {e}")) + { + Ok(_) => (), + Err(e) => { + if e.to_string().contains("unexpected end of file") { + log::warn!("Unexpected end of file, recreating simulator"); + recreate_simulator().expect("Failed to recreate simulator"); + return self.execute(bytecode, inputs); + } else { + panic!("Failed to decode simulator response: {e}"); + } + } + }; let response_line = String::from_utf8(response_line).unwrap(); log::debug!("Gz decoding response time {:?}", gz_decode_step.elapsed()); log::debug!("Decoding response time {:?}", decode_step.elapsed()); From 462bf611517c1dcdf44aa59279d007984cccea23 Mon Sep 17 00:00:00 2001 From: jewelofchaos9 Date: Tue, 30 Sep 2025 13:04:15 +0000 Subject: [PATCH 5/6] fix when one failed to compile and other failed to execute --- tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs b/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs index 3ad3e8f7a96..ec8fc46d2cc 100644 --- a/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs +++ b/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs @@ -102,8 +102,20 @@ impl FuzzerOutput { pub(crate) fn compare_results(&self, other: &Self) -> CompareResults { match (self.is_program_compiled(), other.is_program_compiled()) { (false, false) => CompareResults::BothFailed, - (true, false) => CompareResults::LeftCompilationFailed, - (false, true) => CompareResults::RightCompilationFailed, + (true, false) => { + if self.get_return_witnesses().is_empty() { + CompareResults::BothFailed + } else { + CompareResults::LeftCompilationFailed + } + } + (false, true) => { + if other.get_return_witnesses().is_empty() { + CompareResults::BothFailed + } else { + CompareResults::RightCompilationFailed + } + } (true, true) => { // both programs compiled successfully let left_return_witnesses = self.get_return_witnesses(); From e6a38fda0e3e1ef0097270353186647373feb119 Mon Sep 17 00:00:00 2001 From: jewelofchaos9 Date: Tue, 30 Sep 2025 17:18:06 +0000 Subject: [PATCH 6/6] fix fix fix fix fix fix --- tooling/ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs | 3 +++ tooling/ssa_fuzzer/fuzzer/src/brillig.rs | 3 +++ tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tooling/ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs b/tooling/ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs index 4e207d189a3..3f4e8c5b748 100644 --- a/tooling/ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs +++ b/tooling/ssa_fuzzer/fuzzer/src/acir_vs_brillig.rs @@ -54,6 +54,9 @@ libfuzzer_sys::fuzz_target!(|data: &[u8]| -> Corpus { // https://github.com/noir-lang/noir/issues/9559 point_add_enabled: false, multi_scalar_mul_enabled: false, + // https://github.com/noir-lang/noir/issues/10037 + ecdsa_secp256k1_enabled: false, + ecdsa_secp256r1_enabled: false, ..InstructionOptions::default() }; let modes = vec![FuzzerMode::NonConstant]; diff --git a/tooling/ssa_fuzzer/fuzzer/src/brillig.rs b/tooling/ssa_fuzzer/fuzzer/src/brillig.rs index 080642612f1..45f134b6b93 100644 --- a/tooling/ssa_fuzzer/fuzzer/src/brillig.rs +++ b/tooling/ssa_fuzzer/fuzzer/src/brillig.rs @@ -386,6 +386,9 @@ libfuzzer_sys::fuzz_target!( // https://github.com/AztecProtocol/aztec-packages/issues/16944 shl_enabled: false, shr_enabled: false, + + //https://github.com/noir-lang/noir/issues/10035 + unsafe_get_set_enabled: false, ..InstructionOptions::default() }; let fuzzer_command_options = diff --git a/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs b/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs index ec8fc46d2cc..55da7513a9b 100644 --- a/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs +++ b/tooling/ssa_fuzzer/fuzzer/src/fuzz_lib/fuzzer.rs @@ -106,14 +106,14 @@ impl FuzzerOutput { if self.get_return_witnesses().is_empty() { CompareResults::BothFailed } else { - CompareResults::LeftCompilationFailed + CompareResults::RightCompilationFailed } } (false, true) => { if other.get_return_witnesses().is_empty() { CompareResults::BothFailed } else { - CompareResults::RightCompilationFailed + CompareResults::LeftCompilationFailed } } (true, true) => {