diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp index 3134bc021f62..10e2ce6b15be 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -186,11 +186,8 @@ std::vector Execution::gen_trace(std::vector const& instructio break; // Machine State - Memory case OpCode::SET: { - uint32_t dst_offset = 0; uint128_t val = 0; - // Skip the indirect flag at index 0; AvmMemoryTag in_tag = std::get(inst.operands.at(1)); - dst_offset = std::get(inst.operands.at(3)); switch (in_tag) { case AvmMemoryTag::U8: @@ -212,7 +209,8 @@ std::vector Execution::gen_trace(std::vector const& instructio break; } - trace_builder.set(val, dst_offset, in_tag); + trace_builder.op_set( + std::get(inst.operands.at(0)), val, std::get(inst.operands.at(3)), in_tag); break; } case OpCode::MOV: diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp index 40eb386432bd..a66fcb4edf92 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -629,35 +629,49 @@ void AvmTraceBuilder::op_xor( }); } -// TODO: Finish SET opcode implementation. This is a partial implementation -// facilitating testing of arithmetic operations over non finite field types. -// We add an entry in the memory trace and a simplified one in the main trace -// without operation selector. -// TODO: PIL relations for the SET opcode need to be implemented. -// No check is performed that val pertains to type defined by in_tag. +// TODO: Ensure that the bytecode validation and/or deserialization is +// enforcing that val complies to the tag. /** - * @brief Set a constant from bytecode with direct memory access. + * @brief Set a constant from bytecode with direct or indirect memory access. + * SET opcode is implemented purely as a memory operation. As val is a + * constant passed in the bytecode, the deserialization layer or bytecode + * validation circuit is enforcing that the constant complies to in_tag. + * Therefore, no range check is required as part of this opcode relation. * + * @param indirect A byte encoding information about indirect/direct memory access. * @param val The constant to be written upcasted to u128 * @param dst_offset Memory destination offset where val is written to * @param in_tag The instruction memory tag */ -void AvmTraceBuilder::set(uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag) +void AvmTraceBuilder::op_set(uint8_t indirect, uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag) { - auto clk = static_cast(main_trace.size()); - auto val_ff = FF{ uint256_t::from_uint128(val) }; + auto const clk = static_cast(main_trace.size()); + auto const val_ff = FF{ uint256_t::from_uint128(val) }; + uint32_t direct_dst_offset = dst_offset; // Overriden in indirect mode + bool indirect_dst_flag = is_operand_indirect(indirect, 0); + bool tag_match = true; + + if (indirect_dst_flag) { + auto read_ind_c = + mem_trace_builder.indirect_read_and_load_from_memory(clk, IndirectRegister::IND_C, dst_offset); + tag_match = read_ind_c.tag_match; + direct_dst_offset = uint32_t(read_ind_c.val); + } - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, val_ff, AvmMemoryTag::U0, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, direct_dst_offset, val_ff, AvmMemoryTag::U0, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_ic = val_ff, - .avm_main_internal_return_ptr = FF(internal_return_ptr), - .avm_main_mem_idx_c = FF(dst_offset), - .avm_main_mem_op_c = FF(1), - .avm_main_pc = FF(pc++), - .avm_main_rwc = FF(1), - .avm_main_w_in_tag = FF(static_cast(in_tag)), + .avm_main_ind_c = indirect_dst_flag ? dst_offset : 0, + .avm_main_ind_op_c = static_cast(indirect_dst_flag), + .avm_main_internal_return_ptr = internal_return_ptr, + .avm_main_mem_idx_c = direct_dst_offset, + .avm_main_mem_op_c = 1, + .avm_main_pc = pc++, + .avm_main_rwc = 1, + .avm_main_tag_err = static_cast(!tag_match), + .avm_main_w_in_tag = static_cast(in_tag), }); } @@ -722,7 +736,7 @@ void AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst } /** - * @brief CALLDATACOPY opcode with direct memory access, i.e., + * @brief CALLDATACOPY opcode with direct or indirect memory access, i.e., * direct: M[dst_offset:dst_offset+copy_size] = calldata[cd_offset:cd_offset+copy_size] * indirect: M[M[dst_offset]:M[dst_offset]+copy_size] = calldata[cd_offset:cd_offset+copy_size] * Simplified version with exclusively memory store operations and @@ -730,8 +744,6 @@ void AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst * intermediate registers. * Assume that caller passes call_data_mem which is large enough so that * no out-of-bound memory issues occur. - * TODO: taking care of intermediate register values consistency and propagating their - * values to the next row when not overwritten. * TODO: error handling if dst_offset + copy_size > 2^32 which would lead to * out-of-bound memory write. Similarly, if cd_offset + copy_size is larger * than call_data_mem.size() diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp index ad865def589a..a68439da21af 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -56,8 +56,8 @@ class AvmTraceBuilder { // Bitwise xor with direct or indirect memory access. void op_xor(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Set a constant from bytecode with direct memory access. - void set(uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag); + // Set a constant from bytecode with direct or indirect memory access. + void op_set(uint8_t indirect, uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag); // Move (copy) the value and tag of a memory cell to another one. void op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp index 6b4e422c8918..e9cb034f8a83 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp @@ -176,8 +176,8 @@ std::vector gen_trace_eq(uint128_t const& a, avm_trace::AvmMemoryTag tag) { auto trace_builder = avm_trace::AvmTraceBuilder(); - trace_builder.set(a, addr_a, tag); - trace_builder.set(b, addr_b, tag); + trace_builder.op_set(0, a, addr_a, tag); + trace_builder.op_set(0, b, addr_b, tag); trace_builder.op_eq(0, addr_a, addr_b, addr_c, tag); trace_builder.return_op(0, 0, 0); return trace_builder.finalize(); @@ -189,8 +189,8 @@ std::vector gen_trace_eq(uint128_t const& a, std::vector gen_mutated_trace_add(FF const& a, FF const& b, FF const& c_mutated, avm_trace::AvmMemoryTag tag) { auto trace_builder = avm_trace::AvmTraceBuilder(); - trace_builder.set(uint128_t{ a }, 0, tag); - trace_builder.set(uint128_t{ b }, 1, tag); + trace_builder.op_set(0, uint128_t{ a }, 0, tag); + trace_builder.op_set(0, uint128_t{ b }, 1, tag); trace_builder.op_add(0, 0, 1, 2, tag); trace_builder.halt(); auto trace = trace_builder.finalize(); @@ -207,8 +207,8 @@ std::vector gen_mutated_trace_add(FF const& a, FF const& b, FF const& c_mut std::vector gen_mutated_trace_sub(FF const& a, FF const& b, FF const& c_mutated, avm_trace::AvmMemoryTag tag) { auto trace_builder = avm_trace::AvmTraceBuilder(); - trace_builder.set(uint128_t{ a }, 0, tag); - trace_builder.set(uint128_t{ b }, 1, tag); + trace_builder.op_set(0, uint128_t{ a }, 0, tag); + trace_builder.op_set(0, uint128_t{ b }, 1, tag); trace_builder.op_sub(0, 0, 1, 2, tag); trace_builder.halt(); auto trace = trace_builder.finalize(); @@ -225,8 +225,8 @@ std::vector gen_mutated_trace_sub(FF const& a, FF const& b, FF const& c_mut std::vector gen_mutated_trace_mul(FF const& a, FF const& b, FF const& c_mutated, avm_trace::AvmMemoryTag tag) { auto trace_builder = avm_trace::AvmTraceBuilder(); - trace_builder.set(uint128_t{ a }, 0, tag); - trace_builder.set(uint128_t{ b }, 1, tag); + trace_builder.op_set(0, uint128_t{ a }, 0, tag); + trace_builder.op_set(0, uint128_t{ b }, 1, tag); trace_builder.op_mul(0, 0, 1, 2, tag); trace_builder.halt(); auto trace = trace_builder.finalize(); @@ -246,8 +246,8 @@ std::vector gen_mutated_trace_eq( FF const& a, FF const& b, FF const& c_mutated, FF const& mutated_inv_diff, avm_trace::AvmMemoryTag tag) { auto trace_builder = avm_trace::AvmTraceBuilder(); - trace_builder.set(uint128_t{ a }, 0, tag); - trace_builder.set(uint128_t{ b }, 1, tag); + trace_builder.op_set(0, uint128_t{ a }, 0, tag); + trace_builder.op_set(0, uint128_t{ b }, 1, tag); trace_builder.op_eq(0, 0, 1, 2, tag); trace_builder.halt(); auto trace = trace_builder.finalize(); @@ -559,8 +559,8 @@ TEST_F(AvmArithmeticTestsFF, nonEquality) TEST_F(AvmArithmeticTestsU8, addition) { // trace_builder - trace_builder.set(62, 0, AvmMemoryTag::U8); - trace_builder.set(29, 1, AvmMemoryTag::U8); + trace_builder.op_set(0, 62, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 29, 1, AvmMemoryTag::U8); // Memory layout: [62,29,0,0,0,....] trace_builder.op_add(0, 0, 1, 2, AvmMemoryTag::U8); // [62,29,91,0,0,....] @@ -580,8 +580,8 @@ TEST_F(AvmArithmeticTestsU8, addition) TEST_F(AvmArithmeticTestsU8, additionCarry) { // trace_builder - trace_builder.set(159, 0, AvmMemoryTag::U8); - trace_builder.set(100, 1, AvmMemoryTag::U8); + trace_builder.op_set(0, 159, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 100, 1, AvmMemoryTag::U8); // Memory layout: [159,100,0,0,0,....] trace_builder.op_add(0, 0, 1, 2, AvmMemoryTag::U8); // [159,100,3,0,0,....] @@ -602,8 +602,8 @@ TEST_F(AvmArithmeticTestsU8, additionCarry) TEST_F(AvmArithmeticTestsU8, subtraction) { // trace_builder - trace_builder.set(162, 0, AvmMemoryTag::U8); - trace_builder.set(29, 1, AvmMemoryTag::U8); + trace_builder.op_set(0, 162, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 29, 1, AvmMemoryTag::U8); // Memory layout: [162,29,0,0,0,....] trace_builder.op_sub(0, 0, 1, 2, AvmMemoryTag::U8); // [162,29,133,0,0,....] @@ -624,8 +624,8 @@ TEST_F(AvmArithmeticTestsU8, subtraction) TEST_F(AvmArithmeticTestsU8, subtractionCarry) { // trace_builder - trace_builder.set(5, 0, AvmMemoryTag::U8); - trace_builder.set(29, 1, AvmMemoryTag::U8); + trace_builder.op_set(0, 5, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 29, 1, AvmMemoryTag::U8); // Memory layout: [5,29,0,0,0,....] trace_builder.op_sub(0, 0, 1, 2, AvmMemoryTag::U8); // [5,29,232,0,0,....] @@ -653,8 +653,8 @@ TEST_F(AvmArithmeticTestsU8, subtractionCarry) TEST_F(AvmArithmeticTestsU8, multiplication) { // trace_builder - trace_builder.set(13, 0, AvmMemoryTag::U8); - trace_builder.set(15, 1, AvmMemoryTag::U8); + trace_builder.op_set(0, 13, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 15, 1, AvmMemoryTag::U8); trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U8); trace_builder.return_op(0, 0, 0); @@ -676,8 +676,8 @@ TEST_F(AvmArithmeticTestsU8, multiplication) TEST_F(AvmArithmeticTestsU8, multiplicationOverflow) { // trace_builder - trace_builder.set(200, 0, AvmMemoryTag::U8); - trace_builder.set(170, 1, AvmMemoryTag::U8); + trace_builder.op_set(0, 200, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 170, 1, AvmMemoryTag::U8); trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U8); trace_builder.return_op(0, 0, 0); @@ -730,8 +730,8 @@ TEST_F(AvmArithmeticTestsU8, nonEquality) TEST_F(AvmArithmeticTestsU16, addition) { // trace_builder - trace_builder.set(1775, 119, AvmMemoryTag::U16); - trace_builder.set(33005, 546, AvmMemoryTag::U16); + trace_builder.op_set(0, 1775, 119, AvmMemoryTag::U16); + trace_builder.op_set(0, 33005, 546, AvmMemoryTag::U16); trace_builder.op_add(0, 546, 119, 5, AvmMemoryTag::U16); trace_builder.return_op(0, 0, 0); @@ -752,8 +752,8 @@ TEST_F(AvmArithmeticTestsU16, addition) TEST_F(AvmArithmeticTestsU16, additionCarry) { // trace_builder - trace_builder.set(UINT16_MAX - 982, 0, AvmMemoryTag::U16); - trace_builder.set(1000, 1, AvmMemoryTag::U16); + trace_builder.op_set(0, UINT16_MAX - 982, 0, AvmMemoryTag::U16); + trace_builder.op_set(0, 1000, 1, AvmMemoryTag::U16); trace_builder.op_add(0, 1, 0, 0, AvmMemoryTag::U16); trace_builder.return_op(0, 0, 0); @@ -774,8 +774,8 @@ TEST_F(AvmArithmeticTestsU16, additionCarry) TEST_F(AvmArithmeticTestsU16, subtraction) { // trace_builder - trace_builder.set(1775, 119, AvmMemoryTag::U16); - trace_builder.set(33005, 546, AvmMemoryTag::U16); + trace_builder.op_set(0, 1775, 119, AvmMemoryTag::U16); + trace_builder.op_set(0, 33005, 546, AvmMemoryTag::U16); trace_builder.op_sub(0, 546, 119, 5, AvmMemoryTag::U16); trace_builder.return_op(0, 0, 0); @@ -798,8 +798,8 @@ TEST_F(AvmArithmeticTestsU16, subtraction) TEST_F(AvmArithmeticTestsU16, subtractionCarry) { // trace_builder - trace_builder.set(UINT16_MAX - 982, 0, AvmMemoryTag::U16); - trace_builder.set(1000, 1, AvmMemoryTag::U16); + trace_builder.op_set(0, UINT16_MAX - 982, 0, AvmMemoryTag::U16); + trace_builder.op_set(0, 1000, 1, AvmMemoryTag::U16); trace_builder.op_sub(0, 1, 0, 0, AvmMemoryTag::U16); trace_builder.return_op(0, 0, 0); @@ -827,8 +827,8 @@ TEST_F(AvmArithmeticTestsU16, subtractionCarry) TEST_F(AvmArithmeticTestsU16, multiplication) { // trace_builder - trace_builder.set(200, 0, AvmMemoryTag::U16); - trace_builder.set(245, 1, AvmMemoryTag::U16); + trace_builder.op_set(0, 200, 0, AvmMemoryTag::U16); + trace_builder.op_set(0, 245, 1, AvmMemoryTag::U16); trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U16); trace_builder.return_op(0, 0, 0); @@ -852,8 +852,8 @@ TEST_F(AvmArithmeticTestsU16, multiplication) TEST_F(AvmArithmeticTestsU16, multiplicationOverflow) { // trace_builder - trace_builder.set(512, 0, AvmMemoryTag::U16); - trace_builder.set(1024, 1, AvmMemoryTag::U16); + trace_builder.op_set(0, 512, 0, AvmMemoryTag::U16); + trace_builder.op_set(0, 1024, 1, AvmMemoryTag::U16); trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U16); trace_builder.return_op(0, 0, 0); @@ -908,8 +908,8 @@ TEST_F(AvmArithmeticTestsU16, nonEquality) TEST_F(AvmArithmeticTestsU32, addition) { // trace_builder - trace_builder.set(1000000000, 8, AvmMemoryTag::U32); - trace_builder.set(1234567891, 9, AvmMemoryTag::U32); + trace_builder.op_set(0, 1000000000, 8, AvmMemoryTag::U32); + trace_builder.op_set(0, 1234567891, 9, AvmMemoryTag::U32); trace_builder.op_add(0, 8, 9, 0, AvmMemoryTag::U32); trace_builder.return_op(0, 0, 0); @@ -931,8 +931,8 @@ TEST_F(AvmArithmeticTestsU32, addition) TEST_F(AvmArithmeticTestsU32, additionCarry) { // trace_builder - trace_builder.set(UINT32_MAX - 1293, 8, AvmMemoryTag::U32); - trace_builder.set(2293, 9, AvmMemoryTag::U32); + trace_builder.op_set(0, UINT32_MAX - 1293, 8, AvmMemoryTag::U32); + trace_builder.op_set(0, 2293, 9, AvmMemoryTag::U32); trace_builder.op_add(0, 8, 9, 0, AvmMemoryTag::U32); trace_builder.return_op(0, 0, 0); @@ -953,8 +953,8 @@ TEST_F(AvmArithmeticTestsU32, additionCarry) TEST_F(AvmArithmeticTestsU32, subtraction) { // trace_builder - trace_builder.set(1345678991, 8, AvmMemoryTag::U32); - trace_builder.set(1234567891, 9, AvmMemoryTag::U32); + trace_builder.op_set(0, 1345678991, 8, AvmMemoryTag::U32); + trace_builder.op_set(0, 1234567891, 9, AvmMemoryTag::U32); trace_builder.op_sub(0, 8, 9, 0, AvmMemoryTag::U32); trace_builder.return_op(0, 0, 0); @@ -980,8 +980,8 @@ TEST_F(AvmArithmeticTestsU32, subtraction) TEST_F(AvmArithmeticTestsU32, subtractionCarry) { // trace_builder - trace_builder.set(UINT32_MAX - 99, 8, AvmMemoryTag::U32); - trace_builder.set(3210987654, 9, AvmMemoryTag::U32); + trace_builder.op_set(0, UINT32_MAX - 99, 8, AvmMemoryTag::U32); + trace_builder.op_set(0, 3210987654, 9, AvmMemoryTag::U32); trace_builder.op_sub(0, 9, 8, 0, AvmMemoryTag::U32); trace_builder.return_op(0, 0, 0); @@ -1011,8 +1011,8 @@ TEST_F(AvmArithmeticTestsU32, subtractionCarry) TEST_F(AvmArithmeticTestsU32, multiplication) { // trace_builder - trace_builder.set(11111, 0, AvmMemoryTag::U32); - trace_builder.set(11111, 1, AvmMemoryTag::U32); + trace_builder.op_set(0, 11111, 0, AvmMemoryTag::U32); + trace_builder.op_set(0, 11111, 1, AvmMemoryTag::U32); trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U32); trace_builder.return_op(0, 0, 0); @@ -1040,8 +1040,8 @@ TEST_F(AvmArithmeticTestsU32, multiplication) TEST_F(AvmArithmeticTestsU32, multiplicationOverflow) { // trace_builder - trace_builder.set(11 << 25, 0, AvmMemoryTag::U32); - trace_builder.set(13 << 22, 1, AvmMemoryTag::U32); + trace_builder.op_set(0, 11 << 25, 0, AvmMemoryTag::U32); + trace_builder.op_set(0, 13 << 22, 1, AvmMemoryTag::U32); trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U32); trace_builder.return_op(0, 0, 0); @@ -1105,8 +1105,8 @@ TEST_F(AvmArithmeticTestsU64, addition) uint64_t const c = 10193042407517981LLU; // trace_builder - trace_builder.set(a, 8, AvmMemoryTag::U64); - trace_builder.set(b, 9, AvmMemoryTag::U64); + trace_builder.op_set(0, a, 8, AvmMemoryTag::U64); + trace_builder.op_set(0, b, 9, AvmMemoryTag::U64); trace_builder.op_add(0, 8, 9, 9, AvmMemoryTag::U64); trace_builder.return_op(0, 0, 0); @@ -1135,8 +1135,8 @@ TEST_F(AvmArithmeticTestsU64, additionCarry) uint64_t const c = UINT64_MAX - 201LLU; // trace_builder - trace_builder.set(a, 0, AvmMemoryTag::U64); - trace_builder.set(b, 1, AvmMemoryTag::U64); + trace_builder.op_set(0, a, 0, AvmMemoryTag::U64); + trace_builder.op_set(0, b, 1, AvmMemoryTag::U64); trace_builder.op_add(0, 0, 1, 0, AvmMemoryTag::U64); trace_builder.return_op(0, 0, 0); @@ -1163,8 +1163,8 @@ TEST_F(AvmArithmeticTestsU64, subtraction) uint64_t const c = 10000000000000000LLU; // trace_builder - trace_builder.set(a, 8, AvmMemoryTag::U64); - trace_builder.set(b, 9, AvmMemoryTag::U64); + trace_builder.op_set(0, a, 8, AvmMemoryTag::U64); + trace_builder.op_set(0, b, 9, AvmMemoryTag::U64); trace_builder.op_sub(0, 8, 9, 9, AvmMemoryTag::U64); trace_builder.return_op(0, 0, 0); @@ -1195,8 +1195,8 @@ TEST_F(AvmArithmeticTestsU64, subtractionCarry) uint64_t const c = UINT64_MAX - 74; // trace_builder - trace_builder.set(a, 0, AvmMemoryTag::U64); - trace_builder.set(b, 1, AvmMemoryTag::U64); + trace_builder.op_set(0, a, 0, AvmMemoryTag::U64); + trace_builder.op_set(0, b, 1, AvmMemoryTag::U64); trace_builder.op_sub(0, 0, 1, 0, AvmMemoryTag::U64); trace_builder.return_op(0, 0, 0); @@ -1223,8 +1223,8 @@ TEST_F(AvmArithmeticTestsU64, subtractionCarry) TEST_F(AvmArithmeticTestsU64, multiplication) { // trace_builder - trace_builder.set(999888777, 0, AvmMemoryTag::U64); - trace_builder.set(555444333, 1, AvmMemoryTag::U64); + trace_builder.op_set(0, 999888777, 0, AvmMemoryTag::U64); + trace_builder.op_set(0, 555444333, 1, AvmMemoryTag::U64); trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U64); trace_builder.return_op(0, 0, 0); @@ -1256,8 +1256,8 @@ TEST_F(AvmArithmeticTestsU64, multiplicationOverflow) // (2^64 - 1)^2 = 2^128 - 2^65 + 1 (mod. 2^64) = 1 // trace_builder - trace_builder.set(a, 0, AvmMemoryTag::U64); - trace_builder.set(b, 1, AvmMemoryTag::U64); + trace_builder.op_set(0, a, 0, AvmMemoryTag::U64); + trace_builder.op_set(0, b, 1, AvmMemoryTag::U64); trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U64); trace_builder.return_op(0, 0, 0); @@ -1322,8 +1322,8 @@ TEST_F(AvmArithmeticTestsU128, addition) uint128_t const c = (uint128_t{ 0x8888444466665555LLU } << 64) + uint128_t{ 0xDDDDAAAAFFFFEEEELLU }; // trace_builder - trace_builder.set(a, 8, AvmMemoryTag::U128); - trace_builder.set(b, 9, AvmMemoryTag::U128); + trace_builder.op_set(0, a, 8, AvmMemoryTag::U128); + trace_builder.op_set(0, b, 9, AvmMemoryTag::U128); trace_builder.op_add(0, 8, 9, 9, AvmMemoryTag::U128); trace_builder.return_op(0, 0, 0); @@ -1362,8 +1362,8 @@ TEST_F(AvmArithmeticTestsU128, additionCarry) (uint128_t{ UINT64_MAX } << 64) + uint128_t{ UINT64_MAX } - uint128_t{ 36177345 } - uint128_t{ 72948899 }; // trace_builder - trace_builder.set(a, 8, AvmMemoryTag::U128); - trace_builder.set(b, 9, AvmMemoryTag::U128); + trace_builder.op_set(0, a, 8, AvmMemoryTag::U128); + trace_builder.op_set(0, b, 9, AvmMemoryTag::U128); trace_builder.op_add(0, 8, 9, 9, AvmMemoryTag::U128); trace_builder.return_op(0, 0, 0); @@ -1401,8 +1401,8 @@ TEST_F(AvmArithmeticTestsU128, subtraction) uint128_t const c = 36771555; // 72948899 - 36177344 // trace_builder - trace_builder.set(a, 8, AvmMemoryTag::U128); - trace_builder.set(b, 9, AvmMemoryTag::U128); + trace_builder.op_set(0, a, 8, AvmMemoryTag::U128); + trace_builder.op_set(0, b, 9, AvmMemoryTag::U128); trace_builder.op_sub(0, 8, 9, 9, AvmMemoryTag::U128); trace_builder.return_op(0, 0, 0); @@ -1443,8 +1443,8 @@ TEST_F(AvmArithmeticTestsU128, subtractionCarry) uint128_t const c = (uint128_t{ 0x2222000000003333LLU } << 64) + uint128_t{ 0x3333888855558888LLU }; // trace_builder - trace_builder.set(a, 8, AvmMemoryTag::U128); - trace_builder.set(b, 9, AvmMemoryTag::U128); + trace_builder.op_set(0, a, 8, AvmMemoryTag::U128); + trace_builder.op_set(0, b, 9, AvmMemoryTag::U128); trace_builder.op_sub(0, 8, 9, 9, AvmMemoryTag::U128); trace_builder.return_op(0, 0, 0); @@ -1479,8 +1479,8 @@ TEST_F(AvmArithmeticTestsU128, subtractionCarry) TEST_F(AvmArithmeticTestsU128, multiplication) { // trace_builder - trace_builder.set(0x38D64BF685FFBLLU, 0, AvmMemoryTag::U128); - trace_builder.set(0x1F92C762C98DFLLU, 1, AvmMemoryTag::U128); + trace_builder.op_set(0, 0x38D64BF685FFBLLU, 0, AvmMemoryTag::U128); + trace_builder.op_set(0, 0x1F92C762C98DFLLU, 1, AvmMemoryTag::U128); // Integer multiplication output in HEX: 70289AEB0A7DDA0BAE60CA3A5 FF c{ uint256_t{ 0xA7DDA0BAE60CA3A5, 0x70289AEB0, 0, 0 } }; @@ -1518,8 +1518,8 @@ TEST_F(AvmArithmeticTestsU128, multiplicationOverflow) uint128_t const b = (uint128_t{ UINT64_MAX } << 64) + uint128_t{ UINT64_MAX - 3 }; // trace_builder - trace_builder.set(a, 0, AvmMemoryTag::U128); - trace_builder.set(b, 1, AvmMemoryTag::U128); + trace_builder.op_set(0, a, 0, AvmMemoryTag::U128); + trace_builder.op_set(0, b, 1, AvmMemoryTag::U128); trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U128); trace_builder.return_op(0, 0, 0); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp index 37d10a62712f..be42a1d54538 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -147,7 +147,7 @@ void common_validate_bit_op(std::vector const& trace, std::vector gen_mutated_trace_not(FF const& a, FF const& c_mutated, avm_trace::AvmMemoryTag tag) { auto trace_builder = avm_trace::AvmTraceBuilder(); - trace_builder.set(uint128_t{ a }, 0, tag); + trace_builder.op_set(0, uint128_t{ a }, 0, tag); trace_builder.op_not(0, 0, 1, tag); trace_builder.halt(); auto trace = trace_builder.finalize(); @@ -348,7 +348,7 @@ TEST_P(AvmBitwiseTestsNot, ParamTest) { const auto [operands, mem_tag] = GetParam(); const auto [a, output] = operands; - trace_builder.set(a, 0, mem_tag); + trace_builder.op_set(0, a, 0, mem_tag); trace_builder.op_not(0, 0, 1, mem_tag); // [1,254,0,0,....] trace_builder.return_op(0, 0, 0); auto trace = trace_builder.finalize(); @@ -366,8 +366,8 @@ TEST_P(AvmBitwiseTestsAnd, AllAndTest) { const auto [operands, mem_tag] = GetParam(); const auto [a, b, output] = operands; - trace_builder.set(a, 0, mem_tag); - trace_builder.set(b, 1, mem_tag); + trace_builder.op_set(0, a, 0, mem_tag); + trace_builder.op_set(0, b, 1, mem_tag); trace_builder.op_and(0, 0, 1, 2, mem_tag); trace_builder.return_op(0, 2, 1); @@ -387,8 +387,8 @@ TEST_P(AvmBitwiseTestsOr, AllOrTest) { const auto [operands, mem_tag] = GetParam(); const auto [a, b, output] = operands; - trace_builder.set(a, 0, mem_tag); - trace_builder.set(b, 1, mem_tag); + trace_builder.op_set(0, a, 0, mem_tag); + trace_builder.op_set(0, b, 1, mem_tag); trace_builder.op_or(0, 0, 1, 2, mem_tag); trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); @@ -408,8 +408,8 @@ TEST_P(AvmBitwiseTestsXor, AllXorTest) { const auto [operands, mem_tag] = GetParam(); const auto [a, b, output] = operands; - trace_builder.set(a, 0, mem_tag); - trace_builder.set(b, 1, mem_tag); + trace_builder.op_set(0, a, 0, mem_tag); + trace_builder.op_set(0, b, 1, mem_tag); trace_builder.op_xor(0, 0, 1, 2, mem_tag); trace_builder.return_op(0, 2, 1); auto trace = trace_builder.finalize(); @@ -473,8 +473,8 @@ TEST_P(AvmBitwiseNegativeTestsAnd, AllNegativeTests) const auto [operands, mem_tag] = params; const auto [a, b, output] = operands; auto trace_builder = avm_trace::AvmTraceBuilder(); - trace_builder.set(uint128_t{ a }, 0, mem_tag); - trace_builder.set(uint128_t{ b }, 1, mem_tag); + trace_builder.op_set(0, uint128_t{ a }, 0, mem_tag); + trace_builder.op_set(0, uint128_t{ b }, 1, mem_tag); trace_builder.op_and(0, 0, 1, 2, mem_tag); trace_builder.halt(); auto trace = trace_builder.finalize(); @@ -494,8 +494,8 @@ TEST_P(AvmBitwiseNegativeTestsOr, AllNegativeTests) const auto [operands, mem_tag] = params; const auto [a, b, output] = operands; auto trace_builder = avm_trace::AvmTraceBuilder(); - trace_builder.set(uint128_t{ a }, 0, mem_tag); - trace_builder.set(uint128_t{ b }, 1, mem_tag); + trace_builder.op_set(0, uint128_t{ a }, 0, mem_tag); + trace_builder.op_set(0, uint128_t{ b }, 1, mem_tag); trace_builder.op_or(0, 0, 1, 2, mem_tag); trace_builder.halt(); auto trace = trace_builder.finalize(); @@ -514,8 +514,8 @@ TEST_P(AvmBitwiseNegativeTestsXor, AllNegativeTests) const auto [operands, mem_tag] = params; const auto [a, b, output] = operands; auto trace_builder = avm_trace::AvmTraceBuilder(); - trace_builder.set(uint128_t{ a }, 0, mem_tag); - trace_builder.set(uint128_t{ b }, 1, mem_tag); + trace_builder.op_set(0, uint128_t{ a }, 0, mem_tag); + trace_builder.op_set(0, uint128_t{ b }, 1, mem_tag); trace_builder.op_xor(0, 0, 1, 2, mem_tag); trace_builder.halt(); auto trace = trace_builder.finalize(); @@ -532,7 +532,7 @@ TEST_F(AvmBitwiseNegativeTestsFF, UndefinedOverFF) { auto trace_builder = avm_trace::AvmTraceBuilder(); // Triggers a write row 1 of mem_trace and alu_trace - trace_builder.set(10, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 10, 0, AvmMemoryTag::U8); // Triggers a write in row 2 of alu_trace trace_builder.op_not(0, 0, 1, AvmMemoryTag::U8); // Finally, we will have a write in row 3 of the mem_trace to copy the result diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_indirect_mem.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_indirect_mem.test.cpp index e15356d5ae71..c94bdf795f43 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_indirect_mem.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_indirect_mem.test.cpp @@ -26,13 +26,13 @@ class AvmIndirectMemTests : public ::testing::Test { TEST_F(AvmIndirectMemTests, allIndirectAdd) { // Set direct addresses - trace_builder.set(10, 0, AvmMemoryTag::U32); - trace_builder.set(11, 1, AvmMemoryTag::U32); - trace_builder.set(12, 2, AvmMemoryTag::U32); + trace_builder.op_set(0, 10, 0, AvmMemoryTag::U32); + trace_builder.op_set(0, 11, 1, AvmMemoryTag::U32); + trace_builder.op_set(0, 12, 2, AvmMemoryTag::U32); // Set input values - trace_builder.set(100, 10, AvmMemoryTag::U16); - trace_builder.set(101, 11, AvmMemoryTag::U16); + trace_builder.op_set(0, 100, 10, AvmMemoryTag::U16); + trace_builder.op_set(0, 101, 11, AvmMemoryTag::U16); // All indirect flags are encoded as 7 = 1 + 2 + 4 trace_builder.op_add(7, 0, 1, 2, AvmMemoryTag::U16); @@ -74,11 +74,11 @@ TEST_F(AvmIndirectMemTests, allIndirectAdd) TEST_F(AvmIndirectMemTests, indirectOutputSub) { // Set direct output address - trace_builder.set(52, 5, AvmMemoryTag::U32); + trace_builder.op_set(0, 52, 5, AvmMemoryTag::U32); // Set input values - trace_builder.set(600, 50, AvmMemoryTag::U128); - trace_builder.set(500, 51, AvmMemoryTag::U128); + trace_builder.op_set(0, 600, 50, AvmMemoryTag::U128); + trace_builder.op_set(0, 500, 51, AvmMemoryTag::U128); // The indirect flag is encoded as 4 trace_builder.op_sub(4, 50, 51, 5, AvmMemoryTag::U128); @@ -120,11 +120,11 @@ TEST_F(AvmIndirectMemTests, indirectOutputSub) TEST_F(AvmIndirectMemTests, indirectInputAMul) { // Set direct input address for a - trace_builder.set(100, 1000, AvmMemoryTag::U32); + trace_builder.op_set(0, 100, 1000, AvmMemoryTag::U32); // Set input values - trace_builder.set(4, 100, AvmMemoryTag::U64); - trace_builder.set(7, 101, AvmMemoryTag::U64); + trace_builder.op_set(0, 4, 100, AvmMemoryTag::U64); + trace_builder.op_set(0, 7, 101, AvmMemoryTag::U64); // The indirect flag is encoded as 1 trace_builder.op_mul(1, 1000, 101, 102, AvmMemoryTag::U64); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp index f2292cf5cac1..1d933c72c912 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp @@ -37,8 +37,8 @@ class AvmInterTableTests : public ::testing::Test { TEST_F(AvmInterTableTests, tagErrNotCopiedInMain) { // Equality operation on U128 and second operand is of type U16. - trace_builder.set(32, 18, AvmMemoryTag::U128); - trace_builder.set(32, 76, AvmMemoryTag::U16); + trace_builder.op_set(0, 32, 18, AvmMemoryTag::U128); + trace_builder.op_set(0, 32, 76, AvmMemoryTag::U16); trace_builder.op_eq(0, 18, 76, 65, AvmMemoryTag::U128); trace_builder.halt(); auto trace = trace_builder.finalize(); @@ -87,8 +87,8 @@ class AvmPermMainAluNegativeTests : public AvmInterTableTests { { AvmInterTableTests::SetUp(); - trace_builder.set(19, 0, AvmMemoryTag::U64); - trace_builder.set(15, 1, AvmMemoryTag::U64); + trace_builder.op_set(0, 19, 0, AvmMemoryTag::U64); + trace_builder.op_set(0, 15, 1, AvmMemoryTag::U64); trace_builder.op_add(0, 0, 1, 1, AvmMemoryTag::U64); // 19 + 15 = 34 trace_builder.op_add(0, 0, 1, 1, AvmMemoryTag::U64); // 19 + 34 = 53 trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U64); // 19 * 53 = 1007 @@ -187,8 +187,8 @@ class AvmPermMainMemNegativeTests : public AvmInterTableTests { // for c = a - b at arbitray chosen addresses 52 (a), 11 (b), 55 (c). void executeSub(uint128_t const a, uint128_t const b) { - trace_builder.set(a, 52, AvmMemoryTag::U8); - trace_builder.set(b, 11, AvmMemoryTag::U8); + trace_builder.op_set(0, a, 52, AvmMemoryTag::U8); + trace_builder.op_set(0, b, 11, AvmMemoryTag::U8); trace_builder.op_sub(0, 52, 11, 55, AvmMemoryTag::U8); trace_builder.return_op(0, 0, 0); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp index cb66a0f32b2f..3df1d52ac932 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp @@ -25,20 +25,20 @@ class AvmMemOpcodeTests : public ::testing::Test { // TODO(640): The Standard Honk on Grumpkin test suite fails unless the SRS is initialised for every test. void SetUp() override { srs::init_crs_factory("../srs_db/ignition"); }; - void buildTrace(bool indirect, - uint128_t const& val, - uint32_t src_offset, - uint32_t dst_offset, - AvmMemoryTag tag, - uint32_t dir_src_offset = 0, - uint32_t dir_dst_offset = 0) + void build_mov_trace(bool indirect, + uint128_t const& val, + uint32_t src_offset, + uint32_t dst_offset, + AvmMemoryTag tag, + uint32_t dir_src_offset = 0, + uint32_t dir_dst_offset = 0) { if (indirect) { - trace_builder.set(dir_src_offset, src_offset, AvmMemoryTag::U32); - trace_builder.set(dir_dst_offset, dst_offset, AvmMemoryTag::U32); - trace_builder.set(val, dir_src_offset, tag); + trace_builder.op_set(0, dir_src_offset, src_offset, AvmMemoryTag::U32); + trace_builder.op_set(0, dir_dst_offset, dst_offset, AvmMemoryTag::U32); + trace_builder.op_set(0, val, dir_src_offset, tag); } else { - trace_builder.set(val, src_offset, tag); + trace_builder.op_set(0, val, src_offset, tag); } trace_builder.op_mov(indirect ? 3 : 0, src_offset, dst_offset); @@ -46,7 +46,29 @@ class AvmMemOpcodeTests : public ::testing::Test { trace = trace_builder.finalize(); } - void computeIndices(bool indirect) + static std::function gen_matcher(FF clk, uint32_t sub_clk) + { + return [clk, sub_clk](Row r) { return r.avm_mem_clk == clk && r.avm_mem_sub_clk == sub_clk; }; + }; + + void compute_common_indices(FF clk, bool indirect) + { + // Find the memory trace position corresponding to the write sub-operation of register ic. + auto row = + std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_STORE_C)); + ASSERT_TRUE(row != trace.end()); + mem_c_idx = static_cast(row - trace.begin()); + + // Find the memory trace position of the indirect load for register ic. + if (indirect) { + row = std::ranges::find_if( + trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_IND_LOAD_C)); + ASSERT_TRUE(row != trace.end()); + mem_ind_c_idx = static_cast(row - trace.begin()); + } + } + + void compute_mov_indices(bool indirect) { // Find the first row enabling the MOV selector auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_mov == FF(1); }); @@ -55,41 +77,31 @@ class AvmMemOpcodeTests : public ::testing::Test { auto clk = row->avm_main_clk; - auto gen_matcher = [clk](uint32_t sub_clk) { - return [clk, sub_clk](Row r) { return r.avm_mem_clk == clk && r.avm_mem_sub_clk == sub_clk; }; - }; - // Find the memory trace position corresponding to the load sub-operation of register ia. - row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(AvmMemTraceBuilder::SUB_CLK_LOAD_A)); + row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_LOAD_A)); ASSERT_TRUE(row != trace.end()); mem_a_idx = static_cast(row - trace.begin()); - // Find the memory trace position corresponding to the write sub-operation of register ic. - row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(AvmMemTraceBuilder::SUB_CLK_STORE_C)); - ASSERT_TRUE(row != trace.end()); - mem_c_idx = static_cast(row - trace.begin()); - - // Find the memory trace position of the indirect loads. + // Find the memory trace position of the indirect load for register ia. if (indirect) { - row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(AvmMemTraceBuilder::SUB_CLK_IND_LOAD_A)); + row = std::ranges::find_if( + trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_IND_LOAD_A)); ASSERT_TRUE(row != trace.end()); mem_ind_a_idx = static_cast(row - trace.begin()); - - row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(AvmMemTraceBuilder::SUB_CLK_IND_LOAD_C)); - ASSERT_TRUE(row != trace.end()); - mem_ind_c_idx = static_cast(row - trace.begin()); } + + compute_common_indices(clk, indirect); } - void validate_trace(bool indirect, - uint128_t const& val, - uint32_t src_offset, - uint32_t dst_offset, - AvmMemoryTag tag, - uint32_t dir_src_offset = 0, - uint32_t dir_dst_offset = 0) + void validate_mov_trace(bool indirect, + uint128_t const& val, + uint32_t src_offset, + uint32_t dst_offset, + AvmMemoryTag tag, + uint32_t dir_src_offset = 0, + uint32_t dir_dst_offset = 0) { - computeIndices(indirect); + compute_mov_indices(indirect); FF const val_ff = uint256_t::from_uint128(val); auto const& main_row = trace.at(main_idx); @@ -161,55 +173,55 @@ class AvmMemOpcodeNegativeTests : public AvmMemOpcodeTests {}; TEST_F(AvmMemOpcodeTests, basicMov) { - buildTrace(false, 42, 9, 13, AvmMemoryTag::U64); - validate_trace(false, 42, 9, 13, AvmMemoryTag::U64); + build_mov_trace(false, 42, 9, 13, AvmMemoryTag::U64); + validate_mov_trace(false, 42, 9, 13, AvmMemoryTag::U64); } TEST_F(AvmMemOpcodeTests, sameAddressMov) { - buildTrace(false, 11, 356, 356, AvmMemoryTag::U16); - validate_trace(false, 11, 356, 356, AvmMemoryTag::U16); + build_mov_trace(false, 11, 356, 356, AvmMemoryTag::U16); + validate_mov_trace(false, 11, 356, 356, AvmMemoryTag::U16); } TEST_F(AvmMemOpcodeTests, uninitializedValueMov) { auto trace_builder = AvmTraceBuilder(); - trace_builder.set(4, 1, AvmMemoryTag::U32); + trace_builder.op_set(0, 4, 1, AvmMemoryTag::U32); trace_builder.op_mov(0, 0, 1); trace_builder.return_op(0, 0, 0); trace = trace_builder.finalize(); - validate_trace(false, 0, 0, 1, AvmMemoryTag::U0); + validate_mov_trace(false, 0, 0, 1, AvmMemoryTag::U0); } TEST_F(AvmMemOpcodeTests, indUninitializedValueMov) { auto trace_builder = AvmTraceBuilder(); - trace_builder.set(1, 3, AvmMemoryTag::U32); - trace_builder.set(4, 1, AvmMemoryTag::U32); + trace_builder.op_set(0, 1, 3, AvmMemoryTag::U32); + trace_builder.op_set(0, 4, 1, AvmMemoryTag::U32); trace_builder.op_mov(3, 2, 3); trace_builder.return_op(0, 0, 0); trace = trace_builder.finalize(); - validate_trace(true, 0, 2, 3, AvmMemoryTag::U0, 0, 1); + validate_mov_trace(true, 0, 2, 3, AvmMemoryTag::U0, 0, 1); } TEST_F(AvmMemOpcodeTests, indirectMov) { - buildTrace(true, 23, 0, 1, AvmMemoryTag::U8, 2, 3); - validate_trace(true, 23, 0, 1, AvmMemoryTag::U8, 2, 3); + build_mov_trace(true, 23, 0, 1, AvmMemoryTag::U8, 2, 3); + validate_mov_trace(true, 23, 0, 1, AvmMemoryTag::U8, 2, 3); } TEST_F(AvmMemOpcodeTests, indirectMovInvalidAddressTag) { - trace_builder.set(15, 100, AvmMemoryTag::U32); - trace_builder.set(16, 101, AvmMemoryTag::U128); // This will make the indirect load failing. - trace_builder.set(5, 15, AvmMemoryTag::FF); + trace_builder.op_set(0, 15, 100, AvmMemoryTag::U32); + trace_builder.op_set(0, 16, 101, AvmMemoryTag::U128); // This will make the indirect load failing. + trace_builder.op_set(0, 5, 15, AvmMemoryTag::FF); trace_builder.op_mov(3, 100, 101); trace_builder.return_op(0, 0, 0); trace = trace_builder.finalize(); - computeIndices(true); + compute_mov_indices(true); EXPECT_EQ(trace.at(main_idx).avm_main_tag_err, 1); EXPECT_THAT(trace.at(mem_ind_c_idx), @@ -221,6 +233,103 @@ TEST_F(AvmMemOpcodeTests, indirectMovInvalidAddressTag) validate_trace_proof(std::move(trace)); } +TEST_F(AvmMemOpcodeTests, directSet) +{ + trace_builder.op_set(0, 5683, 99, AvmMemoryTag::U128); + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_common_indices(0, false); + auto const& row = trace.at(1); + + EXPECT_THAT(row, + AllOf(Field(&Row::avm_main_tag_err, 0), + Field(&Row::avm_main_ic, 5683), + Field(&Row::avm_main_mem_idx_c, 99), + Field(&Row::avm_main_mem_op_c, 1), + Field(&Row::avm_main_rwc, 1), + Field(&Row::avm_main_ind_op_c, 0))); + + EXPECT_THAT(trace.at(mem_c_idx), + AllOf(Field(&Row::avm_mem_val, 5683), + Field(&Row::avm_mem_addr, 99), + Field(&Row::avm_mem_op_c, 1), + Field(&Row::avm_mem_rw, 1), + Field(&Row::avm_mem_ind_op_c, 0))); + + validate_trace_proof(std::move(trace)); +} + +TEST_F(AvmMemOpcodeTests, indirectSet) +{ + trace_builder.op_set(0, 100, 10, AvmMemoryTag::U32); + trace_builder.op_set(1, 1979, 10, AvmMemoryTag::U64); // Set 1979 at memory index 100 + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_common_indices(1, true); + auto const& row = trace.at(2); + + EXPECT_THAT(row, + AllOf(Field(&Row::avm_main_tag_err, 0), + Field(&Row::avm_main_ic, 1979), + Field(&Row::avm_main_mem_idx_c, 100), + Field(&Row::avm_main_mem_op_c, 1), + Field(&Row::avm_main_rwc, 1), + Field(&Row::avm_main_ind_op_c, 1), + Field(&Row::avm_main_ind_c, 10))); + + EXPECT_THAT(trace.at(mem_c_idx), + AllOf(Field(&Row::avm_mem_val, 1979), + Field(&Row::avm_mem_addr, 100), + Field(&Row::avm_mem_op_c, 1), + Field(&Row::avm_mem_rw, 1), + Field(&Row::avm_mem_ind_op_c, 0), + Field(&Row::avm_mem_w_in_tag, static_cast(AvmMemoryTag::U64)), + Field(&Row::avm_mem_tag, static_cast(AvmMemoryTag::U64)))); + + EXPECT_THAT(trace.at(mem_ind_c_idx), + AllOf(Field(&Row::avm_mem_val, 100), + Field(&Row::avm_mem_addr, 10), + Field(&Row::avm_mem_op_c, 0), + Field(&Row::avm_mem_rw, 0), + Field(&Row::avm_mem_ind_op_c, 1), + Field(&Row::avm_mem_r_in_tag, static_cast(AvmMemoryTag::U32)), + Field(&Row::avm_mem_tag, static_cast(AvmMemoryTag::U32)))); + + validate_trace_proof(std::move(trace)); +} + +TEST_F(AvmMemOpcodeTests, indirectSetWrongTag) +{ + trace_builder.op_set(0, 100, 10, AvmMemoryTag::U8); // The address 100 has incorrect tag U8. + trace_builder.op_set(1, 1979, 10, AvmMemoryTag::U64); // Set 1979 at memory index 100 + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_common_indices(1, true); + auto const& row = trace.at(2); + + EXPECT_THAT(row, + AllOf(Field(&Row::avm_main_tag_err, 1), + Field(&Row::avm_main_mem_op_c, 1), + Field(&Row::avm_main_rwc, 1), + Field(&Row::avm_main_ind_op_c, 1), + Field(&Row::avm_main_ind_c, 10))); + + EXPECT_THAT(trace.at(mem_ind_c_idx), + AllOf(Field(&Row::avm_mem_val, 100), + Field(&Row::avm_mem_addr, 10), + Field(&Row::avm_mem_op_c, 0), + Field(&Row::avm_mem_rw, 0), + Field(&Row::avm_mem_ind_op_c, 1), + Field(&Row::avm_mem_r_in_tag, static_cast(AvmMemoryTag::U32)), + Field(&Row::avm_mem_tag, static_cast(AvmMemoryTag::U8)), + Field(&Row::avm_mem_tag_err, 1))); + + validate_trace_proof(std::move(trace)); +} + /****************************************************************************** * * MEMORY OPCODE NEGATIVE TESTS @@ -229,8 +338,8 @@ TEST_F(AvmMemOpcodeTests, indirectMovInvalidAddressTag) TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputErrorTag) { - buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); - computeIndices(false); + build_mov_trace(false, 234, 0, 1, AvmMemoryTag::U8); + compute_mov_indices(false); trace.at(main_idx).avm_main_tag_err = 1; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "INCL_MEM_TAG_ERR"); @@ -238,8 +347,8 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputErrorTag) TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputValue) { - buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); - computeIndices(false); + build_mov_trace(false, 234, 0, 1, AvmMemoryTag::U8); + compute_mov_indices(false); trace.at(main_idx).avm_main_ic = 233; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "MOV_SAME_VALUE"); @@ -247,8 +356,8 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputValue) TEST_F(AvmMemOpcodeNegativeTests, indMovWrongOutputValue) { - buildTrace(true, 8732, 23, 24, AvmMemoryTag::U16, 432, 876); - computeIndices(true); + build_mov_trace(true, 8732, 23, 24, AvmMemoryTag::U16, 432, 876); + compute_mov_indices(true); trace.at(main_idx).avm_main_ic = 8733; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "MOV_SAME_VALUE"); @@ -264,8 +373,8 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagLoadIa) FF const tag_u8 = FF(static_cast(AvmMemoryTag::U8)); FF const one_min_inverse_diff = FF(1) - (tag_u64 - tag_u8).invert(); - buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); - computeIndices(false); + build_mov_trace(false, 234, 0, 1, AvmMemoryTag::U8); + compute_mov_indices(false); auto trace_tmp = trace; @@ -289,8 +398,8 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagDisabledSelector) FF const tag_u8 = FF(static_cast(AvmMemoryTag::U8)); FF const one_min_inverse_diff = FF(1) - (tag_u64 - tag_u8).invert(); - buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); - computeIndices(false); + build_mov_trace(false, 234, 0, 1, AvmMemoryTag::U8); + compute_mov_indices(false); trace.at(mem_a_idx).avm_mem_r_in_tag = tag_u64; trace.at(mem_a_idx).avm_mem_w_in_tag = tag_u64; @@ -313,8 +422,8 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagInMainTrace) { FF const tag_u64 = FF(static_cast(AvmMemoryTag::U64)); - buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); - computeIndices(false); + build_mov_trace(false, 234, 0, 1, AvmMemoryTag::U8); + compute_mov_indices(false); trace.at(mem_c_idx).avm_mem_tag = tag_u64; trace.at(mem_c_idx).avm_mem_w_in_tag = tag_u64; @@ -329,8 +438,8 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagMainTraceRead) { FF const tag_u64 = FF(static_cast(AvmMemoryTag::U64)); - buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); - computeIndices(false); + build_mov_trace(false, 234, 0, 1, AvmMemoryTag::U8); + compute_mov_indices(false); trace.at(mem_c_idx).avm_mem_tag = tag_u64; trace.at(mem_c_idx).avm_mem_w_in_tag = tag_u64; diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp index a4f8ae95e1e1..ae48b0e20a2b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp @@ -76,8 +76,8 @@ TEST_F(AvmMemoryTests, mismatchedTagAddOperation) // The proof must pass and we check that the AVM error is raised. TEST_F(AvmMemoryTests, mismatchedTagEqOperation) { - trace_builder.set(3, 0, AvmMemoryTag::U32); - trace_builder.set(5, 1, AvmMemoryTag::U16); + trace_builder.op_set(0, 3, 0, AvmMemoryTag::U32); + trace_builder.op_set(0, 5, 1, AvmMemoryTag::U16); trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U32); trace_builder.halt(); @@ -119,8 +119,8 @@ TEST_F(AvmMemoryTests, mismatchedTagEqOperation) // in the memory trace TEST_F(AvmMemoryTests, mLastAccessViolation) { - trace_builder.set(4, 0, AvmMemoryTag::U8); - trace_builder.set(9, 1, AvmMemoryTag::U8); + trace_builder.op_set(0, 4, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 9, 1, AvmMemoryTag::U8); // Memory layout: [4,9,0,0,0,0,....] trace_builder.op_sub(0, 1, 0, 2, AvmMemoryTag::U8); // [4,9,5,0,0,0.....] @@ -150,8 +150,8 @@ TEST_F(AvmMemoryTests, mLastAccessViolation) // written into memory TEST_F(AvmMemoryTests, readWriteConsistencyValViolation) { - trace_builder.set(4, 0, AvmMemoryTag::U8); - trace_builder.set(9, 1, AvmMemoryTag::U8); + trace_builder.op_set(0, 4, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 9, 1, AvmMemoryTag::U8); // Memory layout: [4,9,0,0,0,0,....] trace_builder.op_mul(0, 1, 0, 2, AvmMemoryTag::U8); // [4,9,36,0,0,0.....] @@ -180,8 +180,8 @@ TEST_F(AvmMemoryTests, readWriteConsistencyValViolation) // written into memory TEST_F(AvmMemoryTests, readWriteConsistencyTagViolation) { - trace_builder.set(4, 0, AvmMemoryTag::U8); - trace_builder.set(9, 1, AvmMemoryTag::U8); + trace_builder.op_set(0, 4, 0, AvmMemoryTag::U8); + trace_builder.op_set(0, 9, 1, AvmMemoryTag::U8); // Memory layout: [4,9,0,0,0,0,....] trace_builder.op_mul(0, 1, 0, 2, AvmMemoryTag::U8); // [4,9,36,0,0,0.....]