From 0e503c14c0c20a93e162a90d8d049f094b64de7d Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:28:43 +0000 Subject: [PATCH] feat(avm): enable main -> mem clk lookups (#4591) Enables lookup for tag err, adds test case for permutation check with two selectors. Edits the permutation check active constraint to be active when either lhs / rhs are active, rather than a third selector. Co-authored-by: jeanmon --- barretenberg/cpp/pil/avm/avm_main.pil | 4 +- barretenberg/cpp/pil/avm/toy_avm.pil | 19 +- .../flavor/generated/avm_flavor.hpp | 129 +++++++------- .../flavor/generated/toy_flavor.hpp | 137 +++++++++++++-- .../generated/avm_circuit_builder.hpp | 83 ++++++--- .../generated/toy_circuit_builder.hpp | 35 +++- .../toy_avm/toy_avm_circuit_builder.test.cpp | 97 ++++++++++ .../relations/generated/avm/avm_alu.hpp | 78 ++++---- .../relations/generated/avm/avm_main.hpp | 74 ++++---- .../relations/generated/avm/avm_mem.hpp | 22 +-- .../relations/generated/avm/declare_views.hpp | 20 ++- .../relations/generated/avm/equiv_tag_err.hpp | 166 ++++++++++++++++++ .../relations/generated/toy/declare_views.hpp | 13 +- .../relations/generated/toy/lookup_err.hpp | 158 +++++++++++++++++ .../generated/toy/two_column_perm.hpp | 2 +- .../generated/toy/two_column_sparse_perm.hpp | 91 ++++++++++ .../generic_permutation_relation.hpp | 14 +- .../vm/avm_trace/avm_mem_trace.cpp | 5 + .../vm/avm_trace/avm_mem_trace.hpp | 4 + .../barretenberg/vm/avm_trace/avm_trace.cpp | 17 ++ .../barretenberg/vm/avm_trace/avm_trace.hpp | 2 + .../vm/generated/avm_verifier.cpp | 3 + .../vm/generated/toy_verifier.cpp | 16 ++ .../vm/tests/avm_arithmetic.test.cpp | 62 +++---- .../vm/tests/avm_bitwise.test.cpp | 10 +- .../barretenberg/vm/tests/helpers.test.cpp | 2 + 26 files changed, 1019 insertions(+), 244 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/equiv_tag_err.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/toy/lookup_err.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/toy/two_column_sparse_perm.hpp diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index 473fe5b70fd..8fd09b8536c 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -192,6 +192,8 @@ namespace avm_main(256); // Inter-table Constraints - // TODO: tag_err {clk} IS avm_mem.m_tag_err {avm_mem.m_clk} + #[equiv_tag_err] + avm_mem.m_tag_err {avm_mem.m_clk} in tag_err {clk}; + // TODO: Map memory trace with intermediate register values whenever there is no tag error, sthg like: // mem_op_a * (1 - tag_err) {mem_idx_a, clk, ia, rwa} IS m_sub_clk == 0 && 1 - m_tag_err {m_addr, m_clk, m_val, m_rw} diff --git a/barretenberg/cpp/pil/avm/toy_avm.pil b/barretenberg/cpp/pil/avm/toy_avm.pil index 422ff4d1a0e..375c29d8ac6 100644 --- a/barretenberg/cpp/pil/avm/toy_avm.pil +++ b/barretenberg/cpp/pil/avm/toy_avm.pil @@ -8,10 +8,18 @@ namespace toy(256); pol commit set_2_column_1; pol commit set_2_column_2; - // This is a column based tuple lookup + // This is a column based tuple lookup, one selector #[two_column_perm] // the name of the inverse q_tuple_set { set_1_column_1, set_1_column_2 } is { set_2_column_1, set_2_column_2 }; + + // Column based lookup, two selectors + pol commit sparse_column_1, sparse_column_2; + pol commit sparse_lhs, sparse_rhs; + + #[two_column_sparse_perm] // the name of the inverse + sparse_lhs { sparse_column_1 } is sparse_rhs { sparse_column_2 }; + // Relation not used -> we currently require a single relation for codegen q_tuple_set * (1 - q_tuple_set) = 0; @@ -45,4 +53,11 @@ namespace toy(256); // Note - if no right hand side selector column is provided, then we will need to build the table ourselves // Note - we can also take advantage of pil creating the lookup columns for us here -> I may be able to do some codegen here ! #[lookup_xor] - q_xor { xor_a, xor_b, xor_c } in q_xor_table { table_xor_a, table_xor_b, table_xor_c }; \ No newline at end of file + q_xor { xor_a, xor_b, xor_c } in q_xor_table { table_xor_a, table_xor_b, table_xor_c }; + + // Minimum repro testing multiple lookups + pol commit q_err, q_err_check; + pol commit clk, m_clk; + + #[lookup_err] + q_err_check {m_clk} in q_err {clk}; diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp index a43887cd19d..85f377b0afb 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp @@ -37,13 +37,13 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 69; + static constexpr size_t NUM_WITNESS_ENTITIES = 71; static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES; // We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for // the unshifted and one for the shifted - static constexpr size_t NUM_ALL_ENTITIES = 85; + static constexpr size_t NUM_ALL_ENTITIES = 87; - using Relations = std::tuple, Avm_vm::avm_main, Avm_vm::avm_alu>; + using Relations = std::tuple, Avm_vm::avm_alu, Avm_vm::avm_main>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -145,7 +145,9 @@ class AvmFlavor { avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, - avm_main_last) + avm_main_last, + equiv_tag_err, + equiv_tag_err_counts) RefVector get_wires() { @@ -217,7 +219,9 @@ class AvmFlavor { avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, - avm_main_last }; + avm_main_last, + equiv_tag_err, + equiv_tag_err_counts }; }; RefVector get_sorted_polynomials() { return {}; }; }; @@ -296,20 +300,22 @@ class AvmFlavor { avm_main_mem_idx_b, avm_main_mem_idx_c, avm_main_last, + equiv_tag_err, + equiv_tag_err_counts, avm_mem_m_rw_shift, - avm_mem_m_tag_shift, - avm_mem_m_val_shift, avm_mem_m_addr_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r0_shift, + avm_mem_m_val_shift, + avm_mem_m_tag_shift, avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r3_shift, avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r4_shift) + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r3_shift, + avm_main_pc_shift, + avm_main_internal_return_ptr_shift) RefVector get_wires() { @@ -384,20 +390,22 @@ class AvmFlavor { avm_main_mem_idx_b, avm_main_mem_idx_c, avm_main_last, + equiv_tag_err, + equiv_tag_err_counts, avm_mem_m_rw_shift, - avm_mem_m_tag_shift, - avm_mem_m_val_shift, avm_mem_m_addr_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r0_shift, + avm_mem_m_val_shift, + avm_mem_m_tag_shift, avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r3_shift, avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r4_shift }; + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r3_shift, + avm_main_pc_shift, + avm_main_internal_return_ptr_shift }; }; RefVector get_unshifted() { @@ -471,41 +479,29 @@ class AvmFlavor { avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, - avm_main_last }; + avm_main_last, + equiv_tag_err, + equiv_tag_err_counts }; }; RefVector get_to_be_shifted() { - return { avm_mem_m_rw, - avm_mem_m_tag, - avm_mem_m_val, - avm_mem_m_addr, - avm_main_internal_return_ptr, - avm_main_pc, - avm_alu_alu_u16_r6, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r2, - avm_alu_alu_u16_r7, - avm_alu_alu_u16_r3, - avm_alu_alu_u16_r1, - avm_alu_alu_u16_r5, - avm_alu_alu_u16_r4 }; + return { avm_mem_m_rw, avm_mem_m_addr, + avm_mem_m_val, avm_mem_m_tag, + avm_alu_alu_u16_r2, avm_alu_alu_u16_r1, + avm_alu_alu_u16_r5, avm_alu_alu_u16_r0, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r6, + avm_alu_alu_u16_r4, avm_alu_alu_u16_r3, + avm_main_pc, avm_main_internal_return_ptr }; }; RefVector get_shifted() { - return { avm_mem_m_rw_shift, - avm_mem_m_tag_shift, - avm_mem_m_val_shift, - avm_mem_m_addr_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r4_shift }; + return { avm_mem_m_rw_shift, avm_mem_m_addr_shift, + avm_mem_m_val_shift, avm_mem_m_tag_shift, + avm_alu_alu_u16_r2_shift, avm_alu_alu_u16_r1_shift, + avm_alu_alu_u16_r5_shift, avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r4_shift, avm_alu_alu_u16_r3_shift, + avm_main_pc_shift, avm_main_internal_return_ptr_shift }; }; }; @@ -518,20 +514,13 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_mem_m_rw, - avm_mem_m_tag, - avm_mem_m_val, - avm_mem_m_addr, - avm_main_internal_return_ptr, - avm_main_pc, - avm_alu_alu_u16_r6, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r2, - avm_alu_alu_u16_r7, - avm_alu_alu_u16_r3, - avm_alu_alu_u16_r1, - avm_alu_alu_u16_r5, - avm_alu_alu_u16_r4 }; + return { avm_mem_m_rw, avm_mem_m_addr, + avm_mem_m_val, avm_mem_m_tag, + avm_alu_alu_u16_r2, avm_alu_alu_u16_r1, + avm_alu_alu_u16_r5, avm_alu_alu_u16_r0, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r6, + avm_alu_alu_u16_r4, avm_alu_alu_u16_r3, + avm_main_pc, avm_main_internal_return_ptr }; }; // The plookup wires that store plookup read data. @@ -679,6 +668,8 @@ class AvmFlavor { Base::avm_main_mem_idx_b = "AVM_MAIN_MEM_IDX_B"; Base::avm_main_mem_idx_c = "AVM_MAIN_MEM_IDX_C"; Base::avm_main_last = "AVM_MAIN_LAST"; + Base::equiv_tag_err = "EQUIV_TAG_ERR"; + Base::equiv_tag_err_counts = "EQUIV_TAG_ERR_COUNTS"; }; }; @@ -767,6 +758,8 @@ class AvmFlavor { Commitment avm_main_mem_idx_b; Commitment avm_main_mem_idx_c; Commitment avm_main_last; + Commitment equiv_tag_err; + Commitment equiv_tag_err_counts; std::vector> sumcheck_univariates; std::array sumcheck_evaluations; @@ -855,6 +848,8 @@ class AvmFlavor { avm_main_mem_idx_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_mem_idx_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_last = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + equiv_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + equiv_tag_err_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); for (size_t i = 0; i < log_n; ++i) { sumcheck_univariates.emplace_back( @@ -947,6 +942,8 @@ class AvmFlavor { serialize_to_buffer(avm_main_mem_idx_b, Transcript::proof_data); serialize_to_buffer(avm_main_mem_idx_c, Transcript::proof_data); serialize_to_buffer(avm_main_last, Transcript::proof_data); + serialize_to_buffer(equiv_tag_err, Transcript::proof_data); + serialize_to_buffer(equiv_tag_err_counts, Transcript::proof_data); for (size_t i = 0; i < log_n; ++i) { serialize_to_buffer(sumcheck_univariates[i], Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/toy_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/toy_flavor.hpp index c13b13f50a2..d13ff8df281 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/toy_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/toy_flavor.hpp @@ -15,6 +15,7 @@ #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/generated/toy/toy_avm.hpp" #include "barretenberg/relations/generated/toy/two_column_perm.hpp" +#include "barretenberg/relations/generated/toy/two_column_sparse_perm.hpp" #include "barretenberg/transcript/transcript.hpp" namespace bb { @@ -36,13 +37,14 @@ class ToyFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 1; - static constexpr size_t NUM_WITNESS_ENTITIES = 16; + static constexpr size_t NUM_WITNESS_ENTITIES = 27; static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES; // We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for // the unshifted and one for the shifted - static constexpr size_t NUM_ALL_ENTITIES = 17; + static constexpr size_t NUM_ALL_ENTITIES = 28; - using Relations = std::tuple, two_column_perm_relation>; + using Relations = + std::tuple, two_column_perm_relation, two_column_sparse_perm_relation>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -81,6 +83,10 @@ class ToyFlavor { toy_set_1_column_2, toy_set_2_column_1, toy_set_2_column_2, + toy_sparse_column_1, + toy_sparse_column_2, + toy_sparse_lhs, + toy_sparse_rhs, toy_xor_a, toy_xor_b, toy_xor_c, @@ -89,16 +95,46 @@ class ToyFlavor { toy_table_xor_c, toy_q_xor, toy_q_xor_table, + toy_q_err, + toy_q_err_check, + toy_clk, + toy_m_clk, two_column_perm, + two_column_sparse_perm, lookup_xor, - lookup_xor_counts) + lookup_err, + lookup_xor_counts, + lookup_err_counts) RefVector get_wires() { - return { toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1, - toy_set_2_column_2, toy_xor_a, toy_xor_b, toy_xor_c, - toy_table_xor_a, toy_table_xor_b, toy_table_xor_c, toy_q_xor, - toy_q_xor_table, two_column_perm, lookup_xor, lookup_xor_counts }; + return { toy_q_tuple_set, + toy_set_1_column_1, + toy_set_1_column_2, + toy_set_2_column_1, + toy_set_2_column_2, + toy_sparse_column_1, + toy_sparse_column_2, + toy_sparse_lhs, + toy_sparse_rhs, + toy_xor_a, + toy_xor_b, + toy_xor_c, + toy_table_xor_a, + toy_table_xor_b, + toy_table_xor_c, + toy_q_xor, + toy_q_xor_table, + toy_q_err, + toy_q_err_check, + toy_clk, + toy_m_clk, + two_column_perm, + two_column_sparse_perm, + lookup_xor, + lookup_err, + lookup_xor_counts, + lookup_err_counts }; }; RefVector get_sorted_polynomials() { return {}; }; }; @@ -112,6 +148,10 @@ class ToyFlavor { toy_set_1_column_2, toy_set_2_column_1, toy_set_2_column_2, + toy_sparse_column_1, + toy_sparse_column_2, + toy_sparse_lhs, + toy_sparse_rhs, toy_xor_a, toy_xor_b, toy_xor_c, @@ -120,23 +160,42 @@ class ToyFlavor { toy_table_xor_c, toy_q_xor, toy_q_xor_table, + toy_q_err, + toy_q_err_check, + toy_clk, + toy_m_clk, two_column_perm, + two_column_sparse_perm, lookup_xor, - lookup_xor_counts) + lookup_err, + lookup_xor_counts, + lookup_err_counts) RefVector get_wires() { - return { toy_first, toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1, - toy_set_2_column_2, toy_xor_a, toy_xor_b, toy_xor_c, toy_table_xor_a, - toy_table_xor_b, toy_table_xor_c, toy_q_xor, toy_q_xor_table, two_column_perm, - lookup_xor, lookup_xor_counts }; + return { toy_first, toy_q_tuple_set, toy_set_1_column_1, + toy_set_1_column_2, toy_set_2_column_1, toy_set_2_column_2, + toy_sparse_column_1, toy_sparse_column_2, toy_sparse_lhs, + toy_sparse_rhs, toy_xor_a, toy_xor_b, + toy_xor_c, toy_table_xor_a, toy_table_xor_b, + toy_table_xor_c, toy_q_xor, toy_q_xor_table, + toy_q_err, toy_q_err_check, toy_clk, + toy_m_clk, two_column_perm, two_column_sparse_perm, + lookup_xor, lookup_err, lookup_xor_counts, + lookup_err_counts }; }; RefVector get_unshifted() { - return { toy_first, toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1, - toy_set_2_column_2, toy_xor_a, toy_xor_b, toy_xor_c, toy_table_xor_a, - toy_table_xor_b, toy_table_xor_c, toy_q_xor, toy_q_xor_table, two_column_perm, - lookup_xor, lookup_xor_counts }; + return { toy_first, toy_q_tuple_set, toy_set_1_column_1, + toy_set_1_column_2, toy_set_2_column_1, toy_set_2_column_2, + toy_sparse_column_1, toy_sparse_column_2, toy_sparse_lhs, + toy_sparse_rhs, toy_xor_a, toy_xor_b, + toy_xor_c, toy_table_xor_a, toy_table_xor_b, + toy_table_xor_c, toy_q_xor, toy_q_xor_table, + toy_q_err, toy_q_err_check, toy_clk, + toy_m_clk, two_column_perm, two_column_sparse_perm, + lookup_xor, lookup_err, lookup_xor_counts, + lookup_err_counts }; }; RefVector get_to_be_shifted() { return {}; }; RefVector get_shifted() { return {}; }; @@ -231,6 +290,10 @@ class ToyFlavor { Base::toy_set_1_column_2 = "TOY_SET_1_COLUMN_2"; Base::toy_set_2_column_1 = "TOY_SET_2_COLUMN_1"; Base::toy_set_2_column_2 = "TOY_SET_2_COLUMN_2"; + Base::toy_sparse_column_1 = "TOY_SPARSE_COLUMN_1"; + Base::toy_sparse_column_2 = "TOY_SPARSE_COLUMN_2"; + Base::toy_sparse_lhs = "TOY_SPARSE_LHS"; + Base::toy_sparse_rhs = "TOY_SPARSE_RHS"; Base::toy_xor_a = "TOY_XOR_A"; Base::toy_xor_b = "TOY_XOR_B"; Base::toy_xor_c = "TOY_XOR_C"; @@ -239,9 +302,16 @@ class ToyFlavor { Base::toy_table_xor_c = "TOY_TABLE_XOR_C"; Base::toy_q_xor = "TOY_Q_XOR"; Base::toy_q_xor_table = "TOY_Q_XOR_TABLE"; + Base::toy_q_err = "TOY_Q_ERR"; + Base::toy_q_err_check = "TOY_Q_ERR_CHECK"; + Base::toy_clk = "TOY_CLK"; + Base::toy_m_clk = "TOY_M_CLK"; Base::two_column_perm = "TWO_COLUMN_PERM"; + Base::two_column_sparse_perm = "TWO_COLUMN_SPARSE_PERM"; Base::lookup_xor = "LOOKUP_XOR"; + Base::lookup_err = "LOOKUP_ERR"; Base::lookup_xor_counts = "LOOKUP_XOR_COUNTS"; + Base::lookup_err_counts = "LOOKUP_ERR_COUNTS"; }; }; @@ -265,6 +335,10 @@ class ToyFlavor { Commitment toy_set_1_column_2; Commitment toy_set_2_column_1; Commitment toy_set_2_column_2; + Commitment toy_sparse_column_1; + Commitment toy_sparse_column_2; + Commitment toy_sparse_lhs; + Commitment toy_sparse_rhs; Commitment toy_xor_a; Commitment toy_xor_b; Commitment toy_xor_c; @@ -273,9 +347,16 @@ class ToyFlavor { Commitment toy_table_xor_c; Commitment toy_q_xor; Commitment toy_q_xor_table; + Commitment toy_q_err; + Commitment toy_q_err_check; + Commitment toy_clk; + Commitment toy_m_clk; Commitment two_column_perm; + Commitment two_column_sparse_perm; Commitment lookup_xor; + Commitment lookup_err; Commitment lookup_xor_counts; + Commitment lookup_err_counts; std::vector> sumcheck_univariates; std::array sumcheck_evaluations; @@ -300,6 +381,10 @@ class ToyFlavor { toy_set_1_column_2 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); toy_set_2_column_1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); toy_set_2_column_2 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + toy_sparse_column_1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + toy_sparse_column_2 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + toy_sparse_lhs = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + toy_sparse_rhs = deserialize_from_buffer(Transcript::proof_data, num_frs_read); toy_xor_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); toy_xor_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); toy_xor_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -308,9 +393,16 @@ class ToyFlavor { toy_table_xor_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); toy_q_xor = deserialize_from_buffer(Transcript::proof_data, num_frs_read); toy_q_xor_table = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + toy_q_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + toy_q_err_check = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + toy_clk = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + toy_m_clk = deserialize_from_buffer(Transcript::proof_data, num_frs_read); two_column_perm = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + two_column_sparse_perm = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_xor = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_xor_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_err_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); for (size_t i = 0; i < log_n; ++i) { sumcheck_univariates.emplace_back( @@ -339,6 +431,10 @@ class ToyFlavor { serialize_to_buffer(toy_set_1_column_2, Transcript::proof_data); serialize_to_buffer(toy_set_2_column_1, Transcript::proof_data); serialize_to_buffer(toy_set_2_column_2, Transcript::proof_data); + serialize_to_buffer(toy_sparse_column_1, Transcript::proof_data); + serialize_to_buffer(toy_sparse_column_2, Transcript::proof_data); + serialize_to_buffer(toy_sparse_lhs, Transcript::proof_data); + serialize_to_buffer(toy_sparse_rhs, Transcript::proof_data); serialize_to_buffer(toy_xor_a, Transcript::proof_data); serialize_to_buffer(toy_xor_b, Transcript::proof_data); serialize_to_buffer(toy_xor_c, Transcript::proof_data); @@ -347,9 +443,16 @@ class ToyFlavor { serialize_to_buffer(toy_table_xor_c, Transcript::proof_data); serialize_to_buffer(toy_q_xor, Transcript::proof_data); serialize_to_buffer(toy_q_xor_table, Transcript::proof_data); + serialize_to_buffer(toy_q_err, Transcript::proof_data); + serialize_to_buffer(toy_q_err_check, Transcript::proof_data); + serialize_to_buffer(toy_clk, Transcript::proof_data); + serialize_to_buffer(toy_m_clk, Transcript::proof_data); serialize_to_buffer(two_column_perm, Transcript::proof_data); + serialize_to_buffer(two_column_sparse_perm, Transcript::proof_data); serialize_to_buffer(lookup_xor, Transcript::proof_data); + serialize_to_buffer(lookup_err, Transcript::proof_data); serialize_to_buffer(lookup_xor_counts, Transcript::proof_data); + serialize_to_buffer(lookup_err_counts, Transcript::proof_data); for (size_t i = 0; i < log_n; ++i) { serialize_to_buffer(sumcheck_univariates[i], Transcript::proof_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 59b53d25c61..f60a3310e83 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 @@ -15,6 +15,7 @@ #include "barretenberg/relations/generated/avm/avm_alu.hpp" #include "barretenberg/relations/generated/avm/avm_main.hpp" #include "barretenberg/relations/generated/avm/avm_mem.hpp" +#include "barretenberg/relations/generated/avm/equiv_tag_err.hpp" namespace bb { @@ -90,20 +91,22 @@ template struct AvmFullRow { FF avm_main_mem_idx_b{}; FF avm_main_mem_idx_c{}; FF avm_main_last{}; + FF equiv_tag_err{}; + FF equiv_tag_err_counts{}; FF avm_mem_m_rw_shift{}; - FF avm_mem_m_tag_shift{}; - FF avm_mem_m_val_shift{}; FF avm_mem_m_addr_shift{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_pc_shift{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u16_r0_shift{}; + FF avm_mem_m_val_shift{}; + FF avm_mem_m_tag_shift{}; FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u16_r3_shift{}; FF avm_alu_alu_u16_r1_shift{}; FF avm_alu_alu_u16_r5_shift{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u16_r6_shift{}; FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r3_shift{}; + FF avm_main_pc_shift{}; + FF avm_main_internal_return_ptr_shift{}; }; class AvmCircuitBuilder { @@ -116,8 +119,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 85; - static constexpr size_t num_polys = 71; + static constexpr size_t num_fixed_columns = 87; + static constexpr size_t num_polys = 73; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -204,22 +207,24 @@ class AvmCircuitBuilder { polys.avm_main_mem_idx_b[i] = rows[i].avm_main_mem_idx_b; polys.avm_main_mem_idx_c[i] = rows[i].avm_main_mem_idx_c; polys.avm_main_last[i] = rows[i].avm_main_last; + polys.equiv_tag_err[i] = rows[i].equiv_tag_err; + polys.equiv_tag_err_counts[i] = rows[i].equiv_tag_err_counts; } polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); - polys.avm_mem_m_tag_shift = Polynomial(polys.avm_mem_m_tag.shifted()); - polys.avm_mem_m_val_shift = Polynomial(polys.avm_mem_m_val.shifted()); polys.avm_mem_m_addr_shift = Polynomial(polys.avm_mem_m_addr.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_alu_alu_u16_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); - polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.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()); polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); - polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); - polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.shifted()); polys.avm_alu_alu_u16_r5_shift = Polynomial(polys.avm_alu_alu_u16_r5.shifted()); + polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.shifted()); + polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); + polys.avm_alu_alu_u16_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); polys.avm_alu_alu_u16_r4_shift = Polynomial(polys.avm_alu_alu_u16_r4.shifted()); + polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); + polys.avm_main_pc_shift = Polynomial(polys.avm_main_pc.shifted()); + polys.avm_main_internal_return_ptr_shift = Polynomial(polys.avm_main_internal_return_ptr.shifted()); return polys; } @@ -227,6 +232,19 @@ class AvmCircuitBuilder { [[maybe_unused]] bool check_circuit() { + const FF gamma = FF::random_element(); + const FF beta = FF::random_element(); + bb::RelationParameters params{ + .eta = 0, + .beta = beta, + .gamma = gamma, + .public_input_delta = 0, + .lookup_grand_product_delta = 0, + .beta_sqr = 0, + .beta_cube = 0, + .eccvm_set_permutation_delta = 0, + }; + auto polys = compute_polynomials(); const size_t num_rows = polys.get_polynomial_size(); @@ -257,16 +275,41 @@ class AvmCircuitBuilder { return true; }; + const auto evaluate_logderivative = [&](const std::string& lookup_name) { + // Check the logderivative relation + bb::compute_logderivative_inverse(polys, params, num_rows); + + typename LogDerivativeSettings::SumcheckArrayOfValuesOverSubrelations lookup_result; + + for (auto& r : lookup_result) { + r = 0; + } + for (size_t i = 0; i < num_rows; ++i) { + LogDerivativeSettings::accumulate(lookup_result, polys.get_row(i), params, 1); + } + for (auto r : lookup_result) { + if (r != 0) { + info("Lookup ", lookup_name, " failed."); + return false; + } + } + return true; + }; + if (!evaluate_relation.template operator()>("avm_mem", Avm_vm::get_relation_label_avm_mem)) { 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_alu", - Avm_vm::get_relation_label_avm_alu)) { + + if (!evaluate_logderivative.template operator()>("equiv_tag_err")) { return false; } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/toy_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/toy_circuit_builder.hpp index ca930d1b51e..f6c1a2fa2dd 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/toy_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/toy_circuit_builder.hpp @@ -12,9 +12,11 @@ #include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" #include "barretenberg/flavor/generated/toy_flavor.hpp" +#include "barretenberg/relations/generated/toy/lookup_err.hpp" #include "barretenberg/relations/generated/toy/lookup_xor.hpp" #include "barretenberg/relations/generated/toy/toy_avm.hpp" #include "barretenberg/relations/generated/toy/two_column_perm.hpp" +#include "barretenberg/relations/generated/toy/two_column_sparse_perm.hpp" namespace bb { @@ -25,6 +27,10 @@ template struct ToyFullRow { FF toy_set_1_column_2{}; FF toy_set_2_column_1{}; FF toy_set_2_column_2{}; + FF toy_sparse_column_1{}; + FF toy_sparse_column_2{}; + FF toy_sparse_lhs{}; + FF toy_sparse_rhs{}; FF toy_xor_a{}; FF toy_xor_b{}; FF toy_xor_c{}; @@ -33,9 +39,16 @@ template struct ToyFullRow { FF toy_table_xor_c{}; FF toy_q_xor{}; FF toy_q_xor_table{}; + FF toy_q_err{}; + FF toy_q_err_check{}; + FF toy_clk{}; + FF toy_m_clk{}; FF two_column_perm{}; + FF two_column_sparse_perm{}; FF lookup_xor{}; + FF lookup_err{}; FF lookup_xor_counts{}; + FF lookup_err_counts{}; }; class ToyCircuitBuilder { @@ -48,8 +61,8 @@ class ToyCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 17; - static constexpr size_t num_polys = 17; + static constexpr size_t num_fixed_columns = 28; + static constexpr size_t num_polys = 28; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -71,6 +84,10 @@ class ToyCircuitBuilder { polys.toy_set_1_column_2[i] = rows[i].toy_set_1_column_2; polys.toy_set_2_column_1[i] = rows[i].toy_set_2_column_1; polys.toy_set_2_column_2[i] = rows[i].toy_set_2_column_2; + polys.toy_sparse_column_1[i] = rows[i].toy_sparse_column_1; + polys.toy_sparse_column_2[i] = rows[i].toy_sparse_column_2; + polys.toy_sparse_lhs[i] = rows[i].toy_sparse_lhs; + polys.toy_sparse_rhs[i] = rows[i].toy_sparse_rhs; polys.toy_xor_a[i] = rows[i].toy_xor_a; polys.toy_xor_b[i] = rows[i].toy_xor_b; polys.toy_xor_c[i] = rows[i].toy_xor_c; @@ -79,9 +96,16 @@ class ToyCircuitBuilder { polys.toy_table_xor_c[i] = rows[i].toy_table_xor_c; polys.toy_q_xor[i] = rows[i].toy_q_xor; polys.toy_q_xor_table[i] = rows[i].toy_q_xor_table; + polys.toy_q_err[i] = rows[i].toy_q_err; + polys.toy_q_err_check[i] = rows[i].toy_q_err_check; + polys.toy_clk[i] = rows[i].toy_clk; + polys.toy_m_clk[i] = rows[i].toy_m_clk; polys.two_column_perm[i] = rows[i].two_column_perm; + polys.two_column_sparse_perm[i] = rows[i].two_column_sparse_perm; polys.lookup_xor[i] = rows[i].lookup_xor; + polys.lookup_err[i] = rows[i].lookup_err; polys.lookup_xor_counts[i] = rows[i].lookup_xor_counts; + polys.lookup_err_counts[i] = rows[i].lookup_err_counts; } return polys; @@ -162,9 +186,16 @@ class ToyCircuitBuilder { if (!evaluate_logderivative.template operator()>("two_column_perm")) { return false; } + if (!evaluate_logderivative.template operator()>( + "two_column_sparse_perm")) { + return false; + } if (!evaluate_logderivative.template operator()>("lookup_xor")) { return false; } + if (!evaluate_logderivative.template operator()>("lookup_err")) { + return false; + } return true; } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp index e20bbaf3a2f..4e1a77810af 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp @@ -115,3 +115,100 @@ TEST(ToyAVMCircuitBuilder, BaseCase) circuit_builder.rows[2].toy_xor_a = tmp; EXPECT_EQ(circuit_builder.check_circuit(), true); } + +/** + * @brief Investigate circuit builder / proving issue + * + */ +TEST(ToyAVMCircuitBuilder, MultiLookup) +{ + using FF = ToyFlavor::FF; + using Builder = ToyCircuitBuilder; + using Row = Builder::Row; + Builder circuit_builder; + + const size_t circuit_size = 16; + std::vector rows; + // init empty rows + for (size_t i = 0; i < circuit_size; i++) { + Row row{}; + rows.push_back(row); + } + + // LOOKUPS + // Create clk mem access lookup table; + // We only want to turn on the mem write when clk is 1 + Row& row_1 = rows[0]; + row_1.toy_q_err = FF(1); + row_1.toy_clk = FF(1); + // Below we lookup two occurances, so our counts is 2 + row_1.lookup_err_counts = FF(2); + + // Set the mem read on two different rows, we will then lookup into the clk + row_1.toy_m_clk = FF(1); + row_1.toy_q_err_check = FF(1); + + Row& row_3 = rows[2]; + row_3.toy_m_clk = FF(1); + row_3.toy_q_err_check = FF(1); + + // Check circuit passes + circuit_builder.set_trace(std::move(rows)); + EXPECT_EQ(circuit_builder.check_circuit(), true); + + // Turn off row_3 lookup selector, expect failure + circuit_builder.rows[2].toy_m_clk = FF(0); + EXPECT_EQ(circuit_builder.check_circuit(), false); +} + +TEST(ToyAVMCircuitBuilder, EmptyLookups) +{ + using Builder = ToyCircuitBuilder; + using Row = Builder::Row; + Builder circuit_builder; + + const size_t circuit_size = 16; + std::vector rows; + // init empty rows + for (size_t i = 0; i < circuit_size; i++) { + Row row{}; + rows.push_back(row); + } + + circuit_builder.set_trace(std::move(rows)); + EXPECT_EQ(circuit_builder.check_circuit(), true); +} + +TEST(ToyAVMCircuitBuilder, SparsePermutation) +{ + // Test sparse permutation, where the permutation check is not active on all rows + using FF = ToyFlavor::FF; + using Builder = ToyCircuitBuilder; + using Row = Builder::Row; + Builder circuit_builder; + + const size_t circuit_size = 16; + std::vector rows; + // init empty rows + for (size_t i = 0; i < circuit_size; i++) { + Row row{}; + rows.push_back(row); + } + + // Activate lhs on row 1 + Row& row_1 = rows[0]; + row_1.toy_sparse_lhs = FF(1); + row_1.toy_sparse_column_1 = FF(420); + + // Activate rhs on row 5 + Row& row_5 = rows[4]; + row_5.toy_sparse_rhs = FF(1); + row_5.toy_sparse_column_2 = FF(420); + + circuit_builder.set_trace(std::move(rows)); + EXPECT_EQ(circuit_builder.check_circuit(), true); + + // Expect it to break after changing row5 + circuit_builder.rows[4].toy_sparse_column_2 = FF(421); + EXPECT_EQ(circuit_builder.check_circuit(), false); +} \ No newline at end of file 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 f46c80ce482..6257ec4d063 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,41 +7,41 @@ namespace bb::Avm_vm { template struct Avm_aluRow { - FF avm_alu_alu_u64_tag{}; - FF avm_alu_alu_ic{}; - FF avm_alu_alu_ia{}; - FF avm_alu_alu_ff_tag{}; - FF avm_alu_alu_u128_tag{}; FF avm_alu_alu_u16_tag{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u8_tag{}; - FF avm_alu_alu_u16_r0{}; - FF avm_alu_alu_op_sub{}; - FF avm_alu_alu_op_add{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u64_r0{}; + FF avm_alu_alu_u16_r6{}; + FF avm_alu_alu_ia{}; + FF avm_alu_alu_ib{}; FF avm_alu_alu_u16_r7{}; + FF avm_alu_alu_u64_tag{}; + FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_u8_r1{}; + FF avm_alu_alu_op_eq_diff_inv{}; + FF avm_alu_alu_u16_r3{}; + FF avm_alu_alu_op_add{}; + FF avm_alu_alu_op_not{}; + FF avm_alu_alu_ff_tag{}; FF avm_alu_alu_u8_r0{}; FF avm_alu_alu_u16_r2{}; + FF avm_alu_alu_u8_tag{}; + FF avm_alu_alu_u16_r1{}; + FF avm_alu_alu_u128_tag{}; FF avm_alu_alu_op_eq{}; FF avm_alu_alu_u16_r4{}; - FF avm_alu_alu_op_eq_diff_inv{}; - FF avm_alu_alu_ib{}; - FF avm_alu_alu_u16_r1{}; - FF avm_alu_alu_u8_r1{}; - FF avm_alu_alu_op_mul{}; - FF avm_alu_alu_u16_r6{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_op_not{}; - FF avm_alu_alu_u16_r5{}; - FF avm_alu_alu_cf{}; + FF avm_alu_alu_u16_r0{}; FF avm_alu_alu_u16_r1_shift{}; FF avm_alu_alu_u32_tag{}; - FF avm_alu_alu_u16_r3{}; + FF avm_alu_alu_op_sub{}; FF avm_alu_alu_u16_r5_shift{}; + FF avm_alu_alu_u16_r5{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_cf{}; + FF avm_alu_alu_u16_r6_shift{}; FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r3_shift{}; + FF avm_alu_alu_op_mul{}; + FF avm_alu_alu_ic{}; + FF avm_alu_alu_u64_r0{}; }; inline std::string get_relation_label_avm_alu(int index) @@ -53,29 +53,29 @@ inline std::string get_relation_label_avm_alu(int index) case 7: return "ALU_ADD_SUB_2"; - case 10: - return "ALU_MUL_COMMON_2"; - - case 14: - return "ALU_FF_NOT_XOR"; - - case 9: - return "ALU_MUL_COMMON_1"; + case 16: + return "ALU_RES_IS_BOOL"; case 13: return "ALU_MULTIPLICATION_OUT_U128"; - case 8: - return "ALU_MULTIPLICATION_FF"; - - case 16: - return "ALU_RES_IS_BOOL"; - case 17: return "ALU_OP_EQ"; + case 14: + return "ALU_FF_NOT_XOR"; + case 6: return "ALU_ADD_SUB_1"; + + case 8: + return "ALU_MULTIPLICATION_FF"; + + case 10: + return "ALU_MUL_COMMON_2"; + + case 9: + return "ALU_MUL_COMMON_1"; } return std::to_string(index); } 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 40aef030283..1d93cbd92be 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_op_err{}; - FF avm_main_tag_err{}; - FF avm_main_sel_op_mul{}; - FF avm_main_mem_op_a{}; - FF avm_main_mem_idx_a{}; - FF avm_main_first{}; - FF avm_main_sel_jump{}; - FF avm_main_sel_internal_return{}; - FF avm_main_rwa{}; - FF avm_main_mem_op_c{}; - FF avm_main_rwc{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_inv{}; + FF avm_main_sel_op_eq{}; FF avm_main_rwb{}; FF avm_main_mem_idx_b{}; - FF avm_main_sel_op_sub{}; - FF avm_main_sel_halt{}; + FF avm_main_sel_internal_call{}; + FF avm_main_pc_shift{}; + FF avm_main_rwa{}; + FF avm_main_mem_op_b{}; + FF avm_main_mem_idx_a{}; + FF avm_main_inv{}; FF avm_main_ia{}; - FF avm_main_sel_op_div{}; - FF avm_main_pc{}; - FF avm_main_ib{}; - FF avm_main_sel_op_not{}; + FF avm_main_mem_op_a{}; + FF avm_main_rwc{}; + FF avm_main_tag_err{}; + FF avm_main_sel_op_sub{}; FF avm_main_internal_return_ptr{}; + FF avm_main_sel_internal_return{}; FF avm_main_sel_op_add{}; - FF avm_main_mem_op_b{}; + FF avm_main_sel_op_mul{}; + FF avm_main_sel_halt{}; + FF avm_main_mem_op_c{}; + FF avm_main_sel_jump{}; + FF avm_main_ib{}; FF avm_main_ic{}; - FF avm_main_sel_op_eq{}; - FF avm_main_sel_internal_call{}; - FF avm_main_pc_shift{}; + FF avm_main_pc{}; + FF avm_main_sel_op_div{}; + FF avm_main_op_err{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_sel_op_not{}; + FF avm_main_first{}; }; inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 21: - return "SUBOP_DIVISION_FF"; - - case 38: - return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 32: return "RETURN_POINTER_DECREMENT"; - case 23: - return "SUBOP_DIVISION_ZERO_ERR2"; - - case 26: - return "RETURN_POINTER_INCREMENT"; + case 22: + return "SUBOP_DIVISION_ZERO_ERR1"; case 37: return "PC_INCREMENT"; - case 22: - return "SUBOP_DIVISION_ZERO_ERR1"; - case 24: return "SUBOP_ERROR_RELEVANT_OP"; + + case 21: + return "SUBOP_DIVISION_FF"; + + case 23: + return "SUBOP_DIVISION_ZERO_ERR2"; + + case 38: + return "INTERNAL_RETURN_POINTER_CONSISTENCY"; + + case 26: + return "RETURN_POINTER_INCREMENT"; } 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 fe909be0a47..d3eea73c93c 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -8,18 +8,18 @@ namespace bb::Avm_vm { template struct Avm_memRow { FF avm_mem_m_rw_shift{}; + FF avm_mem_m_tag{}; + FF avm_mem_m_tag_err{}; + FF avm_mem_m_addr_shift{}; + FF avm_mem_m_addr{}; + FF avm_mem_m_one_min_inv{}; + FF avm_mem_m_lastAccess{}; FF avm_mem_m_rw{}; - FF avm_mem_m_val{}; - FF avm_mem_m_tag_shift{}; FF avm_mem_m_val_shift{}; - FF avm_mem_m_tag{}; FF avm_mem_m_in_tag{}; + FF avm_mem_m_val{}; + FF avm_mem_m_tag_shift{}; FF avm_mem_m_last{}; - FF avm_mem_m_one_min_inv{}; - FF avm_mem_m_addr_shift{}; - FF avm_mem_m_lastAccess{}; - FF avm_mem_m_tag_err{}; - FF avm_mem_m_addr{}; }; inline std::string get_relation_label_avm_mem(int index) @@ -28,15 +28,15 @@ inline std::string get_relation_label_avm_mem(int index) case 7: return "MEM_ZERO_INIT"; + case 9: + return "MEM_IN_TAG_CONSISTENCY_2"; + case 4: return "MEM_LAST_ACCESS_DELIMITER"; case 8: return "MEM_IN_TAG_CONSISTENCY_1"; - case 9: - return "MEM_IN_TAG_CONSISTENCY_2"; - case 6: return "MEM_READ_WRITE_TAG_CONSISTENCY"; 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 d16fe0b41e1..8ac2f57eef6 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,19 @@ [[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 equiv_tag_err = View(new_term.equiv_tag_err); \ + [[maybe_unused]] auto equiv_tag_err_counts = View(new_term.equiv_tag_err_counts); \ [[maybe_unused]] auto avm_mem_m_rw_shift = View(new_term.avm_mem_m_rw_shift); \ - [[maybe_unused]] auto avm_mem_m_tag_shift = View(new_term.avm_mem_m_tag_shift); \ - [[maybe_unused]] auto avm_mem_m_val_shift = View(new_term.avm_mem_m_val_shift); \ [[maybe_unused]] auto avm_mem_m_addr_shift = View(new_term.avm_mem_m_addr_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_alu_alu_u16_r6_shift = View(new_term.avm_alu_alu_u16_r6_shift); \ - [[maybe_unused]] auto avm_alu_alu_u16_r0_shift = View(new_term.avm_alu_alu_u16_r0_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); \ [[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_r7_shift = View(new_term.avm_alu_alu_u16_r7_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_r1_shift = View(new_term.avm_alu_alu_u16_r1_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_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_r7_shift = View(new_term.avm_alu_alu_u16_r7_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_r4_shift = View(new_term.avm_alu_alu_u16_r4_shift); \ + [[maybe_unused]] auto avm_alu_alu_u16_r3_shift = View(new_term.avm_alu_alu_u16_r3_shift); \ + [[maybe_unused]] auto avm_main_pc_shift = View(new_term.avm_main_pc_shift); \ + [[maybe_unused]] auto avm_main_internal_return_ptr_shift = View(new_term.avm_main_internal_return_ptr_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/equiv_tag_err.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/equiv_tag_err.hpp new file mode 100644 index 00000000000..858ecfafa09 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/equiv_tag_err.hpp @@ -0,0 +1,166 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class equiv_tag_err_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 2; + + /** + * @brief The degree of the read term if implemented arbitrarily. This value is not used by basic and scaled read + * terms, but will cause compilation error if not defined + * + */ + static constexpr size_t READ_TERM_DEGREE = 0; + + /** + * @brief The degree of the write term if implemented arbitrarily. This value is not used by the basic write + * term, but will cause compilation error if not defined + * + */ + + static constexpr size_t WRITE_TERM_DEGREE = 0; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial exists at this index. + * Otherwise the value needs to be set to zero. + * + * @details If this is true then the lookup takes place in this row + * + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.avm_mem_m_tag_err == 1 || in.avm_main_tag_err == 1); + } + + /** + * @brief Subprocedure for computing the value deciding if the inverse polynomial value needs to be checked in this + * row + * + * @tparam Accumulator Type specified by the lookup relation + * @tparam AllEntities Values/Univariates of all entities row + * @param in Value/Univariate of all entities at row/edge + * @return Accumulator + */ + + template + static inline auto compute_inverse_exists(const AllEntities& in) + { + using View = typename Accumulator::View; + const auto is_operation = View(in.avm_mem_m_tag_err); + const auto is_table_entry = View(in.avm_main_tag_err); + return (is_operation + is_table_entry - is_operation * is_table_entry); + } + + /** + * @brief Get all the entities for the lookup when need to update them + * + * @details The generic structure of this tuple is described in ./generic_lookup_relation.hpp . The following is + description for the current case: + The entities are returned as a tuple of references in the following order (this is for ): + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that specifies how many times the lookup table entry at this row has been looked up + * - READ_TERMS entities/polynomials that enable individual lookup operations + * - The entity/polynomial that enables adding an entry to the lookup table in this row + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the basic tuple being looked up as the first read term + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the previous accumulators in the second read term + (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the shifts in the second read term (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the current accumulators in the second read term + (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing basic tuples added to the table + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple(in.equiv_tag_err, + in.equiv_tag_err_counts, + in.avm_mem_m_tag_err, + in.avm_main_tag_err, + in.avm_mem_m_clk, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.equiv_tag_err, + in.equiv_tag_err_counts, + in.avm_mem_m_tag_err, + in.avm_main_tag_err, + in.avm_mem_m_clk, + in.avm_main_clk); + } +}; + +template using equiv_tag_err_relation = GenericLookupRelation; +template using equiv_tag_err = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/toy/declare_views.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/toy/declare_views.hpp index 98e120768ea..5b09589e950 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/toy/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/toy/declare_views.hpp @@ -8,6 +8,10 @@ [[maybe_unused]] auto toy_set_1_column_2 = View(new_term.toy_set_1_column_2); \ [[maybe_unused]] auto toy_set_2_column_1 = View(new_term.toy_set_2_column_1); \ [[maybe_unused]] auto toy_set_2_column_2 = View(new_term.toy_set_2_column_2); \ + [[maybe_unused]] auto toy_sparse_column_1 = View(new_term.toy_sparse_column_1); \ + [[maybe_unused]] auto toy_sparse_column_2 = View(new_term.toy_sparse_column_2); \ + [[maybe_unused]] auto toy_sparse_lhs = View(new_term.toy_sparse_lhs); \ + [[maybe_unused]] auto toy_sparse_rhs = View(new_term.toy_sparse_rhs); \ [[maybe_unused]] auto toy_xor_a = View(new_term.toy_xor_a); \ [[maybe_unused]] auto toy_xor_b = View(new_term.toy_xor_b); \ [[maybe_unused]] auto toy_xor_c = View(new_term.toy_xor_c); \ @@ -16,6 +20,13 @@ [[maybe_unused]] auto toy_table_xor_c = View(new_term.toy_table_xor_c); \ [[maybe_unused]] auto toy_q_xor = View(new_term.toy_q_xor); \ [[maybe_unused]] auto toy_q_xor_table = View(new_term.toy_q_xor_table); \ + [[maybe_unused]] auto toy_q_err = View(new_term.toy_q_err); \ + [[maybe_unused]] auto toy_q_err_check = View(new_term.toy_q_err_check); \ + [[maybe_unused]] auto toy_clk = View(new_term.toy_clk); \ + [[maybe_unused]] auto toy_m_clk = View(new_term.toy_m_clk); \ [[maybe_unused]] auto two_column_perm = View(new_term.two_column_perm); \ + [[maybe_unused]] auto two_column_sparse_perm = View(new_term.two_column_sparse_perm); \ [[maybe_unused]] auto lookup_xor = View(new_term.lookup_xor); \ - [[maybe_unused]] auto lookup_xor_counts = View(new_term.lookup_xor_counts); + [[maybe_unused]] auto lookup_err = View(new_term.lookup_err); \ + [[maybe_unused]] auto lookup_xor_counts = View(new_term.lookup_xor_counts); \ + [[maybe_unused]] auto lookup_err_counts = View(new_term.lookup_err_counts); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/toy/lookup_err.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/toy/lookup_err.hpp new file mode 100644 index 00000000000..3cbb30d718f --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/toy/lookup_err.hpp @@ -0,0 +1,158 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_err_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 2; + + /** + * @brief The degree of the read term if implemented arbitrarily. This value is not used by basic and scaled read + * terms, but will cause compilation error if not defined + * + */ + static constexpr size_t READ_TERM_DEGREE = 0; + + /** + * @brief The degree of the write term if implemented arbitrarily. This value is not used by the basic write + * term, but will cause compilation error if not defined + * + */ + + static constexpr size_t WRITE_TERM_DEGREE = 0; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial exists at this index. + * Otherwise the value needs to be set to zero. + * + * @details If this is true then the lookup takes place in this row + * + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.toy_q_err_check == 1 || in.toy_q_err == 1); + } + + /** + * @brief Subprocedure for computing the value deciding if the inverse polynomial value needs to be checked in this + * row + * + * @tparam Accumulator Type specified by the lookup relation + * @tparam AllEntities Values/Univariates of all entities row + * @param in Value/Univariate of all entities at row/edge + * @return Accumulator + */ + + template + static inline auto compute_inverse_exists(const AllEntities& in) + { + using View = typename Accumulator::View; + const auto is_operation = View(in.toy_q_err_check); + const auto is_table_entry = View(in.toy_q_err); + return (is_operation + is_table_entry - is_operation * is_table_entry); + } + + /** + * @brief Get all the entities for the lookup when need to update them + * + * @details The generic structure of this tuple is described in ./generic_lookup_relation.hpp . The following is + description for the current case: + The entities are returned as a tuple of references in the following order (this is for ): + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that specifies how many times the lookup table entry at this row has been looked up + * - READ_TERMS entities/polynomials that enable individual lookup operations + * - The entity/polynomial that enables adding an entry to the lookup table in this row + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the basic tuple being looked up as the first read term + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the previous accumulators in the second read term + (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the shifts in the second read term (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the current accumulators in the second read term + (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing basic tuples added to the table + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple( + in.lookup_err, in.lookup_err_counts, in.toy_q_err_check, in.toy_q_err, in.toy_m_clk, in.toy_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple( + in.lookup_err, in.lookup_err_counts, in.toy_q_err_check, in.toy_q_err, in.toy_m_clk, in.toy_clk); + } +}; + +template using lookup_err_relation = GenericLookupRelation; +template using lookup_err = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/toy/two_column_perm.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/toy/two_column_perm.hpp index c9eb36311cb..5b6220e7f50 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/toy/two_column_perm.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/toy/two_column_perm.hpp @@ -23,7 +23,7 @@ class two_column_perm_permutation_settings { template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) { - return (in.toy_q_tuple_set == 1); + return (in.toy_q_tuple_set == 1 || in.toy_q_tuple_set == 1); } /** diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/toy/two_column_sparse_perm.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/toy/two_column_sparse_perm.hpp new file mode 100644 index 00000000000..4ba979b2529 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/toy/two_column_sparse_perm.hpp @@ -0,0 +1,91 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class two_column_sparse_perm_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 1; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the + * value needs to be set to zero. + * + * @details If this is true then permutation takes place in this row + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.toy_sparse_lhs == 1 || in.toy_sparse_rhs == 1); + } + + /** + * @brief Get all the entities for the permutation when we don't need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple(in.two_column_sparse_perm, + in.toy_sparse_lhs, + in.toy_sparse_lhs, + in.toy_sparse_rhs, + in.toy_sparse_column_1, + in.toy_sparse_column_2); + } + + /** + * @brief Get all the entities for the permutation when need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.two_column_sparse_perm, + in.toy_sparse_lhs, + in.toy_sparse_lhs, + in.toy_sparse_rhs, + in.toy_sparse_column_1, + in.toy_sparse_column_2); + } +}; + +template +using two_column_sparse_perm_relation = GenericPermutationRelation; +template +using two_column_sparse_perm = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp index 084132abfa3..a34290e7544 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp @@ -81,6 +81,7 @@ template class GenericPermutationRelationImpl /** * @brief Get selector/wire switching on(1) or off(0) inverse computation + * We turn it on if either of the permutation contribution selectors are active * */ template @@ -88,9 +89,16 @@ template class GenericPermutationRelationImpl { using View = typename Accumulator::View; - // WIRE/SELECTOR enabling the permutation used in the sumcheck computation. This affects the first subrelation - return Accumulator( - View(std::get(Settings::get_const_entities(in)))); + // WIRE/SELECTOR enabling the permutation used in the sumcheck computation. This affects the first + // subrelation + Accumulator const& first_set_enabled = Accumulator( + View(std::get(Settings::get_const_entities(in)))); + + Accumulator const& second_set_enabled = Accumulator( + View(std::get(Settings::get_const_entities(in)))); + + // This has the truth table of a logical OR + return (first_set_enabled + second_set_enabled - (first_set_enabled * second_set_enabled)); } /** diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.cpp index 0d9f8495983..b0746af1d29 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.cpp @@ -1,4 +1,5 @@ #include "avm_mem_trace.hpp" +#include "barretenberg/vm/avm_trace/avm_common.hpp" namespace avm_trace { @@ -84,6 +85,10 @@ void AvmMemTraceBuilder::load_mismatch_tag_in_mem_trace(uint32_t const m_clk, AvmMemoryTag const m_tag) { FF one_min_inv = FF(1) - (FF(static_cast(m_in_tag)) - FF(static_cast(m_tag))).invert(); + + // Lookup counter hint, used for #[equiv_tag_err] lookup (joined on clk) + m_tag_err_lookup_counts[m_clk]++; + mem_trace.emplace_back(MemoryTraceEntry{ .m_clk = m_clk, .m_sub_clk = m_sub_clk, .m_addr = m_addr, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.hpp index 404c0ce7dc3..43adab419ea 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.hpp @@ -15,6 +15,10 @@ class AvmMemTraceBuilder { static const uint32_t SUB_CLK_STORE_B = 4; static const uint32_t SUB_CLK_STORE_C = 5; + // Keeps track of the number of times a mem tag err should appear in the trace + // clk -> count + std::map m_tag_err_lookup_counts; + struct MemoryTraceEntry { uint32_t m_clk{}; uint32_t m_sub_clk{}; 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 0de230ff0de..80d92bc98f8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -578,6 +578,20 @@ void AvmTraceBuilder::internal_return() internal_return_ptr--; } +// Finalise Lookup Counts +// +// For log derivative lookups, we require a column that contains the number of times each lookup is consumed +// As we build the trace, we keep track of the reads made in a mapping, so that they can be applied to the +// counts column here +// +// NOTE: its coupled to pil - this is not the final iteration +void AvmTraceBuilder::finalise_mem_trace_lookup_counts(std::map const& tag_err_lookup_counts) +{ + for (auto const& [clk, count] : tag_err_lookup_counts) { + main_trace.at(clk).equiv_tag_err_counts = count; + } +} + /** * @brief Finalisation of the memory trace and incorporating it to the main trace. * In particular, sorting the memory trace, setting .m_lastAccess and @@ -594,6 +608,9 @@ std::vector AvmTraceBuilder::finalize() size_t main_trace_size = main_trace.size(); size_t alu_trace_size = alu_trace.size(); + // Get tag_err counts from the mem_trace_builder + this->finalise_mem_trace_lookup_counts(mem_trace_builder.m_tag_err_lookup_counts); + // TODO: We will have to handle this through error handling and not an assertion // Smaller than N because we have to add an extra initial row to support shifted // elements diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp index d205c98214d..d1d354aee06 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -78,6 +78,8 @@ class AvmTraceBuilder { AvmMemTraceBuilder mem_trace_builder; AvmAluTraceBuilder alu_trace_builder; + void finalise_mem_trace_lookup_counts(std::map const& tag_err_lookup_counts); + uint32_t pc = 0; uint32_t internal_return_ptr = CALLSTACK_OFFSET; std::stack internal_call_stack = {}; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 6229a31ad1b..7334d0af652 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -170,6 +170,9 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) commitments.avm_main_mem_idx_c = transcript->template receive_from_prover(commitment_labels.avm_main_mem_idx_c); commitments.avm_main_last = transcript->template receive_from_prover(commitment_labels.avm_main_last); + commitments.equiv_tag_err = transcript->template receive_from_prover(commitment_labels.equiv_tag_err); + commitments.equiv_tag_err_counts = + transcript->template receive_from_prover(commitment_labels.equiv_tag_err_counts); // Execute Sumcheck Verifier const size_t log_circuit_size = numeric::get_msb(circuit_size); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/toy_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/toy_verifier.cpp index 43ae568ea6d..f30cd4207e4 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/toy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/toy_verifier.cpp @@ -61,6 +61,12 @@ bool ToyVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.toy_set_2_column_1); commitments.toy_set_2_column_2 = transcript->template receive_from_prover(commitment_labels.toy_set_2_column_2); + commitments.toy_sparse_column_1 = + transcript->template receive_from_prover(commitment_labels.toy_sparse_column_1); + commitments.toy_sparse_column_2 = + transcript->template receive_from_prover(commitment_labels.toy_sparse_column_2); + commitments.toy_sparse_lhs = transcript->template receive_from_prover(commitment_labels.toy_sparse_lhs); + commitments.toy_sparse_rhs = transcript->template receive_from_prover(commitment_labels.toy_sparse_rhs); commitments.toy_xor_a = transcript->template receive_from_prover(commitment_labels.toy_xor_a); commitments.toy_xor_b = transcript->template receive_from_prover(commitment_labels.toy_xor_b); commitments.toy_xor_c = transcript->template receive_from_prover(commitment_labels.toy_xor_c); @@ -73,11 +79,21 @@ bool ToyVerifier::verify_proof(const HonkProof& proof) commitments.toy_q_xor = transcript->template receive_from_prover(commitment_labels.toy_q_xor); commitments.toy_q_xor_table = transcript->template receive_from_prover(commitment_labels.toy_q_xor_table); + commitments.toy_q_err = transcript->template receive_from_prover(commitment_labels.toy_q_err); + commitments.toy_q_err_check = + transcript->template receive_from_prover(commitment_labels.toy_q_err_check); + commitments.toy_clk = transcript->template receive_from_prover(commitment_labels.toy_clk); + commitments.toy_m_clk = transcript->template receive_from_prover(commitment_labels.toy_m_clk); commitments.two_column_perm = transcript->template receive_from_prover(commitment_labels.two_column_perm); + commitments.two_column_sparse_perm = + transcript->template receive_from_prover(commitment_labels.two_column_sparse_perm); commitments.lookup_xor = transcript->template receive_from_prover(commitment_labels.lookup_xor); + commitments.lookup_err = transcript->template receive_from_prover(commitment_labels.lookup_err); commitments.lookup_xor_counts = transcript->template receive_from_prover(commitment_labels.lookup_xor_counts); + commitments.lookup_err_counts = + transcript->template receive_from_prover(commitment_labels.lookup_err_counts); // Execute Sumcheck Verifier const size_t log_circuit_size = numeric::get_msb(circuit_size); 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 71178fbf277..2f4d24a261f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp @@ -1,6 +1,7 @@ #include "avm_common.test.hpp" #include "barretenberg/numeric/uint128/uint128.hpp" +#include "barretenberg/vm/avm_trace/avm_helper.hpp" using namespace bb; using namespace bb::numeric; @@ -545,7 +546,7 @@ TEST_F(AvmArithmeticTestsU8, addition) // Memory layout: [62,29,0,0,0,....] trace_builder.op_add(0, 1, 2, AvmMemoryTag::U8); // [62,29,91,0,0,....] - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_add(trace, FF(62), FF(29), FF(91), FF(0), FF(1), FF(2), AvmMemoryTag::U8); @@ -553,6 +554,7 @@ TEST_F(AvmArithmeticTestsU8, addition) EXPECT_EQ(alu_row.avm_alu_alu_u8_tag, FF(1)); EXPECT_EQ(alu_row.avm_alu_alu_cf, FF(0)); EXPECT_EQ(alu_row.avm_alu_alu_u8_r0, FF(91)); + validate_trace_proof(std::move(trace)); } @@ -565,7 +567,7 @@ TEST_F(AvmArithmeticTestsU8, additionCarry) // Memory layout: [159,100,0,0,0,....] trace_builder.op_add(0, 1, 2, AvmMemoryTag::U8); // [159,100,3,0,0,....] - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_add(trace, FF(159), FF(100), FF(3), FF(0), FF(1), FF(2), AvmMemoryTag::U8); @@ -587,7 +589,7 @@ TEST_F(AvmArithmeticTestsU8, subtraction) // Memory layout: [162,29,0,0,0,....] trace_builder.op_sub(0, 1, 2, AvmMemoryTag::U8); // [162,29,133,0,0,....] - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_sub(trace, FF(162), FF(29), FF(133), FF(0), FF(1), FF(2), AvmMemoryTag::U8); @@ -609,7 +611,7 @@ TEST_F(AvmArithmeticTestsU8, subtractionCarry) // Memory layout: [5,29,0,0,0,....] trace_builder.op_sub(0, 1, 2, AvmMemoryTag::U8); // [5,29,232,0,0,....] - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_sub(trace, FF(5), FF(29), FF(232), FF(0), FF(1), FF(2), AvmMemoryTag::U8); @@ -637,7 +639,7 @@ TEST_F(AvmArithmeticTestsU8, multiplication) trace_builder.set(15, 1, AvmMemoryTag::U8); trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U8); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = common_validate_mul(trace, FF(13), FF(15), FF(195), FF(0), FF(1), FF(2), AvmMemoryTag::U8); @@ -660,7 +662,7 @@ TEST_F(AvmArithmeticTestsU8, multiplicationOverflow) trace_builder.set(170, 1, AvmMemoryTag::U8); trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U8); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = common_validate_mul(trace, FF(200), FF(170), FF(208), FF(0), FF(1), FF(2), AvmMemoryTag::U8); @@ -722,7 +724,7 @@ TEST_F(AvmArithmeticTestsU16, addition) trace_builder.set(33005, 546, AvmMemoryTag::U16); trace_builder.op_add(546, 119, 5, AvmMemoryTag::U16); - trace_builder.return_op(5, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = @@ -744,7 +746,7 @@ TEST_F(AvmArithmeticTestsU16, additionCarry) trace_builder.set(1000, 1, AvmMemoryTag::U16); trace_builder.op_add(1, 0, 0, AvmMemoryTag::U16); - trace_builder.return_op(0, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = @@ -766,7 +768,7 @@ TEST_F(AvmArithmeticTestsU16, subtraction) trace_builder.set(33005, 546, AvmMemoryTag::U16); trace_builder.op_sub(546, 119, 5, AvmMemoryTag::U16); - trace_builder.return_op(5, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = @@ -790,7 +792,7 @@ TEST_F(AvmArithmeticTestsU16, subtractionCarry) trace_builder.set(1000, 1, AvmMemoryTag::U16); trace_builder.op_sub(1, 0, 0, AvmMemoryTag::U16); - trace_builder.return_op(0, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = @@ -819,7 +821,7 @@ TEST_F(AvmArithmeticTestsU16, multiplication) trace_builder.set(245, 1, AvmMemoryTag::U16); trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U16); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = @@ -844,7 +846,7 @@ TEST_F(AvmArithmeticTestsU16, multiplicationOverflow) trace_builder.set(1024, 1, AvmMemoryTag::U16); trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U16); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = common_validate_mul(trace, FF(512), FF(1024), FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::U16); @@ -908,7 +910,7 @@ TEST_F(AvmArithmeticTestsU32, addition) trace_builder.set(1234567891, 9, AvmMemoryTag::U32); trace_builder.op_add(8, 9, 0, AvmMemoryTag::U32); - trace_builder.return_op(0, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_add( @@ -931,7 +933,7 @@ TEST_F(AvmArithmeticTestsU32, additionCarry) trace_builder.set(2293, 9, AvmMemoryTag::U32); trace_builder.op_add(8, 9, 0, AvmMemoryTag::U32); - trace_builder.return_op(0, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = @@ -953,7 +955,7 @@ TEST_F(AvmArithmeticTestsU32, subtraction) trace_builder.set(1234567891, 9, AvmMemoryTag::U32); trace_builder.op_sub(8, 9, 0, AvmMemoryTag::U32); - trace_builder.return_op(0, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_sub( @@ -980,7 +982,7 @@ TEST_F(AvmArithmeticTestsU32, subtractionCarry) trace_builder.set(3210987654, 9, AvmMemoryTag::U32); trace_builder.op_sub(9, 8, 0, AvmMemoryTag::U32); - trace_builder.return_op(0, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_sub( @@ -1011,7 +1013,7 @@ TEST_F(AvmArithmeticTestsU32, multiplication) trace_builder.set(11111, 1, AvmMemoryTag::U32); trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U32); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = @@ -1040,7 +1042,7 @@ TEST_F(AvmArithmeticTestsU32, multiplicationOverflow) trace_builder.set(13 << 22, 1, AvmMemoryTag::U32); trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U32); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = @@ -1113,7 +1115,7 @@ TEST_F(AvmArithmeticTestsU64, addition) trace_builder.set(b, 9, AvmMemoryTag::U64); trace_builder.op_add(8, 9, 9, AvmMemoryTag::U64); - trace_builder.return_op(9, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_add(trace, FF(a), FF(b), FF(c), FF(8), FF(9), FF(9), AvmMemoryTag::U64); @@ -1143,7 +1145,7 @@ TEST_F(AvmArithmeticTestsU64, additionCarry) trace_builder.set(b, 1, AvmMemoryTag::U64); trace_builder.op_add(0, 1, 0, AvmMemoryTag::U64); - trace_builder.return_op(0, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_add(trace, FF(a), FF(b), FF(c), FF(0), FF(1), FF(0), AvmMemoryTag::U64); @@ -1171,7 +1173,7 @@ TEST_F(AvmArithmeticTestsU64, subtraction) trace_builder.set(b, 9, AvmMemoryTag::U64); trace_builder.op_sub(8, 9, 9, AvmMemoryTag::U64); - trace_builder.return_op(9, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_sub(trace, FF(a), FF(b), FF(c), FF(8), FF(9), FF(9), AvmMemoryTag::U64); @@ -1203,7 +1205,7 @@ TEST_F(AvmArithmeticTestsU64, subtractionCarry) trace_builder.set(b, 1, AvmMemoryTag::U64); trace_builder.op_sub(0, 1, 0, AvmMemoryTag::U64); - trace_builder.return_op(0, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_sub(trace, FF(a), FF(b), FF(c), FF(0), FF(1), FF(0), AvmMemoryTag::U64); @@ -1231,7 +1233,7 @@ TEST_F(AvmArithmeticTestsU64, multiplication) trace_builder.set(555444333, 1, AvmMemoryTag::U64); trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U64); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = common_validate_mul( @@ -1264,7 +1266,7 @@ TEST_F(AvmArithmeticTestsU64, multiplicationOverflow) trace_builder.set(b, 1, AvmMemoryTag::U64); trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U64); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = common_validate_mul(trace, FF(a), FF(b), FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::U64); @@ -1338,7 +1340,7 @@ TEST_F(AvmArithmeticTestsU128, addition) trace_builder.set(b, 9, AvmMemoryTag::U128); trace_builder.op_add(8, 9, 9, AvmMemoryTag::U128); - trace_builder.return_op(9, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_add(trace, @@ -1378,7 +1380,7 @@ TEST_F(AvmArithmeticTestsU128, additionCarry) trace_builder.set(b, 9, AvmMemoryTag::U128); trace_builder.op_add(8, 9, 9, AvmMemoryTag::U128); - trace_builder.return_op(9, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_add(trace, @@ -1417,7 +1419,7 @@ TEST_F(AvmArithmeticTestsU128, subtraction) trace_builder.set(b, 9, AvmMemoryTag::U128); trace_builder.op_sub(8, 9, 9, AvmMemoryTag::U128); - trace_builder.return_op(9, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_sub(trace, @@ -1459,7 +1461,7 @@ TEST_F(AvmArithmeticTestsU128, subtractionCarry) trace_builder.set(b, 9, AvmMemoryTag::U128); trace_builder.op_sub(8, 9, 9, AvmMemoryTag::U128); - trace_builder.return_op(9, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_sub(trace, @@ -1497,7 +1499,7 @@ TEST_F(AvmArithmeticTestsU128, multiplication) FF c{ uint256_t{ 0xA7DDA0BAE60CA3A5, 0x70289AEB0, 0, 0 } }; trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U128); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = common_validate_mul( @@ -1534,7 +1536,7 @@ TEST_F(AvmArithmeticTestsU128, multiplicationOverflow) trace_builder.set(b, 1, AvmMemoryTag::U128); trace_builder.op_mul(0, 1, 2, AvmMemoryTag::U128); - trace_builder.return_op(2, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row_index = common_validate_mul(trace, diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp index 58760e5a6f6..3abc6645219 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -117,7 +117,7 @@ TEST_F(AvmBitwiseTestsU8, BitwiseNot) { trace_builder.set(1, 0, AvmMemoryTag::U8); // Memory Layout: [1,0,0,...] trace_builder.op_not(0, 1, AvmMemoryTag::U8); // [1,254,0,0,....] - trace_builder.return_op(1, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_op_not(trace, FF(1), FF(254), FF(0), FF(1), AvmMemoryTag::U8); @@ -130,7 +130,7 @@ TEST_F(AvmBitwiseTestsU16, BitwiseNot) { trace_builder.set(512, 0, AvmMemoryTag::U16); // Memory Layout: [512,0,0,...] trace_builder.op_not(0, 1, AvmMemoryTag::U16); // [512,65023,0,0,0,....] - trace_builder.return_op(1, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_op_not(trace, FF(512), FF(65'023), FF(0), FF(1), AvmMemoryTag::U16); @@ -143,7 +143,7 @@ TEST_F(AvmBitwiseTestsU32, BitwiseNot) { trace_builder.set(131'072, 0, AvmMemoryTag::U32); // Memory Layout: [131072,0,0,...] trace_builder.op_not(0, 1, AvmMemoryTag::U32); // [131072,4294836223,,0,0,....] - trace_builder.return_op(1, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = common_validate_op_not(trace, FF(131'072), FF(4'294'836'223LLU), FF(0), FF(1), AvmMemoryTag::U32); @@ -156,7 +156,7 @@ TEST_F(AvmBitwiseTestsU64, BitwiseNot) { trace_builder.set(0x100000000LLU, 0, AvmMemoryTag::U64); // Memory Layout: [8589934592,0,0,...] trace_builder.op_not(0, 1, AvmMemoryTag::U64); // [8589934592,18446744069414584319,0,0,....] - trace_builder.return_op(1, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); auto alu_row = @@ -172,7 +172,7 @@ TEST_F(AvmBitwiseTestsU128, BitwiseNot) uint128_t const a = uint128_t{ 0x4000000000000 } << 64; trace_builder.set(a, 0, AvmMemoryTag::U128); trace_builder.op_not(0, 1, AvmMemoryTag::U128); - trace_builder.return_op(1, 1); + trace_builder.return_op(0, 0); auto trace = trace_builder.finalize(); uint128_t const res = (uint128_t{ 0xfffbffffffffffff } << 64) + uint128_t{ 0xffffffffffffffff }; diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp index 9cf2a3b334e..756cc93d6ac 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp @@ -22,6 +22,8 @@ void validate_trace_proof(std::vector&& trace) auto verifier = composer.create_verifier(circuit_builder); bool verified = verifier.verify_proof(proof); + EXPECT_TRUE(verified); + if (!verified) { avm_trace::log_avm_trace(circuit_builder.rows, 0, 10); }