diff --git a/barretenberg/cpp/pil/vm2/instr_fetching.pil b/barretenberg/cpp/pil/vm2/instr_fetching.pil index 41808a89e183..f7844dc34fde 100644 --- a/barretenberg/cpp/pil/vm2/instr_fetching.pil +++ b/barretenberg/cpp/pil/vm2/instr_fetching.pil @@ -30,6 +30,8 @@ pol commit op1, op2, op3, op4, op5, op6, op7; // Wire to execution opcodes translation. pol commit exec_opcode; +pol commit instr_size_in_bytes; + // Bring in the bytes from the bytecode columns. #[BYTES_FROM_BC_DEC] sel { @@ -82,6 +84,7 @@ pol commit sel_op_dc_17; sel { bd0, exec_opcode, + instr_size_in_bytes, sel_op_dc_0, sel_op_dc_1, sel_op_dc_2, sel_op_dc_3, sel_op_dc_4, sel_op_dc_5, sel_op_dc_6, sel_op_dc_7, sel_op_dc_8, sel_op_dc_9, sel_op_dc_10, sel_op_dc_11, @@ -91,6 +94,7 @@ sel { precomputed.sel_range_wire_opcode { precomputed.clk, precomputed.exec_opcode, + precomputed.instr_size_in_bytes, precomputed.sel_op_dc_0, precomputed.sel_op_dc_1, precomputed.sel_op_dc_2, precomputed.sel_op_dc_3, precomputed.sel_op_dc_4, precomputed.sel_op_dc_5, precomputed.sel_op_dc_6, precomputed.sel_op_dc_7, precomputed.sel_op_dc_8, precomputed.sel_op_dc_9, precomputed.sel_op_dc_10, precomputed.sel_op_dc_11, @@ -103,11 +107,19 @@ precomputed.sel_range_wire_opcode { // Remark: Upper-casing the alias needs to be edited manually (not code-generated)! pol SEL_OP_DC_18 = sel_op_dc_2 + sel_op_dc_6; +#[INDIRECT_BYTES_DECOMPOSITION] indirect = sel_op_dc_0 * (bd1 * 2**8 + bd2 * 2**0) + SEL_OP_DC_18 * (bd1 * 2**0); +#[OP1_BYTES_DECOMPOSITION] op1 = sel_op_dc_0 * (bd3 * 2**8 + bd4 * 2**0) + sel_op_dc_2 * (bd2 * 2**8 + bd3 * 2**0) + sel_op_dc_6 * (bd2 * 2**0) + sel_op_dc_15 * (bd1 * 2**24 + bd2 * 2**16 + bd3 * 2**8 + bd4 * 2**0); +#[OP2_BYTES_DECOMPOSITION] op2 = sel_op_dc_0 * (bd5 * 2**8 + bd6 * 2**0) + sel_op_dc_3 * (bd4 * 2**8 + bd5 * 2**0) + sel_op_dc_6 * (bd3 * 2**0) + sel_op_dc_8 * (bd4 * 2**0) + sel_op_dc_16 * (bd4 * 2**24 + bd5 * 2**16 + bd6 * 2**8 + bd7 * 2**0); +#[OP3_BYTES_DECOMPOSITION] op3 = sel_op_dc_0 * (bd7 * 2**8 + bd8 * 2**0) + sel_op_dc_4 * (bd6 * 2**8 + bd7 * 2**0) + sel_op_dc_9 * (bd5 * 2**248 + bd6 * 2**240 + bd7 * 2**232 + bd8 * 2**224 + bd9 * 2**216 + bd10 * 2**208 + bd11 * 2**200 + bd12 * 2**192 + bd13 * 2**184 + bd14 * 2**176 + bd15 * 2**168 + bd16 * 2**160 + bd17 * 2**152 + bd18 * 2**144 + bd19 * 2**136 + bd20 * 2**128 + bd21 * 2**120 + bd22 * 2**112 + bd23 * 2**104 + bd24 * 2**96 + bd25 * 2**88 + bd26 * 2**80 + bd27 * 2**72 + bd28 * 2**64 + bd29 * 2**56 + bd30 * 2**48 + bd31 * 2**40 + bd32 * 2**32 + bd33 * 2**24 + bd34 * 2**16 + bd35 * 2**8 + bd36 * 2**0) + sel_op_dc_10 * (bd5 * 2**120 + bd6 * 2**112 + bd7 * 2**104 + bd8 * 2**96 + bd9 * 2**88 + bd10 * 2**80 + bd11 * 2**72 + bd12 * 2**64 + bd13 * 2**56 + bd14 * 2**48 + bd15 * 2**40 + bd16 * 2**32 + bd17 * 2**24 + bd18 * 2**16 + bd19 * 2**8 + bd20 * 2**0) + sel_op_dc_11 * (bd5 * 2**56 + bd6 * 2**48 + bd7 * 2**40 + bd8 * 2**32 + bd9 * 2**24 + bd10 * 2**16 + bd11 * 2**8 + bd12 * 2**0) + sel_op_dc_12 * (bd5 * 2**24 + bd6 * 2**16 + bd7 * 2**8 + bd8 * 2**0) + sel_op_dc_13 * (bd5 * 2**8 + bd6 * 2**0) + sel_op_dc_14 * (bd4 * 2**0) + sel_op_dc_17 * (bd6 * 2**0); +#[OP4_BYTES_DECOMPOSITION] op4 = sel_op_dc_0 * (bd9 * 2**8 + bd10 * 2**0) + sel_op_dc_5 * (bd8 * 2**8 + bd9 * 2**0) + sel_op_dc_7 * (bd8 * 2**0); +#[OP5_BYTES_DECOMPOSITION] op5 = sel_op_dc_0 * (bd11 * 2**8 + bd12 * 2**0); +#[OP6_BYTES_DECOMPOSITION] op6 = sel_op_dc_1 * (bd13 * 2**8 + bd14 * 2**0); +#[OP7_BYTES_DECOMPOSITION] op7 = sel_op_dc_1 * (bd15 * 2**8 + bd16 * 2**0); diff --git a/barretenberg/cpp/pil/vm2/precomputed.pil b/barretenberg/cpp/pil/vm2/precomputed.pil index 7067e53ea0d7..9fbc178944d6 100644 --- a/barretenberg/cpp/pil/vm2/precomputed.pil +++ b/barretenberg/cpp/pil/vm2/precomputed.pil @@ -75,6 +75,7 @@ pol constant sel_op_dc_16; pol constant sel_op_dc_17; pol constant exec_opcode; +pol constant instr_size_in_bytes; // Toggle the rows which index (clk) is equal to a wire opcode // Is used to lookup into the wire instruction spec table which contains the operand decomposition diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp index ba3238ea35d3..0105bf5e6640 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.cpp @@ -84,162 +84,276 @@ const std::unordered_map> W const std::unordered_map WIRE_INSTRUCTION_SPEC = { { WireOpCode::ADD_8, - { .exec_opcode = ExecutionOpCode::ADD, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::ADD_8) } }, + { .exec_opcode = ExecutionOpCode::ADD, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::ADD_8) } }, { WireOpCode::ADD_16, - { .exec_opcode = ExecutionOpCode::ADD, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::ADD_16) } }, + { .exec_opcode = ExecutionOpCode::ADD, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::ADD_16) } }, { WireOpCode::SUB_8, - { .exec_opcode = ExecutionOpCode::SUB, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SUB_8) } }, + { .exec_opcode = ExecutionOpCode::SUB, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SUB_8) } }, { WireOpCode::SUB_16, - { .exec_opcode = ExecutionOpCode::SUB, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SUB_16) } }, + { .exec_opcode = ExecutionOpCode::SUB, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SUB_16) } }, { WireOpCode::MUL_8, - { .exec_opcode = ExecutionOpCode::MUL, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::MUL_8) } }, + { .exec_opcode = ExecutionOpCode::MUL, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::MUL_8) } }, { WireOpCode::MUL_16, - { .exec_opcode = ExecutionOpCode::MUL, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::MUL_16) } }, + { .exec_opcode = ExecutionOpCode::MUL, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::MUL_16) } }, { WireOpCode::DIV_8, - { .exec_opcode = ExecutionOpCode::DIV, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::DIV_8) } }, + { .exec_opcode = ExecutionOpCode::DIV, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::DIV_8) } }, { WireOpCode::DIV_16, - { .exec_opcode = ExecutionOpCode::DIV, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::DIV_16) } }, + { .exec_opcode = ExecutionOpCode::DIV, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::DIV_16) } }, { WireOpCode::FDIV_8, - { .exec_opcode = ExecutionOpCode::FDIV, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::FDIV_8) } }, + { .exec_opcode = ExecutionOpCode::FDIV, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::FDIV_8) } }, { WireOpCode::FDIV_16, - { .exec_opcode = ExecutionOpCode::FDIV, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::FDIV_16) } }, + { .exec_opcode = ExecutionOpCode::FDIV, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::FDIV_16) } }, { WireOpCode::EQ_8, - { .exec_opcode = ExecutionOpCode::EQ, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::EQ_8) } }, + { .exec_opcode = ExecutionOpCode::EQ, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::EQ_8) } }, { WireOpCode::EQ_16, - { .exec_opcode = ExecutionOpCode::EQ, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::EQ_16) } }, + { .exec_opcode = ExecutionOpCode::EQ, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::EQ_16) } }, { WireOpCode::LT_8, - { .exec_opcode = ExecutionOpCode::LT, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::LT_8) } }, + { .exec_opcode = ExecutionOpCode::LT, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::LT_8) } }, { WireOpCode::LT_16, - { .exec_opcode = ExecutionOpCode::LT, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::LT_16) } }, + { .exec_opcode = ExecutionOpCode::LT, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::LT_16) } }, { WireOpCode::LTE_8, - { .exec_opcode = ExecutionOpCode::LTE, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::LTE_8) } }, + { .exec_opcode = ExecutionOpCode::LTE, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::LTE_8) } }, { WireOpCode::LTE_16, - { .exec_opcode = ExecutionOpCode::LTE, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::LTE_16) } }, + { .exec_opcode = ExecutionOpCode::LTE, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::LTE_16) } }, { WireOpCode::AND_8, - { .exec_opcode = ExecutionOpCode::AND, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::AND_8) } }, + { .exec_opcode = ExecutionOpCode::AND, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::AND_8) } }, { WireOpCode::AND_16, - { .exec_opcode = ExecutionOpCode::AND, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::AND_16) } }, + { .exec_opcode = ExecutionOpCode::AND, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::AND_16) } }, { WireOpCode::OR_8, - { .exec_opcode = ExecutionOpCode::OR, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::OR_8) } }, + { .exec_opcode = ExecutionOpCode::OR, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::OR_8) } }, { WireOpCode::OR_16, - { .exec_opcode = ExecutionOpCode::OR, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::OR_16) } }, + { .exec_opcode = ExecutionOpCode::OR, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::OR_16) } }, { WireOpCode::XOR_8, - { .exec_opcode = ExecutionOpCode::XOR, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::XOR_8) } }, + { .exec_opcode = ExecutionOpCode::XOR, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::XOR_8) } }, { WireOpCode::XOR_16, - { .exec_opcode = ExecutionOpCode::XOR, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::XOR_16) } }, + { .exec_opcode = ExecutionOpCode::XOR, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::XOR_16) } }, { WireOpCode::NOT_8, - { .exec_opcode = ExecutionOpCode::NOT, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::NOT_8) } }, + { .exec_opcode = ExecutionOpCode::NOT, + .size_in_bytes = 4, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::NOT_8) } }, { WireOpCode::NOT_16, - { .exec_opcode = ExecutionOpCode::NOT, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::NOT_16) } }, + { .exec_opcode = ExecutionOpCode::NOT, + .size_in_bytes = 6, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::NOT_16) } }, { WireOpCode::SHL_8, - { .exec_opcode = ExecutionOpCode::SHL, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SHL_8) } }, + { .exec_opcode = ExecutionOpCode::SHL, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SHL_8) } }, { WireOpCode::SHL_16, - { .exec_opcode = ExecutionOpCode::SHL, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SHL_16) } }, + { .exec_opcode = ExecutionOpCode::SHL, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SHL_16) } }, { WireOpCode::SHR_8, - { .exec_opcode = ExecutionOpCode::SHR, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SHR_8) } }, + { .exec_opcode = ExecutionOpCode::SHR, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SHR_8) } }, { WireOpCode::SHR_16, - { .exec_opcode = ExecutionOpCode::SHR, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SHR_16) } }, + { .exec_opcode = ExecutionOpCode::SHR, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SHR_16) } }, { WireOpCode::CAST_8, - { .exec_opcode = ExecutionOpCode::CAST, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::CAST_8) } }, + { .exec_opcode = ExecutionOpCode::CAST, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::CAST_8) } }, { WireOpCode::CAST_16, - { .exec_opcode = ExecutionOpCode::CAST, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::CAST_16) } }, + { .exec_opcode = ExecutionOpCode::CAST, + .size_in_bytes = 7, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::CAST_16) } }, { WireOpCode::GETENVVAR_16, { .exec_opcode = ExecutionOpCode::GETENVVAR, + .size_in_bytes = 5, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::GETENVVAR_16) } }, { WireOpCode::CALLDATACOPY, { .exec_opcode = ExecutionOpCode::CALLDATACOPY, + .size_in_bytes = 8, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::CALLDATACOPY) } }, { WireOpCode::SUCCESSCOPY, { .exec_opcode = ExecutionOpCode::SUCCESSCOPY, + .size_in_bytes = 4, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SUCCESSCOPY) } }, { WireOpCode::RETURNDATASIZE, { .exec_opcode = ExecutionOpCode::RETURNDATASIZE, + .size_in_bytes = 4, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::RETURNDATASIZE) } }, { WireOpCode::RETURNDATACOPY, { .exec_opcode = ExecutionOpCode::RETURNDATACOPY, + .size_in_bytes = 8, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::RETURNDATACOPY) } }, { WireOpCode::JUMP_32, - { .exec_opcode = ExecutionOpCode::JUMP, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::JUMP_32) } }, + { .exec_opcode = ExecutionOpCode::JUMP, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::JUMP_32) } }, { WireOpCode::JUMPI_32, - { .exec_opcode = ExecutionOpCode::JUMPI, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::JUMPI_32) } }, + { .exec_opcode = ExecutionOpCode::JUMPI, + .size_in_bytes = 8, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::JUMPI_32) } }, { WireOpCode::INTERNALCALL, { .exec_opcode = ExecutionOpCode::INTERNALCALL, + .size_in_bytes = 5, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::INTERNALCALL) } }, { WireOpCode::INTERNALRETURN, { .exec_opcode = ExecutionOpCode::INTERNALRETURN, + .size_in_bytes = 1, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::INTERNALRETURN) } }, { WireOpCode::SET_8, - { .exec_opcode = ExecutionOpCode::SET, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_8) } }, + { .exec_opcode = ExecutionOpCode::SET, + .size_in_bytes = 5, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_8) } }, { WireOpCode::SET_16, - { .exec_opcode = ExecutionOpCode::SET, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_16) } }, + { .exec_opcode = ExecutionOpCode::SET, + .size_in_bytes = 7, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_16) } }, { WireOpCode::SET_32, - { .exec_opcode = ExecutionOpCode::SET, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_32) } }, + { .exec_opcode = ExecutionOpCode::SET, + .size_in_bytes = 9, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_32) } }, { WireOpCode::SET_64, - { .exec_opcode = ExecutionOpCode::SET, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_64) } }, + { .exec_opcode = ExecutionOpCode::SET, + .size_in_bytes = 13, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_64) } }, { WireOpCode::SET_128, - { .exec_opcode = ExecutionOpCode::SET, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_128) } }, + { .exec_opcode = ExecutionOpCode::SET, + .size_in_bytes = 21, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_128) } }, { WireOpCode::SET_FF, - { .exec_opcode = ExecutionOpCode::SET, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_FF) } }, + { .exec_opcode = ExecutionOpCode::SET, + .size_in_bytes = 37, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SET_FF) } }, { WireOpCode::MOV_8, - { .exec_opcode = ExecutionOpCode::MOV, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::MOV_8) } }, + { .exec_opcode = ExecutionOpCode::MOV, + .size_in_bytes = 4, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::MOV_8) } }, { WireOpCode::MOV_16, - { .exec_opcode = ExecutionOpCode::MOV, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::MOV_16) } }, + { .exec_opcode = ExecutionOpCode::MOV, + .size_in_bytes = 6, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::MOV_16) } }, { WireOpCode::SLOAD, - { .exec_opcode = ExecutionOpCode::SLOAD, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SLOAD) } }, + { .exec_opcode = ExecutionOpCode::SLOAD, + .size_in_bytes = 6, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SLOAD) } }, { WireOpCode::SSTORE, - { .exec_opcode = ExecutionOpCode::SSTORE, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SSTORE) } }, + { .exec_opcode = ExecutionOpCode::SSTORE, + .size_in_bytes = 6, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SSTORE) } }, { WireOpCode::NOTEHASHEXISTS, { .exec_opcode = ExecutionOpCode::NOTEHASHEXISTS, + .size_in_bytes = 8, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::NOTEHASHEXISTS) } }, { WireOpCode::EMITNOTEHASH, { .exec_opcode = ExecutionOpCode::EMITNOTEHASH, + .size_in_bytes = 4, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::EMITNOTEHASH) } }, { WireOpCode::NULLIFIEREXISTS, { .exec_opcode = ExecutionOpCode::NULLIFIEREXISTS, + .size_in_bytes = 8, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::NULLIFIEREXISTS) } }, { WireOpCode::EMITNULLIFIER, { .exec_opcode = ExecutionOpCode::EMITNULLIFIER, + .size_in_bytes = 4, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::EMITNULLIFIER) } }, { WireOpCode::L1TOL2MSGEXISTS, { .exec_opcode = ExecutionOpCode::L1TOL2MSGEXISTS, + .size_in_bytes = 8, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::L1TOL2MSGEXISTS) } }, { WireOpCode::GETCONTRACTINSTANCE, { .exec_opcode = ExecutionOpCode::GETCONTRACTINSTANCE, + .size_in_bytes = 9, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::GETCONTRACTINSTANCE) } }, { WireOpCode::EMITUNENCRYPTEDLOG, { .exec_opcode = ExecutionOpCode::EMITUNENCRYPTEDLOG, + .size_in_bytes = 6, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::EMITUNENCRYPTEDLOG) } }, { WireOpCode::SENDL2TOL1MSG, { .exec_opcode = ExecutionOpCode::SENDL2TOL1MSG, + .size_in_bytes = 6, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SENDL2TOL1MSG) } }, { WireOpCode::CALL, - { .exec_opcode = ExecutionOpCode::CALL, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::CALL) } }, + { .exec_opcode = ExecutionOpCode::CALL, + .size_in_bytes = 13, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::CALL) } }, { WireOpCode::STATICCALL, { .exec_opcode = ExecutionOpCode::STATICCALL, + .size_in_bytes = 13, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::STATICCALL) } }, { WireOpCode::RETURN, - { .exec_opcode = ExecutionOpCode::RETURN, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::RETURN) } }, + { .exec_opcode = ExecutionOpCode::RETURN, + .size_in_bytes = 6, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::RETURN) } }, { WireOpCode::REVERT_8, - { .exec_opcode = ExecutionOpCode::REVERT, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::REVERT_8) } }, + { .exec_opcode = ExecutionOpCode::REVERT, + .size_in_bytes = 4, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::REVERT_8) } }, { WireOpCode::REVERT_16, { .exec_opcode = ExecutionOpCode::REVERT, + .size_in_bytes = 6, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::REVERT_16) } }, { WireOpCode::DEBUGLOG, { .exec_opcode = ExecutionOpCode::DEBUGLOG, + .size_in_bytes = 10, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::DEBUGLOG) } }, { WireOpCode::POSEIDON2PERM, { .exec_opcode = ExecutionOpCode::POSEIDON2PERM, + .size_in_bytes = 6, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::POSEIDON2PERM) } }, { WireOpCode::SHA256COMPRESSION, { .exec_opcode = ExecutionOpCode::SHA256COMPRESSION, + .size_in_bytes = 8, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::SHA256COMPRESSION) } }, { WireOpCode::KECCAKF1600, { .exec_opcode = ExecutionOpCode::KECCAKF1600, + .size_in_bytes = 6, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::KECCAKF1600) } }, { WireOpCode::ECADD, - { .exec_opcode = ExecutionOpCode::ECADD, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::ECADD) } }, + { .exec_opcode = ExecutionOpCode::ECADD, + .size_in_bytes = 17, + .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::ECADD) } }, { WireOpCode::TORADIXBE, { .exec_opcode = ExecutionOpCode::TORADIXBE, + .size_in_bytes = 13, .op_dc_selectors = WireOpCode_DC_SELECTORS.at(WireOpCode::TORADIXBE) } }, }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.hpp b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.hpp index 4fec33922e31..1e44b3447202 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.hpp @@ -28,6 +28,7 @@ struct ExecInstructionSpec { struct WireInstructionSpec { ExecutionOpCode exec_opcode; + uint32_t size_in_bytes; std::array op_dc_selectors; bool operator==(const WireInstructionSpec& other) const = default; diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.test.cpp new file mode 100644 index 000000000000..045c66ca4a88 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/common/instruction_spec.test.cpp @@ -0,0 +1,39 @@ +#include +#include + +#include "barretenberg/vm2/common/instruction_spec.hpp" +#include "barretenberg/vm2/common/opcodes.hpp" +#include "barretenberg/vm2/simulation/lib/serialization.hpp" + +namespace bb::avm2 { +namespace { + +size_t compute_instruction_size(WireOpCode wire_opcode, + const std::unordered_map>& wire_format, + const std::unordered_map& operand_type_sizes) +{ + size_t instr_size = 1; // Take into account the opcode byte + for (const auto& operand_type : wire_format.at(wire_opcode)) { + instr_size += operand_type_sizes.at(operand_type); + } + + return instr_size; +} + +// Test checking that the hardcoded size for each instruction specified in WIRE_INSTRUCTION_SPEC +// is correct. This test would fail only when we change the wire format of an instruction. +TEST(InstructionSpecTest, CheckAllInstructionSizes) +{ + const auto& wire_format = simulation::testonly::get_instruction_wire_formats(); + const auto& operand_type_sizes = simulation::testonly::get_operand_type_sizes(); + + for (int i = 0; i < static_cast(WireOpCode::LAST_OPCODE_SENTINEL); i++) { + const auto wire_opcode = static_cast(i); + const auto computed_size = compute_instruction_size(wire_opcode, wire_format, operand_type_sizes); + EXPECT_EQ(WIRE_INSTRUCTION_SPEC.at(wire_opcode).size_in_bytes, computed_size) + << "Incorrect size_in_bytes field for " << wire_opcode << " in WIRE_INSTRUCTION_SPEC."; + } +} + +} // namespace +} // namespace bb::avm2 diff --git a/barretenberg/cpp/src/barretenberg/vm2/common/memory_types.hpp b/barretenberg/cpp/src/barretenberg/vm2/common/memory_types.hpp index d3ba454fbb06..1e1cfe273225 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/memory_types.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/common/memory_types.hpp @@ -6,6 +6,7 @@ namespace bb::avm2 { +// Adapt NUM_MEMORY_TAGS in fixtures.cpp if this enum is modified. enum class MemoryTag { FF, U1, diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bc_decomposition.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bc_decomposition.test.cpp index 2d85f9a63f4b..2182eb9cc657 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bc_decomposition.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bc_decomposition.test.cpp @@ -34,11 +34,7 @@ void init_trace(TestTraceContainer& trace) TEST(BytecodeDecompositionConstrainingTest, EmptyRow) { - TestTraceContainer trace({ - { { C::precomputed_first_row, 1 } }, - }); - - check_relation(trace); + check_relation(testing::empty_trace()); } TEST(BytecodeDecompositionConstrainingTest, SingleBytecode) diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bc_hashing.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bc_hashing.test.cpp index 389b19d39af1..bd4088c8d92d 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bc_hashing.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bc_hashing.test.cpp @@ -41,11 +41,7 @@ using length_iv_relation = bb::avm2::lookup_bc_hashing_iv_is_len_relation; TEST(BytecodeHashingConstrainingTest, EmptyRow) { - TestTraceContainer trace({ - { { C::precomputed_first_row, 1 } }, - }); - - check_relation(trace); + check_relation(testing::empty_trace()); } TEST(BytecodeHashingConstrainingTest, SingleBytecodeHash) diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bitwise.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bitwise.test.cpp index decc31579752..e4f346caf2b7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/bitwise.test.cpp @@ -8,6 +8,7 @@ #include "barretenberg/vm2/constraining/testing/check_relation.hpp" #include "barretenberg/vm2/generated/flavor_settings.hpp" #include "barretenberg/vm2/generated/relations/bitwise.hpp" +#include "barretenberg/vm2/testing/fixtures.hpp" #include "barretenberg/vm2/testing/macros.hpp" #include "barretenberg/vm2/tracegen/bitwise_trace.hpp" #include "barretenberg/vm2/tracegen/test_trace_container.hpp" @@ -23,11 +24,7 @@ using bitwise = bb::avm2::bitwise; TEST(BitwiseConstrainingTest, EmptyRow) { - TestTraceContainer trace({ - { { C::precomputed_first_row, 1 } }, - }); - - check_relation(trace); + check_relation(testing::empty_trace()); } // Testing a positive AND operation for each integral type (U1, U8, ... U128) diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/class_id_derivation.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/class_id_derivation.test.cpp index 97c1adb73147..303a587db0a4 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/class_id_derivation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/class_id_derivation.test.cpp @@ -54,12 +54,7 @@ ContractClass generate_contract_class() TEST(ClassIdDerivationConstrainingTest, EmptyRow) { - TestTraceContainer trace({ - { { C::precomputed_first_row, 1 } }, - { { C::precomputed_clk, 0 } }, - }); - - check_relation(trace); + check_relation(testing::empty_trace()); } TEST(ClassIdDerivationConstrainingTest, Basic) diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp index 04ea01b1af5c..1a69d21a6068 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp @@ -5,12 +5,16 @@ #include #include +#include "barretenberg/vm2/common/instruction_spec.hpp" #include "barretenberg/vm2/constraining/testing/check_relation.hpp" #include "barretenberg/vm2/generated/columns.hpp" #include "barretenberg/vm2/generated/flavor_settings.hpp" #include "barretenberg/vm2/generated/relations/instr_fetching.hpp" +#include "barretenberg/vm2/testing/fixtures.hpp" #include "barretenberg/vm2/testing/macros.hpp" #include "barretenberg/vm2/tracegen/bytecode_trace.hpp" +#include "barretenberg/vm2/tracegen/lib/lookup_builder.hpp" +#include "barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_clk.hpp" #include "barretenberg/vm2/tracegen/precomputed_trace.hpp" #include "barretenberg/vm2/tracegen/test_trace_container.hpp" @@ -18,20 +22,19 @@ namespace bb::avm2::constraining { namespace { using tracegen::BytecodeTraceBuilder; +using tracegen::PrecomputedTraceBuilder; using tracegen::TestTraceContainer; using FF = AvmFlavorSettings::FF; using C = Column; using instr_fetching = bb::avm2::instr_fetching; using simulation::Instruction; +using simulation::InstructionFetchingEvent; using simulation::Operand; +using testing::random_bytes; TEST(InstrFetchingConstrainingTest, EmptyRow) { - TestTraceContainer trace({ - { { C::precomputed_clk, 1 } }, - }); - - check_relation(trace); + check_relation(testing::empty_trace()); } // Basic positive test with a hardcoded bytecode for ADD_8 @@ -43,10 +46,9 @@ TEST(InstrFetchingConstrainingTest, Add8WithTraceGen) .opcode = WireOpCode::ADD_8, .indirect = 3, .operands = { Operand::u8(0x34), Operand::u8(0x35), Operand::u8(0x36) }, - .size_in_bytes = 5, }; - std::vector bytecode = { static_cast(WireOpCode::ADD_8), 0x03, 0x34, 0x35, 0x36 }; + std::vector bytecode = add_8_instruction.serialize(); builder.process_instruction_fetching({ { .bytecode_id = 1, .pc = 0, @@ -74,29 +76,9 @@ TEST(InstrFetchingConstrainingTest, EcaddWithTraceGen) Operand::u16(0x127d), Operand::u16(0x127e), Operand::u16(0x127f) }, - .size_in_bytes = 17, - }; - - std::vector bytecode = { - static_cast(WireOpCode::ECADD), - 0x1f, - 0x1f, - 0x12, - 0x79, - 0x12, - 0x7a, - 0x12, - 0x7b, - 0x12, - 0x7c, - 0x12, - 0x7d, - 0x12, - 0x7e, - 0x12, - 0x7f, }; + std::vector bytecode = ecadd_instruction.serialize(); builder.process_instruction_fetching({ { .bytecode_id = 1, .pc = 0, .instruction = ecadd_instruction, @@ -107,40 +89,258 @@ TEST(InstrFetchingConstrainingTest, EcaddWithTraceGen) check_relation(trace); } +// Helper routine generating a vector of instruction fetching events for each +// opcode. +std::vector gen_instr_events_each_opcode() +{ + std::vector bytecode; + std::vector instructions; + constexpr auto num_opcodes = static_cast(WireOpCode::LAST_OPCODE_SENTINEL); + instructions.reserve(num_opcodes); + std::array pc_positions; + + for (size_t i = 0; i < num_opcodes; i++) { + pc_positions.at(i) = static_cast(bytecode.size()); + const auto instr = testing::random_instruction(static_cast(i)); + instructions.emplace_back(instr); + const auto instruction_bytes = instr.serialize(); + bytecode.insert(bytecode.end(), + std::make_move_iterator(instruction_bytes.begin()), + std::make_move_iterator(instruction_bytes.end())); + } + + const auto bytecode_ptr = std::make_shared>(std::move(bytecode)); + // Always use *bytecode_ptr from now on instead of bytecode as this one was moved. + + std::vector instr_events; + instr_events.reserve(num_opcodes); + for (size_t i = 0; i < num_opcodes; i++) { + instr_events.emplace_back(InstructionFetchingEvent{ + .bytecode_id = 1, .pc = pc_positions.at(i), .instruction = instructions.at(i), .bytecode = bytecode_ptr }); + } + return instr_events; +} + // Positive test for each opcode. We assume that decode instruction is working correctly. // It works as long as the relations are not constraining the correct range for TAG nor indirect. TEST(InstrFetchingConstrainingTest, EachOpcodeWithTraceGen) { - uint32_t seed = 987137937; // Arbitrary number serving as pseudo-random seed to generate bytes + TestTraceContainer trace; + BytecodeTraceBuilder builder; - auto gen_40_bytes = [&]() { - std::vector bytes; - bytes.resize(40); + builder.process_instruction_fetching(gen_instr_events_each_opcode(), trace); - for (size_t i = 0; i < 40; i++) { - bytes.at(i) = static_cast(seed % 256); - seed *= seed; - } - return bytes; + constexpr auto num_opcodes = static_cast(WireOpCode::LAST_OPCODE_SENTINEL); + EXPECT_EQ(trace.get_num_rows(), num_opcodes); + check_relation(trace); +} + +// Negative test about decomposition of operands. We mutate correct operand values in the trace. +// This also covers wrong operands which are not "involved" by the instruction. +// We perform this for a random instruction for opcodes: REVERT_16, CAST_8, TORADIXBE +TEST(InstrFetchingConstrainingTest, NegativeWrongOperand) +{ + BytecodeTraceBuilder builder; + + std::vector opcodes = { WireOpCode::REVERT_16, WireOpCode::CAST_8, WireOpCode::TORADIXBE }; + std::vector sub_relations = { + instr_fetching::SR_INDIRECT_BYTES_DECOMPOSITION, instr_fetching::SR_OP1_BYTES_DECOMPOSITION, + instr_fetching::SR_OP2_BYTES_DECOMPOSITION, instr_fetching::SR_OP3_BYTES_DECOMPOSITION, + instr_fetching::SR_OP4_BYTES_DECOMPOSITION, instr_fetching::SR_OP5_BYTES_DECOMPOSITION, + instr_fetching::SR_OP6_BYTES_DECOMPOSITION, instr_fetching::SR_OP7_BYTES_DECOMPOSITION, }; - for (uint8_t i = 0; i < static_cast(WireOpCode::LAST_OPCODE_SENTINEL); i++) { + constexpr std::array operand_cols = { + C::instr_fetching_indirect, C::instr_fetching_op1, C::instr_fetching_op2, C::instr_fetching_op3, + C::instr_fetching_op4, C::instr_fetching_op5, C::instr_fetching_op6, C::instr_fetching_op7, + }; + + for (const auto& opcode : opcodes) { TestTraceContainer trace; - BytecodeTraceBuilder builder; + const auto instr = testing::random_instruction(opcode); + builder.process_instruction_fetching( + { { .bytecode_id = 1, + .pc = 0, + .instruction = instr, + .bytecode = std::make_shared>(instr.serialize()) } }, + trace); + check_relation(trace); - std::vector bytecode = gen_40_bytes(); - bytecode.at(0) = i; + EXPECT_EQ(trace.get_num_rows(), 1); - const auto instr = simulation::decode_instruction(bytecode, 0); + for (size_t i = 0; i < operand_cols.size(); i++) { + auto mutated_trace = trace; + const FF mutated_operand = trace.get(operand_cols.at(i), 0) + 1; // Mutate to value + 1 + mutated_trace.set(operand_cols.at(i), 0, mutated_operand); + EXPECT_THROW_WITH_MESSAGE(check_relation(mutated_trace, sub_relations.at(i)), + instr_fetching::get_subrelation_label(sub_relations.at(i))); + } + } +} - builder.process_instruction_fetching({ { .bytecode_id = 1, - .pc = 0, - .instruction = instr, - .bytecode = std::make_shared>(bytecode) } }, - trace); +// Positive test for interaction with instruction spec table using same events as for the test +// EachOpcodeWithTraceGen, i.e., one event/row is generated per wire opcode. +// It works as long as the relations are not constraining the correct range for TAG nor indirect. +TEST(InstrFetchingConstrainingTest, WireInstructionSpecInteractions) +{ + using wire_instr_spec_lookup = lookup_instr_fetching_wire_instruction_info_relation; - EXPECT_EQ(trace.get_num_rows(), 1); - check_relation(trace); + TestTraceContainer trace; + BytecodeTraceBuilder bytecode_builder; + + PrecomputedTraceBuilder precomputed_builder; + precomputed_builder.process_wire_instruction_spec(trace); + bytecode_builder.process_instruction_fetching(gen_instr_events_each_opcode(), trace); + precomputed_builder.process_misc(trace, trace.get_num_rows()); // Limit to the number of rows we need. + + tracegen::LookupIntoIndexedByClk().process(trace); + + check_relation(trace); + check_interaction(trace); +} + +// Positive test for the interaction with bytecode decomposition table. +// One event/row is generated per wire opcode (same as for test WireInstructionSpecInteractions). +// It works as long as the relations are not constraining the correct range for TAG nor indirect. +TEST(InstrFetchingConstrainingTest, BcDecompositionInteractions) +{ + using bc_decomposition_lookup = lookup_instr_fetching_bytes_from_bc_dec_relation; + + TestTraceContainer trace; + BytecodeTraceBuilder bytecode_builder; + + const auto instr_fetch_events = gen_instr_events_each_opcode(); + bytecode_builder.process_instruction_fetching(instr_fetch_events, trace); + bytecode_builder.process_decomposition({ { + .bytecode_id = instr_fetch_events.at(0).bytecode_id, + .bytecode = instr_fetch_events.at(0).bytecode, + } }, + trace); + + tracegen::LookupIntoDynamicTableSequential().process(trace); + + check_relation(trace); + check_interaction(trace); +} + +// Negative interaction test with some values not matching the instruction spec table. +TEST(InstrFetchingConstrainingTest, NegativeWrongWireInstructionSpecInteractions) +{ + using wire_instr_spec_lookup = lookup_instr_fetching_wire_instruction_info_relation; + using tracegen::LookupIntoIndexedByClk; + + BytecodeTraceBuilder bytecode_builder; + PrecomputedTraceBuilder precomputed_builder; + + // Some arbitrary chosen opcodes. We limit to one as this unit test is costly. + // Test works if the following vector is extended to other opcodes though. + std::vector opcodes = { WireOpCode::CALLDATACOPY }; + + for (const auto& opcode : opcodes) { + TestTraceContainer trace; + const auto instr = testing::random_instruction(opcode); + bytecode_builder.process_instruction_fetching( + { { .bytecode_id = 1, + .pc = 0, + .instruction = instr, + .bytecode = std::make_shared>(instr.serialize()) } }, + trace); + precomputed_builder.process_wire_instruction_spec(trace); + precomputed_builder.process_misc(trace, trace.get_num_rows()); // Limit to the number of rows we need. + + LookupIntoIndexedByClk().process(trace); + + ASSERT_EQ(trace.get(C::lookup_instr_fetching_wire_instruction_info_counts, static_cast(opcode)), 1); + check_interaction(trace); + + constexpr std::array mutated_cols = { + C::instr_fetching_exec_opcode, C::instr_fetching_instr_size_in_bytes, C::instr_fetching_sel_op_dc_0, + C::instr_fetching_sel_op_dc_1, C::instr_fetching_sel_op_dc_2, C::instr_fetching_sel_op_dc_3, + C::instr_fetching_sel_op_dc_4, C::instr_fetching_sel_op_dc_5, C::instr_fetching_sel_op_dc_6, + C::instr_fetching_sel_op_dc_7, C::instr_fetching_sel_op_dc_8, C::instr_fetching_sel_op_dc_9, + C::instr_fetching_sel_op_dc_10, C::instr_fetching_sel_op_dc_11, C::instr_fetching_sel_op_dc_12, + C::instr_fetching_sel_op_dc_13, C::instr_fetching_sel_op_dc_14, C::instr_fetching_sel_op_dc_15, + C::instr_fetching_sel_op_dc_16, C::instr_fetching_sel_op_dc_17, + }; + + // Mutate execution opcode + for (const auto& col : mutated_cols) { + auto mutated_trace = trace; + const FF mutated_value = trace.get(col, 0) + 1; // Mutate to value + 1 + mutated_trace.set(col, 0, mutated_value); + + // We do not need to re-run LookupIntoIndexedByClk().process(trace); + // because we never mutate the indexing column for this lookup (clk) and for this lookup + // find_in_dst only uses column C::instr_fetching_bd0 mapped to (clk). So, the counts are still valid. + + EXPECT_THROW_WITH_MESSAGE(check_interaction(mutated_trace), + "Relation.*WIRE_INSTRUCTION_INFO.* ACCUMULATION.* is non-zero"); + } + } +} + +// Negative interaction test with some values not matching the bytecode decomposition table. +TEST(InstrFetchingConstrainingTest, NegativeWrongBcDecompositionInteractions) +{ + using bc_decomposition_lookup = lookup_instr_fetching_bytes_from_bc_dec_relation; + using tracegen::LookupIntoDynamicTableSequential; + + TestTraceContainer trace; + BytecodeTraceBuilder bytecode_builder; + + // Some arbitrary chosen opcodes. We limit to one as this unit test is costly. + // Test works if the following vector is extended to other opcodes though. + std::vector opcodes = { WireOpCode::STATICCALL }; + + for (const auto& opcode : opcodes) { + TestTraceContainer trace; + const auto instr = testing::random_instruction(opcode); + auto bytecode_ptr = std::make_shared>(instr.serialize()); + bytecode_builder.process_instruction_fetching({ { + .bytecode_id = 1, + .pc = 0, + .instruction = instr, + .bytecode = bytecode_ptr, + } }, + trace); + bytecode_builder.process_decomposition({ { + .bytecode_id = 1, + .bytecode = bytecode_ptr, + } }, + trace); + + auto valid_trace = trace; // Keep original trace before lookup processing + LookupIntoDynamicTableSequential().process(valid_trace); + check_interaction(valid_trace); + + constexpr std::array mutated_cols = { + C::instr_fetching_pc, C::instr_fetching_bytecode_id, C::instr_fetching_bd0, C::instr_fetching_bd1, + C::instr_fetching_bd2, C::instr_fetching_bd3, C::instr_fetching_bd4, C::instr_fetching_bd5, + C::instr_fetching_bd6, C::instr_fetching_bd7, C::instr_fetching_bd8, C::instr_fetching_bd9, + C::instr_fetching_bd10, C::instr_fetching_bd11, C::instr_fetching_bd12, C::instr_fetching_bd13, + C::instr_fetching_bd14, C::instr_fetching_bd15, C::instr_fetching_bd16, C::instr_fetching_bd17, + C::instr_fetching_bd18, C::instr_fetching_bd19, C::instr_fetching_bd20, C::instr_fetching_bd21, + C::instr_fetching_bd22, C::instr_fetching_bd23, C::instr_fetching_bd24, C::instr_fetching_bd25, + C::instr_fetching_bd26, C::instr_fetching_bd27, C::instr_fetching_bd28, C::instr_fetching_bd29, + C::instr_fetching_bd30, C::instr_fetching_bd31, C::instr_fetching_bd32, C::instr_fetching_bd33, + C::instr_fetching_bd34, C::instr_fetching_bd35, C::instr_fetching_bd36, + }; + + // Mutate execution opcode + for (const auto& col : mutated_cols) { + auto mutated_trace = trace; + const FF mutated_value = trace.get(col, 0) + 1; // Mutate to value + 1 + mutated_trace.set(col, 0, mutated_value); + + // This sets the length of the inverse polynomial via SetDummyInverses, so we still need to call this even + // though we know it will fail. + EXPECT_THROW_WITH_MESSAGE( + LookupIntoDynamicTableSequential().process(mutated_trace), + "Failed.*BYTES_FROM_BC_DEC. Could not find tuple in destination."); + + EXPECT_THROW_WITH_MESSAGE(check_interaction(mutated_trace), + "Relation.*BYTES_FROM_BC_DEC.* ACCUMULATION.* is non-zero"); + } } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/op_decomposition.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/op_decomposition.test.cpp index fea485972b50..fe998d6617ba 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/op_decomposition.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/op_decomposition.test.cpp @@ -173,6 +173,8 @@ std::string render_pil( { std::string pil_equations; for (uint8_t i = 0; i < NUM_OF_OPERANDS; i++) { + pil_equations += (i == 0) ? "#[INDIRECT_BYTES_DECOMPOSITION]\n" + : format("#[OP", static_cast(i), "_BYTES_DECOMPOSITION]\n"); pil_equations += (i == 0) ? "indirect = " : format(OPERAND_PREFIX, static_cast(i), " = "); std::vector additive_terms; diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/poseidon2.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/poseidon2.test.cpp index 560ceeb51ec6..0a850c81a3d5 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/poseidon2.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/poseidon2.test.cpp @@ -10,9 +10,11 @@ #include "barretenberg/vm2/generated/relations/poseidon2_hash.hpp" #include "barretenberg/vm2/generated/relations/poseidon2_perm.hpp" #include "barretenberg/vm2/simulation/events/event_emitter.hpp" +#include "barretenberg/vm2/testing/fixtures.hpp" #include "barretenberg/vm2/testing/macros.hpp" #include "barretenberg/vm2/tracegen/lib/lookup_builder.hpp" #include "barretenberg/vm2/tracegen/poseidon2_trace.hpp" + // Temporary imports, see comment in test. #include "barretenberg/vm2/simulation/poseidon2.hpp" #include "barretenberg/vm2/tracegen/test_trace_container.hpp" @@ -38,12 +40,8 @@ using lookup_poseidon2_perm_relation = bb::avm2::lookup_poseidon2_hash_poseidon2 TEST(Poseidon2ConstrainingTest, Poseidon2EmptyRow) { - auto trace = TestTraceContainer::from_rows({ - { .precomputed_first_row = 1 }, - }); - - check_relation(trace); - check_relation(trace); + check_relation(testing::empty_trace()); + check_relation(testing::empty_trace()); } // These tests imports a bunch of external code since hand-generating the poseidon2 trace is a bit laborious atm. diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/range_check.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/range_check.test.cpp index 69a775c2655e..5838673d607a 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/range_check.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/range_check.test.cpp @@ -7,6 +7,7 @@ #include "barretenberg/vm2/constraining/testing/check_relation.hpp" #include "barretenberg/vm2/generated/flavor_settings.hpp" #include "barretenberg/vm2/generated/relations/range_check.hpp" +#include "barretenberg/vm2/testing/fixtures.hpp" #include "barretenberg/vm2/testing/macros.hpp" #include "barretenberg/vm2/tracegen/range_check_trace.hpp" #include "barretenberg/vm2/tracegen/test_trace_container.hpp" @@ -22,11 +23,7 @@ using range_check = bb::avm2::range_check; TEST(RangeCheckConstrainingTest, EmptyRow) { - TestTraceContainer trace({ - { { C::precomputed_clk, 1 } }, - }); - - check_relation(trace); + check_relation(testing::empty_trace()); } TEST(RangeCheckConstrainingTest, IsLteMutuallyExclusive) diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/sha256.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/sha256.test.cpp index 1281c830d313..238a86df530a 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/sha256.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/sha256.test.cpp @@ -9,6 +9,7 @@ #include "barretenberg/vm2/generated/relations/sha256.hpp" #include "barretenberg/vm2/simulation/events/event_emitter.hpp" #include "barretenberg/vm2/simulation/memory.hpp" +#include "barretenberg/vm2/testing/fixtures.hpp" #include "barretenberg/vm2/testing/macros.hpp" #include "barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_clk.hpp" #include "barretenberg/vm2/tracegen/precomputed_trace.hpp" @@ -44,11 +45,7 @@ using lookup_sha256_round_relation = bb::avm2::lookup_sha256_round_constant_rela TEST(Sha256ConstrainingTest, EmptyRow) { - TestTraceContainer trace({ - { { C::precomputed_clk, 1 } }, - }); - - check_relation(trace); + check_relation(testing::empty_trace()); } // This test imports a bunch of external code since hand-generating the sha256 trace is a bit laborious atm. diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp index d73136392081..50245ede1af9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp @@ -9,8 +9,8 @@ namespace bb::avm2 { // The entities that will be used in the flavor. // clang-format off -#define AVM2_PRECOMPUTED_ENTITIES precomputed_as_unary, precomputed_bitwise_input_a, precomputed_bitwise_input_b, precomputed_bitwise_op_id, precomputed_bitwise_output, precomputed_clk, precomputed_exec_opcode, precomputed_first_row, precomputed_integral_tag_length, precomputed_power_of_2, precomputed_sel_bitwise, precomputed_sel_integral_tag, precomputed_sel_op_dc_0, precomputed_sel_op_dc_1, precomputed_sel_op_dc_10, precomputed_sel_op_dc_11, precomputed_sel_op_dc_12, precomputed_sel_op_dc_13, precomputed_sel_op_dc_14, precomputed_sel_op_dc_15, precomputed_sel_op_dc_16, precomputed_sel_op_dc_17, precomputed_sel_op_dc_2, precomputed_sel_op_dc_3, precomputed_sel_op_dc_4, precomputed_sel_op_dc_5, precomputed_sel_op_dc_6, precomputed_sel_op_dc_7, precomputed_sel_op_dc_8, precomputed_sel_op_dc_9, precomputed_sel_range_16, precomputed_sel_range_8, precomputed_sel_range_wire_opcode, precomputed_sel_sha256_compression, precomputed_sel_unary, precomputed_sha256_compression_round_constant, precomputed_zero -#define AVM2_WIRE_ENTITIES execution_input, alu_dst_addr, alu_ia, alu_ia_addr, alu_ib, alu_ib_addr, alu_ic, alu_op, alu_sel_op_add, bc_decomposition_abs_diff, bc_decomposition_bytes, bc_decomposition_bytes_pc_plus_1, bc_decomposition_bytes_pc_plus_10, bc_decomposition_bytes_pc_plus_11, bc_decomposition_bytes_pc_plus_12, bc_decomposition_bytes_pc_plus_13, bc_decomposition_bytes_pc_plus_14, bc_decomposition_bytes_pc_plus_15, bc_decomposition_bytes_pc_plus_16, bc_decomposition_bytes_pc_plus_17, bc_decomposition_bytes_pc_plus_18, bc_decomposition_bytes_pc_plus_19, bc_decomposition_bytes_pc_plus_2, bc_decomposition_bytes_pc_plus_20, bc_decomposition_bytes_pc_plus_21, bc_decomposition_bytes_pc_plus_22, bc_decomposition_bytes_pc_plus_23, bc_decomposition_bytes_pc_plus_24, bc_decomposition_bytes_pc_plus_25, bc_decomposition_bytes_pc_plus_26, bc_decomposition_bytes_pc_plus_27, bc_decomposition_bytes_pc_plus_28, bc_decomposition_bytes_pc_plus_29, bc_decomposition_bytes_pc_plus_3, bc_decomposition_bytes_pc_plus_30, bc_decomposition_bytes_pc_plus_31, bc_decomposition_bytes_pc_plus_32, bc_decomposition_bytes_pc_plus_33, bc_decomposition_bytes_pc_plus_34, bc_decomposition_bytes_pc_plus_35, bc_decomposition_bytes_pc_plus_36, bc_decomposition_bytes_pc_plus_4, bc_decomposition_bytes_pc_plus_5, bc_decomposition_bytes_pc_plus_6, bc_decomposition_bytes_pc_plus_7, bc_decomposition_bytes_pc_plus_8, bc_decomposition_bytes_pc_plus_9, bc_decomposition_bytes_rem_inv, bc_decomposition_bytes_rem_min_one_inv, bc_decomposition_bytes_remaining, bc_decomposition_bytes_to_read, bc_decomposition_bytes_to_read_unary, bc_decomposition_id, bc_decomposition_last_of_contract, bc_decomposition_packed_field, bc_decomposition_pc, bc_decomposition_sel, bc_decomposition_sel_overflow_correction_needed, bc_decomposition_sel_packed, bc_decomposition_sel_pc_plus_1, bc_decomposition_sel_pc_plus_10, bc_decomposition_sel_pc_plus_11, bc_decomposition_sel_pc_plus_12, bc_decomposition_sel_pc_plus_13, bc_decomposition_sel_pc_plus_14, bc_decomposition_sel_pc_plus_15, bc_decomposition_sel_pc_plus_16, bc_decomposition_sel_pc_plus_17, bc_decomposition_sel_pc_plus_18, bc_decomposition_sel_pc_plus_19, bc_decomposition_sel_pc_plus_2, bc_decomposition_sel_pc_plus_20, bc_decomposition_sel_pc_plus_21, bc_decomposition_sel_pc_plus_22, bc_decomposition_sel_pc_plus_23, bc_decomposition_sel_pc_plus_24, bc_decomposition_sel_pc_plus_25, bc_decomposition_sel_pc_plus_26, bc_decomposition_sel_pc_plus_27, bc_decomposition_sel_pc_plus_28, bc_decomposition_sel_pc_plus_29, bc_decomposition_sel_pc_plus_3, bc_decomposition_sel_pc_plus_30, bc_decomposition_sel_pc_plus_31, bc_decomposition_sel_pc_plus_32, bc_decomposition_sel_pc_plus_33, bc_decomposition_sel_pc_plus_34, bc_decomposition_sel_pc_plus_35, bc_decomposition_sel_pc_plus_36, bc_decomposition_sel_pc_plus_4, bc_decomposition_sel_pc_plus_5, bc_decomposition_sel_pc_plus_6, bc_decomposition_sel_pc_plus_7, bc_decomposition_sel_pc_plus_8, bc_decomposition_sel_pc_plus_9, bc_hashing_bytecode_id, bc_hashing_incremental_hash, bc_hashing_latch, bc_hashing_output_hash, bc_hashing_packed_field, bc_hashing_pc_index, bc_hashing_sel, bc_hashing_start, bc_retrieval_address, bc_retrieval_artifact_hash, bc_retrieval_bytecode_id, bc_retrieval_class_id, bc_retrieval_deployer_addr, bc_retrieval_err, bc_retrieval_incoming_viewing_key_x, bc_retrieval_incoming_viewing_key_y, bc_retrieval_init_hash, bc_retrieval_nullifier_key_x, bc_retrieval_nullifier_key_y, bc_retrieval_outgoing_viewing_key_x, bc_retrieval_outgoing_viewing_key_y, bc_retrieval_private_function_root, bc_retrieval_public_bytecode_commitment, bc_retrieval_salt, bc_retrieval_sel, bc_retrieval_siloed_address, bc_retrieval_tagging_key_x, bc_retrieval_tagging_key_y, bitwise_acc_ia, bitwise_acc_ib, bitwise_acc_ic, bitwise_ctr, bitwise_ctr_inv, bitwise_ctr_min_one_inv, bitwise_ia_byte, bitwise_ib_byte, bitwise_ic_byte, bitwise_last, bitwise_op_id, bitwise_sel, bitwise_start, bitwise_tag, class_id_derivation_artifact_hash, class_id_derivation_class_id, class_id_derivation_private_function_root, class_id_derivation_public_bytecode_commitment, class_id_derivation_sel, class_id_derivation_temp_constant_for_lookup, ecc_add_op, ecc_double_op, ecc_inv_2_p_y, ecc_inv_x_diff, ecc_inv_y_diff, ecc_lambda, ecc_p_is_inf, ecc_p_x, ecc_p_y, ecc_q_is_inf, ecc_q_x, ecc_q_y, ecc_r_is_inf, ecc_r_x, ecc_r_y, ecc_result_infinity, ecc_sel, ecc_x_match, ecc_y_match, execution_addressing_error_idx, execution_addressing_error_kind, execution_base_address_tag, execution_base_address_val, execution_bytecode_id, execution_clk, execution_ex_opcode, execution_indirect, execution_last, execution_op1, execution_op1_after_relative, execution_op2, execution_op2_after_relative, execution_op3, execution_op3_after_relative, execution_op4, execution_op4_after_relative, execution_pc, execution_rop1, execution_rop2, execution_rop3, execution_rop4, execution_sel, execution_sel_addressing_error, execution_sel_op1_is_address, execution_sel_op2_is_address, execution_sel_op3_is_address, execution_sel_op4_is_address, instr_fetching_bd0, instr_fetching_bd1, instr_fetching_bd10, instr_fetching_bd11, instr_fetching_bd12, instr_fetching_bd13, instr_fetching_bd14, instr_fetching_bd15, instr_fetching_bd16, instr_fetching_bd17, instr_fetching_bd18, instr_fetching_bd19, instr_fetching_bd2, instr_fetching_bd20, instr_fetching_bd21, instr_fetching_bd22, instr_fetching_bd23, instr_fetching_bd24, instr_fetching_bd25, instr_fetching_bd26, instr_fetching_bd27, instr_fetching_bd28, instr_fetching_bd29, instr_fetching_bd3, instr_fetching_bd30, instr_fetching_bd31, instr_fetching_bd32, instr_fetching_bd33, instr_fetching_bd34, instr_fetching_bd35, instr_fetching_bd36, instr_fetching_bd4, instr_fetching_bd5, instr_fetching_bd6, instr_fetching_bd7, instr_fetching_bd8, instr_fetching_bd9, instr_fetching_bytecode_id, instr_fetching_exec_opcode, instr_fetching_indirect, instr_fetching_op1, instr_fetching_op2, instr_fetching_op3, instr_fetching_op4, instr_fetching_op5, instr_fetching_op6, instr_fetching_op7, instr_fetching_pc, instr_fetching_sel, instr_fetching_sel_op_dc_0, instr_fetching_sel_op_dc_1, instr_fetching_sel_op_dc_10, instr_fetching_sel_op_dc_11, instr_fetching_sel_op_dc_12, instr_fetching_sel_op_dc_13, instr_fetching_sel_op_dc_14, instr_fetching_sel_op_dc_15, instr_fetching_sel_op_dc_16, instr_fetching_sel_op_dc_17, instr_fetching_sel_op_dc_2, instr_fetching_sel_op_dc_3, instr_fetching_sel_op_dc_4, instr_fetching_sel_op_dc_5, instr_fetching_sel_op_dc_6, instr_fetching_sel_op_dc_7, instr_fetching_sel_op_dc_8, instr_fetching_sel_op_dc_9, poseidon2_hash_a_0, poseidon2_hash_a_1, poseidon2_hash_a_2, poseidon2_hash_a_3, poseidon2_hash_b_0, poseidon2_hash_b_1, poseidon2_hash_b_2, poseidon2_hash_b_3, poseidon2_hash_end, poseidon2_hash_input_0, poseidon2_hash_input_1, poseidon2_hash_input_2, poseidon2_hash_input_len, poseidon2_hash_num_perm_rounds_rem, poseidon2_hash_num_perm_rounds_rem_inv, poseidon2_hash_output, poseidon2_hash_padding, poseidon2_hash_sel, poseidon2_hash_start, poseidon2_perm_B_10_0, poseidon2_perm_B_10_1, poseidon2_perm_B_10_2, poseidon2_perm_B_10_3, poseidon2_perm_B_11_0, poseidon2_perm_B_11_1, poseidon2_perm_B_11_2, poseidon2_perm_B_11_3, poseidon2_perm_B_12_0, poseidon2_perm_B_12_1, poseidon2_perm_B_12_2, poseidon2_perm_B_12_3, poseidon2_perm_B_13_0, poseidon2_perm_B_13_1, poseidon2_perm_B_13_2, poseidon2_perm_B_13_3, poseidon2_perm_B_14_0, poseidon2_perm_B_14_1, poseidon2_perm_B_14_2, poseidon2_perm_B_14_3, poseidon2_perm_B_15_0, poseidon2_perm_B_15_1, poseidon2_perm_B_15_2, poseidon2_perm_B_15_3, poseidon2_perm_B_16_0, poseidon2_perm_B_16_1, poseidon2_perm_B_16_2, poseidon2_perm_B_16_3, poseidon2_perm_B_17_0, poseidon2_perm_B_17_1, poseidon2_perm_B_17_2, poseidon2_perm_B_17_3, poseidon2_perm_B_18_0, poseidon2_perm_B_18_1, poseidon2_perm_B_18_2, poseidon2_perm_B_18_3, poseidon2_perm_B_19_0, poseidon2_perm_B_19_1, poseidon2_perm_B_19_2, poseidon2_perm_B_19_3, poseidon2_perm_B_20_0, poseidon2_perm_B_20_1, poseidon2_perm_B_20_2, poseidon2_perm_B_20_3, poseidon2_perm_B_21_0, poseidon2_perm_B_21_1, poseidon2_perm_B_21_2, poseidon2_perm_B_21_3, poseidon2_perm_B_22_0, poseidon2_perm_B_22_1, poseidon2_perm_B_22_2, poseidon2_perm_B_22_3, poseidon2_perm_B_23_0, poseidon2_perm_B_23_1, poseidon2_perm_B_23_2, poseidon2_perm_B_23_3, poseidon2_perm_B_24_0, poseidon2_perm_B_24_1, poseidon2_perm_B_24_2, poseidon2_perm_B_24_3, poseidon2_perm_B_25_0, poseidon2_perm_B_25_1, poseidon2_perm_B_25_2, poseidon2_perm_B_25_3, poseidon2_perm_B_26_0, poseidon2_perm_B_26_1, poseidon2_perm_B_26_2, poseidon2_perm_B_26_3, poseidon2_perm_B_27_0, poseidon2_perm_B_27_1, poseidon2_perm_B_27_2, poseidon2_perm_B_27_3, poseidon2_perm_B_28_0, poseidon2_perm_B_28_1, poseidon2_perm_B_28_2, poseidon2_perm_B_28_3, poseidon2_perm_B_29_0, poseidon2_perm_B_29_1, poseidon2_perm_B_29_2, poseidon2_perm_B_29_3, poseidon2_perm_B_30_0, poseidon2_perm_B_30_1, poseidon2_perm_B_30_2, poseidon2_perm_B_30_3, poseidon2_perm_B_31_0, poseidon2_perm_B_31_1, poseidon2_perm_B_31_2, poseidon2_perm_B_31_3, poseidon2_perm_B_32_0, poseidon2_perm_B_32_1, poseidon2_perm_B_32_2, poseidon2_perm_B_32_3, poseidon2_perm_B_33_0, poseidon2_perm_B_33_1, poseidon2_perm_B_33_2, poseidon2_perm_B_33_3, poseidon2_perm_B_34_0, poseidon2_perm_B_34_1, poseidon2_perm_B_34_2, poseidon2_perm_B_34_3, poseidon2_perm_B_35_0, poseidon2_perm_B_35_1, poseidon2_perm_B_35_2, poseidon2_perm_B_35_3, poseidon2_perm_B_36_0, poseidon2_perm_B_36_1, poseidon2_perm_B_36_2, poseidon2_perm_B_36_3, poseidon2_perm_B_37_0, poseidon2_perm_B_37_1, poseidon2_perm_B_37_2, poseidon2_perm_B_37_3, poseidon2_perm_B_38_0, poseidon2_perm_B_38_1, poseidon2_perm_B_38_2, poseidon2_perm_B_38_3, poseidon2_perm_B_39_0, poseidon2_perm_B_39_1, poseidon2_perm_B_39_2, poseidon2_perm_B_39_3, poseidon2_perm_B_40_0, poseidon2_perm_B_40_1, poseidon2_perm_B_40_2, poseidon2_perm_B_40_3, poseidon2_perm_B_41_0, poseidon2_perm_B_41_1, poseidon2_perm_B_41_2, poseidon2_perm_B_41_3, poseidon2_perm_B_42_0, poseidon2_perm_B_42_1, poseidon2_perm_B_42_2, poseidon2_perm_B_42_3, poseidon2_perm_B_43_0, poseidon2_perm_B_43_1, poseidon2_perm_B_43_2, poseidon2_perm_B_43_3, poseidon2_perm_B_44_0, poseidon2_perm_B_44_1, poseidon2_perm_B_44_2, poseidon2_perm_B_44_3, poseidon2_perm_B_45_0, poseidon2_perm_B_45_1, poseidon2_perm_B_45_2, poseidon2_perm_B_45_3, poseidon2_perm_B_46_0, poseidon2_perm_B_46_1, poseidon2_perm_B_46_2, poseidon2_perm_B_46_3, poseidon2_perm_B_47_0, poseidon2_perm_B_47_1, poseidon2_perm_B_47_2, poseidon2_perm_B_47_3, poseidon2_perm_B_48_0, poseidon2_perm_B_48_1, poseidon2_perm_B_48_2, poseidon2_perm_B_48_3, poseidon2_perm_B_49_0, poseidon2_perm_B_49_1, poseidon2_perm_B_49_2, poseidon2_perm_B_49_3, poseidon2_perm_B_4_0, poseidon2_perm_B_4_1, poseidon2_perm_B_4_2, poseidon2_perm_B_4_3, poseidon2_perm_B_50_0, poseidon2_perm_B_50_1, poseidon2_perm_B_50_2, poseidon2_perm_B_50_3, poseidon2_perm_B_51_0, poseidon2_perm_B_51_1, poseidon2_perm_B_51_2, poseidon2_perm_B_51_3, poseidon2_perm_B_52_0, poseidon2_perm_B_52_1, poseidon2_perm_B_52_2, poseidon2_perm_B_52_3, poseidon2_perm_B_53_0, poseidon2_perm_B_53_1, poseidon2_perm_B_53_2, poseidon2_perm_B_53_3, poseidon2_perm_B_54_0, poseidon2_perm_B_54_1, poseidon2_perm_B_54_2, poseidon2_perm_B_54_3, poseidon2_perm_B_55_0, poseidon2_perm_B_55_1, poseidon2_perm_B_55_2, poseidon2_perm_B_55_3, poseidon2_perm_B_56_0, poseidon2_perm_B_56_1, poseidon2_perm_B_56_2, poseidon2_perm_B_56_3, poseidon2_perm_B_57_0, poseidon2_perm_B_57_1, poseidon2_perm_B_57_2, poseidon2_perm_B_57_3, poseidon2_perm_B_58_0, poseidon2_perm_B_58_1, poseidon2_perm_B_58_2, poseidon2_perm_B_58_3, poseidon2_perm_B_59_0, poseidon2_perm_B_59_1, poseidon2_perm_B_59_2, poseidon2_perm_B_59_3, poseidon2_perm_B_5_0, poseidon2_perm_B_5_1, poseidon2_perm_B_5_2, poseidon2_perm_B_5_3, poseidon2_perm_B_6_0, poseidon2_perm_B_6_1, poseidon2_perm_B_6_2, poseidon2_perm_B_6_3, poseidon2_perm_B_7_0, poseidon2_perm_B_7_1, poseidon2_perm_B_7_2, poseidon2_perm_B_7_3, poseidon2_perm_B_8_0, poseidon2_perm_B_8_1, poseidon2_perm_B_8_2, poseidon2_perm_B_8_3, poseidon2_perm_B_9_0, poseidon2_perm_B_9_1, poseidon2_perm_B_9_2, poseidon2_perm_B_9_3, poseidon2_perm_EXT_LAYER_4, poseidon2_perm_EXT_LAYER_5, poseidon2_perm_EXT_LAYER_6, poseidon2_perm_EXT_LAYER_7, poseidon2_perm_T_0_4, poseidon2_perm_T_0_5, poseidon2_perm_T_0_6, poseidon2_perm_T_0_7, poseidon2_perm_T_1_4, poseidon2_perm_T_1_5, poseidon2_perm_T_1_6, poseidon2_perm_T_1_7, poseidon2_perm_T_2_4, poseidon2_perm_T_2_5, poseidon2_perm_T_2_6, poseidon2_perm_T_2_7, poseidon2_perm_T_3_4, poseidon2_perm_T_3_5, poseidon2_perm_T_3_6, poseidon2_perm_T_3_7, poseidon2_perm_T_60_4, poseidon2_perm_T_60_5, poseidon2_perm_T_60_6, poseidon2_perm_T_60_7, poseidon2_perm_T_61_4, poseidon2_perm_T_61_5, poseidon2_perm_T_61_6, poseidon2_perm_T_61_7, poseidon2_perm_T_62_4, poseidon2_perm_T_62_5, poseidon2_perm_T_62_6, poseidon2_perm_T_62_7, poseidon2_perm_T_63_4, poseidon2_perm_T_63_5, poseidon2_perm_T_63_6, poseidon2_perm_T_63_7, poseidon2_perm_a_0, poseidon2_perm_a_1, poseidon2_perm_a_2, poseidon2_perm_a_3, poseidon2_perm_b_0, poseidon2_perm_b_1, poseidon2_perm_b_2, poseidon2_perm_b_3, poseidon2_perm_sel, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_rng_chk_bits, range_check_sel, range_check_sel_r0_16_bit_rng_lookup, range_check_sel_r1_16_bit_rng_lookup, range_check_sel_r2_16_bit_rng_lookup, range_check_sel_r3_16_bit_rng_lookup, range_check_sel_r4_16_bit_rng_lookup, range_check_sel_r5_16_bit_rng_lookup, range_check_sel_r6_16_bit_rng_lookup, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, scalar_mul_bit, scalar_mul_bit_idx, scalar_mul_bit_radix, scalar_mul_end, scalar_mul_not_end, scalar_mul_point_inf, scalar_mul_point_x, scalar_mul_point_y, scalar_mul_res_inf, scalar_mul_res_x, scalar_mul_res_y, scalar_mul_scalar, scalar_mul_sel, scalar_mul_should_add, scalar_mul_start, scalar_mul_temp_inf, scalar_mul_temp_x, scalar_mul_temp_y, sha256_a, sha256_a_and_b, sha256_a_and_b_xor_a_and_c, sha256_a_and_c, sha256_a_rotr_13, sha256_a_rotr_2, sha256_a_rotr_22, sha256_a_rotr_2_xor_a_rotr_13, sha256_and_sel, sha256_b, sha256_b_and_c, sha256_c, sha256_ch, sha256_clk, sha256_computed_w_lhs, sha256_computed_w_rhs, sha256_d, sha256_e, sha256_e_and_f, sha256_e_rotr_11, sha256_e_rotr_25, sha256_e_rotr_6, sha256_e_rotr_6_xor_e_rotr_11, sha256_f, sha256_g, sha256_h, sha256_helper_w0, sha256_helper_w1, sha256_helper_w10, sha256_helper_w11, sha256_helper_w12, sha256_helper_w13, sha256_helper_w14, sha256_helper_w15, sha256_helper_w2, sha256_helper_w3, sha256_helper_w4, sha256_helper_w5, sha256_helper_w6, sha256_helper_w7, sha256_helper_w8, sha256_helper_w9, sha256_init_a, sha256_init_b, sha256_init_c, sha256_init_d, sha256_init_e, sha256_init_f, sha256_init_g, sha256_init_h, sha256_input_offset, sha256_is_input_round, sha256_latch, sha256_lhs_a_13, sha256_lhs_a_2, sha256_lhs_a_22, sha256_lhs_e_11, sha256_lhs_e_25, sha256_lhs_e_6, sha256_lhs_w_10, sha256_lhs_w_17, sha256_lhs_w_18, sha256_lhs_w_19, sha256_lhs_w_3, sha256_lhs_w_7, sha256_maj, sha256_next_a_lhs, sha256_next_a_rhs, sha256_next_e_lhs, sha256_next_e_rhs, sha256_not_e, sha256_not_e_and_g, sha256_output_a_lhs, sha256_output_a_rhs, sha256_output_b_lhs, sha256_output_b_rhs, sha256_output_c_lhs, sha256_output_c_rhs, sha256_output_d_lhs, sha256_output_d_rhs, sha256_output_e_lhs, sha256_output_e_rhs, sha256_output_f_lhs, sha256_output_f_rhs, sha256_output_g_lhs, sha256_output_g_rhs, sha256_output_h_lhs, sha256_output_h_rhs, sha256_output_offset, sha256_perform_round, sha256_rhs_a_13, sha256_rhs_a_2, sha256_rhs_a_22, sha256_rhs_e_11, sha256_rhs_e_25, sha256_rhs_e_6, sha256_rhs_w_10, sha256_rhs_w_17, sha256_rhs_w_18, sha256_rhs_w_19, sha256_rhs_w_3, sha256_rhs_w_7, sha256_round_constant, sha256_round_count, sha256_rounds_remaining, sha256_rounds_remaining_inv, sha256_s_0, sha256_s_1, sha256_sel, sha256_start, sha256_state_offset, sha256_w, sha256_w_15_rotr_18, sha256_w_15_rotr_7, sha256_w_15_rotr_7_xor_w_15_rotr_18, sha256_w_15_rshift_3, sha256_w_2_rotr_17, sha256_w_2_rotr_17_xor_w_2_rotr_19, sha256_w_2_rotr_19, sha256_w_2_rshift_10, sha256_w_s_0, sha256_w_s_1, sha256_xor_sel, lookup_bc_decomposition_bytes_are_bytes_counts, lookup_bc_decomposition_abs_diff_is_u16_counts, lookup_bc_decomposition_bytes_to_read_as_unary_counts, lookup_poseidon2_hash_poseidon2_perm_counts, lookup_bc_hashing_get_packed_field_counts, lookup_bc_hashing_iv_is_len_counts, lookup_bc_hashing_poseidon2_hash_counts, lookup_bc_retrieval_class_id_derivation_counts, lookup_bc_retrieval_bytecode_hash_is_correct_counts, lookup_instr_fetching_bytes_from_bc_dec_counts, lookup_instr_fetching_wire_instruction_info_counts, lookup_class_id_derivation_class_id_poseidon2_0_counts, lookup_class_id_derivation_class_id_poseidon2_1_counts, lookup_range_check_dyn_rng_chk_pow_2_counts, lookup_range_check_dyn_diff_is_u16_counts, lookup_range_check_r0_is_u16_counts, lookup_range_check_r1_is_u16_counts, lookup_range_check_r2_is_u16_counts, lookup_range_check_r3_is_u16_counts, lookup_range_check_r4_is_u16_counts, lookup_range_check_r5_is_u16_counts, lookup_range_check_r6_is_u16_counts, lookup_range_check_r7_is_u16_counts, lookup_bitwise_integral_tag_length_counts, lookup_bitwise_byte_operations_counts, lookup_sha256_round_constant_counts, lookup_scalar_mul_double_counts, lookup_scalar_mul_add_counts +#define AVM2_PRECOMPUTED_ENTITIES precomputed_as_unary, precomputed_bitwise_input_a, precomputed_bitwise_input_b, precomputed_bitwise_op_id, precomputed_bitwise_output, precomputed_clk, precomputed_exec_opcode, precomputed_first_row, precomputed_instr_size_in_bytes, precomputed_integral_tag_length, precomputed_power_of_2, precomputed_sel_bitwise, precomputed_sel_integral_tag, precomputed_sel_op_dc_0, precomputed_sel_op_dc_1, precomputed_sel_op_dc_10, precomputed_sel_op_dc_11, precomputed_sel_op_dc_12, precomputed_sel_op_dc_13, precomputed_sel_op_dc_14, precomputed_sel_op_dc_15, precomputed_sel_op_dc_16, precomputed_sel_op_dc_17, precomputed_sel_op_dc_2, precomputed_sel_op_dc_3, precomputed_sel_op_dc_4, precomputed_sel_op_dc_5, precomputed_sel_op_dc_6, precomputed_sel_op_dc_7, precomputed_sel_op_dc_8, precomputed_sel_op_dc_9, precomputed_sel_range_16, precomputed_sel_range_8, precomputed_sel_range_wire_opcode, precomputed_sel_sha256_compression, precomputed_sel_unary, precomputed_sha256_compression_round_constant, precomputed_zero +#define AVM2_WIRE_ENTITIES execution_input, alu_dst_addr, alu_ia, alu_ia_addr, alu_ib, alu_ib_addr, alu_ic, alu_op, alu_sel_op_add, bc_decomposition_abs_diff, bc_decomposition_bytes, bc_decomposition_bytes_pc_plus_1, bc_decomposition_bytes_pc_plus_10, bc_decomposition_bytes_pc_plus_11, bc_decomposition_bytes_pc_plus_12, bc_decomposition_bytes_pc_plus_13, bc_decomposition_bytes_pc_plus_14, bc_decomposition_bytes_pc_plus_15, bc_decomposition_bytes_pc_plus_16, bc_decomposition_bytes_pc_plus_17, bc_decomposition_bytes_pc_plus_18, bc_decomposition_bytes_pc_plus_19, bc_decomposition_bytes_pc_plus_2, bc_decomposition_bytes_pc_plus_20, bc_decomposition_bytes_pc_plus_21, bc_decomposition_bytes_pc_plus_22, bc_decomposition_bytes_pc_plus_23, bc_decomposition_bytes_pc_plus_24, bc_decomposition_bytes_pc_plus_25, bc_decomposition_bytes_pc_plus_26, bc_decomposition_bytes_pc_plus_27, bc_decomposition_bytes_pc_plus_28, bc_decomposition_bytes_pc_plus_29, bc_decomposition_bytes_pc_plus_3, bc_decomposition_bytes_pc_plus_30, bc_decomposition_bytes_pc_plus_31, bc_decomposition_bytes_pc_plus_32, bc_decomposition_bytes_pc_plus_33, bc_decomposition_bytes_pc_plus_34, bc_decomposition_bytes_pc_plus_35, bc_decomposition_bytes_pc_plus_36, bc_decomposition_bytes_pc_plus_4, bc_decomposition_bytes_pc_plus_5, bc_decomposition_bytes_pc_plus_6, bc_decomposition_bytes_pc_plus_7, bc_decomposition_bytes_pc_plus_8, bc_decomposition_bytes_pc_plus_9, bc_decomposition_bytes_rem_inv, bc_decomposition_bytes_rem_min_one_inv, bc_decomposition_bytes_remaining, bc_decomposition_bytes_to_read, bc_decomposition_bytes_to_read_unary, bc_decomposition_id, bc_decomposition_last_of_contract, bc_decomposition_packed_field, bc_decomposition_pc, bc_decomposition_sel, bc_decomposition_sel_overflow_correction_needed, bc_decomposition_sel_packed, bc_decomposition_sel_pc_plus_1, bc_decomposition_sel_pc_plus_10, bc_decomposition_sel_pc_plus_11, bc_decomposition_sel_pc_plus_12, bc_decomposition_sel_pc_plus_13, bc_decomposition_sel_pc_plus_14, bc_decomposition_sel_pc_plus_15, bc_decomposition_sel_pc_plus_16, bc_decomposition_sel_pc_plus_17, bc_decomposition_sel_pc_plus_18, bc_decomposition_sel_pc_plus_19, bc_decomposition_sel_pc_plus_2, bc_decomposition_sel_pc_plus_20, bc_decomposition_sel_pc_plus_21, bc_decomposition_sel_pc_plus_22, bc_decomposition_sel_pc_plus_23, bc_decomposition_sel_pc_plus_24, bc_decomposition_sel_pc_plus_25, bc_decomposition_sel_pc_plus_26, bc_decomposition_sel_pc_plus_27, bc_decomposition_sel_pc_plus_28, bc_decomposition_sel_pc_plus_29, bc_decomposition_sel_pc_plus_3, bc_decomposition_sel_pc_plus_30, bc_decomposition_sel_pc_plus_31, bc_decomposition_sel_pc_plus_32, bc_decomposition_sel_pc_plus_33, bc_decomposition_sel_pc_plus_34, bc_decomposition_sel_pc_plus_35, bc_decomposition_sel_pc_plus_36, bc_decomposition_sel_pc_plus_4, bc_decomposition_sel_pc_plus_5, bc_decomposition_sel_pc_plus_6, bc_decomposition_sel_pc_plus_7, bc_decomposition_sel_pc_plus_8, bc_decomposition_sel_pc_plus_9, bc_hashing_bytecode_id, bc_hashing_incremental_hash, bc_hashing_latch, bc_hashing_output_hash, bc_hashing_packed_field, bc_hashing_pc_index, bc_hashing_sel, bc_hashing_start, bc_retrieval_address, bc_retrieval_artifact_hash, bc_retrieval_bytecode_id, bc_retrieval_class_id, bc_retrieval_deployer_addr, bc_retrieval_err, bc_retrieval_incoming_viewing_key_x, bc_retrieval_incoming_viewing_key_y, bc_retrieval_init_hash, bc_retrieval_nullifier_key_x, bc_retrieval_nullifier_key_y, bc_retrieval_outgoing_viewing_key_x, bc_retrieval_outgoing_viewing_key_y, bc_retrieval_private_function_root, bc_retrieval_public_bytecode_commitment, bc_retrieval_salt, bc_retrieval_sel, bc_retrieval_siloed_address, bc_retrieval_tagging_key_x, bc_retrieval_tagging_key_y, bitwise_acc_ia, bitwise_acc_ib, bitwise_acc_ic, bitwise_ctr, bitwise_ctr_inv, bitwise_ctr_min_one_inv, bitwise_ia_byte, bitwise_ib_byte, bitwise_ic_byte, bitwise_last, bitwise_op_id, bitwise_sel, bitwise_start, bitwise_tag, class_id_derivation_artifact_hash, class_id_derivation_class_id, class_id_derivation_private_function_root, class_id_derivation_public_bytecode_commitment, class_id_derivation_sel, class_id_derivation_temp_constant_for_lookup, ecc_add_op, ecc_double_op, ecc_inv_2_p_y, ecc_inv_x_diff, ecc_inv_y_diff, ecc_lambda, ecc_p_is_inf, ecc_p_x, ecc_p_y, ecc_q_is_inf, ecc_q_x, ecc_q_y, ecc_r_is_inf, ecc_r_x, ecc_r_y, ecc_result_infinity, ecc_sel, ecc_x_match, ecc_y_match, execution_addressing_error_idx, execution_addressing_error_kind, execution_base_address_tag, execution_base_address_val, execution_bytecode_id, execution_clk, execution_ex_opcode, execution_indirect, execution_last, execution_op1, execution_op1_after_relative, execution_op2, execution_op2_after_relative, execution_op3, execution_op3_after_relative, execution_op4, execution_op4_after_relative, execution_pc, execution_rop1, execution_rop2, execution_rop3, execution_rop4, execution_sel, execution_sel_addressing_error, execution_sel_op1_is_address, execution_sel_op2_is_address, execution_sel_op3_is_address, execution_sel_op4_is_address, instr_fetching_bd0, instr_fetching_bd1, instr_fetching_bd10, instr_fetching_bd11, instr_fetching_bd12, instr_fetching_bd13, instr_fetching_bd14, instr_fetching_bd15, instr_fetching_bd16, instr_fetching_bd17, instr_fetching_bd18, instr_fetching_bd19, instr_fetching_bd2, instr_fetching_bd20, instr_fetching_bd21, instr_fetching_bd22, instr_fetching_bd23, instr_fetching_bd24, instr_fetching_bd25, instr_fetching_bd26, instr_fetching_bd27, instr_fetching_bd28, instr_fetching_bd29, instr_fetching_bd3, instr_fetching_bd30, instr_fetching_bd31, instr_fetching_bd32, instr_fetching_bd33, instr_fetching_bd34, instr_fetching_bd35, instr_fetching_bd36, instr_fetching_bd4, instr_fetching_bd5, instr_fetching_bd6, instr_fetching_bd7, instr_fetching_bd8, instr_fetching_bd9, instr_fetching_bytecode_id, instr_fetching_exec_opcode, instr_fetching_indirect, instr_fetching_instr_size_in_bytes, instr_fetching_op1, instr_fetching_op2, instr_fetching_op3, instr_fetching_op4, instr_fetching_op5, instr_fetching_op6, instr_fetching_op7, instr_fetching_pc, instr_fetching_sel, instr_fetching_sel_op_dc_0, instr_fetching_sel_op_dc_1, instr_fetching_sel_op_dc_10, instr_fetching_sel_op_dc_11, instr_fetching_sel_op_dc_12, instr_fetching_sel_op_dc_13, instr_fetching_sel_op_dc_14, instr_fetching_sel_op_dc_15, instr_fetching_sel_op_dc_16, instr_fetching_sel_op_dc_17, instr_fetching_sel_op_dc_2, instr_fetching_sel_op_dc_3, instr_fetching_sel_op_dc_4, instr_fetching_sel_op_dc_5, instr_fetching_sel_op_dc_6, instr_fetching_sel_op_dc_7, instr_fetching_sel_op_dc_8, instr_fetching_sel_op_dc_9, poseidon2_hash_a_0, poseidon2_hash_a_1, poseidon2_hash_a_2, poseidon2_hash_a_3, poseidon2_hash_b_0, poseidon2_hash_b_1, poseidon2_hash_b_2, poseidon2_hash_b_3, poseidon2_hash_end, poseidon2_hash_input_0, poseidon2_hash_input_1, poseidon2_hash_input_2, poseidon2_hash_input_len, poseidon2_hash_num_perm_rounds_rem, poseidon2_hash_num_perm_rounds_rem_inv, poseidon2_hash_output, poseidon2_hash_padding, poseidon2_hash_sel, poseidon2_hash_start, poseidon2_perm_B_10_0, poseidon2_perm_B_10_1, poseidon2_perm_B_10_2, poseidon2_perm_B_10_3, poseidon2_perm_B_11_0, poseidon2_perm_B_11_1, poseidon2_perm_B_11_2, poseidon2_perm_B_11_3, poseidon2_perm_B_12_0, poseidon2_perm_B_12_1, poseidon2_perm_B_12_2, poseidon2_perm_B_12_3, poseidon2_perm_B_13_0, poseidon2_perm_B_13_1, poseidon2_perm_B_13_2, poseidon2_perm_B_13_3, poseidon2_perm_B_14_0, poseidon2_perm_B_14_1, poseidon2_perm_B_14_2, poseidon2_perm_B_14_3, poseidon2_perm_B_15_0, poseidon2_perm_B_15_1, poseidon2_perm_B_15_2, poseidon2_perm_B_15_3, poseidon2_perm_B_16_0, poseidon2_perm_B_16_1, poseidon2_perm_B_16_2, poseidon2_perm_B_16_3, poseidon2_perm_B_17_0, poseidon2_perm_B_17_1, poseidon2_perm_B_17_2, poseidon2_perm_B_17_3, poseidon2_perm_B_18_0, poseidon2_perm_B_18_1, poseidon2_perm_B_18_2, poseidon2_perm_B_18_3, poseidon2_perm_B_19_0, poseidon2_perm_B_19_1, poseidon2_perm_B_19_2, poseidon2_perm_B_19_3, poseidon2_perm_B_20_0, poseidon2_perm_B_20_1, poseidon2_perm_B_20_2, poseidon2_perm_B_20_3, poseidon2_perm_B_21_0, poseidon2_perm_B_21_1, poseidon2_perm_B_21_2, poseidon2_perm_B_21_3, poseidon2_perm_B_22_0, poseidon2_perm_B_22_1, poseidon2_perm_B_22_2, poseidon2_perm_B_22_3, poseidon2_perm_B_23_0, poseidon2_perm_B_23_1, poseidon2_perm_B_23_2, poseidon2_perm_B_23_3, poseidon2_perm_B_24_0, poseidon2_perm_B_24_1, poseidon2_perm_B_24_2, poseidon2_perm_B_24_3, poseidon2_perm_B_25_0, poseidon2_perm_B_25_1, poseidon2_perm_B_25_2, poseidon2_perm_B_25_3, poseidon2_perm_B_26_0, poseidon2_perm_B_26_1, poseidon2_perm_B_26_2, poseidon2_perm_B_26_3, poseidon2_perm_B_27_0, poseidon2_perm_B_27_1, poseidon2_perm_B_27_2, poseidon2_perm_B_27_3, poseidon2_perm_B_28_0, poseidon2_perm_B_28_1, poseidon2_perm_B_28_2, poseidon2_perm_B_28_3, poseidon2_perm_B_29_0, poseidon2_perm_B_29_1, poseidon2_perm_B_29_2, poseidon2_perm_B_29_3, poseidon2_perm_B_30_0, poseidon2_perm_B_30_1, poseidon2_perm_B_30_2, poseidon2_perm_B_30_3, poseidon2_perm_B_31_0, poseidon2_perm_B_31_1, poseidon2_perm_B_31_2, poseidon2_perm_B_31_3, poseidon2_perm_B_32_0, poseidon2_perm_B_32_1, poseidon2_perm_B_32_2, poseidon2_perm_B_32_3, poseidon2_perm_B_33_0, poseidon2_perm_B_33_1, poseidon2_perm_B_33_2, poseidon2_perm_B_33_3, poseidon2_perm_B_34_0, poseidon2_perm_B_34_1, poseidon2_perm_B_34_2, poseidon2_perm_B_34_3, poseidon2_perm_B_35_0, poseidon2_perm_B_35_1, poseidon2_perm_B_35_2, poseidon2_perm_B_35_3, poseidon2_perm_B_36_0, poseidon2_perm_B_36_1, poseidon2_perm_B_36_2, poseidon2_perm_B_36_3, poseidon2_perm_B_37_0, poseidon2_perm_B_37_1, poseidon2_perm_B_37_2, poseidon2_perm_B_37_3, poseidon2_perm_B_38_0, poseidon2_perm_B_38_1, poseidon2_perm_B_38_2, poseidon2_perm_B_38_3, poseidon2_perm_B_39_0, poseidon2_perm_B_39_1, poseidon2_perm_B_39_2, poseidon2_perm_B_39_3, poseidon2_perm_B_40_0, poseidon2_perm_B_40_1, poseidon2_perm_B_40_2, poseidon2_perm_B_40_3, poseidon2_perm_B_41_0, poseidon2_perm_B_41_1, poseidon2_perm_B_41_2, poseidon2_perm_B_41_3, poseidon2_perm_B_42_0, poseidon2_perm_B_42_1, poseidon2_perm_B_42_2, poseidon2_perm_B_42_3, poseidon2_perm_B_43_0, poseidon2_perm_B_43_1, poseidon2_perm_B_43_2, poseidon2_perm_B_43_3, poseidon2_perm_B_44_0, poseidon2_perm_B_44_1, poseidon2_perm_B_44_2, poseidon2_perm_B_44_3, poseidon2_perm_B_45_0, poseidon2_perm_B_45_1, poseidon2_perm_B_45_2, poseidon2_perm_B_45_3, poseidon2_perm_B_46_0, poseidon2_perm_B_46_1, poseidon2_perm_B_46_2, poseidon2_perm_B_46_3, poseidon2_perm_B_47_0, poseidon2_perm_B_47_1, poseidon2_perm_B_47_2, poseidon2_perm_B_47_3, poseidon2_perm_B_48_0, poseidon2_perm_B_48_1, poseidon2_perm_B_48_2, poseidon2_perm_B_48_3, poseidon2_perm_B_49_0, poseidon2_perm_B_49_1, poseidon2_perm_B_49_2, poseidon2_perm_B_49_3, poseidon2_perm_B_4_0, poseidon2_perm_B_4_1, poseidon2_perm_B_4_2, poseidon2_perm_B_4_3, poseidon2_perm_B_50_0, poseidon2_perm_B_50_1, poseidon2_perm_B_50_2, poseidon2_perm_B_50_3, poseidon2_perm_B_51_0, poseidon2_perm_B_51_1, poseidon2_perm_B_51_2, poseidon2_perm_B_51_3, poseidon2_perm_B_52_0, poseidon2_perm_B_52_1, poseidon2_perm_B_52_2, poseidon2_perm_B_52_3, poseidon2_perm_B_53_0, poseidon2_perm_B_53_1, poseidon2_perm_B_53_2, poseidon2_perm_B_53_3, poseidon2_perm_B_54_0, poseidon2_perm_B_54_1, poseidon2_perm_B_54_2, poseidon2_perm_B_54_3, poseidon2_perm_B_55_0, poseidon2_perm_B_55_1, poseidon2_perm_B_55_2, poseidon2_perm_B_55_3, poseidon2_perm_B_56_0, poseidon2_perm_B_56_1, poseidon2_perm_B_56_2, poseidon2_perm_B_56_3, poseidon2_perm_B_57_0, poseidon2_perm_B_57_1, poseidon2_perm_B_57_2, poseidon2_perm_B_57_3, poseidon2_perm_B_58_0, poseidon2_perm_B_58_1, poseidon2_perm_B_58_2, poseidon2_perm_B_58_3, poseidon2_perm_B_59_0, poseidon2_perm_B_59_1, poseidon2_perm_B_59_2, poseidon2_perm_B_59_3, poseidon2_perm_B_5_0, poseidon2_perm_B_5_1, poseidon2_perm_B_5_2, poseidon2_perm_B_5_3, poseidon2_perm_B_6_0, poseidon2_perm_B_6_1, poseidon2_perm_B_6_2, poseidon2_perm_B_6_3, poseidon2_perm_B_7_0, poseidon2_perm_B_7_1, poseidon2_perm_B_7_2, poseidon2_perm_B_7_3, poseidon2_perm_B_8_0, poseidon2_perm_B_8_1, poseidon2_perm_B_8_2, poseidon2_perm_B_8_3, poseidon2_perm_B_9_0, poseidon2_perm_B_9_1, poseidon2_perm_B_9_2, poseidon2_perm_B_9_3, poseidon2_perm_EXT_LAYER_4, poseidon2_perm_EXT_LAYER_5, poseidon2_perm_EXT_LAYER_6, poseidon2_perm_EXT_LAYER_7, poseidon2_perm_T_0_4, poseidon2_perm_T_0_5, poseidon2_perm_T_0_6, poseidon2_perm_T_0_7, poseidon2_perm_T_1_4, poseidon2_perm_T_1_5, poseidon2_perm_T_1_6, poseidon2_perm_T_1_7, poseidon2_perm_T_2_4, poseidon2_perm_T_2_5, poseidon2_perm_T_2_6, poseidon2_perm_T_2_7, poseidon2_perm_T_3_4, poseidon2_perm_T_3_5, poseidon2_perm_T_3_6, poseidon2_perm_T_3_7, poseidon2_perm_T_60_4, poseidon2_perm_T_60_5, poseidon2_perm_T_60_6, poseidon2_perm_T_60_7, poseidon2_perm_T_61_4, poseidon2_perm_T_61_5, poseidon2_perm_T_61_6, poseidon2_perm_T_61_7, poseidon2_perm_T_62_4, poseidon2_perm_T_62_5, poseidon2_perm_T_62_6, poseidon2_perm_T_62_7, poseidon2_perm_T_63_4, poseidon2_perm_T_63_5, poseidon2_perm_T_63_6, poseidon2_perm_T_63_7, poseidon2_perm_a_0, poseidon2_perm_a_1, poseidon2_perm_a_2, poseidon2_perm_a_3, poseidon2_perm_b_0, poseidon2_perm_b_1, poseidon2_perm_b_2, poseidon2_perm_b_3, poseidon2_perm_sel, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_rng_chk_bits, range_check_sel, range_check_sel_r0_16_bit_rng_lookup, range_check_sel_r1_16_bit_rng_lookup, range_check_sel_r2_16_bit_rng_lookup, range_check_sel_r3_16_bit_rng_lookup, range_check_sel_r4_16_bit_rng_lookup, range_check_sel_r5_16_bit_rng_lookup, range_check_sel_r6_16_bit_rng_lookup, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, scalar_mul_bit, scalar_mul_bit_idx, scalar_mul_bit_radix, scalar_mul_end, scalar_mul_not_end, scalar_mul_point_inf, scalar_mul_point_x, scalar_mul_point_y, scalar_mul_res_inf, scalar_mul_res_x, scalar_mul_res_y, scalar_mul_scalar, scalar_mul_sel, scalar_mul_should_add, scalar_mul_start, scalar_mul_temp_inf, scalar_mul_temp_x, scalar_mul_temp_y, sha256_a, sha256_a_and_b, sha256_a_and_b_xor_a_and_c, sha256_a_and_c, sha256_a_rotr_13, sha256_a_rotr_2, sha256_a_rotr_22, sha256_a_rotr_2_xor_a_rotr_13, sha256_and_sel, sha256_b, sha256_b_and_c, sha256_c, sha256_ch, sha256_clk, sha256_computed_w_lhs, sha256_computed_w_rhs, sha256_d, sha256_e, sha256_e_and_f, sha256_e_rotr_11, sha256_e_rotr_25, sha256_e_rotr_6, sha256_e_rotr_6_xor_e_rotr_11, sha256_f, sha256_g, sha256_h, sha256_helper_w0, sha256_helper_w1, sha256_helper_w10, sha256_helper_w11, sha256_helper_w12, sha256_helper_w13, sha256_helper_w14, sha256_helper_w15, sha256_helper_w2, sha256_helper_w3, sha256_helper_w4, sha256_helper_w5, sha256_helper_w6, sha256_helper_w7, sha256_helper_w8, sha256_helper_w9, sha256_init_a, sha256_init_b, sha256_init_c, sha256_init_d, sha256_init_e, sha256_init_f, sha256_init_g, sha256_init_h, sha256_input_offset, sha256_is_input_round, sha256_latch, sha256_lhs_a_13, sha256_lhs_a_2, sha256_lhs_a_22, sha256_lhs_e_11, sha256_lhs_e_25, sha256_lhs_e_6, sha256_lhs_w_10, sha256_lhs_w_17, sha256_lhs_w_18, sha256_lhs_w_19, sha256_lhs_w_3, sha256_lhs_w_7, sha256_maj, sha256_next_a_lhs, sha256_next_a_rhs, sha256_next_e_lhs, sha256_next_e_rhs, sha256_not_e, sha256_not_e_and_g, sha256_output_a_lhs, sha256_output_a_rhs, sha256_output_b_lhs, sha256_output_b_rhs, sha256_output_c_lhs, sha256_output_c_rhs, sha256_output_d_lhs, sha256_output_d_rhs, sha256_output_e_lhs, sha256_output_e_rhs, sha256_output_f_lhs, sha256_output_f_rhs, sha256_output_g_lhs, sha256_output_g_rhs, sha256_output_h_lhs, sha256_output_h_rhs, sha256_output_offset, sha256_perform_round, sha256_rhs_a_13, sha256_rhs_a_2, sha256_rhs_a_22, sha256_rhs_e_11, sha256_rhs_e_25, sha256_rhs_e_6, sha256_rhs_w_10, sha256_rhs_w_17, sha256_rhs_w_18, sha256_rhs_w_19, sha256_rhs_w_3, sha256_rhs_w_7, sha256_round_constant, sha256_round_count, sha256_rounds_remaining, sha256_rounds_remaining_inv, sha256_s_0, sha256_s_1, sha256_sel, sha256_start, sha256_state_offset, sha256_w, sha256_w_15_rotr_18, sha256_w_15_rotr_7, sha256_w_15_rotr_7_xor_w_15_rotr_18, sha256_w_15_rshift_3, sha256_w_2_rotr_17, sha256_w_2_rotr_17_xor_w_2_rotr_19, sha256_w_2_rotr_19, sha256_w_2_rshift_10, sha256_w_s_0, sha256_w_s_1, sha256_xor_sel, lookup_bc_decomposition_bytes_are_bytes_counts, lookup_bc_decomposition_abs_diff_is_u16_counts, lookup_bc_decomposition_bytes_to_read_as_unary_counts, lookup_poseidon2_hash_poseidon2_perm_counts, lookup_bc_hashing_get_packed_field_counts, lookup_bc_hashing_iv_is_len_counts, lookup_bc_hashing_poseidon2_hash_counts, lookup_bc_retrieval_class_id_derivation_counts, lookup_bc_retrieval_bytecode_hash_is_correct_counts, lookup_instr_fetching_bytes_from_bc_dec_counts, lookup_instr_fetching_wire_instruction_info_counts, lookup_class_id_derivation_class_id_poseidon2_0_counts, lookup_class_id_derivation_class_id_poseidon2_1_counts, lookup_range_check_dyn_rng_chk_pow_2_counts, lookup_range_check_dyn_diff_is_u16_counts, lookup_range_check_r0_is_u16_counts, lookup_range_check_r1_is_u16_counts, lookup_range_check_r2_is_u16_counts, lookup_range_check_r3_is_u16_counts, lookup_range_check_r4_is_u16_counts, lookup_range_check_r5_is_u16_counts, lookup_range_check_r6_is_u16_counts, lookup_range_check_r7_is_u16_counts, lookup_bitwise_integral_tag_length_counts, lookup_bitwise_byte_operations_counts, lookup_sha256_round_constant_counts, lookup_scalar_mul_double_counts, lookup_scalar_mul_add_counts #define AVM2_DERIVED_WITNESS_ENTITIES lookup_bc_decomposition_bytes_are_bytes_inv, lookup_bc_decomposition_abs_diff_is_u16_inv, lookup_bc_decomposition_bytes_to_read_as_unary_inv, lookup_poseidon2_hash_poseidon2_perm_inv, lookup_bc_hashing_get_packed_field_inv, lookup_bc_hashing_iv_is_len_inv, lookup_bc_hashing_poseidon2_hash_inv, lookup_bc_retrieval_class_id_derivation_inv, lookup_bc_retrieval_bytecode_hash_is_correct_inv, lookup_instr_fetching_bytes_from_bc_dec_inv, lookup_instr_fetching_wire_instruction_info_inv, lookup_class_id_derivation_class_id_poseidon2_0_inv, lookup_class_id_derivation_class_id_poseidon2_1_inv, lookup_range_check_dyn_rng_chk_pow_2_inv, lookup_range_check_dyn_diff_is_u16_inv, lookup_range_check_r0_is_u16_inv, lookup_range_check_r1_is_u16_inv, lookup_range_check_r2_is_u16_inv, lookup_range_check_r3_is_u16_inv, lookup_range_check_r4_is_u16_inv, lookup_range_check_r5_is_u16_inv, lookup_range_check_r6_is_u16_inv, lookup_range_check_r7_is_u16_inv, lookup_bitwise_integral_tag_length_inv, lookup_bitwise_byte_operations_inv, lookup_sha256_round_constant_inv, lookup_scalar_mul_double_inv, lookup_scalar_mul_add_inv #define AVM2_SHIFTED_ENTITIES bc_decomposition_bytes_shift, bc_decomposition_bytes_pc_plus_1_shift, bc_decomposition_bytes_pc_plus_10_shift, bc_decomposition_bytes_pc_plus_11_shift, bc_decomposition_bytes_pc_plus_12_shift, bc_decomposition_bytes_pc_plus_13_shift, bc_decomposition_bytes_pc_plus_14_shift, bc_decomposition_bytes_pc_plus_15_shift, bc_decomposition_bytes_pc_plus_16_shift, bc_decomposition_bytes_pc_plus_17_shift, bc_decomposition_bytes_pc_plus_18_shift, bc_decomposition_bytes_pc_plus_19_shift, bc_decomposition_bytes_pc_plus_2_shift, bc_decomposition_bytes_pc_plus_20_shift, bc_decomposition_bytes_pc_plus_21_shift, bc_decomposition_bytes_pc_plus_22_shift, bc_decomposition_bytes_pc_plus_23_shift, bc_decomposition_bytes_pc_plus_24_shift, bc_decomposition_bytes_pc_plus_25_shift, bc_decomposition_bytes_pc_plus_26_shift, bc_decomposition_bytes_pc_plus_27_shift, bc_decomposition_bytes_pc_plus_28_shift, bc_decomposition_bytes_pc_plus_29_shift, bc_decomposition_bytes_pc_plus_3_shift, bc_decomposition_bytes_pc_plus_30_shift, bc_decomposition_bytes_pc_plus_31_shift, bc_decomposition_bytes_pc_plus_32_shift, bc_decomposition_bytes_pc_plus_33_shift, bc_decomposition_bytes_pc_plus_34_shift, bc_decomposition_bytes_pc_plus_35_shift, bc_decomposition_bytes_pc_plus_4_shift, bc_decomposition_bytes_pc_plus_5_shift, bc_decomposition_bytes_pc_plus_6_shift, bc_decomposition_bytes_pc_plus_7_shift, bc_decomposition_bytes_pc_plus_8_shift, bc_decomposition_bytes_pc_plus_9_shift, bc_decomposition_bytes_remaining_shift, bc_decomposition_id_shift, bc_decomposition_pc_shift, bc_decomposition_sel_shift, bc_hashing_bytecode_id_shift, bc_hashing_incremental_hash_shift, bc_hashing_pc_index_shift, bc_hashing_sel_shift, bc_hashing_start_shift, bitwise_acc_ia_shift, bitwise_acc_ib_shift, bitwise_acc_ic_shift, bitwise_ctr_shift, bitwise_op_id_shift, execution_sel_shift, poseidon2_hash_a_0_shift, poseidon2_hash_a_1_shift, poseidon2_hash_a_2_shift, poseidon2_hash_a_3_shift, poseidon2_hash_input_0_shift, poseidon2_hash_input_1_shift, poseidon2_hash_input_2_shift, poseidon2_hash_num_perm_rounds_rem_shift, poseidon2_hash_output_shift, poseidon2_hash_sel_shift, poseidon2_hash_start_shift, scalar_mul_bit_idx_shift, scalar_mul_point_inf_shift, scalar_mul_point_x_shift, scalar_mul_point_y_shift, scalar_mul_res_inf_shift, scalar_mul_res_x_shift, scalar_mul_res_y_shift, scalar_mul_scalar_shift, scalar_mul_sel_shift, scalar_mul_start_shift, scalar_mul_temp_inf_shift, scalar_mul_temp_x_shift, scalar_mul_temp_y_shift, sha256_a_shift, sha256_b_shift, sha256_c_shift, sha256_d_shift, sha256_e_shift, sha256_f_shift, sha256_g_shift, sha256_h_shift, sha256_helper_w0_shift, sha256_helper_w1_shift, sha256_helper_w10_shift, sha256_helper_w11_shift, sha256_helper_w12_shift, sha256_helper_w13_shift, sha256_helper_w14_shift, sha256_helper_w15_shift, sha256_helper_w2_shift, sha256_helper_w3_shift, sha256_helper_w4_shift, sha256_helper_w5_shift, sha256_helper_w6_shift, sha256_helper_w7_shift, sha256_helper_w8_shift, sha256_helper_w9_shift, sha256_rounds_remaining_shift, sha256_sel_shift, sha256_start_shift #define AVM2_TO_BE_SHIFTED(e) e.bc_decomposition_bytes, e.bc_decomposition_bytes_pc_plus_1, e.bc_decomposition_bytes_pc_plus_10, e.bc_decomposition_bytes_pc_plus_11, e.bc_decomposition_bytes_pc_plus_12, e.bc_decomposition_bytes_pc_plus_13, e.bc_decomposition_bytes_pc_plus_14, e.bc_decomposition_bytes_pc_plus_15, e.bc_decomposition_bytes_pc_plus_16, e.bc_decomposition_bytes_pc_plus_17, e.bc_decomposition_bytes_pc_plus_18, e.bc_decomposition_bytes_pc_plus_19, e.bc_decomposition_bytes_pc_plus_2, e.bc_decomposition_bytes_pc_plus_20, e.bc_decomposition_bytes_pc_plus_21, e.bc_decomposition_bytes_pc_plus_22, e.bc_decomposition_bytes_pc_plus_23, e.bc_decomposition_bytes_pc_plus_24, e.bc_decomposition_bytes_pc_plus_25, e.bc_decomposition_bytes_pc_plus_26, e.bc_decomposition_bytes_pc_plus_27, e.bc_decomposition_bytes_pc_plus_28, e.bc_decomposition_bytes_pc_plus_29, e.bc_decomposition_bytes_pc_plus_3, e.bc_decomposition_bytes_pc_plus_30, e.bc_decomposition_bytes_pc_plus_31, e.bc_decomposition_bytes_pc_plus_32, e.bc_decomposition_bytes_pc_plus_33, e.bc_decomposition_bytes_pc_plus_34, e.bc_decomposition_bytes_pc_plus_35, e.bc_decomposition_bytes_pc_plus_4, e.bc_decomposition_bytes_pc_plus_5, e.bc_decomposition_bytes_pc_plus_6, e.bc_decomposition_bytes_pc_plus_7, e.bc_decomposition_bytes_pc_plus_8, e.bc_decomposition_bytes_pc_plus_9, e.bc_decomposition_bytes_remaining, e.bc_decomposition_id, e.bc_decomposition_pc, e.bc_decomposition_sel, e.bc_hashing_bytecode_id, e.bc_hashing_incremental_hash, e.bc_hashing_pc_index, e.bc_hashing_sel, e.bc_hashing_start, e.bitwise_acc_ia, e.bitwise_acc_ib, e.bitwise_acc_ic, e.bitwise_ctr, e.bitwise_op_id, e.execution_sel, e.poseidon2_hash_a_0, e.poseidon2_hash_a_1, e.poseidon2_hash_a_2, e.poseidon2_hash_a_3, e.poseidon2_hash_input_0, e.poseidon2_hash_input_1, e.poseidon2_hash_input_2, e.poseidon2_hash_num_perm_rounds_rem, e.poseidon2_hash_output, e.poseidon2_hash_sel, e.poseidon2_hash_start, e.scalar_mul_bit_idx, e.scalar_mul_point_inf, e.scalar_mul_point_x, e.scalar_mul_point_y, e.scalar_mul_res_inf, e.scalar_mul_res_x, e.scalar_mul_res_y, e.scalar_mul_scalar, e.scalar_mul_sel, e.scalar_mul_start, e.scalar_mul_temp_inf, e.scalar_mul_temp_x, e.scalar_mul_temp_y, e.sha256_a, e.sha256_b, e.sha256_c, e.sha256_d, e.sha256_e, e.sha256_f, e.sha256_g, e.sha256_h, e.sha256_helper_w0, e.sha256_helper_w1, e.sha256_helper_w10, e.sha256_helper_w11, e.sha256_helper_w12, e.sha256_helper_w13, e.sha256_helper_w14, e.sha256_helper_w15, e.sha256_helper_w2, e.sha256_helper_w3, e.sha256_helper_w4, e.sha256_helper_w5, e.sha256_helper_w6, e.sha256_helper_w7, e.sha256_helper_w8, e.sha256_helper_w9, e.sha256_rounds_remaining, e.sha256_sel, e.sha256_start @@ -31,8 +31,8 @@ enum class ColumnAndShifts { SENTINEL_DO_NOT_USE, }; -constexpr auto NUM_COLUMNS_WITH_SHIFTS = 910; -constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 808; +constexpr auto NUM_COLUMNS_WITH_SHIFTS = 912; +constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 810; constexpr auto TO_BE_SHIFTED_COLUMNS_ARRAY = []() { return std::array{ AVM2_TO_BE_SHIFTED_COLUMNS }; }(); constexpr auto SHIFTED_COLUMNS_ARRAY = []() { return std::array{ AVM2_SHIFTED_COLUMNS }; }(); static_assert(TO_BE_SHIFTED_COLUMNS_ARRAY.size() == SHIFTED_COLUMNS_ARRAY.size()); diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp index 5984d644609c..c3dc8eb1ec9c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp @@ -85,13 +85,13 @@ class AvmFlavor { // This flavor would not be used with ZK Sumcheck static constexpr bool HasZK = false; - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 37; - static constexpr size_t NUM_WITNESS_ENTITIES = 771; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 38; + static constexpr size_t NUM_WITNESS_ENTITIES = 772; static constexpr size_t NUM_SHIFTED_ENTITIES = 102; 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 = 910; + static constexpr size_t NUM_ALL_ENTITIES = 912; // Need to be templated for recursive verifier template @@ -401,6 +401,7 @@ class AvmFlavor { this->precomputed_clk = verification_key->precomputed_clk; this->precomputed_exec_opcode = verification_key->precomputed_exec_opcode; this->precomputed_first_row = verification_key->precomputed_first_row; + this->precomputed_instr_size_in_bytes = verification_key->precomputed_instr_size_in_bytes; this->precomputed_integral_tag_length = verification_key->precomputed_integral_tag_length; this->precomputed_power_of_2 = verification_key->precomputed_power_of_2; this->precomputed_sel_bitwise = verification_key->precomputed_sel_bitwise; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/instr_fetching.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/instr_fetching.hpp index 3145c75d6759..c43da9b15267 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/instr_fetching.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/instr_fetching.hpp @@ -187,9 +187,36 @@ template class instr_fetching : public Relation SRC_COLUMNS = { - ColumnAndShifts::instr_fetching_bd0, ColumnAndShifts::instr_fetching_exec_opcode, - ColumnAndShifts::instr_fetching_sel_op_dc_0, ColumnAndShifts::instr_fetching_sel_op_dc_1, - ColumnAndShifts::instr_fetching_sel_op_dc_2, ColumnAndShifts::instr_fetching_sel_op_dc_3, - ColumnAndShifts::instr_fetching_sel_op_dc_4, ColumnAndShifts::instr_fetching_sel_op_dc_5, - ColumnAndShifts::instr_fetching_sel_op_dc_6, ColumnAndShifts::instr_fetching_sel_op_dc_7, - ColumnAndShifts::instr_fetching_sel_op_dc_8, ColumnAndShifts::instr_fetching_sel_op_dc_9, - ColumnAndShifts::instr_fetching_sel_op_dc_10, ColumnAndShifts::instr_fetching_sel_op_dc_11, - ColumnAndShifts::instr_fetching_sel_op_dc_12, ColumnAndShifts::instr_fetching_sel_op_dc_13, - ColumnAndShifts::instr_fetching_sel_op_dc_14, ColumnAndShifts::instr_fetching_sel_op_dc_15, - ColumnAndShifts::instr_fetching_sel_op_dc_16, ColumnAndShifts::instr_fetching_sel_op_dc_17 + ColumnAndShifts::instr_fetching_bd0, + ColumnAndShifts::instr_fetching_exec_opcode, + ColumnAndShifts::instr_fetching_instr_size_in_bytes, + ColumnAndShifts::instr_fetching_sel_op_dc_0, + ColumnAndShifts::instr_fetching_sel_op_dc_1, + ColumnAndShifts::instr_fetching_sel_op_dc_2, + ColumnAndShifts::instr_fetching_sel_op_dc_3, + ColumnAndShifts::instr_fetching_sel_op_dc_4, + ColumnAndShifts::instr_fetching_sel_op_dc_5, + ColumnAndShifts::instr_fetching_sel_op_dc_6, + ColumnAndShifts::instr_fetching_sel_op_dc_7, + ColumnAndShifts::instr_fetching_sel_op_dc_8, + ColumnAndShifts::instr_fetching_sel_op_dc_9, + ColumnAndShifts::instr_fetching_sel_op_dc_10, + ColumnAndShifts::instr_fetching_sel_op_dc_11, + ColumnAndShifts::instr_fetching_sel_op_dc_12, + ColumnAndShifts::instr_fetching_sel_op_dc_13, + ColumnAndShifts::instr_fetching_sel_op_dc_14, + ColumnAndShifts::instr_fetching_sel_op_dc_15, + ColumnAndShifts::instr_fetching_sel_op_dc_16, + ColumnAndShifts::instr_fetching_sel_op_dc_17 }; static constexpr std::array DST_COLUMNS = { - ColumnAndShifts::precomputed_clk, ColumnAndShifts::precomputed_exec_opcode, - ColumnAndShifts::precomputed_sel_op_dc_0, ColumnAndShifts::precomputed_sel_op_dc_1, - ColumnAndShifts::precomputed_sel_op_dc_2, ColumnAndShifts::precomputed_sel_op_dc_3, - ColumnAndShifts::precomputed_sel_op_dc_4, ColumnAndShifts::precomputed_sel_op_dc_5, - ColumnAndShifts::precomputed_sel_op_dc_6, ColumnAndShifts::precomputed_sel_op_dc_7, - ColumnAndShifts::precomputed_sel_op_dc_8, ColumnAndShifts::precomputed_sel_op_dc_9, - ColumnAndShifts::precomputed_sel_op_dc_10, ColumnAndShifts::precomputed_sel_op_dc_11, - ColumnAndShifts::precomputed_sel_op_dc_12, ColumnAndShifts::precomputed_sel_op_dc_13, - ColumnAndShifts::precomputed_sel_op_dc_14, ColumnAndShifts::precomputed_sel_op_dc_15, - ColumnAndShifts::precomputed_sel_op_dc_16, ColumnAndShifts::precomputed_sel_op_dc_17 + ColumnAndShifts::precomputed_clk, + ColumnAndShifts::precomputed_exec_opcode, + ColumnAndShifts::precomputed_instr_size_in_bytes, + ColumnAndShifts::precomputed_sel_op_dc_0, + ColumnAndShifts::precomputed_sel_op_dc_1, + ColumnAndShifts::precomputed_sel_op_dc_2, + ColumnAndShifts::precomputed_sel_op_dc_3, + ColumnAndShifts::precomputed_sel_op_dc_4, + ColumnAndShifts::precomputed_sel_op_dc_5, + ColumnAndShifts::precomputed_sel_op_dc_6, + ColumnAndShifts::precomputed_sel_op_dc_7, + ColumnAndShifts::precomputed_sel_op_dc_8, + ColumnAndShifts::precomputed_sel_op_dc_9, + ColumnAndShifts::precomputed_sel_op_dc_10, + ColumnAndShifts::precomputed_sel_op_dc_11, + ColumnAndShifts::precomputed_sel_op_dc_12, + ColumnAndShifts::precomputed_sel_op_dc_13, + ColumnAndShifts::precomputed_sel_op_dc_14, + ColumnAndShifts::precomputed_sel_op_dc_15, + ColumnAndShifts::precomputed_sel_op_dc_16, + ColumnAndShifts::precomputed_sel_op_dc_17 }; template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) @@ -308,6 +330,7 @@ class lookup_instr_fetching_wire_instruction_info_settings { in._precomputed_sel_range_wire_opcode(), in._instr_fetching_bd0(), in._instr_fetching_exec_opcode(), + in._instr_fetching_instr_size_in_bytes(), in._instr_fetching_sel_op_dc_0(), in._instr_fetching_sel_op_dc_1(), in._instr_fetching_sel_op_dc_2(), @@ -328,6 +351,7 @@ class lookup_instr_fetching_wire_instruction_info_settings { in._instr_fetching_sel_op_dc_17(), in._precomputed_clk(), in._precomputed_exec_opcode(), + in._precomputed_instr_size_in_bytes(), in._precomputed_sel_op_dc_0(), in._precomputed_sel_op_dc_1(), in._precomputed_sel_op_dc_2(), diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/bytecode_manager.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/bytecode_manager.cpp index b7eb3713ff1a..ecfb70ee31d0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/bytecode_manager.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/bytecode_manager.cpp @@ -57,7 +57,7 @@ Instruction TxBytecodeManager::read_instruction(BytecodeId bytecode_id, uint32_t auto bytecode_ptr = it->second; const auto& bytecode = *bytecode_ptr; // TODO: catch errors etc. - Instruction instruction = decode_instruction(bytecode, pc); + Instruction instruction = deserialize_instruction(bytecode, pc); // The event will be deduplicated internally. fetching_events.emit( diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.cpp index 9574ed6a319b..0e314b11c985 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.cpp @@ -106,7 +106,7 @@ void Execution::execution_loop() try { auto pc = context.get_pc(); Instruction instruction = context.get_bytecode_manager().read_instruction(pc); - context.set_next_pc(pc + instruction.size_in_bytes); + context.set_next_pc(pc + WIRE_INSTRUCTION_SPEC.at(instruction.opcode).size_in_bytes); info("@", pc, " ", instruction.to_string()); ExecutionOpCode opcode = instruction_info_db.map_wire_opcode_to_execution_opcode(instruction.opcode); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp index 2b930d7c47ed..106f0a363cd9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.cpp @@ -12,6 +12,7 @@ #include "barretenberg/common/serialize.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" +#include "barretenberg/vm2/common/instruction_spec.hpp" #include "barretenberg/vm2/common/opcodes.hpp" namespace bb::avm2::simulation { @@ -224,6 +225,27 @@ Operand& Operand::operator=(const Operand& other) return *this; } +bool Operand::operator==(const Operand& other) const +{ + if (this == &other) { + return true; + } + + if (value.index() != other.value.index()) { + return false; + } + + if (std::holds_alternative(value)) { + return *std::get(value) == *std::get(other.value); + } + + if (std::holds_alternative(value)) { + return *std::get(value) == *std::get(other.value); + } + + return value == other.value; +} + Operand::operator bool() const { return (this->operator uint8_t() == 1); @@ -330,10 +352,9 @@ std::string Operand::to_string() const __builtin_unreachable(); } -Instruction decode_instruction(std::span bytecode, size_t pos) +Instruction deserialize_instruction(std::span bytecode, size_t pos) { const auto bytecode_length = bytecode.size(); - const auto starting_pos = pos; assert(pos < bytecode_length); (void)bytecode_length; // Avoid GCC unused parameter warning when asserts are disabled. @@ -451,10 +472,11 @@ Instruction decode_instruction(std::span bytecode, size_t pos) pos += operand_size; } - return { .opcode = opcode, - .indirect = indirect, - .operands = std::move(operands), - .size_in_bytes = static_cast(pos - starting_pos) }; + return { + .opcode = opcode, + .indirect = indirect, + .operands = std::move(operands), + }; }; std::string Instruction::to_string() const @@ -464,8 +486,60 @@ std::string Instruction::to_string() const for (const auto& operand : operands) { oss << operand.to_string() << " "; } - oss << "], size: " << static_cast(size_in_bytes); + oss << "]"; return oss.str(); } +std::vector Instruction::serialize() const +{ + std::vector output; + output.reserve(WIRE_INSTRUCTION_SPEC.at(opcode).size_in_bytes); + output.emplace_back(static_cast(opcode)); + size_t operand_pos = 0; + + for (const auto& operand_type : WireOpCode_WIRE_FORMAT.at(opcode)) { + switch (operand_type) { + case OperandType::INDIRECT8: + output.emplace_back(static_cast(indirect)); + break; + case OperandType::INDIRECT16: { + const auto indirect_vec = to_buffer(indirect); + output.insert(output.end(), + std::make_move_iterator(indirect_vec.begin()), + std::make_move_iterator(indirect_vec.end())); + } break; + case OperandType::TAG: + case OperandType::UINT8: + output.emplace_back(static_cast(operands.at(operand_pos++))); + break; + case OperandType::UINT16: { + const auto operand_vec = to_buffer(static_cast(operands.at(operand_pos++))); + output.insert( + output.end(), std::make_move_iterator(operand_vec.begin()), std::make_move_iterator(operand_vec.end())); + } break; + case OperandType::UINT32: { + const auto operand_vec = to_buffer(static_cast(operands.at(operand_pos++))); + output.insert( + output.end(), std::make_move_iterator(operand_vec.begin()), std::make_move_iterator(operand_vec.end())); + } break; + case OperandType::UINT64: { + const auto operand_vec = to_buffer(static_cast(operands.at(operand_pos++))); + output.insert( + output.end(), std::make_move_iterator(operand_vec.begin()), std::make_move_iterator(operand_vec.end())); + } break; + case OperandType::UINT128: { + const auto operand_vec = to_buffer(static_cast(operands.at(operand_pos++))); + output.insert( + output.end(), std::make_move_iterator(operand_vec.begin()), std::make_move_iterator(operand_vec.end())); + } break; + case OperandType::FF: { + const auto operand_vec = to_buffer(static_cast(operands.at(operand_pos++))); + output.insert( + output.end(), std::make_move_iterator(operand_vec.begin()), std::make_move_iterator(operand_vec.end())); + } break; + } + } + return output; +} + } // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.hpp index 8b8a6a3aa647..010f3218cbb1 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.hpp @@ -42,6 +42,7 @@ class Operand { Operand(const Operand& other); Operand(Operand&&) = default; Operand& operator=(const Operand& other); + bool operator==(const Operand& other) const; // Helpers for when we want to pass a value without casting. static Operand u8(uint8_t value) { return { value }; } @@ -68,9 +69,12 @@ struct Instruction { WireOpCode opcode; uint16_t indirect; std::vector operands; - uint8_t size_in_bytes; std::string to_string() const; + // Serialize the instruction according to the specification from OPCODE_WIRE_FORMAT. + std::vector serialize() const; + + bool operator==(const Instruction& other) const = default; }; /** @@ -83,6 +87,6 @@ struct Instruction { * @throws runtime_error exception when the bytecode is invalid or pos is out-of-range * @return The instruction */ -Instruction decode_instruction(std::span bytecode, size_t pos); +Instruction deserialize_instruction(std::span bytecode, size_t pos); } // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.test.cpp new file mode 100644 index 000000000000..35ef430de2c4 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/serialization.test.cpp @@ -0,0 +1,85 @@ +#include +#include + +#include "barretenberg/vm2/simulation/lib/serialization.hpp" + +namespace bb::avm2 { +namespace { +using simulation::deserialize_instruction; +using simulation::Instruction; +using simulation::Operand; + +// Testing serialization with some u8 variants +TEST(SerializationTest, Not8RoundTrip) +{ + const Instruction instr = { .opcode = WireOpCode::NOT_8, + .indirect = 5, + .operands = { Operand::u8(123), Operand::u8(45) } }; + const auto decoded = deserialize_instruction(instr.serialize(), 0); + EXPECT_EQ(instr, decoded); +} + +// Testing serialization with some u16 variants +TEST(SerializationTest, Add16RoundTrip) +{ + const Instruction instr = { .opcode = WireOpCode::ADD_16, + .indirect = 3, + .operands = { Operand::u16(1000), Operand::u16(1001), Operand::u16(1002) } }; + const auto decoded = deserialize_instruction(instr.serialize(), 0); + EXPECT_EQ(instr, decoded); +} + +// Testing serialization with a u32 variant +TEST(SerializationTest, Jumpi32RoundTrip) +{ + const Instruction instr = { .opcode = WireOpCode::JUMPI_32, + .indirect = 7, + .operands = { Operand::u16(12345), Operand::u32(678901234) } }; + const auto decoded = deserialize_instruction(instr.serialize(), 0); + EXPECT_EQ(instr, decoded); +} + +// Testing serialization with a u64 variant +TEST(SerializationTest, Set64RoundTrip) +{ + const uint64_t value_64 = 0xABCDEF0123456789LLU; + + const Instruction instr = { + .opcode = WireOpCode::SET_64, + .indirect = 2, + .operands = { Operand::u16(1002), Operand::u8(static_cast(MemoryTag::U64)), Operand::u64(value_64) } + }; + const auto decoded = deserialize_instruction(instr.serialize(), 0); + EXPECT_EQ(instr, decoded); +} + +// Testing serialization with a u128 variant +TEST(SerializationTest, Set128RoundTrip) +{ + const uint128_t value_128 = (uint128_t{ 0x123456789ABCDEF0LLU } << 64) + uint128_t{ 0xABCDEF0123456789LLU }; + + const Instruction instr = { + .opcode = WireOpCode::SET_128, + .indirect = 2, + .operands = { Operand::u16(1002), Operand::u8(static_cast(MemoryTag::U128)), Operand::u128(value_128) } + }; + const auto decoded = deserialize_instruction(instr.serialize(), 0); + EXPECT_EQ(instr, decoded); +} + +// Testing serialization with ff variant +TEST(SerializationTest, SetFFRoundTrip) +{ + const FF large_ff = FF::modulus - 981723; + + const Instruction instr = { + .opcode = WireOpCode::SET_FF, + .indirect = 2, + .operands = { Operand::u16(1002), Operand::u8(static_cast(MemoryTag::FF)), Operand::ff(large_ff) } + }; + const auto decoded = deserialize_instruction(instr.serialize(), 0); + EXPECT_EQ(instr, decoded); +} + +} // namespace +} // namespace bb::avm2 diff --git a/barretenberg/cpp/src/barretenberg/vm2/testing/fixtures.cpp b/barretenberg/cpp/src/barretenberg/vm2/testing/fixtures.cpp index 8a772d3d5c6b..48c703f0fdf3 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/testing/fixtures.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/testing/fixtures.cpp @@ -1,12 +1,20 @@ #include "barretenberg/vm2/testing/fixtures.hpp" -#include "barretenberg/vm2/tracegen/test_trace_container.hpp" #include +#include "barretenberg/vm2/common/instruction_spec.hpp" + using bb::avm2::tracegen::TestTraceContainer; namespace bb::avm2::testing { +using simulation::Instruction; +using simulation::Operand; +using simulation::OperandType; + +// If MemoryTag enum changes, this value might need to be adjusted. +constexpr uint8_t NUM_MEMORY_TAGS = static_cast(MemoryTag::U128) + 1; + std::vector random_fields(size_t n) { std::vector fields; @@ -27,6 +35,79 @@ std::vector random_bytes(size_t n) return bytes; } +Operand random_operand(OperandType operand_type) +{ + const auto rand_bytes = random_bytes(simulation::testonly::get_operand_type_sizes().at(operand_type)); + const uint8_t* pos_ptr = &rand_bytes.at(0); + + switch (operand_type) { + case OperandType::INDIRECT8: // Irrelevant bits might be toggled but they are ignored during address resolution. + case OperandType::UINT8: { + uint8_t operand_u8 = 0; + serialize::read(pos_ptr, operand_u8); + return Operand::u8(operand_u8); + } + case OperandType::TAG: { + uint8_t operand_u8 = 0; + serialize::read(pos_ptr, operand_u8); + return Operand::u8(operand_u8 % NUM_MEMORY_TAGS); // Insecure bias but it is fine for testing purposes. + } + case OperandType::INDIRECT16: // Irrelevant bits might be toggled but they are ignored during address resolution. + case OperandType::UINT16: { + uint16_t operand_u16 = 0; + serialize::read(pos_ptr, operand_u16); + return Operand::u16(operand_u16); + } + case OperandType::UINT32: { + uint32_t operand_u32 = 0; + serialize::read(pos_ptr, operand_u32); + return Operand::u32(operand_u32); + } + case OperandType::UINT64: { + uint64_t operand_u64 = 0; + serialize::read(pos_ptr, operand_u64); + return Operand::u64(operand_u64); + } + case OperandType::UINT128: { + uint128_t operand_u128 = 0; + serialize::read(pos_ptr, operand_u128); + return Operand::u128(operand_u128); + } + case OperandType::FF: + return Operand::ff(FF::random_element()); + } + + // Need this for gcc compilation even though we fully handle the switch cases. + // We never reach this point. + __builtin_unreachable(); +} + +Instruction random_instruction(WireOpCode w_opcode) +{ + const auto format = simulation::testonly::get_instruction_wire_formats().at(w_opcode); + std::vector operands; + uint16_t indirect = 0; + operands.reserve(format.size()); // Might be a bit larger (due to indirect) + + for (const auto& operand_type : format) { + switch (operand_type) { + case OperandType::INDIRECT8: + case OperandType::INDIRECT16: + indirect = static_cast(random_operand(operand_type)); + break; + default: + operands.emplace_back(random_operand(operand_type)); + break; + } + } + + return Instruction{ + .opcode = w_opcode, + .indirect = indirect, + .operands = std::move(operands), + }; +} + TestTraceContainer empty_trace() { return TestTraceContainer::from_rows({ { .precomputed_first_row = 1 }, { .precomputed_clk = 1 } }); diff --git a/barretenberg/cpp/src/barretenberg/vm2/testing/fixtures.hpp b/barretenberg/cpp/src/barretenberg/vm2/testing/fixtures.hpp index 8ca3f2a45b9b..e43cd1bb5535 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/testing/fixtures.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/testing/fixtures.hpp @@ -3,12 +3,34 @@ #include #include "barretenberg/vm2/common/field.hpp" +#include "barretenberg/vm2/simulation/lib/serialization.hpp" #include "barretenberg/vm2/tracegen/test_trace_container.hpp" namespace bb::avm2::testing { std::vector random_fields(size_t n); + +// WARNING: Cryptographically insecure randomness routines for testing purposes only. std::vector random_bytes(size_t n); +simulation::Operand random_operand(simulation::OperandType operand_type); + +// This generates a random instruction for a given wire opcode. The output will conform to +// the wire format specified in WireOpCode_WIRE_FORMAT. The format specifies a vector of +// OperandType and we generate a random value for each operand conforming to the OperandType. +// For OperandTypes: +// INDIRECT8, UINT8: single random byte +// INDIRECT16, UINT16: 2 random bytes +// UINTXX: random bytes conforming to the size in bytes of the operand +// FF: random field +// TAG: random tag within the enum MemoryTag range +// We do not provide any guarantee beyond the above static format restrictions. +// For instance, next pc destination in JUMP might overflow the bytecode, etc, .... +// Also, immediate operands which correspond to an enum value might fall outside +// the prescribed range (for instance: GETENVVAR_16 and GETCONTRACTINSTANCE). +// Note that indirect value might have toggled bits which are not relevant to the +// wire opcode. It is in principle not an issue as these bits are ignored during +// address resolution. +simulation::Instruction random_instruction(WireOpCode w_opcode); tracegen::TestTraceContainer empty_trace(); } // namespace bb::avm2::testing diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/bytecode_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/bytecode_trace.cpp index 0278d8239ff5..5e7b445516d0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/bytecode_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/bytecode_trace.cpp @@ -271,14 +271,8 @@ void BytecodeTraceBuilder::process_instruction_fetching( { C::instr_fetching_op5, get_operand(4) }, { C::instr_fetching_op6, get_operand(5) }, { C::instr_fetching_op7, get_operand(6) }, - // From instruction table. - // FIXME: This one is wrong, it's the wire opcode. - // { C::instr_fetching_ex_opcode, event.instruction.opcode }, - // TODO: add the rest. // Single bytes. { C::instr_fetching_bd0, wire_opcode }, - { C::instr_fetching_exec_opcode, - static_cast(WIRE_INSTRUCTION_SPEC.at(w_opcode).exec_opcode) }, { C::instr_fetching_bd1, bytecode_at(event.pc + 1) }, { C::instr_fetching_bd2, bytecode_at(event.pc + 2) }, { C::instr_fetching_bd3, bytecode_at(event.pc + 3) }, @@ -316,6 +310,10 @@ void BytecodeTraceBuilder::process_instruction_fetching( { C::instr_fetching_bd35, bytecode_at(event.pc + 35) }, { C::instr_fetching_bd36, bytecode_at(event.pc + 36) }, + // From instruction table. + { C::instr_fetching_exec_opcode, + static_cast(WIRE_INSTRUCTION_SPEC.at(w_opcode).exec_opcode) }, + { C::instr_fetching_instr_size_in_bytes, WIRE_INSTRUCTION_SPEC.at(w_opcode).size_in_bytes }, // Fill operand decomposition selectors { C::instr_fetching_sel_op_dc_0, WIRE_INSTRUCTION_SPEC.at(w_opcode).op_dc_selectors.at(0) }, { C::instr_fetching_sel_op_dc_1, WIRE_INSTRUCTION_SPEC.at(w_opcode).op_dc_selectors.at(1) }, diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/bytecode_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/bytecode_trace.test.cpp index 56182433a99d..c60eed8bd88c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/bytecode_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/bytecode_trace.test.cpp @@ -8,8 +8,10 @@ #include #include +#include "barretenberg/vm2/common/instruction_spec.hpp" #include "barretenberg/vm2/generated/flavor_settings.hpp" #include "barretenberg/vm2/generated/full_row.hpp" +#include "barretenberg/vm2/testing/fixtures.hpp" #include "barretenberg/vm2/testing/macros.hpp" #include "barretenberg/vm2/tracegen/bytecode_trace.hpp" #include "barretenberg/vm2/tracegen/test_trace_container.hpp" @@ -17,12 +19,12 @@ namespace bb::avm2::tracegen { namespace { -using testing::Field; +using ::testing::Field; using R = TestTraceContainer::Row; using FF = R::FF; -TEST(BytecodeTraceGenTest, basicShortLength) +TEST(BytecodeTraceGenTest, BasicShortLength) { TestTraceContainer trace; BytecodeTraceBuilder builder; @@ -100,7 +102,7 @@ TEST(BytecodeTraceGenTest, basicShortLength) ROW_FIELD_EQ(R, bc_decomposition_last_of_contract, 1))); } -TEST(BytecodeTraceGenTest, basicLongerThanWindowSize) +TEST(BytecodeTraceGenTest, BasicLongerThanWindowSize) { TestTraceContainer trace; BytecodeTraceBuilder builder; @@ -181,7 +183,7 @@ TEST(BytecodeTraceGenTest, basicLongerThanWindowSize) ROW_FIELD_EQ(R, bc_decomposition_last_of_contract, 1))); } -TEST(BytecodeTraceGenTest, multipleEvents) +TEST(BytecodeTraceGenTest, MultipleEvents) { TestTraceContainer trace; BytecodeTraceBuilder builder; @@ -247,7 +249,7 @@ TEST(BytecodeTraceGenTest, multipleEvents) } } -TEST(BytecodeTraceGenTest, basicHashing) +TEST(BytecodeTraceGenTest, BasicHashing) { TestTraceContainer trace; BytecodeTraceBuilder builder; @@ -283,5 +285,103 @@ TEST(BytecodeTraceGenTest, basicHashing) ROW_FIELD_EQ(R, bc_hashing_packed_field, 20))); } +// We build a random InstructionFetchingEvent for each wire opcode. +// We then verify that the bytes (bd0, bd1, ...) correspond to the serialized instruction. +TEST(BytecodeTraceGenTest, InstrDecompositionInBytesEachOpcode) +{ + using simulation::Instruction; + using simulation::InstructionFetchingEvent; + using C = Column; + + TestTraceContainer trace; + BytecodeTraceBuilder builder; + + constexpr std::array bd_columns = { + C::instr_fetching_bd0, C::instr_fetching_bd1, C::instr_fetching_bd2, C::instr_fetching_bd3, + C::instr_fetching_bd4, C::instr_fetching_bd5, C::instr_fetching_bd6, C::instr_fetching_bd7, + C::instr_fetching_bd8, C::instr_fetching_bd9, C::instr_fetching_bd10, C::instr_fetching_bd11, + C::instr_fetching_bd12, C::instr_fetching_bd13, C::instr_fetching_bd14, C::instr_fetching_bd15, + C::instr_fetching_bd16, C::instr_fetching_bd17, C::instr_fetching_bd18, C::instr_fetching_bd19, + C::instr_fetching_bd20, C::instr_fetching_bd21, C::instr_fetching_bd22, C::instr_fetching_bd23, + C::instr_fetching_bd24, C::instr_fetching_bd25, C::instr_fetching_bd26, C::instr_fetching_bd27, + C::instr_fetching_bd28, C::instr_fetching_bd29, C::instr_fetching_bd30, C::instr_fetching_bd31, + C::instr_fetching_bd32, C::instr_fetching_bd33, C::instr_fetching_bd34, C::instr_fetching_bd35, + C::instr_fetching_bd36, + }; + + constexpr std::array operand_columns = { + C::instr_fetching_op1, C::instr_fetching_op2, C::instr_fetching_op3, C::instr_fetching_op4, + C::instr_fetching_op5, C::instr_fetching_op6, C::instr_fetching_op7, + }; + + constexpr auto num_opcodes = static_cast(WireOpCode::LAST_OPCODE_SENTINEL); + + std::vector events; + events.reserve(num_opcodes); + std::vector instructions; + instructions.reserve(num_opcodes); + std::vector pcs; + pcs.reserve(num_opcodes); + std::vector bytecode; + bytecode.reserve(1024); // Rough estimate + + uint32_t pc = 0; + for (size_t i = 0; i < num_opcodes; i++) { + const auto w_opcode = static_cast(i); + const auto instr = testing::random_instruction(w_opcode); + const auto instr_encoded = instr.serialize(); + instructions.emplace_back(instr); + pcs.emplace_back(pc); + pc += instr_encoded.size(); + bytecode.insert(bytecode.end(), + std::make_move_iterator(instr_encoded.begin()), + std::make_move_iterator(instr_encoded.end())); + } + + auto bytecode_ptr = std::make_shared>(bytecode); + for (size_t i = 0; i < num_opcodes; i++) { + events.emplace_back(InstructionFetchingEvent{ + .bytecode_id = 1, + .pc = pcs.at(i), + .instruction = instructions.at(i), + .bytecode = bytecode_ptr, + }); + } + + builder.process_instruction_fetching(events, trace); + + for (uint32_t i = 0; i < num_opcodes; i++) { + const auto instr = instructions.at(i); + const auto instr_encoded = instr.serialize(); + const auto w_opcode = static_cast(i); + + // Check size_in_bytes column + const auto expected_size_in_bytes = WIRE_INSTRUCTION_SPEC.at(w_opcode).size_in_bytes; + ASSERT_EQ(instr_encoded.size(), expected_size_in_bytes); + EXPECT_EQ(FF(expected_size_in_bytes), trace.get(C::instr_fetching_instr_size_in_bytes, i)); + + // Inspect each byte + for (size_t j = 0; j < static_cast(expected_size_in_bytes); j++) { + EXPECT_EQ(FF(instr_encoded.at(j)), trace.get(bd_columns.at(j), i)); + } + + // Check exection opcode + EXPECT_EQ(FF(static_cast(WIRE_INSTRUCTION_SPEC.at(w_opcode).exec_opcode)), + trace.get(C::instr_fetching_exec_opcode, i)); + + // Check indirect + EXPECT_EQ(FF(instr.indirect), trace.get(C::instr_fetching_indirect, i)); + + // Check PCs + EXPECT_EQ(FF(pcs.at(i)), trace.get(C::instr_fetching_pc, i)); + + // Check operands + size_t operand_idx = 0; + for (const auto& operand : instr.operands) { + EXPECT_EQ(FF(operand), trace.get(operand_columns.at(operand_idx++), i)); + } + } +} + } // namespace } // namespace bb::avm2::tracegen diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp index 1d3aa84b6c69..a1dab47e3891 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/precomputed_trace.cpp @@ -206,6 +206,9 @@ void PrecomputedTraceBuilder::process_wire_instruction_spec(TraceContainer& trac trace.set(C::precomputed_exec_opcode, static_cast(wire_opcode), static_cast(wire_instruction_spec.exec_opcode)); + trace.set(C::precomputed_instr_size_in_bytes, + static_cast(wire_opcode), + wire_instruction_spec.size_in_bytes); } }