From 8e111f8bab5a0348fe8c7185f89e979541f91a67 Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Thu, 9 May 2024 12:16:05 +0100 Subject: [PATCH] feat: div opcode (#6053) Please read [contributing guidelines](CONTRIBUTING.md) and remove this line. --------- Co-authored-by: Jean M <132435771+jeanmon@users.noreply.github.com> --- barretenberg/cpp/pil/avm/avm_alu.pil | 123 +++++- barretenberg/cpp/pil/avm/avm_main.pil | 35 +- .../relations/generated/avm/avm_alu.hpp | 318 +++++++++++-- .../relations/generated/avm/avm_main.hpp | 28 +- .../relations/generated/avm/declare_views.hpp | 44 ++ .../generated/avm/lookup_div_u16_0.hpp | 166 +++++++ .../generated/avm/lookup_div_u16_1.hpp | 166 +++++++ .../generated/avm/lookup_div_u16_2.hpp | 166 +++++++ .../generated/avm/lookup_div_u16_3.hpp | 166 +++++++ .../generated/avm/lookup_div_u16_4.hpp | 166 +++++++ .../generated/avm/lookup_div_u16_5.hpp | 166 +++++++ .../generated/avm/lookup_div_u16_6.hpp | 166 +++++++ .../generated/avm/lookup_div_u16_7.hpp | 166 +++++++ .../vm/avm_trace/avm_alu_trace.cpp | 111 ++++- .../vm/avm_trace/avm_alu_trace.hpp | 16 + .../vm/avm_trace/avm_execution.cpp | 7 + .../barretenberg/vm/avm_trace/avm_trace.cpp | 120 ++++- .../barretenberg/vm/avm_trace/avm_trace.hpp | 3 + .../vm/generated/avm_circuit_builder.hpp | 116 ++++- .../barretenberg/vm/generated/avm_flavor.hpp | 417 +++++++++++++++++- .../barretenberg/vm/generated/avm_prover.cpp | 79 ++++ .../vm/generated/avm_verifier.cpp | 68 +++ .../vm/tests/avm_arithmetic.test.cpp | 90 +++- .../vm/tests/avm_bitwise.test.cpp | 158 +++---- .../vm/tests/avm_comparison.test.cpp | 11 - .../barretenberg/vm/tests/helpers.test.cpp | 12 + .../barretenberg/vm/tests/helpers.test.hpp | 4 + 27 files changed, 2897 insertions(+), 191 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_0.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_1.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_2.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_3.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_4.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_5.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_6.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_7.hpp diff --git a/barretenberg/cpp/pil/avm/avm_alu.pil b/barretenberg/cpp/pil/avm/avm_alu.pil index 35771b3fb48..5d6db0544ba 100644 --- a/barretenberg/cpp/pil/avm/avm_alu.pil +++ b/barretenberg/cpp/pil/avm/avm_alu.pil @@ -64,7 +64,7 @@ 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 + op_shr + op_shl; + alu_sel = op_add + op_sub + op_mul + op_not + op_eq + op_cast + op_lt + op_lte + op_shr + op_shl + op_div; cmp_sel = op_lt + op_lte; shift_sel = op_shl + op_shr; @@ -317,9 +317,9 @@ namespace avm_alu(256); // First condition is if borrow = 0, second condition is if borrow = 1 // This underflow check is done by the 128-bit check that is performed on each of these lo and hi limbs. #[SUB_LO_1] - (p_sub_a_lo - (53438638232309528389504892708671455232 - a_lo + p_a_borrow * 2 ** 128)) * (cmp_sel + op_cast) = 0; + (p_sub_a_lo - (53438638232309528389504892708671455232 - a_lo + p_a_borrow * 2 ** 128)) * (cmp_sel + op_cast + op_div_std) = 0; #[SUB_HI_1] - (p_sub_a_hi - (64323764613183177041862057485226039389 - a_hi - p_a_borrow)) * (cmp_sel + op_cast) = 0; + (p_sub_a_hi - (64323764613183177041862057485226039389 - a_hi - p_a_borrow)) * (cmp_sel + op_cast + op_div_std) = 0; pol commit p_sub_b_lo; pol commit p_sub_b_hi; @@ -438,13 +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 + shift_lt_bit_len; + pol RNG_CHK_OP = rng_chk_sel + cmp_sel + op_cast + op_cast_prev + shift_lt_bit_len + op_div; 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' + op_shl' + op_shr'; + 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' + op_div'; // Perform 128-bit range check on lo part #[LOWER_CMP_RNG_CHK] @@ -622,3 +622,116 @@ namespace avm_alu(256); #[SHL_OUTPUT] op_shl * (ic - (b_lo * two_pow_s * shift_lt_bit_len)) = 0; + // ========= INTEGER DIVISION =============================== + // Operands: ia contains the dividend, ib contains the divisor, and ic contains the quotient (i.e. the result). + // All operands are restricted to be up to 128. + // The logic for integer division is to assert the correctness of this relationship: + // dividend - remainder = divisor * quotient ==> ia - remainder = ib * ic; where remainder < ib + // We do this using the following steps + // (1) The only non-trivial division is the situation where ia > ib && ib > 0 + // (a) if ia == ib => ic = 1 and remainder = 0 --> we can handle this as part of the standard division + // (b) if ia < ib => ic = 0 and remainder = ia --> isolating this case eliminates the risk of ia - remainder underflowing as remainder < ib < ia + // (c) if ib == 0 => error_tag = 1 --> Handled in main trace + // (2) Given ib and ic are restricted to U128, at most ib * ic will produce a 256-bit number. + // (3) We use the primality check from cmp to check that this product has not overflowed the field. + // The Primality check takes a field element as input and ouputs two 128-bit limbs. + // i.e. it checks that the field element, represented with two 128-bit limbs lies in [0, p). + // (a) Given x, PC(x) -> [x_lo, x_hi], where x_lo < 2**128 && x_hi < 2**128 && x == x_lo + x_hi * 2**128 + // (b) Additionally produces a witness that the x < (p - 1) + // p_sub_x_lo = p_lo - x_lo + borrow * 2**128 < 2**128 + // p_sub_x_hi = p_hi - x_hi - borrow < 2**128 + // (c) Range checks over 128-bits are applied to x_lo, x_hi, p_sub_x_lo, and p_sub_x_hi. + + // Range check the remainder < divisor. + pol commit remainder; + // The op_div boolean must be set based on which division case it is. + op_div = op_div_std + op_div_a_lt_b; + + // ======= Handling ia < ib ===== + // Boolean if ia < ib ==> ic = 0; + pol commit op_div_a_lt_b; + op_div_a_lt_b * (1 - op_div_a_lt_b) = 0; + // To show this, we constrain ib - ia - 1 to be within 128 bits. + // Since we need a range check we use the existing a_lo column that is range checked over 128 bits. + op_div_a_lt_b * (a_lo - (ib - ia - 1)) = 0; + op_div_a_lt_b * ic = 0; // ic = 0 + op_div_a_lt_b * (ia - remainder) = 0; // remainder = a, might not be needed. + + + // ====== Handling ia >= ib ===== + pol commit op_div_std; + op_div_std * (1 - op_div_std) = 0; + pol commit divisor_lo; // b + pol commit divisor_hi; + op_div_std * (ib - divisor_lo - 2**64 * divisor_hi) = 0; + pol commit quotient_lo; // c + pol commit quotient_hi; + op_div_std * (ic - quotient_lo - 2**64 * quotient_hi) = 0; + + // Multiplying the limbs gives us the following relations. + // (1) divisor_lo * quotient_lo --> Represents the bottom 128 bits of the result, i.e. values between [0, 2**128). + // (2) divisor_lo * quotient_hi + quotient_lo * divisor_hi --> Represents the middle 128 bits of the result, i.e. values between [2**64, 2**196) + // (3) divisor_hi * quotient_hi --> Represents the topmost 128 bits of the result, i.e. values between [2**128, 2**256). + + // We simplify (2) by further decomposing it into two limbs of 64 bits and adding the upper 64 bit to (3) + // divisor_lo * quotient_hi + quotient_lo * divisor_hi = partial_prod_lo + 2**64 * partial_prod_hi + // Need to range check that these are 64 bits + pol commit partial_prod_lo; + pol commit partial_prod_hi; + divisor_hi * quotient_lo + divisor_lo * quotient_hi = partial_prod_lo + 2**64 * partial_prod_hi; + + pol PRODUCT = divisor_lo * quotient_lo + 2**64 * partial_prod_lo + 2**128 * (partial_prod_hi + divisor_hi * quotient_hi); + + // a_lo and a_hi contains the hi and lo limbs of PRODUCT + // p_sub_a_lo and p_sub_a_hi contain the primality checks + #[ALU_PROD_DIV] + op_div_std * (PRODUCT - (a_lo + 2 ** 128 * a_hi)) = 0; + // Range checks already performed via a_lo and a_hi + // Primality checks already performed above via p_sub_a_lo and p_sub_a_hi + + // Range check remainder < ib and put the value in b_hi, it has to fit into a 128 bit range check + #[REMAINDER_RANGE_CHK] + op_div_std * (b_hi - (ib - remainder - 1)) = 0; + + // We need to perform 3 x 256-bit range checks: (a_lo, a_hi), (b_lo, b_hi), and (p_sub_a_lo, p_sub_a_hi) + // One range check happens in-line with the division + #[CMP_CTR_REL_3] + (cmp_rng_ctr' - 2) * op_div_std = 0; + + // If we have more range checks left we cannot do more divisions operations that might truncate the steps + rng_chk_sel * op_div_std = 0; + + // Check PRODUCT = ia - remainder + #[DIVISION_RELATION] + op_div_std * (PRODUCT - (ia - remainder)) = 0; + + // === DIVISION 64-BIT RANGE CHECKS + // 64-bit decompositions and implicit 64-bit range checks for each limb, + // TODO: We need extra slice registers because we are performing an additional 64-bit range check in the same row, look into re-using old columns or refactoring + // range checks to be more modular. + // boolean to account for the division-specific 64-bit range checks. + pol commit div_rng_chk_selector; + div_rng_chk_selector * (1 - div_rng_chk_selector) = 0; + // div_rng_chk_selector && div_rng_chk_selector' = 1 if op_div_std = 1 + div_rng_chk_selector * div_rng_chk_selector' = op_div_std; + + pol commit div_u16_r0; + pol commit div_u16_r1; + pol commit div_u16_r2; + pol commit div_u16_r3; + pol commit div_u16_r4; + pol commit div_u16_r5; + pol commit div_u16_r6; + pol commit div_u16_r7; + + divisor_lo = op_div_std * (div_u16_r0 + div_u16_r1 * 2**16 + div_u16_r2 * 2**32 + div_u16_r3 * 2**48); + divisor_hi = op_div_std * (div_u16_r4 + div_u16_r5 * 2**16 + div_u16_r6 * 2**32 + div_u16_r7 * 2**48); + quotient_lo = op_div_std * (div_u16_r0' + div_u16_r1' * 2**16 + div_u16_r2' * 2**32 + div_u16_r3' * 2**48); + quotient_hi = op_div_std * (div_u16_r4' + div_u16_r5' * 2**16 + div_u16_r6' * 2**32 + div_u16_r7' * 2**48); + + // We need an extra 128 bits to do 2 more 64-bit range checks. We use b_lo (128 bits) to store partial_prod_lo(64 bits) and partial_prod_hi(64 bits. + // Use a shift to access the slices (b_lo is moved into the alu slice registers on the next row anyways as part of the SHIFT_RELS_0 relations) + pol NEXT_SUM_64_LO = u8_r0' + u8_r1' * 2**8 + u16_r0' * 2**16 + u16_r1' * 2**32 + u16_r2' * 2**48; + pol NEXT_SUM_128_HI = u16_r3' + u16_r4' * 2**16 + u16_r5' * 2**32 + u16_r6' * 2**48; + partial_prod_lo = op_div_std * NEXT_SUM_64_LO; + partial_prod_hi = op_div_std * NEXT_SUM_128_HI; diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index 4306643acf3..8d9f3010ec4 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -197,15 +197,16 @@ namespace avm_main(256); #[SUBOP_FDIV] sel_op_fdiv * (1 - op_err) * (ic * ib - ia) = 0; - // When sel_op_fdiv == 1, we want ib == 0 <==> op_err == 1 + // When sel_op_fdiv == 1 or sel_op_div, we want ib == 0 <==> op_err == 1 // This can be achieved with the 2 following relations. // inv is an extra witness to show that we can invert ib, i.e., inv = ib^(-1) // If ib == 0, we have to set inv = 1 to satisfy the second relation, // because op_err == 1 from the first relation. + // TODO: Update the name of these relations once negative tests are updated #[SUBOP_FDIV_ZERO_ERR1] - sel_op_fdiv * (ib * inv - 1 + op_err) = 0; + (sel_op_fdiv + sel_op_div) * (ib * inv - 1 + op_err) = 0; #[SUBOP_FDIV_ZERO_ERR2] - sel_op_fdiv * op_err * (1 - inv) = 0; + (sel_op_fdiv + sel_op_div) * op_err * (1 - inv) = 0; // Enforcement that instruction tags are FF (tag constant 6). // TODO: These 2 conditions might be removed and enforced through @@ -222,7 +223,7 @@ namespace avm_main(256); // that exactly one sel_op_XXX must be true. // At this time, we have only division producing an error. #[SUBOP_ERROR_RELEVANT_OP] - op_err * (sel_op_fdiv - 1) = 0; + op_err * ((sel_op_fdiv + sel_op_div) - 1) = 0; // TODO: constraint that we stop execution at the first error (tag_err or op_err) // An error can only happen at the last sub-operation row. @@ -322,7 +323,7 @@ namespace avm_main(256); // Predicate to activate the copy of intermediate registers to ALU table. If tag_err == 1, // the operation is not copied to the ALU table. - alu_sel = ALU_ALL_SEL * (1 - tag_err); + alu_sel = ALU_ALL_SEL * (1 - tag_err) * (1 - op_err); // Dispatch the correct in_tag for alu ALU_R_TAG_SEL * (alu_in_tag - r_in_tag) = 0; @@ -472,3 +473,27 @@ namespace avm_main(256); #[LOOKUP_U16_14] avm_alu.rng_chk_lookup_selector {avm_alu.u16_r14 } in sel_rng_16 { clk }; + // ==== Additional row range checks for division + #[LOOKUP_DIV_U16_0] + avm_alu.div_rng_chk_selector {avm_alu.div_u16_r0} in sel_rng_16 { clk }; + + #[LOOKUP_DIV_U16_1] + avm_alu.div_rng_chk_selector {avm_alu.div_u16_r1 } in sel_rng_16 { clk }; + + #[LOOKUP_DIV_U16_2] + avm_alu.div_rng_chk_selector {avm_alu.div_u16_r2 } in sel_rng_16 { clk }; + + #[LOOKUP_DIV_U16_3] + avm_alu.div_rng_chk_selector {avm_alu.div_u16_r3 } in sel_rng_16 { clk }; + + #[LOOKUP_DIV_U16_4] + avm_alu.div_rng_chk_selector {avm_alu.div_u16_r4 } in sel_rng_16 { clk }; + + #[LOOKUP_DIV_U16_5] + avm_alu.div_rng_chk_selector {avm_alu.div_u16_r5 } in sel_rng_16 { clk }; + + #[LOOKUP_DIV_U16_6] + avm_alu.div_rng_chk_selector {avm_alu.div_u16_r6 } in sel_rng_16 { clk }; + + #[LOOKUP_DIV_U16_7] + avm_alu.div_rng_chk_selector {avm_alu.div_u16_r7 } in sel_rng_16 { clk }; 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 95ced4b652b..2022d640185 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -23,6 +23,26 @@ template struct Avm_aluRow { FF avm_alu_cmp_rng_ctr_shift{}; FF avm_alu_cmp_sel{}; FF avm_alu_cmp_sel_shift{}; + FF avm_alu_div_rng_chk_selector{}; + FF avm_alu_div_rng_chk_selector_shift{}; + FF avm_alu_div_u16_r0{}; + FF avm_alu_div_u16_r0_shift{}; + FF avm_alu_div_u16_r1{}; + FF avm_alu_div_u16_r1_shift{}; + FF avm_alu_div_u16_r2{}; + FF avm_alu_div_u16_r2_shift{}; + FF avm_alu_div_u16_r3{}; + FF avm_alu_div_u16_r3_shift{}; + FF avm_alu_div_u16_r4{}; + FF avm_alu_div_u16_r4_shift{}; + FF avm_alu_div_u16_r5{}; + FF avm_alu_div_u16_r5_shift{}; + FF avm_alu_div_u16_r6{}; + FF avm_alu_div_u16_r6_shift{}; + FF avm_alu_div_u16_r7{}; + FF avm_alu_div_u16_r7_shift{}; + FF avm_alu_divisor_hi{}; + FF avm_alu_divisor_lo{}; FF avm_alu_ff_tag{}; FF avm_alu_ia{}; FF avm_alu_ib{}; @@ -34,6 +54,10 @@ template struct Avm_aluRow { FF avm_alu_op_cast_prev{}; FF avm_alu_op_cast_prev_shift{}; FF avm_alu_op_cast_shift{}; + FF avm_alu_op_div{}; + FF avm_alu_op_div_a_lt_b{}; + FF avm_alu_op_div_shift{}; + FF avm_alu_op_div_std{}; FF avm_alu_op_eq{}; FF avm_alu_op_eq_diff_inv{}; FF avm_alu_op_lt{}; @@ -57,6 +81,11 @@ template struct Avm_aluRow { FF avm_alu_p_sub_b_hi_shift{}; FF avm_alu_p_sub_b_lo{}; FF avm_alu_p_sub_b_lo_shift{}; + FF avm_alu_partial_prod_hi{}; + FF avm_alu_partial_prod_lo{}; + FF avm_alu_quotient_hi{}; + FF avm_alu_quotient_lo{}; + FF avm_alu_remainder{}; FF avm_alu_res_hi{}; FF avm_alu_res_lo{}; FF avm_alu_rng_chk_lookup_selector_shift{}; @@ -228,6 +257,18 @@ inline std::string get_relation_label_avm_alu(int index) case 64: return "SHL_OUTPUT"; + + case 74: + return "ALU_PROD_DIV"; + + case 75: + return "REMAINDER_RANGE_CHK"; + + case 76: + return "CMP_CTR_REL_3"; + + case 78: + return "DIVISION_RELATION"; } return std::to_string(index); } @@ -236,9 +277,10 @@ template class avm_aluImpl { public: using FF = FF_; - 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, + 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, 2, 3, 3, 3, 3, 3, 4, 4, 3, 5, 3, 3, 3, 5, 3, 3, 4, 4, 4, 4, 4, 4, }; template @@ -252,13 +294,15 @@ 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_shr) + - avm_alu_op_shl)); + 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_shr) + + avm_alu_op_shl) + + avm_alu_op_div)); tmp *= scaling_factor; std::get<0>(evals) += tmp; } @@ -575,7 +619,7 @@ template class avm_aluImpl { 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)); + ((avm_alu_cmp_sel + avm_alu_op_cast) + avm_alu_op_div_std)); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -586,7 +630,7 @@ template class avm_aluImpl { 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)); + ((avm_alu_cmp_sel + avm_alu_op_cast) + avm_alu_op_div_std)); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -694,14 +738,15 @@ 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)); + ((((((((((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) + + avm_alu_op_div_shift)); tmp *= scaling_factor; std::get<39>(evals) += tmp; } @@ -709,16 +754,17 @@ template class avm_aluImpl { { 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))) + - (avm_alu_u16_r2 * FF(281474976710656UL))) + - (avm_alu_u16_r3 * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + - (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_shift_lt_bit_len))); + 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))) + + (avm_alu_u16_r2 * FF(281474976710656UL))) + + (avm_alu_u16_r3 * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + + (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_shift_lt_bit_len) + + avm_alu_op_div))); tmp *= scaling_factor; std::get<40>(evals) += tmp; } @@ -733,8 +779,9 @@ 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) + - avm_alu_shift_lt_bit_len))); + (((((avm_alu_rng_chk_sel + avm_alu_cmp_sel) + avm_alu_op_cast) + avm_alu_op_cast_prev) + + avm_alu_shift_lt_bit_len) + + avm_alu_op_div))); tmp *= scaling_factor; std::get<41>(evals) += tmp; } @@ -958,6 +1005,213 @@ template class avm_aluImpl { tmp *= scaling_factor; std::get<64>(evals) += tmp; } + // Contribution 65 + { + Avm_DECLARE_VIEWS(65); + + auto tmp = (avm_alu_op_div - (avm_alu_op_div_std + avm_alu_op_div_a_lt_b)); + tmp *= scaling_factor; + std::get<65>(evals) += tmp; + } + // Contribution 66 + { + Avm_DECLARE_VIEWS(66); + + auto tmp = (avm_alu_op_div_a_lt_b * (-avm_alu_op_div_a_lt_b + FF(1))); + tmp *= scaling_factor; + std::get<66>(evals) += tmp; + } + // Contribution 67 + { + Avm_DECLARE_VIEWS(67); + + auto tmp = (avm_alu_op_div_a_lt_b * (avm_alu_a_lo - ((avm_alu_ib - avm_alu_ia) - FF(1)))); + tmp *= scaling_factor; + std::get<67>(evals) += tmp; + } + // Contribution 68 + { + Avm_DECLARE_VIEWS(68); + + auto tmp = (avm_alu_op_div_a_lt_b * avm_alu_ic); + tmp *= scaling_factor; + std::get<68>(evals) += tmp; + } + // Contribution 69 + { + Avm_DECLARE_VIEWS(69); + + auto tmp = (avm_alu_op_div_a_lt_b * (avm_alu_ia - avm_alu_remainder)); + tmp *= scaling_factor; + std::get<69>(evals) += tmp; + } + // Contribution 70 + { + Avm_DECLARE_VIEWS(70); + + auto tmp = (avm_alu_op_div_std * (-avm_alu_op_div_std + FF(1))); + tmp *= scaling_factor; + std::get<70>(evals) += tmp; + } + // Contribution 71 + { + Avm_DECLARE_VIEWS(71); + + auto tmp = (avm_alu_op_div_std * ((avm_alu_ib - avm_alu_divisor_lo) - + (avm_alu_divisor_hi * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL })))); + tmp *= scaling_factor; + std::get<71>(evals) += tmp; + } + // Contribution 72 + { + Avm_DECLARE_VIEWS(72); + + auto tmp = (avm_alu_op_div_std * ((avm_alu_ic - avm_alu_quotient_lo) - + (avm_alu_quotient_hi * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL })))); + tmp *= scaling_factor; + std::get<72>(evals) += tmp; + } + // Contribution 73 + { + Avm_DECLARE_VIEWS(73); + + auto tmp = (((avm_alu_divisor_hi * avm_alu_quotient_lo) + (avm_alu_divisor_lo * avm_alu_quotient_hi)) - + (avm_alu_partial_prod_lo + (avm_alu_partial_prod_hi * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL })))); + tmp *= scaling_factor; + std::get<73>(evals) += tmp; + } + // Contribution 74 + { + Avm_DECLARE_VIEWS(74); + + auto tmp = (avm_alu_op_div_std * ((((avm_alu_divisor_lo * avm_alu_quotient_lo) + + (avm_alu_partial_prod_lo * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + + ((avm_alu_partial_prod_hi + (avm_alu_divisor_hi * avm_alu_quotient_hi)) * + FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) - + (avm_alu_a_lo + (avm_alu_a_hi * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))))); + tmp *= scaling_factor; + std::get<74>(evals) += tmp; + } + // Contribution 75 + { + Avm_DECLARE_VIEWS(75); + + auto tmp = (avm_alu_op_div_std * (avm_alu_b_hi - ((avm_alu_ib - avm_alu_remainder) - FF(1)))); + tmp *= scaling_factor; + std::get<75>(evals) += tmp; + } + // Contribution 76 + { + Avm_DECLARE_VIEWS(76); + + auto tmp = ((avm_alu_cmp_rng_ctr_shift - FF(2)) * avm_alu_op_div_std); + tmp *= scaling_factor; + std::get<76>(evals) += tmp; + } + // Contribution 77 + { + Avm_DECLARE_VIEWS(77); + + auto tmp = (avm_alu_rng_chk_sel * avm_alu_op_div_std); + tmp *= scaling_factor; + std::get<77>(evals) += tmp; + } + // Contribution 78 + { + Avm_DECLARE_VIEWS(78); + + auto tmp = (avm_alu_op_div_std * ((((avm_alu_divisor_lo * avm_alu_quotient_lo) + + (avm_alu_partial_prod_lo * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + + ((avm_alu_partial_prod_hi + (avm_alu_divisor_hi * avm_alu_quotient_hi)) * + FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) - + (avm_alu_ia - avm_alu_remainder))); + tmp *= scaling_factor; + std::get<78>(evals) += tmp; + } + // Contribution 79 + { + Avm_DECLARE_VIEWS(79); + + auto tmp = (avm_alu_div_rng_chk_selector * (-avm_alu_div_rng_chk_selector + FF(1))); + tmp *= scaling_factor; + std::get<79>(evals) += tmp; + } + // Contribution 80 + { + Avm_DECLARE_VIEWS(80); + + auto tmp = ((avm_alu_div_rng_chk_selector * avm_alu_div_rng_chk_selector_shift) - avm_alu_op_div_std); + tmp *= scaling_factor; + std::get<80>(evals) += tmp; + } + // Contribution 81 + { + Avm_DECLARE_VIEWS(81); + + auto tmp = + (avm_alu_divisor_lo - (avm_alu_op_div_std * (((avm_alu_div_u16_r0 + (avm_alu_div_u16_r1 * FF(65536))) + + (avm_alu_div_u16_r2 * FF(4294967296UL))) + + (avm_alu_div_u16_r3 * FF(281474976710656UL))))); + tmp *= scaling_factor; + std::get<81>(evals) += tmp; + } + // Contribution 82 + { + Avm_DECLARE_VIEWS(82); + + auto tmp = + (avm_alu_divisor_hi - (avm_alu_op_div_std * (((avm_alu_div_u16_r4 + (avm_alu_div_u16_r5 * FF(65536))) + + (avm_alu_div_u16_r6 * FF(4294967296UL))) + + (avm_alu_div_u16_r7 * FF(281474976710656UL))))); + tmp *= scaling_factor; + std::get<82>(evals) += tmp; + } + // Contribution 83 + { + Avm_DECLARE_VIEWS(83); + + auto tmp = (avm_alu_quotient_lo - + (avm_alu_op_div_std * (((avm_alu_div_u16_r0_shift + (avm_alu_div_u16_r1_shift * FF(65536))) + + (avm_alu_div_u16_r2_shift * FF(4294967296UL))) + + (avm_alu_div_u16_r3_shift * FF(281474976710656UL))))); + tmp *= scaling_factor; + std::get<83>(evals) += tmp; + } + // Contribution 84 + { + Avm_DECLARE_VIEWS(84); + + auto tmp = (avm_alu_quotient_hi - + (avm_alu_op_div_std * (((avm_alu_div_u16_r4_shift + (avm_alu_div_u16_r5_shift * FF(65536))) + + (avm_alu_div_u16_r6_shift * FF(4294967296UL))) + + (avm_alu_div_u16_r7_shift * FF(281474976710656UL))))); + tmp *= scaling_factor; + std::get<84>(evals) += tmp; + } + // Contribution 85 + { + Avm_DECLARE_VIEWS(85); + + auto tmp = + (avm_alu_partial_prod_lo - + (avm_alu_op_div_std * + ((((avm_alu_u8_r0_shift + (avm_alu_u8_r1_shift * FF(256))) + (avm_alu_u16_r0_shift * FF(65536))) + + (avm_alu_u16_r1_shift * FF(4294967296UL))) + + (avm_alu_u16_r2_shift * FF(281474976710656UL))))); + tmp *= scaling_factor; + std::get<85>(evals) += tmp; + } + // Contribution 86 + { + Avm_DECLARE_VIEWS(86); + + auto tmp = (avm_alu_partial_prod_hi - + (avm_alu_op_div_std * (((avm_alu_u16_r3_shift + (avm_alu_u16_r4_shift * FF(65536))) + + (avm_alu_u16_r5_shift * FF(4294967296UL))) + + (avm_alu_u16_r6_shift * FF(281474976710656UL))))); + tmp *= scaling_factor; + std::get<86>(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 681210ee41d..27319832d00 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -131,7 +131,7 @@ template class avm_mainImpl { 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, 3, 5, 4, 4, 3, 3, 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, + 3, 3, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 4, 4, 3, 3, 3, 3, 3, 4, 3, 3, 3, 2, }; template @@ -451,7 +451,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(38); - auto tmp = (avm_main_sel_op_fdiv * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); + auto tmp = ((avm_main_sel_op_fdiv + avm_main_sel_op_div) * + (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); tmp *= scaling_factor; std::get<38>(evals) += tmp; } @@ -459,7 +460,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(39); - auto tmp = ((avm_main_sel_op_fdiv * avm_main_op_err) * (-avm_main_inv + FF(1))); + auto tmp = (((avm_main_sel_op_fdiv + avm_main_sel_op_div) * avm_main_op_err) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; std::get<39>(evals) += tmp; } @@ -483,7 +484,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(42); - auto tmp = (avm_main_op_err * (avm_main_sel_op_fdiv - FF(1))); + auto tmp = (avm_main_op_err * ((avm_main_sel_op_fdiv + avm_main_sel_op_div) - FF(1))); tmp *= scaling_factor; std::get<42>(evals) += tmp; } @@ -676,15 +677,16 @@ template class avm_mainImpl { 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_div) + - 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)))); + ((((((((((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_mul) + avm_main_sel_op_div) + + 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))) * + (-avm_main_op_err + FF(1)))); tmp *= scaling_factor; std::get<64>(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 5225e83adfa..8b595c5ab27 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -14,6 +14,17 @@ [[maybe_unused]] auto avm_alu_clk = View(new_term.avm_alu_clk); \ [[maybe_unused]] auto avm_alu_cmp_rng_ctr = View(new_term.avm_alu_cmp_rng_ctr); \ [[maybe_unused]] auto avm_alu_cmp_sel = View(new_term.avm_alu_cmp_sel); \ + [[maybe_unused]] auto avm_alu_div_rng_chk_selector = View(new_term.avm_alu_div_rng_chk_selector); \ + [[maybe_unused]] auto avm_alu_div_u16_r0 = View(new_term.avm_alu_div_u16_r0); \ + [[maybe_unused]] auto avm_alu_div_u16_r1 = View(new_term.avm_alu_div_u16_r1); \ + [[maybe_unused]] auto avm_alu_div_u16_r2 = View(new_term.avm_alu_div_u16_r2); \ + [[maybe_unused]] auto avm_alu_div_u16_r3 = View(new_term.avm_alu_div_u16_r3); \ + [[maybe_unused]] auto avm_alu_div_u16_r4 = View(new_term.avm_alu_div_u16_r4); \ + [[maybe_unused]] auto avm_alu_div_u16_r5 = View(new_term.avm_alu_div_u16_r5); \ + [[maybe_unused]] auto avm_alu_div_u16_r6 = View(new_term.avm_alu_div_u16_r6); \ + [[maybe_unused]] auto avm_alu_div_u16_r7 = View(new_term.avm_alu_div_u16_r7); \ + [[maybe_unused]] auto avm_alu_divisor_hi = View(new_term.avm_alu_divisor_hi); \ + [[maybe_unused]] auto avm_alu_divisor_lo = View(new_term.avm_alu_divisor_lo); \ [[maybe_unused]] auto avm_alu_ff_tag = View(new_term.avm_alu_ff_tag); \ [[maybe_unused]] auto avm_alu_ia = View(new_term.avm_alu_ia); \ [[maybe_unused]] auto avm_alu_ib = View(new_term.avm_alu_ib); \ @@ -23,6 +34,8 @@ [[maybe_unused]] auto avm_alu_op_cast = View(new_term.avm_alu_op_cast); \ [[maybe_unused]] auto avm_alu_op_cast_prev = View(new_term.avm_alu_op_cast_prev); \ [[maybe_unused]] auto avm_alu_op_div = View(new_term.avm_alu_op_div); \ + [[maybe_unused]] auto avm_alu_op_div_a_lt_b = View(new_term.avm_alu_op_div_a_lt_b); \ + [[maybe_unused]] auto avm_alu_op_div_std = View(new_term.avm_alu_op_div_std); \ [[maybe_unused]] auto avm_alu_op_eq = View(new_term.avm_alu_op_eq); \ [[maybe_unused]] auto avm_alu_op_eq_diff_inv = View(new_term.avm_alu_op_eq_diff_inv); \ [[maybe_unused]] auto avm_alu_op_lt = View(new_term.avm_alu_op_lt); \ @@ -38,6 +51,11 @@ [[maybe_unused]] auto avm_alu_p_sub_a_lo = View(new_term.avm_alu_p_sub_a_lo); \ [[maybe_unused]] auto avm_alu_p_sub_b_hi = View(new_term.avm_alu_p_sub_b_hi); \ [[maybe_unused]] auto avm_alu_p_sub_b_lo = View(new_term.avm_alu_p_sub_b_lo); \ + [[maybe_unused]] auto avm_alu_partial_prod_hi = View(new_term.avm_alu_partial_prod_hi); \ + [[maybe_unused]] auto avm_alu_partial_prod_lo = View(new_term.avm_alu_partial_prod_lo); \ + [[maybe_unused]] auto avm_alu_quotient_hi = View(new_term.avm_alu_quotient_hi); \ + [[maybe_unused]] auto avm_alu_quotient_lo = View(new_term.avm_alu_quotient_lo); \ + [[maybe_unused]] auto avm_alu_remainder = View(new_term.avm_alu_remainder); \ [[maybe_unused]] auto avm_alu_res_hi = View(new_term.avm_alu_res_hi); \ [[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); \ @@ -215,6 +233,14 @@ [[maybe_unused]] auto lookup_u16_12 = View(new_term.lookup_u16_12); \ [[maybe_unused]] auto lookup_u16_13 = View(new_term.lookup_u16_13); \ [[maybe_unused]] auto lookup_u16_14 = View(new_term.lookup_u16_14); \ + [[maybe_unused]] auto lookup_div_u16_0 = View(new_term.lookup_div_u16_0); \ + [[maybe_unused]] auto lookup_div_u16_1 = View(new_term.lookup_div_u16_1); \ + [[maybe_unused]] auto lookup_div_u16_2 = View(new_term.lookup_div_u16_2); \ + [[maybe_unused]] auto lookup_div_u16_3 = View(new_term.lookup_div_u16_3); \ + [[maybe_unused]] auto lookup_div_u16_4 = View(new_term.lookup_div_u16_4); \ + [[maybe_unused]] auto lookup_div_u16_5 = View(new_term.lookup_div_u16_5); \ + [[maybe_unused]] auto lookup_div_u16_6 = View(new_term.lookup_div_u16_6); \ + [[maybe_unused]] auto lookup_div_u16_7 = View(new_term.lookup_div_u16_7); \ [[maybe_unused]] auto lookup_byte_lengths_counts = View(new_term.lookup_byte_lengths_counts); \ [[maybe_unused]] auto lookup_byte_operations_counts = View(new_term.lookup_byte_operations_counts); \ [[maybe_unused]] auto incl_main_tag_err_counts = View(new_term.incl_main_tag_err_counts); \ @@ -240,6 +266,14 @@ [[maybe_unused]] auto lookup_u16_12_counts = View(new_term.lookup_u16_12_counts); \ [[maybe_unused]] auto lookup_u16_13_counts = View(new_term.lookup_u16_13_counts); \ [[maybe_unused]] auto lookup_u16_14_counts = View(new_term.lookup_u16_14_counts); \ + [[maybe_unused]] auto lookup_div_u16_0_counts = View(new_term.lookup_div_u16_0_counts); \ + [[maybe_unused]] auto lookup_div_u16_1_counts = View(new_term.lookup_div_u16_1_counts); \ + [[maybe_unused]] auto lookup_div_u16_2_counts = View(new_term.lookup_div_u16_2_counts); \ + [[maybe_unused]] auto lookup_div_u16_3_counts = View(new_term.lookup_div_u16_3_counts); \ + [[maybe_unused]] auto lookup_div_u16_4_counts = View(new_term.lookup_div_u16_4_counts); \ + [[maybe_unused]] auto lookup_div_u16_5_counts = View(new_term.lookup_div_u16_5_counts); \ + [[maybe_unused]] auto lookup_div_u16_6_counts = View(new_term.lookup_div_u16_6_counts); \ + [[maybe_unused]] auto lookup_div_u16_7_counts = View(new_term.lookup_div_u16_7_counts); \ [[maybe_unused]] auto avm_alu_a_hi_shift = View(new_term.avm_alu_a_hi_shift); \ [[maybe_unused]] auto avm_alu_a_lo_shift = View(new_term.avm_alu_a_lo_shift); \ [[maybe_unused]] auto avm_alu_alu_sel_shift = View(new_term.avm_alu_alu_sel_shift); \ @@ -247,9 +281,19 @@ [[maybe_unused]] auto avm_alu_b_lo_shift = View(new_term.avm_alu_b_lo_shift); \ [[maybe_unused]] auto avm_alu_cmp_rng_ctr_shift = View(new_term.avm_alu_cmp_rng_ctr_shift); \ [[maybe_unused]] auto avm_alu_cmp_sel_shift = View(new_term.avm_alu_cmp_sel_shift); \ + [[maybe_unused]] auto avm_alu_div_rng_chk_selector_shift = View(new_term.avm_alu_div_rng_chk_selector_shift); \ + [[maybe_unused]] auto avm_alu_div_u16_r0_shift = View(new_term.avm_alu_div_u16_r0_shift); \ + [[maybe_unused]] auto avm_alu_div_u16_r1_shift = View(new_term.avm_alu_div_u16_r1_shift); \ + [[maybe_unused]] auto avm_alu_div_u16_r2_shift = View(new_term.avm_alu_div_u16_r2_shift); \ + [[maybe_unused]] auto avm_alu_div_u16_r3_shift = View(new_term.avm_alu_div_u16_r3_shift); \ + [[maybe_unused]] auto avm_alu_div_u16_r4_shift = View(new_term.avm_alu_div_u16_r4_shift); \ + [[maybe_unused]] auto avm_alu_div_u16_r5_shift = View(new_term.avm_alu_div_u16_r5_shift); \ + [[maybe_unused]] auto avm_alu_div_u16_r6_shift = View(new_term.avm_alu_div_u16_r6_shift); \ + [[maybe_unused]] auto avm_alu_div_u16_r7_shift = View(new_term.avm_alu_div_u16_r7_shift); \ [[maybe_unused]] auto avm_alu_op_add_shift = View(new_term.avm_alu_op_add_shift); \ [[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_div_shift = View(new_term.avm_alu_op_div_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); \ diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_0.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_0.hpp new file mode 100644 index 00000000000..67284e42972 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_0.hpp @@ -0,0 +1,166 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_div_u16_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 = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 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_div_rng_chk_selector == 1 || in.avm_main_sel_rng_16 == 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_div_rng_chk_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + 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_div_u16_0, + in.lookup_div_u16_0_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r0, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_div_u16_0, + in.lookup_div_u16_0_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r0, + in.avm_main_clk); + } +}; + +template using lookup_div_u16_0_relation = GenericLookupRelation; +template using lookup_div_u16_0 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_1.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_1.hpp new file mode 100644 index 00000000000..38c6fd614f8 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_1.hpp @@ -0,0 +1,166 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_div_u16_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 = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 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_div_rng_chk_selector == 1 || in.avm_main_sel_rng_16 == 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_div_rng_chk_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + 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_div_u16_1, + in.lookup_div_u16_1_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r1, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_div_u16_1, + in.lookup_div_u16_1_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r1, + in.avm_main_clk); + } +}; + +template using lookup_div_u16_1_relation = GenericLookupRelation; +template using lookup_div_u16_1 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_2.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_2.hpp new file mode 100644 index 00000000000..36c347a5ba9 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_2.hpp @@ -0,0 +1,166 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_div_u16_2_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 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_div_rng_chk_selector == 1 || in.avm_main_sel_rng_16 == 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_div_rng_chk_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + 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_div_u16_2, + in.lookup_div_u16_2_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r2, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_div_u16_2, + in.lookup_div_u16_2_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r2, + in.avm_main_clk); + } +}; + +template using lookup_div_u16_2_relation = GenericLookupRelation; +template using lookup_div_u16_2 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_3.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_3.hpp new file mode 100644 index 00000000000..e167bae69bb --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_3.hpp @@ -0,0 +1,166 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_div_u16_3_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 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_div_rng_chk_selector == 1 || in.avm_main_sel_rng_16 == 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_div_rng_chk_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + 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_div_u16_3, + in.lookup_div_u16_3_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r3, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_div_u16_3, + in.lookup_div_u16_3_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r3, + in.avm_main_clk); + } +}; + +template using lookup_div_u16_3_relation = GenericLookupRelation; +template using lookup_div_u16_3 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_4.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_4.hpp new file mode 100644 index 00000000000..6248bc098d6 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_4.hpp @@ -0,0 +1,166 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_div_u16_4_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 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_div_rng_chk_selector == 1 || in.avm_main_sel_rng_16 == 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_div_rng_chk_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + 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_div_u16_4, + in.lookup_div_u16_4_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r4, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_div_u16_4, + in.lookup_div_u16_4_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r4, + in.avm_main_clk); + } +}; + +template using lookup_div_u16_4_relation = GenericLookupRelation; +template using lookup_div_u16_4 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_5.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_5.hpp new file mode 100644 index 00000000000..052eafcaa3b --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_5.hpp @@ -0,0 +1,166 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_div_u16_5_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 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_div_rng_chk_selector == 1 || in.avm_main_sel_rng_16 == 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_div_rng_chk_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + 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_div_u16_5, + in.lookup_div_u16_5_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r5, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_div_u16_5, + in.lookup_div_u16_5_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r5, + in.avm_main_clk); + } +}; + +template using lookup_div_u16_5_relation = GenericLookupRelation; +template using lookup_div_u16_5 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_6.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_6.hpp new file mode 100644 index 00000000000..c52d71bdb99 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_6.hpp @@ -0,0 +1,166 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_div_u16_6_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 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_div_rng_chk_selector == 1 || in.avm_main_sel_rng_16 == 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_div_rng_chk_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + 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_div_u16_6, + in.lookup_div_u16_6_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r6, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_div_u16_6, + in.lookup_div_u16_6_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r6, + in.avm_main_clk); + } +}; + +template using lookup_div_u16_6_relation = GenericLookupRelation; +template using lookup_div_u16_6 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_7.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_7.hpp new file mode 100644 index 00000000000..dde1e6f54b4 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_div_u16_7.hpp @@ -0,0 +1,166 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_div_u16_7_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 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_div_rng_chk_selector == 1 || in.avm_main_sel_rng_16 == 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_div_rng_chk_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + 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_div_u16_7, + in.lookup_div_u16_7_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r7, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_div_u16_7, + in.lookup_div_u16_7_counts, + in.avm_alu_div_rng_chk_selector, + in.avm_main_sel_rng_16, + in.avm_alu_div_u16_r7, + in.avm_main_clk); + } +}; + +template using lookup_div_u16_7_relation = GenericLookupRelation; +template using lookup_div_u16_7 = 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 497d4143f44..9a055c79aba 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 @@ -1,4 +1,5 @@ #include "avm_alu_trace.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" namespace bb::avm_trace { @@ -50,7 +51,7 @@ bool AvmAluTraceBuilder::is_range_check_required() const 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); + r.alu_op_lte || r.alu_op_shr || r.alu_op_shl || r.alu_op_cast || r.alu_op_div); } /** @@ -468,11 +469,11 @@ std::tuple> AvmAluTraceBuilder::to_al } /** - * @brief This is a helper function that is used to generate the range check entries for the comparison operation - * (LT/LTE opcodes). This additionally increments the counts for the corresponding range lookups entries. + * @brief This is a helper function that is used to generate the range check entries for operations that require + * multi-row range checks This additionally increments the counts for the corresponding range lookups entries. * @param row The initial row where the comparison operation was performed * @param hi_lo_limbs The vector of 128-bit limbs hi and lo pairs of limbs that will be range checked. - * @return A vector of AluTraceEntry rows for the range checks for the comparison operation. + * @return A vector of AluTraceEntry rows for the range checks for the operation. */ std::vector AvmAluTraceBuilder::cmp_range_check_helper( AvmAluTraceBuilder::AluTraceEntry row, std::vector hi_lo_limbs) @@ -544,7 +545,7 @@ std::tuple gt_witness(uint256_t const& a, uint256_t // where q = 1 if a > b and q = 0 if a <= b 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); + uint256_t two_pow_126 = uint256_t(1) << uint256_t(128); auto [a_lo, a_hi] = decompose(a, 128); auto [b_lo, b_hi] = decompose(b, 128); bool isGT = a > b; @@ -553,7 +554,7 @@ std::tuple gt_or_lte_witness(uint256_t const& a, uin } bool borrow = b_lo < a_lo; auto borrow_u256 = uint256_t(static_cast(borrow)); - uint256_t r_lo = b_lo - a_lo + borrow_u256 * two_pow_128; + uint256_t r_lo = b_lo - a_lo + borrow_u256 * two_pow_126; uint256_t r_hi = b_hi - a_hi - borrow_u256; return std::make_tuple(r_lo, r_hi, borrow); } @@ -963,4 +964,102 @@ FF AvmAluTraceBuilder::op_shl(FF const& a, FF const& b, AvmMemoryTag in_tag, uin }); return c; } +FF AvmAluTraceBuilder::op_div(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk) +{ + uint256_t a_u256{ a }; + uint256_t b_u256{ b }; + uint256_t c_u256 = a_u256 / b_u256; + uint256_t rem_u256 = a_u256 % b_u256; + + // If dividing by zero, don't add any rows in the ALU, the error will be handled in the main trace + if (b_u256 == 0) { + return 0; + } + + if (a_u256 < b_u256) { + // If a < b, the result is trivially 0 + uint256_t rng_chk_lo = b_u256 - a_u256 - 1; + auto [u8_r0, u8_r1, u16_reg] = to_alu_slice_registers(rng_chk_lo); + alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry({ + .alu_clk = clk, + .alu_op_div = 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, + .alu_ic = 0, + .alu_u8_r0 = u8_r0, + .alu_u8_r1 = u8_r1, + .alu_u16_reg = u16_reg, + .hi_lo_limbs = { rng_chk_lo, 0, 0, 0, 0, 0 }, + .remainder = a, + + })); + return 0; + } + // Decompose a and primality check that b*c < p when a is a 256-bit integer + auto [a_lo, a_hi] = decompose(b_u256 * c_u256, 128); + auto [p_sub_a_lo, p_sub_a_hi, p_a_borrow] = gt_witness(FF::modulus, b_u256 * c_u256); + // Decompose the divisor + auto [divisor_lo, divisor_hi] = decompose(b_u256, 64); + // Decompose the quotient + auto [quotient_lo, quotient_hi] = decompose(c_u256, 64); + uint256_t partial_prod = divisor_lo * quotient_hi + divisor_hi * quotient_lo; + // Decompose the partial product + auto [partial_prod_lo, partial_prod_hi] = decompose(partial_prod, 64); + + FF b_hi = b_u256 - rem_u256 - 1; + + // 64 bit range checks for the divisor and quotient limbs + // Spread over two rows + std::array div_u64_rng_chk; + std::array div_u64_rng_chk_shifted; + for (size_t i = 0; i < 4; i++) { + div_u64_rng_chk.at(i) = uint16_t(divisor_lo >> (16 * i)); + div_u64_rng_chk.at(i + 4) = uint16_t(divisor_hi >> (16 * i)); + div_u64_range_chk_counters[i][uint16_t(divisor_lo >> (16 * i))]++; + div_u64_range_chk_counters[i + 4][uint16_t(divisor_hi >> (16 * i))]++; + + div_u64_rng_chk_shifted.at(i) = uint16_t(quotient_lo >> (16 * i)); + div_u64_rng_chk_shifted.at(i + 4) = uint16_t(quotient_hi >> (16 * i)); + div_u64_range_chk_counters[i][uint16_t(quotient_lo >> (16 * i))]++; + div_u64_range_chk_counters[i + 4][uint16_t(quotient_hi >> (16 * i))]++; + } + + // Each hi and lo limb is range checked over 128 bits + // Load the range check values into the ALU registers + auto hi_lo_limbs = std::vector{ a_lo, a_hi, partial_prod, b_hi, p_sub_a_lo, p_sub_a_hi }; + AvmAluTraceBuilder::AluTraceEntry row{ + .alu_clk = clk, + .alu_op_div = 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, + .alu_ic = FF{ c_u256 }, + .remainder = rem_u256, + .divisor_lo = divisor_lo, + .divisor_hi = divisor_hi, + .quotient_lo = quotient_lo, + .quotient_hi = quotient_hi, + .partial_prod_lo = partial_prod_lo, + .partial_prod_hi = partial_prod_hi, + .div_u64_range_chk_sel = true, + .div_u64_range_chk = div_u64_rng_chk, + + }; + // We perform the range checks here + std::vector rows = cmp_range_check_helper(row, hi_lo_limbs); + // Add the range checks for the quotient limbs in the row after the division operation + rows.at(1).div_u64_range_chk = div_u64_rng_chk_shifted; + rows.at(1).div_u64_range_chk_sel = true; + alu_trace.insert(alu_trace.end(), rows.begin(), rows.end()); + return c_u256; +} } // 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 e01e8e53b4b..42d2a550fea 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 @@ -21,6 +21,7 @@ class AvmAluTraceBuilder { bool alu_op_cast_prev = false; bool alu_op_shr = false; bool alu_op_shl = false; + bool alu_op_div = false; bool alu_ff_tag = false; bool alu_u8_tag = false; @@ -55,11 +56,25 @@ class AvmAluTraceBuilder { uint8_t mem_tag_bits = 0; uint8_t mem_tag_sub_shift = 0; bool shift_lt_bit_len = true; + FF quot_div_rem_lo{}; + FF quot_div_rem_hi{}; + + // Div Operations + FF remainder{}; + FF divisor_lo{}; + FF divisor_hi{}; + FF quotient_lo{}; + FF quotient_hi{}; + FF partial_prod_lo{}; + FF partial_prod_hi{}; + bool div_u64_range_chk_sel = false; + std::array div_u64_range_chk{}; }; std::array, 2> u8_range_chk_counters; std::array, 2> u8_pow_2_counters; std::array, 15> u16_range_chk_counters; + std::array, 8> div_u64_range_chk_counters; AvmAluTraceBuilder(); void reset(); @@ -75,6 +90,7 @@ class AvmAluTraceBuilder { 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); + FF op_div(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); 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 7cf6154fac8..c472af776a3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -110,6 +110,13 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(2)), std::get(inst.operands.at(3))); break; + case OpCode::DIV: + trace_builder.op_div(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 - Comparators case OpCode::EQ: trace_builder.op_eq(std::get(inst.operands.at(0)), diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp index 39f54fe80b8..6ec6782aa6a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -1118,6 +1118,84 @@ void AvmTraceBuilder::op_cast(uint8_t indirect, uint32_t a_offset, uint32_t dst_ .avm_main_w_in_tag = FF(static_cast(dst_tag)), }); } +/** + * @brief Integer division with direct or indirect memory access. + * + * @param indirect A byte encoding information about indirect/direct memory access. + * @param a_offset An index in memory pointing to the first operand of the division. + * @param b_offset An index in memory pointing to the second operand of the division. + * @param dst_offset An index in memory pointing to the output of the division. + * @param in_tag The instruction memory tag of the operands. + */ +void AvmTraceBuilder::op_div( + 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; + + // a / b = c + FF a = read_a.val; + FF b = read_b.val; + + // In case of a memory tag error, we do not perform the computation. + // Therefore, we do not create any entry in ALU table and store the value 0 as + // output (c) in memory. + FF c; + FF inv; + FF error; + + if (!b.is_zero()) { + // If b is not zero, we prove it is not by providing its inverse as well + inv = b.invert(); + c = tag_match ? alu_trace_builder.op_div(a, b, in_tag, clk) : FF(0); + error = 0; + } else { + inv = 1; + c = 0; + error = 1; + } + + // 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_inv = tag_match ? inv : FF(1), + .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_op_err = tag_match ? error : 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_div = FF(1), + .avm_main_tag_err = FF(static_cast(!tag_match)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), + }); +} /** * @brief CALLDATACOPY opcode with direct or indirect memory access, i.e., @@ -1657,6 +1735,7 @@ std::vector AvmTraceBuilder::finalize() 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_op_div = FF(static_cast(src.alu_op_div)); dest.avm_alu_ff_tag = FF(static_cast(src.alu_ff_tag)); dest.avm_alu_u8_tag = FF(static_cast(src.alu_u8_tag)); @@ -1694,6 +1773,15 @@ std::vector AvmTraceBuilder::finalize() dest.avm_alu_u16_r13 = FF(src.alu_u16_reg.at(13)); dest.avm_alu_u16_r14 = FF(src.alu_u16_reg.at(14)); + dest.avm_alu_div_rng_chk_selector = FF(static_cast(src.div_u64_range_chk_sel)); + dest.avm_alu_div_u16_r0 = FF(src.div_u64_range_chk.at(0)); + dest.avm_alu_div_u16_r1 = FF(src.div_u64_range_chk.at(1)); + dest.avm_alu_div_u16_r2 = FF(src.div_u64_range_chk.at(2)); + dest.avm_alu_div_u16_r3 = FF(src.div_u64_range_chk.at(3)); + dest.avm_alu_div_u16_r4 = FF(src.div_u64_range_chk.at(4)); + dest.avm_alu_div_u16_r5 = FF(src.div_u64_range_chk.at(5)); + dest.avm_alu_div_u16_r6 = FF(src.div_u64_range_chk.at(6)); + dest.avm_alu_div_u16_r7 = FF(src.div_u64_range_chk.at(7)); dest.avm_alu_op_eq_diff_inv = FF(src.alu_op_eq_diff_inv); // Not all rows in ALU are enabled with a selector. For instance, @@ -1716,10 +1804,27 @@ std::vector AvmTraceBuilder::finalize() dest.avm_alu_p_a_borrow = FF(static_cast(src.p_a_borrow)); dest.avm_alu_p_b_borrow = FF(static_cast(src.p_b_borrow)); dest.avm_alu_borrow = FF(static_cast(src.borrow)); - dest.avm_alu_rng_chk_sel = FF(static_cast(src.rng_chk_sel)); dest.avm_alu_cmp_rng_ctr = FF(static_cast(src.cmp_rng_ctr)); dest.avm_alu_rng_chk_lookup_selector = FF(1); } + if (dest.avm_alu_op_div == FF(1)) { + dest.avm_alu_op_div_std = uint256_t(src.alu_ia) >= uint256_t(src.alu_ib); + dest.avm_alu_op_div_a_lt_b = uint256_t(src.alu_ia) < uint256_t(src.alu_ib); + dest.avm_alu_rng_chk_lookup_selector = FF(1); + dest.avm_alu_a_lo = FF(src.hi_lo_limbs.at(0)); + dest.avm_alu_a_hi = FF(src.hi_lo_limbs.at(1)); + dest.avm_alu_b_lo = FF(src.hi_lo_limbs.at(2)); + dest.avm_alu_b_hi = FF(src.hi_lo_limbs.at(3)); + dest.avm_alu_p_sub_a_lo = FF(src.hi_lo_limbs.at(4)); + dest.avm_alu_p_sub_a_hi = FF(src.hi_lo_limbs.at(5)); + dest.avm_alu_remainder = src.remainder; + dest.avm_alu_divisor_lo = src.divisor_lo; + dest.avm_alu_divisor_hi = src.divisor_hi; + dest.avm_alu_quotient_lo = src.quotient_lo; + dest.avm_alu_quotient_hi = src.quotient_hi; + dest.avm_alu_partial_prod_lo = src.partial_prod_lo; + dest.avm_alu_partial_prod_hi = src.partial_prod_hi; + } 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_rng_chk_lookup_selector = FF(1); @@ -1763,8 +1868,8 @@ std::vector AvmTraceBuilder::finalize() 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 == 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_sel_op_shl == FF(1) || r.avm_main_sel_op_div == FF(1)) && + r.avm_main_tag_err == FF(0) && r.avm_main_op_err == FF(0)) { r.avm_main_alu_sel = FF(1); } @@ -1800,6 +1905,15 @@ std::vector AvmTraceBuilder::finalize() r.lookup_mem_rng_chk_hi_counts = mem_rng_check_hi_counts[static_cast(i)]; r.lookup_mem_rng_chk_lo_counts = mem_rng_check_lo_counts[static_cast(i)]; + r.lookup_div_u16_0_counts = alu_trace_builder.div_u64_range_chk_counters[0][static_cast(i)]; + r.lookup_div_u16_1_counts = alu_trace_builder.div_u64_range_chk_counters[1][static_cast(i)]; + r.lookup_div_u16_2_counts = alu_trace_builder.div_u64_range_chk_counters[2][static_cast(i)]; + r.lookup_div_u16_3_counts = alu_trace_builder.div_u64_range_chk_counters[3][static_cast(i)]; + r.lookup_div_u16_4_counts = alu_trace_builder.div_u64_range_chk_counters[4][static_cast(i)]; + r.lookup_div_u16_5_counts = alu_trace_builder.div_u64_range_chk_counters[5][static_cast(i)]; + r.lookup_div_u16_6_counts = alu_trace_builder.div_u64_range_chk_counters[6][static_cast(i)]; + r.lookup_div_u16_7_counts = alu_trace_builder.div_u64_range_chk_counters[7][static_cast(i)]; + r.avm_main_clk = FF(static_cast(i)); r.avm_main_sel_rng_16 = FF(1); } 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 d6ba959df17..88b3ced5578 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -82,6 +82,9 @@ class AvmTraceBuilder { // store the result in address given by dst_offset. void op_cast(uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, AvmMemoryTag dst_tag); + // Integer Division with direct or indirect memory access. + void op_div(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Jump to a given program counter. void jump(uint32_t jmp_dest); 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 8e46d8e00f4..f8b40095206 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,14 @@ #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_div_u16_0.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_1.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_2.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_3.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_4.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_5.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_6.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_7.hpp" #include "barretenberg/relations/generated/avm/lookup_mem_rng_chk_hi.hpp" #include "barretenberg/relations/generated/avm/lookup_mem_rng_chk_lo.hpp" #include "barretenberg/relations/generated/avm/lookup_pow_2_0.hpp" @@ -67,6 +75,17 @@ template struct AvmFullRow { FF avm_alu_clk{}; FF avm_alu_cmp_rng_ctr{}; FF avm_alu_cmp_sel{}; + FF avm_alu_div_rng_chk_selector{}; + FF avm_alu_div_u16_r0{}; + FF avm_alu_div_u16_r1{}; + FF avm_alu_div_u16_r2{}; + FF avm_alu_div_u16_r3{}; + FF avm_alu_div_u16_r4{}; + FF avm_alu_div_u16_r5{}; + FF avm_alu_div_u16_r6{}; + FF avm_alu_div_u16_r7{}; + FF avm_alu_divisor_hi{}; + FF avm_alu_divisor_lo{}; FF avm_alu_ff_tag{}; FF avm_alu_ia{}; FF avm_alu_ib{}; @@ -76,6 +95,8 @@ template struct AvmFullRow { FF avm_alu_op_cast{}; FF avm_alu_op_cast_prev{}; FF avm_alu_op_div{}; + FF avm_alu_op_div_a_lt_b{}; + FF avm_alu_op_div_std{}; FF avm_alu_op_eq{}; FF avm_alu_op_eq_diff_inv{}; FF avm_alu_op_lt{}; @@ -91,6 +112,11 @@ template struct AvmFullRow { FF avm_alu_p_sub_a_lo{}; FF avm_alu_p_sub_b_hi{}; FF avm_alu_p_sub_b_lo{}; + FF avm_alu_partial_prod_hi{}; + FF avm_alu_partial_prod_lo{}; + FF avm_alu_quotient_hi{}; + FF avm_alu_quotient_lo{}; + FF avm_alu_remainder{}; FF avm_alu_res_hi{}; FF avm_alu_res_lo{}; FF avm_alu_rng_chk_lookup_selector{}; @@ -268,6 +294,14 @@ template struct AvmFullRow { FF lookup_u16_12{}; FF lookup_u16_13{}; FF lookup_u16_14{}; + FF lookup_div_u16_0{}; + FF lookup_div_u16_1{}; + FF lookup_div_u16_2{}; + FF lookup_div_u16_3{}; + FF lookup_div_u16_4{}; + FF lookup_div_u16_5{}; + FF lookup_div_u16_6{}; + FF lookup_div_u16_7{}; FF lookup_byte_lengths_counts{}; FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; @@ -293,6 +327,14 @@ template struct AvmFullRow { FF lookup_u16_12_counts{}; FF lookup_u16_13_counts{}; FF lookup_u16_14_counts{}; + FF lookup_div_u16_0_counts{}; + FF lookup_div_u16_1_counts{}; + FF lookup_div_u16_2_counts{}; + FF lookup_div_u16_3_counts{}; + FF lookup_div_u16_4_counts{}; + FF lookup_div_u16_5_counts{}; + FF lookup_div_u16_6_counts{}; + FF lookup_div_u16_7_counts{}; FF avm_alu_a_hi_shift{}; FF avm_alu_a_lo_shift{}; FF avm_alu_alu_sel_shift{}; @@ -300,9 +342,19 @@ template struct AvmFullRow { FF avm_alu_b_lo_shift{}; FF avm_alu_cmp_rng_ctr_shift{}; FF avm_alu_cmp_sel_shift{}; + FF avm_alu_div_rng_chk_selector_shift{}; + FF avm_alu_div_u16_r0_shift{}; + FF avm_alu_div_u16_r1_shift{}; + FF avm_alu_div_u16_r2_shift{}; + FF avm_alu_div_u16_r3_shift{}; + FF avm_alu_div_u16_r4_shift{}; + FF avm_alu_div_u16_r5_shift{}; + FF avm_alu_div_u16_r6_shift{}; + FF avm_alu_div_u16_r7_shift{}; FF avm_alu_op_add_shift{}; FF avm_alu_op_cast_prev_shift{}; FF avm_alu_op_cast_shift{}; + FF avm_alu_op_div_shift{}; FF avm_alu_op_mul_shift{}; FF avm_alu_op_shl_shift{}; FF avm_alu_op_shr_shift{}; @@ -347,8 +399,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 280; - static constexpr size_t num_polys = 238; + static constexpr size_t num_fixed_columns = 324; + static constexpr size_t num_polys = 272; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -376,6 +428,17 @@ class AvmCircuitBuilder { polys.avm_alu_clk[i] = rows[i].avm_alu_clk; polys.avm_alu_cmp_rng_ctr[i] = rows[i].avm_alu_cmp_rng_ctr; polys.avm_alu_cmp_sel[i] = rows[i].avm_alu_cmp_sel; + polys.avm_alu_div_rng_chk_selector[i] = rows[i].avm_alu_div_rng_chk_selector; + polys.avm_alu_div_u16_r0[i] = rows[i].avm_alu_div_u16_r0; + polys.avm_alu_div_u16_r1[i] = rows[i].avm_alu_div_u16_r1; + polys.avm_alu_div_u16_r2[i] = rows[i].avm_alu_div_u16_r2; + polys.avm_alu_div_u16_r3[i] = rows[i].avm_alu_div_u16_r3; + polys.avm_alu_div_u16_r4[i] = rows[i].avm_alu_div_u16_r4; + polys.avm_alu_div_u16_r5[i] = rows[i].avm_alu_div_u16_r5; + polys.avm_alu_div_u16_r6[i] = rows[i].avm_alu_div_u16_r6; + polys.avm_alu_div_u16_r7[i] = rows[i].avm_alu_div_u16_r7; + polys.avm_alu_divisor_hi[i] = rows[i].avm_alu_divisor_hi; + polys.avm_alu_divisor_lo[i] = rows[i].avm_alu_divisor_lo; polys.avm_alu_ff_tag[i] = rows[i].avm_alu_ff_tag; polys.avm_alu_ia[i] = rows[i].avm_alu_ia; polys.avm_alu_ib[i] = rows[i].avm_alu_ib; @@ -385,6 +448,8 @@ class AvmCircuitBuilder { polys.avm_alu_op_cast[i] = rows[i].avm_alu_op_cast; polys.avm_alu_op_cast_prev[i] = rows[i].avm_alu_op_cast_prev; polys.avm_alu_op_div[i] = rows[i].avm_alu_op_div; + polys.avm_alu_op_div_a_lt_b[i] = rows[i].avm_alu_op_div_a_lt_b; + polys.avm_alu_op_div_std[i] = rows[i].avm_alu_op_div_std; polys.avm_alu_op_eq[i] = rows[i].avm_alu_op_eq; polys.avm_alu_op_eq_diff_inv[i] = rows[i].avm_alu_op_eq_diff_inv; polys.avm_alu_op_lt[i] = rows[i].avm_alu_op_lt; @@ -400,6 +465,11 @@ class AvmCircuitBuilder { polys.avm_alu_p_sub_a_lo[i] = rows[i].avm_alu_p_sub_a_lo; polys.avm_alu_p_sub_b_hi[i] = rows[i].avm_alu_p_sub_b_hi; polys.avm_alu_p_sub_b_lo[i] = rows[i].avm_alu_p_sub_b_lo; + polys.avm_alu_partial_prod_hi[i] = rows[i].avm_alu_partial_prod_hi; + polys.avm_alu_partial_prod_lo[i] = rows[i].avm_alu_partial_prod_lo; + polys.avm_alu_quotient_hi[i] = rows[i].avm_alu_quotient_hi; + polys.avm_alu_quotient_lo[i] = rows[i].avm_alu_quotient_lo; + polys.avm_alu_remainder[i] = rows[i].avm_alu_remainder; polys.avm_alu_res_hi[i] = rows[i].avm_alu_res_hi; 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; @@ -567,6 +637,14 @@ class AvmCircuitBuilder { polys.lookup_u16_12_counts[i] = rows[i].lookup_u16_12_counts; polys.lookup_u16_13_counts[i] = rows[i].lookup_u16_13_counts; polys.lookup_u16_14_counts[i] = rows[i].lookup_u16_14_counts; + polys.lookup_div_u16_0_counts[i] = rows[i].lookup_div_u16_0_counts; + polys.lookup_div_u16_1_counts[i] = rows[i].lookup_div_u16_1_counts; + polys.lookup_div_u16_2_counts[i] = rows[i].lookup_div_u16_2_counts; + polys.lookup_div_u16_3_counts[i] = rows[i].lookup_div_u16_3_counts; + polys.lookup_div_u16_4_counts[i] = rows[i].lookup_div_u16_4_counts; + polys.lookup_div_u16_5_counts[i] = rows[i].lookup_div_u16_5_counts; + polys.lookup_div_u16_6_counts[i] = rows[i].lookup_div_u16_6_counts; + polys.lookup_div_u16_7_counts[i] = rows[i].lookup_div_u16_7_counts; } polys.avm_alu_a_hi_shift = Polynomial(polys.avm_alu_a_hi.shifted()); @@ -576,9 +654,19 @@ class AvmCircuitBuilder { polys.avm_alu_b_lo_shift = Polynomial(polys.avm_alu_b_lo.shifted()); polys.avm_alu_cmp_rng_ctr_shift = Polynomial(polys.avm_alu_cmp_rng_ctr.shifted()); polys.avm_alu_cmp_sel_shift = Polynomial(polys.avm_alu_cmp_sel.shifted()); + polys.avm_alu_div_rng_chk_selector_shift = Polynomial(polys.avm_alu_div_rng_chk_selector.shifted()); + polys.avm_alu_div_u16_r0_shift = Polynomial(polys.avm_alu_div_u16_r0.shifted()); + polys.avm_alu_div_u16_r1_shift = Polynomial(polys.avm_alu_div_u16_r1.shifted()); + polys.avm_alu_div_u16_r2_shift = Polynomial(polys.avm_alu_div_u16_r2.shifted()); + polys.avm_alu_div_u16_r3_shift = Polynomial(polys.avm_alu_div_u16_r3.shifted()); + polys.avm_alu_div_u16_r4_shift = Polynomial(polys.avm_alu_div_u16_r4.shifted()); + polys.avm_alu_div_u16_r5_shift = Polynomial(polys.avm_alu_div_u16_r5.shifted()); + polys.avm_alu_div_u16_r6_shift = Polynomial(polys.avm_alu_div_u16_r6.shifted()); + polys.avm_alu_div_u16_r7_shift = Polynomial(polys.avm_alu_div_u16_r7.shifted()); polys.avm_alu_op_add_shift = Polynomial(polys.avm_alu_op_add.shifted()); 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_div_shift = Polynomial(polys.avm_alu_op_div.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()); @@ -805,6 +893,30 @@ class AvmCircuitBuilder { if (!evaluate_logderivative.template operator()>("LOOKUP_U16_14")) { return false; } + if (!evaluate_logderivative.template operator()>("LOOKUP_DIV_U16_0")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_DIV_U16_1")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_DIV_U16_2")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_DIV_U16_3")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_DIV_U16_4")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_DIV_U16_5")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_DIV_U16_6")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_DIV_U16_7")) { + return false; + } return true; } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 08c3cffd783..1921397837f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -21,6 +21,14 @@ #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_div_u16_0.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_1.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_2.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_3.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_4.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_5.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_6.hpp" +#include "barretenberg/relations/generated/avm/lookup_div_u16_7.hpp" #include "barretenberg/relations/generated/avm/lookup_mem_rng_chk_hi.hpp" #include "barretenberg/relations/generated/avm/lookup_mem_rng_chk_lo.hpp" #include "barretenberg/relations/generated/avm/lookup_pow_2_0.hpp" @@ -73,11 +81,11 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 236; + static constexpr size_t NUM_WITNESS_ENTITIES = 270; 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 = 280; + static constexpr size_t NUM_ALL_ENTITIES = 324; using GrandProductRelations = std::tuple, perm_main_bin_relation, @@ -113,7 +121,15 @@ class AvmFlavor { lookup_u16_11_relation, lookup_u16_12_relation, lookup_u16_13_relation, - lookup_u16_14_relation>; + lookup_u16_14_relation, + lookup_div_u16_0_relation, + lookup_div_u16_1_relation, + lookup_div_u16_2_relation, + lookup_div_u16_3_relation, + lookup_div_u16_4_relation, + lookup_div_u16_5_relation, + lookup_div_u16_6_relation, + lookup_div_u16_7_relation>; using Relations = std::tuple, Avm_vm::avm_binary, @@ -153,7 +169,15 @@ class AvmFlavor { lookup_u16_11_relation, lookup_u16_12_relation, lookup_u16_13_relation, - lookup_u16_14_relation>; + lookup_u16_14_relation, + lookup_div_u16_0_relation, + lookup_div_u16_1_relation, + lookup_div_u16_2_relation, + lookup_div_u16_3_relation, + lookup_div_u16_4_relation, + lookup_div_u16_5_relation, + lookup_div_u16_6_relation, + lookup_div_u16_7_relation>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -197,6 +221,17 @@ class AvmFlavor { avm_alu_clk, avm_alu_cmp_rng_ctr, avm_alu_cmp_sel, + avm_alu_div_rng_chk_selector, + avm_alu_div_u16_r0, + avm_alu_div_u16_r1, + avm_alu_div_u16_r2, + avm_alu_div_u16_r3, + avm_alu_div_u16_r4, + avm_alu_div_u16_r5, + avm_alu_div_u16_r6, + avm_alu_div_u16_r7, + avm_alu_divisor_hi, + avm_alu_divisor_lo, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -206,6 +241,8 @@ class AvmFlavor { avm_alu_op_cast, avm_alu_op_cast_prev, avm_alu_op_div, + avm_alu_op_div_a_lt_b, + avm_alu_op_div_std, avm_alu_op_eq, avm_alu_op_eq_diff_inv, avm_alu_op_lt, @@ -221,6 +258,11 @@ class AvmFlavor { avm_alu_p_sub_a_lo, avm_alu_p_sub_b_hi, avm_alu_p_sub_b_lo, + avm_alu_partial_prod_hi, + avm_alu_partial_prod_lo, + avm_alu_quotient_hi, + avm_alu_quotient_lo, + avm_alu_remainder, avm_alu_res_hi, avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, @@ -398,6 +440,14 @@ class AvmFlavor { lookup_u16_12, lookup_u16_13, lookup_u16_14, + lookup_div_u16_0, + lookup_div_u16_1, + lookup_div_u16_2, + lookup_div_u16_3, + lookup_div_u16_4, + lookup_div_u16_5, + lookup_div_u16_6, + lookup_div_u16_7, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, @@ -422,7 +472,15 @@ class AvmFlavor { lookup_u16_11_counts, lookup_u16_12_counts, lookup_u16_13_counts, - lookup_u16_14_counts) + lookup_u16_14_counts, + lookup_div_u16_0_counts, + lookup_div_u16_1_counts, + lookup_div_u16_2_counts, + lookup_div_u16_3_counts, + lookup_div_u16_4_counts, + lookup_div_u16_5_counts, + lookup_div_u16_6_counts, + lookup_div_u16_7_counts) RefVector get_wires() { @@ -436,6 +494,17 @@ class AvmFlavor { avm_alu_clk, avm_alu_cmp_rng_ctr, avm_alu_cmp_sel, + avm_alu_div_rng_chk_selector, + avm_alu_div_u16_r0, + avm_alu_div_u16_r1, + avm_alu_div_u16_r2, + avm_alu_div_u16_r3, + avm_alu_div_u16_r4, + avm_alu_div_u16_r5, + avm_alu_div_u16_r6, + avm_alu_div_u16_r7, + avm_alu_divisor_hi, + avm_alu_divisor_lo, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -445,6 +514,8 @@ class AvmFlavor { avm_alu_op_cast, avm_alu_op_cast_prev, avm_alu_op_div, + avm_alu_op_div_a_lt_b, + avm_alu_op_div_std, avm_alu_op_eq, avm_alu_op_eq_diff_inv, avm_alu_op_lt, @@ -460,6 +531,11 @@ class AvmFlavor { avm_alu_p_sub_a_lo, avm_alu_p_sub_b_hi, avm_alu_p_sub_b_lo, + avm_alu_partial_prod_hi, + avm_alu_partial_prod_lo, + avm_alu_quotient_hi, + avm_alu_quotient_lo, + avm_alu_remainder, avm_alu_res_hi, avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, @@ -637,6 +713,14 @@ class AvmFlavor { lookup_u16_12, lookup_u16_13, lookup_u16_14, + lookup_div_u16_0, + lookup_div_u16_1, + lookup_div_u16_2, + lookup_div_u16_3, + lookup_div_u16_4, + lookup_div_u16_5, + lookup_div_u16_6, + lookup_div_u16_7, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, @@ -661,7 +745,15 @@ class AvmFlavor { lookup_u16_11_counts, lookup_u16_12_counts, lookup_u16_13_counts, - lookup_u16_14_counts }; + lookup_u16_14_counts, + lookup_div_u16_0_counts, + lookup_div_u16_1_counts, + lookup_div_u16_2_counts, + lookup_div_u16_3_counts, + lookup_div_u16_4_counts, + lookup_div_u16_5_counts, + lookup_div_u16_6_counts, + lookup_div_u16_7_counts }; }; }; @@ -680,6 +772,17 @@ class AvmFlavor { avm_alu_clk, avm_alu_cmp_rng_ctr, avm_alu_cmp_sel, + avm_alu_div_rng_chk_selector, + avm_alu_div_u16_r0, + avm_alu_div_u16_r1, + avm_alu_div_u16_r2, + avm_alu_div_u16_r3, + avm_alu_div_u16_r4, + avm_alu_div_u16_r5, + avm_alu_div_u16_r6, + avm_alu_div_u16_r7, + avm_alu_divisor_hi, + avm_alu_divisor_lo, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -689,6 +792,8 @@ class AvmFlavor { avm_alu_op_cast, avm_alu_op_cast_prev, avm_alu_op_div, + avm_alu_op_div_a_lt_b, + avm_alu_op_div_std, avm_alu_op_eq, avm_alu_op_eq_diff_inv, avm_alu_op_lt, @@ -704,6 +809,11 @@ class AvmFlavor { avm_alu_p_sub_a_lo, avm_alu_p_sub_b_hi, avm_alu_p_sub_b_lo, + avm_alu_partial_prod_hi, + avm_alu_partial_prod_lo, + avm_alu_quotient_hi, + avm_alu_quotient_lo, + avm_alu_remainder, avm_alu_res_hi, avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, @@ -881,6 +991,14 @@ class AvmFlavor { lookup_u16_12, lookup_u16_13, lookup_u16_14, + lookup_div_u16_0, + lookup_div_u16_1, + lookup_div_u16_2, + lookup_div_u16_3, + lookup_div_u16_4, + lookup_div_u16_5, + lookup_div_u16_6, + lookup_div_u16_7, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, @@ -906,6 +1024,14 @@ class AvmFlavor { lookup_u16_12_counts, lookup_u16_13_counts, lookup_u16_14_counts, + lookup_div_u16_0_counts, + lookup_div_u16_1_counts, + lookup_div_u16_2_counts, + lookup_div_u16_3_counts, + lookup_div_u16_4_counts, + lookup_div_u16_5_counts, + lookup_div_u16_6_counts, + lookup_div_u16_7_counts, avm_alu_a_hi_shift, avm_alu_a_lo_shift, avm_alu_alu_sel_shift, @@ -913,9 +1039,19 @@ class AvmFlavor { avm_alu_b_lo_shift, avm_alu_cmp_rng_ctr_shift, avm_alu_cmp_sel_shift, + avm_alu_div_rng_chk_selector_shift, + avm_alu_div_u16_r0_shift, + avm_alu_div_u16_r1_shift, + avm_alu_div_u16_r2_shift, + avm_alu_div_u16_r3_shift, + avm_alu_div_u16_r4_shift, + avm_alu_div_u16_r5_shift, + avm_alu_div_u16_r6_shift, + avm_alu_div_u16_r7_shift, avm_alu_op_add_shift, avm_alu_op_cast_prev_shift, avm_alu_op_cast_shift, + avm_alu_op_div_shift, avm_alu_op_mul_shift, avm_alu_op_shl_shift, avm_alu_op_shr_shift, @@ -963,6 +1099,17 @@ class AvmFlavor { avm_alu_clk, avm_alu_cmp_rng_ctr, avm_alu_cmp_sel, + avm_alu_div_rng_chk_selector, + avm_alu_div_u16_r0, + avm_alu_div_u16_r1, + avm_alu_div_u16_r2, + avm_alu_div_u16_r3, + avm_alu_div_u16_r4, + avm_alu_div_u16_r5, + avm_alu_div_u16_r6, + avm_alu_div_u16_r7, + avm_alu_divisor_hi, + avm_alu_divisor_lo, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -972,6 +1119,8 @@ class AvmFlavor { avm_alu_op_cast, avm_alu_op_cast_prev, avm_alu_op_div, + avm_alu_op_div_a_lt_b, + avm_alu_op_div_std, avm_alu_op_eq, avm_alu_op_eq_diff_inv, avm_alu_op_lt, @@ -987,6 +1136,11 @@ class AvmFlavor { avm_alu_p_sub_a_lo, avm_alu_p_sub_b_hi, avm_alu_p_sub_b_lo, + avm_alu_partial_prod_hi, + avm_alu_partial_prod_lo, + avm_alu_quotient_hi, + avm_alu_quotient_lo, + avm_alu_remainder, avm_alu_res_hi, avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, @@ -1164,6 +1318,14 @@ class AvmFlavor { lookup_u16_12, lookup_u16_13, lookup_u16_14, + lookup_div_u16_0, + lookup_div_u16_1, + lookup_div_u16_2, + lookup_div_u16_3, + lookup_div_u16_4, + lookup_div_u16_5, + lookup_div_u16_6, + lookup_div_u16_7, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, @@ -1189,6 +1351,14 @@ class AvmFlavor { lookup_u16_12_counts, lookup_u16_13_counts, lookup_u16_14_counts, + lookup_div_u16_0_counts, + lookup_div_u16_1_counts, + lookup_div_u16_2_counts, + lookup_div_u16_3_counts, + lookup_div_u16_4_counts, + lookup_div_u16_5_counts, + lookup_div_u16_6_counts, + lookup_div_u16_7_counts, avm_alu_a_hi_shift, avm_alu_a_lo_shift, avm_alu_alu_sel_shift, @@ -1196,9 +1366,19 @@ class AvmFlavor { avm_alu_b_lo_shift, avm_alu_cmp_rng_ctr_shift, avm_alu_cmp_sel_shift, + avm_alu_div_rng_chk_selector_shift, + avm_alu_div_u16_r0_shift, + avm_alu_div_u16_r1_shift, + avm_alu_div_u16_r2_shift, + avm_alu_div_u16_r3_shift, + avm_alu_div_u16_r4_shift, + avm_alu_div_u16_r5_shift, + avm_alu_div_u16_r6_shift, + avm_alu_div_u16_r7_shift, avm_alu_op_add_shift, avm_alu_op_cast_prev_shift, avm_alu_op_cast_shift, + avm_alu_op_div_shift, avm_alu_op_mul_shift, avm_alu_op_shl_shift, avm_alu_op_shr_shift, @@ -1246,6 +1426,17 @@ class AvmFlavor { avm_alu_clk, avm_alu_cmp_rng_ctr, avm_alu_cmp_sel, + avm_alu_div_rng_chk_selector, + avm_alu_div_u16_r0, + avm_alu_div_u16_r1, + avm_alu_div_u16_r2, + avm_alu_div_u16_r3, + avm_alu_div_u16_r4, + avm_alu_div_u16_r5, + avm_alu_div_u16_r6, + avm_alu_div_u16_r7, + avm_alu_divisor_hi, + avm_alu_divisor_lo, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -1255,6 +1446,8 @@ class AvmFlavor { avm_alu_op_cast, avm_alu_op_cast_prev, avm_alu_op_div, + avm_alu_op_div_a_lt_b, + avm_alu_op_div_std, avm_alu_op_eq, avm_alu_op_eq_diff_inv, avm_alu_op_lt, @@ -1270,6 +1463,11 @@ class AvmFlavor { avm_alu_p_sub_a_lo, avm_alu_p_sub_b_hi, avm_alu_p_sub_b_lo, + avm_alu_partial_prod_hi, + avm_alu_partial_prod_lo, + avm_alu_quotient_hi, + avm_alu_quotient_lo, + avm_alu_remainder, avm_alu_res_hi, avm_alu_res_lo, avm_alu_rng_chk_lookup_selector, @@ -1447,6 +1645,14 @@ class AvmFlavor { lookup_u16_12, lookup_u16_13, lookup_u16_14, + lookup_div_u16_0, + lookup_div_u16_1, + lookup_div_u16_2, + lookup_div_u16_3, + lookup_div_u16_4, + lookup_div_u16_5, + lookup_div_u16_6, + lookup_div_u16_7, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, @@ -1471,7 +1677,15 @@ class AvmFlavor { lookup_u16_11_counts, lookup_u16_12_counts, lookup_u16_13_counts, - lookup_u16_14_counts }; + lookup_u16_14_counts, + lookup_div_u16_0_counts, + lookup_div_u16_1_counts, + lookup_div_u16_2_counts, + lookup_div_u16_3_counts, + lookup_div_u16_4_counts, + lookup_div_u16_5_counts, + lookup_div_u16_6_counts, + lookup_div_u16_7_counts }; }; RefVector get_to_be_shifted() { @@ -1482,9 +1696,19 @@ class AvmFlavor { avm_alu_b_lo, avm_alu_cmp_rng_ctr, avm_alu_cmp_sel, + avm_alu_div_rng_chk_selector, + avm_alu_div_u16_r0, + avm_alu_div_u16_r1, + avm_alu_div_u16_r2, + avm_alu_div_u16_r3, + avm_alu_div_u16_r4, + avm_alu_div_u16_r5, + avm_alu_div_u16_r6, + avm_alu_div_u16_r7, avm_alu_op_add, avm_alu_op_cast_prev, avm_alu_op_cast, + avm_alu_op_div, avm_alu_op_mul, avm_alu_op_shl, avm_alu_op_shr, @@ -1527,9 +1751,19 @@ class AvmFlavor { avm_alu_b_lo_shift, avm_alu_cmp_rng_ctr_shift, avm_alu_cmp_sel_shift, + avm_alu_div_rng_chk_selector_shift, + avm_alu_div_u16_r0_shift, + avm_alu_div_u16_r1_shift, + avm_alu_div_u16_r2_shift, + avm_alu_div_u16_r3_shift, + avm_alu_div_u16_r4_shift, + avm_alu_div_u16_r5_shift, + avm_alu_div_u16_r6_shift, + avm_alu_div_u16_r7_shift, avm_alu_op_add_shift, avm_alu_op_cast_prev_shift, avm_alu_op_cast_shift, + avm_alu_op_div_shift, avm_alu_op_mul_shift, avm_alu_op_shl_shift, avm_alu_op_shr_shift, @@ -1582,9 +1816,19 @@ class AvmFlavor { avm_alu_b_lo, avm_alu_cmp_rng_ctr, avm_alu_cmp_sel, + avm_alu_div_rng_chk_selector, + avm_alu_div_u16_r0, + avm_alu_div_u16_r1, + avm_alu_div_u16_r2, + avm_alu_div_u16_r3, + avm_alu_div_u16_r4, + avm_alu_div_u16_r5, + avm_alu_div_u16_r6, + avm_alu_div_u16_r7, avm_alu_op_add, avm_alu_op_cast_prev, avm_alu_op_cast, + avm_alu_op_div, avm_alu_op_mul, avm_alu_op_shl, avm_alu_op_shr, @@ -1693,6 +1937,22 @@ 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>( + 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); } }; @@ -1765,13 +2025,6 @@ class AvmFlavor { * @details During folding and sumcheck, the prover evaluates the relations on these univariates. */ template using ProverUnivariates = AllEntities>; - /** - * @brief A container for univariates used during Protogalaxy folding and sumcheck with some of the computation - * optmistically ignored - * @details During folding and sumcheck, the prover evaluates the relations on these univariates. - */ - template - using OptimisedProverUnivariates = AllEntities>; /** * @brief A container for univariates produced during the hot loop in sumcheck. @@ -1804,6 +2057,17 @@ class AvmFlavor { Base::avm_alu_clk = "AVM_ALU_CLK"; Base::avm_alu_cmp_rng_ctr = "AVM_ALU_CMP_RNG_CTR"; Base::avm_alu_cmp_sel = "AVM_ALU_CMP_SEL"; + Base::avm_alu_div_rng_chk_selector = "AVM_ALU_DIV_RNG_CHK_SELECTOR"; + Base::avm_alu_div_u16_r0 = "AVM_ALU_DIV_U16_R0"; + Base::avm_alu_div_u16_r1 = "AVM_ALU_DIV_U16_R1"; + Base::avm_alu_div_u16_r2 = "AVM_ALU_DIV_U16_R2"; + Base::avm_alu_div_u16_r3 = "AVM_ALU_DIV_U16_R3"; + Base::avm_alu_div_u16_r4 = "AVM_ALU_DIV_U16_R4"; + Base::avm_alu_div_u16_r5 = "AVM_ALU_DIV_U16_R5"; + Base::avm_alu_div_u16_r6 = "AVM_ALU_DIV_U16_R6"; + Base::avm_alu_div_u16_r7 = "AVM_ALU_DIV_U16_R7"; + Base::avm_alu_divisor_hi = "AVM_ALU_DIVISOR_HI"; + Base::avm_alu_divisor_lo = "AVM_ALU_DIVISOR_LO"; Base::avm_alu_ff_tag = "AVM_ALU_FF_TAG"; Base::avm_alu_ia = "AVM_ALU_IA"; Base::avm_alu_ib = "AVM_ALU_IB"; @@ -1813,6 +2077,8 @@ class AvmFlavor { Base::avm_alu_op_cast = "AVM_ALU_OP_CAST"; Base::avm_alu_op_cast_prev = "AVM_ALU_OP_CAST_PREV"; Base::avm_alu_op_div = "AVM_ALU_OP_DIV"; + Base::avm_alu_op_div_a_lt_b = "AVM_ALU_OP_DIV_A_LT_B"; + Base::avm_alu_op_div_std = "AVM_ALU_OP_DIV_STD"; Base::avm_alu_op_eq = "AVM_ALU_OP_EQ"; Base::avm_alu_op_eq_diff_inv = "AVM_ALU_OP_EQ_DIFF_INV"; Base::avm_alu_op_lt = "AVM_ALU_OP_LT"; @@ -1828,6 +2094,11 @@ class AvmFlavor { Base::avm_alu_p_sub_a_lo = "AVM_ALU_P_SUB_A_LO"; Base::avm_alu_p_sub_b_hi = "AVM_ALU_P_SUB_B_HI"; Base::avm_alu_p_sub_b_lo = "AVM_ALU_P_SUB_B_LO"; + Base::avm_alu_partial_prod_hi = "AVM_ALU_PARTIAL_PROD_HI"; + Base::avm_alu_partial_prod_lo = "AVM_ALU_PARTIAL_PROD_LO"; + Base::avm_alu_quotient_hi = "AVM_ALU_QUOTIENT_HI"; + Base::avm_alu_quotient_lo = "AVM_ALU_QUOTIENT_LO"; + Base::avm_alu_remainder = "AVM_ALU_REMAINDER"; Base::avm_alu_res_hi = "AVM_ALU_RES_HI"; Base::avm_alu_res_lo = "AVM_ALU_RES_LO"; Base::avm_alu_rng_chk_lookup_selector = "AVM_ALU_RNG_CHK_LOOKUP_SELECTOR"; @@ -2005,6 +2276,14 @@ class AvmFlavor { Base::lookup_u16_12 = "LOOKUP_U16_12"; Base::lookup_u16_13 = "LOOKUP_U16_13"; Base::lookup_u16_14 = "LOOKUP_U16_14"; + Base::lookup_div_u16_0 = "LOOKUP_DIV_U16_0"; + Base::lookup_div_u16_1 = "LOOKUP_DIV_U16_1"; + Base::lookup_div_u16_2 = "LOOKUP_DIV_U16_2"; + Base::lookup_div_u16_3 = "LOOKUP_DIV_U16_3"; + Base::lookup_div_u16_4 = "LOOKUP_DIV_U16_4"; + Base::lookup_div_u16_5 = "LOOKUP_DIV_U16_5"; + Base::lookup_div_u16_6 = "LOOKUP_DIV_U16_6"; + Base::lookup_div_u16_7 = "LOOKUP_DIV_U16_7"; Base::lookup_byte_lengths_counts = "LOOKUP_BYTE_LENGTHS_COUNTS"; Base::lookup_byte_operations_counts = "LOOKUP_BYTE_OPERATIONS_COUNTS"; Base::incl_main_tag_err_counts = "INCL_MAIN_TAG_ERR_COUNTS"; @@ -2030,6 +2309,14 @@ class AvmFlavor { Base::lookup_u16_12_counts = "LOOKUP_U16_12_COUNTS"; Base::lookup_u16_13_counts = "LOOKUP_U16_13_COUNTS"; Base::lookup_u16_14_counts = "LOOKUP_U16_14_COUNTS"; + Base::lookup_div_u16_0_counts = "LOOKUP_DIV_U16_0_COUNTS"; + Base::lookup_div_u16_1_counts = "LOOKUP_DIV_U16_1_COUNTS"; + Base::lookup_div_u16_2_counts = "LOOKUP_DIV_U16_2_COUNTS"; + Base::lookup_div_u16_3_counts = "LOOKUP_DIV_U16_3_COUNTS"; + Base::lookup_div_u16_4_counts = "LOOKUP_DIV_U16_4_COUNTS"; + Base::lookup_div_u16_5_counts = "LOOKUP_DIV_U16_5_COUNTS"; + Base::lookup_div_u16_6_counts = "LOOKUP_DIV_U16_6_COUNTS"; + Base::lookup_div_u16_7_counts = "LOOKUP_DIV_U16_7_COUNTS"; }; }; @@ -2059,6 +2346,17 @@ class AvmFlavor { Commitment avm_alu_clk; Commitment avm_alu_cmp_rng_ctr; Commitment avm_alu_cmp_sel; + Commitment avm_alu_div_rng_chk_selector; + Commitment avm_alu_div_u16_r0; + Commitment avm_alu_div_u16_r1; + Commitment avm_alu_div_u16_r2; + Commitment avm_alu_div_u16_r3; + Commitment avm_alu_div_u16_r4; + Commitment avm_alu_div_u16_r5; + Commitment avm_alu_div_u16_r6; + Commitment avm_alu_div_u16_r7; + Commitment avm_alu_divisor_hi; + Commitment avm_alu_divisor_lo; Commitment avm_alu_ff_tag; Commitment avm_alu_ia; Commitment avm_alu_ib; @@ -2068,6 +2366,8 @@ class AvmFlavor { Commitment avm_alu_op_cast; Commitment avm_alu_op_cast_prev; Commitment avm_alu_op_div; + Commitment avm_alu_op_div_a_lt_b; + Commitment avm_alu_op_div_std; Commitment avm_alu_op_eq; Commitment avm_alu_op_eq_diff_inv; Commitment avm_alu_op_lt; @@ -2083,6 +2383,11 @@ class AvmFlavor { Commitment avm_alu_p_sub_a_lo; Commitment avm_alu_p_sub_b_hi; Commitment avm_alu_p_sub_b_lo; + Commitment avm_alu_partial_prod_hi; + Commitment avm_alu_partial_prod_lo; + Commitment avm_alu_quotient_hi; + Commitment avm_alu_quotient_lo; + Commitment avm_alu_remainder; Commitment avm_alu_res_hi; Commitment avm_alu_res_lo; Commitment avm_alu_rng_chk_lookup_selector; @@ -2260,6 +2565,14 @@ class AvmFlavor { Commitment lookup_u16_12; Commitment lookup_u16_13; Commitment lookup_u16_14; + Commitment lookup_div_u16_0; + Commitment lookup_div_u16_1; + Commitment lookup_div_u16_2; + Commitment lookup_div_u16_3; + Commitment lookup_div_u16_4; + Commitment lookup_div_u16_5; + Commitment lookup_div_u16_6; + Commitment lookup_div_u16_7; Commitment lookup_byte_lengths_counts; Commitment lookup_byte_operations_counts; Commitment incl_main_tag_err_counts; @@ -2285,6 +2598,14 @@ class AvmFlavor { Commitment lookup_u16_12_counts; Commitment lookup_u16_13_counts; Commitment lookup_u16_14_counts; + Commitment lookup_div_u16_0_counts; + Commitment lookup_div_u16_1_counts; + Commitment lookup_div_u16_2_counts; + Commitment lookup_div_u16_3_counts; + Commitment lookup_div_u16_4_counts; + Commitment lookup_div_u16_5_counts; + Commitment lookup_div_u16_6_counts; + Commitment lookup_div_u16_7_counts; std::vector> sumcheck_univariates; std::array sumcheck_evaluations; @@ -2314,6 +2635,17 @@ class AvmFlavor { avm_alu_clk = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_cmp_rng_ctr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_cmp_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_div_rng_chk_selector = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_div_u16_r0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_div_u16_r1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_div_u16_r2 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_div_u16_r3 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_div_u16_r4 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_div_u16_r5 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_div_u16_r6 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_div_u16_r7 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_divisor_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_divisor_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_ff_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_ia = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_ib = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2323,6 +2655,8 @@ class AvmFlavor { avm_alu_op_cast = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_cast_prev = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_div = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_op_div_a_lt_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_op_div_std = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_eq = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_eq_diff_inv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_lt = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2338,6 +2672,11 @@ class AvmFlavor { avm_alu_p_sub_a_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_p_sub_b_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_p_sub_b_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_partial_prod_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_partial_prod_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_quotient_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_quotient_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_remainder = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_res_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); 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); @@ -2516,6 +2855,14 @@ class AvmFlavor { lookup_u16_12 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u16_13 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u16_14 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_2 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_3 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_4 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_5 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_6 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_7 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_byte_lengths_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_byte_operations_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_main_tag_err_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2541,6 +2888,14 @@ class AvmFlavor { lookup_u16_12_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u16_13_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u16_14_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_0_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_1_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_2_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_3_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_4_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_5_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_6_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_div_u16_7_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); for (size_t i = 0; i < log_n; ++i) { sumcheck_univariates.emplace_back( @@ -2574,6 +2929,17 @@ class AvmFlavor { serialize_to_buffer(avm_alu_clk, Transcript::proof_data); serialize_to_buffer(avm_alu_cmp_rng_ctr, Transcript::proof_data); serialize_to_buffer(avm_alu_cmp_sel, Transcript::proof_data); + serialize_to_buffer(avm_alu_div_rng_chk_selector, Transcript::proof_data); + serialize_to_buffer(avm_alu_div_u16_r0, Transcript::proof_data); + serialize_to_buffer(avm_alu_div_u16_r1, Transcript::proof_data); + serialize_to_buffer(avm_alu_div_u16_r2, Transcript::proof_data); + serialize_to_buffer(avm_alu_div_u16_r3, Transcript::proof_data); + serialize_to_buffer(avm_alu_div_u16_r4, Transcript::proof_data); + serialize_to_buffer(avm_alu_div_u16_r5, Transcript::proof_data); + serialize_to_buffer(avm_alu_div_u16_r6, Transcript::proof_data); + serialize_to_buffer(avm_alu_div_u16_r7, Transcript::proof_data); + serialize_to_buffer(avm_alu_divisor_hi, Transcript::proof_data); + serialize_to_buffer(avm_alu_divisor_lo, Transcript::proof_data); serialize_to_buffer(avm_alu_ff_tag, Transcript::proof_data); serialize_to_buffer(avm_alu_ia, Transcript::proof_data); serialize_to_buffer(avm_alu_ib, Transcript::proof_data); @@ -2583,6 +2949,8 @@ class AvmFlavor { serialize_to_buffer(avm_alu_op_cast, Transcript::proof_data); serialize_to_buffer(avm_alu_op_cast_prev, Transcript::proof_data); serialize_to_buffer(avm_alu_op_div, Transcript::proof_data); + serialize_to_buffer(avm_alu_op_div_a_lt_b, Transcript::proof_data); + serialize_to_buffer(avm_alu_op_div_std, Transcript::proof_data); serialize_to_buffer(avm_alu_op_eq, Transcript::proof_data); serialize_to_buffer(avm_alu_op_eq_diff_inv, Transcript::proof_data); serialize_to_buffer(avm_alu_op_lt, Transcript::proof_data); @@ -2598,6 +2966,11 @@ class AvmFlavor { serialize_to_buffer(avm_alu_p_sub_a_lo, Transcript::proof_data); serialize_to_buffer(avm_alu_p_sub_b_hi, Transcript::proof_data); serialize_to_buffer(avm_alu_p_sub_b_lo, Transcript::proof_data); + serialize_to_buffer(avm_alu_partial_prod_hi, Transcript::proof_data); + serialize_to_buffer(avm_alu_partial_prod_lo, Transcript::proof_data); + serialize_to_buffer(avm_alu_quotient_hi, Transcript::proof_data); + serialize_to_buffer(avm_alu_quotient_lo, Transcript::proof_data); + serialize_to_buffer(avm_alu_remainder, Transcript::proof_data); serialize_to_buffer(avm_alu_res_hi, Transcript::proof_data); serialize_to_buffer(avm_alu_res_lo, Transcript::proof_data); serialize_to_buffer(avm_alu_rng_chk_lookup_selector, Transcript::proof_data); @@ -2775,6 +3148,14 @@ class AvmFlavor { serialize_to_buffer(lookup_u16_12, Transcript::proof_data); serialize_to_buffer(lookup_u16_13, Transcript::proof_data); serialize_to_buffer(lookup_u16_14, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_0, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_1, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_2, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_3, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_4, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_5, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_6, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_7, Transcript::proof_data); serialize_to_buffer(lookup_byte_lengths_counts, Transcript::proof_data); serialize_to_buffer(lookup_byte_operations_counts, Transcript::proof_data); serialize_to_buffer(incl_main_tag_err_counts, Transcript::proof_data); @@ -2800,6 +3181,14 @@ class AvmFlavor { serialize_to_buffer(lookup_u16_12_counts, Transcript::proof_data); serialize_to_buffer(lookup_u16_13_counts, Transcript::proof_data); serialize_to_buffer(lookup_u16_14_counts, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_0_counts, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_1_counts, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_2_counts, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_3_counts, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_4_counts, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_5_counts, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_6_counts, Transcript::proof_data); + serialize_to_buffer(lookup_div_u16_7_counts, Transcript::proof_data); for (size_t i = 0; i < log_n; ++i) { serialize_to_buffer(sumcheck_univariates[i], Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp index 064a1e7e3ac..feb378a1326 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp @@ -69,6 +69,17 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_alu_clk = commitment_key->commit(key->avm_alu_clk); witness_commitments.avm_alu_cmp_rng_ctr = commitment_key->commit(key->avm_alu_cmp_rng_ctr); witness_commitments.avm_alu_cmp_sel = commitment_key->commit(key->avm_alu_cmp_sel); + witness_commitments.avm_alu_div_rng_chk_selector = commitment_key->commit(key->avm_alu_div_rng_chk_selector); + witness_commitments.avm_alu_div_u16_r0 = commitment_key->commit(key->avm_alu_div_u16_r0); + witness_commitments.avm_alu_div_u16_r1 = commitment_key->commit(key->avm_alu_div_u16_r1); + witness_commitments.avm_alu_div_u16_r2 = commitment_key->commit(key->avm_alu_div_u16_r2); + witness_commitments.avm_alu_div_u16_r3 = commitment_key->commit(key->avm_alu_div_u16_r3); + witness_commitments.avm_alu_div_u16_r4 = commitment_key->commit(key->avm_alu_div_u16_r4); + witness_commitments.avm_alu_div_u16_r5 = commitment_key->commit(key->avm_alu_div_u16_r5); + witness_commitments.avm_alu_div_u16_r6 = commitment_key->commit(key->avm_alu_div_u16_r6); + witness_commitments.avm_alu_div_u16_r7 = commitment_key->commit(key->avm_alu_div_u16_r7); + witness_commitments.avm_alu_divisor_hi = commitment_key->commit(key->avm_alu_divisor_hi); + witness_commitments.avm_alu_divisor_lo = commitment_key->commit(key->avm_alu_divisor_lo); witness_commitments.avm_alu_ff_tag = commitment_key->commit(key->avm_alu_ff_tag); witness_commitments.avm_alu_ia = commitment_key->commit(key->avm_alu_ia); witness_commitments.avm_alu_ib = commitment_key->commit(key->avm_alu_ib); @@ -78,6 +89,8 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_alu_op_cast = commitment_key->commit(key->avm_alu_op_cast); witness_commitments.avm_alu_op_cast_prev = commitment_key->commit(key->avm_alu_op_cast_prev); witness_commitments.avm_alu_op_div = commitment_key->commit(key->avm_alu_op_div); + witness_commitments.avm_alu_op_div_a_lt_b = commitment_key->commit(key->avm_alu_op_div_a_lt_b); + witness_commitments.avm_alu_op_div_std = commitment_key->commit(key->avm_alu_op_div_std); witness_commitments.avm_alu_op_eq = commitment_key->commit(key->avm_alu_op_eq); witness_commitments.avm_alu_op_eq_diff_inv = commitment_key->commit(key->avm_alu_op_eq_diff_inv); witness_commitments.avm_alu_op_lt = commitment_key->commit(key->avm_alu_op_lt); @@ -93,6 +106,11 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_alu_p_sub_a_lo = commitment_key->commit(key->avm_alu_p_sub_a_lo); witness_commitments.avm_alu_p_sub_b_hi = commitment_key->commit(key->avm_alu_p_sub_b_hi); witness_commitments.avm_alu_p_sub_b_lo = commitment_key->commit(key->avm_alu_p_sub_b_lo); + witness_commitments.avm_alu_partial_prod_hi = commitment_key->commit(key->avm_alu_partial_prod_hi); + witness_commitments.avm_alu_partial_prod_lo = commitment_key->commit(key->avm_alu_partial_prod_lo); + witness_commitments.avm_alu_quotient_hi = commitment_key->commit(key->avm_alu_quotient_hi); + witness_commitments.avm_alu_quotient_lo = commitment_key->commit(key->avm_alu_quotient_lo); + witness_commitments.avm_alu_remainder = commitment_key->commit(key->avm_alu_remainder); witness_commitments.avm_alu_res_hi = commitment_key->commit(key->avm_alu_res_hi); 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); @@ -261,6 +279,14 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.lookup_u16_12_counts = commitment_key->commit(key->lookup_u16_12_counts); witness_commitments.lookup_u16_13_counts = commitment_key->commit(key->lookup_u16_13_counts); witness_commitments.lookup_u16_14_counts = commitment_key->commit(key->lookup_u16_14_counts); + witness_commitments.lookup_div_u16_0_counts = commitment_key->commit(key->lookup_div_u16_0_counts); + witness_commitments.lookup_div_u16_1_counts = commitment_key->commit(key->lookup_div_u16_1_counts); + witness_commitments.lookup_div_u16_2_counts = commitment_key->commit(key->lookup_div_u16_2_counts); + witness_commitments.lookup_div_u16_3_counts = commitment_key->commit(key->lookup_div_u16_3_counts); + witness_commitments.lookup_div_u16_4_counts = commitment_key->commit(key->lookup_div_u16_4_counts); + witness_commitments.lookup_div_u16_5_counts = commitment_key->commit(key->lookup_div_u16_5_counts); + witness_commitments.lookup_div_u16_6_counts = commitment_key->commit(key->lookup_div_u16_6_counts); + witness_commitments.lookup_div_u16_7_counts = commitment_key->commit(key->lookup_div_u16_7_counts); // Send all commitments to the verifier transcript->send_to_verifier(commitment_labels.avm_alu_a_hi, witness_commitments.avm_alu_a_hi); @@ -273,6 +299,18 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_alu_clk, witness_commitments.avm_alu_clk); transcript->send_to_verifier(commitment_labels.avm_alu_cmp_rng_ctr, witness_commitments.avm_alu_cmp_rng_ctr); transcript->send_to_verifier(commitment_labels.avm_alu_cmp_sel, witness_commitments.avm_alu_cmp_sel); + transcript->send_to_verifier(commitment_labels.avm_alu_div_rng_chk_selector, + witness_commitments.avm_alu_div_rng_chk_selector); + transcript->send_to_verifier(commitment_labels.avm_alu_div_u16_r0, witness_commitments.avm_alu_div_u16_r0); + transcript->send_to_verifier(commitment_labels.avm_alu_div_u16_r1, witness_commitments.avm_alu_div_u16_r1); + transcript->send_to_verifier(commitment_labels.avm_alu_div_u16_r2, witness_commitments.avm_alu_div_u16_r2); + transcript->send_to_verifier(commitment_labels.avm_alu_div_u16_r3, witness_commitments.avm_alu_div_u16_r3); + transcript->send_to_verifier(commitment_labels.avm_alu_div_u16_r4, witness_commitments.avm_alu_div_u16_r4); + transcript->send_to_verifier(commitment_labels.avm_alu_div_u16_r5, witness_commitments.avm_alu_div_u16_r5); + transcript->send_to_verifier(commitment_labels.avm_alu_div_u16_r6, witness_commitments.avm_alu_div_u16_r6); + transcript->send_to_verifier(commitment_labels.avm_alu_div_u16_r7, witness_commitments.avm_alu_div_u16_r7); + transcript->send_to_verifier(commitment_labels.avm_alu_divisor_hi, witness_commitments.avm_alu_divisor_hi); + transcript->send_to_verifier(commitment_labels.avm_alu_divisor_lo, witness_commitments.avm_alu_divisor_lo); transcript->send_to_verifier(commitment_labels.avm_alu_ff_tag, witness_commitments.avm_alu_ff_tag); transcript->send_to_verifier(commitment_labels.avm_alu_ia, witness_commitments.avm_alu_ia); transcript->send_to_verifier(commitment_labels.avm_alu_ib, witness_commitments.avm_alu_ib); @@ -282,6 +320,8 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_alu_op_cast, witness_commitments.avm_alu_op_cast); transcript->send_to_verifier(commitment_labels.avm_alu_op_cast_prev, witness_commitments.avm_alu_op_cast_prev); transcript->send_to_verifier(commitment_labels.avm_alu_op_div, witness_commitments.avm_alu_op_div); + transcript->send_to_verifier(commitment_labels.avm_alu_op_div_a_lt_b, witness_commitments.avm_alu_op_div_a_lt_b); + transcript->send_to_verifier(commitment_labels.avm_alu_op_div_std, witness_commitments.avm_alu_op_div_std); transcript->send_to_verifier(commitment_labels.avm_alu_op_eq, witness_commitments.avm_alu_op_eq); transcript->send_to_verifier(commitment_labels.avm_alu_op_eq_diff_inv, witness_commitments.avm_alu_op_eq_diff_inv); transcript->send_to_verifier(commitment_labels.avm_alu_op_lt, witness_commitments.avm_alu_op_lt); @@ -297,6 +337,13 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_alu_p_sub_a_lo, witness_commitments.avm_alu_p_sub_a_lo); transcript->send_to_verifier(commitment_labels.avm_alu_p_sub_b_hi, witness_commitments.avm_alu_p_sub_b_hi); transcript->send_to_verifier(commitment_labels.avm_alu_p_sub_b_lo, witness_commitments.avm_alu_p_sub_b_lo); + transcript->send_to_verifier(commitment_labels.avm_alu_partial_prod_hi, + witness_commitments.avm_alu_partial_prod_hi); + transcript->send_to_verifier(commitment_labels.avm_alu_partial_prod_lo, + witness_commitments.avm_alu_partial_prod_lo); + transcript->send_to_verifier(commitment_labels.avm_alu_quotient_hi, witness_commitments.avm_alu_quotient_hi); + transcript->send_to_verifier(commitment_labels.avm_alu_quotient_lo, witness_commitments.avm_alu_quotient_lo); + transcript->send_to_verifier(commitment_labels.avm_alu_remainder, witness_commitments.avm_alu_remainder); transcript->send_to_verifier(commitment_labels.avm_alu_res_hi, witness_commitments.avm_alu_res_hi); transcript->send_to_verifier(commitment_labels.avm_alu_res_lo, witness_commitments.avm_alu_res_lo); transcript->send_to_verifier(commitment_labels.avm_alu_rng_chk_lookup_selector, @@ -484,6 +531,22 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.lookup_u16_12_counts, witness_commitments.lookup_u16_12_counts); transcript->send_to_verifier(commitment_labels.lookup_u16_13_counts, witness_commitments.lookup_u16_13_counts); transcript->send_to_verifier(commitment_labels.lookup_u16_14_counts, witness_commitments.lookup_u16_14_counts); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_0_counts, + witness_commitments.lookup_div_u16_0_counts); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_1_counts, + witness_commitments.lookup_div_u16_1_counts); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_2_counts, + witness_commitments.lookup_div_u16_2_counts); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_3_counts, + witness_commitments.lookup_div_u16_3_counts); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_4_counts, + witness_commitments.lookup_div_u16_4_counts); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_5_counts, + witness_commitments.lookup_div_u16_5_counts); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_6_counts, + witness_commitments.lookup_div_u16_6_counts); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_7_counts, + witness_commitments.lookup_div_u16_7_counts); } void AvmProver::execute_log_derivative_inverse_round() @@ -531,6 +594,14 @@ void AvmProver::execute_log_derivative_inverse_round() witness_commitments.lookup_u16_12 = commitment_key->commit(key->lookup_u16_12); witness_commitments.lookup_u16_13 = commitment_key->commit(key->lookup_u16_13); witness_commitments.lookup_u16_14 = commitment_key->commit(key->lookup_u16_14); + witness_commitments.lookup_div_u16_0 = commitment_key->commit(key->lookup_div_u16_0); + witness_commitments.lookup_div_u16_1 = commitment_key->commit(key->lookup_div_u16_1); + witness_commitments.lookup_div_u16_2 = commitment_key->commit(key->lookup_div_u16_2); + witness_commitments.lookup_div_u16_3 = commitment_key->commit(key->lookup_div_u16_3); + witness_commitments.lookup_div_u16_4 = commitment_key->commit(key->lookup_div_u16_4); + witness_commitments.lookup_div_u16_5 = commitment_key->commit(key->lookup_div_u16_5); + witness_commitments.lookup_div_u16_6 = commitment_key->commit(key->lookup_div_u16_6); + witness_commitments.lookup_div_u16_7 = commitment_key->commit(key->lookup_div_u16_7); // Send all commitments to the verifier transcript->send_to_verifier(commitment_labels.perm_main_alu, witness_commitments.perm_main_alu); @@ -568,6 +639,14 @@ void AvmProver::execute_log_derivative_inverse_round() transcript->send_to_verifier(commitment_labels.lookup_u16_12, witness_commitments.lookup_u16_12); transcript->send_to_verifier(commitment_labels.lookup_u16_13, witness_commitments.lookup_u16_13); transcript->send_to_verifier(commitment_labels.lookup_u16_14, witness_commitments.lookup_u16_14); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_0, witness_commitments.lookup_div_u16_0); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_1, witness_commitments.lookup_div_u16_1); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_2, witness_commitments.lookup_div_u16_2); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_3, witness_commitments.lookup_div_u16_3); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_4, witness_commitments.lookup_div_u16_4); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_5, witness_commitments.lookup_div_u16_5); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_6, witness_commitments.lookup_div_u16_6); + transcript->send_to_verifier(commitment_labels.lookup_div_u16_7, witness_commitments.lookup_div_u16_7); } /** diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 89f357cc400..ecce0af1b4d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -64,6 +64,28 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_alu_cmp_rng_ctr); commitments.avm_alu_cmp_sel = transcript->template receive_from_prover(commitment_labels.avm_alu_cmp_sel); + commitments.avm_alu_div_rng_chk_selector = + transcript->template receive_from_prover(commitment_labels.avm_alu_div_rng_chk_selector); + commitments.avm_alu_div_u16_r0 = + transcript->template receive_from_prover(commitment_labels.avm_alu_div_u16_r0); + commitments.avm_alu_div_u16_r1 = + transcript->template receive_from_prover(commitment_labels.avm_alu_div_u16_r1); + commitments.avm_alu_div_u16_r2 = + transcript->template receive_from_prover(commitment_labels.avm_alu_div_u16_r2); + commitments.avm_alu_div_u16_r3 = + transcript->template receive_from_prover(commitment_labels.avm_alu_div_u16_r3); + commitments.avm_alu_div_u16_r4 = + transcript->template receive_from_prover(commitment_labels.avm_alu_div_u16_r4); + commitments.avm_alu_div_u16_r5 = + transcript->template receive_from_prover(commitment_labels.avm_alu_div_u16_r5); + commitments.avm_alu_div_u16_r6 = + transcript->template receive_from_prover(commitment_labels.avm_alu_div_u16_r6); + commitments.avm_alu_div_u16_r7 = + transcript->template receive_from_prover(commitment_labels.avm_alu_div_u16_r7); + commitments.avm_alu_divisor_hi = + transcript->template receive_from_prover(commitment_labels.avm_alu_divisor_hi); + commitments.avm_alu_divisor_lo = + transcript->template receive_from_prover(commitment_labels.avm_alu_divisor_lo); commitments.avm_alu_ff_tag = transcript->template receive_from_prover(commitment_labels.avm_alu_ff_tag); commitments.avm_alu_ia = transcript->template receive_from_prover(commitment_labels.avm_alu_ia); commitments.avm_alu_ib = transcript->template receive_from_prover(commitment_labels.avm_alu_ib); @@ -75,6 +97,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) commitments.avm_alu_op_cast_prev = transcript->template receive_from_prover(commitment_labels.avm_alu_op_cast_prev); commitments.avm_alu_op_div = transcript->template receive_from_prover(commitment_labels.avm_alu_op_div); + commitments.avm_alu_op_div_a_lt_b = + transcript->template receive_from_prover(commitment_labels.avm_alu_op_div_a_lt_b); + commitments.avm_alu_op_div_std = + transcript->template receive_from_prover(commitment_labels.avm_alu_op_div_std); commitments.avm_alu_op_eq = transcript->template receive_from_prover(commitment_labels.avm_alu_op_eq); commitments.avm_alu_op_eq_diff_inv = transcript->template receive_from_prover(commitment_labels.avm_alu_op_eq_diff_inv); @@ -97,6 +123,16 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_alu_p_sub_b_hi); commitments.avm_alu_p_sub_b_lo = transcript->template receive_from_prover(commitment_labels.avm_alu_p_sub_b_lo); + commitments.avm_alu_partial_prod_hi = + transcript->template receive_from_prover(commitment_labels.avm_alu_partial_prod_hi); + commitments.avm_alu_partial_prod_lo = + transcript->template receive_from_prover(commitment_labels.avm_alu_partial_prod_lo); + commitments.avm_alu_quotient_hi = + transcript->template receive_from_prover(commitment_labels.avm_alu_quotient_hi); + commitments.avm_alu_quotient_lo = + transcript->template receive_from_prover(commitment_labels.avm_alu_quotient_lo); + commitments.avm_alu_remainder = + transcript->template receive_from_prover(commitment_labels.avm_alu_remainder); commitments.avm_alu_res_hi = transcript->template receive_from_prover(commitment_labels.avm_alu_res_hi); commitments.avm_alu_res_lo = transcript->template receive_from_prover(commitment_labels.avm_alu_res_lo); commitments.avm_alu_rng_chk_lookup_selector = @@ -389,6 +425,22 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.lookup_u16_13_counts); commitments.lookup_u16_14_counts = transcript->template receive_from_prover(commitment_labels.lookup_u16_14_counts); + commitments.lookup_div_u16_0_counts = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_0_counts); + commitments.lookup_div_u16_1_counts = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_1_counts); + commitments.lookup_div_u16_2_counts = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_2_counts); + commitments.lookup_div_u16_3_counts = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_3_counts); + commitments.lookup_div_u16_4_counts = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_4_counts); + commitments.lookup_div_u16_5_counts = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_5_counts); + commitments.lookup_div_u16_6_counts = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_6_counts); + commitments.lookup_div_u16_7_counts = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_7_counts); auto [beta, gamm] = transcript->template get_challenges("beta", "gamma"); relation_parameters.beta = beta; @@ -444,6 +496,22 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) commitments.lookup_u16_12 = transcript->template receive_from_prover(commitment_labels.lookup_u16_12); commitments.lookup_u16_13 = transcript->template receive_from_prover(commitment_labels.lookup_u16_13); commitments.lookup_u16_14 = transcript->template receive_from_prover(commitment_labels.lookup_u16_14); + commitments.lookup_div_u16_0 = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_0); + commitments.lookup_div_u16_1 = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_1); + commitments.lookup_div_u16_2 = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_2); + commitments.lookup_div_u16_3 = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_3); + commitments.lookup_div_u16_4 = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_4); + commitments.lookup_div_u16_5 = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_5); + commitments.lookup_div_u16_6 = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_6); + commitments.lookup_div_u16_7 = + transcript->template receive_from_prover(commitment_labels.lookup_div_u16_7); // Execute Sumcheck Verifier const size_t log_circuit_size = numeric::get_msb(circuit_size); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp index 30601dd613e..c0754b31d4c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp @@ -1,6 +1,7 @@ #include "avm_common.test.hpp" #include "barretenberg/numeric/uint128/uint128.hpp" #include "barretenberg/vm/avm_trace/avm_common.hpp" +#include "barretenberg/vm/tests/helpers.test.hpp" #include namespace tests_avm { @@ -167,6 +168,35 @@ size_t common_validate_eq(std::vector const& trace, return static_cast(alu_row - trace.begin()); } +size_t common_validate_div(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) +{ + // Find the first row enabling the division selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_div == FF(1); }); + + // Find the corresponding Alu trace row + auto 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; }); + + // Check that both rows were found + EXPECT_TRUE(row != trace.end()); + EXPECT_TRUE(alu_row != trace.end()); + + common_validate_arithmetic_op(*row, *alu_row, a, b, c, addr_a, addr_b, addr_c, tag); + EXPECT_EQ(row->avm_main_w_in_tag, FF(static_cast(tag))); + + // Check that division selector is set. + EXPECT_EQ(alu_row->avm_alu_op_div, FF(1)); + + return static_cast(alu_row - trace.begin()); +} + // Generate a trace with an EQ opcode operation. std::vector gen_trace_eq(uint128_t const& a, uint128_t const& b, @@ -282,6 +312,7 @@ class AvmArithmeticTestsU16 : public AvmArithmeticTests {}; class AvmArithmeticTestsU32 : public AvmArithmeticTests {}; class AvmArithmeticTestsU64 : public AvmArithmeticTests {}; class AvmArithmeticTestsU128 : public AvmArithmeticTests {}; +class AvmArithmeticTestsDiv : public AvmArithmeticTests, public testing::WithParamInterface {}; class AvmArithmeticNegativeTestsFF : public AvmArithmeticTests {}; class AvmArithmeticNegativeTestsU8 : public AvmArithmeticTests {}; @@ -290,6 +321,18 @@ class AvmArithmeticNegativeTestsU32 : public AvmArithmeticTests {}; class AvmArithmeticNegativeTestsU64 : public AvmArithmeticTests {}; class AvmArithmeticNegativeTestsU128 : public AvmArithmeticTests {}; +std::vector uint_mem_tags{ + { AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } +}; +std::vector> positive_op_div_test_values = { { + { FF(10), FF(5), FF(2) }, + { FF(5323), FF(5323), FF(1) }, + { FF(13793), FF(10590617LLU), FF(0) }, + { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), FF(1526) }, + { uint256_t::from_uint128((uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }), + uint256_t::from_uint128(uint128_t{ 0xb900000000000001 }), + uint256_t::from_uint128(uint128_t{ 0x162c4ad3b97863a1 }) }, +} }; /****************************************************************************** * * POSITIVE TESTS @@ -334,7 +377,7 @@ TEST_F(AvmArithmeticTestsFF, addition) EXPECT_EQ(alu_row.avm_alu_cf, FF(0)); EXPECT_EQ(alu_row.avm_alu_u8_r0, FF(0)); - validate_trace(std::move(trace)); + validate_trace(std::move(trace), true); } // Test on basic subtraction over finite field type. @@ -549,6 +592,51 @@ TEST_F(AvmArithmeticTestsFF, nonEquality) validate_trace(std::move(trace)); } +TEST_P(AvmArithmeticTestsDiv, division) +{ + const auto [operands, mem_tag] = GetParam(); + const auto [a, b, output] = operands; + auto trace_builder = avm_trace::AvmTraceBuilder(); + trace_builder.op_set(0, uint128_t(a), 0, mem_tag); + trace_builder.op_set(0, uint128_t(b), 1, mem_tag); + trace_builder.op_div(0, 0, 1, 2, mem_tag); + trace_builder.return_op(0, 0, 0); + auto trace = trace_builder.finalize(); + + common_validate_div(trace, a, b, output, 0, 1, 2, mem_tag); + // auto alu_row = trace.at(alu_row_index); + + validate_trace(std::move(trace)); +} +INSTANTIATE_TEST_SUITE_P(AvmArithmeticTestsDiv, + AvmArithmeticTestsDiv, + testing::ValuesIn(gen_three_op_params(positive_op_div_test_values, uint_mem_tags))); + +// Test on division by zero over U128. +// We check that the operator error flag is raised. +TEST_F(AvmArithmeticTests, DivisionByZeroError) +{ + auto trace_builder = avm_trace::AvmTraceBuilder(); + trace_builder.op_set(0, 100, 0, AvmMemoryTag::U128); + trace_builder.op_set(0, 0, 1, AvmMemoryTag::U128); + trace_builder.op_div(0, 0, 1, 2, AvmMemoryTag::U128); + trace_builder.halt(); + auto trace = trace_builder.finalize(); + + // Find the first row enabling the div selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_div == FF(1); }); + + // Check that the correct result is stored at the expected memory location. + EXPECT_TRUE(row != trace.end()); + EXPECT_EQ(row->avm_main_ic, FF(0)); + EXPECT_EQ(row->avm_main_mem_idx_c, FF(2)); + EXPECT_EQ(row->avm_main_mem_op_c, FF(1)); + EXPECT_EQ(row->avm_main_rwc, FF(1)); + EXPECT_EQ(row->avm_main_op_err, FF(1)); + + validate_trace(std::move(trace)); +} + /****************************************************************************** * Positive Tests - U8 ******************************************************************************/ 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 256501f41ea..bbe1ef3e5b0 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -372,7 +372,6 @@ class AvmBitwiseTests : public ::testing::Test { * ******************************************************************************/ -using ThreeOpParamRow = std::tuple, AvmMemoryTag>; using TwoOpParamRow = std::tuple, AvmMemoryTag>; std::vector mem_tags{ { AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } @@ -397,59 +396,51 @@ std::vector gen_two_op_params(std::vector> positive_op_and_test_values = { - { { 1, 1, 1 }, - { 5323, 321, 65 }, - { 13793, 10590617LLU, 4481 }, - { 0x7bff744e3cdf79LLU, 0x14ccccccccb6LLU, 0x14444c0ccc30LLU }, - { (uint128_t{ 0xb900000000000001 } << 64), - (uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }, - (uint128_t{ 0x1000000000000000 } << 64) } } +std::vector positive_op_and_test_values = { + { { FF(1), FF(1), FF(1) }, + { FF(5323), FF(321), FF(65) }, + { FF(13793), FF(10590617LLU), FF(4481) }, + { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), FF(0x14444c0ccc30LLU) }, + { uint256_t::from_uint128(uint128_t{ 0xb900000000000001 } << 64), + uint256_t::from_uint128((uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }), + uint256_t::from_uint128(uint128_t{ 0x1000000000000000 } << 64) } } }; -std::vector> positive_op_or_test_values = { - { { 1, 1, 1 }, - { 5323, 321, 0x15cb }, - { 13793, 10590617LLU, 0xa1bdf9 }, - { 0x7bff744e3cdf79LLU, 0x14ccccccccb6LLU, 0x7bfffccefcdfffLLU }, - { (uint128_t{ 0xb900000000000000 } << 64), - (uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }, - (uint128_t{ 0xb906021301080000 } << 64) + uint128_t{ 0x0001080876844827 } } } +std::vector> positive_op_or_test_values = { + { { FF(1), FF(1), FF(1) }, + { FF(5323), FF(321), FF(0x15cb) }, + { FF(13793), FF(10590617LLU), FF(0xa1bdf9) }, + { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), FF(0x7bfffccefcdfffLLU) }, + { uint256_t::from_uint128(uint128_t{ 0xb900000000000000 } << 64), + uint256_t::from_uint128(uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }, + uint256_t::from_uint128(uint128_t{ 0xb906021301080000 } << 64) + uint128_t{ 0x0001080876844827 } } } }; -std::vector> positive_op_xor_test_values = { - { { 1, 1, 0 }, - { 5323, 321, 0x158a }, - { 13793, 10590617LLU, 0xa1ac78 }, - { 0x7bff744e3cdf79LLU, 0x14ccccccccb6LLU, 0x7bebb882f013cf }, - { (uint128_t{ 0xb900000000000001 } << 64), - (uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }, - (uint128_t{ 0xa906021301080001 } << 64) + uint128_t{ 0x0001080876844827 } } } +std::vector> positive_op_xor_test_values = { + { { FF(1), FF(1), FF(0) }, + { FF(5323), FF(321), FF(0x158a) }, + { FF(13793), FF(10590617LLU), FF(0xa1ac78) }, + { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), uint256_t::from_uint128(0x7bebb882f013cf) }, + { uint256_t::from_uint128(uint128_t{ 0xb900000000000001 } << 64), + uint256_t::from_uint128((uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }), + uint256_t::from_uint128((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_shr_test_values = { + { { FF(20), FF(3), FF(2) }, + { FF(5323), FF(255), FF(0) }, + { FF(36148), FF(13), FF(4) }, + { FF(0x7bff744e3cdf79LLU), FF(64), FF(0) }, + { uint256_t::from_uint128((uint128_t{ 0x1006021301080000 } << 64) + uint128_t{ 0x000000000000001080876844827 }), + FF(123), + FF(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> positive_op_shl_test_values = { + { { FF(20), FF(8), FF(0) }, + { FF(5323), FF(10), FF(11264) }, + { FF(13793), FF(255), FF(0) }, + { FF(239), FF(50), uint256_t::from_uint128(269090077735387136) }, + { FF(9), FF(127), uint256_t::from_uint128(uint128_t{ 0x4800000000000000LLU } << 68) } } }; -std::vector gen_three_op_params(std::vector> operands, - std::vector mem_tags) -{ - std::vector params; - for (size_t i = 0; i < 5; i++) { - params.emplace_back(operands[i], mem_tags[i]); - } - return params; -} - class AvmBitwiseTestsNot : public AvmBitwiseTests, public testing::WithParamInterface {}; class AvmBitwiseTestsAnd : public AvmBitwiseTests, public testing::WithParamInterface {}; class AvmBitwiseTestsOr : public AvmBitwiseTests, public testing::WithParamInterface {}; @@ -490,16 +481,13 @@ TEST_P(AvmBitwiseTestsAnd, AllAndTest) { 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_set(0, uint128_t(a), 0, mem_tag); + trace_builder.op_set(0, uint128_t(b), 1, mem_tag); trace_builder.op_and(0, 0, 1, 2, mem_tag); trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); - FF ff_a = FF(uint256_t::from_uint128(a)); - FF ff_b = FF(uint256_t::from_uint128(b)); - FF ff_output = FF(uint256_t::from_uint128(output)); - common_validate_bit_op(trace, 0, ff_a, ff_b, ff_output, FF(0), FF(1), FF(2), mem_tag); + common_validate_bit_op(trace, 0, a, b, output, FF(0), FF(1), FF(2), mem_tag); validate_trace(std::move(trace), true); } INSTANTIATE_TEST_SUITE_P(AvmBitwiseTests, @@ -510,17 +498,13 @@ TEST_P(AvmBitwiseTestsOr, AllOrTest) { 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_set(0, uint128_t(a), 0, mem_tag); + trace_builder.op_set(0, uint128_t(b), 1, mem_tag); trace_builder.op_or(0, 0, 1, 2, mem_tag); trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); - FF ff_a = FF(uint256_t::from_uint128(a)); - FF ff_b = FF(uint256_t::from_uint128(b)); - FF ff_output = FF(uint256_t::from_uint128(output)); - - common_validate_bit_op(trace, 1, ff_a, ff_b, ff_output, FF(0), FF(1), FF(2), mem_tag); + common_validate_bit_op(trace, 1, a, b, output, FF(0), FF(1), FF(2), mem_tag); validate_trace(std::move(trace)); } INSTANTIATE_TEST_SUITE_P(AvmBitwiseTests, @@ -531,17 +515,13 @@ TEST_P(AvmBitwiseTestsXor, AllXorTest) { 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_set(0, uint128_t(a), 0, mem_tag); + trace_builder.op_set(0, uint128_t(b), 1, mem_tag); trace_builder.op_xor(0, 0, 1, 2, mem_tag); trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); - FF ff_a = FF(uint256_t::from_uint128(a)); - FF ff_b = FF(uint256_t::from_uint128(b)); - FF ff_output = FF(uint256_t::from_uint128(output)); - - common_validate_bit_op(trace, 2, ff_a, ff_b, ff_output, FF(0), FF(1), FF(2), mem_tag); + common_validate_bit_op(trace, 2, a, b, output, FF(0), FF(1), FF(2), mem_tag); validate_trace(std::move(trace)); } @@ -553,20 +533,12 @@ 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_set(0, uint128_t(a), 0, mem_tag); + trace_builder.op_set(0, uint128_t(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); + common_validate_shift_op(trace, a, b, output, FF(0), FF(1), FF(2), mem_tag, true); validate_trace(std::move(trace)); } @@ -578,21 +550,13 @@ 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_set(0, uint128_t(a), 0, mem_tag); + trace_builder.op_set(0, uint128_t(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); + common_validate_shift_op(trace, a, b, output, FF(0), FF(1), FF(2), mem_tag, false); validate_trace(std::move(trace)); } @@ -660,9 +624,8 @@ TEST_P(AvmBitwiseNegativeTestsAnd, AllNegativeTests) trace_builder.op_and(0, 0, 1, 2, mem_tag); trace_builder.halt(); auto trace = trace_builder.finalize(); - FF ff_output = FF(uint256_t::from_uint128(output)); std::function&& select_row = [](Row r) { return r.avm_main_sel_op_and == FF(1); }; - trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); + trace = gen_mutated_trace_bit(trace, std::move(select_row), output, failure_mode); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), failure_string); } INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, @@ -681,9 +644,8 @@ TEST_P(AvmBitwiseNegativeTestsOr, AllNegativeTests) trace_builder.op_or(0, 0, 1, 2, mem_tag); trace_builder.halt(); auto trace = trace_builder.finalize(); - FF ff_output = FF(uint256_t::from_uint128(output)); std::function&& select_row = [](Row r) { return r.avm_main_sel_op_or == FF(1); }; - trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); + trace = gen_mutated_trace_bit(trace, std::move(select_row), output, failure_mode); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), failure_string); } INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, @@ -701,9 +663,8 @@ TEST_P(AvmBitwiseNegativeTestsXor, AllNegativeTests) trace_builder.op_xor(0, 0, 1, 2, mem_tag); trace_builder.halt(); auto trace = trace_builder.finalize(); - FF ff_output = FF(uint256_t::from_uint128(output)); std::function&& select_row = [](Row r) { return r.avm_main_sel_op_xor == FF(1); }; - trace = gen_mutated_trace_bit(trace, std::move(select_row), ff_output, failure_mode); + trace = gen_mutated_trace_bit(trace, std::move(select_row), output, failure_mode); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), failure_string) } INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, @@ -723,8 +684,7 @@ TEST_P(AvmBitwiseNegativeTestsShr, AllNegativeTests) auto trace = trace_builder.finalize(); std::function&& select_row = [](Row r) { return r.avm_main_sel_op_shr == FF(1); }; - auto [mutated_trace, str] = gen_mutated_trace_shift( - std::move(trace), std::move(select_row), FF(uint256_t::from_uint128(output)), failure, true); + auto [mutated_trace, str] = gen_mutated_trace_shift(std::move(trace), std::move(select_row), output, failure, true); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(mutated_trace)), str); } INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, @@ -744,8 +704,8 @@ TEST_P(AvmBitwiseNegativeTestsShl, AllNegativeTests) auto trace = trace_builder.finalize(); std::function&& select_row = [](Row r) { return r.avm_main_sel_op_shl == FF(1); }; - auto [mutated_trace, str] = gen_mutated_trace_shift( - std::move(trace), std::move(select_row), FF(uint256_t::from_uint128(output)), failure, false); + auto [mutated_trace, str] = + gen_mutated_trace_shift(std::move(trace), std::move(select_row), output, failure, false); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(mutated_trace)), str); } INSTANTIATE_TEST_SUITE_P(AvmBitwiseNegativeTests, diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_comparison.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_comparison.test.cpp index 16ea72cbcaf..26eaf202fe7 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_comparison.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_comparison.test.cpp @@ -57,8 +57,6 @@ void common_validate_cmp(Row const& row, EXPECT_EQ(alu_row.avm_alu_ic, c); } } // namespace -using ThreeOpParam = std::array; -using ThreeOpParamRow = std::tuple; std::vector positive_op_lt_test_values = { { { FF(1), FF(1), FF(0) }, { FF(5323), FF(321), FF(0) }, { FF(13793), FF(10590617LLU), FF(1) }, @@ -77,15 +75,6 @@ std::vector positive_op_lte_test_values = { FF(1) } } }; -std::vector gen_three_op_params(std::vector operands, - std::vector mem_tag_arr) -{ - std::vector params; - for (size_t i = 0; i < 5; i++) { - params.emplace_back(operands[i], mem_tag_arr[i]); - } - return params; -} std::vector mem_tag_arr{ { AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } }; diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp index 290b15585a0..b0dc065027d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp @@ -1,7 +1,18 @@ +#include "barretenberg/vm/tests/helpers.test.hpp" #include "avm_common.test.hpp" #include "barretenberg/vm/generated/avm_flavor.hpp" namespace tests_avm { + +std::vector gen_three_op_params(std::vector operands, + std::vector mem_tags) +{ + std::vector params; + for (size_t i = 0; i < 5; i++) { + params.emplace_back(operands[i], mem_tags[i]); + } + return params; +} /** * @brief Helper routine checking the circuit constraints without proving * @@ -25,6 +36,7 @@ void validate_trace(std::vector&& trace, bool with_proof) EXPECT_TRUE(circuit_builder.check_circuit()); if (with_proof) { + info("With proof"); auto composer = AvmComposer(); auto prover = composer.create_prover(circuit_builder); auto proof = prover.construct_proof(); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.hpp b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.hpp index fd1f862404d..5df14f93cd7 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.hpp @@ -15,6 +15,8 @@ namespace tests_avm { using Flavor = bb::AvmFlavor; using FF = Flavor::FF; using Row = bb::AvmFullRow; +using ThreeOpParam = std::array; +using ThreeOpParamRow = std::tuple; // To toggle all relevant unit tests with proving, set the env variable "AVM_TESTS_ENABLE_PROVING". static const bool ENABLE_PROVING = std::getenv("AVM_TESTS_ENABLE_PROVING") != nullptr; @@ -30,5 +32,7 @@ void mutate_ic_in_trace(std::vector& trace, bool alu = false); void clear_range_check_counters(std::vector& trace, uint256_t previous_value); void update_slice_registers(Row& row, uint256_t a); +std::vector gen_three_op_params(std::vector> operands, + std::vector mem_tags); } // namespace tests_avm