From 5596bb3a19fce545b6276231d938464948f08f79 Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Wed, 29 May 2024 15:54:38 +0100 Subject: [PATCH] feat(avm): sha256_compression (#6452) Please read [contributing guidelines](CONTRIBUTING.md) and remove this line. --- barretenberg/cpp/pil/avm/avm_main.pil | 14 +- .../cpp/pil/avm/gadgets/avm_sha256.pil | 14 + .../relations/generated/avm/avm_main.hpp | 459 +++++++++--------- .../relations/generated/avm/avm_sha256.hpp | 47 ++ .../relations/generated/avm/declare_views.hpp | 7 + .../generated/avm/perm_main_sha256.hpp | 102 ++++ .../vm/avm_trace/avm_deserialization.cpp | 3 + .../vm/avm_trace/avm_execution.cpp | 7 + .../barretenberg/vm/avm_trace/avm_opcode.cpp | 9 +- .../barretenberg/vm/avm_trace/avm_opcode.hpp | 18 +- .../barretenberg/vm/avm_trace/avm_trace.cpp | 202 +++++++- .../barretenberg/vm/avm_trace/avm_trace.hpp | 22 + .../vm/avm_trace/gadgets/avm_sha256.cpp | 124 +++++ .../vm/avm_trace/gadgets/avm_sha256.hpp | 30 ++ .../vm/generated/avm_circuit_builder.hpp | 36 +- .../barretenberg/vm/generated/avm_flavor.hpp | 77 ++- .../barretenberg/vm/generated/avm_prover.cpp | 16 + .../vm/generated/avm_verifier.cpp | 13 + .../vm/tests/avm_execution.test.cpp | 95 ++++ .../barretenberg/vm/tests/helpers.test.cpp | 1 + 20 files changed, 1036 insertions(+), 260 deletions(-) create mode 100644 barretenberg/cpp/pil/avm/gadgets/avm_sha256.pil create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_sha256.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_sha256.hpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/avm_trace/gadgets/avm_sha256.cpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/avm_trace/gadgets/avm_sha256.hpp diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index 17e8d37d812..71e0523052f 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -5,6 +5,7 @@ include "avm_binary.pil"; include "constants.pil"; include "avm_kernel.pil"; include "gadgets/avm_conversion.pil"; +include "gadgets/avm_sha256.pil"; namespace avm_main(256); //===== CONSTANT POLYNOMIALS ================================================== @@ -48,6 +49,7 @@ namespace avm_main(256); //===== Gadget Selectors ====================================================== pol commit sel_op_radix_le; + pol commit sel_op_sha256; //===== Fix Range Checks Selectors============================================= // We re-use the clk column for the lookup values of 8-bit resp. 16-bit range check. @@ -202,6 +204,7 @@ namespace avm_main(256); sel_op_sstore * (1 - sel_op_sstore) = 0; sel_op_radix_le * (1 - sel_op_radix_le) = 0; + sel_op_sha256 * (1 - sel_op_sha256) = 0; sel_op_add * (1 - sel_op_add) = 0; sel_op_sub * (1 - sel_op_sub) = 0; @@ -354,8 +357,10 @@ namespace avm_main(256); //===== CONTROL_FLOW_CONSISTENCY ============================================ pol INTERNAL_CALL_STACK_SELECTORS = (first + sel_internal_call + sel_internal_return + sel_halt); - pol OPCODE_SELECTORS = (sel_op_add + sel_op_sub + sel_op_div + sel_op_fdiv + sel_op_mul + sel_op_not - + sel_op_eq + sel_op_and + sel_op_or + sel_op_xor + sel_op_cast + KERNEL_INPUT_SELECTORS + KERNEL_OUTPUT_SELECTORS); + pol ALL_BINARY_SEL = sel_op_and + sel_op_or + sel_op_xor; + pol ALL_GADGET_SEL = sel_op_radix_le + sel_op_sha256; + pol ALL_MEMORY_SEL = sel_cmov + sel_mov; + pol OPCODE_SELECTORS = ALU_ALL_SEL + ALL_BINARY_SEL + ALL_MEMORY_SEL + ALL_GADGET_SEL + KERNEL_INPUT_SELECTORS + KERNEL_OUTPUT_SELECTORS; // Program counter must increment if not jumping or returning #[PC_INCREMENT] @@ -549,6 +554,11 @@ namespace avm_main(256); is avm_conversion.to_radix_le_sel {avm_conversion.clk, avm_conversion.input, avm_conversion.radix, avm_conversion.num_limbs}; + #[PERM_MAIN_SHA256] + sel_op_sha256 {clk, ia, ib, ic} + is + avm_sha256.sha256_compression_sel {avm_sha256.clk, avm_sha256.state, avm_sha256.input, avm_sha256.output}; + #[PERM_MAIN_MEM_A] mem_op_a {clk, space_id, mem_idx_a, ia, rwa , r_in_tag, w_in_tag, sel_mov_a, sel_cmov} diff --git a/barretenberg/cpp/pil/avm/gadgets/avm_sha256.pil b/barretenberg/cpp/pil/avm/gadgets/avm_sha256.pil new file mode 100644 index 00000000000..f7ca8b8337a --- /dev/null +++ b/barretenberg/cpp/pil/avm/gadgets/avm_sha256.pil @@ -0,0 +1,14 @@ +include "../avm_main.pil"; + +namespace avm_sha256(256); + + pol commit clk; + + // Selector for Radix Operation + pol commit sha256_compression_sel; + sha256_compression_sel * (1 - sha256_compression_sel) = 0; + + // These will all be arrays, but we just store the first element for permutation to the main trace for now + pol commit state; + pol commit input; + pol commit output; 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 a8e11c4ca35..1f7ca35ef2c 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -88,6 +88,7 @@ template struct Avm_mainRow { FF avm_main_sel_op_or{}; FF avm_main_sel_op_radix_le{}; FF avm_main_sel_op_sender{}; + FF avm_main_sel_op_sha256{}; FF avm_main_sel_op_shl{}; FF avm_main_sel_op_shr{}; FF avm_main_sel_op_sload{}; @@ -105,127 +106,127 @@ template struct Avm_mainRow { inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 56: + case 57: return "OUTPUT_U8"; - case 57: + case 58: return "SUBOP_FDIV"; - case 58: + case 59: return "SUBOP_FDIV_ZERO_ERR1"; - case 59: + case 60: return "SUBOP_FDIV_ZERO_ERR2"; - case 60: + case 61: return "SUBOP_FDIV_R_IN_TAG_FF"; - case 61: + case 62: return "SUBOP_FDIV_W_IN_TAG_FF"; - case 62: + case 63: return "SUBOP_ERROR_RELEVANT_OP"; - case 63: + case 64: return "KERNEL_INPUT_ACTIVE_CHECK"; - case 64: + case 65: return "KERNEL_OUTPUT_ACTIVE_CHECK"; - case 66: + case 67: return "RETURN_POINTER_INCREMENT"; - case 72: + case 73: return "RETURN_POINTER_DECREMENT"; - case 77: + case 78: return "PC_INCREMENT"; - case 78: + case 79: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 79: + case 80: return "SPACE_ID_INTERNAL"; - case 80: + case 81: return "SPACE_ID_STANDARD_OPCODES"; - case 81: + case 82: return "CMOV_CONDITION_RES_1"; - case 82: + case 83: return "CMOV_CONDITION_RES_2"; - case 85: + case 86: return "MOV_SAME_VALUE_A"; - case 86: + case 87: return "MOV_SAME_VALUE_B"; - case 87: + case 88: return "MOV_MAIN_SAME_TAG"; - case 91: + case 92: return "SENDER_KERNEL"; - case 92: + case 93: return "ADDRESS_KERNEL"; - case 93: + case 94: return "FEE_DA_GAS_KERNEL"; - case 94: + case 95: return "FEE_L2_GAS_KERNEL"; - case 95: + case 96: return "FEE_TRANSACTION_FEE_KERNEL"; - case 96: + case 97: return "CHAIN_ID_KERNEL"; - case 97: + case 98: return "VERSION_KERNEL"; - case 98: + case 99: return "BLOCK_NUMBER_KERNEL"; - case 99: + case 100: return "COINBASE_KERNEL"; - case 100: + case 101: return "TIMESTAMP_KERNEL"; - case 101: + case 102: return "NOTE_HASH_KERNEL_OUTPUT"; - case 103: + case 104: return "EMIT_NOTE_HASH_KERNEL_OUTPUT"; - case 105: + case 106: return "NULLIFIER_EXISTS_KERNEL_OUTPUT"; - case 107: + case 108: return "EMIT_NULLIFIER_KERNEL_OUTPUT"; - case 109: + case 110: return "L1_TO_L2_MSG_EXISTS_KERNEL_OUTPUT"; - case 111: + case 112: return "EMIT_UNENCRYPTED_LOG_KERNEL_OUTPUT"; - case 113: + case 114: return "EMIT_L2_TO_L1_MSGS_KERNEL_OUTPUT"; - case 115: + case 116: return "SLOAD_KERNEL_OUTPUT"; - case 117: + case 118: return "SSTORE_KERNEL_OUTPUT"; - case 120: + case 121: return "BIN_SEL_1"; - case 121: + case 122: return "BIN_SEL_2"; } return std::to_string(index); @@ -235,11 +236,11 @@ template class avm_mainImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 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, 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, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 4, 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, 2, + 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, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 4, 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, 2, }; template @@ -413,7 +414,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = (avm_main_sel_op_add * (-avm_main_sel_op_add + FF(1))); + auto tmp = (avm_main_sel_op_sha256 * (-avm_main_sel_op_sha256 + FF(1))); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -421,7 +422,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = (avm_main_sel_op_sub * (-avm_main_sel_op_sub + FF(1))); + auto tmp = (avm_main_sel_op_add * (-avm_main_sel_op_add + FF(1))); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -429,7 +430,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = (avm_main_sel_op_mul * (-avm_main_sel_op_mul + FF(1))); + auto tmp = (avm_main_sel_op_sub * (-avm_main_sel_op_sub + FF(1))); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -437,7 +438,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (avm_main_sel_op_div * (-avm_main_sel_op_div + FF(1))); + auto tmp = (avm_main_sel_op_mul * (-avm_main_sel_op_mul + FF(1))); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -445,7 +446,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = (avm_main_sel_op_fdiv * (-avm_main_sel_op_fdiv + FF(1))); + auto tmp = (avm_main_sel_op_div * (-avm_main_sel_op_div + FF(1))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -453,7 +454,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (avm_main_sel_op_not * (-avm_main_sel_op_not + FF(1))); + auto tmp = (avm_main_sel_op_fdiv * (-avm_main_sel_op_fdiv + FF(1))); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -461,7 +462,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = (avm_main_sel_op_eq * (-avm_main_sel_op_eq + FF(1))); + auto tmp = (avm_main_sel_op_not * (-avm_main_sel_op_not + FF(1))); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -469,7 +470,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = (avm_main_sel_op_and * (-avm_main_sel_op_and + FF(1))); + auto tmp = (avm_main_sel_op_eq * (-avm_main_sel_op_eq + FF(1))); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -477,7 +478,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(28); - auto tmp = (avm_main_sel_op_or * (-avm_main_sel_op_or + FF(1))); + auto tmp = (avm_main_sel_op_and * (-avm_main_sel_op_and + FF(1))); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -485,7 +486,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(29); - auto tmp = (avm_main_sel_op_xor * (-avm_main_sel_op_xor + FF(1))); + auto tmp = (avm_main_sel_op_or * (-avm_main_sel_op_or + FF(1))); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -493,7 +494,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(30); - auto tmp = (avm_main_sel_op_cast * (-avm_main_sel_op_cast + FF(1))); + auto tmp = (avm_main_sel_op_xor * (-avm_main_sel_op_xor + FF(1))); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -501,7 +502,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(31); - auto tmp = (avm_main_sel_op_lt * (-avm_main_sel_op_lt + FF(1))); + auto tmp = (avm_main_sel_op_cast * (-avm_main_sel_op_cast + FF(1))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -509,7 +510,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(32); - auto tmp = (avm_main_sel_op_lte * (-avm_main_sel_op_lte + FF(1))); + auto tmp = (avm_main_sel_op_lt * (-avm_main_sel_op_lt + FF(1))); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -517,7 +518,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(33); - auto tmp = (avm_main_sel_op_shl * (-avm_main_sel_op_shl + FF(1))); + auto tmp = (avm_main_sel_op_lte * (-avm_main_sel_op_lte + FF(1))); tmp *= scaling_factor; std::get<33>(evals) += tmp; } @@ -525,7 +526,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(34); - auto tmp = (avm_main_sel_op_shr * (-avm_main_sel_op_shr + FF(1))); + auto tmp = (avm_main_sel_op_shl * (-avm_main_sel_op_shl + FF(1))); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -533,7 +534,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(35); - auto tmp = (avm_main_sel_internal_call * (-avm_main_sel_internal_call + FF(1))); + auto tmp = (avm_main_sel_op_shr * (-avm_main_sel_op_shr + FF(1))); tmp *= scaling_factor; std::get<35>(evals) += tmp; } @@ -541,7 +542,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(36); - auto tmp = (avm_main_sel_internal_return * (-avm_main_sel_internal_return + FF(1))); + auto tmp = (avm_main_sel_internal_call * (-avm_main_sel_internal_call + FF(1))); tmp *= scaling_factor; std::get<36>(evals) += tmp; } @@ -549,7 +550,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(37); - auto tmp = (avm_main_sel_jump * (-avm_main_sel_jump + FF(1))); + auto tmp = (avm_main_sel_internal_return * (-avm_main_sel_internal_return + FF(1))); tmp *= scaling_factor; std::get<37>(evals) += tmp; } @@ -557,7 +558,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(38); - auto tmp = (avm_main_sel_halt * (-avm_main_sel_halt + FF(1))); + auto tmp = (avm_main_sel_jump * (-avm_main_sel_jump + FF(1))); tmp *= scaling_factor; std::get<38>(evals) += tmp; } @@ -565,7 +566,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(39); - auto tmp = (avm_main_sel_mov * (-avm_main_sel_mov + FF(1))); + auto tmp = (avm_main_sel_halt * (-avm_main_sel_halt + FF(1))); tmp *= scaling_factor; std::get<39>(evals) += tmp; } @@ -573,7 +574,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(40); - auto tmp = (avm_main_sel_cmov * (-avm_main_sel_cmov + FF(1))); + auto tmp = (avm_main_sel_mov * (-avm_main_sel_mov + FF(1))); tmp *= scaling_factor; std::get<40>(evals) += tmp; } @@ -581,7 +582,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(41); - auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); + auto tmp = (avm_main_sel_cmov * (-avm_main_sel_cmov + FF(1))); tmp *= scaling_factor; std::get<41>(evals) += tmp; } @@ -589,7 +590,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(42); - auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); + auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); tmp *= scaling_factor; std::get<42>(evals) += tmp; } @@ -597,7 +598,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(43); - auto tmp = (avm_main_id_zero * (-avm_main_id_zero + FF(1))); + auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); tmp *= scaling_factor; std::get<43>(evals) += tmp; } @@ -605,7 +606,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(44); - auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); + auto tmp = (avm_main_id_zero * (-avm_main_id_zero + FF(1))); tmp *= scaling_factor; std::get<44>(evals) += tmp; } @@ -613,7 +614,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(45); - auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); + auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); tmp *= scaling_factor; std::get<45>(evals) += tmp; } @@ -621,7 +622,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(46); - auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); + auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); tmp *= scaling_factor; std::get<46>(evals) += tmp; } @@ -629,7 +630,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(47); - auto tmp = (avm_main_mem_op_d * (-avm_main_mem_op_d + FF(1))); + auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); tmp *= scaling_factor; std::get<47>(evals) += tmp; } @@ -637,7 +638,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(48); - auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); + auto tmp = (avm_main_mem_op_d * (-avm_main_mem_op_d + FF(1))); tmp *= scaling_factor; std::get<48>(evals) += tmp; } @@ -645,7 +646,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(49); - auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); + auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); tmp *= scaling_factor; std::get<49>(evals) += tmp; } @@ -653,7 +654,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(50); - auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); + auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); tmp *= scaling_factor; std::get<50>(evals) += tmp; } @@ -661,7 +662,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(51); - auto tmp = (avm_main_rwd * (-avm_main_rwd + FF(1))); + auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); tmp *= scaling_factor; std::get<51>(evals) += tmp; } @@ -669,7 +670,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(52); - auto tmp = (avm_main_ind_op_a * (-avm_main_ind_op_a + FF(1))); + auto tmp = (avm_main_rwd * (-avm_main_rwd + FF(1))); tmp *= scaling_factor; std::get<52>(evals) += tmp; } @@ -677,7 +678,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(53); - auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); + auto tmp = (avm_main_ind_op_a * (-avm_main_ind_op_a + FF(1))); tmp *= scaling_factor; std::get<53>(evals) += tmp; } @@ -685,7 +686,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(54); - auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); + auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); tmp *= scaling_factor; std::get<54>(evals) += tmp; } @@ -693,7 +694,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(55); - auto tmp = (avm_main_ind_op_d * (-avm_main_ind_op_d + FF(1))); + auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); tmp *= scaling_factor; std::get<55>(evals) += tmp; } @@ -701,8 +702,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(56); - auto tmp = - (((avm_main_sel_op_eq + avm_main_sel_op_lte) + avm_main_sel_op_lt) * (avm_main_w_in_tag - FF(1))); + auto tmp = (avm_main_ind_op_d * (-avm_main_ind_op_d + FF(1))); tmp *= scaling_factor; std::get<56>(evals) += tmp; } @@ -711,7 +711,7 @@ template class avm_mainImpl { Avm_DECLARE_VIEWS(57); auto tmp = - ((avm_main_sel_op_fdiv * (-avm_main_op_err + FF(1))) * ((avm_main_ic * avm_main_ib) - avm_main_ia)); + (((avm_main_sel_op_eq + avm_main_sel_op_lte) + avm_main_sel_op_lt) * (avm_main_w_in_tag - FF(1))); tmp *= scaling_factor; std::get<57>(evals) += tmp; } @@ -719,8 +719,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(58); - auto tmp = ((avm_main_sel_op_fdiv + avm_main_sel_op_div) * - (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); + auto tmp = + ((avm_main_sel_op_fdiv * (-avm_main_op_err + FF(1))) * ((avm_main_ic * avm_main_ib) - avm_main_ia)); tmp *= scaling_factor; std::get<58>(evals) += tmp; } @@ -728,7 +728,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(59); - auto tmp = (((avm_main_sel_op_fdiv + avm_main_sel_op_div) * avm_main_op_err) * (-avm_main_inv + FF(1))); + 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<59>(evals) += tmp; } @@ -736,7 +737,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(60); - auto tmp = (avm_main_sel_op_fdiv * (avm_main_r_in_tag - FF(6))); + 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<60>(evals) += tmp; } @@ -744,7 +745,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(61); - auto tmp = (avm_main_sel_op_fdiv * (avm_main_w_in_tag - FF(6))); + auto tmp = (avm_main_sel_op_fdiv * (avm_main_r_in_tag - FF(6))); tmp *= scaling_factor; std::get<61>(evals) += tmp; } @@ -752,7 +753,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(62); - auto tmp = (avm_main_op_err * ((avm_main_sel_op_fdiv + avm_main_sel_op_div) - FF(1))); + auto tmp = (avm_main_sel_op_fdiv * (avm_main_w_in_tag - FF(6))); tmp *= scaling_factor; std::get<62>(evals) += tmp; } @@ -760,6 +761,14 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(63); + auto tmp = (avm_main_op_err * ((avm_main_sel_op_fdiv + avm_main_sel_op_div) - FF(1))); + tmp *= scaling_factor; + std::get<63>(evals) += tmp; + } + // Contribution 64 + { + Avm_DECLARE_VIEWS(64); + auto tmp = ((((((((((avm_main_sel_op_sender + avm_main_sel_op_address) + avm_main_sel_op_chain_id) + avm_main_sel_op_version) + avm_main_sel_op_block_number) + @@ -770,11 +779,11 @@ template class avm_mainImpl { avm_main_sel_op_transaction_fee) * (-avm_main_q_kernel_lookup + FF(1))); tmp *= scaling_factor; - std::get<63>(evals) += tmp; + std::get<64>(evals) += tmp; } - // Contribution 64 + // Contribution 65 { - Avm_DECLARE_VIEWS(64); + Avm_DECLARE_VIEWS(65); auto tmp = (((((((((avm_main_sel_op_note_hash_exists + avm_main_sel_op_emit_note_hash) + avm_main_sel_op_nullifier_exists) + @@ -786,22 +795,13 @@ template class avm_mainImpl { avm_main_sel_op_sstore) * (-avm_main_q_kernel_output_lookup + FF(1))); tmp *= scaling_factor; - std::get<64>(evals) += tmp; - } - // Contribution 65 - { - Avm_DECLARE_VIEWS(65); - - auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); - tmp *= scaling_factor; std::get<65>(evals) += tmp; } // Contribution 66 { Avm_DECLARE_VIEWS(66); - auto tmp = (avm_main_sel_internal_call * - (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr + FF(1)))); + auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<66>(evals) += tmp; } @@ -809,7 +809,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(67); - auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); + auto tmp = (avm_main_sel_internal_call * + (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr + FF(1)))); tmp *= scaling_factor; std::get<67>(evals) += tmp; } @@ -817,7 +818,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(68); - auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); tmp *= scaling_factor; std::get<68>(evals) += tmp; } @@ -825,7 +826,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(69); - auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); + auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<69>(evals) += tmp; } @@ -833,7 +834,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(70); - auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); + auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); tmp *= scaling_factor; std::get<70>(evals) += tmp; } @@ -841,7 +842,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(71); - auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); + auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); tmp *= scaling_factor; std::get<71>(evals) += tmp; } @@ -849,8 +850,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(72); - auto tmp = (avm_main_sel_internal_return * - (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr - FF(1)))); + auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<72>(evals) += tmp; } @@ -858,7 +858,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(73); - auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); + auto tmp = (avm_main_sel_internal_return * + (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr - FF(1)))); tmp *= scaling_factor; std::get<73>(evals) += tmp; } @@ -866,7 +867,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(74); - auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); tmp *= scaling_factor; std::get<74>(evals) += tmp; } @@ -874,7 +875,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(75); - auto tmp = (avm_main_sel_internal_return * avm_main_rwa); + auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<75>(evals) += tmp; } @@ -882,7 +883,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(76); - auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + auto tmp = (avm_main_sel_internal_return * avm_main_rwa); tmp *= scaling_factor; std::get<76>(evals) += tmp; } @@ -890,16 +891,27 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(77); + auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + tmp *= scaling_factor; + std::get<77>(evals) += tmp; + } + // Contribution 78 + { + Avm_DECLARE_VIEWS(78); + auto tmp = ((((-avm_main_first + FF(1)) * (-avm_main_sel_halt + FF(1))) * - ((((((((((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_div) + - avm_main_sel_op_fdiv) + - avm_main_sel_op_mul) + - avm_main_sel_op_not) + - avm_main_sel_op_eq) + - avm_main_sel_op_and) + - avm_main_sel_op_or) + - avm_main_sel_op_xor) + - avm_main_sel_op_cast) + + (((((((((((((((avm_main_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_sel_op_and + avm_main_sel_op_or) + avm_main_sel_op_xor)) + + (avm_main_sel_cmov + avm_main_sel_mov)) + + (avm_main_sel_op_radix_le + avm_main_sel_op_sha256)) + (((((((((avm_main_sel_op_sender + avm_main_sel_op_address) + avm_main_sel_op_chain_id) + avm_main_sel_op_version) + avm_main_sel_op_block_number) + @@ -918,57 +930,24 @@ template class avm_mainImpl { avm_main_sel_op_sstore))) * (avm_main_pc_shift - (avm_main_pc + FF(1)))); tmp *= scaling_factor; - std::get<77>(evals) += tmp; + std::get<78>(evals) += tmp; } - // Contribution 78 + // Contribution 79 { - Avm_DECLARE_VIEWS(78); + Avm_DECLARE_VIEWS(79); auto tmp = ((-(((avm_main_first + avm_main_sel_internal_call) + avm_main_sel_internal_return) + avm_main_sel_halt) + FF(1)) * (avm_main_internal_return_ptr_shift - avm_main_internal_return_ptr)); tmp *= scaling_factor; - std::get<78>(evals) += tmp; - } - // Contribution 79 - { - Avm_DECLARE_VIEWS(79); - - auto tmp = ((avm_main_sel_internal_call + avm_main_sel_internal_return) * (avm_main_space_id - FF(255))); - tmp *= scaling_factor; std::get<79>(evals) += tmp; } // Contribution 80 { Avm_DECLARE_VIEWS(80); - auto tmp = - (((((((((((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_div) + avm_main_sel_op_fdiv) + - avm_main_sel_op_mul) + - avm_main_sel_op_not) + - avm_main_sel_op_eq) + - avm_main_sel_op_and) + - avm_main_sel_op_or) + - avm_main_sel_op_xor) + - avm_main_sel_op_cast) + - (((((((((avm_main_sel_op_sender + avm_main_sel_op_address) + avm_main_sel_op_chain_id) + - avm_main_sel_op_version) + - avm_main_sel_op_block_number) + - avm_main_sel_op_coinbase) + - avm_main_sel_op_timestamp) + - avm_main_sel_op_fee_per_l2_gas) + - avm_main_sel_op_fee_per_da_gas) + - avm_main_sel_op_transaction_fee)) + - ((((((((avm_main_sel_op_note_hash_exists + avm_main_sel_op_emit_note_hash) + - avm_main_sel_op_nullifier_exists) + - avm_main_sel_op_emit_nullifier) + - avm_main_sel_op_l1_to_l2_msg_exists) + - avm_main_sel_op_emit_unencrypted_log) + - avm_main_sel_op_emit_l2_to_l1_msg) + - avm_main_sel_op_sload) + - avm_main_sel_op_sstore)) * - (avm_main_call_ptr - avm_main_space_id)); + auto tmp = ((avm_main_sel_internal_call + avm_main_sel_internal_return) * (avm_main_space_id - FF(255))); tmp *= scaling_factor; std::get<80>(evals) += tmp; } @@ -976,7 +955,35 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(81); - auto tmp = (avm_main_sel_cmov * (((avm_main_id * avm_main_inv) - FF(1)) + avm_main_id_zero)); + auto tmp = ((((((((((((((((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_sel_op_and + avm_main_sel_op_or) + avm_main_sel_op_xor)) + + (avm_main_sel_cmov + avm_main_sel_mov)) + + (avm_main_sel_op_radix_le + avm_main_sel_op_sha256)) + + (((((((((avm_main_sel_op_sender + avm_main_sel_op_address) + avm_main_sel_op_chain_id) + + avm_main_sel_op_version) + + avm_main_sel_op_block_number) + + avm_main_sel_op_coinbase) + + avm_main_sel_op_timestamp) + + avm_main_sel_op_fee_per_l2_gas) + + avm_main_sel_op_fee_per_da_gas) + + avm_main_sel_op_transaction_fee)) + + ((((((((avm_main_sel_op_note_hash_exists + avm_main_sel_op_emit_note_hash) + + avm_main_sel_op_nullifier_exists) + + avm_main_sel_op_emit_nullifier) + + avm_main_sel_op_l1_to_l2_msg_exists) + + avm_main_sel_op_emit_unencrypted_log) + + avm_main_sel_op_emit_l2_to_l1_msg) + + avm_main_sel_op_sload) + + avm_main_sel_op_sstore)) * + (avm_main_call_ptr - avm_main_space_id)); tmp *= scaling_factor; std::get<81>(evals) += tmp; } @@ -984,7 +991,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(82); - auto tmp = ((avm_main_sel_cmov * avm_main_id_zero) * (-avm_main_inv + FF(1))); + auto tmp = (avm_main_sel_cmov * (((avm_main_id * avm_main_inv) - FF(1)) + avm_main_id_zero)); tmp *= scaling_factor; std::get<82>(evals) += tmp; } @@ -992,7 +999,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(83); - auto tmp = (avm_main_sel_mov_a - (avm_main_sel_mov + (avm_main_sel_cmov * (-avm_main_id_zero + FF(1))))); + auto tmp = ((avm_main_sel_cmov * avm_main_id_zero) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; std::get<83>(evals) += tmp; } @@ -1000,7 +1007,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(84); - auto tmp = (avm_main_sel_mov_b - (avm_main_sel_cmov * avm_main_id_zero)); + auto tmp = (avm_main_sel_mov_a - (avm_main_sel_mov + (avm_main_sel_cmov * (-avm_main_id_zero + FF(1))))); tmp *= scaling_factor; std::get<84>(evals) += tmp; } @@ -1008,7 +1015,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(85); - auto tmp = (avm_main_sel_mov_a * (avm_main_ia - avm_main_ic)); + auto tmp = (avm_main_sel_mov_b - (avm_main_sel_cmov * avm_main_id_zero)); tmp *= scaling_factor; std::get<85>(evals) += tmp; } @@ -1016,7 +1023,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(86); - auto tmp = (avm_main_sel_mov_b * (avm_main_ib - avm_main_ic)); + auto tmp = (avm_main_sel_mov_a * (avm_main_ia - avm_main_ic)); tmp *= scaling_factor; std::get<86>(evals) += tmp; } @@ -1024,7 +1031,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(87); - auto tmp = ((avm_main_sel_mov + avm_main_sel_cmov) * (avm_main_r_in_tag - avm_main_w_in_tag)); + auto tmp = (avm_main_sel_mov_b * (avm_main_ib - avm_main_ic)); tmp *= scaling_factor; std::get<87>(evals) += tmp; } @@ -1032,6 +1039,14 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(88); + auto tmp = ((avm_main_sel_mov + avm_main_sel_cmov) * (avm_main_r_in_tag - avm_main_w_in_tag)); + tmp *= scaling_factor; + std::get<88>(evals) += tmp; + } + // Contribution 89 + { + Avm_DECLARE_VIEWS(89); + 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) + @@ -1045,11 +1060,11 @@ template class avm_mainImpl { (-avm_main_tag_err + FF(1))) * (-avm_main_op_err + FF(1)))); tmp *= scaling_factor; - std::get<88>(evals) += tmp; + std::get<89>(evals) += tmp; } - // Contribution 89 + // Contribution 90 { - Avm_DECLARE_VIEWS(89); + Avm_DECLARE_VIEWS(90); auto tmp = ((((((((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_mul) + avm_main_sel_op_div) + @@ -1061,21 +1076,13 @@ template class avm_mainImpl { avm_main_sel_op_shl) * (avm_main_alu_in_tag - avm_main_r_in_tag)); tmp *= scaling_factor; - std::get<89>(evals) += tmp; - } - // Contribution 90 - { - Avm_DECLARE_VIEWS(90); - - auto tmp = (avm_main_sel_op_cast * (avm_main_alu_in_tag - avm_main_w_in_tag)); - tmp *= scaling_factor; std::get<90>(evals) += tmp; } // Contribution 91 { Avm_DECLARE_VIEWS(91); - auto tmp = (avm_main_sel_op_sender * (avm_kernel_kernel_in_offset - FF(0))); + auto tmp = (avm_main_sel_op_cast * (avm_main_alu_in_tag - avm_main_w_in_tag)); tmp *= scaling_factor; std::get<91>(evals) += tmp; } @@ -1083,7 +1090,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(92); - auto tmp = (avm_main_sel_op_address * (avm_kernel_kernel_in_offset - FF(1))); + auto tmp = (avm_main_sel_op_sender * (avm_kernel_kernel_in_offset - FF(0))); tmp *= scaling_factor; std::get<92>(evals) += tmp; } @@ -1091,7 +1098,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(93); - auto tmp = (avm_main_sel_op_fee_per_da_gas * (avm_kernel_kernel_in_offset - FF(38))); + auto tmp = (avm_main_sel_op_address * (avm_kernel_kernel_in_offset - FF(1))); tmp *= scaling_factor; std::get<93>(evals) += tmp; } @@ -1099,7 +1106,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(94); - auto tmp = (avm_main_sel_op_fee_per_l2_gas * (avm_kernel_kernel_in_offset - FF(39))); + auto tmp = (avm_main_sel_op_fee_per_da_gas * (avm_kernel_kernel_in_offset - FF(38))); tmp *= scaling_factor; std::get<94>(evals) += tmp; } @@ -1107,7 +1114,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(95); - auto tmp = (avm_main_sel_op_transaction_fee * (avm_kernel_kernel_in_offset - FF(40))); + auto tmp = (avm_main_sel_op_fee_per_l2_gas * (avm_kernel_kernel_in_offset - FF(39))); tmp *= scaling_factor; std::get<95>(evals) += tmp; } @@ -1115,7 +1122,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(96); - auto tmp = (avm_main_sel_op_chain_id * (avm_kernel_kernel_in_offset - FF(29))); + auto tmp = (avm_main_sel_op_transaction_fee * (avm_kernel_kernel_in_offset - FF(40))); tmp *= scaling_factor; std::get<96>(evals) += tmp; } @@ -1123,7 +1130,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(97); - auto tmp = (avm_main_sel_op_version * (avm_kernel_kernel_in_offset - FF(30))); + auto tmp = (avm_main_sel_op_chain_id * (avm_kernel_kernel_in_offset - FF(29))); tmp *= scaling_factor; std::get<97>(evals) += tmp; } @@ -1131,7 +1138,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(98); - auto tmp = (avm_main_sel_op_block_number * (avm_kernel_kernel_in_offset - FF(31))); + auto tmp = (avm_main_sel_op_version * (avm_kernel_kernel_in_offset - FF(30))); tmp *= scaling_factor; std::get<98>(evals) += tmp; } @@ -1139,7 +1146,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(99); - auto tmp = (avm_main_sel_op_coinbase * (avm_kernel_kernel_in_offset - FF(33))); + auto tmp = (avm_main_sel_op_block_number * (avm_kernel_kernel_in_offset - FF(31))); tmp *= scaling_factor; std::get<99>(evals) += tmp; } @@ -1147,7 +1154,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(100); - auto tmp = (avm_main_sel_op_timestamp * (avm_kernel_kernel_in_offset - FF(32))); + auto tmp = (avm_main_sel_op_coinbase * (avm_kernel_kernel_in_offset - FF(33))); tmp *= scaling_factor; std::get<100>(evals) += tmp; } @@ -1155,8 +1162,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(101); - auto tmp = (avm_main_sel_op_note_hash_exists * - (avm_kernel_kernel_out_offset - (avm_kernel_note_hash_exist_write_offset + FF(0)))); + auto tmp = (avm_main_sel_op_timestamp * (avm_kernel_kernel_in_offset - FF(32))); tmp *= scaling_factor; std::get<101>(evals) += tmp; } @@ -1164,7 +1170,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(102); - auto tmp = (avm_main_first * avm_kernel_note_hash_exist_write_offset); + auto tmp = (avm_main_sel_op_note_hash_exists * + (avm_kernel_kernel_out_offset - (avm_kernel_note_hash_exist_write_offset + FF(0)))); tmp *= scaling_factor; std::get<102>(evals) += tmp; } @@ -1172,8 +1179,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(103); - auto tmp = (avm_main_sel_op_emit_note_hash * - (avm_kernel_kernel_out_offset - (avm_kernel_emit_note_hash_write_offset + FF(4)))); + auto tmp = (avm_main_first * avm_kernel_note_hash_exist_write_offset); tmp *= scaling_factor; std::get<103>(evals) += tmp; } @@ -1181,7 +1187,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(104); - auto tmp = (avm_main_first * avm_kernel_emit_note_hash_write_offset); + auto tmp = (avm_main_sel_op_emit_note_hash * + (avm_kernel_kernel_out_offset - (avm_kernel_emit_note_hash_write_offset + FF(4)))); tmp *= scaling_factor; std::get<104>(evals) += tmp; } @@ -1189,8 +1196,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(105); - auto tmp = (avm_main_sel_op_nullifier_exists * - (avm_kernel_kernel_out_offset - (avm_kernel_nullifier_exists_write_offset + FF(8)))); + auto tmp = (avm_main_first * avm_kernel_emit_note_hash_write_offset); tmp *= scaling_factor; std::get<105>(evals) += tmp; } @@ -1198,7 +1204,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(106); - auto tmp = (avm_main_first * avm_kernel_nullifier_exists_write_offset); + auto tmp = (avm_main_sel_op_nullifier_exists * + (avm_kernel_kernel_out_offset - (avm_kernel_nullifier_exists_write_offset + FF(8)))); tmp *= scaling_factor; std::get<106>(evals) += tmp; } @@ -1206,8 +1213,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(107); - auto tmp = (avm_main_sel_op_emit_nullifier * - (avm_kernel_kernel_out_offset - (avm_kernel_emit_nullifier_write_offset + FF(12)))); + auto tmp = (avm_main_first * avm_kernel_nullifier_exists_write_offset); tmp *= scaling_factor; std::get<107>(evals) += tmp; } @@ -1215,7 +1221,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(108); - auto tmp = (avm_main_first * avm_kernel_emit_nullifier_write_offset); + auto tmp = (avm_main_sel_op_emit_nullifier * + (avm_kernel_kernel_out_offset - (avm_kernel_emit_nullifier_write_offset + FF(12)))); tmp *= scaling_factor; std::get<108>(evals) += tmp; } @@ -1223,8 +1230,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(109); - auto tmp = (avm_main_sel_op_l1_to_l2_msg_exists * - (avm_kernel_kernel_out_offset - (avm_kernel_l1_to_l2_msg_exists_write_offset + FF(16)))); + auto tmp = (avm_main_first * avm_kernel_emit_nullifier_write_offset); tmp *= scaling_factor; std::get<109>(evals) += tmp; } @@ -1232,7 +1238,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(110); - auto tmp = (avm_main_first * avm_kernel_l1_to_l2_msg_exists_write_offset); + auto tmp = (avm_main_sel_op_l1_to_l2_msg_exists * + (avm_kernel_kernel_out_offset - (avm_kernel_l1_to_l2_msg_exists_write_offset + FF(16)))); tmp *= scaling_factor; std::get<110>(evals) += tmp; } @@ -1240,8 +1247,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(111); - auto tmp = (avm_main_sel_op_emit_unencrypted_log * - (avm_kernel_kernel_out_offset - (avm_kernel_emit_unencrypted_log_write_offset + FF(20)))); + auto tmp = (avm_main_first * avm_kernel_l1_to_l2_msg_exists_write_offset); tmp *= scaling_factor; std::get<111>(evals) += tmp; } @@ -1249,7 +1255,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(112); - auto tmp = (avm_main_first * avm_kernel_emit_unencrypted_log_write_offset); + auto tmp = (avm_main_sel_op_emit_unencrypted_log * + (avm_kernel_kernel_out_offset - (avm_kernel_emit_unencrypted_log_write_offset + FF(20)))); tmp *= scaling_factor; std::get<112>(evals) += tmp; } @@ -1257,8 +1264,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(113); - auto tmp = (avm_main_sel_op_emit_l2_to_l1_msg * - (avm_kernel_kernel_out_offset - (avm_kernel_emit_l2_to_l1_msg_write_offset + FF(24)))); + auto tmp = (avm_main_first * avm_kernel_emit_unencrypted_log_write_offset); tmp *= scaling_factor; std::get<113>(evals) += tmp; } @@ -1266,7 +1272,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(114); - auto tmp = (avm_main_first * avm_kernel_emit_l2_to_l1_msg_write_offset); + auto tmp = (avm_main_sel_op_emit_l2_to_l1_msg * + (avm_kernel_kernel_out_offset - (avm_kernel_emit_l2_to_l1_msg_write_offset + FF(24)))); tmp *= scaling_factor; std::get<114>(evals) += tmp; } @@ -1274,8 +1281,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(115); - auto tmp = - (avm_main_sel_op_sload * (avm_kernel_kernel_out_offset - (avm_kernel_sload_write_offset + FF(28)))); + auto tmp = (avm_main_first * avm_kernel_emit_l2_to_l1_msg_write_offset); tmp *= scaling_factor; std::get<115>(evals) += tmp; } @@ -1283,7 +1289,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(116); - auto tmp = (avm_main_first * avm_kernel_sload_write_offset); + auto tmp = + (avm_main_sel_op_sload * (avm_kernel_kernel_out_offset - (avm_kernel_sload_write_offset + FF(28)))); tmp *= scaling_factor; std::get<116>(evals) += tmp; } @@ -1291,8 +1298,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(117); - auto tmp = - (avm_main_sel_op_sstore * (avm_kernel_kernel_out_offset - (avm_kernel_sstore_write_offset + FF(32)))); + auto tmp = (avm_main_first * avm_kernel_sload_write_offset); tmp *= scaling_factor; std::get<117>(evals) += tmp; } @@ -1300,7 +1306,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(118); - auto tmp = (avm_main_first * avm_kernel_sstore_write_offset); + auto tmp = + (avm_main_sel_op_sstore * (avm_kernel_kernel_out_offset - (avm_kernel_sstore_write_offset + FF(32)))); tmp *= scaling_factor; std::get<118>(evals) += tmp; } @@ -1308,6 +1315,14 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(119); + auto tmp = (avm_main_first * avm_kernel_sstore_write_offset); + tmp *= scaling_factor; + std::get<119>(evals) += tmp; + } + // Contribution 120 + { + Avm_DECLARE_VIEWS(120); + auto tmp = (((((((((avm_main_sel_op_note_hash_exists + avm_main_sel_op_emit_note_hash) + avm_main_sel_op_nullifier_exists) + avm_main_sel_op_emit_nullifier) + @@ -1318,23 +1333,23 @@ template class avm_mainImpl { avm_main_sel_op_sstore) * (avm_kernel_side_effect_counter_shift - (avm_kernel_side_effect_counter + FF(1)))); tmp *= scaling_factor; - std::get<119>(evals) += tmp; + std::get<120>(evals) += tmp; } - // Contribution 120 + // Contribution 121 { - Avm_DECLARE_VIEWS(120); + Avm_DECLARE_VIEWS(121); auto tmp = (avm_main_bin_op_id - (avm_main_sel_op_or + (avm_main_sel_op_xor * FF(2)))); tmp *= scaling_factor; - std::get<120>(evals) += tmp; + std::get<121>(evals) += tmp; } - // Contribution 121 + // Contribution 122 { - Avm_DECLARE_VIEWS(121); + Avm_DECLARE_VIEWS(122); auto tmp = (avm_main_bin_sel - ((avm_main_sel_op_and + avm_main_sel_op_or) + avm_main_sel_op_xor)); tmp *= scaling_factor; - std::get<121>(evals) += tmp; + std::get<122>(evals) += tmp; } } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_sha256.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_sha256.hpp new file mode 100644 index 00000000000..8daf1fce39f --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_sha256.hpp @@ -0,0 +1,47 @@ + +#pragma once +#include "../../relation_parameters.hpp" +#include "../../relation_types.hpp" +#include "./declare_views.hpp" + +namespace bb::Avm_vm { + +template struct Avm_sha256Row { + FF avm_sha256_sha256_compression_sel{}; +}; + +inline std::string get_relation_label_avm_sha256(int index) +{ + switch (index) {} + return std::to_string(index); +} + +template class avm_sha256Impl { + public: + using FF = FF_; + + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, + }; + + template + void static accumulate(ContainerOverSubrelations& evals, + const AllEntities& new_term, + [[maybe_unused]] const RelationParameters&, + [[maybe_unused]] const FF& scaling_factor) + { + + // Contribution 0 + { + Avm_DECLARE_VIEWS(0); + + auto tmp = (avm_sha256_sha256_compression_sel * (-avm_sha256_sha256_compression_sel + FF(1))); + tmp *= scaling_factor; + std::get<0>(evals) += tmp; + } + } +}; + +template using avm_sha256 = Relation>; + +} // namespace bb::Avm_vm \ No newline at end of file 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 f0d9c1a2d2c..a3fcd492755 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -214,6 +214,7 @@ [[maybe_unused]] auto avm_main_sel_op_or = View(new_term.avm_main_sel_op_or); \ [[maybe_unused]] auto avm_main_sel_op_radix_le = View(new_term.avm_main_sel_op_radix_le); \ [[maybe_unused]] auto avm_main_sel_op_sender = View(new_term.avm_main_sel_op_sender); \ + [[maybe_unused]] auto avm_main_sel_op_sha256 = View(new_term.avm_main_sel_op_sha256); \ [[maybe_unused]] auto avm_main_sel_op_shl = View(new_term.avm_main_sel_op_shl); \ [[maybe_unused]] auto avm_main_sel_op_shr = View(new_term.avm_main_sel_op_shr); \ [[maybe_unused]] auto avm_main_sel_op_sload = View(new_term.avm_main_sel_op_sload); \ @@ -260,9 +261,15 @@ [[maybe_unused]] auto avm_mem_tsp = View(new_term.avm_mem_tsp); \ [[maybe_unused]] auto avm_mem_val = View(new_term.avm_mem_val); \ [[maybe_unused]] auto avm_mem_w_in_tag = View(new_term.avm_mem_w_in_tag); \ + [[maybe_unused]] auto avm_sha256_clk = View(new_term.avm_sha256_clk); \ + [[maybe_unused]] auto avm_sha256_input = View(new_term.avm_sha256_input); \ + [[maybe_unused]] auto avm_sha256_output = View(new_term.avm_sha256_output); \ + [[maybe_unused]] auto avm_sha256_sha256_compression_sel = View(new_term.avm_sha256_sha256_compression_sel); \ + [[maybe_unused]] auto avm_sha256_state = View(new_term.avm_sha256_state); \ [[maybe_unused]] auto perm_main_alu = View(new_term.perm_main_alu); \ [[maybe_unused]] auto perm_main_bin = View(new_term.perm_main_bin); \ [[maybe_unused]] auto perm_main_conv = View(new_term.perm_main_conv); \ + [[maybe_unused]] auto perm_main_sha256 = View(new_term.perm_main_sha256); \ [[maybe_unused]] auto perm_main_mem_a = View(new_term.perm_main_mem_a); \ [[maybe_unused]] auto perm_main_mem_b = View(new_term.perm_main_mem_b); \ [[maybe_unused]] auto perm_main_mem_c = View(new_term.perm_main_mem_c); \ diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_sha256.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_sha256.hpp new file mode 100644 index 00000000000..d7943e2d5a3 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_sha256.hpp @@ -0,0 +1,102 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class perm_main_sha256_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 4; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the + * value needs to be set to zero. + * + * @details If this is true then permutation takes place in this row + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.avm_main_sel_op_sha256 == 1 || in.avm_sha256_sha256_compression_sel == 1); + } + + /** + * @brief Get all the entities for the permutation when we don't need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_sha256, + in.avm_main_sel_op_sha256, + in.avm_main_sel_op_sha256, + in.avm_sha256_sha256_compression_sel, + in.avm_main_clk, + in.avm_main_ia, + in.avm_main_ib, + in.avm_main_ic, + in.avm_sha256_clk, + in.avm_sha256_state, + in.avm_sha256_input, + in.avm_sha256_output); + } + + /** + * @brief Get all the entities for the permutation when need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_sha256, + in.avm_main_sel_op_sha256, + in.avm_main_sel_op_sha256, + in.avm_sha256_sha256_compression_sel, + in.avm_main_clk, + in.avm_main_ia, + in.avm_main_ib, + in.avm_main_ic, + in.avm_sha256_clk, + in.avm_sha256_state, + in.avm_sha256_input, + in.avm_sha256_output); + } +}; + +template +using perm_main_sha256_relation = GenericPermutationRelation; +template using perm_main_sha256 = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp index 2ff668808ea..94e8417d5c7 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp @@ -107,6 +107,9 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = // Gadget - Conversion { OpCode::TORADIXLE, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, + // Gadget - Hashing + { OpCode::SHA256COMPRESSION, + { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, }; const std::unordered_map OPERAND_TYPE_SIZE = { 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 36e338d359d..beef92d3a92 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -285,6 +285,13 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(3)), std::get(inst.operands.at(4))); break; + case OpCode::SHA256COMPRESSION: + trace_builder.op_sha256_compression(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3))); + + break; default: throw_or_abort("Don't know how to execute opcode " + to_hex(inst.op_code) + " at pc " + std::to_string(pc) + "."); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp index df85cc684fa..1a85e3c4afe 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp @@ -1,9 +1,5 @@ #include "avm_opcode.hpp" -#include -#include -#include - namespace bb::avm_trace { /** @@ -19,10 +15,7 @@ bool Bytecode::is_valid(const uint8_t byte) std::string to_hex(OpCode opcode) { - std::ostringstream stream; - // pad with 0s to fill exactly 2 hex characters - stream << std::setfill('0') << std::setw(2) << std::hex << (static_cast(opcode) & 0xFF); - return stream.str(); + return to_hex(static_cast(opcode)); } } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp index 892ec941bd3..046934a99c2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp @@ -1,7 +1,10 @@ #pragma once +#include #include #include +#include +#include #include #include @@ -100,9 +103,10 @@ enum class OpCode : uint8_t { POSEIDON2, SHA256, PEDERSEN, - // Conversions TORADIXLE, + // Future Gadgets -- pending changes in noir + SHA256COMPRESSION, // Sentinel LAST_OPCODE_SENTINEL, @@ -113,6 +117,18 @@ class Bytecode { static bool is_valid(uint8_t byte); }; +// Look into whether we can do something with concepts here to enable OpCode as a parameter +template + requires(std::unsigned_integral) +std::string to_hex(T value) +{ + std::ostringstream stream; + auto num_bytes = static_cast(sizeof(T)); + uint64_t mask = (static_cast(1) << (num_bytes * 8)) - 1; + auto padding = static_cast(num_bytes * 2); + stream << std::setfill('0') << std::setw(padding) << std::hex << (value & mask); + return stream.str(); +} std::string to_hex(OpCode opcode); } // namespace bb::avm_trace 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 5bbe4f7dcf2..90885886928 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -1905,15 +1905,13 @@ void AvmTraceBuilder::internal_return() } // TODO(ilyas: #6383): Temporary way to bulk write slices -void write_slice_to_memory(uint8_t space_id, - AvmMemTraceBuilder& mem_trace, - std::vector& main_trace, - uint32_t clk, - uint32_t dst_offset, - AvmMemoryTag r_tag, - AvmMemoryTag w_tag, - FF internal_return_ptr, - std::vector const& slice) +void AvmTraceBuilder::write_slice_to_memory(uint8_t space_id, + uint32_t clk, + uint32_t dst_offset, + AvmMemoryTag r_tag, + AvmMemoryTag w_tag, + FF internal_return_ptr, + std::vector const& slice) { // We have 4 registers that we are able to use to write to memory within a single main trace row auto register_order = std::array{ IntermRegister::IA, IntermRegister::IB, IntermRegister::IC, IntermRegister::ID }; @@ -1924,6 +1922,7 @@ void write_slice_to_memory(uint8_t space_id, Row main_row{ .avm_main_clk = clk + i, .avm_main_internal_return_ptr = FF(internal_return_ptr), + .avm_main_pc = FF(pc), .avm_main_r_in_tag = FF(static_cast(r_tag)), .avm_main_w_in_tag = FF(static_cast(w_tag)), }; @@ -1934,7 +1933,7 @@ void write_slice_to_memory(uint8_t space_id, if (offset >= slice.size()) { break; } - mem_trace.write_into_memory( + mem_trace_builder.write_into_memory( space_id, clk + i, register_order[j], dst_offset + offset, slice.at(offset), r_tag, w_tag); // This looks a bit gross, but it is fine for now. if (j == 0) { @@ -1963,6 +1962,60 @@ void write_slice_to_memory(uint8_t space_id, } } +// TODO(ilyas: #6383): Temporary way to bulk read slices +template +void AvmTraceBuilder::read_slice_to_memory(uint8_t space_id, + uint32_t clk, + uint32_t src_offset, + AvmMemoryTag r_tag, + AvmMemoryTag w_tag, + FF internal_return_ptr, + std::array& slice) +{ + // We have 4 registers that we are able to use to read from memory within a single main trace row + auto register_order = std::array{ IntermRegister::IA, IntermRegister::IB, IntermRegister::IC, IntermRegister::ID }; + // If the slice size isnt a multiple of 4, we still need an extra row to write the remainder + uint32_t const num_main_rows = static_cast(T) / 4 + static_cast(T % 4 != 0); + for (uint32_t i = 0; i < num_main_rows; i++) { + Row main_row{ + .avm_main_clk = clk + i, + .avm_main_internal_return_ptr = FF(internal_return_ptr), + .avm_main_pc = FF(pc), + .avm_main_r_in_tag = FF(static_cast(r_tag)), + .avm_main_w_in_tag = FF(static_cast(w_tag)), + }; + // Write 4 values to memory in each_row + for (uint32_t j = 0; j < 4; j++) { + auto offset = i * 4 + j; + // If we exceed the slice size, we break + if (offset >= T) { + break; + } + auto mem_read = mem_trace_builder.read_and_load_from_memory( + space_id, clk + i, register_order[j], src_offset + offset, r_tag, w_tag); + slice.at(offset) = MEM(mem_read.val); + // This looks a bit gross, but it is fine for now. + if (j == 0) { + main_row.avm_main_ia = slice.at(offset); + main_row.avm_main_mem_idx_a = FF(src_offset + offset); + main_row.avm_main_mem_op_a = FF(1); + } else if (j == 1) { + main_row.avm_main_ib = slice.at(offset); + main_row.avm_main_mem_idx_b = FF(src_offset + offset); + main_row.avm_main_mem_op_b = FF(1); + } else if (j == 2) { + main_row.avm_main_ic = slice.at(offset); + main_row.avm_main_mem_idx_c = FF(src_offset + offset); + main_row.avm_main_mem_op_c = FF(1); + } else { + main_row.avm_main_id = slice.at(offset); + main_row.avm_main_mem_idx_d = FF(src_offset + offset); + main_row.avm_main_mem_op_d = FF(1); + } + } + main_trace.emplace_back(main_row); + } +} /** * @brief To_Radix_LE with direct or indirect memory access. * @@ -2044,15 +2097,106 @@ void AvmTraceBuilder::op_to_radix_le( for (auto const& limb : res) { ff_res.emplace_back(limb); } - write_slice_to_memory(call_ptr, - mem_trace_builder, - main_trace, - clk, - direct_dst_offset, - AvmMemoryTag::FF, - AvmMemoryTag::U8, - FF(internal_return_ptr), - ff_res); + write_slice_to_memory( + call_ptr, clk, direct_dst_offset, AvmMemoryTag::FF, AvmMemoryTag::U8, FF(internal_return_ptr), ff_res); +} + +/** + * @brief SHA256 Compression with direct or indirect memory access. + * + * @param indirect byte encoding information about indirect/direct memory access. + * @param h_init_offset An index in memory pointing to the first U32 value of the state array to be used in the next + * instance of sha256 compression. + * @param input_offset An index in memory pointing to the first U32 value of the input array to be used in the next + * instance of sha256 compression. + * @param output_offset An index in memory pointing to where the first U32 value of the output array should be stored. + */ +void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, + uint32_t output_offset, + uint32_t h_init_offset, + uint32_t input_offset) +{ + + // The clk plays a crucial role in this function as we attempt to write across multiple lines in the main trace. + auto clk = static_cast(main_trace.size()); + + // Resolve the indirect flags, the results of this function are used to determine the memory offsets + // that point to the starting memory addresses for the input, output and h_init values + // Note::This function will add memory reads at clk in the mem_trace_builder + auto const res = resolve_ind_three(call_ptr, clk, indirect, h_init_offset, input_offset, output_offset); + + auto read_a = mem_trace_builder.read_and_load_from_memory( + call_ptr, clk, IntermRegister::IA, res.direct_a_offset, AvmMemoryTag::U32, AvmMemoryTag::U32); + auto read_b = mem_trace_builder.read_and_load_from_memory( + call_ptr, clk, IntermRegister::IB, res.direct_b_offset, AvmMemoryTag::U32, AvmMemoryTag::U32); + auto read_c = mem_trace_builder.read_and_load_from_memory( + call_ptr, clk, IntermRegister::IC, res.direct_c_offset, AvmMemoryTag::U32, AvmMemoryTag::U32); + + // Since the above adds mem_reads in the mem_trace_builder at clk, we need to follow up resolving the reads in the + // main trace at the same clk cycle to preserve the cross-table permutation + // + // TODO<#6383>: We put the first value of each of the input, output (which is 0 at this point) and h_init arrays + // into the main trace at the intermediate registers simply for the permutation check, in the future this will + // change. + // Note: we could avoid output being zero if we loaded the input and state beforehand (with a new function that did + // not lay down constraints), but this is a simplification + main_trace.push_back(Row{ + .avm_main_clk = clk, + .avm_main_ia = read_a.val, // First element of output (trivially 0) + .avm_main_ib = read_b.val, // First element of state + .avm_main_ic = read_c.val, // First element of input + .avm_main_ind_a = res.indirect_flag_a ? FF(h_init_offset) : FF(0), + .avm_main_ind_b = res.indirect_flag_b ? FF(input_offset) : FF(0), + .avm_main_ind_c = res.indirect_flag_a ? FF(output_offset) : FF(0), + .avm_main_ind_op_a = FF(static_cast(res.indirect_flag_a)), + .avm_main_ind_op_b = FF(static_cast(res.indirect_flag_b)), + .avm_main_ind_op_c = FF(static_cast(res.indirect_flag_c)), + .avm_main_internal_return_ptr = FF(internal_return_ptr), + .avm_main_mem_idx_a = FF(res.direct_a_offset), + .avm_main_mem_idx_b = FF(res.direct_b_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), + .avm_main_mem_op_a = FF(1), + .avm_main_mem_op_b = FF(1), + .avm_main_mem_op_c = FF(1), + .avm_main_pc = FF(pc++), + .avm_main_r_in_tag = FF(static_cast(AvmMemoryTag::U32)), + .avm_main_sel_op_sha256 = FF(1), + .avm_main_w_in_tag = FF(static_cast(AvmMemoryTag::U32)), + }); + // We store the current clk this main trace row occurred so that we can line up the sha256 gadget operation at the + // same clk later. + auto sha_op_clk = clk; + // We need to increment the clk + clk++; + // State array input is fixed to 256 bits + std::array h_init; + // Input for hash is expanded to 512 bits + std::array input; + // Read results are written to h_init array. + read_slice_to_memory( + call_ptr, clk, res.direct_a_offset, AvmMemoryTag::U32, AvmMemoryTag::U32, FF(internal_return_ptr), h_init); + + // Increment the clock by 2 since (8 reads / 4 reads per row = 2) + clk += 2; + // Read results are written to input array + read_slice_to_memory( + call_ptr, clk, res.direct_b_offset, AvmMemoryTag::U32, AvmMemoryTag::U32, FF(internal_return_ptr), input); + // Increment the clock by 4 since (16 / 4 = 4) + clk += 4; + + // Now that we have read all the values, we can perform the operation to get the resulting witness. + // Note: We use the sha_op_clk to ensure that the sha256 operation is performed at the same clock cycle as the main + // trace that has the selector + std::array result = sha256_trace_builder.sha256_compression(h_init, input, sha_op_clk); + // We convert the results to field elements here + std::vector ff_result; + for (uint32_t i = 0; i < 8; i++) { + ff_result.emplace_back(result[i]); + } + + // Write the result to memory after + write_slice_to_memory( + call_ptr, clk, res.direct_c_offset, AvmMemoryTag::U32, AvmMemoryTag::U32, FF(internal_return_ptr), ff_result); } // Finalise Lookup Counts @@ -2178,11 +2322,13 @@ std::vector AvmTraceBuilder::finalize(uint32_t min_trace_size, bool range_c auto mem_trace = mem_trace_builder.finalize(); auto alu_trace = alu_trace_builder.finalize(); auto conv_trace = conversion_trace_builder.finalize(); + auto sha256_trace = sha256_trace_builder.finalize(); auto bin_trace = bin_trace_builder.finalize(); size_t mem_trace_size = mem_trace.size(); size_t main_trace_size = main_trace.size(); size_t alu_trace_size = alu_trace.size(); size_t conv_trace_size = conv_trace.size(); + size_t sha256_trace_size = sha256_trace.size(); size_t bin_trace_size = bin_trace.size(); // Get tag_err counts from the mem_trace_builder @@ -2200,8 +2346,9 @@ std::vector AvmTraceBuilder::finalize(uint32_t min_trace_size, bool range_c // 2**16 long) size_t const lookup_table_size = (bin_trace_size > 0 && range_check_required) ? 3 * (1 << 16) : 0; size_t const range_check_size = range_check_required ? UINT16_MAX + 1 : 0; - std::vector trace_sizes = { mem_trace_size, main_trace_size, alu_trace_size, lookup_table_size, - range_check_size, conv_trace_size, KERNEL_OUTPUTS_LENGTH, min_trace_size }; + std::vector trace_sizes = { mem_trace_size, main_trace_size, alu_trace_size, + lookup_table_size, range_check_size, conv_trace_size, + sha256_trace_size, KERNEL_OUTPUTS_LENGTH, min_trace_size }; auto trace_size = std::max_element(trace_sizes.begin(), trace_sizes.end()); // We only need to pad with zeroes to the size to the largest trace here, pow_2 padding is handled in the @@ -2547,6 +2694,18 @@ std::vector AvmTraceBuilder::finalize(uint32_t min_trace_size, bool range_c dest.avm_conversion_num_limbs = FF(src.num_limbs); } + // Add SHA256 Gadget table + for (size_t i = 0; i < sha256_trace_size; i++) { + auto const& src = sha256_trace.at(i); + auto& dest = main_trace.at(i); + dest.avm_sha256_clk = FF(src.clk); + dest.avm_sha256_input = src.input[0]; + // TODO: This will need to be enabled later + // dest.avm_sha256_output = src.output[0]; + dest.avm_sha256_sha256_compression_sel = FF(1); + dest.avm_sha256_state = src.state[0]; + } + // Add Binary Trace table for (size_t i = 0; i < bin_trace_size; i++) { auto const& src = bin_trace.at(i); @@ -2766,7 +2925,6 @@ std::vector AvmTraceBuilder::finalize(uint32_t min_trace_size, bool range_c dest.avm_kernel_side_effect_counter = prev.avm_kernel_side_effect_counter; } } - // Adding extra row for the shifted values at the top of the execution trace. Row first_row = Row{ .avm_main_first = FF(1), .avm_mem_lastAccess = FF(1) }; main_trace.insert(main_trace.begin(), first_row); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp index 2949d225c59..40e792027de 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -9,6 +9,7 @@ #include "avm_mem_trace.hpp" #include "barretenberg/common/throw_or_abort.hpp" #include "barretenberg/vm/avm_trace/gadgets/avm_conversion_trace.hpp" +#include "barretenberg/vm/avm_trace/gadgets/avm_sha256.hpp" #include "constants.hpp" #include "barretenberg/relations/generated/avm/avm_main.hpp" @@ -148,6 +149,9 @@ class AvmTraceBuilder { // --- Conversions // To Radix LE conversion operation. void op_to_radix_le(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset, uint32_t radix, uint32_t num_limbs); + // --- Hashing + // Sha256 compression operation + void op_sha256_compression(uint8_t indirect, uint32_t output_offset, uint32_t h_init_offset, uint32_t input_offset); private: // Used for the standard indirect address resolution of three operands opcode. @@ -168,6 +172,7 @@ class AvmTraceBuilder { AvmBinaryTraceBuilder bin_trace_builder; AvmKernelTraceBuilder kernel_trace_builder; AvmConversionTraceBuilder conversion_trace_builder; + AvmSha256TraceBuilder sha256_trace_builder; /** * @brief Create a kernel lookup opcode object @@ -236,5 +241,22 @@ class AvmTraceBuilder { uint32_t internal_return_ptr = 0; // After a nested call, it should be initialized with MAX_SIZE_INTERNAL_STACK * call_ptr uint8_t call_ptr = 0; + + // TODO(ilyas: #6383): Temporary way to bulk read slices + template + void read_slice_to_memory(uint8_t space_id, + uint32_t clk, + uint32_t src_offset, + AvmMemoryTag r_tag, + AvmMemoryTag w_tag, + FF internal_return_ptr, + std::array& slice); + void write_slice_to_memory(uint8_t space_id, + uint32_t clk, + uint32_t dst_offset, + AvmMemoryTag r_tag, + AvmMemoryTag w_tag, + FF internal_return_ptr, + std::vector const& slice); }; } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/gadgets/avm_sha256.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/gadgets/avm_sha256.cpp new file mode 100644 index 00000000000..93cdfa0c88d --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/gadgets/avm_sha256.cpp @@ -0,0 +1,124 @@ +#include "avm_sha256.hpp" +#include "../avm_common.hpp" +#include "barretenberg/crypto/sha256/sha256.hpp" +#include "barretenberg/numeric/uint128/uint128.hpp" +#include +#include +#include +#include +#include + +namespace bb::avm_trace { + +AvmSha256TraceBuilder::AvmSha256TraceBuilder() +{ + sha256_trace.reserve(AVM_TRACE_SIZE); +} + +std::vector AvmSha256TraceBuilder::finalize() +{ + return std::move(sha256_trace); +} + +void AvmSha256TraceBuilder::reset() +{ + sha256_trace.clear(); +} + +// Taken from barretenberg/crypto/sha256/sha256.cpp since it is not exposed directly +constexpr uint32_t round_constants[64]{ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +// Taken from barretenberg/crypto/sha256/sha256.cpp since it is not exposed directly +constexpr uint32_t ror(uint32_t val, uint32_t shift) +{ + return (val >> (shift & 31U)) | (val << (32U - (shift & 31U))); +} + +// Taken from barretenberg/crypto/sha256/sha256.cpp since it is not exposed directly +std::array sha256_block(const std::array& h_init, const std::array& input) +{ + std::array w; + + /** + * Fill first 16 words with the message schedule + **/ + for (size_t i = 0; i < 16; ++i) { + w[i] = input[i]; + } + + /** + * Extend the input data into the remaining 48 words + **/ + for (size_t i = 16; i < 64; ++i) { + uint32_t s0 = ror(w[i - 15], 7) ^ ror(w[i - 15], 18) ^ (w[i - 15] >> 3); + uint32_t s1 = ror(w[i - 2], 17) ^ ror(w[i - 2], 19) ^ (w[i - 2] >> 10); + w[i] = w[i - 16] + w[i - 7] + s0 + s1; + } + + /** + * Initialize round variables with previous block output + **/ + uint32_t a = h_init[0]; + uint32_t b = h_init[1]; + uint32_t c = h_init[2]; + uint32_t d = h_init[3]; + uint32_t e = h_init[4]; + uint32_t f = h_init[5]; + uint32_t g = h_init[6]; + uint32_t h = h_init[7]; + + /** + * Apply SHA-256 compression function to the message schedule + **/ + for (size_t i = 0; i < 64; ++i) { + uint32_t S1 = ror(e, 6U) ^ ror(e, 11U) ^ ror(e, 25U); + uint32_t ch = (e & f) ^ (~e & g); // === (e & f) ^ (~e & g), `+` op is cheaper + uint32_t temp1 = h + S1 + ch + round_constants[i] + w[i]; + uint32_t S0 = ror(a, 2U) ^ ror(a, 13U) ^ ror(a, 22U); + uint32_t maj = (a & b) ^ (a & c) ^ (b & c); // (a & (b + c - (T0 * 2))) + T0; // === (a & b) ^ (a & c) ^ (b & c) + uint32_t temp2 = S0 + maj; + + h = g; + g = f; + f = e; + e = d + temp1; + d = c; + c = b; + b = a; + a = temp1 + temp2; + } + + /** + * Add into previous block output and return + **/ + std::array output; + output[0] = a + h_init[0]; + output[1] = b + h_init[1]; + output[2] = c + h_init[2]; + output[3] = d + h_init[3]; + output[4] = e + h_init[4]; + output[5] = f + h_init[5]; + output[6] = g + h_init[6]; + output[7] = h + h_init[7]; + return output; +} + +std::array AvmSha256TraceBuilder::sha256_compression(const std::array& h_init, + const std::array& input, + uint32_t clk) +{ + auto output = sha256_block(h_init, input); + sha256_trace.push_back({ clk, h_init, input, output }); + return output; +} + +} // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/gadgets/avm_sha256.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/gadgets/avm_sha256.hpp new file mode 100644 index 00000000000..ef81479ee7f --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/gadgets/avm_sha256.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "../avm_common.hpp" +#include "barretenberg/numeric/uint128/uint128.hpp" +#include +#include + +namespace bb::avm_trace { +class AvmSha256TraceBuilder { + public: + struct Sha256TraceEntry { + uint32_t clk = 0; + std::array state; + std::array input; + std::array output; + }; + + AvmSha256TraceBuilder(); + void reset(); + // Finalize the trace + std::vector finalize(); + + std::array sha256_compression(const std::array& h_init, + const std::array& input, + uint32_t clk); + + private: + std::vector sha256_trace; +}; +} // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp index 02dd631a164..eb608383772 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -22,6 +22,7 @@ #include "barretenberg/relations/generated/avm/avm_kernel.hpp" #include "barretenberg/relations/generated/avm/avm_main.hpp" #include "barretenberg/relations/generated/avm/avm_mem.hpp" +#include "barretenberg/relations/generated/avm/avm_sha256.hpp" #include "barretenberg/relations/generated/avm/incl_main_tag_err.hpp" #include "barretenberg/relations/generated/avm/incl_mem_tag_err.hpp" #include "barretenberg/relations/generated/avm/kernel_output_lookup.hpp" @@ -69,6 +70,7 @@ #include "barretenberg/relations/generated/avm/perm_main_mem_ind_b.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_ind_c.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_ind_d.hpp" +#include "barretenberg/relations/generated/avm/perm_main_sha256.hpp" #include "barretenberg/vm/generated/avm_flavor.hpp" namespace bb { @@ -274,6 +276,7 @@ template struct AvmFullRow { FF avm_main_sel_op_or{}; FF avm_main_sel_op_radix_le{}; FF avm_main_sel_op_sender{}; + FF avm_main_sel_op_sha256{}; FF avm_main_sel_op_shl{}; FF avm_main_sel_op_shr{}; FF avm_main_sel_op_sload{}; @@ -320,9 +323,15 @@ template struct AvmFullRow { FF avm_mem_tsp{}; FF avm_mem_val{}; FF avm_mem_w_in_tag{}; + FF avm_sha256_clk{}; + FF avm_sha256_input{}; + FF avm_sha256_output{}; + FF avm_sha256_sha256_compression_sel{}; + FF avm_sha256_state{}; FF perm_main_alu{}; FF perm_main_bin{}; FF perm_main_conv{}; + FF perm_main_sha256{}; FF perm_main_mem_a{}; FF perm_main_mem_b{}; FF perm_main_mem_c{}; @@ -477,8 +486,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 391; - static constexpr size_t num_polys = 329; + static constexpr size_t num_fixed_columns = 398; + static constexpr size_t num_polys = 336; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -698,6 +707,7 @@ class AvmCircuitBuilder { polys.avm_main_sel_op_or[i] = rows[i].avm_main_sel_op_or; polys.avm_main_sel_op_radix_le[i] = rows[i].avm_main_sel_op_radix_le; polys.avm_main_sel_op_sender[i] = rows[i].avm_main_sel_op_sender; + polys.avm_main_sel_op_sha256[i] = rows[i].avm_main_sel_op_sha256; polys.avm_main_sel_op_shl[i] = rows[i].avm_main_sel_op_shl; polys.avm_main_sel_op_shr[i] = rows[i].avm_main_sel_op_shr; polys.avm_main_sel_op_sload[i] = rows[i].avm_main_sel_op_sload; @@ -744,6 +754,11 @@ class AvmCircuitBuilder { polys.avm_mem_tsp[i] = rows[i].avm_mem_tsp; polys.avm_mem_val[i] = rows[i].avm_mem_val; polys.avm_mem_w_in_tag[i] = rows[i].avm_mem_w_in_tag; + polys.avm_sha256_clk[i] = rows[i].avm_sha256_clk; + polys.avm_sha256_input[i] = rows[i].avm_sha256_input; + polys.avm_sha256_output[i] = rows[i].avm_sha256_output; + polys.avm_sha256_sha256_compression_sel[i] = rows[i].avm_sha256_sha256_compression_sel; + polys.avm_sha256_state[i] = rows[i].avm_sha256_state; polys.lookup_byte_lengths_counts[i] = rows[i].lookup_byte_lengths_counts; polys.lookup_byte_operations_counts[i] = rows[i].lookup_byte_operations_counts; polys.kernel_output_lookup_counts[i] = rows[i].kernel_output_lookup_counts; @@ -952,6 +967,11 @@ class AvmCircuitBuilder { Avm_vm::get_relation_label_avm_mem); }; + auto avm_sha256 = [=]() { + return evaluate_relation.template operator()>("avm_sha256", + Avm_vm::get_relation_label_avm_sha256); + }; + auto perm_main_alu = [=]() { return evaluate_logderivative.template operator()>("PERM_MAIN_ALU"); }; @@ -964,6 +984,10 @@ class AvmCircuitBuilder { return evaluate_logderivative.template operator()>("PERM_MAIN_CONV"); }; + auto perm_main_sha256 = [=]() { + return evaluate_logderivative.template operator()>("PERM_MAIN_SHA256"); + }; + auto perm_main_mem_a = [=]() { return evaluate_logderivative.template operator()>("PERM_MAIN_MEM_A"); }; @@ -1162,12 +1186,16 @@ class AvmCircuitBuilder { relation_futures.emplace_back(std::async(std::launch::async, avm_mem)); + relation_futures.emplace_back(std::async(std::launch::async, avm_sha256)); + relation_futures.emplace_back(std::async(std::launch::async, perm_main_alu)); relation_futures.emplace_back(std::async(std::launch::async, perm_main_bin)); relation_futures.emplace_back(std::async(std::launch::async, perm_main_conv)); + relation_futures.emplace_back(std::async(std::launch::async, perm_main_sha256)); + relation_futures.emplace_back(std::async(std::launch::async, perm_main_mem_a)); relation_futures.emplace_back(std::async(std::launch::async, perm_main_mem_b)); @@ -1277,12 +1305,16 @@ class AvmCircuitBuilder { avm_mem(); + avm_sha256(); + perm_main_alu(); perm_main_bin(); perm_main_conv(); + perm_main_sha256(); + perm_main_mem_a(); perm_main_mem_b(); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 48af07a0783..44731d5ba18 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -19,6 +19,7 @@ #include "barretenberg/relations/generated/avm/avm_kernel.hpp" #include "barretenberg/relations/generated/avm/avm_main.hpp" #include "barretenberg/relations/generated/avm/avm_mem.hpp" +#include "barretenberg/relations/generated/avm/avm_sha256.hpp" #include "barretenberg/relations/generated/avm/incl_main_tag_err.hpp" #include "barretenberg/relations/generated/avm/incl_mem_tag_err.hpp" #include "barretenberg/relations/generated/avm/kernel_output_lookup.hpp" @@ -66,6 +67,7 @@ #include "barretenberg/relations/generated/avm/perm_main_mem_ind_b.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_ind_c.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_ind_d.hpp" +#include "barretenberg/relations/generated/avm/perm_main_sha256.hpp" #include "barretenberg/transcript/transcript.hpp" namespace bb { @@ -87,15 +89,16 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 327; + static constexpr size_t NUM_WITNESS_ENTITIES = 334; 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 = 391; + static constexpr size_t NUM_ALL_ENTITIES = 398; using GrandProductRelations = std::tuple, perm_main_bin_relation, perm_main_conv_relation, + perm_main_sha256_relation, perm_main_mem_a_relation, perm_main_mem_b_relation, perm_main_mem_c_relation, @@ -147,9 +150,11 @@ class AvmFlavor { Avm_vm::avm_kernel, Avm_vm::avm_main, Avm_vm::avm_mem, + Avm_vm::avm_sha256, perm_main_alu_relation, perm_main_bin_relation, perm_main_conv_relation, + perm_main_sha256_relation, perm_main_mem_a_relation, perm_main_mem_b_relation, perm_main_mem_c_relation, @@ -425,6 +430,7 @@ class AvmFlavor { avm_main_sel_op_or, avm_main_sel_op_radix_le, avm_main_sel_op_sender, + avm_main_sel_op_sha256, avm_main_sel_op_shl, avm_main_sel_op_shr, avm_main_sel_op_sload, @@ -471,9 +477,15 @@ class AvmFlavor { avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, + avm_sha256_clk, + avm_sha256_input, + avm_sha256_output, + avm_sha256_sha256_compression_sel, + avm_sha256_state, perm_main_alu, perm_main_bin, perm_main_conv, + perm_main_sha256, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, @@ -755,6 +767,7 @@ class AvmFlavor { avm_main_sel_op_or, avm_main_sel_op_radix_le, avm_main_sel_op_sender, + avm_main_sel_op_sha256, avm_main_sel_op_shl, avm_main_sel_op_shr, avm_main_sel_op_sload, @@ -801,9 +814,15 @@ class AvmFlavor { avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, + avm_sha256_clk, + avm_sha256_input, + avm_sha256_output, + avm_sha256_sha256_compression_sel, + avm_sha256_state, perm_main_alu, perm_main_bin, perm_main_conv, + perm_main_sha256, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, @@ -1090,6 +1109,7 @@ class AvmFlavor { avm_main_sel_op_or, avm_main_sel_op_radix_le, avm_main_sel_op_sender, + avm_main_sel_op_sha256, avm_main_sel_op_shl, avm_main_sel_op_shr, avm_main_sel_op_sload, @@ -1136,9 +1156,15 @@ class AvmFlavor { avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, + avm_sha256_clk, + avm_sha256_input, + avm_sha256_output, + avm_sha256_sha256_compression_sel, + avm_sha256_state, perm_main_alu, perm_main_bin, perm_main_conv, + perm_main_sha256, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, @@ -1484,6 +1510,7 @@ class AvmFlavor { avm_main_sel_op_or, avm_main_sel_op_radix_le, avm_main_sel_op_sender, + avm_main_sel_op_sha256, avm_main_sel_op_shl, avm_main_sel_op_shr, avm_main_sel_op_sload, @@ -1530,9 +1557,15 @@ class AvmFlavor { avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, + avm_sha256_clk, + avm_sha256_input, + avm_sha256_output, + avm_sha256_sha256_compression_sel, + avm_sha256_state, perm_main_alu, perm_main_bin, perm_main_conv, + perm_main_sha256, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, @@ -1878,6 +1911,7 @@ class AvmFlavor { avm_main_sel_op_or, avm_main_sel_op_radix_le, avm_main_sel_op_sender, + avm_main_sel_op_sha256, avm_main_sel_op_shl, avm_main_sel_op_shr, avm_main_sel_op_sload, @@ -1924,9 +1958,15 @@ class AvmFlavor { avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, + avm_sha256_clk, + avm_sha256_input, + avm_sha256_output, + avm_sha256_sha256_compression_sel, + avm_sha256_state, perm_main_alu, perm_main_bin, perm_main_conv, + perm_main_sha256, perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, @@ -2224,6 +2264,8 @@ 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>( @@ -2383,7 +2425,7 @@ class AvmFlavor { /** * @brief A container for univariates used during Protogalaxy folding and sumcheck with some of the computation - * optmistically ignored + * optimistically ignored * @details During folding and sumcheck, the prover evaluates the relations on these univariates. */ template @@ -2609,6 +2651,7 @@ class AvmFlavor { Base::avm_main_sel_op_or = "AVM_MAIN_SEL_OP_OR"; Base::avm_main_sel_op_radix_le = "AVM_MAIN_SEL_OP_RADIX_LE"; Base::avm_main_sel_op_sender = "AVM_MAIN_SEL_OP_SENDER"; + Base::avm_main_sel_op_sha256 = "AVM_MAIN_SEL_OP_SHA256"; Base::avm_main_sel_op_shl = "AVM_MAIN_SEL_OP_SHL"; Base::avm_main_sel_op_shr = "AVM_MAIN_SEL_OP_SHR"; Base::avm_main_sel_op_sload = "AVM_MAIN_SEL_OP_SLOAD"; @@ -2655,9 +2698,15 @@ class AvmFlavor { Base::avm_mem_tsp = "AVM_MEM_TSP"; Base::avm_mem_val = "AVM_MEM_VAL"; Base::avm_mem_w_in_tag = "AVM_MEM_W_IN_TAG"; + Base::avm_sha256_clk = "AVM_SHA256_CLK"; + Base::avm_sha256_input = "AVM_SHA256_INPUT"; + Base::avm_sha256_output = "AVM_SHA256_OUTPUT"; + Base::avm_sha256_sha256_compression_sel = "AVM_SHA256_SHA256_COMPRESSION_SEL"; + Base::avm_sha256_state = "AVM_SHA256_STATE"; Base::perm_main_alu = "PERM_MAIN_ALU"; Base::perm_main_bin = "PERM_MAIN_BIN"; Base::perm_main_conv = "PERM_MAIN_CONV"; + Base::perm_main_sha256 = "PERM_MAIN_SHA256"; Base::perm_main_mem_a = "PERM_MAIN_MEM_A"; Base::perm_main_mem_b = "PERM_MAIN_MEM_B"; Base::perm_main_mem_c = "PERM_MAIN_MEM_C"; @@ -2955,6 +3004,7 @@ class AvmFlavor { Commitment avm_main_sel_op_or; Commitment avm_main_sel_op_radix_le; Commitment avm_main_sel_op_sender; + Commitment avm_main_sel_op_sha256; Commitment avm_main_sel_op_shl; Commitment avm_main_sel_op_shr; Commitment avm_main_sel_op_sload; @@ -3001,9 +3051,15 @@ class AvmFlavor { Commitment avm_mem_tsp; Commitment avm_mem_val; Commitment avm_mem_w_in_tag; + Commitment avm_sha256_clk; + Commitment avm_sha256_input; + Commitment avm_sha256_output; + Commitment avm_sha256_sha256_compression_sel; + Commitment avm_sha256_state; Commitment perm_main_alu; Commitment perm_main_bin; Commitment perm_main_conv; + Commitment perm_main_sha256; Commitment perm_main_mem_a; Commitment perm_main_mem_b; Commitment perm_main_mem_c; @@ -3320,6 +3376,7 @@ class AvmFlavor { avm_main_sel_op_or = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_radix_le = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_sender = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_op_sha256 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_shl = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_shr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_sload = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -3366,9 +3423,16 @@ class AvmFlavor { avm_mem_tsp = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_val = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_w_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_sha256_clk = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_sha256_input = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_sha256_output = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_sha256_sha256_compression_sel = + deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_sha256_state = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_alu = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_bin = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_conv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + perm_main_sha256 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -3670,6 +3734,7 @@ class AvmFlavor { serialize_to_buffer(avm_main_sel_op_or, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_radix_le, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_sender, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_op_sha256, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_shl, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_shr, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_sload, Transcript::proof_data); @@ -3716,9 +3781,15 @@ class AvmFlavor { serialize_to_buffer(avm_mem_tsp, Transcript::proof_data); serialize_to_buffer(avm_mem_val, Transcript::proof_data); serialize_to_buffer(avm_mem_w_in_tag, Transcript::proof_data); + serialize_to_buffer(avm_sha256_clk, Transcript::proof_data); + serialize_to_buffer(avm_sha256_input, Transcript::proof_data); + serialize_to_buffer(avm_sha256_output, Transcript::proof_data); + serialize_to_buffer(avm_sha256_sha256_compression_sel, Transcript::proof_data); + serialize_to_buffer(avm_sha256_state, Transcript::proof_data); serialize_to_buffer(perm_main_alu, Transcript::proof_data); serialize_to_buffer(perm_main_bin, Transcript::proof_data); serialize_to_buffer(perm_main_conv, Transcript::proof_data); + serialize_to_buffer(perm_main_sha256, Transcript::proof_data); serialize_to_buffer(perm_main_mem_a, Transcript::proof_data); serialize_to_buffer(perm_main_mem_b, Transcript::proof_data); serialize_to_buffer(perm_main_mem_c, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp index 28172ce8079..7b8ec1b38c9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp @@ -276,6 +276,7 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_main_sel_op_or = commitment_key->commit(key->avm_main_sel_op_or); witness_commitments.avm_main_sel_op_radix_le = commitment_key->commit(key->avm_main_sel_op_radix_le); witness_commitments.avm_main_sel_op_sender = commitment_key->commit(key->avm_main_sel_op_sender); + witness_commitments.avm_main_sel_op_sha256 = commitment_key->commit(key->avm_main_sel_op_sha256); witness_commitments.avm_main_sel_op_shl = commitment_key->commit(key->avm_main_sel_op_shl); witness_commitments.avm_main_sel_op_shr = commitment_key->commit(key->avm_main_sel_op_shr); witness_commitments.avm_main_sel_op_sload = commitment_key->commit(key->avm_main_sel_op_sload); @@ -322,6 +323,12 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_mem_tsp = commitment_key->commit(key->avm_mem_tsp); witness_commitments.avm_mem_val = commitment_key->commit(key->avm_mem_val); witness_commitments.avm_mem_w_in_tag = commitment_key->commit(key->avm_mem_w_in_tag); + witness_commitments.avm_sha256_clk = commitment_key->commit(key->avm_sha256_clk); + witness_commitments.avm_sha256_input = commitment_key->commit(key->avm_sha256_input); + witness_commitments.avm_sha256_output = commitment_key->commit(key->avm_sha256_output); + witness_commitments.avm_sha256_sha256_compression_sel = + commitment_key->commit(key->avm_sha256_sha256_compression_sel); + witness_commitments.avm_sha256_state = commitment_key->commit(key->avm_sha256_state); witness_commitments.lookup_byte_lengths_counts = commitment_key->commit(key->lookup_byte_lengths_counts); witness_commitments.lookup_byte_operations_counts = commitment_key->commit(key->lookup_byte_operations_counts); witness_commitments.kernel_output_lookup_counts = commitment_key->commit(key->kernel_output_lookup_counts); @@ -611,6 +618,7 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_main_sel_op_radix_le, witness_commitments.avm_main_sel_op_radix_le); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_sender, witness_commitments.avm_main_sel_op_sender); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_sha256, witness_commitments.avm_main_sel_op_sha256); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_shl, witness_commitments.avm_main_sel_op_shl); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_shr, witness_commitments.avm_main_sel_op_shr); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_sload, witness_commitments.avm_main_sel_op_sload); @@ -660,6 +668,12 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_mem_tsp, witness_commitments.avm_mem_tsp); transcript->send_to_verifier(commitment_labels.avm_mem_val, witness_commitments.avm_mem_val); transcript->send_to_verifier(commitment_labels.avm_mem_w_in_tag, witness_commitments.avm_mem_w_in_tag); + transcript->send_to_verifier(commitment_labels.avm_sha256_clk, witness_commitments.avm_sha256_clk); + transcript->send_to_verifier(commitment_labels.avm_sha256_input, witness_commitments.avm_sha256_input); + transcript->send_to_verifier(commitment_labels.avm_sha256_output, witness_commitments.avm_sha256_output); + transcript->send_to_verifier(commitment_labels.avm_sha256_sha256_compression_sel, + witness_commitments.avm_sha256_sha256_compression_sel); + transcript->send_to_verifier(commitment_labels.avm_sha256_state, witness_commitments.avm_sha256_state); transcript->send_to_verifier(commitment_labels.lookup_byte_lengths_counts, witness_commitments.lookup_byte_lengths_counts); transcript->send_to_verifier(commitment_labels.lookup_byte_operations_counts, @@ -728,6 +742,7 @@ void AvmProver::execute_log_derivative_inverse_round() witness_commitments.perm_main_alu = commitment_key->commit(key->perm_main_alu); witness_commitments.perm_main_bin = commitment_key->commit(key->perm_main_bin); witness_commitments.perm_main_conv = commitment_key->commit(key->perm_main_conv); + witness_commitments.perm_main_sha256 = commitment_key->commit(key->perm_main_sha256); witness_commitments.perm_main_mem_a = commitment_key->commit(key->perm_main_mem_a); witness_commitments.perm_main_mem_b = commitment_key->commit(key->perm_main_mem_b); witness_commitments.perm_main_mem_c = commitment_key->commit(key->perm_main_mem_c); @@ -777,6 +792,7 @@ void AvmProver::execute_log_derivative_inverse_round() transcript->send_to_verifier(commitment_labels.perm_main_alu, witness_commitments.perm_main_alu); transcript->send_to_verifier(commitment_labels.perm_main_bin, witness_commitments.perm_main_bin); transcript->send_to_verifier(commitment_labels.perm_main_conv, witness_commitments.perm_main_conv); + transcript->send_to_verifier(commitment_labels.perm_main_sha256, witness_commitments.perm_main_sha256); transcript->send_to_verifier(commitment_labels.perm_main_mem_a, witness_commitments.perm_main_mem_a); transcript->send_to_verifier(commitment_labels.perm_main_mem_b, witness_commitments.perm_main_mem_b); transcript->send_to_verifier(commitment_labels.perm_main_mem_c, witness_commitments.perm_main_mem_c); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 0106ab7dbf6..1699db999c1 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -414,6 +414,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vectortemplate receive_from_prover(commitment_labels.avm_main_sel_op_radix_le); commitments.avm_main_sel_op_sender = transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_sender); + commitments.avm_main_sel_op_sha256 = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_sha256); commitments.avm_main_sel_op_shl = transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_shl); commitments.avm_main_sel_op_shr = @@ -495,6 +497,15 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vectortemplate receive_from_prover(commitment_labels.avm_mem_val); commitments.avm_mem_w_in_tag = transcript->template receive_from_prover(commitment_labels.avm_mem_w_in_tag); + commitments.avm_sha256_clk = transcript->template receive_from_prover(commitment_labels.avm_sha256_clk); + commitments.avm_sha256_input = + transcript->template receive_from_prover(commitment_labels.avm_sha256_input); + commitments.avm_sha256_output = + transcript->template receive_from_prover(commitment_labels.avm_sha256_output); + commitments.avm_sha256_sha256_compression_sel = + transcript->template receive_from_prover(commitment_labels.avm_sha256_sha256_compression_sel); + commitments.avm_sha256_state = + transcript->template receive_from_prover(commitment_labels.avm_sha256_state); commitments.lookup_byte_lengths_counts = transcript->template receive_from_prover(commitment_labels.lookup_byte_lengths_counts); commitments.lookup_byte_operations_counts = @@ -576,6 +587,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vectortemplate receive_from_prover(commitment_labels.perm_main_alu); commitments.perm_main_bin = transcript->template receive_from_prover(commitment_labels.perm_main_bin); commitments.perm_main_conv = transcript->template receive_from_prover(commitment_labels.perm_main_conv); + commitments.perm_main_sha256 = + transcript->template receive_from_prover(commitment_labels.perm_main_sha256); commitments.perm_main_mem_a = transcript->template receive_from_prover(commitment_labels.perm_main_mem_a); commitments.perm_main_mem_b = diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp index 3854954ad03..985e868a320 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp @@ -692,6 +692,101 @@ TEST_F(AvmExecutionTests, toRadixLeOpcode) validate_trace(std::move(trace)); } + +// // Positive test with SHA256COMPRESSION. +TEST_F(AvmExecutionTests, sha256CompressionOpcode) +{ + std::string bytecode_preamble; + // Set operations for sha256 state + // Test vectors taken from noir black_box_solver + // State = Uint32Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), + for (uint32_t i = 1; i <= 8; i++) { + bytecode_preamble += to_hex(OpCode::SET) + // opcode SET + "00" // Indirect flag + "03" + // U32 + to_hex(i) + // val i + to_hex(i); // val i + // to_hex(i) + // val i + // to_hex(i); // dst offset + } + // Set operations for sha256 input + // Test vectors taken from noir black_box_solver + // Input = Uint32Array.from([1, 2, 3, 4, 5, 6, 7, 8]), + for (uint32_t i = 1; i <= 16; i++) { + bytecode_preamble += to_hex(OpCode::SET) + // opcode SET + "00" // Indirect flag + "03" + // U32 + to_hex(i) + // val i + to_hex(i + 8); // val i + // to_hex(i) + // val i + // to_hex(i + 8); // dst offset + } + std::string bytecode_hex = bytecode_preamble // Initial SET operations to store state and input + + to_hex(OpCode::SET) + // opcode SET for indirect dst (output) + "00" // Indirect flag + "03" // U32 + "00000100" // value 256 (i.e. where the dst will be written to) + "00000024" // dst_offset 36 + + to_hex(OpCode::SET) + // opcode SET for indirect state + "00" // Indirect flag + "03" // U32 + "00000001" // value 1 (i.e. where the state will be read from) + "00000022" // dst_offset 34 + + to_hex(OpCode::SET) + // opcode SET for indirect input + "00" // Indirect flag + "03" // U32 + "00000009" // value 9 (i.e. where the input will be read from) + "00000023" // dst_offset 35 + + to_hex(OpCode::SHA256COMPRESSION) + // opcode SHA256COMPRESSION + "07" // Indirect flag (first 3 operands indirect) + "00000024" // output offset (indirect 36) + "00000022" // state offset (indirect 34) + "00000023" // input offset (indirect 35) + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000100" // ret offset 256 + "00000008"; // ret size 8 + + auto bytecode = hex_to_bytes(bytecode_hex); + auto instructions = Deserialization::parse(bytecode); + + // 8 SET for state + 16 SET for input + 3 SET for setting up indirects + 1 SHA256COMPRESSION + 1 RETURN + ASSERT_THAT(instructions, SizeIs(29)); + + // SHA256COMPRESSION + EXPECT_THAT(instructions.at(27), + AllOf(Field(&Instruction::op_code, OpCode::SHA256COMPRESSION), + Field(&Instruction::operands, + ElementsAre(VariantWith(7), + VariantWith(36), + VariantWith(34), + VariantWith(35))))); + + // Assign a vector that we will mutate internally in gen_trace to store the return values; + std::vector returndata = std::vector(); + // Test vector output taken from noir black_box_solver + // Uint32Array.from([1862536192, 526086805, 2067405084, 593147560, 726610467, 813867028, 4091010797,3974542186]), + std::vector expected_output = { 1862536192, 526086805, 2067405084, 593147560, + 726610467, 813867028, 4091010797ULL, 3974542186ULL }; + + auto trace = Execution::gen_trace(instructions, returndata); + + // Find the first row enabling the Sha256Compression selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_sha256 == 1; }); + EXPECT_EQ(row->avm_main_ind_a, 34); + EXPECT_EQ(row->avm_main_ind_b, 35); + EXPECT_EQ(row->avm_main_ind_c, 36); + EXPECT_EQ(row->avm_main_mem_idx_a, 1); // Indirect(34) -> 9 + EXPECT_EQ(row->avm_main_mem_idx_b, 9); // Indirect(35) -> 9 + EXPECT_EQ(row->avm_main_mem_idx_c, 256); // Indirect(36) -> 256 + EXPECT_EQ(row->avm_main_ia, 1); // Trivially contains 0. (See avm_trace for explanation why) + EXPECT_EQ(row->avm_main_ib, 1); // Contains first element of the state + EXPECT_EQ(row->avm_main_ic, 0); // Contains first element of the input + + EXPECT_EQ(returndata, expected_output); + + validate_trace(std::move(trace)); +} // Negative test detecting an invalid opcode byte. TEST_F(AvmExecutionTests, invalidOpcode) { diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp index 18e319e1f54..614a1a188a8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp @@ -240,4 +240,5 @@ void clear_range_check_counters(std::vector& trace, uint256_t previous_valu trace.at(lookup_value + 1).lookup_u16_14_counts = trace.at(lookup_value + 1).lookup_u16_14_counts - 1; previous_value >>= 16; } + } // namespace tests_avm