diff --git a/barretenberg/cpp/pil/avm/avm_alu.pil b/barretenberg/cpp/pil/avm/avm_alu.pil index 1270de31f4d2..2d4c91d87098 100644 --- a/barretenberg/cpp/pil/avm/avm_alu.pil +++ b/barretenberg/cpp/pil/avm/avm_alu.pil @@ -225,14 +225,18 @@ namespace avm_alu(256); alu_op_not * (alu_ia + alu_ic - UINT_MAX) = 0; // ========= EQUALITY Operation Constraints =============================== + // TODO: Note this method differs from the approach taken for "equality to zero" checks + // in handling the error tags found in avm_main and avm_mem files. The predicted relation difference + // is minor and when we optimise we will harmonise the methods based on actual performance. + // Equality of two elements is found by performing an "equality to zero" check. - // This relies on the fact than the inverse of a field element exists for all elements except zero - // 1) Given two values a & b, find the difference c = a - b - // 2) If a & b are equal, c == 0 otherwise c != 0 + // This relies on the fact that the inverse of a field element exists for all elements except zero + // 1) Given two values x & y, find the difference z = x - y + // 2) If x & y are equal, z == 0 otherwise z != 0 // 3) Field equality to zero can be done as follows - // a) c(e(1 - y) + y) - 1 + e = 0; - // b) where y = c^-1 and e is a boolean value indicating if c == 0 - // c) if e == 0; cy = 1 && c has an inverse. if e ==1; c = 0 and we set c_inv = 0; + // a) z(e(x - w) + w) - 1 + e = 0; + // b) where w = z^-1 and e is a boolean value indicating if z == 0 + // c) if e == 0; zw = 1 && z has an inverse. If e == 1; z == 0 and we set w = 0; // Registers Ia and Ib hold the values that equality is to be tested on pol DIFF = alu_ia - alu_ib; diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp index b2662f6cba86..3c00d0ee98b3 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp @@ -43,7 +43,7 @@ class AvmFlavor { // the unshifted and one for the shifted static constexpr size_t NUM_ALL_ENTITIES = 85; - using Relations = std::tuple, Avm_vm::avm_alu, Avm_vm::avm_mem>; + using Relations = std::tuple, Avm_vm::avm_main, Avm_vm::avm_mem>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -296,19 +296,19 @@ class AvmFlavor { avm_main_mem_idx_b, avm_main_mem_idx_c, avm_main_last, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift, avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r5_shift, avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r4_shift, avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r5_shift, avm_alu_alu_u16_r1_shift, - avm_mem_m_val_shift, - avm_mem_m_rw_shift, + avm_alu_alu_u16_r6_shift, + avm_main_internal_return_ptr_shift, + avm_main_pc_shift, avm_mem_m_addr_shift, + avm_mem_m_rw_shift, + avm_mem_m_val_shift, avm_mem_m_tag_shift) RefVector get_wires() @@ -384,19 +384,19 @@ class AvmFlavor { avm_main_mem_idx_b, avm_main_mem_idx_c, avm_main_last, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift, avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r5_shift, avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r4_shift, avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r5_shift, avm_alu_alu_u16_r1_shift, - avm_mem_m_val_shift, - avm_mem_m_rw_shift, + avm_alu_alu_u16_r6_shift, + avm_main_internal_return_ptr_shift, + avm_main_pc_shift, avm_mem_m_addr_shift, + avm_mem_m_rw_shift, + avm_mem_m_val_shift, avm_mem_m_tag_shift }; }; RefVector get_unshifted() @@ -475,37 +475,19 @@ class AvmFlavor { }; RefVector get_to_be_shifted() { - return { avm_main_internal_return_ptr, - avm_main_pc, - avm_alu_alu_u16_r2, - avm_alu_alu_u16_r6, - avm_alu_alu_u16_r7, - avm_alu_alu_u16_r4, - avm_alu_alu_u16_r5, - avm_alu_alu_u16_r3, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r1, - avm_mem_m_val, - avm_mem_m_rw, - avm_mem_m_addr, - avm_mem_m_tag }; + return { avm_alu_alu_u16_r2, avm_alu_alu_u16_r7, avm_alu_alu_u16_r3, + avm_alu_alu_u16_r4, avm_alu_alu_u16_r0, avm_alu_alu_u16_r5, + avm_alu_alu_u16_r1, avm_alu_alu_u16_r6, avm_main_internal_return_ptr, + avm_main_pc, avm_mem_m_addr, avm_mem_m_rw, + avm_mem_m_val, avm_mem_m_tag }; }; RefVector get_shifted() { - return { avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r1_shift, - avm_mem_m_val_shift, - avm_mem_m_rw_shift, - avm_mem_m_addr_shift, - avm_mem_m_tag_shift }; + return { avm_alu_alu_u16_r2_shift, avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r4_shift, avm_alu_alu_u16_r0_shift, avm_alu_alu_u16_r5_shift, + avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r6_shift, avm_main_internal_return_ptr_shift, + avm_main_pc_shift, avm_mem_m_addr_shift, avm_mem_m_rw_shift, + avm_mem_m_val_shift, avm_mem_m_tag_shift }; }; }; @@ -518,20 +500,11 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_main_internal_return_ptr, - avm_main_pc, - avm_alu_alu_u16_r2, - avm_alu_alu_u16_r6, - avm_alu_alu_u16_r7, - avm_alu_alu_u16_r4, - avm_alu_alu_u16_r5, - avm_alu_alu_u16_r3, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r1, - avm_mem_m_val, - avm_mem_m_rw, - avm_mem_m_addr, - avm_mem_m_tag }; + return { avm_alu_alu_u16_r2, avm_alu_alu_u16_r7, avm_alu_alu_u16_r3, + avm_alu_alu_u16_r4, avm_alu_alu_u16_r0, avm_alu_alu_u16_r5, + avm_alu_alu_u16_r1, avm_alu_alu_u16_r6, avm_main_internal_return_ptr, + avm_main_pc, avm_mem_m_addr, avm_mem_m_rw, + avm_mem_m_val, avm_mem_m_tag }; }; // The plookup wires that store plookup read data. diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/avm_circuit_builder.hpp index 8d005c78c097..1ebd818d6ba3 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/avm_circuit_builder.hpp @@ -90,19 +90,19 @@ template struct AvmFullRow { FF avm_main_mem_idx_b{}; FF avm_main_mem_idx_c{}; FF avm_main_last{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_pc_shift{}; FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r6_shift{}; FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u16_r4_shift{}; - FF avm_alu_alu_u16_r5_shift{}; FF avm_alu_alu_u16_r3_shift{}; + FF avm_alu_alu_u16_r4_shift{}; FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r5_shift{}; FF avm_alu_alu_u16_r1_shift{}; - FF avm_mem_m_val_shift{}; - FF avm_mem_m_rw_shift{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_pc_shift{}; FF avm_mem_m_addr_shift{}; + FF avm_mem_m_rw_shift{}; + FF avm_mem_m_val_shift{}; FF avm_mem_m_tag_shift{}; }; @@ -206,19 +206,19 @@ class AvmCircuitBuilder { polys.avm_main_last[i] = rows[i].avm_main_last; } - polys.avm_main_internal_return_ptr_shift = Polynomial(polys.avm_main_internal_return_ptr.shifted()); - polys.avm_main_pc_shift = Polynomial(polys.avm_main_pc.shifted()); polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); - polys.avm_alu_alu_u16_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); - polys.avm_alu_alu_u16_r4_shift = Polynomial(polys.avm_alu_alu_u16_r4.shifted()); - polys.avm_alu_alu_u16_r5_shift = Polynomial(polys.avm_alu_alu_u16_r5.shifted()); polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); + polys.avm_alu_alu_u16_r4_shift = Polynomial(polys.avm_alu_alu_u16_r4.shifted()); polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.shifted()); + polys.avm_alu_alu_u16_r5_shift = Polynomial(polys.avm_alu_alu_u16_r5.shifted()); polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.shifted()); - polys.avm_mem_m_val_shift = Polynomial(polys.avm_mem_m_val.shifted()); - polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); + polys.avm_alu_alu_u16_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); + polys.avm_main_internal_return_ptr_shift = Polynomial(polys.avm_main_internal_return_ptr.shifted()); + polys.avm_main_pc_shift = Polynomial(polys.avm_main_pc.shifted()); polys.avm_mem_m_addr_shift = Polynomial(polys.avm_mem_m_addr.shifted()); + polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); + polys.avm_mem_m_val_shift = Polynomial(polys.avm_mem_m_val.shifted()); polys.avm_mem_m_tag_shift = Polynomial(polys.avm_mem_m_tag.shifted()); return polys; @@ -257,14 +257,14 @@ class AvmCircuitBuilder { return true; }; - if (!evaluate_relation.template operator()>("avm_main", - Avm_vm::get_relation_label_avm_main)) { - return false; - } if (!evaluate_relation.template operator()>("avm_alu", Avm_vm::get_relation_label_avm_alu)) { return false; } + if (!evaluate_relation.template operator()>("avm_main", + Avm_vm::get_relation_label_avm_main)) { + return false; + } if (!evaluate_relation.template operator()>("avm_mem", Avm_vm::get_relation_label_avm_mem)) { return false; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp index 5c957cf12007..4d27ef4f632e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,72 +7,72 @@ namespace bb::Avm_vm { template struct Avm_aluRow { + FF avm_alu_alu_op_eq{}; + FF avm_alu_alu_u128_tag{}; + FF avm_alu_alu_u16_r2_shift{}; FF avm_alu_alu_u16_r6{}; + FF avm_alu_alu_op_eq_diff_inv{}; + FF avm_alu_alu_u16_r4{}; + FF avm_alu_alu_u32_tag{}; + FF avm_alu_alu_u8_tag{}; + FF avm_alu_alu_ib{}; + FF avm_alu_alu_u8_r1{}; + FF avm_alu_alu_u16_tag{}; + FF avm_alu_alu_u16_r7{}; + FF avm_alu_alu_op_add{}; + FF avm_alu_alu_u16_r3{}; + FF avm_alu_alu_ff_tag{}; FF avm_alu_alu_u16_r5{}; - FF avm_alu_alu_u8_r0{}; - FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_u64_r0{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u16_r1{}; + FF avm_alu_alu_u16_r3_shift{}; + FF avm_alu_alu_u64_tag{}; FF avm_alu_alu_u16_r0{}; - FF avm_alu_alu_op_sub{}; - FF avm_alu_alu_cf{}; - FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_ic{}; FF avm_alu_alu_u16_r2{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_ib{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_op_eq{}; - FF avm_alu_alu_u8_r1{}; FF avm_alu_alu_u16_r4_shift{}; - FF avm_alu_alu_u16_r5_shift{}; - FF avm_alu_alu_u64_tag{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u16_r4{}; - FF avm_alu_alu_u16_r3{}; + FF avm_alu_alu_u8_r0{}; FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_ic{}; - FF avm_alu_alu_u128_tag{}; - FF avm_alu_alu_u16_r1{}; - FF avm_alu_alu_op_not{}; - FF avm_alu_alu_op_eq_diff_inv{}; - FF avm_alu_alu_ia{}; - FF avm_alu_alu_op_add{}; - FF avm_alu_alu_u32_tag{}; + FF avm_alu_alu_u16_r5_shift{}; + FF avm_alu_alu_cf{}; FF avm_alu_alu_op_mul{}; - FF avm_alu_alu_u16_r7{}; - FF avm_alu_alu_u8_tag{}; FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_u64_r0{}; - FF avm_alu_alu_u16_tag{}; + FF avm_alu_alu_ia{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_alu_alu_op_not{}; + FF avm_alu_alu_op_sub{}; }; inline std::string get_relation_label_avm_alu(int index) { switch (index) { + case 6: + return "ALU_ADD_SUB_1"; + case 9: return "ALU_MUL_COMMON_1"; - case 17: - return "ALU_OP_EQ"; - case 7: return "ALU_ADD_SUB_2"; - case 15: - return "ALU_OP_NOT"; - - case 6: - return "ALU_ADD_SUB_1"; - case 13: return "ALU_MULTIPLICATION_OUT_U128"; + case 10: + return "ALU_MUL_COMMON_2"; + case 16: return "ALU_RES_IS_BOOL"; + case 17: + return "ALU_OP_EQ"; + case 14: return "ALU_FF_NOT_XOR"; - case 10: - return "ALU_MUL_COMMON_2"; + case 15: + return "ALU_OP_NOT"; case 8: return "ALU_MULTIPLICATION_FF"; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp index 912e69bc482c..19042d74afab 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -7,63 +7,63 @@ namespace bb::Avm_vm { template struct Avm_mainRow { - FF avm_main_ib{}; - FF avm_main_sel_op_not{}; - FF avm_main_sel_op_add{}; - FF avm_main_rwb{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_sel_halt{}; - FF avm_main_sel_jump{}; - FF avm_main_mem_op_c{}; - FF avm_main_ia{}; FF avm_main_sel_op_mul{}; - FF avm_main_sel_internal_call{}; FF avm_main_mem_idx_a{}; - FF avm_main_sel_op_eq{}; - FF avm_main_mem_op_a{}; + FF avm_main_sel_op_not{}; FF avm_main_sel_op_sub{}; - FF avm_main_mem_op_b{}; FF avm_main_rwc{}; FF avm_main_op_err{}; - FF avm_main_inv{}; - FF avm_main_first{}; - FF avm_main_sel_op_div{}; + FF avm_main_ia{}; + FF avm_main_sel_jump{}; + FF avm_main_sel_internal_call{}; FF avm_main_internal_return_ptr{}; - FF avm_main_pc_shift{}; + FF avm_main_first{}; FF avm_main_sel_internal_return{}; + FF avm_main_sel_halt{}; FF avm_main_tag_err{}; - FF avm_main_ic{}; FF avm_main_rwa{}; - FF avm_main_mem_idx_b{}; + FF avm_main_mem_op_a{}; + FF avm_main_sel_op_eq{}; + FF avm_main_sel_op_add{}; + FF avm_main_inv{}; FF avm_main_pc{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_mem_op_b{}; + FF avm_main_pc_shift{}; + FF avm_main_rwb{}; + FF avm_main_mem_op_c{}; + FF avm_main_ic{}; + FF avm_main_sel_op_div{}; + FF avm_main_ib{}; + FF avm_main_mem_idx_b{}; }; inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 37: - return "PC_INCREMENT"; + case 23: + return "SUBOP_DIVISION_ZERO_ERR2"; case 21: return "SUBOP_DIVISION_FF"; - case 32: - return "RETURN_POINTER_DECREMENT"; + case 37: + return "PC_INCREMENT"; - case 23: - return "SUBOP_DIVISION_ZERO_ERR2"; + case 26: + return "RETURN_POINTER_INCREMENT"; case 24: return "SUBOP_ERROR_RELEVANT_OP"; - case 38: - return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 22: return "SUBOP_DIVISION_ZERO_ERR1"; - case 26: - return "RETURN_POINTER_INCREMENT"; + case 38: + return "INTERNAL_RETURN_POINTER_CONSISTENCY"; + + case 32: + return "RETURN_POINTER_DECREMENT"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp index 9fdfe6c0cb3e..9b505a84fef4 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -7,29 +7,26 @@ namespace bb::Avm_vm { template struct Avm_memRow { + FF avm_mem_m_tag_err{}; + FF avm_mem_m_addr_shift{}; + FF avm_mem_m_addr{}; + FF avm_mem_m_rw{}; + FF avm_mem_m_rw_shift{}; FF avm_mem_m_val_shift{}; FF avm_mem_m_in_tag{}; - FF avm_mem_m_last{}; FF avm_mem_m_tag{}; - FF avm_mem_m_rw_shift{}; - FF avm_mem_m_addr{}; FF avm_mem_m_one_min_inv{}; - FF avm_mem_m_rw{}; FF avm_mem_m_lastAccess{}; + FF avm_mem_m_last{}; FF avm_mem_m_val{}; - FF avm_mem_m_addr_shift{}; - FF avm_mem_m_tag_err{}; FF avm_mem_m_tag_shift{}; }; inline std::string get_relation_label_avm_mem(int index) { switch (index) { - case 7: - return "MEM_ZERO_INIT"; - - case 6: - return "MEM_READ_WRITE_TAG_CONSISTENCY"; + case 8: + return "MEM_IN_TAG_CONSISTENCY_1"; case 4: return "MEM_LAST_ACCESS_DELIMITER"; @@ -37,11 +34,14 @@ inline std::string get_relation_label_avm_mem(int index) case 5: return "MEM_READ_WRITE_VAL_CONSISTENCY"; - case 8: - return "MEM_IN_TAG_CONSISTENCY_1"; - case 9: return "MEM_IN_TAG_CONSISTENCY_2"; + + case 7: + return "MEM_ZERO_INIT"; + + case 6: + return "MEM_READ_WRITE_TAG_CONSISTENCY"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp index e8a58ee8f79a..3fb21f22e4b8 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -73,17 +73,17 @@ [[maybe_unused]] auto avm_main_mem_idx_b = View(new_term.avm_main_mem_idx_b); \ [[maybe_unused]] auto avm_main_mem_idx_c = View(new_term.avm_main_mem_idx_c); \ [[maybe_unused]] auto avm_main_last = View(new_term.avm_main_last); \ - [[maybe_unused]] auto avm_main_internal_return_ptr_shift = View(new_term.avm_main_internal_return_ptr_shift); \ - [[maybe_unused]] auto avm_main_pc_shift = View(new_term.avm_main_pc_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r2_shift = View(new_term.avm_alu_alu_u16_r2_shift); \ - [[maybe_unused]] auto avm_alu_alu_u16_r6_shift = View(new_term.avm_alu_alu_u16_r6_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r7_shift = View(new_term.avm_alu_alu_u16_r7_shift); \ - [[maybe_unused]] auto avm_alu_alu_u16_r4_shift = View(new_term.avm_alu_alu_u16_r4_shift); \ - [[maybe_unused]] auto avm_alu_alu_u16_r5_shift = View(new_term.avm_alu_alu_u16_r5_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r3_shift = View(new_term.avm_alu_alu_u16_r3_shift); \ + [[maybe_unused]] auto avm_alu_alu_u16_r4_shift = View(new_term.avm_alu_alu_u16_r4_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r0_shift = View(new_term.avm_alu_alu_u16_r0_shift); \ + [[maybe_unused]] auto avm_alu_alu_u16_r5_shift = View(new_term.avm_alu_alu_u16_r5_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r1_shift = View(new_term.avm_alu_alu_u16_r1_shift); \ - [[maybe_unused]] auto avm_mem_m_val_shift = View(new_term.avm_mem_m_val_shift); \ - [[maybe_unused]] auto avm_mem_m_rw_shift = View(new_term.avm_mem_m_rw_shift); \ + [[maybe_unused]] auto avm_alu_alu_u16_r6_shift = View(new_term.avm_alu_alu_u16_r6_shift); \ + [[maybe_unused]] auto avm_main_internal_return_ptr_shift = View(new_term.avm_main_internal_return_ptr_shift); \ + [[maybe_unused]] auto avm_main_pc_shift = View(new_term.avm_main_pc_shift); \ [[maybe_unused]] auto avm_mem_m_addr_shift = View(new_term.avm_mem_m_addr_shift); \ + [[maybe_unused]] auto avm_mem_m_rw_shift = View(new_term.avm_mem_m_rw_shift); \ + [[maybe_unused]] auto avm_mem_m_val_shift = View(new_term.avm_mem_m_val_shift); \ [[maybe_unused]] auto avm_mem_m_tag_shift = View(new_term.avm_mem_m_tag_shift); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp index 967c90dbf2f0..36a4fd8c9a16 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -700,7 +700,8 @@ void AvmTraceBuilder::op_not(uint32_t a_offset, uint32_t dst_offset, AvmMemoryTa auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, a_offset, in_tag); // ~a = c - FF c = alu_trace_builder.op_not(read_a.val, in_tag, clk); + FF a = read_a.tag_match ? read_a.val : FF(0); + FF c = alu_trace_builder.op_not(a, in_tag, clk); // Write into memory value c from intermediate register ic. mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, c, in_tag); @@ -711,7 +712,7 @@ void AvmTraceBuilder::op_not(uint32_t a_offset, uint32_t dst_offset, AvmMemoryTa .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_not = FF(1), .avm_main_in_tag = FF(static_cast(in_tag)), - .avm_main_ia = read_a.val, + .avm_main_ia = a, .avm_main_ic = c, .avm_main_mem_op_a = FF(1), .avm_main_mem_op_c = FF(1), @@ -736,9 +737,12 @@ void AvmTraceBuilder::op_eq(uint32_t a_offset, uint32_t b_offset, uint32_t dst_o // Reading from memory and loading into ia resp. ib. auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, a_offset, in_tag); auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, b_offset, in_tag); + bool tag_match = read_a.tag_match && read_b.tag_match; // c = a == b ? 1 : 0 - FF c = alu_trace_builder.op_eq(read_a.val, read_b.val, in_tag, clk); + FF a = tag_match ? read_a.val : FF(0); + FF b = tag_match ? read_b.val : FF(0); + FF c = alu_trace_builder.op_eq(a, b, in_tag, clk); // Write into memory value c from intermediate register ic. mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, c, in_tag); @@ -749,8 +753,8 @@ void AvmTraceBuilder::op_eq(uint32_t a_offset, uint32_t b_offset, uint32_t dst_o .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_eq = FF(1), .avm_main_in_tag = FF(static_cast(in_tag)), - .avm_main_ia = read_a.val, - .avm_main_ib = read_b.val, + .avm_main_ia = a, + .avm_main_ib = b, .avm_main_ic = c, .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp index 7283c1d12c78..71178fbf277c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp @@ -501,7 +501,7 @@ TEST_F(AvmArithmeticTestsFF, mixedOperationsWithError) TEST_F(AvmArithmeticTestsFF, equality) { // Pick a field-sized number - FF elem = FF::modulus - FF::one(); + FF elem = FF::modulus - FF(1); trace_builder.calldata_copy(0, 3, 0, std::vector{ elem, elem, 1 }); trace_builder.op_eq(0, 1, 2, AvmMemoryTag::FF); // Memory Layout [q - 1, q -1, 1,0..] trace_builder.return_op(0, 3); @@ -518,17 +518,17 @@ TEST_F(AvmArithmeticTestsFF, equality) // Test correct non-equality of FF elements TEST_F(AvmArithmeticTestsFF, nonEquality) { - FF elem = FF::modulus - FF::one(); - trace_builder.calldata_copy(0, 3, 0, std::vector{ elem, elem + FF::one(), 0 }); + FF elem = FF::modulus - FF(1); + trace_builder.calldata_copy(0, 3, 0, std::vector{ elem, elem + FF(1), 0 }); trace_builder.op_eq(0, 1, 2, AvmMemoryTag::FF); // Memory Layout [q - 1, q, 1,0..] trace_builder.return_op(0, 3); auto trace = trace_builder.finalize(); - auto alu_row_index = common_validate_eq(trace, elem, FF::zero(), FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::FF); + auto alu_row_index = common_validate_eq(trace, elem, FF(0), FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::FF); auto alu_row = trace.at(alu_row_index); EXPECT_EQ(alu_row.avm_alu_alu_ff_tag, FF(1)); - EXPECT_EQ(alu_row.avm_alu_alu_op_eq_diff_inv, -FF::one().invert()); + EXPECT_EQ(alu_row.avm_alu_alu_op_eq_diff_inv, FF(-1).invert()); validate_trace_proof(std::move(trace)); } @@ -693,6 +693,7 @@ TEST_F(AvmArithmeticTestsU8, equality) validate_trace_proof(std::move(trace)); } +// Test correct non-equality of U8 elements TEST_F(AvmArithmeticTestsU8, nonEquality) { trace_builder.set(84, 0, AvmMemoryTag::U8); @@ -705,7 +706,7 @@ TEST_F(AvmArithmeticTestsU8, nonEquality) auto alu_row = trace.at(alu_row_index); EXPECT_EQ(alu_row.avm_alu_alu_u8_tag, FF(1)); - EXPECT_EQ(alu_row.avm_alu_alu_op_eq_diff_inv, -FF(116).invert()); + EXPECT_EQ(alu_row.avm_alu_alu_op_eq_diff_inv, FF(-116).invert()); validate_trace_proof(std::move(trace)); } @@ -878,6 +879,7 @@ TEST_F(AvmArithmeticTestsU16, equality) validate_trace_proof(std::move(trace)); } +// Test correct non-equality of U16 elements TEST_F(AvmArithmeticTestsU16, nonEquality) { trace_builder.set(35'823, 0, AvmMemoryTag::U16); @@ -1077,6 +1079,7 @@ TEST_F(AvmArithmeticTestsU32, equality) validate_trace_proof(std::move(trace)); } +// Test correct non-equality of U32 elements TEST_F(AvmArithmeticTestsU32, nonEquality) { trace_builder.set(0xb435e9c1, 0, AvmMemoryTag::U32); @@ -1090,7 +1093,7 @@ TEST_F(AvmArithmeticTestsU32, nonEquality) auto alu_row = trace.at(alu_row_index); EXPECT_EQ(alu_row.avm_alu_alu_u32_tag, FF(1)); - EXPECT_EQ(alu_row.avm_alu_alu_op_eq_diff_inv, FF::one().invert()); + EXPECT_EQ(alu_row.avm_alu_alu_op_eq_diff_inv, FF(1).invert()); validate_trace_proof(std::move(trace)); } @@ -1286,10 +1289,8 @@ TEST_F(AvmArithmeticTestsU64, multiplicationOverflow) TEST_F(AvmArithmeticTestsU64, equality) { - uint64_t elem = 0xffffffffffffffe0; - trace_builder.calldata_copy(0, 3, 0, std::vector{ elem, elem, 1 }); - trace_builder.set(0xffffffffffffffe0LLU, 0, AvmMemoryTag::U64); trace_builder.set(0xffffffffffffffe0LLU, 0, AvmMemoryTag::U64); + trace_builder.set(0xffffffffffffffe0LLU, 1, AvmMemoryTag::U64); trace_builder.op_eq(0, 1, 2, AvmMemoryTag::U64); trace_builder.return_op(0, 3); auto trace = trace_builder.finalize(); @@ -1303,6 +1304,7 @@ TEST_F(AvmArithmeticTestsU64, equality) validate_trace_proof(std::move(trace)); } +// Test correct non-equality of U64 elements TEST_F(AvmArithmeticTestsU64, nonEquality) { trace_builder.set(0xffffffffffffffe0LLU, 0, AvmMemoryTag::U64); @@ -1603,6 +1605,7 @@ TEST_F(AvmArithmeticTestsU128, equality) validate_trace_proof(std::move(trace)); } +// Test correct non-equality of U128 elements TEST_F(AvmArithmeticTestsU128, nonEquality) { uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; @@ -1811,7 +1814,7 @@ TEST_F(AvmArithmeticNegativeTestsFF, operationWithErrorFlag) // Tests a situation for field elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsFF, invalidEquality) { - std::vector trace = gen_mutated_trace_eq(FF::modulus_minus_two, FF::zero(), FF(1), FF(0), AvmMemoryTag::FF); + std::vector trace = gen_mutated_trace_eq(FF::modulus_minus_two, FF(0), FF(1), FF(0), AvmMemoryTag::FF); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } @@ -1836,7 +1839,7 @@ TEST_F(AvmArithmeticNegativeTestsFF, invalidInverseDifference) { // The a, b and c registers contain the correct information, only the inversion of differences is wrong. std::vector trace = - gen_mutated_trace_eq(FF::modulus_minus_two, FF::zero(), FF(0), FF(5).invert(), AvmMemoryTag::FF); + gen_mutated_trace_eq(FF::modulus_minus_two, FF(0), FF(0), FF(5).invert(), AvmMemoryTag::FF); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } @@ -1865,28 +1868,32 @@ TEST_F(AvmArithmeticNegativeTestsU8, multiplication) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_MUL_COMMON_2"); } +// Tests a situation for field elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU8, invalidEquality) { std::vector trace = gen_mutated_trace_eq(FF(10), FF(255), FF(1), FF(0), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U8 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU8, invalidInequality) { std::vector trace = gen_mutated_trace_eq(FF(128), FF(128), FF(0), FF(0), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U8 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU8, nonBooleanEq) { std::vector trace = gen_mutated_trace_eq(FF(128), FF(128), FF(200), FF(0), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U8 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU8, invalidInverseDifference) { // The a, b and c registers contain the correct information, only the inversion of differences is wrong. - std::vector trace = gen_mutated_trace_eq(FF(130), FF::zero(), FF(0), FF(1000).invert(), AvmMemoryTag::U8); + std::vector trace = gen_mutated_trace_eq(FF(130), FF(0), FF(0), FF(1000).invert(), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } @@ -1915,28 +1922,32 @@ TEST_F(AvmArithmeticNegativeTestsU16, multiplication) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_MUL_COMMON_2"); } +// Tests a situation for U16 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU16, invalidEquality) { std::vector trace = gen_mutated_trace_eq(FF(10), FF(255), FF(1), FF(0), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U16 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU16, invalidInequality) { std::vector trace = gen_mutated_trace_eq(FF(128), FF(128), FF(0), FF(0), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U16 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU16, nonBooleanEq) { std::vector trace = gen_mutated_trace_eq(FF(128), FF(128), FF(200), FF(0), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U16 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU16, invalidInverseDifference) { // The a, b and c registers contain the correct information, only the inversion of differences is wrong. - std::vector trace = gen_mutated_trace_eq(FF(130), FF::zero(), FF(0), FF(1000).invert(), AvmMemoryTag::U16); + std::vector trace = gen_mutated_trace_eq(FF(130), FF(0), FF(0), FF(1000).invert(), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } /****************************************************************************** @@ -1964,18 +1975,21 @@ TEST_F(AvmArithmeticNegativeTestsU32, multiplication) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_MUL_COMMON_2"); } +// Tests a situation for U32 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU32, invalidEquality) { std::vector trace = gen_mutated_trace_eq(FF(UINT32_MAX - 10), FF(UINT32_MAX), FF(1), FF(0), AvmMemoryTag::U32); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U32 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU32, invalidInequality) { std::vector trace = gen_mutated_trace_eq(FF(73934721LLU), FF(73934721LLU), FF(0), FF(0), AvmMemoryTag::U32); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U32 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU32, nonBooleanEq) { std::vector trace = @@ -1983,6 +1997,7 @@ TEST_F(AvmArithmeticNegativeTestsU32, nonBooleanEq) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U32 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU32, invalidInverseDifference) { // The a, b and c registers contain the correct information, only the inversion of differences is wrong. @@ -2019,6 +2034,7 @@ TEST_F(AvmArithmeticNegativeTestsU64, multiplication) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_MUL_COMMON_2"); } +// Tests a situation for U64 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU64, invalidEquality) { std::vector trace = @@ -2026,6 +2042,7 @@ TEST_F(AvmArithmeticNegativeTestsU64, invalidEquality) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U64 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU64, invalidInequality) { std::vector trace = @@ -2033,6 +2050,7 @@ TEST_F(AvmArithmeticNegativeTestsU64, invalidInequality) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U64 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU64, nonBooleanEq) { std::vector trace = @@ -2040,6 +2058,7 @@ TEST_F(AvmArithmeticNegativeTestsU64, nonBooleanEq) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U64 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU64, invalidInverseDifference) { // The a, b and c registers contain the correct information, only the inversion of differences is wrong. @@ -2094,6 +2113,7 @@ TEST_F(AvmArithmeticNegativeTestsU128, multiplication) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_MULTIPLICATION_OUT_U128"); } +// Tests a situation for U128 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU128, invalidEquality) { uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; @@ -2105,6 +2125,7 @@ TEST_F(AvmArithmeticNegativeTestsU128, invalidEquality) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U128 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU128, invalidInequality) { uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; @@ -2114,14 +2135,16 @@ TEST_F(AvmArithmeticNegativeTestsU128, invalidInequality) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_OP_EQ"); } +// Tests a situation for U128 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU128, nonBooleanEq) { uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; FF const ff_a = FF{ uint256_t::from_uint128(a) }; - std::vector trace = gen_mutated_trace_eq(ff_a, ff_a, FF::modulus - FF::one(), FF(0), AvmMemoryTag::U128); + std::vector trace = gen_mutated_trace_eq(ff_a, ff_a, FF::modulus - FF(1), FF(0), AvmMemoryTag::U128); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U128 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU128, invalidInverseDifference) { uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU };