From 8e4f29988e5adcbf424b5a45916e44ad7b3fcac9 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Thu, 11 Jan 2024 12:58:52 +0000 Subject: [PATCH] 3738 - add witness generation for multiplication with types u8, u16, u32, u64 --- barretenberg/cpp/pil/avm/alu_chip.pil | 4 + barretenberg/cpp/pil/avm/avm_mini.pil | 4 - .../flavor/generated/AvmMini_flavor.hpp | 105 ++++++-------- .../generated/AvmMini_circuit_builder.hpp | 48 +++---- .../relations/generated/AvmMini/alu_chip.hpp | 122 +++++++++-------- .../relations/generated/AvmMini/avm_mini.hpp | 128 ++++++++---------- .../generated/AvmMini/declare_views.hpp | 20 +-- .../relations/generated/AvmMini/mem_trace.hpp | 34 ++--- .../vm/avm_trace/AvmMini_alu_trace.cpp | 113 +++++++++++++++- .../vm/avm_trace/AvmMini_alu_trace.hpp | 3 + .../vm/avm_trace/AvmMini_helper.cpp | 6 + .../vm/avm_trace/AvmMini_trace.cpp | 16 ++- .../vm/tests/AvmMini_arithmetic.test.cpp | 13 +- 13 files changed, 362 insertions(+), 254 deletions(-) diff --git a/barretenberg/cpp/pil/avm/alu_chip.pil b/barretenberg/cpp/pil/avm/alu_chip.pil index 8a95d3ad454..c3eaa6f5fc2 100644 --- a/barretenberg/cpp/pil/avm/alu_chip.pil +++ b/barretenberg/cpp/pil/avm/alu_chip.pil @@ -157,6 +157,10 @@ namespace aluChip(256); // ========= MULTIPLICATION Operation Constraints =============================== + // ff multiplication + #[SUBOP_MULTIPLICATION_FF] + alu_ff_tag * alu_op_mul * (alu_ia * alu_ib - alu_ic) = 0; + // We need 2k bits to express the product (a*b) over the integer, i.e., for type uk // we express the product as sum_k (u8 is an exception as we need 8-bit registers) diff --git a/barretenberg/cpp/pil/avm/avm_mini.pil b/barretenberg/cpp/pil/avm/avm_mini.pil index ad9374dcc46..26268fe25cd 100644 --- a/barretenberg/cpp/pil/avm/avm_mini.pil +++ b/barretenberg/cpp/pil/avm/avm_mini.pil @@ -103,10 +103,6 @@ namespace avmMini(256); tag_err * ib = 0; tag_err * ic = 0; - // Relation for multiplication over the finite field - #[SUBOP_MULTIPLICATION_FF] - sel_op_mul * (ia * ib - ic) = 0; - // Relation for division over the finite field // If tag_err == 1 in a division, then ib == 0 and op_err == 1. #[SUBOP_DIVISION_FF] diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp index 7bcf828cfa0..5b97550ac3a 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp @@ -43,7 +43,7 @@ class AvmMiniFlavor { // the unshifted and one for the shifted static constexpr size_t NUM_ALL_ENTITIES = 80; - using Relations = std::tuple, AvmMini_vm::alu_chip, AvmMini_vm::avm_mini>; + using Relations = std::tuple, AvmMini_vm::alu_chip, AvmMini_vm::mem_trace>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -281,20 +281,20 @@ class AvmMiniFlavor { avmMini_mem_idx_b, avmMini_mem_idx_c, avmMini_last, - memTrace_m_rw_shift, - memTrace_m_val_shift, - memTrace_m_addr_shift, - memTrace_m_tag_shift, + avmMini_pc_shift, + avmMini_internal_return_ptr_shift, + aluChip_alu_u16_r0_shift, + aluChip_alu_u16_r7_shift, aluChip_alu_u16_r6_shift, - aluChip_alu_u16_r1_shift, + aluChip_alu_u16_r3_shift, aluChip_alu_u16_r4_shift, aluChip_alu_u16_r2_shift, + aluChip_alu_u16_r1_shift, aluChip_alu_u16_r5_shift, - aluChip_alu_u16_r0_shift, - aluChip_alu_u16_r7_shift, - aluChip_alu_u16_r3_shift, - avmMini_internal_return_ptr_shift, - avmMini_pc_shift) + memTrace_m_addr_shift, + memTrace_m_val_shift, + memTrace_m_tag_shift, + memTrace_m_rw_shift) RefVector get_wires() { @@ -364,20 +364,20 @@ class AvmMiniFlavor { avmMini_mem_idx_b, avmMini_mem_idx_c, avmMini_last, - memTrace_m_rw_shift, - memTrace_m_val_shift, - memTrace_m_addr_shift, - memTrace_m_tag_shift, + avmMini_pc_shift, + avmMini_internal_return_ptr_shift, + aluChip_alu_u16_r0_shift, + aluChip_alu_u16_r7_shift, aluChip_alu_u16_r6_shift, - aluChip_alu_u16_r1_shift, + aluChip_alu_u16_r3_shift, aluChip_alu_u16_r4_shift, aluChip_alu_u16_r2_shift, + aluChip_alu_u16_r1_shift, aluChip_alu_u16_r5_shift, - aluChip_alu_u16_r0_shift, - aluChip_alu_u16_r7_shift, - aluChip_alu_u16_r3_shift, - avmMini_internal_return_ptr_shift, - avmMini_pc_shift }; + memTrace_m_addr_shift, + memTrace_m_val_shift, + memTrace_m_tag_shift, + memTrace_m_rw_shift }; }; RefVector get_unshifted() { @@ -450,37 +450,23 @@ class AvmMiniFlavor { }; RefVector get_to_be_shifted() { - return { memTrace_m_rw, - memTrace_m_val, - memTrace_m_addr, - memTrace_m_tag, - aluChip_alu_u16_r6, - aluChip_alu_u16_r1, - aluChip_alu_u16_r4, - aluChip_alu_u16_r2, - aluChip_alu_u16_r5, - aluChip_alu_u16_r0, - aluChip_alu_u16_r7, - aluChip_alu_u16_r3, - avmMini_internal_return_ptr, - avmMini_pc }; + return { avmMini_pc, avmMini_internal_return_ptr, + aluChip_alu_u16_r0, aluChip_alu_u16_r7, + aluChip_alu_u16_r6, aluChip_alu_u16_r3, + aluChip_alu_u16_r4, aluChip_alu_u16_r2, + aluChip_alu_u16_r1, aluChip_alu_u16_r5, + memTrace_m_addr, memTrace_m_val, + memTrace_m_tag, memTrace_m_rw }; }; RefVector get_shifted() { - return { memTrace_m_rw_shift, - memTrace_m_val_shift, - memTrace_m_addr_shift, - memTrace_m_tag_shift, - aluChip_alu_u16_r6_shift, - aluChip_alu_u16_r1_shift, - aluChip_alu_u16_r4_shift, - aluChip_alu_u16_r2_shift, - aluChip_alu_u16_r5_shift, - aluChip_alu_u16_r0_shift, - aluChip_alu_u16_r7_shift, - aluChip_alu_u16_r3_shift, - avmMini_internal_return_ptr_shift, - avmMini_pc_shift }; + return { avmMini_pc_shift, avmMini_internal_return_ptr_shift, + aluChip_alu_u16_r0_shift, aluChip_alu_u16_r7_shift, + aluChip_alu_u16_r6_shift, aluChip_alu_u16_r3_shift, + aluChip_alu_u16_r4_shift, aluChip_alu_u16_r2_shift, + aluChip_alu_u16_r1_shift, aluChip_alu_u16_r5_shift, + memTrace_m_addr_shift, memTrace_m_val_shift, + memTrace_m_tag_shift, memTrace_m_rw_shift }; }; }; @@ -493,20 +479,13 @@ class AvmMiniFlavor { RefVector get_to_be_shifted() { - return { memTrace_m_rw, - memTrace_m_val, - memTrace_m_addr, - memTrace_m_tag, - aluChip_alu_u16_r6, - aluChip_alu_u16_r1, - aluChip_alu_u16_r4, - aluChip_alu_u16_r2, - aluChip_alu_u16_r5, - aluChip_alu_u16_r0, - aluChip_alu_u16_r7, - aluChip_alu_u16_r3, - avmMini_internal_return_ptr, - avmMini_pc }; + return { avmMini_pc, avmMini_internal_return_ptr, + aluChip_alu_u16_r0, aluChip_alu_u16_r7, + aluChip_alu_u16_r6, aluChip_alu_u16_r3, + aluChip_alu_u16_r4, aluChip_alu_u16_r2, + aluChip_alu_u16_r1, aluChip_alu_u16_r5, + memTrace_m_addr, memTrace_m_val, + memTrace_m_tag, memTrace_m_rw }; }; // The plookup wires that store plookup read data. diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp index bc246a5152d..48a77acbb64 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp @@ -86,20 +86,20 @@ template struct AvmMiniFullRow { FF avmMini_mem_idx_b{}; FF avmMini_mem_idx_c{}; FF avmMini_last{}; - FF memTrace_m_rw_shift{}; - FF memTrace_m_val_shift{}; - FF memTrace_m_addr_shift{}; - FF memTrace_m_tag_shift{}; + FF avmMini_pc_shift{}; + FF avmMini_internal_return_ptr_shift{}; + FF aluChip_alu_u16_r0_shift{}; + FF aluChip_alu_u16_r7_shift{}; FF aluChip_alu_u16_r6_shift{}; - FF aluChip_alu_u16_r1_shift{}; + FF aluChip_alu_u16_r3_shift{}; FF aluChip_alu_u16_r4_shift{}; FF aluChip_alu_u16_r2_shift{}; + FF aluChip_alu_u16_r1_shift{}; FF aluChip_alu_u16_r5_shift{}; - FF aluChip_alu_u16_r0_shift{}; - FF aluChip_alu_u16_r7_shift{}; - FF aluChip_alu_u16_r3_shift{}; - FF avmMini_internal_return_ptr_shift{}; - FF avmMini_pc_shift{}; + FF memTrace_m_addr_shift{}; + FF memTrace_m_val_shift{}; + FF memTrace_m_tag_shift{}; + FF memTrace_m_rw_shift{}; }; class AvmMiniCircuitBuilder { @@ -197,20 +197,20 @@ class AvmMiniCircuitBuilder { polys.avmMini_last[i] = rows[i].avmMini_last; } - polys.memTrace_m_rw_shift = Polynomial(polys.memTrace_m_rw.shifted()); - polys.memTrace_m_val_shift = Polynomial(polys.memTrace_m_val.shifted()); - polys.memTrace_m_addr_shift = Polynomial(polys.memTrace_m_addr.shifted()); - polys.memTrace_m_tag_shift = Polynomial(polys.memTrace_m_tag.shifted()); + polys.avmMini_pc_shift = Polynomial(polys.avmMini_pc.shifted()); + polys.avmMini_internal_return_ptr_shift = Polynomial(polys.avmMini_internal_return_ptr.shifted()); + polys.aluChip_alu_u16_r0_shift = Polynomial(polys.aluChip_alu_u16_r0.shifted()); + polys.aluChip_alu_u16_r7_shift = Polynomial(polys.aluChip_alu_u16_r7.shifted()); polys.aluChip_alu_u16_r6_shift = Polynomial(polys.aluChip_alu_u16_r6.shifted()); - polys.aluChip_alu_u16_r1_shift = Polynomial(polys.aluChip_alu_u16_r1.shifted()); + polys.aluChip_alu_u16_r3_shift = Polynomial(polys.aluChip_alu_u16_r3.shifted()); polys.aluChip_alu_u16_r4_shift = Polynomial(polys.aluChip_alu_u16_r4.shifted()); polys.aluChip_alu_u16_r2_shift = Polynomial(polys.aluChip_alu_u16_r2.shifted()); + polys.aluChip_alu_u16_r1_shift = Polynomial(polys.aluChip_alu_u16_r1.shifted()); polys.aluChip_alu_u16_r5_shift = Polynomial(polys.aluChip_alu_u16_r5.shifted()); - polys.aluChip_alu_u16_r0_shift = Polynomial(polys.aluChip_alu_u16_r0.shifted()); - polys.aluChip_alu_u16_r7_shift = Polynomial(polys.aluChip_alu_u16_r7.shifted()); - polys.aluChip_alu_u16_r3_shift = Polynomial(polys.aluChip_alu_u16_r3.shifted()); - polys.avmMini_internal_return_ptr_shift = Polynomial(polys.avmMini_internal_return_ptr.shifted()); - polys.avmMini_pc_shift = Polynomial(polys.avmMini_pc.shifted()); + polys.memTrace_m_addr_shift = Polynomial(polys.memTrace_m_addr.shifted()); + polys.memTrace_m_val_shift = Polynomial(polys.memTrace_m_val.shifted()); + polys.memTrace_m_tag_shift = Polynomial(polys.memTrace_m_tag.shifted()); + polys.memTrace_m_rw_shift = Polynomial(polys.memTrace_m_rw.shifted()); return polys; } @@ -248,16 +248,16 @@ class AvmMiniCircuitBuilder { return true; }; - if (!evaluate_relation.template operator()>( - "mem_trace", AvmMini_vm::get_relation_label_mem_trace)) { + if (!evaluate_relation.template operator()>("avm_mini", + AvmMini_vm::get_relation_label_avm_mini)) { return false; } if (!evaluate_relation.template operator()>("alu_chip", AvmMini_vm::get_relation_label_alu_chip)) { return false; } - if (!evaluate_relation.template operator()>("avm_mini", - AvmMini_vm::get_relation_label_avm_mini)) { + if (!evaluate_relation.template operator()>( + "mem_trace", AvmMini_vm::get_relation_label_mem_trace)) { return false; } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/alu_chip.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/alu_chip.hpp index 602789b8182..13c95170b5f 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/alu_chip.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/alu_chip.hpp @@ -7,48 +7,51 @@ namespace proof_system::AvmMini_vm { template struct Alu_chipRow { - FF aluChip_alu_op_mul{}; - FF aluChip_alu_ia{}; - FF aluChip_alu_u16_r3{}; - FF aluChip_alu_u16_r6_shift{}; - FF aluChip_alu_u16_r1_shift{}; + FF aluChip_alu_op_sub{}; FF aluChip_alu_u8_r0{}; - FF aluChip_alu_ib{}; - FF aluChip_alu_u16_r7{}; - FF aluChip_alu_u16_r2{}; - FF aluChip_alu_u8_r1{}; + FF aluChip_alu_u16_r0_shift{}; + FF aluChip_alu_cf{}; + FF aluChip_alu_ic{}; + FF aluChip_alu_u16_r7_shift{}; FF aluChip_alu_u128_tag{}; + FF aluChip_alu_u16_r1{}; + FF aluChip_alu_u16_r4{}; FF aluChip_alu_u16_r6{}; - FF aluChip_alu_u8_tag{}; - FF aluChip_alu_u16_tag{}; + FF aluChip_alu_u16_r6_shift{}; + FF aluChip_alu_op_add{}; + FF aluChip_alu_u64_tag{}; FF aluChip_alu_ff_tag{}; + FF aluChip_alu_u16_r3{}; + FF aluChip_alu_u16_r3_shift{}; + FF aluChip_alu_u16_r7{}; + FF aluChip_alu_u16_tag{}; + FF aluChip_alu_op_mul{}; + FF aluChip_alu_u16_r5{}; + FF aluChip_alu_u8_tag{}; + FF aluChip_alu_u32_tag{}; + FF aluChip_alu_ia{}; + FF aluChip_alu_u64_r0{}; FF aluChip_alu_u16_r4_shift{}; FF aluChip_alu_u16_r2_shift{}; - FF aluChip_alu_u32_tag{}; - FF aluChip_alu_u16_r1{}; - FF aluChip_alu_cf{}; - FF aluChip_alu_ic{}; - FF aluChip_alu_u16_r0{}; + FF aluChip_alu_u16_r2{}; + FF aluChip_alu_ib{}; + FF aluChip_alu_u8_r1{}; + FF aluChip_alu_u16_r1_shift{}; FF aluChip_alu_u16_r5_shift{}; - FF aluChip_alu_op_sub{}; - FF aluChip_alu_op_add{}; - FF aluChip_alu_u16_r5{}; - FF aluChip_alu_u16_r4{}; - FF aluChip_alu_u64_tag{}; - FF aluChip_alu_u16_r0_shift{}; - FF aluChip_alu_u16_r7_shift{}; - FF aluChip_alu_u64_r0{}; - FF aluChip_alu_u16_r3_shift{}; + FF aluChip_alu_u16_r0{}; }; inline std::string get_relation_label_alu_chip(int index) { switch (index) { - case 6: - return "SUBOP_ADDITION_FF"; - case 17: return "SUBOP_SUBTRACTION_FF"; + + case 28: + return "SUBOP_MULTIPLICATION_FF"; + + case 6: + return "SUBOP_ADDITION_FF"; } return std::to_string(index); } @@ -57,9 +60,9 @@ template class alu_chipImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ 3, 3, 3, 3, 3, 3, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 4, 5, 4, - 5, 4, 5, 5, 5, 5, 5, 5, 5, 4, 5, 4, 5, 5, 5, 5, 6, 6, 8, + 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 5, 4, 5, 5, 5, 5, 6, 6, 8, }; template @@ -369,8 +372,8 @@ template class alu_chipImpl { { AvmMini_DECLARE_VIEWS(28); - auto tmp = ((aluChip_alu_u8_tag * aluChip_alu_op_mul) * - ((aluChip_alu_u8_r0 + (aluChip_alu_u8_r1 * FF(256))) - (aluChip_alu_ia * aluChip_alu_ib))); + auto tmp = + ((aluChip_alu_ff_tag * aluChip_alu_op_mul) * ((aluChip_alu_ia * aluChip_alu_ib) - aluChip_alu_ic)); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -378,7 +381,8 @@ template class alu_chipImpl { { AvmMini_DECLARE_VIEWS(29); - auto tmp = ((aluChip_alu_u8_tag * aluChip_alu_op_mul) * (aluChip_alu_u8_r0 - aluChip_alu_ic)); + auto tmp = ((aluChip_alu_u8_tag * aluChip_alu_op_mul) * + ((aluChip_alu_u8_r0 + (aluChip_alu_u8_r1 * FF(256))) - (aluChip_alu_ia * aluChip_alu_ib))); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -386,8 +390,7 @@ template class alu_chipImpl { { AvmMini_DECLARE_VIEWS(30); - auto tmp = ((aluChip_alu_u16_tag * aluChip_alu_op_mul) * - ((aluChip_alu_u16_r0 + (aluChip_alu_u16_r1 * FF(65536))) - (aluChip_alu_ia * aluChip_alu_ib))); + auto tmp = ((aluChip_alu_u8_tag * aluChip_alu_op_mul) * (aluChip_alu_u8_r0 - aluChip_alu_ic)); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -395,7 +398,8 @@ template class alu_chipImpl { { AvmMini_DECLARE_VIEWS(31); - auto tmp = ((aluChip_alu_u16_tag * aluChip_alu_op_mul) * (aluChip_alu_u16_r0 - aluChip_alu_ic)); + auto tmp = ((aluChip_alu_u16_tag * aluChip_alu_op_mul) * + ((aluChip_alu_u16_r0 + (aluChip_alu_u16_r1 * FF(65536))) - (aluChip_alu_ia * aluChip_alu_ib))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -403,26 +407,34 @@ template class alu_chipImpl { { AvmMini_DECLARE_VIEWS(32); + auto tmp = ((aluChip_alu_u16_tag * aluChip_alu_op_mul) * (aluChip_alu_u16_r0 - aluChip_alu_ic)); + tmp *= scaling_factor; + std::get<32>(evals) += tmp; + } + // Contribution 33 + { + AvmMini_DECLARE_VIEWS(33); + auto tmp = ((aluChip_alu_u32_tag * aluChip_alu_op_mul) * ((((aluChip_alu_u16_r0 + (aluChip_alu_u16_r1 * FF(65536))) + (aluChip_alu_u16_r2 * FF(4294967296UL))) + (aluChip_alu_u16_r3 * FF(281474976710656UL))) - (aluChip_alu_ia * aluChip_alu_ib))); tmp *= scaling_factor; - std::get<32>(evals) += tmp; + std::get<33>(evals) += tmp; } - // Contribution 33 + // Contribution 34 { - AvmMini_DECLARE_VIEWS(33); + AvmMini_DECLARE_VIEWS(34); auto tmp = ((aluChip_alu_u32_tag * aluChip_alu_op_mul) * ((aluChip_alu_u16_r0 + (aluChip_alu_u16_r1 * FF(65536))) - aluChip_alu_ic)); tmp *= scaling_factor; - std::get<33>(evals) += tmp; + std::get<34>(evals) += tmp; } - // Contribution 34 + // Contribution 35 { - AvmMini_DECLARE_VIEWS(34); + AvmMini_DECLARE_VIEWS(35); auto tmp = ((aluChip_alu_u64_tag * aluChip_alu_op_mul) * ((((((((aluChip_alu_u16_r0 + (aluChip_alu_u16_r1 * FF(65536))) + @@ -434,11 +446,11 @@ template class alu_chipImpl { (aluChip_alu_u16_r7 * FF(uint256_t{ 0, 281474976710656, 0, 0 }))) - (aluChip_alu_ia * aluChip_alu_ib))); tmp *= scaling_factor; - std::get<34>(evals) += tmp; + std::get<35>(evals) += tmp; } - // Contribution 35 + // Contribution 36 { - AvmMini_DECLARE_VIEWS(35); + AvmMini_DECLARE_VIEWS(36); auto tmp = ((aluChip_alu_u64_tag * aluChip_alu_op_mul) * @@ -446,11 +458,11 @@ template class alu_chipImpl { (aluChip_alu_u16_r3 * FF(281474976710656UL))) - aluChip_alu_ic)); tmp *= scaling_factor; - std::get<35>(evals) += tmp; + std::get<36>(evals) += tmp; } - // Contribution 36 + // Contribution 37 { - AvmMini_DECLARE_VIEWS(36); + AvmMini_DECLARE_VIEWS(37); auto tmp = ((aluChip_alu_u128_tag * aluChip_alu_op_mul) * (((((aluChip_alu_u16_r0 + (aluChip_alu_u16_r1 * FF(65536))) + @@ -462,11 +474,11 @@ template class alu_chipImpl { FF(uint256_t{ 0, 1, 0, 0 }))) - aluChip_alu_ia)); tmp *= scaling_factor; - std::get<36>(evals) += tmp; + std::get<37>(evals) += tmp; } - // Contribution 37 + // Contribution 38 { - AvmMini_DECLARE_VIEWS(37); + AvmMini_DECLARE_VIEWS(38); auto tmp = ((aluChip_alu_u128_tag * aluChip_alu_op_mul) * (((((aluChip_alu_u16_r0_shift + (aluChip_alu_u16_r1_shift * FF(65536))) + @@ -478,11 +490,11 @@ template class alu_chipImpl { FF(uint256_t{ 0, 1, 0, 0 }))) - aluChip_alu_ib)); tmp *= scaling_factor; - std::get<37>(evals) += tmp; + std::get<38>(evals) += tmp; } - // Contribution 38 + // Contribution 39 { - AvmMini_DECLARE_VIEWS(38); + AvmMini_DECLARE_VIEWS(39); auto tmp = ((aluChip_alu_u128_tag * aluChip_alu_op_mul) * ((((aluChip_alu_ia * (((aluChip_alu_u16_r0_shift + (aluChip_alu_u16_r1_shift * FF(65536))) + @@ -499,7 +511,7 @@ template class alu_chipImpl { FF(uint256_t{ 0, 0, 1, 0 }))) - aluChip_alu_ic)); tmp *= scaling_factor; - std::get<38>(evals) += tmp; + std::get<39>(evals) += tmp; } } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp index 540adee863c..f4b48ef9ab8 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp @@ -7,63 +7,60 @@ namespace proof_system::AvmMini_vm { template struct Avm_miniRow { - FF avmMini_internal_return_ptr{}; - FF avmMini_sel_internal_return{}; - FF avmMini_internal_return_ptr_shift{}; - FF avmMini_mem_op_a{}; - FF avmMini_rwb{}; + FF avmMini_mem_idx_a{}; + FF avmMini_tag_err{}; FF avmMini_sel_op_sub{}; - FF avmMini_mem_op_b{}; FF avmMini_rwc{}; - FF avmMini_mem_idx_b{}; - FF avmMini_sel_internal_call{}; - FF avmMini_ic{}; - FF avmMini_tag_err{}; + FF avmMini_internal_return_ptr{}; + FF avmMini_first{}; + FF avmMini_ib{}; FF avmMini_mem_op_c{}; - FF avmMini_inv{}; - FF avmMini_sel_op_add{}; - FF avmMini_pc_shift{}; - FF avmMini_sel_jump{}; + FF avmMini_mem_op_a{}; + FF avmMini_sel_internal_return{}; FF avmMini_sel_halt{}; - FF avmMini_rwa{}; - FF avmMini_ia{}; - FF avmMini_first{}; + FF avmMini_mem_idx_b{}; + FF avmMini_pc{}; FF avmMini_sel_op_div{}; FF avmMini_sel_op_mul{}; + FF avmMini_sel_op_add{}; + FF avmMini_rwa{}; + FF avmMini_ia{}; + FF avmMini_sel_internal_call{}; + FF avmMini_mem_op_b{}; + FF avmMini_sel_jump{}; FF avmMini_op_err{}; - FF avmMini_pc{}; - FF avmMini_ib{}; - FF avmMini_mem_idx_a{}; + FF avmMini_ic{}; + FF avmMini_rwb{}; + FF avmMini_inv{}; + FF avmMini_pc_shift{}; + FF avmMini_internal_return_ptr_shift{}; }; inline std::string get_relation_label_avm_mini(int index) { switch (index) { - case 21: - return "SUBOP_DIVISION_ZERO_ERR1"; - - case 20: - return "SUBOP_DIVISION_FF"; + case 24: + return "RETURN_POINTER_INCREMENT"; - case 19: - return "SUBOP_MULTIPLICATION_FF"; + case 30: + return "RETURN_POINTER_DECREMENT"; - case 36: + case 35: return "PC_INCREMENT"; - case 37: - return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - - case 25: - return "RETURN_POINTER_INCREMENT"; + case 19: + return "SUBOP_DIVISION_FF"; - case 31: - return "RETURN_POINTER_DECREMENT"; + case 20: + return "SUBOP_DIVISION_ZERO_ERR1"; - case 23: + case 22: return "SUBOP_ERROR_RELEVANT_OP"; - case 22: + case 36: + return "INTERNAL_RETURN_POINTER_CONSISTENCY"; + + case 21: return "SUBOP_DIVISION_ZERO_ERR2"; } return std::to_string(index); @@ -73,9 +70,8 @@ template class avm_miniImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, }; template @@ -241,7 +237,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(19); - auto tmp = (avmMini_sel_op_mul * ((avmMini_ia * avmMini_ib) - avmMini_ic)); + auto tmp = ((avmMini_sel_op_div * (-avmMini_op_err + FF(1))) * ((avmMini_ic * avmMini_ib) - avmMini_ia)); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -249,7 +245,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(20); - auto tmp = ((avmMini_sel_op_div * (-avmMini_op_err + FF(1))) * ((avmMini_ic * avmMini_ib) - avmMini_ia)); + auto tmp = (avmMini_sel_op_div * (((avmMini_ib * avmMini_inv) - FF(1)) + avmMini_op_err)); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -257,7 +253,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(21); - auto tmp = (avmMini_sel_op_div * (((avmMini_ib * avmMini_inv) - FF(1)) + avmMini_op_err)); + auto tmp = ((avmMini_sel_op_div * avmMini_op_err) * (-avmMini_inv + FF(1))); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -265,7 +261,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(22); - auto tmp = ((avmMini_sel_op_div * avmMini_op_err) * (-avmMini_inv + FF(1))); + auto tmp = (avmMini_op_err * (avmMini_sel_op_div - FF(1))); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -273,7 +269,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(23); - auto tmp = (avmMini_op_err * (avmMini_sel_op_div - FF(1))); + auto tmp = (avmMini_sel_jump * (avmMini_pc_shift - avmMini_ia)); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -281,7 +277,8 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(24); - auto tmp = (avmMini_sel_jump * (avmMini_pc_shift - avmMini_ia)); + auto tmp = (avmMini_sel_internal_call * + (avmMini_internal_return_ptr_shift - (avmMini_internal_return_ptr + FF(1)))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -289,8 +286,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(25); - auto tmp = (avmMini_sel_internal_call * - (avmMini_internal_return_ptr_shift - (avmMini_internal_return_ptr + FF(1)))); + auto tmp = (avmMini_sel_internal_call * (avmMini_internal_return_ptr - avmMini_mem_idx_b)); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -298,7 +294,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(26); - auto tmp = (avmMini_sel_internal_call * (avmMini_internal_return_ptr - avmMini_mem_idx_b)); + auto tmp = (avmMini_sel_internal_call * (avmMini_pc_shift - avmMini_ia)); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -306,7 +302,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(27); - auto tmp = (avmMini_sel_internal_call * (avmMini_pc_shift - avmMini_ia)); + auto tmp = (avmMini_sel_internal_call * ((avmMini_pc + FF(1)) - avmMini_ib)); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -314,7 +310,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(28); - auto tmp = (avmMini_sel_internal_call * ((avmMini_pc + FF(1)) - avmMini_ib)); + auto tmp = (avmMini_sel_internal_call * (avmMini_rwb - FF(1))); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -322,7 +318,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(29); - auto tmp = (avmMini_sel_internal_call * (avmMini_rwb - FF(1))); + auto tmp = (avmMini_sel_internal_call * (avmMini_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -330,7 +326,8 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(30); - auto tmp = (avmMini_sel_internal_call * (avmMini_mem_op_b - FF(1))); + auto tmp = (avmMini_sel_internal_return * + (avmMini_internal_return_ptr_shift - (avmMini_internal_return_ptr - FF(1)))); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -338,8 +335,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(31); - auto tmp = (avmMini_sel_internal_return * - (avmMini_internal_return_ptr_shift - (avmMini_internal_return_ptr - FF(1)))); + auto tmp = (avmMini_sel_internal_return * ((avmMini_internal_return_ptr - FF(1)) - avmMini_mem_idx_a)); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -347,7 +343,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(32); - auto tmp = (avmMini_sel_internal_return * ((avmMini_internal_return_ptr - FF(1)) - avmMini_mem_idx_a)); + auto tmp = (avmMini_sel_internal_return * (avmMini_pc_shift - avmMini_ia)); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -355,7 +351,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(33); - auto tmp = (avmMini_sel_internal_return * (avmMini_pc_shift - avmMini_ia)); + auto tmp = (avmMini_sel_internal_return * avmMini_rwa); tmp *= scaling_factor; std::get<33>(evals) += tmp; } @@ -363,7 +359,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(34); - auto tmp = (avmMini_sel_internal_return * avmMini_rwa); + auto tmp = (avmMini_sel_internal_return * (avmMini_mem_op_a - FF(1))); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -371,30 +367,22 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(35); - auto tmp = (avmMini_sel_internal_return * (avmMini_mem_op_a - FF(1))); - tmp *= scaling_factor; - std::get<35>(evals) += tmp; - } - // Contribution 36 - { - AvmMini_DECLARE_VIEWS(36); - auto tmp = ((((-avmMini_first + FF(1)) * (-avmMini_sel_halt + FF(1))) * (((avmMini_sel_op_add + avmMini_sel_op_sub) + avmMini_sel_op_div) + avmMini_sel_op_mul)) * (avmMini_pc_shift - (avmMini_pc + FF(1)))); tmp *= scaling_factor; - std::get<36>(evals) += tmp; + std::get<35>(evals) += tmp; } - // Contribution 37 + // Contribution 36 { - AvmMini_DECLARE_VIEWS(37); + AvmMini_DECLARE_VIEWS(36); auto tmp = ((-(((avmMini_first + avmMini_sel_internal_call) + avmMini_sel_internal_return) + avmMini_sel_halt) + FF(1)) * (avmMini_internal_return_ptr_shift - avmMini_internal_return_ptr)); tmp *= scaling_factor; - std::get<37>(evals) += tmp; + std::get<36>(evals) += tmp; } } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp index 37df4bbab68..32e3626e5ee 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp @@ -68,17 +68,17 @@ [[maybe_unused]] auto avmMini_mem_idx_b = View(new_term.avmMini_mem_idx_b); \ [[maybe_unused]] auto avmMini_mem_idx_c = View(new_term.avmMini_mem_idx_c); \ [[maybe_unused]] auto avmMini_last = View(new_term.avmMini_last); \ - [[maybe_unused]] auto memTrace_m_rw_shift = View(new_term.memTrace_m_rw_shift); \ - [[maybe_unused]] auto memTrace_m_val_shift = View(new_term.memTrace_m_val_shift); \ - [[maybe_unused]] auto memTrace_m_addr_shift = View(new_term.memTrace_m_addr_shift); \ - [[maybe_unused]] auto memTrace_m_tag_shift = View(new_term.memTrace_m_tag_shift); \ + [[maybe_unused]] auto avmMini_pc_shift = View(new_term.avmMini_pc_shift); \ + [[maybe_unused]] auto avmMini_internal_return_ptr_shift = View(new_term.avmMini_internal_return_ptr_shift); \ + [[maybe_unused]] auto aluChip_alu_u16_r0_shift = View(new_term.aluChip_alu_u16_r0_shift); \ + [[maybe_unused]] auto aluChip_alu_u16_r7_shift = View(new_term.aluChip_alu_u16_r7_shift); \ [[maybe_unused]] auto aluChip_alu_u16_r6_shift = View(new_term.aluChip_alu_u16_r6_shift); \ - [[maybe_unused]] auto aluChip_alu_u16_r1_shift = View(new_term.aluChip_alu_u16_r1_shift); \ + [[maybe_unused]] auto aluChip_alu_u16_r3_shift = View(new_term.aluChip_alu_u16_r3_shift); \ [[maybe_unused]] auto aluChip_alu_u16_r4_shift = View(new_term.aluChip_alu_u16_r4_shift); \ [[maybe_unused]] auto aluChip_alu_u16_r2_shift = View(new_term.aluChip_alu_u16_r2_shift); \ + [[maybe_unused]] auto aluChip_alu_u16_r1_shift = View(new_term.aluChip_alu_u16_r1_shift); \ [[maybe_unused]] auto aluChip_alu_u16_r5_shift = View(new_term.aluChip_alu_u16_r5_shift); \ - [[maybe_unused]] auto aluChip_alu_u16_r0_shift = View(new_term.aluChip_alu_u16_r0_shift); \ - [[maybe_unused]] auto aluChip_alu_u16_r7_shift = View(new_term.aluChip_alu_u16_r7_shift); \ - [[maybe_unused]] auto aluChip_alu_u16_r3_shift = View(new_term.aluChip_alu_u16_r3_shift); \ - [[maybe_unused]] auto avmMini_internal_return_ptr_shift = View(new_term.avmMini_internal_return_ptr_shift); \ - [[maybe_unused]] auto avmMini_pc_shift = View(new_term.avmMini_pc_shift); + [[maybe_unused]] auto memTrace_m_addr_shift = View(new_term.memTrace_m_addr_shift); \ + [[maybe_unused]] auto memTrace_m_val_shift = View(new_term.memTrace_m_val_shift); \ + [[maybe_unused]] auto memTrace_m_tag_shift = View(new_term.memTrace_m_tag_shift); \ + [[maybe_unused]] auto memTrace_m_rw_shift = View(new_term.memTrace_m_rw_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp index 4de2e1cc3b6..62a871802cb 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp @@ -7,24 +7,33 @@ namespace proof_system::AvmMini_vm { template struct Mem_traceRow { - FF memTrace_m_rw{}; - FF memTrace_m_tag_err{}; - FF memTrace_m_addr{}; FF memTrace_m_last{}; - FF memTrace_m_rw_shift{}; + FF memTrace_m_rw{}; FF memTrace_m_tag{}; + FF memTrace_m_lastAccess{}; + FF memTrace_m_addr_shift{}; + FF memTrace_m_in_tag{}; FF memTrace_m_one_min_inv{}; FF memTrace_m_val_shift{}; - FF memTrace_m_val{}; - FF memTrace_m_addr_shift{}; FF memTrace_m_tag_shift{}; - FF memTrace_m_in_tag{}; - FF memTrace_m_lastAccess{}; + FF memTrace_m_addr{}; + FF memTrace_m_val{}; + FF memTrace_m_tag_err{}; + FF memTrace_m_rw_shift{}; }; inline std::string get_relation_label_mem_trace(int index) { switch (index) { + case 6: + return "MEM_READ_WRITE_TAG_CONSISTENCY"; + + case 9: + return "MEM_IN_TAG_CONSISTENCY_2"; + + case 7: + return "MEM_ZERO_INIT"; + case 5: return "MEM_READ_WRITE_VAL_CONSISTENCY"; @@ -33,15 +42,6 @@ inline std::string get_relation_label_mem_trace(int index) case 4: return "MEM_LAST_ACCESS_DELIMITER"; - - case 9: - return "MEM_IN_TAG_CONSISTENCY_2"; - - case 7: - return "MEM_ZERO_INIT"; - - case 6: - return "MEM_READ_WRITE_TAG_CONSISTENCY"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_alu_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_alu_trace.cpp index 708ecbe1f45..92dc198ed09 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_alu_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_alu_trace.cpp @@ -33,7 +33,7 @@ std::vector AvmMiniAluTraceBuilder::final /** * @brief Build Alu trace and compute the result of an addition of type defined by in_tag. * - * @param a Left operand of the additon + * @param a Left operand of the addition * @param b Right operand of the addition * @param in_tag Instruction tag defining the number of bits on which the addition applies. * It is assumed that the caller never uses the type u0. @@ -51,6 +51,7 @@ FF AvmMiniAluTraceBuilder::add(FF const& a, FF const& b, AvmMemoryTag in_tag, ui switch (in_tag) { case AvmMemoryTag::ff: c = a + b; + break; case AvmMemoryTag::u8: { uint8_t a_u8 = static_cast(uint256_t(a).data[0]); uint8_t b_u8 = static_cast(uint256_t(b).data[0]); @@ -175,6 +176,7 @@ FF AvmMiniAluTraceBuilder::sub(FF const& a, FF const& b, AvmMemoryTag in_tag, ui switch (in_tag) { case AvmMemoryTag::ff: c = a - b; + break; case AvmMemoryTag::u8: { uint8_t a_u8 = static_cast(uint256_t(a).data[0]); uint8_t b_u8 = static_cast(uint256_t(b).data[0]); @@ -288,4 +290,113 @@ FF AvmMiniAluTraceBuilder::sub(FF const& a, FF const& b, AvmMemoryTag in_tag, ui return c; } +/** + * @brief Build Alu trace and compute the result of an multiplication of type defined by in_tag. + * + * @param a Left operand of the multiplication + * @param b Right operand of the multiplication + * @param in_tag Instruction tag defining the number of bits on which the multiplication applies. + * It is assumed that the caller never uses the type u0. + * @param clk Clock referring to the operation in the main trace. + * + * @return FF The result of the multiplication casted in a finite field element + */ +FF AvmMiniAluTraceBuilder::mul(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t const clk) +{ + FF c{}; + bool carry = false; + uint8_t alu_u8_r0{}; + uint8_t alu_u8_r1{}; + + std::array alu_u16_reg{}; + + switch (in_tag) { + case AvmMemoryTag::ff: + c = a * b; + break; + case AvmMemoryTag::u8: { + uint16_t a_u16 = static_cast(uint256_t(a).data[0]); + uint16_t b_u16 = static_cast(uint256_t(b).data[0]); + uint16_t c_u16 = a_u16 * b_u16; // Multiplication over the integers (not mod. 2^8) + + // Decompose c_u16 = r0 + 2^8 * r1 with r0, r1 8-bit registers + alu_u8_r0 = static_cast(c_u16); + alu_u8_r1 = static_cast(c_u16 >> 8); + + c = FF{ uint256_t{ alu_u8_r0 } }; + break; + } + case AvmMemoryTag::u16: { + uint32_t a_u32 = static_cast(uint256_t(a).data[0]); + uint32_t b_u32 = static_cast(uint256_t(b).data[0]); + uint32_t c_u32 = a_u32 * b_u32; // Multiplication over the integers (not mod. 2^16) + + // Decompose c_u32 = r0 + 2^16 * r1 with r0, r1 16-bit registers + alu_u16_reg.at(0) = static_cast(c_u32); + alu_u16_reg.at(1) = static_cast(c_u32 >> 16); + + c = FF{ uint256_t{ alu_u16_reg.at(0) } }; + break; + } + case AvmMemoryTag::u32: { + uint64_t a_u64 = static_cast(uint256_t(a).data[0]); + uint64_t b_u64 = static_cast(uint256_t(b).data[0]); + uint64_t c_u64 = a_u64 * b_u64; // Multiplication over the integers (not mod. 2^32) + + // Decompose c_u64 = r0 + 2^16 * r1 + 2^32 * r2 + 2^48 * r3 with r0, r1, r2, r3 16-bit registers + uint64_t c_trunc_64 = c_u64; + for (size_t i = 0; i < 4; i++) { + alu_u16_reg.at(i) = static_cast(c_trunc_64); + c_trunc_64 >>= 16; + } + + c = FF{ uint256_t{ static_cast(c_u64) } }; + + break; + } + case AvmMemoryTag::u64: { + uint128_t a_u128 = static_cast(uint256_t(a).data[0]); + uint128_t b_u128 = static_cast(uint256_t(b).data[0]); + uint128_t c_u128 = a_u128 * b_u128; // Multiplication over the integers (not mod. 2^64) + + // Decompose c_u128 = r0 + 2^16 * r1 + .. + 2^112 r7 with r0, r1 ... r7 16-bit registers + uint128_t c_trunc_128 = c_u128; + for (size_t i = 0; i < 8; i++) { + alu_u16_reg.at(i) = static_cast(c_trunc_128); + c_trunc_128 >>= 16; + } + + c = FF{ uint256_t{ static_cast(c_u128) } }; + + break; + } + case AvmMemoryTag::u128: { + break; + // TODO + } + case AvmMemoryTag::u0: // Unsupported as instruction tag + return FF{ 0 }; + } + + alu_trace.push_back(AvmMiniAluTraceBuilder::AluTraceEntry{ + .alu_clk = clk, + .alu_op_mul = true, + .alu_ff_tag = in_tag == AvmMemoryTag::ff, + .alu_u8_tag = in_tag == AvmMemoryTag::u8, + .alu_u16_tag = in_tag == AvmMemoryTag::u16, + .alu_u32_tag = in_tag == AvmMemoryTag::u32, + .alu_u64_tag = in_tag == AvmMemoryTag::u64, + .alu_u128_tag = in_tag == AvmMemoryTag::u128, + .alu_ia = a, + .alu_ib = b, + .alu_ic = c, + .alu_cf = carry, + .alu_u8_r0 = alu_u8_r0, + .alu_u8_r1 = alu_u8_r1, + .alu_u16_reg = alu_u16_reg, + }); + + return c; +} + } // namespace avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_alu_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_alu_trace.hpp index 977e51949f0..c8715710ed5 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_alu_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_alu_trace.hpp @@ -12,6 +12,7 @@ class AvmMiniAluTraceBuilder { bool alu_op_add = false; bool alu_op_sub = false; + bool alu_op_mul = false; bool alu_ff_tag = false; bool alu_u8_tag = false; @@ -27,6 +28,7 @@ class AvmMiniAluTraceBuilder { bool alu_cf = false; uint8_t alu_u8_r0{}; + uint8_t alu_u8_r1{}; std::array alu_u16_reg{}; }; @@ -37,6 +39,7 @@ class AvmMiniAluTraceBuilder { FF add(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); FF sub(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); + FF mul(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); private: std::vector alu_trace; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_helper.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_helper.cpp index 207485ac63d..9e1fd096c89 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_helper.cpp @@ -39,6 +39,12 @@ void log_avmMini_trace(std::vector const& trace, size_t beg, size_t end) info("internal_return: ", trace.at(i).avmMini_sel_internal_return); info("internal_return_ptr:", trace.at(i).avmMini_internal_return_ptr); + info("=======ALU TRACE====================================================================="); + info("alu_clk ", trace.at(i).aluChip_alu_clk); + info("alu_ia ", trace.at(i).aluChip_alu_ia); + info("alu_ib ", trace.at(i).aluChip_alu_ib); + info("alu_ic ", trace.at(i).aluChip_alu_ic); + info("=======MAIN TRACE===================================================================="); info("ia: ", trace.at(i).avmMini_ia); info("ib: ", trace.at(i).avmMini_ib); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_trace.cpp index 411a335dd19..b112a01be02 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/AvmMini_trace.cpp @@ -122,7 +122,7 @@ void AvmMiniTraceBuilder::sub(uint32_t a_offset, uint32_t b_offset, uint32_t dst }); }; -/** TODO: Implement for non finite field types +/** * @brief Multiplication with direct memory access. * * @param a_offset An index in memory pointing to the first operand of the multiplication. @@ -140,9 +140,9 @@ void AvmMiniTraceBuilder::mul(uint32_t a_offset, uint32_t b_offset, uint32_t dst bool tag_match = read_a.tag_match && read_b.tag_match; // a * b = c - FF a = read_a.val; - FF b = read_b.val; - FF c = a * b; + FF a = tag_match ? read_a.val : FF(0); + FF b = tag_match ? read_b.val : FF(0); + FF c = alu_trace_builder.mul(a, b, in_tag, clk); // Write into memory value c from intermediate register ic. mem_trace_builder.write_into_memory(clk, IntermRegister::ic, dst_offset, c, in_tag); @@ -154,9 +154,9 @@ void AvmMiniTraceBuilder::mul(uint32_t a_offset, uint32_t b_offset, uint32_t dst .avmMini_sel_op_mul = FF(1), .avmMini_in_tag = FF(static_cast(in_tag)), .avmMini_tag_err = FF(static_cast(!tag_match)), - .avmMini_ia = tag_match ? a : FF(0), - .avmMini_ib = tag_match ? b : FF(0), - .avmMini_ic = tag_match ? c : FF(0), + .avmMini_ia = a, + .avmMini_ib = b, + .avmMini_ic = c, .avmMini_mem_op_a = FF(1), .avmMini_mem_op_b = FF(1), .avmMini_mem_op_c = FF(1), @@ -629,6 +629,7 @@ std::vector AvmMiniTraceBuilder::finalize() dest.aluChip_alu_op_add = FF(static_cast(src.alu_op_add)); dest.aluChip_alu_op_sub = FF(static_cast(src.alu_op_sub)); + dest.aluChip_alu_op_mul = FF(static_cast(src.alu_op_mul)); dest.aluChip_alu_ff_tag = FF(static_cast(src.alu_ff_tag)); dest.aluChip_alu_u8_tag = FF(static_cast(src.alu_u8_tag)); @@ -644,6 +645,7 @@ std::vector AvmMiniTraceBuilder::finalize() dest.aluChip_alu_cf = FF(static_cast(src.alu_cf)); dest.aluChip_alu_u8_r0 = FF(src.alu_u8_r0); + dest.aluChip_alu_u8_r1 = FF(src.alu_u8_r1); dest.aluChip_alu_u16_r0 = FF(src.alu_u16_reg.at(0)); dest.aluChip_alu_u16_r1 = FF(src.alu_u16_reg.at(1)); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/AvmMini_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/AvmMini_arithmetic.test.cpp index feb58ee9c97..c4ac9ab809a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/AvmMini_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/AvmMini_arithmetic.test.cpp @@ -168,7 +168,7 @@ TEST_F(AvmMiniArithmeticTestsFF, addition) EXPECT_EQ(alu_row.aluChip_alu_ff_tag, FF(1)); EXPECT_EQ(alu_row.aluChip_alu_cf, FF(0)); - EXPECT_EQ(alu_row.aluChip_alu_u8_r0, FF(41)); + EXPECT_EQ(alu_row.aluChip_alu_u8_r0, FF(0)); validate_trace_proof(std::move(trace)); } @@ -187,7 +187,7 @@ TEST_F(AvmMiniArithmeticTestsFF, subtraction) EXPECT_EQ(alu_row.aluChip_alu_ff_tag, FF(1)); EXPECT_EQ(alu_row.aluChip_alu_cf, FF(0)); - EXPECT_EQ(alu_row.aluChip_alu_u8_r0, FF(17)); + EXPECT_EQ(alu_row.aluChip_alu_u8_r0, FF(0)); validate_trace_proof(std::move(trace)); } @@ -954,6 +954,8 @@ TEST_F(AvmMiniArithmeticNegativeTestsFF, subtraction) // Memory layout: [8,4,17,0,0,0,....] trace_builder.sub(2, 0, 1, AvmMemoryTag::ff); // [8,9,17,0,0,0....] + trace_builder.halt(); + auto trace = trace_builder.finalize(); auto select_row = [](Row r) { return r.avmMini_sel_op_sub == FF(1); }; @@ -969,10 +971,11 @@ TEST_F(AvmMiniArithmeticNegativeTestsFF, multiplication) // Memory layout: [5,0,20,0,0,0,....] trace_builder.mul(2, 0, 1, AvmMemoryTag::ff); // [5,100,20,0,0,0....] + trace_builder.halt(); auto trace = trace_builder.finalize(); auto select_row = [](Row r) { return r.avmMini_sel_op_mul == FF(1); }; - mutate_ic_in_trace(trace, std::move(select_row), FF(1000)); + mutate_ic_in_trace(trace, std::move(select_row), FF(1000), true); EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "SUBOP_MULTIPLICATION_FF"); } @@ -984,6 +987,7 @@ TEST_F(AvmMiniArithmeticNegativeTestsFF, divisionFF) // Memory layout: [15,315,0,0,0,0,....] trace_builder.div(1, 0, 2, AvmMemoryTag::ff); // [15,315,21,0,0,0....] + trace_builder.halt(); auto trace = trace_builder.finalize(); auto select_row = [](Row r) { return r.avmMini_sel_op_div == FF(1); }; @@ -1000,6 +1004,7 @@ TEST_F(AvmMiniArithmeticNegativeTestsFF, divisionNoZeroButError) // Memory layout: [15,315,0,0,0,0,....] trace_builder.div(1, 0, 2, AvmMemoryTag::ff); // [15,315,21,0,0,0....] + trace_builder.halt(); auto trace = trace_builder.finalize(); // Find the first row enabling the division selector @@ -1042,6 +1047,7 @@ TEST_F(AvmMiniArithmeticNegativeTestsFF, divisionZeroByZeroNoError) { // Memory layout: [0,0,0,0,0,0,....] trace_builder.div(0, 1, 2, AvmMemoryTag::ff); // [0,0,0,0,0,0....] + trace_builder.halt(); auto trace = trace_builder.finalize(); // Find the first row enabling the division selector @@ -1062,6 +1068,7 @@ TEST_F(AvmMiniArithmeticNegativeTestsFF, operationWithErrorFlag) // Memory layout: [37,4,11,0,0,0,....] trace_builder.add(0, 1, 4, AvmMemoryTag::ff); // [37,4,11,0,41,0,....] trace_builder.return_op(0, 5); + trace_builder.halt(); auto trace = trace_builder.finalize(); // Find the first row enabling the addition selector