From 72be88de7498cbc9a83ce26c5738337e4b09c0a5 Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Tue, 5 Mar 2024 10:40:03 +0000 Subject: [PATCH 1/8] feat: lookup and/or/xor --- barretenberg/cpp/pil/avm/avm_binary.pil | 73 +++ barretenberg/cpp/pil/avm/avm_byte_lookup.pil | 12 + barretenberg/cpp/pil/avm/avm_main.pil | 35 +- barretenberg/cpp/pil/avm/avm_mem.pil | 2 +- .../generated/avm/INCL_MAIN_TAG_ERR.hpp | 167 +++++++ .../relations/generated/avm/PERM_MAIN_ALU.hpp | 126 +++++ .../generated/avm/PERM_MAIN_MEM_A.hpp | 106 ++++ .../generated/avm/PERM_MAIN_MEM_B.hpp | 106 ++++ .../generated/avm/PERM_MAIN_MEM_C.hpp | 106 ++++ .../relations/generated/avm/avm_alu.hpp | 88 ++-- .../relations/generated/avm/avm_binary.hpp | 146 ++++++ .../relations/generated/avm/avm_main.hpp | 231 +++++---- .../relations/generated/avm/avm_mem.hpp | 46 +- .../relations/generated/avm/declare_views.hpp | 58 ++- .../generated/avm/lookup_byte_lengths.hpp | 171 +++++++ .../generated/avm/lookup_byte_operations.hpp | 179 +++++++ .../relations/generated/avm/perm_main_bin.hpp | 110 +++++ .../vm/avm_trace/avm_binary_trace.cpp | 175 +++++++ .../vm/avm_trace/avm_binary_trace.hpp | 49 ++ .../barretenberg/vm/avm_trace/avm_common.hpp | 3 +- .../barretenberg/vm/avm_trace/avm_helper.cpp | 1 - .../barretenberg/vm/avm_trace/avm_trace.cpp | 194 +++++++- .../barretenberg/vm/avm_trace/avm_trace.hpp | 11 + .../vm/generated/avm_circuit_builder.hpp | 142 +++++- .../barretenberg/vm/generated/avm_flavor.hpp | 424 +++++++++++++--- .../vm/generated/avm_verifier.cpp | 59 +++ .../vm/tests/avm_bitwise.test.cpp | 454 +++++++++++++++--- 27 files changed, 2952 insertions(+), 322 deletions(-) create mode 100644 barretenberg/cpp/pil/avm/avm_binary.pil create mode 100644 barretenberg/cpp/pil/avm/avm_byte_lookup.pil create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/INCL_MAIN_TAG_ERR.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_ALU.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_A.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_B.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_C.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_lengths.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_operations.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp diff --git a/barretenberg/cpp/pil/avm/avm_binary.pil b/barretenberg/cpp/pil/avm/avm_binary.pil new file mode 100644 index 00000000000..f27e906a821 --- /dev/null +++ b/barretenberg/cpp/pil/avm/avm_binary.pil @@ -0,0 +1,73 @@ + +include "avm_byte_lookup.pil"; +include "avm_main.pil"; + +namespace avm_binary(256); + + pol commit bin_clk; + + // Selector for Binary Operation + pol commit bin_sel; + bin_sel * (1 - bin_sel) = 0; + + // The last element in this column is what part of equivalence check to main trace + pol commit acc_ia; + pol commit acc_ib; + pol commit acc_ic; + + // This is the instruction tag {1,2,3,4,5} (restricted to not be a field) + // Operations over FF are not supported, it is assumed this exclusion is handled + // outside of this subtrace. + // Constraints come from equiv to main_trace + pol commit instr_tag; + + // Selectors for binary operations, correctness checked by permutation to the main trace. + pol commit op_id; + + pol commit bin_ia_bytes; + pol commit bin_ib_bytes; + pol commit bin_ic_bytes; + + pol commit latch; //Identifies when we want to capture the output + pol commit factor; // Identifies the byte position when accumulating + + // latch is restricted to be a boolean + latch * (1 - latch) = 0; + + // If latch is 0, the next factor must be the current factor * 256. + pol NO_LATCH = (1 - latch) * (factor * 256); + // If latch is 1 or this is the first row in the trace, then the next factor starts at 1; + latch * avm_main.first = 0; // latch and first cannot both be 1 + + // Given the above condition, LATCH_OR_FIRST is guaranteed to be 0 or 1; + pol LATCH_OR_FIRST = latch + avm_main.first; + + // Both conditions are mutually exclusive, (i.e. "xor" since Factor initially starts at 0). + #[FACTOR_REL] + factor' = (NO_LATCH + LATCH_OR_FIRST) * bin_sel'; + + // To support dynamically sized memory operands we use a counter against a lookup + // This counter goes from [0, MEM_TAG] where MEM_TAG is the number of bytes in the + // corresponding integer. i.e. MEM_TAG is between 1 (U8) and 16(U128). + // Consistency can be achieved with a lookup table between the instr_tag and bytes_length + pol commit mem_tag_ctr; + #[MEM_TAG_REL] + mem_tag_ctr' = (mem_tag_ctr + 1) * (1 - latch) * bin_sel; + + #[LOOKUP_BYTE_LENGTHS] + latch {instr_tag, mem_tag_ctr} + in + avm_byte_lookup.bin_sel {avm_byte_lookup.table_instr_tags, avm_byte_lookup.table_byte_lengths}; + + #[LOOKUP_BYTE_OPERATIONS] + bin_sel {op_id, bin_ia_bytes, bin_ib_bytes, bin_ic_bytes} + in + avm_byte_lookup.bin_sel {avm_byte_lookup.table_op_id, avm_byte_lookup.table_input_a,avm_byte_lookup.table_input_b, avm_byte_lookup.table_output}; + + #[ACC_REL_A] + acc_ia' = (acc_ia * (1 - latch) + bin_ia_bytes * factor) * bin_sel'; + #[ACC_REL_B] + acc_ib' = (acc_ib * (1 - latch) + bin_ib_bytes * factor) * bin_sel'; + #[ACC_REL_C] + acc_ic' = (acc_ic * (1 - latch) + bin_ic_bytes * factor) * bin_sel'; + diff --git a/barretenberg/cpp/pil/avm/avm_byte_lookup.pil b/barretenberg/cpp/pil/avm/avm_byte_lookup.pil new file mode 100644 index 00000000000..8fff072d85f --- /dev/null +++ b/barretenberg/cpp/pil/avm/avm_byte_lookup.pil @@ -0,0 +1,12 @@ + +namespace avm_byte_lookup(256); + // These columns are commited for now, but will be migrated to constant/fixed when + // we support more *exotic* code generation options + pol commit table_op_id; // identifies if operation is AND/OR/XOR + pol commit table_input_a; // column of all 8-bit numbers + pol commit table_input_b; // column of all 8-bit numbers + pol commit table_output; // column of all combinations of AND/OR/XOR + pol commit bin_sel; + + pol commit table_instr_tags; // Column of U8,U16,...,U128 + pol commit table_byte_lengths; // Columns of byte lengths 1,2,...,16; diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index 02b102fa470..43c6ce5982c 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -1,6 +1,7 @@ include "avm_mem.pil"; include "avm_alu.pil"; +include "avm_binary.pil"; namespace avm_main(256); @@ -41,10 +42,19 @@ namespace avm_main(256); pol commit sel_op_not; // EQ pol commit sel_op_eq; + // AND + pol commit sel_op_and; + // OR + pol commit sel_op_or; + // XOR + pol commit sel_op_xor; // Helper selector to characterize an ALU chiplet selector pol commit alu_sel; + // Helper selector to characterize a Binary chiplet selector + pol commit bin_sel; + // Instruction memory tag (1: u8, 2: u16, 3: u32, 4: u64, 5: u128, 6: field) pol commit in_tag; @@ -102,6 +112,9 @@ namespace avm_main(256); sel_op_div * (1 - sel_op_div) = 0; sel_op_not * (1 - sel_op_not) = 0; sel_op_eq * (1 - sel_op_eq) = 0; + sel_op_and * (1 - sel_op_and) = 0; + sel_op_or * (1 - sel_op_or) = 0; + sel_op_xor * (1 - sel_op_xor) = 0; sel_internal_call * (1 - sel_internal_call) = 0; sel_internal_return * (1 - sel_internal_return) = 0; @@ -202,7 +215,7 @@ namespace avm_main(256); //===== CONTROL_FLOW_CONSISTENCY ============================================ pol INTERNAL_CALL_STACK_SELECTORS = (first + sel_internal_call + sel_internal_return + sel_halt); - pol OPCODE_SELECTORS = (sel_op_add + sel_op_sub + sel_op_div + sel_op_mul + sel_op_not + sel_op_eq); + pol OPCODE_SELECTORS = (sel_op_add + sel_op_sub + sel_op_div + sel_op_mul + sel_op_not + sel_op_eq + sel_op_and + sel_op_or + sel_op_xor); // Program counter must increment if not jumping or returning #[PC_INCREMENT] @@ -239,6 +252,24 @@ namespace avm_main(256); avm_alu.alu_op_add, avm_alu.alu_op_sub, avm_alu.alu_op_mul, avm_alu.alu_op_eq, avm_alu.alu_op_not, avm_alu.alu_in_tag}; + + // Based on the boolean selectors, we derive the binary op id to lookup in the table; + // TODO: Check if having 4 columns (op_id + 3 boolean selectors) is more optimal that just using the op_id + // but with a higher degree constraint: op_id * (op_id - 1) * (op_id - 2) + pol commit bin_op_id; + #[BIN_SEL_1] + bin_op_id = sel_op_or + 2 * sel_op_xor; // sel_op_and excluded since op_id = 0 for op_and + + // Only 1 of the binary selectors should be set (i.e. Mutual Exclusivity) + #[BIN_SEL_2] + bin_sel = (sel_op_and + sel_op_or + sel_op_xor); + + #[PERM_MAIN_BIN] + bin_sel {clk, ia, ib, ic, bin_op_id, in_tag} + is + avm_binary.latch {avm_binary.bin_clk, avm_binary.acc_ia, avm_binary.acc_ib, avm_binary.acc_ic, + avm_binary.op_id, avm_binary.instr_tag}; + #[PERM_MAIN_MEM_A] mem_op_a {clk, mem_idx_a, ia, rwa, in_tag, sel_mov} is @@ -267,4 +298,4 @@ namespace avm_main(256); #[PERM_MAIN_MEM_IND_C] ind_op_c {clk, ind_c, mem_idx_c} is - avm_mem.m_ind_op_c {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val}; \ No newline at end of file + avm_mem.m_ind_op_c {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val}; diff --git a/barretenberg/cpp/pil/avm/avm_mem.pil b/barretenberg/cpp/pil/avm/avm_mem.pil index 2f2af729775..f6d995b030e 100644 --- a/barretenberg/cpp/pil/avm/avm_mem.pil +++ b/barretenberg/cpp/pil/avm/avm_mem.pil @@ -147,4 +147,4 @@ namespace avm_mem(256); // Finally, the following constraint guarantees that m_tag is correct for // the output. #[MOV_SAME_TAG] - m_sel_mov * m_tag_err = 0; // Equivalent to m_sel_mov * (m_in_tag - m_tag) = 0 \ No newline at end of file + m_sel_mov * m_tag_err = 0; // Equivalent to m_sel_mov * (m_in_tag - m_tag) = 0 diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/INCL_MAIN_TAG_ERR.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/INCL_MAIN_TAG_ERR.hpp new file mode 100644 index 00000000000..093947b109b --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/INCL_MAIN_TAG_ERR.hpp @@ -0,0 +1,167 @@ + + +#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 INCL_MAIN_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.INCL_MAIN_TAG_ERR, + in.INCL_MAIN_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.INCL_MAIN_TAG_ERR, + in.INCL_MAIN_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 INCL_MAIN_TAG_ERR_relation = GenericLookupRelation; +template using INCL_MAIN_TAG_ERR = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_ALU.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_ALU.hpp new file mode 100644 index 00000000000..a493df59414 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_ALU.hpp @@ -0,0 +1,126 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class PERM_MAIN_ALU_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 10; + + /** + * @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.avm_main_alu_sel == 1 || in.avm_alu_alu_sel == 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.PERM_MAIN_ALU, + in.avm_main_alu_sel, + in.avm_main_alu_sel, + in.avm_alu_alu_sel, + in.avm_main_clk, + in.avm_main_ia, + in.avm_main_ib, + in.avm_main_ic, + in.avm_main_sel_op_add, + in.avm_main_sel_op_sub, + in.avm_main_sel_op_mul, + in.avm_main_sel_op_eq, + in.avm_main_sel_op_not, + in.avm_main_in_tag, + in.avm_alu_alu_clk, + in.avm_alu_alu_ia, + in.avm_alu_alu_ib, + in.avm_alu_alu_ic, + in.avm_alu_alu_op_add, + in.avm_alu_alu_op_sub, + in.avm_alu_alu_op_mul, + in.avm_alu_alu_op_eq, + in.avm_alu_alu_op_not, + in.avm_alu_alu_in_tag); + } + + /** + * @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.PERM_MAIN_ALU, + in.avm_main_alu_sel, + in.avm_main_alu_sel, + in.avm_alu_alu_sel, + in.avm_main_clk, + in.avm_main_ia, + in.avm_main_ib, + in.avm_main_ic, + in.avm_main_sel_op_add, + in.avm_main_sel_op_sub, + in.avm_main_sel_op_mul, + in.avm_main_sel_op_eq, + in.avm_main_sel_op_not, + in.avm_main_in_tag, + in.avm_alu_alu_clk, + in.avm_alu_alu_ia, + in.avm_alu_alu_ib, + in.avm_alu_alu_ic, + in.avm_alu_alu_op_add, + in.avm_alu_alu_op_sub, + in.avm_alu_alu_op_mul, + in.avm_alu_alu_op_eq, + in.avm_alu_alu_op_not, + in.avm_alu_alu_in_tag); + } +}; + +template +using PERM_MAIN_ALU_relation = GenericPermutationRelation; +template using PERM_MAIN_ALU = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_A.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_A.hpp new file mode 100644 index 00000000000..777eb91bfb0 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_A.hpp @@ -0,0 +1,106 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class PERM_MAIN_MEM_A_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 5; + + /** + * @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.avm_main_mem_op_a == 1 || in.avm_mem_m_op_a == 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.PERM_MAIN_MEM_A, + in.avm_main_mem_op_a, + in.avm_main_mem_op_a, + in.avm_mem_m_op_a, + in.avm_main_clk, + in.avm_main_mem_idx_a, + in.avm_main_ia, + in.avm_main_rwa, + in.avm_main_in_tag, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val, + in.avm_mem_m_rw, + in.avm_mem_m_in_tag); + } + + /** + * @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.PERM_MAIN_MEM_A, + in.avm_main_mem_op_a, + in.avm_main_mem_op_a, + in.avm_mem_m_op_a, + in.avm_main_clk, + in.avm_main_mem_idx_a, + in.avm_main_ia, + in.avm_main_rwa, + in.avm_main_in_tag, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val, + in.avm_mem_m_rw, + in.avm_mem_m_in_tag); + } +}; + +template +using PERM_MAIN_MEM_A_relation = GenericPermutationRelation; +template using PERM_MAIN_MEM_A = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_B.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_B.hpp new file mode 100644 index 00000000000..9facbaf2594 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_B.hpp @@ -0,0 +1,106 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class PERM_MAIN_MEM_B_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 5; + + /** + * @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.avm_main_mem_op_b == 1 || in.avm_mem_m_op_b == 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.PERM_MAIN_MEM_B, + in.avm_main_mem_op_b, + in.avm_main_mem_op_b, + in.avm_mem_m_op_b, + in.avm_main_clk, + in.avm_main_mem_idx_b, + in.avm_main_ib, + in.avm_main_rwb, + in.avm_main_in_tag, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val, + in.avm_mem_m_rw, + in.avm_mem_m_in_tag); + } + + /** + * @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.PERM_MAIN_MEM_B, + in.avm_main_mem_op_b, + in.avm_main_mem_op_b, + in.avm_mem_m_op_b, + in.avm_main_clk, + in.avm_main_mem_idx_b, + in.avm_main_ib, + in.avm_main_rwb, + in.avm_main_in_tag, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val, + in.avm_mem_m_rw, + in.avm_mem_m_in_tag); + } +}; + +template +using PERM_MAIN_MEM_B_relation = GenericPermutationRelation; +template using PERM_MAIN_MEM_B = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_C.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_C.hpp new file mode 100644 index 00000000000..51c6d002f04 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_C.hpp @@ -0,0 +1,106 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class PERM_MAIN_MEM_C_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 5; + + /** + * @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.avm_main_mem_op_c == 1 || in.avm_mem_m_op_c == 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.PERM_MAIN_MEM_C, + in.avm_main_mem_op_c, + in.avm_main_mem_op_c, + in.avm_mem_m_op_c, + in.avm_main_clk, + in.avm_main_mem_idx_c, + in.avm_main_ic, + in.avm_main_rwc, + in.avm_main_in_tag, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val, + in.avm_mem_m_rw, + in.avm_mem_m_in_tag); + } + + /** + * @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.PERM_MAIN_MEM_C, + in.avm_main_mem_op_c, + in.avm_main_mem_op_c, + in.avm_mem_m_op_c, + in.avm_main_clk, + in.avm_main_mem_idx_c, + in.avm_main_ic, + in.avm_main_rwc, + in.avm_main_in_tag, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val, + in.avm_mem_m_rw, + in.avm_mem_m_in_tag); + } +}; + +template +using PERM_MAIN_MEM_C_relation = GenericPermutationRelation; +template using PERM_MAIN_MEM_C = GenericPermutation; + +} // namespace bb 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 fc1970fc8fc..24db1fe7b49 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,77 +7,77 @@ namespace bb::Avm_vm { template struct Avm_aluRow { - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u8_tag{}; - FF avm_alu_alu_u128_tag{}; - FF avm_alu_alu_ib{}; FF avm_alu_alu_u16_r4{}; - FF avm_alu_alu_u16_r0{}; - FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_op_mul{}; - FF avm_alu_alu_u16_tag{}; + FF avm_alu_alu_in_tag{}; FF avm_alu_alu_u16_r2{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_alu_alu_ib{}; + FF avm_alu_alu_u16_r4_shift{}; FF avm_alu_alu_u16_r1{}; - FF avm_alu_alu_u16_r3{}; - FF avm_alu_alu_in_tag{}; - FF avm_alu_alu_u8_r1{}; - FF avm_alu_alu_u16_r7{}; - FF avm_alu_alu_u16_r6{}; - FF avm_alu_alu_op_eq{}; - FF avm_alu_alu_u64_tag{}; - FF avm_alu_alu_ia{}; - FF avm_alu_alu_ic{}; - FF avm_alu_alu_u16_r5_shift{}; - FF avm_alu_alu_op_eq_diff_inv{}; FF avm_alu_alu_op_add{}; + FF avm_alu_alu_u16_r6{}; + FF avm_alu_alu_u32_tag{}; FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_ic{}; + FF avm_alu_alu_op_not{}; + FF avm_alu_alu_op_mul{}; + FF avm_alu_alu_u16_tag{}; + FF avm_alu_alu_u16_r0{}; + FF avm_alu_alu_u8_tag{}; FF avm_alu_alu_u16_r5{}; - FF avm_alu_alu_u32_tag{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_op_sub{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u64_tag{}; FF avm_alu_alu_u8_r0{}; - FF avm_alu_alu_op_not{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r1_shift{}; + FF avm_alu_alu_u8_r1{}; + FF avm_alu_alu_u16_r5_shift{}; + FF avm_alu_alu_u16_r3{}; + FF avm_alu_alu_cf{}; + FF avm_alu_alu_ia{}; + FF avm_alu_alu_op_eq{}; + FF avm_alu_alu_sel{}; + FF avm_alu_alu_op_sub{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_op_eq_diff_inv{}; + FF avm_alu_alu_u128_tag{}; FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_u16_r7{}; FF avm_alu_alu_u16_r3_shift{}; FF avm_alu_alu_u64_r0{}; - FF avm_alu_alu_sel{}; - FF avm_alu_alu_cf{}; }; inline std::string get_relation_label_avm_alu(int index) { switch (index) { - case 19: - return "ALU_RES_IS_BOOL"; + case 17: + return "ALU_FF_NOT_XOR"; - case 20: - return "ALU_OP_EQ"; + case 16: + return "ALU_MULTIPLICATION_OUT_U128"; - case 13: - return "ALU_MUL_COMMON_2"; + case 18: + return "ALU_OP_NOT"; - case 11: - return "ALU_MULTIPLICATION_FF"; + case 12: + return "ALU_MUL_COMMON_1"; + + case 20: + return "ALU_OP_EQ"; case 10: return "ALU_ADD_SUB_2"; - case 16: - return "ALU_MULTIPLICATION_OUT_U128"; + case 13: + return "ALU_MUL_COMMON_2"; - case 18: - return "ALU_OP_NOT"; + case 19: + return "ALU_RES_IS_BOOL"; case 9: return "ALU_ADD_SUB_1"; - case 17: - return "ALU_FF_NOT_XOR"; - - case 12: - return "ALU_MUL_COMMON_1"; + case 11: + return "ALU_MULTIPLICATION_FF"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp new file mode 100644 index 00000000000..bcaacefa4aa --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp @@ -0,0 +1,146 @@ + +#pragma once +#include "../../relation_parameters.hpp" +#include "../../relation_types.hpp" +#include "./declare_views.hpp" + +namespace bb::Avm_vm { + +template struct Avm_binaryRow { + FF avm_binary_bin_sel_shift{}; + FF avm_binary_acc_ic_shift{}; + FF avm_binary_bin_ib_bytes{}; + FF avm_binary_acc_ia{}; + FF avm_main_first{}; + FF avm_binary_acc_ib_shift{}; + FF avm_binary_factor{}; + FF avm_binary_acc_ic{}; + FF avm_binary_factor_shift{}; + FF avm_binary_mem_tag_ctr_shift{}; + FF avm_binary_mem_tag_ctr{}; + FF avm_binary_latch{}; + FF avm_binary_bin_ia_bytes{}; + FF avm_binary_acc_ia_shift{}; + FF avm_binary_acc_ib{}; + FF avm_binary_bin_sel{}; + FF avm_binary_bin_ic_bytes{}; +}; + +inline std::string get_relation_label_avm_binary(int index) +{ + switch (index) { + case 6: + return "ACC_REL_B"; + + case 5: + return "ACC_REL_A"; + + case 7: + return "ACC_REL_C"; + + case 4: + return "MEM_TAG_REL"; + + case 3: + return "FACTOR_REL"; + } + return std::to_string(index); +} + +template class avm_binaryImpl { + public: + using FF = FF_; + + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 5, 4, 4, 4, 4, + }; + + template + void static accumulate(ContainerOverSubrelations& evals, + const AllEntities& new_term, + [[maybe_unused]] const RelationParameters&, + [[maybe_unused]] const FF& scaling_factor) + { + + // Contribution 0 + { + Avm_DECLARE_VIEWS(0); + + auto tmp = (avm_binary_bin_sel * (-avm_binary_bin_sel + FF(1))); + tmp *= scaling_factor; + std::get<0>(evals) += tmp; + } + // Contribution 1 + { + Avm_DECLARE_VIEWS(1); + + auto tmp = (avm_binary_latch * (-avm_binary_latch + FF(1))); + tmp *= scaling_factor; + std::get<1>(evals) += tmp; + } + // Contribution 2 + { + Avm_DECLARE_VIEWS(2); + + auto tmp = (avm_binary_latch * avm_main_first); + tmp *= scaling_factor; + std::get<2>(evals) += tmp; + } + // Contribution 3 + { + Avm_DECLARE_VIEWS(3); + + auto tmp = (avm_binary_factor_shift - ((((-avm_binary_latch + FF(1)) * (avm_binary_factor * FF(256))) + + (avm_binary_latch + avm_main_first)) * + avm_binary_bin_sel_shift)); + tmp *= scaling_factor; + std::get<3>(evals) += tmp; + } + // Contribution 4 + { + Avm_DECLARE_VIEWS(4); + + auto tmp = (avm_binary_mem_tag_ctr_shift - + (((avm_binary_mem_tag_ctr + FF(1)) * (-avm_binary_latch + FF(1))) * avm_binary_bin_sel)); + tmp *= scaling_factor; + std::get<4>(evals) += tmp; + } + // Contribution 5 + { + Avm_DECLARE_VIEWS(5); + + auto tmp = + (avm_binary_acc_ia_shift - + (((avm_binary_acc_ia * (-avm_binary_latch + FF(1))) + (avm_binary_bin_ia_bytes * avm_binary_factor)) * + avm_binary_bin_sel_shift)); + tmp *= scaling_factor; + std::get<5>(evals) += tmp; + } + // Contribution 6 + { + Avm_DECLARE_VIEWS(6); + + auto tmp = + (avm_binary_acc_ib_shift - + (((avm_binary_acc_ib * (-avm_binary_latch + FF(1))) + (avm_binary_bin_ib_bytes * avm_binary_factor)) * + avm_binary_bin_sel_shift)); + tmp *= scaling_factor; + std::get<6>(evals) += tmp; + } + // Contribution 7 + { + Avm_DECLARE_VIEWS(7); + + auto tmp = + (avm_binary_acc_ic_shift - + (((avm_binary_acc_ic * (-avm_binary_latch + FF(1))) + (avm_binary_bin_ic_bytes * avm_binary_factor)) * + avm_binary_bin_sel_shift)); + tmp *= scaling_factor; + std::get<7>(evals) += tmp; + } + } +}; + +template using avm_binary = Relation>; + +} // namespace bb::Avm_vm \ No newline at end of file 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 713d12a8964..854bb5ad6d7 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -7,71 +7,82 @@ namespace bb::Avm_vm { template struct Avm_mainRow { - FF avm_main_ind_op_b{}; + FF avm_main_internal_return_ptr_shift{}; FF avm_main_mem_idx_b{}; - FF avm_main_mem_idx_a{}; - FF avm_main_internal_return_ptr{}; - FF avm_main_sel_op_not{}; - FF avm_main_sel_op_mul{}; FF avm_main_sel_op_add{}; - FF avm_main_sel_internal_call{}; - FF avm_main_mem_op_c{}; - FF avm_main_internal_return_ptr_shift{}; + FF avm_main_ind_op_b{}; + FF avm_main_sel_op_mul{}; FF avm_main_mem_op_b{}; + FF avm_main_rwc{}; + FF avm_main_ind_op_c{}; + FF avm_main_mem_op_c{}; FF avm_main_sel_halt{}; - FF avm_main_first{}; - FF avm_main_rwa{}; - FF avm_main_ia{}; - FF avm_main_ib{}; - FF avm_main_sel_jump{}; + FF avm_main_sel_op_or{}; + FF avm_main_tag_err{}; FF avm_main_sel_op_sub{}; - FF avm_main_alu_sel{}; - FF avm_main_inv{}; - FF avm_main_pc_shift{}; + FF avm_main_bin_op_id{}; + FF avm_main_sel_op_not{}; FF avm_main_ic{}; - FF avm_main_sel_internal_return{}; - FF avm_main_ind_op_c{}; - FF avm_main_tag_err{}; + FF avm_main_sel_jump{}; + FF avm_main_sel_op_and{}; + FF avm_main_mem_op_a{}; FF avm_main_op_err{}; - FF avm_main_ind_op_a{}; - FF avm_main_pc{}; + FF avm_main_sel_op_div{}; + FF avm_main_sel_internal_call{}; + FF avm_main_rwa{}; + FF avm_main_mem_idx_a{}; + FF avm_main_bin_sel{}; + FF avm_main_sel_op_xor{}; + FF avm_main_ia{}; + FF avm_main_sel_op_eq{}; FF avm_main_sel_mov{}; + FF avm_main_alu_sel{}; + FF avm_main_ind_op_a{}; + FF avm_main_sel_internal_return{}; + FF avm_main_ib{}; + FF avm_main_internal_return_ptr{}; + FF avm_main_inv{}; FF avm_main_rwb{}; - FF avm_main_mem_op_a{}; - FF avm_main_rwc{}; - FF avm_main_sel_op_eq{}; - FF avm_main_sel_op_div{}; + FF avm_main_pc{}; + FF avm_main_pc_shift{}; + FF avm_main_first{}; }; inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 27: - return "RETURN_POINTER_INCREMENT"; + case 28: + return "SUBOP_ERROR_RELEVANT_OP"; - case 23: - return "SUBOP_DIVISION_ZERO_ERR1"; + case 42: + return "INTERNAL_RETURN_POINTER_CONSISTENCY"; + + case 46: + return "BIN_SEL_2"; - case 38: + case 41: return "PC_INCREMENT"; - case 24: + case 36: + return "RETURN_POINTER_DECREMENT"; + + case 27: return "SUBOP_DIVISION_ZERO_ERR2"; - case 40: + case 43: return "MOV_SAME_VALUE"; - case 33: - return "RETURN_POINTER_DECREMENT"; + case 45: + return "BIN_SEL_1"; - case 22: + case 25: return "SUBOP_DIVISION_FF"; - case 39: - return "INTERNAL_RETURN_POINTER_CONSISTENCY"; + case 30: + return "RETURN_POINTER_INCREMENT"; - case 25: - return "SUBOP_ERROR_RELEVANT_OP"; + case 26: + return "SUBOP_DIVISION_ZERO_ERR1"; } return std::to_string(index); } @@ -80,9 +91,9 @@ template class avm_mainImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 2, }; template @@ -144,7 +155,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(6); - auto tmp = (avm_main_sel_internal_call * (-avm_main_sel_internal_call + FF(1))); + auto tmp = (avm_main_sel_op_and * (-avm_main_sel_op_and + FF(1))); tmp *= scaling_factor; std::get<6>(evals) += tmp; } @@ -152,7 +163,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(7); - auto tmp = (avm_main_sel_internal_return * (-avm_main_sel_internal_return + FF(1))); + auto tmp = (avm_main_sel_op_or * (-avm_main_sel_op_or + FF(1))); tmp *= scaling_factor; std::get<7>(evals) += tmp; } @@ -160,7 +171,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(8); - auto tmp = (avm_main_sel_jump * (-avm_main_sel_jump + FF(1))); + auto tmp = (avm_main_sel_op_xor * (-avm_main_sel_op_xor + FF(1))); tmp *= scaling_factor; std::get<8>(evals) += tmp; } @@ -168,7 +179,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(9); - auto tmp = (avm_main_sel_halt * (-avm_main_sel_halt + FF(1))); + auto tmp = (avm_main_sel_internal_call * (-avm_main_sel_internal_call + FF(1))); tmp *= scaling_factor; std::get<9>(evals) += tmp; } @@ -176,7 +187,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(10); - auto tmp = (avm_main_sel_mov * (-avm_main_sel_mov + FF(1))); + auto tmp = (avm_main_sel_internal_return * (-avm_main_sel_internal_return + FF(1))); tmp *= scaling_factor; std::get<10>(evals) += tmp; } @@ -184,7 +195,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(11); - auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); + auto tmp = (avm_main_sel_jump * (-avm_main_sel_jump + FF(1))); tmp *= scaling_factor; std::get<11>(evals) += tmp; } @@ -192,7 +203,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(12); - auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); + auto tmp = (avm_main_sel_halt * (-avm_main_sel_halt + FF(1))); tmp *= scaling_factor; std::get<12>(evals) += tmp; } @@ -200,7 +211,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(13); - auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); + auto tmp = (avm_main_sel_mov * (-avm_main_sel_mov + FF(1))); tmp *= scaling_factor; std::get<13>(evals) += tmp; } @@ -208,7 +219,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(14); - auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); + auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); tmp *= scaling_factor; std::get<14>(evals) += tmp; } @@ -216,7 +227,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(15); - auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); + auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); tmp *= scaling_factor; std::get<15>(evals) += tmp; } @@ -224,7 +235,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(16); - auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); + auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); tmp *= scaling_factor; std::get<16>(evals) += tmp; } @@ -232,7 +243,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(17); - auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); + auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); tmp *= scaling_factor; std::get<17>(evals) += tmp; } @@ -240,7 +251,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(18); - auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); + auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -248,7 +259,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(19); - auto tmp = (avm_main_ind_op_a * (-avm_main_ind_op_a + FF(1))); + auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -256,7 +267,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); + auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -264,7 +275,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); + auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -272,8 +283,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = - ((avm_main_sel_op_div * (-avm_main_op_err + FF(1))) * ((avm_main_ic * avm_main_ib) - avm_main_ia)); + auto tmp = (avm_main_ind_op_a * (-avm_main_ind_op_a + FF(1))); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -281,7 +291,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); + auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -289,7 +299,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); + auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -297,7 +307,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); + auto tmp = + ((avm_main_sel_op_div * (-avm_main_op_err + FF(1))) * ((avm_main_ic * avm_main_ib) - avm_main_ia)); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -305,7 +316,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -313,8 +324,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = (avm_main_sel_internal_call * - (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr + FF(1)))); + auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -322,7 +332,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(28); - auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); + auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -330,7 +340,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(29); - auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -338,7 +348,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(30); - auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); + auto tmp = (avm_main_sel_internal_call * + (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr + FF(1)))); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -346,7 +357,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(31); - auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); + auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -354,7 +365,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(32); - auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); + auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -362,8 +373,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(33); - auto tmp = (avm_main_sel_internal_return * - (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr - FF(1)))); + auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); tmp *= scaling_factor; std::get<33>(evals) += tmp; } @@ -371,7 +381,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(34); - auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); + auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -379,7 +389,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(35); - auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<35>(evals) += tmp; } @@ -387,7 +397,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(36); - auto tmp = (avm_main_sel_internal_return * avm_main_rwa); + auto tmp = (avm_main_sel_internal_return * + (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr - FF(1)))); tmp *= scaling_factor; std::get<36>(evals) += tmp; } @@ -395,7 +406,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(37); - auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); tmp *= scaling_factor; std::get<37>(evals) += tmp; } @@ -403,11 +414,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(38); - auto tmp = ((((-avm_main_first + FF(1)) * (-avm_main_sel_halt + FF(1))) * - (((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_div) + avm_main_sel_op_mul) + - avm_main_sel_op_not) + - avm_main_sel_op_eq)) * - (avm_main_pc_shift - (avm_main_pc + FF(1)))); + auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<38>(evals) += tmp; } @@ -415,10 +422,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(39); - auto tmp = ((-(((avm_main_first + avm_main_sel_internal_call) + avm_main_sel_internal_return) + - avm_main_sel_halt) + - FF(1)) * - (avm_main_internal_return_ptr_shift - avm_main_internal_return_ptr)); + auto tmp = (avm_main_sel_internal_return * avm_main_rwa); tmp *= scaling_factor; std::get<39>(evals) += tmp; } @@ -426,7 +430,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(40); - auto tmp = (avm_main_sel_mov * (avm_main_ia - avm_main_ic)); + auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); tmp *= scaling_factor; std::get<40>(evals) += tmp; } @@ -434,12 +438,63 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(41); + auto tmp = + ((((-avm_main_first + FF(1)) * (-avm_main_sel_halt + FF(1))) * + ((((((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_div) + avm_main_sel_op_mul) + + avm_main_sel_op_not) + + avm_main_sel_op_eq) + + avm_main_sel_op_and) + + avm_main_sel_op_or) + + avm_main_sel_op_xor)) * + (avm_main_pc_shift - (avm_main_pc + FF(1)))); + tmp *= scaling_factor; + std::get<41>(evals) += tmp; + } + // Contribution 42 + { + Avm_DECLARE_VIEWS(42); + + auto tmp = ((-(((avm_main_first + avm_main_sel_internal_call) + avm_main_sel_internal_return) + + avm_main_sel_halt) + + FF(1)) * + (avm_main_internal_return_ptr_shift - avm_main_internal_return_ptr)); + tmp *= scaling_factor; + std::get<42>(evals) += tmp; + } + // Contribution 43 + { + Avm_DECLARE_VIEWS(43); + + auto tmp = (avm_main_sel_mov * (avm_main_ia - avm_main_ic)); + tmp *= scaling_factor; + std::get<43>(evals) += tmp; + } + // Contribution 44 + { + Avm_DECLARE_VIEWS(44); + auto tmp = (avm_main_alu_sel - (((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_mul) + avm_main_sel_op_not) + avm_main_sel_op_eq) * (-avm_main_tag_err + FF(1)))); tmp *= scaling_factor; - std::get<41>(evals) += tmp; + std::get<44>(evals) += tmp; + } + // Contribution 45 + { + Avm_DECLARE_VIEWS(45); + + auto tmp = (avm_main_bin_op_id - (avm_main_sel_op_or + (avm_main_sel_op_xor * FF(2)))); + tmp *= scaling_factor; + std::get<45>(evals) += tmp; + } + // Contribution 46 + { + Avm_DECLARE_VIEWS(46); + + auto tmp = (avm_main_bin_sel - ((avm_main_sel_op_and + avm_main_sel_op_or) + avm_main_sel_op_xor)); + tmp *= scaling_factor; + std::get<46>(evals) += tmp; } } }; 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 7863ebbbc7b..17f5fe1b5fa 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -7,52 +7,52 @@ namespace bb::Avm_vm { template struct Avm_memRow { - FF avm_mem_m_one_min_inv{}; - FF avm_mem_m_sel_mov{}; - FF avm_mem_m_ind_op_c{}; + FF avm_mem_m_tag_err{}; + FF avm_mem_m_lastAccess{}; + FF avm_mem_m_addr{}; FF avm_mem_m_ind_op_b{}; + FF avm_mem_m_rw_shift{}; + FF avm_mem_m_val_shift{}; FF avm_mem_m_op_b{}; - FF avm_mem_m_sub_clk{}; - FF avm_mem_m_addr{}; - FF avm_mem_m_op_c{}; + FF avm_mem_m_tag_shift{}; + FF avm_mem_m_tag{}; + FF avm_mem_m_one_min_inv{}; FF avm_mem_m_last{}; - FF avm_mem_m_addr_shift{}; - FF avm_mem_m_val_shift{}; + FF avm_mem_m_val{}; FF avm_mem_m_op_a{}; - FF avm_mem_m_tag_shift{}; - FF avm_mem_m_rw_shift{}; FF avm_mem_m_ind_op_a{}; - FF avm_mem_m_tag_err{}; - FF avm_mem_m_val{}; - FF avm_mem_m_lastAccess{}; - FF avm_mem_m_tag{}; FF avm_mem_m_rw{}; + FF avm_mem_m_ind_op_c{}; + FF avm_mem_m_sub_clk{}; + FF avm_mem_m_addr_shift{}; + FF avm_mem_m_op_c{}; + FF avm_mem_m_sel_mov{}; FF avm_mem_m_in_tag{}; }; inline std::string get_relation_label_avm_mem(int index) { switch (index) { + case 14: + return "MEM_READ_WRITE_TAG_CONSISTENCY"; + + case 15: + return "MEM_ZERO_INIT"; + case 12: return "MEM_LAST_ACCESS_DELIMITER"; - case 16: - return "MEM_IN_TAG_CONSISTENCY_1"; - case 17: return "MEM_IN_TAG_CONSISTENCY_2"; case 24: return "MOV_SAME_TAG"; - case 15: - return "MEM_ZERO_INIT"; - - case 14: - return "MEM_READ_WRITE_TAG_CONSISTENCY"; - case 13: return "MEM_READ_WRITE_VAL_CONSISTENCY"; + + case 16: + return "MEM_IN_TAG_CONSISTENCY_1"; } 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 3b840e95441..6fdce84eef4 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -53,6 +53,26 @@ [[maybe_unused]] auto avm_alu_alu_u64_r0 = View(new_term.avm_alu_alu_u64_r0); \ [[maybe_unused]] auto avm_alu_alu_cf = View(new_term.avm_alu_alu_cf); \ [[maybe_unused]] auto avm_alu_alu_op_eq_diff_inv = View(new_term.avm_alu_alu_op_eq_diff_inv); \ + [[maybe_unused]] auto avm_byte_lookup_table_op_id = View(new_term.avm_byte_lookup_table_op_id); \ + [[maybe_unused]] auto avm_byte_lookup_table_input_a = View(new_term.avm_byte_lookup_table_input_a); \ + [[maybe_unused]] auto avm_byte_lookup_table_input_b = View(new_term.avm_byte_lookup_table_input_b); \ + [[maybe_unused]] auto avm_byte_lookup_table_output = View(new_term.avm_byte_lookup_table_output); \ + [[maybe_unused]] auto avm_byte_lookup_bin_sel = View(new_term.avm_byte_lookup_bin_sel); \ + [[maybe_unused]] auto avm_byte_lookup_table_instr_tags = View(new_term.avm_byte_lookup_table_instr_tags); \ + [[maybe_unused]] auto avm_byte_lookup_table_byte_lengths = View(new_term.avm_byte_lookup_table_byte_lengths); \ + [[maybe_unused]] auto avm_binary_bin_clk = View(new_term.avm_binary_bin_clk); \ + [[maybe_unused]] auto avm_binary_bin_sel = View(new_term.avm_binary_bin_sel); \ + [[maybe_unused]] auto avm_binary_acc_ia = View(new_term.avm_binary_acc_ia); \ + [[maybe_unused]] auto avm_binary_acc_ib = View(new_term.avm_binary_acc_ib); \ + [[maybe_unused]] auto avm_binary_acc_ic = View(new_term.avm_binary_acc_ic); \ + [[maybe_unused]] auto avm_binary_instr_tag = View(new_term.avm_binary_instr_tag); \ + [[maybe_unused]] auto avm_binary_op_id = View(new_term.avm_binary_op_id); \ + [[maybe_unused]] auto avm_binary_bin_ia_bytes = View(new_term.avm_binary_bin_ia_bytes); \ + [[maybe_unused]] auto avm_binary_bin_ib_bytes = View(new_term.avm_binary_bin_ib_bytes); \ + [[maybe_unused]] auto avm_binary_bin_ic_bytes = View(new_term.avm_binary_bin_ic_bytes); \ + [[maybe_unused]] auto avm_binary_latch = View(new_term.avm_binary_latch); \ + [[maybe_unused]] auto avm_binary_factor = View(new_term.avm_binary_factor); \ + [[maybe_unused]] auto avm_binary_mem_tag_ctr = View(new_term.avm_binary_mem_tag_ctr); \ [[maybe_unused]] auto avm_main_pc = View(new_term.avm_main_pc); \ [[maybe_unused]] auto avm_main_internal_return_ptr = View(new_term.avm_main_internal_return_ptr); \ [[maybe_unused]] auto avm_main_sel_internal_call = View(new_term.avm_main_sel_internal_call); \ @@ -66,7 +86,11 @@ [[maybe_unused]] auto avm_main_sel_op_div = View(new_term.avm_main_sel_op_div); \ [[maybe_unused]] auto avm_main_sel_op_not = View(new_term.avm_main_sel_op_not); \ [[maybe_unused]] auto avm_main_sel_op_eq = View(new_term.avm_main_sel_op_eq); \ + [[maybe_unused]] auto avm_main_sel_op_and = View(new_term.avm_main_sel_op_and); \ + [[maybe_unused]] auto avm_main_sel_op_or = View(new_term.avm_main_sel_op_or); \ + [[maybe_unused]] auto avm_main_sel_op_xor = View(new_term.avm_main_sel_op_xor); \ [[maybe_unused]] auto avm_main_alu_sel = View(new_term.avm_main_alu_sel); \ + [[maybe_unused]] auto avm_main_bin_sel = View(new_term.avm_main_bin_sel); \ [[maybe_unused]] auto avm_main_in_tag = View(new_term.avm_main_in_tag); \ [[maybe_unused]] auto avm_main_op_err = View(new_term.avm_main_op_err); \ [[maybe_unused]] auto avm_main_tag_err = View(new_term.avm_main_tag_err); \ @@ -90,28 +114,40 @@ [[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_bin_op_id = View(new_term.avm_main_bin_op_id); \ [[maybe_unused]] auto perm_main_alu = View(new_term.perm_main_alu); \ + [[maybe_unused]] auto perm_main_bin = View(new_term.perm_main_bin); \ [[maybe_unused]] auto perm_main_mem_a = View(new_term.perm_main_mem_a); \ [[maybe_unused]] auto perm_main_mem_b = View(new_term.perm_main_mem_b); \ [[maybe_unused]] auto perm_main_mem_c = View(new_term.perm_main_mem_c); \ [[maybe_unused]] auto perm_main_mem_ind_a = View(new_term.perm_main_mem_ind_a); \ [[maybe_unused]] auto perm_main_mem_ind_b = View(new_term.perm_main_mem_ind_b); \ [[maybe_unused]] auto perm_main_mem_ind_c = View(new_term.perm_main_mem_ind_c); \ + [[maybe_unused]] auto lookup_byte_lengths = View(new_term.lookup_byte_lengths); \ + [[maybe_unused]] auto lookup_byte_operations = View(new_term.lookup_byte_operations); \ [[maybe_unused]] auto incl_main_tag_err = View(new_term.incl_main_tag_err); \ [[maybe_unused]] auto incl_mem_tag_err = View(new_term.incl_mem_tag_err); \ + [[maybe_unused]] auto lookup_byte_lengths_counts = View(new_term.lookup_byte_lengths_counts); \ + [[maybe_unused]] auto lookup_byte_operations_counts = View(new_term.lookup_byte_operations_counts); \ [[maybe_unused]] auto incl_main_tag_err_counts = View(new_term.incl_main_tag_err_counts); \ [[maybe_unused]] auto incl_mem_tag_err_counts = View(new_term.incl_mem_tag_err_counts); \ - [[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_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_mem_m_rw_shift = View(new_term.avm_mem_m_rw_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_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_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_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_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_r7_shift = View(new_term.avm_alu_alu_u16_r7_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_r3_shift = View(new_term.avm_alu_alu_u16_r3_shift); + [[maybe_unused]] auto avm_alu_alu_u16_r3_shift = View(new_term.avm_alu_alu_u16_r3_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); \ + [[maybe_unused]] auto avm_mem_m_addr_shift = View(new_term.avm_mem_m_addr_shift); \ + [[maybe_unused]] auto avm_binary_bin_sel_shift = View(new_term.avm_binary_bin_sel_shift); \ + [[maybe_unused]] auto avm_binary_acc_ic_shift = View(new_term.avm_binary_acc_ic_shift); \ + [[maybe_unused]] auto avm_binary_acc_ib_shift = View(new_term.avm_binary_acc_ib_shift); \ + [[maybe_unused]] auto avm_binary_factor_shift = View(new_term.avm_binary_factor_shift); \ + [[maybe_unused]] auto avm_binary_mem_tag_ctr_shift = View(new_term.avm_binary_mem_tag_ctr_shift); \ + [[maybe_unused]] auto avm_binary_acc_ia_shift = View(new_term.avm_binary_acc_ia_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); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_lengths.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_lengths.hpp new file mode 100644 index 00000000000..4fa896bac55 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_lengths.hpp @@ -0,0 +1,171 @@ + + +#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_byte_lengths_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 = 2; + + /** + * @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_binary_latch == 1 || in.avm_byte_lookup_bin_sel == 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_binary_latch); + const auto is_table_entry = View(in.avm_byte_lookup_bin_sel); + 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_byte_lengths, + in.lookup_byte_lengths_counts, + in.avm_binary_latch, + in.avm_byte_lookup_bin_sel, + in.avm_binary_instr_tag, + in.avm_binary_mem_tag_ctr, + in.avm_byte_lookup_table_instr_tags, + in.avm_byte_lookup_table_byte_lengths); + } + + /** + * @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_byte_lengths, + in.lookup_byte_lengths_counts, + in.avm_binary_latch, + in.avm_byte_lookup_bin_sel, + in.avm_binary_instr_tag, + in.avm_binary_mem_tag_ctr, + in.avm_byte_lookup_table_instr_tags, + in.avm_byte_lookup_table_byte_lengths); + } +}; + +template +using lookup_byte_lengths_relation = GenericLookupRelation; +template using lookup_byte_lengths = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_operations.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_operations.hpp new file mode 100644 index 00000000000..cc9a2fdf891 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_operations.hpp @@ -0,0 +1,179 @@ + + +#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_byte_operations_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 = 4; + + /** + * @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_binary_bin_sel == 1 || in.avm_byte_lookup_bin_sel == 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_binary_bin_sel); + const auto is_table_entry = View(in.avm_byte_lookup_bin_sel); + 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_byte_operations, + in.lookup_byte_operations_counts, + in.avm_binary_bin_sel, + in.avm_byte_lookup_bin_sel, + in.avm_binary_op_id, + in.avm_binary_bin_ia_bytes, + in.avm_binary_bin_ib_bytes, + in.avm_binary_bin_ic_bytes, + in.avm_byte_lookup_table_op_id, + in.avm_byte_lookup_table_input_a, + in.avm_byte_lookup_table_input_b, + in.avm_byte_lookup_table_output); + } + + /** + * @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_byte_operations, + in.lookup_byte_operations_counts, + in.avm_binary_bin_sel, + in.avm_byte_lookup_bin_sel, + in.avm_binary_op_id, + in.avm_binary_bin_ia_bytes, + in.avm_binary_bin_ib_bytes, + in.avm_binary_bin_ic_bytes, + in.avm_byte_lookup_table_op_id, + in.avm_byte_lookup_table_input_a, + in.avm_byte_lookup_table_input_b, + in.avm_byte_lookup_table_output); + } +}; + +template +using lookup_byte_operations_relation = GenericLookupRelation; +template using lookup_byte_operations = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp new file mode 100644 index 00000000000..4e81dafacf7 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp @@ -0,0 +1,110 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class perm_main_bin_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 6; + + /** + * @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.avm_main_bin_sel == 1 || in.avm_binary_latch == 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.perm_main_bin, + in.avm_main_bin_sel, + in.avm_main_bin_sel, + in.avm_binary_latch, + in.avm_main_clk, + in.avm_main_ia, + in.avm_main_ib, + in.avm_main_ic, + in.avm_main_bin_op_id, + in.avm_main_in_tag, + in.avm_binary_bin_clk, + in.avm_binary_acc_ia, + in.avm_binary_acc_ib, + in.avm_binary_acc_ic, + in.avm_binary_op_id, + in.avm_binary_instr_tag); + } + + /** + * @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.perm_main_bin, + in.avm_main_bin_sel, + in.avm_main_bin_sel, + in.avm_binary_latch, + in.avm_main_clk, + in.avm_main_ia, + in.avm_main_ib, + in.avm_main_ic, + in.avm_main_bin_op_id, + in.avm_main_in_tag, + in.avm_binary_bin_clk, + in.avm_binary_acc_ia, + in.avm_binary_acc_ib, + in.avm_binary_acc_ic, + in.avm_binary_op_id, + in.avm_binary_instr_tag); + } +}; + +template +using perm_main_bin_relation = GenericPermutationRelation; +template using perm_main_bin = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp new file mode 100644 index 00000000000..dadce494887 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp @@ -0,0 +1,175 @@ + +#include "avm_binary_trace.hpp" +#include "barretenberg/numeric/uint128/uint128.hpp" +#include "barretenberg/vm/avm_trace/avm_common.hpp" +#include +#include +#include +#include +#include + +namespace bb::avm_trace { + +AvmBinaryTraceBuilder::AvmBinaryTraceBuilder() +{ + // lookup_table = std::make_unique(); + binary_trace.reserve(AVM_TRACE_SIZE); +} + +std::vector AvmBinaryTraceBuilder::finalize() +{ + return std::move(binary_trace); +} + +void AvmBinaryTraceBuilder::reset() +{ + binary_trace.clear(); +} + +/** + * @brief Helper function to correctly decompose and pad inputs + * @param val The constant to be written upcasted to u128 + * @return LE encoded bytes with an extra zero padding. + */ +std::vector bytes_decompose(uint128_t const& val) +{ + // This uses a Network Byte Order (Big-Endian) and since a uint128_t is used + // this is guaranteed to be of length 16 (zero-padded if necessary). + std::vector bytes = to_buffer(val); + + // We convert it back to Little-Endian. + std::reverse(bytes.begin(), bytes.end()); + // To simplify the loop in witness generation we add a zero at the MSB + // as the last accumulated value has a zero in the bytes column + bytes.push_back(0); + return bytes; +} + +/** + * @brief Build and Insert and entry into the binary trace table depending on op_id + * @param a Left operand of the bitwise operation + * @param b Right operand of the bitwise operation + * @param in_tag Instruction tag + * @param clk Clock referring to the operation in the main trace. + * @param op_id which bitwise operation {0: And, 1: Or, 2: Xor } this entry corresponds to. + */ +void AvmBinaryTraceBuilder::entry_builder( + uint128_t const& a, uint128_t const& b, uint128_t const& c, AvmMemoryTag instr_tag, uint32_t clk, uint8_t op_id) +{ + // Given the instruction tag, calculate the number of bytes to decompose values into + // The number of rows for this entry will be number of bytes + 1 + size_t num_bytes = 1 << (static_cast(instr_tag) - 1); + + // Big Endian encoded + std::vector a_bytes = bytes_decompose(a); + std::vector b_bytes = bytes_decompose(b); + std::vector c_bytes = bytes_decompose(c); + + uint128_t acc_ia = 0; + uint128_t acc_ib = 0; + uint128_t acc_ic = 0; + // Factor set to 256bit. In the last row of accumulation the factor will be 2**num_bytes. + // This causes it to overflow the cpp type when we are working with U128. + uint256_t factor = 1; + + // We have num_bytes + 1 rows to add to the binary trace; + for (size_t i = 0; i <= num_bytes; i++) { + binary_trace.push_back(AvmBinaryTraceBuilder::BinaryTraceEntry{ + .binary_clk = clk, + .op_id = op_id, + .instr_tag = static_cast(instr_tag), + .mem_tag_ctr = static_cast(i), + .factor = factor, + .latch = i == num_bytes, + .acc_ia = FF(uint256_t::from_uint128(acc_ia)), + .acc_ib = FF(uint256_t::from_uint128(acc_ib)), + .acc_ic = FF(uint256_t::from_uint128(acc_ic)), + .bin_ia_bytes = a_bytes[i], + .bin_ib_bytes = b_bytes[i], + .bin_ic_bytes = c_bytes[i], + }); + auto lookup_index = static_cast((op_id << 16) + (a_bytes[i] << 8) + b_bytes[i]); + byte_operation_counter[lookup_index]++; + factor *= 256; + + acc_ia += a_bytes[i] * static_cast(std::pow(2, 8 * i)); + acc_ib += b_bytes[i] * static_cast(std::pow(2, 8 * i)); + acc_ic += c_bytes[i] * static_cast(std::pow(2, 8 * i)); + } + // There is 1 latch per call, therefore byte_length check increments + byte_length_counter[static_cast(instr_tag)]++; +} + +/** + * @brief Build Binary trace and return the result of bitwise And operation. + * + * @param a Left operand of the And + * @param b Right operand of the And + * @param in_tag Instruction tag defining the number of bits for And + * @param clk Clock referring to the operation in the main trace. + * + * @return FF The result of bitwise And casted to a Field element. + */ +FF AvmBinaryTraceBuilder::op_and(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk) +{ + if (instr_tag == AvmMemoryTag::FF || instr_tag == AvmMemoryTag::U0) { + return FF::zero(); + } + // Cast to bits and perform And operation + auto a_uint128 = static_cast(a); + auto b_uint128 = static_cast(b); + uint128_t c_uint128 = a_uint128 & b_uint128; + + this->entry_builder(a_uint128, b_uint128, c_uint128, instr_tag, clk, 0); + return uint256_t::from_uint128(c_uint128); +} + +/** + * @brief Build Binary trace and return the result of bitwise Or operation. + * + * @param a Left operand of the Or + * @param b Right operand of the Or + * @param in_tag Instruction tag defining the number of bits for Or + * @param clk Clock referring to the operation in the main trace. + * + * @return FF The result of bitwise Or casted to a Field element. + */ +FF AvmBinaryTraceBuilder::op_or(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk) +{ + if (instr_tag == AvmMemoryTag::FF || instr_tag == AvmMemoryTag::U0) { + return FF::zero(); + } + // Cast to bits and perform Or operation + auto a_uint128 = static_cast(a); + auto b_uint128 = static_cast(b); + uint128_t c_uint128 = a_uint128 | b_uint128; + + this->entry_builder(a_uint128, b_uint128, c_uint128, instr_tag, clk, 1); + return uint256_t::from_uint128(c_uint128); +} + +/** + * @brief Build Binary trace and return the result of bitwise Xor operation. + * + * @param a Left operand of the Xor + * @param b Right operand of the Xor + * @param in_tag Instruction tag defining the number of bits for Xor + * @param clk Clock referring to the operation in the main trace. + * + * @return FF The result of bitwise Xor casted to a Field element. + */ +FF AvmBinaryTraceBuilder::op_xor(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk) +{ + if (instr_tag == AvmMemoryTag::FF || instr_tag == AvmMemoryTag::U0) { + return FF::zero(); + } + // Cast to bits and perform Xor operation + auto a_uint128 = static_cast(a); + auto b_uint128 = static_cast(b); + uint128_t c_uint128 = a_uint128 ^ b_uint128; + + this->entry_builder(a_uint128, b_uint128, c_uint128, instr_tag, clk, 2); + return uint256_t::from_uint128(c_uint128); +} + +} // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp new file mode 100644 index 00000000000..4cc45549155 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "avm_common.hpp" +#include "barretenberg/numeric/uint128/uint128.hpp" +#include + +namespace bb::avm_trace { +class AvmBinaryTraceBuilder { + public: + struct BinaryTraceEntry { + uint32_t binary_clk = 0; + uint8_t op_id = 0; + uint8_t instr_tag = 0; + uint8_t mem_tag_ctr = 0; + + uint256_t factor = 0; + bool latch = false; + + FF acc_ia = FF(0); + FF acc_ib = FF(0); + FF acc_ic = FF(0); + uint8_t bin_ia_bytes = 0; + uint8_t bin_ib_bytes = 0; + uint8_t bin_ic_bytes = 0; + }; + + std::unordered_map byte_operation_counter; + std::unordered_map byte_length_counter; + + AvmBinaryTraceBuilder(); + void reset(); + // Finalize the trace + std::vector finalize(); + + FF op_and(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk); + FF op_or(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk); + FF op_xor(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk); + + private: + std::vector binary_trace; + // Helper Function to build binary trace entries + void entry_builder(uint128_t const& a, + uint128_t const& b, + uint128_t const& c, + AvmMemoryTag instr_tag, + uint32_t clk, + uint8_t op_id); +}; +} // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp index 2d3e9e9ecb6..04ed5dc05d6 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp @@ -1,5 +1,6 @@ #pragma once +#include "barretenberg/relations/generated/avm/avm_binary.hpp" #include "barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp" #include "barretenberg/vm/generated/avm_circuit_builder.hpp" #include @@ -11,7 +12,7 @@ using FF = Flavor::FF; using Row = bb::AvmFullRow; // Number of rows -static const size_t AVM_TRACE_SIZE = 256; +static const size_t AVM_TRACE_SIZE = 1 << 18; enum class IntermRegister : uint32_t { IA = 0, IB = 1, IC = 2 }; enum class IndirectRegister : uint32_t { IND_A = 0, IND_B = 1, IND_C = 2 }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp index 2a2784ee731..27a1ac9c63e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp @@ -79,7 +79,6 @@ void log_avm_trace(std::vector const& trace, size_t beg, size_t end, bool e info("sel_op_not: ", trace.at(i).avm_main_sel_op_not); info("sel_op_sel_alu: ", trace.at(i).avm_main_alu_sel); } - info("\n"); } } 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 57e21c331cd..a340f8eac8e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -1,9 +1,11 @@ +#include #include #include #include #include #include #include +#include #include #include #include @@ -33,6 +35,7 @@ void AvmTraceBuilder::reset() main_trace.clear(); mem_trace_builder.reset(); alu_trace_builder.reset(); + bin_trace_builder.reset(); } AvmTraceBuilder::IndirectThreeResolution AvmTraceBuilder::resolve_ind_three( @@ -455,6 +458,126 @@ void AvmTraceBuilder::op_eq( }); } +void AvmTraceBuilder::op_and(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) +{ + auto clk = static_cast(main_trace.size()); + + // 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 a = tag_match ? read_a.val : FF(0); + FF b = tag_match ? read_b.val : FF(0); + + FF c = tag_match ? bin_trace_builder.op_and(a, b, in_tag, clk) : FF(0); + + // Write into memory value c from intermediate register ic. + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, c, in_tag); + + main_trace.push_back(Row{ + .avm_main_clk = clk, + .avm_main_pc = FF(pc++), + .avm_main_internal_return_ptr = FF(internal_return_ptr), + .avm_main_sel_op_and = FF(1), + .avm_main_bin_sel = FF(1), + .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_tag_err = FF(static_cast(!tag_match)), + .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), + .avm_main_mem_op_c = FF(1), + .avm_main_rwc = FF(1), + .avm_main_mem_idx_a = FF(a_offset), + .avm_main_mem_idx_b = FF(b_offset), + .avm_main_mem_idx_c = FF(dst_offset), + .avm_main_bin_op_id = FF(0), + }); +} + +void AvmTraceBuilder::op_or(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) +{ + auto clk = static_cast(main_trace.size()); + + // 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 a = tag_match ? read_a.val : FF(0); + FF b = tag_match ? read_b.val : FF(0); + + FF c = tag_match ? bin_trace_builder.op_or(a, b, in_tag, clk) : FF(0); + + // Write into memory value c from intermediate register ic. + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, c, in_tag); + + main_trace.push_back(Row{ + .avm_main_clk = clk, + .avm_main_pc = FF(pc++), + .avm_main_internal_return_ptr = FF(internal_return_ptr), + .avm_main_sel_op_or = FF(1), + .avm_main_bin_sel = FF(1), + .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_tag_err = FF(static_cast(!tag_match)), + .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), + .avm_main_mem_op_c = FF(1), + .avm_main_rwc = FF(1), + .avm_main_mem_idx_a = FF(a_offset), + .avm_main_mem_idx_b = FF(b_offset), + .avm_main_mem_idx_c = FF(dst_offset), + .avm_main_bin_op_id = FF(1), + }); +} + +void AvmTraceBuilder::op_xor(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) +{ + auto clk = static_cast(main_trace.size()); + + // 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 a = tag_match ? read_a.val : FF(0); + FF b = tag_match ? read_b.val : FF(0); + + FF c = tag_match ? bin_trace_builder.op_xor(a, b, in_tag, clk) : FF(0); + + // Write into memory value c from intermediate register ic. + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, c, in_tag); + + main_trace.push_back(Row{ + .avm_main_clk = clk, + .avm_main_pc = FF(pc++), + .avm_main_internal_return_ptr = FF(internal_return_ptr), + .avm_main_sel_op_xor = FF(1), + .avm_main_bin_sel = FF(1), + .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_tag_err = FF(static_cast(!tag_match)), + .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), + .avm_main_mem_op_c = FF(1), + .avm_main_rwc = FF(1), + .avm_main_mem_idx_a = FF(a_offset), + .avm_main_mem_idx_b = FF(b_offset), + .avm_main_mem_idx_c = FF(dst_offset), + .avm_main_bin_op_id = FF(2), + }); +} + // TODO: Finish SET opcode implementation. This is a partial implementation // facilitating testing of arithmetic operations over non finite field types. // We add an entry in the memory trace and a simplified one in the main trace @@ -930,9 +1053,11 @@ std::vector AvmTraceBuilder::finalize() { auto mem_trace = mem_trace_builder.finalize(); auto alu_trace = alu_trace_builder.finalize(); + auto bin_trace = bin_trace_builder.finalize(); size_t mem_trace_size = mem_trace.size(); size_t main_trace_size = main_trace.size(); size_t alu_trace_size = alu_trace.size(); + size_t bin_trace_size = bin_trace.size(); // Get tag_err counts from the mem_trace_builder finalise_mem_trace_lookup_counts(); @@ -944,8 +1069,15 @@ std::vector AvmTraceBuilder::finalize() assert(main_trace_size < AVM_TRACE_SIZE); assert(alu_trace_size < AVM_TRACE_SIZE); - // Fill the rest with zeros. - size_t zero_rows_num = AVM_TRACE_SIZE - main_trace_size - 1; + // Main Trace needs to be at least as big as the biggest subtrace. + // If the bin_trace_size has entries, we need the main_trace to be as big as our byte lookup table (3 * 2**16 long) + size_t lookup_table = bin_trace_size > 0 ? 3 * (1 << 16) : 0; + std::vector trace_sizes = { mem_trace_size, main_trace_size, alu_trace_size, lookup_table }; + auto trace_size = std::max_element(trace_sizes.begin(), trace_sizes.end()); + + // We only need to pad with zeroes to the size to the largest trace here, pow_2 padding is handled in the + // subgroup_size check in bb + size_t zero_rows_num = *trace_size - main_trace_size; while (zero_rows_num-- > 0) { main_trace.push_back({}); } @@ -1067,6 +1199,64 @@ std::vector AvmTraceBuilder::finalize() } } + // Add Binary Trace table + for (size_t i = 0; i < bin_trace_size; i++) { + auto const& src = bin_trace.at(i); + auto& dest = main_trace.at(i); + dest.avm_binary_bin_clk = src.binary_clk; + dest.avm_binary_bin_sel = FF(1); + dest.avm_binary_acc_ia = src.acc_ia; + dest.avm_binary_acc_ib = src.acc_ib; + dest.avm_binary_acc_ic = src.acc_ic; + dest.avm_binary_instr_tag = src.instr_tag; + dest.avm_binary_op_id = src.op_id; + dest.avm_binary_bin_ia_bytes = src.bin_ia_bytes; + dest.avm_binary_bin_ib_bytes = src.bin_ib_bytes; + dest.avm_binary_bin_ic_bytes = src.bin_ic_bytes; + dest.avm_binary_latch = FF(static_cast(src.latch)); + dest.avm_binary_factor = FF(src.factor); + dest.avm_binary_mem_tag_ctr = src.mem_tag_ctr; + } + + // Only generate precomputed byte tables if we are actually going to use them in this main trace. + if (bin_trace_size > 0) { + // Generate Lookup Table of all combinations of 2, 8-bit numbers and op_id. + for (size_t op_id = 0; op_id < 3; op_id++) { + for (size_t input_a = 0; input_a <= std::numeric_limits::max(); input_a++) { + for (size_t input_b = 0; input_b <= std::numeric_limits::max(); input_b++) { + auto a = static_cast(input_a); + auto b = static_cast(input_b); + + // Derive a unique row index given op_id, a, and b. + auto main_trace_index = static_cast((op_id << 16) + (input_a << 8) + b); + + main_trace.at(main_trace_index).avm_byte_lookup_bin_sel = FF(1); + main_trace.at(main_trace_index).avm_byte_lookup_table_op_id = op_id; + main_trace.at(main_trace_index).avm_byte_lookup_table_input_a = a; + main_trace.at(main_trace_index).avm_byte_lookup_table_input_b = b; + // Add the counter value stored throughout the execution + main_trace.at(main_trace_index).lookup_byte_operations_counts = + bin_trace_builder.byte_operation_counter[main_trace_index]; + if (op_id == 0) { + main_trace.at(main_trace_index).avm_byte_lookup_table_output = a & b; + } else if (op_id == 1) { + main_trace.at(main_trace_index).avm_byte_lookup_table_output = a | b; + } else { + main_trace.at(main_trace_index).avm_byte_lookup_table_output = a ^ b; + } + } + } + } + // Generate ByteLength Lookup table of instruction tags to the number of bytes + // {U8: 1, U16: 2, U32: 4, U64: 8, U128: 16} + for (uint8_t avm_in_tag = 0; avm_in_tag < 5; avm_in_tag++) { + // The +1 here is because the instruction tags we care about (i.e excl U0 and FF) has the range [1,5] + main_trace.at(avm_in_tag).avm_byte_lookup_table_instr_tags = avm_in_tag + 1; + main_trace.at(avm_in_tag).avm_byte_lookup_table_byte_lengths = static_cast(pow(2, avm_in_tag)); + main_trace.at(avm_in_tag).lookup_byte_lengths_counts = + bin_trace_builder.byte_length_counter[avm_in_tag + 1]; + } + } // Adding extra row for the shifted values at the top of the execution trace. Row first_row = Row{ .avm_main_first = FF(1), .avm_mem_m_lastAccess = FF(1) }; main_trace.insert(main_trace.begin(), first_row); 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 8c62d03a470..84219b325a3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -3,6 +3,7 @@ #include #include "avm_alu_trace.hpp" +#include "avm_binary_trace.hpp" #include "avm_common.hpp" #include "avm_instructions.hpp" #include "avm_mem_trace.hpp" @@ -46,6 +47,15 @@ class AvmTraceBuilder { // Equality with direct or indirect memory access. void op_eq(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Bitwise and with direct memory access. + void op_and(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + + // Bitwise or with direct memory access. + void op_or(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + + // Bitwise xor with direct memory access. + void op_xor(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Set a constant from bytecode with direct memory access. void set(uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag); @@ -95,6 +105,7 @@ class AvmTraceBuilder { std::vector main_trace; AvmMemTraceBuilder mem_trace_builder; AvmAluTraceBuilder alu_trace_builder; + AvmBinaryTraceBuilder bin_trace_builder; void finalise_mem_trace_lookup_counts(); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp index ee78ecf56ee..b90de9351d9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -12,11 +12,15 @@ #include "barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp" #include "barretenberg/relations/generated/avm/avm_alu.hpp" +#include "barretenberg/relations/generated/avm/avm_binary.hpp" #include "barretenberg/relations/generated/avm/avm_main.hpp" #include "barretenberg/relations/generated/avm/avm_mem.hpp" #include "barretenberg/relations/generated/avm/incl_main_tag_err.hpp" #include "barretenberg/relations/generated/avm/incl_mem_tag_err.hpp" +#include "barretenberg/relations/generated/avm/lookup_byte_lengths.hpp" +#include "barretenberg/relations/generated/avm/lookup_byte_operations.hpp" #include "barretenberg/relations/generated/avm/perm_main_alu.hpp" +#include "barretenberg/relations/generated/avm/perm_main_bin.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_a.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_b.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_c.hpp" @@ -79,6 +83,26 @@ template struct AvmFullRow { FF avm_alu_alu_u64_r0{}; FF avm_alu_alu_cf{}; FF avm_alu_alu_op_eq_diff_inv{}; + FF avm_byte_lookup_table_op_id{}; + FF avm_byte_lookup_table_input_a{}; + FF avm_byte_lookup_table_input_b{}; + FF avm_byte_lookup_table_output{}; + FF avm_byte_lookup_bin_sel{}; + FF avm_byte_lookup_table_instr_tags{}; + FF avm_byte_lookup_table_byte_lengths{}; + FF avm_binary_bin_clk{}; + FF avm_binary_bin_sel{}; + FF avm_binary_acc_ia{}; + FF avm_binary_acc_ib{}; + FF avm_binary_acc_ic{}; + FF avm_binary_instr_tag{}; + FF avm_binary_op_id{}; + FF avm_binary_bin_ia_bytes{}; + FF avm_binary_bin_ib_bytes{}; + FF avm_binary_bin_ic_bytes{}; + FF avm_binary_latch{}; + FF avm_binary_factor{}; + FF avm_binary_mem_tag_ctr{}; FF avm_main_pc{}; FF avm_main_internal_return_ptr{}; FF avm_main_sel_internal_call{}; @@ -92,7 +116,11 @@ template struct AvmFullRow { FF avm_main_sel_op_div{}; FF avm_main_sel_op_not{}; FF avm_main_sel_op_eq{}; + FF avm_main_sel_op_and{}; + FF avm_main_sel_op_or{}; + FF avm_main_sel_op_xor{}; FF avm_main_alu_sel{}; + FF avm_main_bin_sel{}; FF avm_main_in_tag{}; FF avm_main_op_err{}; FF avm_main_tag_err{}; @@ -116,31 +144,43 @@ template struct AvmFullRow { FF avm_main_mem_idx_b{}; FF avm_main_mem_idx_c{}; FF avm_main_last{}; + FF avm_main_bin_op_id{}; FF perm_main_alu{}; + FF perm_main_bin{}; FF perm_main_mem_a{}; FF perm_main_mem_b{}; FF perm_main_mem_c{}; FF perm_main_mem_ind_a{}; FF perm_main_mem_ind_b{}; FF perm_main_mem_ind_c{}; + FF lookup_byte_lengths{}; + FF lookup_byte_operations{}; FF incl_main_tag_err{}; FF incl_mem_tag_err{}; + FF lookup_byte_lengths_counts{}; + FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_pc_shift{}; - FF avm_mem_m_addr_shift{}; - FF avm_mem_m_val_shift{}; - FF avm_mem_m_tag_shift{}; - FF avm_mem_m_rw_shift{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_u16_r5_shift{}; FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u16_r0_shift{}; FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r1_shift{}; + FF avm_alu_alu_u16_r5_shift{}; + FF avm_alu_alu_u16_r7_shift{}; FF avm_alu_alu_u16_r2_shift{}; FF avm_alu_alu_u16_r3_shift{}; + FF avm_mem_m_rw_shift{}; + FF avm_mem_m_val_shift{}; + FF avm_mem_m_tag_shift{}; + FF avm_mem_m_addr_shift{}; + FF avm_binary_bin_sel_shift{}; + FF avm_binary_acc_ic_shift{}; + FF avm_binary_acc_ib_shift{}; + FF avm_binary_factor_shift{}; + FF avm_binary_mem_tag_ctr_shift{}; + FF avm_binary_acc_ia_shift{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_pc_shift{}; }; class AvmCircuitBuilder { @@ -153,8 +193,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 113; - static constexpr size_t num_polys = 99; + static constexpr size_t num_fixed_columns = 149; + static constexpr size_t num_polys = 129; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -221,6 +261,26 @@ class AvmCircuitBuilder { polys.avm_alu_alu_u64_r0[i] = rows[i].avm_alu_alu_u64_r0; polys.avm_alu_alu_cf[i] = rows[i].avm_alu_alu_cf; polys.avm_alu_alu_op_eq_diff_inv[i] = rows[i].avm_alu_alu_op_eq_diff_inv; + polys.avm_byte_lookup_table_op_id[i] = rows[i].avm_byte_lookup_table_op_id; + polys.avm_byte_lookup_table_input_a[i] = rows[i].avm_byte_lookup_table_input_a; + polys.avm_byte_lookup_table_input_b[i] = rows[i].avm_byte_lookup_table_input_b; + polys.avm_byte_lookup_table_output[i] = rows[i].avm_byte_lookup_table_output; + polys.avm_byte_lookup_bin_sel[i] = rows[i].avm_byte_lookup_bin_sel; + polys.avm_byte_lookup_table_instr_tags[i] = rows[i].avm_byte_lookup_table_instr_tags; + polys.avm_byte_lookup_table_byte_lengths[i] = rows[i].avm_byte_lookup_table_byte_lengths; + polys.avm_binary_bin_clk[i] = rows[i].avm_binary_bin_clk; + polys.avm_binary_bin_sel[i] = rows[i].avm_binary_bin_sel; + polys.avm_binary_acc_ia[i] = rows[i].avm_binary_acc_ia; + polys.avm_binary_acc_ib[i] = rows[i].avm_binary_acc_ib; + polys.avm_binary_acc_ic[i] = rows[i].avm_binary_acc_ic; + polys.avm_binary_instr_tag[i] = rows[i].avm_binary_instr_tag; + polys.avm_binary_op_id[i] = rows[i].avm_binary_op_id; + polys.avm_binary_bin_ia_bytes[i] = rows[i].avm_binary_bin_ia_bytes; + polys.avm_binary_bin_ib_bytes[i] = rows[i].avm_binary_bin_ib_bytes; + polys.avm_binary_bin_ic_bytes[i] = rows[i].avm_binary_bin_ic_bytes; + polys.avm_binary_latch[i] = rows[i].avm_binary_latch; + polys.avm_binary_factor[i] = rows[i].avm_binary_factor; + polys.avm_binary_mem_tag_ctr[i] = rows[i].avm_binary_mem_tag_ctr; polys.avm_main_pc[i] = rows[i].avm_main_pc; polys.avm_main_internal_return_ptr[i] = rows[i].avm_main_internal_return_ptr; polys.avm_main_sel_internal_call[i] = rows[i].avm_main_sel_internal_call; @@ -234,7 +294,11 @@ class AvmCircuitBuilder { polys.avm_main_sel_op_div[i] = rows[i].avm_main_sel_op_div; polys.avm_main_sel_op_not[i] = rows[i].avm_main_sel_op_not; polys.avm_main_sel_op_eq[i] = rows[i].avm_main_sel_op_eq; + polys.avm_main_sel_op_and[i] = rows[i].avm_main_sel_op_and; + polys.avm_main_sel_op_or[i] = rows[i].avm_main_sel_op_or; + polys.avm_main_sel_op_xor[i] = rows[i].avm_main_sel_op_xor; polys.avm_main_alu_sel[i] = rows[i].avm_main_alu_sel; + polys.avm_main_bin_sel[i] = rows[i].avm_main_bin_sel; polys.avm_main_in_tag[i] = rows[i].avm_main_in_tag; polys.avm_main_op_err[i] = rows[i].avm_main_op_err; polys.avm_main_tag_err[i] = rows[i].avm_main_tag_err; @@ -258,33 +322,45 @@ 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.avm_main_bin_op_id[i] = rows[i].avm_main_bin_op_id; polys.perm_main_alu[i] = rows[i].perm_main_alu; + polys.perm_main_bin[i] = rows[i].perm_main_bin; polys.perm_main_mem_a[i] = rows[i].perm_main_mem_a; polys.perm_main_mem_b[i] = rows[i].perm_main_mem_b; polys.perm_main_mem_c[i] = rows[i].perm_main_mem_c; polys.perm_main_mem_ind_a[i] = rows[i].perm_main_mem_ind_a; polys.perm_main_mem_ind_b[i] = rows[i].perm_main_mem_ind_b; polys.perm_main_mem_ind_c[i] = rows[i].perm_main_mem_ind_c; + polys.lookup_byte_lengths[i] = rows[i].lookup_byte_lengths; + polys.lookup_byte_operations[i] = rows[i].lookup_byte_operations; polys.incl_main_tag_err[i] = rows[i].incl_main_tag_err; polys.incl_mem_tag_err[i] = rows[i].incl_mem_tag_err; + polys.lookup_byte_lengths_counts[i] = rows[i].lookup_byte_lengths_counts; + polys.lookup_byte_operations_counts[i] = rows[i].lookup_byte_operations_counts; polys.incl_main_tag_err_counts[i] = rows[i].incl_main_tag_err_counts; polys.incl_mem_tag_err_counts[i] = rows[i].incl_mem_tag_err_counts; } - 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_val_shift = Polynomial(polys.avm_mem_m_val.shifted()); - polys.avm_mem_m_tag_shift = Polynomial(polys.avm_mem_m_tag.shifted()); - polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); - polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.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_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_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_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_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.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()); + polys.avm_mem_m_addr_shift = Polynomial(polys.avm_mem_m_addr.shifted()); + polys.avm_binary_bin_sel_shift = Polynomial(polys.avm_binary_bin_sel.shifted()); + polys.avm_binary_acc_ic_shift = Polynomial(polys.avm_binary_acc_ic.shifted()); + polys.avm_binary_acc_ib_shift = Polynomial(polys.avm_binary_acc_ib.shifted()); + polys.avm_binary_factor_shift = Polynomial(polys.avm_binary_factor.shifted()); + polys.avm_binary_mem_tag_ctr_shift = Polynomial(polys.avm_binary_mem_tag_ctr.shifted()); + polys.avm_binary_acc_ia_shift = Polynomial(polys.avm_binary_acc_ia.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()); return polys; } @@ -356,22 +432,29 @@ class AvmCircuitBuilder { return true; }; - if (!evaluate_relation.template operator()>("avm_main", - Avm_vm::get_relation_label_avm_main)) { + if (!evaluate_relation.template operator()>("avm_alu", + Avm_vm::get_relation_label_avm_alu)) { return false; } 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)) { + if (!evaluate_relation.template operator()>("avm_binary", + Avm_vm::get_relation_label_avm_binary)) { + return false; + } + if (!evaluate_relation.template operator()>("avm_main", + Avm_vm::get_relation_label_avm_main)) { return false; } if (!evaluate_logderivative.template operator()>("PERM_MAIN_ALU")) { return false; } + if (!evaluate_logderivative.template operator()>("PERM_MAIN_BIN")) { + return false; + } if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_A")) { return false; } @@ -390,6 +473,13 @@ class AvmCircuitBuilder { if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_IND_C")) { return false; } + if (!evaluate_logderivative.template operator()>("LOOKUP_BYTE_LENGTHS")) { + return false; + } + if (!evaluate_logderivative.template operator()>( + "LOOKUP_BYTE_OPERATIONS")) { + return false; + } if (!evaluate_logderivative.template operator()>("INCL_MAIN_TAG_ERR")) { return false; } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 2d5393cdf9c..3b5350b9008 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -14,9 +14,11 @@ #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/generated/avm/avm_alu.hpp" +#include "barretenberg/relations/generated/avm/avm_binary.hpp" #include "barretenberg/relations/generated/avm/avm_main.hpp" #include "barretenberg/relations/generated/avm/avm_mem.hpp" #include "barretenberg/relations/generated/avm/perm_main_alu.hpp" +#include "barretenberg/relations/generated/avm/perm_main_bin.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_a.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_b.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_c.hpp" @@ -44,16 +46,18 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 97; + static constexpr size_t NUM_WITNESS_ENTITIES = 127; 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 = 113; + static constexpr size_t NUM_ALL_ENTITIES = 149; - using Relations = std::tuple, + using Relations = std::tuple, Avm_vm::avm_mem, - Avm_vm::avm_alu, + Avm_vm::avm_binary, + Avm_vm::avm_main, perm_main_alu_relation, + perm_main_bin_relation, perm_main_mem_a_relation, perm_main_mem_b_relation, perm_main_mem_c_relation, @@ -142,6 +146,26 @@ class AvmFlavor { avm_alu_alu_u64_r0, avm_alu_alu_cf, avm_alu_alu_op_eq_diff_inv, + avm_byte_lookup_table_op_id, + avm_byte_lookup_table_input_a, + avm_byte_lookup_table_input_b, + avm_byte_lookup_table_output, + avm_byte_lookup_bin_sel, + avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_byte_lengths, + avm_binary_bin_clk, + avm_binary_bin_sel, + avm_binary_acc_ia, + avm_binary_acc_ib, + avm_binary_acc_ic, + avm_binary_instr_tag, + avm_binary_op_id, + avm_binary_bin_ia_bytes, + avm_binary_bin_ib_bytes, + avm_binary_bin_ic_bytes, + avm_binary_latch, + avm_binary_factor, + avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -155,7 +179,11 @@ class AvmFlavor { avm_main_sel_op_div, avm_main_sel_op_not, avm_main_sel_op_eq, + avm_main_sel_op_and, + avm_main_sel_op_or, + avm_main_sel_op_xor, avm_main_alu_sel, + avm_main_bin_sel, avm_main_in_tag, avm_main_op_err, avm_main_tag_err, @@ -179,15 +207,21 @@ class AvmFlavor { avm_main_mem_idx_b, avm_main_mem_idx_c, avm_main_last, + avm_main_bin_op_id, perm_main_alu, + perm_main_bin, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + lookup_byte_lengths, + lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_byte_lengths_counts, + lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts) @@ -242,6 +276,26 @@ class AvmFlavor { avm_alu_alu_u64_r0, avm_alu_alu_cf, avm_alu_alu_op_eq_diff_inv, + avm_byte_lookup_table_op_id, + avm_byte_lookup_table_input_a, + avm_byte_lookup_table_input_b, + avm_byte_lookup_table_output, + avm_byte_lookup_bin_sel, + avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_byte_lengths, + avm_binary_bin_clk, + avm_binary_bin_sel, + avm_binary_acc_ia, + avm_binary_acc_ib, + avm_binary_acc_ic, + avm_binary_instr_tag, + avm_binary_op_id, + avm_binary_bin_ia_bytes, + avm_binary_bin_ib_bytes, + avm_binary_bin_ic_bytes, + avm_binary_latch, + avm_binary_factor, + avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -255,7 +309,11 @@ class AvmFlavor { avm_main_sel_op_div, avm_main_sel_op_not, avm_main_sel_op_eq, + avm_main_sel_op_and, + avm_main_sel_op_or, + avm_main_sel_op_xor, avm_main_alu_sel, + avm_main_bin_sel, avm_main_in_tag, avm_main_op_err, avm_main_tag_err, @@ -279,15 +337,21 @@ class AvmFlavor { avm_main_mem_idx_b, avm_main_mem_idx_c, avm_main_last, + avm_main_bin_op_id, perm_main_alu, + perm_main_bin, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + lookup_byte_lengths, + lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_byte_lengths_counts, + lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts }; }; @@ -348,6 +412,26 @@ class AvmFlavor { avm_alu_alu_u64_r0, avm_alu_alu_cf, avm_alu_alu_op_eq_diff_inv, + avm_byte_lookup_table_op_id, + avm_byte_lookup_table_input_a, + avm_byte_lookup_table_input_b, + avm_byte_lookup_table_output, + avm_byte_lookup_bin_sel, + avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_byte_lengths, + avm_binary_bin_clk, + avm_binary_bin_sel, + avm_binary_acc_ia, + avm_binary_acc_ib, + avm_binary_acc_ic, + avm_binary_instr_tag, + avm_binary_op_id, + avm_binary_bin_ia_bytes, + avm_binary_bin_ib_bytes, + avm_binary_bin_ic_bytes, + avm_binary_latch, + avm_binary_factor, + avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -361,7 +445,11 @@ class AvmFlavor { avm_main_sel_op_div, avm_main_sel_op_not, avm_main_sel_op_eq, + avm_main_sel_op_and, + avm_main_sel_op_or, + avm_main_sel_op_xor, avm_main_alu_sel, + avm_main_bin_sel, avm_main_in_tag, avm_main_op_err, avm_main_tag_err, @@ -385,31 +473,43 @@ class AvmFlavor { avm_main_mem_idx_b, avm_main_mem_idx_c, avm_main_last, + avm_main_bin_op_id, perm_main_alu, + perm_main_bin, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + lookup_byte_lengths, + lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_byte_lengths_counts, + lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_mem_m_addr_shift, - avm_mem_m_val_shift, - avm_mem_m_tag_shift, - avm_mem_m_rw_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r5_shift, avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r0_shift, avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r1_shift, + avm_alu_alu_u16_r5_shift, + avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r3_shift) + avm_alu_alu_u16_r3_shift, + avm_mem_m_rw_shift, + avm_mem_m_val_shift, + avm_mem_m_tag_shift, + avm_mem_m_addr_shift, + avm_binary_bin_sel_shift, + avm_binary_acc_ic_shift, + avm_binary_acc_ib_shift, + avm_binary_factor_shift, + avm_binary_mem_tag_ctr_shift, + avm_binary_acc_ia_shift, + avm_main_internal_return_ptr_shift, + avm_main_pc_shift) RefVector get_wires() { @@ -464,6 +564,26 @@ class AvmFlavor { avm_alu_alu_u64_r0, avm_alu_alu_cf, avm_alu_alu_op_eq_diff_inv, + avm_byte_lookup_table_op_id, + avm_byte_lookup_table_input_a, + avm_byte_lookup_table_input_b, + avm_byte_lookup_table_output, + avm_byte_lookup_bin_sel, + avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_byte_lengths, + avm_binary_bin_clk, + avm_binary_bin_sel, + avm_binary_acc_ia, + avm_binary_acc_ib, + avm_binary_acc_ic, + avm_binary_instr_tag, + avm_binary_op_id, + avm_binary_bin_ia_bytes, + avm_binary_bin_ib_bytes, + avm_binary_bin_ic_bytes, + avm_binary_latch, + avm_binary_factor, + avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -477,7 +597,11 @@ class AvmFlavor { avm_main_sel_op_div, avm_main_sel_op_not, avm_main_sel_op_eq, + avm_main_sel_op_and, + avm_main_sel_op_or, + avm_main_sel_op_xor, avm_main_alu_sel, + avm_main_bin_sel, avm_main_in_tag, avm_main_op_err, avm_main_tag_err, @@ -501,31 +625,43 @@ class AvmFlavor { avm_main_mem_idx_b, avm_main_mem_idx_c, avm_main_last, + avm_main_bin_op_id, perm_main_alu, + perm_main_bin, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + lookup_byte_lengths, + lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_byte_lengths_counts, + lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_mem_m_addr_shift, - avm_mem_m_val_shift, - avm_mem_m_tag_shift, - avm_mem_m_rw_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r5_shift, avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r0_shift, avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r1_shift, + avm_alu_alu_u16_r5_shift, + avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r3_shift }; + avm_alu_alu_u16_r3_shift, + avm_mem_m_rw_shift, + avm_mem_m_val_shift, + avm_mem_m_tag_shift, + avm_mem_m_addr_shift, + avm_binary_bin_sel_shift, + avm_binary_acc_ic_shift, + avm_binary_acc_ib_shift, + avm_binary_factor_shift, + avm_binary_mem_tag_ctr_shift, + avm_binary_acc_ia_shift, + avm_main_internal_return_ptr_shift, + avm_main_pc_shift }; }; RefVector get_unshifted() { @@ -580,6 +716,26 @@ class AvmFlavor { avm_alu_alu_u64_r0, avm_alu_alu_cf, avm_alu_alu_op_eq_diff_inv, + avm_byte_lookup_table_op_id, + avm_byte_lookup_table_input_a, + avm_byte_lookup_table_input_b, + avm_byte_lookup_table_output, + avm_byte_lookup_bin_sel, + avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_byte_lengths, + avm_binary_bin_clk, + avm_binary_bin_sel, + avm_binary_acc_ia, + avm_binary_acc_ib, + avm_binary_acc_ic, + avm_binary_instr_tag, + avm_binary_op_id, + avm_binary_bin_ia_bytes, + avm_binary_bin_ib_bytes, + avm_binary_bin_ic_bytes, + avm_binary_latch, + avm_binary_factor, + avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -593,7 +749,11 @@ class AvmFlavor { avm_main_sel_op_div, avm_main_sel_op_not, avm_main_sel_op_eq, + avm_main_sel_op_and, + avm_main_sel_op_or, + avm_main_sel_op_xor, avm_main_alu_sel, + avm_main_bin_sel, avm_main_in_tag, avm_main_op_err, avm_main_tag_err, @@ -617,51 +777,69 @@ class AvmFlavor { avm_main_mem_idx_b, avm_main_mem_idx_c, avm_main_last, + avm_main_bin_op_id, perm_main_alu, + perm_main_bin, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + lookup_byte_lengths, + lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_byte_lengths_counts, + lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts }; }; RefVector get_to_be_shifted() { - return { avm_main_internal_return_ptr, - avm_main_pc, - avm_mem_m_addr, - avm_mem_m_val, - avm_mem_m_tag, - avm_mem_m_rw, - avm_alu_alu_u16_r7, + return { avm_alu_alu_u16_r6, + avm_alu_alu_u16_r4, + avm_alu_alu_u16_r0, avm_alu_alu_u16_r1, avm_alu_alu_u16_r5, - avm_alu_alu_u16_r6, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r4, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r2, - avm_alu_alu_u16_r3 }; + avm_alu_alu_u16_r3, + avm_mem_m_rw, + avm_mem_m_val, + avm_mem_m_tag, + avm_mem_m_addr, + avm_binary_bin_sel, + avm_binary_acc_ic, + avm_binary_acc_ib, + avm_binary_factor, + avm_binary_mem_tag_ctr, + avm_binary_acc_ia, + avm_main_internal_return_ptr, + avm_main_pc }; }; RefVector get_shifted() { - return { avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_mem_m_addr_shift, - avm_mem_m_val_shift, - avm_mem_m_tag_shift, - avm_mem_m_rw_shift, - avm_alu_alu_u16_r7_shift, + return { avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r0_shift, avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r3_shift }; + avm_alu_alu_u16_r3_shift, + avm_mem_m_rw_shift, + avm_mem_m_val_shift, + avm_mem_m_tag_shift, + avm_mem_m_addr_shift, + avm_binary_bin_sel_shift, + avm_binary_acc_ic_shift, + avm_binary_acc_ib_shift, + avm_binary_factor_shift, + avm_binary_mem_tag_ctr_shift, + avm_binary_acc_ia_shift, + avm_main_internal_return_ptr_shift, + avm_main_pc_shift }; }; }; @@ -674,20 +852,26 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_main_internal_return_ptr, - avm_main_pc, - avm_mem_m_addr, - avm_mem_m_val, - avm_mem_m_tag, - avm_mem_m_rw, - avm_alu_alu_u16_r7, + return { avm_alu_alu_u16_r6, + avm_alu_alu_u16_r4, + avm_alu_alu_u16_r0, avm_alu_alu_u16_r1, avm_alu_alu_u16_r5, - avm_alu_alu_u16_r6, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r4, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r2, - avm_alu_alu_u16_r3 }; + avm_alu_alu_u16_r3, + avm_mem_m_rw, + avm_mem_m_val, + avm_mem_m_tag, + avm_mem_m_addr, + avm_binary_bin_sel, + avm_binary_acc_ic, + avm_binary_acc_ib, + avm_binary_factor, + avm_binary_mem_tag_ctr, + avm_binary_acc_ia, + avm_main_internal_return_ptr, + avm_main_pc }; }; // The plookup wires that store plookup read data. @@ -815,6 +999,26 @@ class AvmFlavor { Base::avm_alu_alu_u64_r0 = "AVM_ALU_ALU_U64_R0"; Base::avm_alu_alu_cf = "AVM_ALU_ALU_CF"; Base::avm_alu_alu_op_eq_diff_inv = "AVM_ALU_ALU_OP_EQ_DIFF_INV"; + Base::avm_byte_lookup_table_op_id = "AVM_BYTE_LOOKUP_TABLE_OP_ID"; + Base::avm_byte_lookup_table_input_a = "AVM_BYTE_LOOKUP_TABLE_INPUT_A"; + Base::avm_byte_lookup_table_input_b = "AVM_BYTE_LOOKUP_TABLE_INPUT_B"; + Base::avm_byte_lookup_table_output = "AVM_BYTE_LOOKUP_TABLE_OUTPUT"; + Base::avm_byte_lookup_bin_sel = "AVM_BYTE_LOOKUP_BIN_SEL"; + Base::avm_byte_lookup_table_instr_tags = "AVM_BYTE_LOOKUP_TABLE_INSTR_TAGS"; + Base::avm_byte_lookup_table_byte_lengths = "AVM_BYTE_LOOKUP_TABLE_BYTE_LENGTHS"; + Base::avm_binary_bin_clk = "AVM_BINARY_BIN_CLK"; + Base::avm_binary_bin_sel = "AVM_BINARY_BIN_SEL"; + Base::avm_binary_acc_ia = "AVM_BINARY_ACC_IA"; + Base::avm_binary_acc_ib = "AVM_BINARY_ACC_IB"; + Base::avm_binary_acc_ic = "AVM_BINARY_ACC_IC"; + Base::avm_binary_instr_tag = "AVM_BINARY_INSTR_TAG"; + Base::avm_binary_op_id = "AVM_BINARY_OP_ID"; + Base::avm_binary_bin_ia_bytes = "AVM_BINARY_BIN_IA_BYTES"; + Base::avm_binary_bin_ib_bytes = "AVM_BINARY_BIN_IB_BYTES"; + Base::avm_binary_bin_ic_bytes = "AVM_BINARY_BIN_IC_BYTES"; + Base::avm_binary_latch = "AVM_BINARY_LATCH"; + Base::avm_binary_factor = "AVM_BINARY_FACTOR"; + Base::avm_binary_mem_tag_ctr = "AVM_BINARY_MEM_TAG_CTR"; Base::avm_main_pc = "AVM_MAIN_PC"; Base::avm_main_internal_return_ptr = "AVM_MAIN_INTERNAL_RETURN_PTR"; Base::avm_main_sel_internal_call = "AVM_MAIN_SEL_INTERNAL_CALL"; @@ -828,7 +1032,11 @@ class AvmFlavor { Base::avm_main_sel_op_div = "AVM_MAIN_SEL_OP_DIV"; Base::avm_main_sel_op_not = "AVM_MAIN_SEL_OP_NOT"; Base::avm_main_sel_op_eq = "AVM_MAIN_SEL_OP_EQ"; + Base::avm_main_sel_op_and = "AVM_MAIN_SEL_OP_AND"; + Base::avm_main_sel_op_or = "AVM_MAIN_SEL_OP_OR"; + Base::avm_main_sel_op_xor = "AVM_MAIN_SEL_OP_XOR"; Base::avm_main_alu_sel = "AVM_MAIN_ALU_SEL"; + Base::avm_main_bin_sel = "AVM_MAIN_BIN_SEL"; Base::avm_main_in_tag = "AVM_MAIN_IN_TAG"; Base::avm_main_op_err = "AVM_MAIN_OP_ERR"; Base::avm_main_tag_err = "AVM_MAIN_TAG_ERR"; @@ -852,15 +1060,21 @@ 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::avm_main_bin_op_id = "AVM_MAIN_BIN_OP_ID"; Base::perm_main_alu = "PERM_MAIN_ALU"; + Base::perm_main_bin = "PERM_MAIN_BIN"; Base::perm_main_mem_a = "PERM_MAIN_MEM_A"; Base::perm_main_mem_b = "PERM_MAIN_MEM_B"; Base::perm_main_mem_c = "PERM_MAIN_MEM_C"; Base::perm_main_mem_ind_a = "PERM_MAIN_MEM_IND_A"; Base::perm_main_mem_ind_b = "PERM_MAIN_MEM_IND_B"; Base::perm_main_mem_ind_c = "PERM_MAIN_MEM_IND_C"; + Base::lookup_byte_lengths = "LOOKUP_BYTE_LENGTHS"; + Base::lookup_byte_operations = "LOOKUP_BYTE_OPERATIONS"; Base::incl_main_tag_err = "INCL_MAIN_TAG_ERR"; Base::incl_mem_tag_err = "INCL_MEM_TAG_ERR"; + Base::lookup_byte_lengths_counts = "LOOKUP_BYTE_LENGTHS_COUNTS"; + Base::lookup_byte_operations_counts = "LOOKUP_BYTE_OPERATIONS_COUNTS"; Base::incl_main_tag_err_counts = "INCL_MAIN_TAG_ERR_COUNTS"; Base::incl_mem_tag_err_counts = "INCL_MEM_TAG_ERR_COUNTS"; }; @@ -931,6 +1145,26 @@ class AvmFlavor { Commitment avm_alu_alu_u64_r0; Commitment avm_alu_alu_cf; Commitment avm_alu_alu_op_eq_diff_inv; + Commitment avm_byte_lookup_table_op_id; + Commitment avm_byte_lookup_table_input_a; + Commitment avm_byte_lookup_table_input_b; + Commitment avm_byte_lookup_table_output; + Commitment avm_byte_lookup_bin_sel; + Commitment avm_byte_lookup_table_instr_tags; + Commitment avm_byte_lookup_table_byte_lengths; + Commitment avm_binary_bin_clk; + Commitment avm_binary_bin_sel; + Commitment avm_binary_acc_ia; + Commitment avm_binary_acc_ib; + Commitment avm_binary_acc_ic; + Commitment avm_binary_instr_tag; + Commitment avm_binary_op_id; + Commitment avm_binary_bin_ia_bytes; + Commitment avm_binary_bin_ib_bytes; + Commitment avm_binary_bin_ic_bytes; + Commitment avm_binary_latch; + Commitment avm_binary_factor; + Commitment avm_binary_mem_tag_ctr; Commitment avm_main_pc; Commitment avm_main_internal_return_ptr; Commitment avm_main_sel_internal_call; @@ -944,7 +1178,11 @@ class AvmFlavor { Commitment avm_main_sel_op_div; Commitment avm_main_sel_op_not; Commitment avm_main_sel_op_eq; + Commitment avm_main_sel_op_and; + Commitment avm_main_sel_op_or; + Commitment avm_main_sel_op_xor; Commitment avm_main_alu_sel; + Commitment avm_main_bin_sel; Commitment avm_main_in_tag; Commitment avm_main_op_err; Commitment avm_main_tag_err; @@ -968,15 +1206,21 @@ class AvmFlavor { Commitment avm_main_mem_idx_b; Commitment avm_main_mem_idx_c; Commitment avm_main_last; + Commitment avm_main_bin_op_id; Commitment perm_main_alu; + Commitment perm_main_bin; Commitment perm_main_mem_a; Commitment perm_main_mem_b; Commitment perm_main_mem_c; Commitment perm_main_mem_ind_a; Commitment perm_main_mem_ind_b; Commitment perm_main_mem_ind_c; + Commitment lookup_byte_lengths; + Commitment lookup_byte_operations; Commitment incl_main_tag_err; Commitment incl_mem_tag_err; + Commitment lookup_byte_lengths_counts; + Commitment lookup_byte_operations_counts; Commitment incl_main_tag_err_counts; Commitment incl_mem_tag_err_counts; @@ -1047,6 +1291,28 @@ class AvmFlavor { avm_alu_alu_u64_r0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_alu_cf = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_alu_op_eq_diff_inv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_byte_lookup_table_op_id = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_byte_lookup_table_input_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_byte_lookup_table_input_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_byte_lookup_table_output = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_byte_lookup_bin_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_byte_lookup_table_instr_tags = + deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_byte_lookup_table_byte_lengths = + deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_bin_clk = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_bin_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_acc_ia = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_acc_ib = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_acc_ic = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_instr_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_op_id = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_bin_ia_bytes = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_bin_ib_bytes = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_bin_ic_bytes = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_latch = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_factor = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_mem_tag_ctr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_pc = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_internal_return_ptr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_internal_call = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1060,7 +1326,11 @@ class AvmFlavor { avm_main_sel_op_div = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_not = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_eq = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_op_and = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_op_or = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_op_xor = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_alu_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_bin_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_op_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1084,15 +1354,21 @@ 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); + avm_main_bin_op_id = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_alu = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + perm_main_bin = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_ind_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_ind_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_ind_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_byte_lengths = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_byte_operations = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_main_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_mem_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_byte_lengths_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_byte_operations_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_main_tag_err_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_mem_tag_err_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1167,6 +1443,26 @@ class AvmFlavor { serialize_to_buffer(avm_alu_alu_u64_r0, Transcript::proof_data); serialize_to_buffer(avm_alu_alu_cf, Transcript::proof_data); serialize_to_buffer(avm_alu_alu_op_eq_diff_inv, Transcript::proof_data); + serialize_to_buffer(avm_byte_lookup_table_op_id, Transcript::proof_data); + serialize_to_buffer(avm_byte_lookup_table_input_a, Transcript::proof_data); + serialize_to_buffer(avm_byte_lookup_table_input_b, Transcript::proof_data); + serialize_to_buffer(avm_byte_lookup_table_output, Transcript::proof_data); + serialize_to_buffer(avm_byte_lookup_bin_sel, Transcript::proof_data); + serialize_to_buffer(avm_byte_lookup_table_instr_tags, Transcript::proof_data); + serialize_to_buffer(avm_byte_lookup_table_byte_lengths, Transcript::proof_data); + serialize_to_buffer(avm_binary_bin_clk, Transcript::proof_data); + serialize_to_buffer(avm_binary_bin_sel, Transcript::proof_data); + serialize_to_buffer(avm_binary_acc_ia, Transcript::proof_data); + serialize_to_buffer(avm_binary_acc_ib, Transcript::proof_data); + serialize_to_buffer(avm_binary_acc_ic, Transcript::proof_data); + serialize_to_buffer(avm_binary_instr_tag, Transcript::proof_data); + serialize_to_buffer(avm_binary_op_id, Transcript::proof_data); + serialize_to_buffer(avm_binary_bin_ia_bytes, Transcript::proof_data); + serialize_to_buffer(avm_binary_bin_ib_bytes, Transcript::proof_data); + serialize_to_buffer(avm_binary_bin_ic_bytes, Transcript::proof_data); + serialize_to_buffer(avm_binary_latch, Transcript::proof_data); + serialize_to_buffer(avm_binary_factor, Transcript::proof_data); + serialize_to_buffer(avm_binary_mem_tag_ctr, Transcript::proof_data); serialize_to_buffer(avm_main_pc, Transcript::proof_data); serialize_to_buffer(avm_main_internal_return_ptr, Transcript::proof_data); serialize_to_buffer(avm_main_sel_internal_call, Transcript::proof_data); @@ -1180,7 +1476,11 @@ class AvmFlavor { serialize_to_buffer(avm_main_sel_op_div, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_not, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_eq, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_op_and, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_op_or, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_op_xor, Transcript::proof_data); serialize_to_buffer(avm_main_alu_sel, Transcript::proof_data); + serialize_to_buffer(avm_main_bin_sel, Transcript::proof_data); serialize_to_buffer(avm_main_in_tag, Transcript::proof_data); serialize_to_buffer(avm_main_op_err, Transcript::proof_data); serialize_to_buffer(avm_main_tag_err, Transcript::proof_data); @@ -1204,15 +1504,21 @@ 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(avm_main_bin_op_id, Transcript::proof_data); serialize_to_buffer(perm_main_alu, Transcript::proof_data); + serialize_to_buffer(perm_main_bin, Transcript::proof_data); serialize_to_buffer(perm_main_mem_a, Transcript::proof_data); serialize_to_buffer(perm_main_mem_b, Transcript::proof_data); serialize_to_buffer(perm_main_mem_c, Transcript::proof_data); serialize_to_buffer(perm_main_mem_ind_a, Transcript::proof_data); serialize_to_buffer(perm_main_mem_ind_b, Transcript::proof_data); serialize_to_buffer(perm_main_mem_ind_c, Transcript::proof_data); + serialize_to_buffer(lookup_byte_lengths, Transcript::proof_data); + serialize_to_buffer(lookup_byte_operations, Transcript::proof_data); serialize_to_buffer(incl_main_tag_err, Transcript::proof_data); serialize_to_buffer(incl_mem_tag_err, Transcript::proof_data); + serialize_to_buffer(lookup_byte_lengths_counts, Transcript::proof_data); + serialize_to_buffer(lookup_byte_operations_counts, Transcript::proof_data); serialize_to_buffer(incl_main_tag_err_counts, Transcript::proof_data); serialize_to_buffer(incl_mem_tag_err_counts, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 87e34d8179d..49bb8fe10c2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -136,6 +136,46 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) commitments.avm_alu_alu_cf = transcript->template receive_from_prover(commitment_labels.avm_alu_alu_cf); commitments.avm_alu_alu_op_eq_diff_inv = transcript->template receive_from_prover(commitment_labels.avm_alu_alu_op_eq_diff_inv); + commitments.avm_byte_lookup_table_op_id = + transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_op_id); + commitments.avm_byte_lookup_table_input_a = + transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_input_a); + commitments.avm_byte_lookup_table_input_b = + transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_input_b); + commitments.avm_byte_lookup_table_output = + transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_output); + commitments.avm_byte_lookup_bin_sel = + transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_bin_sel); + commitments.avm_byte_lookup_table_instr_tags = + transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_instr_tags); + commitments.avm_byte_lookup_table_byte_lengths = + transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_byte_lengths); + commitments.avm_binary_bin_clk = + transcript->template receive_from_prover(commitment_labels.avm_binary_bin_clk); + commitments.avm_binary_bin_sel = + transcript->template receive_from_prover(commitment_labels.avm_binary_bin_sel); + commitments.avm_binary_acc_ia = + transcript->template receive_from_prover(commitment_labels.avm_binary_acc_ia); + commitments.avm_binary_acc_ib = + transcript->template receive_from_prover(commitment_labels.avm_binary_acc_ib); + commitments.avm_binary_acc_ic = + transcript->template receive_from_prover(commitment_labels.avm_binary_acc_ic); + commitments.avm_binary_instr_tag = + transcript->template receive_from_prover(commitment_labels.avm_binary_instr_tag); + commitments.avm_binary_op_id = + transcript->template receive_from_prover(commitment_labels.avm_binary_op_id); + commitments.avm_binary_bin_ia_bytes = + transcript->template receive_from_prover(commitment_labels.avm_binary_bin_ia_bytes); + commitments.avm_binary_bin_ib_bytes = + transcript->template receive_from_prover(commitment_labels.avm_binary_bin_ib_bytes); + commitments.avm_binary_bin_ic_bytes = + transcript->template receive_from_prover(commitment_labels.avm_binary_bin_ic_bytes); + commitments.avm_binary_latch = + transcript->template receive_from_prover(commitment_labels.avm_binary_latch); + commitments.avm_binary_factor = + transcript->template receive_from_prover(commitment_labels.avm_binary_factor); + commitments.avm_binary_mem_tag_ctr = + transcript->template receive_from_prover(commitment_labels.avm_binary_mem_tag_ctr); commitments.avm_main_pc = transcript->template receive_from_prover(commitment_labels.avm_main_pc); commitments.avm_main_internal_return_ptr = transcript->template receive_from_prover(commitment_labels.avm_main_internal_return_ptr); @@ -161,8 +201,16 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_not); commitments.avm_main_sel_op_eq = transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_eq); + commitments.avm_main_sel_op_and = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_and); + commitments.avm_main_sel_op_or = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_or); + commitments.avm_main_sel_op_xor = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_xor); commitments.avm_main_alu_sel = transcript->template receive_from_prover(commitment_labels.avm_main_alu_sel); + commitments.avm_main_bin_sel = + transcript->template receive_from_prover(commitment_labels.avm_main_bin_sel); commitments.avm_main_in_tag = transcript->template receive_from_prover(commitment_labels.avm_main_in_tag); commitments.avm_main_op_err = @@ -198,7 +246,10 @@ 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.avm_main_bin_op_id = + transcript->template receive_from_prover(commitment_labels.avm_main_bin_op_id); commitments.perm_main_alu = transcript->template receive_from_prover(commitment_labels.perm_main_alu); + commitments.perm_main_bin = transcript->template receive_from_prover(commitment_labels.perm_main_bin); commitments.perm_main_mem_a = transcript->template receive_from_prover(commitment_labels.perm_main_mem_a); commitments.perm_main_mem_b = @@ -211,10 +262,18 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.perm_main_mem_ind_b); commitments.perm_main_mem_ind_c = transcript->template receive_from_prover(commitment_labels.perm_main_mem_ind_c); + commitments.lookup_byte_lengths = + transcript->template receive_from_prover(commitment_labels.lookup_byte_lengths); + commitments.lookup_byte_operations = + transcript->template receive_from_prover(commitment_labels.lookup_byte_operations); commitments.incl_main_tag_err = transcript->template receive_from_prover(commitment_labels.incl_main_tag_err); commitments.incl_mem_tag_err = transcript->template receive_from_prover(commitment_labels.incl_mem_tag_err); + commitments.lookup_byte_lengths_counts = + transcript->template receive_from_prover(commitment_labels.lookup_byte_lengths_counts); + commitments.lookup_byte_operations_counts = + transcript->template receive_from_prover(commitment_labels.lookup_byte_operations_counts); commitments.incl_main_tag_err_counts = transcript->template receive_from_prover(commitment_labels.incl_main_tag_err_counts); commitments.incl_mem_tag_err_counts = 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 0fb368cb1e5..a911c8ae996 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -1,7 +1,13 @@ #include "avm_common.test.hpp" #include "barretenberg/numeric/uint128/uint128.hpp" +#include "barretenberg/vm/tests/helpers.test.hpp" +#include "gtest/gtest.h" #include +#include #include +#include +#include +#include #include namespace tests_avm { @@ -9,12 +15,12 @@ using namespace bb::avm_trace; namespace { -Row common_validate_op_not(std::vector const& trace, - FF const& a, - FF const& c, - FF const& addr_a, - FF const& addr_c, - avm_trace::AvmMemoryTag const tag) +void common_validate_op_not(std::vector const& trace, + FF const& a, + FF const& c, + FF const& addr_a, + FF const& addr_c, + avm_trace::AvmMemoryTag const tag) { // Find the first row enabling the not selector @@ -51,8 +57,94 @@ Row common_validate_op_not(std::vector const& trace, // Check that not selector is set. EXPECT_EQ(row->avm_main_sel_op_not, FF(1)); EXPECT_EQ(alu_row->avm_alu_alu_op_not, FF(1)); + switch (tag) { + // Handle the different mem_tags here since this is part of a + // parameterised test + case AvmMemoryTag::U0: + FAIL() << "Unintialized Mem Tags Disallowed"; + break; + case AvmMemoryTag::U8: + EXPECT_EQ(alu_row->avm_alu_alu_u8_tag, FF(1)); + break; + case AvmMemoryTag::U16: + EXPECT_EQ(alu_row->avm_alu_alu_u16_tag, FF(1)); + break; + case AvmMemoryTag::U32: + EXPECT_EQ(alu_row->avm_alu_alu_u32_tag, FF(1)); + break; + case AvmMemoryTag::U64: + EXPECT_EQ(alu_row->avm_alu_alu_u64_tag, FF(1)); + break; + case AvmMemoryTag::U128: + EXPECT_EQ(alu_row->avm_alu_alu_u128_tag, FF(1)); + break; + case AvmMemoryTag::FF: + FAIL() << "FF Mem Tags Disallowed for bitwise"; + break; + } +} + +void common_validate_bit_op(std::vector const& trace, + uint8_t op_id, + FF const& a, + FF const& b, + FF const& c, + FF const& addr_a, + FF const& addr_b, + FF const& addr_c, + avm_trace::AvmMemoryTag const tag) +{ + + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_xor == FF(1); }); + if (op_id == 0) { + row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_and == FF(1); }); + EXPECT_EQ(row->avm_main_sel_op_and, FF(1)); + } else if (op_id == 1) { + row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_or == FF(1); }); + EXPECT_EQ(row->avm_main_sel_op_or, FF(1)); + } else { + EXPECT_EQ(row->avm_main_sel_op_xor, FF(1)); + } + + // Use the row in the main trace to find the same operation in the alu trace. + FF clk = row->avm_main_clk; + auto bin_row_latched = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { + return r.avm_binary_bin_clk == clk && r.avm_binary_latch == FF(1); + }); + + // Check that both rows were found + EXPECT_TRUE(bin_row_latched != trace.end()); + EXPECT_TRUE(row != trace.end()); + + // Check that the correct result is stored at the expected memory location. + EXPECT_EQ(row->avm_main_ic, c); + EXPECT_EQ(row->avm_main_mem_idx_c, addr_c); + EXPECT_EQ(row->avm_main_mem_op_c, FF(1)); + EXPECT_EQ(row->avm_main_rwc, FF(1)); + + // Check that ia register is correctly set with memory load operations. + EXPECT_EQ(row->avm_main_ia, a); + EXPECT_EQ(row->avm_main_mem_idx_a, addr_a); + EXPECT_EQ(row->avm_main_mem_op_a, FF(1)); + EXPECT_EQ(row->avm_main_rwa, FF(0)); + + // Check that ia register is correctly set with memory load operations. + EXPECT_EQ(row->avm_main_ib, b); + EXPECT_EQ(row->avm_main_mem_idx_b, addr_b); + EXPECT_EQ(row->avm_main_mem_op_b, FF(1)); + EXPECT_EQ(row->avm_main_rwb, FF(0)); + + // Check the instruction tag + EXPECT_EQ(row->avm_main_in_tag, FF(static_cast(tag))); - return *alu_row; + // Check that latched row is the same as what is copied into the main trace + EXPECT_EQ(bin_row_latched->avm_binary_acc_ia, a); + EXPECT_EQ(bin_row_latched->avm_binary_acc_ib, b); + EXPECT_EQ(bin_row_latched->avm_binary_acc_ic, c); + + EXPECT_EQ(bin_row_latched->avm_binary_op_id, op_id); + EXPECT_EQ(bin_row_latched->avm_binary_bin_sel, FF(1)); + EXPECT_EQ(bin_row_latched->avm_binary_instr_tag, static_cast(tag)); } std::vector gen_mutated_trace_not(FF const& a, FF const& c_mutated, avm_trace::AvmMemoryTag tag) @@ -68,6 +160,79 @@ std::vector gen_mutated_trace_not(FF const& a, FF const& c_mutated, avm_tra return trace; } + +// These are the potential failures we handle for the negative tests involving the binary trace. +enum BIT_FAILURES { + IncorrectFactor, + BitDecomposition, + MemTagCtr, + IncorrectAcc, + ByteLookupError, + ByteLengthError, +}; +std::vector gen_mutated_trace_bit(std::vector trace, + std::function&& select_row, + FF const& c_mutated, + BIT_FAILURES fail_mode) +{ + auto main_trace_row = std::ranges::find_if(trace.begin(), trace.end(), select_row); + auto main_clk = main_trace_row->avm_main_clk; + // The corresponding row in the binary trace + auto binary_row = std::ranges::find_if( + trace.begin(), trace.end(), [main_clk](Row r) { return r.avm_binary_bin_clk == main_clk; }); + // The corresponding row in the binary trace where the latch is set to 1 + auto latched_row = std::ranges::find_if(trace.begin(), trace.end(), [main_clk](Row r) { + return r.avm_binary_bin_clk == main_clk && r.avm_binary_latch == FF(1); + }); + switch (fail_mode) { + case IncorrectFactor: { + // Simply zero the factor at the start as the relation checks it is 1. + binary_row->avm_binary_factor = 0; + break; + } + case BitDecomposition: { + // Incrementing the bytes should indicate an incorrect decomposition + binary_row->avm_binary_bin_ic_bytes++; + break; + } + case MemTagCtr: { + // mem_tag_ctr' - mem_tag_ctr = 2, breaking the incrementing relation + binary_row->avm_binary_mem_tag_ctr++; + break; + } + case IncorrectAcc: { + // Accumulator should start at 0; + binary_row->avm_binary_acc_ic++; + break; + } + case ByteLookupError: { + // In the latched row the bytes = 0, this sets it to a value where the lookup + // involving a_bytes and b_bytes are incorrect + latched_row->avm_binary_bin_ic_bytes = static_cast(uint128_t{ c_mutated }); + break; + } + case ByteLengthError: + auto latch_index = static_cast(std::distance(trace.begin(), latched_row)); + // Set the latched row to be 1 earlier than it should be, this triggers the byte length lookup table check. + trace.at(latch_index - 1).avm_binary_latch = FF(1); + // We need to set the result here or it will be deemed incorrectly copied in the equivalence check to main. + trace.at(latch_index - 1).avm_binary_acc_ic = c_mutated; + // We need to zero out the previously latched row so we dont trigger any other relation checks + latched_row->avm_binary_mem_tag_ctr = 0; + latched_row->avm_binary_bin_sel = 0; + latched_row->avm_binary_latch = 0; + latched_row->avm_binary_factor = 0; + latched_row->avm_binary_acc_ia = 0; + latched_row->avm_binary_acc_ib = 0; + latched_row->avm_binary_acc_ic = 0; + latched_row->avm_binary_bin_ia_bytes = 0; + latched_row->avm_binary_bin_ib_bytes = 0; + latched_row->avm_binary_bin_ic_bytes = 0; + break; + } + + return trace; +} } // namespace class AvmBitwiseTests : public ::testing::Test { @@ -79,18 +244,79 @@ class AvmBitwiseTests : public ::testing::Test { void SetUp() override { srs::init_crs_factory("../srs_db/ignition"); }; }; -class AvmBitwiseTestsU8 : public AvmBitwiseTests {}; -class AvmBitwiseTestsU16 : public AvmBitwiseTests {}; -class AvmBitwiseTestsU32 : public AvmBitwiseTests {}; -class AvmBitwiseTestsU64 : public AvmBitwiseTests {}; -class AvmBitwiseTestsU128 : public AvmBitwiseTests {}; +/****************************************************************************** + * + * Helpers to set up Test Params + * + ******************************************************************************/ -class AvmBitwiseNegativeTestsFF : public AvmBitwiseTests {}; -class AvmBitwiseNegativeTestsU8 : public AvmBitwiseTests {}; -class AvmBitwiseNegativeTestsU16 : public AvmBitwiseTests {}; -class AvmBitwiseNegativeTestsU32 : public AvmBitwiseTests {}; -class AvmBitwiseNegativeTestsU64 : public AvmBitwiseTests {}; -class AvmBitwiseNegativeTestsU128 : public AvmBitwiseTests {}; +using ThreeOpParamRow = std::tuple, AvmMemoryTag>; +using TwoOpParamRow = std::tuple, AvmMemoryTag>; +std::vector mem_tags{ + { AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } +}; + +std::vector> positive_op_not_test_values = { { { 1, 254 }, + { 512, 65'023 }, + { 131'072, 4'294'836'223LLU }, + { 0x100000000LLU, 0xfffffffeffffffffLLU }, + { uint128_t{ 0x4000000000000 } << 64, + (uint128_t{ 0xfffbffffffffffff } << 64) + + uint128_t{ 0xffffffffffffffff } } } }; + +// This is essentially a zip while we wait for C++23 +std::vector gen_two_op_params(std::vector> operands, + std::vector mem_tags) +{ + std::vector params; + for (size_t i = 0; i < 5; i++) { + params.emplace_back(operands[i], mem_tags[i]); + } + return params; +} + +std::vector> positive_op_and_test_values = { + { { 1, 1, 1 }, + { 5323, 321, 65 }, + { 13793, 10590617LLU, 4481 }, + { 0x7bff744e3cdf79LLU, 0x14ccccccccb6LLU, 0x14444c0ccc30LLU }, + { (uint128_t{ 0xb900000000000001 } << 64), + (uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }, + (uint128_t{ 0x1000000000000000 } << 64) } } +}; + +std::vector> positive_op_or_test_values = { + { { 1, 1, 1 }, + { 5323, 321, 0x15cb }, + { 13793, 10590617LLU, 0xa1bdf9 }, + { 0x7bff744e3cdf79LLU, 0x14ccccccccb6LLU, 0x7bfffccefcdfffLLU }, + { (uint128_t{ 0xb900000000000000 } << 64), + (uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }, + (uint128_t{ 0xb906021301080000 } << 64) + uint128_t{ 0x0001080876844827 } } } +}; +std::vector> positive_op_xor_test_values = { + { { 1, 1, 0 }, + { 5323, 321, 0x158a }, + { 13793, 10590617LLU, 0xa1ac78 }, + { 0x7bff744e3cdf79LLU, 0x14ccccccccb6LLU, 0x7bebb882f013cf }, + { (uint128_t{ 0xb900000000000001 } << 64), + (uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }, + (uint128_t{ 0xa906021301080001 } << 64) + uint128_t{ 0x0001080876844827 } } } +}; +std::vector gen_three_op_params(std::vector> operands, + std::vector mem_tags) +{ + std::vector params; + for (size_t i = 0; i < 5; i++) { + params.emplace_back(operands[i], mem_tags[i]); + } + return params; +} + +class AvmBitwiseTestsNot : public AvmBitwiseTests, public testing::WithParamInterface {}; +class AvmBitwiseTestsAnd : public AvmBitwiseTests, public testing::WithParamInterface {}; +class AvmBitwiseTestsOr : public AvmBitwiseTests, public testing::WithParamInterface {}; +class AvmBitwiseTestsXor : public AvmBitwiseTests, public testing::WithParamInterface {}; /****************************************************************************** * @@ -101,79 +327,90 @@ class AvmBitwiseNegativeTestsU128 : public AvmBitwiseTests {}; ******************************************************************************/ /****************************************************************************** - * Positive Tests - U8 + * Positive Tests ******************************************************************************/ - -TEST_F(AvmBitwiseTestsU8, BitwiseNot) +TEST_P(AvmBitwiseTestsNot, ParamTest) { - trace_builder.set(1, 0, AvmMemoryTag::U8); // Memory Layout: [1,0,0,...] - trace_builder.op_not(0, 0, 1, AvmMemoryTag::U8); // [1,254,0,0,....] + const auto [operands, mem_tag] = GetParam(); + const auto [a, output] = operands; + trace_builder.set(a, 0, mem_tag); + trace_builder.op_not(0, 0, 1, mem_tag); // [1,254,0,0,....] trace_builder.return_op(0, 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); - - EXPECT_EQ(alu_row.avm_alu_alu_u8_tag, FF(1)); + FF ff_a = FF(uint256_t::from_uint128(a)); + FF ff_output = FF(uint256_t::from_uint128(output)); + common_validate_op_not(trace, ff_a, ff_output, FF(0), FF(1), mem_tag); validate_trace_proof(std::move(trace)); } -TEST_F(AvmBitwiseTestsU16, BitwiseNot) -{ - trace_builder.set(512, 0, AvmMemoryTag::U16); // Memory Layout: [512,0,0,...] - trace_builder.op_not(0, 0, 1, AvmMemoryTag::U16); // [512,65023,0,0,0,....] - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); +INSTANTIATE_TEST_SUITE_P(AvmBitwiseTests, + AvmBitwiseTestsNot, + testing::ValuesIn(gen_two_op_params(positive_op_not_test_values, mem_tags))); - auto alu_row = common_validate_op_not(trace, FF(512), FF(65'023), FF(0), FF(1), AvmMemoryTag::U16); - - EXPECT_EQ(alu_row.avm_alu_alu_u16_tag, FF(1)); - validate_trace_proof(std::move(trace)); -} - -TEST_F(AvmBitwiseTestsU32, BitwiseNot) +TEST_P(AvmBitwiseTestsAnd, AllAndTest) { - trace_builder.set(131'072, 0, AvmMemoryTag::U32); // Memory Layout: [131072,0,0,...] - trace_builder.op_not(0, 0, 1, AvmMemoryTag::U32); // [131072,4294836223,,0,0,....] - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + const auto [operands, mem_tag] = GetParam(); + const auto [a, b, output] = operands; + trace_builder.set(a, 0, mem_tag); + trace_builder.set(b, 1, mem_tag); + trace_builder.op_and(0, 1, 2, mem_tag); + trace_builder.return_op(0, 2, 1); - auto alu_row = common_validate_op_not(trace, FF(131'072), FF(4'294'836'223LLU), FF(0), FF(1), AvmMemoryTag::U32); - - EXPECT_EQ(alu_row.avm_alu_alu_u32_tag, FF(1)); + auto trace = trace_builder.finalize(); + FF ff_a = FF(uint256_t::from_uint128(a)); + FF ff_b = FF(uint256_t::from_uint128(b)); + FF ff_output = FF(uint256_t::from_uint128(output)); + // EXPECT_EQ(1, 2) << "a ^ b " << (a ^ b) << '\n'; + common_validate_bit_op(trace, 0, ff_a, ff_b, ff_output, FF(0), FF(1), FF(2), mem_tag); validate_trace_proof(std::move(trace)); } +INSTANTIATE_TEST_SUITE_P(AvmBitwiseTests, + AvmBitwiseTestsAnd, + testing::ValuesIn(gen_three_op_params(positive_op_and_test_values, mem_tags))); -TEST_F(AvmBitwiseTestsU64, BitwiseNot) +TEST_P(AvmBitwiseTestsOr, AllOrTest) { - trace_builder.set(0x100000000LLU, 0, AvmMemoryTag::U64); // Memory Layout: [8589934592,0,0,...] - trace_builder.op_not(0, 0, 1, AvmMemoryTag::U64); // [8589934592,18446744069414584319,0,0,....] - trace_builder.return_op(0, 0, 0); + const auto [operands, mem_tag] = GetParam(); + const auto [a, b, output] = operands; + trace_builder.set(a, 0, mem_tag); + trace_builder.set(b, 1, mem_tag); + trace_builder.op_or(0, 1, 2, mem_tag); + trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); - auto alu_row = - common_validate_op_not(trace, FF(0x100000000LLU), FF(0xfffffffeffffffffLLU), FF(0), FF(1), AvmMemoryTag::U64); + FF ff_a = FF(uint256_t::from_uint128(a)); + FF ff_b = FF(uint256_t::from_uint128(b)); + FF ff_output = FF(uint256_t::from_uint128(output)); - EXPECT_EQ(alu_row.avm_alu_alu_u64_tag, FF(1)); + common_validate_bit_op(trace, 1, ff_a, ff_b, ff_output, FF(0), FF(1), FF(2), mem_tag); validate_trace_proof(std::move(trace)); } +INSTANTIATE_TEST_SUITE_P(AvmBitwiseTests, + AvmBitwiseTestsOr, + testing::ValuesIn(gen_three_op_params(positive_op_or_test_values, mem_tags))); -TEST_F(AvmBitwiseTestsU128, BitwiseNot) +TEST_P(AvmBitwiseTestsXor, AllXorTest) { - - uint128_t const a = uint128_t{ 0x4000000000000 } << 64; - trace_builder.set(a, 0, AvmMemoryTag::U128); - trace_builder.op_not(0, 0, 1, AvmMemoryTag::U128); - trace_builder.return_op(0, 0, 0); + const auto [operands, mem_tag] = GetParam(); + const auto [a, b, output] = operands; + trace_builder.set(a, 0, mem_tag); + trace_builder.set(b, 1, mem_tag); + trace_builder.op_xor(0, 1, 2, mem_tag); + trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); - uint128_t const res = (uint128_t{ 0xfffbffffffffffff } << 64) + uint128_t{ 0xffffffffffffffff }; - auto alu_row = common_validate_op_not( - trace, FF(uint256_t::from_uint128(a)), FF(uint256_t::from_uint128(res)), FF(0), FF(1), AvmMemoryTag::U128); + FF ff_a = FF(uint256_t::from_uint128(a)); + FF ff_b = FF(uint256_t::from_uint128(b)); + FF ff_output = FF(uint256_t::from_uint128(output)); - EXPECT_EQ(alu_row.avm_alu_alu_u128_tag, FF(1)); + common_validate_bit_op(trace, 2, ff_a, ff_b, ff_output, FF(0), FF(1), FF(2), mem_tag); validate_trace_proof(std::move(trace)); } +INSTANTIATE_TEST_SUITE_P(AvmBitwiseTests, + AvmBitwiseTestsXor, + testing::ValuesIn(gen_three_op_params(positive_op_xor_test_values, mem_tags))); + /****************************************************************************** * * NEGATIVE TESTS - Finite Field Type @@ -181,10 +418,99 @@ TEST_F(AvmBitwiseTestsU128, BitwiseNot) ****************************************************************************** * See Avm_arithmetic.cpp for explanation of negative tests ******************************************************************************/ +using EXPECTED_ERRORS = std::tuple; + +class AvmBitwiseNegativeTestsAnd : public AvmBitwiseTests, + public testing::WithParamInterface> {}; +class AvmBitwiseNegativeTestsOr : public AvmBitwiseTests, + public testing::WithParamInterface> {}; +class AvmBitwiseNegativeTestsXor : public AvmBitwiseTests, + public testing::WithParamInterface> {}; +class AvmBitwiseNegativeTestsFF : public AvmBitwiseTests {}; +class AvmBitwiseNegativeTestsU8 : public AvmBitwiseTests {}; +class AvmBitwiseNegativeTestsU16 : public AvmBitwiseTests {}; +class AvmBitwiseNegativeTestsU32 : public AvmBitwiseTests {}; +class AvmBitwiseNegativeTestsU64 : public AvmBitwiseTests {}; +class AvmBitwiseNegativeTestsU128 : public AvmBitwiseTests {}; +std::vector> bit_failures = { + { "ACC_REL_C", BIT_FAILURES::IncorrectAcc }, + { "ACC_REL_C", BIT_FAILURES::BitDecomposition }, + { "MEM_TAG_REL", BIT_FAILURES::MemTagCtr }, + { "FACTOR_REL", BIT_FAILURES::IncorrectFactor }, + { "LOOKUP_BYTE_LENGTHS", BIT_FAILURES::ByteLengthError }, + { "LOOKUP_BYTE_OPERATIONS", BIT_FAILURES::ByteLookupError } +}; +std::vector neg_test_and = { { { 13793, 10590617LLU, 4481 }, AvmMemoryTag::U32 } }; +// For the negativ Or and Xor we carefully select inputs such that the most significant 16-bits are zero for both +// operands This makes it easier when doing to the lookup-based error checks since we dont have to worry about the +// equivalence check to main. +std::vector neg_test_or = { { { 13793, 31385, 32761 }, AvmMemoryTag::U32 } }; +std::vector neg_test_xor = { { { 13793, 31385, 20344 }, AvmMemoryTag::U32 } }; /****************************************************************************** * Negative Tests - FF ******************************************************************************/ +TEST_P(AvmBitwiseNegativeTestsAnd, AllNegativeTests) +{ + const auto [failure, params] = GetParam(); + const auto [failure_string, failure_mode] = failure; + const auto [operands, mem_tag] = params; + const auto [a, b, output] = operands; + auto trace_builder = avm_trace::AvmTraceBuilder(); + trace_builder.set(uint128_t{ a }, 0, mem_tag); + trace_builder.set(uint128_t{ b }, 1, mem_tag); + trace_builder.op_and(0, 1, 2, mem_tag); + trace_builder.halt(); + auto trace = trace_builder.finalize(); + FF ff_output = FF(uint256_t::from_uint128(output)); + std::function&& select_row = [](Row r) { return r.avm_main_sel_op_and == FF(1); }; + trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), failure_string); +} +INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, + AvmBitwiseNegativeTestsAnd, + testing::Combine(testing::ValuesIn(bit_failures), testing::ValuesIn(neg_test_and))); + +TEST_P(AvmBitwiseNegativeTestsOr, AllNegativeTests) +{ + const auto [failure, params] = GetParam(); + const auto [failure_string, failure_mode] = failure; + const auto [operands, mem_tag] = params; + const auto [a, b, output] = operands; + auto trace_builder = avm_trace::AvmTraceBuilder(); + trace_builder.set(uint128_t{ a }, 0, mem_tag); + trace_builder.set(uint128_t{ b }, 1, mem_tag); + trace_builder.op_or(0, 1, 2, mem_tag); + trace_builder.halt(); + auto trace = trace_builder.finalize(); + FF ff_output = FF(uint256_t::from_uint128(output)); + std::function&& select_row = [](Row r) { return r.avm_main_sel_op_or == FF(1); }; + trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), failure_string); +} +INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, + AvmBitwiseNegativeTestsOr, + testing::Combine(testing::ValuesIn(bit_failures), testing::ValuesIn(neg_test_or))); +TEST_P(AvmBitwiseNegativeTestsXor, AllNegativeTests) +{ + const auto [failure, params] = GetParam(); + const auto [failure_string, failure_mode] = failure; + const auto [operands, mem_tag] = params; + const auto [a, b, output] = operands; + auto trace_builder = avm_trace::AvmTraceBuilder(); + trace_builder.set(uint128_t{ a }, 0, mem_tag); + trace_builder.set(uint128_t{ b }, 1, mem_tag); + trace_builder.op_xor(0, 1, 2, mem_tag); + trace_builder.halt(); + auto trace = trace_builder.finalize(); + FF ff_output = FF(uint256_t::from_uint128(output)); + std::function&& select_row = [](Row r) { return r.avm_main_sel_op_xor == FF(1); }; + trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), failure_string) +} +INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, + AvmBitwiseNegativeTestsXor, + testing::Combine(testing::ValuesIn(bit_failures), testing::ValuesIn(neg_test_xor))); TEST_F(AvmBitwiseNegativeTestsFF, UndefinedOverFF) { From 514f3cfb98c68a1cccc16ee11a6dff6c60258d6b Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Thu, 21 Mar 2024 16:32:56 +0000 Subject: [PATCH 2/8] feat: horner's method for factor, latch/mem_tag simplification --- barretenberg/cpp/pil/avm/avm_binary.pil | 18 +- .../generated/avm/INCL_MAIN_TAG_ERR.hpp | 167 ------------------ .../relations/generated/avm/PERM_MAIN_ALU.hpp | 126 ------------- .../generated/avm/PERM_MAIN_MEM_A.hpp | 106 ----------- .../generated/avm/PERM_MAIN_MEM_B.hpp | 106 ----------- .../generated/avm/PERM_MAIN_MEM_C.hpp | 106 ----------- .../relations/generated/avm/avm_alu.hpp | 86 ++++----- .../relations/generated/avm/avm_binary.hpp | 77 +++----- .../relations/generated/avm/avm_main.hpp | 100 +++++------ .../relations/generated/avm/avm_mem.hpp | 50 +++--- .../relations/generated/avm/declare_views.hpp | 26 ++- .../vm/avm_trace/avm_binary_trace.cpp | 34 ++-- .../barretenberg/vm/avm_trace/avm_trace.cpp | 3 +- .../vm/generated/avm_circuit_builder.hpp | 58 +++--- .../barretenberg/vm/generated/avm_flavor.hpp | 136 +++++--------- .../vm/tests/avm_bitwise.test.cpp | 19 +- 16 files changed, 253 insertions(+), 965 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/INCL_MAIN_TAG_ERR.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_ALU.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_A.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_B.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_C.hpp diff --git a/barretenberg/cpp/pil/avm/avm_binary.pil b/barretenberg/cpp/pil/avm/avm_binary.pil index f27e906a821..876e76374d5 100644 --- a/barretenberg/cpp/pil/avm/avm_binary.pil +++ b/barretenberg/cpp/pil/avm/avm_binary.pil @@ -34,18 +34,6 @@ namespace avm_binary(256); // latch is restricted to be a boolean latch * (1 - latch) = 0; - // If latch is 0, the next factor must be the current factor * 256. - pol NO_LATCH = (1 - latch) * (factor * 256); - // If latch is 1 or this is the first row in the trace, then the next factor starts at 1; - latch * avm_main.first = 0; // latch and first cannot both be 1 - - // Given the above condition, LATCH_OR_FIRST is guaranteed to be 0 or 1; - pol LATCH_OR_FIRST = latch + avm_main.first; - - // Both conditions are mutually exclusive, (i.e. "xor" since Factor initially starts at 0). - #[FACTOR_REL] - factor' = (NO_LATCH + LATCH_OR_FIRST) * bin_sel'; - // To support dynamically sized memory operands we use a counter against a lookup // This counter goes from [0, MEM_TAG] where MEM_TAG is the number of bytes in the // corresponding integer. i.e. MEM_TAG is between 1 (U8) and 16(U128). @@ -65,9 +53,9 @@ namespace avm_binary(256); avm_byte_lookup.bin_sel {avm_byte_lookup.table_op_id, avm_byte_lookup.table_input_a,avm_byte_lookup.table_input_b, avm_byte_lookup.table_output}; #[ACC_REL_A] - acc_ia' = (acc_ia * (1 - latch) + bin_ia_bytes * factor) * bin_sel'; + acc_ia' = (bin_ia_bytes + 256 * acc_ia) * (1 - latch); #[ACC_REL_B] - acc_ib' = (acc_ib * (1 - latch) + bin_ib_bytes * factor) * bin_sel'; + acc_ib' = (bin_ib_bytes + 256 * acc_ib) * (1 - latch); #[ACC_REL_C] - acc_ic' = (acc_ic * (1 - latch) + bin_ic_bytes * factor) * bin_sel'; + acc_ic' = (bin_ic_bytes + 256 * acc_ic) * (1 - latch); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/INCL_MAIN_TAG_ERR.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/INCL_MAIN_TAG_ERR.hpp deleted file mode 100644 index 093947b109b..00000000000 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/INCL_MAIN_TAG_ERR.hpp +++ /dev/null @@ -1,167 +0,0 @@ - - -#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 INCL_MAIN_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.INCL_MAIN_TAG_ERR, - in.INCL_MAIN_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.INCL_MAIN_TAG_ERR, - in.INCL_MAIN_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 INCL_MAIN_TAG_ERR_relation = GenericLookupRelation; -template using INCL_MAIN_TAG_ERR = GenericLookup; - -} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_ALU.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_ALU.hpp deleted file mode 100644 index a493df59414..00000000000 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_ALU.hpp +++ /dev/null @@ -1,126 +0,0 @@ - - -#pragma once - -#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" - -#include -#include - -namespace bb { - -class PERM_MAIN_ALU_permutation_settings { - public: - // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 10; - - /** - * @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.avm_main_alu_sel == 1 || in.avm_alu_alu_sel == 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.PERM_MAIN_ALU, - in.avm_main_alu_sel, - in.avm_main_alu_sel, - in.avm_alu_alu_sel, - in.avm_main_clk, - in.avm_main_ia, - in.avm_main_ib, - in.avm_main_ic, - in.avm_main_sel_op_add, - in.avm_main_sel_op_sub, - in.avm_main_sel_op_mul, - in.avm_main_sel_op_eq, - in.avm_main_sel_op_not, - in.avm_main_in_tag, - in.avm_alu_alu_clk, - in.avm_alu_alu_ia, - in.avm_alu_alu_ib, - in.avm_alu_alu_ic, - in.avm_alu_alu_op_add, - in.avm_alu_alu_op_sub, - in.avm_alu_alu_op_mul, - in.avm_alu_alu_op_eq, - in.avm_alu_alu_op_not, - in.avm_alu_alu_in_tag); - } - - /** - * @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.PERM_MAIN_ALU, - in.avm_main_alu_sel, - in.avm_main_alu_sel, - in.avm_alu_alu_sel, - in.avm_main_clk, - in.avm_main_ia, - in.avm_main_ib, - in.avm_main_ic, - in.avm_main_sel_op_add, - in.avm_main_sel_op_sub, - in.avm_main_sel_op_mul, - in.avm_main_sel_op_eq, - in.avm_main_sel_op_not, - in.avm_main_in_tag, - in.avm_alu_alu_clk, - in.avm_alu_alu_ia, - in.avm_alu_alu_ib, - in.avm_alu_alu_ic, - in.avm_alu_alu_op_add, - in.avm_alu_alu_op_sub, - in.avm_alu_alu_op_mul, - in.avm_alu_alu_op_eq, - in.avm_alu_alu_op_not, - in.avm_alu_alu_in_tag); - } -}; - -template -using PERM_MAIN_ALU_relation = GenericPermutationRelation; -template using PERM_MAIN_ALU = GenericPermutation; - -} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_A.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_A.hpp deleted file mode 100644 index 777eb91bfb0..00000000000 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_A.hpp +++ /dev/null @@ -1,106 +0,0 @@ - - -#pragma once - -#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" - -#include -#include - -namespace bb { - -class PERM_MAIN_MEM_A_permutation_settings { - public: - // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 5; - - /** - * @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.avm_main_mem_op_a == 1 || in.avm_mem_m_op_a == 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.PERM_MAIN_MEM_A, - in.avm_main_mem_op_a, - in.avm_main_mem_op_a, - in.avm_mem_m_op_a, - in.avm_main_clk, - in.avm_main_mem_idx_a, - in.avm_main_ia, - in.avm_main_rwa, - in.avm_main_in_tag, - in.avm_mem_m_clk, - in.avm_mem_m_addr, - in.avm_mem_m_val, - in.avm_mem_m_rw, - in.avm_mem_m_in_tag); - } - - /** - * @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.PERM_MAIN_MEM_A, - in.avm_main_mem_op_a, - in.avm_main_mem_op_a, - in.avm_mem_m_op_a, - in.avm_main_clk, - in.avm_main_mem_idx_a, - in.avm_main_ia, - in.avm_main_rwa, - in.avm_main_in_tag, - in.avm_mem_m_clk, - in.avm_mem_m_addr, - in.avm_mem_m_val, - in.avm_mem_m_rw, - in.avm_mem_m_in_tag); - } -}; - -template -using PERM_MAIN_MEM_A_relation = GenericPermutationRelation; -template using PERM_MAIN_MEM_A = GenericPermutation; - -} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_B.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_B.hpp deleted file mode 100644 index 9facbaf2594..00000000000 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_B.hpp +++ /dev/null @@ -1,106 +0,0 @@ - - -#pragma once - -#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" - -#include -#include - -namespace bb { - -class PERM_MAIN_MEM_B_permutation_settings { - public: - // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 5; - - /** - * @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.avm_main_mem_op_b == 1 || in.avm_mem_m_op_b == 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.PERM_MAIN_MEM_B, - in.avm_main_mem_op_b, - in.avm_main_mem_op_b, - in.avm_mem_m_op_b, - in.avm_main_clk, - in.avm_main_mem_idx_b, - in.avm_main_ib, - in.avm_main_rwb, - in.avm_main_in_tag, - in.avm_mem_m_clk, - in.avm_mem_m_addr, - in.avm_mem_m_val, - in.avm_mem_m_rw, - in.avm_mem_m_in_tag); - } - - /** - * @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.PERM_MAIN_MEM_B, - in.avm_main_mem_op_b, - in.avm_main_mem_op_b, - in.avm_mem_m_op_b, - in.avm_main_clk, - in.avm_main_mem_idx_b, - in.avm_main_ib, - in.avm_main_rwb, - in.avm_main_in_tag, - in.avm_mem_m_clk, - in.avm_mem_m_addr, - in.avm_mem_m_val, - in.avm_mem_m_rw, - in.avm_mem_m_in_tag); - } -}; - -template -using PERM_MAIN_MEM_B_relation = GenericPermutationRelation; -template using PERM_MAIN_MEM_B = GenericPermutation; - -} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_C.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_C.hpp deleted file mode 100644 index 51c6d002f04..00000000000 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/PERM_MAIN_MEM_C.hpp +++ /dev/null @@ -1,106 +0,0 @@ - - -#pragma once - -#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" - -#include -#include - -namespace bb { - -class PERM_MAIN_MEM_C_permutation_settings { - public: - // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 5; - - /** - * @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.avm_main_mem_op_c == 1 || in.avm_mem_m_op_c == 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.PERM_MAIN_MEM_C, - in.avm_main_mem_op_c, - in.avm_main_mem_op_c, - in.avm_mem_m_op_c, - in.avm_main_clk, - in.avm_main_mem_idx_c, - in.avm_main_ic, - in.avm_main_rwc, - in.avm_main_in_tag, - in.avm_mem_m_clk, - in.avm_mem_m_addr, - in.avm_mem_m_val, - in.avm_mem_m_rw, - in.avm_mem_m_in_tag); - } - - /** - * @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.PERM_MAIN_MEM_C, - in.avm_main_mem_op_c, - in.avm_main_mem_op_c, - in.avm_mem_m_op_c, - in.avm_main_clk, - in.avm_main_mem_idx_c, - in.avm_main_ic, - in.avm_main_rwc, - in.avm_main_in_tag, - in.avm_mem_m_clk, - in.avm_mem_m_addr, - in.avm_mem_m_val, - in.avm_mem_m_rw, - in.avm_mem_m_in_tag); - } -}; - -template -using PERM_MAIN_MEM_C_relation = GenericPermutationRelation; -template using PERM_MAIN_MEM_C = GenericPermutation; - -} // namespace bb 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 24db1fe7b49..d4381548898 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,77 +7,77 @@ namespace bb::Avm_vm { template struct Avm_aluRow { - FF avm_alu_alu_u16_r4{}; - FF avm_alu_alu_in_tag{}; - FF avm_alu_alu_u16_r2{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_ib{}; - FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u64_r0{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u8_tag{}; + FF avm_alu_alu_u64_tag{}; FF avm_alu_alu_u16_r1{}; - FF avm_alu_alu_op_add{}; - FF avm_alu_alu_u16_r6{}; - FF avm_alu_alu_u32_tag{}; - FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r1_shift{}; + FF avm_alu_alu_u8_r0{}; + FF avm_alu_alu_ia{}; FF avm_alu_alu_ic{}; FF avm_alu_alu_op_not{}; - FF avm_alu_alu_op_mul{}; + FF avm_alu_alu_u16_r3_shift{}; + FF avm_alu_alu_cf{}; + FF avm_alu_alu_sel{}; + FF avm_alu_alu_u16_r6{}; + FF avm_alu_alu_u16_r2{}; FF avm_alu_alu_u16_tag{}; FF avm_alu_alu_u16_r0{}; - FF avm_alu_alu_u8_tag{}; + FF avm_alu_alu_op_mul{}; + FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_u128_tag{}; + FF avm_alu_alu_u16_r3{}; FF avm_alu_alu_u16_r5{}; - FF avm_alu_alu_u64_tag{}; - FF avm_alu_alu_u8_r0{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_u16_r1_shift{}; + FF avm_alu_alu_op_eq_diff_inv{}; FF avm_alu_alu_u8_r1{}; - FF avm_alu_alu_u16_r5_shift{}; - FF avm_alu_alu_u16_r3{}; - FF avm_alu_alu_cf{}; - FF avm_alu_alu_ia{}; - FF avm_alu_alu_op_eq{}; - FF avm_alu_alu_sel{}; + FF avm_alu_alu_u32_tag{}; + FF avm_alu_alu_op_add{}; + FF avm_alu_alu_u16_r4{}; + FF avm_alu_alu_u16_r7{}; FF avm_alu_alu_op_sub{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_op_eq_diff_inv{}; - FF avm_alu_alu_u128_tag{}; + FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_alu_alu_op_eq{}; + FF avm_alu_alu_in_tag{}; + FF avm_alu_alu_ib{}; FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r7{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u64_r0{}; + FF avm_alu_alu_u16_r5_shift{}; }; inline std::string get_relation_label_avm_alu(int index) { switch (index) { - case 17: - return "ALU_FF_NOT_XOR"; - case 16: return "ALU_MULTIPLICATION_OUT_U128"; - case 18: - return "ALU_OP_NOT"; - - case 12: - return "ALU_MUL_COMMON_1"; - case 20: return "ALU_OP_EQ"; + case 9: + return "ALU_ADD_SUB_1"; + + case 19: + return "ALU_RES_IS_BOOL"; + case 10: return "ALU_ADD_SUB_2"; + case 11: + return "ALU_MULTIPLICATION_FF"; + case 13: return "ALU_MUL_COMMON_2"; - case 19: - return "ALU_RES_IS_BOOL"; + case 12: + return "ALU_MUL_COMMON_1"; - case 9: - return "ALU_ADD_SUB_1"; + case 17: + return "ALU_FF_NOT_XOR"; - case 11: - return "ALU_MULTIPLICATION_FF"; + case 18: + return "ALU_OP_NOT"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp index bcaacefa4aa..2e8769d9ca8 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp @@ -7,42 +7,35 @@ namespace bb::Avm_vm { template struct Avm_binaryRow { - FF avm_binary_bin_sel_shift{}; - FF avm_binary_acc_ic_shift{}; - FF avm_binary_bin_ib_bytes{}; FF avm_binary_acc_ia{}; - FF avm_main_first{}; - FF avm_binary_acc_ib_shift{}; - FF avm_binary_factor{}; - FF avm_binary_acc_ic{}; - FF avm_binary_factor_shift{}; FF avm_binary_mem_tag_ctr_shift{}; + FF avm_binary_bin_sel{}; FF avm_binary_mem_tag_ctr{}; - FF avm_binary_latch{}; - FF avm_binary_bin_ia_bytes{}; - FF avm_binary_acc_ia_shift{}; + FF avm_binary_bin_ib_bytes{}; FF avm_binary_acc_ib{}; - FF avm_binary_bin_sel{}; + FF avm_binary_acc_ic_shift{}; + FF avm_binary_acc_ic{}; + FF avm_binary_latch{}; FF avm_binary_bin_ic_bytes{}; + FF avm_binary_acc_ib_shift{}; + FF avm_binary_acc_ia_shift{}; + FF avm_binary_bin_ia_bytes{}; }; inline std::string get_relation_label_avm_binary(int index) { switch (index) { - case 6: + case 4: return "ACC_REL_B"; - case 5: + case 3: return "ACC_REL_A"; - case 7: - return "ACC_REL_C"; - - case 4: + case 2: return "MEM_TAG_REL"; - case 3: - return "FACTOR_REL"; + case 5: + return "ACC_REL_C"; } return std::to_string(index); } @@ -51,8 +44,8 @@ template class avm_binaryImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 5, 4, 4, 4, 4, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 4, 4, 4, 4, }; template @@ -82,7 +75,8 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(2); - auto tmp = (avm_binary_latch * avm_main_first); + auto tmp = (avm_binary_mem_tag_ctr_shift - + (((avm_binary_mem_tag_ctr + FF(1)) * (-avm_binary_latch + FF(1))) * avm_binary_bin_sel)); tmp *= scaling_factor; std::get<2>(evals) += tmp; } @@ -90,9 +84,8 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(3); - auto tmp = (avm_binary_factor_shift - ((((-avm_binary_latch + FF(1)) * (avm_binary_factor * FF(256))) + - (avm_binary_latch + avm_main_first)) * - avm_binary_bin_sel_shift)); + auto tmp = (avm_binary_acc_ia_shift - + ((avm_binary_bin_ia_bytes + (avm_binary_acc_ia * FF(256))) * (-avm_binary_latch + FF(1)))); tmp *= scaling_factor; std::get<3>(evals) += tmp; } @@ -100,8 +93,8 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(4); - auto tmp = (avm_binary_mem_tag_ctr_shift - - (((avm_binary_mem_tag_ctr + FF(1)) * (-avm_binary_latch + FF(1))) * avm_binary_bin_sel)); + auto tmp = (avm_binary_acc_ib_shift - + ((avm_binary_bin_ib_bytes + (avm_binary_acc_ib * FF(256))) * (-avm_binary_latch + FF(1)))); tmp *= scaling_factor; std::get<4>(evals) += tmp; } @@ -109,35 +102,11 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(5); - auto tmp = - (avm_binary_acc_ia_shift - - (((avm_binary_acc_ia * (-avm_binary_latch + FF(1))) + (avm_binary_bin_ia_bytes * avm_binary_factor)) * - avm_binary_bin_sel_shift)); + auto tmp = (avm_binary_acc_ic_shift - + ((avm_binary_bin_ic_bytes + (avm_binary_acc_ic * FF(256))) * (-avm_binary_latch + FF(1)))); tmp *= scaling_factor; std::get<5>(evals) += tmp; } - // Contribution 6 - { - Avm_DECLARE_VIEWS(6); - - auto tmp = - (avm_binary_acc_ib_shift - - (((avm_binary_acc_ib * (-avm_binary_latch + FF(1))) + (avm_binary_bin_ib_bytes * avm_binary_factor)) * - avm_binary_bin_sel_shift)); - tmp *= scaling_factor; - std::get<6>(evals) += tmp; - } - // Contribution 7 - { - Avm_DECLARE_VIEWS(7); - - auto tmp = - (avm_binary_acc_ic_shift - - (((avm_binary_acc_ic * (-avm_binary_latch + FF(1))) + (avm_binary_bin_ic_bytes * avm_binary_factor)) * - avm_binary_bin_sel_shift)); - tmp *= scaling_factor; - std::get<7>(evals) += tmp; - } } }; 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 854bb5ad6d7..6c92c06bb39 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -7,82 +7,82 @@ namespace bb::Avm_vm { template struct Avm_mainRow { - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_mem_idx_b{}; - FF avm_main_sel_op_add{}; - FF avm_main_ind_op_b{}; FF avm_main_sel_op_mul{}; - FF avm_main_mem_op_b{}; - FF avm_main_rwc{}; - FF avm_main_ind_op_c{}; - FF avm_main_mem_op_c{}; FF avm_main_sel_halt{}; - FF avm_main_sel_op_or{}; - FF avm_main_tag_err{}; - FF avm_main_sel_op_sub{}; - FF avm_main_bin_op_id{}; - FF avm_main_sel_op_not{}; - FF avm_main_ic{}; - FF avm_main_sel_jump{}; + FF avm_main_inv{}; + FF avm_main_bin_sel{}; FF avm_main_sel_op_and{}; - FF avm_main_mem_op_a{}; + FF avm_main_sel_op_not{}; + FF avm_main_first{}; + FF avm_main_internal_return_ptr{}; + FF avm_main_bin_op_id{}; + FF avm_main_mem_op_c{}; + FF avm_main_sel_op_xor{}; FF avm_main_op_err{}; + FF avm_main_ib{}; + FF avm_main_rwb{}; + FF avm_main_pc{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_sel_op_sub{}; + FF avm_main_sel_op_eq{}; + FF avm_main_tag_err{}; FF avm_main_sel_op_div{}; - FF avm_main_sel_internal_call{}; - FF avm_main_rwa{}; FF avm_main_mem_idx_a{}; - FF avm_main_bin_sel{}; - FF avm_main_sel_op_xor{}; - FF avm_main_ia{}; - FF avm_main_sel_op_eq{}; - FF avm_main_sel_mov{}; + FF avm_main_sel_jump{}; + FF avm_main_sel_op_add{}; + FF avm_main_ind_op_c{}; + FF avm_main_ind_op_b{}; + FF avm_main_sel_internal_return{}; + FF avm_main_mem_op_b{}; + FF avm_main_rwa{}; + FF avm_main_ic{}; + FF avm_main_mem_idx_b{}; FF avm_main_alu_sel{}; + FF avm_main_ia{}; + FF avm_main_mem_op_a{}; + FF avm_main_sel_internal_call{}; FF avm_main_ind_op_a{}; - FF avm_main_sel_internal_return{}; - FF avm_main_ib{}; - FF avm_main_internal_return_ptr{}; - FF avm_main_inv{}; - FF avm_main_rwb{}; - FF avm_main_pc{}; FF avm_main_pc_shift{}; - FF avm_main_first{}; + FF avm_main_rwc{}; + FF avm_main_sel_mov{}; + FF avm_main_sel_op_or{}; }; inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 28: - return "SUBOP_ERROR_RELEVANT_OP"; + case 26: + return "SUBOP_DIVISION_ZERO_ERR1"; + + case 45: + return "BIN_SEL_1"; + + case 43: + return "MOV_SAME_VALUE"; + + case 25: + return "SUBOP_DIVISION_FF"; case 42: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; + case 30: + return "RETURN_POINTER_INCREMENT"; + case 46: return "BIN_SEL_2"; - case 41: - return "PC_INCREMENT"; - - case 36: - return "RETURN_POINTER_DECREMENT"; - case 27: return "SUBOP_DIVISION_ZERO_ERR2"; - case 43: - return "MOV_SAME_VALUE"; - - case 45: - return "BIN_SEL_1"; - - case 25: - return "SUBOP_DIVISION_FF"; + case 28: + return "SUBOP_ERROR_RELEVANT_OP"; - case 30: - return "RETURN_POINTER_INCREMENT"; + case 36: + return "RETURN_POINTER_DECREMENT"; - case 26: - return "SUBOP_DIVISION_ZERO_ERR1"; + case 41: + return "PC_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 17f5fe1b5fa..4ba1673671e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -7,52 +7,52 @@ namespace bb::Avm_vm { template struct Avm_memRow { - FF avm_mem_m_tag_err{}; FF avm_mem_m_lastAccess{}; - FF avm_mem_m_addr{}; - FF avm_mem_m_ind_op_b{}; - FF avm_mem_m_rw_shift{}; + FF avm_mem_m_op_a{}; FF avm_mem_m_val_shift{}; - FF avm_mem_m_op_b{}; - FF avm_mem_m_tag_shift{}; + FF avm_mem_m_in_tag{}; + FF avm_mem_m_ind_op_b{}; + FF avm_mem_m_sel_mov{}; + FF avm_mem_m_addr_shift{}; FF avm_mem_m_tag{}; - FF avm_mem_m_one_min_inv{}; FF avm_mem_m_last{}; - FF avm_mem_m_val{}; - FF avm_mem_m_op_a{}; - FF avm_mem_m_ind_op_a{}; - FF avm_mem_m_rw{}; FF avm_mem_m_ind_op_c{}; + FF avm_mem_m_addr{}; + FF avm_mem_m_tag_shift{}; + FF avm_mem_m_rw_shift{}; + FF avm_mem_m_one_min_inv{}; + FF avm_mem_m_ind_op_a{}; + FF avm_mem_m_op_b{}; + FF avm_mem_m_tag_err{}; + FF avm_mem_m_val{}; FF avm_mem_m_sub_clk{}; - FF avm_mem_m_addr_shift{}; FF avm_mem_m_op_c{}; - FF avm_mem_m_sel_mov{}; - FF avm_mem_m_in_tag{}; + FF avm_mem_m_rw{}; }; inline std::string get_relation_label_avm_mem(int index) { switch (index) { - case 14: - return "MEM_READ_WRITE_TAG_CONSISTENCY"; + case 17: + return "MEM_IN_TAG_CONSISTENCY_2"; + + case 16: + return "MEM_IN_TAG_CONSISTENCY_1"; + + case 24: + return "MOV_SAME_TAG"; case 15: return "MEM_ZERO_INIT"; + case 14: + return "MEM_READ_WRITE_TAG_CONSISTENCY"; + case 12: return "MEM_LAST_ACCESS_DELIMITER"; - case 17: - return "MEM_IN_TAG_CONSISTENCY_2"; - - case 24: - return "MOV_SAME_TAG"; - case 13: return "MEM_READ_WRITE_VAL_CONSISTENCY"; - - case 16: - return "MEM_IN_TAG_CONSISTENCY_1"; } 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 6fdce84eef4..9b2317a264d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -131,23 +131,21 @@ [[maybe_unused]] auto lookup_byte_operations_counts = View(new_term.lookup_byte_operations_counts); \ [[maybe_unused]] auto incl_main_tag_err_counts = View(new_term.incl_main_tag_err_counts); \ [[maybe_unused]] auto incl_mem_tag_err_counts = View(new_term.incl_mem_tag_err_counts); \ - [[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_r0_shift = View(new_term.avm_alu_alu_u16_r0_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_r7_shift = View(new_term.avm_alu_alu_u16_r7_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_r3_shift = View(new_term.avm_alu_alu_u16_r3_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); \ [[maybe_unused]] auto avm_mem_m_addr_shift = View(new_term.avm_mem_m_addr_shift); \ - [[maybe_unused]] auto avm_binary_bin_sel_shift = View(new_term.avm_binary_bin_sel_shift); \ + [[maybe_unused]] auto avm_mem_m_tag_shift = View(new_term.avm_mem_m_tag_shift); \ + [[maybe_unused]] auto avm_mem_m_rw_shift = View(new_term.avm_mem_m_rw_shift); \ + [[maybe_unused]] auto avm_binary_mem_tag_ctr_shift = View(new_term.avm_binary_mem_tag_ctr_shift); \ [[maybe_unused]] auto avm_binary_acc_ic_shift = View(new_term.avm_binary_acc_ic_shift); \ [[maybe_unused]] auto avm_binary_acc_ib_shift = View(new_term.avm_binary_acc_ib_shift); \ - [[maybe_unused]] auto avm_binary_factor_shift = View(new_term.avm_binary_factor_shift); \ - [[maybe_unused]] auto avm_binary_mem_tag_ctr_shift = View(new_term.avm_binary_mem_tag_ctr_shift); \ [[maybe_unused]] auto avm_binary_acc_ia_shift = View(new_term.avm_binary_acc_ia_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_main_pc_shift = View(new_term.avm_main_pc_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_r0_shift = View(new_term.avm_alu_alu_u16_r0_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_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_r6_shift = View(new_term.avm_alu_alu_u16_r6_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_r5_shift = View(new_term.avm_alu_alu_u16_r5_shift); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp index dadce494887..fa3f8fb6008 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp @@ -28,19 +28,19 @@ void AvmBinaryTraceBuilder::reset() /** * @brief Helper function to correctly decompose and pad inputs - * @param val The constant to be written upcasted to u128 - * @return LE encoded bytes with an extra zero padding. + * @param val The value to decompose + * @param num_bytes The number of bytes given the instr_tag. + * @return BE encoded bytes with an extra zero padding (final length is num_bytes + 1). */ -std::vector bytes_decompose(uint128_t const& val) +std::vector bytes_decompose_be(uint128_t const& val, size_t num_bytes) { // This uses a Network Byte Order (Big-Endian) and since a uint128_t is used // this is guaranteed to be of length 16 (zero-padded if necessary). - std::vector bytes = to_buffer(val); + std::vector val_bytes = to_buffer(val); + // Since the trace expects BE, we take only the portion that corresponds to the bytes we need (given the instr_tag) + std::vector bytes(val_bytes.end() - static_cast(num_bytes), val_bytes.end()); - // We convert it back to Little-Endian. - std::reverse(bytes.begin(), bytes.end()); - // To simplify the loop in witness generation we add a zero at the MSB - // as the last accumulated value has a zero in the bytes column + // To simplify the loop in witness generation we add a zero at the end since it's a "free input" bytes.push_back(0); return bytes; } @@ -61,16 +61,13 @@ void AvmBinaryTraceBuilder::entry_builder( size_t num_bytes = 1 << (static_cast(instr_tag) - 1); // Big Endian encoded - std::vector a_bytes = bytes_decompose(a); - std::vector b_bytes = bytes_decompose(b); - std::vector c_bytes = bytes_decompose(c); + std::vector a_bytes = bytes_decompose_be(a, num_bytes); + std::vector b_bytes = bytes_decompose_be(b, num_bytes); + std::vector c_bytes = bytes_decompose_be(c, num_bytes); uint128_t acc_ia = 0; uint128_t acc_ib = 0; uint128_t acc_ic = 0; - // Factor set to 256bit. In the last row of accumulation the factor will be 2**num_bytes. - // This causes it to overflow the cpp type when we are working with U128. - uint256_t factor = 1; // We have num_bytes + 1 rows to add to the binary trace; for (size_t i = 0; i <= num_bytes; i++) { @@ -79,7 +76,6 @@ void AvmBinaryTraceBuilder::entry_builder( .op_id = op_id, .instr_tag = static_cast(instr_tag), .mem_tag_ctr = static_cast(i), - .factor = factor, .latch = i == num_bytes, .acc_ia = FF(uint256_t::from_uint128(acc_ia)), .acc_ib = FF(uint256_t::from_uint128(acc_ib)), @@ -90,11 +86,9 @@ void AvmBinaryTraceBuilder::entry_builder( }); auto lookup_index = static_cast((op_id << 16) + (a_bytes[i] << 8) + b_bytes[i]); byte_operation_counter[lookup_index]++; - factor *= 256; - - acc_ia += a_bytes[i] * static_cast(std::pow(2, 8 * i)); - acc_ib += b_bytes[i] * static_cast(std::pow(2, 8 * i)); - acc_ic += c_bytes[i] * static_cast(std::pow(2, 8 * i)); + acc_ia = acc_ia * 256 + a_bytes[i]; + acc_ib = acc_ib * 256 + b_bytes[i]; + acc_ic = acc_ic * 256 + c_bytes[i]; } // There is 1 latch per call, therefore byte_length check increments byte_length_counter[static_cast(instr_tag)]++; 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 a340f8eac8e..50f36fea2cc 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -1214,7 +1214,6 @@ std::vector AvmTraceBuilder::finalize() dest.avm_binary_bin_ib_bytes = src.bin_ib_bytes; dest.avm_binary_bin_ic_bytes = src.bin_ic_bytes; dest.avm_binary_latch = FF(static_cast(src.latch)); - dest.avm_binary_factor = FF(src.factor); dest.avm_binary_mem_tag_ctr = src.mem_tag_ctr; } @@ -1258,7 +1257,7 @@ std::vector AvmTraceBuilder::finalize() } } // Adding extra row for the shifted values at the top of the execution trace. - Row first_row = Row{ .avm_main_first = FF(1), .avm_mem_m_lastAccess = FF(1) }; + Row first_row = Row{ .avm_main_first = FF(1), .avm_mem_m_lastAccess = FF(1), .avm_binary_latch = FF() }; main_trace.insert(main_trace.begin(), first_row); auto trace = std::move(main_trace); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp index b90de9351d9..14e13c08bc3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -161,26 +161,24 @@ template struct AvmFullRow { FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u16_r4_shift{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_u16_r5_shift{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_mem_m_rw_shift{}; FF avm_mem_m_val_shift{}; - FF avm_mem_m_tag_shift{}; FF avm_mem_m_addr_shift{}; - FF avm_binary_bin_sel_shift{}; + FF avm_mem_m_tag_shift{}; + FF avm_mem_m_rw_shift{}; + FF avm_binary_mem_tag_ctr_shift{}; FF avm_binary_acc_ic_shift{}; FF avm_binary_acc_ib_shift{}; - FF avm_binary_factor_shift{}; - FF avm_binary_mem_tag_ctr_shift{}; FF avm_binary_acc_ia_shift{}; FF avm_main_internal_return_ptr_shift{}; FF avm_main_pc_shift{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r1_shift{}; + FF avm_alu_alu_u16_r3_shift{}; + FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_u16_r5_shift{}; }; class AvmCircuitBuilder { @@ -193,7 +191,7 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 149; + static constexpr size_t num_fixed_columns = 147; static constexpr size_t num_polys = 129; std::vector rows; @@ -341,26 +339,24 @@ class AvmCircuitBuilder { polys.incl_mem_tag_err_counts[i] = rows[i].incl_mem_tag_err_counts; } - 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_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.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_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); - polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); - polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.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()); polys.avm_mem_m_addr_shift = Polynomial(polys.avm_mem_m_addr.shifted()); - polys.avm_binary_bin_sel_shift = Polynomial(polys.avm_binary_bin_sel.shifted()); + polys.avm_mem_m_tag_shift = Polynomial(polys.avm_mem_m_tag.shifted()); + polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); + polys.avm_binary_mem_tag_ctr_shift = Polynomial(polys.avm_binary_mem_tag_ctr.shifted()); polys.avm_binary_acc_ic_shift = Polynomial(polys.avm_binary_acc_ic.shifted()); polys.avm_binary_acc_ib_shift = Polynomial(polys.avm_binary_acc_ib.shifted()); - polys.avm_binary_factor_shift = Polynomial(polys.avm_binary_factor.shifted()); - polys.avm_binary_mem_tag_ctr_shift = Polynomial(polys.avm_binary_mem_tag_ctr.shifted()); polys.avm_binary_acc_ia_shift = Polynomial(polys.avm_binary_acc_ia.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_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); + polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.shifted()); + polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.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_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); + polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); + polys.avm_alu_alu_u16_r5_shift = Polynomial(polys.avm_alu_alu_u16_r5.shifted()); return polys; } @@ -432,10 +428,6 @@ class AvmCircuitBuilder { return true; }; - if (!evaluate_relation.template operator()>("avm_alu", - Avm_vm::get_relation_label_avm_alu)) { - return false; - } if (!evaluate_relation.template operator()>("avm_mem", Avm_vm::get_relation_label_avm_mem)) { return false; @@ -448,6 +440,10 @@ class AvmCircuitBuilder { 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_logderivative.template operator()>("PERM_MAIN_ALU")) { return false; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 3b5350b9008..26e30d2b8e3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -50,12 +50,12 @@ class AvmFlavor { 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 = 149; + static constexpr size_t NUM_ALL_ENTITIES = 147; - using Relations = std::tuple, - Avm_vm::avm_mem, + using Relations = std::tuple, Avm_vm::avm_binary, Avm_vm::avm_main, + Avm_vm::avm_alu, perm_main_alu_relation, perm_main_bin_relation, perm_main_mem_a_relation, @@ -490,26 +490,24 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r3_shift, - avm_mem_m_rw_shift, avm_mem_m_val_shift, - avm_mem_m_tag_shift, avm_mem_m_addr_shift, - avm_binary_bin_sel_shift, + avm_mem_m_tag_shift, + avm_mem_m_rw_shift, + avm_binary_mem_tag_ctr_shift, avm_binary_acc_ic_shift, avm_binary_acc_ib_shift, - avm_binary_factor_shift, - avm_binary_mem_tag_ctr_shift, avm_binary_acc_ia_shift, avm_main_internal_return_ptr_shift, - avm_main_pc_shift) + avm_main_pc_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r1_shift, + avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r5_shift) RefVector get_wires() { @@ -642,26 +640,24 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r3_shift, - avm_mem_m_rw_shift, avm_mem_m_val_shift, - avm_mem_m_tag_shift, avm_mem_m_addr_shift, - avm_binary_bin_sel_shift, + avm_mem_m_tag_shift, + avm_mem_m_rw_shift, + avm_binary_mem_tag_ctr_shift, avm_binary_acc_ic_shift, avm_binary_acc_ib_shift, - avm_binary_factor_shift, - avm_binary_mem_tag_ctr_shift, avm_binary_acc_ia_shift, avm_main_internal_return_ptr_shift, - avm_main_pc_shift }; + avm_main_pc_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r1_shift, + avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r5_shift }; }; RefVector get_unshifted() { @@ -797,49 +793,21 @@ class AvmFlavor { }; RefVector get_to_be_shifted() { - return { avm_alu_alu_u16_r6, - avm_alu_alu_u16_r4, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r1, - avm_alu_alu_u16_r5, - avm_alu_alu_u16_r7, - avm_alu_alu_u16_r2, - avm_alu_alu_u16_r3, - avm_mem_m_rw, - avm_mem_m_val, - avm_mem_m_tag, - avm_mem_m_addr, - avm_binary_bin_sel, - avm_binary_acc_ic, - avm_binary_acc_ib, - avm_binary_factor, - avm_binary_mem_tag_ctr, - avm_binary_acc_ia, - avm_main_internal_return_ptr, - avm_main_pc }; + return { avm_mem_m_val, avm_mem_m_addr, avm_mem_m_tag, + avm_mem_m_rw, avm_binary_mem_tag_ctr, avm_binary_acc_ic, + avm_binary_acc_ib, avm_binary_acc_ia, avm_main_internal_return_ptr, + avm_main_pc, avm_alu_alu_u16_r7, avm_alu_alu_u16_r0, + avm_alu_alu_u16_r1, avm_alu_alu_u16_r3, avm_alu_alu_u16_r4, + avm_alu_alu_u16_r6, avm_alu_alu_u16_r2, avm_alu_alu_u16_r5 }; }; RefVector get_shifted() { - return { avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r3_shift, - avm_mem_m_rw_shift, - avm_mem_m_val_shift, - avm_mem_m_tag_shift, - avm_mem_m_addr_shift, - avm_binary_bin_sel_shift, - avm_binary_acc_ic_shift, - avm_binary_acc_ib_shift, - avm_binary_factor_shift, - avm_binary_mem_tag_ctr_shift, - avm_binary_acc_ia_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift }; + return { avm_mem_m_val_shift, avm_mem_m_addr_shift, avm_mem_m_tag_shift, + avm_mem_m_rw_shift, avm_binary_mem_tag_ctr_shift, avm_binary_acc_ic_shift, + avm_binary_acc_ib_shift, avm_binary_acc_ia_shift, avm_main_internal_return_ptr_shift, + avm_main_pc_shift, avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r3_shift, avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r2_shift, avm_alu_alu_u16_r5_shift }; }; }; @@ -852,26 +820,12 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_alu_alu_u16_r6, - avm_alu_alu_u16_r4, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r1, - avm_alu_alu_u16_r5, - avm_alu_alu_u16_r7, - avm_alu_alu_u16_r2, - avm_alu_alu_u16_r3, - avm_mem_m_rw, - avm_mem_m_val, - avm_mem_m_tag, - avm_mem_m_addr, - avm_binary_bin_sel, - avm_binary_acc_ic, - avm_binary_acc_ib, - avm_binary_factor, - avm_binary_mem_tag_ctr, - avm_binary_acc_ia, - avm_main_internal_return_ptr, - avm_main_pc }; + return { avm_mem_m_val, avm_mem_m_addr, avm_mem_m_tag, + avm_mem_m_rw, avm_binary_mem_tag_ctr, avm_binary_acc_ic, + avm_binary_acc_ib, avm_binary_acc_ia, avm_main_internal_return_ptr, + avm_main_pc, avm_alu_alu_u16_r7, avm_alu_alu_u16_r0, + avm_alu_alu_u16_r1, avm_alu_alu_u16_r3, avm_alu_alu_u16_r4, + avm_alu_alu_u16_r6, avm_alu_alu_u16_r2, avm_alu_alu_u16_r5 }; }; // The plookup wires that store plookup read data. 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 a911c8ae996..ef662417695 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -215,8 +215,8 @@ std::vector gen_mutated_trace_bit(std::vector trace, auto latch_index = static_cast(std::distance(trace.begin(), latched_row)); // Set the latched row to be 1 earlier than it should be, this triggers the byte length lookup table check. trace.at(latch_index - 1).avm_binary_latch = FF(1); - // We need to set the result here or it will be deemed incorrectly copied in the equivalence check to main. - trace.at(latch_index - 1).avm_binary_acc_ic = c_mutated; + // Update the result in the main_ic to be this new value so we dont trigger an incorrect equivalence check. + mutate_ic_in_trace(trace, std::move(select_row), trace.at(latch_index - 1).avm_binary_acc_ic, false); // We need to zero out the previously latched row so we dont trigger any other relation checks latched_row->avm_binary_mem_tag_ctr = 0; latched_row->avm_binary_bin_sel = 0; @@ -437,16 +437,15 @@ std::vector> bit_failures = { { "ACC_REL_C", BIT_FAILURES::IncorrectAcc }, { "ACC_REL_C", BIT_FAILURES::BitDecomposition }, { "MEM_TAG_REL", BIT_FAILURES::MemTagCtr }, - { "FACTOR_REL", BIT_FAILURES::IncorrectFactor }, { "LOOKUP_BYTE_LENGTHS", BIT_FAILURES::ByteLengthError }, { "LOOKUP_BYTE_OPERATIONS", BIT_FAILURES::ByteLookupError } }; -std::vector neg_test_and = { { { 13793, 10590617LLU, 4481 }, AvmMemoryTag::U32 } }; -// For the negativ Or and Xor we carefully select inputs such that the most significant 16-bits are zero for both -// operands This makes it easier when doing to the lookup-based error checks since we dont have to worry about the -// equivalence check to main. -std::vector neg_test_or = { { { 13793, 31385, 32761 }, AvmMemoryTag::U32 } }; -std::vector neg_test_xor = { { { 13793, 31385, 20344 }, AvmMemoryTag::U32 } }; +// For the negative test the output is set to be incorrect so that we can test the byte lookups. +// Picking "simple" inputs such as zero also makes it easier when check the byte length lookups as we dont +// need to worry about copying the accmulated a & b registers into the main trace. +std::vector neg_test_and = { { { 0, 0, 1 }, AvmMemoryTag::U32 } }; +std::vector neg_test_or = { { { 0, 0, 1 }, AvmMemoryTag::U32 } }; +std::vector neg_test_xor = { { { 0, 0, 1 }, AvmMemoryTag::U32 } }; /****************************************************************************** * Negative Tests - FF ******************************************************************************/ @@ -486,6 +485,7 @@ TEST_P(AvmBitwiseNegativeTestsOr, AllNegativeTests) FF ff_output = FF(uint256_t::from_uint128(output)); std::function&& select_row = [](Row r) { return r.avm_main_sel_op_or == FF(1); }; trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); + // validate_trace_proof(std::move(trace)); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), failure_string); } INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, @@ -506,6 +506,7 @@ TEST_P(AvmBitwiseNegativeTestsXor, AllNegativeTests) FF ff_output = FF(uint256_t::from_uint128(output)); std::function&& select_row = [](Row r) { return r.avm_main_sel_op_xor == FF(1); }; trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); + // validate_trace_proof(std::move(trace)); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), failure_string) } INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, From f12dde522c18a2ab0af2633ddfc8388afb7a9f06 Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Fri, 22 Mar 2024 14:11:23 +0000 Subject: [PATCH 3/8] feat: invert accumulation -> top-down --- barretenberg/cpp/pil/avm/avm_binary.pil | 33 ++-- barretenberg/cpp/pil/avm/avm_byte_lookup.pil | 8 +- barretenberg/cpp/pil/avm/avm_main.pil | 6 +- .../relations/generated/avm/avm_alu.hpp | 76 ++++----- .../relations/generated/avm/avm_binary.hpp | 79 ++++++--- .../relations/generated/avm/avm_main.hpp | 88 +++++----- .../relations/generated/avm/avm_mem.hpp | 54 +++--- .../relations/generated/avm/declare_views.hpp | 30 ++-- .../generated/avm/lookup_byte_lengths.hpp | 16 +- .../relations/generated/avm/perm_main_bin.hpp | 16 +- .../vm/avm_trace/avm_binary_trace.cpp | 31 ++-- .../vm/avm_trace/avm_binary_trace.hpp | 4 +- .../barretenberg/vm/avm_trace/avm_trace.cpp | 8 +- .../vm/generated/avm_circuit_builder.hpp | 66 ++++---- .../barretenberg/vm/generated/avm_flavor.hpp | 155 +++++++++--------- .../vm/generated/avm_verifier.cpp | 14 +- .../vm/tests/avm_bitwise.test.cpp | 101 ++++++------ 17 files changed, 411 insertions(+), 374 deletions(-) diff --git a/barretenberg/cpp/pil/avm/avm_binary.pil b/barretenberg/cpp/pil/avm/avm_binary.pil index 876e76374d5..32f3f159b5e 100644 --- a/barretenberg/cpp/pil/avm/avm_binary.pil +++ b/barretenberg/cpp/pil/avm/avm_binary.pil @@ -10,7 +10,8 @@ namespace avm_binary(256); pol commit bin_sel; bin_sel * (1 - bin_sel) = 0; - // The last element in this column is what part of equivalence check to main trace + // Byte recomposition column, the value in these columns are part of the equivalence + // check to main wherever Start is set to 1. pol commit acc_ia; pol commit acc_ib; pol commit acc_ic; @@ -18,21 +19,23 @@ namespace avm_binary(256); // This is the instruction tag {1,2,3,4,5} (restricted to not be a field) // Operations over FF are not supported, it is assumed this exclusion is handled // outside of this subtrace. + // Constraints come from equiv to main_trace - pol commit instr_tag; + pol commit in_tag; // Selectors for binary operations, correctness checked by permutation to the main trace. + // Op Id is restricted to be the same during the same computation (i.e. between Starts) pol commit op_id; + #[OP_ID_REL] + (op_id' - op_id) * mem_tag_ctr = 0; + // Little Endian bitwise decomposition, constrained to be U8 given the lookup the avm_byte_lookup pol commit bin_ia_bytes; pol commit bin_ib_bytes; pol commit bin_ic_bytes; - pol commit latch; //Identifies when we want to capture the output - pol commit factor; // Identifies the byte position when accumulating + pol commit start; // Identifies when we want to capture the output to the main tracssssss - // latch is restricted to be a boolean - latch * (1 - latch) = 0; // To support dynamically sized memory operands we use a counter against a lookup // This counter goes from [0, MEM_TAG] where MEM_TAG is the number of bytes in the @@ -40,12 +43,16 @@ namespace avm_binary(256); // Consistency can be achieved with a lookup table between the instr_tag and bytes_length pol commit mem_tag_ctr; #[MEM_TAG_REL] - mem_tag_ctr' = (mem_tag_ctr + 1) * (1 - latch) * bin_sel; + (mem_tag_ctr' - mem_tag_ctr + 1) * mem_tag_ctr = 0; + + (1 - bin_sel) * mem_tag_ctr = 0; // bin_sel is 1 when mem_tag_ctr is not zero + (1 - bin_sel) * acc_ia = 0; // Forces accumulator to start at zero when mem_tag_ctr == 0 + (1 - bin_sel) * acc_ib = 0; // Forces accumulator to start at zero when mem_tag_ctr == 0 #[LOOKUP_BYTE_LENGTHS] - latch {instr_tag, mem_tag_ctr} + start {in_tag, mem_tag_ctr} in - avm_byte_lookup.bin_sel {avm_byte_lookup.table_instr_tags, avm_byte_lookup.table_byte_lengths}; + avm_byte_lookup.bin_sel {avm_byte_lookup.table_in_tags, avm_byte_lookup.table_byte_lengths}; #[LOOKUP_BYTE_OPERATIONS] bin_sel {op_id, bin_ia_bytes, bin_ib_bytes, bin_ic_bytes} @@ -53,9 +60,9 @@ namespace avm_binary(256); avm_byte_lookup.bin_sel {avm_byte_lookup.table_op_id, avm_byte_lookup.table_input_a,avm_byte_lookup.table_input_b, avm_byte_lookup.table_output}; #[ACC_REL_A] - acc_ia' = (bin_ia_bytes + 256 * acc_ia) * (1 - latch); + (acc_ia - bin_ia_bytes - 256 * acc_ia') * mem_tag_ctr = 0; #[ACC_REL_B] - acc_ib' = (bin_ib_bytes + 256 * acc_ib) * (1 - latch); - #[ACC_REL_C] - acc_ic' = (bin_ic_bytes + 256 * acc_ic) * (1 - latch); + (acc_ib - bin_ib_bytes - 256 * acc_ib') * mem_tag_ctr = 0; + #[ACC_REL_C] + (acc_ic - bin_ic_bytes - 256 * acc_ic') * mem_tag_ctr = 0; diff --git a/barretenberg/cpp/pil/avm/avm_byte_lookup.pil b/barretenberg/cpp/pil/avm/avm_byte_lookup.pil index 8fff072d85f..d06135389fd 100644 --- a/barretenberg/cpp/pil/avm/avm_byte_lookup.pil +++ b/barretenberg/cpp/pil/avm/avm_byte_lookup.pil @@ -5,8 +5,12 @@ namespace avm_byte_lookup(256); pol commit table_op_id; // identifies if operation is AND/OR/XOR pol commit table_input_a; // column of all 8-bit numbers pol commit table_input_b; // column of all 8-bit numbers - pol commit table_output; // column of all combinations of AND/OR/XOR + pol commit table_output; // output = a AND/OR/XOR b + // Selector to indicate when to utilise the lookup table + // TODO: Support for 1-sided lookups may make this redundant. pol commit bin_sel; - pol commit table_instr_tags; // Column of U8,U16,...,U128 + // These two columns are a mapping between instruction tags and their byte lengths + // {U8: 1, U16: 2, ... , U128: 16} + pol commit table_in_tags; // Column of U8,U16,...,U128 pol commit table_byte_lengths; // Columns of byte lengths 1,2,...,16; diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index 43c6ce5982c..f984ab4197e 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -265,10 +265,10 @@ namespace avm_main(256); bin_sel = (sel_op_and + sel_op_or + sel_op_xor); #[PERM_MAIN_BIN] - bin_sel {clk, ia, ib, ic, bin_op_id, in_tag} + bin_sel {ia, ib, ic, bin_op_id, in_tag} is - avm_binary.latch {avm_binary.bin_clk, avm_binary.acc_ia, avm_binary.acc_ib, avm_binary.acc_ic, - avm_binary.op_id, avm_binary.instr_tag}; + avm_binary.start {avm_binary.acc_ia, avm_binary.acc_ib, avm_binary.acc_ic, + avm_binary.op_id, avm_binary.in_tag}; #[PERM_MAIN_MEM_A] mem_op_a {clk, mem_idx_a, ia, rwa, in_tag, sel_mov} 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 d4381548898..7c2e056bec9 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,66 +7,57 @@ namespace bb::Avm_vm { template struct Avm_aluRow { - FF avm_alu_alu_u64_r0{}; - FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u16_r4{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_op_eq_diff_inv{}; + FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_u16_r0{}; + FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r7{}; FF avm_alu_alu_u8_tag{}; + FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_u16_r6{}; + FF avm_alu_alu_u16_r3{}; FF avm_alu_alu_u64_tag{}; + FF avm_alu_alu_u128_tag{}; + FF avm_alu_alu_op_mul{}; + FF avm_alu_alu_op_add{}; + FF avm_alu_alu_op_not{}; FF avm_alu_alu_u16_r1{}; - FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_in_tag{}; + FF avm_alu_alu_u16_r3_shift{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_alu_alu_op_sub{}; + FF avm_alu_alu_u16_r5{}; + FF avm_alu_alu_u8_r1{}; + FF avm_alu_alu_u64_r0{}; FF avm_alu_alu_u16_r1_shift{}; + FF avm_alu_alu_sel{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_ib{}; + FF avm_alu_alu_u16_r2{}; + FF avm_alu_alu_u32_tag{}; + FF avm_alu_alu_u16_tag{}; FF avm_alu_alu_u8_r0{}; FF avm_alu_alu_ia{}; FF avm_alu_alu_ic{}; - FF avm_alu_alu_op_not{}; - FF avm_alu_alu_u16_r3_shift{}; FF avm_alu_alu_cf{}; - FF avm_alu_alu_sel{}; - FF avm_alu_alu_u16_r6{}; - FF avm_alu_alu_u16_r2{}; - FF avm_alu_alu_u16_tag{}; - FF avm_alu_alu_u16_r0{}; - FF avm_alu_alu_op_mul{}; - FF avm_alu_alu_ff_tag{}; - FF avm_alu_alu_u128_tag{}; - FF avm_alu_alu_u16_r3{}; - FF avm_alu_alu_u16_r5{}; - FF avm_alu_alu_op_eq_diff_inv{}; - FF avm_alu_alu_u8_r1{}; - FF avm_alu_alu_u32_tag{}; - FF avm_alu_alu_op_add{}; - FF avm_alu_alu_u16_r4{}; - FF avm_alu_alu_u16_r7{}; - FF avm_alu_alu_op_sub{}; - FF avm_alu_alu_u16_r4_shift{}; - FF avm_alu_alu_u16_r6_shift{}; FF avm_alu_alu_op_eq{}; - FF avm_alu_alu_in_tag{}; - FF avm_alu_alu_ib{}; - FF avm_alu_alu_u16_r2_shift{}; FF avm_alu_alu_u16_r5_shift{}; }; inline std::string get_relation_label_avm_alu(int index) { switch (index) { - case 16: - return "ALU_MULTIPLICATION_OUT_U128"; - - case 20: - return "ALU_OP_EQ"; - case 9: return "ALU_ADD_SUB_1"; - case 19: - return "ALU_RES_IS_BOOL"; + case 11: + return "ALU_MULTIPLICATION_FF"; case 10: return "ALU_ADD_SUB_2"; - case 11: - return "ALU_MULTIPLICATION_FF"; - case 13: return "ALU_MUL_COMMON_2"; @@ -78,6 +69,15 @@ inline std::string get_relation_label_avm_alu(int index) case 18: return "ALU_OP_NOT"; + + case 16: + return "ALU_MULTIPLICATION_OUT_U128"; + + case 19: + return "ALU_RES_IS_BOOL"; + + case 20: + return "ALU_OP_EQ"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp index 2e8769d9ca8..d78add96ce9 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp @@ -7,35 +7,39 @@ namespace bb::Avm_vm { template struct Avm_binaryRow { - FF avm_binary_acc_ia{}; - FF avm_binary_mem_tag_ctr_shift{}; + FF avm_binary_acc_ic_shift{}; + FF avm_binary_acc_ib{}; FF avm_binary_bin_sel{}; + FF avm_binary_acc_ib_shift{}; + FF avm_binary_op_id{}; + FF avm_binary_bin_ic_bytes{}; + FF avm_binary_acc_ic{}; + FF avm_binary_acc_ia{}; FF avm_binary_mem_tag_ctr{}; FF avm_binary_bin_ib_bytes{}; - FF avm_binary_acc_ib{}; - FF avm_binary_acc_ic_shift{}; - FF avm_binary_acc_ic{}; - FF avm_binary_latch{}; - FF avm_binary_bin_ic_bytes{}; - FF avm_binary_acc_ib_shift{}; + FF avm_binary_op_id_shift{}; FF avm_binary_acc_ia_shift{}; FF avm_binary_bin_ia_bytes{}; + FF avm_binary_mem_tag_ctr_shift{}; }; inline std::string get_relation_label_avm_binary(int index) { switch (index) { - case 4: - return "ACC_REL_B"; - - case 3: - return "ACC_REL_A"; - case 2: return "MEM_TAG_REL"; - case 5: + case 8: return "ACC_REL_C"; + + case 6: + return "ACC_REL_A"; + + case 7: + return "ACC_REL_B"; + + case 1: + return "OP_ID_REL"; } return std::to_string(index); } @@ -44,8 +48,8 @@ template class avm_binaryImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 4, 4, 4, 4, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 3, 3, 3, 4, 4, 4, }; template @@ -67,7 +71,7 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(1); - auto tmp = (avm_binary_latch * (-avm_binary_latch + FF(1))); + auto tmp = ((avm_binary_op_id_shift - avm_binary_op_id) * avm_binary_mem_tag_ctr); tmp *= scaling_factor; std::get<1>(evals) += tmp; } @@ -75,8 +79,7 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(2); - auto tmp = (avm_binary_mem_tag_ctr_shift - - (((avm_binary_mem_tag_ctr + FF(1)) * (-avm_binary_latch + FF(1))) * avm_binary_bin_sel)); + auto tmp = (((avm_binary_mem_tag_ctr_shift - avm_binary_mem_tag_ctr) + FF(1)) * avm_binary_mem_tag_ctr); tmp *= scaling_factor; std::get<2>(evals) += tmp; } @@ -84,8 +87,7 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(3); - auto tmp = (avm_binary_acc_ia_shift - - ((avm_binary_bin_ia_bytes + (avm_binary_acc_ia * FF(256))) * (-avm_binary_latch + FF(1)))); + auto tmp = ((-avm_binary_bin_sel + FF(1)) * avm_binary_mem_tag_ctr); tmp *= scaling_factor; std::get<3>(evals) += tmp; } @@ -93,8 +95,7 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(4); - auto tmp = (avm_binary_acc_ib_shift - - ((avm_binary_bin_ib_bytes + (avm_binary_acc_ib * FF(256))) * (-avm_binary_latch + FF(1)))); + auto tmp = ((-avm_binary_bin_sel + FF(1)) * avm_binary_acc_ia); tmp *= scaling_factor; std::get<4>(evals) += tmp; } @@ -102,11 +103,37 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(5); - auto tmp = (avm_binary_acc_ic_shift - - ((avm_binary_bin_ic_bytes + (avm_binary_acc_ic * FF(256))) * (-avm_binary_latch + FF(1)))); + auto tmp = ((-avm_binary_bin_sel + FF(1)) * avm_binary_acc_ib); tmp *= scaling_factor; std::get<5>(evals) += tmp; } + // Contribution 6 + { + Avm_DECLARE_VIEWS(6); + + auto tmp = (((avm_binary_acc_ia - avm_binary_bin_ia_bytes) - (avm_binary_acc_ia_shift * FF(256))) * + avm_binary_mem_tag_ctr); + tmp *= scaling_factor; + std::get<6>(evals) += tmp; + } + // Contribution 7 + { + Avm_DECLARE_VIEWS(7); + + auto tmp = (((avm_binary_acc_ib - avm_binary_bin_ib_bytes) - (avm_binary_acc_ib_shift * FF(256))) * + avm_binary_mem_tag_ctr); + tmp *= scaling_factor; + std::get<7>(evals) += tmp; + } + // Contribution 8 + { + Avm_DECLARE_VIEWS(8); + + auto tmp = (((avm_binary_acc_ic - avm_binary_bin_ic_bytes) - (avm_binary_acc_ic_shift * FF(256))) * + avm_binary_mem_tag_ctr); + tmp *= scaling_factor; + std::get<8>(evals) += tmp; + } } }; 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 6c92c06bb39..9ca7ab7619c 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -7,79 +7,79 @@ namespace bb::Avm_vm { template struct Avm_mainRow { - FF avm_main_sel_op_mul{}; - FF avm_main_sel_halt{}; - FF avm_main_inv{}; - FF avm_main_bin_sel{}; FF avm_main_sel_op_and{}; - FF avm_main_sel_op_not{}; - FF avm_main_first{}; - FF avm_main_internal_return_ptr{}; - FF avm_main_bin_op_id{}; - FF avm_main_mem_op_c{}; - FF avm_main_sel_op_xor{}; - FF avm_main_op_err{}; - FF avm_main_ib{}; - FF avm_main_rwb{}; - FF avm_main_pc{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_sel_op_sub{}; - FF avm_main_sel_op_eq{}; - FF avm_main_tag_err{}; FF avm_main_sel_op_div{}; - FF avm_main_mem_idx_a{}; - FF avm_main_sel_jump{}; FF avm_main_sel_op_add{}; + FF avm_main_sel_op_mul{}; + FF avm_main_sel_internal_call{}; + FF avm_main_sel_jump{}; + FF avm_main_sel_mov{}; + FF avm_main_mem_op_b{}; + FF avm_main_sel_op_xor{}; + FF avm_main_rwc{}; + FF avm_main_internal_return_ptr{}; + FF avm_main_first{}; + FF avm_main_mem_op_a{}; FF avm_main_ind_op_c{}; - FF avm_main_ind_op_b{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_ind_op_a{}; + FF avm_main_bin_op_id{}; FF avm_main_sel_internal_return{}; - FF avm_main_mem_op_b{}; - FF avm_main_rwa{}; + FF avm_main_mem_op_c{}; + FF avm_main_rwb{}; FF avm_main_ic{}; - FF avm_main_mem_idx_b{}; - FF avm_main_alu_sel{}; FF avm_main_ia{}; - FF avm_main_mem_op_a{}; - FF avm_main_sel_internal_call{}; - FF avm_main_ind_op_a{}; FF avm_main_pc_shift{}; - FF avm_main_rwc{}; - FF avm_main_sel_mov{}; + FF avm_main_sel_op_not{}; + FF avm_main_mem_idx_b{}; + FF avm_main_tag_err{}; + FF avm_main_alu_sel{}; + FF avm_main_mem_idx_a{}; + FF avm_main_sel_op_sub{}; + FF avm_main_inv{}; + FF avm_main_pc{}; + FF avm_main_op_err{}; + FF avm_main_sel_halt{}; FF avm_main_sel_op_or{}; + FF avm_main_bin_sel{}; + FF avm_main_ib{}; + FF avm_main_sel_op_eq{}; + FF avm_main_ind_op_b{}; + FF avm_main_rwa{}; }; inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 26: - return "SUBOP_DIVISION_ZERO_ERR1"; + case 36: + return "RETURN_POINTER_DECREMENT"; + + case 43: + return "MOV_SAME_VALUE"; case 45: return "BIN_SEL_1"; - case 43: - return "MOV_SAME_VALUE"; + case 28: + return "SUBOP_ERROR_RELEVANT_OP"; case 25: return "SUBOP_DIVISION_FF"; + case 27: + return "SUBOP_DIVISION_ZERO_ERR2"; + case 42: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 30: - return "RETURN_POINTER_INCREMENT"; + case 26: + return "SUBOP_DIVISION_ZERO_ERR1"; case 46: return "BIN_SEL_2"; - case 27: - return "SUBOP_DIVISION_ZERO_ERR2"; - - case 28: - return "SUBOP_ERROR_RELEVANT_OP"; - - case 36: - return "RETURN_POINTER_DECREMENT"; + case 30: + return "RETURN_POINTER_INCREMENT"; case 41: return "PC_INCREMENT"; 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 4ba1673671e..432bc8643c2 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -7,52 +7,52 @@ namespace bb::Avm_vm { template struct Avm_memRow { - FF avm_mem_m_lastAccess{}; - FF avm_mem_m_op_a{}; - FF avm_mem_m_val_shift{}; - FF avm_mem_m_in_tag{}; - FF avm_mem_m_ind_op_b{}; - FF avm_mem_m_sel_mov{}; - FF avm_mem_m_addr_shift{}; + FF avm_mem_m_rw{}; + FF avm_mem_m_val{}; FF avm_mem_m_tag{}; - FF avm_mem_m_last{}; - FF avm_mem_m_ind_op_c{}; - FF avm_mem_m_addr{}; + FF avm_mem_m_sel_mov{}; + FF avm_mem_m_op_c{}; + FF avm_mem_m_val_shift{}; FF avm_mem_m_tag_shift{}; + FF avm_mem_m_in_tag{}; + FF avm_mem_m_sub_clk{}; + FF avm_mem_m_tag_err{}; + FF avm_mem_m_op_b{}; FF avm_mem_m_rw_shift{}; FF avm_mem_m_one_min_inv{}; + FF avm_mem_m_last{}; FF avm_mem_m_ind_op_a{}; - FF avm_mem_m_op_b{}; - FF avm_mem_m_tag_err{}; - FF avm_mem_m_val{}; - FF avm_mem_m_sub_clk{}; - FF avm_mem_m_op_c{}; - FF avm_mem_m_rw{}; + FF avm_mem_m_addr{}; + FF avm_mem_m_ind_op_c{}; + FF avm_mem_m_lastAccess{}; + FF avm_mem_m_addr_shift{}; + FF avm_mem_m_ind_op_b{}; + FF avm_mem_m_op_a{}; }; inline std::string get_relation_label_avm_mem(int index) { switch (index) { - case 17: - return "MEM_IN_TAG_CONSISTENCY_2"; - - case 16: - return "MEM_IN_TAG_CONSISTENCY_1"; + case 13: + return "MEM_READ_WRITE_VAL_CONSISTENCY"; case 24: return "MOV_SAME_TAG"; - case 15: - return "MEM_ZERO_INIT"; + case 16: + return "MEM_IN_TAG_CONSISTENCY_1"; + + case 12: + return "MEM_LAST_ACCESS_DELIMITER"; case 14: return "MEM_READ_WRITE_TAG_CONSISTENCY"; - case 12: - return "MEM_LAST_ACCESS_DELIMITER"; + case 15: + return "MEM_ZERO_INIT"; - case 13: - return "MEM_READ_WRITE_VAL_CONSISTENCY"; + case 17: + return "MEM_IN_TAG_CONSISTENCY_2"; } 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 9b2317a264d..dc9e42dfa39 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -58,20 +58,19 @@ [[maybe_unused]] auto avm_byte_lookup_table_input_b = View(new_term.avm_byte_lookup_table_input_b); \ [[maybe_unused]] auto avm_byte_lookup_table_output = View(new_term.avm_byte_lookup_table_output); \ [[maybe_unused]] auto avm_byte_lookup_bin_sel = View(new_term.avm_byte_lookup_bin_sel); \ - [[maybe_unused]] auto avm_byte_lookup_table_instr_tags = View(new_term.avm_byte_lookup_table_instr_tags); \ + [[maybe_unused]] auto avm_byte_lookup_table_in_tags = View(new_term.avm_byte_lookup_table_in_tags); \ [[maybe_unused]] auto avm_byte_lookup_table_byte_lengths = View(new_term.avm_byte_lookup_table_byte_lengths); \ [[maybe_unused]] auto avm_binary_bin_clk = View(new_term.avm_binary_bin_clk); \ [[maybe_unused]] auto avm_binary_bin_sel = View(new_term.avm_binary_bin_sel); \ [[maybe_unused]] auto avm_binary_acc_ia = View(new_term.avm_binary_acc_ia); \ [[maybe_unused]] auto avm_binary_acc_ib = View(new_term.avm_binary_acc_ib); \ [[maybe_unused]] auto avm_binary_acc_ic = View(new_term.avm_binary_acc_ic); \ - [[maybe_unused]] auto avm_binary_instr_tag = View(new_term.avm_binary_instr_tag); \ + [[maybe_unused]] auto avm_binary_in_tag = View(new_term.avm_binary_in_tag); \ [[maybe_unused]] auto avm_binary_op_id = View(new_term.avm_binary_op_id); \ [[maybe_unused]] auto avm_binary_bin_ia_bytes = View(new_term.avm_binary_bin_ia_bytes); \ [[maybe_unused]] auto avm_binary_bin_ib_bytes = View(new_term.avm_binary_bin_ib_bytes); \ [[maybe_unused]] auto avm_binary_bin_ic_bytes = View(new_term.avm_binary_bin_ic_bytes); \ - [[maybe_unused]] auto avm_binary_latch = View(new_term.avm_binary_latch); \ - [[maybe_unused]] auto avm_binary_factor = View(new_term.avm_binary_factor); \ + [[maybe_unused]] auto avm_binary_start = View(new_term.avm_binary_start); \ [[maybe_unused]] auto avm_binary_mem_tag_ctr = View(new_term.avm_binary_mem_tag_ctr); \ [[maybe_unused]] auto avm_main_pc = View(new_term.avm_main_pc); \ [[maybe_unused]] auto avm_main_internal_return_ptr = View(new_term.avm_main_internal_return_ptr); \ @@ -131,21 +130,22 @@ [[maybe_unused]] auto lookup_byte_operations_counts = View(new_term.lookup_byte_operations_counts); \ [[maybe_unused]] auto incl_main_tag_err_counts = View(new_term.incl_main_tag_err_counts); \ [[maybe_unused]] auto incl_mem_tag_err_counts = View(new_term.incl_mem_tag_err_counts); \ + [[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_r4_shift = View(new_term.avm_alu_alu_u16_r4_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_r3_shift = View(new_term.avm_alu_alu_u16_r3_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_r1_shift = View(new_term.avm_alu_alu_u16_r1_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_r5_shift = View(new_term.avm_alu_alu_u16_r5_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_mem_m_tag_shift = View(new_term.avm_mem_m_tag_shift); \ [[maybe_unused]] auto avm_mem_m_rw_shift = View(new_term.avm_mem_m_rw_shift); \ - [[maybe_unused]] auto avm_binary_mem_tag_ctr_shift = View(new_term.avm_binary_mem_tag_ctr_shift); \ + [[maybe_unused]] auto avm_mem_m_addr_shift = View(new_term.avm_mem_m_addr_shift); \ [[maybe_unused]] auto avm_binary_acc_ic_shift = View(new_term.avm_binary_acc_ic_shift); \ [[maybe_unused]] auto avm_binary_acc_ib_shift = View(new_term.avm_binary_acc_ib_shift); \ + [[maybe_unused]] auto avm_binary_op_id_shift = View(new_term.avm_binary_op_id_shift); \ [[maybe_unused]] auto avm_binary_acc_ia_shift = View(new_term.avm_binary_acc_ia_shift); \ + [[maybe_unused]] auto avm_binary_mem_tag_ctr_shift = View(new_term.avm_binary_mem_tag_ctr_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_r7_shift = View(new_term.avm_alu_alu_u16_r7_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_r1_shift = View(new_term.avm_alu_alu_u16_r1_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_r6_shift = View(new_term.avm_alu_alu_u16_r6_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_r5_shift = View(new_term.avm_alu_alu_u16_r5_shift); + [[maybe_unused]] auto avm_main_pc_shift = View(new_term.avm_main_pc_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_lengths.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_lengths.hpp index 4fa896bac55..4c5a6bd0d48 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_lengths.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_byte_lengths.hpp @@ -87,7 +87,7 @@ class lookup_byte_lengths_lookup_settings { template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) { - return (in.avm_binary_latch == 1 || in.avm_byte_lookup_bin_sel == 1); + return (in.avm_binary_start == 1 || in.avm_byte_lookup_bin_sel == 1); } /** @@ -104,7 +104,7 @@ class lookup_byte_lengths_lookup_settings { static inline auto compute_inverse_exists(const AllEntities& in) { using View = typename Accumulator::View; - const auto is_operation = View(in.avm_binary_latch); + const auto is_operation = View(in.avm_binary_start); const auto is_table_entry = View(in.avm_byte_lookup_bin_sel); return (is_operation + is_table_entry - is_operation * is_table_entry); } @@ -135,11 +135,11 @@ class lookup_byte_lengths_lookup_settings { return std::forward_as_tuple(in.lookup_byte_lengths, in.lookup_byte_lengths_counts, - in.avm_binary_latch, + in.avm_binary_start, in.avm_byte_lookup_bin_sel, - in.avm_binary_instr_tag, + in.avm_binary_in_tag, in.avm_binary_mem_tag_ctr, - in.avm_byte_lookup_table_instr_tags, + in.avm_byte_lookup_table_in_tags, in.avm_byte_lookup_table_byte_lengths); } @@ -155,11 +155,11 @@ class lookup_byte_lengths_lookup_settings { return std::forward_as_tuple(in.lookup_byte_lengths, in.lookup_byte_lengths_counts, - in.avm_binary_latch, + in.avm_binary_start, in.avm_byte_lookup_bin_sel, - in.avm_binary_instr_tag, + in.avm_binary_in_tag, in.avm_binary_mem_tag_ctr, - in.avm_byte_lookup_table_instr_tags, + in.avm_byte_lookup_table_in_tags, in.avm_byte_lookup_table_byte_lengths); } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp index 4e81dafacf7..1c68236d82f 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp @@ -12,7 +12,7 @@ namespace bb { class perm_main_bin_permutation_settings { public: // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 6; + constexpr static size_t COLUMNS_PER_SET = 5; /** * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the @@ -23,7 +23,7 @@ class perm_main_bin_permutation_settings { template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) { - return (in.avm_main_bin_sel == 1 || in.avm_binary_latch == 1); + return (in.avm_main_bin_sel == 1 || in.avm_binary_start == 1); } /** @@ -49,19 +49,17 @@ class perm_main_bin_permutation_settings { return std::forward_as_tuple(in.perm_main_bin, in.avm_main_bin_sel, in.avm_main_bin_sel, - in.avm_binary_latch, - in.avm_main_clk, + in.avm_binary_start, in.avm_main_ia, in.avm_main_ib, in.avm_main_ic, in.avm_main_bin_op_id, in.avm_main_in_tag, - in.avm_binary_bin_clk, in.avm_binary_acc_ia, in.avm_binary_acc_ib, in.avm_binary_acc_ic, in.avm_binary_op_id, - in.avm_binary_instr_tag); + in.avm_binary_in_tag); } /** @@ -87,19 +85,17 @@ class perm_main_bin_permutation_settings { return std::forward_as_tuple(in.perm_main_bin, in.avm_main_bin_sel, in.avm_main_bin_sel, - in.avm_binary_latch, - in.avm_main_clk, + in.avm_binary_start, in.avm_main_ia, in.avm_main_ib, in.avm_main_ic, in.avm_main_bin_op_id, in.avm_main_in_tag, - in.avm_binary_bin_clk, in.avm_binary_acc_ia, in.avm_binary_acc_ib, in.avm_binary_acc_ic, in.avm_binary_op_id, - in.avm_binary_instr_tag); + in.avm_binary_in_tag); } }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp index fa3f8fb6008..c2969a0d32f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp @@ -32,13 +32,14 @@ void AvmBinaryTraceBuilder::reset() * @param num_bytes The number of bytes given the instr_tag. * @return BE encoded bytes with an extra zero padding (final length is num_bytes + 1). */ -std::vector bytes_decompose_be(uint128_t const& val, size_t num_bytes) +std::vector bytes_decompose_le(uint128_t const& val) { // This uses a Network Byte Order (Big-Endian) and since a uint128_t is used // this is guaranteed to be of length 16 (zero-padded if necessary). - std::vector val_bytes = to_buffer(val); + std::vector bytes = to_buffer(val); // Since the trace expects BE, we take only the portion that corresponds to the bytes we need (given the instr_tag) - std::vector bytes(val_bytes.end() - static_cast(num_bytes), val_bytes.end()); + std::reverse(bytes.begin(), bytes.end()); + // std::vector bytes(val_bytes.end() - static_cast(num_bytes), val_bytes.end()); // To simplify the loop in witness generation we add a zero at the end since it's a "free input" bytes.push_back(0); @@ -61,22 +62,22 @@ void AvmBinaryTraceBuilder::entry_builder( size_t num_bytes = 1 << (static_cast(instr_tag) - 1); // Big Endian encoded - std::vector a_bytes = bytes_decompose_be(a, num_bytes); - std::vector b_bytes = bytes_decompose_be(b, num_bytes); - std::vector c_bytes = bytes_decompose_be(c, num_bytes); + std::vector a_bytes = bytes_decompose_le(a); + std::vector b_bytes = bytes_decompose_le(b); + std::vector c_bytes = bytes_decompose_le(c); - uint128_t acc_ia = 0; - uint128_t acc_ib = 0; - uint128_t acc_ic = 0; + uint128_t acc_ia = a; + uint128_t acc_ib = b; + uint128_t acc_ic = c; // We have num_bytes + 1 rows to add to the binary trace; for (size_t i = 0; i <= num_bytes; i++) { binary_trace.push_back(AvmBinaryTraceBuilder::BinaryTraceEntry{ .binary_clk = clk, .op_id = op_id, - .instr_tag = static_cast(instr_tag), - .mem_tag_ctr = static_cast(i), - .latch = i == num_bytes, + .in_tag = static_cast(instr_tag), + .mem_tag_ctr = static_cast(num_bytes - i), + .start = i == 0, .acc_ia = FF(uint256_t::from_uint128(acc_ia)), .acc_ib = FF(uint256_t::from_uint128(acc_ib)), .acc_ic = FF(uint256_t::from_uint128(acc_ic)), @@ -86,9 +87,9 @@ void AvmBinaryTraceBuilder::entry_builder( }); auto lookup_index = static_cast((op_id << 16) + (a_bytes[i] << 8) + b_bytes[i]); byte_operation_counter[lookup_index]++; - acc_ia = acc_ia * 256 + a_bytes[i]; - acc_ib = acc_ib * 256 + b_bytes[i]; - acc_ic = acc_ic * 256 + c_bytes[i]; + acc_ia = (acc_ia - a_bytes[i]) / 256; + acc_ib = (acc_ib - b_bytes[i]) / 256; + acc_ic = (acc_ic - c_bytes[i]) / 256; } // There is 1 latch per call, therefore byte_length check increments byte_length_counter[static_cast(instr_tag)]++; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp index 4cc45549155..0bfcd074cb0 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp @@ -10,11 +10,11 @@ class AvmBinaryTraceBuilder { struct BinaryTraceEntry { uint32_t binary_clk = 0; uint8_t op_id = 0; - uint8_t instr_tag = 0; + uint8_t in_tag = 0; uint8_t mem_tag_ctr = 0; uint256_t factor = 0; - bool latch = false; + bool start = false; FF acc_ia = FF(0); FF acc_ib = FF(0); 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 50f36fea2cc..aefc8d0081a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -1208,12 +1208,12 @@ std::vector AvmTraceBuilder::finalize() dest.avm_binary_acc_ia = src.acc_ia; dest.avm_binary_acc_ib = src.acc_ib; dest.avm_binary_acc_ic = src.acc_ic; - dest.avm_binary_instr_tag = src.instr_tag; + dest.avm_binary_in_tag = src.in_tag; dest.avm_binary_op_id = src.op_id; dest.avm_binary_bin_ia_bytes = src.bin_ia_bytes; dest.avm_binary_bin_ib_bytes = src.bin_ib_bytes; dest.avm_binary_bin_ic_bytes = src.bin_ic_bytes; - dest.avm_binary_latch = FF(static_cast(src.latch)); + dest.avm_binary_start = FF(static_cast(src.start)); dest.avm_binary_mem_tag_ctr = src.mem_tag_ctr; } @@ -1250,14 +1250,14 @@ std::vector AvmTraceBuilder::finalize() // {U8: 1, U16: 2, U32: 4, U64: 8, U128: 16} for (uint8_t avm_in_tag = 0; avm_in_tag < 5; avm_in_tag++) { // The +1 here is because the instruction tags we care about (i.e excl U0 and FF) has the range [1,5] - main_trace.at(avm_in_tag).avm_byte_lookup_table_instr_tags = avm_in_tag + 1; + main_trace.at(avm_in_tag).avm_byte_lookup_table_in_tags = avm_in_tag + 1; main_trace.at(avm_in_tag).avm_byte_lookup_table_byte_lengths = static_cast(pow(2, avm_in_tag)); main_trace.at(avm_in_tag).lookup_byte_lengths_counts = bin_trace_builder.byte_length_counter[avm_in_tag + 1]; } } // Adding extra row for the shifted values at the top of the execution trace. - Row first_row = Row{ .avm_main_first = FF(1), .avm_mem_m_lastAccess = FF(1), .avm_binary_latch = FF() }; + Row first_row = Row{ .avm_main_first = FF(1), .avm_mem_m_lastAccess = FF(1) }; main_trace.insert(main_trace.begin(), first_row); auto trace = std::move(main_trace); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp index 14e13c08bc3..4d29b1944e4 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -88,20 +88,19 @@ template struct AvmFullRow { FF avm_byte_lookup_table_input_b{}; FF avm_byte_lookup_table_output{}; FF avm_byte_lookup_bin_sel{}; - FF avm_byte_lookup_table_instr_tags{}; + FF avm_byte_lookup_table_in_tags{}; FF avm_byte_lookup_table_byte_lengths{}; FF avm_binary_bin_clk{}; FF avm_binary_bin_sel{}; FF avm_binary_acc_ia{}; FF avm_binary_acc_ib{}; FF avm_binary_acc_ic{}; - FF avm_binary_instr_tag{}; + FF avm_binary_in_tag{}; FF avm_binary_op_id{}; FF avm_binary_bin_ia_bytes{}; FF avm_binary_bin_ib_bytes{}; FF avm_binary_bin_ic_bytes{}; - FF avm_binary_latch{}; - FF avm_binary_factor{}; + FF avm_binary_start{}; FF avm_binary_mem_tag_ctr{}; FF avm_main_pc{}; FF avm_main_internal_return_ptr{}; @@ -161,24 +160,25 @@ template struct AvmFullRow { FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_u16_r3_shift{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_alu_alu_u16_r1_shift{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u16_r5_shift{}; FF avm_mem_m_val_shift{}; - FF avm_mem_m_addr_shift{}; FF avm_mem_m_tag_shift{}; FF avm_mem_m_rw_shift{}; - FF avm_binary_mem_tag_ctr_shift{}; + FF avm_mem_m_addr_shift{}; FF avm_binary_acc_ic_shift{}; FF avm_binary_acc_ib_shift{}; + FF avm_binary_op_id_shift{}; FF avm_binary_acc_ia_shift{}; + FF avm_binary_mem_tag_ctr_shift{}; FF avm_main_internal_return_ptr_shift{}; FF avm_main_pc_shift{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u16_r4_shift{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r5_shift{}; }; class AvmCircuitBuilder { @@ -192,7 +192,7 @@ class AvmCircuitBuilder { using ProverPolynomials = Flavor::ProverPolynomials; static constexpr size_t num_fixed_columns = 147; - static constexpr size_t num_polys = 129; + static constexpr size_t num_polys = 128; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -264,20 +264,19 @@ class AvmCircuitBuilder { polys.avm_byte_lookup_table_input_b[i] = rows[i].avm_byte_lookup_table_input_b; polys.avm_byte_lookup_table_output[i] = rows[i].avm_byte_lookup_table_output; polys.avm_byte_lookup_bin_sel[i] = rows[i].avm_byte_lookup_bin_sel; - polys.avm_byte_lookup_table_instr_tags[i] = rows[i].avm_byte_lookup_table_instr_tags; + polys.avm_byte_lookup_table_in_tags[i] = rows[i].avm_byte_lookup_table_in_tags; polys.avm_byte_lookup_table_byte_lengths[i] = rows[i].avm_byte_lookup_table_byte_lengths; polys.avm_binary_bin_clk[i] = rows[i].avm_binary_bin_clk; polys.avm_binary_bin_sel[i] = rows[i].avm_binary_bin_sel; polys.avm_binary_acc_ia[i] = rows[i].avm_binary_acc_ia; polys.avm_binary_acc_ib[i] = rows[i].avm_binary_acc_ib; polys.avm_binary_acc_ic[i] = rows[i].avm_binary_acc_ic; - polys.avm_binary_instr_tag[i] = rows[i].avm_binary_instr_tag; + polys.avm_binary_in_tag[i] = rows[i].avm_binary_in_tag; polys.avm_binary_op_id[i] = rows[i].avm_binary_op_id; polys.avm_binary_bin_ia_bytes[i] = rows[i].avm_binary_bin_ia_bytes; polys.avm_binary_bin_ib_bytes[i] = rows[i].avm_binary_bin_ib_bytes; polys.avm_binary_bin_ic_bytes[i] = rows[i].avm_binary_bin_ic_bytes; - polys.avm_binary_latch[i] = rows[i].avm_binary_latch; - polys.avm_binary_factor[i] = rows[i].avm_binary_factor; + polys.avm_binary_start[i] = rows[i].avm_binary_start; polys.avm_binary_mem_tag_ctr[i] = rows[i].avm_binary_mem_tag_ctr; polys.avm_main_pc[i] = rows[i].avm_main_pc; polys.avm_main_internal_return_ptr[i] = rows[i].avm_main_internal_return_ptr; @@ -339,24 +338,25 @@ class AvmCircuitBuilder { polys.incl_mem_tag_err_counts[i] = rows[i].incl_mem_tag_err_counts; } + polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.shifted()); + polys.avm_alu_alu_u16_r4_shift = Polynomial(polys.avm_alu_alu_u16_r4.shifted()); + polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); + polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); + polys.avm_alu_alu_u16_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); + polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.shifted()); + polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); + polys.avm_alu_alu_u16_r5_shift = Polynomial(polys.avm_alu_alu_u16_r5.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_mem_m_tag_shift = Polynomial(polys.avm_mem_m_tag.shifted()); polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); - polys.avm_binary_mem_tag_ctr_shift = Polynomial(polys.avm_binary_mem_tag_ctr.shifted()); + polys.avm_mem_m_addr_shift = Polynomial(polys.avm_mem_m_addr.shifted()); polys.avm_binary_acc_ic_shift = Polynomial(polys.avm_binary_acc_ic.shifted()); polys.avm_binary_acc_ib_shift = Polynomial(polys.avm_binary_acc_ib.shifted()); + polys.avm_binary_op_id_shift = Polynomial(polys.avm_binary_op_id.shifted()); polys.avm_binary_acc_ia_shift = Polynomial(polys.avm_binary_acc_ia.shifted()); + polys.avm_binary_mem_tag_ctr_shift = Polynomial(polys.avm_binary_mem_tag_ctr.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_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); - polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.shifted()); - polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.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_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); - polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); - polys.avm_alu_alu_u16_r5_shift = Polynomial(polys.avm_alu_alu_u16_r5.shifted()); return polys; } @@ -428,6 +428,10 @@ class AvmCircuitBuilder { return true; }; + if (!evaluate_relation.template operator()>("avm_alu", + Avm_vm::get_relation_label_avm_alu)) { + return false; + } if (!evaluate_relation.template operator()>("avm_mem", Avm_vm::get_relation_label_avm_mem)) { return false; @@ -440,10 +444,6 @@ class AvmCircuitBuilder { 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_logderivative.template operator()>("PERM_MAIN_ALU")) { return false; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 26e30d2b8e3..17b9911e1f2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -46,16 +46,16 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 127; + static constexpr size_t NUM_WITNESS_ENTITIES = 126; 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 = 147; - using Relations = std::tuple, + using Relations = std::tuple, + Avm_vm::avm_mem, Avm_vm::avm_binary, Avm_vm::avm_main, - Avm_vm::avm_alu, perm_main_alu_relation, perm_main_bin_relation, perm_main_mem_a_relation, @@ -151,20 +151,19 @@ class AvmFlavor { avm_byte_lookup_table_input_b, avm_byte_lookup_table_output, avm_byte_lookup_bin_sel, - avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_in_tags, avm_byte_lookup_table_byte_lengths, avm_binary_bin_clk, avm_binary_bin_sel, avm_binary_acc_ia, avm_binary_acc_ib, avm_binary_acc_ic, - avm_binary_instr_tag, + avm_binary_in_tag, avm_binary_op_id, avm_binary_bin_ia_bytes, avm_binary_bin_ib_bytes, avm_binary_bin_ic_bytes, - avm_binary_latch, - avm_binary_factor, + avm_binary_start, avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, @@ -281,20 +280,19 @@ class AvmFlavor { avm_byte_lookup_table_input_b, avm_byte_lookup_table_output, avm_byte_lookup_bin_sel, - avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_in_tags, avm_byte_lookup_table_byte_lengths, avm_binary_bin_clk, avm_binary_bin_sel, avm_binary_acc_ia, avm_binary_acc_ib, avm_binary_acc_ic, - avm_binary_instr_tag, + avm_binary_in_tag, avm_binary_op_id, avm_binary_bin_ia_bytes, avm_binary_bin_ib_bytes, avm_binary_bin_ic_bytes, - avm_binary_latch, - avm_binary_factor, + avm_binary_start, avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, @@ -417,20 +415,19 @@ class AvmFlavor { avm_byte_lookup_table_input_b, avm_byte_lookup_table_output, avm_byte_lookup_bin_sel, - avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_in_tags, avm_byte_lookup_table_byte_lengths, avm_binary_bin_clk, avm_binary_bin_sel, avm_binary_acc_ia, avm_binary_acc_ib, avm_binary_acc_ic, - avm_binary_instr_tag, + avm_binary_in_tag, avm_binary_op_id, avm_binary_bin_ia_bytes, avm_binary_bin_ib_bytes, avm_binary_bin_ic_bytes, - avm_binary_latch, - avm_binary_factor, + avm_binary_start, avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, @@ -490,24 +487,25 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r1_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r5_shift, avm_mem_m_val_shift, - avm_mem_m_addr_shift, avm_mem_m_tag_shift, avm_mem_m_rw_shift, - avm_binary_mem_tag_ctr_shift, + avm_mem_m_addr_shift, avm_binary_acc_ic_shift, avm_binary_acc_ib_shift, + avm_binary_op_id_shift, avm_binary_acc_ia_shift, + avm_binary_mem_tag_ctr_shift, avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r5_shift) + avm_main_pc_shift) RefVector get_wires() { @@ -567,20 +565,19 @@ class AvmFlavor { avm_byte_lookup_table_input_b, avm_byte_lookup_table_output, avm_byte_lookup_bin_sel, - avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_in_tags, avm_byte_lookup_table_byte_lengths, avm_binary_bin_clk, avm_binary_bin_sel, avm_binary_acc_ia, avm_binary_acc_ib, avm_binary_acc_ic, - avm_binary_instr_tag, + avm_binary_in_tag, avm_binary_op_id, avm_binary_bin_ia_bytes, avm_binary_bin_ib_bytes, avm_binary_bin_ic_bytes, - avm_binary_latch, - avm_binary_factor, + avm_binary_start, avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, @@ -640,24 +637,25 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r1_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r5_shift, avm_mem_m_val_shift, - avm_mem_m_addr_shift, avm_mem_m_tag_shift, avm_mem_m_rw_shift, - avm_binary_mem_tag_ctr_shift, + avm_mem_m_addr_shift, avm_binary_acc_ic_shift, avm_binary_acc_ib_shift, + avm_binary_op_id_shift, avm_binary_acc_ia_shift, + avm_binary_mem_tag_ctr_shift, avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r5_shift }; + avm_main_pc_shift }; }; RefVector get_unshifted() { @@ -717,20 +715,19 @@ class AvmFlavor { avm_byte_lookup_table_input_b, avm_byte_lookup_table_output, avm_byte_lookup_bin_sel, - avm_byte_lookup_table_instr_tags, + avm_byte_lookup_table_in_tags, avm_byte_lookup_table_byte_lengths, avm_binary_bin_clk, avm_binary_bin_sel, avm_binary_acc_ia, avm_binary_acc_ib, avm_binary_acc_ic, - avm_binary_instr_tag, + avm_binary_in_tag, avm_binary_op_id, avm_binary_bin_ia_bytes, avm_binary_bin_ib_bytes, avm_binary_bin_ic_bytes, - avm_binary_latch, - avm_binary_factor, + avm_binary_start, avm_binary_mem_tag_ctr, avm_main_pc, avm_main_internal_return_ptr, @@ -793,21 +790,23 @@ class AvmFlavor { }; RefVector get_to_be_shifted() { - return { avm_mem_m_val, avm_mem_m_addr, avm_mem_m_tag, - avm_mem_m_rw, avm_binary_mem_tag_ctr, avm_binary_acc_ic, - avm_binary_acc_ib, avm_binary_acc_ia, avm_main_internal_return_ptr, - avm_main_pc, avm_alu_alu_u16_r7, avm_alu_alu_u16_r0, - avm_alu_alu_u16_r1, avm_alu_alu_u16_r3, avm_alu_alu_u16_r4, - avm_alu_alu_u16_r6, avm_alu_alu_u16_r2, avm_alu_alu_u16_r5 }; + return { avm_alu_alu_u16_r0, avm_alu_alu_u16_r4, avm_alu_alu_u16_r2, + avm_alu_alu_u16_r3, avm_alu_alu_u16_r6, avm_alu_alu_u16_r1, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r5, avm_mem_m_val, + avm_mem_m_tag, avm_mem_m_rw, avm_mem_m_addr, + avm_binary_acc_ic, avm_binary_acc_ib, avm_binary_op_id, + avm_binary_acc_ia, avm_binary_mem_tag_ctr, avm_main_internal_return_ptr, + avm_main_pc }; }; RefVector get_shifted() { - return { avm_mem_m_val_shift, avm_mem_m_addr_shift, avm_mem_m_tag_shift, - avm_mem_m_rw_shift, avm_binary_mem_tag_ctr_shift, avm_binary_acc_ic_shift, - avm_binary_acc_ib_shift, avm_binary_acc_ia_shift, avm_main_internal_return_ptr_shift, - avm_main_pc_shift, avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r3_shift, avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r2_shift, avm_alu_alu_u16_r5_shift }; + return { avm_alu_alu_u16_r0_shift, avm_alu_alu_u16_r4_shift, avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r3_shift, avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r1_shift, + avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r5_shift, avm_mem_m_val_shift, + avm_mem_m_tag_shift, avm_mem_m_rw_shift, avm_mem_m_addr_shift, + avm_binary_acc_ic_shift, avm_binary_acc_ib_shift, avm_binary_op_id_shift, + avm_binary_acc_ia_shift, avm_binary_mem_tag_ctr_shift, avm_main_internal_return_ptr_shift, + avm_main_pc_shift }; }; }; @@ -820,12 +819,13 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_mem_m_val, avm_mem_m_addr, avm_mem_m_tag, - avm_mem_m_rw, avm_binary_mem_tag_ctr, avm_binary_acc_ic, - avm_binary_acc_ib, avm_binary_acc_ia, avm_main_internal_return_ptr, - avm_main_pc, avm_alu_alu_u16_r7, avm_alu_alu_u16_r0, - avm_alu_alu_u16_r1, avm_alu_alu_u16_r3, avm_alu_alu_u16_r4, - avm_alu_alu_u16_r6, avm_alu_alu_u16_r2, avm_alu_alu_u16_r5 }; + return { avm_alu_alu_u16_r0, avm_alu_alu_u16_r4, avm_alu_alu_u16_r2, + avm_alu_alu_u16_r3, avm_alu_alu_u16_r6, avm_alu_alu_u16_r1, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r5, avm_mem_m_val, + avm_mem_m_tag, avm_mem_m_rw, avm_mem_m_addr, + avm_binary_acc_ic, avm_binary_acc_ib, avm_binary_op_id, + avm_binary_acc_ia, avm_binary_mem_tag_ctr, avm_main_internal_return_ptr, + avm_main_pc }; }; // The plookup wires that store plookup read data. @@ -958,20 +958,19 @@ class AvmFlavor { Base::avm_byte_lookup_table_input_b = "AVM_BYTE_LOOKUP_TABLE_INPUT_B"; Base::avm_byte_lookup_table_output = "AVM_BYTE_LOOKUP_TABLE_OUTPUT"; Base::avm_byte_lookup_bin_sel = "AVM_BYTE_LOOKUP_BIN_SEL"; - Base::avm_byte_lookup_table_instr_tags = "AVM_BYTE_LOOKUP_TABLE_INSTR_TAGS"; + Base::avm_byte_lookup_table_in_tags = "AVM_BYTE_LOOKUP_TABLE_IN_TAGS"; Base::avm_byte_lookup_table_byte_lengths = "AVM_BYTE_LOOKUP_TABLE_BYTE_LENGTHS"; Base::avm_binary_bin_clk = "AVM_BINARY_BIN_CLK"; Base::avm_binary_bin_sel = "AVM_BINARY_BIN_SEL"; Base::avm_binary_acc_ia = "AVM_BINARY_ACC_IA"; Base::avm_binary_acc_ib = "AVM_BINARY_ACC_IB"; Base::avm_binary_acc_ic = "AVM_BINARY_ACC_IC"; - Base::avm_binary_instr_tag = "AVM_BINARY_INSTR_TAG"; + Base::avm_binary_in_tag = "AVM_BINARY_IN_TAG"; Base::avm_binary_op_id = "AVM_BINARY_OP_ID"; Base::avm_binary_bin_ia_bytes = "AVM_BINARY_BIN_IA_BYTES"; Base::avm_binary_bin_ib_bytes = "AVM_BINARY_BIN_IB_BYTES"; Base::avm_binary_bin_ic_bytes = "AVM_BINARY_BIN_IC_BYTES"; - Base::avm_binary_latch = "AVM_BINARY_LATCH"; - Base::avm_binary_factor = "AVM_BINARY_FACTOR"; + Base::avm_binary_start = "AVM_BINARY_START"; Base::avm_binary_mem_tag_ctr = "AVM_BINARY_MEM_TAG_CTR"; Base::avm_main_pc = "AVM_MAIN_PC"; Base::avm_main_internal_return_ptr = "AVM_MAIN_INTERNAL_RETURN_PTR"; @@ -1104,20 +1103,19 @@ class AvmFlavor { Commitment avm_byte_lookup_table_input_b; Commitment avm_byte_lookup_table_output; Commitment avm_byte_lookup_bin_sel; - Commitment avm_byte_lookup_table_instr_tags; + Commitment avm_byte_lookup_table_in_tags; Commitment avm_byte_lookup_table_byte_lengths; Commitment avm_binary_bin_clk; Commitment avm_binary_bin_sel; Commitment avm_binary_acc_ia; Commitment avm_binary_acc_ib; Commitment avm_binary_acc_ic; - Commitment avm_binary_instr_tag; + Commitment avm_binary_in_tag; Commitment avm_binary_op_id; Commitment avm_binary_bin_ia_bytes; Commitment avm_binary_bin_ib_bytes; Commitment avm_binary_bin_ic_bytes; - Commitment avm_binary_latch; - Commitment avm_binary_factor; + Commitment avm_binary_start; Commitment avm_binary_mem_tag_ctr; Commitment avm_main_pc; Commitment avm_main_internal_return_ptr; @@ -1250,8 +1248,7 @@ class AvmFlavor { avm_byte_lookup_table_input_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_byte_lookup_table_output = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_byte_lookup_bin_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); - avm_byte_lookup_table_instr_tags = - deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_byte_lookup_table_in_tags = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_byte_lookup_table_byte_lengths = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_bin_clk = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1259,13 +1256,12 @@ class AvmFlavor { avm_binary_acc_ia = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_acc_ib = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_acc_ic = deserialize_from_buffer(Transcript::proof_data, num_frs_read); - avm_binary_instr_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_op_id = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_bin_ia_bytes = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_bin_ib_bytes = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_bin_ic_bytes = deserialize_from_buffer(Transcript::proof_data, num_frs_read); - avm_binary_latch = deserialize_from_buffer(Transcript::proof_data, num_frs_read); - avm_binary_factor = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_start = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_mem_tag_ctr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_pc = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_internal_return_ptr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1402,20 +1398,19 @@ class AvmFlavor { serialize_to_buffer(avm_byte_lookup_table_input_b, Transcript::proof_data); serialize_to_buffer(avm_byte_lookup_table_output, Transcript::proof_data); serialize_to_buffer(avm_byte_lookup_bin_sel, Transcript::proof_data); - serialize_to_buffer(avm_byte_lookup_table_instr_tags, Transcript::proof_data); + serialize_to_buffer(avm_byte_lookup_table_in_tags, Transcript::proof_data); serialize_to_buffer(avm_byte_lookup_table_byte_lengths, Transcript::proof_data); serialize_to_buffer(avm_binary_bin_clk, Transcript::proof_data); serialize_to_buffer(avm_binary_bin_sel, Transcript::proof_data); serialize_to_buffer(avm_binary_acc_ia, Transcript::proof_data); serialize_to_buffer(avm_binary_acc_ib, Transcript::proof_data); serialize_to_buffer(avm_binary_acc_ic, Transcript::proof_data); - serialize_to_buffer(avm_binary_instr_tag, Transcript::proof_data); + serialize_to_buffer(avm_binary_in_tag, Transcript::proof_data); serialize_to_buffer(avm_binary_op_id, Transcript::proof_data); serialize_to_buffer(avm_binary_bin_ia_bytes, Transcript::proof_data); serialize_to_buffer(avm_binary_bin_ib_bytes, Transcript::proof_data); serialize_to_buffer(avm_binary_bin_ic_bytes, Transcript::proof_data); - serialize_to_buffer(avm_binary_latch, Transcript::proof_data); - serialize_to_buffer(avm_binary_factor, Transcript::proof_data); + serialize_to_buffer(avm_binary_start, Transcript::proof_data); serialize_to_buffer(avm_binary_mem_tag_ctr, Transcript::proof_data); serialize_to_buffer(avm_main_pc, Transcript::proof_data); serialize_to_buffer(avm_main_internal_return_ptr, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 49bb8fe10c2..76edb640982 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -146,8 +146,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_output); commitments.avm_byte_lookup_bin_sel = transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_bin_sel); - commitments.avm_byte_lookup_table_instr_tags = - transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_instr_tags); + commitments.avm_byte_lookup_table_in_tags = + transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_in_tags); commitments.avm_byte_lookup_table_byte_lengths = transcript->template receive_from_prover(commitment_labels.avm_byte_lookup_table_byte_lengths); commitments.avm_binary_bin_clk = @@ -160,8 +160,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_binary_acc_ib); commitments.avm_binary_acc_ic = transcript->template receive_from_prover(commitment_labels.avm_binary_acc_ic); - commitments.avm_binary_instr_tag = - transcript->template receive_from_prover(commitment_labels.avm_binary_instr_tag); + commitments.avm_binary_in_tag = + transcript->template receive_from_prover(commitment_labels.avm_binary_in_tag); commitments.avm_binary_op_id = transcript->template receive_from_prover(commitment_labels.avm_binary_op_id); commitments.avm_binary_bin_ia_bytes = @@ -170,10 +170,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_binary_bin_ib_bytes); commitments.avm_binary_bin_ic_bytes = transcript->template receive_from_prover(commitment_labels.avm_binary_bin_ic_bytes); - commitments.avm_binary_latch = - transcript->template receive_from_prover(commitment_labels.avm_binary_latch); - commitments.avm_binary_factor = - transcript->template receive_from_prover(commitment_labels.avm_binary_factor); + commitments.avm_binary_start = + transcript->template receive_from_prover(commitment_labels.avm_binary_start); commitments.avm_binary_mem_tag_ctr = transcript->template receive_from_prover(commitment_labels.avm_binary_mem_tag_ctr); commitments.avm_main_pc = transcript->template receive_from_prover(commitment_labels.avm_main_pc); 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 ef662417695..644d53de2d9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -108,12 +108,12 @@ void common_validate_bit_op(std::vector const& trace, // Use the row in the main trace to find the same operation in the alu trace. FF clk = row->avm_main_clk; - auto bin_row_latched = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_binary_bin_clk == clk && r.avm_binary_latch == FF(1); + auto bin_row_start = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { + return r.avm_binary_bin_clk == clk && r.avm_binary_start == FF(1); }); // Check that both rows were found - EXPECT_TRUE(bin_row_latched != trace.end()); + EXPECT_TRUE(bin_row_start != trace.end()); EXPECT_TRUE(row != trace.end()); // Check that the correct result is stored at the expected memory location. @@ -137,14 +137,14 @@ void common_validate_bit_op(std::vector const& trace, // Check the instruction tag EXPECT_EQ(row->avm_main_in_tag, FF(static_cast(tag))); - // Check that latched row is the same as what is copied into the main trace - EXPECT_EQ(bin_row_latched->avm_binary_acc_ia, a); - EXPECT_EQ(bin_row_latched->avm_binary_acc_ib, b); - EXPECT_EQ(bin_row_latched->avm_binary_acc_ic, c); + // Check that start row is the same as what is copied into the main trace + EXPECT_EQ(bin_row_start->avm_binary_acc_ia, a); + EXPECT_EQ(bin_row_start->avm_binary_acc_ib, b); + EXPECT_EQ(bin_row_start->avm_binary_acc_ic, c); - EXPECT_EQ(bin_row_latched->avm_binary_op_id, op_id); - EXPECT_EQ(bin_row_latched->avm_binary_bin_sel, FF(1)); - EXPECT_EQ(bin_row_latched->avm_binary_instr_tag, static_cast(tag)); + EXPECT_EQ(bin_row_start->avm_binary_op_id, op_id); + EXPECT_EQ(bin_row_start->avm_binary_bin_sel, FF(1)); + EXPECT_EQ(bin_row_start->avm_binary_in_tag, static_cast(tag)); } std::vector gen_mutated_trace_not(FF const& a, FF const& c_mutated, avm_trace::AvmMemoryTag tag) @@ -163,10 +163,10 @@ std::vector gen_mutated_trace_not(FF const& a, FF const& c_mutated, avm_tra // These are the potential failures we handle for the negative tests involving the binary trace. enum BIT_FAILURES { - IncorrectFactor, BitDecomposition, MemTagCtr, IncorrectAcc, + InconsistentOpId, ByteLookupError, ByteLengthError, }; @@ -177,60 +177,70 @@ std::vector gen_mutated_trace_bit(std::vector trace, { auto main_trace_row = std::ranges::find_if(trace.begin(), trace.end(), select_row); auto main_clk = main_trace_row->avm_main_clk; - // The corresponding row in the binary trace + // The corresponding row in the binary trace as well as the row where start = 1 auto binary_row = std::ranges::find_if( trace.begin(), trace.end(), [main_clk](Row r) { return r.avm_binary_bin_clk == main_clk; }); - // The corresponding row in the binary trace where the latch is set to 1 - auto latched_row = std::ranges::find_if(trace.begin(), trace.end(), [main_clk](Row r) { - return r.avm_binary_bin_clk == main_clk && r.avm_binary_latch == FF(1); + // The corresponding row in the binary trace where the computation ends. + auto last_row = std::ranges::find_if(trace.begin(), trace.end(), [main_clk](Row r) { + return r.avm_binary_bin_clk == main_clk && r.avm_binary_mem_tag_ctr == FF(0); }); switch (fail_mode) { - case IncorrectFactor: { - // Simply zero the factor at the start as the relation checks it is 1. - binary_row->avm_binary_factor = 0; - break; - } case BitDecomposition: { // Incrementing the bytes should indicate an incorrect decomposition + // The lookups are checked later so this will throw an error about decomposition binary_row->avm_binary_bin_ic_bytes++; break; } case MemTagCtr: { - // mem_tag_ctr' - mem_tag_ctr = 2, breaking the incrementing relation + // Increment instead of decrementing binary_row->avm_binary_mem_tag_ctr++; break; } case IncorrectAcc: { - // Accumulator should start at 0; + // The lookups are checked later so this will throw an error about accumulation binary_row->avm_binary_acc_ic++; break; } + case InconsistentOpId: { + // We don't update the first index as that is checked by the permutation check. + // So we update the next op_id to be incorrect. + auto first_index = static_cast(std::distance(trace.begin(), binary_row)); + trace.at(first_index + 1).avm_binary_op_id++; + break; + } case ByteLookupError: { - // In the latched row the bytes = 0, this sets it to a value where the lookup - // involving a_bytes and b_bytes are incorrect - latched_row->avm_binary_bin_ic_bytes = static_cast(uint128_t{ c_mutated }); + // Update the trace to be the mutated value, which also (conveniently) + // fits into a byte so we can also update the ic_byte decomposition. + // We intentionally select the mutated value to be 0-bytes everywhere else so we dont need to + // update anything there or in the corresponding accumulators. + mutate_ic_in_trace(trace, std::move(select_row), c_mutated, false); + binary_row->avm_binary_acc_ic = c_mutated; + binary_row->avm_binary_bin_ic_bytes = static_cast(uint128_t{ c_mutated }); break; } - case ByteLengthError: - auto latch_index = static_cast(std::distance(trace.begin(), latched_row)); - // Set the latched row to be 1 earlier than it should be, this triggers the byte length lookup table check. - trace.at(latch_index - 1).avm_binary_latch = FF(1); - // Update the result in the main_ic to be this new value so we dont trigger an incorrect equivalence check. - mutate_ic_in_trace(trace, std::move(select_row), trace.at(latch_index - 1).avm_binary_acc_ic, false); - // We need to zero out the previously latched row so we dont trigger any other relation checks - latched_row->avm_binary_mem_tag_ctr = 0; - latched_row->avm_binary_bin_sel = 0; - latched_row->avm_binary_latch = 0; - latched_row->avm_binary_factor = 0; - latched_row->avm_binary_acc_ia = 0; - latched_row->avm_binary_acc_ib = 0; - latched_row->avm_binary_acc_ic = 0; - latched_row->avm_binary_bin_ia_bytes = 0; - latched_row->avm_binary_bin_ib_bytes = 0; - latched_row->avm_binary_bin_ic_bytes = 0; + case ByteLengthError: { + // To trigger this error, we need to start the mem_tag ctr to be incorrect (one less than is should be) + // However, to avoid the MEM_REL_TAG error from happening instead, we need to ensure we update the mem_tag + // of all rows between the start = 1 and mem_tag = 0; + auto last_index = static_cast(std::distance(trace.begin(), last_row)); + auto first_index = static_cast(std::distance(trace.begin(), binary_row)); + for (size_t i = first_index; i <= last_index; i++) { + FF ctr = trace.at(i).avm_binary_mem_tag_ctr; + if (ctr == FF::one()) { + // If the tag is currently 1, it will be set to 0 which means we need to set bin_sel to 1. + trace.at(i).avm_binary_bin_sel = FF(1); + trace.at(i).avm_binary_mem_tag_ctr = trace.at(i).avm_binary_mem_tag_ctr - 1; + } else if (ctr == FF::zero()) { + // Leave as zero instead of underflowing + trace.at(i).avm_binary_mem_tag_ctr = 0; + } else { + // Just decrement the mem_tag_ctr + trace.at(i).avm_binary_mem_tag_ctr = trace.at(i).avm_binary_mem_tag_ctr - 1; + } + } break; } - + } return trace; } } // namespace @@ -438,7 +448,8 @@ std::vector> bit_failures = { { "ACC_REL_C", BIT_FAILURES::BitDecomposition }, { "MEM_TAG_REL", BIT_FAILURES::MemTagCtr }, { "LOOKUP_BYTE_LENGTHS", BIT_FAILURES::ByteLengthError }, - { "LOOKUP_BYTE_OPERATIONS", BIT_FAILURES::ByteLookupError } + { "LOOKUP_BYTE_OPERATIONS", BIT_FAILURES::ByteLookupError }, + { "OP_ID_REL", BIT_FAILURES::InconsistentOpId } }; // For the negative test the output is set to be incorrect so that we can test the byte lookups. // Picking "simple" inputs such as zero also makes it easier when check the byte length lookups as we dont @@ -485,7 +496,6 @@ TEST_P(AvmBitwiseNegativeTestsOr, AllNegativeTests) FF ff_output = FF(uint256_t::from_uint128(output)); std::function&& select_row = [](Row r) { return r.avm_main_sel_op_or == FF(1); }; trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); - // validate_trace_proof(std::move(trace)); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), failure_string); } INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, @@ -506,7 +516,6 @@ TEST_P(AvmBitwiseNegativeTestsXor, AllNegativeTests) FF ff_output = FF(uint256_t::from_uint128(output)); std::function&& select_row = [](Row r) { return r.avm_main_sel_op_xor == FF(1); }; trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); - // validate_trace_proof(std::move(trace)); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), failure_string) } INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, From a3bab6ce592d61f3ef593a309b7cca669f41c990 Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Fri, 22 Mar 2024 14:50:55 +0000 Subject: [PATCH 4/8] feat: update execution and deserialisation --- .../vm/avm_trace/avm_deserialization.cpp | 3 + .../vm/avm_trace/avm_execution.cpp | 23 +++++ .../barretenberg/vm/avm_trace/avm_trace.cpp | 84 +++++++++++++------ .../barretenberg/vm/avm_trace/avm_trace.hpp | 12 +-- .../vm/tests/avm_bitwise.test.cpp | 12 +-- 5 files changed, 96 insertions(+), 38 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp index 657ae07ebfb..549f68dd408 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp @@ -30,6 +30,9 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = { OpCode::EQ, three_operand_format }, // Compute - Bitwise { OpCode::NOT, { OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32 } }, + { OpCode::AND, three_operand_format }, + { OpCode::OR, three_operand_format }, + { OpCode::XOR, three_operand_format }, // Execution Environment - Calldata { OpCode::CALLDATACOPY, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, // Machine State - Internal Control Flow diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp index 2ac52622538..c14fb217f66 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -135,6 +135,29 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; + + case OpCode::AND: + trace_builder.op_and(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::OR: + trace_builder.op_or(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + + case OpCode::XOR: + trace_builder.op_xor(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; // Execution Environment - Calldata case OpCode::CALLDATACOPY: trace_builder.calldata_copy(std::get(inst.operands.at(0)), 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 aefc8d0081a..55a0648b444 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -458,14 +458,18 @@ void AvmTraceBuilder::op_eq( }); } -void AvmTraceBuilder::op_and(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) +void AvmTraceBuilder::op_and( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) { auto clk = static_cast(main_trace.size()); + auto const res = resolve_ind_three(clk, indirect, a_offset, b_offset, dst_offset); + bool tag_match = res.tag_match; + // 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; + auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); + auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + tag_match = read_a.tag_match && read_b.tag_match; // c = a == b ? 1 : 0 FF a = tag_match ? read_a.val : FF(0); @@ -474,7 +478,7 @@ void AvmTraceBuilder::op_and(uint32_t a_offset, uint32_t b_offset, uint32_t dst_ FF c = tag_match ? bin_trace_builder.op_and(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -491,21 +495,31 @@ void AvmTraceBuilder::op_and(uint32_t a_offset, uint32_t b_offset, uint32_t dst_ .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), .avm_main_rwc = FF(1), - .avm_main_mem_idx_a = FF(a_offset), - .avm_main_mem_idx_b = FF(b_offset), - .avm_main_mem_idx_c = FF(dst_offset), + .avm_main_ind_a = res.indirect_flag_a ? FF(a_offset) : FF(0), + .avm_main_ind_b = res.indirect_flag_b ? FF(b_offset) : FF(0), + .avm_main_ind_c = res.indirect_flag_c ? FF(dst_offset) : FF(0), + .avm_main_ind_op_a = FF(static_cast(res.indirect_flag_a)), + .avm_main_ind_op_b = FF(static_cast(res.indirect_flag_b)), + .avm_main_ind_op_c = FF(static_cast(res.indirect_flag_c)), + .avm_main_mem_idx_a = FF(res.direct_a_offset), + .avm_main_mem_idx_b = FF(res.direct_b_offset), + .avm_main_mem_idx_c = FF(res.direct_dst_offset), .avm_main_bin_op_id = FF(0), }); } -void AvmTraceBuilder::op_or(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) +void AvmTraceBuilder::op_or( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) { auto clk = static_cast(main_trace.size()); + auto const res = resolve_ind_three(clk, indirect, a_offset, b_offset, dst_offset); + bool tag_match = res.tag_match; + // 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; + auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); + auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + tag_match = read_a.tag_match && read_b.tag_match; // c = a == b ? 1 : 0 FF a = tag_match ? read_a.val : FF(0); @@ -514,7 +528,7 @@ void AvmTraceBuilder::op_or(uint32_t a_offset, uint32_t b_offset, uint32_t dst_o FF c = tag_match ? bin_trace_builder.op_or(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -531,21 +545,31 @@ void AvmTraceBuilder::op_or(uint32_t a_offset, uint32_t b_offset, uint32_t dst_o .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), .avm_main_rwc = FF(1), - .avm_main_mem_idx_a = FF(a_offset), - .avm_main_mem_idx_b = FF(b_offset), - .avm_main_mem_idx_c = FF(dst_offset), + .avm_main_ind_a = res.indirect_flag_a ? FF(a_offset) : FF(0), + .avm_main_ind_b = res.indirect_flag_b ? FF(b_offset) : FF(0), + .avm_main_ind_c = res.indirect_flag_c ? FF(dst_offset) : FF(0), + .avm_main_ind_op_a = FF(static_cast(res.indirect_flag_a)), + .avm_main_ind_op_b = FF(static_cast(res.indirect_flag_b)), + .avm_main_ind_op_c = FF(static_cast(res.indirect_flag_c)), + .avm_main_mem_idx_a = FF(res.direct_a_offset), + .avm_main_mem_idx_b = FF(res.direct_b_offset), + .avm_main_mem_idx_c = FF(res.direct_dst_offset), .avm_main_bin_op_id = FF(1), }); } -void AvmTraceBuilder::op_xor(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) +void AvmTraceBuilder::op_xor( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) { auto clk = static_cast(main_trace.size()); + auto const res = resolve_ind_three(clk, indirect, a_offset, b_offset, dst_offset); + bool tag_match = res.tag_match; + // 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; + auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); + auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + tag_match = read_a.tag_match && read_b.tag_match; // c = a == b ? 1 : 0 FF a = tag_match ? read_a.val : FF(0); @@ -554,7 +578,7 @@ void AvmTraceBuilder::op_xor(uint32_t a_offset, uint32_t b_offset, uint32_t dst_ FF c = tag_match ? bin_trace_builder.op_xor(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -571,9 +595,15 @@ void AvmTraceBuilder::op_xor(uint32_t a_offset, uint32_t b_offset, uint32_t dst_ .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), .avm_main_rwc = FF(1), - .avm_main_mem_idx_a = FF(a_offset), - .avm_main_mem_idx_b = FF(b_offset), - .avm_main_mem_idx_c = FF(dst_offset), + .avm_main_ind_a = res.indirect_flag_a ? FF(a_offset) : FF(0), + .avm_main_ind_b = res.indirect_flag_b ? FF(b_offset) : FF(0), + .avm_main_ind_c = res.indirect_flag_c ? FF(dst_offset) : FF(0), + .avm_main_ind_op_a = FF(static_cast(res.indirect_flag_a)), + .avm_main_ind_op_b = FF(static_cast(res.indirect_flag_b)), + .avm_main_ind_op_c = FF(static_cast(res.indirect_flag_c)), + .avm_main_mem_idx_a = FF(res.direct_a_offset), + .avm_main_mem_idx_b = FF(res.direct_b_offset), + .avm_main_mem_idx_c = FF(res.direct_dst_offset), .avm_main_bin_op_id = FF(2), }); } @@ -996,7 +1026,8 @@ void AvmTraceBuilder::internal_call(uint32_t jmp_dest) * - Set the next program counter to the return location * - Decrement the return stack pointer * - * TODO(https://github.com/AztecProtocol/aztec-packages/issues/3740): This function MUST come after a call instruction. + * TODO(https://github.com/AztecProtocol/aztec-packages/issues/3740): This function MUST come after a call + * instruction. */ void AvmTraceBuilder::internal_return() { @@ -1070,7 +1101,8 @@ std::vector AvmTraceBuilder::finalize() assert(alu_trace_size < AVM_TRACE_SIZE); // Main Trace needs to be at least as big as the biggest subtrace. - // If the bin_trace_size has entries, we need the main_trace to be as big as our byte lookup table (3 * 2**16 long) + // If the bin_trace_size has entries, we need the main_trace to be as big as our byte lookup table (3 * 2**16 + // long) size_t lookup_table = bin_trace_size > 0 ? 3 * (1 << 16) : 0; std::vector trace_sizes = { mem_trace_size, main_trace_size, alu_trace_size, lookup_table }; auto trace_size = std::max_element(trace_sizes.begin(), trace_sizes.end()); 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 84219b325a3..db65d015d65 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -47,14 +47,14 @@ class AvmTraceBuilder { // Equality with direct or indirect memory access. void op_eq(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Bitwise and with direct memory access. - void op_and(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Bitwise and with direct or indirect memory access. + void op_and(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Bitwise or with direct memory access. - void op_or(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Bitwise or with direct or indirect memory access. + void op_or(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Bitwise xor with direct memory access. - void op_xor(uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Bitwise xor with direct or indirect memory access. + void op_xor(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); // Set a constant from bytecode with direct memory access. void set(uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag); 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 644d53de2d9..506c6f8e93f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -363,7 +363,7 @@ TEST_P(AvmBitwiseTestsAnd, AllAndTest) const auto [a, b, output] = operands; trace_builder.set(a, 0, mem_tag); trace_builder.set(b, 1, mem_tag); - trace_builder.op_and(0, 1, 2, mem_tag); + trace_builder.op_and(0, 0, 1, 2, mem_tag); trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); @@ -384,7 +384,7 @@ TEST_P(AvmBitwiseTestsOr, AllOrTest) const auto [a, b, output] = operands; trace_builder.set(a, 0, mem_tag); trace_builder.set(b, 1, mem_tag); - trace_builder.op_or(0, 1, 2, mem_tag); + trace_builder.op_or(0, 0, 1, 2, mem_tag); trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); @@ -405,7 +405,7 @@ TEST_P(AvmBitwiseTestsXor, AllXorTest) const auto [a, b, output] = operands; trace_builder.set(a, 0, mem_tag); trace_builder.set(b, 1, mem_tag); - trace_builder.op_xor(0, 1, 2, mem_tag); + trace_builder.op_xor(0, 0, 1, 2, mem_tag); trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); @@ -469,7 +469,7 @@ TEST_P(AvmBitwiseNegativeTestsAnd, AllNegativeTests) auto trace_builder = avm_trace::AvmTraceBuilder(); trace_builder.set(uint128_t{ a }, 0, mem_tag); trace_builder.set(uint128_t{ b }, 1, mem_tag); - trace_builder.op_and(0, 1, 2, mem_tag); + trace_builder.op_and(0, 0, 1, 2, mem_tag); trace_builder.halt(); auto trace = trace_builder.finalize(); FF ff_output = FF(uint256_t::from_uint128(output)); @@ -490,7 +490,7 @@ TEST_P(AvmBitwiseNegativeTestsOr, AllNegativeTests) auto trace_builder = avm_trace::AvmTraceBuilder(); trace_builder.set(uint128_t{ a }, 0, mem_tag); trace_builder.set(uint128_t{ b }, 1, mem_tag); - trace_builder.op_or(0, 1, 2, mem_tag); + trace_builder.op_or(0, 0, 1, 2, mem_tag); trace_builder.halt(); auto trace = trace_builder.finalize(); FF ff_output = FF(uint256_t::from_uint128(output)); @@ -510,7 +510,7 @@ TEST_P(AvmBitwiseNegativeTestsXor, AllNegativeTests) auto trace_builder = avm_trace::AvmTraceBuilder(); trace_builder.set(uint128_t{ a }, 0, mem_tag); trace_builder.set(uint128_t{ b }, 1, mem_tag); - trace_builder.op_xor(0, 1, 2, mem_tag); + trace_builder.op_xor(0, 0, 1, 2, mem_tag); trace_builder.halt(); auto trace = trace_builder.finalize(); FF ff_output = FF(uint256_t::from_uint128(output)); From 35d6386d14c3361243f87ab802730118a381107e Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Fri, 22 Mar 2024 15:45:57 +0000 Subject: [PATCH 5/8] fix: clean up some comments --- .../src/barretenberg/vm/avm_trace/avm_binary_trace.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp index c2969a0d32f..ea5226785bc 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp @@ -30,18 +30,18 @@ void AvmBinaryTraceBuilder::reset() * @brief Helper function to correctly decompose and pad inputs * @param val The value to decompose * @param num_bytes The number of bytes given the instr_tag. - * @return BE encoded bytes with an extra zero padding (final length is num_bytes + 1). + * @return LE encoded bytes with an extra zero padding (final length is num_bytes + 1). */ std::vector bytes_decompose_le(uint128_t const& val) { // This uses a Network Byte Order (Big-Endian) and since a uint128_t is used // this is guaranteed to be of length 16 (zero-padded if necessary). std::vector bytes = to_buffer(val); - // Since the trace expects BE, we take only the portion that corresponds to the bytes we need (given the instr_tag) + // Since the trace expects LE. std::reverse(bytes.begin(), bytes.end()); - // std::vector bytes(val_bytes.end() - static_cast(num_bytes), val_bytes.end()); - - // To simplify the loop in witness generation we add a zero at the end since it's a "free input" + // To simplify the loop in witness generation we need an extra zero at index num_bytes + 1. + // Since the array is already padded to length 16, we still need to add one more 0 for the instance + // where we are operating on a U128 bytes.push_back(0); return bytes; } From dc4f0a78eb1f5091775b67c2630f3d0c21b343f3 Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Mon, 25 Mar 2024 15:36:14 +0000 Subject: [PATCH 6/8] fix: additional bin_sel constraints --- barretenberg/cpp/pil/avm/avm_binary.pil | 18 +++++++++++++++++- .../vm/avm_trace/avm_binary_trace.cpp | 2 ++ .../vm/avm_trace/avm_binary_trace.hpp | 2 ++ .../barretenberg/vm/avm_trace/avm_trace.cpp | 3 ++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/pil/avm/avm_binary.pil b/barretenberg/cpp/pil/avm/avm_binary.pil index 32f3f159b5e..7681df454df 100644 --- a/barretenberg/cpp/pil/avm/avm_binary.pil +++ b/barretenberg/cpp/pil/avm/avm_binary.pil @@ -45,7 +45,23 @@ namespace avm_binary(256); #[MEM_TAG_REL] (mem_tag_ctr' - mem_tag_ctr + 1) * mem_tag_ctr = 0; - (1 - bin_sel) * mem_tag_ctr = 0; // bin_sel is 1 when mem_tag_ctr is not zero + // Bin_sel is a boolean that is set to 1 if mem_tag_ctr != 0. + // This is checked by two relation conditions and utilising mem_tag_ctr_inv + pol commit mem_tag_ctr_inv; + + // a) Bin_sel constrained to be a boolean + // b) When mem_tag_ctr != 0, bin_sel must be 1 + // c) When mem_tag_ctr = 0, bin_sel must be 0. + #[BIN_SEL_CTR_REL] + mem_tag_ctr * mem_tag_ctr_inv - bin_sel = 0; + + // Must ensure that mem_tag_ctr_inv !=0 if mem_tag_ctr != 0, + // otherwise it is possible to set bin_sel = 0 when mem_tag_ctr != 0 in BIN_SEL_CTR_REL. + // a) When mem_tag_ctr == 0, bin_sel is 0 from BIN_SEL_CTR_REL. + // b) if bin_sel is 0, mem_tag_ctr_inv must be 1. + // c) if bin_sel is 1, mem_tag_ctr_inv constrained by BIN_SEL_CTR_REL. + (1 - bin_sel) * (mem_tag_ctr_inv - 1) = 0; + (1 - bin_sel) * acc_ia = 0; // Forces accumulator to start at zero when mem_tag_ctr == 0 (1 - bin_sel) * acc_ib = 0; // Forces accumulator to start at zero when mem_tag_ctr == 0 diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp index ea5226785bc..321d2b1ef16 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp @@ -74,9 +74,11 @@ void AvmBinaryTraceBuilder::entry_builder( for (size_t i = 0; i <= num_bytes; i++) { binary_trace.push_back(AvmBinaryTraceBuilder::BinaryTraceEntry{ .binary_clk = clk, + .bin_sel = i != num_bytes, .op_id = op_id, .in_tag = static_cast(instr_tag), .mem_tag_ctr = static_cast(num_bytes - i), + .mem_tag_ctr_inv = i == num_bytes ? FF(1) : FF(num_bytes - i).invert(), .start = i == 0, .acc_ia = FF(uint256_t::from_uint128(acc_ia)), .acc_ib = FF(uint256_t::from_uint128(acc_ib)), diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp index 0bfcd074cb0..78de178b369 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.hpp @@ -9,9 +9,11 @@ class AvmBinaryTraceBuilder { public: struct BinaryTraceEntry { uint32_t binary_clk = 0; + bool bin_sel = 0; uint8_t op_id = 0; uint8_t in_tag = 0; uint8_t mem_tag_ctr = 0; + FF mem_tag_ctr_inv = 0; uint256_t factor = 0; bool start = false; 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 55a0648b444..feee035d9f7 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -1236,7 +1236,7 @@ std::vector AvmTraceBuilder::finalize() auto const& src = bin_trace.at(i); auto& dest = main_trace.at(i); dest.avm_binary_bin_clk = src.binary_clk; - dest.avm_binary_bin_sel = FF(1); + dest.avm_binary_bin_sel = src.bin_sel; dest.avm_binary_acc_ia = src.acc_ia; dest.avm_binary_acc_ib = src.acc_ib; dest.avm_binary_acc_ic = src.acc_ic; @@ -1247,6 +1247,7 @@ std::vector AvmTraceBuilder::finalize() dest.avm_binary_bin_ic_bytes = src.bin_ic_bytes; dest.avm_binary_start = FF(static_cast(src.start)); dest.avm_binary_mem_tag_ctr = src.mem_tag_ctr; + dest.avm_binary_mem_tag_ctr_inv = src.mem_tag_ctr_inv; } // Only generate precomputed byte tables if we are actually going to use them in this main trace. From 040ceaf558c1ae8b8788e8ad9062404b8a31d892 Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Mon, 25 Mar 2024 16:49:03 +0000 Subject: [PATCH 7/8] fix: more constraints and tests --- barretenberg/cpp/pil/avm/avm_binary.pil | 16 +-- .../relations/generated/avm/avm_alu.hpp | 84 ++++++------ .../relations/generated/avm/avm_binary.hpp | 37 +++--- .../relations/generated/avm/avm_main.hpp | 96 +++++++------- .../relations/generated/avm/avm_mem.hpp | 52 ++++---- .../relations/generated/avm/declare_views.hpp | 29 ++-- .../vm/avm_trace/avm_binary_trace.cpp | 9 +- .../barretenberg/vm/avm_trace/avm_trace.cpp | 2 +- .../vm/generated/avm_circuit_builder.hpp | 70 +++++----- .../barretenberg/vm/generated/avm_flavor.hpp | 124 ++++++++++-------- .../barretenberg/vm/generated/avm_prover.hpp | 1 + .../vm/generated/avm_verifier.cpp | 2 + .../vm/tests/avm_bitwise.test.cpp | 22 +++- 13 files changed, 290 insertions(+), 254 deletions(-) diff --git a/barretenberg/cpp/pil/avm/avm_binary.pil b/barretenberg/cpp/pil/avm/avm_binary.pil index 7681df454df..78d40f4a595 100644 --- a/barretenberg/cpp/pil/avm/avm_binary.pil +++ b/barretenberg/cpp/pil/avm/avm_binary.pil @@ -49,18 +49,12 @@ namespace avm_binary(256); // This is checked by two relation conditions and utilising mem_tag_ctr_inv pol commit mem_tag_ctr_inv; - // a) Bin_sel constrained to be a boolean - // b) When mem_tag_ctr != 0, bin_sel must be 1 - // c) When mem_tag_ctr = 0, bin_sel must be 0. + // bin_sel is set to 1 when mem_tag_ctr != 0, and 0 otherwise. + // we constrain it such that bin_sel = mem_tag * mem_tag_ctr_inv unless mem_tag = 0 the bin_sel = 0 + // In here we use the consolidated equality relation because it doesnt require us to enforce + // this additional relation: mem_tag_ctr_inv = 1 when mem_tag_ctr = 0. #[BIN_SEL_CTR_REL] - mem_tag_ctr * mem_tag_ctr_inv - bin_sel = 0; - - // Must ensure that mem_tag_ctr_inv !=0 if mem_tag_ctr != 0, - // otherwise it is possible to set bin_sel = 0 when mem_tag_ctr != 0 in BIN_SEL_CTR_REL. - // a) When mem_tag_ctr == 0, bin_sel is 0 from BIN_SEL_CTR_REL. - // b) if bin_sel is 0, mem_tag_ctr_inv must be 1. - // c) if bin_sel is 1, mem_tag_ctr_inv constrained by BIN_SEL_CTR_REL. - (1 - bin_sel) * (mem_tag_ctr_inv - 1) = 0; + mem_tag_ctr * ((1 - bin_sel) * (1 - mem_tag_ctr_inv) + mem_tag_ctr_inv) - bin_sel = 0; (1 - bin_sel) * acc_ia = 0; // Forces accumulator to start at zero when mem_tag_ctr == 0 (1 - bin_sel) * acc_ib = 0; // Forces accumulator to start at zero when mem_tag_ctr == 0 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 7c2e056bec9..17d4073d115 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,43 +7,43 @@ namespace bb::Avm_vm { template struct Avm_aluRow { - FF avm_alu_alu_u16_r4{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_op_eq_diff_inv{}; + FF avm_alu_alu_u16_r5{}; + FF avm_alu_alu_cf{}; + FF avm_alu_alu_u8_r1{}; + FF avm_alu_alu_u16_r7{}; + FF avm_alu_alu_u16_r3_shift{}; FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_op_eq_diff_inv{}; + FF avm_alu_alu_sel{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u32_tag{}; + FF avm_alu_alu_u16_r6{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_ia{}; + FF avm_alu_alu_ib{}; + FF avm_alu_alu_op_sub{}; + FF avm_alu_alu_op_eq{}; + FF avm_alu_alu_u16_tag{}; + FF avm_alu_alu_u64_r0{}; FF avm_alu_alu_u16_r0{}; + FF avm_alu_alu_u16_r6_shift{}; FF avm_alu_alu_u16_r4_shift{}; - FF avm_alu_alu_u16_r7{}; + FF avm_alu_alu_u16_r2{}; FF avm_alu_alu_u8_tag{}; FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r6{}; - FF avm_alu_alu_u16_r3{}; - FF avm_alu_alu_u64_tag{}; - FF avm_alu_alu_u128_tag{}; + FF avm_alu_alu_u16_r5_shift{}; FF avm_alu_alu_op_mul{}; - FF avm_alu_alu_op_add{}; - FF avm_alu_alu_op_not{}; + FF avm_alu_alu_u64_tag{}; + FF avm_alu_alu_u16_r1_shift{}; FF avm_alu_alu_u16_r1{}; FF avm_alu_alu_in_tag{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_op_sub{}; - FF avm_alu_alu_u16_r5{}; - FF avm_alu_alu_u8_r1{}; - FF avm_alu_alu_u64_r0{}; - FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_sel{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_ib{}; - FF avm_alu_alu_u16_r2{}; - FF avm_alu_alu_u32_tag{}; - FF avm_alu_alu_u16_tag{}; - FF avm_alu_alu_u8_r0{}; - FF avm_alu_alu_ia{}; FF avm_alu_alu_ic{}; - FF avm_alu_alu_cf{}; - FF avm_alu_alu_op_eq{}; - FF avm_alu_alu_u16_r5_shift{}; + FF avm_alu_alu_op_not{}; + FF avm_alu_alu_op_add{}; + FF avm_alu_alu_u8_r0{}; + FF avm_alu_alu_u128_tag{}; + FF avm_alu_alu_u16_r3{}; + FF avm_alu_alu_u16_r4{}; }; inline std::string get_relation_label_avm_alu(int index) @@ -52,11 +52,14 @@ inline std::string get_relation_label_avm_alu(int index) case 9: return "ALU_ADD_SUB_1"; - case 11: - return "ALU_MULTIPLICATION_FF"; + case 16: + return "ALU_MULTIPLICATION_OUT_U128"; - case 10: - return "ALU_ADD_SUB_2"; + case 20: + return "ALU_OP_EQ"; + + case 18: + return "ALU_OP_NOT"; case 13: return "ALU_MUL_COMMON_2"; @@ -64,20 +67,17 @@ inline std::string get_relation_label_avm_alu(int index) case 12: return "ALU_MUL_COMMON_1"; + case 19: + return "ALU_RES_IS_BOOL"; + case 17: return "ALU_FF_NOT_XOR"; - case 18: - return "ALU_OP_NOT"; - - case 16: - return "ALU_MULTIPLICATION_OUT_U128"; - - case 19: - return "ALU_RES_IS_BOOL"; + case 11: + return "ALU_MULTIPLICATION_FF"; - case 20: - return "ALU_OP_EQ"; + case 10: + return "ALU_ADD_SUB_2"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp index d78add96ce9..1c33aa64b58 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp @@ -7,39 +7,43 @@ namespace bb::Avm_vm { template struct Avm_binaryRow { - FF avm_binary_acc_ic_shift{}; - FF avm_binary_acc_ib{}; - FF avm_binary_bin_sel{}; - FF avm_binary_acc_ib_shift{}; - FF avm_binary_op_id{}; - FF avm_binary_bin_ic_bytes{}; FF avm_binary_acc_ic{}; + FF avm_binary_acc_ib_shift{}; FF avm_binary_acc_ia{}; - FF avm_binary_mem_tag_ctr{}; + FF avm_binary_acc_ia_shift{}; + FF avm_binary_acc_ib{}; + FF avm_binary_op_id{}; FF avm_binary_bin_ib_bytes{}; FF avm_binary_op_id_shift{}; - FF avm_binary_acc_ia_shift{}; FF avm_binary_bin_ia_bytes{}; FF avm_binary_mem_tag_ctr_shift{}; + FF avm_binary_bin_ic_bytes{}; + FF avm_binary_acc_ic_shift{}; + FF avm_binary_mem_tag_ctr_inv{}; + FF avm_binary_mem_tag_ctr{}; + FF avm_binary_bin_sel{}; }; inline std::string get_relation_label_avm_binary(int index) { switch (index) { + case 8: + return "ACC_REL_C"; + case 2: return "MEM_TAG_REL"; - case 8: - return "ACC_REL_C"; + case 3: + return "BIN_SEL_CTR_REL"; + + case 1: + return "OP_ID_REL"; case 6: return "ACC_REL_A"; case 7: return "ACC_REL_B"; - - case 1: - return "OP_ID_REL"; } return std::to_string(index); } @@ -49,7 +53,7 @@ template class avm_binaryImpl { using FF = FF_; static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 3, 3, 3, 4, 4, 4, + 3, 3, 3, 4, 3, 3, 4, 4, 4, }; template @@ -87,7 +91,10 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(3); - auto tmp = ((-avm_binary_bin_sel + FF(1)) * avm_binary_mem_tag_ctr); + auto tmp = + ((avm_binary_mem_tag_ctr * (((-avm_binary_bin_sel + FF(1)) * (-avm_binary_mem_tag_ctr_inv + FF(1))) + + avm_binary_mem_tag_ctr_inv)) - + avm_binary_bin_sel); tmp *= scaling_factor; std::get<3>(evals) += tmp; } 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 9ca7ab7619c..ba6f7068cfd 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -7,82 +7,82 @@ namespace bb::Avm_vm { template struct Avm_mainRow { + FF avm_main_tag_err{}; + FF avm_main_sel_op_sub{}; + FF avm_main_internal_return_ptr{}; FF avm_main_sel_op_and{}; - FF avm_main_sel_op_div{}; + FF avm_main_rwa{}; + FF avm_main_ind_op_c{}; FF avm_main_sel_op_add{}; - FF avm_main_sel_op_mul{}; - FF avm_main_sel_internal_call{}; - FF avm_main_sel_jump{}; - FF avm_main_sel_mov{}; - FF avm_main_mem_op_b{}; - FF avm_main_sel_op_xor{}; - FF avm_main_rwc{}; - FF avm_main_internal_return_ptr{}; - FF avm_main_first{}; FF avm_main_mem_op_a{}; - FF avm_main_ind_op_c{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_ind_op_a{}; + FF avm_main_inv{}; FF avm_main_bin_op_id{}; - FF avm_main_sel_internal_return{}; - FF avm_main_mem_op_c{}; + FF avm_main_op_err{}; FF avm_main_rwb{}; - FF avm_main_ic{}; - FF avm_main_ia{}; - FF avm_main_pc_shift{}; - FF avm_main_sel_op_not{}; - FF avm_main_mem_idx_b{}; - FF avm_main_tag_err{}; - FF avm_main_alu_sel{}; + FF avm_main_bin_sel{}; + FF avm_main_sel_mov{}; + FF avm_main_sel_op_or{}; + FF avm_main_ind_op_b{}; FF avm_main_mem_idx_a{}; - FF avm_main_sel_op_sub{}; - FF avm_main_inv{}; - FF avm_main_pc{}; - FF avm_main_op_err{}; + FF avm_main_alu_sel{}; FF avm_main_sel_halt{}; - FF avm_main_sel_op_or{}; - FF avm_main_bin_sel{}; + FF avm_main_sel_op_not{}; + FF avm_main_sel_op_xor{}; + FF avm_main_pc_shift{}; FF avm_main_ib{}; + FF avm_main_first{}; + FF avm_main_ic{}; + FF avm_main_sel_op_div{}; + FF avm_main_mem_op_b{}; + FF avm_main_sel_internal_return{}; + FF avm_main_rwc{}; + FF avm_main_sel_op_mul{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_pc{}; FF avm_main_sel_op_eq{}; - FF avm_main_ind_op_b{}; - FF avm_main_rwa{}; + FF avm_main_ia{}; + FF avm_main_ind_op_a{}; + FF avm_main_mem_idx_b{}; + FF avm_main_mem_op_c{}; + FF avm_main_sel_internal_call{}; + FF avm_main_sel_jump{}; }; inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 36: - return "RETURN_POINTER_DECREMENT"; - - case 43: - return "MOV_SAME_VALUE"; - - case 45: - return "BIN_SEL_1"; - - case 28: - return "SUBOP_ERROR_RELEVANT_OP"; - case 25: return "SUBOP_DIVISION_FF"; - case 27: - return "SUBOP_DIVISION_ZERO_ERR2"; + case 41: + return "PC_INCREMENT"; case 42: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 26: - return "SUBOP_DIVISION_ZERO_ERR1"; + case 28: + return "SUBOP_ERROR_RELEVANT_OP"; + + case 43: + return "MOV_SAME_VALUE"; case 46: return "BIN_SEL_2"; + case 27: + return "SUBOP_DIVISION_ZERO_ERR2"; + case 30: return "RETURN_POINTER_INCREMENT"; - case 41: - return "PC_INCREMENT"; + case 36: + return "RETURN_POINTER_DECREMENT"; + + case 45: + return "BIN_SEL_1"; + + case 26: + return "SUBOP_DIVISION_ZERO_ERR1"; } 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 432bc8643c2..5b28b9053ed 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -7,52 +7,52 @@ namespace bb::Avm_vm { template struct Avm_memRow { - FF avm_mem_m_rw{}; - FF avm_mem_m_val{}; - FF avm_mem_m_tag{}; - FF avm_mem_m_sel_mov{}; - FF avm_mem_m_op_c{}; - FF avm_mem_m_val_shift{}; - FF avm_mem_m_tag_shift{}; - FF avm_mem_m_in_tag{}; - FF avm_mem_m_sub_clk{}; - FF avm_mem_m_tag_err{}; - FF avm_mem_m_op_b{}; + FF avm_mem_m_op_a{}; FF avm_mem_m_rw_shift{}; + FF avm_mem_m_sub_clk{}; FF avm_mem_m_one_min_inv{}; + FF avm_mem_m_lastAccess{}; + FF avm_mem_m_op_c{}; + FF avm_mem_m_tag{}; + FF avm_mem_m_ind_op_c{}; + FF avm_mem_m_addr{}; + FF avm_mem_m_tag_err{}; + FF avm_mem_m_rw{}; + FF avm_mem_m_val{}; FF avm_mem_m_last{}; FF avm_mem_m_ind_op_a{}; - FF avm_mem_m_addr{}; - FF avm_mem_m_ind_op_c{}; - FF avm_mem_m_lastAccess{}; - FF avm_mem_m_addr_shift{}; FF avm_mem_m_ind_op_b{}; - FF avm_mem_m_op_a{}; + FF avm_mem_m_tag_shift{}; + FF avm_mem_m_val_shift{}; + FF avm_mem_m_op_b{}; + FF avm_mem_m_addr_shift{}; + FF avm_mem_m_in_tag{}; + FF avm_mem_m_sel_mov{}; }; inline std::string get_relation_label_avm_mem(int index) { switch (index) { - case 13: - return "MEM_READ_WRITE_VAL_CONSISTENCY"; + case 15: + return "MEM_ZERO_INIT"; + + case 16: + return "MEM_IN_TAG_CONSISTENCY_1"; + + case 17: + return "MEM_IN_TAG_CONSISTENCY_2"; case 24: return "MOV_SAME_TAG"; - case 16: - return "MEM_IN_TAG_CONSISTENCY_1"; + case 13: + return "MEM_READ_WRITE_VAL_CONSISTENCY"; case 12: return "MEM_LAST_ACCESS_DELIMITER"; case 14: return "MEM_READ_WRITE_TAG_CONSISTENCY"; - - case 15: - return "MEM_ZERO_INIT"; - - case 17: - return "MEM_IN_TAG_CONSISTENCY_2"; } 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 dc9e42dfa39..ec5948a3a5e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -72,6 +72,7 @@ [[maybe_unused]] auto avm_binary_bin_ic_bytes = View(new_term.avm_binary_bin_ic_bytes); \ [[maybe_unused]] auto avm_binary_start = View(new_term.avm_binary_start); \ [[maybe_unused]] auto avm_binary_mem_tag_ctr = View(new_term.avm_binary_mem_tag_ctr); \ + [[maybe_unused]] auto avm_binary_mem_tag_ctr_inv = View(new_term.avm_binary_mem_tag_ctr_inv); \ [[maybe_unused]] auto avm_main_pc = View(new_term.avm_main_pc); \ [[maybe_unused]] auto avm_main_internal_return_ptr = View(new_term.avm_main_internal_return_ptr); \ [[maybe_unused]] auto avm_main_sel_internal_call = View(new_term.avm_main_sel_internal_call); \ @@ -130,22 +131,22 @@ [[maybe_unused]] auto lookup_byte_operations_counts = View(new_term.lookup_byte_operations_counts); \ [[maybe_unused]] auto incl_main_tag_err_counts = View(new_term.incl_main_tag_err_counts); \ [[maybe_unused]] auto incl_mem_tag_err_counts = View(new_term.incl_mem_tag_err_counts); \ - [[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_r4_shift = View(new_term.avm_alu_alu_u16_r4_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_r3_shift = View(new_term.avm_alu_alu_u16_r3_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_r1_shift = View(new_term.avm_alu_alu_u16_r1_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_r5_shift = View(new_term.avm_alu_alu_u16_r5_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_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); \ [[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_binary_acc_ic_shift = View(new_term.avm_binary_acc_ic_shift); \ [[maybe_unused]] auto avm_binary_acc_ib_shift = View(new_term.avm_binary_acc_ib_shift); \ - [[maybe_unused]] auto avm_binary_op_id_shift = View(new_term.avm_binary_op_id_shift); \ [[maybe_unused]] auto avm_binary_acc_ia_shift = View(new_term.avm_binary_acc_ia_shift); \ + [[maybe_unused]] auto avm_binary_op_id_shift = View(new_term.avm_binary_op_id_shift); \ [[maybe_unused]] auto avm_binary_mem_tag_ctr_shift = View(new_term.avm_binary_mem_tag_ctr_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_binary_acc_ic_shift = View(new_term.avm_binary_acc_ic_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_r7_shift = View(new_term.avm_alu_alu_u16_r7_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_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_r2_shift = View(new_term.avm_alu_alu_u16_r2_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); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp index 321d2b1ef16..d5167680214 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp @@ -78,7 +78,7 @@ void AvmBinaryTraceBuilder::entry_builder( .op_id = op_id, .in_tag = static_cast(instr_tag), .mem_tag_ctr = static_cast(num_bytes - i), - .mem_tag_ctr_inv = i == num_bytes ? FF(1) : FF(num_bytes - i).invert(), + .mem_tag_ctr_inv = i == num_bytes ? FF(0) : FF(num_bytes - i).invert(), .start = i == 0, .acc_ia = FF(uint256_t::from_uint128(acc_ia)), .acc_ib = FF(uint256_t::from_uint128(acc_ib)), @@ -87,8 +87,11 @@ void AvmBinaryTraceBuilder::entry_builder( .bin_ib_bytes = b_bytes[i], .bin_ic_bytes = c_bytes[i], }); - auto lookup_index = static_cast((op_id << 16) + (a_bytes[i] << 8) + b_bytes[i]); - byte_operation_counter[lookup_index]++; + // We only perform a lookup when bin_sel = 1, i.e. when we still have bytes to process + if (i != num_bytes) { + auto lookup_index = static_cast((op_id << 16) + (a_bytes[i] << 8) + b_bytes[i]); + byte_operation_counter[lookup_index]++; + } acc_ia = (acc_ia - a_bytes[i]) / 256; acc_ib = (acc_ib - b_bytes[i]) / 256; acc_ic = (acc_ic - c_bytes[i]) / 256; 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 feee035d9f7..11aa3d13147 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -1236,7 +1236,7 @@ std::vector AvmTraceBuilder::finalize() auto const& src = bin_trace.at(i); auto& dest = main_trace.at(i); dest.avm_binary_bin_clk = src.binary_clk; - dest.avm_binary_bin_sel = src.bin_sel; + dest.avm_binary_bin_sel = static_cast(src.bin_sel); dest.avm_binary_acc_ia = src.acc_ia; dest.avm_binary_acc_ib = src.acc_ib; dest.avm_binary_acc_ic = src.acc_ic; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp index 4d29b1944e4..1dcbfb5bfbc 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -102,6 +102,7 @@ template struct AvmFullRow { FF avm_binary_bin_ic_bytes{}; FF avm_binary_start{}; FF avm_binary_mem_tag_ctr{}; + FF avm_binary_mem_tag_ctr_inv{}; FF avm_main_pc{}; FF avm_main_internal_return_ptr{}; FF avm_main_sel_internal_call{}; @@ -160,25 +161,25 @@ template struct AvmFullRow { FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_u16_r4_shift{}; - FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u16_r5_shift{}; - FF avm_mem_m_val_shift{}; - FF avm_mem_m_tag_shift{}; + FF avm_main_pc_shift{}; + FF avm_main_internal_return_ptr_shift{}; 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_binary_acc_ic_shift{}; FF avm_binary_acc_ib_shift{}; - FF avm_binary_op_id_shift{}; FF avm_binary_acc_ia_shift{}; + FF avm_binary_op_id_shift{}; FF avm_binary_mem_tag_ctr_shift{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_pc_shift{}; + FF avm_binary_acc_ic_shift{}; + FF avm_alu_alu_u16_r3_shift{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_u16_r5_shift{}; + FF avm_alu_alu_u16_r1_shift{}; }; class AvmCircuitBuilder { @@ -191,8 +192,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 147; - static constexpr size_t num_polys = 128; + static constexpr size_t num_fixed_columns = 148; + static constexpr size_t num_polys = 129; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -278,6 +279,7 @@ class AvmCircuitBuilder { polys.avm_binary_bin_ic_bytes[i] = rows[i].avm_binary_bin_ic_bytes; polys.avm_binary_start[i] = rows[i].avm_binary_start; polys.avm_binary_mem_tag_ctr[i] = rows[i].avm_binary_mem_tag_ctr; + polys.avm_binary_mem_tag_ctr_inv[i] = rows[i].avm_binary_mem_tag_ctr_inv; polys.avm_main_pc[i] = rows[i].avm_main_pc; polys.avm_main_internal_return_ptr[i] = rows[i].avm_main_internal_return_ptr; polys.avm_main_sel_internal_call[i] = rows[i].avm_main_sel_internal_call; @@ -338,25 +340,25 @@ class AvmCircuitBuilder { polys.incl_mem_tag_err_counts[i] = rows[i].incl_mem_tag_err_counts; } - polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.shifted()); - polys.avm_alu_alu_u16_r4_shift = Polynomial(polys.avm_alu_alu_u16_r4.shifted()); - polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); - polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); - polys.avm_alu_alu_u16_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); - polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.shifted()); - polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); - polys.avm_alu_alu_u16_r5_shift = Polynomial(polys.avm_alu_alu_u16_r5.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_main_pc_shift = Polynomial(polys.avm_main_pc.shifted()); + polys.avm_main_internal_return_ptr_shift = Polynomial(polys.avm_main_internal_return_ptr.shifted()); 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_binary_acc_ic_shift = Polynomial(polys.avm_binary_acc_ic.shifted()); polys.avm_binary_acc_ib_shift = Polynomial(polys.avm_binary_acc_ib.shifted()); - polys.avm_binary_op_id_shift = Polynomial(polys.avm_binary_op_id.shifted()); polys.avm_binary_acc_ia_shift = Polynomial(polys.avm_binary_acc_ia.shifted()); + polys.avm_binary_op_id_shift = Polynomial(polys.avm_binary_op_id.shifted()); polys.avm_binary_mem_tag_ctr_shift = Polynomial(polys.avm_binary_mem_tag_ctr.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_binary_acc_ic_shift = Polynomial(polys.avm_binary_acc_ic.shifted()); + polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); + polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); + polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.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_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.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()); return polys; } @@ -428,8 +430,8 @@ class AvmCircuitBuilder { return true; }; - if (!evaluate_relation.template operator()>("avm_alu", - Avm_vm::get_relation_label_avm_alu)) { + if (!evaluate_relation.template operator()>("avm_main", + Avm_vm::get_relation_label_avm_main)) { return false; } if (!evaluate_relation.template operator()>("avm_mem", @@ -440,8 +442,8 @@ class AvmCircuitBuilder { Avm_vm::get_relation_label_avm_binary)) { return false; } - if (!evaluate_relation.template operator()>("avm_main", - Avm_vm::get_relation_label_avm_main)) { + if (!evaluate_relation.template operator()>("avm_alu", + Avm_vm::get_relation_label_avm_alu)) { return false; } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 17b9911e1f2..d463174c687 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -46,16 +46,16 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 126; + static constexpr size_t NUM_WITNESS_ENTITIES = 127; 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 = 147; + static constexpr size_t NUM_ALL_ENTITIES = 148; - using Relations = std::tuple, + using Relations = std::tuple, Avm_vm::avm_mem, Avm_vm::avm_binary, - Avm_vm::avm_main, + Avm_vm::avm_alu, perm_main_alu_relation, perm_main_bin_relation, perm_main_mem_a_relation, @@ -165,6 +165,7 @@ class AvmFlavor { avm_binary_bin_ic_bytes, avm_binary_start, avm_binary_mem_tag_ctr, + avm_binary_mem_tag_ctr_inv, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -294,6 +295,7 @@ class AvmFlavor { avm_binary_bin_ic_bytes, avm_binary_start, avm_binary_mem_tag_ctr, + avm_binary_mem_tag_ctr_inv, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -429,6 +431,7 @@ class AvmFlavor { avm_binary_bin_ic_bytes, avm_binary_start, avm_binary_mem_tag_ctr, + avm_binary_mem_tag_ctr_inv, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -487,25 +490,25 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r5_shift, - avm_mem_m_val_shift, - avm_mem_m_tag_shift, + avm_main_pc_shift, + avm_main_internal_return_ptr_shift, avm_mem_m_rw_shift, + avm_mem_m_tag_shift, + avm_mem_m_val_shift, avm_mem_m_addr_shift, - avm_binary_acc_ic_shift, avm_binary_acc_ib_shift, - avm_binary_op_id_shift, avm_binary_acc_ia_shift, + avm_binary_op_id_shift, avm_binary_mem_tag_ctr_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift) + avm_binary_acc_ic_shift, + avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r5_shift, + avm_alu_alu_u16_r1_shift) RefVector get_wires() { @@ -579,6 +582,7 @@ class AvmFlavor { avm_binary_bin_ic_bytes, avm_binary_start, avm_binary_mem_tag_ctr, + avm_binary_mem_tag_ctr_inv, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -637,25 +641,25 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r5_shift, - avm_mem_m_val_shift, - avm_mem_m_tag_shift, + avm_main_pc_shift, + avm_main_internal_return_ptr_shift, avm_mem_m_rw_shift, + avm_mem_m_tag_shift, + avm_mem_m_val_shift, avm_mem_m_addr_shift, - avm_binary_acc_ic_shift, avm_binary_acc_ib_shift, - avm_binary_op_id_shift, avm_binary_acc_ia_shift, + avm_binary_op_id_shift, avm_binary_mem_tag_ctr_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift }; + avm_binary_acc_ic_shift, + avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r5_shift, + avm_alu_alu_u16_r1_shift }; }; RefVector get_unshifted() { @@ -729,6 +733,7 @@ class AvmFlavor { avm_binary_bin_ic_bytes, avm_binary_start, avm_binary_mem_tag_ctr, + avm_binary_mem_tag_ctr_inv, avm_main_pc, avm_main_internal_return_ptr, avm_main_sel_internal_call, @@ -790,23 +795,29 @@ class AvmFlavor { }; RefVector get_to_be_shifted() { - return { avm_alu_alu_u16_r0, avm_alu_alu_u16_r4, avm_alu_alu_u16_r2, - avm_alu_alu_u16_r3, avm_alu_alu_u16_r6, avm_alu_alu_u16_r1, - avm_alu_alu_u16_r7, avm_alu_alu_u16_r5, avm_mem_m_val, - avm_mem_m_tag, avm_mem_m_rw, avm_mem_m_addr, - avm_binary_acc_ic, avm_binary_acc_ib, avm_binary_op_id, - avm_binary_acc_ia, avm_binary_mem_tag_ctr, avm_main_internal_return_ptr, - avm_main_pc }; + return { avm_main_pc, avm_main_internal_return_ptr, + avm_mem_m_rw, avm_mem_m_tag, + avm_mem_m_val, avm_mem_m_addr, + avm_binary_acc_ib, avm_binary_acc_ia, + avm_binary_op_id, avm_binary_mem_tag_ctr, + avm_binary_acc_ic, avm_alu_alu_u16_r3, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r0, + avm_alu_alu_u16_r6, avm_alu_alu_u16_r4, + avm_alu_alu_u16_r2, avm_alu_alu_u16_r5, + avm_alu_alu_u16_r1 }; }; RefVector get_shifted() { - return { avm_alu_alu_u16_r0_shift, avm_alu_alu_u16_r4_shift, avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r3_shift, avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r5_shift, avm_mem_m_val_shift, - avm_mem_m_tag_shift, avm_mem_m_rw_shift, avm_mem_m_addr_shift, - avm_binary_acc_ic_shift, avm_binary_acc_ib_shift, avm_binary_op_id_shift, - avm_binary_acc_ia_shift, avm_binary_mem_tag_ctr_shift, avm_main_internal_return_ptr_shift, - avm_main_pc_shift }; + return { avm_main_pc_shift, avm_main_internal_return_ptr_shift, + avm_mem_m_rw_shift, avm_mem_m_tag_shift, + avm_mem_m_val_shift, avm_mem_m_addr_shift, + avm_binary_acc_ib_shift, avm_binary_acc_ia_shift, + avm_binary_op_id_shift, avm_binary_mem_tag_ctr_shift, + avm_binary_acc_ic_shift, avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r2_shift, avm_alu_alu_u16_r5_shift, + avm_alu_alu_u16_r1_shift }; }; }; @@ -819,13 +830,16 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_alu_alu_u16_r0, avm_alu_alu_u16_r4, avm_alu_alu_u16_r2, - avm_alu_alu_u16_r3, avm_alu_alu_u16_r6, avm_alu_alu_u16_r1, - avm_alu_alu_u16_r7, avm_alu_alu_u16_r5, avm_mem_m_val, - avm_mem_m_tag, avm_mem_m_rw, avm_mem_m_addr, - avm_binary_acc_ic, avm_binary_acc_ib, avm_binary_op_id, - avm_binary_acc_ia, avm_binary_mem_tag_ctr, avm_main_internal_return_ptr, - avm_main_pc }; + return { avm_main_pc, avm_main_internal_return_ptr, + avm_mem_m_rw, avm_mem_m_tag, + avm_mem_m_val, avm_mem_m_addr, + avm_binary_acc_ib, avm_binary_acc_ia, + avm_binary_op_id, avm_binary_mem_tag_ctr, + avm_binary_acc_ic, avm_alu_alu_u16_r3, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r0, + avm_alu_alu_u16_r6, avm_alu_alu_u16_r4, + avm_alu_alu_u16_r2, avm_alu_alu_u16_r5, + avm_alu_alu_u16_r1 }; }; // The plookup wires that store plookup read data. @@ -972,6 +986,7 @@ class AvmFlavor { Base::avm_binary_bin_ic_bytes = "AVM_BINARY_BIN_IC_BYTES"; Base::avm_binary_start = "AVM_BINARY_START"; Base::avm_binary_mem_tag_ctr = "AVM_BINARY_MEM_TAG_CTR"; + Base::avm_binary_mem_tag_ctr_inv = "AVM_BINARY_MEM_TAG_CTR_INV"; Base::avm_main_pc = "AVM_MAIN_PC"; Base::avm_main_internal_return_ptr = "AVM_MAIN_INTERNAL_RETURN_PTR"; Base::avm_main_sel_internal_call = "AVM_MAIN_SEL_INTERNAL_CALL"; @@ -1117,6 +1132,7 @@ class AvmFlavor { Commitment avm_binary_bin_ic_bytes; Commitment avm_binary_start; Commitment avm_binary_mem_tag_ctr; + Commitment avm_binary_mem_tag_ctr_inv; Commitment avm_main_pc; Commitment avm_main_internal_return_ptr; Commitment avm_main_sel_internal_call; @@ -1263,6 +1279,7 @@ class AvmFlavor { avm_binary_bin_ic_bytes = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_start = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_binary_mem_tag_ctr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_binary_mem_tag_ctr_inv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_pc = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_internal_return_ptr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_internal_call = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1412,6 +1429,7 @@ class AvmFlavor { serialize_to_buffer(avm_binary_bin_ic_bytes, Transcript::proof_data); serialize_to_buffer(avm_binary_start, Transcript::proof_data); serialize_to_buffer(avm_binary_mem_tag_ctr, Transcript::proof_data); + serialize_to_buffer(avm_binary_mem_tag_ctr_inv, Transcript::proof_data); serialize_to_buffer(avm_main_pc, Transcript::proof_data); serialize_to_buffer(avm_main_internal_return_ptr, Transcript::proof_data); serialize_to_buffer(avm_main_sel_internal_call, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.hpp index e5463dc4a45..1e15b341e17 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.hpp @@ -6,6 +6,7 @@ #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/sumcheck/sumcheck_output.hpp" #include "barretenberg/transcript/transcript.hpp" + #include "barretenberg/vm/generated/avm_flavor.hpp" namespace bb { diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 76edb640982..0f651bc29b7 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -174,6 +174,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_binary_start); commitments.avm_binary_mem_tag_ctr = transcript->template receive_from_prover(commitment_labels.avm_binary_mem_tag_ctr); + commitments.avm_binary_mem_tag_ctr_inv = + transcript->template receive_from_prover(commitment_labels.avm_binary_mem_tag_ctr_inv); commitments.avm_main_pc = transcript->template receive_from_prover(commitment_labels.avm_main_pc); commitments.avm_main_internal_return_ptr = transcript->template receive_from_prover(commitment_labels.avm_main_internal_return_ptr); 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 506c6f8e93f..079198ce39e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -169,6 +169,7 @@ enum BIT_FAILURES { InconsistentOpId, ByteLookupError, ByteLengthError, + IncorrectBinSelector, }; std::vector gen_mutated_trace_bit(std::vector trace, std::function&& select_row, @@ -227,19 +228,25 @@ std::vector gen_mutated_trace_bit(std::vector trace, for (size_t i = first_index; i <= last_index; i++) { FF ctr = trace.at(i).avm_binary_mem_tag_ctr; if (ctr == FF::one()) { - // If the tag is currently 1, it will be set to 0 which means we need to set bin_sel to 1. - trace.at(i).avm_binary_bin_sel = FF(1); - trace.at(i).avm_binary_mem_tag_ctr = trace.at(i).avm_binary_mem_tag_ctr - 1; + // If the tag is currently 1, it will be set to 0 which means we need to set bin_sel to 0. + trace.at(i).avm_binary_bin_sel = FF(0); + trace.at(i).avm_binary_mem_tag_ctr = FF(0); + trace.at(i).avm_binary_mem_tag_ctr_inv = FF(0); } else if (ctr == FF::zero()) { // Leave as zero instead of underflowing - trace.at(i).avm_binary_mem_tag_ctr = 0; + trace.at(i).avm_binary_mem_tag_ctr = FF(0); } else { - // Just decrement the mem_tag_ctr - trace.at(i).avm_binary_mem_tag_ctr = trace.at(i).avm_binary_mem_tag_ctr - 1; + // Replace the values with the next row's values + trace.at(i).avm_binary_mem_tag_ctr = trace.at(i + 1).avm_binary_mem_tag_ctr; + trace.at(i).avm_binary_mem_tag_ctr_inv = trace.at(i + 1).avm_binary_mem_tag_ctr_inv; + trace.at(i).avm_binary_bin_sel = trace.at(i + 1).avm_binary_bin_sel; } } break; } + case IncorrectBinSelector: + binary_row->avm_binary_bin_sel = FF(0); + break; } return trace; } @@ -449,7 +456,8 @@ std::vector> bit_failures = { { "MEM_TAG_REL", BIT_FAILURES::MemTagCtr }, { "LOOKUP_BYTE_LENGTHS", BIT_FAILURES::ByteLengthError }, { "LOOKUP_BYTE_OPERATIONS", BIT_FAILURES::ByteLookupError }, - { "OP_ID_REL", BIT_FAILURES::InconsistentOpId } + { "OP_ID_REL", BIT_FAILURES::InconsistentOpId }, + { "BIN_SEL_CTR_REL", BIT_FAILURES::IncorrectBinSelector }, }; // For the negative test the output is set to be incorrect so that we can test the byte lookups. // Picking "simple" inputs such as zero also makes it easier when check the byte length lookups as we dont From 3119877e897d11205e7b3dbe758a6e8b836914d4 Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Tue, 26 Mar 2024 11:22:57 +0000 Subject: [PATCH 8/8] fix: more comments --- barretenberg/cpp/pil/avm/avm_binary.pil | 19 +-- barretenberg/cpp/pil/avm/avm_main.pil | 4 +- .../relations/generated/avm/avm_alu.hpp | 78 ++++++------ .../relations/generated/avm/avm_binary.hpp | 62 +++++----- .../relations/generated/avm/avm_main.hpp | 84 ++++++------- .../relations/generated/avm/avm_mem.hpp | 50 ++++---- .../relations/generated/avm/declare_views.hpp | 26 ++-- .../vm/avm_trace/avm_binary_trace.cpp | 63 +++++----- .../barretenberg/vm/avm_trace/avm_trace.cpp | 14 +-- .../vm/generated/avm_circuit_builder.hpp | 68 +++++------ .../barretenberg/vm/generated/avm_flavor.hpp | 112 +++++++++--------- .../vm/tests/avm_bitwise.test.cpp | 8 +- 12 files changed, 295 insertions(+), 293 deletions(-) diff --git a/barretenberg/cpp/pil/avm/avm_binary.pil b/barretenberg/cpp/pil/avm/avm_binary.pil index 78d40f4a595..6ef9c3b4cc4 100644 --- a/barretenberg/cpp/pil/avm/avm_binary.pil +++ b/barretenberg/cpp/pil/avm/avm_binary.pil @@ -29,16 +29,17 @@ namespace avm_binary(256); #[OP_ID_REL] (op_id' - op_id) * mem_tag_ctr = 0; - // Little Endian bitwise decomposition, constrained to be U8 given the lookup the avm_byte_lookup + // Little Endian bitwise decomposition of accumulators (which are processed top-down), + // constrained to be U8 given by the lookup to the avm_byte_lookup pol commit bin_ia_bytes; pol commit bin_ib_bytes; pol commit bin_ic_bytes; - pol commit start; // Identifies when we want to capture the output to the main tracssssss + pol commit start; // Identifies when we want to capture the output to the main trace. // To support dynamically sized memory operands we use a counter against a lookup - // This counter goes from [0, MEM_TAG] where MEM_TAG is the number of bytes in the + // This decrementing counter goes from [MEM_TAG, 0] where MEM_TAG is the number of bytes in the // corresponding integer. i.e. MEM_TAG is between 1 (U8) and 16(U128). // Consistency can be achieved with a lookup table between the instr_tag and bytes_length pol commit mem_tag_ctr; @@ -50,14 +51,16 @@ namespace avm_binary(256); pol commit mem_tag_ctr_inv; // bin_sel is set to 1 when mem_tag_ctr != 0, and 0 otherwise. - // we constrain it such that bin_sel = mem_tag * mem_tag_ctr_inv unless mem_tag = 0 the bin_sel = 0 + // we constrain it such that bin_sel = mem_tag_ctr * mem_tag_ctr_inv unless mem_tag_ctr = 0 the bin_sel = 0 // In here we use the consolidated equality relation because it doesnt require us to enforce - // this additional relation: mem_tag_ctr_inv = 1 when mem_tag_ctr = 0. + // this additional relation: mem_tag_ctr_inv = 1 when mem_tag_ctr = 0. (allows default zero value in trace) #[BIN_SEL_CTR_REL] mem_tag_ctr * ((1 - bin_sel) * (1 - mem_tag_ctr_inv) + mem_tag_ctr_inv) - bin_sel = 0; - (1 - bin_sel) * acc_ia = 0; // Forces accumulator to start at zero when mem_tag_ctr == 0 - (1 - bin_sel) * acc_ib = 0; // Forces accumulator to start at zero when mem_tag_ctr == 0 + // Forces accumulator to start at zero when mem_tag_ctr == 0 + (1 - bin_sel) * acc_ia = 0; + (1 - bin_sel) * acc_ib = 0; + (1 - bin_sel) * acc_ic = 0; #[LOOKUP_BYTE_LENGTHS] start {in_tag, mem_tag_ctr} @@ -67,7 +70,7 @@ namespace avm_binary(256); #[LOOKUP_BYTE_OPERATIONS] bin_sel {op_id, bin_ia_bytes, bin_ib_bytes, bin_ic_bytes} in - avm_byte_lookup.bin_sel {avm_byte_lookup.table_op_id, avm_byte_lookup.table_input_a,avm_byte_lookup.table_input_b, avm_byte_lookup.table_output}; + avm_byte_lookup.bin_sel {avm_byte_lookup.table_op_id, avm_byte_lookup.table_input_a, avm_byte_lookup.table_input_b, avm_byte_lookup.table_output}; #[ACC_REL_A] (acc_ia - bin_ia_bytes - 256 * acc_ia') * mem_tag_ctr = 0; diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index f984ab4197e..ac13de7477f 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -261,8 +261,10 @@ namespace avm_main(256); bin_op_id = sel_op_or + 2 * sel_op_xor; // sel_op_and excluded since op_id = 0 for op_and // Only 1 of the binary selectors should be set (i.e. Mutual Exclusivity) + // Bin_sel is not explicitly constrained to be boolean, however this is enforced through + // the operation decomposition step during bytecode unpacking. #[BIN_SEL_2] - bin_sel = (sel_op_and + sel_op_or + sel_op_xor); + bin_sel = sel_op_and + sel_op_or + sel_op_xor; #[PERM_MAIN_BIN] bin_sel {ia, ib, ic, bin_op_id, in_tag} 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 17d4073d115..654dbdd83b5 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,75 +7,75 @@ namespace bb::Avm_vm { template struct Avm_aluRow { - FF avm_alu_alu_u16_r5{}; - FF avm_alu_alu_cf{}; - FF avm_alu_alu_u8_r1{}; - FF avm_alu_alu_u16_r7{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_u8_r0{}; FF avm_alu_alu_op_eq_diff_inv{}; - FF avm_alu_alu_sel{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u32_tag{}; - FF avm_alu_alu_u16_r6{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_ia{}; - FF avm_alu_alu_ib{}; - FF avm_alu_alu_op_sub{}; FF avm_alu_alu_op_eq{}; - FF avm_alu_alu_u16_tag{}; + FF avm_alu_alu_u16_r3{}; FF avm_alu_alu_u64_r0{}; - FF avm_alu_alu_u16_r0{}; + FF avm_alu_alu_u16_r4{}; + FF avm_alu_alu_u16_r3_shift{}; FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u16_r4_shift{}; - FF avm_alu_alu_u16_r2{}; - FF avm_alu_alu_u8_tag{}; - FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r5_shift{}; - FF avm_alu_alu_op_mul{}; - FF avm_alu_alu_u64_tag{}; + FF avm_alu_alu_u16_r0_shift{}; FF avm_alu_alu_u16_r1_shift{}; FF avm_alu_alu_u16_r1{}; FF avm_alu_alu_in_tag{}; - FF avm_alu_alu_ic{}; + FF avm_alu_alu_cf{}; FF avm_alu_alu_op_not{}; + FF avm_alu_alu_u16_r6{}; + FF avm_alu_alu_ib{}; FF avm_alu_alu_op_add{}; - FF avm_alu_alu_u8_r0{}; FF avm_alu_alu_u128_tag{}; - FF avm_alu_alu_u16_r3{}; - FF avm_alu_alu_u16_r4{}; + FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_sel{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u16_r7{}; + FF avm_alu_alu_u16_r0{}; + FF avm_alu_alu_u32_tag{}; + FF avm_alu_alu_ia{}; + FF avm_alu_alu_ic{}; + FF avm_alu_alu_u8_tag{}; + FF avm_alu_alu_u8_r1{}; + FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r5_shift{}; + FF avm_alu_alu_u16_r2{}; + FF avm_alu_alu_op_mul{}; + FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_u64_tag{}; + FF avm_alu_alu_op_sub{}; + FF avm_alu_alu_u16_tag{}; + FF avm_alu_alu_u16_r5{}; }; inline std::string get_relation_label_avm_alu(int index) { switch (index) { - case 9: - return "ALU_ADD_SUB_1"; + case 20: + return "ALU_OP_EQ"; + + case 13: + return "ALU_MUL_COMMON_2"; case 16: return "ALU_MULTIPLICATION_OUT_U128"; - case 20: - return "ALU_OP_EQ"; - case 18: return "ALU_OP_NOT"; - case 13: - return "ALU_MUL_COMMON_2"; + case 19: + return "ALU_RES_IS_BOOL"; + + case 11: + return "ALU_MULTIPLICATION_FF"; case 12: return "ALU_MUL_COMMON_1"; - case 19: - return "ALU_RES_IS_BOOL"; + case 9: + return "ALU_ADD_SUB_1"; case 17: return "ALU_FF_NOT_XOR"; - case 11: - return "ALU_MULTIPLICATION_FF"; - case 10: return "ALU_ADD_SUB_2"; } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp index 1c33aa64b58..4d5179c6579 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp @@ -7,43 +7,43 @@ namespace bb::Avm_vm { template struct Avm_binaryRow { - FF avm_binary_acc_ic{}; - FF avm_binary_acc_ib_shift{}; + FF avm_binary_bin_sel{}; + FF avm_binary_acc_ib{}; + FF avm_binary_mem_tag_ctr{}; + FF avm_binary_bin_ic_bytes{}; + FF avm_binary_acc_ic_shift{}; FF avm_binary_acc_ia{}; + FF avm_binary_op_id_shift{}; FF avm_binary_acc_ia_shift{}; - FF avm_binary_acc_ib{}; FF avm_binary_op_id{}; - FF avm_binary_bin_ib_bytes{}; - FF avm_binary_op_id_shift{}; - FF avm_binary_bin_ia_bytes{}; FF avm_binary_mem_tag_ctr_shift{}; - FF avm_binary_bin_ic_bytes{}; - FF avm_binary_acc_ic_shift{}; + FF avm_binary_acc_ic{}; + FF avm_binary_bin_ia_bytes{}; + FF avm_binary_bin_ib_bytes{}; FF avm_binary_mem_tag_ctr_inv{}; - FF avm_binary_mem_tag_ctr{}; - FF avm_binary_bin_sel{}; + FF avm_binary_acc_ib_shift{}; }; inline std::string get_relation_label_avm_binary(int index) { switch (index) { - case 8: - return "ACC_REL_C"; - - case 2: - return "MEM_TAG_REL"; - - case 3: - return "BIN_SEL_CTR_REL"; - case 1: return "OP_ID_REL"; - case 6: + case 7: return "ACC_REL_A"; - case 7: + case 8: return "ACC_REL_B"; + + case 9: + return "ACC_REL_C"; + + case 3: + return "BIN_SEL_CTR_REL"; + + case 2: + return "MEM_TAG_REL"; } return std::to_string(index); } @@ -52,8 +52,8 @@ template class avm_binaryImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 4, 3, 3, 4, 4, 4, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 4, 3, 3, 3, 4, 4, 4, }; template @@ -118,8 +118,7 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(6); - auto tmp = (((avm_binary_acc_ia - avm_binary_bin_ia_bytes) - (avm_binary_acc_ia_shift * FF(256))) * - avm_binary_mem_tag_ctr); + auto tmp = ((-avm_binary_bin_sel + FF(1)) * avm_binary_acc_ic); tmp *= scaling_factor; std::get<6>(evals) += tmp; } @@ -127,7 +126,7 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(7); - auto tmp = (((avm_binary_acc_ib - avm_binary_bin_ib_bytes) - (avm_binary_acc_ib_shift * FF(256))) * + auto tmp = (((avm_binary_acc_ia - avm_binary_bin_ia_bytes) - (avm_binary_acc_ia_shift * FF(256))) * avm_binary_mem_tag_ctr); tmp *= scaling_factor; std::get<7>(evals) += tmp; @@ -136,11 +135,20 @@ template class avm_binaryImpl { { Avm_DECLARE_VIEWS(8); - auto tmp = (((avm_binary_acc_ic - avm_binary_bin_ic_bytes) - (avm_binary_acc_ic_shift * FF(256))) * + auto tmp = (((avm_binary_acc_ib - avm_binary_bin_ib_bytes) - (avm_binary_acc_ib_shift * FF(256))) * avm_binary_mem_tag_ctr); tmp *= scaling_factor; std::get<8>(evals) += tmp; } + // Contribution 9 + { + Avm_DECLARE_VIEWS(9); + + auto tmp = (((avm_binary_acc_ic - avm_binary_bin_ic_bytes) - (avm_binary_acc_ic_shift * FF(256))) * + avm_binary_mem_tag_ctr); + tmp *= scaling_factor; + std::get<9>(evals) += tmp; + } } }; 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 ba6f7068cfd..316e839ed50 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -7,82 +7,82 @@ namespace bb::Avm_vm { template struct Avm_mainRow { - FF avm_main_tag_err{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_sel_internal_return{}; FF avm_main_sel_op_sub{}; - FF avm_main_internal_return_ptr{}; - FF avm_main_sel_op_and{}; - FF avm_main_rwa{}; - FF avm_main_ind_op_c{}; - FF avm_main_sel_op_add{}; + FF avm_main_ind_op_b{}; FF avm_main_mem_op_a{}; - FF avm_main_inv{}; - FF avm_main_bin_op_id{}; FF avm_main_op_err{}; + FF avm_main_sel_op_and{}; + FF avm_main_mem_op_b{}; FF avm_main_rwb{}; - FF avm_main_bin_sel{}; + FF avm_main_pc{}; + FF avm_main_bin_op_id{}; + FF avm_main_sel_op_xor{}; + FF avm_main_rwa{}; + FF avm_main_rwc{}; + FF avm_main_ind_op_a{}; FF avm_main_sel_mov{}; - FF avm_main_sel_op_or{}; - FF avm_main_ind_op_b{}; + FF avm_main_sel_jump{}; + FF avm_main_inv{}; + FF avm_main_ia{}; + FF avm_main_ind_op_c{}; + FF avm_main_internal_return_ptr{}; + FF avm_main_sel_internal_call{}; + FF avm_main_sel_op_eq{}; + FF avm_main_tag_err{}; FF avm_main_mem_idx_a{}; FF avm_main_alu_sel{}; - FF avm_main_sel_halt{}; - FF avm_main_sel_op_not{}; - FF avm_main_sel_op_xor{}; - FF avm_main_pc_shift{}; - FF avm_main_ib{}; + FF avm_main_sel_op_or{}; + FF avm_main_sel_op_add{}; + FF avm_main_sel_op_mul{}; FF avm_main_first{}; + FF avm_main_ib{}; + FF avm_main_bin_sel{}; + FF avm_main_pc_shift{}; FF avm_main_ic{}; - FF avm_main_sel_op_div{}; - FF avm_main_mem_op_b{}; - FF avm_main_sel_internal_return{}; - FF avm_main_rwc{}; - FF avm_main_sel_op_mul{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_pc{}; - FF avm_main_sel_op_eq{}; - FF avm_main_ia{}; - FF avm_main_ind_op_a{}; - FF avm_main_mem_idx_b{}; FF avm_main_mem_op_c{}; - FF avm_main_sel_internal_call{}; - FF avm_main_sel_jump{}; + FF avm_main_mem_idx_b{}; + FF avm_main_sel_op_div{}; + FF avm_main_sel_op_not{}; + FF avm_main_sel_halt{}; }; inline std::string get_relation_label_avm_main(int index) { switch (index) { + case 28: + return "SUBOP_ERROR_RELEVANT_OP"; + case 25: return "SUBOP_DIVISION_FF"; - case 41: - return "PC_INCREMENT"; + case 27: + return "SUBOP_DIVISION_ZERO_ERR2"; case 42: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 28: - return "SUBOP_ERROR_RELEVANT_OP"; - case 43: return "MOV_SAME_VALUE"; + case 26: + return "SUBOP_DIVISION_ZERO_ERR1"; + case 46: return "BIN_SEL_2"; - case 27: - return "SUBOP_DIVISION_ZERO_ERR2"; + case 45: + return "BIN_SEL_1"; case 30: return "RETURN_POINTER_INCREMENT"; + case 41: + return "PC_INCREMENT"; + case 36: return "RETURN_POINTER_DECREMENT"; - - case 45: - return "BIN_SEL_1"; - - case 26: - return "SUBOP_DIVISION_ZERO_ERR1"; } 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 5b28b9053ed..29f83221e7a 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -7,52 +7,52 @@ namespace bb::Avm_vm { template struct Avm_memRow { - FF avm_mem_m_op_a{}; - FF avm_mem_m_rw_shift{}; - FF avm_mem_m_sub_clk{}; - FF avm_mem_m_one_min_inv{}; - FF avm_mem_m_lastAccess{}; - FF avm_mem_m_op_c{}; - FF avm_mem_m_tag{}; - FF avm_mem_m_ind_op_c{}; - FF avm_mem_m_addr{}; - FF avm_mem_m_tag_err{}; + FF avm_mem_m_op_b{}; + FF avm_mem_m_tag_shift{}; FF avm_mem_m_rw{}; - FF avm_mem_m_val{}; - FF avm_mem_m_last{}; FF avm_mem_m_ind_op_a{}; - FF avm_mem_m_ind_op_b{}; - FF avm_mem_m_tag_shift{}; FF avm_mem_m_val_shift{}; - FF avm_mem_m_op_b{}; - FF avm_mem_m_addr_shift{}; + FF avm_mem_m_ind_op_b{}; FF avm_mem_m_in_tag{}; FF avm_mem_m_sel_mov{}; + FF avm_mem_m_one_min_inv{}; + FF avm_mem_m_addr_shift{}; + FF avm_mem_m_last{}; + FF avm_mem_m_tag{}; + FF avm_mem_m_op_c{}; + FF avm_mem_m_rw_shift{}; + FF avm_mem_m_ind_op_c{}; + FF avm_mem_m_val{}; + FF avm_mem_m_lastAccess{}; + FF avm_mem_m_tag_err{}; + FF avm_mem_m_addr{}; + FF avm_mem_m_sub_clk{}; + FF avm_mem_m_op_a{}; }; inline std::string get_relation_label_avm_mem(int index) { switch (index) { + case 12: + return "MEM_LAST_ACCESS_DELIMITER"; + case 15: return "MEM_ZERO_INIT"; + case 13: + return "MEM_READ_WRITE_VAL_CONSISTENCY"; + case 16: return "MEM_IN_TAG_CONSISTENCY_1"; + case 14: + return "MEM_READ_WRITE_TAG_CONSISTENCY"; + case 17: return "MEM_IN_TAG_CONSISTENCY_2"; case 24: return "MOV_SAME_TAG"; - - case 13: - return "MEM_READ_WRITE_VAL_CONSISTENCY"; - - case 12: - return "MEM_LAST_ACCESS_DELIMITER"; - - case 14: - 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 ec5948a3a5e..3afa82ed463 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -131,22 +131,22 @@ [[maybe_unused]] auto lookup_byte_operations_counts = View(new_term.lookup_byte_operations_counts); \ [[maybe_unused]] auto incl_main_tag_err_counts = View(new_term.incl_main_tag_err_counts); \ [[maybe_unused]] auto incl_mem_tag_err_counts = View(new_term.incl_mem_tag_err_counts); \ - [[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); \ - [[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_binary_acc_ib_shift = View(new_term.avm_binary_acc_ib_shift); \ - [[maybe_unused]] auto avm_binary_acc_ia_shift = View(new_term.avm_binary_acc_ia_shift); \ + [[maybe_unused]] auto avm_binary_acc_ic_shift = View(new_term.avm_binary_acc_ic_shift); \ [[maybe_unused]] auto avm_binary_op_id_shift = View(new_term.avm_binary_op_id_shift); \ + [[maybe_unused]] auto avm_binary_acc_ia_shift = View(new_term.avm_binary_acc_ia_shift); \ [[maybe_unused]] auto avm_binary_mem_tag_ctr_shift = View(new_term.avm_binary_mem_tag_ctr_shift); \ - [[maybe_unused]] auto avm_binary_acc_ic_shift = View(new_term.avm_binary_acc_ic_shift); \ + [[maybe_unused]] auto avm_binary_acc_ib_shift = View(new_term.avm_binary_acc_ib_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_r7_shift = View(new_term.avm_alu_alu_u16_r7_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_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_r0_shift = View(new_term.avm_alu_alu_u16_r0_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_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_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_r1_shift = View(new_term.avm_alu_alu_u16_r1_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_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_mem_m_rw_shift = View(new_term.avm_mem_m_rw_shift); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp index d5167680214..79a301ee820 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_binary_trace.cpp @@ -12,7 +12,6 @@ namespace bb::avm_trace { AvmBinaryTraceBuilder::AvmBinaryTraceBuilder() { - // lookup_table = std::make_unique(); binary_trace.reserve(AVM_TRACE_SIZE); } @@ -52,7 +51,7 @@ std::vector bytes_decompose_le(uint128_t const& val) * @param b Right operand of the bitwise operation * @param in_tag Instruction tag * @param clk Clock referring to the operation in the main trace. - * @param op_id which bitwise operation {0: And, 1: Or, 2: Xor } this entry corresponds to. + * @param op_id which bitwise operation {0: AND, 1: OR, 2: XOR } this entry corresponds to. */ void AvmBinaryTraceBuilder::entry_builder( uint128_t const& a, uint128_t const& b, uint128_t const& c, AvmMemoryTag instr_tag, uint32_t clk, uint8_t op_id) @@ -92,83 +91,83 @@ void AvmBinaryTraceBuilder::entry_builder( auto lookup_index = static_cast((op_id << 16) + (a_bytes[i] << 8) + b_bytes[i]); byte_operation_counter[lookup_index]++; } - acc_ia = (acc_ia - a_bytes[i]) / 256; - acc_ib = (acc_ib - b_bytes[i]) / 256; - acc_ic = (acc_ic - c_bytes[i]) / 256; + acc_ia = (acc_ia - a_bytes[i]) >> 8; + acc_ib = (acc_ib - b_bytes[i]) >> 8; + acc_ic = (acc_ic - c_bytes[i]) >> 8; } // There is 1 latch per call, therefore byte_length check increments byte_length_counter[static_cast(instr_tag)]++; } /** - * @brief Build Binary trace and return the result of bitwise And operation. + * @brief Build Binary trace and return the result of bitwise AND operation. * - * @param a Left operand of the And - * @param b Right operand of the And - * @param in_tag Instruction tag defining the number of bits for And + * @param a Left operand of the AND + * @param b Right operand of the AND + * @param in_tag Instruction tag defining the number of bits for AND * @param clk Clock referring to the operation in the main trace. * - * @return FF The result of bitwise And casted to a Field element. + * @return FF The result of bitwise AND casted to a Field element. */ FF AvmBinaryTraceBuilder::op_and(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk) { if (instr_tag == AvmMemoryTag::FF || instr_tag == AvmMemoryTag::U0) { return FF::zero(); } - // Cast to bits and perform And operation - auto a_uint128 = static_cast(a); - auto b_uint128 = static_cast(b); + // Cast to bits and perform AND operation + auto a_uint128 = uint128_t(a); + auto b_uint128 = uint128_t(b); uint128_t c_uint128 = a_uint128 & b_uint128; - this->entry_builder(a_uint128, b_uint128, c_uint128, instr_tag, clk, 0); + entry_builder(a_uint128, b_uint128, c_uint128, instr_tag, clk, 0); return uint256_t::from_uint128(c_uint128); } /** - * @brief Build Binary trace and return the result of bitwise Or operation. + * @brief Build Binary trace and return the result of bitwise OR operation. * - * @param a Left operand of the Or - * @param b Right operand of the Or - * @param in_tag Instruction tag defining the number of bits for Or + * @param a Left operand of the OR + * @param b Right operand of the OR + * @param in_tag Instruction tag defining the number of bits for OR * @param clk Clock referring to the operation in the main trace. * - * @return FF The result of bitwise Or casted to a Field element. + * @return FF The result of bitwise OR casted to a Field element. */ FF AvmBinaryTraceBuilder::op_or(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk) { if (instr_tag == AvmMemoryTag::FF || instr_tag == AvmMemoryTag::U0) { return FF::zero(); } - // Cast to bits and perform Or operation - auto a_uint128 = static_cast(a); - auto b_uint128 = static_cast(b); + // Cast to bits and perform OR operation + auto a_uint128 = uint128_t(a); + auto b_uint128 = uint128_t(b); uint128_t c_uint128 = a_uint128 | b_uint128; - this->entry_builder(a_uint128, b_uint128, c_uint128, instr_tag, clk, 1); + entry_builder(a_uint128, b_uint128, c_uint128, instr_tag, clk, 1); return uint256_t::from_uint128(c_uint128); } /** - * @brief Build Binary trace and return the result of bitwise Xor operation. + * @brief Build Binary trace and return the result of bitwise XOR operation. * - * @param a Left operand of the Xor - * @param b Right operand of the Xor - * @param in_tag Instruction tag defining the number of bits for Xor + * @param a Left operand of the XOR + * @param b Right operand of the XOR + * @param in_tag Instruction tag defining the number of bits for XOR * @param clk Clock referring to the operation in the main trace. * - * @return FF The result of bitwise Xor casted to a Field element. + * @return FF The result of bitwise XOR casted to a Field element. */ FF AvmBinaryTraceBuilder::op_xor(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk) { if (instr_tag == AvmMemoryTag::FF || instr_tag == AvmMemoryTag::U0) { return FF::zero(); } - // Cast to bits and perform Xor operation - auto a_uint128 = static_cast(a); - auto b_uint128 = static_cast(b); + // Cast to bits and perform XOR operation + auto a_uint128 = uint128_t(a); + auto b_uint128 = uint128_t(b); uint128_t c_uint128 = a_uint128 ^ b_uint128; - this->entry_builder(a_uint128, b_uint128, c_uint128, instr_tag, clk, 2); + entry_builder(a_uint128, b_uint128, c_uint128, instr_tag, clk, 2); return uint256_t::from_uint128(c_uint128); } 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 11aa3d13147..24ec44192ab 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -420,7 +420,6 @@ void AvmTraceBuilder::op_eq( auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); tag_match = read_a.tag_match && read_b.tag_match; - // c = a == b ? 1 : 0 FF a = read_a.val; FF b = read_b.val; @@ -471,7 +470,6 @@ void AvmTraceBuilder::op_and( auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); tag_match = read_a.tag_match && read_b.tag_match; - // c = a == b ? 1 : 0 FF a = tag_match ? read_a.val : FF(0); FF b = tag_match ? read_b.val : FF(0); @@ -521,7 +519,6 @@ void AvmTraceBuilder::op_or( auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); tag_match = read_a.tag_match && read_b.tag_match; - // c = a == b ? 1 : 0 FF a = tag_match ? read_a.val : FF(0); FF b = tag_match ? read_b.val : FF(0); @@ -571,7 +568,6 @@ void AvmTraceBuilder::op_xor( auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); tag_match = read_a.tag_match && read_b.tag_match; - // c = a == b ? 1 : 0 FF a = tag_match ? read_a.val : FF(0); FF b = tag_match ? read_b.val : FF(0); @@ -1109,10 +1105,8 @@ std::vector AvmTraceBuilder::finalize() // We only need to pad with zeroes to the size to the largest trace here, pow_2 padding is handled in the // subgroup_size check in bb - size_t zero_rows_num = *trace_size - main_trace_size; - while (zero_rows_num-- > 0) { - main_trace.push_back({}); - } + // Resize the main_trace to accomodate a potential lookup, filling with default empty rows. + main_trace.resize(*trace_size, {}); main_trace.at(main_trace_size - 1).avm_main_last = FF(1); @@ -1254,8 +1248,8 @@ std::vector AvmTraceBuilder::finalize() if (bin_trace_size > 0) { // Generate Lookup Table of all combinations of 2, 8-bit numbers and op_id. for (size_t op_id = 0; op_id < 3; op_id++) { - for (size_t input_a = 0; input_a <= std::numeric_limits::max(); input_a++) { - for (size_t input_b = 0; input_b <= std::numeric_limits::max(); input_b++) { + for (size_t input_a = 0; input_a <= UINT8_MAX; input_a++) { + for (size_t input_b = 0; input_b <= UINT8_MAX; input_b++) { auto a = static_cast(input_a); auto b = static_cast(input_b); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp index 1dcbfb5bfbc..db1f2cee12f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -161,25 +161,25 @@ template struct AvmFullRow { FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; - FF avm_main_pc_shift{}; - FF avm_main_internal_return_ptr_shift{}; - 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_binary_acc_ib_shift{}; - FF avm_binary_acc_ia_shift{}; + FF avm_binary_acc_ic_shift{}; FF avm_binary_op_id_shift{}; + FF avm_binary_acc_ia_shift{}; FF avm_binary_mem_tag_ctr_shift{}; - FF avm_binary_acc_ic_shift{}; + FF avm_binary_acc_ib_shift{}; FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u16_r0_shift{}; FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r1_shift{}; FF avm_alu_alu_u16_r2_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_r1_shift{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_pc_shift{}; + FF avm_mem_m_tag_shift{}; + FF avm_mem_m_val_shift{}; + FF avm_mem_m_addr_shift{}; + FF avm_mem_m_rw_shift{}; }; class AvmCircuitBuilder { @@ -340,25 +340,25 @@ class AvmCircuitBuilder { polys.incl_mem_tag_err_counts[i] = rows[i].incl_mem_tag_err_counts; } - 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()); - 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_binary_acc_ib_shift = Polynomial(polys.avm_binary_acc_ib.shifted()); - polys.avm_binary_acc_ia_shift = Polynomial(polys.avm_binary_acc_ia.shifted()); + polys.avm_binary_acc_ic_shift = Polynomial(polys.avm_binary_acc_ic.shifted()); polys.avm_binary_op_id_shift = Polynomial(polys.avm_binary_op_id.shifted()); + polys.avm_binary_acc_ia_shift = Polynomial(polys.avm_binary_acc_ia.shifted()); polys.avm_binary_mem_tag_ctr_shift = Polynomial(polys.avm_binary_mem_tag_ctr.shifted()); - polys.avm_binary_acc_ic_shift = Polynomial(polys.avm_binary_acc_ic.shifted()); + polys.avm_binary_acc_ib_shift = Polynomial(polys.avm_binary_acc_ib.shifted()); polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); - polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); - polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.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_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.shifted()); + polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.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_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_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.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_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_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); return polys; } @@ -430,14 +430,6 @@ 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_mem", - Avm_vm::get_relation_label_avm_mem)) { - return false; - } if (!evaluate_relation.template operator()>("avm_binary", Avm_vm::get_relation_label_avm_binary)) { return false; @@ -446,6 +438,14 @@ class AvmCircuitBuilder { 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; + } if (!evaluate_logderivative.template operator()>("PERM_MAIN_ALU")) { return false; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index d463174c687..81f872a6b56 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -52,10 +52,10 @@ class AvmFlavor { // the unshifted and one for the shifted static constexpr size_t NUM_ALL_ENTITIES = 148; - using Relations = std::tuple, - Avm_vm::avm_mem, - Avm_vm::avm_binary, + using Relations = std::tuple, Avm_vm::avm_alu, + Avm_vm::avm_main, + Avm_vm::avm_mem, perm_main_alu_relation, perm_main_bin_relation, perm_main_mem_a_relation, @@ -490,25 +490,25 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_main_pc_shift, - avm_main_internal_return_ptr_shift, - avm_mem_m_rw_shift, - avm_mem_m_tag_shift, - avm_mem_m_val_shift, - avm_mem_m_addr_shift, - avm_binary_acc_ib_shift, - avm_binary_acc_ia_shift, + avm_binary_acc_ic_shift, avm_binary_op_id_shift, + avm_binary_acc_ia_shift, avm_binary_mem_tag_ctr_shift, - avm_binary_acc_ic_shift, + avm_binary_acc_ib_shift, avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r0_shift, avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r4_shift, avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r1_shift) + avm_main_internal_return_ptr_shift, + avm_main_pc_shift, + avm_mem_m_tag_shift, + avm_mem_m_val_shift, + avm_mem_m_addr_shift, + avm_mem_m_rw_shift) RefVector get_wires() { @@ -641,25 +641,25 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_main_pc_shift, - avm_main_internal_return_ptr_shift, - avm_mem_m_rw_shift, - avm_mem_m_tag_shift, - avm_mem_m_val_shift, - avm_mem_m_addr_shift, - avm_binary_acc_ib_shift, - avm_binary_acc_ia_shift, + avm_binary_acc_ic_shift, avm_binary_op_id_shift, + avm_binary_acc_ia_shift, avm_binary_mem_tag_ctr_shift, - avm_binary_acc_ic_shift, + avm_binary_acc_ib_shift, avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r0_shift, avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r4_shift, avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r1_shift }; + avm_main_internal_return_ptr_shift, + avm_main_pc_shift, + avm_mem_m_tag_shift, + avm_mem_m_val_shift, + avm_mem_m_addr_shift, + avm_mem_m_rw_shift }; }; RefVector get_unshifted() { @@ -795,29 +795,29 @@ class AvmFlavor { }; RefVector get_to_be_shifted() { - return { avm_main_pc, avm_main_internal_return_ptr, - avm_mem_m_rw, avm_mem_m_tag, + return { avm_binary_acc_ic, avm_binary_op_id, + avm_binary_acc_ia, avm_binary_mem_tag_ctr, + avm_binary_acc_ib, avm_alu_alu_u16_r3, + avm_alu_alu_u16_r6, avm_alu_alu_u16_r0, + avm_alu_alu_u16_r1, avm_alu_alu_u16_r2, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r4, + avm_alu_alu_u16_r5, avm_main_internal_return_ptr, + avm_main_pc, avm_mem_m_tag, avm_mem_m_val, avm_mem_m_addr, - avm_binary_acc_ib, avm_binary_acc_ia, - avm_binary_op_id, avm_binary_mem_tag_ctr, - avm_binary_acc_ic, avm_alu_alu_u16_r3, - avm_alu_alu_u16_r7, avm_alu_alu_u16_r0, - avm_alu_alu_u16_r6, avm_alu_alu_u16_r4, - avm_alu_alu_u16_r2, avm_alu_alu_u16_r5, - avm_alu_alu_u16_r1 }; + avm_mem_m_rw }; }; RefVector get_shifted() { - return { avm_main_pc_shift, avm_main_internal_return_ptr_shift, - avm_mem_m_rw_shift, avm_mem_m_tag_shift, + return { avm_binary_acc_ic_shift, avm_binary_op_id_shift, + avm_binary_acc_ia_shift, avm_binary_mem_tag_ctr_shift, + avm_binary_acc_ib_shift, avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r5_shift, avm_main_internal_return_ptr_shift, + avm_main_pc_shift, avm_mem_m_tag_shift, avm_mem_m_val_shift, avm_mem_m_addr_shift, - avm_binary_acc_ib_shift, avm_binary_acc_ia_shift, - avm_binary_op_id_shift, avm_binary_mem_tag_ctr_shift, - avm_binary_acc_ic_shift, avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r2_shift, avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r1_shift }; + avm_mem_m_rw_shift }; }; }; @@ -830,16 +830,16 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_main_pc, avm_main_internal_return_ptr, - avm_mem_m_rw, avm_mem_m_tag, + return { avm_binary_acc_ic, avm_binary_op_id, + avm_binary_acc_ia, avm_binary_mem_tag_ctr, + avm_binary_acc_ib, avm_alu_alu_u16_r3, + avm_alu_alu_u16_r6, avm_alu_alu_u16_r0, + avm_alu_alu_u16_r1, avm_alu_alu_u16_r2, + avm_alu_alu_u16_r7, avm_alu_alu_u16_r4, + avm_alu_alu_u16_r5, avm_main_internal_return_ptr, + avm_main_pc, avm_mem_m_tag, avm_mem_m_val, avm_mem_m_addr, - avm_binary_acc_ib, avm_binary_acc_ia, - avm_binary_op_id, avm_binary_mem_tag_ctr, - avm_binary_acc_ic, avm_alu_alu_u16_r3, - avm_alu_alu_u16_r7, avm_alu_alu_u16_r0, - avm_alu_alu_u16_r6, avm_alu_alu_u16_r4, - avm_alu_alu_u16_r2, avm_alu_alu_u16_r5, - avm_alu_alu_u16_r1 }; + avm_mem_m_rw }; }; // The plookup wires that store plookup read data. 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 079198ce39e..3399e5736d3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -98,12 +98,8 @@ void common_validate_bit_op(std::vector const& trace, auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_xor == FF(1); }); if (op_id == 0) { row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_and == FF(1); }); - EXPECT_EQ(row->avm_main_sel_op_and, FF(1)); } else if (op_id == 1) { row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_or == FF(1); }); - EXPECT_EQ(row->avm_main_sel_op_or, FF(1)); - } else { - EXPECT_EQ(row->avm_main_sel_op_xor, FF(1)); } // Use the row in the main trace to find the same operation in the alu trace. @@ -113,8 +109,8 @@ void common_validate_bit_op(std::vector const& trace, }); // Check that both rows were found - EXPECT_TRUE(bin_row_start != trace.end()); - EXPECT_TRUE(row != trace.end()); + ASSERT_TRUE(bin_row_start != trace.end()); + ASSERT_TRUE(row != trace.end()); // Check that the correct result is stored at the expected memory location. EXPECT_EQ(row->avm_main_ic, c);