From a51663707b96914b0a300440611748ce44fbe933 Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Tue, 23 Apr 2024 14:11:52 +0100 Subject: [PATCH] feat(avm): shift relations (#5716) Please read [contributing guidelines](CONTRIBUTING.md) and remove this line. --- barretenberg/cpp/CMakeLists.txt | 1 + barretenberg/cpp/pil/avm/avm_alu.pil | 134 ++++- barretenberg/cpp/pil/avm/avm_main.pil | 26 +- .../relations/generated/avm/avm_alu.hpp | 484 ++++++++++++------ .../relations/generated/avm/avm_main.hpp | 219 ++++---- .../relations/generated/avm/declare_views.hpp | 16 + .../generated/avm/lookup_pow_2_0.hpp | 170 ++++++ .../generated/avm/lookup_pow_2_1.hpp | 170 ++++++ .../relations/generated/avm/perm_main_alu.hpp | 10 +- .../relations/generated/avm/pow_2_lookups.hpp | 170 ++++++ .../vm/avm_trace/avm_alu_trace.cpp | 253 ++++++++- .../vm/avm_trace/avm_alu_trace.hpp | 11 + .../vm/avm_trace/avm_deserialization.cpp | 2 + .../vm/avm_trace/avm_execution.cpp | 14 + .../barretenberg/vm/avm_trace/avm_helper.cpp | 122 ++--- .../barretenberg/vm/avm_trace/avm_trace.cpp | 129 ++++- .../barretenberg/vm/avm_trace/avm_trace.hpp | 6 + .../vm/generated/avm_circuit_builder.hpp | 42 +- .../barretenberg/vm/generated/avm_flavor.hpp | 150 +++++- .../barretenberg/vm/generated/avm_prover.cpp | 30 ++ .../vm/generated/avm_verifier.cpp | 24 + .../vm/tests/avm_bitwise.test.cpp | 115 ++++- 22 files changed, 1934 insertions(+), 364 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_pow_2_0.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_pow_2_1.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/pow_2_lookups.hpp diff --git a/barretenberg/cpp/CMakeLists.txt b/barretenberg/cpp/CMakeLists.txt index 6a6f3170757..f33ff1034bd 100644 --- a/barretenberg/cpp/CMakeLists.txt +++ b/barretenberg/cpp/CMakeLists.txt @@ -80,6 +80,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_EXTENSIONS ON) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-fbracket-depth=512) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "14") message(WARNING "Clang <14 is not supported") endif() diff --git a/barretenberg/cpp/pil/avm/avm_alu.pil b/barretenberg/cpp/pil/avm/avm_alu.pil index cc39ef9ca7e..35771b3fb48 100644 --- a/barretenberg/cpp/pil/avm/avm_alu.pil +++ b/barretenberg/cpp/pil/avm/avm_alu.pil @@ -23,7 +23,10 @@ namespace avm_alu(256); pol commit op_lt; pol commit op_lte; pol commit cmp_sel; // Predicate if LT or LTE is set - pol commit rng_chk_sel; // Predicate representing a range check row used in LT/LTE. + pol commit rng_chk_sel; // Predicate representing a range check row. + pol commit op_shl; + pol commit op_shr; + pol commit shift_sel; // Predicate if SHR or SHR is set // Instruction tag (1: u8, 2: u16, 3: u32, 4: u64, 5: u128, 6: field) copied from Main table pol commit in_tag; @@ -61,8 +64,9 @@ namespace avm_alu(256); pol commit cf; // Compute predicate telling whether there is a row entry in the ALU table. - alu_sel = op_add + op_sub + op_mul + op_not + op_eq + op_cast + op_lt + op_lte; + alu_sel = op_add + op_sub + op_mul + op_not + op_eq + op_cast + op_lt + op_lte + op_shr + op_shl; cmp_sel = op_lt + op_lte; + shift_sel = op_shl + op_shr; // ========= Type Constraints ============================================= // TODO: Range constraints @@ -355,7 +359,7 @@ namespace avm_alu(256); // (b) IS_GT = 1 - ic = 0 // (c) res_lo = B_SUB_A_LO and res_hi = B_SUB_A_HI // (d) res_lo = y_lo - x_lo + borrow * 2**128 and res_hi = y_hi - x_hi - borrow. - // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, y_lo, we + // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, x_hi, we // have the guarantee that res_lo >= 0 && res_hi >= 0. Furthermore, borrow is // boolean and so we have two cases to consider: // (i) borrow == 0 ==> y_lo >= x_lo && y_hi >= x_hi @@ -368,7 +372,7 @@ namespace avm_alu(256); // (b) IS_GT = 1 - ic = 1 // (c) res_lo = A_SUB_B_LO and res_hi = A_SUB_B_HI // (d) res_lo = x_lo - y_lo - 1 + borrow * 2**128 and res_hi = x_hi - y_hi - borrow. - // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, y_lo, we + // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, x_hi, we // have the guarantee that res_lo >= 0 && res_hi >= 0. Furthermore, borrow is // boolean and so we have two cases to consider: // (i) borrow == 0 ==> x_lo > y_lo && x_hi >= y_hi @@ -383,7 +387,7 @@ namespace avm_alu(256); // (b) IS_GT = ic = 1 // (c) res_lo = A_SUB_B_LO and res_hi = A_SUB_B_HI, **remember we have swapped inputs** // (d) res_lo = y_lo - x_lo - 1 + borrow * 2**128 and res_hi = y_hi - x_hi - borrow. - // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, y_lo, we + // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, x_hi, we // have the guarantee that res_lo >= 0 && res_hi >= 0. Furthermore, borrow is // boolean and so we have two cases to consider: // (i) borrow == 0 ==> y_lo > x_lo && y_hi >= x_hi @@ -395,8 +399,8 @@ namespace avm_alu(256); // (a) We DO swap the operands, so a = y and b = x, // (b) IS_GT = ic = 0 // (c) res_lo = B_SUB_A_LO and res_hi = B_SUB_A_HI, **remember we have swapped inputs** - // (d) res_lo = x_lo - y_lo + borrow * 2**128 and res_hi = x_hi - y_hi - borrow. - // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, y_lo, we + // (d) res_lo = a_lo - y_lo + borrow * 2**128 and res_hi = a_hi - y_hi - borrow. + // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, x_hi, we // have the guarantee that res_lo >= 0 && res_hi >= 0. Furthermore, borrow is // boolean and so we have two cases to consider: // (i) borrow == 0 ==> x_lo >= y_lo && x_hi >= y_hi @@ -434,11 +438,13 @@ namespace avm_alu(256); cmp_rng_ctr * ((1 - rng_chk_sel) * (1 - op_eq_diff_inv) + op_eq_diff_inv) - rng_chk_sel = 0; // We perform a range check if we have some range checks remaining or we are performing a comparison op - pol RNG_CHK_OP = rng_chk_sel + cmp_sel + op_cast + op_cast_prev; + pol RNG_CHK_OP = rng_chk_sel + cmp_sel + op_cast + op_cast_prev + shift_lt_bit_len; pol commit rng_chk_lookup_selector; + // TODO: Possible optimisation here if we swap the op_shl and op_shr with shift_lt_bit_len. + // Shift_lt_bit_len is a more restrictive form therefore we can avoid performing redundant range checks when we know the result == 0. #[RNG_CHK_LOOKUP_SELECTOR] - rng_chk_lookup_selector' = cmp_sel' + rng_chk_sel' + op_add' + op_sub' + op_mul' + op_mul * u128_tag + op_cast' + op_cast_prev'; + rng_chk_lookup_selector' = cmp_sel' + rng_chk_sel' + op_add' + op_sub' + op_mul' + op_mul * u128_tag + op_cast' + op_cast_prev' + op_shl' + op_shr'; // Perform 128-bit range check on lo part #[LOWER_CMP_RNG_CHK] @@ -469,7 +475,6 @@ namespace avm_alu(256); (p_sub_b_lo' - res_lo) * rng_chk_sel'= 0; (p_sub_b_hi' - res_hi) * rng_chk_sel'= 0; - // ========= CAST Operation Constraints =============================== // We handle the input ia independently of its tag, i.e., we suppose it can take // any value between 0 and p-1. @@ -509,4 +514,111 @@ namespace avm_alu(256); // 128-bit multiplication and CAST need two rows in ALU trace. We need to ensure // that another ALU operation does not start in the second row. #[TWO_LINE_OP_NO_OVERLAP] - (op_mul * ff_tag + op_cast) * alu_sel' = 0; \ No newline at end of file + (op_mul * ff_tag + op_cast) * alu_sel' = 0; + + // ========= SHIFT LEFT/RIGHT OPERATIONS =============================== + // Given (1) an input b, within the range [0, 2**128-1], + // (2) a value s, the amount of bits to shift b by, + // (3) and a memory tag, mem_tag that supports a maximum of t bits. + // Split input b into Big Endian hi and lo limbs, (we re-use the b_hi and b_lo columns we used for the comparison operators) + // b_hi and b_lo, and the number of bits represented by the memory tag, t. + // If we are shifting by more than the bit length represented by the memory tag, the result is trivially zero + // + // === Steps when performing SHR + // (1) Prove the correct decomposition: b_hi * 2**s + b_lo = b + // (2) Range check b_hi < 2**(t-s) && b_lo < 2**s, ensure we have not overflowed the limbs during decomp + // (3) Return b_hi + // + // <--(t-s) bits --> | <-- s bits --> + // -------------------|------------------- + // | b_hi | b_lo | --> b + // --------------------------------------- + // + // === Steps when performing SHL + // (1) Prove the correct decomposition: b_hi * 2**(t-s) + b_lo = b + // (2) Range check b_hi < 2**s && b_lo < 2**(t-s) + // (3) Return b_lo * 2**s + // + // <-- s bits --> | <-- (t-s) bits --> + // ------------------|------------------- + // | b_hi | b_lo | --> b + // -------------------------------------- + + // Check that b_lo and b_hi are range checked such that: + // SHR: b_hi < 2**(t - s) && b_lo < 2**s + // SHL: b_hi < 2**s && b_lo < 2**(t - s) + + // In lieu of a variable length check, we can utilise 2 fixed range checks instead. + // Given the dynamic range check of 0 <= b_hi < 2**(t-s), where s < t + // (1) 0 <= b_hi < 2**128 + // (2) 0 <= 2**(t - s) - b_hi < 2**128 + // Note that (1) is guaranteed elsewhere through the tagged memory model, so we focus on (2) here. + + // === General Notes: + // There are probably ways to merge various relations for the SHL/SHR, but they are separate + // now while we are still figuring out. + + + // We re-use the a_lo and a_hi cols from the comparison operators for the range checks + // SHR: (1) a_lo = 2**s - b_lo, (2) a_hi = 2**(t-s) - b_hi + // === Range checks: (1) a_lo < 2**128, (2) a_hi < 2**128. + #[SHR_RANGE_0] + shift_lt_bit_len * op_shr * (a_lo - (two_pow_s - b_lo - 1)) = 0; + #[SHR_RANGE_1] + shift_lt_bit_len * op_shr * (a_hi - (two_pow_t_sub_s - b_hi - 1)) = 0; + + // SHL: (1) a_lo = 2**(t-s) - b_lo, (2) a_hi = 2**s - b_hi + // === Range checks: (1) a_lo < 2**128, (2) a_hi < 2**128. + #[SHL_RANGE_0] + shift_lt_bit_len * op_shl * (a_lo - (two_pow_t_sub_s - b_lo - 1)) = 0; + #[SHL_RANGE_1] + shift_lt_bit_len * op_shl * (a_hi - (two_pow_s - b_hi - 1)) = 0; + + // Indicate if the shift amount < MAX_BITS + pol commit shift_lt_bit_len; + shift_lt_bit_len * (1 - shift_lt_bit_len) = 0; + + // The number of bits represented by the memory tag, any shifts greater than this will result in zero. + pol MAX_BITS = u8_tag * 8 + + u16_tag * 16 + + u32_tag * 32 + + u64_tag * 64 + + u128_tag * 128; + + // The result of MAX_BITS - ib, this used as part of the range check with the main trace + pol commit t_sub_s_bits; + + // Lookups for powers of 2. + // 2**(MAX_BITS - ib), constrained as part of the range check to the main trace + pol commit two_pow_t_sub_s; + // 2 ** ib, constrained as part of the range check to the main trace + pol commit two_pow_s; + + // For our assumptions to hold, we must check that s < MAX_BITS. This can be achieved by the following relation. + // We check if s <= MAX_BITS || s >= MAX_BITS using boolean shift_lt_bit_len. + // Regardless of which side is evaluated, the value of t_sub_s_bits < 2**8 + // There is no chance of an underflow involving ib to result in a t_sub_b_bits < 2**8 ib is range checked to be < 2**8 + // The range checking of t_sub_b_bits in the range [0, 2**8) is done by the lookup for 2**t_sub_s_bits + #[SHIFT_LT_BIT_LEN] + t_sub_s_bits = shift_sel * (shift_lt_bit_len * (MAX_BITS - ib) + (1 - shift_lt_bit_len) * (ib - MAX_BITS)); + + // ========= SHIFT RIGHT OPERATIONS =============================== + // a_hi * 2**s + a_lo = a + // If ib >= MAX_BITS, we trivially skip this check since the result will be forced to 0. + #[SHR_INPUT_DECOMPOSITION] + shift_lt_bit_len * op_shr * ((b_hi * two_pow_s + b_lo) - ia) = 0; + + // Return hi limb, if ib >= MAX_BITS, the output is forced to be 0 + #[SHR_OUTPUT] + op_shr * (ic - (b_hi * shift_lt_bit_len)) = 0; + + // ========= SHIFT LEFT OPERATIONS =============================== + // a_hi * 2**(t-s) + a_lo = a + // If ib >= MAX_BITS, we trivially skip this check since the result will be forced to 0. + #[SHL_INPUT_DECOMPOSITION] + shift_lt_bit_len * op_shl * ((b_hi * two_pow_t_sub_s + b_lo) - ia) = 0; + + // Return lo limb a_lo * 2**s, if ib >= MAX_BITS, the output is forced to be 0 + #[SHL_OUTPUT] + op_shl * (ic - (b_lo * two_pow_s * shift_lt_bit_len)) = 0; + diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index f4ce7214edb..74ce4b93574 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -15,6 +15,9 @@ namespace avm_main(256); pol commit sel_rng_8; // Boolean selector for the 8-bit range check lookup pol commit sel_rng_16; // Boolean selector for the 16-bit range check lookup + //===== Lookup table powers of 2 ============================================= + pol commit table_pow_2; // Table of powers of 2 for 8-bit numbers. + //===== CONTROL FLOW ========================================================== // Program counter pol commit pc; @@ -60,6 +63,10 @@ namespace avm_main(256); pol commit sel_op_lt; // LTE pol commit sel_op_lte; + // SHL + pol commit sel_op_shl; + // SHR + pol commit sel_op_shr; // Helper selector to characterize an ALU chiplet selector pol commit alu_sel; @@ -138,6 +145,8 @@ namespace avm_main(256); sel_op_cast * (1 - sel_op_cast) = 0; sel_op_lt * (1 - sel_op_lt) = 0; sel_op_lte * (1 - sel_op_lte) = 0; + sel_op_shl * (1 - sel_op_shl) = 0; + sel_op_shr * (1 - sel_op_shr) = 0; sel_internal_call * (1 - sel_internal_call) = 0; sel_internal_return * (1 - sel_internal_return) = 0; @@ -295,7 +304,7 @@ namespace avm_main(256); //===== ALU CONSTRAINTS ===================================================== // TODO: when division is moved to the alu, we will need to add the selector in the list below. - pol ALU_R_TAG_SEL = sel_op_add + sel_op_sub + sel_op_mul + sel_op_not + sel_op_eq + sel_op_lt + sel_op_lte; + pol ALU_R_TAG_SEL = sel_op_add + sel_op_sub + sel_op_mul + sel_op_not + sel_op_eq + sel_op_lt + sel_op_lte + sel_op_shr + sel_op_shl; pol ALU_W_TAG_SEL = sel_op_cast; pol ALU_ALL_SEL = ALU_R_TAG_SEL + ALU_W_TAG_SEL; @@ -317,11 +326,11 @@ namespace avm_main(256); #[PERM_MAIN_ALU] alu_sel {clk, ia, ib, ic, sel_op_add, sel_op_sub, sel_op_mul, sel_op_eq, sel_op_not, sel_op_cast, - sel_op_lt, sel_op_lte, alu_in_tag} + sel_op_lt, sel_op_lte, sel_op_shr, sel_op_shl, alu_in_tag} is avm_alu.alu_sel {avm_alu.clk, avm_alu.ia, avm_alu.ib, avm_alu.ic, avm_alu.op_add, avm_alu.op_sub, avm_alu.op_mul, avm_alu.op_eq, avm_alu.op_not, avm_alu.op_cast, - avm_alu.op_lt, avm_alu.op_lte, avm_alu.in_tag}; + avm_alu.op_lt, avm_alu.op_lte, avm_alu.op_shr, avm_alu.op_shl, avm_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 @@ -379,6 +388,17 @@ namespace avm_main(256); #[PERM_MAIN_MEM_IND_D] ind_op_d {clk, ind_d, mem_idx_d} is avm_mem.ind_op_d {avm_mem.clk, avm_mem.addr, avm_mem.val}; + //====== Inter-table Shift Constraints (Lookups) ============================================ + // Currently only used for shift operations but can be generalised for other uses. + + // Lookup for 2**(ib) + #[LOOKUP_POW_2_0] + avm_alu.shift_sel {avm_alu.ib, avm_alu.two_pow_s} in sel_rng_8 {clk, table_pow_2}; + + // Lookup for 2**(t-ib) + #[LOOKUP_POW_2_1] + avm_alu.shift_sel {avm_alu.t_sub_s_bits , avm_alu.two_pow_t_sub_s} in sel_rng_8 {clk, table_pow_2}; + //====== Inter-table Constraints (Range Checks) ============================================ // TODO: Investigate optimising these range checks. Handling non-FF elements should require less range checks. // One can increase the granularity based on the operation and tag. In the most extreme case, 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 ac09315024a..95ced4b652b 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -41,6 +41,10 @@ template struct Avm_aluRow { FF avm_alu_op_mul{}; FF avm_alu_op_mul_shift{}; FF avm_alu_op_not{}; + FF avm_alu_op_shl{}; + FF avm_alu_op_shl_shift{}; + FF avm_alu_op_shr{}; + FF avm_alu_op_shr_shift{}; FF avm_alu_op_sub{}; FF avm_alu_op_sub_shift{}; FF avm_alu_p_a_borrow{}; @@ -58,6 +62,11 @@ template struct Avm_aluRow { FF avm_alu_rng_chk_lookup_selector_shift{}; FF avm_alu_rng_chk_sel{}; FF avm_alu_rng_chk_sel_shift{}; + FF avm_alu_shift_lt_bit_len{}; + FF avm_alu_shift_sel{}; + FF avm_alu_t_sub_s_bits{}; + FF avm_alu_two_pow_s{}; + FF avm_alu_two_pow_t_sub_s{}; FF avm_alu_u128_tag{}; FF avm_alu_u16_r0{}; FF avm_alu_u16_r0_shift{}; @@ -94,104 +103,131 @@ template struct Avm_aluRow { inline std::string get_relation_label_avm_alu(int index) { switch (index) { - case 11: + case 12: return "ALU_ADD_SUB_1"; - case 12: + case 13: return "ALU_ADD_SUB_2"; - case 13: + case 14: return "ALU_MULTIPLICATION_FF"; - case 14: + case 15: return "ALU_MUL_COMMON_1"; - case 15: + case 16: return "ALU_MUL_COMMON_2"; - case 18: + case 19: return "ALU_MULTIPLICATION_OUT_U128"; - case 19: + case 20: return "ALU_FF_NOT_XOR"; - case 20: + case 21: return "ALU_OP_NOT"; - case 21: + case 22: return "ALU_RES_IS_BOOL"; - case 22: + case 23: return "ALU_OP_EQ"; - case 23: + case 24: return "INPUT_DECOMP_1"; - case 24: + case 25: return "INPUT_DECOMP_2"; - case 26: + case 27: return "SUB_LO_1"; - case 27: + case 28: return "SUB_HI_1"; - case 29: + case 30: return "SUB_LO_2"; - case 30: + case 31: return "SUB_HI_2"; - case 31: + case 32: return "RES_LO"; - case 32: + case 33: return "RES_HI"; - case 33: + case 34: return "CMP_CTR_REL_1"; - case 34: + case 35: return "CMP_CTR_REL_2"; - case 37: + case 38: return "CTR_NON_ZERO_REL"; - case 38: + case 39: return "RNG_CHK_LOOKUP_SELECTOR"; - case 39: + case 40: return "LOWER_CMP_RNG_CHK"; - case 40: + case 41: return "UPPER_CMP_RNG_CHK"; - case 41: + case 42: return "SHIFT_RELS_0"; - case 43: + case 44: return "SHIFT_RELS_1"; - case 45: + case 46: return "SHIFT_RELS_2"; - case 47: + case 48: return "SHIFT_RELS_3"; - case 49: + case 50: return "OP_CAST_PREV_LINE"; - case 50: + case 51: return "ALU_OP_CAST"; - case 51: + case 52: return "OP_CAST_RNG_CHECK_P_SUB_A_LOW"; - case 52: + case 53: return "OP_CAST_RNG_CHECK_P_SUB_A_HIGH"; - case 53: + case 54: return "TWO_LINE_OP_NO_OVERLAP"; + + case 55: + return "SHR_RANGE_0"; + + case 56: + return "SHR_RANGE_1"; + + case 57: + return "SHL_RANGE_0"; + + case 58: + return "SHL_RANGE_1"; + + case 60: + return "SHIFT_LT_BIT_LEN"; + + case 61: + return "SHR_INPUT_DECOMPOSITION"; + + case 62: + return "SHR_OUTPUT"; + + case 63: + return "SHL_INPUT_DECOMPOSITION"; + + case 64: + return "SHL_OUTPUT"; } return std::to_string(index); } @@ -200,9 +236,9 @@ template class avm_aluImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 8, 3, 4, 4, 5, 4, 4, 3, 4, - 3, 3, 4, 3, 6, 5, 3, 3, 3, 3, 4, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 5, 3, 3, 4, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 8, 3, 4, 4, 5, 4, 4, 3, 4, 3, 3, 4, 3, 6, + 5, 3, 3, 3, 3, 4, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 5, 3, 3, 4, 4, 4, 4, 4, 3, 5, 5, 4, 5, 5, }; template @@ -217,10 +253,12 @@ template class avm_aluImpl { Avm_DECLARE_VIEWS(0); auto tmp = (avm_alu_alu_sel - - (((((((avm_alu_op_add + avm_alu_op_sub) + avm_alu_op_mul) + avm_alu_op_not) + avm_alu_op_eq) + - avm_alu_op_cast) + - avm_alu_op_lt) + - avm_alu_op_lte)); + (((((((((avm_alu_op_add + avm_alu_op_sub) + avm_alu_op_mul) + avm_alu_op_not) + avm_alu_op_eq) + + avm_alu_op_cast) + + avm_alu_op_lt) + + avm_alu_op_lte) + + avm_alu_op_shr) + + avm_alu_op_shl)); tmp *= scaling_factor; std::get<0>(evals) += tmp; } @@ -236,7 +274,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(2); - auto tmp = (avm_alu_cf * (-avm_alu_cf + FF(1))); + auto tmp = (avm_alu_shift_sel - (avm_alu_op_shl + avm_alu_op_shr)); tmp *= scaling_factor; std::get<2>(evals) += tmp; } @@ -244,7 +282,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(3); - auto tmp = (avm_alu_ff_tag * (-avm_alu_ff_tag + FF(1))); + auto tmp = (avm_alu_cf * (-avm_alu_cf + FF(1))); tmp *= scaling_factor; std::get<3>(evals) += tmp; } @@ -252,7 +290,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(4); - auto tmp = (avm_alu_u8_tag * (-avm_alu_u8_tag + FF(1))); + auto tmp = (avm_alu_ff_tag * (-avm_alu_ff_tag + FF(1))); tmp *= scaling_factor; std::get<4>(evals) += tmp; } @@ -260,7 +298,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(5); - auto tmp = (avm_alu_u16_tag * (-avm_alu_u16_tag + FF(1))); + auto tmp = (avm_alu_u8_tag * (-avm_alu_u8_tag + FF(1))); tmp *= scaling_factor; std::get<5>(evals) += tmp; } @@ -268,7 +306,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(6); - auto tmp = (avm_alu_u32_tag * (-avm_alu_u32_tag + FF(1))); + auto tmp = (avm_alu_u16_tag * (-avm_alu_u16_tag + FF(1))); tmp *= scaling_factor; std::get<6>(evals) += tmp; } @@ -276,7 +314,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(7); - auto tmp = (avm_alu_u64_tag * (-avm_alu_u64_tag + FF(1))); + auto tmp = (avm_alu_u32_tag * (-avm_alu_u32_tag + FF(1))); tmp *= scaling_factor; std::get<7>(evals) += tmp; } @@ -284,7 +322,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(8); - auto tmp = (avm_alu_u128_tag * (-avm_alu_u128_tag + FF(1))); + auto tmp = (avm_alu_u64_tag * (-avm_alu_u64_tag + FF(1))); tmp *= scaling_factor; std::get<8>(evals) += tmp; } @@ -292,28 +330,36 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(9); + auto tmp = (avm_alu_u128_tag * (-avm_alu_u128_tag + FF(1))); + tmp *= scaling_factor; + std::get<9>(evals) += tmp; + } + // Contribution 10 + { + Avm_DECLARE_VIEWS(10); + auto tmp = (avm_alu_alu_sel * ((((((avm_alu_ff_tag + avm_alu_u8_tag) + avm_alu_u16_tag) + avm_alu_u32_tag) + avm_alu_u64_tag) + avm_alu_u128_tag) - FF(1))); tmp *= scaling_factor; - std::get<9>(evals) += tmp; + std::get<10>(evals) += tmp; } - // Contribution 10 + // Contribution 11 { - Avm_DECLARE_VIEWS(10); + Avm_DECLARE_VIEWS(11); auto tmp = (avm_alu_in_tag - (((((avm_alu_u8_tag + (avm_alu_u16_tag * FF(2))) + (avm_alu_u32_tag * FF(3))) + (avm_alu_u64_tag * FF(4))) + (avm_alu_u128_tag * FF(5))) + (avm_alu_ff_tag * FF(6)))); tmp *= scaling_factor; - std::get<10>(evals) += tmp; + std::get<11>(evals) += tmp; } - // Contribution 11 + // Contribution 12 { - Avm_DECLARE_VIEWS(11); + Avm_DECLARE_VIEWS(12); auto tmp = (((avm_alu_op_add + avm_alu_op_sub) * ((((((((((avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))) + (avm_alu_u16_r0 * FF(65536))) + @@ -328,11 +374,11 @@ template class avm_aluImpl { ((avm_alu_op_add - avm_alu_op_sub) * ((avm_alu_cf * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL })) - avm_alu_ib))); tmp *= scaling_factor; - std::get<11>(evals) += tmp; + std::get<12>(evals) += tmp; } - // Contribution 12 + // Contribution 13 { - Avm_DECLARE_VIEWS(12); + Avm_DECLARE_VIEWS(13); auto tmp = (((avm_alu_op_add + avm_alu_op_sub) * (((((((avm_alu_u8_tag * avm_alu_u8_r0) + @@ -355,19 +401,19 @@ template class avm_aluImpl { avm_alu_ic)) + ((avm_alu_ff_tag * (avm_alu_op_add - avm_alu_op_sub)) * avm_alu_ib)); tmp *= scaling_factor; - std::get<12>(evals) += tmp; + std::get<13>(evals) += tmp; } - // Contribution 13 + // Contribution 14 { - Avm_DECLARE_VIEWS(13); + Avm_DECLARE_VIEWS(14); auto tmp = ((avm_alu_ff_tag * avm_alu_op_mul) * ((avm_alu_ia * avm_alu_ib) - avm_alu_ic)); tmp *= scaling_factor; - std::get<13>(evals) += tmp; + std::get<14>(evals) += tmp; } - // Contribution 14 + // Contribution 15 { - Avm_DECLARE_VIEWS(14); + Avm_DECLARE_VIEWS(15); auto tmp = ((((-avm_alu_ff_tag + FF(1)) - avm_alu_u128_tag) * avm_alu_op_mul) * (((((((((avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))) + (avm_alu_u16_r0 * FF(65536))) + @@ -379,11 +425,11 @@ template class avm_aluImpl { (avm_alu_u16_r6 * FF(uint256_t{ 0UL, 281474976710656UL, 0UL, 0UL }))) - (avm_alu_ia * avm_alu_ib))); tmp *= scaling_factor; - std::get<14>(evals) += tmp; + std::get<15>(evals) += tmp; } - // Contribution 15 + // Contribution 16 { - Avm_DECLARE_VIEWS(15); + Avm_DECLARE_VIEWS(16); auto tmp = (avm_alu_op_mul * @@ -395,11 +441,11 @@ template class avm_aluImpl { (avm_alu_u16_r2 * FF(281474976710656UL))))) - (((-avm_alu_ff_tag + FF(1)) - avm_alu_u128_tag) * avm_alu_ic))); tmp *= scaling_factor; - std::get<15>(evals) += tmp; + std::get<16>(evals) += tmp; } - // Contribution 16 + // Contribution 17 { - Avm_DECLARE_VIEWS(16); + Avm_DECLARE_VIEWS(17); auto tmp = ((avm_alu_u128_tag * avm_alu_op_mul) * ((((((avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))) + (avm_alu_u16_r0 * FF(65536))) + @@ -410,11 +456,11 @@ template class avm_aluImpl { FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) - avm_alu_ia)); tmp *= scaling_factor; - std::get<16>(evals) += tmp; + std::get<17>(evals) += tmp; } - // Contribution 17 + // Contribution 18 { - Avm_DECLARE_VIEWS(17); + Avm_DECLARE_VIEWS(18); auto tmp = ((avm_alu_u128_tag * avm_alu_op_mul) * @@ -427,11 +473,11 @@ template class avm_aluImpl { FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) - avm_alu_ib)); tmp *= scaling_factor; - std::get<17>(evals) += tmp; + std::get<18>(evals) += tmp; } - // Contribution 18 + // Contribution 19 { - Avm_DECLARE_VIEWS(18); + Avm_DECLARE_VIEWS(19); auto tmp = ((avm_alu_u128_tag * avm_alu_op_mul) * @@ -452,19 +498,19 @@ template class avm_aluImpl { FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) - avm_alu_ic)); tmp *= scaling_factor; - std::get<18>(evals) += tmp; + std::get<19>(evals) += tmp; } - // Contribution 19 + // Contribution 20 { - Avm_DECLARE_VIEWS(19); + Avm_DECLARE_VIEWS(20); auto tmp = (avm_alu_op_not * avm_alu_ff_tag); tmp *= scaling_factor; - std::get<19>(evals) += tmp; + std::get<20>(evals) += tmp; } - // Contribution 20 + // Contribution 21 { - Avm_DECLARE_VIEWS(20); + Avm_DECLARE_VIEWS(21); auto tmp = (avm_alu_op_not * ((avm_alu_ia + avm_alu_ic) - ((((((avm_alu_u8_tag * FF(256)) + (avm_alu_u16_tag * FF(65536))) + @@ -473,25 +519,13 @@ template class avm_aluImpl { (avm_alu_u128_tag * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) - FF(1)))); tmp *= scaling_factor; - std::get<20>(evals) += tmp; - } - // Contribution 21 - { - Avm_DECLARE_VIEWS(21); - - auto tmp = ((avm_alu_cmp_sel + avm_alu_op_eq) * (avm_alu_ic * (-avm_alu_ic + FF(1)))); - tmp *= scaling_factor; std::get<21>(evals) += tmp; } // Contribution 22 { Avm_DECLARE_VIEWS(22); - auto tmp = - (avm_alu_op_eq * ((((avm_alu_ia - avm_alu_ib) * - ((avm_alu_ic * (-avm_alu_op_eq_diff_inv + FF(1))) + avm_alu_op_eq_diff_inv)) - - FF(1)) + - avm_alu_ic)); + auto tmp = ((avm_alu_cmp_sel + avm_alu_op_eq) * (avm_alu_ic * (-avm_alu_ic + FF(1)))); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -499,9 +533,11 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (((avm_alu_op_lt * avm_alu_ib) + ((avm_alu_op_lte + avm_alu_op_cast) * avm_alu_ia)) - - ((avm_alu_a_lo + (avm_alu_a_hi * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) * - (avm_alu_cmp_sel + avm_alu_op_cast))); + auto tmp = + (avm_alu_op_eq * ((((avm_alu_ia - avm_alu_ib) * + ((avm_alu_ic * (-avm_alu_op_eq_diff_inv + FF(1))) + avm_alu_op_eq_diff_inv)) - + FF(1)) + + avm_alu_ic)); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -509,8 +545,9 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = (((avm_alu_op_lt * avm_alu_ia) + (avm_alu_op_lte * avm_alu_ib)) - - ((avm_alu_b_lo + (avm_alu_b_hi * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) * avm_alu_cmp_sel)); + auto tmp = (((avm_alu_op_lt * avm_alu_ib) + ((avm_alu_op_lte + avm_alu_op_cast) * avm_alu_ia)) - + ((avm_alu_a_lo + (avm_alu_a_hi * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) * + (avm_alu_cmp_sel + avm_alu_op_cast))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -518,7 +555,8 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (avm_alu_p_a_borrow * (-avm_alu_p_a_borrow + FF(1))); + auto tmp = (((avm_alu_op_lt * avm_alu_ia) + (avm_alu_op_lte * avm_alu_ib)) - + ((avm_alu_b_lo + (avm_alu_b_hi * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) * avm_alu_cmp_sel)); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -526,10 +564,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = ((avm_alu_p_sub_a_lo - - ((-avm_alu_a_lo + FF(uint256_t{ 4891460686036598784UL, 2896914383306846353UL, 0UL, 0UL })) + - (avm_alu_p_a_borrow * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL })))) * - (avm_alu_cmp_sel + avm_alu_op_cast)); + auto tmp = (avm_alu_p_a_borrow * (-avm_alu_p_a_borrow + FF(1))); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -537,9 +572,9 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = ((avm_alu_p_sub_a_hi - - ((-avm_alu_a_hi + FF(uint256_t{ 13281191951274694749UL, 3486998266802970665UL, 0UL, 0UL })) - - avm_alu_p_a_borrow)) * + auto tmp = ((avm_alu_p_sub_a_lo - + ((-avm_alu_a_lo + FF(uint256_t{ 4891460686036598784UL, 2896914383306846353UL, 0UL, 0UL })) + + (avm_alu_p_a_borrow * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL })))) * (avm_alu_cmp_sel + avm_alu_op_cast)); tmp *= scaling_factor; std::get<27>(evals) += tmp; @@ -548,7 +583,10 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(28); - auto tmp = (avm_alu_p_b_borrow * (-avm_alu_p_b_borrow + FF(1))); + auto tmp = ((avm_alu_p_sub_a_hi - + ((-avm_alu_a_hi + FF(uint256_t{ 13281191951274694749UL, 3486998266802970665UL, 0UL, 0UL })) - + avm_alu_p_a_borrow)) * + (avm_alu_cmp_sel + avm_alu_op_cast)); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -556,27 +594,35 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(29); + auto tmp = (avm_alu_p_b_borrow * (-avm_alu_p_b_borrow + FF(1))); + tmp *= scaling_factor; + std::get<29>(evals) += tmp; + } + // Contribution 30 + { + Avm_DECLARE_VIEWS(30); + auto tmp = ((avm_alu_p_sub_b_lo - ((-avm_alu_b_lo + FF(uint256_t{ 4891460686036598784UL, 2896914383306846353UL, 0UL, 0UL })) + (avm_alu_p_b_borrow * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL })))) * avm_alu_cmp_sel); tmp *= scaling_factor; - std::get<29>(evals) += tmp; + std::get<30>(evals) += tmp; } - // Contribution 30 + // Contribution 31 { - Avm_DECLARE_VIEWS(30); + Avm_DECLARE_VIEWS(31); auto tmp = ((avm_alu_p_sub_b_hi - ((-avm_alu_b_hi + FF(uint256_t{ 13281191951274694749UL, 3486998266802970665UL, 0UL, 0UL })) - avm_alu_p_b_borrow)) * avm_alu_cmp_sel); tmp *= scaling_factor; - std::get<30>(evals) += tmp; + std::get<31>(evals) += tmp; } - // Contribution 31 + // Contribution 32 { - Avm_DECLARE_VIEWS(31); + Avm_DECLARE_VIEWS(32); auto tmp = ((avm_alu_res_lo - @@ -586,11 +632,11 @@ template class avm_aluImpl { (-((avm_alu_op_lt * avm_alu_ic) + ((-avm_alu_ic + FF(1)) * avm_alu_op_lte)) + FF(1))))) * avm_alu_cmp_sel); tmp *= scaling_factor; - std::get<31>(evals) += tmp; + std::get<32>(evals) += tmp; } - // Contribution 32 + // Contribution 33 { - Avm_DECLARE_VIEWS(32); + Avm_DECLARE_VIEWS(33); auto tmp = ((avm_alu_res_hi - ((((avm_alu_a_hi - avm_alu_b_hi) - avm_alu_borrow) * @@ -599,21 +645,13 @@ template class avm_aluImpl { (-((avm_alu_op_lt * avm_alu_ic) + ((-avm_alu_ic + FF(1)) * avm_alu_op_lte)) + FF(1))))) * avm_alu_cmp_sel); tmp *= scaling_factor; - std::get<32>(evals) += tmp; - } - // Contribution 33 - { - Avm_DECLARE_VIEWS(33); - - auto tmp = (((avm_alu_cmp_rng_ctr_shift - avm_alu_cmp_rng_ctr) + FF(1)) * avm_alu_cmp_rng_ctr); - tmp *= scaling_factor; std::get<33>(evals) += tmp; } // Contribution 34 { Avm_DECLARE_VIEWS(34); - auto tmp = ((avm_alu_cmp_rng_ctr_shift - FF(4)) * avm_alu_cmp_sel); + auto tmp = (((avm_alu_cmp_rng_ctr_shift - avm_alu_cmp_rng_ctr) + FF(1)) * avm_alu_cmp_rng_ctr); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -621,7 +659,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(35); - auto tmp = (avm_alu_rng_chk_sel * (-avm_alu_rng_chk_sel + FF(1))); + auto tmp = ((avm_alu_cmp_rng_ctr_shift - FF(4)) * avm_alu_cmp_sel); tmp *= scaling_factor; std::get<35>(evals) += tmp; } @@ -629,7 +667,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(36); - auto tmp = (avm_alu_rng_chk_sel * avm_alu_cmp_sel); + auto tmp = (avm_alu_rng_chk_sel * (-avm_alu_rng_chk_sel + FF(1))); tmp *= scaling_factor; std::get<36>(evals) += tmp; } @@ -637,9 +675,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(37); - auto tmp = ((avm_alu_cmp_rng_ctr * (((-avm_alu_rng_chk_sel + FF(1)) * (-avm_alu_op_eq_diff_inv + FF(1))) + - avm_alu_op_eq_diff_inv)) - - avm_alu_rng_chk_sel); + auto tmp = (avm_alu_rng_chk_sel * avm_alu_cmp_sel); tmp *= scaling_factor; std::get<37>(evals) += tmp; } @@ -647,13 +683,9 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(38); - auto tmp = (avm_alu_rng_chk_lookup_selector_shift - - (((((((avm_alu_cmp_sel_shift + avm_alu_rng_chk_sel_shift) + avm_alu_op_add_shift) + - avm_alu_op_sub_shift) + - avm_alu_op_mul_shift) + - (avm_alu_op_mul * avm_alu_u128_tag)) + - avm_alu_op_cast_shift) + - avm_alu_op_cast_prev_shift)); + auto tmp = ((avm_alu_cmp_rng_ctr * (((-avm_alu_rng_chk_sel + FF(1)) * (-avm_alu_op_eq_diff_inv + FF(1))) + + avm_alu_op_eq_diff_inv)) - + avm_alu_rng_chk_sel); tmp *= scaling_factor; std::get<38>(evals) += tmp; } @@ -661,6 +693,22 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(39); + auto tmp = (avm_alu_rng_chk_lookup_selector_shift - + (((((((((avm_alu_cmp_sel_shift + avm_alu_rng_chk_sel_shift) + avm_alu_op_add_shift) + + avm_alu_op_sub_shift) + + avm_alu_op_mul_shift) + + (avm_alu_op_mul * avm_alu_u128_tag)) + + avm_alu_op_cast_shift) + + avm_alu_op_cast_prev_shift) + + avm_alu_op_shl_shift) + + avm_alu_op_shr_shift)); + tmp *= scaling_factor; + std::get<39>(evals) += tmp; + } + // Contribution 40 + { + Avm_DECLARE_VIEWS(40); + auto tmp = (avm_alu_a_lo - (((((((((avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))) + (avm_alu_u16_r0 * FF(65536))) + (avm_alu_u16_r1 * FF(4294967296UL))) + @@ -669,13 +717,14 @@ template class avm_aluImpl { (avm_alu_u16_r4 * FF(uint256_t{ 0UL, 65536UL, 0UL, 0UL }))) + (avm_alu_u16_r5 * FF(uint256_t{ 0UL, 4294967296UL, 0UL, 0UL }))) + (avm_alu_u16_r6 * FF(uint256_t{ 0UL, 281474976710656UL, 0UL, 0UL }))) * - (((avm_alu_rng_chk_sel + avm_alu_cmp_sel) + avm_alu_op_cast) + avm_alu_op_cast_prev))); + ((((avm_alu_rng_chk_sel + avm_alu_cmp_sel) + avm_alu_op_cast) + avm_alu_op_cast_prev) + + avm_alu_shift_lt_bit_len))); tmp *= scaling_factor; - std::get<39>(evals) += tmp; + std::get<40>(evals) += tmp; } - // Contribution 40 + // Contribution 41 { - Avm_DECLARE_VIEWS(40); + Avm_DECLARE_VIEWS(41); auto tmp = (avm_alu_a_hi - ((((((((avm_alu_u16_r7 + (avm_alu_u16_r8 * FF(65536))) + (avm_alu_u16_r9 * FF(4294967296UL))) + @@ -684,15 +733,8 @@ template class avm_aluImpl { (avm_alu_u16_r12 * FF(uint256_t{ 0UL, 65536UL, 0UL, 0UL }))) + (avm_alu_u16_r13 * FF(uint256_t{ 0UL, 4294967296UL, 0UL, 0UL }))) + (avm_alu_u16_r14 * FF(uint256_t{ 0UL, 281474976710656UL, 0UL, 0UL }))) * - (((avm_alu_rng_chk_sel + avm_alu_cmp_sel) + avm_alu_op_cast) + avm_alu_op_cast_prev))); - tmp *= scaling_factor; - std::get<40>(evals) += tmp; - } - // Contribution 41 - { - Avm_DECLARE_VIEWS(41); - - auto tmp = ((avm_alu_a_lo_shift - avm_alu_b_lo) * avm_alu_rng_chk_sel_shift); + ((((avm_alu_rng_chk_sel + avm_alu_cmp_sel) + avm_alu_op_cast) + avm_alu_op_cast_prev) + + avm_alu_shift_lt_bit_len))); tmp *= scaling_factor; std::get<41>(evals) += tmp; } @@ -700,7 +742,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(42); - auto tmp = ((avm_alu_a_hi_shift - avm_alu_b_hi) * avm_alu_rng_chk_sel_shift); + auto tmp = ((avm_alu_a_lo_shift - avm_alu_b_lo) * avm_alu_rng_chk_sel_shift); tmp *= scaling_factor; std::get<42>(evals) += tmp; } @@ -708,7 +750,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(43); - auto tmp = ((avm_alu_b_lo_shift - avm_alu_p_sub_a_lo) * avm_alu_rng_chk_sel_shift); + auto tmp = ((avm_alu_a_hi_shift - avm_alu_b_hi) * avm_alu_rng_chk_sel_shift); tmp *= scaling_factor; std::get<43>(evals) += tmp; } @@ -716,7 +758,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(44); - auto tmp = ((avm_alu_b_hi_shift - avm_alu_p_sub_a_hi) * avm_alu_rng_chk_sel_shift); + auto tmp = ((avm_alu_b_lo_shift - avm_alu_p_sub_a_lo) * avm_alu_rng_chk_sel_shift); tmp *= scaling_factor; std::get<44>(evals) += tmp; } @@ -724,7 +766,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(45); - auto tmp = ((avm_alu_p_sub_a_lo_shift - avm_alu_p_sub_b_lo) * avm_alu_rng_chk_sel_shift); + auto tmp = ((avm_alu_b_hi_shift - avm_alu_p_sub_a_hi) * avm_alu_rng_chk_sel_shift); tmp *= scaling_factor; std::get<45>(evals) += tmp; } @@ -732,7 +774,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(46); - auto tmp = ((avm_alu_p_sub_a_hi_shift - avm_alu_p_sub_b_hi) * avm_alu_rng_chk_sel_shift); + auto tmp = ((avm_alu_p_sub_a_lo_shift - avm_alu_p_sub_b_lo) * avm_alu_rng_chk_sel_shift); tmp *= scaling_factor; std::get<46>(evals) += tmp; } @@ -740,7 +782,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(47); - auto tmp = ((avm_alu_p_sub_b_lo_shift - avm_alu_res_lo) * avm_alu_rng_chk_sel_shift); + auto tmp = ((avm_alu_p_sub_a_hi_shift - avm_alu_p_sub_b_hi) * avm_alu_rng_chk_sel_shift); tmp *= scaling_factor; std::get<47>(evals) += tmp; } @@ -748,7 +790,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(48); - auto tmp = ((avm_alu_p_sub_b_hi_shift - avm_alu_res_hi) * avm_alu_rng_chk_sel_shift); + auto tmp = ((avm_alu_p_sub_b_lo_shift - avm_alu_res_lo) * avm_alu_rng_chk_sel_shift); tmp *= scaling_factor; std::get<48>(evals) += tmp; } @@ -756,7 +798,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(49); - auto tmp = (avm_alu_op_cast_prev_shift - avm_alu_op_cast); + auto tmp = ((avm_alu_p_sub_b_hi_shift - avm_alu_res_hi) * avm_alu_rng_chk_sel_shift); tmp *= scaling_factor; std::get<49>(evals) += tmp; } @@ -764,6 +806,14 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(50); + auto tmp = (avm_alu_op_cast_prev_shift - avm_alu_op_cast); + tmp *= scaling_factor; + std::get<50>(evals) += tmp; + } + // Contribution 51 + { + Avm_DECLARE_VIEWS(51); + auto tmp = (avm_alu_op_cast * (((((((avm_alu_u8_tag * avm_alu_u8_r0) + @@ -784,21 +834,13 @@ template class avm_aluImpl { (avm_alu_ff_tag * avm_alu_ia)) - avm_alu_ic)); tmp *= scaling_factor; - std::get<50>(evals) += tmp; - } - // Contribution 51 - { - Avm_DECLARE_VIEWS(51); - - auto tmp = (avm_alu_op_cast * (avm_alu_a_lo_shift - avm_alu_p_sub_a_lo)); - tmp *= scaling_factor; std::get<51>(evals) += tmp; } // Contribution 52 { Avm_DECLARE_VIEWS(52); - auto tmp = (avm_alu_op_cast * (avm_alu_a_hi_shift - avm_alu_p_sub_a_hi)); + auto tmp = (avm_alu_op_cast * (avm_alu_a_lo_shift - avm_alu_p_sub_a_lo)); tmp *= scaling_factor; std::get<52>(evals) += tmp; } @@ -806,10 +848,116 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(53); - auto tmp = (((avm_alu_op_mul * avm_alu_ff_tag) + avm_alu_op_cast) * avm_alu_alu_sel_shift); + auto tmp = (avm_alu_op_cast * (avm_alu_a_hi_shift - avm_alu_p_sub_a_hi)); tmp *= scaling_factor; std::get<53>(evals) += tmp; } + // Contribution 54 + { + Avm_DECLARE_VIEWS(54); + + auto tmp = (((avm_alu_op_mul * avm_alu_ff_tag) + avm_alu_op_cast) * avm_alu_alu_sel_shift); + tmp *= scaling_factor; + std::get<54>(evals) += tmp; + } + // Contribution 55 + { + Avm_DECLARE_VIEWS(55); + + auto tmp = ((avm_alu_shift_lt_bit_len * avm_alu_op_shr) * + (avm_alu_a_lo - ((avm_alu_two_pow_s - avm_alu_b_lo) - FF(1)))); + tmp *= scaling_factor; + std::get<55>(evals) += tmp; + } + // Contribution 56 + { + Avm_DECLARE_VIEWS(56); + + auto tmp = ((avm_alu_shift_lt_bit_len * avm_alu_op_shr) * + (avm_alu_a_hi - ((avm_alu_two_pow_t_sub_s - avm_alu_b_hi) - FF(1)))); + tmp *= scaling_factor; + std::get<56>(evals) += tmp; + } + // Contribution 57 + { + Avm_DECLARE_VIEWS(57); + + auto tmp = ((avm_alu_shift_lt_bit_len * avm_alu_op_shl) * + (avm_alu_a_lo - ((avm_alu_two_pow_t_sub_s - avm_alu_b_lo) - FF(1)))); + tmp *= scaling_factor; + std::get<57>(evals) += tmp; + } + // Contribution 58 + { + Avm_DECLARE_VIEWS(58); + + auto tmp = ((avm_alu_shift_lt_bit_len * avm_alu_op_shl) * + (avm_alu_a_hi - ((avm_alu_two_pow_s - avm_alu_b_hi) - FF(1)))); + tmp *= scaling_factor; + std::get<58>(evals) += tmp; + } + // Contribution 59 + { + Avm_DECLARE_VIEWS(59); + + auto tmp = (avm_alu_shift_lt_bit_len * (-avm_alu_shift_lt_bit_len + FF(1))); + tmp *= scaling_factor; + std::get<59>(evals) += tmp; + } + // Contribution 60 + { + Avm_DECLARE_VIEWS(60); + + auto tmp = (avm_alu_t_sub_s_bits - + (avm_alu_shift_sel * + ((avm_alu_shift_lt_bit_len * + ((((((avm_alu_u8_tag * FF(8)) + (avm_alu_u16_tag * FF(16))) + (avm_alu_u32_tag * FF(32))) + + (avm_alu_u64_tag * FF(64))) + + (avm_alu_u128_tag * FF(128))) - + avm_alu_ib)) + + ((-avm_alu_shift_lt_bit_len + FF(1)) * + (avm_alu_ib - + (((((avm_alu_u8_tag * FF(8)) + (avm_alu_u16_tag * FF(16))) + (avm_alu_u32_tag * FF(32))) + + (avm_alu_u64_tag * FF(64))) + + (avm_alu_u128_tag * FF(128)))))))); + tmp *= scaling_factor; + std::get<60>(evals) += tmp; + } + // Contribution 61 + { + Avm_DECLARE_VIEWS(61); + + auto tmp = ((avm_alu_shift_lt_bit_len * avm_alu_op_shr) * + (((avm_alu_b_hi * avm_alu_two_pow_s) + avm_alu_b_lo) - avm_alu_ia)); + tmp *= scaling_factor; + std::get<61>(evals) += tmp; + } + // Contribution 62 + { + Avm_DECLARE_VIEWS(62); + + auto tmp = (avm_alu_op_shr * (avm_alu_ic - (avm_alu_b_hi * avm_alu_shift_lt_bit_len))); + tmp *= scaling_factor; + std::get<62>(evals) += tmp; + } + // Contribution 63 + { + Avm_DECLARE_VIEWS(63); + + auto tmp = ((avm_alu_shift_lt_bit_len * avm_alu_op_shl) * + (((avm_alu_b_hi * avm_alu_two_pow_t_sub_s) + avm_alu_b_lo) - avm_alu_ia)); + tmp *= scaling_factor; + std::get<63>(evals) += tmp; + } + // Contribution 64 + { + Avm_DECLARE_VIEWS(64); + + auto tmp = + (avm_alu_op_shl * (avm_alu_ic - ((avm_alu_b_lo * avm_alu_two_pow_s) * avm_alu_shift_lt_bit_len))); + tmp *= scaling_factor; + std::get<64>(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 b9c4dfd14df..93ab5869174 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -56,6 +56,8 @@ template struct Avm_mainRow { FF avm_main_sel_op_mul{}; FF avm_main_sel_op_not{}; FF avm_main_sel_op_or{}; + FF avm_main_sel_op_shl{}; + FF avm_main_sel_op_shr{}; FF avm_main_sel_op_sub{}; FF avm_main_sel_op_xor{}; FF avm_main_tag_err{}; @@ -65,52 +67,52 @@ template struct Avm_mainRow { inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 33: + case 35: return "OUTPUT_U8"; - case 34: + case 36: return "SUBOP_DIVISION_FF"; - case 35: + case 37: return "SUBOP_DIVISION_ZERO_ERR1"; - case 36: + case 38: return "SUBOP_DIVISION_ZERO_ERR2"; - case 37: + case 39: return "SUBOP_ERROR_RELEVANT_OP"; - case 39: + case 41: return "RETURN_POINTER_INCREMENT"; - case 45: + case 47: return "RETURN_POINTER_DECREMENT"; - case 50: + case 52: return "PC_INCREMENT"; - case 51: + case 53: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 52: + case 54: return "CMOV_CONDITION_RES_1"; - case 53: + case 55: return "CMOV_CONDITION_RES_2"; - case 56: + case 58: return "MOV_SAME_VALUE_A"; - case 57: + case 59: return "MOV_SAME_VALUE_B"; - case 58: + case 60: return "MOV_MAIN_SAME_TAG"; - case 62: + case 64: return "BIN_SEL_1"; - case 63: + case 65: return "BIN_SEL_2"; } return std::to_string(index); @@ -120,9 +122,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, 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, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 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, 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, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, }; template @@ -232,7 +234,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(12); - auto tmp = (avm_main_sel_internal_call * (-avm_main_sel_internal_call + FF(1))); + auto tmp = (avm_main_sel_op_shl * (-avm_main_sel_op_shl + FF(1))); tmp *= scaling_factor; std::get<12>(evals) += tmp; } @@ -240,7 +242,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(13); - auto tmp = (avm_main_sel_internal_return * (-avm_main_sel_internal_return + FF(1))); + auto tmp = (avm_main_sel_op_shr * (-avm_main_sel_op_shr + FF(1))); tmp *= scaling_factor; std::get<13>(evals) += tmp; } @@ -248,7 +250,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(14); - auto tmp = (avm_main_sel_jump * (-avm_main_sel_jump + FF(1))); + auto tmp = (avm_main_sel_internal_call * (-avm_main_sel_internal_call + FF(1))); tmp *= scaling_factor; std::get<14>(evals) += tmp; } @@ -256,7 +258,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(15); - auto tmp = (avm_main_sel_halt * (-avm_main_sel_halt + FF(1))); + auto tmp = (avm_main_sel_internal_return * (-avm_main_sel_internal_return + FF(1))); tmp *= scaling_factor; std::get<15>(evals) += tmp; } @@ -264,7 +266,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(16); - auto tmp = (avm_main_sel_mov * (-avm_main_sel_mov + FF(1))); + auto tmp = (avm_main_sel_jump * (-avm_main_sel_jump + FF(1))); tmp *= scaling_factor; std::get<16>(evals) += tmp; } @@ -272,7 +274,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(17); - auto tmp = (avm_main_sel_cmov * (-avm_main_sel_cmov + FF(1))); + auto tmp = (avm_main_sel_halt * (-avm_main_sel_halt + FF(1))); tmp *= scaling_factor; std::get<17>(evals) += tmp; } @@ -280,7 +282,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(18); - auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); + auto tmp = (avm_main_sel_mov * (-avm_main_sel_mov + FF(1))); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -288,7 +290,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(19); - auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); + auto tmp = (avm_main_sel_cmov * (-avm_main_sel_cmov + FF(1))); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -296,7 +298,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = (avm_main_id_zero * (-avm_main_id_zero + FF(1))); + auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -304,7 +306,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); + auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -312,7 +314,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); + auto tmp = (avm_main_id_zero * (-avm_main_id_zero + FF(1))); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -320,7 +322,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); + auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -328,7 +330,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = (avm_main_mem_op_d * (-avm_main_mem_op_d + FF(1))); + auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -336,7 +338,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); + auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -344,7 +346,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); + auto tmp = (avm_main_mem_op_d * (-avm_main_mem_op_d + FF(1))); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -352,7 +354,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); + auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -360,7 +362,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(28); - auto tmp = (avm_main_rwd * (-avm_main_rwd + FF(1))); + auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -368,7 +370,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(29); - auto tmp = (avm_main_ind_op_a * (-avm_main_ind_op_a + FF(1))); + auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -376,7 +378,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(30); - auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); + auto tmp = (avm_main_rwd * (-avm_main_rwd + FF(1))); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -384,7 +386,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(31); - auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); + auto tmp = (avm_main_ind_op_a * (-avm_main_ind_op_a + FF(1))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -392,7 +394,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(32); - auto tmp = (avm_main_ind_op_d * (-avm_main_ind_op_d + FF(1))); + auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -400,8 +402,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(33); - auto tmp = - (((avm_main_sel_op_eq + avm_main_sel_op_lte) + avm_main_sel_op_lt) * (avm_main_w_in_tag - FF(1))); + auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); tmp *= scaling_factor; std::get<33>(evals) += tmp; } @@ -409,8 +410,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(34); - 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_d * (-avm_main_ind_op_d + FF(1))); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -418,7 +418,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(35); - auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); + auto tmp = + (((avm_main_sel_op_eq + avm_main_sel_op_lte) + avm_main_sel_op_lt) * (avm_main_w_in_tag - FF(1))); tmp *= scaling_factor; std::get<35>(evals) += tmp; } @@ -426,7 +427,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(36); - auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + 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<36>(evals) += tmp; } @@ -434,7 +436,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(37); - auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); + auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); tmp *= scaling_factor; std::get<37>(evals) += tmp; } @@ -442,7 +444,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(38); - auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); + auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; std::get<38>(evals) += tmp; } @@ -450,8 +452,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(39); - auto tmp = (avm_main_sel_internal_call * - (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr + FF(1)))); + auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); tmp *= scaling_factor; std::get<39>(evals) += tmp; } @@ -459,7 +460,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(40); - auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); + auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<40>(evals) += tmp; } @@ -467,7 +468,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(41); - auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); + 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<41>(evals) += tmp; } @@ -475,7 +477,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(42); - 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 - avm_main_mem_idx_b)); tmp *= scaling_factor; std::get<42>(evals) += tmp; } @@ -483,7 +485,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(43); - auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); + auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<43>(evals) += tmp; } @@ -491,7 +493,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(44); - auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); + auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); tmp *= scaling_factor; std::get<44>(evals) += tmp; } @@ -499,8 +501,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(45); - 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_rwb - FF(1))); tmp *= scaling_factor; std::get<45>(evals) += tmp; } @@ -508,7 +509,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(46); - 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_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<46>(evals) += tmp; } @@ -516,7 +517,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(47); - auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); + 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<47>(evals) += tmp; } @@ -524,7 +526,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(48); - auto tmp = (avm_main_sel_internal_return * avm_main_rwa); + auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); tmp *= scaling_factor; std::get<48>(evals) += tmp; } @@ -532,7 +534,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(49); - auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<49>(evals) += tmp; } @@ -540,16 +542,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(50); - 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_sel_op_cast)) * - (avm_main_pc_shift - (avm_main_pc + FF(1)))); + auto tmp = (avm_main_sel_internal_return * avm_main_rwa); tmp *= scaling_factor; std::get<50>(evals) += tmp; } @@ -557,10 +550,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(51); - 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_mem_op_a - FF(1))); tmp *= scaling_factor; std::get<51>(evals) += tmp; } @@ -568,7 +558,16 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(52); - auto tmp = (avm_main_sel_cmov * (((avm_main_id * avm_main_inv) - FF(1)) + avm_main_id_zero)); + 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_sel_op_cast)) * + (avm_main_pc_shift - (avm_main_pc + FF(1)))); tmp *= scaling_factor; std::get<52>(evals) += tmp; } @@ -576,7 +575,10 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(53); - auto tmp = ((avm_main_sel_cmov * avm_main_id_zero) * (-avm_main_inv + FF(1))); + 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<53>(evals) += tmp; } @@ -584,7 +586,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(54); - auto tmp = (avm_main_sel_mov_a - (avm_main_sel_mov + (avm_main_sel_cmov * (-avm_main_id_zero + FF(1))))); + auto tmp = (avm_main_sel_cmov * (((avm_main_id * avm_main_inv) - FF(1)) + avm_main_id_zero)); tmp *= scaling_factor; std::get<54>(evals) += tmp; } @@ -592,7 +594,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(55); - auto tmp = (avm_main_sel_mov_b - (avm_main_sel_cmov * avm_main_id_zero)); + auto tmp = ((avm_main_sel_cmov * avm_main_id_zero) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; std::get<55>(evals) += tmp; } @@ -600,7 +602,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(56); - auto tmp = (avm_main_sel_mov_a * (avm_main_ia - avm_main_ic)); + auto tmp = (avm_main_sel_mov_a - (avm_main_sel_mov + (avm_main_sel_cmov * (-avm_main_id_zero + FF(1))))); tmp *= scaling_factor; std::get<56>(evals) += tmp; } @@ -608,7 +610,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(57); - auto tmp = (avm_main_sel_mov_b * (avm_main_ib - avm_main_ic)); + auto tmp = (avm_main_sel_mov_b - (avm_main_sel_cmov * avm_main_id_zero)); tmp *= scaling_factor; std::get<57>(evals) += tmp; } @@ -616,7 +618,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(58); - auto tmp = ((avm_main_sel_mov + avm_main_sel_cmov) * (avm_main_r_in_tag - avm_main_w_in_tag)); + auto tmp = (avm_main_sel_mov_a * (avm_main_ia - avm_main_ic)); tmp *= scaling_factor; std::get<58>(evals) += tmp; } @@ -624,14 +626,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(59); - 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_sel_op_lt) + - avm_main_sel_op_lte) + - avm_main_sel_op_cast) * - (-avm_main_tag_err + FF(1)))); + auto tmp = (avm_main_sel_mov_b * (avm_main_ib - avm_main_ic)); tmp *= scaling_factor; std::get<59>(evals) += tmp; } @@ -639,11 +634,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(60); - auto tmp = (((((((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_sel_op_lt) + - avm_main_sel_op_lte) * - (avm_main_alu_in_tag - avm_main_r_in_tag)); + auto tmp = ((avm_main_sel_mov + avm_main_sel_cmov) * (avm_main_r_in_tag - avm_main_w_in_tag)); tmp *= scaling_factor; std::get<60>(evals) += tmp; } @@ -651,7 +642,16 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(61); - auto tmp = (avm_main_sel_op_cast * (avm_main_alu_in_tag - avm_main_w_in_tag)); + 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_sel_op_lt) + + avm_main_sel_op_lte) + + avm_main_sel_op_shr) + + avm_main_sel_op_shl) + + avm_main_sel_op_cast) * + (-avm_main_tag_err + FF(1)))); tmp *= scaling_factor; std::get<61>(evals) += tmp; } @@ -659,7 +659,14 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(62); - auto tmp = (avm_main_bin_op_id - (avm_main_sel_op_or + (avm_main_sel_op_xor * FF(2)))); + auto tmp = + (((((((((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_sel_op_lt) + + avm_main_sel_op_lte) + + avm_main_sel_op_shr) + + avm_main_sel_op_shl) * + (avm_main_alu_in_tag - avm_main_r_in_tag)); tmp *= scaling_factor; std::get<62>(evals) += tmp; } @@ -667,10 +674,26 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(63); - auto tmp = (avm_main_bin_sel - ((avm_main_sel_op_and + avm_main_sel_op_or) + avm_main_sel_op_xor)); + auto tmp = (avm_main_sel_op_cast * (avm_main_alu_in_tag - avm_main_w_in_tag)); tmp *= scaling_factor; std::get<63>(evals) += tmp; } + // Contribution 64 + { + Avm_DECLARE_VIEWS(64); + + auto tmp = (avm_main_bin_op_id - (avm_main_sel_op_or + (avm_main_sel_op_xor * FF(2)))); + tmp *= scaling_factor; + std::get<64>(evals) += tmp; + } + // Contribution 65 + { + Avm_DECLARE_VIEWS(65); + + 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<65>(evals) += tmp; + } } }; 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 e427a1bf7be..43acfc68dd1 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -29,6 +29,8 @@ [[maybe_unused]] auto avm_alu_op_lte = View(new_term.avm_alu_op_lte); \ [[maybe_unused]] auto avm_alu_op_mul = View(new_term.avm_alu_op_mul); \ [[maybe_unused]] auto avm_alu_op_not = View(new_term.avm_alu_op_not); \ + [[maybe_unused]] auto avm_alu_op_shl = View(new_term.avm_alu_op_shl); \ + [[maybe_unused]] auto avm_alu_op_shr = View(new_term.avm_alu_op_shr); \ [[maybe_unused]] auto avm_alu_op_sub = View(new_term.avm_alu_op_sub); \ [[maybe_unused]] auto avm_alu_p_a_borrow = View(new_term.avm_alu_p_a_borrow); \ [[maybe_unused]] auto avm_alu_p_b_borrow = View(new_term.avm_alu_p_b_borrow); \ @@ -40,6 +42,11 @@ [[maybe_unused]] auto avm_alu_res_lo = View(new_term.avm_alu_res_lo); \ [[maybe_unused]] auto avm_alu_rng_chk_lookup_selector = View(new_term.avm_alu_rng_chk_lookup_selector); \ [[maybe_unused]] auto avm_alu_rng_chk_sel = View(new_term.avm_alu_rng_chk_sel); \ + [[maybe_unused]] auto avm_alu_shift_lt_bit_len = View(new_term.avm_alu_shift_lt_bit_len); \ + [[maybe_unused]] auto avm_alu_shift_sel = View(new_term.avm_alu_shift_sel); \ + [[maybe_unused]] auto avm_alu_t_sub_s_bits = View(new_term.avm_alu_t_sub_s_bits); \ + [[maybe_unused]] auto avm_alu_two_pow_s = View(new_term.avm_alu_two_pow_s); \ + [[maybe_unused]] auto avm_alu_two_pow_t_sub_s = View(new_term.avm_alu_two_pow_t_sub_s); \ [[maybe_unused]] auto avm_alu_u128_tag = View(new_term.avm_alu_u128_tag); \ [[maybe_unused]] auto avm_alu_u16_r0 = View(new_term.avm_alu_u16_r0); \ [[maybe_unused]] auto avm_alu_u16_r1 = View(new_term.avm_alu_u16_r1); \ @@ -135,10 +142,13 @@ [[maybe_unused]] auto avm_main_sel_op_mul = View(new_term.avm_main_sel_op_mul); \ [[maybe_unused]] auto avm_main_sel_op_not = View(new_term.avm_main_sel_op_not); \ [[maybe_unused]] auto avm_main_sel_op_or = View(new_term.avm_main_sel_op_or); \ + [[maybe_unused]] auto avm_main_sel_op_shl = View(new_term.avm_main_sel_op_shl); \ + [[maybe_unused]] auto avm_main_sel_op_shr = View(new_term.avm_main_sel_op_shr); \ [[maybe_unused]] auto avm_main_sel_op_sub = View(new_term.avm_main_sel_op_sub); \ [[maybe_unused]] auto avm_main_sel_op_xor = View(new_term.avm_main_sel_op_xor); \ [[maybe_unused]] auto avm_main_sel_rng_16 = View(new_term.avm_main_sel_rng_16); \ [[maybe_unused]] auto avm_main_sel_rng_8 = View(new_term.avm_main_sel_rng_8); \ + [[maybe_unused]] auto avm_main_table_pow_2 = View(new_term.avm_main_table_pow_2); \ [[maybe_unused]] auto avm_main_tag_err = View(new_term.avm_main_tag_err); \ [[maybe_unused]] auto avm_main_w_in_tag = View(new_term.avm_main_w_in_tag); \ [[maybe_unused]] auto avm_mem_addr = View(new_term.avm_mem_addr); \ @@ -179,6 +189,8 @@ [[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_pow_2_0 = View(new_term.lookup_pow_2_0); \ + [[maybe_unused]] auto lookup_pow_2_1 = View(new_term.lookup_pow_2_1); \ [[maybe_unused]] auto lookup_u8_0 = View(new_term.lookup_u8_0); \ [[maybe_unused]] auto lookup_u8_1 = View(new_term.lookup_u8_1); \ [[maybe_unused]] auto lookup_u16_0 = View(new_term.lookup_u16_0); \ @@ -200,6 +212,8 @@ [[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 lookup_pow_2_0_counts = View(new_term.lookup_pow_2_0_counts); \ + [[maybe_unused]] auto lookup_pow_2_1_counts = View(new_term.lookup_pow_2_1_counts); \ [[maybe_unused]] auto lookup_u8_0_counts = View(new_term.lookup_u8_0_counts); \ [[maybe_unused]] auto lookup_u8_1_counts = View(new_term.lookup_u8_1_counts); \ [[maybe_unused]] auto lookup_u16_0_counts = View(new_term.lookup_u16_0_counts); \ @@ -228,6 +242,8 @@ [[maybe_unused]] auto avm_alu_op_cast_prev_shift = View(new_term.avm_alu_op_cast_prev_shift); \ [[maybe_unused]] auto avm_alu_op_cast_shift = View(new_term.avm_alu_op_cast_shift); \ [[maybe_unused]] auto avm_alu_op_mul_shift = View(new_term.avm_alu_op_mul_shift); \ + [[maybe_unused]] auto avm_alu_op_shl_shift = View(new_term.avm_alu_op_shl_shift); \ + [[maybe_unused]] auto avm_alu_op_shr_shift = View(new_term.avm_alu_op_shr_shift); \ [[maybe_unused]] auto avm_alu_op_sub_shift = View(new_term.avm_alu_op_sub_shift); \ [[maybe_unused]] auto avm_alu_p_sub_a_hi_shift = View(new_term.avm_alu_p_sub_a_hi_shift); \ [[maybe_unused]] auto avm_alu_p_sub_a_lo_shift = View(new_term.avm_alu_p_sub_a_lo_shift); \ diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_pow_2_0.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_pow_2_0.hpp new file mode 100644 index 00000000000..a4629615a75 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_pow_2_0.hpp @@ -0,0 +1,170 @@ + + +#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_pow_2_0_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 = 4; + + /** + * @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_alu_shift_sel == 1 || in.avm_main_sel_rng_8 == 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_alu_shift_sel); + const auto is_table_entry = View(in.avm_main_sel_rng_8); + 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_pow_2_0, + in.lookup_pow_2_0_counts, + in.avm_alu_shift_sel, + in.avm_main_sel_rng_8, + in.avm_alu_ib, + in.avm_alu_two_pow_s, + in.avm_main_clk, + in.avm_main_table_pow_2); + } + + /** + * @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_pow_2_0, + in.lookup_pow_2_0_counts, + in.avm_alu_shift_sel, + in.avm_main_sel_rng_8, + in.avm_alu_ib, + in.avm_alu_two_pow_s, + in.avm_main_clk, + in.avm_main_table_pow_2); + } +}; + +template using lookup_pow_2_0_relation = GenericLookupRelation; +template using lookup_pow_2_0 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_pow_2_1.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_pow_2_1.hpp new file mode 100644 index 00000000000..e1e7284056e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_pow_2_1.hpp @@ -0,0 +1,170 @@ + + +#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_pow_2_1_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 = 4; + + /** + * @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_alu_shift_sel == 1 || in.avm_main_sel_rng_8 == 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_alu_shift_sel); + const auto is_table_entry = View(in.avm_main_sel_rng_8); + 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_pow_2_1, + in.lookup_pow_2_1_counts, + in.avm_alu_shift_sel, + in.avm_main_sel_rng_8, + in.avm_alu_t_sub_s_bits, + in.avm_alu_two_pow_t_sub_s, + in.avm_main_clk, + in.avm_main_table_pow_2); + } + + /** + * @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_pow_2_1, + in.lookup_pow_2_1_counts, + in.avm_alu_shift_sel, + in.avm_main_sel_rng_8, + in.avm_alu_t_sub_s_bits, + in.avm_alu_two_pow_t_sub_s, + in.avm_main_clk, + in.avm_main_table_pow_2); + } +}; + +template using lookup_pow_2_1_relation = GenericLookupRelation; +template using lookup_pow_2_1 = 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 index d79a11acf7c..69ec55c1d2c 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp @@ -12,7 +12,7 @@ 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 = 13; + constexpr static size_t COLUMNS_PER_SET = 15; /** * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the @@ -62,6 +62,8 @@ class perm_main_alu_permutation_settings { in.avm_main_sel_op_cast, in.avm_main_sel_op_lt, in.avm_main_sel_op_lte, + in.avm_main_sel_op_shr, + in.avm_main_sel_op_shl, in.avm_main_alu_in_tag, in.avm_alu_clk, in.avm_alu_ia, @@ -75,6 +77,8 @@ class perm_main_alu_permutation_settings { in.avm_alu_op_cast, in.avm_alu_op_lt, in.avm_alu_op_lte, + in.avm_alu_op_shr, + in.avm_alu_op_shl, in.avm_alu_in_tag); } @@ -114,6 +118,8 @@ class perm_main_alu_permutation_settings { in.avm_main_sel_op_cast, in.avm_main_sel_op_lt, in.avm_main_sel_op_lte, + in.avm_main_sel_op_shr, + in.avm_main_sel_op_shl, in.avm_main_alu_in_tag, in.avm_alu_clk, in.avm_alu_ia, @@ -127,6 +133,8 @@ class perm_main_alu_permutation_settings { in.avm_alu_op_cast, in.avm_alu_op_lt, in.avm_alu_op_lte, + in.avm_alu_op_shr, + in.avm_alu_op_shl, in.avm_alu_in_tag); } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/pow_2_lookups.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/pow_2_lookups.hpp new file mode 100644 index 00000000000..b66844e7d06 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/pow_2_lookups.hpp @@ -0,0 +1,170 @@ + + +#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 pow_2_lookups_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 = 4; + + /** + * @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_alu_pow_2_sel == 1 || in.avm_main_sel_rng_8 == 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_alu_pow_2_sel); + const auto is_table_entry = View(in.avm_main_sel_rng_8); + 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.pow_2_lookups, + in.pow_2_lookups_counts, + in.avm_alu_pow_2_sel, + in.avm_main_sel_rng_8, + in.avm_alu_ib, + in.avm_alu_two_pow_b, + in.avm_main_clk, + in.avm_main_table_pow_2); + } + + /** + * @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.pow_2_lookups, + in.pow_2_lookups_counts, + in.avm_alu_pow_2_sel, + in.avm_main_sel_rng_8, + in.avm_alu_ib, + in.avm_alu_two_pow_b, + in.avm_main_clk, + in.avm_main_table_pow_2); + } +}; + +template using pow_2_lookups_relation = GenericLookupRelation; +template using pow_2_lookups = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.cpp index 9935a74b840..d7bea240603 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.cpp @@ -41,6 +41,18 @@ bool AvmAluTraceBuilder::is_range_check_required() const return range_checked_required; } +/** + * @brief Helper function that returns a boolean if this entry is an alu operation. + * This is helpful to filter out range check rows or the second row in the 128-bit multiply. + * + * @return A boolean telling whether range check is required. + */ +bool AvmAluTraceBuilder::is_alu_row_enabled(AvmAluTraceBuilder::AluTraceEntry const& r) +{ + return (r.alu_op_add || r.alu_op_sub || r.alu_op_mul || r.alu_op_eq || r.alu_op_not || r.alu_op_lt || + r.alu_op_lte || r.alu_op_shr || r.alu_op_shl || r.alu_op_cast); +} + /** * @brief Build Alu trace and compute the result of an addition of type defined by in_tag. * Besides the addition calculation, for the types u8, u16, u32, u64, and u128, we @@ -501,15 +513,15 @@ std::vector AvmAluTraceBuilder::cmp_range_che } /** - * Helper function to decompose a uint256_t into upper 128-bit and lower 128-bit tuple. + * Helper function to decompose a uint256_t into a b-lower bits and (256-b) upper bits * The outputs are cast to uint256_t so they are easier to use in checks */ -std::tuple decompose(uint256_t const& a) +std::tuple decompose(uint256_t const& a, uint8_t const b) { - uint256_t upper_bitmask = (uint256_t(1) << uint256_t(128)) - 1; + uint256_t upper_bitmask = (uint256_t(1) << uint256_t(b)) - 1; uint256_t a_lo = a & upper_bitmask; - uint256_t a_hi = a >> 128; + uint256_t a_hi = a >> b; return std::make_tuple(a_lo, a_hi); } @@ -518,8 +530,8 @@ std::tuple decompose(uint256_t const& a) std::tuple gt_witness(uint256_t const& a, uint256_t const& b) { uint256_t two_pow_128 = uint256_t(1) << uint256_t(128); - auto [a_lo, a_hi] = decompose(a); - auto [b_lo, b_hi] = decompose(b); + auto [a_lo, a_hi] = decompose(a, 128); + auto [b_lo, b_hi] = decompose(b, 128); bool borrow = a_lo <= b_lo; auto borrow_u256 = uint256_t(static_cast(borrow)); uint256_t r_lo = a_lo - b_lo - 1 + borrow_u256 * two_pow_128; @@ -533,8 +545,8 @@ std::tuple gt_witness(uint256_t const& a, uint256_t std::tuple gt_or_lte_witness(uint256_t const& a, uint256_t const& b) { uint256_t two_pow_128 = uint256_t(1) << uint256_t(128); - auto [a_lo, a_hi] = decompose(a); - auto [b_lo, b_hi] = decompose(b); + auto [a_lo, a_hi] = decompose(a, 128); + auto [b_lo, b_hi] = decompose(b, 128); bool isGT = a > b; if (isGT) { return gt_witness(a, b); @@ -566,9 +578,9 @@ FF AvmAluTraceBuilder::op_lt(FF const& a, FF const& b, AvmMemoryTag in_tag, uint // Note: This is counter-intuitive, to show that a < b we actually show that b > a // The subtlety is here that the circuit is designed as a GT(x,y) circuit, therefore we swap the inputs a & b // Get the decomposition of b - auto [a_lo, a_hi] = decompose(b); + auto [a_lo, a_hi] = decompose(b, 128); // Get the decomposition of a - auto [b_lo, b_hi] = decompose(a); + auto [b_lo, b_hi] = decompose(a, 128); // Get the decomposition of p - a and p - b **remember that we swap the inputs** // Note that a valid witness here is ONLY that p > a and p > b auto [p_sub_a_lo, p_sub_a_hi, p_a_borrow] = gt_witness(FF::modulus, b); @@ -620,9 +632,9 @@ FF AvmAluTraceBuilder::op_lte(FF const& a, FF const& b, AvmMemoryTag in_tag, uin bool c = uint256_t(a) <= uint256_t(b); // Get the decomposition of a - auto [a_lo, a_hi] = decompose(a); + auto [a_lo, a_hi] = decompose(a, 128); // Get the decomposition of b - auto [b_lo, b_hi] = decompose(b); + auto [b_lo, b_hi] = decompose(b, 128); // Get the decomposition of p - a and p - b // Note that a valid witness here is that p > a and p > b auto [p_sub_a_lo, p_sub_a_hi, p_a_borrow] = gt_witness(FF::modulus, a); @@ -694,7 +706,7 @@ FF AvmAluTraceBuilder::op_cast(FF const& a, AvmMemoryTag in_tag, uint32_t clk) } // Get the decomposition of a - auto [a_lo, a_hi] = decompose(uint256_t(a)); + auto [a_lo, a_hi] = decompose(uint256_t(a), 128); // Decomposition of p-a auto [p_sub_a_lo, p_sub_a_hi, p_a_borrow] = gt_witness(FF::modulus, uint256_t(a)); auto [u8_r0, u8_r1, u16_reg] = to_alu_slice_registers(uint256_t(a)); @@ -731,4 +743,219 @@ FF AvmAluTraceBuilder::op_cast(FF const& a, AvmMemoryTag in_tag, uint32_t clk) return c; } +// Returns the number of bits associated with a given memory tag +uint8_t mem_tag_bits(AvmMemoryTag in_tag) +{ + switch (in_tag) { + case AvmMemoryTag::U8: + return 8; + case AvmMemoryTag::U16: + return 16; + case AvmMemoryTag::U32: + return 32; + case AvmMemoryTag::U64: + return 64; + case AvmMemoryTag::U128: + return 128; + case AvmMemoryTag::FF: + return 254; + case AvmMemoryTag::U0: + return 0; + } + return 0; +} + +/** + * @brief Build Alu trace and compute the result of a SHR operation on two operands of type defined by in_tag. + * + * @param a Left operand of the SHR + * @param b Right operand of the SHR + * @param clk Clock referring to the operation in the main trace. + * @param in_tag Instruction tag defining the number of bits for the SHR. + * + * @return FF The boolean result of SHR casted to a finite field element + */ +FF AvmAluTraceBuilder::op_shr(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk) +{ + // Perform the shift operation over 256-bit integers + uint256_t a_u256{ a }; + // Check that the shifted amount is an 8-bit integer + ASSERT(uint256_t(b) < 256); + + uint8_t b_u8 = static_cast(uint256_t(b)); + uint256_t c_u256 = a_u256 >> b_u8; + + uint8_t num_bits = mem_tag_bits(in_tag); + u8_pow_2_counters[0][b_u8]++; + + // If we are shifting more than the number of bits, the result is trivially 0 + if (b_u8 >= num_bits) { + u8_pow_2_counters[1][b_u8 - num_bits]++; + // Even though the registers are trivially zero, we call this function to increment the lookup counters + [[maybe_unused]] auto [alu_u8_r0, alu_u8_r1, alu_u16_reg] = AvmAluTraceBuilder::to_alu_slice_registers(0); + alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ + .alu_clk = clk, + .alu_op_shr = true, + .alu_ff_tag = in_tag == AvmMemoryTag::FF, + .alu_u8_tag = in_tag == AvmMemoryTag::U8, + .alu_u16_tag = in_tag == AvmMemoryTag::U16, + .alu_u32_tag = in_tag == AvmMemoryTag::U32, + .alu_u64_tag = in_tag == AvmMemoryTag::U64, + .alu_u128_tag = in_tag == AvmMemoryTag::U128, + .alu_ia = a, + .alu_ib = FF(b_u8), + .alu_ic = 0, + .hi_lo_limbs = { 0, 0, 0, 0 }, + .mem_tag_bits = num_bits, + .mem_tag_sub_shift = static_cast(b_u8 - num_bits), + .shift_lt_bit_len = false, + }); + return 0; + } + // We decompose the input into two limbs partitioned at the b-th bit, we use x_lo and x_hi + // to avoid any confusion with the a_lo and a_hi that form part of the range check + auto [x_lo, x_hi] = decompose(a, b_u8); + // We can modify the dynamic range check by performing an additional static one + // rng_chk_lo = 2^b - x_lo - 1 && rng_chk_hi = 2^(num_bits - b) - x_hi - 1 + uint256_t rng_chk_lo = (uint256_t(1) << b_u8) - x_lo - 1; + uint256_t rng_chk_hi = (uint256_t(1) << (num_bits - b_u8)) - x_hi - 1; + + // Each hi and lo limb is range checked over 128bits + uint256_t limb = rng_chk_lo + (rng_chk_hi << uint256_t(128)); + // Load the range check values into the ALU registers + auto [alu_u8_r0, alu_u8_r1, alu_u16_reg] = AvmAluTraceBuilder::to_alu_slice_registers(limb); + + // Add counters for the pow of two lookups + u8_pow_2_counters[1][num_bits - b_u8]++; + + alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ + .alu_clk = clk, + .alu_op_shr = true, + .alu_u8_tag = in_tag == AvmMemoryTag::U8, + .alu_u16_tag = in_tag == AvmMemoryTag::U16, + .alu_u32_tag = in_tag == AvmMemoryTag::U32, + .alu_u64_tag = in_tag == AvmMemoryTag::U64, + .alu_u128_tag = in_tag == AvmMemoryTag::U128, + .alu_ia = a, + .alu_ib = b, + // Could be replaced with x_hi but nice to have 2 ways of calculating the result + .alu_ic = FF(c_u256), + .alu_u8_r0 = alu_u8_r0, + .alu_u8_r1 = alu_u8_r1, + .alu_u16_reg = alu_u16_reg, + .hi_lo_limbs{ rng_chk_lo, rng_chk_hi, x_lo, x_hi }, + .mem_tag_bits = num_bits, + .mem_tag_sub_shift = static_cast(num_bits - b_u8), + .shift_lt_bit_len = true, + + }); + return c_u256; +} + +/** + * @brief Build Alu trace and compute the result of a SHL operation on two operands of type defined by in_tag. + * + * @param a Left operand of the SHL + * @param b Right operand of the SHL + * @param clk Clock referring to the operation in the main trace. + * @param in_tag Instruction tag defining the number of bits for the SHL. + * + * @return FF The boolean result of SHL casted to a finite field element + */ +FF AvmAluTraceBuilder::op_shl(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk) +{ + // Perform the shift operation over 256-bit integers + uint256_t a_u256{ a }; + // Check that the shift amount is an 8-bit integer + ASSERT(uint256_t(b) < 256); + uint8_t b_u8 = static_cast(uint256_t(b)); + + uint256_t c_u256 = a_u256 << b_u8; + + uint8_t num_bits = mem_tag_bits(in_tag); + u8_pow_2_counters[0][b_u8]++; + // If we are shifting more than the number of bits, the result is trivially 0 + if (b_u8 >= num_bits) { + u8_pow_2_counters[1][b_u8 - num_bits]++; + // Even though the registers are trivially zero, we call this function to increment the lookup counters + [[maybe_unused]] auto [alu_u8_r0, alu_u8_r1, alu_u16_reg] = AvmAluTraceBuilder::to_alu_slice_registers(0); + alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ + .alu_clk = clk, + .alu_op_shl = true, + .alu_ff_tag = in_tag == AvmMemoryTag::FF, + .alu_u8_tag = in_tag == AvmMemoryTag::U8, + .alu_u16_tag = in_tag == AvmMemoryTag::U16, + .alu_u32_tag = in_tag == AvmMemoryTag::U32, + .alu_u64_tag = in_tag == AvmMemoryTag::U64, + .alu_u128_tag = in_tag == AvmMemoryTag::U128, + .alu_ia = a, + .alu_ib = FF(b_u8), + .alu_ic = 0, + .hi_lo_limbs = { 0, 0, 0, 0 }, + .mem_tag_bits = num_bits, + .mem_tag_sub_shift = static_cast(b_u8 - num_bits), + .shift_lt_bit_len = false, + }); + return 0; + } + // We decompose the input into two limbs partitioned at the b-th bit, we use x_lo and x_hi + // to avoid any confusion with the a_lo and a_hi that form part of the range check + auto [x_lo, x_hi] = decompose(a, num_bits - b_u8); + + u8_pow_2_counters[1][num_bits - b_u8]++; + // We can modify the dynamic range check by performing an additional static one + // rng_chk_lo = 2^(num_bits - b) - x_lo - 1 && rng_chk_hi = 2^b - x_hi - 1 + uint256_t rng_chk_lo = uint256_t(uint256_t(1) << (num_bits - b_u8)) - x_lo - 1; + uint256_t rng_chk_hi = uint256_t(uint256_t(1) << b_u8) - x_hi - 1; + + // Each hi and lo limb is range checked over 128bits + uint256_t limb = rng_chk_lo + (rng_chk_hi << 128); + // Load the range check values into the ALU registers + auto [alu_u8_r0, alu_u8_r1, alu_u16_reg] = AvmAluTraceBuilder::to_alu_slice_registers(limb); + + FF c = 0; + switch (in_tag) { + case AvmMemoryTag::U8: + c = FF{ uint8_t(c_u256) }; + break; + case AvmMemoryTag::U16: + c = FF{ uint16_t(c_u256) }; + break; + case AvmMemoryTag::U32: + c = FF{ uint32_t(c_u256) }; + break; + case AvmMemoryTag::U64: + c = FF{ uint64_t(c_u256) }; + break; + case AvmMemoryTag::U128: + c = FF{ uint256_t::from_uint128(uint128_t(c_u256)) }; + break; + // Unsupported instruction tags + case AvmMemoryTag::U0: + case AvmMemoryTag::FF: + return 0; + } + + alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ + .alu_clk = clk, + .alu_op_shl = true, + .alu_ff_tag = in_tag == AvmMemoryTag::FF, + .alu_u8_tag = in_tag == AvmMemoryTag::U8, + .alu_u16_tag = in_tag == AvmMemoryTag::U16, + .alu_u32_tag = in_tag == AvmMemoryTag::U32, + .alu_u64_tag = in_tag == AvmMemoryTag::U64, + .alu_u128_tag = in_tag == AvmMemoryTag::U128, + .alu_ia = a, + .alu_ib = b, + .alu_ic = c, + .alu_u8_r0 = alu_u8_r0, + .alu_u8_r1 = alu_u8_r1, + .alu_u16_reg = alu_u16_reg, + .hi_lo_limbs{ rng_chk_lo, rng_chk_hi, x_lo, x_hi }, + .mem_tag_bits = num_bits, + .mem_tag_sub_shift = static_cast(num_bits - b_u8), + .shift_lt_bit_len = true, + }); + return c; +} } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.hpp index 7920aabd28e..e01e8e53b4b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.hpp @@ -19,6 +19,8 @@ class AvmAluTraceBuilder { bool alu_op_lte = false; bool alu_op_cast = false; bool alu_op_cast_prev = false; + bool alu_op_shr = false; + bool alu_op_shl = false; bool alu_ff_tag = false; bool alu_u8_tag = false; @@ -48,9 +50,15 @@ class AvmAluTraceBuilder { bool p_b_borrow = false; uint8_t cmp_rng_ctr = 0; bool rng_chk_sel = false; + + // Shift Operations + uint8_t mem_tag_bits = 0; + uint8_t mem_tag_sub_shift = 0; + bool shift_lt_bit_len = true; }; std::array, 2> u8_range_chk_counters; + std::array, 2> u8_pow_2_counters; std::array, 15> u16_range_chk_counters; AvmAluTraceBuilder(); @@ -65,8 +73,11 @@ class AvmAluTraceBuilder { FF op_lt(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); FF op_lte(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); FF op_cast(FF const& a, AvmMemoryTag in_tag, uint32_t clk); + FF op_shr(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); + FF op_shl(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); bool is_range_check_required() const; + static bool is_alu_row_enabled(AvmAluTraceBuilder::AluTraceEntry const& r); private: std::vector alu_trace; 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 9b9c4bd7b3e..bce4188712d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp @@ -35,6 +35,8 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = { OpCode::AND, three_operand_format }, { OpCode::OR, three_operand_format }, { OpCode::XOR, three_operand_format }, + { OpCode::SHR, three_operand_format }, + { OpCode::SHL, three_operand_format }, // Compute - Type Conversions { OpCode::CAST, { OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32 } }, // Execution Environment - Calldata 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 e25d9ad1807..85c5ed9ebea 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -180,6 +180,20 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; + case OpCode::SHR: + trace_builder.op_shr(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::SHL: + trace_builder.op_shl(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; // Compute - Type Conversions case OpCode::CAST: trace_builder.op_cast(std::get(inst.operands.at(0)), 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 71bc1b292ae..08691c39e83 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp @@ -11,77 +11,79 @@ namespace bb::avm_trace { */ void log_avm_trace(std::vector const& trace, size_t beg, size_t end, bool enable_selectors) { - info("Built circuit with ", trace.size(), " rows"); + { + info("Built circuit with ", trace.size(), " rows"); - for (size_t i = beg; i < end; i++) { - info("====================================================================================="); - info("== ROW ", i); - info("====================================================================================="); + for (size_t i = beg; i < end; i++) { + info("====================================================================================="); + info("== ROW ", i); + info("====================================================================================="); - info("=======MEMORY TRACE=================================================================="); - info("m_addr: ", trace.at(i).avm_mem_addr); - info("m_clk: ", trace.at(i).avm_mem_clk); - info("m_sub_clk: ", trace.at(i).avm_mem_sub_clk); - info("m_val: ", trace.at(i).avm_mem_val); - info("m_rw: ", trace.at(i).avm_mem_rw); - info("m_tag: ", trace.at(i).avm_mem_tag); - info("r_in_tag: ", trace.at(i).avm_mem_r_in_tag); - info("w_in_tag: ", trace.at(i).avm_mem_w_in_tag); - info("m_tag_err: ", trace.at(i).avm_mem_tag_err); - info("m_one_min_inv: ", trace.at(i).avm_mem_one_min_inv); + info("=======MEMORY TRACE=================================================================="); + info("m_addr: ", trace.at(i).avm_mem_addr); + info("m_clk: ", trace.at(i).avm_mem_clk); + info("m_sub_clk: ", trace.at(i).avm_mem_sub_clk); + info("m_val: ", trace.at(i).avm_mem_val); + info("m_rw: ", trace.at(i).avm_mem_rw); + info("m_tag: ", trace.at(i).avm_mem_tag); + info("r_in_tag: ", trace.at(i).avm_mem_r_in_tag); + info("w_in_tag: ", trace.at(i).avm_mem_w_in_tag); + info("m_tag_err: ", trace.at(i).avm_mem_tag_err); + info("m_one_min_inv: ", trace.at(i).avm_mem_one_min_inv); - info("m_lastAccess: ", trace.at(i).avm_mem_lastAccess); - info("m_last: ", trace.at(i).avm_mem_last); - info("m_val_shift: ", trace.at(i).avm_mem_val_shift); + info("m_lastAccess: ", trace.at(i).avm_mem_lastAccess); + info("m_last: ", trace.at(i).avm_mem_last); + info("m_val_shift: ", trace.at(i).avm_mem_val_shift); - info("=======CONTROL_FLOW==================================================================="); - info("pc: ", trace.at(i).avm_main_pc); - info("internal_call: ", trace.at(i).avm_main_sel_internal_call); - info("internal_return: ", trace.at(i).avm_main_sel_internal_return); - info("internal_return_ptr:", trace.at(i).avm_main_internal_return_ptr); + info("=======CONTROL_FLOW==================================================================="); + info("pc: ", trace.at(i).avm_main_pc); + info("internal_call: ", trace.at(i).avm_main_sel_internal_call); + info("internal_return: ", trace.at(i).avm_main_sel_internal_return); + info("internal_return_ptr:", trace.at(i).avm_main_internal_return_ptr); - info("=======ALU TRACE====================================================================="); - info("alu_clk ", trace.at(i).avm_alu_clk); - info("alu_ia ", trace.at(i).avm_alu_ia); - info("alu_ib ", trace.at(i).avm_alu_ib); - info("alu_ic ", trace.at(i).avm_alu_ic); + info("=======ALU TRACE====================================================================="); + info("alu_clk ", trace.at(i).avm_alu_clk); + info("alu_ia ", trace.at(i).avm_alu_ia); + info("alu_ib ", trace.at(i).avm_alu_ib); + info("alu_ic ", trace.at(i).avm_alu_ic); - info("=======MAIN TRACE===================================================================="); - info("clk: ", trace.at(i).avm_main_clk); - info("ia: ", trace.at(i).avm_main_ia); - info("ib: ", trace.at(i).avm_main_ib); - info("ic: ", trace.at(i).avm_main_ic); - info("r_in_tag ", trace.at(i).avm_main_r_in_tag); - info("w_in_tag ", trace.at(i).avm_main_w_in_tag); - info("tag_err ", trace.at(i).avm_main_tag_err); - info("first: ", trace.at(i).avm_main_first); - info("last: ", trace.at(i).avm_main_last); + info("=======MAIN TRACE===================================================================="); + info("clk: ", trace.at(i).avm_main_clk); + info("ia: ", trace.at(i).avm_main_ia); + info("ib: ", trace.at(i).avm_main_ib); + info("ic: ", trace.at(i).avm_main_ic); + info("r_in_tag ", trace.at(i).avm_main_r_in_tag); + info("w_in_tag ", trace.at(i).avm_main_w_in_tag); + info("tag_err ", trace.at(i).avm_main_tag_err); + info("first: ", trace.at(i).avm_main_first); + info("last: ", trace.at(i).avm_main_last); - info("=======MEM_OP_A======================================================================"); - info("mem_op_a: ", trace.at(i).avm_main_mem_op_a); - info("mem_idx_a: ", trace.at(i).avm_main_mem_idx_a); - info("rwa: ", trace.at(i).avm_main_rwa); + info("=======MEM_OP_A======================================================================"); + info("mem_op_a: ", trace.at(i).avm_main_mem_op_a); + info("mem_idx_a: ", trace.at(i).avm_main_mem_idx_a); + info("rwa: ", trace.at(i).avm_main_rwa); - info("=======MEM_OP_B======================================================================"); - info("mem_op_b: ", trace.at(i).avm_main_mem_op_b); - info("mem_idx_b: ", trace.at(i).avm_main_mem_idx_b); - info("rwb: ", trace.at(i).avm_main_rwb); + info("=======MEM_OP_B======================================================================"); + info("mem_op_b: ", trace.at(i).avm_main_mem_op_b); + info("mem_idx_b: ", trace.at(i).avm_main_mem_idx_b); + info("rwb: ", trace.at(i).avm_main_rwb); - info("=======MEM_OP_C======================================================================"); - info("mem_op_c: ", trace.at(i).avm_main_mem_op_c); - info("mem_idx_c: ", trace.at(i).avm_main_mem_idx_c); - info("rwc: ", trace.at(i).avm_main_rwc); + info("=======MEM_OP_C======================================================================"); + info("mem_op_c: ", trace.at(i).avm_main_mem_op_c); + info("mem_idx_c: ", trace.at(i).avm_main_mem_idx_c); + info("rwc: ", trace.at(i).avm_main_rwc); - if (enable_selectors) { - info("=======SELECTORS======================================================================"); - info("sel_op_add: ", trace.at(i).avm_main_sel_op_add); - info("sel_op_sub: ", trace.at(i).avm_main_sel_op_sub); - info("sel_op_mul: ", trace.at(i).avm_main_sel_op_mul); - info("sel_op_eq: ", trace.at(i).avm_main_sel_op_eq); - info("sel_op_not: ", trace.at(i).avm_main_sel_op_not); - info("sel_op_sel_alu: ", trace.at(i).avm_main_alu_sel); + if (enable_selectors) { + info("=======SELECTORS======================================================================"); + info("sel_op_add: ", trace.at(i).avm_main_sel_op_add); + info("sel_op_sub: ", trace.at(i).avm_main_sel_op_sub); + info("sel_op_mul: ", trace.at(i).avm_main_sel_op_mul); + info("sel_op_eq: ", trace.at(i).avm_main_sel_op_eq); + 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"); } - 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 9a449eb43e8..8b92cfbeddc 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -735,6 +735,109 @@ void AvmTraceBuilder::op_lte( }); } +void AvmTraceBuilder::op_shr( + 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, res.direct_a_offset, in_tag, in_tag); + auto read_b = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag, in_tag); + tag_match = read_a.tag_match && read_b.tag_match; + + FF a = tag_match ? read_a.val : FF(0); + FF b = tag_match ? read_b.val : FF(0); + + FF c = tag_match ? alu_trace_builder.op_shr(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, res.direct_c_offset, c, in_tag, in_tag); + + main_trace.push_back(Row{ + .avm_main_clk = clk, + .avm_main_alu_in_tag = FF(static_cast(in_tag)), + .avm_main_ia = a, + .avm_main_ib = b, + .avm_main_ic = c, + .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_internal_return_ptr = FF(internal_return_ptr), + .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_c_offset), + .avm_main_mem_op_a = FF(1), + .avm_main_mem_op_b = FF(1), + .avm_main_mem_op_c = FF(1), + .avm_main_pc = FF(pc++), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_rwc = FF(1), + .avm_main_sel_op_shr = FF(1), + .avm_main_tag_err = FF(static_cast(!tag_match)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), + }); +} + +void AvmTraceBuilder::op_shl( + 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, res.direct_a_offset, in_tag, in_tag); + auto read_b = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag, in_tag); + tag_match = read_a.tag_match && read_b.tag_match; + + FF a = tag_match ? read_a.val : FF(0); + FF b = tag_match ? read_b.val : FF(0); + + FF c = tag_match ? alu_trace_builder.op_shl(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, res.direct_c_offset, c, in_tag, in_tag); + + main_trace.push_back(Row{ + .avm_main_clk = clk, + .avm_main_alu_in_tag = FF(static_cast(in_tag)), + .avm_main_ia = a, + .avm_main_ib = b, + .avm_main_ic = c, + .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_internal_return_ptr = FF(internal_return_ptr), + .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_c_offset), + .avm_main_mem_op_a = FF(1), + .avm_main_mem_op_b = FF(1), + .avm_main_mem_op_c = FF(1), + .avm_main_pc = FF(pc++), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_rwc = FF(1), + .avm_main_sel_op_shl = FF(1), + .avm_main_tag_err = FF(static_cast(!tag_match)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), + }); +} // TODO: Ensure that the bytecode validation and/or deserialization is // enforcing that val complies to the tag. /** @@ -1519,6 +1622,8 @@ std::vector AvmTraceBuilder::finalize() dest.avm_alu_op_cast_prev = FF(static_cast(src.alu_op_cast_prev)); dest.avm_alu_cmp_sel = FF(static_cast(src.alu_op_lt) + static_cast(src.alu_op_lte)); dest.avm_alu_rng_chk_sel = FF(static_cast(src.rng_chk_sel)); + dest.avm_alu_op_shr = FF(static_cast(src.alu_op_shr)); + dest.avm_alu_op_shl = FF(static_cast(src.alu_op_shl)); dest.avm_alu_ff_tag = FF(static_cast(src.alu_ff_tag)); dest.avm_alu_u8_tag = FF(static_cast(src.alu_u8_tag)); @@ -1560,9 +1665,7 @@ std::vector AvmTraceBuilder::finalize() // Not all rows in ALU are enabled with a selector. For instance, // multiplication over u128 is taking two lines. - if (dest.avm_alu_op_add == FF(1) || dest.avm_alu_op_sub == FF(1) || dest.avm_alu_op_mul == FF(1) || - dest.avm_alu_op_eq == FF(1) || dest.avm_alu_op_not == FF(1) || dest.avm_alu_op_lt == FF(1) || - dest.avm_alu_op_lte == FF(1) || dest.avm_alu_op_cast == FF(1)) { + if (AvmAluTraceBuilder::is_alu_row_enabled(src)) { dest.avm_alu_alu_sel = FF(1); } @@ -1607,14 +1710,27 @@ std::vector AvmTraceBuilder::finalize() if (dest.avm_alu_op_mul == FF(1) && dest.avm_alu_u128_tag) { main_trace.at(i + 1).avm_alu_rng_chk_lookup_selector = FF(1); } + if (src.alu_op_shr || src.alu_op_shl) { + dest.avm_alu_a_lo = FF(src.hi_lo_limbs[0]); + dest.avm_alu_a_hi = FF(src.hi_lo_limbs[1]); + dest.avm_alu_b_lo = FF(src.hi_lo_limbs[2]); + dest.avm_alu_b_hi = FF(src.hi_lo_limbs[3]); + dest.avm_alu_shift_sel = FF(1); + dest.avm_alu_shift_lt_bit_len = FF(static_cast(src.shift_lt_bit_len)); + dest.avm_alu_t_sub_s_bits = FF(src.mem_tag_sub_shift); + dest.avm_alu_two_pow_s = FF(uint256_t(1) << dest.avm_alu_ib); + dest.avm_alu_two_pow_t_sub_s = FF(uint256_t(1) << uint256_t(dest.avm_alu_t_sub_s_bits)); + dest.avm_alu_rng_chk_lookup_selector = FF(1); + } } for (size_t i = 0; i < main_trace_size; i++) { auto& r = main_trace.at(i); if ((r.avm_main_sel_op_add == FF(1) || r.avm_main_sel_op_sub == FF(1) || r.avm_main_sel_op_mul == FF(1) || - r.avm_main_sel_op_eq == FF(1) || r.avm_main_sel_op_not == FF(1) || r.avm_main_sel_op_lt || - r.avm_main_sel_op_lte || r.avm_main_sel_op_cast == FF(1)) && + r.avm_main_sel_op_eq == FF(1) || r.avm_main_sel_op_not == FF(1) || r.avm_main_sel_op_lt == FF(1) || + r.avm_main_sel_op_lte == FF(1) || r.avm_main_sel_op_cast == FF(1) || r.avm_main_sel_op_shr == FF(1) || + r.avm_main_sel_op_shl == FF(1)) && r.avm_main_tag_err == FF(0)) { r.avm_main_alu_sel = FF(1); } @@ -1622,7 +1738,10 @@ std::vector AvmTraceBuilder::finalize() if (i <= UINT8_MAX) { r.lookup_u8_0_counts = alu_trace_builder.u8_range_chk_counters[0][static_cast(i)]; r.lookup_u8_1_counts = alu_trace_builder.u8_range_chk_counters[1][static_cast(i)]; + r.lookup_pow_2_0_counts = alu_trace_builder.u8_pow_2_counters[0][static_cast(i)]; + r.lookup_pow_2_1_counts = alu_trace_builder.u8_pow_2_counters[1][static_cast(i)]; r.avm_main_sel_rng_8 = FF(1); + r.avm_main_table_pow_2 = uint256_t(1) << uint256_t(i); } if (i <= UINT16_MAX) { 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 71b1aabe368..059d2fdd6c9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -62,6 +62,12 @@ class AvmTraceBuilder { // Less Than or Equal to with direct or indirect memory access. void op_lte(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Shift Right with direct or indirect memory access. + void op_shr(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + + // Shift Left with direct or indirect memory access. + void op_shl(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 or indirect memory access. void op_set(uint8_t indirect, uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag); 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 4bfaa9fa499..d43ce2b914b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -19,6 +19,8 @@ #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/lookup_pow_2_0.hpp" +#include "barretenberg/relations/generated/avm/lookup_pow_2_1.hpp" #include "barretenberg/relations/generated/avm/lookup_u16_0.hpp" #include "barretenberg/relations/generated/avm/lookup_u16_1.hpp" #include "barretenberg/relations/generated/avm/lookup_u16_10.hpp" @@ -78,6 +80,8 @@ template struct AvmFullRow { FF avm_alu_op_lte{}; FF avm_alu_op_mul{}; FF avm_alu_op_not{}; + FF avm_alu_op_shl{}; + FF avm_alu_op_shr{}; FF avm_alu_op_sub{}; FF avm_alu_p_a_borrow{}; FF avm_alu_p_b_borrow{}; @@ -89,6 +93,11 @@ template struct AvmFullRow { FF avm_alu_res_lo{}; FF avm_alu_rng_chk_lookup_selector{}; FF avm_alu_rng_chk_sel{}; + FF avm_alu_shift_lt_bit_len{}; + FF avm_alu_shift_sel{}; + FF avm_alu_t_sub_s_bits{}; + FF avm_alu_two_pow_s{}; + FF avm_alu_two_pow_t_sub_s{}; FF avm_alu_u128_tag{}; FF avm_alu_u16_r0{}; FF avm_alu_u16_r1{}; @@ -184,10 +193,13 @@ template struct AvmFullRow { FF avm_main_sel_op_mul{}; FF avm_main_sel_op_not{}; FF avm_main_sel_op_or{}; + FF avm_main_sel_op_shl{}; + FF avm_main_sel_op_shr{}; FF avm_main_sel_op_sub{}; FF avm_main_sel_op_xor{}; FF avm_main_sel_rng_16{}; FF avm_main_sel_rng_8{}; + FF avm_main_table_pow_2{}; FF avm_main_tag_err{}; FF avm_main_w_in_tag{}; FF avm_mem_addr{}; @@ -228,6 +240,8 @@ template struct AvmFullRow { FF lookup_byte_operations{}; FF incl_main_tag_err{}; FF incl_mem_tag_err{}; + FF lookup_pow_2_0{}; + FF lookup_pow_2_1{}; FF lookup_u8_0{}; FF lookup_u8_1{}; FF lookup_u16_0{}; @@ -249,6 +263,8 @@ template struct AvmFullRow { FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; + FF lookup_pow_2_0_counts{}; + FF lookup_pow_2_1_counts{}; FF lookup_u8_0_counts{}; FF lookup_u8_1_counts{}; FF lookup_u16_0_counts{}; @@ -277,6 +293,8 @@ template struct AvmFullRow { FF avm_alu_op_cast_prev_shift{}; FF avm_alu_op_cast_shift{}; FF avm_alu_op_mul_shift{}; + FF avm_alu_op_shl_shift{}; + FF avm_alu_op_shr_shift{}; FF avm_alu_op_sub_shift{}; FF avm_alu_p_sub_a_hi_shift{}; FF avm_alu_p_sub_a_lo_shift{}; @@ -316,8 +334,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 253; - static constexpr size_t num_polys = 215; + static constexpr size_t num_fixed_columns = 269; + static constexpr size_t num_polys = 229; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -360,6 +378,8 @@ class AvmCircuitBuilder { polys.avm_alu_op_lte[i] = rows[i].avm_alu_op_lte; polys.avm_alu_op_mul[i] = rows[i].avm_alu_op_mul; polys.avm_alu_op_not[i] = rows[i].avm_alu_op_not; + polys.avm_alu_op_shl[i] = rows[i].avm_alu_op_shl; + polys.avm_alu_op_shr[i] = rows[i].avm_alu_op_shr; polys.avm_alu_op_sub[i] = rows[i].avm_alu_op_sub; polys.avm_alu_p_a_borrow[i] = rows[i].avm_alu_p_a_borrow; polys.avm_alu_p_b_borrow[i] = rows[i].avm_alu_p_b_borrow; @@ -371,6 +391,11 @@ class AvmCircuitBuilder { polys.avm_alu_res_lo[i] = rows[i].avm_alu_res_lo; polys.avm_alu_rng_chk_lookup_selector[i] = rows[i].avm_alu_rng_chk_lookup_selector; polys.avm_alu_rng_chk_sel[i] = rows[i].avm_alu_rng_chk_sel; + polys.avm_alu_shift_lt_bit_len[i] = rows[i].avm_alu_shift_lt_bit_len; + polys.avm_alu_shift_sel[i] = rows[i].avm_alu_shift_sel; + polys.avm_alu_t_sub_s_bits[i] = rows[i].avm_alu_t_sub_s_bits; + polys.avm_alu_two_pow_s[i] = rows[i].avm_alu_two_pow_s; + polys.avm_alu_two_pow_t_sub_s[i] = rows[i].avm_alu_two_pow_t_sub_s; polys.avm_alu_u128_tag[i] = rows[i].avm_alu_u128_tag; polys.avm_alu_u16_r0[i] = rows[i].avm_alu_u16_r0; polys.avm_alu_u16_r1[i] = rows[i].avm_alu_u16_r1; @@ -466,10 +491,13 @@ class AvmCircuitBuilder { polys.avm_main_sel_op_mul[i] = rows[i].avm_main_sel_op_mul; polys.avm_main_sel_op_not[i] = rows[i].avm_main_sel_op_not; polys.avm_main_sel_op_or[i] = rows[i].avm_main_sel_op_or; + polys.avm_main_sel_op_shl[i] = rows[i].avm_main_sel_op_shl; + polys.avm_main_sel_op_shr[i] = rows[i].avm_main_sel_op_shr; polys.avm_main_sel_op_sub[i] = rows[i].avm_main_sel_op_sub; polys.avm_main_sel_op_xor[i] = rows[i].avm_main_sel_op_xor; polys.avm_main_sel_rng_16[i] = rows[i].avm_main_sel_rng_16; polys.avm_main_sel_rng_8[i] = rows[i].avm_main_sel_rng_8; + polys.avm_main_table_pow_2[i] = rows[i].avm_main_table_pow_2; polys.avm_main_tag_err[i] = rows[i].avm_main_tag_err; polys.avm_main_w_in_tag[i] = rows[i].avm_main_w_in_tag; polys.avm_mem_addr[i] = rows[i].avm_mem_addr; @@ -500,6 +528,8 @@ class AvmCircuitBuilder { 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.lookup_pow_2_0_counts[i] = rows[i].lookup_pow_2_0_counts; + polys.lookup_pow_2_1_counts[i] = rows[i].lookup_pow_2_1_counts; polys.lookup_u8_0_counts[i] = rows[i].lookup_u8_0_counts; polys.lookup_u8_1_counts[i] = rows[i].lookup_u8_1_counts; polys.lookup_u16_0_counts[i] = rows[i].lookup_u16_0_counts; @@ -530,6 +560,8 @@ class AvmCircuitBuilder { polys.avm_alu_op_cast_prev_shift = Polynomial(polys.avm_alu_op_cast_prev.shifted()); polys.avm_alu_op_cast_shift = Polynomial(polys.avm_alu_op_cast.shifted()); polys.avm_alu_op_mul_shift = Polynomial(polys.avm_alu_op_mul.shifted()); + polys.avm_alu_op_shl_shift = Polynomial(polys.avm_alu_op_shl.shifted()); + polys.avm_alu_op_shr_shift = Polynomial(polys.avm_alu_op_shr.shifted()); polys.avm_alu_op_sub_shift = Polynomial(polys.avm_alu_op_sub.shifted()); polys.avm_alu_p_sub_a_hi_shift = Polynomial(polys.avm_alu_p_sub_a_hi.shifted()); polys.avm_alu_p_sub_a_lo_shift = Polynomial(polys.avm_alu_p_sub_a_lo.shifted()); @@ -688,6 +720,12 @@ class AvmCircuitBuilder { if (!evaluate_logderivative.template operator()>("INCL_MEM_TAG_ERR")) { return false; } + if (!evaluate_logderivative.template operator()>("LOOKUP_POW_2_0")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_POW_2_1")) { + return false; + } if (!evaluate_logderivative.template operator()>("LOOKUP_U8_0")) { 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 bcdaabdbd6c..bad383523e2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -21,6 +21,8 @@ #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/lookup_pow_2_0.hpp" +#include "barretenberg/relations/generated/avm/lookup_pow_2_1.hpp" #include "barretenberg/relations/generated/avm/lookup_u16_0.hpp" #include "barretenberg/relations/generated/avm/lookup_u16_1.hpp" #include "barretenberg/relations/generated/avm/lookup_u16_10.hpp" @@ -69,11 +71,11 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 213; + static constexpr size_t NUM_WITNESS_ENTITIES = 227; 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 = 253; + static constexpr size_t NUM_ALL_ENTITIES = 269; using GrandProductRelations = std::tuple, perm_main_bin_relation, @@ -89,6 +91,8 @@ class AvmFlavor { lookup_byte_operations_relation, incl_main_tag_err_relation, incl_mem_tag_err_relation, + lookup_pow_2_0_relation, + lookup_pow_2_1_relation, lookup_u8_0_relation, lookup_u8_1_relation, lookup_u16_0_relation, @@ -125,6 +129,8 @@ class AvmFlavor { lookup_byte_operations_relation, incl_main_tag_err_relation, incl_mem_tag_err_relation, + lookup_pow_2_0_relation, + lookup_pow_2_1_relation, lookup_u8_0_relation, lookup_u8_1_relation, lookup_u16_0_relation, @@ -200,6 +206,8 @@ class AvmFlavor { avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, + avm_alu_op_shl, + avm_alu_op_shr, avm_alu_op_sub, avm_alu_p_a_borrow, avm_alu_p_b_borrow, @@ -211,6 +219,11 @@ class AvmFlavor { avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, avm_alu_rng_chk_sel, + avm_alu_shift_lt_bit_len, + avm_alu_shift_sel, + avm_alu_t_sub_s_bits, + avm_alu_two_pow_s, + avm_alu_two_pow_t_sub_s, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -306,10 +319,13 @@ class AvmFlavor { avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, + avm_main_sel_op_shl, + avm_main_sel_op_shr, avm_main_sel_op_sub, avm_main_sel_op_xor, avm_main_sel_rng_16, avm_main_sel_rng_8, + avm_main_table_pow_2, avm_main_tag_err, avm_main_w_in_tag, avm_mem_addr, @@ -350,6 +366,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_pow_2_0, + lookup_pow_2_1, lookup_u8_0, lookup_u8_1, lookup_u16_0, @@ -371,6 +389,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_pow_2_0_counts, + lookup_pow_2_1_counts, lookup_u8_0_counts, lookup_u8_1_counts, lookup_u16_0_counts, @@ -416,6 +436,8 @@ class AvmFlavor { avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, + avm_alu_op_shl, + avm_alu_op_shr, avm_alu_op_sub, avm_alu_p_a_borrow, avm_alu_p_b_borrow, @@ -427,6 +449,11 @@ class AvmFlavor { avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, avm_alu_rng_chk_sel, + avm_alu_shift_lt_bit_len, + avm_alu_shift_sel, + avm_alu_t_sub_s_bits, + avm_alu_two_pow_s, + avm_alu_two_pow_t_sub_s, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -522,10 +549,13 @@ class AvmFlavor { avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, + avm_main_sel_op_shl, + avm_main_sel_op_shr, avm_main_sel_op_sub, avm_main_sel_op_xor, avm_main_sel_rng_16, avm_main_sel_rng_8, + avm_main_table_pow_2, avm_main_tag_err, avm_main_w_in_tag, avm_mem_addr, @@ -566,6 +596,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_pow_2_0, + lookup_pow_2_1, lookup_u8_0, lookup_u8_1, lookup_u16_0, @@ -587,6 +619,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_pow_2_0_counts, + lookup_pow_2_1_counts, lookup_u8_0_counts, lookup_u8_1_counts, lookup_u16_0_counts, @@ -637,6 +671,8 @@ class AvmFlavor { avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, + avm_alu_op_shl, + avm_alu_op_shr, avm_alu_op_sub, avm_alu_p_a_borrow, avm_alu_p_b_borrow, @@ -648,6 +684,11 @@ class AvmFlavor { avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, avm_alu_rng_chk_sel, + avm_alu_shift_lt_bit_len, + avm_alu_shift_sel, + avm_alu_t_sub_s_bits, + avm_alu_two_pow_s, + avm_alu_two_pow_t_sub_s, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -743,10 +784,13 @@ class AvmFlavor { avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, + avm_main_sel_op_shl, + avm_main_sel_op_shr, avm_main_sel_op_sub, avm_main_sel_op_xor, avm_main_sel_rng_16, avm_main_sel_rng_8, + avm_main_table_pow_2, avm_main_tag_err, avm_main_w_in_tag, avm_mem_addr, @@ -787,6 +831,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_pow_2_0, + lookup_pow_2_1, lookup_u8_0, lookup_u8_1, lookup_u16_0, @@ -808,6 +854,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_pow_2_0_counts, + lookup_pow_2_1_counts, lookup_u8_0_counts, lookup_u8_1_counts, lookup_u16_0_counts, @@ -836,6 +884,8 @@ class AvmFlavor { avm_alu_op_cast_prev_shift, avm_alu_op_cast_shift, avm_alu_op_mul_shift, + avm_alu_op_shl_shift, + avm_alu_op_shr_shift, avm_alu_op_sub_shift, avm_alu_p_sub_a_hi_shift, avm_alu_p_sub_a_lo_shift, @@ -893,6 +943,8 @@ class AvmFlavor { avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, + avm_alu_op_shl, + avm_alu_op_shr, avm_alu_op_sub, avm_alu_p_a_borrow, avm_alu_p_b_borrow, @@ -904,6 +956,11 @@ class AvmFlavor { avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, avm_alu_rng_chk_sel, + avm_alu_shift_lt_bit_len, + avm_alu_shift_sel, + avm_alu_t_sub_s_bits, + avm_alu_two_pow_s, + avm_alu_two_pow_t_sub_s, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -999,10 +1056,13 @@ class AvmFlavor { avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, + avm_main_sel_op_shl, + avm_main_sel_op_shr, avm_main_sel_op_sub, avm_main_sel_op_xor, avm_main_sel_rng_16, avm_main_sel_rng_8, + avm_main_table_pow_2, avm_main_tag_err, avm_main_w_in_tag, avm_mem_addr, @@ -1043,6 +1103,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_pow_2_0, + lookup_pow_2_1, lookup_u8_0, lookup_u8_1, lookup_u16_0, @@ -1064,6 +1126,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_pow_2_0_counts, + lookup_pow_2_1_counts, lookup_u8_0_counts, lookup_u8_1_counts, lookup_u16_0_counts, @@ -1092,6 +1156,8 @@ class AvmFlavor { avm_alu_op_cast_prev_shift, avm_alu_op_cast_shift, avm_alu_op_mul_shift, + avm_alu_op_shl_shift, + avm_alu_op_shr_shift, avm_alu_op_sub_shift, avm_alu_p_sub_a_hi_shift, avm_alu_p_sub_a_lo_shift, @@ -1149,6 +1215,8 @@ class AvmFlavor { avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, + avm_alu_op_shl, + avm_alu_op_shr, avm_alu_op_sub, avm_alu_p_a_borrow, avm_alu_p_b_borrow, @@ -1160,6 +1228,11 @@ class AvmFlavor { avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, avm_alu_rng_chk_sel, + avm_alu_shift_lt_bit_len, + avm_alu_shift_sel, + avm_alu_t_sub_s_bits, + avm_alu_two_pow_s, + avm_alu_two_pow_t_sub_s, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -1255,10 +1328,13 @@ class AvmFlavor { avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, + avm_main_sel_op_shl, + avm_main_sel_op_shr, avm_main_sel_op_sub, avm_main_sel_op_xor, avm_main_sel_rng_16, avm_main_sel_rng_8, + avm_main_table_pow_2, avm_main_tag_err, avm_main_w_in_tag, avm_mem_addr, @@ -1299,6 +1375,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_pow_2_0, + lookup_pow_2_1, lookup_u8_0, lookup_u8_1, lookup_u16_0, @@ -1320,6 +1398,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_pow_2_0_counts, + lookup_pow_2_1_counts, lookup_u8_0_counts, lookup_u8_1_counts, lookup_u16_0_counts, @@ -1351,6 +1431,8 @@ class AvmFlavor { avm_alu_op_cast_prev, avm_alu_op_cast, avm_alu_op_mul, + avm_alu_op_shl, + avm_alu_op_shr, avm_alu_op_sub, avm_alu_p_sub_a_hi, avm_alu_p_sub_a_lo, @@ -1392,6 +1474,8 @@ class AvmFlavor { avm_alu_op_cast_prev_shift, avm_alu_op_cast_shift, avm_alu_op_mul_shift, + avm_alu_op_shl_shift, + avm_alu_op_shr_shift, avm_alu_op_sub_shift, avm_alu_p_sub_a_hi_shift, avm_alu_p_sub_a_lo_shift, @@ -1442,6 +1526,8 @@ class AvmFlavor { avm_alu_op_cast_prev, avm_alu_op_cast, avm_alu_op_mul, + avm_alu_op_shl, + avm_alu_op_shr, avm_alu_op_sub, avm_alu_p_sub_a_hi, avm_alu_p_sub_a_lo, @@ -1503,6 +1589,10 @@ class AvmFlavor { prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( @@ -1656,6 +1746,8 @@ class AvmFlavor { Base::avm_alu_op_lte = "AVM_ALU_OP_LTE"; Base::avm_alu_op_mul = "AVM_ALU_OP_MUL"; Base::avm_alu_op_not = "AVM_ALU_OP_NOT"; + Base::avm_alu_op_shl = "AVM_ALU_OP_SHL"; + Base::avm_alu_op_shr = "AVM_ALU_OP_SHR"; Base::avm_alu_op_sub = "AVM_ALU_OP_SUB"; Base::avm_alu_p_a_borrow = "AVM_ALU_P_A_BORROW"; Base::avm_alu_p_b_borrow = "AVM_ALU_P_B_BORROW"; @@ -1667,6 +1759,11 @@ class AvmFlavor { Base::avm_alu_res_lo = "AVM_ALU_RES_LO"; Base::avm_alu_rng_chk_lookup_selector = "AVM_ALU_RNG_CHK_LOOKUP_SELECTOR"; Base::avm_alu_rng_chk_sel = "AVM_ALU_RNG_CHK_SEL"; + Base::avm_alu_shift_lt_bit_len = "AVM_ALU_SHIFT_LT_BIT_LEN"; + Base::avm_alu_shift_sel = "AVM_ALU_SHIFT_SEL"; + Base::avm_alu_t_sub_s_bits = "AVM_ALU_T_SUB_S_BITS"; + Base::avm_alu_two_pow_s = "AVM_ALU_TWO_POW_S"; + Base::avm_alu_two_pow_t_sub_s = "AVM_ALU_TWO_POW_T_SUB_S"; Base::avm_alu_u128_tag = "AVM_ALU_U128_TAG"; Base::avm_alu_u16_r0 = "AVM_ALU_U16_R0"; Base::avm_alu_u16_r1 = "AVM_ALU_U16_R1"; @@ -1762,10 +1859,13 @@ class AvmFlavor { Base::avm_main_sel_op_mul = "AVM_MAIN_SEL_OP_MUL"; Base::avm_main_sel_op_not = "AVM_MAIN_SEL_OP_NOT"; Base::avm_main_sel_op_or = "AVM_MAIN_SEL_OP_OR"; + Base::avm_main_sel_op_shl = "AVM_MAIN_SEL_OP_SHL"; + Base::avm_main_sel_op_shr = "AVM_MAIN_SEL_OP_SHR"; Base::avm_main_sel_op_sub = "AVM_MAIN_SEL_OP_SUB"; Base::avm_main_sel_op_xor = "AVM_MAIN_SEL_OP_XOR"; Base::avm_main_sel_rng_16 = "AVM_MAIN_SEL_RNG_16"; Base::avm_main_sel_rng_8 = "AVM_MAIN_SEL_RNG_8"; + Base::avm_main_table_pow_2 = "AVM_MAIN_TABLE_POW_2"; Base::avm_main_tag_err = "AVM_MAIN_TAG_ERR"; Base::avm_main_w_in_tag = "AVM_MAIN_W_IN_TAG"; Base::avm_mem_addr = "AVM_MEM_ADDR"; @@ -1806,6 +1906,8 @@ class AvmFlavor { 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_pow_2_0 = "LOOKUP_POW_2_0"; + Base::lookup_pow_2_1 = "LOOKUP_POW_2_1"; Base::lookup_u8_0 = "LOOKUP_U8_0"; Base::lookup_u8_1 = "LOOKUP_U8_1"; Base::lookup_u16_0 = "LOOKUP_U16_0"; @@ -1827,6 +1929,8 @@ class AvmFlavor { 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"; + Base::lookup_pow_2_0_counts = "LOOKUP_POW_2_0_COUNTS"; + Base::lookup_pow_2_1_counts = "LOOKUP_POW_2_1_COUNTS"; Base::lookup_u8_0_counts = "LOOKUP_U8_0_COUNTS"; Base::lookup_u8_1_counts = "LOOKUP_U8_1_COUNTS"; Base::lookup_u16_0_counts = "LOOKUP_U16_0_COUNTS"; @@ -1888,6 +1992,8 @@ class AvmFlavor { Commitment avm_alu_op_lte; Commitment avm_alu_op_mul; Commitment avm_alu_op_not; + Commitment avm_alu_op_shl; + Commitment avm_alu_op_shr; Commitment avm_alu_op_sub; Commitment avm_alu_p_a_borrow; Commitment avm_alu_p_b_borrow; @@ -1899,6 +2005,11 @@ class AvmFlavor { Commitment avm_alu_res_lo; Commitment avm_alu_rng_chk_lookup_selector; Commitment avm_alu_rng_chk_sel; + Commitment avm_alu_shift_lt_bit_len; + Commitment avm_alu_shift_sel; + Commitment avm_alu_t_sub_s_bits; + Commitment avm_alu_two_pow_s; + Commitment avm_alu_two_pow_t_sub_s; Commitment avm_alu_u128_tag; Commitment avm_alu_u16_r0; Commitment avm_alu_u16_r1; @@ -1994,10 +2105,13 @@ class AvmFlavor { Commitment avm_main_sel_op_mul; Commitment avm_main_sel_op_not; Commitment avm_main_sel_op_or; + Commitment avm_main_sel_op_shl; + Commitment avm_main_sel_op_shr; Commitment avm_main_sel_op_sub; Commitment avm_main_sel_op_xor; Commitment avm_main_sel_rng_16; Commitment avm_main_sel_rng_8; + Commitment avm_main_table_pow_2; Commitment avm_main_tag_err; Commitment avm_main_w_in_tag; Commitment avm_mem_addr; @@ -2038,6 +2152,8 @@ class AvmFlavor { Commitment lookup_byte_operations; Commitment incl_main_tag_err; Commitment incl_mem_tag_err; + Commitment lookup_pow_2_0; + Commitment lookup_pow_2_1; Commitment lookup_u8_0; Commitment lookup_u8_1; Commitment lookup_u16_0; @@ -2059,6 +2175,8 @@ class AvmFlavor { Commitment lookup_byte_operations_counts; Commitment incl_main_tag_err_counts; Commitment incl_mem_tag_err_counts; + Commitment lookup_pow_2_0_counts; + Commitment lookup_pow_2_1_counts; Commitment lookup_u8_0_counts; Commitment lookup_u8_1_counts; Commitment lookup_u16_0_counts; @@ -2120,6 +2238,8 @@ class AvmFlavor { avm_alu_op_lte = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_mul = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_not = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_op_shl = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_op_shr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_sub = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_p_a_borrow = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_p_b_borrow = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2131,6 +2251,11 @@ class AvmFlavor { avm_alu_res_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_rng_chk_lookup_selector = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_rng_chk_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_shift_lt_bit_len = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_shift_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_t_sub_s_bits = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_two_pow_s = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_two_pow_t_sub_s = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_u128_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_u16_r0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_u16_r1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2227,10 +2352,13 @@ class AvmFlavor { avm_main_sel_op_mul = 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_or = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_op_shl = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_op_shr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_sub = 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_sel_rng_16 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_rng_8 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_table_pow_2 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_w_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_addr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2271,6 +2399,8 @@ class AvmFlavor { 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_pow_2_0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_pow_2_1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u8_0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u8_1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u16_0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2292,6 +2422,8 @@ class AvmFlavor { 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); + lookup_pow_2_0_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_pow_2_1_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u8_0_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u8_1_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u16_0_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2357,6 +2489,8 @@ class AvmFlavor { serialize_to_buffer(avm_alu_op_lte, Transcript::proof_data); serialize_to_buffer(avm_alu_op_mul, Transcript::proof_data); serialize_to_buffer(avm_alu_op_not, Transcript::proof_data); + serialize_to_buffer(avm_alu_op_shl, Transcript::proof_data); + serialize_to_buffer(avm_alu_op_shr, Transcript::proof_data); serialize_to_buffer(avm_alu_op_sub, Transcript::proof_data); serialize_to_buffer(avm_alu_p_a_borrow, Transcript::proof_data); serialize_to_buffer(avm_alu_p_b_borrow, Transcript::proof_data); @@ -2368,6 +2502,11 @@ class AvmFlavor { serialize_to_buffer(avm_alu_res_lo, Transcript::proof_data); serialize_to_buffer(avm_alu_rng_chk_lookup_selector, Transcript::proof_data); serialize_to_buffer(avm_alu_rng_chk_sel, Transcript::proof_data); + serialize_to_buffer(avm_alu_shift_lt_bit_len, Transcript::proof_data); + serialize_to_buffer(avm_alu_shift_sel, Transcript::proof_data); + serialize_to_buffer(avm_alu_t_sub_s_bits, Transcript::proof_data); + serialize_to_buffer(avm_alu_two_pow_s, Transcript::proof_data); + serialize_to_buffer(avm_alu_two_pow_t_sub_s, Transcript::proof_data); serialize_to_buffer(avm_alu_u128_tag, Transcript::proof_data); serialize_to_buffer(avm_alu_u16_r0, Transcript::proof_data); serialize_to_buffer(avm_alu_u16_r1, Transcript::proof_data); @@ -2463,10 +2602,13 @@ class AvmFlavor { serialize_to_buffer(avm_main_sel_op_mul, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_not, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_or, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_op_shl, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_op_shr, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_sub, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_xor, Transcript::proof_data); serialize_to_buffer(avm_main_sel_rng_16, Transcript::proof_data); serialize_to_buffer(avm_main_sel_rng_8, Transcript::proof_data); + serialize_to_buffer(avm_main_table_pow_2, Transcript::proof_data); serialize_to_buffer(avm_main_tag_err, Transcript::proof_data); serialize_to_buffer(avm_main_w_in_tag, Transcript::proof_data); serialize_to_buffer(avm_mem_addr, Transcript::proof_data); @@ -2507,6 +2649,8 @@ class AvmFlavor { 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_pow_2_0, Transcript::proof_data); + serialize_to_buffer(lookup_pow_2_1, Transcript::proof_data); serialize_to_buffer(lookup_u8_0, Transcript::proof_data); serialize_to_buffer(lookup_u8_1, Transcript::proof_data); serialize_to_buffer(lookup_u16_0, Transcript::proof_data); @@ -2528,6 +2672,8 @@ class AvmFlavor { 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); + serialize_to_buffer(lookup_pow_2_0_counts, Transcript::proof_data); + serialize_to_buffer(lookup_pow_2_1_counts, Transcript::proof_data); serialize_to_buffer(lookup_u8_0_counts, Transcript::proof_data); serialize_to_buffer(lookup_u8_1_counts, Transcript::proof_data); serialize_to_buffer(lookup_u16_0_counts, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp index d5b48dee516..9343f80ba62 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp @@ -84,6 +84,8 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_alu_op_lte = commitment_key->commit(key->avm_alu_op_lte); witness_commitments.avm_alu_op_mul = commitment_key->commit(key->avm_alu_op_mul); witness_commitments.avm_alu_op_not = commitment_key->commit(key->avm_alu_op_not); + witness_commitments.avm_alu_op_shl = commitment_key->commit(key->avm_alu_op_shl); + witness_commitments.avm_alu_op_shr = commitment_key->commit(key->avm_alu_op_shr); witness_commitments.avm_alu_op_sub = commitment_key->commit(key->avm_alu_op_sub); witness_commitments.avm_alu_p_a_borrow = commitment_key->commit(key->avm_alu_p_a_borrow); witness_commitments.avm_alu_p_b_borrow = commitment_key->commit(key->avm_alu_p_b_borrow); @@ -95,6 +97,11 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_alu_res_lo = commitment_key->commit(key->avm_alu_res_lo); witness_commitments.avm_alu_rng_chk_lookup_selector = commitment_key->commit(key->avm_alu_rng_chk_lookup_selector); witness_commitments.avm_alu_rng_chk_sel = commitment_key->commit(key->avm_alu_rng_chk_sel); + witness_commitments.avm_alu_shift_lt_bit_len = commitment_key->commit(key->avm_alu_shift_lt_bit_len); + witness_commitments.avm_alu_shift_sel = commitment_key->commit(key->avm_alu_shift_sel); + witness_commitments.avm_alu_t_sub_s_bits = commitment_key->commit(key->avm_alu_t_sub_s_bits); + witness_commitments.avm_alu_two_pow_s = commitment_key->commit(key->avm_alu_two_pow_s); + witness_commitments.avm_alu_two_pow_t_sub_s = commitment_key->commit(key->avm_alu_two_pow_t_sub_s); witness_commitments.avm_alu_u128_tag = commitment_key->commit(key->avm_alu_u128_tag); witness_commitments.avm_alu_u16_r0 = commitment_key->commit(key->avm_alu_u16_r0); witness_commitments.avm_alu_u16_r1 = commitment_key->commit(key->avm_alu_u16_r1); @@ -191,10 +198,13 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_main_sel_op_mul = commitment_key->commit(key->avm_main_sel_op_mul); witness_commitments.avm_main_sel_op_not = commitment_key->commit(key->avm_main_sel_op_not); witness_commitments.avm_main_sel_op_or = commitment_key->commit(key->avm_main_sel_op_or); + witness_commitments.avm_main_sel_op_shl = commitment_key->commit(key->avm_main_sel_op_shl); + witness_commitments.avm_main_sel_op_shr = commitment_key->commit(key->avm_main_sel_op_shr); witness_commitments.avm_main_sel_op_sub = commitment_key->commit(key->avm_main_sel_op_sub); witness_commitments.avm_main_sel_op_xor = commitment_key->commit(key->avm_main_sel_op_xor); witness_commitments.avm_main_sel_rng_16 = commitment_key->commit(key->avm_main_sel_rng_16); witness_commitments.avm_main_sel_rng_8 = commitment_key->commit(key->avm_main_sel_rng_8); + witness_commitments.avm_main_table_pow_2 = commitment_key->commit(key->avm_main_table_pow_2); witness_commitments.avm_main_tag_err = commitment_key->commit(key->avm_main_tag_err); witness_commitments.avm_main_w_in_tag = commitment_key->commit(key->avm_main_w_in_tag); witness_commitments.avm_mem_addr = commitment_key->commit(key->avm_mem_addr); @@ -225,6 +235,8 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.lookup_byte_operations_counts = commitment_key->commit(key->lookup_byte_operations_counts); witness_commitments.incl_main_tag_err_counts = commitment_key->commit(key->incl_main_tag_err_counts); witness_commitments.incl_mem_tag_err_counts = commitment_key->commit(key->incl_mem_tag_err_counts); + witness_commitments.lookup_pow_2_0_counts = commitment_key->commit(key->lookup_pow_2_0_counts); + witness_commitments.lookup_pow_2_1_counts = commitment_key->commit(key->lookup_pow_2_1_counts); witness_commitments.lookup_u8_0_counts = commitment_key->commit(key->lookup_u8_0_counts); witness_commitments.lookup_u8_1_counts = commitment_key->commit(key->lookup_u8_1_counts); witness_commitments.lookup_u16_0_counts = commitment_key->commit(key->lookup_u16_0_counts); @@ -269,6 +281,8 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_alu_op_lte, witness_commitments.avm_alu_op_lte); transcript->send_to_verifier(commitment_labels.avm_alu_op_mul, witness_commitments.avm_alu_op_mul); transcript->send_to_verifier(commitment_labels.avm_alu_op_not, witness_commitments.avm_alu_op_not); + transcript->send_to_verifier(commitment_labels.avm_alu_op_shl, witness_commitments.avm_alu_op_shl); + transcript->send_to_verifier(commitment_labels.avm_alu_op_shr, witness_commitments.avm_alu_op_shr); transcript->send_to_verifier(commitment_labels.avm_alu_op_sub, witness_commitments.avm_alu_op_sub); transcript->send_to_verifier(commitment_labels.avm_alu_p_a_borrow, witness_commitments.avm_alu_p_a_borrow); transcript->send_to_verifier(commitment_labels.avm_alu_p_b_borrow, witness_commitments.avm_alu_p_b_borrow); @@ -281,6 +295,13 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_alu_rng_chk_lookup_selector, witness_commitments.avm_alu_rng_chk_lookup_selector); transcript->send_to_verifier(commitment_labels.avm_alu_rng_chk_sel, witness_commitments.avm_alu_rng_chk_sel); + transcript->send_to_verifier(commitment_labels.avm_alu_shift_lt_bit_len, + witness_commitments.avm_alu_shift_lt_bit_len); + transcript->send_to_verifier(commitment_labels.avm_alu_shift_sel, witness_commitments.avm_alu_shift_sel); + transcript->send_to_verifier(commitment_labels.avm_alu_t_sub_s_bits, witness_commitments.avm_alu_t_sub_s_bits); + transcript->send_to_verifier(commitment_labels.avm_alu_two_pow_s, witness_commitments.avm_alu_two_pow_s); + transcript->send_to_verifier(commitment_labels.avm_alu_two_pow_t_sub_s, + witness_commitments.avm_alu_two_pow_t_sub_s); transcript->send_to_verifier(commitment_labels.avm_alu_u128_tag, witness_commitments.avm_alu_u128_tag); transcript->send_to_verifier(commitment_labels.avm_alu_u16_r0, witness_commitments.avm_alu_u16_r0); transcript->send_to_verifier(commitment_labels.avm_alu_u16_r1, witness_commitments.avm_alu_u16_r1); @@ -387,10 +408,13 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_main_sel_op_mul, witness_commitments.avm_main_sel_op_mul); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_not, witness_commitments.avm_main_sel_op_not); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_or, witness_commitments.avm_main_sel_op_or); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_shl, witness_commitments.avm_main_sel_op_shl); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_shr, witness_commitments.avm_main_sel_op_shr); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_sub, witness_commitments.avm_main_sel_op_sub); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_xor, witness_commitments.avm_main_sel_op_xor); transcript->send_to_verifier(commitment_labels.avm_main_sel_rng_16, witness_commitments.avm_main_sel_rng_16); transcript->send_to_verifier(commitment_labels.avm_main_sel_rng_8, witness_commitments.avm_main_sel_rng_8); + transcript->send_to_verifier(commitment_labels.avm_main_table_pow_2, witness_commitments.avm_main_table_pow_2); transcript->send_to_verifier(commitment_labels.avm_main_tag_err, witness_commitments.avm_main_tag_err); transcript->send_to_verifier(commitment_labels.avm_main_w_in_tag, witness_commitments.avm_main_w_in_tag); transcript->send_to_verifier(commitment_labels.avm_mem_addr, witness_commitments.avm_mem_addr); @@ -425,6 +449,8 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.incl_main_tag_err_counts); transcript->send_to_verifier(commitment_labels.incl_mem_tag_err_counts, witness_commitments.incl_mem_tag_err_counts); + transcript->send_to_verifier(commitment_labels.lookup_pow_2_0_counts, witness_commitments.lookup_pow_2_0_counts); + transcript->send_to_verifier(commitment_labels.lookup_pow_2_1_counts, witness_commitments.lookup_pow_2_1_counts); transcript->send_to_verifier(commitment_labels.lookup_u8_0_counts, witness_commitments.lookup_u8_0_counts); transcript->send_to_verifier(commitment_labels.lookup_u8_1_counts, witness_commitments.lookup_u8_1_counts); transcript->send_to_verifier(commitment_labels.lookup_u16_0_counts, witness_commitments.lookup_u16_0_counts); @@ -468,6 +494,8 @@ void AvmProver::execute_log_derivative_inverse_round() witness_commitments.lookup_byte_operations = commitment_key->commit(key->lookup_byte_operations); witness_commitments.incl_main_tag_err = commitment_key->commit(key->incl_main_tag_err); witness_commitments.incl_mem_tag_err = commitment_key->commit(key->incl_mem_tag_err); + witness_commitments.lookup_pow_2_0 = commitment_key->commit(key->lookup_pow_2_0); + witness_commitments.lookup_pow_2_1 = commitment_key->commit(key->lookup_pow_2_1); witness_commitments.lookup_u8_0 = commitment_key->commit(key->lookup_u8_0); witness_commitments.lookup_u8_1 = commitment_key->commit(key->lookup_u8_1); witness_commitments.lookup_u16_0 = commitment_key->commit(key->lookup_u16_0); @@ -501,6 +529,8 @@ void AvmProver::execute_log_derivative_inverse_round() transcript->send_to_verifier(commitment_labels.lookup_byte_operations, witness_commitments.lookup_byte_operations); transcript->send_to_verifier(commitment_labels.incl_main_tag_err, witness_commitments.incl_main_tag_err); transcript->send_to_verifier(commitment_labels.incl_mem_tag_err, witness_commitments.incl_mem_tag_err); + transcript->send_to_verifier(commitment_labels.lookup_pow_2_0, witness_commitments.lookup_pow_2_0); + transcript->send_to_verifier(commitment_labels.lookup_pow_2_1, witness_commitments.lookup_pow_2_1); transcript->send_to_verifier(commitment_labels.lookup_u8_0, witness_commitments.lookup_u8_0); transcript->send_to_verifier(commitment_labels.lookup_u8_1, witness_commitments.lookup_u8_1); transcript->send_to_verifier(commitment_labels.lookup_u16_0, witness_commitments.lookup_u16_0); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index a7b418bab60..5edd090d1e6 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -82,6 +82,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) commitments.avm_alu_op_lte = transcript->template receive_from_prover(commitment_labels.avm_alu_op_lte); commitments.avm_alu_op_mul = transcript->template receive_from_prover(commitment_labels.avm_alu_op_mul); commitments.avm_alu_op_not = transcript->template receive_from_prover(commitment_labels.avm_alu_op_not); + commitments.avm_alu_op_shl = transcript->template receive_from_prover(commitment_labels.avm_alu_op_shl); + commitments.avm_alu_op_shr = transcript->template receive_from_prover(commitment_labels.avm_alu_op_shr); commitments.avm_alu_op_sub = transcript->template receive_from_prover(commitment_labels.avm_alu_op_sub); commitments.avm_alu_p_a_borrow = transcript->template receive_from_prover(commitment_labels.avm_alu_p_a_borrow); @@ -101,6 +103,16 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_alu_rng_chk_lookup_selector); commitments.avm_alu_rng_chk_sel = transcript->template receive_from_prover(commitment_labels.avm_alu_rng_chk_sel); + commitments.avm_alu_shift_lt_bit_len = + transcript->template receive_from_prover(commitment_labels.avm_alu_shift_lt_bit_len); + commitments.avm_alu_shift_sel = + transcript->template receive_from_prover(commitment_labels.avm_alu_shift_sel); + commitments.avm_alu_t_sub_s_bits = + transcript->template receive_from_prover(commitment_labels.avm_alu_t_sub_s_bits); + commitments.avm_alu_two_pow_s = + transcript->template receive_from_prover(commitment_labels.avm_alu_two_pow_s); + commitments.avm_alu_two_pow_t_sub_s = + transcript->template receive_from_prover(commitment_labels.avm_alu_two_pow_t_sub_s); commitments.avm_alu_u128_tag = transcript->template receive_from_prover(commitment_labels.avm_alu_u128_tag); commitments.avm_alu_u16_r0 = transcript->template receive_from_prover(commitment_labels.avm_alu_u16_r0); @@ -262,6 +274,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_not); commitments.avm_main_sel_op_or = transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_or); + commitments.avm_main_sel_op_shl = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_shl); + commitments.avm_main_sel_op_shr = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_shr); commitments.avm_main_sel_op_sub = transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_sub); commitments.avm_main_sel_op_xor = @@ -270,6 +286,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_main_sel_rng_16); commitments.avm_main_sel_rng_8 = transcript->template receive_from_prover(commitment_labels.avm_main_sel_rng_8); + commitments.avm_main_table_pow_2 = + transcript->template receive_from_prover(commitment_labels.avm_main_table_pow_2); commitments.avm_main_tag_err = transcript->template receive_from_prover(commitment_labels.avm_main_tag_err); commitments.avm_main_w_in_tag = @@ -320,6 +338,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.incl_main_tag_err_counts); commitments.incl_mem_tag_err_counts = transcript->template receive_from_prover(commitment_labels.incl_mem_tag_err_counts); + commitments.lookup_pow_2_0_counts = + transcript->template receive_from_prover(commitment_labels.lookup_pow_2_0_counts); + commitments.lookup_pow_2_1_counts = + transcript->template receive_from_prover(commitment_labels.lookup_pow_2_1_counts); commitments.lookup_u8_0_counts = transcript->template receive_from_prover(commitment_labels.lookup_u8_0_counts); commitments.lookup_u8_1_counts = @@ -386,6 +408,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) 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_pow_2_0 = transcript->template receive_from_prover(commitment_labels.lookup_pow_2_0); + commitments.lookup_pow_2_1 = transcript->template receive_from_prover(commitment_labels.lookup_pow_2_1); commitments.lookup_u8_0 = transcript->template receive_from_prover(commitment_labels.lookup_u8_0); commitments.lookup_u8_1 = transcript->template receive_from_prover(commitment_labels.lookup_u8_1); commitments.lookup_u16_0 = transcript->template receive_from_prover(commitment_labels.lookup_u16_0); 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 ce4e07e8f2c..16789ac3dc6 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -1,5 +1,6 @@ #include "avm_common.test.hpp" #include "barretenberg/numeric/uint128/uint128.hpp" +#include "barretenberg/vm/avm_trace/avm_common.hpp" #include "barretenberg/vm/tests/helpers.test.hpp" #include "gtest/gtest.h" #include @@ -85,6 +86,52 @@ void common_validate_op_not(std::vector const& trace, } } +void common_validate_shift_op(std::vector const& trace, + 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, + bool shr) +{ + auto row = + shr ? std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_shr == FF(1); }) + : std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_shl == FF(1); }); + ASSERT_TRUE(row != trace.end()); + FF clk = row->avm_main_clk; + auto alu_row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { return r.avm_alu_clk == clk; }); + ASSERT_TRUE(alu_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 tags + EXPECT_EQ(row->avm_main_r_in_tag, FF(static_cast(tag))); + EXPECT_EQ(row->avm_main_w_in_tag, FF(static_cast(tag))); + + // Check that start row is the same as what is copied into the main trace + EXPECT_EQ(alu_row->avm_alu_ia, a); + EXPECT_EQ(alu_row->avm_alu_ib, b); + EXPECT_EQ(alu_row->avm_alu_ic, c); +} + void common_validate_bit_op(std::vector const& trace, uint8_t op_id, FF const& a, @@ -318,6 +365,21 @@ std::vector> positive_op_xor_test_values = { (uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }, (uint128_t{ 0xa906021301080001 } << 64) + uint128_t{ 0x0001080876844827 } } } }; +std::vector> positive_op_shr_test_values = { + { { 20, 3, 2 }, + { 5323, 255, 0 }, + { 36148, 13, 4 }, + { 0x7bff744e3cdf79LLU, 64, 0 }, + { (uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }, 123, 2 } } +}; +std::vector> positive_op_shl_test_values = { + { { 20, 8, 0 }, + { 5323, 10, 11264 }, + { 13793, 255, 0 }, + { 239, 50, 269090077735387136 }, + { 9, 127, (uint128_t{ 0x4800000000000000LLU } << 68) } } +}; + std::vector gen_three_op_params(std::vector> operands, std::vector mem_tags) { @@ -332,6 +394,8 @@ class AvmBitwiseTestsNot : public AvmBitwiseTests, public testing::WithParamInte class AvmBitwiseTestsAnd : public AvmBitwiseTests, public testing::WithParamInterface {}; class AvmBitwiseTestsOr : public AvmBitwiseTests, public testing::WithParamInterface {}; class AvmBitwiseTestsXor : public AvmBitwiseTests, public testing::WithParamInterface {}; +class AvmBitwiseTestsShr : public AvmBitwiseTests, public testing::WithParamInterface {}; +class AvmBitwiseTestsShl : public AvmBitwiseTests, public testing::WithParamInterface {}; /****************************************************************************** * @@ -375,7 +439,6 @@ TEST_P(AvmBitwiseTestsAnd, AllAndTest) 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(std::move(trace)); } @@ -426,6 +489,56 @@ INSTANTIATE_TEST_SUITE_P(AvmBitwiseTests, AvmBitwiseTestsXor, testing::ValuesIn(gen_three_op_params(positive_op_xor_test_values, mem_tags))); +TEST_P(AvmBitwiseTestsShr, AllShrTest) +{ + const auto [operands, mem_tag] = GetParam(); + const auto [a, b, output] = operands; + trace_builder.op_set(0, a, 0, mem_tag); + trace_builder.op_set(0, b, 1, mem_tag); + trace_builder.op_shr(0, 0, 1, 2, mem_tag); + trace_builder.return_op(0, 2, 1); + auto trace = trace_builder.finalize(); + common_validate_shift_op(trace, + uint256_t::from_uint128(a), + uint256_t::from_uint128(b), + uint256_t::from_uint128(output), + FF(0), + FF(1), + FF(2), + mem_tag, + true); + validate_trace(std::move(trace)); +} + +INSTANTIATE_TEST_SUITE_P(AvmBitwiseTests, + AvmBitwiseTestsShr, + testing::ValuesIn(gen_three_op_params(positive_op_shr_test_values, mem_tags))); + +TEST_P(AvmBitwiseTestsShl, AllShlTest) +{ + const auto [operands, mem_tag] = GetParam(); + const auto [a, b, output] = operands; + trace_builder.op_set(0, a, 0, mem_tag); + trace_builder.op_set(0, b, 1, mem_tag); + trace_builder.op_shl(0, 0, 1, 2, mem_tag); + trace_builder.return_op(0, 2, 1); + auto trace = trace_builder.finalize(); + + common_validate_shift_op(trace, + uint256_t::from_uint128(a), + uint256_t::from_uint128(b), + uint256_t::from_uint128(output), + FF(0), + FF(1), + FF(2), + mem_tag, + false); + validate_trace(std::move(trace)); +} + +INSTANTIATE_TEST_SUITE_P(AvmBitwiseTests, + AvmBitwiseTestsShl, + testing::ValuesIn(gen_three_op_params(positive_op_shl_test_values, mem_tags))); /****************************************************************************** * * NEGATIVE TESTS - Finite Field Type