From b1b2e7ca28ba56cf0bae0f906734df00458714b9 Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:45:48 +0000 Subject: [PATCH] feat(avm): add standalone jump opcode (#3781) - Add missing check that program counter advanced in call opcode ( oops ) - Moved return storing to intermediate register b - jump dest goes on register a - Implement trivial jump opcode ( subset of call ) --- barretenberg/cpp/pil/avm/avm_mini.pil | 39 ++-- barretenberg/cpp/pil/avm/avm_mini_opt.pil | 68 ------- .../flavor/generated/AvmMini_flavor.hpp | 49 ++--- .../circuit_builder/AvmMini_trace.cpp | 35 +++- .../circuit_builder/AvmMini_trace.hpp | 3 + .../generated/AvmMini_circuit_builder.hpp | 30 +-- .../relations/generated/AvmMini/avm_mini.hpp | 177 ++++++++++-------- .../generated/AvmMini/declare_views.hpp | 9 +- .../relations/generated/AvmMini/mem_trace.hpp | 30 +-- .../vm/generated/AvmMini_verifier.cpp | 2 + .../vm/tests/AvmMini_control_flow.test.cpp | 78 ++++++-- 11 files changed, 289 insertions(+), 231 deletions(-) delete mode 100644 barretenberg/cpp/pil/avm/avm_mini_opt.pil diff --git a/barretenberg/cpp/pil/avm/avm_mini.pil b/barretenberg/cpp/pil/avm/avm_mini.pil index b2e10e30cca..cd3fb8f29e4 100644 --- a/barretenberg/cpp/pil/avm/avm_mini.pil +++ b/barretenberg/cpp/pil/avm/avm_mini.pil @@ -16,6 +16,7 @@ namespace avmMini(256); pol commit sel_internal_call; pol commit sel_internal_return; + pol commit sel_jump; // Halt program execution pol commit sel_halt; @@ -80,6 +81,7 @@ namespace avmMini(256); sel_internal_call * (1 - sel_internal_call) = 0; sel_internal_return * (1 - sel_internal_return) = 0; + sel_jump * (1 - sel_jump) = 0; sel_halt * (1 - sel_halt) = 0; op_err * (1 - op_err) = 0; @@ -147,25 +149,32 @@ namespace avmMini(256); // This works in combination with op_div_err * (sel_op_div - 1) = 0; // Drawback is the need to paralllelize the latter. + //===== CONTROL FLOW ======================================================= + //===== JUMP =============================================================== + sel_jump * (pc' - ia) = 0; - //===== CALL_RETURN ======================================================== - // The program counter in the next row should be equal to the value loaded from the ia register - // This implies that a load from memory must occur at the same time - // Imply that we must load the return location into mem_idx_a + //===== INTERNAL_CALL ====================================================== + // - The program counter in the next row should be equal to the value loaded from the ia register + // - We then write the return location (pc + 1) into the call stack (in memory) #[RETURN_POINTER_INCREMENT] - sel_internal_call * ( internal_return_ptr' - ( internal_return_ptr + 1)) = 0; - sel_internal_call * ( internal_return_ptr - mem_idx_a) = 0; - sel_internal_call * ((pc + 1) - ia) = 0; - + sel_internal_call * (internal_return_ptr' - (internal_return_ptr + 1)) = 0; + sel_internal_call * (internal_return_ptr - mem_idx_b) = 0; + sel_internal_call * (pc' - ia) = 0; + sel_internal_call * ((pc + 1) - ib) = 0; + // TODO(md): Below relations may be removed through sub-op table lookup - sel_internal_call * (rwa - 1) = 0; - sel_internal_call * (mem_op_a - 1) = 0; + sel_internal_call * (rwb - 1) = 0; + sel_internal_call * (mem_op_b - 1) = 0; - // We must load the memory pointer to be the internal_return_ptr + //===== INTERNAL_RETURN =================================================== + // - We load the memory pointer to be the internal_return_ptr + // - Constrain then next program counter to be the loaded value + // - decrement the internal_return_ptr + #[RETURN_POINTER_DECREMENT] - sel_internal_return * ( internal_return_ptr' - ( internal_return_ptr - 1)) = 0; - sel_internal_return * ( (internal_return_ptr - 1) - mem_idx_a) = 0; + sel_internal_return * (internal_return_ptr' - (internal_return_ptr - 1)) = 0; + sel_internal_return * ((internal_return_ptr - 1) - mem_idx_a) = 0; sel_internal_return * (pc' - ia) = 0; // TODO(md): Below relations may be removed through sub-op table lookup @@ -173,7 +182,7 @@ namespace avmMini(256); sel_internal_return * (mem_op_a - 1) = 0; //===== CONTROL_FLOW_CONSISTENCY ============================================ - pol CONTROL_FLOW_SELECTORS = (first + sel_internal_call + sel_internal_return + sel_halt); + pol INTERNAL_CALL_STACK_SELECTORS = (first + sel_internal_call + sel_internal_return + sel_halt); pol OPCODE_SELECTORS = (sel_op_add + sel_op_sub + sel_op_div + sel_op_mul); // Program counter must increment if not jumping or returning @@ -182,7 +191,7 @@ namespace avmMini(256); // first == 0 && sel_internal_call == 0 && sel_internal_return == 0 && sel_halt == 0 ==> internal_return_ptr == internal_return_ptr' #[INTERNAL_RETURN_POINTER_CONSISTENCY] - (1 - CONTROL_FLOW_SELECTORS) * (internal_return_ptr' - internal_return_ptr) = 0; + (1 - INTERNAL_CALL_STACK_SELECTORS) * (internal_return_ptr' - internal_return_ptr) = 0; // TODO: we want to set an initial number for the reserved memory of the jump pointer diff --git a/barretenberg/cpp/pil/avm/avm_mini_opt.pil b/barretenberg/cpp/pil/avm/avm_mini_opt.pil deleted file mode 100644 index f3a75411a99..00000000000 --- a/barretenberg/cpp/pil/avm/avm_mini_opt.pil +++ /dev/null @@ -1,68 +0,0 @@ -namespace memTrace(256); - col witness m_clk; - col witness m_sub_clk; - col witness m_addr; - col witness m_tag; - col witness m_val; - col witness m_lastAccess; - col witness m_last; - col witness m_rw; - col witness m_in_tag; - col witness m_tag_err; - col witness m_one_min_inv; - (memTrace.m_lastAccess * (1 - memTrace.m_lastAccess)) = 0; - (memTrace.m_last * (1 - memTrace.m_last)) = 0; - (memTrace.m_rw * (1 - memTrace.m_rw)) = 0; - (memTrace.m_tag_err * (1 - memTrace.m_tag_err)) = 0; - ((1 - memTrace.m_lastAccess) * (memTrace.m_addr' - memTrace.m_addr)) = 0; - (((1 - memTrace.m_lastAccess) * (1 - memTrace.m_rw')) * (memTrace.m_val' - memTrace.m_val)) = 0; - (((1 - memTrace.m_lastAccess) * (1 - memTrace.m_rw')) * (memTrace.m_tag' - memTrace.m_tag)) = 0; - ((memTrace.m_lastAccess * (1 - memTrace.m_rw')) * memTrace.m_val') = 0; - ((memTrace.m_in_tag - memTrace.m_tag) * (1 - memTrace.m_one_min_inv)) = memTrace.m_tag_err; - ((1 - memTrace.m_tag_err) * memTrace.m_one_min_inv) = 0; -namespace avmMini(256); - col fixed clk(i) { i }; - col fixed first = [1] + [0]*; - col witness sel_op_add; - col witness sel_op_sub; - col witness sel_op_mul; - col witness sel_op_div; - col witness in_tag; - col witness op_err; - col witness tag_err; - col witness inv; - col witness ia; - col witness ib; - col witness ic; - col witness mem_op_a; - col witness mem_op_b; - col witness mem_op_c; - col witness rwa; - col witness rwb; - col witness rwc; - col witness mem_idx_a; - col witness mem_idx_b; - col witness mem_idx_c; - col witness last; - (avmMini.sel_op_add * (1 - avmMini.sel_op_add)) = 0; - (avmMini.sel_op_sub * (1 - avmMini.sel_op_sub)) = 0; - (avmMini.sel_op_mul * (1 - avmMini.sel_op_mul)) = 0; - (avmMini.sel_op_div * (1 - avmMini.sel_op_div)) = 0; - (avmMini.op_err * (1 - avmMini.op_err)) = 0; - (avmMini.tag_err * (1 - avmMini.tag_err)) = 0; - (avmMini.mem_op_a * (1 - avmMini.mem_op_a)) = 0; - (avmMini.mem_op_b * (1 - avmMini.mem_op_b)) = 0; - (avmMini.mem_op_c * (1 - avmMini.mem_op_c)) = 0; - (avmMini.rwa * (1 - avmMini.rwa)) = 0; - (avmMini.rwb * (1 - avmMini.rwb)) = 0; - (avmMini.rwc * (1 - avmMini.rwc)) = 0; - (avmMini.tag_err * avmMini.ia) = 0; - (avmMini.tag_err * avmMini.ib) = 0; - (avmMini.tag_err * avmMini.ic) = 0; - (avmMini.sel_op_add * ((avmMini.ia + avmMini.ib) - avmMini.ic)) = 0; - (avmMini.sel_op_sub * ((avmMini.ia - avmMini.ib) - avmMini.ic)) = 0; - (avmMini.sel_op_mul * ((avmMini.ia * avmMini.ib) - avmMini.ic)) = 0; - ((avmMini.sel_op_div * (1 - avmMini.op_err)) * ((avmMini.ic * avmMini.ib) - avmMini.ia)) = 0; - (avmMini.sel_op_div * (((avmMini.ib * avmMini.inv) - 1) + avmMini.op_err)) = 0; - ((avmMini.sel_op_div * avmMini.op_err) * (1 - avmMini.inv)) = 0; - (avmMini.op_err * (avmMini.sel_op_div - 1)) = 0; diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp index d9b5edb8c61..9240275729e 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp @@ -36,13 +36,13 @@ class AvmMiniFlavor { using VerifierCommitmentKey = pcs::VerifierCommitmentKey; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 37; + static constexpr size_t NUM_WITNESS_ENTITIES = 38; 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 = 45; + static constexpr size_t NUM_ALL_ENTITIES = 46; - using Relations = std::tuple, AvmMini_vm::mem_trace>; + using Relations = std::tuple, AvmMini_vm::avm_mini>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -91,6 +91,7 @@ class AvmMiniFlavor { avmMini_internal_return_ptr, avmMini_sel_internal_call, avmMini_sel_internal_return, + avmMini_sel_jump, avmMini_sel_halt, avmMini_sel_op_add, avmMini_sel_op_sub, @@ -131,6 +132,7 @@ class AvmMiniFlavor { avmMini_internal_return_ptr, avmMini_sel_internal_call, avmMini_sel_internal_return, + avmMini_sel_jump, avmMini_sel_halt, avmMini_sel_op_add, avmMini_sel_op_sub, @@ -177,6 +179,7 @@ class AvmMiniFlavor { avmMini_internal_return_ptr, avmMini_sel_internal_call, avmMini_sel_internal_return, + avmMini_sel_jump, avmMini_sel_halt, avmMini_sel_op_add, avmMini_sel_op_sub, @@ -199,12 +202,12 @@ class AvmMiniFlavor { avmMini_mem_idx_b, avmMini_mem_idx_c, avmMini_last, - avmMini_internal_return_ptr_shift, - avmMini_pc_shift, - memTrace_m_tag_shift, memTrace_m_val_shift, + memTrace_m_addr_shift, + memTrace_m_tag_shift, memTrace_m_rw_shift, - memTrace_m_addr_shift) + avmMini_internal_return_ptr_shift, + avmMini_pc_shift) RefVector get_wires() { @@ -225,6 +228,7 @@ class AvmMiniFlavor { avmMini_internal_return_ptr, avmMini_sel_internal_call, avmMini_sel_internal_return, + avmMini_sel_jump, avmMini_sel_halt, avmMini_sel_op_add, avmMini_sel_op_sub, @@ -247,12 +251,12 @@ class AvmMiniFlavor { avmMini_mem_idx_b, avmMini_mem_idx_c, avmMini_last, - avmMini_internal_return_ptr_shift, - avmMini_pc_shift, - memTrace_m_tag_shift, memTrace_m_val_shift, + memTrace_m_addr_shift, + memTrace_m_tag_shift, memTrace_m_rw_shift, - memTrace_m_addr_shift }; + avmMini_internal_return_ptr_shift, + avmMini_pc_shift }; }; RefVector get_unshifted() { @@ -273,6 +277,7 @@ class AvmMiniFlavor { avmMini_internal_return_ptr, avmMini_sel_internal_call, avmMini_sel_internal_return, + avmMini_sel_jump, avmMini_sel_halt, avmMini_sel_op_add, avmMini_sel_op_sub, @@ -298,18 +303,17 @@ class AvmMiniFlavor { }; RefVector get_to_be_shifted() { - return { - avmMini_internal_return_ptr, avmMini_pc, memTrace_m_tag, memTrace_m_val, memTrace_m_rw, memTrace_m_addr - }; + return { memTrace_m_val, memTrace_m_addr, memTrace_m_tag, memTrace_m_rw, avmMini_internal_return_ptr, + avmMini_pc }; }; RefVector get_shifted() { - return { avmMini_internal_return_ptr_shift, - avmMini_pc_shift, + return { memTrace_m_val_shift, + memTrace_m_addr_shift, memTrace_m_tag_shift, - memTrace_m_val_shift, memTrace_m_rw_shift, - memTrace_m_addr_shift }; + avmMini_internal_return_ptr_shift, + avmMini_pc_shift }; }; }; @@ -322,9 +326,8 @@ class AvmMiniFlavor { RefVector get_to_be_shifted() { - return { - avmMini_internal_return_ptr, avmMini_pc, memTrace_m_tag, memTrace_m_val, memTrace_m_rw, memTrace_m_addr - }; + return { memTrace_m_val, memTrace_m_addr, memTrace_m_tag, memTrace_m_rw, avmMini_internal_return_ptr, + avmMini_pc }; }; // The plookup wires that store plookup read data. @@ -418,6 +421,7 @@ class AvmMiniFlavor { Base::avmMini_internal_return_ptr = "AVMMINI_INTERNAL_RETURN_PTR"; Base::avmMini_sel_internal_call = "AVMMINI_SEL_INTERNAL_CALL"; Base::avmMini_sel_internal_return = "AVMMINI_SEL_INTERNAL_RETURN"; + Base::avmMini_sel_jump = "AVMMINI_SEL_JUMP"; Base::avmMini_sel_halt = "AVMMINI_SEL_HALT"; Base::avmMini_sel_op_add = "AVMMINI_SEL_OP_ADD"; Base::avmMini_sel_op_sub = "AVMMINI_SEL_OP_SUB"; @@ -474,6 +478,7 @@ class AvmMiniFlavor { Commitment avmMini_internal_return_ptr; Commitment avmMini_sel_internal_call; Commitment avmMini_sel_internal_return; + Commitment avmMini_sel_jump; Commitment avmMini_sel_halt; Commitment avmMini_sel_op_add; Commitment avmMini_sel_op_sub; @@ -530,6 +535,7 @@ class AvmMiniFlavor { avmMini_internal_return_ptr = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); avmMini_sel_internal_call = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); avmMini_sel_internal_return = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); + avmMini_sel_jump = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); avmMini_sel_halt = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); avmMini_sel_op_add = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); avmMini_sel_op_sub = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); @@ -590,6 +596,7 @@ class AvmMiniFlavor { serialize_to_buffer(avmMini_internal_return_ptr, Transcript::proof_data); serialize_to_buffer(avmMini_sel_internal_call, Transcript::proof_data); serialize_to_buffer(avmMini_sel_internal_return, Transcript::proof_data); + serialize_to_buffer(avmMini_sel_jump, Transcript::proof_data); serialize_to_buffer(avmMini_sel_halt, Transcript::proof_data); serialize_to_buffer(avmMini_sel_op_add, Transcript::proof_data); serialize_to_buffer(avmMini_sel_op_sub, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.cpp index 9c6721160f8..308724f2e16 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.cpp @@ -566,6 +566,30 @@ void AvmMiniTraceBuilder::halt() }); } +/** + * @brief JUMP OPCODE + * Jumps to a new `jmpDest` + * This function must: + * - Set the next program counter to the provided `jmpDest`. + * + * @param jmpDest - The destination to jump to + */ +void AvmMiniTraceBuilder::jump(uint32_t jmpDest) +{ + auto clk = mainTrace.size(); + + mainTrace.push_back(Row{ + .avmMini_clk = clk, + .avmMini_pc = FF(pc), + .avmMini_internal_return_ptr = FF(internal_return_ptr), + .avmMini_sel_jump = FF(1), + .avmMini_ia = FF(jmpDest), + }); + + // Adjust parameters for the next row + pc = jmpDest; +} + /** * @brief INTERNAL_CALL OPCODE * This opcode effectively jumps to a new `jmpDest` and stores the return program counter @@ -588,7 +612,7 @@ void AvmMiniTraceBuilder::internal_call(uint32_t jmpDest) internal_call_stack.push(stored_pc); // Add the return location to the memory trace - storeInMemTrace(IntermRegister::ia, internal_return_ptr, FF(stored_pc), AvmMemoryTag::ff); + storeInMemTrace(IntermRegister::ib, internal_return_ptr, FF(stored_pc), AvmMemoryTag::ff); memory.at(internal_return_ptr) = stored_pc; mainTrace.push_back(Row{ @@ -596,10 +620,11 @@ void AvmMiniTraceBuilder::internal_call(uint32_t jmpDest) .avmMini_pc = FF(pc), .avmMini_internal_return_ptr = FF(internal_return_ptr), .avmMini_sel_internal_call = FF(1), - .avmMini_ia = stored_pc, - .avmMini_mem_op_a = FF(1), - .avmMini_rwa = FF(1), - .avmMini_mem_idx_a = FF(internal_return_ptr), + .avmMini_ia = FF(jmpDest), + .avmMini_ib = stored_pc, + .avmMini_mem_op_b = FF(1), + .avmMini_rwb = FF(1), + .avmMini_mem_idx_b = FF(internal_return_ptr), }); // Adjust parameters for the next row diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.hpp index f7dd66f3b3e..0185d76cf97 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.hpp @@ -60,6 +60,9 @@ class AvmMiniTraceBuilder { void div(uint32_t aOffset, uint32_t bOffset, uint32_t dstOffset, AvmMemoryTag inTag); // Jump to a given program counter. + void jump(uint32_t jmpDest); + + // Jump to a given program counter; storing the return location on a call stack. // TODO(md): this program counter MUST be an operand to the OPCODE. void internal_call(uint32_t jmpDest); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp index a41fb694b9c..bd32d969d15 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp @@ -36,6 +36,7 @@ template struct AvmMiniFullRow { FF avmMini_internal_return_ptr{}; FF avmMini_sel_internal_call{}; FF avmMini_sel_internal_return{}; + FF avmMini_sel_jump{}; FF avmMini_sel_halt{}; FF avmMini_sel_op_add{}; FF avmMini_sel_op_sub{}; @@ -58,12 +59,12 @@ template struct AvmMiniFullRow { FF avmMini_mem_idx_b{}; FF avmMini_mem_idx_c{}; FF avmMini_last{}; - FF avmMini_internal_return_ptr_shift{}; - FF avmMini_pc_shift{}; - FF memTrace_m_tag_shift{}; FF memTrace_m_val_shift{}; - FF memTrace_m_rw_shift{}; FF memTrace_m_addr_shift{}; + FF memTrace_m_tag_shift{}; + FF memTrace_m_rw_shift{}; + FF avmMini_internal_return_ptr_shift{}; + FF avmMini_pc_shift{}; }; class AvmMiniCircuitBuilder { @@ -76,8 +77,8 @@ class AvmMiniCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 45; - static constexpr size_t num_polys = 39; + static constexpr size_t num_fixed_columns = 46; + static constexpr size_t num_polys = 40; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -110,6 +111,7 @@ class AvmMiniCircuitBuilder { polys.avmMini_internal_return_ptr[i] = rows[i].avmMini_internal_return_ptr; polys.avmMini_sel_internal_call[i] = rows[i].avmMini_sel_internal_call; polys.avmMini_sel_internal_return[i] = rows[i].avmMini_sel_internal_return; + polys.avmMini_sel_jump[i] = rows[i].avmMini_sel_jump; polys.avmMini_sel_halt[i] = rows[i].avmMini_sel_halt; polys.avmMini_sel_op_add[i] = rows[i].avmMini_sel_op_add; polys.avmMini_sel_op_sub[i] = rows[i].avmMini_sel_op_sub; @@ -134,12 +136,12 @@ class AvmMiniCircuitBuilder { polys.avmMini_last[i] = rows[i].avmMini_last; } - polys.avmMini_internal_return_ptr_shift = Polynomial(polys.avmMini_internal_return_ptr.shifted()); - polys.avmMini_pc_shift = Polynomial(polys.avmMini_pc.shifted()); - polys.memTrace_m_tag_shift = Polynomial(polys.memTrace_m_tag.shifted()); polys.memTrace_m_val_shift = Polynomial(polys.memTrace_m_val.shifted()); - polys.memTrace_m_rw_shift = Polynomial(polys.memTrace_m_rw.shifted()); polys.memTrace_m_addr_shift = Polynomial(polys.memTrace_m_addr.shifted()); + polys.memTrace_m_tag_shift = Polynomial(polys.memTrace_m_tag.shifted()); + polys.memTrace_m_rw_shift = Polynomial(polys.memTrace_m_rw.shifted()); + polys.avmMini_internal_return_ptr_shift = Polynomial(polys.avmMini_internal_return_ptr.shifted()); + polys.avmMini_pc_shift = Polynomial(polys.avmMini_pc.shifted()); return polys; } @@ -177,14 +179,14 @@ class AvmMiniCircuitBuilder { return true; }; - if (!evaluate_relation.template operator()>("avm_mini", - AvmMini_vm::get_relation_label_avm_mini)) { - return false; - } if (!evaluate_relation.template operator()>( "mem_trace", AvmMini_vm::get_relation_label_mem_trace)) { return false; } + if (!evaluate_relation.template operator()>("avm_mini", + AvmMini_vm::get_relation_label_avm_mini)) { + return false; + } return true; } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp index 46d9a5bc9e9..7ad4452af56 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp @@ -7,68 +7,70 @@ namespace proof_system::AvmMini_vm { template struct Avm_miniRow { + FF avmMini_first{}; + FF avmMini_sel_jump{}; + FF avmMini_internal_return_ptr_shift{}; + FF avmMini_pc{}; + FF avmMini_tag_err{}; + FF avmMini_mem_idx_a{}; + FF avmMini_sel_op_add{}; + FF avmMini_rwb{}; + FF avmMini_rwc{}; + FF avmMini_sel_internal_return{}; FF avmMini_rwa{}; - FF avmMini_sel_op_div{}; FF avmMini_inv{}; - FF avmMini_internal_return_ptr{}; FF avmMini_sel_internal_call{}; - FF avmMini_ic{}; - FF avmMini_rwb{}; - FF avmMini_sel_halt{}; - FF avmMini_sel_op_add{}; - FF avmMini_mem_op_b{}; FF avmMini_op_err{}; - FF avmMini_rwc{}; - FF avmMini_ib{}; - FF avmMini_mem_idx_a{}; - FF avmMini_sel_op_sub{}; + FF avmMini_pc_shift{}; FF avmMini_sel_op_mul{}; + FF avmMini_sel_op_div{}; + FF avmMini_sel_op_sub{}; + FF avmMini_mem_op_b{}; + FF avmMini_sel_halt{}; FF avmMini_ia{}; - FF avmMini_internal_return_ptr_shift{}; - FF avmMini_pc{}; - FF avmMini_pc_shift{}; - FF avmMini_tag_err{}; - FF avmMini_mem_op_c{}; FF avmMini_mem_op_a{}; - FF avmMini_sel_internal_return{}; - FF avmMini_first{}; + FF avmMini_ic{}; + FF avmMini_ib{}; + FF avmMini_internal_return_ptr{}; + FF avmMini_mem_op_c{}; + FF avmMini_mem_idx_b{}; }; inline std::string get_relation_label_avm_mini(int index) { switch (index) { + case 24: + return "SUBOP_DIVISION_ZERO_ERR2"; + case 20: - return "SUBOP_MULTIPLICATION_FF"; + return "SUBOP_SUBTRACTION_FF"; + + case 38: + return "PC_INCREMENT"; case 22: - return "SUBOP_DIVISION_ZERO_ERR1"; + return "SUBOP_DIVISION_FF"; case 23: - return "SUBOP_DIVISION_ZERO_ERR2"; - - case 24: - return "SUBOP_ERROR_RELEVANT_OP"; - - case 25: - return "RETURN_POINTER_INCREMENT"; - - case 30: - return "RETURN_POINTER_DECREMENT"; + return "SUBOP_DIVISION_ZERO_ERR1"; - case 35: - return "PC_INCREMENT"; + case 21: + return "SUBOP_MULTIPLICATION_FF"; case 19: - return "SUBOP_SUBTRACTION_FF"; + return "SUBOP_ADDITION_FF"; - case 21: - return "SUBOP_DIVISION_FF"; + case 33: + return "RETURN_POINTER_DECREMENT"; - case 36: + case 39: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 18: - return "SUBOP_ADDITION_FF"; + case 25: + return "SUBOP_ERROR_RELEVANT_OP"; + + case 27: + return "RETURN_POINTER_INCREMENT"; } return std::to_string(index); } @@ -77,8 +79,9 @@ template class avm_miniImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, }; template @@ -140,7 +143,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(6); - auto tmp = (avmMini_sel_halt * (-avmMini_sel_halt + FF(1))); + auto tmp = (avmMini_sel_jump * (-avmMini_sel_jump + FF(1))); tmp *= scaling_factor; std::get<6>(evals) += tmp; } @@ -148,7 +151,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(7); - auto tmp = (avmMini_op_err * (-avmMini_op_err + FF(1))); + auto tmp = (avmMini_sel_halt * (-avmMini_sel_halt + FF(1))); tmp *= scaling_factor; std::get<7>(evals) += tmp; } @@ -156,7 +159,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(8); - auto tmp = (avmMini_tag_err * (-avmMini_tag_err + FF(1))); + auto tmp = (avmMini_op_err * (-avmMini_op_err + FF(1))); tmp *= scaling_factor; std::get<8>(evals) += tmp; } @@ -164,7 +167,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(9); - auto tmp = (avmMini_mem_op_a * (-avmMini_mem_op_a + FF(1))); + auto tmp = (avmMini_tag_err * (-avmMini_tag_err + FF(1))); tmp *= scaling_factor; std::get<9>(evals) += tmp; } @@ -172,7 +175,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(10); - auto tmp = (avmMini_mem_op_b * (-avmMini_mem_op_b + FF(1))); + auto tmp = (avmMini_mem_op_a * (-avmMini_mem_op_a + FF(1))); tmp *= scaling_factor; std::get<10>(evals) += tmp; } @@ -180,7 +183,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(11); - auto tmp = (avmMini_mem_op_c * (-avmMini_mem_op_c + FF(1))); + auto tmp = (avmMini_mem_op_b * (-avmMini_mem_op_b + FF(1))); tmp *= scaling_factor; std::get<11>(evals) += tmp; } @@ -188,7 +191,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(12); - auto tmp = (avmMini_rwa * (-avmMini_rwa + FF(1))); + auto tmp = (avmMini_mem_op_c * (-avmMini_mem_op_c + FF(1))); tmp *= scaling_factor; std::get<12>(evals) += tmp; } @@ -196,7 +199,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(13); - auto tmp = (avmMini_rwb * (-avmMini_rwb + FF(1))); + auto tmp = (avmMini_rwa * (-avmMini_rwa + FF(1))); tmp *= scaling_factor; std::get<13>(evals) += tmp; } @@ -204,7 +207,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(14); - auto tmp = (avmMini_rwc * (-avmMini_rwc + FF(1))); + auto tmp = (avmMini_rwb * (-avmMini_rwb + FF(1))); tmp *= scaling_factor; std::get<14>(evals) += tmp; } @@ -212,7 +215,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(15); - auto tmp = (avmMini_tag_err * avmMini_ia); + auto tmp = (avmMini_rwc * (-avmMini_rwc + FF(1))); tmp *= scaling_factor; std::get<15>(evals) += tmp; } @@ -220,7 +223,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(16); - auto tmp = (avmMini_tag_err * avmMini_ib); + auto tmp = (avmMini_tag_err * avmMini_ia); tmp *= scaling_factor; std::get<16>(evals) += tmp; } @@ -228,7 +231,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(17); - auto tmp = (avmMini_tag_err * avmMini_ic); + auto tmp = (avmMini_tag_err * avmMini_ib); tmp *= scaling_factor; std::get<17>(evals) += tmp; } @@ -236,7 +239,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(18); - auto tmp = (avmMini_sel_op_add * ((avmMini_ia + avmMini_ib) - avmMini_ic)); + auto tmp = (avmMini_tag_err * avmMini_ic); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -244,7 +247,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(19); - auto tmp = (avmMini_sel_op_sub * ((avmMini_ia - avmMini_ib) - avmMini_ic)); + auto tmp = (avmMini_sel_op_add * ((avmMini_ia + avmMini_ib) - avmMini_ic)); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -252,7 +255,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(20); - auto tmp = (avmMini_sel_op_mul * ((avmMini_ia * avmMini_ib) - avmMini_ic)); + auto tmp = (avmMini_sel_op_sub * ((avmMini_ia - avmMini_ib) - avmMini_ic)); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -260,7 +263,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(21); - auto tmp = ((avmMini_sel_op_div * (-avmMini_op_err + FF(1))) * ((avmMini_ic * avmMini_ib) - avmMini_ia)); + auto tmp = (avmMini_sel_op_mul * ((avmMini_ia * avmMini_ib) - avmMini_ic)); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -268,7 +271,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(22); - auto tmp = (avmMini_sel_op_div * (((avmMini_ib * avmMini_inv) - FF(1)) + avmMini_op_err)); + auto tmp = ((avmMini_sel_op_div * (-avmMini_op_err + FF(1))) * ((avmMini_ic * avmMini_ib) - avmMini_ia)); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -276,7 +279,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(23); - auto tmp = ((avmMini_sel_op_div * avmMini_op_err) * (-avmMini_inv + FF(1))); + auto tmp = (avmMini_sel_op_div * (((avmMini_ib * avmMini_inv) - FF(1)) + avmMini_op_err)); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -284,7 +287,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(24); - auto tmp = (avmMini_op_err * (avmMini_sel_op_div - FF(1))); + auto tmp = ((avmMini_sel_op_div * avmMini_op_err) * (-avmMini_inv + FF(1))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -292,8 +295,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(25); - auto tmp = (avmMini_sel_internal_call * - (avmMini_internal_return_ptr_shift - (avmMini_internal_return_ptr + FF(1)))); + auto tmp = (avmMini_op_err * (avmMini_sel_op_div - FF(1))); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -301,7 +303,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(26); - auto tmp = (avmMini_sel_internal_call * (avmMini_internal_return_ptr - avmMini_mem_idx_a)); + auto tmp = (avmMini_sel_jump * (avmMini_pc_shift - avmMini_ia)); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -309,7 +311,8 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(27); - auto tmp = (avmMini_sel_internal_call * ((avmMini_pc + FF(1)) - avmMini_ia)); + auto tmp = (avmMini_sel_internal_call * + (avmMini_internal_return_ptr_shift - (avmMini_internal_return_ptr + FF(1)))); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -317,7 +320,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(28); - auto tmp = (avmMini_sel_internal_call * (avmMini_rwa - FF(1))); + auto tmp = (avmMini_sel_internal_call * (avmMini_internal_return_ptr - avmMini_mem_idx_b)); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -325,7 +328,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(29); - auto tmp = (avmMini_sel_internal_call * (avmMini_mem_op_a - FF(1))); + auto tmp = (avmMini_sel_internal_call * (avmMini_pc_shift - avmMini_ia)); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -333,8 +336,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(30); - auto tmp = (avmMini_sel_internal_return * - (avmMini_internal_return_ptr_shift - (avmMini_internal_return_ptr - FF(1)))); + auto tmp = (avmMini_sel_internal_call * ((avmMini_pc + FF(1)) - avmMini_ib)); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -342,7 +344,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(31); - auto tmp = (avmMini_sel_internal_return * ((avmMini_internal_return_ptr - FF(1)) - avmMini_mem_idx_a)); + auto tmp = (avmMini_sel_internal_call * (avmMini_rwb - FF(1))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -350,7 +352,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(32); - auto tmp = (avmMini_sel_internal_return * (avmMini_pc_shift - avmMini_ia)); + auto tmp = (avmMini_sel_internal_call * (avmMini_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -358,7 +360,8 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(33); - auto tmp = (avmMini_sel_internal_return * avmMini_rwa); + auto tmp = (avmMini_sel_internal_return * + (avmMini_internal_return_ptr_shift - (avmMini_internal_return_ptr - FF(1)))); tmp *= scaling_factor; std::get<33>(evals) += tmp; } @@ -366,7 +369,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(34); - auto tmp = (avmMini_sel_internal_return * (avmMini_mem_op_a - FF(1))); + auto tmp = (avmMini_sel_internal_return * ((avmMini_internal_return_ptr - FF(1)) - avmMini_mem_idx_a)); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -374,9 +377,7 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(35); - auto tmp = ((((-avmMini_first + FF(1)) * (-avmMini_sel_halt + FF(1))) * - (((avmMini_sel_op_add + avmMini_sel_op_sub) + avmMini_sel_op_div) + avmMini_sel_op_mul)) * - (avmMini_pc_shift - (avmMini_pc + FF(1)))); + auto tmp = (avmMini_sel_internal_return * (avmMini_pc_shift - avmMini_ia)); tmp *= scaling_factor; std::get<35>(evals) += tmp; } @@ -384,12 +385,38 @@ template class avm_miniImpl { { AvmMini_DECLARE_VIEWS(36); + auto tmp = (avmMini_sel_internal_return * avmMini_rwa); + tmp *= scaling_factor; + std::get<36>(evals) += tmp; + } + // Contribution 37 + { + AvmMini_DECLARE_VIEWS(37); + + auto tmp = (avmMini_sel_internal_return * (avmMini_mem_op_a - FF(1))); + tmp *= scaling_factor; + std::get<37>(evals) += tmp; + } + // Contribution 38 + { + AvmMini_DECLARE_VIEWS(38); + + auto tmp = ((((-avmMini_first + FF(1)) * (-avmMini_sel_halt + FF(1))) * + (((avmMini_sel_op_add + avmMini_sel_op_sub) + avmMini_sel_op_div) + avmMini_sel_op_mul)) * + (avmMini_pc_shift - (avmMini_pc + FF(1)))); + tmp *= scaling_factor; + std::get<38>(evals) += tmp; + } + // Contribution 39 + { + AvmMini_DECLARE_VIEWS(39); + auto tmp = ((-(((avmMini_first + avmMini_sel_internal_call) + avmMini_sel_internal_return) + avmMini_sel_halt) + FF(1)) * (avmMini_internal_return_ptr_shift - avmMini_internal_return_ptr)); tmp *= scaling_factor; - std::get<36>(evals) += tmp; + std::get<39>(evals) += tmp; } } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp index 0c711d83429..2bd134b6298 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp @@ -19,6 +19,7 @@ [[maybe_unused]] auto avmMini_internal_return_ptr = View(new_term.avmMini_internal_return_ptr); \ [[maybe_unused]] auto avmMini_sel_internal_call = View(new_term.avmMini_sel_internal_call); \ [[maybe_unused]] auto avmMini_sel_internal_return = View(new_term.avmMini_sel_internal_return); \ + [[maybe_unused]] auto avmMini_sel_jump = View(new_term.avmMini_sel_jump); \ [[maybe_unused]] auto avmMini_sel_halt = View(new_term.avmMini_sel_halt); \ [[maybe_unused]] auto avmMini_sel_op_add = View(new_term.avmMini_sel_op_add); \ [[maybe_unused]] auto avmMini_sel_op_sub = View(new_term.avmMini_sel_op_sub); \ @@ -41,9 +42,9 @@ [[maybe_unused]] auto avmMini_mem_idx_b = View(new_term.avmMini_mem_idx_b); \ [[maybe_unused]] auto avmMini_mem_idx_c = View(new_term.avmMini_mem_idx_c); \ [[maybe_unused]] auto avmMini_last = View(new_term.avmMini_last); \ - [[maybe_unused]] auto avmMini_internal_return_ptr_shift = View(new_term.avmMini_internal_return_ptr_shift); \ - [[maybe_unused]] auto avmMini_pc_shift = View(new_term.avmMini_pc_shift); \ - [[maybe_unused]] auto memTrace_m_tag_shift = View(new_term.memTrace_m_tag_shift); \ [[maybe_unused]] auto memTrace_m_val_shift = View(new_term.memTrace_m_val_shift); \ + [[maybe_unused]] auto memTrace_m_addr_shift = View(new_term.memTrace_m_addr_shift); \ + [[maybe_unused]] auto memTrace_m_tag_shift = View(new_term.memTrace_m_tag_shift); \ [[maybe_unused]] auto memTrace_m_rw_shift = View(new_term.memTrace_m_rw_shift); \ - [[maybe_unused]] auto memTrace_m_addr_shift = View(new_term.memTrace_m_addr_shift); + [[maybe_unused]] auto avmMini_internal_return_ptr_shift = View(new_term.avmMini_internal_return_ptr_shift); \ + [[maybe_unused]] auto avmMini_pc_shift = View(new_term.avmMini_pc_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp index 2adc17baf9f..ef96061a9ca 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp @@ -7,32 +7,29 @@ namespace proof_system::AvmMini_vm { template struct Mem_traceRow { - FF memTrace_m_tag_shift{}; - FF memTrace_m_tag{}; - FF memTrace_m_rw{}; - FF memTrace_m_lastAccess{}; FF memTrace_m_last{}; + FF memTrace_m_val_shift{}; + FF memTrace_m_rw{}; FF memTrace_m_tag_err{}; + FF memTrace_m_addr_shift{}; + FF memTrace_m_lastAccess{}; + FF memTrace_m_tag_shift{}; + FF memTrace_m_tag{}; FF memTrace_m_val{}; - FF memTrace_m_one_min_inv{}; - FF memTrace_m_val_shift{}; - FF memTrace_m_addr{}; FF memTrace_m_rw_shift{}; - FF memTrace_m_addr_shift{}; FF memTrace_m_in_tag{}; + FF memTrace_m_addr{}; + FF memTrace_m_one_min_inv{}; }; inline std::string get_relation_label_mem_trace(int index) { switch (index) { - case 5: - return "MEM_READ_WRITE_VAL_CONSISTENCY"; - case 7: return "MEM_ZERO_INIT"; - case 9: - return "MEM_IN_TAG_CONSISTENCY_2"; + case 6: + return "MEM_READ_WRITE_TAG_CONSISTENCY"; case 8: return "MEM_IN_TAG_CONSISTENCY_1"; @@ -40,8 +37,11 @@ inline std::string get_relation_label_mem_trace(int index) case 4: return "MEM_LAST_ACCESS_DELIMITER"; - case 6: - return "MEM_READ_WRITE_TAG_CONSISTENCY"; + case 5: + return "MEM_READ_WRITE_VAL_CONSISTENCY"; + + case 9: + return "MEM_IN_TAG_CONSISTENCY_2"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp index 5673710fa24..f0b102ede71 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp @@ -80,6 +80,8 @@ bool AvmMiniVerifier::verify_proof(const plonk::proof& proof) transcript->template receive_from_prover(commitment_labels.avmMini_sel_internal_call); commitments.avmMini_sel_internal_return = transcript->template receive_from_prover(commitment_labels.avmMini_sel_internal_return); + commitments.avmMini_sel_jump = + transcript->template receive_from_prover(commitment_labels.avmMini_sel_jump); commitments.avmMini_sel_halt = transcript->template receive_from_prover(commitment_labels.avmMini_sel_halt); commitments.avmMini_sel_op_add = diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/AvmMini_control_flow.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/AvmMini_control_flow.test.cpp index 376f7ed1e5f..c771ad6eaf6 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/AvmMini_control_flow.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/AvmMini_control_flow.test.cpp @@ -56,9 +56,10 @@ TEST_F(AvmMiniControlFlowTests, simpleCall) trace.begin(), trace.end(), [](Row r) { return r.avmMini_sel_internal_call == FF(1); }); EXPECT_TRUE(call_row != trace.end()); EXPECT_EQ(call_row->avmMini_pc, FF(0)); + EXPECT_EQ(call_row->avmMini_ia, FF(CALL_ADDRESS)); EXPECT_EQ(call_row->avmMini_internal_return_ptr, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET)); - EXPECT_EQ(call_row->avmMini_ia, FF(1)); - EXPECT_EQ(call_row->avmMini_mem_idx_a, + EXPECT_EQ(call_row->avmMini_ib, FF(1)); + EXPECT_EQ(call_row->avmMini_mem_idx_b, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET)); // Store the return address (0) in memory } @@ -75,6 +76,39 @@ TEST_F(AvmMiniControlFlowTests, simpleCall) validateTraceProof(std::move(trace)); } +TEST_F(AvmMiniControlFlowTests, simpleJump) +{ + uint32_t const JUMP_ADDRESS = 4; + + // trace_builder for the following operation + // pc opcode + // 0 JUMP(pc=4) + // 4 HALT + trace_builder.jump(JUMP_ADDRESS); + trace_builder.halt(); + + auto trace = trace_builder.finalize(); + + // Check jump + { + auto call_row = + std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avmMini_sel_jump == FF(1); }); + EXPECT_TRUE(call_row != trace.end()); + EXPECT_EQ(call_row->avmMini_pc, FF(0)); + EXPECT_EQ(call_row->avmMini_ia, FF(JUMP_ADDRESS)); + } + + // Check halt + { + auto halt_row = + std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avmMini_sel_halt == FF(1); }); + + EXPECT_TRUE(halt_row != trace.end()); + EXPECT_EQ(halt_row->avmMini_pc, FF(JUMP_ADDRESS)); + } + validateTraceProof(std::move(trace)); +} + TEST_F(AvmMiniControlFlowTests, simpleCallAndReturn) { uint32_t const CALL_ADDRESS = 20; @@ -97,8 +131,8 @@ TEST_F(AvmMiniControlFlowTests, simpleCallAndReturn) EXPECT_TRUE(call_row != trace.end()); EXPECT_EQ(call_row->avmMini_pc, FF(0)); EXPECT_EQ(call_row->avmMini_internal_return_ptr, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET)); - EXPECT_EQ(call_row->avmMini_ia, FF(1)); - EXPECT_EQ(call_row->avmMini_mem_idx_a, + EXPECT_EQ(call_row->avmMini_ib, FF(1)); + EXPECT_EQ(call_row->avmMini_mem_idx_b, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET)); // Store the return address (0) in memory } @@ -132,6 +166,8 @@ TEST_F(AvmMiniControlFlowTests, multipleCallsAndReturns) uint32_t const CALL_ADDRESS_3 = 1337; uint32_t const CALL_ADDRESS_4 = 4; + uint32_t const JUMP_ADDRESS_1 = 22; + // trace_builder for the following operation // pc opcode // 0 INTERNAL_CALL(pc=420) @@ -140,7 +176,8 @@ TEST_F(AvmMiniControlFlowTests, multipleCallsAndReturns) // 1337 INTERNAL_RETURN // 70 INTERNAL_CALL(pc=4) // 4 INTERNAL_RETURN - // 71 INTERNAL_RETURN + // 71 JUMP(pc=22) + // 22 INTERNAL_RETURN // 421 INTERNAL_RETURN // 1 HALT trace_builder.internal_call(CALL_ADDRESS_1); @@ -149,6 +186,7 @@ TEST_F(AvmMiniControlFlowTests, multipleCallsAndReturns) trace_builder.internal_return(); trace_builder.internal_call(CALL_ADDRESS_4); trace_builder.internal_return(); + trace_builder.jump(JUMP_ADDRESS_1); trace_builder.internal_return(); trace_builder.internal_return(); trace_builder.halt(); @@ -158,12 +196,13 @@ TEST_F(AvmMiniControlFlowTests, multipleCallsAndReturns) // Check call 1 { auto call_1 = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { - return r.avmMini_sel_internal_call == FF(1) && r.avmMini_ia == FF(1); + return r.avmMini_sel_internal_call == FF(1) && r.avmMini_ib == FF(1); }); EXPECT_TRUE(call_1 != trace.end()); EXPECT_EQ(call_1->avmMini_pc, FF(0)); + EXPECT_EQ(call_1->avmMini_ia, FF(CALL_ADDRESS_1)); EXPECT_EQ(call_1->avmMini_internal_return_ptr, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET)); - EXPECT_EQ(call_1->avmMini_mem_idx_a, + EXPECT_EQ(call_1->avmMini_mem_idx_b, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET)); // Store the return address (0) in memory } @@ -173,9 +212,10 @@ TEST_F(AvmMiniControlFlowTests, multipleCallsAndReturns) return r.avmMini_sel_internal_call == FF(1) && r.avmMini_pc == FF(CALL_ADDRESS_1); }); EXPECT_TRUE(call_2 != trace.end()); - EXPECT_EQ(call_2->avmMini_ia, FF(CALL_ADDRESS_1 + 1)); + EXPECT_EQ(call_2->avmMini_ib, FF(CALL_ADDRESS_1 + 1)); + EXPECT_EQ(call_2->avmMini_ia, FF(CALL_ADDRESS_2)); EXPECT_EQ(call_2->avmMini_internal_return_ptr, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET + 1)); - EXPECT_EQ(call_2->avmMini_mem_idx_a, + EXPECT_EQ(call_2->avmMini_mem_idx_b, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET + 1)); // Store the return address (0) in memory } @@ -185,9 +225,9 @@ TEST_F(AvmMiniControlFlowTests, multipleCallsAndReturns) return r.avmMini_sel_internal_call == FF(1) && r.avmMini_pc == FF(CALL_ADDRESS_2); }); EXPECT_TRUE(call_3 != trace.end()); - EXPECT_EQ(call_3->avmMini_ia, FF(CALL_ADDRESS_2 + 1)); + EXPECT_EQ(call_3->avmMini_ib, FF(CALL_ADDRESS_2 + 1)); EXPECT_EQ(call_3->avmMini_internal_return_ptr, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET + 2)); - EXPECT_EQ(call_3->avmMini_mem_idx_a, + EXPECT_EQ(call_3->avmMini_mem_idx_b, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET + 2)); // Store the return address (0) in memory } @@ -206,9 +246,9 @@ TEST_F(AvmMiniControlFlowTests, multipleCallsAndReturns) return r.avmMini_sel_internal_call == FF(1) && r.avmMini_pc == FF(CALL_ADDRESS_2 + 1); }); EXPECT_TRUE(call_4 != trace.end()); - EXPECT_EQ(call_4->avmMini_ia, FF(CALL_ADDRESS_2 + 2)); + EXPECT_EQ(call_4->avmMini_ib, FF(CALL_ADDRESS_2 + 2)); EXPECT_EQ(call_4->avmMini_internal_return_ptr, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET + 2)); - EXPECT_EQ(call_4->avmMini_mem_idx_a, + EXPECT_EQ(call_4->avmMini_mem_idx_b, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET + 2)); // Store the return address (0) in memory } @@ -222,10 +262,20 @@ TEST_F(AvmMiniControlFlowTests, multipleCallsAndReturns) EXPECT_EQ(return_2->avmMini_internal_return_ptr, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET + 3)); } + // Jump 1 + { + auto jump_1 = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { + return r.avmMini_sel_jump == FF(1) && r.avmMini_pc == FF(CALL_ADDRESS_2 + 2); + }); + EXPECT_TRUE(jump_1 != trace.end()); + EXPECT_EQ(jump_1->avmMini_ia, FF(JUMP_ADDRESS_1)); + EXPECT_EQ(jump_1->avmMini_internal_return_ptr, FF(AvmMiniTraceBuilder::CALLSTACK_OFFSET + 2)); + } + // Return 3 { auto return_3 = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { - return r.avmMini_sel_internal_return == FF(1) && r.avmMini_pc == FF(CALL_ADDRESS_2 + 2); + return r.avmMini_sel_internal_return == FF(1) && r.avmMini_pc == FF(JUMP_ADDRESS_1); }); EXPECT_TRUE(return_3 != trace.end()); EXPECT_EQ(return_3->avmMini_ia, FF(CALL_ADDRESS_1 + 1));