diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index eff4e6928ae3..2aa6557b03f9 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -79,24 +79,24 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit) * } **/ RangeConstraint range_a{ - .witness = 1, + .witness = 0, .num_bits = 32, }; RangeConstraint range_b{ - .witness = 2, + .witness = 1, .num_bits = 32, }; LogicConstraint logic_constraint{ - .a = 1, - .b = 2, - .result = 3, + .a = 0, + .b = 1, + .result = 2, .num_bits = 32, .is_xor_gate = 1, }; poly_triple expr_a{ - .a = 3, - .b = 4, + .a = 2, + .b = 3, .c = 0, .q_m = 0, .q_l = 1, @@ -105,9 +105,9 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit) .q_c = -10, }; poly_triple expr_b{ - .a = 4, - .b = 5, - .c = 6, + .a = 3, + .b = 4, + .c = 5, .q_m = 1, .q_l = 0, .q_r = 0, @@ -115,9 +115,9 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit) .q_c = 0, }; poly_triple expr_c{ - .a = 4, - .b = 6, - .c = 4, + .a = 3, + .b = 5, + .c = 3, .q_m = 1, .q_l = 0, .q_r = 0, @@ -126,7 +126,7 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit) }; poly_triple expr_d{ - .a = 6, + .a = 5, .b = 0, .c = 0, .q_m = 0, @@ -139,8 +139,8 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit) // EXPR [ (1, _4, _6) (-1, _4) 0 ] // EXPR [ (-1, _6) 1 ] - acir_format constraint_system{ .varnum = 7, - .public_inputs = { 2 }, + acir_format constraint_system{ .varnum = 6, + .public_inputs = { 1 }, .logic_constraints = { logic_constraint }, .range_constraints = { range_a, range_b }, .sha256_constraints = {}, @@ -181,13 +181,13 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass) std::vector range_constraints; for (uint32_t i = 0; i < 10; i++) { range_constraints.push_back(RangeConstraint{ - .witness = i + 1, + .witness = i, .num_bits = 15, }); } std::vector signature(64); - for (uint32_t i = 0, value = 13; i < 64; i++, value++) { + for (uint32_t i = 0, value = 12; i < 64; i++, value++) { signature[i] = value; range_constraints.push_back(RangeConstraint{ .witness = value, @@ -196,13 +196,13 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass) } SchnorrConstraint schnorr_constraint{ - .message = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, - .public_key_x = 11, - .public_key_y = 12, - .result = 77, + .message = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + .public_key_x = 10, + .public_key_y = 11, + .result = 76, .signature = signature, }; - acir_format constraint_system{ .varnum = 82, + acir_format constraint_system{ .varnum = 81, .public_inputs = {}, .logic_constraints = {}, .range_constraints = range_constraints, @@ -271,13 +271,13 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange) std::vector range_constraints; for (uint32_t i = 0; i < 10; i++) { range_constraints.push_back(RangeConstraint{ - .witness = i + 1, + .witness = i, .num_bits = 8, }); } std::vector signature(64); - for (uint32_t i = 0, value = 13; i < 64; i++, value++) { + for (uint32_t i = 0, value = 12; i < 64; i++, value++) { signature[i] = value; range_constraints.push_back(RangeConstraint{ .witness = value, @@ -286,14 +286,14 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange) } SchnorrConstraint schnorr_constraint{ - .message = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, - .public_key_x = 11, - .public_key_y = 12, - .result = 77, + .message = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + .public_key_x = 10, + .public_key_y = 11, + .result = 76, .signature = signature, }; acir_format constraint_system{ - .varnum = 82, + .varnum = 81, .public_inputs = {}, .logic_constraints = {}, .range_constraints = range_constraints, @@ -360,39 +360,39 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange) TEST_F(AcirFormatTests, TestVarKeccak) { HashInput input1; - input1.witness = 1; + input1.witness = 0; input1.num_bits = 8; HashInput input2; - input2.witness = 2; + input2.witness = 1; input2.num_bits = 8; HashInput input3; - input3.witness = 3; + input3.witness = 2; input3.num_bits = 8; KeccakVarConstraint keccak; keccak.inputs = { input1, input2, input3 }; - keccak.var_message_size = 4; - keccak.result = { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }; + keccak.var_message_size = 3; + keccak.result = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 }; RangeConstraint range_a{ - .witness = 1, + .witness = 0, .num_bits = 8, }; RangeConstraint range_b{ - .witness = 2, + .witness = 1, .num_bits = 8, }; RangeConstraint range_c{ - .witness = 3, + .witness = 2, .num_bits = 8, }; RangeConstraint range_d{ - .witness = 4, + .witness = 3, .num_bits = 8, }; auto dummy = poly_triple{ - .a = 1, + .a = 0, .b = 0, .c = 0, .q_m = 0, @@ -403,7 +403,7 @@ TEST_F(AcirFormatTests, TestVarKeccak) }; acir_format constraint_system{ - .varnum = 37, + .varnum = 36, .public_inputs = {}, .logic_constraints = {}, .range_constraints = { range_a, range_b, range_c, range_d }, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp index 491c2e79de4d..d1ebbb6b89f3 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp @@ -29,12 +29,12 @@ namespace acir_format { */ poly_triple serialize_arithmetic_gate(Circuit::Expression const& arg) { - // TODO(https://github.com/AztecProtocol/barretenberg/issues/816): Instead of zeros for a,b,c, what we really want - // is something like the bberg zero_idx. Hardcoding these to 0 has the same effect only if zero_idx == 0, as has - // historically been the case. If that changes, this might break since now "0" points to some non-zero witness in - // variables. (From some testing, it seems like it may not break but only because the selectors multiplying the - // erroneously non-zero value are zero. Still, it seems like a bad idea to have erroneous wire values even if they - // dont break the relation. They'll still add cost in commitments, for example). + // TODO(https://github.com/AztecProtocol/barretenberg/issues/816): The initialization of the witness indices a,b,c + // to 0 is implicitly assuming that (builder.zero_idx == 0) which is no longer the case. Now, witness idx 0 in + // general will correspond to some non-zero value and some witnesses which are not explicitly set below will be + // erroneously populated with this value. This does not cause failures however because the corresponding selector + // will indeed be 0 so the gate will be satisfied. Still, its a bad idea to have erroneous wire values + // even if they dont break the relation. They'll still add cost in commitments, for example. poly_triple pt{ .a = 0, .b = 0, @@ -72,8 +72,8 @@ poly_triple serialize_arithmetic_gate(Circuit::Expression const& arg) // If the witness index has not yet been set or if the corresponding linear term is active, set the witness // index and the corresponding selector value. // TODO(https://github.com/AztecProtocol/barretenberg/issues/816): May need to adjust the pt.a == witness_idx - // check (and the others like it) since we initialize a,b,c with 0 but 0 becomes a valid witness index if the +1 - // offset is removed from noir. + // check (and the others like it) since we initialize a,b,c with 0 but 0 is a valid witness index once the + // +1 offset is removed from noir. if (!a_set || pt.a == witness_idx) { // q_l * w_l pt.a = witness_idx; pt.q_l = selector_value; @@ -294,7 +294,8 @@ acir_format circuit_buf_to_acir_format(std::vector const& buf) auto circuit = Circuit::Circuit::bincodeDeserialize(buf); acir_format af; - af.varnum = circuit.current_witness_index; + // `varnum` is the true number of variables, thus we add one to the index which starts at zero + af.varnum = circuit.current_witness_index + 1; af.public_inputs = join({ map(circuit.public_parameters.value, [](auto e) { return e.value; }), map(circuit.return_values.value, [](auto e) { return e.value; }) }); std::map block_id_to_block_constraint; @@ -340,9 +341,7 @@ WitnessVector witness_buf_to_witness_data(std::vector const& buf) { auto w = WitnessMap::WitnessMap::bincodeDeserialize(buf); WitnessVector wv; - // TODO(https://github.com/AztecProtocol/barretenberg/issues/816): Does "index" need to be initialized to 0 once we - // get rid of the +1 offset in noir? - size_t index = 1; + size_t index = 0; for (auto& e : w.value) { // ACIR uses a sparse format for WitnessMap where unused witness indices may be left unassigned. // To ensure that witnesses sit at the correct indices in the `WitnessVector`, we fill any indices diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index 4451cfb7956e..526eabed4812 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -14,13 +14,13 @@ class UltraPlonkRAM : public ::testing::Test { }; size_t generate_block_constraint(BlockConstraint& constraint, WitnessVector& witness_values) { - size_t witness_len = 1; + size_t witness_len = 0; witness_values.emplace_back(1); witness_len++; fr two = fr::one() + fr::one(); poly_triple a0 = poly_triple{ - .a = 1, + .a = 0, .b = 0, .c = 0, .q_m = 0, @@ -41,7 +41,7 @@ size_t generate_block_constraint(BlockConstraint& constraint, WitnessVector& wit .q_c = three, }; poly_triple r1 = poly_triple{ - .a = 1, + .a = 0, .b = 0, .c = 0, .q_m = 0, @@ -51,7 +51,7 @@ size_t generate_block_constraint(BlockConstraint& constraint, WitnessVector& wit .q_c = fr::neg_one(), }; poly_triple r2 = poly_triple{ - .a = 1, + .a = 0, .b = 0, .c = 0, .q_m = 0, @@ -61,7 +61,7 @@ size_t generate_block_constraint(BlockConstraint& constraint, WitnessVector& wit .q_c = fr::neg_one(), }; poly_triple y = poly_triple{ - .a = 2, + .a = 1, .b = 0, .c = 0, .q_m = 0, @@ -73,7 +73,7 @@ size_t generate_block_constraint(BlockConstraint& constraint, WitnessVector& wit witness_values.emplace_back(2); witness_len++; poly_triple z = poly_triple{ - .a = 3, + .a = 2, .b = 0, .c = 0, .q_m = 0, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp index c5ce13927801..be404915e22d 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp @@ -40,7 +40,7 @@ size_t generate_ecdsa_constraint(EcdsaSecp256k1Constraint& ecdsa_constraint, Wit std::vector pub_x_indices_in; std::vector pub_y_indices_in; std::vector signature_in; - size_t offset = 1; + size_t offset = 0; for (size_t i = 0; i < hashed_message.size(); ++i) { message_in.emplace_back(i + offset); const auto byte = static_cast(hashed_message[i]); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp index 0c9b56e37fed..a87876e87892 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp @@ -23,7 +23,7 @@ size_t generate_r1_constraints(EcdsaSecp256r1Constraint& ecdsa_r1_constraint, std::vector pub_x_indices_in; std::vector pub_y_indices_in; std::vector signature_in; - size_t offset = 1; + size_t offset = 0; for (size_t i = 0; i < hashed_message.size(); ++i) { message_in.emplace_back(i + offset); const auto byte = static_cast(hashed_message[i]); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp index 170734597794..4e8e53ff3272 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp @@ -24,24 +24,24 @@ Builder create_inner_circuit() * } **/ RangeConstraint range_a{ - .witness = 1, + .witness = 0, .num_bits = 32, }; RangeConstraint range_b{ - .witness = 2, + .witness = 1, .num_bits = 32, }; LogicConstraint logic_constraint{ - .a = 1, - .b = 2, - .result = 3, + .a = 0, + .b = 1, + .result = 2, .num_bits = 32, .is_xor_gate = 1, }; poly_triple expr_a{ - .a = 3, - .b = 4, + .a = 2, + .b = 3, .c = 0, .q_m = 0, .q_l = 1, @@ -50,9 +50,9 @@ Builder create_inner_circuit() .q_c = -10, }; poly_triple expr_b{ - .a = 4, - .b = 5, - .c = 6, + .a = 3, + .b = 4, + .c = 5, .q_m = 1, .q_l = 0, .q_r = 0, @@ -60,9 +60,9 @@ Builder create_inner_circuit() .q_c = 0, }; poly_triple expr_c{ - .a = 4, - .b = 6, - .c = 4, + .a = 3, + .b = 5, + .c = 3, .q_m = 1, .q_l = 0, .q_r = 0, @@ -71,7 +71,7 @@ Builder create_inner_circuit() }; poly_triple expr_d{ - .a = 6, + .a = 5, .b = 0, .c = 0, .q_m = 0, @@ -81,8 +81,8 @@ Builder create_inner_circuit() .q_c = 1, }; - acir_format constraint_system{ .varnum = 7, - .public_inputs = { 2, 3 }, + acir_format constraint_system{ .varnum = 6, + .public_inputs = { 1, 2 }, .logic_constraints = { logic_constraint }, .range_constraints = { range_a, range_b }, .sha256_constraints = {}, @@ -122,8 +122,7 @@ Builder create_outer_circuit(std::vector& inner_circuits) { std::vector recursion_constraints; - // witness count starts at 1 (Composer reserves 1st witness to be the zero-valued zero_idx) - size_t witness_offset = 1; + size_t witness_offset = 0; std::array output_aggregation_object; std::vector> witness; @@ -226,7 +225,7 @@ Builder create_outer_circuit(std::vector& inner_circuits) // then we could get a segmentation fault as `inner_public_inputs` was never filled with values. if (!has_nested_proof) { for (size_t i = 0; i < num_inner_public_inputs; ++i) { - witness[inner_public_inputs[i] - 1] = inner_public_input_values[i]; + witness[inner_public_inputs[i]] = inner_public_input_values[i]; } } @@ -234,7 +233,7 @@ Builder create_outer_circuit(std::vector& inner_circuits) circuit_idx++; } - acir_format constraint_system{ .varnum = static_cast(witness.size() + 1), + acir_format constraint_system{ .varnum = static_cast(witness.size()), .public_inputs = {}, .logic_constraints = {}, .range_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp index c1ce11576f1f..3a36a3595918 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp @@ -64,20 +64,10 @@ std::vector AcirComposer::create_proof(bool is_recursive) void AcirComposer::create_goblin_circuit(acir_format::acir_format& constraint_system, acir_format::WitnessVector& witness) { - // TODO(https://github.com/AztecProtocol/barretenberg/issues/816): The public inputs in constraint_system do not - // index into "witness" but rather into the future "variables" which it assumes will be equal to witness but with a - // prepended zero. We want to remove this +1 so that public_inputs properly indexes into witness because we're about - // to make calls like add_variable(witness[public_inputs[idx]]). Once the +1 is removed from noir, this correction - // can be removed entirely and we can use constraint_system.public_inputs directly. - const uint32_t pre_applied_noir_offset = 1; - std::vector corrected_public_inputs; - for (const auto& index : constraint_system.public_inputs) { - corrected_public_inputs.emplace_back(index - pre_applied_noir_offset); - } - // Construct a builder using the witness and public input data from acir - goblin_builder_ = - acir_format::GoblinBuilder{ goblin.op_queue, witness, corrected_public_inputs, constraint_system.varnum }; + goblin_builder_ = acir_format::GoblinBuilder{ + goblin.op_queue, witness, constraint_system.public_inputs, constraint_system.varnum + }; // Populate constraints in the builder via the data in constraint_system acir_format::build_constraints(goblin_builder_, constraint_system, true); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp index 7fee2764e601..214d16dde80f 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp @@ -95,23 +95,9 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui auto& witness_values, std::vector& public_inputs, size_t varnum) - : UltraCircuitBuilder_>() + : UltraCircuitBuilder_>(/*size_hint=*/0, witness_values, public_inputs, varnum) , op_queue(op_queue_in) { - // TODO(https://github.com/AztecProtocol/barretenberg/issues/816): NOTE: This still works even though the - // witness indices in the explicit acir gates are +1 offset because we're still adding the const 0 before - // anything else via the UCB constructor. Once we remove the +1 from Noir, we'll need to update the UCB by - // moving that const 0 to get these tests to pass again. Add the witness variables known directly from acir - for (size_t idx = 0; idx < varnum; ++idx) { - // Zeros are added for variables whose existence is known but whose values are not yet known. The values may - // be "set" later on via the assert_equal mechanism. - auto value = idx < witness_values.size() ? witness_values[idx] : 0; - this->add_variable(value); - } - - // Add the public_inputs from acir - this->public_inputs = public_inputs; - // Set indices to constants corresponding to Goblin ECC op codes set_goblin_ecc_op_code_constant_variables(); }; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 013410a2a4e5..63f65ed23d8b 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -682,12 +682,6 @@ class UltraCircuitBuilder_ : public CircuitBuilderBasezero_idx = put_constant_variable(FF::zero()); - this->tau.insert({ DUMMY_TAG, DUMMY_TAG }); // TODO(luke): explain this - for (size_t idx = 0; idx < varnum; ++idx) { // Zeros are added for variables whose existence is known but whose values are not yet known. The values may // be "set" later on via the assert_equal mechanism. @@ -697,6 +691,11 @@ class UltraCircuitBuilder_ : public CircuitBuilderBasepublic_inputs = public_inputs; + + // Add the const zero variable after the acir witness has been + // incorporated into variables. + this->zero_idx = put_constant_variable(FF::zero()); + this->tau.insert({ DUMMY_TAG, DUMMY_TAG }); // TODO(luke): explain this }; UltraCircuitBuilder_(const UltraCircuitBuilder_& other) = default; UltraCircuitBuilder_(UltraCircuitBuilder_&& other) diff --git a/noir/compiler/noirc_evaluator/src/ssa.rs b/noir/compiler/noirc_evaluator/src/ssa.rs index deffe84baeab..f11c077d49a5 100644 --- a/noir/compiler/noirc_evaluator/src/ssa.rs +++ b/noir/compiler/noirc_evaluator/src/ssa.rs @@ -93,8 +93,8 @@ pub fn create_circuit( let mut generated_acir = optimize_into_acir(program, enable_ssa_logging, enable_brillig_logging)?; let opcodes = generated_acir.take_opcodes(); + let current_witness_index = generated_acir.current_witness_index().0; let GeneratedAcir { - current_witness_index, return_witnesses, locations, input_witnesses, diff --git a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 623810d1bfe8..73f30054cce8 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -28,9 +28,12 @@ use num_bigint::BigUint; /// The output of the Acir-gen pass pub(crate) struct GeneratedAcir { /// The next witness index that may be declared. - /// + /// If witness index is `None` then we have not yet created a witness + /// and thus next witness index that be declared is zero. + /// This field is private should only ever be accessed through its getter and setter. + /// /// Equivalent to acvm::acir::circuit::Circuit's field of the same name. - pub(crate) current_witness_index: u32, + current_witness_index: Option, /// The opcodes of which the compiled ACIR will comprise. opcodes: Vec, @@ -60,7 +63,7 @@ pub(crate) struct GeneratedAcir { impl GeneratedAcir { /// Returns the current witness index. pub(crate) fn current_witness_index(&self) -> Witness { - Witness(self.current_witness_index) + Witness(self.current_witness_index.unwrap_or(0)) } /// Adds a new opcode into ACIR. @@ -78,8 +81,12 @@ impl GeneratedAcir { /// Updates the witness index counter and returns /// the next witness index. pub(crate) fn next_witness_index(&mut self) -> Witness { - self.current_witness_index += 1; - Witness(self.current_witness_index) + if let Some(current_index) = self.current_witness_index { + self.current_witness_index.replace(current_index + 1); + } else { + self.current_witness_index = Some(0); + } + Witness(self.current_witness_index.expect("ICE: current_witness_index should exist")) } /// Converts [`Expression`] `expr` into a [`Witness`]. diff --git a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index e65e71b045d7..c0e3ed1ff661 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -294,7 +294,7 @@ impl Context { dfg: &DataFlowGraph, ) -> Result, RuntimeError> { // The first witness (if any) is the next one - let start_witness = self.acir_context.current_witness_index().0 + 1; + let start_witness = self.acir_context.current_witness_index().0; for param_id in params { let typ = dfg.type_of_value(*param_id); let value = self.convert_ssa_block_param(&typ)?; diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 5df69a7037e9..062cfdf4def7 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -106,7 +106,7 @@ export class ClientExecutionContext extends ViewDataOracle { ...args, ]; - return toACVMWitness(1, fields); + return toACVMWitness(0, fields); } /** diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts index d197ec386fbc..c59fe74c405e 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts @@ -26,7 +26,7 @@ export async function executeUnconstrainedFunction( log(`Executing unconstrained function ${contractAddress}:${functionSelector}`); const acir = Buffer.from(artifact.bytecode, 'base64'); - const initialWitness = toACVMWitness(1, args); + const initialWitness = toACVMWitness(0, args); const { partialWitness } = await acvm( await AcirSimulator.getSolver(), acir, diff --git a/yarn-project/acir-simulator/src/public/public_execution_context.ts b/yarn-project/acir-simulator/src/public/public_execution_context.ts index 75942e7d93ca..886c0c40434b 100644 --- a/yarn-project/acir-simulator/src/public/public_execution_context.ts +++ b/yarn-project/acir-simulator/src/public/public_execution_context.ts @@ -53,7 +53,7 @@ export class PublicExecutionContext extends TypedOracle { * @param witnessStartIndex - The index where to start inserting the parameters. * @returns The initial witness. */ - public getInitialWitness(witnessStartIndex = 1) { + public getInitialWitness(witnessStartIndex = 0) { const { callContext, args } = this.execution; const fields = [ ...toACVMCallContext(callContext),