From 9b4c0f3327badfe390eb012baae1eba257ea9133 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 17:20:03 -0300 Subject: [PATCH 01/13] Use Circuit parser in simulator tests --- acvm-repo/acvm/src/compiler/simulator.rs | 157 ++++++----------------- 1 file changed, 40 insertions(+), 117 deletions(-) diff --git a/acvm-repo/acvm/src/compiler/simulator.rs b/acvm-repo/acvm/src/compiler/simulator.rs index 2917080a93d..54d619e2f06 100644 --- a/acvm-repo/acvm/src/compiler/simulator.rs +++ b/acvm-repo/acvm/src/compiler/simulator.rs @@ -193,147 +193,70 @@ impl CircuitSimulator { #[cfg(test)] mod tests { - use std::collections::BTreeSet; - use crate::compiler::CircuitSimulator; - use acir::{ - FieldElement, - acir_field::AcirField, - circuit::{ - Circuit, Opcode, PublicInputs, - brillig::{BrilligFunctionId, BrilligInputs}, - opcodes::{BlockId, BlockType, MemOp}, - }, - native_types::{Expression, Witness}, - }; - - fn test_circuit( - opcodes: Vec>, - private_parameters: BTreeSet, - public_parameters: PublicInputs, - ) -> Circuit { - Circuit { - function_name: "test_circuit".to_string(), - current_witness_index: 1, - opcodes, - private_parameters, - public_parameters, - return_values: PublicInputs::default(), - assert_messages: Default::default(), - } - } + use acir::circuit::Circuit; #[test] fn reports_true_for_empty_circuit() { - let empty_circuit = test_circuit(vec![], BTreeSet::default(), PublicInputs::default()); - + let src = " + private parameters: [] + public parameters: [] + return values: [] + "; + let empty_circuit = Circuit::from_str(src).unwrap(); assert!(CircuitSimulator::default().check_circuit(&empty_circuit).is_none()); } #[test] fn reports_true_for_connected_circuit() { - let connected_circuit = test_circuit( - vec![Opcode::AssertZero(Expression { - mul_terms: Vec::new(), - linear_combinations: vec![ - (FieldElement::one(), Witness(1)), - (-FieldElement::one(), Witness(2)), - ], - q_c: FieldElement::zero(), - })], - BTreeSet::from([Witness(1)]), - PublicInputs::default(), - ); - + let src = " + private parameters: [w1] + public parameters: [] + return values: [] + ASSERT w2 = w1 + "; + let connected_circuit = Circuit::from_str(src).unwrap(); assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); } #[test] fn reports_false_for_disconnected_circuit() { - let disconnected_circuit = test_circuit( - vec![ - Opcode::AssertZero(Expression { - mul_terms: Vec::new(), - linear_combinations: vec![ - (FieldElement::one(), Witness(1)), - (-FieldElement::one(), Witness(2)), - ], - q_c: FieldElement::zero(), - }), - Opcode::AssertZero(Expression { - mul_terms: Vec::new(), - linear_combinations: vec![ - (FieldElement::one(), Witness(3)), - (-FieldElement::one(), Witness(4)), - ], - q_c: FieldElement::zero(), - }), - ], - BTreeSet::from([Witness(1)]), - PublicInputs::default(), - ); - + let src = " + private parameters: [w1] + public parameters: [] + return values: [] + ASSERT w2 = w1 + ASSERT w4 = w3 + "; + let disconnected_circuit = Circuit::from_str(src).unwrap(); assert!(CircuitSimulator::default().check_circuit(&disconnected_circuit).is_some()); } #[test] fn reports_true_when_memory_block_passed_to_brillig_and_then_written_to() { - let circuit = test_circuit( - vec![ - Opcode::AssertZero(Expression { - mul_terms: Vec::new(), - linear_combinations: vec![(FieldElement::one(), Witness(1))], - q_c: FieldElement::zero(), - }), - Opcode::MemoryInit { - block_id: BlockId(0), - init: vec![Witness(0)], - block_type: BlockType::Memory, - }, - Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![BrilligInputs::MemoryArray(BlockId(0))], - outputs: Vec::new(), - predicate: None, - }, - Opcode::MemoryOp { - block_id: BlockId(0), - op: MemOp::read_at_mem_index( - Expression { - mul_terms: Vec::new(), - linear_combinations: Vec::new(), - q_c: FieldElement::one(), - }, - Witness(2), - ), - }, - ], - BTreeSet::from([Witness(1)]), - PublicInputs::default(), - ); - + let src = " + private parameters: [w1] + public parameters: [] + return values: [] + ASSERT w1 = 0 + INIT b0 = [w0] + BRILLIG CALL func: 0, inputs: [b0], outputs: [] + READ w2 = b0[1] + "; + let circuit = Circuit::from_str(src).unwrap(); assert!(CircuitSimulator::default().check_circuit(&circuit).is_some()); } #[test] fn reports_false_when_attempting_to_reinitialize_memory_block() { - let circuit = test_circuit( - vec![ - Opcode::MemoryInit { - block_id: BlockId(0), - init: vec![Witness(0)], - block_type: BlockType::Memory, - }, - Opcode::MemoryInit { - block_id: BlockId(0), - init: vec![Witness(0)], - block_type: BlockType::Memory, - }, - ], - BTreeSet::from([Witness(0)]), - PublicInputs::default(), - ); - + let src = " + private parameters: [w0] + public parameters: [] + return values: [] + INIT b0 = [w0] + INIT b0 = [w0] + "; + let circuit = Circuit::from_str(src).unwrap(); assert!(CircuitSimulator::default().check_circuit(&circuit).is_some()); } } From 1db93c75ed86ab3d4b67ac22035c0122017d4f94 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 17:24:11 -0300 Subject: [PATCH 02/13] Add a test --- acvm-repo/acvm/src/compiler/simulator.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/acvm-repo/acvm/src/compiler/simulator.rs b/acvm-repo/acvm/src/compiler/simulator.rs index 54d619e2f06..0a61e4b7702 100644 --- a/acvm-repo/acvm/src/compiler/simulator.rs +++ b/acvm-repo/acvm/src/compiler/simulator.rs @@ -259,4 +259,18 @@ mod tests { let circuit = Circuit::from_str(src).unwrap(); assert!(CircuitSimulator::default().check_circuit(&circuit).is_some()); } + + #[test] + fn reports_false_when_unknown_witness_is_multiplied_by_itself() { + // If an AssertZero contains just one unknown witness, it might still not possible + // to solve if: if that unknown witness is being multiplied by itself. + let src = " + private parameters: [w0] + public parameters: [] + return values: [] + ASSERT w0 = w1*w1 + "; + let circuit = Circuit::from_str(src).unwrap(); + assert!(CircuitSimulator::default().check_circuit(&circuit).is_some()); + } } From bfe27a1962897e32d9709e7674537b5f008570ae Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 17:30:08 -0300 Subject: [PATCH 03/13] Improve test names and fix test --- acvm-repo/acvm/src/compiler/simulator.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/acvm-repo/acvm/src/compiler/simulator.rs b/acvm-repo/acvm/src/compiler/simulator.rs index 0a61e4b7702..00399044906 100644 --- a/acvm-repo/acvm/src/compiler/simulator.rs +++ b/acvm-repo/acvm/src/compiler/simulator.rs @@ -197,7 +197,7 @@ mod tests { use acir::circuit::Circuit; #[test] - fn reports_true_for_empty_circuit() { + fn reports_none_for_empty_circuit() { let src = " private parameters: [] public parameters: [] @@ -208,7 +208,7 @@ mod tests { } #[test] - fn reports_true_for_connected_circuit() { + fn reports_none_for_connected_circuit() { let src = " private parameters: [w1] public parameters: [] @@ -220,7 +220,7 @@ mod tests { } #[test] - fn reports_false_for_disconnected_circuit() { + fn reports_some_for_disconnected_circuit() { let src = " private parameters: [w1] public parameters: [] @@ -229,26 +229,24 @@ mod tests { ASSERT w4 = w3 "; let disconnected_circuit = Circuit::from_str(src).unwrap(); - assert!(CircuitSimulator::default().check_circuit(&disconnected_circuit).is_some()); + assert_eq!(CircuitSimulator::default().check_circuit(&disconnected_circuit), Some(1)); } #[test] - fn reports_true_when_memory_block_passed_to_brillig_and_then_written_to() { + fn reports_some_when_memory_block_is_passed_an_unknown_witness() { let src = " private parameters: [w1] public parameters: [] return values: [] ASSERT w1 = 0 INIT b0 = [w0] - BRILLIG CALL func: 0, inputs: [b0], outputs: [] - READ w2 = b0[1] "; let circuit = Circuit::from_str(src).unwrap(); - assert!(CircuitSimulator::default().check_circuit(&circuit).is_some()); + assert_eq!(CircuitSimulator::default().check_circuit(&circuit), Some(1)); } #[test] - fn reports_false_when_attempting_to_reinitialize_memory_block() { + fn reports_some_when_attempting_to_reinitialize_memory_block() { let src = " private parameters: [w0] public parameters: [] @@ -257,11 +255,11 @@ mod tests { INIT b0 = [w0] "; let circuit = Circuit::from_str(src).unwrap(); - assert!(CircuitSimulator::default().check_circuit(&circuit).is_some()); + assert_eq!(CircuitSimulator::default().check_circuit(&circuit), Some(1)); } #[test] - fn reports_false_when_unknown_witness_is_multiplied_by_itself() { + fn reports_some_when_unknown_witness_is_multiplied_by_itself() { // If an AssertZero contains just one unknown witness, it might still not possible // to solve if: if that unknown witness is being multiplied by itself. let src = " @@ -271,6 +269,6 @@ mod tests { ASSERT w0 = w1*w1 "; let circuit = Circuit::from_str(src).unwrap(); - assert!(CircuitSimulator::default().check_circuit(&circuit).is_some()); + assert_eq!(CircuitSimulator::default().check_circuit(&circuit), Some(0)); } } From 4cfde500e806ec31f7fa3c868432d42604a8f4fb Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 17:35:12 -0300 Subject: [PATCH 04/13] Add some more tests --- acvm-repo/acvm/src/compiler/simulator.rs | 53 ++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/acvm-repo/acvm/src/compiler/simulator.rs b/acvm-repo/acvm/src/compiler/simulator.rs index 00399044906..1202efcaa16 100644 --- a/acvm-repo/acvm/src/compiler/simulator.rs +++ b/acvm-repo/acvm/src/compiler/simulator.rs @@ -219,6 +219,59 @@ mod tests { assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); } + #[test] + fn reports_none_for_blackbout_output() { + let src = " + private parameters: [w0, w1] + public parameters: [] + return values: [] + BLACKBOX::AND lhs: w0, rhs: w1, output: w2, bits: 32 + ASSERT w3 = w2 + "; + let connected_circuit = Circuit::from_str(src).unwrap(); + assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); + } + + #[test] + fn reports_none_for_read_memory() { + let src = " + private parameters: [w0] + public parameters: [] + return values: [] + INIT b0 = [w0] + READ w1 = b0[0] + ASSERT w2 = w1 + "; + let connected_circuit = Circuit::from_str(src).unwrap(); + assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); + } + + #[test] + fn reports_none_for_call_output() { + let src = " + private parameters: [w0] + public parameters: [] + return values: [] + CALL func: 0, inputs: [w0], outputs: [w1] + ASSERT w2 = w1 + "; + let connected_circuit = Circuit::from_str(src).unwrap(); + assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); + } + + #[test] + fn reports_none_for_brillig_call_output() { + let src = " + private parameters: [w0] + public parameters: [] + return values: [] + BRILLIG CALL func: 0, inputs: [w0], outputs: [w1] + ASSERT w2 = w1 + "; + let connected_circuit = Circuit::from_str(src).unwrap(); + assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); + } + #[test] fn reports_some_for_disconnected_circuit() { let src = " From c5eb07fe6459820526a79c1acc66f70c4cfd4242 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 17:37:43 -0300 Subject: [PATCH 05/13] Rename --- acvm-repo/acvm/src/compiler/simulator.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acvm-repo/acvm/src/compiler/simulator.rs b/acvm-repo/acvm/src/compiler/simulator.rs index 1202efcaa16..ba910d12efc 100644 --- a/acvm-repo/acvm/src/compiler/simulator.rs +++ b/acvm-repo/acvm/src/compiler/simulator.rs @@ -228,8 +228,8 @@ mod tests { BLACKBOX::AND lhs: w0, rhs: w1, output: w2, bits: 32 ASSERT w3 = w2 "; - let connected_circuit = Circuit::from_str(src).unwrap(); - assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); + let circuit = Circuit::from_str(src).unwrap(); + assert!(CircuitSimulator::default().check_circuit(&circuit).is_none()); } #[test] @@ -242,8 +242,8 @@ mod tests { READ w1 = b0[0] ASSERT w2 = w1 "; - let connected_circuit = Circuit::from_str(src).unwrap(); - assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); + let circuit = Circuit::from_str(src).unwrap(); + assert!(CircuitSimulator::default().check_circuit(&circuit).is_none()); } #[test] @@ -255,8 +255,8 @@ mod tests { CALL func: 0, inputs: [w0], outputs: [w1] ASSERT w2 = w1 "; - let connected_circuit = Circuit::from_str(src).unwrap(); - assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); + let circuit = Circuit::from_str(src).unwrap(); + assert!(CircuitSimulator::default().check_circuit(&circuit).is_none()); } #[test] @@ -268,8 +268,8 @@ mod tests { BRILLIG CALL func: 0, inputs: [w0], outputs: [w1] ASSERT w2 = w1 "; - let connected_circuit = Circuit::from_str(src).unwrap(); - assert!(CircuitSimulator::default().check_circuit(&connected_circuit).is_none()); + let circuit = Circuit::from_str(src).unwrap(); + assert!(CircuitSimulator::default().check_circuit(&circuit).is_none()); } #[test] From b7a41999ac8998d509762fd0556ebb8401a79e51 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 17:44:35 -0300 Subject: [PATCH 06/13] More circuit parsing --- tooling/debugger/src/context.rs | 96 +++++++++++---------------------- 1 file changed, 30 insertions(+), 66 deletions(-) diff --git a/tooling/debugger/src/context.rs b/tooling/debugger/src/context.rs index e08cfb5833e..5ca33f53834 100644 --- a/tooling/debugger/src/context.rs +++ b/tooling/debugger/src/context.rs @@ -1087,10 +1087,7 @@ mod tests { acir::{ AcirField, brillig::{HeapVector, IntegerBitSize}, - circuit::{ - brillig::{BrilligFunctionId, BrilligInputs, BrilligOutputs}, - opcodes::{AcirFunctionId, BlockId, BlockType}, - }, + circuit::brillig::{BrilligFunctionId, BrilligInputs}, native_types::Expression, }, blackbox_solver::StubbedBlackBoxSolver, @@ -1253,7 +1250,6 @@ mod tests { #[test] fn test_break_brillig_block_while_stepping_acir_opcodes() { let solver = StubbedBlackBoxSolver::default(); - let fe_0 = FieldElement::zero(); let fe_1 = FieldElement::one(); let w_x = Witness(1); let w_y = Witness(2); @@ -1297,32 +1293,16 @@ mod tests { }, ], }; - let opcodes = vec![ - // z = x + y - Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![ - BrilligInputs::Single(Expression { - linear_combinations: vec![(fe_1, w_x)], - ..Expression::default() - }), - BrilligInputs::Single(Expression { - linear_combinations: vec![(fe_1, w_y)], - ..Expression::default() - }), - ], - outputs: vec![BrilligOutputs::Simple(w_z)], - predicate: None, - }, - // x + y - z = 0 - Opcode::AssertZero(Expression { - mul_terms: vec![], - linear_combinations: vec![(fe_1, w_x), (fe_1, w_y), (-fe_1, w_z)], - q_c: fe_0, - }), - ]; - let current_witness_index = 3; - let circuit = Circuit { current_witness_index, opcodes, ..Circuit::default() }; + let src = format!( + " + private parameters: [] + public parameters: [] + return values: [] + BRILLIG CALL func: 0, inputs: [{w_x}, {w_y}], outputs: [{w_z}] + ASSERT {w_z} = {w_x} + {w_y} + " + ); + let circuit = Circuit::from_str(&src).unwrap(); let circuits = &[circuit]; let debug_symbols = vec![]; @@ -1391,41 +1371,25 @@ mod tests { bytecode: vec![BrilligOpcode::Return, BrilligOpcode::Return, BrilligOpcode::Return], }; - let circuit_one = Circuit { - opcodes: vec![ - Opcode::MemoryInit { - block_id: BlockId(0), - init: vec![], - block_type: BlockType::Memory, - }, - Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![], - outputs: vec![], - predicate: None, - }, - Opcode::Call { - id: AcirFunctionId(1), - inputs: vec![], - outputs: vec![], - predicate: None, - }, - Opcode::AssertZero(Expression::default()), - ], - ..Circuit::default() - }; - let circuit_two = Circuit { - opcodes: vec![ - Opcode::BrilligCall { - id: BrilligFunctionId(1), - inputs: vec![], - outputs: vec![], - predicate: None, - }, - Opcode::AssertZero(Expression::default()), - ], - ..Circuit::default() - }; + let src_one = " + private parameters: [] + public parameters: [] + return values: [] + INIT b0 = [] + BRILLIG CALL func: 0, inputs: [], outputs: [] + CALL func: 1, inputs: [], outputs: [] + ASSERT 0 = 0 + "; + let circuit_one = Circuit::from_str(src_one).unwrap(); + + let src_two = " + private parameters: [] + public parameters: [] + return values: [] + BRILLIG CALL func: 1, inputs: [], outputs: [] + ASSERT 0 = 0 + "; + let circuit_two = Circuit::from_str(src_two).unwrap(); let circuits = vec![circuit_one, circuit_two]; let debug_artifact = DebugArtifact { debug_symbols: vec![], file_map: BTreeMap::new() }; let brillig_functions = &[brillig_one, brillig_two]; From 1bd4e5b0a08bd7523980c5cc717da5b4a2c7f67f Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 17:52:59 -0300 Subject: [PATCH 07/13] More circuit parsing --- acvm-repo/acir/src/circuit/mod.rs | 106 +++++++++--------------------- 1 file changed, 31 insertions(+), 75 deletions(-) diff --git a/acvm-repo/acir/src/circuit/mod.rs b/acvm-repo/acir/src/circuit/mod.rs index b383aa64ca6..639c1d514bc 100644 --- a/acvm-repo/acir/src/circuit/mod.rs +++ b/acvm-repo/acir/src/circuit/mod.rs @@ -409,51 +409,24 @@ impl PublicInputs { #[cfg(test)] mod tests { - use std::collections::BTreeSet; - use super::{ - Circuit, Compression, Opcode, PublicInputs, + Circuit, Compression, Opcode, opcodes::{BlackBoxFuncCall, FunctionInput}, }; use crate::{circuit::Program, native_types::Witness}; use acir_field::{AcirField, FieldElement}; use serde::{Deserialize, Serialize}; - fn and_opcode() -> Opcode { - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::AND { - lhs: FunctionInput::Witness(Witness(1)), - rhs: FunctionInput::Witness(Witness(2)), - num_bits: 4, - output: Witness(3), - }) - } - - fn range_opcode() -> Opcode { - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { - input: FunctionInput::Witness(Witness(1)), - num_bits: 8, - }) - } - - fn keccakf1600_opcode() -> Opcode { - let inputs: Box<[FunctionInput; 25]> = - Box::new(std::array::from_fn(|i| FunctionInput::Witness(Witness(i as u32 + 1)))); - let outputs: Box<[Witness; 25]> = Box::new(std::array::from_fn(|i| Witness(i as u32 + 26))); - - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Keccakf1600 { inputs, outputs }) - } - #[test] fn serialization_roundtrip() { - let circuit = Circuit { - function_name: "test".to_string(), - current_witness_index: 5, - opcodes: vec![and_opcode::(), range_opcode()], - private_parameters: BTreeSet::new(), - public_parameters: PublicInputs(BTreeSet::from_iter(vec![Witness(2), Witness(12)])), - return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(4), Witness(12)])), - assert_messages: Default::default(), - }; + let src = " + private parameters: [] + public parameters: [w2, w12] + return values: [w4, w12] + BLACKBOX::AND lhs: w1, rhs: w2, output: w3, bits: 4 + BLACKBOX::RANGE input: w1, bits: 8 + "; + let circuit = Circuit::from_str(src).unwrap(); let program = Program { functions: vec![circuit], unconstrained_functions: Vec::new() }; fn read_write Deserialize<'a> + AcirField>( @@ -470,24 +443,16 @@ mod tests { #[test] fn test_serialize() { - let circuit = Circuit { - function_name: "test".to_string(), - current_witness_index: 0, - opcodes: vec![ - Opcode::AssertZero(crate::native_types::Expression { - mul_terms: vec![], - linear_combinations: vec![], - q_c: FieldElement::from(8u128), - }), - range_opcode(), - and_opcode(), - keccakf1600_opcode(), - ], - private_parameters: BTreeSet::new(), - public_parameters: PublicInputs(BTreeSet::from_iter(vec![Witness(2)])), - return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(2)])), - assert_messages: Default::default(), - }; + let src = " + private parameters: [] + public parameters: [w2] + return values: [w2] + ASSERT 0 = 8 + BLACKBOX::RANGE input: w1, bits: 8 + BLACKBOX::AND lhs: w1, rhs: w2, output: w3, bits: 4 + BLACKBOX::KECCAKF1600 inputs: [w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25], outputs: [w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36, w37, w38, w39, w40, w41, w42, w43, w44, w45, w46, w47, w48, w49, w50] + "; + let circuit = Circuit::from_str(src).unwrap(); let program = Program { functions: vec![circuit], unconstrained_functions: Vec::new() }; let json = serde_json::to_string_pretty(&program).unwrap(); @@ -516,27 +481,18 @@ mod tests { #[test] fn circuit_display_snapshot() { - let circuit = Circuit { - function_name: "test".to_string(), - current_witness_index: 3, - opcodes: vec![ - Opcode::AssertZero(crate::native_types::Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::from(2u128), Witness(1))], - q_c: FieldElement::from(8u128), - }), - range_opcode(), - and_opcode(), - keccakf1600_opcode(), - ], - private_parameters: BTreeSet::new(), - public_parameters: PublicInputs(BTreeSet::from_iter(vec![Witness(2)])), - return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(2)])), - assert_messages: Default::default(), - }; - - // We want to make sure that we witness indices are displayed in a unified format. - // All witnesses are expected to be formatted as `_{witness_index}`. + let src = " + private parameters: [] + public parameters: [w2] + return values: [w2] + ASSERT 0 = 2*w1 + 8 + BLACKBOX::RANGE input: w1, bits: 8 + BLACKBOX::AND lhs: w1, rhs: w2, output: w3, bits: 4 + BLACKBOX::KECCAKF1600 inputs: [w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24, w25], outputs: [w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36, w37, w38, w39, w40, w41, w42, w43, w44, w45, w46, w47, w48, w49, w50] + "; + let circuit = Circuit::from_str(src).unwrap(); + + // All witnesses are expected to be formatted as `w{witness_index}`. insta::assert_snapshot!( circuit.to_string(), @r" From af168e2cd7ad91c7d4762fb657d5898e9f8bf62b Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 17:59:58 -0300 Subject: [PATCH 08/13] Remove unused imports --- acvm-repo/acir/src/circuit/mod.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/acvm-repo/acir/src/circuit/mod.rs b/acvm-repo/acir/src/circuit/mod.rs index 639c1d514bc..24726d1b8a4 100644 --- a/acvm-repo/acir/src/circuit/mod.rs +++ b/acvm-repo/acir/src/circuit/mod.rs @@ -409,11 +409,8 @@ impl PublicInputs { #[cfg(test)] mod tests { - use super::{ - Circuit, Compression, Opcode, - opcodes::{BlackBoxFuncCall, FunctionInput}, - }; - use crate::{circuit::Program, native_types::Witness}; + use super::{Circuit, Compression}; + use crate::circuit::Program; use acir_field::{AcirField, FieldElement}; use serde::{Deserialize, Serialize}; From f66ad1116bada4e2b5c9c6d37c968ba050ec53b3 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 18:24:02 -0300 Subject: [PATCH 09/13] Use Expression parsing, and more Circuit parsing --- .../acir/src/native_types/expression/mod.rs | 31 +-- .../src/native_types/expression/operators.rs | 57 +--- acvm-repo/acir/src/parser/mod.rs | 24 ++ .../acir/tests/test_program_serialization.rs | 263 +++++------------- 4 files changed, 105 insertions(+), 270 deletions(-) diff --git a/acvm-repo/acir/src/native_types/expression/mod.rs b/acvm-repo/acir/src/native_types/expression/mod.rs index 7b45c654938..8bb07226529 100644 --- a/acvm-repo/acir/src/native_types/expression/mod.rs +++ b/acvm-repo/acir/src/native_types/expression/mod.rs @@ -510,40 +510,17 @@ fn display_term( #[cfg(test)] mod tests { use super::*; - use acir_field::{AcirField, FieldElement}; + use acir_field::FieldElement; #[test] fn add_mul_smoke_test() { - let a = Expression { - mul_terms: vec![(FieldElement::from(2u128), Witness(1), Witness(2))], - ..Default::default() - }; + let a = Expression::from_str("2*w1*w2").unwrap(); let k = FieldElement::from(10u128); - - let b = Expression { - mul_terms: vec![ - (FieldElement::from(3u128), Witness(0), Witness(2)), - (FieldElement::from(3u128), Witness(1), Witness(2)), - (FieldElement::from(4u128), Witness(4), Witness(5)), - ], - linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], - q_c: FieldElement::one(), - }; + let b = Expression::from_str("3*w0*w2 + 3*w1*w2 + 4*w4*w5 + 4*w4 + 1").unwrap(); let result = a.add_mul(k, &b); - assert_eq!( - result, - Expression { - mul_terms: vec![ - (FieldElement::from(30u128), Witness(0), Witness(2)), - (FieldElement::from(32u128), Witness(1), Witness(2)), - (FieldElement::from(40u128), Witness(4), Witness(5)), - ], - linear_combinations: vec![(FieldElement::from(40u128), Witness(4))], - q_c: FieldElement::from(10u128) - } - ); + assert_eq!(result.to_string(), "30*w0*w2 + 32*w1*w2 + 40*w4*w5 + 40*w4 + 10"); } #[test] diff --git a/acvm-repo/acir/src/native_types/expression/operators.rs b/acvm-repo/acir/src/native_types/expression/operators.rs index a8f5dc8e7ad..6e475aa357b 100644 --- a/acvm-repo/acir/src/native_types/expression/operators.rs +++ b/acvm-repo/acir/src/native_types/expression/operators.rs @@ -207,34 +207,14 @@ fn single_mul(w: Witness, b: &Expression) -> Expression { #[cfg(test)] mod tests { - use super::*; - use acir_field::{AcirField, FieldElement}; + use crate::native_types::Expression; #[test] fn add_smoke_test() { - let a = Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], - q_c: FieldElement::from(2u128), - }; - - let b = Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], - q_c: FieldElement::one(), - }; - - assert_eq!( - &a + &b, - Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::from(2u128), Witness(2)), - (FieldElement::from(4u128), Witness(4)) - ], - q_c: FieldElement::from(3u128) - } - ); + let a = Expression::from_str("2*w2 + 2").unwrap(); + let b = Expression::from_str("4*w4 + 1").unwrap(); + let result = Expression::from_str("2*w2 + 4*w4 + 3").unwrap(); + assert_eq!(&a + &b, result); // Enforce commutativity assert_eq!(&a + &b, &b + &a); @@ -242,29 +222,10 @@ mod tests { #[test] fn mul_smoke_test() { - let a = Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], - q_c: FieldElement::from(2u128), - }; - - let b = Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], - q_c: FieldElement::one(), - }; - - assert_eq!( - (&a * &b).unwrap(), - Expression { - mul_terms: vec![(FieldElement::from(8u128), Witness(2), Witness(4)),], - linear_combinations: vec![ - (FieldElement::from(2u128), Witness(2)), - (FieldElement::from(8u128), Witness(4)) - ], - q_c: FieldElement::from(2u128) - } - ); + let a = Expression::from_str("2*w2 + 2").unwrap(); + let b = Expression::from_str("4*w4 + 1").unwrap(); + let result = Expression::from_str("8*w2*w4 + 2*w2 + 8*w4 + 2").unwrap(); + assert_eq!((&a * &b).unwrap(), result); // Enforce commutativity assert_eq!(&a * &b, &b * &a); diff --git a/acvm-repo/acir/src/parser/mod.rs b/acvm-repo/acir/src/parser/mod.rs index 2965783762c..7ddfed77122 100644 --- a/acvm-repo/acir/src/parser/mod.rs +++ b/acvm-repo/acir/src/parser/mod.rs @@ -111,6 +111,30 @@ impl Circuit { } } +impl FromStr for Expression { + type Err = AcirParserErrorWithSource; + + fn from_str(src: &str) -> Result { + Self::from_str_impl(src) + } +} + +impl Expression { + /// Creates a [Expression] object from the given string. + #[allow(clippy::should_implement_trait)] + pub fn from_str(src: &str) -> Result { + FromStr::from_str(src) + } + + pub fn from_str_impl(src: &str) -> Result { + let mut parser = + Parser::new(src).map_err(|err| AcirParserErrorWithSource::parse_error(err, src))?; + parser + .parse_arithmetic_expression() + .map_err(|err| AcirParserErrorWithSource::parse_error(err, src)) + } +} + struct Parser<'a> { lexer: Lexer<'a>, token: SpannedToken, diff --git a/acvm-repo/acir/tests/test_program_serialization.rs b/acvm-repo/acir/tests/test_program_serialization.rs index a90346673f7..aefb2aed559 100644 --- a/acvm-repo/acir/tests/test_program_serialization.rs +++ b/acvm-repo/acir/tests/test_program_serialization.rs @@ -9,40 +9,24 @@ //! Generally in this situation we just need to refresh the `expected_serialization` variables to match the //! actual output, **HOWEVER** note that this results in a breaking change to the backend ACIR format. -use std::collections::BTreeSet; - use acir::{ - circuit::{ - Circuit, Opcode, Program, PublicInputs, - brillig::{BrilligBytecode, BrilligFunctionId, BrilligInputs, BrilligOutputs}, - opcodes::{AcirFunctionId, BlackBoxFuncCall, BlockId, FunctionInput, MemOp}, - }, - native_types::{Expression, Witness}, + circuit::{Circuit, Program, brillig::BrilligBytecode}, + native_types::Witness, }; -use acir_field::{AcirField, FieldElement}; +use acir_field::FieldElement; use brillig::{ BitSize, HeapArray, HeapValueType, HeapVector, IntegerBitSize, MemoryAddress, ValueOrArray, }; #[test] fn addition_circuit() { - let addition = Opcode::AssertZero(Expression { - mul_terms: Vec::new(), - linear_combinations: vec![ - (FieldElement::one(), Witness(1)), - (FieldElement::one(), Witness(2)), - (-FieldElement::one(), Witness(3)), - ], - q_c: FieldElement::zero(), - }); - - let circuit: Circuit = Circuit { - current_witness_index: 4, - opcodes: vec![addition], - private_parameters: BTreeSet::from([Witness(1), Witness(2)]), - return_values: PublicInputs([Witness(3)].into()), - ..Circuit::::default() - }; + let src = " + private parameters: [w1, w2] + public parameters: [] + return values: [w3] + ASSERT w3 = w1 + w2 + "; + let circuit = Circuit::from_str(src).unwrap(); let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); @@ -55,32 +39,13 @@ fn addition_circuit() { #[test] fn multi_scalar_mul_circuit() { - let multi_scalar_mul: Opcode = - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::MultiScalarMul { - points: vec![ - FunctionInput::Witness(Witness(1)), - FunctionInput::Witness(Witness(2)), - FunctionInput::Witness(Witness(3)), - ], - scalars: vec![FunctionInput::Witness(Witness(4)), FunctionInput::Witness(Witness(5))], - predicate: FunctionInput::Witness(Witness(6)), - outputs: (Witness(7), Witness(8), Witness(9)), - }); - - let circuit = Circuit { - current_witness_index: 10, - opcodes: vec![multi_scalar_mul], - private_parameters: BTreeSet::from([ - Witness(1), - Witness(2), - Witness(3), - Witness(4), - Witness(5), - Witness(6), - ]), - return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(7), Witness(8), Witness(9)])), - ..Circuit::default() - }; + let src = " + private parameters: [w1, w2, w3, w4, w5, w6] + public parameters: [] + return values: [w7, w8, w9] + BLACKBOX::MULTI_SCALAR_MUL points: [w1, w2, w3], scalars: [w4, w5], predicate: w6, outputs: [w7, w8, w9] + "; + let circuit = Circuit::from_str(src).unwrap(); let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); @@ -131,24 +96,15 @@ fn simple_brillig_foreign_call() { ], }; - let opcodes = vec![Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![ - BrilligInputs::Single(w_input.into()), // Input Register 0, - ], - // This tells the BrilligSolver which witnesses its output values correspond to - outputs: vec![ - BrilligOutputs::Simple(w_inverted), // Output Register 1 - ], - predicate: None, - }]; - - let circuit: Circuit = Circuit { - current_witness_index: 8, - opcodes, - private_parameters: BTreeSet::from([Witness(1), Witness(2)]), - ..Circuit::default() - }; + let src = format!( + " + private parameters: [{w_input}, {w_inverted}] + public parameters: [] + return values: [] + BRILLIG CALL func: 0, inputs: [{w_input}], outputs: [{w_inverted}] + " + ); + let circuit = Circuit::from_str(&src).unwrap(); let program = Program { functions: vec![circuit], unconstrained_functions: vec![brillig_bytecode] }; @@ -162,8 +118,6 @@ fn simple_brillig_foreign_call() { #[test] fn complex_brillig_foreign_call() { - let fe_0 = FieldElement::zero(); - let fe_1 = FieldElement::one(); let a = Witness(1); let b = Witness(2); let c = Witness(3); @@ -259,37 +213,13 @@ fn complex_brillig_foreign_call() { ], }; - let opcodes = vec![Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![ - // Input 0,1,2 - BrilligInputs::Array(vec![ - Expression::from(a), - Expression::from(b), - Expression::from(c), - ]), - // Input 3 - BrilligInputs::Single(Expression { - mul_terms: vec![], - linear_combinations: vec![(fe_1, a), (fe_1, b), (fe_1, c)], - q_c: fe_0, - }), - ], - // This tells the BrilligSolver which witnesses its output values correspond to - outputs: vec![ - BrilligOutputs::Array(vec![a_times_2, b_times_3, c_times_4]), // Output 0,1,2 - BrilligOutputs::Simple(a_plus_b_plus_c), // Output 3 - BrilligOutputs::Simple(a_plus_b_plus_c_times_2), // Output 4 - ], - predicate: None, - }]; - - let circuit = Circuit { - current_witness_index: 8, - opcodes, - private_parameters: BTreeSet::from([Witness(1), Witness(2), Witness(3)]), - ..Circuit::default() - }; + let src = format!(" + private parameters: [{a}, {b}, {c}] + public parameters: [] + return values: [] + BRILLIG CALL func: 0, inputs: [[{a}, {b}, {c}], {a} + {b} + {c}], outputs: [[{a_times_2}, {b_times_3}, {c_times_4}], {a_plus_b_plus_c}, {a_plus_b_plus_c_times_2}] + "); + let circuit = Circuit::from_str(&src).unwrap(); let program = Program { functions: vec![circuit], unconstrained_functions: vec![brillig_bytecode] }; @@ -303,29 +233,15 @@ fn complex_brillig_foreign_call() { #[test] fn memory_op_circuit() { - let init = vec![Witness(1), Witness(2)]; - - let memory_init = Opcode::MemoryInit { - block_id: BlockId(0), - init, - block_type: acir::circuit::opcodes::BlockType::Memory, - }; - let write = Opcode::MemoryOp { - block_id: BlockId(0), - op: MemOp::write_to_mem_index(FieldElement::from(1u128).into(), Witness(3).into()), - }; - let read = Opcode::MemoryOp { - block_id: BlockId(0), - op: MemOp::read_at_mem_index(FieldElement::one().into(), Witness(4)), - }; - - let circuit = Circuit { - current_witness_index: 5, - opcodes: vec![memory_init, write, read], - private_parameters: BTreeSet::from([Witness(1), Witness(2), Witness(3)]), - return_values: PublicInputs([Witness(4)].into()), - ..Circuit::default() - }; + let src = " + private parameters: [w1, w2, w3] + public parameters: [] + return values: [w4] + INIT b0 = [w1, w2] + WRITE b0[1] = w3 + READ w4 = b0[1] + "; + let circuit = Circuit::from_str(src).unwrap(); let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); @@ -353,75 +269,32 @@ fn nested_acir_call_circuit() { // assert(x == y); // x // } - let nested_call = Opcode::Call { - id: AcirFunctionId(1), - inputs: vec![Witness(0), Witness(1)], - outputs: vec![Witness(2)], - predicate: None, - }; - let nested_call_two = Opcode::Call { - id: AcirFunctionId(1), - inputs: vec![Witness(0), Witness(1)], - outputs: vec![Witness(3)], - predicate: None, - }; - - let assert_nested_call_results = Opcode::AssertZero(Expression { - mul_terms: Vec::new(), - linear_combinations: vec![ - (FieldElement::one(), Witness(2)), - (-FieldElement::one(), Witness(3)), - ], - q_c: FieldElement::zero(), - }); - - let main = Circuit { - current_witness_index: 3, - private_parameters: BTreeSet::from([Witness(0)]), - public_parameters: PublicInputs([Witness(1)].into()), - opcodes: vec![nested_call, nested_call_two, assert_nested_call_results], - ..Circuit::default() - }; - - let call_parameter_addition = Opcode::AssertZero(Expression { - mul_terms: Vec::new(), - linear_combinations: vec![ - (FieldElement::one(), Witness(0)), - (-FieldElement::one(), Witness(2)), - ], - q_c: FieldElement::one() + FieldElement::one(), - }); - let call = Opcode::Call { - id: AcirFunctionId(2), - inputs: vec![Witness(2), Witness(1)], - outputs: vec![Witness(3)], - predicate: None, - }; - - let nested_call = Circuit { - current_witness_index: 3, - private_parameters: BTreeSet::from([Witness(0), Witness(1)]), - return_values: PublicInputs([Witness(3)].into()), - opcodes: vec![call_parameter_addition, call], - ..Circuit::default() - }; - - let assert_param_equality = Opcode::AssertZero(Expression { - mul_terms: Vec::new(), - linear_combinations: vec![ - (FieldElement::one(), Witness(0)), - (-FieldElement::one(), Witness(1)), - ], - q_c: FieldElement::zero(), - }); - - let inner_call = Circuit { - current_witness_index: 1, - private_parameters: BTreeSet::from([Witness(0), Witness(1)]), - return_values: PublicInputs([Witness(0)].into()), - opcodes: vec![assert_param_equality], - ..Circuit::default() - }; + let src = " + private parameters: [w0] + public parameters: [w1] + return values: [] + CALL func: 1, inputs: [w0, w1], outputs: [w2] + CALL func: 1, inputs: [w0, w1], outputs: [w3] + ASSERT 0 = w2 - w3 + "; + let main = Circuit::from_str(src).unwrap(); + + let src = " + private parameters: [w0, w1] + public parameters: [] + return values: [w3] + ASSERT 0 = w0 - w2 + 2 + CALL func: 2, inputs: [w2, w1], outputs: [w3] + "; + let nested_call = Circuit::from_str(src).unwrap(); + + let src = " + private parameters: [w0, w1] + public parameters: [] + return values: [w0] + ASSERT 0 = w0 - w1 + "; + let inner_call = Circuit::from_str(src).unwrap(); let program = Program { functions: vec![main, nested_call, inner_call], unconstrained_functions: vec![] }; From b82808c16892077f094411ad521a897e7ae30990 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 20 Oct 2025 18:57:20 -0300 Subject: [PATCH 10/13] `parse_opcodes`, and more parsing --- acvm-repo/acir/src/lib.rs | 1 + acvm-repo/acir/src/parser/mod.rs | 6 + .../acvm/src/compiler/transformers/csat.rs | 53 +--- acvm-repo/acvm/src/pwg/arithmetic.rs | 37 +-- acvm-repo/acvm/src/pwg/mod.rs | 43 +-- acvm-repo/acvm/tests/solver.rs | 261 ++++-------------- tooling/debugger/src/context.rs | 23 +- 7 files changed, 93 insertions(+), 331 deletions(-) diff --git a/acvm-repo/acir/src/lib.rs b/acvm-repo/acir/src/lib.rs index 16e7a1cd377..0ac9607b890 100644 --- a/acvm-repo/acir/src/lib.rs +++ b/acvm-repo/acir/src/lib.rs @@ -19,6 +19,7 @@ pub use acir_field::{AcirField, FieldElement}; pub use brillig; pub use circuit::black_box_functions::BlackBoxFunc; pub use circuit::opcodes::InvalidInputBitSize; +pub use parser::parse_opcodes; #[cfg(test)] mod reflection { diff --git a/acvm-repo/acir/src/parser/mod.rs b/acvm-repo/acir/src/parser/mod.rs index 7ddfed77122..9e79628cf6f 100644 --- a/acvm-repo/acir/src/parser/mod.rs +++ b/acvm-repo/acir/src/parser/mod.rs @@ -135,6 +135,12 @@ impl Expression { } } +pub fn parse_opcodes(src: &str) -> Result>, AcirParserErrorWithSource> { + let mut parser = + Parser::new(src).map_err(|err| AcirParserErrorWithSource::parse_error(err, src))?; + parser.parse_opcodes().map_err(|err| AcirParserErrorWithSource::parse_error(err, src)) +} + struct Parser<'a> { lexer: Lexer<'a>, token: SpannedToken, diff --git a/acvm-repo/acvm/src/compiler/transformers/csat.rs b/acvm-repo/acvm/src/compiler/transformers/csat.rs index cef969107b9..4be7dd53ff7 100644 --- a/acvm-repo/acvm/src/compiler/transformers/csat.rs +++ b/acvm-repo/acvm/src/compiler/transformers/csat.rs @@ -430,7 +430,7 @@ fn fits_in_one_identity(expr: &Expression, width: usize) -> boo #[cfg(test)] mod tests { use super::*; - use acir::{AcirField, FieldElement}; + use acir::FieldElement; #[test] fn simple_reduction_smoke_test() { @@ -440,16 +440,7 @@ mod tests { let d = Witness(3); // a = b + c + d; - let opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), a), - (-FieldElement::one(), b), - (-FieldElement::one(), c), - (-FieldElement::one(), d), - ], - q_c: FieldElement::zero(), - }; + let opcode_a = Expression::from_str(&format!("{a} - {b} - {c} - {d}")).unwrap(); let mut intermediate_variables: IndexMap< Expression, @@ -472,25 +463,15 @@ mod tests { // // a - b + e = 0 let e = Witness(4); - let expected_optimized_opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), a), - (-FieldElement::one(), d), - (FieldElement::one(), e), - ], - q_c: FieldElement::zero(), - }; + let expected_optimized_opcode_a = + Expression::from_str(&format!("{a} - {d} + {e}")).unwrap(); + assert_eq!(expected_optimized_opcode_a, got_optimized_opcode_a); assert_eq!(intermediate_variables.len(), 1); // e = - c - b - let expected_intermediate_opcode = Expression { - mul_terms: vec![], - linear_combinations: vec![(-FieldElement::one(), c), (-FieldElement::one(), b)], - q_c: FieldElement::zero(), - }; + let expected_intermediate_opcode = Expression::from_str(&format!("-{c} - {b}")).unwrap(); let (_, normalized_opcode) = CSatTransformer::normalize(expected_intermediate_opcode); assert!(intermediate_variables.contains_key(&normalized_opcode)); assert_eq!(intermediate_variables[&normalized_opcode].1, e); @@ -505,17 +486,7 @@ mod tests { let e = Witness(4); // a = b + c + d + e; - let opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (-FieldElement::one(), a), - (FieldElement::one(), b), - (FieldElement::one(), c), - (FieldElement::one(), d), - (FieldElement::one(), e), - ], - q_c: FieldElement::zero(), - }; + let opcode_a = Expression::from_str(&format!("-{a} + {b} + {c} + {d} + {e}")).unwrap(); let mut intermediate_variables: IndexMap< Expression, @@ -541,15 +512,7 @@ mod tests { fn recognize_expr_with_single_shared_witness_which_fits_in_single_identity() { // Regression test for an expression which Zac found which should have been preserved but // was being split into two expressions. - let expr = Expression { - mul_terms: vec![(-FieldElement::from(555u128), Witness(8), Witness(10))], - linear_combinations: vec![ - (FieldElement::one(), Witness(10)), - (FieldElement::one(), Witness(11)), - (-FieldElement::one(), Witness(13)), - ], - q_c: FieldElement::zero(), - }; + let expr = Expression::from_str("-555*w8*w10 + w10 + w11 - w13").unwrap(); assert!(fits_in_one_identity(&expr, 4)); } } diff --git a/acvm-repo/acvm/src/pwg/arithmetic.rs b/acvm-repo/acvm/src/pwg/arithmetic.rs index 664b643e5a0..cf771815827 100644 --- a/acvm-repo/acvm/src/pwg/arithmetic.rs +++ b/acvm-repo/acvm/src/pwg/arithmetic.rs @@ -304,11 +304,7 @@ mod tests { let a = Witness(0); // a - 1 == 0; - let opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![(FieldElement::one(), a)], - q_c: -FieldElement::one(), - }; + let opcode_a = Expression::from_str(&format!("{a} - 1")).unwrap(); let mut values = WitnessMap::new(); assert_eq!(ExpressionSolver::solve(&mut values, &opcode_a), Ok(())); @@ -324,15 +320,7 @@ mod tests { let d = Witness(3); // a * b - b - c - d == 0; - let opcode_a = Expression { - mul_terms: vec![(FieldElement::one(), a, b)], - linear_combinations: vec![ - (-FieldElement::one(), b), - (-FieldElement::one(), c), - (-FieldElement::one(), d), - ], - q_c: FieldElement::zero(), - }; + let opcode_a = Expression::from_str(&format!("{a}*{b} - {b} - {c} - {d}")).unwrap(); let mut values = WitnessMap::new(); values.insert(b, FieldElement::from(2_i128)); @@ -352,27 +340,10 @@ mod tests { let d = Witness(3); // a = b + c + d; - let opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), a), - (-FieldElement::one(), b), - (-FieldElement::one(), c), - (-FieldElement::one(), d), - ], - q_c: FieldElement::zero(), - }; + let opcode_a = Expression::from_str(&format!("{a} - {b} - {c} - {d}")).unwrap(); let e = Witness(4); - let opcode_b = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), e), - (-FieldElement::one(), a), - (-FieldElement::one(), b), - ], - q_c: FieldElement::zero(), - }; + let opcode_b = Expression::from_str(&format!("{e} - {a} - {b}")).unwrap(); let mut values = WitnessMap::new(); values.insert(b, FieldElement::from(2_i128)); diff --git a/acvm-repo/acvm/src/pwg/mod.rs b/acvm-repo/acvm/src/pwg/mod.rs index 2db4fb564aa..ab00bb071d3 100644 --- a/acvm-repo/acvm/src/pwg/mod.rs +++ b/acvm-repo/acvm/src/pwg/mod.rs @@ -942,11 +942,8 @@ mod tests { use acir::{ FieldElement, - circuit::{ - Opcode, - opcodes::{BlackBoxFuncCall, FunctionInput}, - }, native_types::{Witness, WitnessMap}, + parse_opcodes, }; use crate::pwg::{ACVM, ACVMStatus}; @@ -959,34 +956,16 @@ mod tests { (Witness(3), FieldElement::from(2u128)), ])); let backend = acvm_blackbox_solver::StubbedBlackBoxSolver(false); - let opcodes = vec![ - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { - input: FunctionInput::Witness(Witness(1)), - num_bits: 32, - }), - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { - input: FunctionInput::Witness(Witness(2)), - num_bits: 32, - }), - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { - input: FunctionInput::Witness(Witness(3)), - num_bits: 32, - }), - Opcode::AssertZero(acir::native_types::Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::from(2u128), Witness(1)), - (FieldElement::from(-1_i128), Witness(2)), - (FieldElement::from(-1_i128), Witness(4)), - ], - q_c: FieldElement::from(0u128), - }), - Opcode::AssertZero(acir::native_types::Expression { - mul_terms: vec![(FieldElement::from(1u128), Witness(2), Witness(4))], - linear_combinations: vec![(FieldElement::from(1u128), Witness(5))], - q_c: FieldElement::from(-1_i128), - }), - ]; + + let src = " + BLACKBOX::RANGE input: w1, bits: 32 + BLACKBOX::RANGE input: w2, bits: 32 + BLACKBOX::RANGE input: w3, bits: 32 + ASSERT w4 = 2*w1 - w2 + ASSERT w5 = -w2*w4 + 1 + "; + let opcodes = parse_opcodes(src).unwrap(); + let empty1 = Vec::new(); let empty2 = Vec::new(); let mut acvm = ACVM::new(&backend, &opcodes, initial_witness, &empty1, &empty2); diff --git a/acvm-repo/acvm/tests/solver.rs b/acvm-repo/acvm/tests/solver.rs index 64c50002710..3a828daaacf 100644 --- a/acvm-repo/acvm/tests/solver.rs +++ b/acvm-repo/acvm/tests/solver.rs @@ -1,19 +1,19 @@ use std::collections::BTreeMap; use std::sync::Arc; -use acir::InvalidInputBitSize; +use acir::acir_field::GenericFieldElement; use acir::brillig::{BitSize, HeapVector, IntegerBitSize}; use acir::{ AcirField, FieldElement, - acir_field::GenericFieldElement, brillig::{BinaryFieldOp, MemoryAddress, Opcode as BrilligOpcode, ValueOrArray}, circuit::{ Opcode, OpcodeLocation, - brillig::{BrilligBytecode, BrilligFunctionId, BrilligInputs, BrilligOutputs}, - opcodes::{BlackBoxFuncCall, BlockId, BlockType, FunctionInput, MemOp}, + brillig::{BrilligBytecode, BrilligFunctionId}, + opcodes::{BlackBoxFuncCall, FunctionInput}, }, native_types::{Expression, Witness, WitnessMap}, }; +use acir::{InvalidInputBitSize, parse_opcodes}; use acvm::pwg::{ACVM, ACVMStatus, ErrorLocation, ForeignCallWaitInfo, OpcodeResolutionError}; use acvm_blackbox_solver::StubbedBlackBoxSolver; @@ -68,8 +68,6 @@ fn inversion_brillig_oracle_equivalence() { // } // Also performs an unrelated equality check // just for the sake of testing multiple brillig opcodes. - let fe_0 = FieldElement::zero(); - let fe_1 = FieldElement::one(); let w_x = Witness(1); let w_y = Witness(2); let w_oracle = Witness(3); @@ -78,43 +76,15 @@ fn inversion_brillig_oracle_equivalence() { let w_x_plus_y = Witness(6); let w_equal_res = Witness(7); - let opcodes = vec![ - Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![ - BrilligInputs::Single(Expression { - // Input Register 0 - mul_terms: vec![], - linear_combinations: vec![(fe_1, w_x), (fe_1, w_y)], - q_c: fe_0, - }), - BrilligInputs::Single(Expression::default()), // Input Register 1 - ], - // This tells the BrilligSolver which witnesses its output values correspond to - outputs: vec![ - BrilligOutputs::Simple(w_x_plus_y), // Output Register 0 - from input - BrilligOutputs::Simple(w_oracle), // Output Register 1 - BrilligOutputs::Simple(w_equal_res), // Output Register 2 - ], - predicate: None, - }, - Opcode::AssertZero(Expression { - mul_terms: vec![], - linear_combinations: vec![(fe_1, w_x), (fe_1, w_y), (-fe_1, w_z)], - q_c: fe_0, - }), - // Opcode::Directive(Directive::Invert { x: w_z, result: w_z_inverse }), - Opcode::AssertZero(Expression { - mul_terms: vec![(fe_1, w_z, w_z_inverse)], - linear_combinations: vec![], - q_c: -fe_1, - }), - Opcode::AssertZero(Expression { - mul_terms: vec![], - linear_combinations: vec![(-fe_1, w_oracle), (fe_1, w_z_inverse)], - q_c: fe_0, - }), - ]; + let src = format!( + " + BRILLIG CALL func: 0, inputs: [{w_x} + {w_y}, 0], outputs: [{w_x_plus_y}, {w_oracle}, {w_equal_res}] + ASSERT {w_z} = {w_x} + {w_y} + ASSERT 0 = {w_z}*{w_z_inverse} - 1 + ASSERT {w_z_inverse} = {w_oracle} + " + ); + let opcodes = parse_opcodes(&src).unwrap(); let equal_opcode = BrilligOpcode::BinaryFieldOp { op: BinaryFieldOp::Equals, @@ -210,8 +180,6 @@ fn double_inversion_brillig_oracle() { // } // Also performs an unrelated equality check // just for the sake of testing multiple brillig opcodes. - let fe_0 = FieldElement::zero(); - let fe_1 = FieldElement::one(); let w_x = Witness(1); let w_y = Witness(2); let w_oracle = Witness(3); @@ -224,50 +192,15 @@ fn double_inversion_brillig_oracle() { let w_ij_oracle = Witness(10); let w_i_plus_j = Witness(11); - let opcodes = vec![ - Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![ - BrilligInputs::Single(Expression { - // Input Register 0 - mul_terms: vec![], - linear_combinations: vec![(fe_1, w_x), (fe_1, w_y)], - q_c: fe_0, - }), - BrilligInputs::Single(Expression::default()), // Input Register 1 - BrilligInputs::Single(Expression { - // Input Register 2 - mul_terms: vec![], - linear_combinations: vec![(fe_1, w_i), (fe_1, w_j)], - q_c: fe_0, - }), - ], - outputs: vec![ - BrilligOutputs::Simple(w_x_plus_y), // Output Register 0 - from input - BrilligOutputs::Simple(w_oracle), // Output Register 1 - BrilligOutputs::Simple(w_i_plus_j), // Output Register 2 - from input - BrilligOutputs::Simple(w_ij_oracle), // Output Register 3 - BrilligOutputs::Simple(w_equal_res), // Output Register 4 - ], - predicate: None, - }, - Opcode::AssertZero(Expression { - mul_terms: vec![], - linear_combinations: vec![(fe_1, w_x), (fe_1, w_y), (-fe_1, w_z)], - q_c: fe_0, - }), - // Opcode::Directive(Directive::Invert { x: w_z, result: w_z_inverse }), - Opcode::AssertZero(Expression { - mul_terms: vec![(fe_1, w_z, w_z_inverse)], - linear_combinations: vec![], - q_c: -fe_1, - }), - Opcode::AssertZero(Expression { - mul_terms: vec![], - linear_combinations: vec![(-fe_1, w_oracle), (fe_1, w_z_inverse)], - q_c: fe_0, - }), - ]; + let src = format!( + " + BRILLIG CALL func: 0, inputs: [{w_x} + {w_y}, 0, {w_i} + {w_j}], outputs: [{w_x_plus_y}, {w_oracle}, {w_i_plus_j}, {w_ij_oracle}, {w_equal_res}] + ASSERT {w_z} = {w_x} + {w_y} + ASSERT 0 = {w_z}*{w_z_inverse} - 1 + ASSERT {w_z_inverse} = {w_oracle} + " + ); + let opcodes = parse_opcodes(&src).unwrap(); let zero_usize = MemoryAddress::direct(5); let three_usize = MemoryAddress::direct(6); @@ -394,8 +327,6 @@ fn oracle_dependent_execution() { // } // Also performs an unrelated equality check // just for the sake of testing multiple brillig opcodes. - let fe_0 = FieldElement::zero(); - let fe_1 = FieldElement::one(); let w_x = Witness(1); let w_y = Witness(2); let w_x_inv = Witness(3); @@ -448,40 +379,17 @@ fn oracle_dependent_execution() { ], }; + let src = format!( + " // This equality check can be executed immediately before resolving any foreign calls. - let equality_check = Expression { - mul_terms: vec![], - linear_combinations: vec![(-fe_1, w_x), (fe_1, w_y)], - q_c: fe_0, - }; - + ASSERT {w_y} = {w_x} + BRILLIG CALL func: 0, inputs: [{w_x}, 0, {w_y}], outputs: [{w_x}, {w_y_inv}, {w_y}, {w_y_inv}] // This equality check relies on the outputs of the Brillig call. // It then cannot be solved until the foreign calls are resolved. - let inverse_equality_check = Expression { - mul_terms: vec![], - linear_combinations: vec![(-fe_1, w_x_inv), (fe_1, w_y_inv)], - q_c: fe_0, - }; - - let opcodes = vec![ - Opcode::AssertZero(equality_check), - Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![ - BrilligInputs::Single(w_x.into()), // Input Register 0 - BrilligInputs::Single(Expression::default()), // Input Register 1 - BrilligInputs::Single(w_y.into()), // Input Register 2, - ], - outputs: vec![ - BrilligOutputs::Simple(w_x), // Output Register 0 - from input - BrilligOutputs::Simple(w_y_inv), // Output Register 1 - BrilligOutputs::Simple(w_y), // Output Register 2 - from input - BrilligOutputs::Simple(w_y_inv), // Output Register 3 - ], - predicate: None, - }, - Opcode::AssertZero(inverse_equality_check), - ]; + ASSERT {w_y_inv} = {w_x_inv} + " + ); + let opcodes = parse_opcodes(&src).unwrap(); let witness_assignments = BTreeMap::from([(w_x, FieldElement::from(2u128)), (w_y, FieldElement::from(2u128))]).into(); @@ -533,8 +441,6 @@ fn oracle_dependent_execution() { #[test] fn brillig_oracle_predicate() { let solver = StubbedBlackBoxSolver::default(); - let fe_0 = FieldElement::zero(); - let fe_1 = FieldElement::one(); let w_x = Witness(1); let w_y = Witness(2); let w_oracle = Witness(3); @@ -579,24 +485,12 @@ fn brillig_oracle_predicate() { ], }; - let opcodes = vec![Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![ - BrilligInputs::Single(Expression { - mul_terms: vec![], - linear_combinations: vec![(fe_1, w_x), (fe_1, w_y)], - q_c: fe_0, - }), - BrilligInputs::Single(Expression::default()), - ], - outputs: vec![ - BrilligOutputs::Simple(w_x_plus_y), - BrilligOutputs::Simple(w_oracle), - BrilligOutputs::Simple(w_equal_res), - BrilligOutputs::Simple(w_lt_res), - ], - predicate: Some(Expression::default()), - }]; + let src = format!( + " + BRILLIG CALL func: 0, predicate: 0, inputs: [{w_x} + {w_y}, 0], outputs: [{w_x_plus_y}, {w_oracle}, {w_equal_res}, {w_lt_res}] + " + ); + let opcodes = parse_opcodes(&src).unwrap(); let witness_assignments = BTreeMap::from([ (Witness(1), FieldElement::from(2u128)), @@ -620,25 +514,15 @@ fn unsatisfied_opcode_resolved() { let c = Witness(2); let d = Witness(3); - // a = b + c + d; - let opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), a), - (-FieldElement::one(), b), - (-FieldElement::one(), c), - (-FieldElement::one(), d), - ], - q_c: FieldElement::zero(), - }; - let mut values = WitnessMap::new(); values.insert(a, FieldElement::from(4_i128)); values.insert(b, FieldElement::from(2_i128)); values.insert(c, FieldElement::from(1_i128)); values.insert(d, FieldElement::from(2_i128)); - let opcodes = vec![Opcode::AssertZero(opcode_a)]; + let src = format!("ASSERT {a} = {b} + {c} + {d}"); + let opcodes = parse_opcodes(&src).unwrap(); + let unconstrained_functions = vec![]; let mut acvm = ACVM::new(&solver, &opcodes, values, &unconstrained_functions, &[]); let solver_status = acvm.solve(); @@ -660,8 +544,6 @@ fn unsatisfied_opcode_resolved_brillig() { let c = Witness(2); let d = Witness(3); - let fe_1 = FieldElement::one(); - let fe_0 = FieldElement::zero(); let w_x = Witness(4); let w_y = Witness(5); let w_result = Witness(6); @@ -724,17 +606,6 @@ fn unsatisfied_opcode_resolved_brillig() { ], }; - let opcode_a = Expression { - mul_terms: vec![], - linear_combinations: vec![ - (FieldElement::one(), a), - (-FieldElement::one(), b), - (-FieldElement::one(), c), - (-FieldElement::one(), d), - ], - q_c: FieldElement::zero(), - }; - let mut values = WitnessMap::new(); values.insert(a, FieldElement::from(4_i128)); values.insert(b, FieldElement::from(2_i128)); @@ -744,26 +615,14 @@ fn unsatisfied_opcode_resolved_brillig() { values.insert(w_y, FieldElement::from(1_i128)); values.insert(w_result, FieldElement::from(0_i128)); - let opcodes = vec![ - Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![ - BrilligInputs::Single(Expression { - mul_terms: vec![], - linear_combinations: vec![(fe_1, w_x)], - q_c: fe_0, - }), - BrilligInputs::Single(Expression { - mul_terms: vec![], - linear_combinations: vec![(fe_1, w_y)], - q_c: fe_0, - }), - ], - outputs: vec![BrilligOutputs::Simple(w_result)], - predicate: Some(Expression::one()), - }, - Opcode::AssertZero(opcode_a), - ]; + let src = format!( + " + BRILLIG CALL func: 0, predicate: 1, inputs: [{w_x}, {w_y}], outputs: [{w_result}] + ASSERT {a} = {b} + {c} + {d} + " + ); + let opcodes = parse_opcodes(&src).unwrap(); + let unconstrained_functions = vec![brillig_bytecode]; let mut acvm = ACVM::new(&solver, &opcodes, values, &unconstrained_functions, &[]); let solver_status = acvm.solve(); @@ -791,27 +650,13 @@ fn memory_operations() { (Witness(6), FieldElement::from(4u128)), ])); - let block_id = BlockId(0); - - let init = Opcode::MemoryInit { - block_id, - init: (1..6).map(Witness).collect(), - block_type: BlockType::Memory, - }; - - let read_op = - Opcode::MemoryOp { block_id, op: MemOp::read_at_mem_index(Witness(6).into(), Witness(7)) }; - - let expression = Opcode::AssertZero(Expression { - mul_terms: Vec::new(), - linear_combinations: vec![ - (FieldElement::one(), Witness(7)), - (-FieldElement::one(), Witness(8)), - ], - q_c: FieldElement::one(), - }); + let src = " + INIT b0 = [w1, w2, w3, w4, w5] + READ w7 = b0[w6] + ASSERT w8 = w7 + 1 + "; + let opcodes = parse_opcodes(src).unwrap(); - let opcodes = vec![init, read_op, expression]; let unconstrained_functions = vec![]; let mut acvm = ACVM::new(&solver, &opcodes, initial_witness, &unconstrained_functions, &[]); let solver_status = acvm.solve(); diff --git a/tooling/debugger/src/context.rs b/tooling/debugger/src/context.rs index 5ca33f53834..5950555e0cc 100644 --- a/tooling/debugger/src/context.rs +++ b/tooling/debugger/src/context.rs @@ -1087,8 +1087,7 @@ mod tests { acir::{ AcirField, brillig::{HeapVector, IntegerBitSize}, - circuit::brillig::{BrilligFunctionId, BrilligInputs}, - native_types::Expression, + circuit::brillig::BrilligFunctionId, }, blackbox_solver::StubbedBlackBoxSolver, brillig_vm::brillig::{ @@ -1135,18 +1134,16 @@ mod tests { }, ], }; - let opcodes = vec![Opcode::BrilligCall { - id: BrilligFunctionId(0), - inputs: vec![BrilligInputs::Single(Expression { - linear_combinations: vec![(fe_1, w_x)], - ..Expression::default() - })], - outputs: vec![], - predicate: None, - }]; let brillig_functions = &[brillig_bytecode]; - let current_witness_index = 2; - let circuit = Circuit { current_witness_index, opcodes, ..Circuit::default() }; + let src = format!( + " + private parameters: [] + public parameters: [] + return values: [] + BRILLIG CALL func: 0, inputs: [{w_x}], outputs: [] + " + ); + let circuit = Circuit::from_str(&src).unwrap(); let circuits = &[circuit]; let debug_symbols = vec![]; From 1374c6fc4571def036a6646349e59bdb292905a7 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 21 Oct 2025 09:11:44 -0300 Subject: [PATCH 11/13] Snapshots --- acvm-repo/acir/tests/test_program_serialization.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acvm-repo/acir/tests/test_program_serialization.rs b/acvm-repo/acir/tests/test_program_serialization.rs index aefb2aed559..eb17baa9ba1 100644 --- a/acvm-repo/acir/tests/test_program_serialization.rs +++ b/acvm-repo/acir/tests/test_program_serialization.rs @@ -31,7 +31,7 @@ fn addition_circuit() { let bytes = Program::serialize_program(&program); - insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 149, 143, 49, 10, 128, 48, 12, 69, 127, 170, 7, 113, 212, 77, 241, 8, 34, 56, 137, 163, 139, 155, 7, 16, 55, 199, 30, 65, 188, 128, 167, 16, 61, 78, 55, 71, 23, 119, 29, 90, 140, 116, 105, 31, 132, 36, 240, 73, 254, 39, 252, 9, 223, 34, 216, 4, 186, 71, 112, 130, 200, 67, 43, 152, 54, 237, 235, 81, 101, 107, 178, 55, 229, 38, 101, 219, 197, 249, 89, 77, 199, 48, 23, 234, 94, 46, 237, 195, 241, 46, 132, 121, 192, 102, 179, 3, 95, 38, 206, 3, 2, 103, 244, 195, 16, 1, 0, 0]"); + insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 141, 143, 49, 10, 128, 48, 12, 69, 19, 115, 17, 71, 221, 20, 143, 32, 130, 147, 56, 186, 184, 121, 0, 113, 115, 236, 17, 196, 11, 120, 10, 209, 227, 116, 115, 116, 113, 183, 148, 22, 82, 186, 228, 65, 72, 2, 15, 242, 131, 16, 66, 166, 16, 98, 200, 245, 20, 68, 32, 49, 183, 152, 186, 69, 151, 71, 126, 245, 205, 169, 212, 48, 102, 213, 211, 174, 247, 188, 213, 250, 219, 95, 119, 79, 234, 38, 242, 12, 214, 181, 97, 216, 236, 119, 254, 19, 231, 7, 15, 145, 103, 34, 16, 1, 0, 0]"); let program_de = Program::deserialize_program(&bytes).unwrap(); assert_eq!(program_de, program); @@ -50,7 +50,7 @@ fn multi_scalar_mul_circuit() { let bytes = Program::serialize_program(&program); - insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 12, 66, 87, 235, 127, 255, 3, 183, 224, 5, 214, 64, 84, 68, 151, 236, 189, 21, 72, 232, 195, 35, 224, 226, 47, 50, 236, 232, 155, 23, 184, 194, 45, 208, 217, 153, 120, 147, 13, 167, 83, 37, 51, 249, 169, 221, 255, 54, 129, 45, 40, 232, 188, 0, 0, 0]"); + insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 12, 66, 87, 235, 123, 255, 11, 183, 224, 13, 172, 129, 168, 136, 174, 216, 123, 59, 80, 208, 151, 87, 192, 197, 39, 42, 236, 232, 204, 27, 220, 225, 17, 152, 236, 108, 188, 201, 134, 211, 233, 146, 153, 252, 212, 238, 127, 7, 52, 214, 247, 34, 188, 0, 0, 0]"); let program_de = Program::deserialize_program(&bytes).unwrap(); assert_eq!(program_de, program); @@ -110,7 +110,7 @@ fn simple_brillig_foreign_call() { let bytes = Program::serialize_program(&program); - insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 149, 81, 237, 10, 128, 32, 12, 116, 246, 193, 160, 127, 61, 65, 111, 22, 17, 253, 8, 164, 31, 17, 61, 127, 69, 91, 204, 156, 48, 7, 58, 61, 239, 240, 142, 129, 139, 11, 239, 5, 116, 174, 169, 131, 75, 139, 177, 193, 153, 10, 192, 206, 141, 254, 243, 223, 70, 15, 222, 32, 236, 168, 175, 219, 185, 236, 199, 56, 79, 33, 52, 4, 225, 143, 250, 244, 170, 192, 27, 74, 95, 229, 122, 104, 21, 80, 70, 146, 17, 152, 251, 198, 208, 166, 32, 21, 185, 123, 14, 239, 21, 156, 157, 92, 163, 94, 232, 115, 22, 2, 0, 0]"); + insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 149, 81, 237, 10, 128, 32, 12, 116, 235, 3, 161, 127, 61, 65, 111, 22, 17, 253, 8, 164, 31, 17, 61, 127, 69, 91, 204, 156, 48, 7, 58, 61, 239, 240, 142, 129, 139, 11, 239, 5, 116, 174, 169, 131, 75, 139, 177, 193, 153, 10, 192, 206, 141, 254, 195, 111, 163, 7, 52, 8, 59, 234, 235, 118, 46, 251, 49, 206, 83, 8, 13, 65, 254, 71, 125, 122, 85, 224, 205, 75, 95, 229, 122, 104, 21, 80, 70, 146, 17, 152, 251, 198, 208, 166, 32, 21, 185, 123, 14, 239, 21, 156, 157, 92, 239, 80, 232, 201, 22, 2, 0, 0]"); let program_de = Program::deserialize_program(&bytes).unwrap(); assert_eq!(program_de, program); @@ -246,7 +246,7 @@ fn memory_op_circuit() { let bytes = Program::serialize_program(&program); - insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 165, 81, 65, 10, 0, 32, 8, 115, 106, 255, 232, 255, 175, 172, 131, 70, 129, 7, 211, 129, 108, 135, 13, 28, 3, 189, 24, 251, 196, 180, 51, 27, 227, 210, 76, 49, 38, 165, 128, 110, 14, 159, 57, 201, 123, 187, 221, 170, 185, 114, 55, 205, 123, 207, 166, 190, 165, 4, 15, 104, 144, 91, 71, 10, 197, 194, 40, 2, 0, 0]"); + insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 165, 81, 91, 10, 0, 48, 8, 202, 234, 32, 187, 255, 41, 183, 143, 26, 27, 244, 209, 67, 8, 253, 80, 72, 4, 253, 208, 115, 98, 218, 153, 141, 241, 104, 166, 24, 139, 82, 192, 52, 135, 98, 78, 242, 222, 105, 183, 110, 174, 221, 77, 243, 222, 187, 169, 111, 41, 193, 3, 26, 228, 54, 173, 63, 252, 25, 40, 2, 0, 0]"); let program_de = Program::deserialize_program(&bytes).unwrap(); assert_eq!(program_de, program); From 7d265130ebee3635900be3a76f81a221383f3de9 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 21 Oct 2025 10:33:16 -0300 Subject: [PATCH 12/13] Typo --- acvm-repo/acvm/src/compiler/simulator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acvm-repo/acvm/src/compiler/simulator.rs b/acvm-repo/acvm/src/compiler/simulator.rs index ba910d12efc..092f776f6d7 100644 --- a/acvm-repo/acvm/src/compiler/simulator.rs +++ b/acvm-repo/acvm/src/compiler/simulator.rs @@ -220,7 +220,7 @@ mod tests { } #[test] - fn reports_none_for_blackbout_output() { + fn reports_none_for_blackbox_output() { let src = " private parameters: [w0, w1] public parameters: [] From dc09d01a8e3f2eb0bc011acf1ffbd7e7b8420157 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 21 Oct 2025 10:36:40 -0300 Subject: [PATCH 13/13] Use old `current_witness_index` to preserve old snapshots --- .../acir/tests/test_program_serialization.rs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/acvm-repo/acir/tests/test_program_serialization.rs b/acvm-repo/acir/tests/test_program_serialization.rs index eb17baa9ba1..f34f1fe3f82 100644 --- a/acvm-repo/acir/tests/test_program_serialization.rs +++ b/acvm-repo/acir/tests/test_program_serialization.rs @@ -24,14 +24,16 @@ fn addition_circuit() { private parameters: [w1, w2] public parameters: [] return values: [w3] - ASSERT w3 = w1 + w2 + ASSERT 0 = w1 + w2 - w3 "; - let circuit = Circuit::from_str(src).unwrap(); + let mut circuit = Circuit::from_str(src).unwrap(); + circuit.current_witness_index = 4; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); - insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 141, 143, 49, 10, 128, 48, 12, 69, 19, 115, 17, 71, 221, 20, 143, 32, 130, 147, 56, 186, 184, 121, 0, 113, 115, 236, 17, 196, 11, 120, 10, 209, 227, 116, 115, 116, 113, 183, 148, 22, 82, 186, 228, 65, 72, 2, 15, 242, 131, 16, 66, 166, 16, 98, 200, 245, 20, 68, 32, 49, 183, 152, 186, 69, 151, 71, 126, 245, 205, 169, 212, 48, 102, 213, 211, 174, 247, 188, 213, 250, 219, 95, 119, 79, 234, 38, 242, 12, 214, 181, 97, 216, 236, 119, 254, 19, 231, 7, 15, 145, 103, 34, 16, 1, 0, 0]"); + insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 149, 143, 49, 10, 128, 48, 12, 69, 127, 170, 7, 113, 212, 77, 241, 8, 34, 56, 137, 163, 139, 155, 7, 16, 55, 199, 30, 65, 188, 128, 167, 16, 61, 78, 55, 71, 23, 119, 29, 90, 140, 116, 105, 31, 132, 36, 240, 73, 254, 39, 252, 9, 223, 34, 216, 4, 186, 71, 112, 130, 200, 67, 43, 152, 54, 237, 235, 81, 101, 107, 178, 55, 229, 38, 101, 219, 197, 249, 89, 77, 199, 48, 23, 234, 94, 46, 237, 195, 241, 46, 132, 121, 192, 102, 179, 3, 95, 38, 206, 3, 2, 103, 244, 195, 16, 1, 0, 0]"); let program_de = Program::deserialize_program(&bytes).unwrap(); assert_eq!(program_de, program); @@ -45,12 +47,14 @@ fn multi_scalar_mul_circuit() { return values: [w7, w8, w9] BLACKBOX::MULTI_SCALAR_MUL points: [w1, w2, w3], scalars: [w4, w5], predicate: w6, outputs: [w7, w8, w9] "; - let circuit = Circuit::from_str(src).unwrap(); + let mut circuit = Circuit::from_str(src).unwrap(); + circuit.current_witness_index = 10; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); - insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 12, 66, 87, 235, 123, 255, 11, 183, 224, 13, 172, 129, 168, 136, 174, 216, 123, 59, 80, 208, 151, 87, 192, 197, 39, 42, 236, 232, 204, 27, 220, 225, 17, 152, 236, 108, 188, 201, 134, 211, 233, 146, 153, 252, 212, 238, 127, 7, 52, 214, 247, 34, 188, 0, 0, 0]"); + insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 12, 66, 87, 235, 127, 255, 3, 183, 224, 5, 214, 64, 84, 68, 151, 236, 189, 21, 72, 232, 195, 35, 224, 226, 47, 50, 236, 232, 155, 23, 184, 194, 45, 208, 217, 153, 120, 147, 13, 167, 83, 37, 51, 249, 169, 221, 255, 54, 129, 45, 40, 232, 188, 0, 0, 0]"); let program_de = Program::deserialize_program(&bytes).unwrap(); assert_eq!(program_de, program); @@ -104,13 +108,15 @@ fn simple_brillig_foreign_call() { BRILLIG CALL func: 0, inputs: [{w_input}], outputs: [{w_inverted}] " ); - let circuit = Circuit::from_str(&src).unwrap(); + let mut circuit = Circuit::from_str(&src).unwrap(); + circuit.current_witness_index = 8; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![brillig_bytecode] }; let bytes = Program::serialize_program(&program); - insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 149, 81, 237, 10, 128, 32, 12, 116, 235, 3, 161, 127, 61, 65, 111, 22, 17, 253, 8, 164, 31, 17, 61, 127, 69, 91, 204, 156, 48, 7, 58, 61, 239, 240, 142, 129, 139, 11, 239, 5, 116, 174, 169, 131, 75, 139, 177, 193, 153, 10, 192, 206, 141, 254, 195, 111, 163, 7, 52, 8, 59, 234, 235, 118, 46, 251, 49, 206, 83, 8, 13, 65, 254, 71, 125, 122, 85, 224, 205, 75, 95, 229, 122, 104, 21, 80, 70, 146, 17, 152, 251, 198, 208, 166, 32, 21, 185, 123, 14, 239, 21, 156, 157, 92, 239, 80, 232, 201, 22, 2, 0, 0]"); + insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 149, 81, 237, 10, 128, 32, 12, 116, 246, 193, 160, 127, 61, 65, 111, 22, 17, 253, 8, 164, 31, 17, 61, 127, 69, 91, 204, 156, 48, 7, 58, 61, 239, 240, 142, 129, 139, 11, 239, 5, 116, 174, 169, 131, 75, 139, 177, 193, 153, 10, 192, 206, 141, 254, 243, 223, 70, 15, 222, 32, 236, 168, 175, 219, 185, 236, 199, 56, 79, 33, 52, 4, 225, 143, 250, 244, 170, 192, 27, 74, 95, 229, 122, 104, 21, 80, 70, 146, 17, 152, 251, 198, 208, 166, 32, 21, 185, 123, 14, 239, 21, 156, 157, 92, 163, 94, 232, 115, 22, 2, 0, 0]"); let program_de = Program::deserialize_program(&bytes).unwrap(); assert_eq!(program_de, program); @@ -241,12 +247,14 @@ fn memory_op_circuit() { WRITE b0[1] = w3 READ w4 = b0[1] "; - let circuit = Circuit::from_str(src).unwrap(); + let mut circuit = Circuit::from_str(src).unwrap(); + circuit.current_witness_index = 5; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); - insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 165, 81, 91, 10, 0, 48, 8, 202, 234, 32, 187, 255, 41, 183, 143, 26, 27, 244, 209, 67, 8, 253, 80, 72, 4, 253, 208, 115, 98, 218, 153, 141, 241, 104, 166, 24, 139, 82, 192, 52, 135, 98, 78, 242, 222, 105, 183, 110, 174, 221, 77, 243, 222, 187, 169, 111, 41, 193, 3, 26, 228, 54, 173, 63, 252, 25, 40, 2, 0, 0]"); + insta::assert_compact_debug_snapshot!(bytes, @"[31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 165, 81, 65, 10, 0, 32, 8, 115, 106, 255, 232, 255, 175, 172, 131, 70, 129, 7, 211, 129, 108, 135, 13, 28, 3, 189, 24, 251, 196, 180, 51, 27, 227, 210, 76, 49, 38, 165, 128, 110, 14, 159, 57, 201, 123, 187, 221, 170, 185, 114, 55, 205, 123, 207, 166, 190, 165, 4, 15, 104, 144, 91, 71, 10, 197, 194, 40, 2, 0, 0]"); let program_de = Program::deserialize_program(&bytes).unwrap(); assert_eq!(program_de, program);