diff --git a/Cargo.lock b/Cargo.lock index 6051d356fca..c0c3079f36b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2459,6 +2459,7 @@ dependencies = [ "log", "nargo", "noirc_driver", + "noirc_errors", "noirc_frontend", "serde", "wasm-bindgen", diff --git a/acvm-repo/acir/codegen/acir.cpp b/acvm-repo/acir/codegen/acir.cpp index 428f6210fe1..1c01c4f23d5 100644 --- a/acvm-repo/acir/codegen/acir.cpp +++ b/acvm-repo/acir/codegen/acir.cpp @@ -674,43 +674,9 @@ namespace Circuit { static BrilligOutputs bincodeDeserialize(std::vector); }; - struct ForeignCallParam { - - struct Single { - Circuit::Value value; - - friend bool operator==(const Single&, const Single&); - std::vector bincodeSerialize() const; - static Single bincodeDeserialize(std::vector); - }; - - struct Array { - std::vector value; - - friend bool operator==(const Array&, const Array&); - std::vector bincodeSerialize() const; - static Array bincodeDeserialize(std::vector); - }; - - std::variant value; - - friend bool operator==(const ForeignCallParam&, const ForeignCallParam&); - std::vector bincodeSerialize() const; - static ForeignCallParam bincodeDeserialize(std::vector); - }; - - struct ForeignCallResult { - std::vector values; - - friend bool operator==(const ForeignCallResult&, const ForeignCallResult&); - std::vector bincodeSerialize() const; - static ForeignCallResult bincodeDeserialize(std::vector); - }; - struct Brillig { std::vector inputs; std::vector outputs; - std::vector foreign_call_results; std::vector bytecode; std::optional predicate; @@ -2761,7 +2727,6 @@ namespace Circuit { inline bool operator==(const Brillig &lhs, const Brillig &rhs) { if (!(lhs.inputs == rhs.inputs)) { return false; } if (!(lhs.outputs == rhs.outputs)) { return false; } - if (!(lhs.foreign_call_results == rhs.foreign_call_results)) { return false; } if (!(lhs.bytecode == rhs.bytecode)) { return false; } if (!(lhs.predicate == rhs.predicate)) { return false; } return true; @@ -2790,7 +2755,6 @@ void serde::Serializable::serialize(const Circuit::Brillig &ob serializer.increase_container_depth(); serde::Serializable::serialize(obj.inputs, serializer); serde::Serializable::serialize(obj.outputs, serializer); - serde::Serializable::serialize(obj.foreign_call_results, serializer); serde::Serializable::serialize(obj.bytecode, serializer); serde::Serializable::serialize(obj.predicate, serializer); serializer.decrease_container_depth(); @@ -2803,7 +2767,6 @@ Circuit::Brillig serde::Deserializable::deserialize(Deserializ Circuit::Brillig obj; obj.inputs = serde::Deserializable::deserialize(deserializer); obj.outputs = serde::Deserializable::deserialize(deserializer); - obj.foreign_call_results = serde::Deserializable::deserialize(deserializer); obj.bytecode = serde::Deserializable::deserialize(deserializer); obj.predicate = serde::Deserializable::deserialize(deserializer); deserializer.decrease_container_depth(); @@ -3970,166 +3933,6 @@ Circuit::Expression serde::Deserializable::deserialize(Dese return obj; } -namespace Circuit { - - inline bool operator==(const ForeignCallParam &lhs, const ForeignCallParam &rhs) { - if (!(lhs.value == rhs.value)) { return false; } - return true; - } - - inline std::vector ForeignCallParam::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline ForeignCallParam ForeignCallParam::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Circuit - -template <> -template -void serde::Serializable::serialize(const Circuit::ForeignCallParam &obj, Serializer &serializer) { - serializer.increase_container_depth(); - serde::Serializable::serialize(obj.value, serializer); - serializer.decrease_container_depth(); -} - -template <> -template -Circuit::ForeignCallParam serde::Deserializable::deserialize(Deserializer &deserializer) { - deserializer.increase_container_depth(); - Circuit::ForeignCallParam obj; - obj.value = serde::Deserializable::deserialize(deserializer); - deserializer.decrease_container_depth(); - return obj; -} - -namespace Circuit { - - inline bool operator==(const ForeignCallParam::Single &lhs, const ForeignCallParam::Single &rhs) { - if (!(lhs.value == rhs.value)) { return false; } - return true; - } - - inline std::vector ForeignCallParam::Single::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline ForeignCallParam::Single ForeignCallParam::Single::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Circuit - -template <> -template -void serde::Serializable::serialize(const Circuit::ForeignCallParam::Single &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.value, serializer); -} - -template <> -template -Circuit::ForeignCallParam::Single serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::ForeignCallParam::Single obj; - obj.value = serde::Deserializable::deserialize(deserializer); - return obj; -} - -namespace Circuit { - - inline bool operator==(const ForeignCallParam::Array &lhs, const ForeignCallParam::Array &rhs) { - if (!(lhs.value == rhs.value)) { return false; } - return true; - } - - inline std::vector ForeignCallParam::Array::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline ForeignCallParam::Array ForeignCallParam::Array::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Circuit - -template <> -template -void serde::Serializable::serialize(const Circuit::ForeignCallParam::Array &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.value, serializer); -} - -template <> -template -Circuit::ForeignCallParam::Array serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::ForeignCallParam::Array obj; - obj.value = serde::Deserializable::deserialize(deserializer); - return obj; -} - -namespace Circuit { - - inline bool operator==(const ForeignCallResult &lhs, const ForeignCallResult &rhs) { - if (!(lhs.values == rhs.values)) { return false; } - return true; - } - - inline std::vector ForeignCallResult::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline ForeignCallResult ForeignCallResult::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Circuit - -template <> -template -void serde::Serializable::serialize(const Circuit::ForeignCallResult &obj, Serializer &serializer) { - serializer.increase_container_depth(); - serde::Serializable::serialize(obj.values, serializer); - serializer.decrease_container_depth(); -} - -template <> -template -Circuit::ForeignCallResult serde::Deserializable::deserialize(Deserializer &deserializer) { - deserializer.increase_container_depth(); - Circuit::ForeignCallResult obj; - obj.values = serde::Deserializable::deserialize(deserializer); - deserializer.decrease_container_depth(); - return obj; -} - namespace Circuit { inline bool operator==(const FunctionInput &lhs, const FunctionInput &rhs) { diff --git a/acvm-repo/acir/src/circuit/brillig.rs b/acvm-repo/acir/src/circuit/brillig.rs index 5b1ec9d032a..63c6ad2a3d4 100644 --- a/acvm-repo/acir/src/circuit/brillig.rs +++ b/acvm-repo/acir/src/circuit/brillig.rs @@ -1,5 +1,4 @@ use crate::native_types::{Expression, Witness}; -use brillig::ForeignCallResult; use brillig::Opcode as BrilligOpcode; use serde::{Deserialize, Serialize}; @@ -23,9 +22,6 @@ pub enum BrilligOutputs { pub struct Brillig { pub inputs: Vec, pub outputs: Vec, - /// Results of oracles/functions external to brillig like a database read. - // Each element of this vector corresponds to a single foreign call but may contain several values. - pub foreign_call_results: Vec, /// The Brillig VM bytecode to be executed by this ACIR opcode. pub bytecode: Vec, /// Predicate of the Brillig execution - indicates if it should be skipped diff --git a/acvm-repo/acir/src/lib.rs b/acvm-repo/acir/src/lib.rs index b21aeb1a0dd..b7bcaa0c5c0 100644 --- a/acvm-repo/acir/src/lib.rs +++ b/acvm-repo/acir/src/lib.rs @@ -32,8 +32,7 @@ mod reflection { }; use brillig::{ - BinaryFieldOp, BinaryIntOp, BlackBoxOp, ForeignCallParam, ForeignCallResult, - Opcode as BrilligOpcode, RegisterOrMemory, + BinaryFieldOp, BinaryIntOp, BlackBoxOp, Opcode as BrilligOpcode, RegisterOrMemory, }; use serde_reflection::{Tracer, TracerConfig}; @@ -70,8 +69,6 @@ mod reflection { tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); let registry = tracer.registry().unwrap(); diff --git a/acvm-repo/acir/tests/test_program_serialization.rs b/acvm-repo/acir/tests/test_program_serialization.rs index 5aa51237dd9..6b2e85ab449 100644 --- a/acvm-repo/acir/tests/test_program_serialization.rs +++ b/acvm-repo/acir/tests/test_program_serialization.rs @@ -181,8 +181,6 @@ fn simple_brillig_foreign_call() { outputs: vec![ BrilligOutputs::Simple(w_inverted), // Output Register 1 ], - // stack of foreign call/oracle resolutions, starts empty - foreign_call_results: vec![], bytecode: vec![brillig::Opcode::ForeignCall { function: "invert".into(), destinations: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(0))], @@ -203,11 +201,10 @@ fn simple_brillig_foreign_call() { circuit.write(&mut bytes).unwrap(); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 143, 81, 10, 0, 16, 16, 68, 199, 42, 57, 14, 55, - 112, 25, 31, 126, 124, 72, 206, 79, 161, 86, 225, 135, 87, 219, 78, 187, 53, 205, 104, 0, - 2, 29, 201, 52, 103, 222, 220, 216, 230, 13, 43, 254, 121, 25, 158, 151, 54, 153, 117, 27, - 53, 116, 136, 197, 167, 124, 107, 184, 64, 236, 73, 56, 83, 1, 18, 139, 122, 157, 67, 1, 0, - 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 143, 49, 10, 64, 33, 12, 67, 99, 63, 124, 60, 142, + 222, 192, 203, 56, 184, 56, 136, 120, 126, 5, 21, 226, 160, 139, 62, 40, 13, 45, 132, 68, + 3, 80, 232, 124, 164, 153, 121, 115, 99, 155, 59, 172, 122, 231, 101, 56, 175, 80, 86, 221, + 230, 31, 58, 196, 226, 83, 62, 53, 91, 16, 122, 10, 246, 84, 99, 243, 0, 30, 59, 1, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -248,8 +245,6 @@ fn complex_brillig_foreign_call() { BrilligOutputs::Simple(a_plus_b_plus_c), // Output Register 1 BrilligOutputs::Simple(a_plus_b_plus_c_times_2), // Output Register 2 ], - // stack of foreign call/oracle resolutions, starts empty - foreign_call_results: vec![], bytecode: vec![ // Oracles are named 'foreign calls' in brillig brillig::Opcode::ForeignCall { @@ -280,13 +275,13 @@ fn complex_brillig_foreign_call() { circuit.write(&mut bytes).unwrap(); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 219, 10, 128, 48, 8, 245, 210, 101, 159, 179, - 254, 160, 127, 137, 222, 138, 122, 236, 243, 27, 228, 64, 44, 232, 33, 7, 237, 128, 56, - 157, 147, 131, 103, 6, 0, 64, 184, 192, 201, 72, 206, 40, 177, 70, 174, 27, 197, 199, 111, - 24, 208, 175, 87, 44, 197, 145, 42, 224, 200, 5, 56, 230, 255, 240, 83, 189, 61, 117, 113, - 157, 31, 63, 236, 79, 147, 172, 77, 214, 73, 220, 139, 15, 106, 214, 168, 114, 249, 126, - 218, 214, 125, 153, 15, 54, 37, 90, 26, 155, 39, 227, 95, 223, 232, 230, 4, 247, 157, 215, - 56, 1, 153, 86, 63, 138, 44, 4, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 219, 10, 128, 48, 8, 117, 174, 139, 159, 179, + 254, 160, 127, 137, 222, 138, 122, 236, 243, 19, 114, 32, 22, 244, 144, 131, 118, 64, 156, + 178, 29, 14, 59, 74, 0, 16, 224, 66, 228, 64, 57, 7, 169, 53, 242, 189, 81, 114, 250, 134, + 33, 248, 113, 165, 82, 26, 177, 2, 141, 177, 128, 198, 60, 15, 63, 245, 219, 211, 23, 215, + 255, 139, 15, 251, 211, 112, 180, 28, 157, 212, 189, 100, 82, 179, 64, 170, 63, 109, 235, + 190, 204, 135, 166, 178, 150, 216, 62, 154, 252, 250, 70, 147, 35, 220, 119, 93, 227, 4, + 182, 131, 81, 25, 36, 4, 0, 0, ]; assert_eq!(bytes, expected_serialization) diff --git a/acvm-repo/acvm/src/compiler/transformers/fallback.rs b/acvm-repo/acvm/src/compiler/transformers/fallback.rs index d3e4ea506f8..06dfc84a798 100644 --- a/acvm-repo/acvm/src/compiler/transformers/fallback.rs +++ b/acvm-repo/acvm/src/compiler/transformers/fallback.rs @@ -60,7 +60,11 @@ impl FallbackTransformer { } Ok(( - Circuit { current_witness_index: witness_idx, opcodes: acir_supported_opcodes, ..acir }, + Circuit { + current_witness_index: witness_idx - 1, + opcodes: acir_supported_opcodes, + ..acir + }, new_opcode_positions, )) } diff --git a/acvm-repo/acvm/src/pwg/brillig.rs b/acvm-repo/acvm/src/pwg/brillig.rs index b35e227a77c..6fc54d42eab 100644 --- a/acvm-repo/acvm/src/pwg/brillig.rs +++ b/acvm-repo/acvm/src/pwg/brillig.rs @@ -1,5 +1,5 @@ use acir::{ - brillig::{ForeignCallParam, RegisterIndex, Value}, + brillig::{ForeignCallParam, ForeignCallResult, RegisterIndex, Value}, circuit::{ brillig::{Brillig, BrilligInputs, BrilligOutputs}, OpcodeLocation, @@ -14,28 +14,59 @@ use crate::{pwg::OpcodeNotSolvable, OpcodeResolutionError}; use super::{get_value, insert_value}; -pub(super) struct BrilligSolver; +pub(super) enum BrilligSolverStatus { + Finished, + InProgress, + ForeignCallWait(ForeignCallWaitInfo), +} -impl BrilligSolver { - pub(super) fn solve( - initial_witness: &mut WitnessMap, +pub(super) struct BrilligSolver<'b, B: BlackBoxFunctionSolver> { + vm: VM<'b, B>, + acir_index: usize, +} + +impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { + /// Evaluates if the Brillig block should be skipped entirely + pub(super) fn should_skip( + witness: &WitnessMap, brillig: &Brillig, - bb_solver: &B, - acir_index: usize, - ) -> Result, OpcodeResolutionError> { - // If the predicate is `None`, then we simply return the value 1 + ) -> Result { + // If the predicate is `None`, the block should never be skipped // If the predicate is `Some` but we cannot find a value, then we return stalled - let pred_value = match &brillig.predicate { - Some(pred) => get_value(pred, initial_witness), - None => Ok(FieldElement::one()), - }?; + match &brillig.predicate { + Some(pred) => Ok(get_value(pred, witness)?.is_zero()), + None => Ok(false), + } + } - // A zero predicate indicates the oracle should be skipped, and its outputs zeroed. - if pred_value.is_zero() { - Self::zero_out_brillig_outputs(initial_witness, brillig)?; - return Ok(None); + /// Assigns the zero value to all outputs of the given [`Brillig`] bytecode. + pub(super) fn zero_out_brillig_outputs( + initial_witness: &mut WitnessMap, + brillig: &Brillig, + ) -> Result<(), OpcodeResolutionError> { + for output in &brillig.outputs { + match output { + BrilligOutputs::Simple(witness) => { + insert_value(witness, FieldElement::zero(), initial_witness)?; + } + BrilligOutputs::Array(witness_arr) => { + for witness in witness_arr { + insert_value(witness, FieldElement::zero(), initial_witness)?; + } + } + } } + Ok(()) + } + /// Constructs a solver for a Brillig block given the bytecode and initial + /// witness. + pub(super) fn new( + initial_witness: &mut WitnessMap, + brillig: &'b Brillig, + bb_solver: &'b B, + acir_index: usize, + ) -> Result { // Set input values let mut input_register_values: Vec = Vec::new(); let mut input_memory: Vec = Vec::new(); @@ -74,80 +105,92 @@ impl BrilligSolver { } // Instantiate a Brillig VM given the solved input registers and memory - // along with the Brillig bytecode, and any present foreign call results. + // along with the Brillig bytecode. let input_registers = Registers::load(input_register_values); - let mut vm = VM::new( - input_registers, - input_memory, - &brillig.bytecode, - brillig.foreign_call_results.clone(), - bb_solver, - ); + let vm = VM::new(input_registers, input_memory, &brillig.bytecode, vec![], bb_solver); + Ok(Self { vm, acir_index }) + } - // Run the Brillig VM on these inputs, bytecode, etc! - let vm_status = vm.process_opcodes(); + pub(super) fn solve(&mut self) -> Result { + let status = self.vm.process_opcodes(); + self.handle_vm_status(status) + } - // Check the status of the Brillig VM. + fn handle_vm_status( + &self, + vm_status: VMStatus, + ) -> Result { + // Check the status of the Brillig VM and return a resolution. // It may be finished, in-progress, failed, or may be waiting for results of a foreign call. // Return the "resolution" to the caller who may choose to make subsequent calls // (when it gets foreign call results for example). match vm_status { - VMStatus::Finished => { - for (i, output) in brillig.outputs.iter().enumerate() { - let register_value = vm.get_registers().get(RegisterIndex::from(i)); - match output { - BrilligOutputs::Simple(witness) => { - insert_value(witness, register_value.to_field(), initial_witness)?; - } - BrilligOutputs::Array(witness_arr) => { - // Treat the register value as a pointer to memory - for (i, witness) in witness_arr.iter().enumerate() { - let value = &vm.get_memory()[register_value.to_usize() + i]; - insert_value(witness, value.to_field(), initial_witness)?; - } - } - } - } - Ok(None) - } - VMStatus::InProgress => unreachable!("Brillig VM has not completed execution"), + VMStatus::Finished => Ok(BrilligSolverStatus::Finished), + VMStatus::InProgress => Ok(BrilligSolverStatus::InProgress), VMStatus::Failure { message, call_stack } => { Err(OpcodeResolutionError::BrilligFunctionFailed { message, call_stack: call_stack .iter() .map(|brillig_index| OpcodeLocation::Brillig { - acir_index, + acir_index: self.acir_index, brillig_index: *brillig_index, }) .collect(), }) } VMStatus::ForeignCallWait { function, inputs } => { - Ok(Some(ForeignCallWaitInfo { function, inputs })) + Ok(BrilligSolverStatus::ForeignCallWait(ForeignCallWaitInfo { function, inputs })) } } } - /// Assigns the zero value to all outputs of the given [`Brillig`] bytecode. - fn zero_out_brillig_outputs( - initial_witness: &mut WitnessMap, + pub(super) fn finalize( + self, + witness: &mut WitnessMap, brillig: &Brillig, ) -> Result<(), OpcodeResolutionError> { - for output in &brillig.outputs { + // Finish the Brillig execution by writing the outputs to the witness map + let vm_status = self.vm.get_status(); + match vm_status { + VMStatus::Finished => { + self.write_brillig_outputs(witness, brillig)?; + Ok(()) + } + _ => panic!("Brillig VM has not completed execution"), + } + } + + fn write_brillig_outputs( + &self, + witness_map: &mut WitnessMap, + brillig: &Brillig, + ) -> Result<(), OpcodeResolutionError> { + // Write VM execution results into the witness map + for (i, output) in brillig.outputs.iter().enumerate() { + let register_value = self.vm.get_registers().get(RegisterIndex::from(i)); match output { BrilligOutputs::Simple(witness) => { - insert_value(witness, FieldElement::zero(), initial_witness)?; + insert_value(witness, register_value.to_field(), witness_map)?; } BrilligOutputs::Array(witness_arr) => { - for witness in witness_arr { - insert_value(witness, FieldElement::zero(), initial_witness)?; + // Treat the register value as a pointer to memory + for (i, witness) in witness_arr.iter().enumerate() { + let value = &self.vm.get_memory()[register_value.to_usize() + i]; + insert_value(witness, value.to_field(), witness_map)?; } } } } Ok(()) } + + pub(super) fn resolve_pending_foreign_call(&mut self, foreign_call_result: ForeignCallResult) { + match self.vm.get_status() { + VMStatus::ForeignCallWait { .. } => self.vm.resolve_foreign_call(foreign_call_result), + _ => unreachable!("Brillig VM is not waiting for a foreign call"), + } + } } /// Encapsulates a request from a Brillig VM process that encounters a [foreign call opcode][acir::brillig_vm::Opcode::ForeignCall] diff --git a/acvm-repo/acvm/src/pwg/mod.rs b/acvm-repo/acvm/src/pwg/mod.rs index 3fcf1088225..057597e6392 100644 --- a/acvm-repo/acvm/src/pwg/mod.rs +++ b/acvm-repo/acvm/src/pwg/mod.rs @@ -11,7 +11,9 @@ use acir::{ use acvm_blackbox_solver::BlackBoxResolutionError; use self::{ - arithmetic::ArithmeticSolver, brillig::BrilligSolver, directives::solve_directives, + arithmetic::ArithmeticSolver, + brillig::{BrilligSolver, BrilligSolverStatus}, + directives::solve_directives, memory_op::MemoryOpSolver, }; use crate::{BlackBoxFunctionSolver, Language}; @@ -126,24 +128,26 @@ impl From for OpcodeResolutionError { } } -pub struct ACVM<'backend, B: BlackBoxFunctionSolver> { +pub struct ACVM<'a, B: BlackBoxFunctionSolver> { status: ACVMStatus, - backend: &'backend B, + backend: &'a B, /// Stores the solver for memory operations acting on blocks of memory disambiguated by [block][`BlockId`]. block_solvers: HashMap, /// A list of opcodes which are to be executed by the ACVM. - opcodes: Vec, + opcodes: &'a [Opcode], /// Index of the next opcode to be executed. instruction_pointer: usize, witness_map: WitnessMap, + + brillig_solver: Option>, } -impl<'backend, B: BlackBoxFunctionSolver> ACVM<'backend, B> { - pub fn new(backend: &'backend B, opcodes: Vec, initial_witness: WitnessMap) -> Self { +impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { + pub fn new(backend: &'a B, opcodes: &'a [Opcode], initial_witness: WitnessMap) -> Self { let status = if opcodes.is_empty() { ACVMStatus::Solved } else { ACVMStatus::InProgress }; ACVM { status, @@ -152,6 +156,7 @@ impl<'backend, B: BlackBoxFunctionSolver> ACVM<'backend, B> { opcodes, instruction_pointer: 0, witness_map: initial_witness, + brillig_solver: None, } } @@ -164,7 +169,7 @@ impl<'backend, B: BlackBoxFunctionSolver> ACVM<'backend, B> { /// Returns a slice containing the opcodes of the circuit being executed. pub fn opcodes(&self) -> &[Opcode] { - &self.opcodes + self.opcodes } /// Returns the index of the current opcode to be executed. @@ -216,12 +221,8 @@ impl<'backend, B: BlackBoxFunctionSolver> ACVM<'backend, B> { panic!("ACVM is not expecting a foreign call response as no call was made"); } - // We want to inject the foreign call result into the brillig opcode which initiated the call. - let opcode = &mut self.opcodes[self.instruction_pointer]; - let Opcode::Brillig(brillig) = opcode else { - unreachable!("ACVM can only enter `RequiresForeignCall` state on a Brillig opcode"); - }; - brillig.foreign_call_results.push(foreign_call_result); + let brillig_solver = self.brillig_solver.as_mut().expect("No active Brillig solver"); + brillig_solver.resolve_pending_foreign_call(foreign_call_result); // Now that the foreign call has been resolved then we can resume execution. self.status(ACVMStatus::InProgress); @@ -257,17 +258,10 @@ impl<'backend, B: BlackBoxFunctionSolver> ACVM<'backend, B> { let solver = self.block_solvers.entry(*block_id).or_default(); solver.solve_memory_op(op, &mut self.witness_map, predicate) } - Opcode::Brillig(brillig) => { - match BrilligSolver::solve( - &mut self.witness_map, - brillig, - self.backend, - self.instruction_pointer, - ) { - Ok(Some(foreign_call)) => return self.wait_for_foreign_call(foreign_call), - res => res.map(|_| ()), - } - } + Opcode::Brillig(_) => match self.solve_brillig_opcode() { + Ok(Some(foreign_call)) => return self.wait_for_foreign_call(foreign_call), + res => res.map(|_| ()), + }, }; match resolution { Ok(()) => { @@ -301,6 +295,42 @@ impl<'backend, B: BlackBoxFunctionSolver> ACVM<'backend, B> { } } } + + fn solve_brillig_opcode( + &mut self, + ) -> Result, OpcodeResolutionError> { + let Opcode::Brillig(brillig) = &self.opcodes[self.instruction_pointer] else { + unreachable!("Not executing a Brillig opcode"); + }; + let witness = &mut self.witness_map; + if BrilligSolver::::should_skip(witness, brillig)? { + BrilligSolver::::zero_out_brillig_outputs(witness, brillig).map(|_| None) + } else { + // If we're resuming execution after resolving a foreign call then + // there will be a cached `BrilligSolver` to avoid recomputation. + let mut solver: BrilligSolver<'_, B> = match self.brillig_solver.take() { + Some(solver) => solver, + None => { + BrilligSolver::new(witness, brillig, self.backend, self.instruction_pointer)? + } + }; + match solver.solve()? { + BrilligSolverStatus::ForeignCallWait(foreign_call) => { + // Cache the current state of the solver + self.brillig_solver = Some(solver); + Ok(Some(foreign_call)) + } + BrilligSolverStatus::InProgress => { + unreachable!("Brillig solver still in progress") + } + BrilligSolverStatus::Finished => { + // Write execution outputs + solver.finalize(witness, brillig)?; + Ok(None) + } + } + } + } } // Returns the concrete value for a particular witness diff --git a/acvm-repo/acvm/tests/solver.rs b/acvm-repo/acvm/tests/solver.rs index d2bd3347945..1d287d70c1b 100644 --- a/acvm-repo/acvm/tests/solver.rs +++ b/acvm-repo/acvm/tests/solver.rs @@ -90,8 +90,6 @@ fn inversion_brillig_oracle_equivalence() { BrilligOutputs::Simple(w_oracle), // Output Register 1 BrilligOutputs::Simple(w_equal_res), // Output Register 2 ], - // stack of foreign call/oracle resolutions, starts empty - foreign_call_results: vec![], bytecode: vec![ equal_opcode, // Oracles are named 'foreign calls' in brillig @@ -130,7 +128,7 @@ fn inversion_brillig_oracle_equivalence() { ]) .into(); - let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &opcodes, witness_assignments); // use the partial witness generation solver with our acir program let solver_status = acvm.solve(); @@ -214,8 +212,6 @@ fn double_inversion_brillig_oracle() { BrilligOutputs::Simple(w_ij_oracle), // Output Register 3 BrilligOutputs::Simple(w_equal_res), // Output Register 4 ], - // stack of foreign call/oracle resolutions, starts empty - foreign_call_results: vec![], bytecode: vec![ equal_opcode, // Oracles are named 'foreign calls' in brillig @@ -261,7 +257,7 @@ fn double_inversion_brillig_oracle() { ]) .into(); - let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &opcodes, witness_assignments); // use the partial witness generation solver with our acir program let solver_status = acvm.solve(); @@ -342,8 +338,6 @@ fn oracle_dependent_execution() { BrilligOutputs::Simple(w_y), // Output Register 2 - from input BrilligOutputs::Simple(w_y_inv), // Output Register 3 ], - // stack of foreign call/oracle resolutions, starts empty - foreign_call_results: vec![], bytecode: vec![ // Oracles are named 'foreign calls' in brillig BrilligOpcode::ForeignCall { @@ -384,7 +378,7 @@ fn oracle_dependent_execution() { let witness_assignments = BTreeMap::from([(w_x, FieldElement::from(2u128)), (w_y, FieldElement::from(2u128))]).into(); - let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &opcodes, witness_assignments); // use the partial witness generation solver with our acir program let solver_status = acvm.solve(); @@ -473,8 +467,6 @@ fn brillig_oracle_predicate() { }, ], predicate: Some(Expression::default()), - // oracle results - foreign_call_results: vec![], }); let opcodes = vec![brillig_opcode]; @@ -485,7 +477,7 @@ fn brillig_oracle_predicate() { ]) .into(); - let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &opcodes, witness_assignments); let solver_status = acvm.solve(); assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); @@ -518,7 +510,7 @@ fn unsatisfied_opcode_resolved() { values.insert(d, FieldElement::from(2_i128)); let opcodes = vec![Opcode::Arithmetic(opcode_a)]; - let mut acvm = ACVM::new(&StubbedBackend, opcodes, values); + let mut acvm = ACVM::new(&StubbedBackend, &opcodes, values); let solver_status = acvm.solve(); assert_eq!( solver_status, @@ -574,8 +566,6 @@ fn unsatisfied_opcode_resolved_brillig() { outputs: vec![BrilligOutputs::Simple(w_result)], bytecode: vec![equal_opcode, jmp_if_opcode, trap_opcode, stop_opcode], predicate: Some(Expression::one()), - // oracle results - foreign_call_results: vec![], }); let opcode_a = Expression { @@ -600,7 +590,7 @@ fn unsatisfied_opcode_resolved_brillig() { let opcodes = vec![brillig_opcode, Opcode::Arithmetic(opcode_a)]; - let mut acvm = ACVM::new(&StubbedBackend, opcodes, values); + let mut acvm = ACVM::new(&StubbedBackend, &opcodes, values); let solver_status = acvm.solve(); assert_eq!( solver_status, @@ -644,7 +634,7 @@ fn memory_operations() { let opcodes = vec![init, read_op, expression]; - let mut acvm = ACVM::new(&StubbedBackend, opcodes, initial_witness); + let mut acvm = ACVM::new(&StubbedBackend, &opcodes, initial_witness); let solver_status = acvm.solve(); assert_eq!(solver_status, ACVMStatus::Solved); let witness_map = acvm.finalize(); diff --git a/acvm-repo/acvm/tests/stdlib.rs b/acvm-repo/acvm/tests/stdlib.rs index 309130d3992..c96c55f9401 100644 --- a/acvm-repo/acvm/tests/stdlib.rs +++ b/acvm-repo/acvm/tests/stdlib.rs @@ -74,7 +74,7 @@ macro_rules! test_uint_inner { let uint = $uint::new(w); let (w, extra_opcodes, _) = uint.rol(y, 2); let witness_assignments = BTreeMap::from([(Witness(1), fe)]).into(); - let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &extra_opcodes, witness_assignments); let solver_status = acvm.solve(); prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); @@ -89,7 +89,7 @@ macro_rules! test_uint_inner { let uint = $uint::new(w); let (w, extra_opcodes, _) = uint.ror(y, 2); let witness_assignments = BTreeMap::from([(Witness(1), fe)]).into(); - let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &extra_opcodes, witness_assignments); let solver_status = acvm.solve(); prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); @@ -109,7 +109,7 @@ macro_rules! test_uint_inner { let u32_2 = $uint::new(w2); let (q_w, r_w, extra_opcodes, _) = $uint::euclidean_division(&u32_1, &u32_2, 3); let witness_assignments = BTreeMap::from([(Witness(1), lhs),(Witness(2), rhs)]).into(); - let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &extra_opcodes, witness_assignments); let solver_status = acvm.solve(); prop_assert_eq!(acvm.witness_map().get(&q_w.get_inner()).unwrap(), &FieldElement::from(q as u128)); @@ -135,7 +135,7 @@ macro_rules! test_uint_inner { let (w2, extra_opcodes, _) = w.add(&u32_3, num_witness); opcodes.extend(extra_opcodes); let witness_assignments = BTreeMap::from([(Witness(1), lhs), (Witness(2), rhs), (Witness(3), rhs_z)]).into(); - let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &opcodes, witness_assignments); let solver_status = acvm.solve(); prop_assert_eq!(acvm.witness_map().get(&w2.get_inner()).unwrap(), &result); @@ -160,7 +160,7 @@ macro_rules! test_uint_inner { let (w2, extra_opcodes, _) = w.sub(&u32_3, num_witness); opcodes.extend(extra_opcodes); let witness_assignments = BTreeMap::from([(Witness(1), lhs), (Witness(2), rhs), (Witness(3), rhs_z)]).into(); - let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &opcodes, witness_assignments); let solver_status = acvm.solve(); prop_assert_eq!(acvm.witness_map().get(&w2.get_inner()).unwrap(), &result); @@ -175,7 +175,7 @@ macro_rules! test_uint_inner { let u32_1 = $uint::new(w1); let (w, extra_opcodes, _) = u32_1.leftshift(y, 2); let witness_assignments = BTreeMap::from([(Witness(1), lhs)]).into(); - let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &extra_opcodes, witness_assignments); let solver_status = acvm.solve(); prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); @@ -190,7 +190,7 @@ macro_rules! test_uint_inner { let u32_1 = $uint::new(w1); let (w, extra_opcodes, _) = u32_1.rightshift(y, 2); let witness_assignments = BTreeMap::from([(Witness(1), lhs)]).into(); - let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &extra_opcodes, witness_assignments); let solver_status = acvm.solve(); prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); @@ -208,7 +208,7 @@ macro_rules! test_uint_inner { let u32_2 = $uint::new(w2); let (w, extra_opcodes, _) = u32_1.less_than_comparison(&u32_2, 3); let witness_assignments = BTreeMap::from([(Witness(1), lhs), (Witness(2), rhs)]).into(); - let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let mut acvm = ACVM::new(&StubbedBackend, &extra_opcodes, witness_assignments); let solver_status = acvm.solve(); prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); @@ -290,7 +290,7 @@ macro_rules! test_hashes { let circuit = compile(circuit, Language::PLONKCSat{ width: 3 }, $opcode_support).unwrap().0; // solve witnesses - let mut acvm = ACVM::new(&StubbedBackend, circuit.opcodes, witness_assignments.into()); + let mut acvm = ACVM::new(&StubbedBackend, &circuit.opcodes, witness_assignments.into()); let solver_status = acvm.solve(); prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); @@ -346,7 +346,7 @@ proptest! { let circuit = compile(circuit, Language::PLONKCSat{ width: 3 }, does_not_support_hash_to_field).unwrap().0; // solve witnesses - let mut acvm = ACVM::new(&StubbedBackend, circuit.opcodes, witness_assignments.into()); + let mut acvm = ACVM::new(&StubbedBackend, &circuit.opcodes, witness_assignments.into()); let solver_status = acvm.solve(); prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); diff --git a/acvm-repo/acvm_js/src/execute.rs b/acvm-repo/acvm_js/src/execute.rs index e623aff42bd..eff9dcf8c25 100644 --- a/acvm-repo/acvm_js/src/execute.rs +++ b/acvm-repo/acvm_js/src/execute.rs @@ -66,7 +66,7 @@ pub async fn execute_circuit_with_black_box_solver( console_error_panic_hook::set_once(); let circuit: Circuit = Circuit::read(&*circuit).expect("Failed to deserialize circuit"); - let mut acvm = ACVM::new(&solver.0, circuit.opcodes, initial_witness.into()); + let mut acvm = ACVM::new(&solver.0, &circuit.opcodes, initial_witness.into()); loop { let solver_status = acvm.solve(); diff --git a/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts b/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts index 9fad300add1..1b6f5e4319a 100644 --- a/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts +++ b/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts @@ -2,11 +2,11 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `complex_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 219, 10, 128, 48, 8, 245, 210, 101, 159, 179, 254, 160, 127, 137, 222, - 138, 122, 236, 243, 27, 228, 64, 44, 232, 33, 7, 237, 128, 56, 157, 147, 131, 103, 6, 0, 64, 184, 192, 201, 72, 206, - 40, 177, 70, 174, 27, 197, 199, 111, 24, 208, 175, 87, 44, 197, 145, 42, 224, 200, 5, 56, 230, 255, 240, 83, 189, 61, - 117, 113, 157, 31, 63, 236, 79, 147, 172, 77, 214, 73, 220, 139, 15, 106, 214, 168, 114, 249, 126, 218, 214, 125, 153, - 15, 54, 37, 90, 26, 155, 39, 227, 95, 223, 232, 230, 4, 247, 157, 215, 56, 1, 153, 86, 63, 138, 44, 4, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 219, 10, 128, 48, 8, 117, 174, 139, 159, 179, 254, 160, 127, 137, 222, + 138, 122, 236, 243, 19, 114, 32, 22, 244, 144, 131, 118, 64, 156, 178, 29, 14, 59, 74, 0, 16, 224, 66, 228, 64, 57, 7, + 169, 53, 242, 189, 81, 114, 250, 134, 33, 248, 113, 165, 82, 26, 177, 2, 141, 177, 128, 198, 60, 15, 63, 245, 219, + 211, 23, 215, 255, 139, 15, 251, 211, 112, 180, 28, 157, 212, 189, 100, 82, 179, 64, 170, 63, 109, 235, 190, 204, 135, + 166, 178, 150, 216, 62, 154, 252, 250, 70, 147, 35, 220, 119, 93, 227, 4, 182, 131, 81, 25, 36, 4, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], diff --git a/acvm-repo/acvm_js/test/shared/foreign_call.ts b/acvm-repo/acvm_js/test/shared/foreign_call.ts index 8f4c76effd2..178ec3a09d1 100644 --- a/acvm-repo/acvm_js/test/shared/foreign_call.ts +++ b/acvm-repo/acvm_js/test/shared/foreign_call.ts @@ -2,10 +2,10 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `simple_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 143, 81, 10, 0, 16, 16, 68, 199, 42, 57, 14, 55, 112, 25, 31, 126, 124, 72, - 206, 79, 161, 86, 225, 135, 87, 219, 78, 187, 53, 205, 104, 0, 2, 29, 201, 52, 103, 222, 220, 216, 230, 13, 43, 254, - 121, 25, 158, 151, 54, 153, 117, 27, 53, 116, 136, 197, 167, 124, 107, 184, 64, 236, 73, 56, 83, 1, 18, 139, 122, 157, - 67, 1, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 143, 49, 10, 64, 33, 12, 67, 99, 63, 124, 60, 142, 222, 192, 203, 56, 184, 56, + 136, 120, 126, 5, 21, 226, 160, 139, 62, 40, 13, 45, 132, 68, 3, 80, 232, 124, 164, 153, 121, 115, 99, 155, 59, 172, + 122, 231, 101, 56, 175, 80, 86, 221, 230, 31, 58, 196, 226, 83, 62, 53, 91, 16, 122, 10, 246, 84, 99, 243, 0, 30, 59, + 1, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000005'], diff --git a/acvm-repo/brillig_vm/src/lib.rs b/acvm-repo/brillig_vm/src/lib.rs index 6da34c6a498..48f6bf5f1c4 100644 --- a/acvm-repo/brillig_vm/src/lib.rs +++ b/acvm-repo/brillig_vm/src/lib.rs @@ -112,6 +112,10 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { status } + pub fn get_status(&self) -> VMStatus { + self.status.clone() + } + /// Sets the current status of the VM to Finished (completed execution). fn finish(&mut self) -> VMStatus { self.status(VMStatus::Finished) @@ -127,6 +131,14 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.status(VMStatus::ForeignCallWait { function, inputs }) } + pub fn resolve_foreign_call(&mut self, foreign_call_result: ForeignCallResult) { + if self.foreign_call_counter < self.foreign_call_results.len() { + panic!("No unresolved foreign calls"); + } + self.foreign_call_results.push(foreign_call_result); + self.status(VMStatus::InProgress); + } + /// Sets the current status of the VM to `fail`. /// Indicating that the VM encountered a `Trap` Opcode /// or an invalid state. @@ -926,7 +938,7 @@ mod tests { ); // Push result we're waiting for - vm.foreign_call_results.push( + vm.resolve_foreign_call( Value::from(10u128).into(), // Result of doubling 5u128 ); @@ -987,7 +999,7 @@ mod tests { ); // Push result we're waiting for - vm.foreign_call_results.push(expected_result.clone().into()); + vm.resolve_foreign_call(expected_result.clone().into()); // Resume VM brillig_execute(&mut vm); @@ -1060,7 +1072,7 @@ mod tests { ); // Push result we're waiting for - vm.foreign_call_results.push(ForeignCallResult { + vm.resolve_foreign_call(ForeignCallResult { values: vec![ForeignCallParam::Array(output_string.clone())], }); @@ -1122,7 +1134,7 @@ mod tests { ); // Push result we're waiting for - vm.foreign_call_results.push(expected_result.clone().into()); + vm.resolve_foreign_call(expected_result.clone().into()); // Resume VM brillig_execute(&mut vm); @@ -1207,7 +1219,7 @@ mod tests { ); // Push result we're waiting for - vm.foreign_call_results.push(expected_result.clone().into()); + vm.resolve_foreign_call(expected_result.clone().into()); // Resume VM brillig_execute(&mut vm); diff --git a/acvm-repo/stdlib/src/blackbox_fallbacks/hash_to_field.rs b/acvm-repo/stdlib/src/blackbox_fallbacks/hash_to_field.rs index 46e2de6f129..91a7cdd09e4 100644 --- a/acvm-repo/stdlib/src/blackbox_fallbacks/hash_to_field.rs +++ b/acvm-repo/stdlib/src/blackbox_fallbacks/hash_to_field.rs @@ -103,7 +103,6 @@ fn field_addition( }), ], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![brillig::Opcode::BinaryFieldOp { op: brillig::BinaryFieldOp::Add, lhs: RegisterIndex::from(0), @@ -149,7 +148,6 @@ pub(crate) fn field_mul( }), ], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![brillig::Opcode::BinaryFieldOp { op: brillig::BinaryFieldOp::Mul, lhs: RegisterIndex::from(0), diff --git a/acvm-repo/stdlib/src/blackbox_fallbacks/sha256.rs b/acvm-repo/stdlib/src/blackbox_fallbacks/sha256.rs index c9de55ffd0d..1661b030bcc 100644 --- a/acvm-repo/stdlib/src/blackbox_fallbacks/sha256.rs +++ b/acvm-repo/stdlib/src/blackbox_fallbacks/sha256.rs @@ -155,7 +155,6 @@ pub(crate) fn pad(number: u32, bit_size: u32, mut num_witness: u32) -> (u32, Wit q_c: FieldElement::from(number as u128), })], outputs: vec![BrilligOutputs::Simple(pad)], - foreign_call_results: vec![], bytecode: vec![brillig::Opcode::Stop], predicate: None, }); diff --git a/acvm-repo/stdlib/src/blackbox_fallbacks/uint.rs b/acvm-repo/stdlib/src/blackbox_fallbacks/uint.rs index a65cf776e54..6f4039835f7 100644 --- a/acvm-repo/stdlib/src/blackbox_fallbacks/uint.rs +++ b/acvm-repo/stdlib/src/blackbox_fallbacks/uint.rs @@ -55,7 +55,6 @@ macro_rules! impl_uint { q_c: FieldElement::from(2_u128.pow(self.width)), })], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![brillig::Opcode::Stop], predicate: None, }); @@ -81,7 +80,6 @@ macro_rules! impl_uint { q_c: FieldElement::from(constant as u128), })], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![brillig::Opcode::Stop], predicate: None, }); @@ -230,7 +228,6 @@ macro_rules! impl_uint { }), ], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![brillig::Opcode::BinaryIntOp { op: brillig::BinaryIntOp::Add, bit_size: 127, @@ -289,7 +286,6 @@ macro_rules! impl_uint { }), ], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![ brillig::Opcode::BinaryIntOp { op: brillig::BinaryIntOp::Add, @@ -364,7 +360,6 @@ macro_rules! impl_uint { }), ], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![ brillig::Opcode::BinaryIntOp { op: brillig::BinaryIntOp::Sub, @@ -421,7 +416,6 @@ macro_rules! impl_uint { }), ], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![brillig::Opcode::BinaryFieldOp { op: brillig::BinaryFieldOp::Mul, lhs: RegisterIndex::from(0), @@ -519,7 +513,6 @@ macro_rules! impl_uint { }), ], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![brillig::Opcode::BinaryIntOp { op: brillig::BinaryIntOp::Sub, bit_size: self.width, @@ -573,7 +566,6 @@ macro_rules! impl_uint { }), ], outputs: vec![BrilligOutputs::Simple(new_witness)], - foreign_call_results: vec![], bytecode: vec![ brillig::Opcode::BinaryIntOp { op: brillig::BinaryIntOp::Add, diff --git a/compiler/integration-tests/package.json b/compiler/integration-tests/package.json index cf6df8b4703..344d1361263 100644 --- a/compiler/integration-tests/package.json +++ b/compiler/integration-tests/package.json @@ -25,7 +25,6 @@ "eslint": "^8.50.0", "eslint-plugin-prettier": "^5.0.0", "ethers": "^6.7.1", - "fflate": "^0.8.0", "hardhat": "^2.17.4", "prettier": "3.0.3", "smol-toml": "^1.1.2", diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 325088dbf0b..7f04105e05f 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -878,7 +878,7 @@ impl AcirContext { // Optimistically try executing the brillig now, if we can complete execution they just return the results. // This is a temporary measure pending SSA optimizations being applied to Brillig which would remove constant-input opcodes (See #2066) if let Some(brillig_outputs) = - self.execute_brillig(generated_brillig.byte_code.clone(), &b_inputs, &outputs) + self.execute_brillig(&generated_brillig.byte_code, &b_inputs, &outputs) { return Ok(brillig_outputs); } @@ -965,7 +965,7 @@ impl AcirContext { fn execute_brillig( &mut self, - code: Vec, + code: &[BrilligOpcode], inputs: &[BrilligInputs], outputs_types: &[AcirType], ) -> Option> { @@ -1238,7 +1238,7 @@ pub(crate) struct AcirVar(usize); /// /// Returns `None` if complete execution of the Brillig bytecode is not possible. fn execute_brillig( - code: Vec, + code: &[BrilligOpcode], inputs: &[BrilligInputs], ) -> Option<(Registers, Vec)> { struct NullBbSolver; @@ -1294,7 +1294,7 @@ fn execute_brillig( // Instantiate a Brillig VM given the solved input registers and memory, along with the Brillig bytecode. let input_registers = Registers::load(input_register_values); - let mut vm = VM::new(input_registers, input_memory, &code, Vec::new(), &NullBbSolver); + let mut vm = VM::new(input_registers, input_memory, code, Vec::new(), &NullBbSolver); // Run the Brillig VM on these inputs, bytecode, etc! let vm_status = vm.process_opcodes(); diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index bbba5bcac82..aae9ed97006 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -844,7 +844,6 @@ impl GeneratedAcir { let opcode = AcirOpcode::Brillig(AcvmBrillig { inputs, outputs, - foreign_call_results: Vec::new(), bytecode: generated_brillig.byte_code, predicate, }); diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index ed317f69a16..93e5722aee0 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1864,13 +1864,7 @@ impl Context { mod tests { use std::{collections::HashMap, rc::Rc}; - use acvm::{ - acir::{ - circuit::Opcode, - native_types::{Expression, Witness}, - }, - FieldElement, - }; + use acvm::FieldElement; use crate::{ brillig::Brillig, diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 38fb88f742c..86cdd936b0d 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -394,15 +394,12 @@ fn collect_impls( let module = &mut def_maps.get_mut(&crate_id).unwrap().modules[type_module.0]; for (_, method_id, method) in &unresolved.functions { - let result = module.declare_function(method.name_ident().clone(), *method_id); - - if let Err((first_def, second_def)) = result { - let error = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::Function, - first_def, - second_def, - }; - errors.push((error.into(), unresolved.file_id)); + // If this method was already declared, remove it from the module so it cannot + // be accessed with the `TypeName::method` syntax. We'll check later whether the + // object types in each method overlap or not. If they do, we issue an error. + // If not, that is specialization which is allowed. + if module.declare_function(method.name_ident().clone(), *method_id).is_err() { + module.remove_function(method.name_ident()); } } // Prohibit defining impls for primitive types if we're not in the stdlib diff --git a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs index 7dcc5051a0c..78375ab2bc0 100644 --- a/compiler/noirc_frontend/src/hir/def_map/item_scope.rs +++ b/compiler/noirc_frontend/src/hir/def_map/item_scope.rs @@ -85,4 +85,9 @@ impl ItemScope { pub fn values(&self) -> &HashMap { &self.values } + + pub fn remove_definition(&mut self, name: &Ident) { + self.types.remove(name); + self.values.remove(name); + } } diff --git a/compiler/noirc_frontend/src/hir/def_map/module_data.rs b/compiler/noirc_frontend/src/hir/def_map/module_data.rs index a1ed5587306..5528312c0fc 100644 --- a/compiler/noirc_frontend/src/hir/def_map/module_data.rs +++ b/compiler/noirc_frontend/src/hir/def_map/module_data.rs @@ -53,6 +53,11 @@ impl ModuleData { self.declare(name, id.into()) } + pub fn remove_function(&mut self, name: &Ident) { + self.scope.remove_definition(name); + self.definitions.remove_definition(name); + } + pub fn declare_global(&mut self, name: Ident, id: StmtId) -> Result<(), (Ident, Ident)> { self.declare(name, id.into()) } diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index 3b61f2b2b6b..b7e9fe953fd 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -826,7 +826,8 @@ impl<'interner> TypeChecker<'interner> { ) -> Option { match object_type { Type::Struct(typ, _args) => { - match self.interner.lookup_method(typ.borrow().id, method_name) { + let id = typ.borrow().id; + match self.interner.lookup_method(object_type, id, method_name, false) { Some(method_id) => Some(HirMethodReference::FuncId(method_id)), None => { self.errors.push(TypeCheckError::UnresolvedMethodCall { diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index e6c9d7bee9a..ef321ee2f71 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -782,7 +782,7 @@ impl Type { /// `try_unify` is a bit of a misnomer since although errors are not committed, /// any unified bindings are on success. - fn try_unify(&self, other: &Type) -> Result<(), UnificationError> { + pub fn try_unify(&self, other: &Type) -> Result<(), UnificationError> { use Type::*; use TypeVariableKind as Kind; @@ -995,7 +995,7 @@ impl Type { /// Instantiate this type, replacing any type variables it is quantified /// over with fresh type variables. If this type is not a Type::Forall, /// it is unchanged. - pub fn instantiate(&self, interner: &mut NodeInterner) -> (Type, TypeBindings) { + pub fn instantiate(&self, interner: &NodeInterner) -> (Type, TypeBindings) { match self { Type::Forall(typevars, typ) => { let replacements = typevars diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index 67009746c4d..4f26f212afa 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -87,9 +87,6 @@ pub struct NodeInterner { // Each trait definition is possibly shared across multiple type nodes. // It is also mutated through the RefCell during name resolution to append // methods from impls to the type. - // - // TODO: We may be able to remove the Shared wrapper once traits are no longer types. - // We'd just lookup their methods as needed through the NodeInterner. traits: HashMap, // Trait implementation map @@ -108,10 +105,15 @@ pub struct NodeInterner { globals: HashMap, // NOTE: currently only used for checking repeat globals and restricting their scope to a module - next_type_variable_id: usize, + next_type_variable_id: std::cell::Cell, /// A map from a struct type and method name to a function id for the method. - struct_methods: HashMap<(StructId, String), FuncId>, + /// This can resolve to potentially multiple methods if the same method name is + /// specialized for different generics on the same type. E.g. for `Struct`, we + /// may have both `impl Struct { fn foo(){} }` and `impl Struct { fn foo(){} }`. + /// If this happens, the returned Vec will have 2 entries and we'll need to further + /// disambiguate them by checking the type of each function. + struct_methods: HashMap<(StructId, String), Vec>, /// Methods on primitive types defined in the stdlib. primitive_methods: HashMap<(TypeMethodKey, String), FuncId>, @@ -381,7 +383,7 @@ impl Default for NodeInterner { trait_implementations: HashMap::new(), instantiation_bindings: HashMap::new(), field_indices: HashMap::new(), - next_type_variable_id: 0, + next_type_variable_id: std::cell::Cell::new(0), globals: HashMap::new(), struct_methods: HashMap::new(), primitive_methods: HashMap::new(), @@ -829,13 +831,13 @@ impl NodeInterner { *old = Node::Expression(new); } - pub fn next_type_variable_id(&mut self) -> TypeVariableId { - let id = self.next_type_variable_id; - self.next_type_variable_id += 1; + pub fn next_type_variable_id(&self) -> TypeVariableId { + let id = self.next_type_variable_id.get(); + self.next_type_variable_id.set(id + 1); TypeVariableId(id) } - pub fn next_type_variable(&mut self) -> Type { + pub fn next_type_variable(&self) -> Type { Type::type_variable(self.next_type_variable_id()) } @@ -863,9 +865,10 @@ impl NodeInterner { self.function_definition_ids[&function] } - /// Add a method to a type. - /// This will panic for non-struct types currently as we do not support methods - /// for primitives. We could allow this in the future however. + /// Adds a non-trait method to a type. + /// + /// Returns `Some(duplicate)` if a matching method was already defined. + /// Returns `None` otherwise. pub fn add_method( &mut self, self_type: &Type, @@ -874,8 +877,15 @@ impl NodeInterner { ) -> Option { match self_type { Type::Struct(struct_type, _generics) => { - let key = (struct_type.borrow().id, method_name); - self.struct_methods.insert(key, method_id) + let id = struct_type.borrow().id; + + if let Some(existing) = self.lookup_method(self_type, id, &method_name, true) { + return Some(existing); + } + + let key = (id, method_name); + self.struct_methods.entry(key).or_default().push(method_id); + None } Type::Error => None, @@ -899,11 +909,10 @@ impl NodeInterner { ) -> bool { self.trait_implementations.insert(key.clone(), trait_impl.clone()); match &key.typ { - Type::Struct(struct_type, _generics) => { + Type::Struct(..) => { for func_id in &trait_impl.borrow().methods { let method_name = self.function_name(func_id).to_owned(); - let key = (struct_type.borrow().id, method_name); - self.struct_methods.insert(key, *func_id); + self.add_method(&key.typ, method_name, *func_id); } true } @@ -938,9 +947,50 @@ impl NodeInterner { } } - /// Search by name for a method on the given struct - pub fn lookup_method(&self, id: StructId, method_name: &str) -> Option { - self.struct_methods.get(&(id, method_name.to_owned())).copied() + /// Search by name for a method on the given struct. + /// + /// If `check_type` is true, this will force `lookup_method` to check the type + /// of each candidate instead of returning only the first candidate if there is exactly one. + /// This is generally only desired when declaring new methods to check if they overlap any + /// existing methods. + /// + /// Another detail is that this method does not handle auto-dereferencing through `&mut T`. + /// So if an object is of type `self : &mut T` but a method only accepts `self: T` (or + /// vice-versa), the call will not be selected. If this is ever implemented into this method, + /// we can remove the `methods.len() == 1` check and the `check_type` early return. + pub fn lookup_method( + &self, + typ: &Type, + id: StructId, + method_name: &str, + check_type: bool, + ) -> Option { + let methods = self.struct_methods.get(&(id, method_name.to_owned()))?; + + // If there is only one method, just return it immediately. + // It will still be typechecked later. + if !check_type && methods.len() == 1 { + return Some(methods[0]); + } + + // When adding methods we always check they do not overlap, so there should be + // at most 1 matching method in this list. + for method in methods { + match self.function_meta(method).typ.instantiate(self).0 { + Type::Function(args, _, _) => { + if let Some(object) = args.get(0) { + // TODO #3089: This is dangerous! try_unify may commit type bindings even on failure + if object.try_unify(typ).is_ok() { + return Some(*method); + } + } + } + Type::Error => (), + other => unreachable!("Expected function type, found {other}"), + } + } + + None } /// Looks up a given method name on the given primitive type. diff --git a/compiler/wasm/Cargo.toml b/compiler/wasm/Cargo.toml index 47a0acdf8ac..b527e2de203 100644 --- a/compiler/wasm/Cargo.toml +++ b/compiler/wasm/Cargo.toml @@ -17,6 +17,7 @@ fm.workspace = true nargo.workspace = true noirc_driver.workspace = true noirc_frontend.workspace = true +noirc_errors.workspace = true wasm-bindgen.workspace = true serde.workspace = true js-sys.workspace = true diff --git a/compiler/wasm/src/compile.rs b/compiler/wasm/src/compile.rs index fbe6e761fa5..0f7baff4819 100644 --- a/compiler/wasm/src/compile.rs +++ b/compiler/wasm/src/compile.rs @@ -56,7 +56,9 @@ pub fn compile( if contracts.unwrap_or_default() { let compiled_contract = compile_contract(&mut context, crate_id, &compile_options) - .map_err(|_| JsCompileError::new("Failed to compile contract".to_string()))? + .map_err(|errs| { + JsCompileError::new("Failed to compile contract", errs, &context.file_manager) + })? .0; let optimized_contract = @@ -68,7 +70,9 @@ pub fn compile( Ok(::from_serde(&preprocessed_contract).unwrap()) } else { let compiled_program = compile_main(&mut context, crate_id, &compile_options, None, true) - .map_err(|_| JsCompileError::new("Failed to compile program".to_string()))? + .map_err(|errs| { + JsCompileError::new("Failed to compile program", errs, &context.file_manager) + })? .0; let optimized_program = diff --git a/compiler/wasm/src/errors.rs b/compiler/wasm/src/errors.rs index 6aa70dafa90..7090bf6f19f 100644 --- a/compiler/wasm/src/errors.rs +++ b/compiler/wasm/src/errors.rs @@ -1,29 +1,82 @@ -use js_sys::JsString; - +use gloo_utils::format::JsValueSerdeExt; +use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; +use fm::FileManager; +use noirc_errors::FileDiagnostic; + #[wasm_bindgen(typescript_custom_section)] -const COMPILE_ERROR: &'static str = r#" -export type CompileError = Error; +const DIAGNOSTICS: &'static str = r#" +export type Diagnostic = { + message: string; + file_path: string; + secondaries: ReadonlyArray<{ + message: string; + start: number; + end: number; + }>; +} + +interface CompileError { + diagnostics: ReadonlyArray; +} "#; -/// `CompileError` is a raw js error. -/// It'd be ideal that `CompileError` was a subclass of `Error`, but for that we'd need to use JS snippets or a js module. -/// Currently JS snippets don't work with a nodejs target. And a module would be too much for just a custom error type. -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(extends = js_sys::Error, js_name = "CompileError", typescript_type = "CompileError")] - #[derive(Clone, Debug, PartialEq, Eq)] - pub type JsCompileError; - - #[wasm_bindgen(constructor, js_class = "Error")] - fn constructor(message: JsString) -> JsCompileError; +#[derive(Serialize, Deserialize)] +struct JsDiagnosticLabel { + message: String, + start: u32, + end: u32, +} + +#[derive(Serialize, Deserialize)] +struct JsDiagnostic { + message: String, + file_path: String, + secondaries: Vec, +} + +impl JsDiagnostic { + fn new(file_diagnostic: &FileDiagnostic, file_path: String) -> JsDiagnostic { + let diagnostic = &file_diagnostic.diagnostic; + let message = diagnostic.message.clone(); + + let secondaries = diagnostic + .secondaries + .iter() + .map(|label| JsDiagnosticLabel { + message: label.message.clone(), + start: label.span.start(), + end: label.span.end(), + }) + .collect(); + + JsDiagnostic { message, file_path, secondaries } + } +} + +#[wasm_bindgen(getter_with_clone, js_name = "CompileError")] +pub struct JsCompileError { + pub message: js_sys::JsString, + pub diagnostics: JsValue, } impl JsCompileError { - /// Creates a new execution error with the given call stack. - /// Call stacks won't be optional in the future, after removing ErrorLocation in ACVM. - pub fn new(message: String) -> Self { - JsCompileError::constructor(JsString::from(message)) + pub fn new( + message: &str, + file_diagnostics: Vec, + file_manager: &FileManager, + ) -> JsCompileError { + let diagnostics: Vec<_> = file_diagnostics + .iter() + .map(|err| { + JsDiagnostic::new(err, file_manager.path(err.file_id).to_str().unwrap().to_string()) + }) + .collect(); + + JsCompileError { + message: js_sys::JsString::from(message.to_string()), + diagnostics: ::from_serde(&diagnostics).unwrap(), + } } } diff --git a/package.json b/package.json index 8ccf11e8408..a72d208f55b 100644 --- a/package.json +++ b/package.json @@ -44,8 +44,5 @@ "ts-node": "^10.9.1", "typescript": "^5.0.4" }, - "packageManager": "yarn@3.6.4", - "dependencies": { - "tslog": "^4.9.2" - } + "packageManager": "yarn@3.6.4" } diff --git a/tooling/bb_abstraction_leaks/build.rs b/tooling/bb_abstraction_leaks/build.rs index 6f92d1bc7c3..baf3cfdf6a6 100644 --- a/tooling/bb_abstraction_leaks/build.rs +++ b/tooling/bb_abstraction_leaks/build.rs @@ -10,7 +10,7 @@ use const_format::formatcp; const USERNAME: &str = "AztecProtocol"; const REPO: &str = "aztec-packages"; -const VERSION: &str = "0.7.3"; +const VERSION: &str = "0.8.10"; const TAG: &str = formatcp!("aztec-packages-v{}", VERSION); const API_URL: &str = diff --git a/tooling/bb_abstraction_leaks/src/contract.sol b/tooling/bb_abstraction_leaks/src/contract.sol index abd45567969..814c81d235e 100644 --- a/tooling/bb_abstraction_leaks/src/contract.sol +++ b/tooling/bb_abstraction_leaks/src/contract.sol @@ -1,4 +1,3 @@ - /** * @title Ultra Plonk proof verification contract * @dev Top level Plonk proof verification contract, which allows Plonk proof to be verified @@ -282,6 +281,9 @@ abstract contract BaseUltraVerifier { uint256 internal constant LIMB_SIZE = 0x100000000000000000; // 2<<68 uint256 internal constant SUBLIMB_SHIFT = 0x4000; // 2<<14 + // y^2 = x^3 + ax + b + // for Grumpkin, a = 0 and b = -17. We use b in a custom gate relation that evaluates elliptic curve arithmetic + uint256 internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = 17; error PUBLIC_INPUT_COUNT_INVALID(uint256 expected, uint256 actual); error PUBLIC_INPUT_INVALID_BN128_G1_POINT(); error PUBLIC_INPUT_GE_P(); @@ -1154,96 +1156,130 @@ abstract contract BaseUltraVerifier { * sign_term += sign_term * sign_term *= q_sign */ + // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0 + let x_diff := addmod(mload(X2_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p) + let y2_sqr := mulmod(mload(Y2_EVAL_LOC), mload(Y2_EVAL_LOC), p) + let y1_sqr := mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p) + let y1y2 := mulmod(mulmod(mload(Y1_EVAL_LOC), mload(Y2_EVAL_LOC), p), mload(QSIGN_LOC), p) - let endo_term := + let x_add_identity := + addmod( + mulmod( + addmod(mload(X3_EVAL_LOC), addmod(mload(X2_EVAL_LOC), mload(X1_EVAL_LOC), p), p), + mulmod(x_diff, x_diff, p), + p + ), + addmod( + sub( + p, + addmod(y2_sqr, y1_sqr, p) + ), + addmod(y1y2, y1y2, p), + p + ), + p + ) + x_add_identity := mulmod( mulmod( - mulmod(sub(p, mload(X2_EVAL_LOC)), mload(X1_EVAL_LOC), p), - addmod(addmod(mload(X3_EVAL_LOC), mload(X3_EVAL_LOC), p), mload(X1_EVAL_LOC), p), + x_add_identity, + addmod( + 1, + sub(p, mload(QM_EVAL_LOC)), + p + ), p ), - mload(QBETA_LOC), + mload(C_ALPHA_BASE_LOC), p ) - let endo_sqr_term := mulmod(mload(X2_EVAL_LOC), mload(X2_EVAL_LOC), p) - endo_sqr_term := mulmod(endo_sqr_term, addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), p) - endo_sqr_term := mulmod(endo_sqr_term, mload(QBETA_SQR_LOC), p) + // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0 + let y1_plus_y3 := addmod( + mload(Y1_EVAL_LOC), + mload(Y3_EVAL_LOC), + p + ) + let y_diff := addmod(mulmod(mload(Y2_EVAL_LOC), mload(QSIGN_LOC), p), sub(p, mload(Y1_EVAL_LOC)), p) + let y_add_identity := + addmod( + mulmod(y1_plus_y3, x_diff, p), + mulmod(addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), y_diff, p), + p + ) + y_add_identity := + mulmod( + mulmod(y_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), + mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), + p + ) - let leftovers := mulmod(mload(X2_EVAL_LOC), mload(X2_EVAL_LOC), p) - leftovers := mulmod(leftovers, mload(X2_EVAL_LOC), p) - leftovers := + // ELLIPTIC_IDENTITY = (x_identity + y_identity) * Q_ELLIPTIC_EVAL + mstore( + ELLIPTIC_IDENTITY, mulmod(addmod(x_add_identity, y_add_identity, p), mload(QELLIPTIC_EVAL_LOC), p) + ) + } + { + /** + * x_pow_4 = (y_1_sqr - curve_b) * x_1; + * y_1_sqr_mul_4 = y_1_sqr + y_1_sqr; + * y_1_sqr_mul_4 += y_1_sqr_mul_4; + * x_1_pow_4_mul_9 = x_pow_4; + * x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + * x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + * x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + * x_1_pow_4_mul_9 += x_pow_4; + * x_1_sqr_mul_3 = x_1_sqr + x_1_sqr + x_1_sqr; + * x_double_identity = (x_3 + x_1 + x_1) * y_1_sqr_mul_4 - x_1_pow_4_mul_9; + * y_double_identity = x_1_sqr_mul_3 * (x_1 - x_3) - (y_1 + y_1) * (y_1 + y_3); + */ + // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0 + let x1_sqr := mulmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p) + let y1_sqr := mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p) + let x_pow_4 := mulmod(addmod(y1_sqr, GRUMPKIN_CURVE_B_PARAMETER_NEGATED, p), mload(X1_EVAL_LOC), p) + let y1_sqr_mul_4 := mulmod(y1_sqr, 4, p) + let x1_pow_4_mul_9 := mulmod(x_pow_4, 9, p) + let x1_sqr_mul_3 := mulmod(x1_sqr, 3, p) + let x_double_identity := addmod( - leftovers, mulmod( - mulmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), - addmod(mload(X3_EVAL_LOC), mload(X1_EVAL_LOC), p), + addmod(mload(X3_EVAL_LOC), addmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), p), + y1_sqr_mul_4, p ), + sub(p, x1_pow_4_mul_9), p ) - leftovers := + // (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0 + let y_double_identity := addmod( - leftovers, + mulmod(x1_sqr_mul_3, addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p), sub( p, - addmod( - mulmod(mload(Y2_EVAL_LOC), mload(Y2_EVAL_LOC), p), - mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p), + mulmod( + addmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p), + addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p), p ) ), p ) - - let sign_term := mulmod(mload(Y2_EVAL_LOC), mload(Y1_EVAL_LOC), p) - sign_term := addmod(sign_term, sign_term, p) - sign_term := mulmod(sign_term, mload(QSIGN_LOC), p) - - /** - * x_identity = endo_term + endo_sqr_term + sign_term + leftovers - * x_identity *= alpha_base - * endo_term = (x_2 * q_beta) * (y_3 + y_1) - * sign_term = -((y2 * q_sign) * (x_1 + x_3)) - * leftovers = - x1 * (y_3 + y_1) + y_1 * (x_1 - x_3) - * y_identity = (endo_term + sign_term + leftovers) * (alpha_base * α) - */ - - let x_identity := addmod(addmod(endo_term, endo_sqr_term, p), addmod(sign_term, leftovers, p), p) - x_identity := mulmod(x_identity, mload(C_ALPHA_BASE_LOC), p) - endo_term := - mulmod( - mulmod(mload(X2_EVAL_LOC), mload(QBETA_LOC), p), - addmod(mload(Y3_EVAL_LOC), mload(Y1_EVAL_LOC), p), - p - ) - sign_term := - sub( - p, - mulmod( - mulmod(mload(Y2_EVAL_LOC), mload(QSIGN_LOC), p), - addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), - p - ) - ) - leftovers := + x_double_identity := mulmod(x_double_identity, mload(C_ALPHA_BASE_LOC), p) + y_double_identity := + mulmod(y_double_identity, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), p) + x_double_identity := mulmod(x_double_identity, mload(QM_EVAL_LOC), p) + y_double_identity := mulmod(y_double_identity, mload(QM_EVAL_LOC), p) + // ELLIPTIC_IDENTITY += (x_double_identity + y_double_identity) * Q_DOUBLE_EVAL + mstore( + ELLIPTIC_IDENTITY, addmod( - sub(p, mulmod(mload(X1_EVAL_LOC), addmod(mload(Y3_EVAL_LOC), mload(Y1_EVAL_LOC), p), p)), - mulmod(mload(Y1_EVAL_LOC), addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p), + mload(ELLIPTIC_IDENTITY), + mulmod(addmod(x_double_identity, y_double_identity, p), mload(QELLIPTIC_EVAL_LOC), p), p ) - let y_identity := - mulmod( - addmod(addmod(endo_term, sign_term, p), leftovers, p), - mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), - p - ) - - // ELLIPTIC_IDENTITY = (x_identity + y_identity) * Q_ELLIPTIC_EVAL - mstore(ELLIPTIC_IDENTITY, mulmod(addmod(x_identity, y_identity, p), mload(QELLIPTIC_EVAL_LOC), p)) + ) // update alpha - // The paper says to use ALPHA^2, we use ALPHA^4 this is a small oversight in the prover protocol mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_QUAD_LOC), p)) } diff --git a/tooling/nargo/src/ops/execute.rs b/tooling/nargo/src/ops/execute.rs index f64c92f1b3d..5fd130c9412 100644 --- a/tooling/nargo/src/ops/execute.rs +++ b/tooling/nargo/src/ops/execute.rs @@ -9,11 +9,11 @@ use super::foreign_calls::ForeignCallExecutor; pub fn execute_circuit( blackbox_solver: &B, - circuit: Circuit, + circuit: &Circuit, initial_witness: WitnessMap, show_output: bool, ) -> Result { - let mut acvm = ACVM::new(blackbox_solver, circuit.opcodes, initial_witness); + let mut acvm = ACVM::new(blackbox_solver, &circuit.opcodes, initial_witness); // Assert messages are not a map due to https://github.com/noir-lang/acvm/issues/522 let get_assert_message = |opcode_location| { diff --git a/tooling/nargo/src/ops/test.rs b/tooling/nargo/src/ops/test.rs index 31e7d62dfc9..d2ef2659e4d 100644 --- a/tooling/nargo/src/ops/test.rs +++ b/tooling/nargo/src/ops/test.rs @@ -27,7 +27,7 @@ pub fn run_test( // Run the backend to ensure the PWG evaluates functions like std::hash::pedersen, // otherwise constraints involving these expressions will not error. let circuit_execution = - execute_circuit(blackbox_solver, program.circuit, WitnessMap::new(), show_output); + execute_circuit(blackbox_solver, &program.circuit, WitnessMap::new(), show_output); test_status_program_compile_pass(test_function, program.debug, circuit_execution) } Err(err) => test_status_program_compile_fail(err, test_function), diff --git a/tooling/nargo_cli/src/cli/execute_cmd.rs b/tooling/nargo_cli/src/cli/execute_cmd.rs index 4fa828fb747..c61dc6db69c 100644 --- a/tooling/nargo_cli/src/cli/execute_cmd.rs +++ b/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -104,7 +104,7 @@ pub(crate) fn execute_program( let solved_witness_err = nargo::ops::execute_circuit( &blackbox_solver, - compiled_program.circuit.clone(), + &compiled_program.circuit, initial_witness, true, ); diff --git a/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/acir.gz index 958ea7e1c5c..50a2be61dac 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/2_div/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/2_div/target/acir.gz index 5b64d6c475e..dbe4de9485a 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/2_div/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/2_div/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/3_add/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/3_add/target/acir.gz index 649972b26bb..e9d898ebfaa 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/3_add/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/3_add/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/acir.gz index 2ce67472465..1819020069a 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/5_over/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/5_over/target/acir.gz index c2aed6689df..304724930e3 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/5_over/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/5_over/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz index ad3b0eee27b..db8652ef2b1 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz index 740e05c34d7..a7e330713f6 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/acir.gz deleted file mode 100644 index 3045571f758..00000000000 Binary files a/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/acir.gz and /dev/null differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/witness.gz deleted file mode 100644 index 0df10c44eaa..00000000000 Binary files a/tooling/nargo_cli/tests/acir_artifacts/8_integration/target/witness.gz and /dev/null differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/acir.gz deleted file mode 100644 index 5e277296609..00000000000 Binary files a/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/acir.gz and /dev/null differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/witness.gz deleted file mode 100644 index 21d41a12a4c..00000000000 Binary files a/tooling/nargo_cli/tests/acir_artifacts/9_conditional/target/witness.gz and /dev/null differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/acir.gz index 652dc59d26e..45007d3de3b 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz index 88874ee0460..4e70f3500f8 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz index 98bafa23595..3fc214188a6 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz index 4b0fd2a2c3c..02c1b4460d5 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/acir.gz index 68e87da5b94..e89ab2e990e 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/acir.gz index 334b841587a..e4dfc6a1fb9 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/acir.gz index a53dbf42efc..07e3db2d498 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz index 30040eb85e6..cea92f8a7f3 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz index a1fd1524bdd..c6f1053d57e 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz index 4fb242e65e0..d88034dcfd3 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz index 1c1f9dc412a..8c2c2a0ee48 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz index 17e04949a1a..8e5f44f9f2b 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz index def20ee1ea0..753475df6b1 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz index 83e0e98f79c..816fd018b4d 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz index b710943ba44..f5f05e0ae4e 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz index 96a3d7dfb79..3cb8211bb5d 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz index 2a99d731c5a..221aa632c9d 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz index b92855cf9de..73278d95462 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz index 15a7ed691c0..51f3aea170a 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz index 111946896b0..f048dfbf740 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz index 81c60622294..92bb93fcf3a 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz index 13ec1f0b022..ad63ca80fd9 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz index f2ac07ced35..fd6fea24874 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz index 3f1406ac1a7..483c24add00 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz index 5bfc7385a68..4411b4381da 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz index e2a840a5724..5a3dd291e78 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz index 10d5cbc9968..5ff2027b973 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz index 5c2e2a5c89b..2c29941121f 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz index 4c324e00a9b..c3675e56ef2 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz index c03443b5781..924efdc4270 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz index baa95785a59..270329d70c6 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz index 56d76e2edb3..5d42d1d088e 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz index 4e387fba7fd..dafe5b20fc3 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz index 3185cd4a200..dcbea001f6f 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz index 147717fe624..f0f13ee9dea 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/acir.gz index efd03095e26..3337139e860 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/acir.gz index ee56d6da2ff..a0ffcd3a17c 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz index 93678e77178..3c60eb1582d 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_2/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_2/target/acir.gz index 147c89e821e..ca259337933 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_2/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/conditional_2/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_3_regression/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_3_regression/target/acir.gz deleted file mode 100644 index 6ee1f3d1bf8..00000000000 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_3_regression/target/acir.gz and /dev/null differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_3_regression/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_3_regression/target/witness.gz deleted file mode 100644 index 00e39a68b37..00000000000 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_3_regression/target/witness.gz and /dev/null differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_421/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_421/target/acir.gz index cd5570c38ac..930d414825e 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_421/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_421/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/acir.gz index 720e8a3bd00..350a4daf676 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/witness.gz index 37c6d67fada..16880cedea2 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/witness.gz and b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_661/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_661/target/acir.gz index 5a192a898b5..078d874ec91 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_661/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_661/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_short_circuit/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_short_circuit/target/acir.gz index fdee0356323..82221bfd02e 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_short_circuit/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_short_circuit/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/acir.gz deleted file mode 100644 index f12dad0a254..00000000000 Binary files a/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/acir.gz and /dev/null differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/witness.gz deleted file mode 100644 index 2a69317d1c3..00000000000 Binary files a/tooling/nargo_cli/tests/acir_artifacts/constant_return/target/witness.gz and /dev/null differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz index 67e3179cc34..4ecdb39c47e 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/acir.gz index 039fe6395d5..61b37c09081 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/field_attribute/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/field_attribute/target/acir.gz index 014c18761a8..2eaa1ddbb09 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/field_attribute/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/field_attribute/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/acir.gz index 141db7f47f6..938aa5ce925 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/acir.gz index 24c7e72da51..e964d33d840 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/witness.gz index 6f7fa8e6304..deefbab76e5 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/witness.gz and b/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/acir.gz index e56a10c983b..95a8357b37c 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/import/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/import/target/acir.gz index ea92f4d5d02..5d716ecd89a 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/import/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/import/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz index 61371df643c..3fb0794c238 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/acir.gz index 957eefc034b..f952b731324 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz index d514448f0fa..ef447347713 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/mock_oracle/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/mock_oracle/target/acir.gz index 67ad194b490..40aac645003 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/mock_oracle/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/mock_oracle/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/modules/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/modules/target/acir.gz index 7207902b1f7..b2a5e0352bb 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/modules/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/modules/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/acir.gz index ea92f4d5d02..5d716ecd89a 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz index 660adf7c0f8..57f194bf95f 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/modulus/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/modulus/target/witness.gz index 57691426484..02931c632ff 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/modulus/target/witness.gz and b/tooling/nargo_cli/tests/acir_artifacts/modulus/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/acir.gz index 94cb1dc9193..9bb7df48483 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz index b500e41f90f..f9bf2088829 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/nested_slice_dynamic/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/nested_slice_dynamic/target/acir.gz index 45a8fb391f2..366baabac87 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/nested_slice_dynamic/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/nested_slice_dynamic/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/acir.gz index ee56d6da2ff..a0ffcd3a17c 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz index 708fe08a83c..9b65966266d 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/regression_2854/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/regression_2854/target/acir.gz index d1092470c0d..194163133ed 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/regression_2854/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/regression_2854/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/acir.gz index 0d77a649ca6..ea0679ed77f 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz index b69375dabde..0cffadb13aa 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/acir.gz index 9200fd06a33..4746bf75a68 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz index 348d093d61d..c4a0376fdc3 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz index 2d576039d91..be37fde4db7 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/acir.gz index 2a54a42ff1e..385bee61cf8 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/sha2_blocks/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz index 9b8f3c022d0..025a4eebb6f 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/signed_arithmetic/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/signed_arithmetic/target/acir.gz index 3eb9b46b2cc..cbb050199f1 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/signed_arithmetic/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/signed_arithmetic/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/acir.gz index c3d2217b92c..e968085be64 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/acir.gz index c86d1f4adb4..be9aa5c5fa5 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/acir.gz index 1cf787f1905..0d9d364f344 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz index 0182c469132..f5db91fb9a4 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/acir.gz index cd96a649c48..402ba7603ba 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz index 28060cf26b8..7f8f38b47e5 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/acir.gz index d3efbff8c80..fddd4366dba 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz index b057cbf4868..fe4c578d57a 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz index 1a612ad2435..dd80d6523c0 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz index b0cd9257a69..8eef9d732a6 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/acir.gz index 45afeaa0271..76a70a60d71 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/acir.gz index c0c09003841..5b768e5753d 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/witness.gz index fba47bd9943..f2e2e29d62b 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/witness.gz and b/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/acir.gz index 5783200dcf3..91d2fc4659a 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/acir.gz index 3eea435b13a..c9e6ad478d1 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/acir.gz index d4146815c8e..99533f1bbb1 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/acir.gz index 3ec012379a6..60df59819bc 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/witness.gz index f1e95d7eb89..0af5fc52ec4 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/witness.gz and b/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz index 7a4e650f01b..002b5e4a169 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/acir.gz index bf3b7dac900..2a2153f9706 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/xor/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/xor/target/acir.gz index f6fb8bc1721..a9dca272c62 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/xor/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/xor/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/compile_success_empty/specialization/Nargo.toml b/tooling/nargo_cli/tests/compile_success_empty/specialization/Nargo.toml new file mode 100644 index 00000000000..df379491dc9 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/specialization/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "specialization" +type = "bin" +authors = [""] +compiler_version = "0.16.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/nargo_cli/tests/compile_success_empty/specialization/src/main.nr b/tooling/nargo_cli/tests/compile_success_empty/specialization/src/main.nr new file mode 100644 index 00000000000..32102ad1437 --- /dev/null +++ b/tooling/nargo_cli/tests/compile_success_empty/specialization/src/main.nr @@ -0,0 +1,15 @@ +struct Foo {} + +impl Foo { + fn foo(_self: Self) -> Field { 1 } +} + +impl Foo { + fn foo(_self: Self) -> Field { 2 } +} + +fn main() { + let f1: Foo = Foo{}; + let f2: Foo = Foo{}; + assert(f1.foo() + f2.foo() == 3); +} diff --git a/tooling/nargo_cli/tests/rebuild.sh b/tooling/nargo_cli/tests/rebuild.sh index 9e22455afa5..9776745a1f7 100755 --- a/tooling/nargo_cli/tests/rebuild.sh +++ b/tooling/nargo_cli/tests/rebuild.sh @@ -6,7 +6,8 @@ excluded_dirs=("workspace" "workspace_default_member") current_dir=$(pwd) base_path="$current_dir/execution_success" -# Ensure the base acir_artifacts directory exists +# Clear the acir_artifacts directory of any existing artifacts +rm -rf $current_dir/acir_artifacts mkdir -p $current_dir/acir_artifacts # Loop over every directory diff --git a/tooling/nargo_fmt/src/visitor/expr.rs b/tooling/nargo_fmt/src/visitor/expr.rs index fa55ac71f78..7677a6284ec 100644 --- a/tooling/nargo_fmt/src/visitor/expr.rs +++ b/tooling/nargo_fmt/src/visitor/expr.rs @@ -39,6 +39,45 @@ impl FmtVisitor<'_> { self.format_expr(infix.rhs) ) } + ExpressionKind::Call(call_expr) => { + let formatted_func = self.format_expr(*call_expr.func); + let formatted_args = call_expr + .arguments + .into_iter() + .map(|arg| self.format_expr(arg)) + .collect::>() + .join(", "); + format!("{}({})", formatted_func, formatted_args) + } + ExpressionKind::MethodCall(method_call_expr) => { + let formatted_object = self.format_expr(method_call_expr.object).trim().to_string(); + let formatted_args = method_call_expr + .arguments + .iter() + .map(|arg| { + let arg_str = self.format_expr(arg.clone()).trim().to_string(); + if arg_str.contains('(') { + return arg_str + .replace(" ,", ",") + .replace("( ", "(") + .replace(" )", ")"); + } + arg_str + }) + .collect::>() + .join(", "); + format!("{}.{}({})", formatted_object, method_call_expr.method_name, formatted_args) + } + ExpressionKind::MemberAccess(member_access_expr) => { + let lhs_str = self.format_expr(member_access_expr.lhs); + format!("{}.{}", lhs_str, member_access_expr.rhs) + } + ExpressionKind::Index(index_expr) => { + let formatted_collection = + self.format_expr(index_expr.collection).trim_end().to_string(); + let formatted_index = self.format_expr(index_expr.index); + format!("{}[{}]", formatted_collection, formatted_index) + } ExpressionKind::Literal(literal) => match literal { Literal::Integer(_) => slice!(self, span.start(), span.end()).to_string(), Literal::Array(ArrayLiteral::Repeated { repeated_element, length }) => { diff --git a/tooling/nargo_fmt/tests/expected/call.nr b/tooling/nargo_fmt/tests/expected/call.nr index ca4d5b82683..105a69acedc 100644 --- a/tooling/nargo_fmt/tests/expected/call.nr +++ b/tooling/nargo_fmt/tests/expected/call.nr @@ -1,3 +1,3 @@ -fn main() { - main(4, 3); +fn foo() { + my_function(10, some_value, another_func(20, 30)); } diff --git a/tooling/nargo_fmt/tests/expected/index.nr b/tooling/nargo_fmt/tests/expected/index.nr new file mode 100644 index 00000000000..79430e5c0e6 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/index.nr @@ -0,0 +1,5 @@ +fn foo() { + let arr = [10, 20, 30, 40]; + arr[2]; + arr[2]; +} diff --git a/tooling/nargo_fmt/tests/expected/member_access.nr b/tooling/nargo_fmt/tests/expected/member_access.nr new file mode 100644 index 00000000000..2330ec826c7 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/member_access.nr @@ -0,0 +1,15 @@ +struct Address { + city: String, + country: String, +} + +struct Person { + name: String, + age: u8, + address: Address, +} + +fn foo(p: Person) { + p.name; + p.address.country; +} diff --git a/tooling/nargo_fmt/tests/expected/method_call.nr b/tooling/nargo_fmt/tests/expected/method_call.nr new file mode 100644 index 00000000000..c2ee71237f8 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/method_call.nr @@ -0,0 +1,3 @@ +fn foo() { + my_object.some_method(10, var_value, inner_method(20, 30)); +} diff --git a/tooling/nargo_fmt/tests/input/call.nr b/tooling/nargo_fmt/tests/input/call.nr index 8927ebc85db..93d2597a05c 100644 --- a/tooling/nargo_fmt/tests/input/call.nr +++ b/tooling/nargo_fmt/tests/input/call.nr @@ -1,3 +1,3 @@ -fn main() { - main(4, 3); -} \ No newline at end of file +fn foo() { + my_function( 10,some_value,another_func( 20 , 30) ); +} diff --git a/tooling/nargo_fmt/tests/input/index.nr b/tooling/nargo_fmt/tests/input/index.nr new file mode 100644 index 00000000000..e1c6fed02c1 --- /dev/null +++ b/tooling/nargo_fmt/tests/input/index.nr @@ -0,0 +1,5 @@ +fn foo() { + let arr = [10, 20, 30, 40]; + arr [2]; + arr [2]; +} \ No newline at end of file diff --git a/tooling/nargo_fmt/tests/input/member_access.nr b/tooling/nargo_fmt/tests/input/member_access.nr new file mode 100644 index 00000000000..abcab671836 --- /dev/null +++ b/tooling/nargo_fmt/tests/input/member_access.nr @@ -0,0 +1,15 @@ +struct Address { + city: String, + country: String, +} + +struct Person { + name: String, + age: u8, + address: Address, +} + +fn foo(p: Person) { + p . name; + p.address . country; +} diff --git a/tooling/nargo_fmt/tests/input/method_call.nr b/tooling/nargo_fmt/tests/input/method_call.nr new file mode 100644 index 00000000000..175647b4650 --- /dev/null +++ b/tooling/nargo_fmt/tests/input/method_call.nr @@ -0,0 +1,3 @@ +fn foo() { + my_object . some_method( 10,var_value,inner_method( 20 , 30) ); +} diff --git a/tooling/noir_js/package.json b/tooling/noir_js/package.json index a1a9cb850f4..3f17a1a44b2 100644 --- a/tooling/noir_js/package.json +++ b/tooling/noir_js/package.json @@ -10,8 +10,7 @@ "dependencies": { "@noir-lang/acvm_js": "workspace:*", "@noir-lang/noirc_abi": "workspace:*", - "@noir-lang/types": "workspace:*", - "fflate": "^0.8.0" + "@noir-lang/types": "workspace:*" }, "files": [ "lib", @@ -40,7 +39,6 @@ "clean": "rm -rf ./lib" }, "devDependencies": { - "@aztec/bb.js": "0.7.2", "@types/chai": "^4", "@types/mocha": "^10.0.1", "@types/node": "^20.6.2", diff --git a/tooling/noir_js/src/index.ts b/tooling/noir_js/src/index.ts index 7c8d1bc7544..3d424ca0dea 100644 --- a/tooling/noir_js/src/index.ts +++ b/tooling/noir_js/src/index.ts @@ -3,6 +3,6 @@ import * as abi from '@noir-lang/noirc_abi'; export { acvm, abi }; -export { acirToUint8Array, witnessMapToUint8Array } from './serialize.js'; +export { WitnessMap } from '@noir-lang/acvm_js'; export { Noir } from './program.js'; diff --git a/tooling/noir_js/src/program.ts b/tooling/noir_js/src/program.ts index 7d11166c0a7..bf48e15fcad 100644 --- a/tooling/noir_js/src/program.ts +++ b/tooling/noir_js/src/program.ts @@ -2,8 +2,7 @@ import { Backend, CompiledCircuit, ProofData } from '@noir-lang/types'; import { generateWitness } from './witness_generation.js'; import initAbi, { abiDecode, InputMap, InputValue } from '@noir-lang/noirc_abi'; -import initACVM from '@noir-lang/acvm_js'; -import { witnessMapToUint8Array } from './serialize.js'; +import initACVM, { compressWitness } from '@noir-lang/acvm_js'; export class Noir { constructor( @@ -20,6 +19,10 @@ export class Noir { } } + async destroy(): Promise { + await this.backend?.destroy(); + } + private getBackend(): Backend { if (this.backend === undefined) throw new Error('Operation requires a backend but none was provided'); return this.backend; @@ -30,7 +33,7 @@ export class Noir { await this.init(); const witness = await generateWitness(this.circuit, inputs); const { return_value: returnValue } = abiDecode(this.circuit.abi, witness); - return { witness: witnessMapToUint8Array(witness), returnValue }; + return { witness: compressWitness(witness), returnValue }; } // Initial inputs to your program diff --git a/tooling/noir_js/src/serialize.ts b/tooling/noir_js/src/serialize.ts deleted file mode 100644 index df01769c06e..00000000000 --- a/tooling/noir_js/src/serialize.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { WitnessMap, compressWitness } from '@noir-lang/acvm_js'; -import { decompressSync as gunzip } from 'fflate'; -import { base64Decode } from './base64_decode.js'; - -// After solving the witness, to pass it a backend, we need to serialize it to a Uint8Array -export function witnessMapToUint8Array(solvedWitness: WitnessMap): Uint8Array { - // TODO: We just want to serialize, but this will zip up the witness - // TODO so its not ideal - const compressedWitness = compressWitness(solvedWitness); - return gunzip(compressedWitness); -} - -// Converts an bytecode to a Uint8Array -export function acirToUint8Array(base64EncodedBytecode): Uint8Array { - const compressedByteCode = base64Decode(base64EncodedBytecode); - return gunzip(compressedByteCode); -} diff --git a/tooling/noir_js/test/node/e2e.test.ts b/tooling/noir_js/test/node/e2e.test.ts index 773d6c5fc6c..f7c3ea37a1a 100644 --- a/tooling/noir_js/test/node/e2e.test.ts +++ b/tooling/noir_js/test/node/e2e.test.ts @@ -72,7 +72,7 @@ it('end-to-end proof creation and verification (inner)', async () => { // The "real" workflow will involve a prover and a verifier on different systems. // // We cannot do this in our tests because they will panic with: -// `RuntimeError: null function or function signature mismatch` +// `unreachable` // // This happens when we we create a proof with one barretenberg instance and // try to verify it with another. @@ -81,7 +81,7 @@ it('end-to-end proof creation and verification (inner)', async () => { // a prover and verifier class to more accurately reflect what happens in production. // // If its not fixable, we can leave it in as documentation of this behavior. -it('[BUG] -- bb.js null function or function signature mismatch (different instance) ', async () => { +it('[BUG] -- bb.js unreachable (different instance) ', async () => { // Noir.Js part const inputs = { x: '2', @@ -105,7 +105,7 @@ it('[BUG] -- bb.js null function or function signature mismatch (different insta ); } catch (error) { const knownError = error as Error; - expect(knownError.message).to.contain('null function or function signature mismatch'); + expect(knownError.message).to.contain('unreachable'); } }); @@ -139,15 +139,9 @@ it('[BUG] -- bb.js null function or function signature mismatch (outer-inner) ', // Proof verification // - try { - const isValidOuter = await prover.verifyFinalProof(proofOuter); - expect(isValidOuter).to.be.true; - // We can also try verifying an inner proof and it will fail. - // const isValidInner = await prover.verifyInnerProof(_proofInner); - // expect(isValidInner).to.be.true; - expect.fail('bb.js currently returns a bug when we try to verify an inner and outer proof with the same backend'); - } catch (error) { - const knownError = error as Error; - expect(knownError.message).to.contain('null function or function signature mismatch'); - } + const isValidOuter = await prover.verifyFinalProof(proofOuter); + expect(isValidOuter).to.be.true; + // We can also try verifying an inner proof and it will fail. + const isValidInner = await prover.verifyIntermediateProof(_proofInner); + expect(isValidInner).to.be.true; }); diff --git a/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json b/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json index 23e660377e7..3b2b1b2c5a1 100644 --- a/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json +++ b/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json @@ -1 +1 @@ -{"hash":7965745029883743051,"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"}],"param_witnesses":{"x":[1],"y":[2]},"return_type":{"kind":"integer","sign":"unsigned","width":64},"return_witnesses":[12]},"bytecode":"H4sIAAAAAAAA/+1WXW6DMAw2oVAGqNqedg2HQAlv1W4yNHr/I2yoieRmlIfGZpNaS8jBCl/8F/O9AcA7XCT5eZTTJ/Ku3DuVxGlvN3hs26lvJm30JzbDaDtsu/FotdWd7b4aa8xkW9sP49DjoFsz6XM3mDNeJL0fCwMsnRL/1nzGONEpHxZSf3cLa0VsqdO5QEwQnBPm8bBgYz1cokg7AdwM+JpfKu6Mv0ZIIEVzipEyx08vjRfF7HPC2Afqfr90aFgInQ2b5jV3ek9sGekPv3e+gx/wu3cSslZuj1rZk9zAeSE2/73osPLB5cRB5RJxCs5MBc72WJxNF4t1AJlBE+YvliHkjDHvGesakb/VAcDN1nLY5ocS62fB2DNbscqCD+uKVdIB+WSVkZiFSyg3bgn/m1XOcZf8NRJllSWjn3/BKjFOtAKZOkX2wCqrrJyuie2hWGUF16yyhm1ZJcaJ5mSVryDTwNyssmKMuWasBWf+bl0wv6YX9htJ8OlsXBQAAA=="} \ No newline at end of file +{"hash":13834844072603749544,"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"}],"param_witnesses":{"x":[1],"y":[2]},"return_type":{"kind":"integer","sign":"unsigned","width":64},"return_witnesses":[12]},"bytecode":"H4sIAAAAAAAA/+1WUW6DMAx1QksZoGr72jUcAiX8VbvJ0Oj9j7ChJpKbtXw0NpvUWkImUXixn53w3gDgHc6mfh7t/ZGMtR9TU96HeYuHtp36ZjLWfGIzjK7DthsPzjjTue6rcdZOrnX9MA49Dqa1kzl1gz3h2bL7sTDCMhmJbylmTDOT8WEhjXfjH/DcB8u8zwVygWifmL/9lTnWzSWKsxHA3QJf00vlveWvERJIUU4x0eb86aEJppljVox9oO+Py8QTV1Jnw6a85t7vSL8pwvN89j7gd88o8q79Gr2wRt3AeSFz4XvRSyokl5MAtSfgGO2ZCewdsDibLRVrDzIXTMxfqiLIGXPeMdY1gb/Fg8+tznJY50eSGmfB2DNrqciCD+tCRc4X5FNFJmIWnkhu3BL+t4qc8y75aySqIkvGOP9CRWKaGQ0ydUrsgUUVWXlfw4OpyAouVWQN66pITDPDqSJfQaZxuVVkxZhzzVgLTv5uHbDwXhN+vwGywklHPBQAAA=="} \ No newline at end of file diff --git a/tooling/noir_js_backend_barretenberg/package.json b/tooling/noir_js_backend_barretenberg/package.json index a10c5baf96a..afc0a75d19e 100644 --- a/tooling/noir_js_backend_barretenberg/package.json +++ b/tooling/noir_js_backend_barretenberg/package.json @@ -32,13 +32,10 @@ "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "dependencies": { - "@aztec/bb.js": "0.7.10", + "@aztec/bb.js": "0.8.10", "@noir-lang/types": "workspace:*", "fflate": "^0.8.0" }, - "peerDependencies": { - "@noir-lang/backend_barretenberg": "workspace:*" - }, "devDependencies": { "@types/node": "^20.6.2", "@types/prettier": "^3", diff --git a/tooling/noir_js_backend_barretenberg/src/index.ts b/tooling/noir_js_backend_barretenberg/src/index.ts index a2f8240f6f7..11c56a7384d 100644 --- a/tooling/noir_js_backend_barretenberg/src/index.ts +++ b/tooling/noir_js_backend_barretenberg/src/index.ts @@ -1,6 +1,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { decompressSync as gunzip } from 'fflate'; import { acirToUint8Array } from './serialize.js'; import { Backend, CompiledCircuit, ProofData } from '@noir-lang/types'; +import { BackendOptions } from './types.js'; // This is the number of bytes in a UltraPlonk proof // minus the public inputs. @@ -14,11 +16,12 @@ export class BarretenbergBackend implements Backend { private api: any; private acirComposer: any; private acirUncompressedBytecode: Uint8Array; - private numberOfThreads = 1; - constructor(acirCircuit: CompiledCircuit, numberOfThreads = 1) { + constructor( + acirCircuit: CompiledCircuit, + private options: BackendOptions = { threads: 1 }, + ) { const acirBytecodeBase64 = acirCircuit.bytecode; - this.numberOfThreads = numberOfThreads; this.acirUncompressedBytecode = acirToUint8Array(acirBytecodeBase64); } @@ -27,7 +30,7 @@ export class BarretenbergBackend implements Backend { // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore const { Barretenberg, RawBuffer, Crs } = await import('@aztec/bb.js'); - const api = await Barretenberg.new(this.numberOfThreads); + const api = await Barretenberg.new(this.options.threads); const [_exact, _total, subgroupSize] = await api.acirGetCircuitSizes(this.acirUncompressedBytecode); const crs = await Crs.new(subgroupSize + 1); @@ -65,12 +68,12 @@ export class BarretenbergBackend implements Backend { return this.generateProof(witness, makeEasyToVerifyInCircuit); } - async generateProof(decompressedWitness: Uint8Array, makeEasyToVerifyInCircuit: boolean): Promise { + async generateProof(compressedWitness: Uint8Array, makeEasyToVerifyInCircuit: boolean): Promise { await this.instantiate(); const proofWithPublicInputs = await this.api.acirCreateProof( this.acirComposer, this.acirUncompressedBytecode, - decompressedWitness, + gunzip(compressedWitness), makeEasyToVerifyInCircuit, ); diff --git a/tooling/noir_js_backend_barretenberg/src/types.ts b/tooling/noir_js_backend_barretenberg/src/types.ts new file mode 100644 index 00000000000..b88a942d986 --- /dev/null +++ b/tooling/noir_js_backend_barretenberg/src/types.ts @@ -0,0 +1,3 @@ +export type BackendOptions = { + threads: number; +}; diff --git a/tooling/noir_js_types/src/types.ts b/tooling/noir_js_types/src/types.ts index 6285972d1e9..f534ec9a920 100644 --- a/tooling/noir_js_types/src/types.ts +++ b/tooling/noir_js_types/src/types.ts @@ -10,8 +10,8 @@ export interface Backend { generateIntermediateProof(decompressedWitness: Uint8Array): Promise; verifyFinalProof(proofData: ProofData): Promise; - verifyIntermediateProof(proofData: ProofData): Promise; + destroy(): Promise; } export type ProofData = { diff --git a/yarn.lock b/yarn.lock index 66773cf275e..856493ee802 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,9 +29,9 @@ __metadata: languageName: node linkType: hard -"@aztec/bb.js@npm:0.7.10": - version: 0.7.10 - resolution: "@aztec/bb.js@npm:0.7.10" +"@aztec/bb.js@npm:0.8.10": + version: 0.8.10 + resolution: "@aztec/bb.js@npm:0.8.10" dependencies: comlink: ^4.4.1 commander: ^10.0.1 @@ -39,21 +39,7 @@ __metadata: tslib: ^2.4.0 bin: bb.js: dest/node/main.js - checksum: 0410278e6ec2a6ecdcbaa58633b181ec1d91e1c267c76e7e587fb69c8f2fd394e79f65bd96cfcdb2a2b20fe5abeb86ababd45bd6364ba07555fc0643bf0e4307 - languageName: node - linkType: hard - -"@aztec/bb.js@npm:0.7.2": - version: 0.7.2 - resolution: "@aztec/bb.js@npm:0.7.2" - dependencies: - comlink: ^4.4.1 - commander: ^10.0.1 - debug: ^4.3.4 - tslib: ^2.4.0 - bin: - bb.js: dest/node/main.js - checksum: 68299e5b0ef9583d78d1aaeb4e6a80cf5e049d45e48fb02798a41a2dfda0e68d729e8fbc1d23ab692914ce3857c729b48da9200fca49b838416b7988e5516d0b + checksum: c77f6e27f626edca1477e4d94794d43b373dfcb527f00579e20270fc92794f9e4bc5df2c25ebbce564700c114cdf69e0b213ddb0192c24af4fc4cdf468918702 languageName: node linkType: hard @@ -924,7 +910,7 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg" dependencies: - "@aztec/bb.js": 0.7.10 + "@aztec/bb.js": 0.8.10 "@noir-lang/types": "workspace:*" "@types/node": ^20.6.2 "@types/prettier": ^3 @@ -933,8 +919,6 @@ __metadata: fflate: ^0.8.0 prettier: 3.0.3 typescript: 5.1.5 - peerDependencies: - "@noir-lang/backend_barretenberg": "workspace:*" languageName: unknown linkType: soft @@ -942,7 +926,6 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/noir_js@workspace:tooling/noir_js" dependencies: - "@aztec/bb.js": 0.7.2 "@noir-lang/acvm_js": "workspace:*" "@noir-lang/noirc_abi": "workspace:*" "@noir-lang/types": "workspace:*" @@ -953,7 +936,6 @@ __metadata: chai: ^4.3.8 eslint: ^8.50.0 eslint-plugin-prettier: ^5.0.0 - fflate: ^0.8.0 mocha: ^10.2.0 prettier: 3.0.3 ts-node: ^10.9.1 @@ -1001,7 +983,6 @@ __metadata: mocha: ^10.2.0 prettier: 3.0.3 ts-node: ^10.9.1 - tslog: ^4.9.2 typescript: ^5.0.4 languageName: unknown linkType: soft @@ -5370,7 +5351,6 @@ __metadata: eslint: ^8.50.0 eslint-plugin-prettier: ^5.0.0 ethers: ^6.7.1 - fflate: ^0.8.0 hardhat: ^2.17.4 prettier: 3.0.3 smol-toml: ^1.1.2