From d85d8dbbe41ae5be1d38e372b8949106f06c02f6 Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Thu, 15 Jan 2026 12:18:11 +0000 Subject: [PATCH 01/15] feat(avm): contract instance mutation (#19499) Mutations for contract instances --- .../barretenberg/avm_fuzzer/fuzzer_lib.cpp | 6 +- .../barretenberg/avm_fuzzer/fuzzer_lib.hpp | 5 +- .../avm_fuzzer/mutations/bytecode.cpp | 88 +++++++++++++++++++ .../avm_fuzzer/mutations/bytecode.hpp | 4 + 4 files changed, 98 insertions(+), 5 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp index 82acfe5ca704..04c3db7896a5 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp @@ -341,9 +341,9 @@ size_t mutate_tx_data(FuzzerContext& context, // So when we mutate contract classes, we also need to update the corresponding artifacts break; - // case TxDataMutationType::ContractInstanceMutation: - // // Mutations here are likely to cause immediate failure - // break; + case FuzzerTxDataMutationType::ContractInstanceMutation: + mutate_contract_instances(tx_data.contract_instances, tx_data.contract_addresses, rng); + break; // case TxDataMutationType::GlobalVariablesMutation: // break; // case TxDataMutationType::ProtocolContractsMutation: diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp index 0187d50c3826..3be0c1b62b77 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp @@ -62,17 +62,18 @@ enum class FuzzerTxDataMutationType : uint8_t { TxMutation, BytecodeMutation, ContractClassMutation, - // ContractInstanceMutation, + ContractInstanceMutation, // GlobalVariablesMutation, // ProtocolContractsMutation }; -using FuzzerTxDataMutationConfig = WeightedSelectionConfig; +using FuzzerTxDataMutationConfig = WeightedSelectionConfig; constexpr FuzzerTxDataMutationConfig FUZZER_TX_DATA_MUTATION_CONFIGURATION = FuzzerTxDataMutationConfig({ { FuzzerTxDataMutationType::TxMutation, 10 }, { FuzzerTxDataMutationType::BytecodeMutation, 1 }, { FuzzerTxDataMutationType::ContractClassMutation, 1 }, + { FuzzerTxDataMutationType::ContractInstanceMutation, 1 }, }); // Build bytecode and contract artifacts from fuzzer data diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp index 8427cb86c2b1..98b5e3c06c9e 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp @@ -5,10 +5,39 @@ #include "barretenberg/crypto/poseidon2/poseidon2.hpp" #include "barretenberg/vm2/common/aztec_constants.hpp" #include "barretenberg/vm2/common/aztec_types.hpp" +#include "barretenberg/vm2/common/field.hpp" #include "barretenberg/vm2/simulation/lib/contract_crypto.hpp" extern "C" size_t LLVMFuzzerMutate(uint8_t* Data, size_t Size, size_t MaxSize); +namespace { + +avm2::Fq random_fq_scalar(std::mt19937_64& rng) +{ + std::uniform_int_distribution dist(0, std::numeric_limits::max()); + + std::array limbs; + for (size_t i = 0; i < 4; ++i) { + limbs[i] = dist(rng); + } + + return avm2::Fq(limbs[0], limbs[1], limbs[2], limbs[3]); +} + +void mutate_point(AffinePoint& point, std::mt19937_64& rng) +{ + // Generates a new valid on-curve point via scalar multiplication of the generator + // We make some assumptions for this point mutation: + // - The point is not at infinity + // - The point is valid (on curve) + + // Generate scalar + Fq scalar = random_fq_scalar(rng); + point = grumpkin::g1::affine_element::one() * scalar; +} + +} // namespace + namespace bb::avm2::fuzzer { void mutate_bytecode(std::vector& contract_classes, @@ -142,4 +171,63 @@ void mutate_contract_classes(std::vector& contract_ klass.id = new_class_id; } +void mutate_contract_instances(std::vector& contract_instances, + std::vector& contract_addresses, + std::mt19937_64& rng) +{ + // Skip if no contracts to mutate + if (contract_instances.empty()) { + return; + } + + // Select a random contract + size_t idx = std::uniform_int_distribution(0, contract_instances.size() - 1)(rng); + + ContractInstance& instance = contract_instances[idx]; + auto original_address = simulation::compute_contract_address(instance); + + // We don't mutate the class IDs here, only the other fields + constexpr size_t num_mutable_fields = 7; + auto choice = std::uniform_int_distribution(0, num_mutable_fields - 1)(rng); + switch (choice) { + case 0: + // Mutate salt + mutate_field(instance.salt, rng, BASIC_FIELD_MUTATION_CONFIGURATION); + break; + case 1: + // Mutate deployer + mutate_field(instance.deployer, rng, BASIC_FIELD_MUTATION_CONFIGURATION); + break; + case 2: + // Mutate initialization hash + mutate_field(instance.initialization_hash, rng, BASIC_FIELD_MUTATION_CONFIGURATION); + break; + case 3: + // Mutate nullifier key + mutate_point(instance.public_keys.nullifier_key, rng); + break; + case 4: + // Mutate incoming viewing key + mutate_point(instance.public_keys.incoming_viewing_key, rng); + break; + case 5: + // Mutate outgoing viewing key + mutate_point(instance.public_keys.outgoing_viewing_key, rng); + break; + case 6: + // Mutate tagging key + mutate_point(instance.public_keys.tagging_key, rng); + break; + default: + break; + } + + auto new_address = simulation::compute_contract_address(instance); + + // This should always find a contract address, since we are mutating an existing instance + auto contract_address = + std::ranges::find_if(contract_addresses, [&](const AztecAddress& addr) { return addr == original_address; }); + *contract_address = new_address; +} + } // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.hpp index b58d496a13d6..6cb28e9aa3f9 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.hpp @@ -18,4 +18,8 @@ void mutate_contract_classes(std::vector& contract_ std::vector& contract_addresses, std::mt19937_64& rng); +void mutate_contract_instances(std::vector& contract_instances, + std::vector& contract_addresses, + std::mt19937_64& rng); + } // namespace bb::avm2::fuzzer From 206028c57e1e3433f3bab84ee372c3a67ab94172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Thu, 15 Jan 2026 13:23:00 +0100 Subject: [PATCH 02/15] fix(avm): Fix note hash exists fuzzing (#19616) Now we allow prefilling the tree with some note hashes and we notify instruction generation with existing note hashes (prefill + nonrevertible inserted) --- .../avm_fuzzer/common/interfaces/dbs.cpp | 10 ++++ .../avm_fuzzer/common/interfaces/dbs.hpp | 1 + .../barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp | 4 +- .../avm_fuzzer/fuzz_lib/fuzz.test.cpp | 38 +++++++++----- .../avm_fuzzer/fuzz_lib/fuzzer_context.cpp | 14 +++++ .../avm_fuzzer/fuzz_lib/fuzzer_context.hpp | 5 ++ .../avm_fuzzer/fuzz_lib/instruction.hpp | 18 ++----- .../avm_fuzzer/fuzz_lib/memory_manager.cpp | 21 -------- .../avm_fuzzer/fuzz_lib/memory_manager.hpp | 10 ---- .../avm_fuzzer/fuzz_lib/program_block.cpp | 24 --------- .../avm_fuzzer/fuzz_lib/simulator.cpp | 14 +++-- .../avm_fuzzer/fuzz_lib/simulator.hpp | 37 ++++++++----- .../barretenberg/avm_fuzzer/fuzzer_lib.cpp | 52 ++++++++++++++++--- .../barretenberg/avm_fuzzer/fuzzer_lib.hpp | 10 ++-- .../avm_fuzzer/mutations/configuration.hpp | 5 +- .../mutations/instructions/instruction.cpp | 43 +++++++++++---- .../mutations/instructions/instruction.hpp | 1 + .../public/fuzzing/avm_fuzzer_simulator.ts | 12 +++++ .../src/public/fuzzing/avm_simulator_bin.ts | 4 ++ 19 files changed, 198 insertions(+), 125 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp index 0aef0f60a56f..c18c20d60d0b 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.cpp @@ -250,4 +250,14 @@ void FuzzerWorldStateManager::public_data_write(const bb::crypto::merkle_tree::P ws->update_public_data(public_data, fork_id); } +void FuzzerWorldStateManager::append_note_hashes(const std::vector& note_hashes) +{ + auto fork_id = fork_ids.top(); + + uint64_t padding_leaves = MAX_NOTE_HASHES_PER_TX - (note_hashes.size() % MAX_NOTE_HASHES_PER_TX); + + ws->append_leaves(MerkleTreeId::NOTE_HASH_TREE, note_hashes, fork_id); + ws->append_leaves(MerkleTreeId::NOTE_HASH_TREE, std::vector(padding_leaves, FF(0)), fork_id); +} + } // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.hpp index cbe4b56510ce..8866587cc5ca 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/common/interfaces/dbs.hpp @@ -89,6 +89,7 @@ class FuzzerWorldStateManager { void register_contract_address(const AztecAddress& contract_address); void write_fee_payer_balance(const AztecAddress& fee_payer, const FF& balance); void public_data_write(const bb::crypto::merkle_tree::PublicDataLeafValue& public_data); + void append_note_hashes(const std::vector& note_hashes); world_state::WorldStateRevision get_current_revision() const; world_state::WorldStateRevision fork(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp index b104917ebe5f..4ab5b2ce0a44 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp @@ -42,14 +42,14 @@ SimulatorResult fuzz_against_ts_simulator(FuzzerData& fuzzer_data, FuzzerContext try { ws_mgr->checkpoint(); - cpp_result = cpp_simulator.simulate(*ws_mgr, contract_db, tx, /*public_data_writes=*/{}); + cpp_result = cpp_simulator.simulate(*ws_mgr, contract_db, tx, /*public_data_writes=*/{}, /*note_hashes=*/{}); ws_mgr->revert(); } catch (const std::exception& e) { throw std::runtime_error(std::string("CppSimulator threw an exception: ") + e.what()); } ws_mgr->checkpoint(); - auto js_result = js_simulator->simulate(*ws_mgr, contract_db, tx, /*public_data_writes=*/{}); + auto js_result = js_simulator->simulate(*ws_mgr, contract_db, tx, /*public_data_writes=*/{}, /*note_hashes=*/{}); context.reset(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp index ce8b4efa795a..6eb296962ba9 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp @@ -43,9 +43,18 @@ class FuzzTest : public ::testing::Test { void TearDown() override { ws_mgr->reset_world_state(); } SimulatorResult simulate_with_default_tx(std::vector& bytecode, std::vector calldata) + { + return simulate_with_default_tx(bytecode, calldata, {}); + } + + SimulatorResult simulate_with_default_tx(std::vector& bytecode, + std::vector calldata, + const std::vector& note_hashes) { ws_mgr->checkpoint(); + ws_mgr->append_note_hashes(note_hashes); + auto contract_address = context.register_contract_from_bytecode(bytecode); FuzzerContractDB contract_db = context.get_contract_db(); @@ -55,7 +64,7 @@ class FuzzTest : public ::testing::Test { ws_mgr->write_fee_payer_balance(tx.fee_payer, fee_required_da + fee_required_l2); auto cpp_simulator = CppSimulator(); - auto result = cpp_simulator.simulate(*ws_mgr, contract_db, tx); + auto result = cpp_simulator.simulate(*ws_mgr, contract_db, tx, {}, {}); ws_mgr->revert(); @@ -1187,28 +1196,29 @@ TEST_F(FuzzTest, EmitNullifierThenNullifierExistsOverwritingPreviousNullifier) TEST_F(FuzzTest, EmitNoteHashThenNoteHashExists) { - auto emit_note_hash_instruction = - EMITNOTEHASH_Instruction{ .note_hash_address = AddressRef{ .address = 0, .mode = AddressingMode::Direct }, - .note_hash = 1 }; + FF note_hash = 42; + uint64_t leaf_index = 0; + auto set_note_hash_instruction = + SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF, + .result_address = AddressRef{ .address = 0, .mode = AddressingMode::Direct }, + .value = note_hash }; + auto set_leaf_index_instruction = + SET_64_Instruction{ .value_tag = bb::avm2::MemoryTag::U64, + .result_address = AddressRef{ .address = 1, .mode = AddressingMode::Direct }, + .value = leaf_index }; auto note_hash_exists_instruction = - NOTEHASHEXISTS_Instruction{ .notehash_index = 0, - .notehash_address = AddressRef{ .address = 0, .mode = AddressingMode::Direct }, + NOTEHASHEXISTS_Instruction{ .notehash_address = AddressRef{ .address = 0, .mode = AddressingMode::Direct }, .leaf_index_address = AddressRef{ .address = 1, .mode = AddressingMode::Direct }, .result_address = AddressRef{ .address = 2, .mode = AddressingMode::Direct } }; auto instruction_blocks = std::vector{ InstructionBlock{ - .instructions = { emit_note_hash_instruction, note_hash_exists_instruction } } }; + .instructions = { set_note_hash_instruction, set_leaf_index_instruction, note_hash_exists_instruction } } }; auto control_flow = ControlFlow(instruction_blocks); control_flow.process_cfg_instruction(InsertSimpleInstructionBlock{ .instruction_block_idx = 0 }); auto bytecode = control_flow.build_bytecode( ReturnOptions{ .return_size = 1, .return_value_tag = bb::avm2::MemoryTag::U1, .return_value_offset_index = 0 }); - auto result = simulate_with_default_tx(bytecode, {}); + auto result = simulate_with_default_tx(bytecode, {}, { note_hash }); EXPECT_FALSE(result.reverted); - // TODO(defkit): fix notehashexists - // Right now we cannot know the contract address during bytecode construction - // because contract address depends on bytecode commitment - // So we cannot compute actual unique_note_hash for NOTEHASHEXISTS instruction - // - // EXPECT_EQ(result.output.at(0), 1); + EXPECT_EQ(result.output.at(0), 1); } } // namespace notes_and_nullifiers diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp index 9b6c307c731b..c2b9121b17b3 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp @@ -73,10 +73,24 @@ FF FuzzerContext::register_contract_from_bytecode(const std::vector& by return contract_address; } +std::optional> FuzzerContext::get_existing_note_hash(size_t index) const +{ + if (existing_note_hashes_.size() == 0) { + return std::nullopt; + } + return existing_note_hashes_[index % existing_note_hashes_.size()]; +} + +void FuzzerContext::set_existing_note_hashes(std::span> note_hashes) +{ + existing_note_hashes_.assign(note_hashes.begin(), note_hashes.end()); +} + void FuzzerContext::reset() { contract_addresses_.clear(); contract_db_ = std::make_unique(); + existing_note_hashes_.clear(); } } // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.hpp index 30126a7e2728..4c02d222cda5 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.hpp @@ -53,9 +53,14 @@ class FuzzerContext { /// @brief Get the contract database for simulation FuzzerContractDB& get_contract_db() const { return *contract_db_; } + std::optional> get_existing_note_hash(size_t index) const; + + void set_existing_note_hashes(std::span> note_hashes); + private: std::vector contract_addresses_; std::unique_ptr contract_db_; + std::vector> existing_note_hashes_; }; } // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp index 2194094604ea..1729dec60ec5 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp @@ -501,21 +501,11 @@ struct EMITNOTEHASH_Instruction { MSGPACK_FIELDS(note_hash_address, note_hash); }; -/// @brief NOTEHASHEXISTS: M[result_offset] = NOTEHASHEXISTS(M[notehash_offset], M[leaf_index_offset]) -/// len = length(memory_manager.emitted_note_hashes); -/// M[notehash_offset] = unique_note_hash(CONTRACT_ADDRESS, memory_manager.emitted_note_hashes[notehash_index % len]); -/// M[leaf_index_offset] = notehash_index % len; -/// M[result_offset] = NOTEHASHEXISTS(M[notehash_offset], M[leaf_index_offset]); struct NOTEHASHEXISTS_Instruction { - // index of the note hash in the memory_manager.emitted_note_hashes - uint16_t notehash_index; - // absolute address where the note hash will be stored - AddressRef notehash_address; - // absolute address where the leaf index will be stored - AddressRef leaf_index_address; - // absolute address where the result will be stored - AddressRef result_address; - MSGPACK_FIELDS(notehash_index, notehash_address, leaf_index_address, result_address); + ParamRef notehash_address; + ParamRef leaf_index_address; + AddressRef result_address; + MSGPACK_FIELDS(notehash_address, leaf_index_address, result_address); }; /// @brief CALLDATACOPY: M[dstOffset:dstOffset+M[copySizeOffset]] = diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/memory_manager.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/memory_manager.cpp index ed89cf4e1dc1..125ed6891101 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/memory_manager.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/memory_manager.cpp @@ -304,27 +304,6 @@ std::optional MemoryManager::get_slot(uint16_t slot_offset_index) return storage_addresses[slot_offset_index % storage_addresses.size()]; } -void MemoryManager::append_emitted_note_hash(bb::avm2::FF note_hash) -{ - emitted_note_hashes.push_back(note_hash); -} - -std::optional MemoryManager::get_emitted_note_hash(uint16_t note_hash_index) -{ - if (emitted_note_hashes.empty()) { - return std::nullopt; - } - return emitted_note_hashes[note_hash_index % emitted_note_hashes.size()]; -} - -std::optional MemoryManager::get_leaf_index(uint16_t note_hash_index) -{ - if (emitted_note_hashes.empty()) { - return std::nullopt; - } - return note_hash_index % emitted_note_hashes.size(); -} - void MemoryManager::set_base_offset(uint32_t base_offset) { this->base_offset = base_offset; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/memory_manager.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/memory_manager.hpp index a4f3a7b116df..59a564f42e90 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/memory_manager.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/memory_manager.hpp @@ -19,8 +19,6 @@ class MemoryManager { // Public Storage used addresses std::vector storage_addresses; - std::vector emitted_note_hashes; - bb::avm2::testing::OperandBuilder get_memory_address_operand(bb::avm2::testing::OperandBuilder operand, AddressingMode mode); ResolvedAddress resolve_address(VariableRef address, uint32_t absolute_address, uint32_t max_operand_address); @@ -62,13 +60,5 @@ class MemoryManager { // Get slot from storage_addresses std::optional get_slot(uint16_t slot_offset_index); - // Append emitted note hash to emitted_note_hashes - void append_emitted_note_hash(bb::avm2::FF note_hash); - // Get emitted note hash from emitted_note_hashes - std::optional get_emitted_note_hash(uint16_t note_hash_index); - // Get leaf index from emitted_note_hashes, nullopt if emitted_note_hashes is empty - // note_hash_index % length(emitted_note_hashes) - std::optional get_leaf_index(uint16_t note_hash_index); - void set_base_offset(uint32_t base_offset); }; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp index f579abad6ba1..f94f23164dfc 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp @@ -1070,7 +1070,6 @@ void ProgramBlock::process_emitnotehash_instruction(EMITNOTEHASH_Instruction ins .operand(note_hash_address_operand.value().second) .build(); instructions.push_back(emitnotehash_instruction); - memory_manager.append_emitted_note_hash(instruction.note_hash); } void ProgramBlock::process_notehashexists_instruction(NOTEHASHEXISTS_Instruction instruction) @@ -1078,29 +1077,6 @@ void ProgramBlock::process_notehashexists_instruction(NOTEHASHEXISTS_Instruction #ifdef DISABLE_NOTEHASHEXISTS_INSTRUCTION return; #endif - auto note_hash = memory_manager.get_emitted_note_hash(instruction.notehash_index); - if (!note_hash.has_value()) { - return; - } - auto leaf_index = memory_manager.get_leaf_index(instruction.notehash_index); - if (!leaf_index.has_value()) { - return; - } - auto contract_address = CONTRACT_ADDRESS; - auto note_hash_counter = static_cast(*leaf_index); - auto siloed_note_computed_hash = bb::avm2::simulation::unconstrained_silo_note_hash(contract_address, *note_hash); - auto unique_note_computed_hash = bb::avm2::simulation::unconstrained_make_unique_note_hash( - siloed_note_computed_hash, FIRST_NULLIFIER, note_hash_counter); - - auto set_note_hash_instruction = SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF, - .result_address = instruction.notehash_address, - .value = unique_note_computed_hash }; - this->process_set_ff_instruction(set_note_hash_instruction); - auto set_leaf_index_instruction = SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::U64, - .result_address = instruction.leaf_index_address, - .value = *leaf_index }; - this->process_set_ff_instruction(set_leaf_index_instruction); - auto notehash_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.notehash_address); auto leaf_index_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.leaf_index_address); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp index 87773722977a..cb8386b8eb62 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp @@ -38,7 +38,8 @@ std::string serialize_simulation_request( const Tx& tx, const GlobalVariables& globals, const FuzzerContractDB& contract_db, - const std::vector& public_data_writes) + const std::vector& public_data_writes, + const std::vector& note_hashes) { // Build vectors from contract_db std::vector classes_vec = contract_db.get_contract_classes(); @@ -52,6 +53,7 @@ std::string serialize_simulation_request( .contract_classes = std::move(classes_vec), .contract_instances = std::move(instances_vec), .public_data_writes = public_data_writes, + .note_hashes = note_hashes, }; auto [buffer, size] = msgpack_encode_buffer(request); @@ -79,9 +81,10 @@ SimulatorResult CppSimulator::simulate( fuzzer::FuzzerWorldStateManager& ws_mgr, fuzzer::FuzzerContractDB& contract_db, const Tx& tx, - [[maybe_unused]] const std::vector& public_data_writes) + [[maybe_unused]] const std::vector& public_data_writes, + [[maybe_unused]] const std::vector& note_hashes) { - // Note: public_data_writes are already applied to C++ world state in setup_fuzzer_state + // Note: public_data_writes and note_hashes are already applied to C++ world state in setup_fuzzer_state const PublicSimulatorConfig config{ .skip_fee_enforcement = false, @@ -153,11 +156,12 @@ SimulatorResult JsSimulator::simulate( [[maybe_unused]] fuzzer::FuzzerWorldStateManager& ws_mgr, fuzzer::FuzzerContractDB& contract_db, const Tx& tx, - const std::vector& public_data_writes) + const std::vector& public_data_writes, + const std::vector& note_hashes) { auto globals = create_default_globals(); - std::string serialized = serialize_simulation_request(tx, globals, contract_db, public_data_writes); + std::string serialized = serialize_simulation_request(tx, globals, contract_db, public_data_writes, note_hashes); // Send the request process.write_line(serialized); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp index 97c1c2a02512..540fffcd6ee9 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp @@ -27,9 +27,17 @@ struct FuzzerSimulationRequest { std::vector> contract_instances; // Public data tree writes to apply before simulation (e.g., for bytecode upgrades) std::vector public_data_writes; - - MSGPACK_CAMEL_CASE_FIELDS( - ws_data_dir, ws_map_size_kb, tx, globals, contract_classes, contract_instances, public_data_writes); + // Note hashes to be applied before simulation + std::vector note_hashes; + + MSGPACK_CAMEL_CASE_FIELDS(ws_data_dir, + ws_map_size_kb, + tx, + globals, + contract_classes, + contract_instances, + public_data_writes, + note_hashes); }; struct SimulatorResult { @@ -53,17 +61,18 @@ class Simulator { fuzzer::FuzzerWorldStateManager& ws_mgr, fuzzer::FuzzerContractDB& contract_db, const Tx& tx, - const std::vector& public_data_writes) = 0; + const std::vector& public_data_writes, + const std::vector& note_hashes) = 0; }; /// @brief uses barretenberg/vm2 to simulate the bytecode class CppSimulator : public Simulator { public: - SimulatorResult simulate( - fuzzer::FuzzerWorldStateManager& ws_mgr, - fuzzer::FuzzerContractDB& contract_db, - const Tx& tx, - const std::vector& public_data_writes) override; + SimulatorResult simulate(fuzzer::FuzzerWorldStateManager& ws_mgr, + fuzzer::FuzzerContractDB& contract_db, + const Tx& tx, + const std::vector& public_data_writes, + const std::vector& note_hashes) override; }; /// @brief uses the yarn-project/simulator to simulate the bytecode @@ -85,11 +94,11 @@ class JsSimulator : public Simulator { static JsSimulator* getInstance(); static void initialize(std::string& simulator_path); - SimulatorResult simulate( - fuzzer::FuzzerWorldStateManager& ws_mgr, - fuzzer::FuzzerContractDB& contract_db, - const Tx& tx, - const std::vector& public_data_writes) override; + SimulatorResult simulate(fuzzer::FuzzerWorldStateManager& ws_mgr, + fuzzer::FuzzerContractDB& contract_db, + const Tx& tx, + const std::vector& public_data_writes, + const std::vector& note_hashes) override; }; GlobalVariables create_default_globals(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp index 04c3db7896a5..d7fdc233240b 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp @@ -11,6 +11,7 @@ #include "barretenberg/avm_fuzzer/fuzz_lib/control_flow.hpp" #include "barretenberg/avm_fuzzer/fuzz_lib/fuzz.hpp" #include "barretenberg/avm_fuzzer/fuzzer_comparison_helper.hpp" +#include "barretenberg/avm_fuzzer/mutations/basic_types/field.hpp" #include "barretenberg/avm_fuzzer/mutations/fuzzer_data.hpp" #include "barretenberg/avm_fuzzer/mutations/tx_data.hpp" #include "barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp" @@ -54,6 +55,8 @@ void setup_fuzzer_state(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contr for (const auto& write : tx_data.public_data_writes) { ws_mgr.public_data_write(write); } + + ws_mgr.append_note_hashes(tx_data.note_hashes); } void fund_fee_payer(FuzzerWorldStateManager& ws_mgr, const Tx& tx) @@ -79,7 +82,8 @@ SimulatorResult fuzz_tx(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contr try { ws_mgr.checkpoint(); - cpp_result = cpp_simulator.simulate(ws_mgr, contract_db, tx_data.tx, tx_data.public_data_writes); + cpp_result = + cpp_simulator.simulate(ws_mgr, contract_db, tx_data.tx, tx_data.public_data_writes, tx_data.note_hashes); fuzz_info("CppSimulator completed without exception"); fuzz_info("CppSimulator result: ", cpp_result); ws_mgr.revert(); @@ -95,7 +99,8 @@ SimulatorResult fuzz_tx(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contr } ws_mgr.checkpoint(); - auto js_result = js_simulator->simulate(ws_mgr, contract_db, tx_data.tx, tx_data.public_data_writes); + auto js_result = + js_simulator->simulate(ws_mgr, contract_db, tx_data.tx, tx_data.public_data_writes, tx_data.note_hashes); // If the results do not match if (!compare_simulator_results(cpp_result, js_result)) { @@ -198,11 +203,9 @@ int fuzz_prover(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contract_db, } // Initialize FuzzerTxData with sensible defaults -FuzzerTxData create_default_tx_data(std::mt19937_64& rng, const FuzzerContext& context) +FuzzerTxData create_default_tx_data(std::mt19937_64& rng, FuzzerContext& context) { - FuzzerData fuzzer_data = generate_fuzzer_data(rng, context); FuzzerTxData tx_data = { - .input_programs = { fuzzer_data }, .tx = create_default_tx(MSG_SENDER, MSG_SENDER, {}, TRANSACTION_FEE, IS_STATIC_CALL, GAS_LIMIT), .global_variables = { .chain_id = CHAIN_ID, .version = VERSION, @@ -214,11 +217,21 @@ FuzzerTxData create_default_tx_data(std::mt19937_64& rng, const FuzzerContext& c .gas_fees = GasFees{ .fee_per_da_gas = FEE_PER_DA_GAS, .fee_per_l2_gas = FEE_PER_L2_GAS } }, .protocol_contracts = {}, + // We can write proper mutations for this. However it might not be of much value since we have variability from + // nonrevertible note hashes. + .note_hashes = { generate_random_field(rng), generate_random_field(rng), generate_random_field(rng) } }; + + // TODO(alvaro): This is messy, we mutate when creating default tx data. Maybe we should just remove the mutation + // from generate_fuzzer_data altogether. + populate_context_from_tx_data(context, tx_data); + FuzzerData fuzzer_data = generate_fuzzer_data(rng, context); + tx_data.input_programs.push_back(fuzzer_data); + return tx_data; } -FuzzerTxData create_default_tx_data(const FuzzerContext& context) +FuzzerTxData create_default_tx_data(FuzzerContext& context) { std::mt19937_64 rng(0); return create_default_tx_data(rng, context); @@ -274,6 +287,8 @@ size_t mutate_tx_data(FuzzerContext& context, tx_data = create_default_tx_data(rng, context); } + populate_context_from_tx_data(context, tx_data); + // Mutate the fuzzer data multiple times for better bytecode variety auto num_mutations = std::uniform_int_distribution(1, 5)(rng); for (uint8_t i = 0; i < num_mutations; i++) { @@ -379,3 +394,28 @@ size_t mutate_tx_data(FuzzerContext& context, return mutated_serialized_fuzzer_data_size; } + +void populate_context_from_tx_data(FuzzerContext& context, const FuzzerTxData& tx_data) +{ + std::vector> note_hash_leaf_index_pairs; + note_hash_leaf_index_pairs.reserve(tx_data.note_hashes.size() + + tx_data.tx.non_revertible_accumulated_data.note_hashes.size()); + + // For note hashes we assume we start from an empty tree. We could read size everytime but it'd slow things down. + // If you're having trouble with that check initialization on FuzzerWorldStateManager::initialize() + uint64_t leaf_offset = 0; + + for (uint64_t i = 0; i < tx_data.note_hashes.size(); ++i) { + note_hash_leaf_index_pairs.push_back({ tx_data.note_hashes[i], leaf_offset + i }); + } + + uint64_t padding_leaves = MAX_NOTE_HASHES_PER_TX - (tx_data.note_hashes.size() % MAX_NOTE_HASHES_PER_TX); + leaf_offset += tx_data.note_hashes.size() + padding_leaves; + + for (uint64_t i = 0; i < tx_data.tx.non_revertible_accumulated_data.note_hashes.size(); ++i) { + note_hash_leaf_index_pairs.push_back( + { tx_data.tx.non_revertible_accumulated_data.note_hashes[i], leaf_offset + i }); + } + + context.set_existing_note_hashes(note_hash_leaf_index_pairs); +} diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp index 3be0c1b62b77..08c6cf3abd16 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp @@ -33,6 +33,7 @@ struct FuzzerTxData { // Public data tree writes to be applied during state setup (e.g., for bytecode upgrades) std::vector public_data_writes; + std::vector note_hashes; MSGPACK_FIELDS(input_programs, contract_classes, @@ -41,7 +42,8 @@ struct FuzzerTxData { tx, global_variables, protocol_contracts, - public_data_writes); + public_data_writes, + note_hashes); }; inline std::ostream& operator<<(std::ostream& os, const FuzzerTxData& data) @@ -80,8 +82,8 @@ constexpr FuzzerTxDataMutationConfig FUZZER_TX_DATA_MUTATION_CONFIGURATION = Fuz ContractArtifacts build_bytecode_and_artifacts(FuzzerData& fuzzer_data); // Create a default FuzzerTxData with sensible defaults -FuzzerTxData create_default_tx_data(std::mt19937_64& rng, const FuzzerContext& context); -FuzzerTxData create_default_tx_data(const FuzzerContext& context); +FuzzerTxData create_default_tx_data(std::mt19937_64& rng, FuzzerContext& context); +FuzzerTxData create_default_tx_data(FuzzerContext& context); // Setup fuzzer state: register contracts and addresses in the world state void setup_fuzzer_state(bb::avm2::fuzzer::FuzzerWorldStateManager& ws_mgr, @@ -110,4 +112,6 @@ size_t mutate_tx_data(FuzzerContext& context, size_t max_size, unsigned int seed); +void populate_context_from_tx_data(FuzzerContext& context, const FuzzerTxData& tx_data); + bool compare_cpp_simulator_results(const std::vector& results); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp index bcc1195cf302..27f2e2b4cb51 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp @@ -392,11 +392,10 @@ constexpr EmitNoteHashMutationConfig BASIC_EMITNOTEHASH_MUTATION_CONFIGURATION = { EmitNoteHashMutationOptions::note_hash, 1 }, }); -enum class NoteHashExistsMutationOptions { notehash_index, notehash_address, leaf_index_address, result_address }; -using NoteHashExistsMutationConfig = WeightedSelectionConfig; +enum class NoteHashExistsMutationOptions { notehash_address, leaf_index_address, result_address }; +using NoteHashExistsMutationConfig = WeightedSelectionConfig; constexpr NoteHashExistsMutationConfig BASIC_NOTEHASHEXISTS_MUTATION_CONFIGURATION = NoteHashExistsMutationConfig({ - { NoteHashExistsMutationOptions::notehash_index, 1 }, { NoteHashExistsMutationOptions::notehash_address, 1 }, { NoteHashExistsMutationOptions::leaf_index_address, 1 }, { NoteHashExistsMutationOptions::result_address, 1 }, diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp index c36276809372..81a3c55f6439 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp @@ -238,10 +238,7 @@ std::vector InstructionMutator::generate_instruction(std::mt199 return { EMITNOTEHASH_Instruction{ .note_hash_address = generate_address_ref(rng, MAX_16BIT_OPERAND), .note_hash = generate_random_field(rng) } }; case InstructionGenerationOptions::NOTEHASHEXISTS: - return { NOTEHASHEXISTS_Instruction{ .notehash_index = generate_random_uint16(rng), - .notehash_address = generate_address_ref(rng, MAX_16BIT_OPERAND), - .leaf_index_address = generate_address_ref(rng, MAX_16BIT_OPERAND), - .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } }; + return generate_notehashexists_instruction(rng); case InstructionGenerationOptions::CALLDATACOPY: return { CALLDATACOPY_Instruction{ .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND), .copy_size = generate_random_uint8(rng), @@ -879,6 +876,37 @@ std::vector InstructionMutator::generate_getcontractinstance_in return instructions; } +std::vector InstructionMutator::generate_notehashexists_instruction(std::mt19937_64& rng) +{ + bool use_backfill = std::uniform_int_distribution(0, 4)(rng) != 0; + if (!use_backfill) { + return { NOTEHASHEXISTS_Instruction{ .notehash_address = generate_variable_ref(rng), + .leaf_index_address = generate_variable_ref(rng), + .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } }; + } + auto existing_note_hash = context.get_existing_note_hash(generate_random_uint16(rng)); + FF note_hash = existing_note_hash.has_value() ? existing_note_hash.value().first : generate_random_field(rng); + uint64_t leaf_index = + existing_note_hash.has_value() ? existing_note_hash.value().second : generate_random_uint64(rng); + AddressRef note_hash_address = generate_address_ref(rng, MAX_16BIT_OPERAND); + AddressRef leaf_index_address = generate_address_ref(rng, MAX_16BIT_OPERAND); + + std::vector instructions; + instructions.reserve(3); + + instructions.push_back(SET_FF_Instruction{ + .value_tag = bb::avm2::MemoryTag::FF, .result_address = note_hash_address, .value = note_hash }); + instructions.push_back(SET_64_Instruction{ + .value_tag = bb::avm2::MemoryTag::U64, .result_address = leaf_index_address, .value = leaf_index }); + + instructions.push_back( + NOTEHASHEXISTS_Instruction{ .notehash_address = note_hash_address, + .leaf_index_address = leaf_index_address, + .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) }); + + return instructions; +} + void InstructionMutator::mutate_param_ref(ParamRef& param, std::mt19937_64& rng, std::optional default_tag, @@ -1215,14 +1243,11 @@ void InstructionMutator::mutate_note_hash_exists_instruction(NOTEHASHEXISTS_Inst { NoteHashExistsMutationOptions option = BASIC_NOTEHASHEXISTS_MUTATION_CONFIGURATION.select(rng); switch (option) { - case NoteHashExistsMutationOptions::notehash_index: - mutate_uint16_t(instruction.notehash_index, rng, BASIC_UINT16_T_MUTATION_CONFIGURATION); - break; case NoteHashExistsMutationOptions::notehash_address: - mutate_address_ref(instruction.notehash_address, rng, MAX_16BIT_OPERAND); + mutate_param_ref(instruction.notehash_address, rng, MemoryTag::FF, MAX_16BIT_OPERAND); break; case NoteHashExistsMutationOptions::leaf_index_address: - mutate_address_ref(instruction.leaf_index_address, rng, MAX_16BIT_OPERAND); + mutate_param_ref(instruction.leaf_index_address, rng, MemoryTag::U64, MAX_16BIT_OPERAND); break; case NoteHashExistsMutationOptions::result_address: mutate_address_ref(instruction.result_address, rng, MAX_16BIT_OPERAND); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.hpp index 589f9ee58956..e07bb9c53e58 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.hpp @@ -46,6 +46,7 @@ class InstructionMutator { std::vector generate_emitunencryptedlog_instruction(std::mt19937_64& rng); std::vector generate_call_instruction(std::mt19937_64& rng); std::vector generate_getcontractinstance_instruction(std::mt19937_64& rng); + std::vector generate_notehashexists_instruction(std::mt19937_64& rng); void mutate_variable_ref(VariableRef& variable, std::mt19937_64& rng, std::optional default_tag); void mutate_address_ref(AddressRef& address, std::mt19937_64& rng, uint32_t max_operand_value); diff --git a/yarn-project/simulator/src/public/fuzzing/avm_fuzzer_simulator.ts b/yarn-project/simulator/src/public/fuzzing/avm_fuzzer_simulator.ts index 40ca179cb68d..bac801cd87ad 100644 --- a/yarn-project/simulator/src/public/fuzzing/avm_fuzzer_simulator.ts +++ b/yarn-project/simulator/src/public/fuzzing/avm_fuzzer_simulator.ts @@ -41,6 +41,7 @@ export class FuzzerSimulationRequest { public readonly contractClasses: any[], // Raw, processed by addContractClassFromCpp public readonly contractInstances: [any, any][], // Raw pairs [address, instance] public readonly publicDataWrites: any[], // Raw public data tree writes to apply before simulation + public readonly noteHashes: any[], // Raw note hashes to apply before simulation ) {} static fromPlainObject(obj: any): FuzzerSimulationRequest { @@ -55,6 +56,7 @@ export class FuzzerSimulationRequest { obj.contractClasses, obj.contractInstances, obj.publicDataWrites ?? [], + obj.noteHashes ?? [], ); } } @@ -250,4 +252,14 @@ export class AvmFuzzerSimulator extends BaseAvmSimulationTester { await this.merkleTrees.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, [leaf.toBuffer()]); } } + + /** + * Apply note hashes from C++ raw msgpack data. + * This is used to pre-populate the note hash tree before simulation. + */ + public async applyNoteHashes(rawNoteHashes: any[]): Promise { + const paddingLeaves = MAX_NOTE_HASHES_PER_TX - (rawNoteHashes.length % MAX_NOTE_HASHES_PER_TX); + const paddedNoteHashes = [...rawNoteHashes, ...Array(paddingLeaves).fill(Fr.ZERO)]; + await this.merkleTrees.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, paddedNoteHashes); + } } diff --git a/yarn-project/simulator/src/public/fuzzing/avm_simulator_bin.ts b/yarn-project/simulator/src/public/fuzzing/avm_simulator_bin.ts index 95cfa07c4e03..423aeb9e95e0 100644 --- a/yarn-project/simulator/src/public/fuzzing/avm_simulator_bin.ts +++ b/yarn-project/simulator/src/public/fuzzing/avm_simulator_bin.ts @@ -56,6 +56,7 @@ async function simulateWithFuzzer( rawContractClasses: any[], // Replace these when we are moving contract classes to TS rawContractInstances: [any, any][], // Replace these when we are moving contract instances to TS rawPublicDataWrites: any[], // Public data tree writes to apply before simulation + rawNoteHashes: any[], // Note hashes to apply before simulation ): Promise<{ reverted: boolean; output: Fr[]; revertReason?: string; publicInputs: AvmCircuitPublicInputs }> { const worldStateService = await openExistingWorldState(dataDir, mapSizeKb); @@ -64,6 +65,8 @@ async function simulateWithFuzzer( // Apply public data writes before simulation (e.g., for bytecode upgrades) await simulator.applyPublicDataWrites(rawPublicDataWrites); + await simulator.applyNoteHashes(rawNoteHashes); + // Register contract classes from C++ for (const rawClass of rawContractClasses) { await simulator.addContractClassFromCpp(rawClass); @@ -104,6 +107,7 @@ async function execute(base64Line: string): Promise { request.contractClasses, request.contractInstances, request.publicDataWrites, + request.noteHashes, ); // Serialize the result to msgpack and encode it in base64 for output From c20f3bcc3ca1c19d945e603ef414546790d42947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Thu, 15 Jan 2026 15:25:39 +0100 Subject: [PATCH 03/15] fix(avm): Build trace on coverage prover runs (#19627) We weren't tracegening on coverage prover runs! --- .../cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp index d7fdc233240b..35dc4cb8cc89 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp @@ -22,6 +22,7 @@ #include "barretenberg/vm2/simulation/lib/contract_crypto.hpp" #include "barretenberg/vm2/simulation_helper.hpp" #include "barretenberg/vm2/tooling/stats.hpp" +#include "barretenberg/vm2/tracegen_helper.hpp" using namespace bb::avm2::fuzzer; using namespace bb::avm2::simulation; @@ -192,11 +193,14 @@ int fuzz_prover(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contract_db, BB_ASSERT(check_circuit_result, "check_circuit returned false in fuzzer with no exception, this indicates a failure"); #else - // In coverage builds, run simulate_for_witgen instead of check_circuit + // In coverage builds, run simulate_for_witgen and tracegen instead of check_circuit // This gives us coverage the the event and tracegen code paths without the overhead of check_circuit vinfo("Running simulate_for_witgen in coverage build (skipping check_circuit)"); avm2::AvmSimulationHelper simulation_helper; - simulation_helper.simulate_for_witgen(proving_inputs.hints); + auto events = simulation_helper.simulate_for_witgen(proving_inputs.hints); + AvmTraceGenHelper tracegen_helper; + tracegen::TraceContainer trace; + tracegen_helper.fill_trace_columns(trace, std::move(events), hint_result.public_inputs.value()); #endif return 0; From 86e2ae7b016893d920d999aacaf389d5e441dd74 Mon Sep 17 00:00:00 2001 From: Jean M <132435771+jeanmon@users.noreply.github.com> Date: Thu, 15 Jan 2026 15:37:52 +0100 Subject: [PATCH 04/15] chore(avm): Use PC alias type consistently (#19625) This alias type was only used partially (e.g. in internal_call_stack_manager) --- .../vm2/simulation/events/bytecode_events.hpp | 4 ++-- .../vm2/simulation/events/context_events.hpp | 4 ++-- .../vm2/simulation/gadgets/bytecode_manager.cpp | 4 ++-- .../vm2/simulation/gadgets/bytecode_manager.hpp | 6 +++--- .../barretenberg/vm2/simulation/gadgets/context.hpp | 12 ++++++------ .../vm2/simulation/gadgets/execution.cpp | 2 +- .../vm2/simulation/gadgets/execution.hpp | 2 +- .../vm2/simulation/gadgets/execution.test.cpp | 6 +++--- .../vm2/simulation/interfaces/bytecode_manager.hpp | 6 +++--- .../interfaces/call_stack_metadata_collector.hpp | 4 ++-- .../vm2/simulation/interfaces/context.hpp | 8 ++++---- .../simulation/lib/call_stack_metadata_collector.cpp | 4 ++-- .../simulation/lib/call_stack_metadata_collector.hpp | 8 ++++---- .../lib/call_stack_metadata_collector.test.cpp | 4 ++-- .../vm2/simulation/standalone/hybrid_execution.cpp | 2 +- .../simulation/standalone/pure_bytecode_manager.cpp | 4 ++-- .../simulation/standalone/pure_bytecode_manager.hpp | 6 +++--- .../vm2/simulation/testing/mock_bytecode_manager.hpp | 2 +- .../testing/mock_call_stack_metadata_collector.hpp | 4 ++-- 19 files changed, 46 insertions(+), 46 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/bytecode_events.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/bytecode_events.hpp index 11c2e3877678..1920128b12ec 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/bytecode_events.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/bytecode_events.hpp @@ -43,14 +43,14 @@ struct BytecodeRetrievalEvent { struct InstructionFetchingEvent { BytecodeId bytecode_id; - uint32_t pc; + PC pc; // TODO: Do we want to have a dep on Instruction here or do we redefine what we need? Instruction instruction; std::shared_ptr> bytecode; std::optional error; // To be used with deduplicating event emitters. - using Key = std::tuple; + using Key = std::tuple; Key get_key() const { return { bytecode_id, pc }; } }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/context_events.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/context_events.hpp index 24927022d3e1..89fb1ba349f1 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/context_events.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/context_events.hpp @@ -12,7 +12,7 @@ struct ContextEvent { uint32_t last_child_id = 0; // State - uint32_t pc = 0; + PC pc = 0; AztecAddress msg_sender = 0; AztecAddress contract_addr = 0; BytecodeId bytecode_id = 0; @@ -59,7 +59,7 @@ struct ContextStackEvent { uint32_t entered_context_id = 0; // State - uint32_t next_pc = 0; + PC next_pc = 0; AztecAddress msg_sender = 0; AztecAddress contract_addr = 0; BytecodeId bytecode_id = 0; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/bytecode_manager.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/bytecode_manager.cpp index 80ee05a504b5..e259b46f05af 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/bytecode_manager.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/bytecode_manager.cpp @@ -101,14 +101,14 @@ BytecodeId TxBytecodeManager::get_bytecode(const AztecAddress& address) return bytecode_id; } -Instruction TxBytecodeManager::read_instruction(const BytecodeId& bytecode_id, uint32_t pc) +Instruction TxBytecodeManager::read_instruction(const BytecodeId& bytecode_id, PC pc) { return read_instruction(bytecode_id, get_bytecode_data(bytecode_id), pc); } Instruction TxBytecodeManager::read_instruction(const BytecodeId& bytecode_id, std::shared_ptr> bytecode_ptr, - uint32_t pc) + PC pc) { BB_BENCH_NAME("TxBytecodeManager::read_instruction"); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/bytecode_manager.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/bytecode_manager.hpp index 539c174227ec..6de82522f004 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/bytecode_manager.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/bytecode_manager.hpp @@ -48,10 +48,10 @@ class TxBytecodeManager : public TxBytecodeManagerInterface { BytecodeId get_bytecode(const AztecAddress& address) override; std::shared_ptr> get_bytecode_data(const BytecodeId& bytecode_id) override; - Instruction read_instruction(const BytecodeId& bytecode_id, uint32_t pc) override; + Instruction read_instruction(const BytecodeId& bytecode_id, PC pc) override; Instruction read_instruction(const BytecodeId& bytecode_id, std::shared_ptr> bytecode_ptr, - uint32_t pc) override; + PC pc) override; private: ContractDBInterface& contract_db; @@ -76,7 +76,7 @@ class BytecodeManager : public BytecodeManagerInterface { , tx_bytecode_manager(tx_bytecode_manager) {} - Instruction read_instruction(uint32_t pc) override + Instruction read_instruction(PC pc) override { // We only assert in debug mode because this is in the hot path of the execution. BB_ASSERT_DEBUG(bytecode_id.has_value(), "Bytecode not retrieved before call to read_instruction"); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context.hpp index 95f2c0f824d1..a3dc9be44fa8 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context.hpp @@ -72,10 +72,10 @@ class BaseContext : public ContextInterface { return *internal_call_stack_manager; } - uint32_t get_pc() const override { return pc; } - void set_pc(uint32_t new_pc) override { pc = new_pc; } - uint32_t get_next_pc() const override { return next_pc; } - void set_next_pc(uint32_t new_next_pc) override { next_pc = new_next_pc; } + PC get_pc() const override { return pc; } + void set_pc(PC new_pc) override { pc = new_pc; } + PC get_next_pc() const override { return next_pc; } + void set_next_pc(PC new_next_pc) override { next_pc = new_next_pc; } bool halted() const override { return has_halted; } void halt() override { has_halted = true; } @@ -142,8 +142,8 @@ class BaseContext : public ContextInterface { uint32_t context_id; // Machine state. - uint32_t pc = 0; - uint32_t next_pc = 0; + PC pc = 0; + PC next_pc = 0; bool has_halted = false; Gas gas_used; Gas gas_limit; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp index 761ede9b9547..e7214cf3f619 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp @@ -1771,7 +1771,7 @@ EnqueuedCallResult Execution::execute(std::unique_ptr enqueued instruction = context.get_bytecode_manager().read_instruction(pc); debug("@", pc, " ", instruction.to_string()); - context.set_next_pc(pc + static_cast(instruction.size_in_bytes())); + context.set_next_pc(pc + static_cast(instruction.size_in_bytes())); // next_pc is overwritten in dispatch_opcode() for JUMP, JUMPI, INTERNALCALL, and INTERNALRETURN. // Resolve the operands. diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp index 0e6fcfa514c7..d65a0ae67713 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.hpp @@ -211,7 +211,7 @@ class Execution : public ExecutionInterface { MemoryAddress rd_size; Gas gas_used; bool success; - uint32_t halting_pc = 0; // PC at which the context halted. + PC halting_pc = 0; // PC at which the context halted. std::optional halting_message; // If reverted. }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp index 5b7ad0ec7fe3..b94506eef02c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.test.cpp @@ -478,9 +478,9 @@ TEST_F(ExecutionSimulationTest, ExternalCallStaticnessPropagation) TEST_F(ExecutionSimulationTest, InternalCall) { - uint32_t pc = 100; // This is the pc of the current call. - uint32_t return_pc = 500; // This is next pc that we should return to after the internal call. - uint32_t pc_loc = 11; // This is the pc of the internal call + PC pc = 100; // This is the pc of the current call. + PC return_pc = 500; // This is next pc that we should return to after the internal call. + PC pc_loc = 11; // This is the pc of the internal call NiceMock internal_call_stack_manager; ON_CALL(context, get_internal_call_stack_manager).WillByDefault(ReturnRef(internal_call_stack_manager)); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/bytecode_manager.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/bytecode_manager.hpp index 1e6e60f70e40..440f03b5d8e6 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/bytecode_manager.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/bytecode_manager.hpp @@ -22,11 +22,11 @@ class TxBytecodeManagerInterface { virtual std::shared_ptr> get_bytecode_data(const BytecodeId& bytecode_id) = 0; // Retrieves an instruction and decomposes it if needed. // This version of read_instruction might retrieve the bytecode (and generate an event) if not already done. - virtual Instruction read_instruction(const BytecodeId& bytecode_id, uint32_t pc) = 0; + virtual Instruction read_instruction(const BytecodeId& bytecode_id, PC pc) = 0; // This version of read_instruction does not retrieve the bytecode. virtual Instruction read_instruction(const BytecodeId& bytecode_id, std::shared_ptr> bytecode_ptr, - uint32_t pc) = 0; + PC pc) = 0; }; // Manages the bytecode of a single nested call. Therefore always the same bytecode. @@ -35,7 +35,7 @@ class BytecodeManagerInterface { public: virtual ~BytecodeManagerInterface() = default; - virtual Instruction read_instruction(uint32_t pc) = 0; + virtual Instruction read_instruction(PC pc) = 0; // Returns the id of the current bytecode. Tries to fetch it if not already done. // Throws BytecodeNotFoundError if contract does not exist. diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/call_stack_metadata_collector.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/call_stack_metadata_collector.hpp index e0701bfddea1..e4dc894e623e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/call_stack_metadata_collector.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/call_stack_metadata_collector.hpp @@ -18,12 +18,12 @@ class CallStackMetadataCollectorInterface { virtual void set_phase(CoarseTransactionPhase phase) = 0; virtual void notify_enter_call(const AztecAddress& contract_address, - uint32_t caller_pc, + PC caller_pc, const CalldataProvider& calldata_provider, bool is_static_call, const Gas& gas_limit) = 0; virtual void notify_exit_call(bool success, - uint32_t pc, + PC pc, const std::optional& halting_message, const ReturnDataProvider& return_data_provider, const InternalCallStackProvider& internal_call_stack_provider) = 0; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/context.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/context.hpp index d9f60dd71d52..8696eeea4a6c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/context.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/context.hpp @@ -27,10 +27,10 @@ class ContextInterface { virtual const MemoryInterface& get_memory() const = 0; virtual BytecodeManagerInterface& get_bytecode_manager() = 0; virtual InternalCallStackManagerInterface& get_internal_call_stack_manager() = 0; - virtual uint32_t get_pc() const = 0; - virtual void set_pc(uint32_t new_pc) = 0; - virtual uint32_t get_next_pc() const = 0; - virtual void set_next_pc(uint32_t new_next_pc) = 0; + virtual PC get_pc() const = 0; + virtual void set_pc(PC new_pc) = 0; + virtual PC get_next_pc() const = 0; + virtual void set_next_pc(PC new_next_pc) = 0; virtual bool halted() const = 0; virtual void halt() = 0; virtual uint32_t get_context_id() const = 0; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.cpp index 6a1e8f633b16..8ba8d0f5b9b5 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.cpp @@ -26,7 +26,7 @@ bool CallStackMetadataCollector::should_skip_collection() const } void CallStackMetadataCollector::notify_enter_call(const AztecAddress& contract_address, - uint32_t caller_pc, + PC caller_pc, const CalldataProvider& calldata_provider, bool is_static_call, const Gas& gas_limit) @@ -60,7 +60,7 @@ void CallStackMetadataCollector::notify_enter_call(const AztecAddress& contract_ } void CallStackMetadataCollector::notify_exit_call(bool success, - uint32_t pc, + PC pc, const std::optional& halting_message, const ReturnDataProvider& return_data_provider, const InternalCallStackProvider& internal_call_stack_provider) diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.hpp index b66fd5895646..7e8eb6791b3e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.hpp @@ -21,12 +21,12 @@ class CallStackMetadataCollector : public CallStackMetadataCollectorInterface { void set_phase(CoarseTransactionPhase phase) override; void notify_enter_call(const AztecAddress& contract_address, - uint32_t caller_pc, + PC caller_pc, const CalldataProvider& calldata_provider, bool is_static_call, const Gas& gas_limit) override; void notify_exit_call(bool success, - uint32_t pc, + PC pc, const std::optional& halting_message, const ReturnDataProvider& return_data_provider, const InternalCallStackProvider& internal_call_stack_provider) override; @@ -62,9 +62,9 @@ InternalCallStackProvider make_internal_call_stack_provider( class NoopCallStackMetadataCollector : public CallStackMetadataCollectorInterface { public: void set_phase(CoarseTransactionPhase) override {} - void notify_enter_call(const AztecAddress&, uint32_t, const CalldataProvider&, bool, const Gas&) override {} + void notify_enter_call(const AztecAddress&, PC, const CalldataProvider&, bool, const Gas&) override {} void notify_exit_call(bool, - uint32_t, + PC, const std::optional&, const ReturnDataProvider&, const InternalCallStackProvider&) override diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.test.cpp index 863cadb41048..92e65c9e7bf8 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/lib/call_stack_metadata_collector.test.cpp @@ -27,8 +27,8 @@ TEST(CallStackMetadataCollectorTest, SingleCallEnterAndExit) { CallStackMetadataCollector collector(limits); AztecAddress contract_addr(0x1234); - uint32_t caller_pc = 100; - uint32_t exit_pc = 200; + PC caller_pc = 100; + PC exit_pc = 200; Gas gas_limit{ 1000, 2000 }; std::vector calldata = { FF(0xabcd), FF(0xef01) }; std::vector return_data = { FF(0x5678), FF(0x9abc) }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/hybrid_execution.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/hybrid_execution.cpp index 82edd369dc88..7c97e540b9c2 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/hybrid_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/hybrid_execution.cpp @@ -51,7 +51,7 @@ EnqueuedCallResult HybridExecution::execute(std::unique_ptr en Instruction instruction = context.get_bytecode_manager().read_instruction(pc); debug("@", pc, " ", instruction.to_string()); - context.set_next_pc(pc + static_cast(instruction.size_in_bytes())); + context.set_next_pc(pc + static_cast(instruction.size_in_bytes())); //// Temporality group 4 starts //// diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/pure_bytecode_manager.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/pure_bytecode_manager.cpp index 514145741977..bedddc8dac0c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/pure_bytecode_manager.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/pure_bytecode_manager.cpp @@ -86,7 +86,7 @@ BytecodeId PureTxBytecodeManager::get_bytecode(const AztecAddress& address) return bytecode_id; } -Instruction PureTxBytecodeManager::read_instruction(const BytecodeId& bytecode_id, uint32_t pc) +Instruction PureTxBytecodeManager::read_instruction(const BytecodeId& bytecode_id, PC pc) { // The corresponding bytecode is already stored in the cache if we call this routine. This is safe-guarded by the // fact that it is added in the cache when we retrieve the bytecode_id. @@ -95,7 +95,7 @@ Instruction PureTxBytecodeManager::read_instruction(const BytecodeId& bytecode_i Instruction PureTxBytecodeManager::read_instruction(const BytecodeId&, std::shared_ptr> bytecode_ptr, - uint32_t pc) + PC pc) { BB_BENCH_NAME("TxBytecodeManager::read_instruction"); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/pure_bytecode_manager.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/pure_bytecode_manager.hpp index 5b10d6f9be1a..df86be8e5472 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/pure_bytecode_manager.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/standalone/pure_bytecode_manager.hpp @@ -31,10 +31,10 @@ class PureTxBytecodeManager : public TxBytecodeManagerInterface { BytecodeId get_bytecode(const AztecAddress& address) override; std::shared_ptr> get_bytecode_data(const BytecodeId& bytecode_id) override; - Instruction read_instruction(const BytecodeId& bytecode_id, uint32_t pc) override; + Instruction read_instruction(const BytecodeId& bytecode_id, PC pc) override; Instruction read_instruction(const BytecodeId& bytecode_id, std::shared_ptr> bytecode_ptr, - uint32_t pc) override; + PC pc) override; private: ContractDBInterface& contract_db; @@ -42,7 +42,7 @@ class PureTxBytecodeManager : public TxBytecodeManagerInterface { unordered_flat_map>> bytecodes; unordered_flat_set retrieved_class_ids; - using InstructionIdentifier = std::tuple; + using InstructionIdentifier = std::tuple; unordered_flat_map instruction_cache; }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_bytecode_manager.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_bytecode_manager.hpp index 5f4b843a505f..a151ee7e9706 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_bytecode_manager.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_bytecode_manager.hpp @@ -17,7 +17,7 @@ class MockBytecodeManager : public BytecodeManagerInterface { MockBytecodeManager(); ~MockBytecodeManager() override; - MOCK_METHOD(Instruction, read_instruction, (uint32_t pc), (override)); + MOCK_METHOD(Instruction, read_instruction, (PC pc), (override)); MOCK_METHOD(BytecodeId, get_bytecode_id, (), (override)); MOCK_METHOD(std::optional, get_retrieved_bytecode_id, (), (override)); }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_call_stack_metadata_collector.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_call_stack_metadata_collector.hpp index ff9f85bc7b2e..4c16feb4a59a 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_call_stack_metadata_collector.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_call_stack_metadata_collector.hpp @@ -16,7 +16,7 @@ class MockCallStackMetadataCollector : public CallStackMetadataCollectorInterfac MOCK_METHOD(void, notify_enter_call, (const AztecAddress& contract_address, - uint32_t caller_pc, + PC caller_pc, const CalldataProvider& calldata_provider, bool is_static_call, const Gas& gas_limit), @@ -24,7 +24,7 @@ class MockCallStackMetadataCollector : public CallStackMetadataCollectorInterfac MOCK_METHOD(void, notify_exit_call, (bool success, - uint32_t pc, + PC pc, const std::optional& halting_message, const ReturnDataProvider& return_data_provider, const InternalCallStackProvider& internal_call_stack_provider), From 010bf282fd4e8e611f0dee381b8f21140528c306 Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Thu, 15 Jan 2026 16:32:09 +0000 Subject: [PATCH 05/15] feat(avm): mutate global gas fees and timestamp (#19500) Very very simple mutations for globals --- .../barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp | 8 +++++-- .../avm_fuzzer/fuzz_lib/fuzz.test.cpp | 3 ++- .../avm_fuzzer/fuzz_lib/simulator.cpp | 6 ++--- .../avm_fuzzer/fuzz_lib/simulator.hpp | 5 +++-- .../barretenberg/avm_fuzzer/fuzzer_lib.cpp | 22 ++++++++++++++----- .../barretenberg/avm_fuzzer/fuzzer_lib.hpp | 5 +++-- .../avm_fuzzer/mutations/bytecode.cpp | 1 + 7 files changed, 33 insertions(+), 17 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp index 4ab5b2ce0a44..38b098d71fe8 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp @@ -40,16 +40,20 @@ SimulatorResult fuzz_against_ts_simulator(FuzzerData& fuzzer_data, FuzzerContext FF fee_required_l2 = FF(tx.effective_gas_fees.fee_per_l2_gas) * FF(tx.gas_settings.gas_limits.l2_gas); ws_mgr->write_fee_payer_balance(tx.fee_payer, fee_required_da + fee_required_l2); + auto globals = create_default_globals(); + try { ws_mgr->checkpoint(); - cpp_result = cpp_simulator.simulate(*ws_mgr, contract_db, tx, /*public_data_writes=*/{}, /*note_hashes=*/{}); + cpp_result = + cpp_simulator.simulate(*ws_mgr, contract_db, tx, globals, /*public_data_writes=*/{}, /*note_hashes=*/{}); ws_mgr->revert(); } catch (const std::exception& e) { throw std::runtime_error(std::string("CppSimulator threw an exception: ") + e.what()); } ws_mgr->checkpoint(); - auto js_result = js_simulator->simulate(*ws_mgr, contract_db, tx, /*public_data_writes=*/{}, /*note_hashes=*/{}); + auto js_result = + js_simulator->simulate(*ws_mgr, contract_db, tx, globals, /*public_data_writes=*/{}, /*note_hashes=*/{}); context.reset(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp index 6eb296962ba9..cab37e206251 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp @@ -63,8 +63,9 @@ class FuzzTest : public ::testing::Test { FF fee_required_l2 = FF(tx.effective_gas_fees.fee_per_l2_gas) * FF(tx.gas_settings.gas_limits.l2_gas); ws_mgr->write_fee_payer_balance(tx.fee_payer, fee_required_da + fee_required_l2); auto cpp_simulator = CppSimulator(); + auto globals = create_default_globals(); - auto result = cpp_simulator.simulate(*ws_mgr, contract_db, tx, {}, {}); + auto result = cpp_simulator.simulate(*ws_mgr, contract_db, tx, globals, /*public_data_writes=*/{}, {}); ws_mgr->revert(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp index cb8386b8eb62..010aa2cc35d6 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp @@ -81,6 +81,7 @@ SimulatorResult CppSimulator::simulate( fuzzer::FuzzerWorldStateManager& ws_mgr, fuzzer::FuzzerContractDB& contract_db, const Tx& tx, + const GlobalVariables& globals, [[maybe_unused]] const std::vector& public_data_writes, [[maybe_unused]] const std::vector& note_hashes) { @@ -97,8 +98,6 @@ SimulatorResult CppSimulator::simulate( ProtocolContracts protocol_contracts{}; - auto globals = create_default_globals(); - WorldState& ws = ws_mgr.get_world_state(); WorldStateRevision ws_rev = ws_mgr.get_current_revision(); @@ -156,11 +155,10 @@ SimulatorResult JsSimulator::simulate( [[maybe_unused]] fuzzer::FuzzerWorldStateManager& ws_mgr, fuzzer::FuzzerContractDB& contract_db, const Tx& tx, + const GlobalVariables& globals, const std::vector& public_data_writes, const std::vector& note_hashes) { - auto globals = create_default_globals(); - std::string serialized = serialize_simulation_request(tx, globals, contract_db, public_data_writes, note_hashes); // Send the request diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp index 540fffcd6ee9..d9cd3c3bfd2e 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp @@ -61,6 +61,7 @@ class Simulator { fuzzer::FuzzerWorldStateManager& ws_mgr, fuzzer::FuzzerContractDB& contract_db, const Tx& tx, + const GlobalVariables& globals, const std::vector& public_data_writes, const std::vector& note_hashes) = 0; }; @@ -71,6 +72,7 @@ class CppSimulator : public Simulator { SimulatorResult simulate(fuzzer::FuzzerWorldStateManager& ws_mgr, fuzzer::FuzzerContractDB& contract_db, const Tx& tx, + const GlobalVariables& globals, const std::vector& public_data_writes, const std::vector& note_hashes) override; }; @@ -97,6 +99,7 @@ class JsSimulator : public Simulator { SimulatorResult simulate(fuzzer::FuzzerWorldStateManager& ws_mgr, fuzzer::FuzzerContractDB& contract_db, const Tx& tx, + const GlobalVariables& globals, const std::vector& public_data_writes, const std::vector& note_hashes) override; }; @@ -111,5 +114,3 @@ Tx create_default_tx(const AztecAddress& contract_address, const Gas& gas_limit); bool compare_simulator_results(SimulatorResult& result1, SimulatorResult& result2); - -GlobalVariables create_default_globals(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp index 35dc4cb8cc89..12d2d292d25e 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp @@ -12,6 +12,8 @@ #include "barretenberg/avm_fuzzer/fuzz_lib/fuzz.hpp" #include "barretenberg/avm_fuzzer/fuzzer_comparison_helper.hpp" #include "barretenberg/avm_fuzzer/mutations/basic_types/field.hpp" +#include "barretenberg/avm_fuzzer/mutations/basic_types/uint64_t.hpp" +#include "barretenberg/avm_fuzzer/mutations/configuration.hpp" #include "barretenberg/avm_fuzzer/mutations/fuzzer_data.hpp" #include "barretenberg/avm_fuzzer/mutations/tx_data.hpp" #include "barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp" @@ -83,8 +85,8 @@ SimulatorResult fuzz_tx(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contr try { ws_mgr.checkpoint(); - cpp_result = - cpp_simulator.simulate(ws_mgr, contract_db, tx_data.tx, tx_data.public_data_writes, tx_data.note_hashes); + cpp_result = cpp_simulator.simulate( + ws_mgr, contract_db, tx_data.tx, tx_data.global_variables, tx_data.public_data_writes, tx_data.note_hashes); fuzz_info("CppSimulator completed without exception"); fuzz_info("CppSimulator result: ", cpp_result); ws_mgr.revert(); @@ -100,8 +102,8 @@ SimulatorResult fuzz_tx(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contr } ws_mgr.checkpoint(); - auto js_result = - js_simulator->simulate(ws_mgr, contract_db, tx_data.tx, tx_data.public_data_writes, tx_data.note_hashes); + auto js_result = js_simulator->simulate( + ws_mgr, contract_db, tx_data.tx, tx_data.global_variables, tx_data.public_data_writes, tx_data.note_hashes); // If the results do not match if (!compare_simulator_results(cpp_result, js_result)) { @@ -363,8 +365,16 @@ size_t mutate_tx_data(FuzzerContext& context, case FuzzerTxDataMutationType::ContractInstanceMutation: mutate_contract_instances(tx_data.contract_instances, tx_data.contract_addresses, rng); break; - // case TxDataMutationType::GlobalVariablesMutation: - // break; + case FuzzerTxDataMutationType::GlobalVariablesMutation: + // This is just mutating the gas values and timestamp + mutate_uint64_t(tx_data.global_variables.timestamp, rng, BASIC_UINT64_T_MUTATION_CONFIGURATION); + mutate_gas_fees(tx_data.global_variables.gas_fees, rng); + // This must be less than or equal to the tx max fees per gas + tx_data.global_variables.gas_fees.fee_per_da_gas = std::min( + tx_data.global_variables.gas_fees.fee_per_da_gas, tx_data.tx.gas_settings.max_fees_per_gas.fee_per_da_gas); + tx_data.global_variables.gas_fees.fee_per_l2_gas = std::min( + tx_data.global_variables.gas_fees.fee_per_l2_gas, tx_data.tx.gas_settings.max_fees_per_gas.fee_per_l2_gas); + break; // case TxDataMutationType::ProtocolContractsMutation: // break; } diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp index 08c6cf3abd16..f78e40e05bb7 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp @@ -65,17 +65,18 @@ enum class FuzzerTxDataMutationType : uint8_t { BytecodeMutation, ContractClassMutation, ContractInstanceMutation, - // GlobalVariablesMutation, + GlobalVariablesMutation, // ProtocolContractsMutation }; -using FuzzerTxDataMutationConfig = WeightedSelectionConfig; +using FuzzerTxDataMutationConfig = WeightedSelectionConfig; constexpr FuzzerTxDataMutationConfig FUZZER_TX_DATA_MUTATION_CONFIGURATION = FuzzerTxDataMutationConfig({ { FuzzerTxDataMutationType::TxMutation, 10 }, { FuzzerTxDataMutationType::BytecodeMutation, 1 }, { FuzzerTxDataMutationType::ContractClassMutation, 1 }, { FuzzerTxDataMutationType::ContractInstanceMutation, 1 }, + { FuzzerTxDataMutationType::GlobalVariablesMutation, 4 }, }); // Build bytecode and contract artifacts from fuzzer data diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp index 98b5e3c06c9e..9d1e413280a7 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/bytecode.cpp @@ -98,6 +98,7 @@ void mutate_bytecode(std::vector& contract_classes, FF delayed_public_mutable_slot = Poseidon2::hash({ FF(UPDATED_CLASS_IDS_SLOT), address }); // Build preimage + // todo(ilyas): make this somewhat random but also take into account the mutation on global variables.timestamp FF metadata = 0; // The lower 32 bits are the timestamp_of_change, we set to 0 so it has "taken effect" FF hash = Poseidon2::hash({ metadata, original_class_id, new_class_id }); From 1ffa9c37db1bc517d91650627c51fbfbb430a096 Mon Sep 17 00:00:00 2001 From: David Banks <47112877+dbanks12@users.noreply.github.com> Date: Thu, 15 Jan 2026 19:04:20 -0500 Subject: [PATCH 06/15] docs: avm docs (#19603) Review via github's markdown viewer: https://github.com/AztecProtocol/aztec-packages/blob/db/avm-docs/yarn-project/simulator/docs/avm/README.md --- yarn-project/simulator/README.md | 2 + yarn-project/simulator/docs/avm/README.md | 80 +++++ yarn-project/simulator/docs/avm/addressing.md | 98 +++++++ .../docs/avm/avm-isa-quick-reference.md | 267 +++++++++++++++++ .../simulator/docs/avm/calldata-returndata.md | 82 ++++++ .../simulator/docs/avm/enqueued-calls.md | 95 ++++++ yarn-project/simulator/docs/avm/errors.md | 44 +++ .../simulator/docs/avm/execution-lifecycle.md | 62 ++++ .../simulator/docs/avm/external-calls.md | 182 ++++++++++++ yarn-project/simulator/docs/avm/gas.md | 108 +++++++ yarn-project/simulator/docs/avm/memory.md | 139 +++++++++ .../simulator/docs/avm/opcodes/add.md | 113 ++++++++ .../simulator/docs/avm/opcodes/and.md | 116 ++++++++ .../simulator/docs/avm/opcodes/call.md | 125 ++++++++ .../docs/avm/opcodes/calldatacopy.md | 102 +++++++ .../simulator/docs/avm/opcodes/cast.md | 109 +++++++ .../simulator/docs/avm/opcodes/debuglog.md | 99 +++++++ .../simulator/docs/avm/opcodes/div.md | 116 ++++++++ .../simulator/docs/avm/opcodes/ecadd.md | 123 ++++++++ .../docs/avm/opcodes/emitnotehash.md | 90 ++++++ .../docs/avm/opcodes/emitnullifier.md | 91 ++++++ .../docs/avm/opcodes/emitunencryptedlog.md | 95 ++++++ yarn-project/simulator/docs/avm/opcodes/eq.md | 113 ++++++++ .../simulator/docs/avm/opcodes/fdiv.md | 116 ++++++++ .../docs/avm/opcodes/getcontractinstance.md | 118 ++++++++ .../simulator/docs/avm/opcodes/getenvvar.md | 107 +++++++ .../docs/avm/opcodes/internalcall.md | 51 ++++ .../docs/avm/opcodes/internalreturn.md | 48 +++ .../simulator/docs/avm/opcodes/jump.md | 51 ++++ .../simulator/docs/avm/opcodes/jumpi.md | 90 ++++++ .../simulator/docs/avm/opcodes/keccakf1600.md | 94 ++++++ .../docs/avm/opcodes/l1tol2msgexists.md | 97 +++++++ yarn-project/simulator/docs/avm/opcodes/lt.md | 113 ++++++++ .../simulator/docs/avm/opcodes/lte.md | 113 ++++++++ .../simulator/docs/avm/opcodes/mov.md | 105 +++++++ .../simulator/docs/avm/opcodes/mul.md | 113 ++++++++ .../simulator/docs/avm/opcodes/not.md | 110 +++++++ .../docs/avm/opcodes/notehashexists.md | 97 +++++++ .../docs/avm/opcodes/nullifierexists.md | 97 +++++++ yarn-project/simulator/docs/avm/opcodes/or.md | 116 ++++++++ .../simulator/docs/avm/opcodes/poseidon2.md | 94 ++++++ .../simulator/docs/avm/opcodes/return.md | 96 ++++++ .../docs/avm/opcodes/returndatacopy.md | 102 +++++++ .../docs/avm/opcodes/returndatasize.md | 92 ++++++ .../simulator/docs/avm/opcodes/revert.md | 112 +++++++ .../docs/avm/opcodes/sendl2tol1msg.md | 93 ++++++ .../simulator/docs/avm/opcodes/set.md | 177 +++++++++++ .../docs/avm/opcodes/sha256compression.md | 97 +++++++ .../simulator/docs/avm/opcodes/shl.md | 113 ++++++++ .../simulator/docs/avm/opcodes/shr.md | 113 ++++++++ .../simulator/docs/avm/opcodes/sload.md | 94 ++++++ .../simulator/docs/avm/opcodes/sstore.md | 94 ++++++ .../simulator/docs/avm/opcodes/staticcall.md | 126 ++++++++ .../simulator/docs/avm/opcodes/sub.md | 113 ++++++++ .../simulator/docs/avm/opcodes/successcopy.md | 91 ++++++ .../simulator/docs/avm/opcodes/toradixbe.md | 123 ++++++++ .../simulator/docs/avm/opcodes/xor.md | 116 ++++++++ .../docs/avm/public-tx-simulation.md | 274 ++++++++++++++++++ yarn-project/simulator/docs/avm/state.md | 47 +++ yarn-project/simulator/docs/avm/tooling.md | 46 +++ .../simulator/docs/avm/wire-format.md | 84 ++++++ 61 files changed, 6384 insertions(+) create mode 100644 yarn-project/simulator/docs/avm/README.md create mode 100644 yarn-project/simulator/docs/avm/addressing.md create mode 100644 yarn-project/simulator/docs/avm/avm-isa-quick-reference.md create mode 100644 yarn-project/simulator/docs/avm/calldata-returndata.md create mode 100644 yarn-project/simulator/docs/avm/enqueued-calls.md create mode 100644 yarn-project/simulator/docs/avm/errors.md create mode 100644 yarn-project/simulator/docs/avm/execution-lifecycle.md create mode 100644 yarn-project/simulator/docs/avm/external-calls.md create mode 100644 yarn-project/simulator/docs/avm/gas.md create mode 100644 yarn-project/simulator/docs/avm/memory.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/add.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/and.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/call.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/calldatacopy.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/cast.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/debuglog.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/div.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/ecadd.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/emitnotehash.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/emitnullifier.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/emitunencryptedlog.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/eq.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/fdiv.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/getenvvar.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/internalcall.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/internalreturn.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/jump.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/jumpi.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/keccakf1600.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/l1tol2msgexists.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/lt.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/lte.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/mov.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/mul.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/not.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/notehashexists.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/nullifierexists.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/or.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/poseidon2.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/return.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/returndatacopy.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/returndatasize.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/revert.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/sendl2tol1msg.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/set.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/sha256compression.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/shl.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/shr.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/sload.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/sstore.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/staticcall.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/sub.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/successcopy.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/toradixbe.md create mode 100644 yarn-project/simulator/docs/avm/opcodes/xor.md create mode 100644 yarn-project/simulator/docs/avm/public-tx-simulation.md create mode 100644 yarn-project/simulator/docs/avm/state.md create mode 100644 yarn-project/simulator/docs/avm/tooling.md create mode 100644 yarn-project/simulator/docs/avm/wire-format.md diff --git a/yarn-project/simulator/README.md b/yarn-project/simulator/README.md index 1f29f54f2134..3533c59d89b9 100644 --- a/yarn-project/simulator/README.md +++ b/yarn-project/simulator/README.md @@ -28,6 +28,8 @@ They are run with the assistance of an oracle that provides any value read from Public functions can call other public function, but no private functions. +See the specifications of the [Aztec Virtual Machine (AVM) for public execution](./docs/avm/index.md). + ### Unconstrained Functions Unconstrained functions are useful to extract useful data for users that could produce very large execution traces - such as the summed balance of all a users notes diff --git a/yarn-project/simulator/docs/avm/README.md b/yarn-project/simulator/docs/avm/README.md new file mode 100644 index 000000000000..eea6fd284b94 --- /dev/null +++ b/yarn-project/simulator/docs/avm/README.md @@ -0,0 +1,80 @@ +# Aztec Virtual Machine (AVM) + +While private execution is performed client-side and proven in a traditional ZK circuit, +public execution follows a more standard Ethereum-style execution model in a Virtual +Machine (VM). As with execution on Ethereum, Aztec's public execution must be +performed by network participants to guarantee global, deterministic and sequential +ordering of public state accesses. + +While using a VM instead of a series of compiled circuits introduces some costs, it is +required on a generally programmable platform like Aztec. Without one, errors during +the execution of a public function cannot be distinguished from a proof which is simply +invalid (i.e., a proof with unsatisfiable constraints). This would create an opportunity for +a Sequencer or Prover to censor user transactions by crafting invalid witnesses, or for a +user to grief the network by submitting transactions which can never be successfully +proven. + +Given that public execution must be performed network-side, network participants must +be fairly compensated for their time and resources. Not only does that imply the need for +gas/mana metering of public execution, but it also means that network participants +must be compensated for transactions that error during public execution to ensure fair +compensation and prevent DDoS attacks. + +These two critical requirements, gas metering and compensation for failing transactions, +render standard ZK circuits impractical for Aztec's public execution. A VM is the clear +alternative. + +Furthermore, as part of a ZK-rollup system, every transaction's execution must be +provable, including its public portion. Only once a transaction is proven and rolled up in +a block are its state updates accepted by the network. Therefore, a VM for public +execution must be provable and compatible with Aztec’s ZK-SNARK proving system. + +The Aztec Virtual Machine was designed with all of these requirements in mind. + +The AVM features a custom Instruction Set Architecture (ISA). Contracts with public +logic contain public bytecode, a sequence of AVM instructions with a bit-format optimized +for efficient constraining in a zkVM. A contract’s public bytecode can be invoked by +public execution requests. + +The AVM: +* Executes specified public bytecode, instruction by instruction, given some arguments. +* Meters execution by tracking gas costs per-executed-instruction. +* Tracks both "mana" (aka L2 gas) and "data availability" gas. +* Supports nested contract calls and conditional error recovery. +* Manages access to public state, L1↔L2 messages, public logs, and some limited private state. +* Finalizes state updates initiated during private execution. +* Handles fee payment based on accumulated gas costs. +* Uses field elements (not raw bytes) for calldata and return data. + +All public execution for a transaction is performed as a unit and eventually proven in a +single AVM proof. + +## Sections + +### Overview of Public Simulation +- **[Enqueued Calls](./enqueued-calls.md)**: How public calls are enqueued from private and delivered to the AVM +- **[Public Transaction Simulation](./public-tx-simulation.md)**: Execution phases, rollback on reverts, fee payment, and finalization + +### The Machine Model +- **[State](./state.md)**: World state (persistent) vs execution state (transient) +- **[Memory Model](./memory.md)**: Tagged memory and type system +- **[Addressing Modes](./addressing.md)**: Direct, indirect, and relative addressing + +### Execution +- **[Execution Lifecycle](./execution-lifecycle.md)**: VM initialization, PC rules, halting, gas charging order +- **[Gas Metering](./gas.md)**: Two-dimensional gas (L2 + DA) calculation +- **[Errors](./errors.md)**: Error types, triggers, and gas/state behavior + +### External Contract Calls +- **[External Calls](./external-calls.md)**: Nested contract calls (CALL, STATICCALL, RETURN, REVERT) +- **[Calldata and Return Data](./calldata-returndata.md)**: Passing data in and out of calls + +### Instruction Set Reference +- **[Wire Formats](./wire-format.md)**: How instructions are encoded in bytecode +- **[Instruction Set: Quick Reference](./avm-isa-quick-reference.md)**: All AVM instructions (links to individual opcode docs) + +### Miscellaneous +- **[Tooling and Compilation](./tooling.md)**: Noir to AVM bytecode pipeline + +--- +Next: [Enqueued Calls](./enqueued-calls.md) → diff --git a/yarn-project/simulator/docs/avm/addressing.md b/yarn-project/simulator/docs/avm/addressing.md new file mode 100644 index 000000000000..5f90e6953398 --- /dev/null +++ b/yarn-project/simulator/docs/avm/addressing.md @@ -0,0 +1,98 @@ +# Addressing + +## Addressing Modes + +The AVM supports three addressing modes that determine how memory offsets/addresses in instructions are resolved to their final memory addresses. Each instruction can use a mix of addressing modes for different operands. + +This page uses `M[x]` to denote the value at memory offset `x` (see [Memory Notation](memory.md#memory-notation)). + + +### Direct Addressing + +Direct addressing uses the memory offset value directly as specified in the instruction. + +**Notation**: `M[x]` + +**Example**: If an instruction specifies offset `100`, the VM reads or writes memory at address `100` (`M[100]`). + +### Indirect Addressing + +Indirect addressing treats the memory offset as a pointer to another memory location that contains the actual address. + +**Notation**: `M[M[x]]` + +**Example**: If an instruction specifies offset `100` with indirect addressing, the VM: +1. Reads the value at memory address `100` (reads `M[100]` and gets `250`) +2. Uses that value as the actual memory address (reads/writes to `M[250]`) + +### Relative Addressing + +Relative addressing adds the memory offset to the value stored at memory address `0` (the base pointer). + +**Notation**: `M[x + M[0]]` + +**Example**: If memory address `0` contains `1000` and an instruction specifies offset `50` with relative addressing: +1. The VM reads `M[0]` (e.g., `1000`) +2. Adds the offset: `50 + 1000 = 1050` +3. Uses `1050` as the actual memory address (reads/writes to `M[1050]`) + +### Indirect and Relative Addressing + +When both indirect and relative addressing modes are applied to an offset `x`, **relative addressing is resolved first, then indirect addressing**. + +**Notation**: `M[x + M[0]]` (resolved address) + +This means the VM first adds the base pointer `M[0]` to the offset to compute an intermediate address, then reads the pointer from that intermediate address to get the final address. + +**Example**: +- `M[0]` (base pointer) = `1000` +- Instruction specifies offset `x = 50` with both indirect and relative addressing. +- `M[1050]` contains the value `200`. + +1. **Relative Resolution**: The VM adds the base pointer to the offset: `50 + M[0] = 50 + 1000 = 1050`. +2. **Indirect Resolution**: The VM reads the pointer at the intermediate address: `M[1050] = 200`. +3. The final memory address is `200`, so the VM reads/writes `M[200]`. + +### Addressing Mode Bitmask + +Each instruction encodes its addressing modes in a bitmask where each bit corresponds to one memory offset operand. The bitmask determines which addressing mode applies to each operand. + +#### Bitmask Encoding + +Each of an instruction's memory-offset operands uses **2 bits** in the addressing mode bitmask: + +| Bits | Mode | +|------|------| +| `00` | Direct | +| `01` | Indirect | +| `10` | Relative | +| `11` | Indirect _and_ relative | + +#### Reading the Bitmask + +Operands are encoded from **right to left** (least significant bits first): +- Bits 0-1: First memory offset operand's addressing mode +- Bits 2-3: Second memory offset operand's addressing mode +- Bits 4-5: Third memory offset operand's addressing mode +- And so on... + +**Example**: For an instruction with 3 memory-offset operands: +- Bitmask `0x06` (hex) = `000110` (binary) + - First memory offset operand (bits 0-1 = `10`): Relative + - Second memory offset operand (bits 2-3 = `01`): Indirect + - Third memory offset operand (bits 4-5 = `00`): Direct + +**Wire format note**: In the bytecode encoding, all memory offset operands are grouped together before any immediate operands. The addressing mode bitmask applies only to these memory offset operands—immediate values (constants embedded in the instruction) are not subject to addressing modes. See [Wire Formats](./wire-format.md) for encoding details. + +### Gas Cost Considerations + +Each memory offset operand that uses non-direct addressing mode(s) incurs additional L2 gas costs: + +- **Direct**: No additional cost +- **Indirect**: 3 L2 gas per operand +- **Relative**: 3 L2 gas per operand + +These costs are charged **before** operands are resolved, based on the addressing mode bitmask. If a memory offset operand is flagged as _both_ indirect _and_ relative via the bitmask, 6 additional L2 gas is charged for that operand's addressing. + +--- +← Previous: [Memory Model](./memory.md) | Next: [Execution Lifecycle](./execution-lifecycle.md) → \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md b/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md new file mode 100644 index 000000000000..de90a50ea76d --- /dev/null +++ b/yarn-project/simulator/docs/avm/avm-isa-quick-reference.md @@ -0,0 +1,267 @@ +# Instruction Set: Quick Reference + +Quick reference for all Aztec Virtual Machine (AVM) opcodes. + +## Supporting Materials + +Before diving into the instruction set, familiarize yourself with these core concepts: + +- **[Introduction](index.md)**: What is the AVM and why do we need it? +- **[State](state.md)**: World state (persistent) vs execution state (transient) +- **[Memory Model](memory.md)**: Memory notation and tagged memory (`M[x]` and `T[x]`) +- **[Addressing Modes](addressing.md)**: Direct, indirect, and relative addressing along with their gas implications +- **[Execution Lifecycle](execution-lifecycle.md)**: VM initialization, PC rules, halting, gas charging order +- **[Gas Metering](gas.md)**: How L2 and DA gas costs are calculated and charged during instruction execution +- **[Errors](errors.md)**: Error types, triggers, and gas/state behavior +- **[Wire Formats](wire-format.md)**: How instructions are encoded in bytecode and why opcodes have variants like `ADD_8` and `ADD_16` + +## Quick Reference + +Click on an opcode name to view its detailed documentation. + +* **[🔗ADD](opcodes/add.md)**: Addition (a + b) + * Opcodes `0x00`-`0x01` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] + M[bOffset] + ``` +* **[🔗SUB](opcodes/sub.md)**: Subtraction (a - b) + * Opcodes `0x02`-`0x03` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] - M[bOffset] + ``` +* **[🔗MUL](opcodes/mul.md)**: Multiplication (a * b) + * Opcodes `0x04`-`0x05` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] * M[bOffset] + ``` +* **[🔗DIV](opcodes/div.md)**: Integer division (a / b) + * Opcodes `0x06`-`0x07` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] / M[bOffset] + ``` +* **[🔗FDIV](opcodes/fdiv.md)**: Field division (a / b) + * Opcodes `0x08`-`0x09` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] / M[bOffset] + ``` +* **[🔗EQ](opcodes/eq.md)**: Equality check (a == b) + * Opcodes `0x0A`-`0x0B` (2 wire formats) + ```javascript + M[dstOffset] = (M[aOffset] == M[bOffset]) ? 1 : 0 + ``` +* **[🔗LT](opcodes/lt.md)**: Less than (a < b) + * Opcodes `0x0C`-`0x0D` (2 wire formats) + ```javascript + M[dstOffset] = (M[aOffset] < M[bOffset]) ? 1 : 0 + ``` +* **[🔗LTE](opcodes/lte.md)**: Less than or equal (a <= b) + * Opcodes `0x0E`-`0x0F` (2 wire formats) + ```javascript + M[dstOffset] = (M[aOffset] <= M[bOffset]) ? 1 : 0 + ``` +* **[🔗AND](opcodes/and.md)**: Bitwise AND (a & b) + * Opcodes `0x10`-`0x11` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] & M[bOffset] + ``` +* **[🔗OR](opcodes/or.md)**: Bitwise OR (a | b) + * Opcodes `0x12`-`0x13` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] | M[bOffset] + ``` +* **[🔗XOR](opcodes/xor.md)**: Bitwise XOR (a ^ b) + * Opcodes `0x14`-`0x15` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] ^ M[bOffset] + ``` +* **[🔗NOT](opcodes/not.md)**: Bitwise NOT (~a) + * Opcodes `0x16`-`0x17` (2 wire formats) + ```javascript + M[dstOffset] = ~M[srcOffset] + ``` +* **[🔗SHL](opcodes/shl.md)**: Shift left (a << b) + * Opcodes `0x18`-`0x19` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] << M[bOffset] + ``` +* **[🔗SHR](opcodes/shr.md)**: Shift right (a >> b) + * Opcodes `0x1A`-`0x1B` (2 wire formats) + ```javascript + M[dstOffset] = M[aOffset] >> M[bOffset] + ``` +* **[🔗CAST](opcodes/cast.md)**: Type cast memory value + * Opcodes `0x1C`-`0x1D` (2 wire formats) + ```javascript + M[dstOffset] = M[srcOffset] as tag + ``` +* **[🔗GETENVVAR](opcodes/getenvvar.md)**: Get environment variable + * Opcode `0x1E` + ```javascript + M[dstOffset] = environmentVariable[varEnum] + ``` +* **[🔗CALLDATACOPY](opcodes/calldatacopy.md)**: Copy calldata to memory + * Opcode `0x1F` + ```javascript + M[dstOffset:dstOffset+M[copySizeOffset]] = calldata[M[cdStartOffset]:M[cdStartOffset]+M[copySizeOffset]] + ``` +* **[🔗SUCCESSCOPY](opcodes/successcopy.md)**: Get success status of latest external call + * Opcode `0x20` + ```javascript + M[dstOffset] = nestedCallSuccess ? 1 : 0 + ``` +* **[🔗RETURNDATASIZE](opcodes/returndatasize.md)**: Get returndata size + * Opcode `0x21` + ```javascript + M[dstOffset] = nestedReturndata.length + ``` +* **[🔗RETURNDATACOPY](opcodes/returndatacopy.md)**: Copy returndata to memory + * Opcode `0x22` + ```javascript + M[dstOffset:dstOffset+M[copySizeOffset]] = nestedReturndata[M[rdStartOffset]:M[rdStartOffset]+M[copySizeOffset]] + ``` +* **[🔗JUMP](opcodes/jump.md)**: Unconditional jump + * Opcode `0x23` + ```javascript + PC = jumpOffset + ``` +* **[🔗JUMPI](opcodes/jumpi.md)**: Conditional jump + * Opcode `0x24` + ```javascript + if M[condOffset] != 0 then PC = loc else PC = PC + instructionSize + ``` +* **[🔗INTERNALCALL](opcodes/internalcall.md)**: Internal function call + * Opcode `0x25` + ```javascript + internalCallStack.push({callPc: PC, returnPc: PC + instructionSize}); PC = loc + ``` +* **[🔗INTERNALRETURN](opcodes/internalreturn.md)**: Return from internal call + * Opcode `0x26` + ```javascript + PC = internalCallStack.pop().returnPc + ``` +* **[🔗SET](opcodes/set.md)**: Set memory to immediate value + * Opcodes `0x27`-`0x2C` (6 wire formats) + ```javascript + M[dstOffset] = value + ``` +* **[🔗MOV](opcodes/mov.md)**: Move value between memory locations + * Opcodes `0x2D`-`0x2E` (2 wire formats) + ```javascript + M[dstOffset] = M[srcOffset] + ``` +* **[🔗SLOAD](opcodes/sload.md)**: Load value from public storage + * Opcode `0x2F` + ```javascript + M[dstOffset] = storage[contractAddress][M[slotOffset]] + ``` +* **[🔗SSTORE](opcodes/sstore.md)**: Store value to public storage + * Opcode `0x30` + ```javascript + storage[contractAddress][M[slotOffset]] = M[srcOffset] + ``` +* **[🔗NOTEHASHEXISTS](opcodes/notehashexists.md)**: Check existence of note hash + * Opcode `0x31` + ```javascript + M[existsOffset] = noteHashTree.exists(M[noteHashOffset], M[leafIndexOffset]) ? 1 : 0 + ``` +* **[🔗EMITNOTEHASH](opcodes/emitnotehash.md)**: Emit note hash + * Opcode `0x32` + ```javascript + noteHashes.append(M[noteHashOffset]) + ``` +* **[🔗NULLIFIEREXISTS](opcodes/nullifierexists.md)**: Check existence of nullifier + * Opcode `0x33` + ```javascript + M[existsOffset] = nullifierTree.exists(M[addressOffset], M[nullifierOffset]) ? 1 : 0 + ``` +* **[🔗EMITNULLIFIER](opcodes/emitnullifier.md)**: Emit nullifier + * Opcode `0x34` + ```javascript + nullifiers.append(M[nullifierOffset]) + ``` +* **[🔗L1TOL2MSGEXISTS](opcodes/l1tol2msgexists.md)**: Check existence of L1-to-L2 message + * Opcode `0x35` + ```javascript + M[existsOffset] = l1ToL2Messages.exists(M[msgHashOffset], M[msgLeafIndexOffset]) ? 1 : 0 + ``` +* **[🔗GETCONTRACTINSTANCE](opcodes/getcontractinstance.md)**: Get contract instance information + * Opcode `0x36` + ```javascript + M[dstOffset] = contractInstance.exists ? 1 : 0; M[dstOffset+1] = contractInstance[memberEnum] + ``` +* **[🔗EMITUNENCRYPTEDLOG](opcodes/emitunencryptedlog.md)**: Emit public log + * Opcode `0x37` + ```javascript + unencryptedLogs.append(M[logOffset:logOffset+M[logSizeOffset]]) + ``` +* **[🔗SENDL2TOL1MSG](opcodes/sendl2tol1msg.md)**: Send L2-to-L1 message + * Opcode `0x38` + ```javascript + l2ToL1Messages.append({recipient: M[recipientOffset], content: M[contentOffset]}) + ``` +* **[🔗CALL](opcodes/call.md)**: Call external contract + * Opcode `0x39` + ```javascript + nestedCallResult = executeContract( + /*address=*/M[addrOffset], + /*args=*/M[argsOffset:argsOffset+M[argsSizeOffset]], + {l2Gas: M[l2GasOffset], daGas: M[daGasOffset]} + ) + ``` +* **[🔗STATICCALL](opcodes/staticcall.md)**: Static call to external contract + * Opcode `0x3A` + ```javascript + nestedCallResult = executeContractStatic( + /*address=*/M[addrOffset], + /*args=*/M[argsOffset:argsOffset+M[argsSizeOffset]], + {l2Gas: M[l2GasOffset], daGas: M[daGasOffset]} + ) + ``` +* **[🔗RETURN](opcodes/return.md)**: Return from call + * Opcode `0x3B` + ```javascript + return M[returnOffset:returnOffset+M[returnSizeOffset]]; halt + ``` +* **[🔗REVERT](opcodes/revert.md)**: Revert execution + * Opcodes `0x3C`-`0x3D` (2 wire formats) + ```javascript + revert M[returnOffset:returnOffset+M[retSizeOffset]]; halt + ``` +* **[🔗DEBUGLOG](opcodes/debuglog.md)**: Output debug log + * Opcode `0x3E` + ```javascript + debugLog(level, message, M[fieldsOffset:fieldsOffset+M[fieldsSizeOffset]]) + ``` +* **[🔗POSEIDON2](opcodes/poseidon2.md)**: Poseidon2 permutation + * Opcode `0x3F` + ```javascript + M[outputStateOffset:outputStateOffset+4] = poseidon2Permutation(/*input=*/M[inputStateOffset:inputStateOffset+4]) + ``` +* **[🔗SHA256COMPRESSION](opcodes/sha256compression.md)**: SHA-256 compression + * Opcode `0x40` + ```javascript + M[outputOffset:outputOffset+8] = sha256compress(/*state=*/M[stateOffset:stateOffset+8], /*inputs=*/M[inputsOffset:inputsOffset+16]) + ``` +* **[🔗KECCAKF1600](opcodes/keccakf1600.md)**: Keccak-f[1600] permutation + * Opcode `0x41` + ```javascript + M[dstOffset:dstOffset+25] = keccakf1600(/*input=*/M[inputOffset:inputOffset+25]) + ``` +* **[🔗ECADD](opcodes/ecadd.md)**: Grumpkin elliptic curve addition + * Opcode `0x42` + ```javascript + M[dstOffset:dstOffset+3] = grumpkinAdd( + /*point1=*/{x: M[p1XOffset], y: M[p1YOffset], isInfinite: M[p1IsInfiniteOffset]}, + /*point2=*/{x: M[p2XOffset], y: M[p2YOffset], isInfinite: M[p2IsInfiniteOffset]} + ) + ``` +* **[🔗TORADIXBE](opcodes/toradixbe.md)**: Convert to radix (big-endian) + * Opcode `0x43` + ```javascript + M[dstOffset:dstOffset+M[numLimbsOffset]] = toRadixBE( + /*value=*/M[srcOffset], + /*radix=*/M[radixOffset], + /*numLimbs=*/M[numLimbsOffset], + /*outputBits=*/M[outputBitsOffset] + ) + ``` diff --git a/yarn-project/simulator/docs/avm/calldata-returndata.md b/yarn-project/simulator/docs/avm/calldata-returndata.md new file mode 100644 index 000000000000..1690490f4a61 --- /dev/null +++ b/yarn-project/simulator/docs/avm/calldata-returndata.md @@ -0,0 +1,82 @@ +# Calldata and Return Data + +This document explains how data is passed into and out of AVM execution contexts. + +## Overview + +The AVM uses memory-based data passing for nested calls: +- **Calldata**: Input arguments passed to a contract. +- **Return data**: Output values returned from a nested call + +Unlike the EVM, the AVM uses field elements (not raw bytes). Calldata is _always_ fields. + +## Calldata + +### Accessing Calldata + +The current context's calldata is accessed via: +- `CALLDATASIZE` — Returns the number of field elements in calldata +- `CALLDATACOPY` — Copies calldata to memory + +``` +CALLDATASIZE dstOffset // M[dstOffset] = calldata.length +CALLDATACOPY cdOffset size copyOffset // Copy calldata[cdOffset..cdOffset+size] to M[copyOffset..] +``` + +### Passing Calldata to Nested Calls + +When making a `CALL` or `STATICCALL`, the caller specifies calldata via memory: +- `argsOffset` — Memory offset where arguments start +- `argsSize` — Number of field elements to pass + +The callee receives these values as its calldata. The values are copied from the caller's memory—type tags are not preserved in the transfer. Calldata is _always_ received by the callee as field elements and _the callee is responsible for casting inputs to the expected types if strict type safety is required._ + +**Note**: `CALL` (and `STATICCALL`) only _set_ the calldata parameters—they don't immediately copy or validate memory access. If callee attempts to read from a memory address ≥ 2³² in the caller's memory via `CALLDATACOPY` , an error occurs in the callee's context. Reading past the logical calldata size (beyond `argsSize`) is not an error—it returns zeros. + +## Return Data + +### Returning Data + +A context returns data via the `RETURN` instruction: +- `retOffset` — Memory offset where return data starts +- `retSize` — Number of field elements to return + +On `REVERT`, the same parameters specify revert data. + +**Note**: `RETURN` (and `REVERT`) only _set_ the return data parameters—they don't immediately copy or validate memory access. If caller attempts to read from a memory address ≥ 2³² in the callee's memory via `RETURNDATACOPY` , an error occurs in the caller's context. Reading past the logical return data size (beyond `retSize`) is not an error—it returns zeros. + +### Accessing Return Data + +After a nested call completes, the caller accesses return data via: +- `RETURNDATASIZE` — Returns the number of field elements returned +- `RETURNDATACOPY` — Copies return data to memory +- `SUCCESSCOPY` — Copies the success flag (0 or 1) + +``` +// After a nested call +SUCCESSCOPY dstOffset // M[dstOffset] = 0 (failed) or 1 (success) +RETURNDATASIZE dstOffset // M[dstOffset] = returndata.length +RETURNDATACOPY rdOffset size memOffset // Copy returndata[rdOffset..] to M[memOffset..] +``` + +**Important**: Return data is only available from the most recent external call. Making another call overwrites the return data buffer. + +## Data Layout + +The AVM does not enforce any specific encoding for calldata or return data. Conventions are determined by the compiler (Noir) and contract design. Typical patterns: + +- Arguments are laid out sequentially as field elements +- Structs and arrays follow compiler-defined layouts +- No function selectors at the AVM level (generally injected by the compiler alongside function dispatch logic) + +## Example: Forwarding a Call + +``` +// Forward all calldata to another contract +CALLDATASIZE cdSizeOffset // Get calldata size +CALLDATACOPY 0 M[cdSizeOffset] 0 // Copy all calldata to M[0..] +CALL ... 0 M[cdSizeOffset] ... // Pass M[0..size] as calldata +``` + +--- +← Previous: [External Calls](./external-calls.md) | Next: [Wire Formats](./wire-format.md) → diff --git a/yarn-project/simulator/docs/avm/enqueued-calls.md b/yarn-project/simulator/docs/avm/enqueued-calls.md new file mode 100644 index 000000000000..d5b81efe8255 --- /dev/null +++ b/yarn-project/simulator/docs/avm/enqueued-calls.md @@ -0,0 +1,95 @@ +# Enqueued Calls + +This document explains how public function calls are enqueued during private execution and delivered to the AVM for execution. + +## Overview + +Aztec's execution model separates private and public execution: +- **Private execution** happens on the user's device before transaction submission +- **Public execution** happens on the network (sequencer) after the transaction is submitted + +Since public functions need access to the current Aztec state (which isn't available client-side), private execution cannot directly execute public functions. Instead, it **enqueues** them—recording the intent to execute public code later. + +## Definitions + +### Public Call Request + +A `PublicCallRequest` is a lightweight record of a public function call to be executed. It contains: + +| Field | Description | +|-------|-------------| +| `msgSender` | Address of the caller (the private function's contract, or a null address if hidden) | +| `contractAddress` | Target contract to invoke | +| `isStaticCall` | Whether this is a read-only call (no state modifications allowed) | +| `calldataHash` | Hash of the function selector and arguments | + +The actual calldata is stored separately in the transaction to reduce proof size. The calldata hash is _not_ validated by private-side protocol circuits. The protocol relies on the AVM to verify that the calldata in a transaction matches the hash in the `PublicCallRequest`. + +### Enqueued Call + +An **enqueued call** is a public call request that has been scheduled during private execution for later execution by the AVM. The term emphasizes that: +1. The call is not executed immediately—all private execution completes first client-side +2. It will be processed later by the network +3. Its order relative to other enqueued calls is preserved via side-effect counters + +**Public Call Request** and **Enqueued Call** are often used interchangeably. + +## Enqueuing Public Calls from Private + +During private execution, a contract can enqueue public calls using methods on the private context: + +**Importantly, this is just pseudocode and does not reflect real interfaces for enqueueing calls.** + +```noir +// Standard public function call +context.call_public_function(contract_address, selector, args); + +// Read-only public call (no state changes allowed) +context.static_call_public_function(contract_address, selector, args); + +// Teardown function (always executes, even if app logic reverts) +context.set_public_teardown_function(contract_address, selector, args); +``` + +When a public call is enqueued: +1. The calldata is hashed to produce `calldataHash` +2. The calldata (preimage) is accumulated for later inclusion in the transaction +3. A `PublicCallRequest` is created referencing the `calldataHash` +4. The request is added to the private context's accumulated requests +5. A side-effect counter tracks ordering relative to other enqueued calls + +> **Note:** Enqueued calls (scheduled from private) are distinct from nested calls made via `CALL`/`STATICCALL` during AVM execution. Enqueued calls define the top-level public functions to execute; nested calls happen dynamically within those executions. + +## Transaction Structure + +After private execution completes, the transaction contains: + +``` +Transaction +├── Proof (proves correct private execution) +├── Side effects (from private execution) +├── Public Call Requests (each contains calldataHash) +│ ├── Non-revertible (setup phase) +│ ├── Revertible (app logic phase) +│ └── Teardown (optional, single call) +└── Public Call Calldata (raw fields, referenced by calldataHash) + ├── [arg0, arg1, ...] + └── ... +``` + +The kernel circuits aggregate all enqueued calls from nested private function calls and organize them by execution phase. + +## Execution Phases + +Enqueued calls are organized into three phases, each with different reversion semantics. See [Public Transaction Simulation](./public-tx-simulation.md) for detailed coverage of phase execution, rollback mechanics, and fee payment. + +1. **Setup Phase (Non-Revertible)**: If any call in this phase reverts, the entire transaction is dropped +2. **App Logic Phase (Revertible)**: Reverts are tolerated; side effects are rolled back but the transaction continues +3. **Teardown Phase (Revertible)**: Like app logic, reverts are tolerated and don't drop the transaction + +## Core AVM Execution + +Each enqueued call triggers execution of the core AVM instruction-by-instruction (see [Execution Lifecycle](./execution-lifecycle.md)). + +--- +← Previous: [Introduction](./README.md) | Next: [Public Transaction Simulation](./public-tx-simulation.md) → diff --git a/yarn-project/simulator/docs/avm/errors.md b/yarn-project/simulator/docs/avm/errors.md new file mode 100644 index 000000000000..12331661202a --- /dev/null +++ b/yarn-project/simulator/docs/avm/errors.md @@ -0,0 +1,44 @@ +# Errors + +This document provides a reference for AVM errors and their trigger conditions. + +## Overview + +An **error** occurs when the AVM encounters an invalid condition during execution. An error leads to an **exceptional halt**, stopping execution of the current context immediately. This differs from the two other ways execution can halt: explicit RETURN opcode and explicit REVERT opcode. + +## Error Reference + +| Error | Trigger | Category | During Private Insertions? | +|-------|---------|----------|-------------------| +| `INVALID_PROGRAM_COUNTER` | PC points beyond bytecode bounds | Instruction fetch | No | +| `INVALID_OPCODE` | PC points to an unrecognized opcode byte | Instruction fetch | No | +| `INSTRUCTION_PARSING_ERROR` | Malformed instruction encoding | Instruction fetch | No | +| `OUT_OF_GAS` | Insufficient L2 gas or DA gas for instruction | Gas charging | No | +| `TAG_MISMATCH` | Type tag mismatch between operands | Validation | No | +| `INVALID_TAG` | Operand tag is not valid for the operation | Validation | No | +| `INVALID_TAG_TYPE` | Operand is not an integral type (for bitwise/div ops) | Validation | No | +| `MEMORY_ACCESS_OUT_OF_RANGE` | Memory offset exceeds 32-bit addressable space | Validation | No | +| `RELATIVE_ADDRESS_OVERFLOW` | Base address + relative offset exceeds max memory | Validation | No | +| `STATIC_CALL_VIOLATION` | State-modifying operation in static context | Execution | No | +| `SIDE_EFFECT_LIMIT_REACHED` | Transaction limit exceeded for a side effect type | Execution | Yes | +| `NULLIFIER_COLLISION` | Emitted nullifier already exists | Execution (opcode-specific) | Yes | +| `INTERNAL_CALL_STACK_UNDERFLOW` | INTERNALRETURN with empty internal call stack | Execution (opcode-specific) | No | +| `DIVISION_BY_ZERO` | Division or modulo operation with divisor = 0 | Execution (opcode-specific) | No | +| `POINT_NOT_ON_CURVE` | ECADD operand is not a valid Grumpkin curve point | Execution (opcode-specific) | No | +| `INVALID_RADIX` | TORADIXBE radix not in range [2, 256] | Execution (opcode-specific) | No | +| `INVALID_DECOMPOSITION` | TORADIXBE value cannot be decomposed into specified radix/limbs | Execution (opcode-specific) | No | +| `INVALID_ENV_VAR` | GETENVVAR enum value out of range | Execution (opcode-specific) | No | +| `INVALID_MEMBER_ENUM` | GETCONTRACTINSTANCE member enum out of range | Execution (opcode-specific) | No | + + +## Error Behavior Summary + +| Halt | Outcome | Gas Behavior | State Behavior | Example | +|---------|---------|--------------|----------------|---------| +| **Exceptional halt** | Failure | All allocated gas consumed | Changes discarded | `OUT_OF_GAS`, `TAG_MISMATCH` | +| **Explicit REVERT** | Failure | Unused gas refunded | Changes discarded | REVERT instruction | +| **Explicit RETURN** | Success | Unused gas refunded | Changes merged | RETURN instruction | + + +--- +← Previous: [Gas Metering](./gas.md) | Next: [External Calls](./external-calls.md) → diff --git a/yarn-project/simulator/docs/avm/execution-lifecycle.md b/yarn-project/simulator/docs/avm/execution-lifecycle.md new file mode 100644 index 000000000000..bef58e34fa63 --- /dev/null +++ b/yarn-project/simulator/docs/avm/execution-lifecycle.md @@ -0,0 +1,62 @@ +# Execution Lifecycle + +This document describes the AVM execution lifecycle. It focuses on control-flow rules, halts, gas and state changes. + +## VM Initialization + +On creation of a VM execution context (top-level call or a nested CALL/STATICCALL frame), the VM initializes: + +- **Program Counter (PC)**: Set to `0` +- **Memory**: Initialized as empty +- **Gas Limits**: Derived from the enqueued call (top-level call initiated from private) or call instruction parameters (nested). The AVM tracks two gas dimensions: L2 gas and DA gas. +- **Internal Call Stack**: Starts empty (used by INTERNALCALL/INTERNALRETURN) + +A CALL/STATICCALL creates a fresh execution context; it does not reuse the caller's memory, PC, or internal call stack. + +## Program Counter + +The VM executes instructions at `PC`, which is a **byte offset** into the bytecode (not an instruction index). Unless an instruction specifies otherwise, control flow advances by instruction byte length: + +- **Default**: `PC += instruction_size_bytes` +- **JUMP**: `PC = target` +- **JUMPI**: If `condition != 0`, `PC = target`; otherwise advances normally +- **INTERNALCALL**: Pushes the return address onto the internal call stack, then sets `PC = target` +- **INTERNALRETURN**: Pops from the internal call stack and sets `PC` to that value +- **CALL/STATICCALL**: Creates a nested execution context; the caller's `PC` is not modified by the callee's control flow (the caller continues at its next instruction after the call completes) + +## Gas Charging Order + +Each instruction validates inputs, charges gas, executes, then writes outputs. Base and addressing costs are charged before operand resolution; dynamic costs are charged after. See [Gas Metering](gas.md) for cost components and calculation. + +## Call Frame/Context Management + +The AVM uses a "Fork and Merge" model for nested execution via `CALL` and `STATICCALL`: + +**Creation**: +- Fresh memory and fresh `PC` (starting at 0) +- Forked world state (callee sees a snapshot derived from the caller's state) +- Gas limit set to the amount the caller explicitly allocated for this call + +**Resolution**: +- **Success (RETURN)**: State changes are merged into the caller +- **Failure (REVERT)**: State changes are discarded; unused gas is returned to caller +- **Exceptional halt**: State changes are discarded; all allocated gas is consumed (no refund) + +## Halting Conditions + +Execution halts and the VM produces a completion result. + +**Normal halts**: +- **RETURN**: Halts with `success = true` and return data +- **REVERT**: Halts with `success = false` and revert data + +**Exceptional halts (errors)**: + +Exceptional halts stop execution immediately. For call-frame merging, exceptional halts are treated the same as REVERT (state discarded), but they consume all allocated gas. + +For a complete list of errors that trigger exceptional halts, see [Errors](errors.md). Common examples include: +- `OUT_OF_GAS`: Insufficient gas for instruction +- `TAG_MISMATCH`: Type tag mismatch on operands + +--- +← Previous: [Addressing Modes](./addressing.md) | Next: [Gas Metering](./gas.md) → diff --git a/yarn-project/simulator/docs/avm/external-calls.md b/yarn-project/simulator/docs/avm/external-calls.md new file mode 100644 index 000000000000..9f78a38596f1 --- /dev/null +++ b/yarn-project/simulator/docs/avm/external-calls.md @@ -0,0 +1,182 @@ +# External Calls + +The AVM allows one contract's execution to make an **external call** to another contract (or even the same contract). Each external call initializes a new **nested execution context** that runs in isolation from the caller. + +See [State](state.md) for background on world state vs execution state. + +## Nested Execution Contexts + +When [CALL](opcodes/call.md) or [STATICCALL](opcodes/staticcall.md) executes, the AVM creates a nested context for the callee: + +**Fresh execution state:** +- Memory starts empty (caller and callee have separate memory spaces) +- Program counter resets to 0 +- Internal call stack is empty +- Gas is allocated from the caller's remaining gas (see [Gas Allocation](#gas-allocation)) +- `nestedCallSuccess` and `nestedReturndata` are reset + +**Forked world state:** +- The callee operates on a fork of the caller's world state +- The callee can read the caller's uncommitted writes +- The callee's writes go to its own fork, isolated from the caller +- On success, the fork merges back; on revert, it's discarded + +**Derived environment:** + +The nested call inherits some environment fields unchanged and derives others: + +| Field | Behavior | Description | +|-------|----------|-------------| +| `address` | **Changed** | Set to the target contract's address | +| `sender` | **Changed** | Set to the caller's contract address | +| `calldata` | **Changed** | Set to the arguments specified by the caller | +| `isStaticCall` | **Propagated** | `true` if caller is static OR if using STATICCALL (see [Static Calls](#static-calls)) | +| `transactionFee` | Inherited | Same as caller | +| `globals` | Inherited | Same as caller (block number, timestamp, etc.) | + +## Transaction Limits + +The AVM enforces limits on side effects per transaction. These limits exist because the ZK circuits that prove execution have fixed capacity. + +### Unique Contract Class IDs + +Each transaction can call contracts from at most **21 unique contract class IDs** (`MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS`). This counts distinct contract classes, not individual calls—calling the same contract multiple times only counts once. + +If exceeded, the nested call fails with **SIDE_EFFECT_LIMIT_REACHED**. Control returns to the caller with `nestedCallSuccess = false`, allowing the caller to handle the failure via [SUCCESSCOPY](opcodes/successcopy.md). + +**Important**: Unlike other side effects, unique contract class IDs are tracked even if the nested call reverts. Once a contract class is called, it counts toward the limit for the entire transaction, regardless of whether that call succeeds. + +### Other Side Effect Limits + +These limits apply transaction-wide (across all nested calls): + +| Side Effect | Limit Constant | Error | +|-------------|----------------|-------| +| Storage writes | `MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX` | SIDE_EFFECT_LIMIT_REACHED | +| Nullifier emissions | `MAX_NULLIFIERS_PER_TX` | SIDE_EFFECT_LIMIT_REACHED | +| Note hash emissions | `MAX_NOTE_HASHES_PER_TX` | SIDE_EFFECT_LIMIT_REACHED | +| L2-to-L1 messages | `MAX_L2_TO_L1_MSGS_PER_TX` | SIDE_EFFECT_LIMIT_REACHED | +| Public log payload | `FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH` (total bytes) | SIDE_EFFECT_LIMIT_REACHED | + +**Reverted side effects**: When a nested call reverts, its side effects (storage writes, nullifiers, note hashes, logs, messages) are discarded and do **not** count toward transaction limits. The exception is unique contract class IDs, which always count (see above). + +## Gas Allocation + +The caller specifies how much L2 and DA gas to allocate to the nested call via memory operands. The actual allocation follows these rules: + +1. **Capped by available gas**: The allocated gas cannot exceed the caller's remaining gas. If the caller requests more than available, the allocation is silently capped. + +2. **Charged immediately**: The full allocated amount is deducted from the caller's gas before the nested call begins. + +3. **Refunded on completion**: When the nested call finishes via RETURN or REVERT, any unused gas is refunded to the caller. However, **exceptional halts** (errors) consume all allocated gas with no refund. + +**Example**: If the caller has 10,000 L2 gas remaining and allocates 8,000 to a nested call: +- 8,000 is deducted from the caller (leaving 2,000) +- The nested call runs with 8,000 L2 gas +- If the nested call uses 3,000 and returns, 5,000 is refunded to the caller +- The caller now has 7,000 L2 gas remaining + +## World State Isolation + +The nested call's world state is **forked** from the caller's state. This means: + +- **Reads see uncommitted writes**: The callee can read storage values written by the caller. + +- **Writes are isolated**: The callee's storage writes, nullifier emissions, note hash emissions, logs, and messages go to its own fork—not directly to the caller's state. + +- **Success merges the fork**: If the nested call returns successfully (via [RETURN](opcodes/return.md)), all its world state changes are merged into the caller's state. + +- **Revert discards the fork**: If the nested call reverts (via [REVERT](opcodes/revert.md) or an error), all its world state changes are discarded. The caller's state is unchanged. + +This isolation protects the caller from failed nested calls. A caller can attempt a call, check if it succeeded via [SUCCESSCOPY](opcodes/successcopy.md), and continue execution regardless of the outcome. + +## RETURN vs REVERT vs error + +Both instructions halt the nested call and return control to the caller: + +| Aspect | [RETURN](opcodes/return.md) | [REVERT](opcodes/revert.md) | error | +|--------|------------------------------|------------------------------|-------| +| `nestedCallSuccess` | `true` | `false` | `false` | +| World state changes | Merged to caller | Discarded | Discarded | +| Gas refund | Unused gas returned | Unused gas returned | All allocated gas consumed | +| Output data | Return value(s) | Error message/data | None | + +The caller retrieves the success flag via [SUCCESSCOPY](opcodes/successcopy.md) and the output data via [RETURNDATASIZE](opcodes/returndatasize.md) and [RETURNDATACOPY](opcodes/returndatacopy.md). + +## Errors + +Errors during nested execution (e.g., out of gas, invalid opcode, tag mismatch, side effect limit reached) cause an **exceptional halt**: + +- Execution stops immediately at the faulting instruction +- **All remaining gas is consumed** (no refund for errors) +- `nestedCallSuccess` is set to `false` +- `nestedReturndata` is empty (no output data) +- All world state changes are discarded + +This differs from an explicit REVERT, which refunds unused gas and can include output data. + +### Some Error Types + +This is not a comprehensive list. See individual opcode docs for more details. + +| Error | Cause | +|-------|-------| +| OUT_OF_GAS | Insufficient gas for instruction | +| INVALID_TAG | Type tag mismatch on operands | +| MEMORY_ACCESS_OUT_OF_RANGE | Memory offset exceeds addressable space | +| SIDE_EFFECT_LIMIT_REACHED | Transaction limit exceeded (see [Transaction Limits](#transaction-limits)) | +| STATIC_CALL_VIOLATION | State modification attempted in static context | + + +## Static Calls + +[STATICCALL](opcodes/staticcall.md) enforces **read-only execution**. The nested call (and any calls it makes) cannot modify world state. + +**Blocked operations** (cause STATIC_CALL_VIOLATION error if attempted): +- Storage writes ([SSTORE](opcodes/sstore.md)) +- Nullifier emissions ([EMITNULLIFIER](opcodes/emitnullifier.md)) +- Note hash emissions ([EMITNOTEHASH](opcodes/emitnotehash.md)) +- Log emissions ([EMITUNENCRYPTEDLOG](opcodes/emitunencryptedlog.md)) +- L2-to-L1 messages ([SENDL2TOL1MSG](opcodes/sendl2tol1msg.md)) + +**Allowed operations**: +- Storage reads ([SLOAD](opcodes/sload.md)) +- Existence checks (nullifiers, note hashes, L1-to-L2 messages) +- All computation and memory operations (even memory writes) +- Nested calls (which inherit the static restriction) + +**Propagation**: If a call is static, all nested calls from it are also static. A contract cannot "escape" read-only mode by making a regular CALL. + +Static calls are useful for safely querying untrusted contracts without risking unintended state changes. + +## Example: Nested Call with Error Handling + +``` +// Caller has 10,000 L2 gas +// Allocate 5,000 gas for nested call to contract B + +CALL(l2Gas=5000, daGas=100, addr=B, args=[1,2,3]) + +// After call: +// - Caller has ~5,000 L2 gas (5,000 kept + refund from B) +// - nestedCallSuccess indicates if B returned or reverted +// - nestedReturndata contains B's output + +SUCCESSCOPY(dstOffset=100) // M[100] = 0 (failed) or 1 (success) +JUMPI(successPath, 100) // JUMPI jumps when M[100] != 0, i.e., on success + +// Failure path (success == 0): B's state changes are discarded +// Caller can inspect revert data or take alternative action +JUMP(done) + +successPath: +// Success path (success == 1): B's state changes are merged +RETURNDATASIZE(dstOffset=101) // Get return data size +RETURNDATACOPY(...) // Copy return data to memory +// ... continue processing + +done: +``` + +--- +← Previous: [Errors](./errors.md) | Next: [Calldata and Return Data](./calldata-returndata.md) → diff --git a/yarn-project/simulator/docs/avm/gas.md b/yarn-project/simulator/docs/avm/gas.md new file mode 100644 index 000000000000..43171a8f5f7a --- /dev/null +++ b/yarn-project/simulator/docs/avm/gas.md @@ -0,0 +1,108 @@ +# Gas Metering + +The AVM tracks gas consumption across two dimensions: **L2 gas** (execution costs, also called **mana**) and **DA gas** (data availability costs). + +## Gas Dimensions + +* **L2 Gas** (mana): roughly represents the computational cost of executing (and especially proving) operations. +* **DA Gas**: represents the cost of publishing data to Layer 1 for data availability. This includes: + - State updates that must be published to L1 + - Emitting logs + - Writing to public storage + - Emitting new nullifiers + - Emitting new note hashes + - Sending new l2 to l1 messages + +## Gas Cost Components + +Every opcode has an L2 base cost. The remaining cost components are present for some opcodes on a case-by-case basis: +1. L2 base cost +2. DA base cost +3. Addressing cost +4. L2 dynamic cost +5. DA dynamic cost + +### Base Costs + +**Base costs** are fixed amounts charged for every execution of an opcode: +- **L2 Base**: Fixed computational cost +- **DA Base**: Fixed data availability cost (0 for most opcodes) + +Base costs are charged at the start of an instruction's execution. + +### Addressing Costs + +**Addressing costs** are L2 costs charged for non-direct memory addressing modes (see [Addressing Modes](addressing.md)): +- **3 L2 gas** per indirect memory offset +- **3 L2 gas** per relative memory offset + +These are statically determined by an instruction's addressing mode bitmask. + +Addressing costs are _also_ charged at the start of an instruction's execution. + +### Dynamic Costs + +**Dynamic costs** scale with runtime values, typically based on data sizes or operation complexity: +- **L2 Dynamic**: Variable computational cost +- **DA Dynamic**: Variable data availability cost + +Dynamic costs are charged after operands are resolved as they often scale with some resolved memory value. Most instructions do _not_ have dynamic costs. + +## Example +Some instructions have gas costs that scale with runtime values (e.g., data sizes). Since these values often come from resolved memory offsets, dynamic gas must be charged **after** operand resolution. + +**Example**: `CALLDATACOPY` has dynamic L2 gas that scales with `M[copySizeOffset]`. The VM must: +1. Charge base gas +2. Charge L2 Addressing costs for the addressing modes +3. Resolve `copySizeOffset` and access the actual memory value containing `copySize` +4. Charge dynamic L2 gas: `base_dynamic_cost × M[copySizeOffset]` + +## Gas Cost Tables + +Each instruction in the [Instruction Set](avm-isa-quick-reference.md) includes a Gas Costs table with these columns: + +- **Component**: The type of gas cost (L2 Base, DA Base, L2 Addressing, L2 Dynamic, DA Dynamic) +- **Value**: The amount of gas charged per unit +- **Scales with**: What the cost scales with (for dynamic and addressing costs) + +### Example Gas Cost Table + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 50 | - | +| DA Base | 100 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | +| L2 Dynamic | 10 | `M[sizeOffset]` | + +This indicates: +- 50 L2 gas - charged immediately (base) +- 100 DA gas - charged immediately (base) +- 3 L2 gas per indirect/relative addressing mode used - charged immediately +- Additional L2 gas equal to `10 × M[sizeOffset]` - charged after operand resolution + +## Measuring Total Gas + +To calculate the total gas consumed by an instruction: + +``` +Total L2 Gas = L2_Base + L2_Addressing + L2_Dynamic +Total DA Gas = DA_Base + DA_Dynamic + +Where: + L2_Addressing = 3 × (indirect_count + relative_count) + L2_Dynamic = dynamic_rate × resolved_scaling_value (if applicable) + DA_Dynamic = dynamic_rate × resolved_scaling_value (if applicable) +``` + +> Note that sometimes dynamic scaling is not as straightforward as just a single multiplication! + +## Gas Exhaustion + +If an instruction attempts to charge gas that exceeds the remaining available gas, this triggers an execution error. + +## Gas in External Calls + +When a contract makes an external call via `CALL` or `STATICCALL`, gas is explicitly allocated to the nested call. The caller specifies how much L2 and DA gas to pass, and any unused gas is refunded when the nested call returns. See [External Calls](./external-calls.md) for details on gas allocation, charging, and refunds during nested contract calls. + +--- +← Previous: [Execution Lifecycle](./execution-lifecycle.md) | Next: [Errors](./errors.md) → \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/memory.md b/yarn-project/simulator/docs/avm/memory.md new file mode 100644 index 000000000000..db7c1b005c2e --- /dev/null +++ b/yarn-project/simulator/docs/avm/memory.md @@ -0,0 +1,139 @@ +# Memory + +AVM memory stores the internal state of the current program being executed. It can be written to as well as read. + +The AVM uses a **tagged memory model** where each memory cell contains a value and an associated type tag. + + +## Tagged Memory + +Cells in memory are "type-tagged" when they are written. Cells that have never been written before have value 0 and tag `FIELD`. + +Some AVM opcodes (see the [Instruction Set](avm-isa-quick-reference.md)) write to memory. Any opcode that writes to memory is responsible for properly tagging written cells and ensuring that written values fit in the associated range. + +In other words, values are range-checked when _written_ to memory. This means that when _reading_ a value from memory, it can be safely assumed that the value is within the range specified by its tag. + +### Type Tags + +The following type tags are supported in the AVM: + +| Tag Name | Max Value | Modulus | +|----------|-----------|---------| +| `FIELD` | $p - 1$ | $p$ (BN254 field prime) | +| `UINT1` | $2^1 - 1$ | $2^1$ | +| `UINT8` | $2^8 - 1$ | $2^8$ | +| `UINT16` | $2^{16} - 1$ | $2^{16}$ | +| `UINT32` | $2^{32} - 1$ | $2^{32}$ | +| `UINT64` | $2^{64} - 1$ | $2^{64}$ | +| `UINT128` | $2^{128} - 1$ | $2^{128}$ | + +Where $p$ is the BN254 field prime: +``` +p = 21888242871839275222246405745257275088548364400416034343698204186575808495617 +``` + +**Notes:** +- `UINT32` is used for offsets into the VM's 32-bit addressable main memory +- All arithmetic operations on integer types are performed modulo $2^k$ where $k$ is the bit-width +- Field operations are performed modulo $p$ + +## Memory Notation + +### Memory Accesses + +`M[x]` denotes the value stored in memory at offset `x`. Memory is organized as a linear array of field elements, with each cell capable of holding a value from the BN254 field. + +Instructions may resolve operands using [addressing modes](addressing.md#addressing-modes) (direct, indirect, and/or relative) to determine the final memory offset. + +### Type Tags + +`T[x]` denotes the type tag associated with the memory cell at offset `x`. Type tags specify how the value should be interpreted, what operations are valid, and what modulus applies to arithmetic operations. + + +## Tag Checking and Updates: The ADD Instruction + +Most AVM instructions explicitly check input tags and assign output tags. Here's how the `ADD` instruction demonstrates these principles: + +**Instruction:** `ADD aOffset bOffset dstOffset` + +**Semantics:** +```javascript +M[dstOffset] = M[aOffset] + M[bOffset] +``` + +**Tag Checks:** +- Both operands must have matching tags: `T[aOffset] == T[bOffset]` +- If tags don't match, a `TAG_MISMATCH` error is raised and execution in the current context exceptionally halts (See [Errors](./errors.md)). + +**Tag Updates:** +- The destination inherits the tag from the operands: `T[dstOffset] = T[aOffset]` +- This ensures the result is properly constrained to the same type as the inputs + +**Example:** +``` +# Before execution +T[100] = UINT32 M[100] = 42 +T[200] = UINT32 M[200] = 58 +T[300] = M[300] = + +# Execute: ADD 100 200 300 + +# After execution (successful) +T[100] = UINT32 M[100] = 42 +T[200] = UINT32 M[200] = 58 +T[300] = UINT32 M[300] = 100 # 42 + 58 = 100 + +# The VM enforced: +# 1. T[100] == T[200] (both UINT32) ✓ +# 2. T[300] = T[100] (destination tagged as UINT32) +# 3. Result constrained to fit in UINT32 (already satisfied since inputs are UINT32) +``` + +**Error Example:** +``` +# Before execution +T[100] = UINT32 M[100] = 42 +T[200] = UINT64 M[200] = 58 + +# Execute: ADD 100 200 300 + +# Result: TAG_MISMATCH error, execution exceptionally halts +# T[100] (UINT32) ≠ T[200] (UINT64) +``` + +## Special Instructions and Tag Handling + +### CAST: Tag Conversion + +The `CAST` instruction is the only way to convert between type tags: + +``` +CAST srcOffset dstOffset +T[dstOffset] = dstTag # Assign new tag +M[dstOffset] = cast(M[srcOffset]) # Convert value +``` + +When casting to a smaller type (e.g., UINT128 → UINT32), the value is truncated. When casting to a larger type, the value is preserved. + +## Indirect Memory Access and Tag Requirements + +Indirect memory addressing (`M[M[x]]`) requires the pointer cell to be tagged as `UINT32`, since main memory is a 32-bit addressable space. + +**Example with indirect MOV:** +``` +# MOV srcOffset dstOffset (with indirect source) +assert T[srcOffset] == UINT32 # Pointer must be UINT32 +T[dstOffset] = T[M[srcOffset]] # Tag destination to match indirect source tag +M[dstOffset] = M[M[srcOffset]] # Perform move from indirect source +``` + +## Memory Bounds + +An out-of-bounds memory access can be encountered when: +- An instruction operand uses relative addressing which derives a memory offset from the addition of two values (see [Addressing](addressing.md)). +- An instruction operates on a _range_ of data (see [EMITUNENCRYPTEDLOG](opcodes/emitunencryptedlog.md)) + +When this happens, the instruction errors and execution in the current context exceptionally halts (See [Errors](./errors.md). + +--- +← Previous: [State](./state.md) | Next: [Addressing Modes](./addressing.md) → diff --git a/yarn-project/simulator/docs/avm/opcodes/add.md b/yarn-project/simulator/docs/avm/opcodes/add.md new file mode 100644 index 000000000000..330bacc91ec9 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/add.md @@ -0,0 +1,113 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# ADD + +Addition (a + b) + +Opcodes `0x00`-`0x01` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] + M[bOffset] +``` + +## Details + +Performs addition. Both operands must have the same type tag. For integer types (UINT8, UINT16, UINT32, UINT64, UINT128), the operation is performed modulo 2^k where k is the bit-width (e.g., k=8 for UINT8). For FIELD type, the operation is performed modulo p (the BN254 field prime). The result inherits the tag from the operands. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of first input | +| `bOffset` | Memory offset | Memory offset of second input | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**ADD_8** (Opcode 0x00): + +```mermaid +--- +title: "ADD_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x0)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**ADD_16** (Opcode 0x01): + +```mermaid +--- +title: "ADD_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x1)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` + +## Tag Updates + +- `T[dstOffset] = T[aOffset]` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/and.md b/yarn-project/simulator/docs/avm/opcodes/and.md new file mode 100644 index 000000000000..31572103c341 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/and.md @@ -0,0 +1,116 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# AND + +Bitwise AND (a & b) + +Opcodes `0x10`-`0x11` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] & M[bOffset] +``` + +## Details + +Performs bitwise AND operation. Both operands must have the same integral type tag (UINT1, UINT8, UINT16, UINT32, UINT64, UINT128). The result inherits the tag from the operands. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | +| L2 Dynamic | 3 | - | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of first input | +| `bOffset` | Memory offset | Memory offset of second input | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**AND_8** (Opcode 0x10): + +```mermaid +--- +title: "AND_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x10)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**AND_16** (Opcode 0x11): + +```mermaid +--- +title: "AND_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x11)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` +- `T[aOffset] is integral` + +## Tag Updates + +- `T[dstOffset] = T[aOffset]` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **INVALID_TAG_TYPE**: Operands are not integral types +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/call.md b/yarn-project/simulator/docs/avm/opcodes/call.md new file mode 100644 index 000000000000..06f9a4bb51cc --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/call.md @@ -0,0 +1,125 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# CALL + +Call external contract + +Opcode `0x39` + +```javascript +childContext = createChildContext( + contract: M[addrOffset], + calldataOffset: argsOffset, + calldataSize: M[argsSizeOffset], + l2Gas: M[l2GasOffset], + daGas: M[daGasOffset] +) +execute childContext +``` + +## Details + +Calls another contract with the specified calldata and gas allocation. Can modify state. The call consumes the allocated gas and refunds unused gas. Updates nestedCallSuccess and nestedReturndata. Child can access caller's `M[calldataOffset:calldataOffset+calldataSize]` via CALLDATACOPY. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 9936 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `l2GasOffset` | Memory offset | Memory offset of the L2 gas to allocate to the nested call | +| `daGasOffset` | Memory offset | Memory offset of the DA gas to allocate to the nested call | +| `addrOffset` | Memory offset | Memory offset of the target contract address | +| `argsSizeOffset` | Memory offset | Memory offset of the calldata size | +| `argsOffset` | Memory offset | Memory offset of the start of the calldata | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**CALL** (Opcode 0x39): + +```mermaid +--- +title: "CALL" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x39)" +8-23: "Addressing modes" +24-39: "Operand: l2GasOffset" +40-55: "Operand: daGasOffset" +56-71: "Operand: addrOffset" +72-87: "Operand: argsSizeOffset" +88-103: "Operand: argsOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +16-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`l2GasOffset`, `daGasOffset`, `addrOffset`, `argsSizeOffset`, `argsOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "l2GasOffset is indirect" + 1: "l2GasOffset is relative" + 2: "daGasOffset is indirect" + 3: "daGasOffset is relative" + 4: "addrOffset is indirect" + 5: "addrOffset is relative" + 6: "argsSizeOffset is indirect" + 7: "argsSizeOffset is relative" + 8: "argsOffset is indirect" + 9: "argsOffset is relative" + 10: "Unused" + 11: "Unused" + 12: "Unused" + 13: "Unused" + 14: "Unused" + 15: "Unused" +``` + +## Tag Checks + +- `T[l2GasOffset] == UINT32` +- `T[daGasOffset] == UINT32` +- `T[addrOffset] == FIELD` +- `T[argsSizeOffset] == UINT32` + +## Tag Updates + +- `T[successOffset] = UINT1` + +## Error Conditions + +- **INVALID_TAG**: Gas, address, or size operands have incorrect tags +- **OUT_OF_GAS**: Insufficient gas for the nested call +- **SIDE_EFFECT_LIMIT_REACHED**: Exceeded maximum unique contract class IDs per transaction (MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS) +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +## Notes + +- See [External Calls](../external-calls.md) for more details on execution flow. +- See [Calldata and Return Data](../calldata-returndata.md) for more details on passing data. + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/calldatacopy.md b/yarn-project/simulator/docs/avm/opcodes/calldatacopy.md new file mode 100644 index 000000000000..9cd7084b6b7b --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/calldatacopy.md @@ -0,0 +1,102 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# CALLDATACOPY + +Copy calldata to memory + +Opcode `0x1F` + +```javascript +M[dstOffset:dstOffset+M[copySizeOffset]] = calldata[M[cdStartOffset]:M[cdStartOffset]+M[copySizeOffset]] +``` + +## Details + +Copies a section of the current call's calldata into memory at the specified offset. Reads M[copySizeOffset] elements starting at calldata offset M[cdStartOffset], writing them to memory starting at dstOffset. If the read extends past the end of calldata, the out-of-bounds region is padded with zeros. If the read or write would exceed addressable memory (≥ 2³²), the instruction errors. For nested calls, the read occurs in the caller's memory space. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 18 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | +| L2 Dynamic | 3 | `M[copySizeOffset]` | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `copySizeOffset` | Memory offset | Memory offset of the number of elements to copy | +| `cdStartOffset` | Memory offset | Memory offset of the calldata start index to copy from | +| `dstOffset` | Memory offset | Memory offset for writing calldata | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**CALLDATACOPY** (Opcode 0x1F): + +```mermaid +--- +title: "CALLDATACOPY" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x1F)" +8-15: "Addressing modes" +16-31: "Operand: copySizeOffset" +32-47: "Operand: cdStartOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`copySizeOffset`, `cdStartOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "copySizeOffset is indirect" + 1: "copySizeOffset is relative" + 2: "cdStartOffset is indirect" + 3: "cdStartOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[copySizeOffset] == UINT32` + +## Tag Updates + +- `T[dstOffset:dstOffset+M[copySizeOffset]] = FIELD` + +## Error Conditions + +- **INVALID_TAG**: Size operand is not Uint32 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +## Notes + +- See [External Calls](../external-calls.md) for how calldata is passed to nested calls. +- See [Calldata and Return Data](../calldata-returndata.md) for more details. + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/cast.md b/yarn-project/simulator/docs/avm/opcodes/cast.md new file mode 100644 index 000000000000..ab74f8f27d17 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/cast.md @@ -0,0 +1,109 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# CAST + +Type cast memory value + +Opcodes `0x1C`-`0x1D` (2 wire formats) + +```javascript +M[dstOffset] = M[srcOffset] as tag +``` + +## Details + +Changes the type tag of a value. The value itself is preserved if casting to a larger type. When casting to a smaller type, the value is truncated by keeping only the least significant bits that fit in the destination type (equivalent to modulo 2^k where k is the bit-width of the destination type). + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 27 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `srcOffset` | Memory offset | Memory offset of the value to cast | +| `dstOffset` | Memory offset | Memory offset for casted value | +| `dstTag` | Type tag | Type tag to cast the value to | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**CAST_8** (Opcode 0x1C): + +```mermaid +--- +title: "CAST_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x1C)" +8-15: "Addressing modes" +16-23: "Operand: srcOffset" +24-31: "Operand: dstOffset" +32-39: "Operand: dstTag" +``` + +**CAST_16** (Opcode 0x1D): + +```mermaid +--- +title: "CAST_16" +config: + packet: + bitsPerRow: 56 +--- +packet-beta +0-7: "Opcode (0x1D)" +8-15: "Addressing modes" +16-31: "Operand: srcOffset" +32-47: "Operand: dstOffset" +48-55: "Operand: dstTag" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`srcOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "srcOffset is indirect" + 1: "srcOffset is relative" + 2: "dstOffset is indirect" + 3: "dstOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Updates + +- `T[dstOffset] = dstTag` + +## Error Conditions + +- **INVALID_TAG**: Destination tag is not a valid TypeTag +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/debuglog.md b/yarn-project/simulator/docs/avm/opcodes/debuglog.md new file mode 100644 index 000000000000..a89d685c4bc6 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/debuglog.md @@ -0,0 +1,99 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# DEBUGLOG + +Output debug log + +Opcode `0x3E` + +```javascript +debugLog(level, message, M[fieldsOffset:fieldsOffset+M[fieldsSizeOffset]]) +``` + +## Details + +Prints a debug log to console as a formatted a message, and pushes a structured debug object (`{contractAddress, level, message, fields[]}`) to an accumulated list for the transaction. This opcode does nearly nothing when executed by sequencers or provers (only performs PC increment and address resolution). It is meant for local debugging or for use by RPC nodes and wallets. Logs are only printed if logging level is "Debug" (6) or higher. Message size is an immediate (constant in the bytecode). Throws an irrecoverable error if truly doing debug logging and log level is invalid (greater than 7) or upon reaching the node's configured maxDebugLogMemoryReads. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 9 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `levelOffset` | Memory offset | Memory offset | +| `messageOffset` | Memory offset | Memory offset of the message string | +| `fieldsOffset` | Memory offset | Memory offset of the start of field values to log | +| `fieldsSizeOffset` | Memory offset | Memory offset of the number of fields to log | +| `messageSize` | Memory offset | Immediate value specifying message string length | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**DEBUGLOG** (Opcode 0x3E): + +```mermaid +--- +title: "DEBUGLOG" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x3E)" +8-15: "Addressing modes" +16-31: "Operand: levelOffset" +32-47: "Operand: messageOffset" +48-63: "Operand: fieldsOffset" +64-79: "Operand: fieldsSizeOffset" +80-95: "Operand: messageSize" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`levelOffset`, `messageOffset`, `fieldsOffset`, `fieldsSizeOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "levelOffset is indirect" + 1: "levelOffset is relative" + 2: "messageOffset is indirect" + 3: "messageOffset is relative" + 4: "fieldsOffset is indirect" + 5: "fieldsOffset is relative" + 6: "fieldsSizeOffset is indirect" + 7: "fieldsSizeOffset is relative" +``` + +## Tag Checks + +- `T[fieldsSizeOffset] == UINT32` +- `T[fieldsOffset:fieldsOffset+M[fieldsSizeOffset]] == FIELD` + +## Error Conditions + +- **INVALID_TAG**: Fields operands are not FIELD type +- **INVALID_LOG_LEVEL**: Log level is not a valid LogLevel enum value +- **DEBUG_MEMORY_LIMIT_EXCEEDED**: Exceeded maximum debug log memory reads +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/div.md b/yarn-project/simulator/docs/avm/opcodes/div.md new file mode 100644 index 000000000000..23e190e0d8ab --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/div.md @@ -0,0 +1,116 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# DIV + +Integer division (a / b) + +Opcodes `0x06`-`0x07` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] / M[bOffset] +``` + +## Details + +Performs integer division (truncating). Both operands must have the same integral type tag (not FIELD). The result inherits the tag from the operands. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 27 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of the dividend | +| `bOffset` | Memory offset | Memory offset of the divisor | +| `dstOffset` | Memory offset | Memory offset for quotient | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**DIV_8** (Opcode 0x06): + +```mermaid +--- +title: "DIV_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x6)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**DIV_16** (Opcode 0x07): + +```mermaid +--- +title: "DIV_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x7)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` +- `T[aOffset] is integral` + +## Tag Updates + +- `T[dstOffset] = T[aOffset]` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **INVALID_TAG_TYPE**: Operands are not integral types +- **DIVISION_BY_ZERO**: Second operand (divisor) is zero +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/ecadd.md b/yarn-project/simulator/docs/avm/opcodes/ecadd.md new file mode 100644 index 000000000000..b7a1bbfb9b48 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/ecadd.md @@ -0,0 +1,123 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# ECADD + +Grumpkin elliptic curve addition + +Opcode `0x42` + +```javascript +M[dstOffset:dstOffset+3] = grumpkinAdd( + /*point1=*/{x: M[p1XOffset], y: M[p1YOffset], isInfinite: M[p1IsInfiniteOffset]}, + /*point2=*/{x: M[p2XOffset], y: M[p2YOffset], isInfinite: M[p2IsInfiniteOffset]} + ) +``` + +## Details + +Performs elliptic curve point addition on the Grumpkin curve. Each point is represented as (x: FIELD, y: FIELD, isInfinite: Uint1). Returns result point in same format. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 270 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `p1XOffset` | Memory offset | Memory offset of the first point's x-coordinate | +| `p1YOffset` | Memory offset | Memory offset of the first point's y-coordinate | +| `p1IsInfiniteOffset` | Memory offset | Memory offset of the first point's infinity flag | +| `p2XOffset` | Memory offset | Memory offset of the second point's x-coordinate | +| `p2YOffset` | Memory offset | Memory offset of the second point's y-coordinate | +| `p2IsInfiniteOffset` | Memory offset | Memory offset of the second point's infinity flag | +| `dstOffset` | Memory offset | Memory offset for result point will be written (3 values) | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**ECADD** (Opcode 0x42): + +```mermaid +--- +title: "ECADD" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x42)" +8-23: "Addressing modes" +24-39: "Operand: p1XOffset" +40-55: "Operand: p1YOffset" +56-71: "Operand: p1IsInfiniteOffset" +72-87: "Operand: p2XOffset" +88-103: "Operand: p2YOffset" +104-119: "Operand: p2IsInfiniteOffset" +120-135: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +16-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`p1XOffset`, `p1YOffset`, `p1IsInfiniteOffset`, `p2XOffset`, `p2YOffset`, `p2IsInfiniteOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "p1XOffset is indirect" + 1: "p1XOffset is relative" + 2: "p1YOffset is indirect" + 3: "p1YOffset is relative" + 4: "p1IsInfiniteOffset is indirect" + 5: "p1IsInfiniteOffset is relative" + 6: "p2XOffset is indirect" + 7: "p2XOffset is relative" + 8: "p2YOffset is indirect" + 9: "p2YOffset is relative" + 10: "p2IsInfiniteOffset is indirect" + 11: "p2IsInfiniteOffset is relative" + 12: "dstOffset is indirect" + 13: "dstOffset is relative" + 14: "Unused" + 15: "Unused" +``` + +## Tag Checks + +- `T[p1XOffset] == FIELD` +- `T[p1YOffset] == FIELD` +- `T[p1IsInfiniteOffset] == UINT1` +- `T[p2XOffset] == FIELD` +- `T[p2YOffset] == FIELD` +- `T[p2IsInfiniteOffset] == UINT1` + +## Tag Updates + +- `T[dstOffset] = FIELD` +- `T[dstOffset+1] = FIELD` +- `T[dstOffset+2] = UINT1` + +## Error Conditions + +- **INVALID_TAG**: Point coordinates are not FIELD or infinity flags are not Uint1 +- **POINT_NOT_ON_CURVE**: One or both points are not on the Grumpkin curve +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/emitnotehash.md b/yarn-project/simulator/docs/avm/opcodes/emitnotehash.md new file mode 100644 index 000000000000..c1aafd2b576d --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/emitnotehash.md @@ -0,0 +1,90 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# EMITNOTEHASH + +Emit note hash + +Opcode `0x32` + +```javascript +noteHashes.append(M[noteHashOffset]) +``` + +## Details + +Writes a new note hash to the Note Hash Tree. Note hash must have type tag FIELD. Reverts in static calls. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 19275 | - | +| DA Base | 512 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `noteHashOffset` | Memory offset | Memory offset of the note hash to emit | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**EMITNOTEHASH** (Opcode 0x32): + +```mermaid +--- +title: "EMITNOTEHASH" +config: + packet: + bitsPerRow: 32 +--- +packet-beta +0-7: "Opcode (0x32)" +8-15: "Addressing modes" +16-31: "Operand: noteHashOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`noteHashOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "noteHashOffset is indirect" + 1: "noteHashOffset is relative" + 2: "Unused" + 3: "Unused" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[noteHashOffset] == FIELD` + +## Error Conditions + +- **INVALID_TAG**: Note hash operand is not FIELD +- **STATIC_CALL_ALTERATION**: Attempted note hash emission in static call context +- **SIDE_EFFECT_LIMIT_REACHED**: Exceeded maximum note hashes per transaction (MAX_NOTE_HASHES_PER_TX) +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/emitnullifier.md b/yarn-project/simulator/docs/avm/opcodes/emitnullifier.md new file mode 100644 index 000000000000..49660e235402 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/emitnullifier.md @@ -0,0 +1,91 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# EMITNULLIFIER + +Emit nullifier + +Opcode `0x34` + +```javascript +nullifiers.append(M[nullifierOffset]) +``` + +## Details + +Writes a new nullifier to the Nullifier Tree. This opcode can only emit nullifiers from the currently executing contract address. Nullifier must have type tag FIELD. Reverts in static calls or if nullifier already exists. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 30800 | - | +| DA Base | 512 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `nullifierOffset` | Memory offset | Memory offset of the nullifier to emit | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**EMITNULLIFIER** (Opcode 0x34): + +```mermaid +--- +title: "EMITNULLIFIER" +config: + packet: + bitsPerRow: 32 +--- +packet-beta +0-7: "Opcode (0x34)" +8-15: "Addressing modes" +16-31: "Operand: nullifierOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`nullifierOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "nullifierOffset is indirect" + 1: "nullifierOffset is relative" + 2: "Unused" + 3: "Unused" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[nullifierOffset] == FIELD` + +## Error Conditions + +- **INVALID_TAG**: Nullifier operand is not FIELD +- **STATIC_CALL_ALTERATION**: Attempted nullifier emission in static call context +- **NULLIFIER_COLLISION**: Nullifier already exists +- **SIDE_EFFECT_LIMIT_REACHED**: Exceeded maximum nullifiers per transaction (MAX_NULLIFIERS_PER_TX) +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/emitunencryptedlog.md b/yarn-project/simulator/docs/avm/opcodes/emitunencryptedlog.md new file mode 100644 index 000000000000..d4fff3685f54 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/emitunencryptedlog.md @@ -0,0 +1,95 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# EMITUNENCRYPTEDLOG + +Emit public log + +Opcode `0x37` + +```javascript +unencryptedLogs.append(M[logOffset:logOffset+M[logSizeOffset]]) +``` + +## Details + +Emits a public log from the currently executing contract. Log size must be Uint32, log data must be FIELD elements. Reverts in static calls. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 15 | - | +| DA Base | 1024 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | +| L2 Dynamic | 3 | `M[logSizeOffset]` | +| DA Dynamic | 512 | `M[logSizeOffset]` | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `logSizeOffset` | Memory offset | Memory offset of the log size (number of fields) | +| `logOffset` | Memory offset | Memory offset of the start of the log data | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**EMITUNENCRYPTEDLOG** (Opcode 0x37): + +```mermaid +--- +title: "EMITUNENCRYPTEDLOG" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x37)" +8-15: "Addressing modes" +16-31: "Operand: logSizeOffset" +32-47: "Operand: logOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`logSizeOffset`, `logOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "logSizeOffset is indirect" + 1: "logSizeOffset is relative" + 2: "logOffset is indirect" + 3: "logOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[logSizeOffset] == UINT32` +- `T[logOffset:logOffset+M[logSizeOffset]]` == FIELD + +## Error Conditions + +- **INVALID_TAG**: Log size is not Uint32 or log data is not FIELD +- **STATIC_CALL_ALTERATION**: Attempted log emission in static call context +- **SIDE_EFFECT_LIMIT_REACHED**: Exceeded maximum cumulative log size per transaction (FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH) +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/eq.md b/yarn-project/simulator/docs/avm/opcodes/eq.md new file mode 100644 index 000000000000..6be7631fb759 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/eq.md @@ -0,0 +1,113 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# EQ + +Equality check (a == b) + +Opcodes `0x0A`-`0x0B` (2 wire formats) + +```javascript +M[dstOffset] = (M[aOffset] == M[bOffset]) ? 1 : 0 +``` + +## Details + +Compares two values for equality. Both operands must have the same type tag. The result is a Uint1 (0 or 1). + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of first value to compare | +| `bOffset` | Memory offset | Memory offset of second value to compare | +| `dstOffset` | Memory offset | Memory offset for result (0 or 1) | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**EQ_8** (Opcode 0x0A): + +```mermaid +--- +title: "EQ_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0xA)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**EQ_16** (Opcode 0x0B): + +```mermaid +--- +title: "EQ_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0xB)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` + +## Tag Updates + +- `T[dstOffset] = UINT1` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/fdiv.md b/yarn-project/simulator/docs/avm/opcodes/fdiv.md new file mode 100644 index 000000000000..5f643842fb3d --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/fdiv.md @@ -0,0 +1,116 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# FDIV + +Field division (a / b) + +Opcodes `0x08`-`0x09` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] / M[bOffset] +``` + +## Details + +Performs field division (computes a * b^(-1) mod p where p is the BN254 field modulus). Both operands must have FIELD type tag. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 225 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of the dividend | +| `bOffset` | Memory offset | Memory offset of the divisor | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**FDIV_8** (Opcode 0x08): + +```mermaid +--- +title: "FDIV_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x8)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**FDIV_16** (Opcode 0x09): + +```mermaid +--- +title: "FDIV_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x9)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` +- `T[aOffset] == FIELD` + +## Tag Updates + +- `T[dstOffset] = FIELD` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **INVALID_TAG_TYPE**: Operands do not have FIELD type tag +- **DIVISION_BY_ZERO**: Second operand (divisor) is zero +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md b/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md new file mode 100644 index 000000000000..02c6fd81b215 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/getcontractinstance.md @@ -0,0 +1,118 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# GETCONTRACTINSTANCE + +Get contract instance information + +Opcode `0x36` + +```javascript +M[dstOffset] = contractInstance.exists ? 1 : 0; M[dstOffset+1] = contractInstance[memberEnum] +``` + +## Details + +Looks up contract instance by address and retrieves the specified member. This opcode can get contract instance information for any contract address, not just the currently executing one. Returns existence flag (Uint1) and member value (FIELD). If the contract does not exist, the member value is set to 0. Supported enum values: `[DEPLOYER=0, CLASS_ID, INIT_HASH]`. + +## Contract Classes and Instances + +In Aztec, the logic of a contract is separated from its state-bearing instance, enabling a powerful model for code reuse and upgradeability. This is different from Ethereum's model where code and state are tightly coupled in a single address. + +- **Contract Class**: A template that defines a contract's public and private functions, its storage layout, and other logic. It is identified by a `CLASS_ID`. A single contract class can be used by many different contract instances. +- **Contract Instance**: A deployed, stateful instance of a contract class at a specific address. Each instance has its own storage, but it executes the code of its associated contract class. + +This separation allows for: +- **Upgradeability**: An instance can be upgraded to point to a new contract class, changing its logic while preserving its state and address. +- **Code Reuse**: Multiple instances can share the same underlying code from a single class, which is more efficient. + +## Contract Instance Members + +| Member | Description | +|---|---| +| **Deployer Address** | The address of the account that deployed this contract instance. | +| **Class ID** | The identifier of the contract class that this instance uses for its code. | +| **Initialization Hash** | A hash of the constructor arguments used when the contract instance was deployed. | + +**Example**: To check if a contract at a given `address` is an instance of a known `CLASS_ID`: +1. Use `GETCONTRACTINSTANCE` with the `address` and the `CLASS_ID` member enum. +2. The opcode returns two values: an `exists` flag and the `class_id` of the instance. +3. Compare the returned `class_id` with the known `CLASS_ID`. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 6108 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `addressOffset` | Memory offset | Memory offset | +| `dstOffset` | Memory offset | Memory offset | +| `memberEnum` | Memory offset | Immediate value specifying which contract instance member to retrieve | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**GETCONTRACTINSTANCE** (Opcode 0x36): + +```mermaid +--- +title: "GETCONTRACTINSTANCE" +config: + packet: + bitsPerRow: 56 +--- +packet-beta +0-7: "Opcode (0x36)" +8-15: "Addressing modes" +16-31: "Operand: addressOffset" +32-47: "Operand: dstOffset" +48-55: "Operand: memberEnum" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`addressOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "addressOffset is indirect" + 1: "addressOffset is relative" + 2: "dstOffset is indirect" + 3: "dstOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Updates + +- `T[dstOffset] = UINT1` +- `T[dstOffset+1] = FIELD` + +## Error Conditions + +- **INVALID_TAG**: Address operand is not FIELD +- **INVALID_MEMBER_ENUM**: Member enum is not in the range of valid enum values +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/getenvvar.md b/yarn-project/simulator/docs/avm/opcodes/getenvvar.md new file mode 100644 index 000000000000..96ce69f91fed --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/getenvvar.md @@ -0,0 +1,107 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# GETENVVAR + +Get environment variable + +Opcode `0x1E` + +```javascript +M[dstOffset] = environmentVariable[varEnum] +``` + +## Details + +Retrieves environment variables from the currently executing context. The variable is specified by an immediate enum value. + +## Variable Reference + +| Index | Variable | Type | Description | +|-------|----------|------|-------------| +| 0 | `ADDRESS` | `FIELD` | Current executing contract address | +| 1 | `SENDER` | `FIELD` | Immediate caller of this context | +| 2 | `TRANSACTIONFEE` | `FIELD` | Total transaction fee | +| 3 | `CHAINID` | `FIELD` | Chain identifier | +| 4 | `VERSION` | `FIELD` | Protocol version | +| 5 | `BLOCKNUMBER` | `UINT32` | Current block number | +| 6 | `TIMESTAMP` | `UINT64` | Block timestamp | +| 7 | `MINFEEPERL2GAS` | `UINT128` | Minimum fee per L2 gas unit | +| 8 | `MINFEEPERDAGAS` | `UINT128` | Minimum fee per DA gas unit | +| 9 | `ISSTATICCALL` | `UINT1` | Whether current call is static (1) or not (0) | +| 10 | `L2GASLEFT` | `UINT32` | Remaining L2 gas at time of query | +| 11 | `DAGASLEFT` | `UINT32` | Remaining DA gas at time of query | + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `dstOffset` | Memory offset | Memory offset | +| `varEnum` | Memory offset | Immediate value specifying which environment variable to read | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**GETENVVAR_16** (Opcode 0x1E): + +```mermaid +--- +title: "GETENVVAR_16" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x1E)" +8-15: "Addressing modes" +16-31: "Operand: dstOffset" +32-39: "Operand: varEnum" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "dstOffset is indirect" + 1: "dstOffset is relative" + 2: "Unused" + 3: "Unused" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Updates + +- `T[dstOffset] = FIELD` + +## Error Conditions + +- **INVALID_ENV_VAR**: Env var enum is not in the range of valid enum values +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/internalcall.md b/yarn-project/simulator/docs/avm/opcodes/internalcall.md new file mode 100644 index 000000000000..b2085cee4116 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/internalcall.md @@ -0,0 +1,51 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# INTERNALCALL + +Internal function call + +Opcode `0x25` + +```javascript +internalCallStack.push({callPc: PC, returnPc: PC + instructionSize}); PC = loc +``` + +## Details + +Pushes current PC and return PC onto internal call stack, then jumps to the target location. While this instruction itself does not validate the jump target, an invalid target will trigger an instruction fetching error at the start of the next instruction's processing. + +## Gas Costs + +| Component | Value | +|-----------|-------| +| L2 Base | 9 | +| DA Base | 0 | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `loc` | Memory offset | Immediate bytecode offset of the function to call | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**INTERNALCALL** (Opcode 0x25): + +```mermaid +--- +title: "INTERNALCALL" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x25)" +8-39: "Operand: loc" +``` + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/internalreturn.md b/yarn-project/simulator/docs/avm/opcodes/internalreturn.md new file mode 100644 index 000000000000..f03528b6137e --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/internalreturn.md @@ -0,0 +1,48 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# INTERNALRETURN + +Return from internal call + +Opcode `0x26` + +```javascript +PC = internalCallStack.pop().returnPc +``` + +## Details + +Pops return PC from internal call stack and sets PC to it. + +## Gas Costs + +| Component | Value | +|-----------|-------| +| L2 Base | 9 | +| DA Base | 0 | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**INTERNALRETURN** (Opcode 0x26): + +```mermaid +--- +title: "INTERNALRETURN" +config: + packet: + bitsPerRow: 8 +--- +packet-beta +0-7: "Opcode (0x26)" +``` + +## Error Conditions + +- **INTERNAL_CALL_STACK_EMPTY**: Internal call stack is empty + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/jump.md b/yarn-project/simulator/docs/avm/opcodes/jump.md new file mode 100644 index 000000000000..abed52ffa10b --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/jump.md @@ -0,0 +1,51 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# JUMP + +Unconditional jump + +Opcode `0x23` + +```javascript +PC = jumpOffset +``` + +## Details + +Sets the program counter to the specified offset. The offset is an immediate value (not from memory). While this instruction itself does not validate the jump target, an invalid target will trigger an instruction fetching error at the start of the next instruction's processing. + +## Gas Costs + +| Component | Value | +|-----------|-------| +| L2 Base | 9 | +| DA Base | 0 | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `jumpOffset` | Memory offset | Immediate bytecode offset to jump to | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**JUMP** (Opcode 0x23): + +```mermaid +--- +title: "JUMP" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x23)" +8-39: "Operand: jumpOffset" +``` + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/jumpi.md b/yarn-project/simulator/docs/avm/opcodes/jumpi.md new file mode 100644 index 000000000000..23c9f98c14ad --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/jumpi.md @@ -0,0 +1,90 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# JUMPI + +Conditional jump + +Opcode `0x24` + +```javascript +if M[condOffset] != 0 then PC = loc else PC = PC + instructionSize +``` + +## Details + +Jumps to the specified location if the condition is non-zero (true). The condition must have type tag Uint1. While this instruction itself does not validate the jump target, an invalid target will trigger an instruction fetching error at the start of the next instruction's processing. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 9 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `condOffset` | Memory offset | Memory offset of the condition value (Uint1) | +| `loc` | Memory offset | Immediate bytecode offset to jump to if condition is true | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**JUMPI** (Opcode 0x24): + +```mermaid +--- +title: "JUMPI" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x24)" +8-15: "Addressing modes" +16-31: "Operand: condOffset" +32-63: "Operand: loc" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`condOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "condOffset is indirect" + 1: "condOffset is relative" + 2: "Unused" + 3: "Unused" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[condOffset] == UINT1` + +## Error Conditions + +- **INVALID_TAG**: Condition operand is not Uint1 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/keccakf1600.md b/yarn-project/simulator/docs/avm/opcodes/keccakf1600.md new file mode 100644 index 000000000000..ed8728bbb92c --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/keccakf1600.md @@ -0,0 +1,94 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# KECCAKF1600 + +Keccak-f[1600] permutation + +Opcode `0x41` + +```javascript +M[dstOffset:dstOffset+25] = keccakf1600(/*input=*/M[inputOffset:inputOffset+25]) +``` + +## Details + +Computes the Keccak-f[1600] permutation on a state of 25 Uint64 elements. Input and output must have type tag Uint64. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 58176 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `dstOffset` | Memory offset | Memory offset for output state will be written | +| `inputOffset` | Memory offset | Memory offset of the input state (25 Uint64 elements) | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**KECCAKF1600** (Opcode 0x41): + +```mermaid +--- +title: "KECCAKF1600" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x41)" +8-15: "Addressing modes" +16-31: "Operand: dstOffset" +32-47: "Operand: inputOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`dstOffset`, `inputOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "dstOffset is indirect" + 1: "dstOffset is relative" + 2: "inputOffset is indirect" + 3: "inputOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[inputOffset:inputOffset+25] == UINT64` + +## Tag Updates + +- `T[dstOffset:dstOffset+25] = UINT64` + +## Error Conditions + +- **INVALID_TAG**: Input state elements are not Uint64 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/l1tol2msgexists.md b/yarn-project/simulator/docs/avm/opcodes/l1tol2msgexists.md new file mode 100644 index 000000000000..bfe88e3567fd --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/l1tol2msgexists.md @@ -0,0 +1,97 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# L1TOL2MSGEXISTS + +Check existence of L1-to-L2 message + +Opcode `0x35` + +```javascript +M[existsOffset] = l1ToL2Messages.exists(M[msgHashOffset], M[msgLeafIndexOffset]) ? 1 : 0 +``` + +## Details + +Checks whether the specified L1-to-L2 message hash exists in the L1 to L2 message tree at the given leaf index. Since this opcode checks for existence at a specified leafIndex, it is _not_ limited to checking for messages with any particular recipient. If the leaf index exceeds the maximum tree size, the result is 0 (does not exist). Message hash must be FIELD, leaf index must be Uint64. Result is Uint1. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 540 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `msgHashOffset` | Memory offset | Memory offset of the L1-to-L2 message hash | +| `msgLeafIndexOffset` | Memory offset | Memory offset of the leaf index in the message tree | +| `existsOffset` | Memory offset | Memory offset for result (0 or 1) will be written | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**L1TOL2MSGEXISTS** (Opcode 0x35): + +```mermaid +--- +title: "L1TOL2MSGEXISTS" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x35)" +8-15: "Addressing modes" +16-31: "Operand: msgHashOffset" +32-47: "Operand: msgLeafIndexOffset" +48-63: "Operand: existsOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`msgHashOffset`, `msgLeafIndexOffset`, `existsOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "msgHashOffset is indirect" + 1: "msgHashOffset is relative" + 2: "msgLeafIndexOffset is indirect" + 3: "msgLeafIndexOffset is relative" + 4: "existsOffset is indirect" + 5: "existsOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[msgHashOffset] == FIELD` +- `T[msgLeafIndexOffset] == UINT64` + +## Tag Updates + +- `T[existsOffset] = UINT1` + +## Error Conditions + +- **INVALID_TAG**: Message hash is not FIELD or leaf index is not Uint64 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/lt.md b/yarn-project/simulator/docs/avm/opcodes/lt.md new file mode 100644 index 000000000000..d5765f270fe2 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/lt.md @@ -0,0 +1,113 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# LT + +Less than (a < b) + +Opcodes `0x0C`-`0x0D` (2 wire formats) + +```javascript +M[dstOffset] = (M[aOffset] < M[bOffset]) ? 1 : 0 +``` + +## Details + +Compares two values. Both operands must have the same type tag. For integer types, performs standard numeric comparison. For FIELD type, performs lexicographic comparison treating field elements as integers (0 < 1 < ... < p-1). The result is a Uint1 (0 or 1). + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 42 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of first value to compare | +| `bOffset` | Memory offset | Memory offset of second value to compare | +| `dstOffset` | Memory offset | Memory offset for result (0 or 1) | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**LT_8** (Opcode 0x0C): + +```mermaid +--- +title: "LT_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0xC)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**LT_16** (Opcode 0x0D): + +```mermaid +--- +title: "LT_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0xD)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` + +## Tag Updates + +- `T[dstOffset] = UINT1` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/lte.md b/yarn-project/simulator/docs/avm/opcodes/lte.md new file mode 100644 index 000000000000..2f3486a4b00e --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/lte.md @@ -0,0 +1,113 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# LTE + +Less than or equal (a <= b) + +Opcodes `0x0E`-`0x0F` (2 wire formats) + +```javascript +M[dstOffset] = (M[aOffset] <= M[bOffset]) ? 1 : 0 +``` + +## Details + +Compares two values. Both operands must have the same type tag. For integer types, performs standard numeric comparison. For FIELD type, performs lexicographic comparison treating field elements as integers (0 < 1 < ... < p-1). The result is a Uint1 (0 or 1). + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 42 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of first value to compare | +| `bOffset` | Memory offset | Memory offset of second value to compare | +| `dstOffset` | Memory offset | Memory offset for result (0 or 1) | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**LTE_8** (Opcode 0x0E): + +```mermaid +--- +title: "LTE_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0xE)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**LTE_16** (Opcode 0x0F): + +```mermaid +--- +title: "LTE_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0xF)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` + +## Tag Updates + +- `T[dstOffset] = UINT1` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/mov.md b/yarn-project/simulator/docs/avm/opcodes/mov.md new file mode 100644 index 000000000000..08f43a244b75 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/mov.md @@ -0,0 +1,105 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# MOV + +Move value between memory locations + +Opcodes `0x2D`-`0x2E` (2 wire formats) + +```javascript +M[dstOffset] = M[srcOffset] +``` + +## Details + +Copies a value and its type tag from the source memory offset to the destination offset. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `srcOffset` | Memory offset | Memory offset to read from | +| `dstOffset` | Memory offset | Memory offset to write to | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**MOV_8** (Opcode 0x2D): + +```mermaid +--- +title: "MOV_8" +config: + packet: + bitsPerRow: 32 +--- +packet-beta +0-7: "Opcode (0x2D)" +8-15: "Addressing modes" +16-23: "Operand: srcOffset" +24-31: "Operand: dstOffset" +``` + +**MOV_16** (Opcode 0x2E): + +```mermaid +--- +title: "MOV_16" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x2E)" +8-15: "Addressing modes" +16-31: "Operand: srcOffset" +32-47: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`srcOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "srcOffset is indirect" + 1: "srcOffset is relative" + 2: "dstOffset is indirect" + 3: "dstOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Updates + +- `T[dstOffset] = T[srcOffset]` + +## Error Conditions + +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/mul.md b/yarn-project/simulator/docs/avm/opcodes/mul.md new file mode 100644 index 000000000000..84e5397ff938 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/mul.md @@ -0,0 +1,113 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# MUL + +Multiplication (a * b) + +Opcodes `0x04`-`0x05` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] * M[bOffset] +``` + +## Details + +Performs multiplication. Both operands must have the same type tag. For integer types (UINT8, UINT16, UINT32, UINT64, UINT128), the operation is performed modulo 2^k where k is the bit-width (e.g., k=8 for UINT8). For FIELD type, the operation is performed modulo p (the BN254 field prime). The result inherits the tag from the operands. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 27 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of the first factor | +| `bOffset` | Memory offset | Memory offset of the second factor | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**MUL_8** (Opcode 0x04): + +```mermaid +--- +title: "MUL_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x4)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**MUL_16** (Opcode 0x05): + +```mermaid +--- +title: "MUL_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x5)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` + +## Tag Updates + +- `T[dstOffset] = T[aOffset]` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/not.md b/yarn-project/simulator/docs/avm/opcodes/not.md new file mode 100644 index 000000000000..9d55730c9c89 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/not.md @@ -0,0 +1,110 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# NOT + +Bitwise NOT (~a) + +Opcodes `0x16`-`0x17` (2 wire formats) + +```javascript +M[dstOffset] = ~M[srcOffset] +``` + +## Details + +Performs bitwise NOT operation (one's complement). The operand must have an integral type tag (UINT1, UINT8, UINT16, UINT32, UINT64, UINT128). The result inherits the tag from the operand. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `srcOffset` | Memory offset | Memory offset of the value to negate | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**NOT_8** (Opcode 0x16): + +```mermaid +--- +title: "NOT_8" +config: + packet: + bitsPerRow: 32 +--- +packet-beta +0-7: "Opcode (0x16)" +8-15: "Addressing modes" +16-23: "Operand: srcOffset" +24-31: "Operand: dstOffset" +``` + +**NOT_16** (Opcode 0x17): + +```mermaid +--- +title: "NOT_16" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x17)" +8-15: "Addressing modes" +16-31: "Operand: srcOffset" +32-47: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`srcOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "srcOffset is indirect" + 1: "srcOffset is relative" + 2: "dstOffset is indirect" + 3: "dstOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[srcOffset] is integral` + +## Tag Updates + +- `T[dstOffset] = T[srcOffset]` + +## Error Conditions + +- **INVALID_TAG_TYPE**: Operand is not an integral type +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/notehashexists.md b/yarn-project/simulator/docs/avm/opcodes/notehashexists.md new file mode 100644 index 000000000000..ec0827f81e07 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/notehashexists.md @@ -0,0 +1,97 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# NOTEHASHEXISTS + +Check existence of note hash + +Opcode `0x31` + +```javascript +M[existsOffset] = noteHashTree.exists(M[noteHashOffset], M[leafIndexOffset]) ? 1 : 0 +``` + +## Details + +Performs a read of the Note Hash Tree to query whether the specified note hash exists at the given leaf index. Since this opcode checks for existence at a specified leafIndex, it is _not_ limited to checking for note hashes of only the currently executing contract. Note that it is difficult to check for existence of a note hash emitted earlier in the same block because this opcode requires leafIndex. If the leaf index exceeds the maximum tree size, the result is 0 (does not exist). Note hash must be FIELD, leaf index must be Uint64. Result is Uint1. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 504 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `noteHashOffset` | Memory offset | Memory offset of the note hash to check | +| `leafIndexOffset` | Memory offset | Memory offset of the leaf index in the note hash tree | +| `existsOffset` | Memory offset | Memory offset for result (0 or 1) will be written | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**NOTEHASHEXISTS** (Opcode 0x31): + +```mermaid +--- +title: "NOTEHASHEXISTS" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x31)" +8-15: "Addressing modes" +16-31: "Operand: noteHashOffset" +32-47: "Operand: leafIndexOffset" +48-63: "Operand: existsOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`noteHashOffset`, `leafIndexOffset`, `existsOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "noteHashOffset is indirect" + 1: "noteHashOffset is relative" + 2: "leafIndexOffset is indirect" + 3: "leafIndexOffset is relative" + 4: "existsOffset is indirect" + 5: "existsOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[noteHashOffset] == FIELD` +- `T[leafIndexOffset] == UINT64` + +## Tag Updates + +- `T[existsOffset] = UINT1` + +## Error Conditions + +- **INVALID_TAG**: Note hash is not FIELD or leaf index is not Uint64 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/nullifierexists.md b/yarn-project/simulator/docs/avm/opcodes/nullifierexists.md new file mode 100644 index 000000000000..00984d10ce6d --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/nullifierexists.md @@ -0,0 +1,97 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# NULLIFIEREXISTS + +Check existence of nullifier + +Opcode `0x33` + +```javascript +M[existsOffset] = nullifierTree.exists(M[addressOffset], M[nullifierOffset]) ? 1 : 0 +``` + +## Details + +Performs a read of the Nullifier Tree to query whether the specified nullifier exists for the given contract address. Any contract address can be specified, not just the currently executing contract. Both address and nullifier must be FIELD. Result is Uint1. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 924 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `nullifierOffset` | Memory offset | Memory offset of the nullifier to check | +| `addressOffset` | Memory offset | Memory offset of the contract address | +| `existsOffset` | Memory offset | Memory offset for result (0 or 1) will be written | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**NULLIFIEREXISTS** (Opcode 0x33): + +```mermaid +--- +title: "NULLIFIEREXISTS" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x33)" +8-15: "Addressing modes" +16-31: "Operand: nullifierOffset" +32-47: "Operand: addressOffset" +48-63: "Operand: existsOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`nullifierOffset`, `addressOffset`, `existsOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "nullifierOffset is indirect" + 1: "nullifierOffset is relative" + 2: "addressOffset is indirect" + 3: "addressOffset is relative" + 4: "existsOffset is indirect" + 5: "existsOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[addressOffset] == FIELD` +- `T[nullifierOffset] == FIELD` + +## Tag Updates + +- `T[existsOffset] = UINT1` + +## Error Conditions + +- **INVALID_TAG**: Address or nullifier is not FIELD +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/or.md b/yarn-project/simulator/docs/avm/opcodes/or.md new file mode 100644 index 000000000000..b02293f9d1b2 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/or.md @@ -0,0 +1,116 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# OR + +Bitwise OR (a | b) + +Opcodes `0x12`-`0x13` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] | M[bOffset] +``` + +## Details + +Performs bitwise OR operation. Both operands must have the same integral type tag (UINT1, UINT8, UINT16, UINT32, UINT64, UINT128). The result inherits the tag from the operands. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | +| L2 Dynamic | 3 | - | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of first input | +| `bOffset` | Memory offset | Memory offset of second input | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**OR_8** (Opcode 0x12): + +```mermaid +--- +title: "OR_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x12)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**OR_16** (Opcode 0x13): + +```mermaid +--- +title: "OR_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x13)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` +- `T[aOffset] is integral` + +## Tag Updates + +- `T[dstOffset] = T[aOffset]` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **INVALID_TAG_TYPE**: Operands are not integral types +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/poseidon2.md b/yarn-project/simulator/docs/avm/opcodes/poseidon2.md new file mode 100644 index 000000000000..ea5ec81a5557 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/poseidon2.md @@ -0,0 +1,94 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# POSEIDON2 + +Poseidon2 permutation + +Opcode `0x3F` + +```javascript +M[outputStateOffset:outputStateOffset+4] = poseidon2Permutation(/*input=*/M[inputStateOffset:inputStateOffset+4]) +``` + +## Details + +Computes the Poseidon2 permutation on a state of 4 field elements. Input and output states must have type tag FIELD. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 360 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `inputStateOffset` | Memory offset | Memory offset of the input state (4 field elements) | +| `outputStateOffset` | Memory offset | Memory offset for output state will be written | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**POSEIDON2** (Opcode 0x3F): + +```mermaid +--- +title: "POSEIDON2" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x3F)" +8-15: "Addressing modes" +16-31: "Operand: inputStateOffset" +32-47: "Operand: outputStateOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`inputStateOffset`, `outputStateOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "inputStateOffset is indirect" + 1: "inputStateOffset is relative" + 2: "outputStateOffset is indirect" + 3: "outputStateOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[inputStateOffset:inputStateOffset+4] == FIELD` + +## Tag Updates + +- `T[outputStateOffset:outputStateOffset+4] = FIELD` + +## Error Conditions + +- **INVALID_TAG**: Input state elements are not FIELD +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/return.md b/yarn-project/simulator/docs/avm/opcodes/return.md new file mode 100644 index 000000000000..c8991ba81d11 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/return.md @@ -0,0 +1,96 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# RETURN + +Return from call + +Opcode `0x3B` + +```javascript +exposeReturnData(offset: returnOffset, size: M[returnSizeOffset]) +halt +``` + +## Details + +Halts execution and returns data to the caller. Return size must be Uint32. Sets success flag. Caller can access this context's `M[offset:offset+size]` via RETURNDATACOPY. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 9 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `returnSizeOffset` | Memory offset | Memory offset of the return data size | +| `returnOffset` | Memory offset | Memory offset of the start of the return data | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**RETURN** (Opcode 0x3B): + +```mermaid +--- +title: "RETURN" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x3B)" +8-15: "Addressing modes" +16-31: "Operand: returnSizeOffset" +32-47: "Operand: returnOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`returnSizeOffset`, `returnOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "returnSizeOffset is indirect" + 1: "returnSizeOffset is relative" + 2: "returnOffset is indirect" + 3: "returnOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[returnSizeOffset] == UINT32` + +## Error Conditions + +- **INVALID_TAG**: Return size operand is not Uint32 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +## Notes + +- See [External Calls](../external-calls.md) for more details on execution flow. +- See [Calldata and Return Data](../calldata-returndata.md) for more details on passing data. + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/returndatacopy.md b/yarn-project/simulator/docs/avm/opcodes/returndatacopy.md new file mode 100644 index 000000000000..62e1494f5228 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/returndatacopy.md @@ -0,0 +1,102 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# RETURNDATACOPY + +Copy returndata to memory + +Opcode `0x22` + +```javascript +M[dstOffset:dstOffset+M[copySizeOffset]] = nestedReturndata[M[rdStartOffset]:M[rdStartOffset]+M[copySizeOffset]] +``` + +## Details + +Copies a section of the returndata from the most recent nested external call (CALL or STATICCALL instruction) into memory. Reads M[copySizeOffset] elements starting at return data offset M[rdStartOffset], writing them to memory starting at dstOffset. If the read extends past the end of return data, the out-of-bounds region is padded with zeros. If the read or write would exceed addressable memory (≥ 2³²), the instruction errors. The read occurs in the callee's memory space. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 18 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | +| L2 Dynamic | 3 | `M[copySizeOffset]` | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `copySizeOffset` | Memory offset | Memory offset of the number of elements to copy | +| `rdStartOffset` | Memory offset | Memory offset of the return data start index to copy from | +| `dstOffset` | Memory offset | Memory offset for writing return data | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**RETURNDATACOPY** (Opcode 0x22): + +```mermaid +--- +title: "RETURNDATACOPY" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x22)" +8-15: "Addressing modes" +16-31: "Operand: copySizeOffset" +32-47: "Operand: rdStartOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`copySizeOffset`, `rdStartOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "copySizeOffset is indirect" + 1: "copySizeOffset is relative" + 2: "rdStartOffset is indirect" + 3: "rdStartOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[copySizeOffset] == UINT32` + +## Tag Updates + +- `T[dstOffset:dstOffset+M[copySizeOffset]] = FIELD` + +## Error Conditions + +- **INVALID_TAG**: Size operand is not Uint32 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +## Notes + +- See [External Calls](../external-calls.md) for more details on nested calls. +- See [Calldata and Return Data](../calldata-returndata.md) for more details on return data. + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/returndatasize.md b/yarn-project/simulator/docs/avm/opcodes/returndatasize.md new file mode 100644 index 000000000000..945ec65063d2 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/returndatasize.md @@ -0,0 +1,92 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# RETURNDATASIZE + +Get returndata size + +Opcode `0x21` + +```javascript +M[dstOffset] = nestedReturndata.length +``` + +## Details + +Returns the size of the return data from the most recent nested external call (CALL or STATICCALL instruction). The size is determined by the nested call's RETURN or REVERT instruction. If there has been no nested external call, or if the nested call truly errored (did not explicitly execute a REVERT instruction), this returns 0. Result is Uint32. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `dstOffset` | Memory offset | Memory offset for size will be written | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**RETURNDATASIZE** (Opcode 0x21): + +```mermaid +--- +title: "RETURNDATASIZE" +config: + packet: + bitsPerRow: 32 +--- +packet-beta +0-7: "Opcode (0x21)" +8-15: "Addressing modes" +16-31: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "dstOffset is indirect" + 1: "dstOffset is relative" + 2: "Unused" + 3: "Unused" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Updates + +- `T[dstOffset] = UINT32` + +## Error Conditions + +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +## Notes + +- See [External Calls](../external-calls.md) for more details on nested calls. +- See [Calldata and Return Data](../calldata-returndata.md) for more details on return data. + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/revert.md b/yarn-project/simulator/docs/avm/opcodes/revert.md new file mode 100644 index 000000000000..9780209f60ae --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/revert.md @@ -0,0 +1,112 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# REVERT + +Revert execution + +Opcodes `0x3C`-`0x3D` (2 wire formats) + +```javascript +exposeRevertData(offset: returnOffset, size: M[retSizeOffset]) +halt +``` + +## Details + +Halts execution with revert status and returns error data to the caller. Revert size must be Uint32. Undoes state changes. Caller can access this context's `M[offset:offset+size]` via RETURNDATACOPY. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 9 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `retSizeOffset` | Memory offset | Memory offset of the revert data size | +| `returnOffset` | Memory offset | Memory offset of the start of the revert data | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**REVERT_8** (Opcode 0x3C): + +```mermaid +--- +title: "REVERT_8" +config: + packet: + bitsPerRow: 32 +--- +packet-beta +0-7: "Opcode (0x3C)" +8-15: "Addressing modes" +16-23: "Operand: retSizeOffset" +24-31: "Operand: returnOffset" +``` + +**REVERT_16** (Opcode 0x3D): + +```mermaid +--- +title: "REVERT_16" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x3D)" +8-15: "Addressing modes" +16-31: "Operand: retSizeOffset" +32-47: "Operand: returnOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`retSizeOffset`, `returnOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "retSizeOffset is indirect" + 1: "retSizeOffset is relative" + 2: "returnOffset is indirect" + 3: "returnOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[retSizeOffset] == UINT32` + +## Error Conditions + +- **INVALID_TAG**: Revert size operand is not Uint32 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +## Notes + +- See [External Calls](../external-calls.md) for more details on execution flow. +- See [Calldata and Return Data](../calldata-returndata.md) for more details on passing data. + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/sendl2tol1msg.md b/yarn-project/simulator/docs/avm/opcodes/sendl2tol1msg.md new file mode 100644 index 000000000000..5f3e797686e2 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/sendl2tol1msg.md @@ -0,0 +1,93 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# SENDL2TOL1MSG + +Send L2-to-L1 message + +Opcode `0x38` + +```javascript +l2ToL1Messages.append({recipient: M[recipientOffset], content: M[contentOffset]}) +``` + +## Details + +Sends a message to L1, with the specified recipient, from the currently executing contract. Both recipient and content must have type tag FIELD. Reverts in static calls. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 418 | - | +| DA Base | 512 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `recipientOffset` | Memory offset | Memory offset of the L1 recipient address | +| `contentOffset` | Memory offset | Memory offset of the message content | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**SENDL2TOL1MSG** (Opcode 0x38): + +```mermaid +--- +title: "SENDL2TOL1MSG" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x38)" +8-15: "Addressing modes" +16-31: "Operand: recipientOffset" +32-47: "Operand: contentOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`recipientOffset`, `contentOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "recipientOffset is indirect" + 1: "recipientOffset is relative" + 2: "contentOffset is indirect" + 3: "contentOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[recipientOffset] == FIELD` +- `T[contentOffset] == FIELD` + +## Error Conditions + +- **INVALID_TAG**: Recipient or content is not FIELD +- **STATIC_CALL_ALTERATION**: Attempted L2-to-L1 message send in static call context +- **SIDE_EFFECT_LIMIT_REACHED**: Exceeded maximum L2-to-L1 messages per transaction (MAX_L2_TO_L1_MSGS_PER_TX) +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/set.md b/yarn-project/simulator/docs/avm/opcodes/set.md new file mode 100644 index 000000000000..32a43d8e7322 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/set.md @@ -0,0 +1,177 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# SET + +Set memory to immediate value + +Opcodes `0x27`-`0x2C` (6 wire formats) + +```javascript +M[dstOffset] = value +``` + +## Details + +Stores an immediate value (a constant encoded directly in the bytecode) at the specified memory offset with the given type tag. Multiple wire formats support different value sizes. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 27 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `dstOffset` | Memory offset | Memory offset for value will be stored | +| `inTag` | Type tag | Type tag to assign to the value. Unrelated to the opcode's wire format (`SET_8` vs `SET_16`, etc.) | +| `value` | Immediate value | Constant from the bytecode to store into memory | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**SET_8** (Opcode 0x27): + +```mermaid +--- +title: "SET_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x27)" +8-15: "Addressing modes" +16-23: "Operand: dstOffset" +24-31: "Operand: inTag" +32-39: "Operand: value" +``` + +**SET_16** (Opcode 0x28): + +```mermaid +--- +title: "SET_16" +config: + packet: + bitsPerRow: 56 +--- +packet-beta +0-7: "Opcode (0x28)" +8-15: "Addressing modes" +16-31: "Operand: dstOffset" +32-39: "Operand: inTag" +40-55: "Operand: value" +``` + +**SET_32** (Opcode 0x29): + +```mermaid +--- +title: "SET_32" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x29)" +8-15: "Addressing modes" +16-31: "Operand: dstOffset" +32-39: "Operand: inTag" +40-71: "Operand: value" +``` + +**SET_64** (Opcode 0x2A): + +```mermaid +--- +title: "SET_64" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x2A)" +8-15: "Addressing modes" +16-31: "Operand: dstOffset" +32-39: "Operand: inTag" +40-103: "Operand: value" +``` + +**SET_128** (Opcode 0x2B): + +```mermaid +--- +title: "SET_128" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x2B)" +8-15: "Addressing modes" +16-31: "Operand: dstOffset" +32-39: "Operand: inTag" +40-167: "Operand: value" +``` + +**SET_FF** (Opcode 0x2C): + +```mermaid +--- +title: "SET_FF" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x2C)" +8-15: "Addressing modes" +16-31: "Operand: dstOffset" +32-39: "Operand: inTag" +40-295: "Operand: value" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "dstOffset is indirect" + 1: "dstOffset is relative" + 2: "Unused" + 3: "Unused" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Updates + +- `T[dstOffset] = tag` + +## Error Conditions + +- **INVALID_TAG**: Specified tag is not a valid TypeTag +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/sha256compression.md b/yarn-project/simulator/docs/avm/opcodes/sha256compression.md new file mode 100644 index 000000000000..9007589258e0 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/sha256compression.md @@ -0,0 +1,97 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# SHA256COMPRESSION + +SHA-256 compression + +Opcode `0x40` + +```javascript +M[outputOffset:outputOffset+8] = sha256compress(/*state=*/M[stateOffset:stateOffset+8], /*inputs=*/M[inputsOffset:inputsOffset+16]) +``` + +## Details + +Computes the SHA-256 compression function on an 8-word state and 16-word input block. State and inputs must be Uint32. Outputs 8 Uint32 words. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12288 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `outputOffset` | Memory offset | Memory offset for 8-word output state will be written | +| `stateOffset` | Memory offset | Memory offset of the 8-word SHA-256 state | +| `inputsOffset` | Memory offset | Memory offset of the 16-word input block | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**SHA256COMPRESSION** (Opcode 0x40): + +```mermaid +--- +title: "SHA256COMPRESSION" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x40)" +8-15: "Addressing modes" +16-31: "Operand: outputOffset" +32-47: "Operand: stateOffset" +48-63: "Operand: inputsOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`outputOffset`, `stateOffset`, `inputsOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "outputOffset is indirect" + 1: "outputOffset is relative" + 2: "stateOffset is indirect" + 3: "stateOffset is relative" + 4: "inputsOffset is indirect" + 5: "inputsOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[stateOffset:stateOffset+8] == UINT32` +- `T[inputsOffset:inputsOffset+16] == UINT32` + +## Tag Updates + +- `T[outputOffset:outputOffset+8] = UINT32` + +## Error Conditions + +- **INVALID_TAG**: State or inputs are not Uint32 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/shl.md b/yarn-project/simulator/docs/avm/opcodes/shl.md new file mode 100644 index 000000000000..d96713a0a3e7 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/shl.md @@ -0,0 +1,113 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# SHL + +Shift left (a << b) + +Opcodes `0x18`-`0x19` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] << M[bOffset] +``` + +## Details + +Performs left bit shift. Both operands must have the same integral type tag (UINT1, UINT8, UINT16, UINT32, UINT64, UINT128). The result is computed modulo 2^k where k is the bit-width of the operand type (e.g., k=8 for UINT8). If the shift amount is greater than or equal to the bit-width of the operand type, the result is 0. The result inherits the tag from the operands. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 18 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of the value to shift | +| `bOffset` | Memory offset | Memory offset of the shift amount | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**SHL_8** (Opcode 0x18): + +```mermaid +--- +title: "SHL_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x18)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**SHL_16** (Opcode 0x19): + +```mermaid +--- +title: "SHL_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x19)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` + +## Tag Updates + +- `T[dstOffset] = T[aOffset]` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/shr.md b/yarn-project/simulator/docs/avm/opcodes/shr.md new file mode 100644 index 000000000000..bf336dbb57af --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/shr.md @@ -0,0 +1,113 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# SHR + +Shift right (a >> b) + +Opcodes `0x1A`-`0x1B` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] >> M[bOffset] +``` + +## Details + +Performs right bit shift (logical, zero-fill). Both operands must have the same integral type tag (UINT1, UINT8, UINT16, UINT32, UINT64, UINT128). If the shift amount is greater than or equal to the bit-width of the operand type, the result is 0. The result inherits the tag from the operands. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 18 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of the value to shift | +| `bOffset` | Memory offset | Memory offset of the shift amount | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**SHR_8** (Opcode 0x1A): + +```mermaid +--- +title: "SHR_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x1A)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**SHR_16** (Opcode 0x1B): + +```mermaid +--- +title: "SHR_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x1B)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` + +## Tag Updates + +- `T[dstOffset] = T[aOffset]` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/sload.md b/yarn-project/simulator/docs/avm/opcodes/sload.md new file mode 100644 index 000000000000..f6c47406c69c --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/sload.md @@ -0,0 +1,94 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# SLOAD + +Load value from public storage + +Opcode `0x2F` + +```javascript +M[dstOffset] = storage[contractAddress][M[slotOffset]] +``` + +## Details + +Reads from public storage at the specified slot. Performs a read of the Public Data Tree. The contractAddress is the address of the currently executing contract and does not come from the bytecode. Both slot and result have type tag FIELD. Gas cost varies based on whether the slot is warm (recently accessed) or cold (first access in this transaction). + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 1290 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `slotOffset` | Memory offset | Memory offset of the storage slot to read from | +| `dstOffset` | Memory offset | Memory offset for loaded value will be written | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**SLOAD** (Opcode 0x2F): + +```mermaid +--- +title: "SLOAD" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x2F)" +8-15: "Addressing modes" +16-31: "Operand: slotOffset" +32-47: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`slotOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "slotOffset is indirect" + 1: "slotOffset is relative" + 2: "dstOffset is indirect" + 3: "dstOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[slotOffset] == FIELD` + +## Tag Updates + +- `T[dstOffset] = FIELD` + +## Error Conditions + +- **INVALID_TAG**: Slot operand is not FIELD +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/sstore.md b/yarn-project/simulator/docs/avm/opcodes/sstore.md new file mode 100644 index 000000000000..546f7fbcb021 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/sstore.md @@ -0,0 +1,94 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# SSTORE + +Store value to public storage + +Opcode `0x30` + +```javascript +storage[contractAddress][M[slotOffset]] = M[srcOffset] +``` + +## Details + +Writes to public storage at the specified slot. Performs a write to the Public Data Tree. The contractAddress is the address of the currently executing contract and does not come from the bytecode. Both slot and value must have type tag FIELD. Gas cost varies based on whether the slot is warm (recently accessed) or cold (first access in this transaction). Reverts in static calls. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 33140 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | +| DA Dynamic | 1024 | - | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `srcOffset` | Memory offset | Memory offset of the value to store | +| `slotOffset` | Memory offset | Memory offset of the storage slot to write to | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**SSTORE** (Opcode 0x30): + +```mermaid +--- +title: "SSTORE" +config: + packet: + bitsPerRow: 48 +--- +packet-beta +0-7: "Opcode (0x30)" +8-15: "Addressing modes" +16-31: "Operand: srcOffset" +32-47: "Operand: slotOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`srcOffset`, `slotOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "srcOffset is indirect" + 1: "srcOffset is relative" + 2: "slotOffset is indirect" + 3: "slotOffset is relative" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[slotOffset] == FIELD` +- `T[srcOffset] == FIELD` + +## Error Conditions + +- **INVALID_TAG**: Slot or value operand is not FIELD +- **STATIC_CALL_ALTERATION**: Attempted storage write in static call context +- **SIDE_EFFECT_LIMIT_REACHED**: Exceeded maximum public data updates per transaction (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/staticcall.md b/yarn-project/simulator/docs/avm/opcodes/staticcall.md new file mode 100644 index 000000000000..98a86d5bfaac --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/staticcall.md @@ -0,0 +1,126 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# STATICCALL + +Static call to external contract + +Opcode `0x3A` + +```javascript +childContext = createChildContext( + contract: M[addrOffset], + calldataOffset: argsOffset, + calldataSize: M[argsSizeOffset], + l2Gas: M[l2GasOffset], + daGas: M[daGasOffset], + isStatic: true +) +execute childContext +``` + +## Details + +Calls another contract in static mode (read-only). Any state modifications in the nested call will cause it to revert. Updates nestedCallSuccess and nestedReturndata. Child can access caller's `M[calldataOffset:calldataOffset+calldataSize]` via CALLDATACOPY. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 9936 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `l2GasOffset` | Memory offset | Memory offset of the L2 gas to allocate to the nested call | +| `daGasOffset` | Memory offset | Memory offset of the DA gas to allocate to the nested call | +| `addrOffset` | Memory offset | Memory offset of the target contract address | +| `argsSizeOffset` | Memory offset | Memory offset of the calldata size | +| `argsOffset` | Memory offset | Memory offset of the start of the calldata | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**STATICCALL** (Opcode 0x3A): + +```mermaid +--- +title: "STATICCALL" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x3A)" +8-23: "Addressing modes" +24-39: "Operand: l2GasOffset" +40-55: "Operand: daGasOffset" +56-71: "Operand: addrOffset" +72-87: "Operand: argsSizeOffset" +88-103: "Operand: argsOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +16-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`l2GasOffset`, `daGasOffset`, `addrOffset`, `argsSizeOffset`, `argsOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "l2GasOffset is indirect" + 1: "l2GasOffset is relative" + 2: "daGasOffset is indirect" + 3: "daGasOffset is relative" + 4: "addrOffset is indirect" + 5: "addrOffset is relative" + 6: "argsSizeOffset is indirect" + 7: "argsSizeOffset is relative" + 8: "argsOffset is indirect" + 9: "argsOffset is relative" + 10: "Unused" + 11: "Unused" + 12: "Unused" + 13: "Unused" + 14: "Unused" + 15: "Unused" +``` + +## Tag Checks + +- `T[l2GasOffset] == UINT32` +- `T[daGasOffset] == UINT32` +- `T[addrOffset] == FIELD` +- `T[argsSizeOffset] == UINT32` + +## Tag Updates + +- `T[successOffset] = UINT1` + +## Error Conditions + +- **INVALID_TAG**: Gas, address, or size operands have incorrect tags +- **OUT_OF_GAS**: Insufficient gas for the nested call +- **SIDE_EFFECT_LIMIT_REACHED**: Exceeded maximum unique contract class IDs per transaction (MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS) +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +## Notes + +- See [External Calls](../external-calls.md) for more details on execution flow. +- See [Calldata and Return Data](../calldata-returndata.md) for more details on passing data. + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/sub.md b/yarn-project/simulator/docs/avm/opcodes/sub.md new file mode 100644 index 000000000000..2681ce633c4c --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/sub.md @@ -0,0 +1,113 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# SUB + +Subtraction (a - b) + +Opcodes `0x02`-`0x03` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] - M[bOffset] +``` + +## Details + +Performs subtraction. Both operands must have the same type tag. For integer types (UINT8, UINT16, UINT32, UINT64, UINT128), the operation is performed modulo 2^k where k is the bit-width (e.g., k=8 for UINT8). For FIELD type, the operation is performed modulo p (the BN254 field prime). The result inherits the tag from the operands. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of the minuend | +| `bOffset` | Memory offset | Memory offset of the subtrahend | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**SUB_8** (Opcode 0x02): + +```mermaid +--- +title: "SUB_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x2)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**SUB_16** (Opcode 0x03): + +```mermaid +--- +title: "SUB_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x3)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` + +## Tag Updates + +- `T[dstOffset] = T[aOffset]` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/successcopy.md b/yarn-project/simulator/docs/avm/opcodes/successcopy.md new file mode 100644 index 000000000000..b1da9a951a2c --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/successcopy.md @@ -0,0 +1,91 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# SUCCESSCOPY + +Get success status of latest external call + +Opcode `0x20` + +```javascript +M[dstOffset] = nestedCallSuccess ? 1 : 0 +``` + +## Details + +Returns 1 if the most recent nested external call (CALL or STATICCALL instruction) succeeded, 0 if it reverted. Result is Uint1. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `dstOffset` | Memory offset | Memory offset for success status (0 or 1) will be written | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**SUCCESSCOPY** (Opcode 0x20): + +```mermaid +--- +title: "SUCCESSCOPY" +config: + packet: + bitsPerRow: 32 +--- +packet-beta +0-7: "Opcode (0x20)" +8-15: "Addressing modes" +16-31: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "dstOffset is indirect" + 1: "dstOffset is relative" + 2: "Unused" + 3: "Unused" + 4: "Unused" + 5: "Unused" + 6: "Unused" + 7: "Unused" +``` + +## Tag Updates + +- `T[dstOffset] = UINT1` + +## Error Conditions + +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +## Notes + +- See [External Calls](../external-calls.md) for more details on nested calls and success handling. + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/toradixbe.md b/yarn-project/simulator/docs/avm/opcodes/toradixbe.md new file mode 100644 index 000000000000..29f5f3682168 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/toradixbe.md @@ -0,0 +1,123 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# TORADIXBE + +Convert to radix (big-endian) + +Opcode `0x43` + +```javascript +M[dstOffset:dstOffset+M[numLimbsOffset]] = toRadixBE( + /*value=*/M[srcOffset], + /*radix=*/M[radixOffset], + /*numLimbs=*/M[numLimbsOffset], + /*outputBits=*/M[outputBitsOffset] + ) +``` + +## Details + +Decomposes a field element into limbs in the specified radix (2-256). If outputBits is true (Uint1), outputs Uint1 array; otherwise outputs Uint8 array. Source must be FIELD, radix and numLimbs must be Uint32. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 24 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | +| L2 Dynamic | 3 | `M[numLimbsOffset]`, `M[radixOffset]`* | + +*Note: The L2 gas cost scales linearly with M[numLimbsOffset], but also includes a per-limb multiplier based on M[radixOffset] + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `srcOffset` | Memory offset | Memory offset of the field element to decompose | +| `radixOffset` | Memory offset | Memory offset of the radix (base) for decomposition | +| `numLimbsOffset` | Memory offset | Memory offset of the number of limbs to generate | +| `outputBitsOffset` | Memory offset | Memory offset of the output mode flag (1 for bits, 0 for bytes) | +| `dstOffset` | Memory offset | Memory offset for limb array will be written | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**TORADIXBE** (Opcode 0x43): + +```mermaid +--- +title: "TORADIXBE" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x43)" +8-23: "Addressing modes" +24-39: "Operand: srcOffset" +40-55: "Operand: radixOffset" +56-71: "Operand: numLimbsOffset" +72-87: "Operand: outputBitsOffset" +88-103: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +16-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`srcOffset`, `radixOffset`, `numLimbsOffset`, `outputBitsOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "srcOffset is indirect" + 1: "srcOffset is relative" + 2: "radixOffset is indirect" + 3: "radixOffset is relative" + 4: "numLimbsOffset is indirect" + 5: "numLimbsOffset is relative" + 6: "outputBitsOffset is indirect" + 7: "outputBitsOffset is relative" + 8: "dstOffset is indirect" + 9: "dstOffset is relative" + 10: "Unused" + 11: "Unused" + 12: "Unused" + 13: "Unused" + 14: "Unused" + 15: "Unused" +``` + +## Tag Checks + +- `T[srcOffset] == FIELD` +- `T[radixOffset] == UINT32` +- `T[numLimbsOffset] == UINT32` +- `T[outputBitsOffset] == UINT1` + +## Tag Updates + +- `T[dstOffset:dstOffset+M[numLimbsOffset]] = (M[outputBitsOffset] ? UINT1 : UINT8)` + +## Error Conditions + +- **INVALID_TAG**: Operands have incorrect type tags +- **INVALID_RADIX**: Radix is not in range [2, 256] +- **INVALID_NUM_LIMBS**: Number of limbs is zero but value is non-zero +- **INVALID_DECOMPOSITION**: Value cannot be decomposed into specified radix/limbs +- **INVALID_BIT_MODE**: Bit mode is enabled but radix is not 2 +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/opcodes/xor.md b/yarn-project/simulator/docs/avm/opcodes/xor.md new file mode 100644 index 000000000000..1ecc54db5160 --- /dev/null +++ b/yarn-project/simulator/docs/avm/opcodes/xor.md @@ -0,0 +1,116 @@ +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) + +# XOR + +Bitwise XOR (a ^ b) + +Opcodes `0x14`-`0x15` (2 wire formats) + +```javascript +M[dstOffset] = M[aOffset] ^ M[bOffset] +``` + +## Details + +Performs bitwise XOR operation. Both operands must have the same integral type tag (UINT1, UINT8, UINT16, UINT32, UINT64, UINT128). The result inherits the tag from the operands. + +## Gas Costs + +| Component | Value | Scales with | +|-----------|-------|-------------| +| L2 Base | 12 | - | +| DA Base | 0 | - | +| L2 Addressing | 3 | 3 L2 gas per indirect memory offset
3 L2 gas per relative memory offset | +| L2 Dynamic | 3 | - | + +*See [Gas Metering](gas.md) for details on how gas costs are computed and applied. + +## Operands + +| Name | Type | Description | +|------|------|-------------| +| `aOffset` | Memory offset | Memory offset of first input | +| `bOffset` | Memory offset | Memory offset of second input | +| `dstOffset` | Memory offset | Memory offset for result | + +## Wire Formats +See [Wire Format](wire-format.md) page for an explanation of wire format variants and opcode naming (e.g., why `ADD_8` vs `ADD_16`). + +**XOR_8** (Opcode 0x14): + +```mermaid +--- +title: "XOR_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x14)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**XOR_16** (Opcode 0x15): + +```mermaid +--- +title: "XOR_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x15)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +## Addressing Modes +See [Addressing](addressing.md) page for a detailed explanation. + +8-bit bitmask: 2 bits per memory offset operand (indirect flag + relative flag) + +Memory offset operands (`aOffset`, `bOffset`, `dstOffset`) are encoded as follows: + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +## Tag Checks + +- `T[aOffset] == T[bOffset]` +- `T[aOffset] is integral` + +## Tag Updates + +- `T[dstOffset] = T[aOffset]` + +## Error Conditions + +- **TAG_MISMATCH**: Operands have different type tags +- **INVALID_TAG_TYPE**: Operands are not integral types +- **MEMORY_ACCESS_OUT_OF_RANGE**: Memory offset operand exceeds addressable memory + +--- + +[← Back to Instruction Set: Quick Reference](../avm-isa-quick-reference.md) \ No newline at end of file diff --git a/yarn-project/simulator/docs/avm/public-tx-simulation.md b/yarn-project/simulator/docs/avm/public-tx-simulation.md new file mode 100644 index 000000000000..1ba0a7026d8d --- /dev/null +++ b/yarn-project/simulator/docs/avm/public-tx-simulation.md @@ -0,0 +1,274 @@ +# Public Transaction Simulation + +This document describes the lifecycle of a transaction's public execution beyond what happens inside individual enqueued public calls. It covers insertions of side-effects from private, execution phases, revert handling and state rollback, fee payment, and the tree padding steps required before a transaction can be proven. + +## Overview + +A transaction in Aztec may include both private and public execution. Private execution happens client-side and produces a set of side effects (nullifiers, note hashes, messages) along with enqueued public call requests. These public calls are then executed by the sequencer. + +Public transaction simulation encompasses: + +1. **Execution phases** - Organizing public calls into setup, app logic, and teardown +2. **Side effect integration** - Committing side effects from private execution into world state +3. **State management** - Handling reverts with proper rollback semantics +4. **Fee payment** - Deducting the transaction fee from the fee payer +5. **Tree padding** - + +## Execution Phases + +Public execution is divided into three phases, each with different revert semantics: + +### SETUP Phase (Non-Revertible) + +The setup phase contains critical operations that **must succeed** for the transaction to be valid. These are typically protocol-level operations or prerequisite checks. + +- If any call in setup reverts, the **entire transaction is discarded** +- No state changes from the transaction are preserved +- The transaction never appears on-chain +- Even teardown does not execute + +### APP_LOGIC Phase (Revertible) + +The app logic phase contains the main application functionality. This is where most user-initiated public calls execute. + +- If app logic reverts, the transaction **still succeeds** (with a revert code) +- State changes from app logic are rolled back +- Side effects from private's revertible portion are also discarded +- Teardown still executes +- The transaction appears on-chain with `APP_LOGIC_REVERTED` status + +### TEARDOWN Phase (Revertible, Always Runs) + +The teardown phase always executes, even if app logic reverted. + +- Has its own separate gas allocation +- Only phase that can access the actual transaction fee +- If teardown reverts, its state changes are rolled back + +### Phase Execution Order + +``` +TX execution begins + │ + ▼ +┌──────────────────┐ +│ Insert private │ ◄─── Non-revertible side effects from private +│ side effects │ (nullifiers, note hashes, L2→L1 msgs) +└────────┬─────────┘ Revert here = TX discarded entirely + │ + ▼ +┌──────────────────┐ +│ SETUP Phase │ ──── Revert here = TX discarded entirely +└────────┬─────────┘ + │ + ▼ + ═══ CHECKPOINT ═══ ◄─── Point we can roll back to + │ + ▼ +┌──────────────────┐ +│ Insert private │ ◄─── Revertible side effects from private +│ side effects │ (nullifiers, note hashes, L2→L1 msgs) +└────────┬─────────┘ Revert here = rollback to checkpoint + │ + ▼ +┌──────────────────┐ +│ APP_LOGIC Phase │ ──── Revert here = rollback to checkpoint +└────────┬─────────┘ + │ + ▼ +┌──────────────────┐ +│ TEARDOWN Phase │ ──── Revert here = rollback to checkpoint +└────────┬─────────┘ + │ + ▼ +┌──────────────────┐ +│ Fee Payment │ +└────────┬─────────┘ + │ + ▼ +┌──────────────────┐ +│ Tree padding │ +└──────────────────┘ +``` + +## Revert Handling and State Rollback + +Aztec implements a checkpoint-based rollback mechanism that allows graceful handling of reverts in revertible phases while preserving the results of non-revertible work. + +### The Post-Setup Checkpoint + +After the setup phase completes successfully, a **checkpoint** is created. This checkpoint captures: + +- The state of all merkle trees (nullifier, note hash, public data) +- Pending storage writes +- Pending nullifiers +- All accumulated side effects + +This checkpoint is the "safe point" that revertible phases can roll back to. + +### Rollback Triggers + +Rollback to the post-setup checkpoint occurs when: + +1. **Revertible private insertions fail** - A nullifier from private's revertible portion collides with an existing nullifier, or a limit is exceeded +2. **App logic reverts** - Any enqueued call in the app logic phase reverts +3. **Teardown reverts** - The teardown call reverts + +### What Gets Rolled Back + +When a revertible phase reverts: + +| Rolled Back | Preserved | +|-------------|-----------| +| Storage writes from the phase | Setup phase state changes | +| Nullifiers from the phase | Non-revertible private side effects | +| Note hashes from the phase | Gas consumption tracking | +| L2→L1 messages from the phase | Execution logs (for debugging) | +| Public logs from the phase | The fact that a revert occurred | + + +## Private Side Effect Integration + +Before public execution begins, side effects from private execution must be integrated into world state. + +### Non-Revertible Side Effects + +Inserted **before** the setup phase: + +- **Nullifiers** from private's non-revertible portion (including deployed contracts) +- **Note hashes** from private's non-revertible portion +- **L2→L1 messages** from private's non-revertible portion + +If any insertion fails (e.g., nullifier already exists), the transaction is discarded entirely. + +### Revertible Side Effects + +Inserted **after** the post-setup checkpoint: + +- **Nullifiers** from private's revertible portion (including deployed contracts) +- **Note hashes** from private's revertible portion +- **L2→L1 messages** from private's revertible portion + +If any insertion fails (e.g., nullifier collision), state rolls back to the post-setup checkpoint, and execution proceeds immediately to the TEARDOWN phase. + +## Gas Allocation and Metering + +Gas is tracked in two dimensions: **L2 gas** (computation) and **DA gas** (data availability). The transaction sender specifies gas limits that constrain execution. + +### Gas Limit Structure + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Transaction Gas Limits │ +├───────────────────────────────────────┬─────────────────────┤ +│ gasLimits │ teardownGasLimits │ +│ (private + setup + app logic) │ (teardown only) │ +└───────────────────────────────────────┴─────────────────────┘ +``` + +The teardown phase has a **separate gas allocation** that doesn't compete with other phases. This ensures teardown can always execute even if app logic exhausts its gas budget. + +### Gas Accounting During Private Execution + +When private execution completes, the reported "gas used by private" includes: + +- Actual gas consumed during private execution +- The **entire teardown gas limit** (reserved, not yet consumed) + +This reservation ensures that the gas available for public setup and app logic is: `gasLimits - gasUsedByPrivate`, which already accounts for teardown's reserved budget. + +### Gas Allocation Per Enqueued Call + +Each enqueued call within a phase is allocated **all remaining gas** for that phase. After the call completes, actual consumption is deducted: + +- First call in setup: gets `gasLimits - gasUsedByPrivate` +- Second call in setup: gets remaining after first call +- Teardown call: gets `teardownGasLimits` + +### Billed Gas vs Actual Gas + +The protocol distinguishes between: + +| Metric | Description | +|--------|-------------| +| **Billed gas** | Used for fee calculation. Includes teardown gas **limit** (not actual). | +| **Actual gas** | Real consumption. Replaces teardown limit with actual teardown usage. | + +This distinction exists because teardown needs to know the transaction fee before it executes. If fees depended on teardown's actual consumption, there would be a circular dependency. By using the teardown gas limit for billing, the fee is deterministic before teardown runs. + +## Fee Payment + +Every transaction must pay a fee based on gas consumption. + +### Effective Gas Fees + +The transaction fee is computed using **effective gas fees**, which combine: + +- **Base gas fees** - Set by the protocol based on network conditions +- **Priority fees** - Optional tip from the sender to incentivize inclusion + +The effective fee per gas unit is: `min(baseFee + priorityFee, maxFeePerGas)` + +### Fee Calculation + +The transaction fee is: `billedGas.l2Gas × effectiveFeePerL2Gas + billedGas.daGas × effectiveFeePerDaGas` + +Where billed gas = private gas + setup gas + app logic gas + **teardown gas limit**. + +### Fee Visibility During Execution + +| Phase | Can Access Transaction Fee? | +|-------|---------------------------| +| SETUP | No (sees zero) | +| APP_LOGIC | No (sees zero) | +| TEARDOWN | Yes (sees computed fee) | + +This design allows teardown to perform fee-related operations like refunds while preventing earlier phases from gaming fee calculations. Since the fee uses the teardown gas limit (not actual), the fee value seen during teardown is the final fee. + +### Fee Payment Mechanism + +After all phases complete: + +1. The transaction fee is computed from billed gas and effective fees +2. The fee is deducted from the fee payer's Fee Juice balance +3. This deduction is recorded as a public data write + +If the fee payer has insufficient balance: +- During simulation for fee estimation: can be skipped +- During simulation for block building or proving: transaction fails + +## Tree Padding + +Before a transaction can be proven, merkle trees must be padded to fixed increment sizes. + +### Why Padding Is Needed + +Padding inserts empty values into the trees to keep them aligned to fixed increments per transaction. + +### What Gets Padded + +| Tree | Padding Value | +|------|---------------| +| Note hash tree | Zero | +| Nullifier tree | Empty nullifier leaf | +| Public data tree | Empty public data leaf | + +## Transaction Outputs + +After simulation completes, the following outputs are produced: + +- **Start tree snapshots** - Merkle tree roots before public execution +- **End tree snapshots** - Merkle tree roots after public execution and padding +- **Accumulated data** - All side effects with counters (note hashes, nullifiers, messages, public data writes, public logs) + +## Execution Context Isolation + +Each enqueued call executes with its own context, but within the shared transaction context: + +- **Isolated**: Each call has its own memory, calldata, and return data +- **Shared**: All calls in a phase share the same world state view +- **Ordered**: Calls execute sequentially within their phase +- **Bounded**: Each call's gas consumption is tracked and limited + +--- +← Previous: [Enqueued Calls](./enqueued-calls.md) | Next: [State](./state.md) → diff --git a/yarn-project/simulator/docs/avm/state.md b/yarn-project/simulator/docs/avm/state.md new file mode 100644 index 000000000000..05be8a1b3b44 --- /dev/null +++ b/yarn-project/simulator/docs/avm/state.md @@ -0,0 +1,47 @@ +# AVM State + +The AVM manages two categories of state during execution: **world state** (persistent changes to the blockchain) and **execution state** (transient data local to a call). + +## World State + +World state represents persistent changes that are committed to Aztec when a transaction succeeds. These are tracked during execution and only finalized after the entire transaction completes successfully. + +| Component | Description | +|-----------|-------------| +| **Public Storage** | Contract storage slots (key-value mapping per contract) | +| **Nullifiers** | Unique identifiers that mark notes as "spent" | +| **Note Hashes** | Commitments to private notes | +| **L2-to-L1 Messages** | Messages sent from Aztec to Ethereum | +| **Public Logs** | Event logs emitted during public execution | + +World state modifications accumulate during execution. If the top-level call reverts, all world state changes from the entire transaction are discarded. + +## Execution State + +Execution state is transient data that exists only during a call's execution. + +| Component | Description | +|-----------|-------------| +| **Memory** | The call's working memory (tagged field elements) | +| **Gas** | Remaining L2 and DA gas for this call | +| **Program Counter** | Current position in the bytecode | +| **Internal Call Stack** | Return addresses for [INTERNALCALL](opcodes/internalcall.md)/[INTERNALRETURN](opcodes/internalreturn.md) | +| **Nested Call Results** | Return data and success flag from the last external call | + +Each [external call](external-calls.md) creates a new execution context with fresh execution state. Memory is **not** shared between calls—the caller and callee have completely independent memory spaces. + +## State Isolation in Nested Calls + +When a contract makes an [external call](external-calls.md), the AVM creates a **fork** of the current world state for the nested call to operate on. This fork is isolated from the caller: + +- The nested call can read any world state (including the caller's uncommitted writes) +- The nested call's writes go to its own fork, not directly to the caller's state +- If the nested call succeeds, its fork is **merged** back into the caller's state +- If the nested call reverts, its fork is **discarded** entirely + +This isolation means a reverted nested call cannot corrupt the caller's state. The caller can safely attempt calls and handle failures without risking its own accumulated state changes. + +See [External Calls](external-calls.md) for details on how calls execute and how state is merged or discarded. + +--- +← Previous: [Public Transaction Simulation](./public-tx-simulation.md) | Next: [Memory Model](./memory.md) → diff --git a/yarn-project/simulator/docs/avm/tooling.md b/yarn-project/simulator/docs/avm/tooling.md new file mode 100644 index 000000000000..efdd54598078 --- /dev/null +++ b/yarn-project/simulator/docs/avm/tooling.md @@ -0,0 +1,46 @@ +# Tooling and Compilation + +This document provides a high-level overview of the AVM compilation pipeline. + +## Compilation Flow + +Public code in Aztec contracts is generally written in Noir and compiled to AVM bytecode: + +``` +Noir source (.nr) + ↓ + nargo compile + ↓ + Brillig + ↓ + AVM Transpiler + ↓ + AVM Bytecode +``` + +**Stages**: +1. **Noir source**: Contract code written in Noir +2. **nargo compile**: The Noir compiler produces ACIR (for private functions) and Brillig (for public functions) +3. **AVM Transpiler**: Converts Brillig to AVM bytecode for public execution + +Private functions use ACIR and are proven client-side. Public functions use AVM bytecode and are proven by the AVM circuit. + +## Bytecode + +AVM bytecode is a sequence of instructions that can be executed and eventually proven in Aztec's VM for public execution. + +See [Wire Format](wire-format.md) for instruction encoding details. + +## Artifacts + +The compilation process produces: +- Contract artifact containing AVM bytecode for public functions +- Function metadata (selectors, names, parameters) +- Deployment information (class ID, address derivation) + +## Versioning + +AVM bytecode format may evolve between protocol versions. Bytecode produced by a compiler version must match the protocol's expected format. + +--- +← Previous: [AVM vs EVM](./avm-vs-evm.md) diff --git a/yarn-project/simulator/docs/avm/wire-format.md b/yarn-project/simulator/docs/avm/wire-format.md new file mode 100644 index 000000000000..6c3ca4dc648d --- /dev/null +++ b/yarn-project/simulator/docs/avm/wire-format.md @@ -0,0 +1,84 @@ +# Wire Formats + +The AVM bytecode uses a compact binary encoding where each instruction is serialized as a sequence of bytes according to its **wire format**. + +## Key Concept: Opcode Suffixes + +>[!IMPORTANT] +> Opcode suffixes like `ADD_8` and `ADD_16` refer to the **size of memory offset operands in the bytecode**, NOT the type of data being operated on. +> +> - `ADD_8`: Memory offsets fit in 8 bits (1 byte each) +> - `ADD_16`: Memory offsets fit in 16 bits (2 bytes each) +> +> Both execute the same ADD operation and work with any supported type (FIELD, UINT1, UINT8, UINT32, UINT64, UINT128, etc.). The difference is purely about bytecode compactness. + +### Example: `ADD_8` and `ADD_16` + +The numeric suffixes in these opcode names (`_8` or `_16`) indicate the **size of memory offset operands + in the bytecode**, not the type of data being operated on. + +The actual operation type is determined by the [type tags](memory.md#type-tags) of the resolved memory +locations. For example, `ADD_8` encodes its `aOffset` and `bOffset` operands as 8-bit values in the +bytecode. However, if these offsets (after [addressing mode](addressing.md) resolution) point to memory +cells tagged as UINT128, the instruction performs 128-bit addition. For `ADD`s (and for many other operations), +the AVM enforces that the inputs have matching tags (`T[aOffset] == T[bOffset]`) and then tags the result with that same tag. + +Below are the full wire formats for this example along with the addressing modes bitmask: + +**ADD_8** + +```mermaid +--- +title: "ADD_8" +config: + packet: + bitsPerRow: 40 +--- +packet-beta +0-7: "Opcode (0x0)" +8-15: "Addressing modes" +16-23: "Operand: aOffset" +24-31: "Operand: bOffset" +32-39: "Operand: dstOffset" +``` + +**ADD_16**: + +```mermaid +--- +title: "ADD_16" +config: + packet: + bitsPerRow: 64 +--- +packet-beta +0-7: "Opcode (0x1)" +8-15: "Addressing modes" +16-31: "Operand: aOffset" +32-47: "Operand: bOffset" +48-63: "Operand: dstOffset" +``` + +**Addressing Modes** + +```mermaid +--- +title: "Addressing Mode Bitmask" +config: + packet: + bitWidth: 128 + bitsPerRow: 8 +--- +packet-beta + 0: "aOffset is indirect" + 1: "aOffset is relative" + 2: "bOffset is indirect" + 3: "bOffset is relative" + 4: "dstOffset is indirect" + 5: "dstOffset is relative" + 6: "Unused" + 7: "Unused" +``` + +--- +← Previous: [Calldata and Return Data](./calldata-returndata.md) | Next: [Instruction Set: Quick Reference](./avm-isa-quick-reference.md) → From 99def2e265ddb9fe17e8cdec5a94bf1580ea1210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Fri, 16 Jan 2026 12:12:35 +0100 Subject: [PATCH 07/15] fix(avm): Increase chances of fuzzer finding limits (#19656) Resolves https://linear.app/aztec-labs/issue/AVM-176/cover-executioncpp-tree-limits --- .../avm_fuzzer/mutations/tx_types/accumulated_data.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.hpp index 2a1609656a11..d183f99ea2f4 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.hpp @@ -20,11 +20,11 @@ enum class AccumulatedDataMutationOptions : uint8_t { using AccumulatedDataMutationConfig = WeightedSelectionConfig; constexpr AccumulatedDataMutationConfig ACCUMULATED_DATA_MUTATION_CONFIGURATION = AccumulatedDataMutationConfig({ - { AccumulatedDataMutationOptions::NoteHashes, 20 }, + { AccumulatedDataMutationOptions::NoteHashes, 10 }, { AccumulatedDataMutationOptions::NoteHashesLimit, 1 }, - { AccumulatedDataMutationOptions::Nullifiers, 20 }, + { AccumulatedDataMutationOptions::Nullifiers, 10 }, { AccumulatedDataMutationOptions::NullifiersLimit, 1 }, - { AccumulatedDataMutationOptions::L2ToL1Messages, 20 }, + { AccumulatedDataMutationOptions::L2ToL1Messages, 10 }, { AccumulatedDataMutationOptions::L2ToL1MessagesLimit, 1 }, }); From 6d215f3dffe598aad0ae6e24a82e9fe96725b5bf Mon Sep 17 00:00:00 2001 From: Jean M <132435771+jeanmon@users.noreply.github.com> Date: Fri, 16 Jan 2026 12:27:00 +0100 Subject: [PATCH 08/15] fix(avm)!: de-risk memory injection attacks (#19620) Linear issue [AVM-180](https://linear.app/aztec-labs/issue/AVM-180/de-risk-memory-corruption-attacks) --- barretenberg/cpp/pil/vm2/keccak_memory.pil | 93 ++- barretenberg/cpp/pil/vm2/keccakf1600.pil | 109 ++- barretenberg/cpp/pil/vm2/memory.pil | 2 +- barretenberg/cpp/pil/vm2/poseidon2_mem.pil | 1 - barretenberg/cpp/pil/vm2/sha256_mem.pil | 18 +- barretenberg/cpp/pil/vm2/to_radix_mem.pil | 25 +- .../constraining/relations/to_radix.test.cpp | 3 +- .../barretenberg/vm2/generated/columns.hpp | 14 +- .../vm2/generated/flavor_variables.hpp | 4 +- .../vm2/generated/relations/keccak_memory.hpp | 97 +-- .../relations/keccak_memory_impl.hpp | 296 +++---- .../vm2/generated/relations/keccakf1600.hpp | 268 +++---- .../generated/relations/keccakf1600_impl.hpp | 719 +++++++++--------- .../vm2/generated/relations/sha256_mem.hpp | 16 +- .../generated/relations/sha256_mem_impl.hpp | 32 +- .../vm2/generated/relations/to_radix_mem.hpp | 12 +- .../generated/relations/to_radix_mem_impl.hpp | 45 +- .../vm2/tracegen/keccakf1600_trace.cpp | 18 - 18 files changed, 950 insertions(+), 822 deletions(-) diff --git a/barretenberg/cpp/pil/vm2/keccak_memory.pil b/barretenberg/cpp/pil/vm2/keccak_memory.pil index f9ce40f3ea32..60a9eab54054 100644 --- a/barretenberg/cpp/pil/vm2/keccak_memory.pil +++ b/barretenberg/cpp/pil/vm2/keccak_memory.pil @@ -90,6 +90,9 @@ sel * (1 - sel) = 0; #[skippable_if] sel = 0; +#[TRACE_CONTINUITY] +(1 - precomputed.first_row) * (1 - sel) * sel' = 0; + pol commit start_read; // @boolean start_read * (1 - start_read) = 0; @@ -109,11 +112,13 @@ pol commit val[25]; // We enforce the initial ctr to be set to 1. #[CTR_INIT] (start_read + start_write) * (ctr - 1) = 0; +// It follows that: `start_read == 1 ==> sel == 1` and `start_write == 1 ==> sel == 1`. #[RW_READ_INIT] start_read * rw = 0; #[RW_WRITE_INIT] start_write * (1 - rw) = 0; +// It follows that `start_read` and `start_write` are mutually exclusive. // sel == 1 <==> ctr != 0 pol commit ctr_inv; @@ -137,9 +142,18 @@ pol commit last; // @boolean (by definition) #[LAST] last = 1 - (1 - ctr_end) * (1 - single_tag_error); +#[LAST_HAS_SEL_ON] +last * (1 - sel) = 0; + +// Latch condition is boolean because `last` cannot be activated at first row due to #[LAST_HAS_SEL_ON]. +pol LATCH_CONDITION = last + precomputed.first_row; + +#[START_AFTER_LATCH] +sel' * (start_read' + start_write' - LATCH_CONDITION) = 0; + #[CTR_INCREMENT] // Note: sel factor is required for an empty row to satisfy this relation -sel * (1 - last) * (ctr' - ctr - 1) = 0; +sel * (1 - LATCH_CONDITION) * (ctr' - ctr - 1) = 0; // Copied from memory.pil through lookup and constrained to be boolean in memory.pil. pol commit rw; // @boolean (constrained by memory.pil) @@ -155,21 +169,21 @@ rw * single_tag_error = 0; last * (tag_error - single_tag_error) = 0; #[TAG_ERROR_PROPAGATION] -(1 - last) * (tag_error - tag_error') = 0; +(1 - LATCH_CONDITION) * (tag_error - tag_error') = 0; // No need to enforce a boolean constraint for tag_error as it follows from the above constraints. #[MEM_ADDR_INCREMENT] -sel * (1 - last) * (addr + 1 - addr') = 0; +sel * (1 - LATCH_CONDITION) * (addr + 1 - addr') = 0; #[SPACEID_PROPAGATION] -(1 - last) * (space_id - space_id') = 0; +(1 - LATCH_CONDITION) * (space_id - space_id') = 0; #[CLK_PROPAGATION] -(1 - last) * (clk' - clk) = 0; +(1 - LATCH_CONDITION) * (clk' - clk) = 0; #[RW_PROPAGATION] -(1 - last) * (rw' - rw) = 0; +(1 - LATCH_CONDITION) * (rw' - rw) = 0; // Check if the tag is U64 // We constrain single_tag_error == 1 <==> tag is not U64. @@ -179,53 +193,53 @@ pol TAG_MIN_U64 = tag - constants.MEM_TAG_U64; sel * (TAG_MIN_U64 * ((1 - single_tag_error) * (1 - tag_min_u64_inv) + tag_min_u64_inv) - single_tag_error) = 0; #[VAL01] -val[1] = (1 - last) * val[0]'; +val[1] = (1 - LATCH_CONDITION) * val[0]'; #[VAL02] -val[2] = (1 - last) * val[1]'; +val[2] = (1 - LATCH_CONDITION) * val[1]'; #[VAL03] -val[3] = (1 - last) * val[2]'; +val[3] = (1 - LATCH_CONDITION) * val[2]'; #[VAL04] -val[4] = (1 - last) * val[3]'; +val[4] = (1 - LATCH_CONDITION) * val[3]'; #[VAL05] -val[5] = (1 - last) * val[4]'; +val[5] = (1 - LATCH_CONDITION) * val[4]'; #[VAL06] -val[6] = (1 - last) * val[5]'; +val[6] = (1 - LATCH_CONDITION) * val[5]'; #[VAL07] -val[7] = (1 - last) * val[6]'; +val[7] = (1 - LATCH_CONDITION) * val[6]'; #[VAL8] -val[8] = (1 - last) * val[7]'; +val[8] = (1 - LATCH_CONDITION) * val[7]'; #[VAL09] -val[9] = (1 - last) * val[8]'; +val[9] = (1 - LATCH_CONDITION) * val[8]'; #[VAL10] -val[10] = (1 - last) * val[9]'; +val[10] = (1 - LATCH_CONDITION) * val[9]'; #[VAL11] -val[11] = (1 - last) * val[10]'; +val[11] = (1 - LATCH_CONDITION) * val[10]'; #[VAL12] -val[12] = (1 - last) * val[11]'; +val[12] = (1 - LATCH_CONDITION) * val[11]'; #[VAL13] -val[13] = (1 - last) * val[12]'; +val[13] = (1 - LATCH_CONDITION) * val[12]'; #[VAL14] -val[14] = (1 - last) * val[13]'; +val[14] = (1 - LATCH_CONDITION) * val[13]'; #[VAL15] -val[15] = (1 - last) * val[14]'; +val[15] = (1 - LATCH_CONDITION) * val[14]'; #[VAL16] -val[16] = (1 - last) * val[15]'; +val[16] = (1 - LATCH_CONDITION) * val[15]'; #[VAL17] -val[17] = (1 - last) * val[16]'; +val[17] = (1 - LATCH_CONDITION) * val[16]'; #[VAL18] -val[18] = (1 - last) * val[17]'; +val[18] = (1 - LATCH_CONDITION) * val[17]'; #[VAL19] -val[19] = (1 - last) * val[18]'; +val[19] = (1 - LATCH_CONDITION) * val[18]'; #[VAL20] -val[20] = (1 - last) * val[19]'; +val[20] = (1 - LATCH_CONDITION) * val[19]'; #[VAL21] -val[21] = (1 - last) * val[20]'; +val[21] = (1 - LATCH_CONDITION) * val[20]'; #[VAL22] -val[22] = (1 - last) * val[21]'; +val[22] = (1 - LATCH_CONDITION) * val[21]'; #[VAL23] -val[23] = (1 - last) * val[22]'; +val[23] = (1 - LATCH_CONDITION) * val[22]'; #[VAL24] -val[24] = (1 - last) * val[23]'; +val[24] = (1 - LATCH_CONDITION) * val[23]'; #[SLICE_TO_MEM] sel { clk, space_id, addr, val[0], tag, rw } @@ -234,3 +248,22 @@ is memory.sel_keccak { memory.clk, memory.space_id, memory.address, memory.value // Used to constrain the number of rounds in keccakf1600.pil through the slice_write lookup. pol commit num_rounds; sel * (num_rounds - constants.AVM_KECCAKF1600_NUM_ROUNDS) = 0; // TODO: Remove once we support constants in lookups + +/* Prevention of illegal memory operations: + * + * If `sel == 1` (required to trigger a memory operation) we have `ctr != 0` by #[SEL_CTR_NON_ZERO]. + * We consider two cases for the previous row above: + * 1) LATCH_CONDITION == 1: By #[START_AFTER_LATCH] we have `start_read == 1` or `start_write` == 1 and implies that + * `ctr == 1` which is legitimate. + * 2) LATCH_CONDITION == 0: By #[CTR_INCREMENT] and #[TRACE_CONTINUITY], we have ctr - 1 on the previous row. + * We can continue this propagation bottom-up until we reach a row whose previous row + * has `LATCH_CONDITION == 1`. We know that this exists because at the latest it + * happens at the very first row of the trace (precomputed.first_row == 1). When this happens, + * by #[START_AFTER_LATCH] we have `start_read == 1` or `start_write` == 1 and we must have + * `ctr == 1`. This shows that this is a legitimate memory operation. + * Note that if we were to start with a counter larger than AVM_KECCAKF1600_STATE_SIZE, then + * in a bottom-up propagation, we would reach a row with `ctr == AVM_KECCAKF1600_STATE_SIZE` + * and `last` and `LATCH_CONDITION` equal to 1. However, this would contradict that on the + * below row `ctr == AVM_KECCAKF1600_STATE_SIZE + 1` and `start_read == 1` or `start_write == 1`. + * Namely, #[CTR_INIT] enforces `ctr == 1`. + */ diff --git a/barretenberg/cpp/pil/vm2/keccakf1600.pil b/barretenberg/cpp/pil/vm2/keccakf1600.pil index 244a53a62d1c..e2a3d920de4e 100644 --- a/barretenberg/cpp/pil/vm2/keccakf1600.pil +++ b/barretenberg/cpp/pil/vm2/keccakf1600.pil @@ -76,10 +76,13 @@ sel * (1 - sel) = 0; #[skippable_if] sel = 0; +#[TRACE_CONTINUITY] +(1 - precomputed.first_row) * (1 - sel) * sel' = 0; + // error is defined below after round function pol commit sel_no_error; // @boolean (by definition) #[SEL_NO_ERROR] -start * (sel_no_error - 1 + error) = 0; +sel * (sel_no_error - 1 + error) = 0; // Round number which starts at 1 and ends at AVM_KECCAKF1600_NUM_ROUNDS (24). pol commit round; @@ -96,21 +99,36 @@ start * (round - 1) = 0; pol commit round_inv; #[KECCAK_SEL_ROUND_NON_ZERO] round * ((1 - sel) * (1 - round_inv) + round_inv) - sel = 0; - -#[KECCAK_ROUND_INCREMENT] -// Note: sel factor is required for an empty row to satisfy this relation -sel * (1 - last) * (round' - round - 1) = 0; +// This implies that `start == 1 ==> sel == 1`. // Selector for the last round of a keccak permutation // If no error is detected in row where `start == 1`, we have last == 1 <==> round == AVM_KECCAKF1600_NUM_ROUNDS (24) -// Otherwise, `last` is unconstrained but witness generator will toggle it on the initial row. // This is achieved through #[SEL_SLICE_WRITE] and #[WRITE_TO_SLICE]. If there is no error, // the former guarantees that the write slice is active whenever `last == 1`. The latter guarantees // that `round` is equal to 24 (by fixing a constant 24 in the destination permutation tuple). pol commit last; // @boolean last * (1 - last) = 0; -// TODO: We need this temporarily while we do not allow for constants in the lookup tuple +// We enforce that `last == 1` whenever `error == 1`. +// Note that error is constrained only on the start row. +#[LAST_ON_ERROR] +error * (last - 1) = 0; + +#[START_AFTER_LATCH] +sel' * (start' - LATCH_CONDITION) = 0; + +#[LAST_HAS_SEL_ON] +last * (1 - sel) = 0; + +// `sel == 0` on the first row because of shift relations and thus `last` is mutually +// exclusive with `precomputed.first_row`. +pol LATCH_CONDITION = last + precomputed.first_row; + +#[KECCAK_ROUND_INCREMENT] +// Note: sel factor is required for an empty row to satisfy this relation +sel * (1 - LATCH_CONDITION) * (round' - round - 1) = 0; + +// Lookup tuple constants: We need this temporarily while we do not allow for constants in the lookup tuple pol commit bitwise_xor_op_id; sel * (bitwise_xor_op_id - constants.AVM_BITWISE_XOR_OP_ID) = 0; pol commit bitwise_and_op_id; @@ -1280,59 +1298,59 @@ bitwise.start_keccak { bitwise.op_id, bitwise.acc_ia, bitwise.acc_ib, bitwise.ac // the output state, otherwise we initialize the next state_in values for the next round. #[NEXT_STATE_IN_00] -(1 - last) * (state_in_00' - state_iota_00) = 0; +(1 - LATCH_CONDITION) * (state_in_00' - state_iota_00) = 0; #[NEXT_STATE_IN_01] -(1 - last) * (state_in_01' - state_chi_01) = 0; +(1 - LATCH_CONDITION) * (state_in_01' - state_chi_01) = 0; #[NEXT_STATE_IN_02] -(1 - last) * (state_in_02' - state_chi_02) = 0; +(1 - LATCH_CONDITION) * (state_in_02' - state_chi_02) = 0; #[NEXT_STATE_IN_03] -(1 - last) * (state_in_03' - state_chi_03) = 0; +(1 - LATCH_CONDITION) * (state_in_03' - state_chi_03) = 0; #[NEXT_STATE_IN_04] -(1 - last) * (state_in_04' - state_chi_04) = 0; +(1 - LATCH_CONDITION) * (state_in_04' - state_chi_04) = 0; #[NEXT_STATE_IN_10] -(1 - last) * (state_in_10' - state_chi_10) = 0; +(1 - LATCH_CONDITION) * (state_in_10' - state_chi_10) = 0; #[NEXT_STATE_IN_11] -(1 - last) * (state_in_11' - state_chi_11) = 0; +(1 - LATCH_CONDITION) * (state_in_11' - state_chi_11) = 0; #[NEXT_STATE_IN_12] -(1 - last) * (state_in_12' - state_chi_12) = 0; +(1 - LATCH_CONDITION) * (state_in_12' - state_chi_12) = 0; #[NEXT_STATE_IN_13] -(1 - last) * (state_in_13' - state_chi_13) = 0; +(1 - LATCH_CONDITION) * (state_in_13' - state_chi_13) = 0; #[NEXT_STATE_IN_14] -(1 - last) * (state_in_14' - state_chi_14) = 0; +(1 - LATCH_CONDITION) * (state_in_14' - state_chi_14) = 0; #[NEXT_STATE_IN_20] -(1 - last) * (state_in_20' - state_chi_20) = 0; +(1 - LATCH_CONDITION) * (state_in_20' - state_chi_20) = 0; #[NEXT_STATE_IN_21] -(1 - last) * (state_in_21' - state_chi_21) = 0; +(1 - LATCH_CONDITION) * (state_in_21' - state_chi_21) = 0; #[NEXT_STATE_IN_22] -(1 - last) * (state_in_22' - state_chi_22) = 0; +(1 - LATCH_CONDITION) * (state_in_22' - state_chi_22) = 0; #[NEXT_STATE_IN_23] -(1 - last) * (state_in_23' - state_chi_23) = 0; +(1 - LATCH_CONDITION) * (state_in_23' - state_chi_23) = 0; #[NEXT_STATE_IN_24] -(1 - last) * (state_in_24' - state_chi_24) = 0; +(1 - LATCH_CONDITION) * (state_in_24' - state_chi_24) = 0; #[NEXT_STATE_IN_30] -(1 - last) * (state_in_30' - state_chi_30) = 0; +(1 - LATCH_CONDITION) * (state_in_30' - state_chi_30) = 0; #[NEXT_STATE_IN_31] -(1 - last) * (state_in_31' - state_chi_31) = 0; +(1 - LATCH_CONDITION) * (state_in_31' - state_chi_31) = 0; #[NEXT_STATE_IN_32] -(1 - last) * (state_in_32' - state_chi_32) = 0; +(1 - LATCH_CONDITION) * (state_in_32' - state_chi_32) = 0; #[NEXT_STATE_IN_33] -(1 - last) * (state_in_33' - state_chi_33) = 0; +(1 - LATCH_CONDITION) * (state_in_33' - state_chi_33) = 0; #[NEXT_STATE_IN_34] -(1 - last) * (state_in_34' - state_chi_34) = 0; +(1 - LATCH_CONDITION) * (state_in_34' - state_chi_34) = 0; #[NEXT_STATE_IN_40] -(1 - last) * (state_in_40' - state_chi_40) = 0; +(1 - LATCH_CONDITION) * (state_in_40' - state_chi_40) = 0; #[NEXT_STATE_IN_41] -(1 - last) * (state_in_41' - state_chi_41) = 0; +(1 - LATCH_CONDITION) * (state_in_41' - state_chi_41) = 0; #[NEXT_STATE_IN_42] -(1 - last) * (state_in_42' - state_chi_42) = 0; +(1 - LATCH_CONDITION) * (state_in_42' - state_chi_42) = 0; #[NEXT_STATE_IN_43] -(1 - last) * (state_in_43' - state_chi_43) = 0; +(1 - LATCH_CONDITION) * (state_in_43' - state_chi_43) = 0; #[NEXT_STATE_IN_44] -(1 - last) * (state_in_44' - state_chi_44) = 0; +(1 - LATCH_CONDITION) * (state_in_44' - state_chi_44) = 0; //############################################################################# // Read-Write to memory slice and error handling @@ -1373,16 +1391,16 @@ start { dst_addr, highest_slice_address, dst_out_of_range_error } in gt.sel_othe error = 1 - (1 - src_out_of_range_error) * (1 - dst_out_of_range_error) * (1 - tag_error); #[DST_ADDR_PROPAGATION] -(1 - last) * (dst_addr' - dst_addr) = 0; +(1 - LATCH_CONDITION) * (dst_addr' - dst_addr) = 0; #[CLK_PROPAGATION] -(1 - last) * (clk' - clk) = 0; +(1 - LATCH_CONDITION) * (clk' - clk) = 0; #[SPACE_ID_PROPAGATION] -(1 - last) * (space_id' - space_id) = 0; +(1 - LATCH_CONDITION) * (space_id' - space_id) = 0; // It is crucial to propagate sel_no_error to the bottom (last == 1) as to properly // activate the slice write lookup (see below). #[SEL_NO_ERROR_PROPAGATION] -(1 - last) * (sel_no_error' - sel_no_error) = 0; +(1 - LATCH_CONDITION) * (sel_no_error' - sel_no_error) = 0; // Note that we do not propagate src_out_of_range_error, dst_out_of_range_error, tag_error, error // as they are not affecting constraints in the other rows. Error propagation to the caller @@ -1399,6 +1417,23 @@ sel_slice_read = start * (1 - src_out_of_range_error) * (1 - dst_out_of_range_er #[SEL_SLICE_WRITE] sel_slice_write = sel_no_error * last; +// Prevention of illegitimate writes to memory: +// sel_slice_write == 1 ==> round == 24 (by #[WRITE_TO_SLICE]) +// From #[KECCAK_SEL_ROUND_NON_ZERO], we have `sel == 1`. +// Since `last` is a boolean and `sel_no_error` is boolean on an active row, +// `last == 1` and `sel_no_error == 1`. +// This row must have `start == 0` because otherwise `round` would be equal to 1 instead of 24. +// As a consequence, the previous row must have `LATCH_CONDITION == 0` by #[START_AFTER_LATCH] +// which enforces a bottom-up propagation of `sel_no_error` and a decreasing counter for `round` +// by #[SEL_NO_ERROR_PROPAGATION] and #[KECCAK_ROUND_INCREMENT]. When the propagation reaches +// `round == 1`, we have `sel == 1` (#[KECCAK_SEL_ROUND_NON_ZERO]) two possible cases: +// 1) The row above is `precomputed.first_row == 1` which implies that `start == 1`. +// 2) Otherwise, by #[TRACE_CONTINUITY], the above row must be active (sel == 1) +// and we cannot decrement `round` anymore (would be zero which contradicts #[KECCAK_SEL_ROUND_NON_ZERO]). +// As a consequence, the above row must have `last == LATCH_CONDITION == 1` which implies that `start == 1`. +// This shows that any "slice write to memory" operation was triggered by a legitimate keccak permutation +// because `start` is the destination selector for the keccak permutation. + #[READ_TO_SLICE] // Standard Keccak layout: memory[(y * 5) + x] = A[x][y] // State columns ordered in column-major order (by x coordinate first, then y) @@ -1429,7 +1464,7 @@ sel_slice_write { state_iota_00, state_chi_10, state_chi_20, state_chi_30, state state_chi_03, state_chi_13, state_chi_23, state_chi_33, state_chi_43, state_chi_04, state_chi_14, state_chi_24, state_chi_34, state_chi_44, clk, dst_addr, space_id, round } -is +is // Crucial to be a permutation to prevent any illegal write to memory in keccak_memory.pil. keccak_memory.start_write { keccak_memory.val[0], keccak_memory.val[1], keccak_memory.val[2], keccak_memory.val[3], keccak_memory.val[4], keccak_memory.val[5], keccak_memory.val[6], keccak_memory.val[7], keccak_memory.val[8], keccak_memory.val[9], keccak_memory.val[10], keccak_memory.val[11], keccak_memory.val[12], keccak_memory.val[13], keccak_memory.val[14], diff --git a/barretenberg/cpp/pil/vm2/memory.pil b/barretenberg/cpp/pil/vm2/memory.pil index dc5553781658..d806b3c69e86 100644 --- a/barretenberg/cpp/pil/vm2/memory.pil +++ b/barretenberg/cpp/pil/vm2/memory.pil @@ -174,7 +174,7 @@ sel = // Addressing. // Other boolean constraints. sel * (1 - sel) = 0; // Ensure mutual exclusivity of the permutation selectors. last_access * (1 - last_access) = 0; -rw * (1 - rw) = 0; // TODO: should already be constrained by each source of interaction lookups. +rw * (1 - rw) = 0; // Some source sub-trace relies on this constraint (e.g., keccak_memory.pil) sel_tag_is_ff * (1 - sel_tag_is_ff) = 0; // Trace must be contiguous. diff --git a/barretenberg/cpp/pil/vm2/poseidon2_mem.pil b/barretenberg/cpp/pil/vm2/poseidon2_mem.pil index c3ab5f609f3c..1e2f99ea3141 100644 --- a/barretenberg/cpp/pil/vm2/poseidon2_mem.pil +++ b/barretenberg/cpp/pil/vm2/poseidon2_mem.pil @@ -168,7 +168,6 @@ namespace poseidon2_perm_mem; //////////////////////////////////////////////// // Write output to memory //////////////////////////////////////////////// - // TODO: These need to be changed to permutations once we have the custom permutation selectors #[POS_WRITE_MEM_0] sel_should_exec { execution_clk, space_id, diff --git a/barretenberg/cpp/pil/vm2/sha256_mem.pil b/barretenberg/cpp/pil/vm2/sha256_mem.pil index 47f0272bc0c5..564fbe4d66b3 100644 --- a/barretenberg/cpp/pil/vm2/sha256_mem.pil +++ b/barretenberg/cpp/pil/vm2/sha256_mem.pil @@ -96,6 +96,9 @@ namespace sha256; #[skippable_if] sel = 0; + #[TRACE_CONTINUITY] + (1 - precomputed.first_row) * (1 - sel) * sel' = 0; + // Inputs pol commit execution_clk; pol commit space_id; @@ -125,10 +128,10 @@ namespace sha256; sel' * (start' - LATCH_CONDITION) = 0; pol NOT_LAST = sel * (1 - LATCH_CONDITION); - // We match the lookup on start, and start implies sel - // we then force sel = 1 on all subsequent rows unless we hit a LATCH_CONDITION - #[CONTINUITY_SEL] // Propagate sel - (1 - LATCH_CONDITION) * (sel' - sel) = 0; + // Since start == 1 and latch == 1 both imply `sel == 1`, the trace continuity + // #[TRACE_CONTINUITY] guarantees that `sel = 1` on all rows between the start and latch rows. + // Furthermore, it enforces that a non-emtpy subtrace must have `start == 1` just after the first row. + #[CONTINUITY_EXEC_CLK] // Propagate exec clk (1 - LATCH_CONDITION) * (execution_clk' - execution_clk) = 0; #[CONTINUITY_SPACE_ID] // Propagate space id down @@ -178,8 +181,11 @@ namespace sha256; in gt.sel_others { gt.input_a, gt.input_b, gt.res }; + // If any of the out of range errors are set, the memory out of range error is set. + // We gate by `start` to ensure it can only be set on this row. Any of these out of range + // errors are not constrained on non-start rows. pol commit mem_out_of_range_err; - mem_out_of_range_err = 1 - (1 - sel_state_out_of_range_err) * (1 - sel_input_out_of_range_err) * (1 - sel_output_out_of_range_err); + mem_out_of_range_err = start * (1 - (1 - sel_state_out_of_range_err) * (1 - sel_input_out_of_range_err) * (1 - sel_output_out_of_range_err)); //////////////////////////////////////////////////////// // Memory Operations: State and Output @@ -434,7 +440,7 @@ namespace sha256; // We latch on rows that have a memory error, state tag error or the row that has an invalid input tag error // We cannot simply latch on error because we do not want to latch on the propagated sel_invalid_input_tag_err pol LATCH_ON_ERROR = 1 - (1 - mem_out_of_range_err) * (1 - sel_invalid_state_tag_err) * (1 - sel_invalid_input_row_tag_err); - sel * LATCH_ON_ERROR * (latch - 1) = 0; + LATCH_ON_ERROR * (latch - 1) = 0; // No need to gate by `sel`, our tracegen never sets an error on an inactive row. // Based on the above, if sel_invalid_input_row_tag_err = 1, LATCH_CONDITION = 1. // If we latched BECAUSE sel_invalid_input_row_tag_err = 1, we set the propagated sel_invalid_input_tag_err = 1 diff --git a/barretenberg/cpp/pil/vm2/to_radix_mem.pil b/barretenberg/cpp/pil/vm2/to_radix_mem.pil index 71d8cd390df0..0c311c7cd3be 100644 --- a/barretenberg/cpp/pil/vm2/to_radix_mem.pil +++ b/barretenberg/cpp/pil/vm2/to_radix_mem.pil @@ -91,21 +91,20 @@ namespace to_radix_mem; // on the next row. #[START_AFTER_LAST] sel' * (start' - LATCH_CONDITION) = 0; - pol NOT_LAST = sel * (1 - LATCH_CONDITION); // Continuity checks - #[SEL_CONTINUITY] + #[TRACE_CONTINUITY] (1 - precomputed.first_row) * (1 - sel) * sel' = 0; #[EXEC_CLK_CONTINUITY] - NOT_LAST * (execution_clk' - execution_clk) = 0; + (1 - LATCH_CONDITION) * (execution_clk' - execution_clk) = 0; #[SPACE_ID_CONTINUITY] - NOT_LAST * (space_id' - space_id) = 0; + (1 - LATCH_CONDITION) * (space_id' - space_id) = 0; #[VALUE_CONTINUITY] - NOT_LAST * (value_to_decompose' - value_to_decompose) = 0; + (1 - LATCH_CONDITION) * (value_to_decompose' - value_to_decompose) = 0; #[RADIX_CONTINUITY] - NOT_LAST * (radix' - radix) = 0; + (1 - LATCH_CONDITION) * (radix' - radix) = 0; #[IS_OUTPUT_BITS_CONTINUITY] - NOT_LAST * (is_output_bits' - is_output_bits) = 0; + (1 - LATCH_CONDITION) * (is_output_bits' - is_output_bits) = 0; //////////////////////////////////////////////// // Error Handling - Out of Range Memory Access @@ -196,9 +195,9 @@ namespace to_radix_mem; // We can't inline input_validation_error because of the degree. start * ((1 - input_validation_error) * (1 - sel_num_limbs_is_zero) - sel_should_decompose) = 0; - // On following rows, we propagate input_validation_error. + // On the following rows, we propagate sel_should_decompose. #[SEL_SHOULD_DECOMPOSE_CONTINUITY] - NOT_LAST * (sel_should_decompose' - sel_should_decompose) = 0; + (1 - LATCH_CONDITION) * (sel_should_decompose' - sel_should_decompose) = 0; pol commit limb_index_to_lookup; // Need this since we want Big-Endian but the gadget is Little-Endian limb_index_to_lookup = sel_should_decompose * (num_limbs - 1); @@ -228,6 +227,7 @@ namespace to_radix_mem; ///////////////////////////////////////////////////// // Control flow management and terminating trace ///////////////////////////////////////////////////// + pol NOT_LAST = sel * (1 - LATCH_CONDITION); // As we process the results from to_radix, we decrement the num of limbs // and increment the dst address. #[DECR_NUM_LIMBS] @@ -242,7 +242,7 @@ namespace to_radix_mem; // Note: These conditions are not mutually exclusive. #[LAST_ROW_ERR_COMPUTATION] // last == 1 if err == 1 (can only occur on the start row) - start * err * (last - 1) = 0; + err * (last - 1) = 0; // The implication of the above condition is that LATCH_CONDITION = 1 if there is an error #[LAST_ROW_NUM_LIMBS_ZERO] // last == 1 if num_limbs == 0 (can only occur on the start row) @@ -250,7 +250,8 @@ namespace to_radix_mem; // Introduce a selector covering all active rows except the start row with an error or the start row // with num_limbs == 0. - pol NO_ERR_NOR_NUM_LIMBS_ZERO = start * (1 - err) * (1 - sel_num_limbs_is_zero) + (1 - start) * sel; // Error can only occur on the start row. + // start * (1 - err) = start - start * err = start - err (because err is defined with a factor `start`) + pol NO_ERR_NOR_NUM_LIMBS_ZERO = (start - err) * (1 - sel_num_limbs_is_zero) + (1 - start) * sel; // Error can only occur on the start row. pol NUM_LIMBS_MINUS_ONE = num_limbs - 1; pol commit num_limbs_minus_one_inv; @@ -266,7 +267,7 @@ namespace to_radix_mem; start * ((1 - err) * (1 - sel_num_limbs_is_zero) - sel_should_write_mem) = 0; // On following rows, we propagate sel_should_write_mem. #[SEL_SHOULD_WRITE_MEM_CONTINUITY] - NOT_LAST * (sel_should_write_mem' - sel_should_write_mem) = 0; + (1 - LATCH_CONDITION) * (sel_should_write_mem' - sel_should_write_mem) = 0; // Force sel_should_write_mem to 0 when sel is 0 (prevents ghost row injection attacks) #[SEL_SHOULD_WRITE_MEM_REQUIRES_SEL] sel_should_write_mem * (1 - sel) = 0; diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/to_radix.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/to_radix.test.cpp index f3f454269cc9..1947b318c0d7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/to_radix.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/to_radix.test.cpp @@ -1038,7 +1038,8 @@ TEST(ToRadixMemoryConstrainingTest, NegativeGhostRowMemoryWrite_RelationsOnly) // The fix: sel_should_write_mem * (1 - sel) = 0 // When sel=0 and sel_should_write_mem=1: 1 * (1-0) = 1 != 0 -> FAILS - EXPECT_THROW_WITH_MESSAGE(check_relation(trace), "SEL_SHOULD_WRITE_MEM_REQUIRES_SEL"); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, to_radix_mem::SR_SEL_SHOULD_WRITE_MEM_REQUIRES_SEL), + "SEL_SHOULD_WRITE_MEM_REQUIRES_SEL"); } // Test that the fix blocks ghost row injection attacks with full traces. diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp index 35fac1dd2840..06c0913ece08 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp @@ -8,10 +8,10 @@ namespace bb::avm2 { // clang-format off #define AVM2_PRECOMPUTED_ENTITIES_E(e) e precomputed_addressing_gas, e precomputed_bitwise_input_a, e precomputed_bitwise_input_b, e precomputed_bitwise_op_id, e precomputed_bitwise_output, e precomputed_clk, e precomputed_dyn_gas_id, e precomputed_envvar_pi_row_idx, e precomputed_exec_opcode, e precomputed_exec_opcode_base_da_gas, e precomputed_exec_opcode_dynamic_da_gas, e precomputed_exec_opcode_dynamic_l2_gas, e precomputed_exec_opcode_opcode_gas, e precomputed_expected_tag_reg_0_, e precomputed_expected_tag_reg_1_, e precomputed_expected_tag_reg_2_, e precomputed_expected_tag_reg_3_, e precomputed_expected_tag_reg_4_, e precomputed_expected_tag_reg_5_, e precomputed_first_row, e precomputed_instr_size, e precomputed_invalid_envvar_enum, e precomputed_is_address, e precomputed_is_class_id, e precomputed_is_cleanup, e precomputed_is_collect_fee, e precomputed_is_dagasleft, e precomputed_is_deployer, e precomputed_is_init_hash, e precomputed_is_isstaticcall, e precomputed_is_l2gasleft, e precomputed_is_public_call_request, e precomputed_is_revertible, e precomputed_is_sender, e precomputed_is_teardown, e precomputed_is_transactionfee, e precomputed_is_tree_padding, e precomputed_is_valid_member_enum, e precomputed_keccak_round_constant, e precomputed_next_phase_on_revert, e precomputed_opcode_out_of_range, e precomputed_out_tag, e precomputed_p_decomposition_limb, e precomputed_p_decomposition_limb_index, e precomputed_p_decomposition_radix, e precomputed_power_of_2, e precomputed_read_pi_length_offset, e precomputed_read_pi_start_offset, e precomputed_rw_reg_0_, e precomputed_rw_reg_1_, e precomputed_rw_reg_2_, e precomputed_rw_reg_3_, e precomputed_rw_reg_4_, e precomputed_rw_reg_5_, e precomputed_sel_addressing_gas, e precomputed_sel_bitwise, e precomputed_sel_envvar_pi_lookup_col0, e precomputed_sel_envvar_pi_lookup_col1, e precomputed_sel_exec_spec, e precomputed_sel_has_tag, e precomputed_sel_keccak, e precomputed_sel_mem_op_reg_0_, e precomputed_sel_mem_op_reg_1_, e precomputed_sel_mem_op_reg_2_, e precomputed_sel_mem_op_reg_3_, e precomputed_sel_mem_op_reg_4_, e precomputed_sel_mem_op_reg_5_, e precomputed_sel_mem_tag_out_of_range, e precomputed_sel_non_revertible_append_l2_l1_msg, e precomputed_sel_non_revertible_append_note_hash, e precomputed_sel_non_revertible_append_nullifier, e precomputed_sel_op_dc_0, e precomputed_sel_op_dc_1, e precomputed_sel_op_dc_10, e precomputed_sel_op_dc_11, e precomputed_sel_op_dc_12, e precomputed_sel_op_dc_13, e precomputed_sel_op_dc_14, e precomputed_sel_op_dc_15, e precomputed_sel_op_dc_16, e precomputed_sel_op_dc_17, e precomputed_sel_op_dc_2, e precomputed_sel_op_dc_3, e precomputed_sel_op_dc_4, e precomputed_sel_op_dc_5, e precomputed_sel_op_dc_6, e precomputed_sel_op_dc_7, e precomputed_sel_op_dc_8, e precomputed_sel_op_dc_9, e precomputed_sel_op_is_address_0_, e precomputed_sel_op_is_address_1_, e precomputed_sel_op_is_address_2_, e precomputed_sel_op_is_address_3_, e precomputed_sel_op_is_address_4_, e precomputed_sel_op_is_address_5_, e precomputed_sel_op_is_address_6_, e precomputed_sel_p_decomposition, e precomputed_sel_phase, e precomputed_sel_range_16, e precomputed_sel_range_8, e precomputed_sel_revertible_append_l2_l1_msg, e precomputed_sel_revertible_append_note_hash, e precomputed_sel_revertible_append_nullifier, e precomputed_sel_sha256_compression, e precomputed_sel_tag_check_reg_0_, e precomputed_sel_tag_check_reg_1_, e precomputed_sel_tag_check_reg_2_, e precomputed_sel_tag_check_reg_3_, e precomputed_sel_tag_check_reg_4_, e precomputed_sel_tag_check_reg_5_, e precomputed_sel_tag_is_op2, e precomputed_sel_tag_parameters, e precomputed_sel_to_radix_p_limb_counts, e precomputed_sha256_compression_round_constant, e precomputed_subtrace_id, e precomputed_subtrace_operation_id, e precomputed_tag_byte_length, e precomputed_tag_max_bits, e precomputed_tag_max_value, e precomputed_to_radix_num_limbs_for_p, e precomputed_to_radix_safe_limbs, e precomputed_zero, e public_inputs_sel -#define AVM2_WIRE_ENTITIES_E(e) e public_inputs_cols_0_, e public_inputs_cols_1_, e public_inputs_cols_2_, e public_inputs_cols_3_, e address_derivation_address, e address_derivation_address_y, e address_derivation_class_id, e address_derivation_const_five, e address_derivation_const_four, e address_derivation_const_three, e address_derivation_const_two, e address_derivation_deployer_addr, e address_derivation_g1_x, e address_derivation_g1_y, e address_derivation_incoming_viewing_key_x, e address_derivation_incoming_viewing_key_y, e address_derivation_init_hash, e address_derivation_nullifier_key_x, e address_derivation_nullifier_key_y, e address_derivation_outgoing_viewing_key_x, e address_derivation_outgoing_viewing_key_y, e address_derivation_partial_address, e address_derivation_partial_address_domain_separator, e address_derivation_preaddress, e address_derivation_preaddress_domain_separator, e address_derivation_preaddress_public_key_x, e address_derivation_preaddress_public_key_y, e address_derivation_public_keys_hash, e address_derivation_public_keys_hash_domain_separator, e address_derivation_salt, e address_derivation_salted_init_hash, e address_derivation_sel, e address_derivation_tagging_key_x, e address_derivation_tagging_key_y, e alu_a_hi, e alu_a_hi_bits, e alu_a_lo, e alu_a_lo_bits, e alu_ab_diff_inv, e alu_ab_tags_diff_inv, e alu_b_hi, e alu_b_inv, e alu_b_lo, e alu_c_hi, e alu_cf, e alu_constant_64, e alu_gt_input_a, e alu_gt_input_b, e alu_gt_result_c, e alu_helper1, e alu_ia, e alu_ia_tag, e alu_ib, e alu_ib_tag, e alu_ic, e alu_ic_tag, e alu_max_bits, e alu_max_value, e alu_mid, e alu_mid_bits, e alu_op_id, e alu_sel, e alu_sel_ab_tag_mismatch, e alu_sel_decompose_a, e alu_sel_div_0_err, e alu_sel_div_no_err, e alu_sel_err, e alu_sel_ff_gt, e alu_sel_int_gt, e alu_sel_is_ff, e alu_sel_is_u128, e alu_sel_mul_div_u128, e alu_sel_mul_no_err_non_ff, e alu_sel_op_add, e alu_sel_op_div, e alu_sel_op_eq, e alu_sel_op_fdiv, e alu_sel_op_lt, e alu_sel_op_lte, e alu_sel_op_mul, e alu_sel_op_not, e alu_sel_op_shl, e alu_sel_op_shr, e alu_sel_op_sub, e alu_sel_op_truncate, e alu_sel_shift_ops_no_overflow, e alu_sel_tag_err, e alu_sel_trunc_gte_128, e alu_sel_trunc_lt_128, e alu_sel_trunc_non_trivial, e alu_sel_trunc_trivial, e alu_shift_lo_bits, e alu_tag_ff_diff_inv, e alu_tag_u128_diff_inv, e alu_two_pow_shift_lo_bits, e bc_decomposition_bytes_pc_plus_36, e bc_decomposition_bytes_rem_inv, e bc_decomposition_bytes_rem_min_one_inv, e bc_decomposition_bytes_to_read, e bc_decomposition_is_windows_eq_remaining, e bc_decomposition_last_of_contract, e bc_decomposition_next_packed_pc_min_pc_inv, e bc_decomposition_packed_field, e bc_decomposition_sel_packed_read_0_, e bc_decomposition_sel_packed_read_1_, e bc_decomposition_sel_packed_read_2_, e bc_decomposition_windows_min_remaining_inv, e bc_hashing_input_len, e bc_hashing_latch, e bc_hashing_output_hash, e bc_hashing_packed_fields_0, e bc_hashing_packed_fields_1, e bc_hashing_packed_fields_2, e bc_hashing_pc_at_final_field, e bc_hashing_pc_index_1, e bc_hashing_pc_index_2, e bc_hashing_sel_not_padding_1, e bc_hashing_sel_not_padding_2, e bc_hashing_sel_not_start, e bc_retrieval_address, e bc_retrieval_artifact_hash, e bc_retrieval_bytecode_id, e bc_retrieval_current_class_id, e bc_retrieval_error, e bc_retrieval_instance_exists, e bc_retrieval_is_new_class, e bc_retrieval_next_retrieved_bytecodes_tree_root, e bc_retrieval_next_retrieved_bytecodes_tree_size, e bc_retrieval_no_remaining_bytecodes, e bc_retrieval_nullifier_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_size, e bc_retrieval_private_functions_root, e bc_retrieval_public_data_tree_root, e bc_retrieval_remaining_bytecodes_inv, e bc_retrieval_should_retrieve, e bitwise_ctr_inv, e bitwise_ctr_min_one_inv, e bitwise_err, e bitwise_ia_byte, e bitwise_ib_byte, e bitwise_ic_byte, e bitwise_last, e bitwise_sel, e bitwise_sel_get_ctr, e bitwise_sel_tag_ff_err, e bitwise_sel_tag_mismatch_err, e bitwise_start, e bitwise_start_keccak, e bitwise_start_sha256, e bitwise_tag_a, e bitwise_tag_a_inv, e bitwise_tag_ab_diff_inv, e bitwise_tag_b, e bitwise_tag_c, e calldata_diff_context_id, e calldata_hashing_index_1_, e calldata_hashing_index_2_, e calldata_hashing_input_0_, e calldata_hashing_input_1_, e calldata_hashing_input_2_, e calldata_hashing_input_len, e calldata_hashing_latch, e calldata_hashing_sel_not_padding_1, e calldata_hashing_sel_not_padding_2, e calldata_hashing_sel_not_start, e calldata_latch, e calldata_value, e class_id_derivation_artifact_hash, e class_id_derivation_class_id, e class_id_derivation_const_two, e class_id_derivation_gen_index_contract_class_id, e class_id_derivation_private_functions_root, e class_id_derivation_public_bytecode_commitment, e class_id_derivation_sel, e context_stack_bytecode_id, e context_stack_context_id, e context_stack_contract_address, e context_stack_entered_context_id, e context_stack_is_static, e context_stack_msg_sender, e context_stack_next_pc, e context_stack_note_hash_tree_root, e context_stack_note_hash_tree_size, e context_stack_nullifier_tree_root, e context_stack_nullifier_tree_size, e context_stack_num_l2_to_l1_messages, e context_stack_num_note_hashes_emitted, e context_stack_num_nullifiers_emitted, e context_stack_num_unencrypted_log_fields, e context_stack_parent_calldata_addr, e context_stack_parent_calldata_size, e context_stack_parent_da_gas_limit, e context_stack_parent_da_gas_used, e context_stack_parent_id, e context_stack_parent_l2_gas_limit, e context_stack_parent_l2_gas_used, e context_stack_public_data_tree_root, e context_stack_public_data_tree_size, e context_stack_sel, e context_stack_written_public_data_slots_tree_root, e context_stack_written_public_data_slots_tree_size, e contract_instance_retrieval_address, e contract_instance_retrieval_address_sub_one, e contract_instance_retrieval_current_class_id, e contract_instance_retrieval_deployer_addr, e contract_instance_retrieval_deployer_protocol_contract_address, e contract_instance_retrieval_derived_address, e contract_instance_retrieval_derived_address_pi_index, e contract_instance_retrieval_exists, e contract_instance_retrieval_incoming_viewing_key_x, e contract_instance_retrieval_incoming_viewing_key_y, e contract_instance_retrieval_init_hash, e contract_instance_retrieval_is_protocol_contract, e contract_instance_retrieval_max_protocol_contracts, e contract_instance_retrieval_nullifier_key_x, e contract_instance_retrieval_nullifier_key_y, e contract_instance_retrieval_nullifier_tree_root, e contract_instance_retrieval_original_class_id, e contract_instance_retrieval_outgoing_viewing_key_x, e contract_instance_retrieval_outgoing_viewing_key_y, e contract_instance_retrieval_protocol_contract_derived_address_inv, e contract_instance_retrieval_public_data_tree_root, e contract_instance_retrieval_salt, e contract_instance_retrieval_sel, e contract_instance_retrieval_should_check_for_update, e contract_instance_retrieval_should_check_nullifier, e contract_instance_retrieval_tagging_key_x, e contract_instance_retrieval_tagging_key_y, e data_copy_cd_copy_col_read, e data_copy_data_index_upper_bound, e data_copy_data_index_upper_bound_gt_offset, e data_copy_dst_out_of_range_err, e data_copy_err, e data_copy_is_top_level, e data_copy_mem_size, e data_copy_offset, e data_copy_offset_plus_size, e data_copy_offset_plus_size_is_gt, e data_copy_parent_id_inv, e data_copy_read_addr_plus_one, e data_copy_read_addr_upper_bound, e data_copy_reads_left_inv, e data_copy_sel_cd_copy_start, e data_copy_sel_end, e data_copy_sel_mem_read, e data_copy_sel_mem_write, e data_copy_sel_rd_copy_start, e data_copy_sel_start_no_err, e data_copy_sel_write_count_is_zero, e data_copy_src_addr, e data_copy_src_data_size, e data_copy_src_out_of_range_err, e data_copy_tag, e data_copy_value, e data_copy_write_addr_upper_bound, e data_copy_write_count_minus_one_inv, e data_copy_write_count_zero_inv, e ecc_add_mem_dst_addr_0_, e ecc_add_mem_dst_addr_1_, e ecc_add_mem_dst_addr_2_, e ecc_add_mem_err, e ecc_add_mem_execution_clk, e ecc_add_mem_max_mem_addr, e ecc_add_mem_p_is_inf, e ecc_add_mem_p_is_on_curve_eqn, e ecc_add_mem_p_is_on_curve_eqn_inv, e ecc_add_mem_p_x, e ecc_add_mem_p_x_n, e ecc_add_mem_p_y, e ecc_add_mem_p_y_n, e ecc_add_mem_q_is_inf, e ecc_add_mem_q_is_on_curve_eqn, e ecc_add_mem_q_is_on_curve_eqn_inv, e ecc_add_mem_q_x, e ecc_add_mem_q_x_n, e ecc_add_mem_q_y, e ecc_add_mem_q_y_n, e ecc_add_mem_res_is_inf, e ecc_add_mem_res_x, e ecc_add_mem_res_y, e ecc_add_mem_sel, e ecc_add_mem_sel_dst_out_of_range_err, e ecc_add_mem_sel_p_not_on_curve_err, e ecc_add_mem_sel_q_not_on_curve_err, e ecc_add_mem_sel_should_exec, e ecc_add_mem_space_id, e ecc_add_op, e ecc_double_op, e ecc_inv_2_p_y, e ecc_inv_x_diff, e ecc_inv_y_diff, e ecc_lambda, e ecc_p_is_inf, e ecc_p_x, e ecc_p_y, e ecc_q_is_inf, e ecc_q_x, e ecc_q_y, e ecc_r_is_inf, e ecc_r_x, e ecc_r_y, e ecc_result_infinity, e ecc_sel, e ecc_use_computed_result, e ecc_x_match, e ecc_y_match, e emit_unencrypted_log_discard, e emit_unencrypted_log_end, e emit_unencrypted_log_end_log_address_upper_bound, e emit_unencrypted_log_error, e emit_unencrypted_log_error_too_many_log_fields, e emit_unencrypted_log_error_too_many_logs_wrong_tag_is_static, e emit_unencrypted_log_expected_next_log_fields, e emit_unencrypted_log_is_static, e emit_unencrypted_log_log_size, e emit_unencrypted_log_max_mem_size, e emit_unencrypted_log_next_num_unencrypted_log_fields, e emit_unencrypted_log_prev_num_unencrypted_log_fields, e emit_unencrypted_log_public_inputs_value, e emit_unencrypted_log_public_logs_payload_length, e emit_unencrypted_log_remaining_rows_inv, e emit_unencrypted_log_sel_should_read_memory, e emit_unencrypted_log_tag, e emit_unencrypted_log_tag_inv, e emit_unencrypted_log_value, e execution_addressing_error_collection_inv, e execution_addressing_gas, e execution_addressing_mode, e execution_base_address_tag, e execution_base_address_tag_diff_inv, e execution_base_address_val, e execution_base_da_gas, e execution_batched_tags_diff_inv, e execution_batched_tags_diff_inv_reg, e execution_da_gas_left, e execution_da_gas_used, e execution_dying_context_diff_inv, e execution_dying_context_id_inv, e execution_dyn_gas_id, e execution_dynamic_da_gas, e execution_dynamic_da_gas_factor, e execution_dynamic_l2_gas, e execution_dynamic_l2_gas_factor, e execution_enqueued_call_end, e execution_envvar_pi_row_idx, e execution_ex_opcode, e execution_expected_tag_reg_0_, e execution_expected_tag_reg_1_, e execution_expected_tag_reg_2_, e execution_expected_tag_reg_3_, e execution_expected_tag_reg_4_, e execution_expected_tag_reg_5_, e execution_has_parent_ctx, e execution_highest_address, e execution_instr_length, e execution_internal_call_return_id_inv, e execution_is_address, e execution_is_da_gas_left_gt_allocated, e execution_is_dagasleft, e execution_is_dying_context, e execution_is_isstaticcall, e execution_is_l2_gas_left_gt_allocated, e execution_is_l2gasleft, e execution_is_parent_id_inv, e execution_is_sender, e execution_is_transactionfee, e execution_l1_to_l2_msg_leaf_in_range, e execution_l1_to_l2_msg_tree_leaf_count, e execution_l2_gas_left, e execution_l2_gas_used, e execution_max_data_writes_reached, e execution_mem_tag_reg_0_, e execution_mem_tag_reg_1_, e execution_mem_tag_reg_2_, e execution_mem_tag_reg_3_, e execution_mem_tag_reg_4_, e execution_mem_tag_reg_5_, e execution_nested_failure, e execution_nested_return, e execution_next_pc, e execution_note_hash_leaf_in_range, e execution_note_hash_tree_leaf_count, e execution_note_hash_tree_root, e execution_note_hash_tree_size, e execution_nullifier_tree_root, e execution_nullifier_tree_size, e execution_num_l2_to_l1_messages, e execution_num_note_hashes_emitted, e execution_num_nullifiers_emitted, e execution_num_p_limbs, e execution_num_relative_operands_inv, e execution_num_unencrypted_log_fields, e execution_op_0_, e execution_op_1_, e execution_op_2_, e execution_op_3_, e execution_op_4_, e execution_op_5_, e execution_op_6_, e execution_op_after_relative_0_, e execution_op_after_relative_1_, e execution_op_after_relative_2_, e execution_op_after_relative_3_, e execution_op_after_relative_4_, e execution_op_after_relative_5_, e execution_op_after_relative_6_, e execution_opcode_gas, e execution_out_of_gas_da, e execution_out_of_gas_l2, e execution_public_data_tree_root, e execution_public_data_tree_size, e execution_public_inputs_index, e execution_register_0_, e execution_register_1_, e execution_register_2_, e execution_register_3_, e execution_register_4_, e execution_register_5_, e execution_remaining_data_writes_inv, e execution_remaining_l2_to_l1_msgs_inv, e execution_remaining_note_hashes_inv, e execution_remaining_nullifiers_inv, e execution_retrieved_bytecodes_tree_root, e execution_retrieved_bytecodes_tree_size, e execution_rop_0_, e execution_rop_1_, e execution_rop_2_, e execution_rop_3_, e execution_rop_4_, e execution_rop_5_, e execution_rop_6_, e execution_rop_tag_0_, e execution_rop_tag_1_, e execution_rop_tag_2_, e execution_rop_tag_3_, e execution_rop_tag_4_, e execution_rop_tag_5_, e execution_rop_tag_6_, e execution_rw_reg_0_, e execution_rw_reg_1_, e execution_rw_reg_2_, e execution_rw_reg_3_, e execution_rw_reg_4_, e execution_rw_reg_5_, e execution_sel_addressing_error, e execution_sel_base_address_failure, e execution_sel_bytecode_retrieval_failure, e execution_sel_bytecode_retrieval_success, e execution_sel_do_base_check, e execution_sel_enter_call, e execution_sel_envvar_pi_lookup_col0, e execution_sel_envvar_pi_lookup_col1, e execution_sel_error, e execution_sel_exec_dispatch_alu, e execution_sel_exec_dispatch_bitwise, e execution_sel_exec_dispatch_calldata_copy, e execution_sel_exec_dispatch_cast, e execution_sel_exec_dispatch_ecc_add, e execution_sel_exec_dispatch_emit_unencrypted_log, e execution_sel_exec_dispatch_execution, e execution_sel_exec_dispatch_get_contract_instance, e execution_sel_exec_dispatch_keccakf1600, e execution_sel_exec_dispatch_poseidon2_perm, e execution_sel_exec_dispatch_returndata_copy, e execution_sel_exec_dispatch_set, e execution_sel_exec_dispatch_sha256_compression, e execution_sel_exec_dispatch_to_radix, e execution_sel_execute_call, e execution_sel_execute_debug_log, e execution_sel_execute_emit_notehash, e execution_sel_execute_emit_nullifier, e execution_sel_execute_get_env_var, e execution_sel_execute_internal_call, e execution_sel_execute_internal_return, e execution_sel_execute_jump, e execution_sel_execute_jumpi, e execution_sel_execute_l1_to_l2_message_exists, e execution_sel_execute_mov, e execution_sel_execute_notehash_exists, e execution_sel_execute_nullifier_exists, e execution_sel_execute_return, e execution_sel_execute_returndata_size, e execution_sel_execute_revert, e execution_sel_execute_send_l2_to_l1_msg, e execution_sel_execute_sload, e execution_sel_execute_sstore, e execution_sel_execute_static_call, e execution_sel_execute_success_copy, e execution_sel_exit_call, e execution_sel_failure, e execution_sel_gas_bitwise, e execution_sel_gas_calldata_copy, e execution_sel_gas_emit_unencrypted_log, e execution_sel_gas_returndata_copy, e execution_sel_gas_sstore, e execution_sel_gas_to_radix, e execution_sel_instruction_fetching_failure, e execution_sel_instruction_fetching_success, e execution_sel_l2_to_l1_msg_limit_error, e execution_sel_lookup_num_p_limbs, e execution_sel_mem_op_reg_0_, e execution_sel_mem_op_reg_1_, e execution_sel_mem_op_reg_2_, e execution_sel_mem_op_reg_3_, e execution_sel_mem_op_reg_4_, e execution_sel_mem_op_reg_5_, e execution_sel_op_do_overflow_check_0_, e execution_sel_op_do_overflow_check_1_, e execution_sel_op_do_overflow_check_2_, e execution_sel_op_do_overflow_check_3_, e execution_sel_op_do_overflow_check_4_, e execution_sel_op_do_overflow_check_5_, e execution_sel_op_do_overflow_check_6_, e execution_sel_op_is_address_0_, e execution_sel_op_is_address_1_, e execution_sel_op_is_address_2_, e execution_sel_op_is_address_3_, e execution_sel_op_is_address_4_, e execution_sel_op_is_address_5_, e execution_sel_op_is_address_6_, e execution_sel_op_is_indirect_wire_0_, e execution_sel_op_is_indirect_wire_1_, e execution_sel_op_is_indirect_wire_2_, e execution_sel_op_is_indirect_wire_3_, e execution_sel_op_is_indirect_wire_4_, e execution_sel_op_is_indirect_wire_5_, e execution_sel_op_is_indirect_wire_6_, e execution_sel_op_is_indirect_wire_7_, e execution_sel_op_is_relative_wire_0_, e execution_sel_op_is_relative_wire_1_, e execution_sel_op_is_relative_wire_2_, e execution_sel_op_is_relative_wire_3_, e execution_sel_op_is_relative_wire_4_, e execution_sel_op_is_relative_wire_5_, e execution_sel_op_is_relative_wire_6_, e execution_sel_op_is_relative_wire_7_, e execution_sel_op_reg_effective_0_, e execution_sel_op_reg_effective_1_, e execution_sel_op_reg_effective_2_, e execution_sel_op_reg_effective_3_, e execution_sel_op_reg_effective_4_, e execution_sel_op_reg_effective_5_, e execution_sel_opcode_error, e execution_sel_out_of_gas, e execution_sel_radix_gt_256, e execution_sel_reached_max_note_hashes, e execution_sel_reached_max_nullifiers, e execution_sel_read_unwind_call_stack, e execution_sel_register_read_error, e execution_sel_relative_overflow_0_, e execution_sel_relative_overflow_1_, e execution_sel_relative_overflow_2_, e execution_sel_relative_overflow_3_, e execution_sel_relative_overflow_4_, e execution_sel_relative_overflow_5_, e execution_sel_relative_overflow_6_, e execution_sel_should_apply_indirection_0_, e execution_sel_should_apply_indirection_1_, e execution_sel_should_apply_indirection_2_, e execution_sel_should_apply_indirection_3_, e execution_sel_should_apply_indirection_4_, e execution_sel_should_apply_indirection_5_, e execution_sel_should_apply_indirection_6_, e execution_sel_should_check_gas, e execution_sel_should_execute_opcode, e execution_sel_should_read_registers, e execution_sel_should_write_registers, e execution_sel_some_final_check_failed, e execution_sel_tag_check_reg_0_, e execution_sel_tag_check_reg_1_, e execution_sel_tag_check_reg_2_, e execution_sel_tag_check_reg_3_, e execution_sel_tag_check_reg_4_, e execution_sel_tag_check_reg_5_, e execution_sel_use_num_limbs, e execution_sel_write_l2_to_l1_msg, e execution_sel_write_note_hash, e execution_sel_write_nullifier, e execution_sel_write_public_data, e execution_subtrace_id, e execution_subtrace_operation_id, e execution_total_gas_da, e execution_total_gas_l2, e execution_two_five_six, e execution_value_from_pi, e execution_written_public_data_slots_tree_root, e execution_written_public_data_slots_tree_size, e ff_gt_a, e ff_gt_b, e ff_gt_borrow, e ff_gt_cmp_rng_ctr_inv, e ff_gt_constant_128, e ff_gt_p_a_borrow, e ff_gt_p_b_borrow, e ff_gt_res_hi, e ff_gt_res_lo, e ff_gt_result, e ff_gt_sel_shift_rng, e get_contract_instance_clk, e get_contract_instance_contract_address, e get_contract_instance_dst_offset, e get_contract_instance_dst_offset_diff_max_inv, e get_contract_instance_exists_tag, e get_contract_instance_instance_exists, e get_contract_instance_is_class_id, e get_contract_instance_is_deployer, e get_contract_instance_is_init_hash, e get_contract_instance_is_valid_member_enum, e get_contract_instance_is_valid_writes_in_bounds, e get_contract_instance_member_enum, e get_contract_instance_member_tag, e get_contract_instance_member_write_offset, e get_contract_instance_nullifier_tree_root, e get_contract_instance_public_data_tree_root, e get_contract_instance_retrieved_class_id, e get_contract_instance_retrieved_deployer_addr, e get_contract_instance_retrieved_init_hash, e get_contract_instance_sel, e get_contract_instance_sel_error, e get_contract_instance_selected_member, e get_contract_instance_space_id, e gt_abs_diff, e gt_input_a, e gt_input_b, e gt_num_bits, e gt_res, e gt_sel, e gt_sel_addressing, e gt_sel_alu, e gt_sel_gas, e gt_sel_others, e gt_sel_sha256, e instr_fetching_addressing_mode, e instr_fetching_bd0, e instr_fetching_bd1, e instr_fetching_bd10, e instr_fetching_bd11, e instr_fetching_bd12, e instr_fetching_bd13, e instr_fetching_bd14, e instr_fetching_bd15, e instr_fetching_bd16, e instr_fetching_bd17, e instr_fetching_bd18, e instr_fetching_bd19, e instr_fetching_bd2, e instr_fetching_bd20, e instr_fetching_bd21, e instr_fetching_bd22, e instr_fetching_bd23, e instr_fetching_bd24, e instr_fetching_bd25, e instr_fetching_bd26, e instr_fetching_bd27, e instr_fetching_bd28, e instr_fetching_bd29, e instr_fetching_bd3, e instr_fetching_bd30, e instr_fetching_bd31, e instr_fetching_bd32, e instr_fetching_bd33, e instr_fetching_bd34, e instr_fetching_bd35, e instr_fetching_bd36, e instr_fetching_bd4, e instr_fetching_bd5, e instr_fetching_bd6, e instr_fetching_bd7, e instr_fetching_bd8, e instr_fetching_bd9, e instr_fetching_bytecode_id, e instr_fetching_bytecode_size, e instr_fetching_bytes_to_read, e instr_fetching_exec_opcode, e instr_fetching_instr_abs_diff, e instr_fetching_instr_out_of_range, e instr_fetching_instr_size, e instr_fetching_op1, e instr_fetching_op2, e instr_fetching_op3, e instr_fetching_op4, e instr_fetching_op5, e instr_fetching_op6, e instr_fetching_op7, e instr_fetching_opcode_out_of_range, e instr_fetching_pc, e instr_fetching_pc_abs_diff, e instr_fetching_pc_out_of_range, e instr_fetching_pc_size_in_bits, e instr_fetching_sel, e instr_fetching_sel_has_tag, e instr_fetching_sel_op_dc_0, e instr_fetching_sel_op_dc_1, e instr_fetching_sel_op_dc_10, e instr_fetching_sel_op_dc_11, e instr_fetching_sel_op_dc_12, e instr_fetching_sel_op_dc_13, e instr_fetching_sel_op_dc_14, e instr_fetching_sel_op_dc_15, e instr_fetching_sel_op_dc_16, e instr_fetching_sel_op_dc_2, e instr_fetching_sel_op_dc_3, e instr_fetching_sel_op_dc_4, e instr_fetching_sel_op_dc_5, e instr_fetching_sel_op_dc_6, e instr_fetching_sel_op_dc_7, e instr_fetching_sel_op_dc_8, e instr_fetching_sel_op_dc_9, e instr_fetching_sel_parsing_err, e instr_fetching_sel_pc_in_range, e instr_fetching_sel_tag_is_op2, e instr_fetching_tag_out_of_range, e instr_fetching_tag_value, e internal_call_stack_context_id, e internal_call_stack_entered_call_id, e internal_call_stack_id, e internal_call_stack_return_id, e internal_call_stack_return_pc, e internal_call_stack_sel, e keccak_memory_ctr_end, e keccak_memory_ctr_inv, e keccak_memory_last, e keccak_memory_num_rounds, e keccak_memory_sel, e keccak_memory_single_tag_error, e keccak_memory_start_read, e keccak_memory_start_write, e keccak_memory_state_size_min_ctr_inv, e keccak_memory_tag, e keccak_memory_tag_min_u64_inv, e keccak_memory_val_24_, e keccakf1600_bitwise_and_op_id, e keccakf1600_bitwise_xor_op_id, e keccakf1600_dst_out_of_range_error, e keccakf1600_error, e keccakf1600_highest_slice_address, e keccakf1600_last, e keccakf1600_rot_64_min_len_01, e keccakf1600_rot_64_min_len_03, e keccakf1600_rot_64_min_len_11, e keccakf1600_rot_64_min_len_13, e keccakf1600_rot_64_min_len_20, e keccakf1600_rot_64_min_len_22, e keccakf1600_rot_64_min_len_24, e keccakf1600_rot_64_min_len_31, e keccakf1600_rot_64_min_len_34, e keccakf1600_rot_64_min_len_42, e keccakf1600_rot_len_02, e keccakf1600_rot_len_04, e keccakf1600_rot_len_10, e keccakf1600_rot_len_12, e keccakf1600_rot_len_14, e keccakf1600_rot_len_21, e keccakf1600_rot_len_23, e keccakf1600_rot_len_30, e keccakf1600_rot_len_32, e keccakf1600_rot_len_33, e keccakf1600_rot_len_40, e keccakf1600_rot_len_41, e keccakf1600_rot_len_43, e keccakf1600_rot_len_44, e keccakf1600_round_cst, e keccakf1600_round_inv, e keccakf1600_sel, e keccakf1600_sel_slice_read, e keccakf1600_sel_slice_write, e keccakf1600_src_addr, e keccakf1600_src_out_of_range_error, e keccakf1600_start, e keccakf1600_state_chi_00, e keccakf1600_state_chi_01, e keccakf1600_state_chi_02, e keccakf1600_state_chi_03, e keccakf1600_state_chi_04, e keccakf1600_state_chi_10, e keccakf1600_state_chi_11, e keccakf1600_state_chi_12, e keccakf1600_state_chi_13, e keccakf1600_state_chi_14, e keccakf1600_state_chi_20, e keccakf1600_state_chi_21, e keccakf1600_state_chi_22, e keccakf1600_state_chi_23, e keccakf1600_state_chi_24, e keccakf1600_state_chi_30, e keccakf1600_state_chi_31, e keccakf1600_state_chi_32, e keccakf1600_state_chi_33, e keccakf1600_state_chi_34, e keccakf1600_state_chi_40, e keccakf1600_state_chi_41, e keccakf1600_state_chi_42, e keccakf1600_state_chi_43, e keccakf1600_state_chi_44, e keccakf1600_state_iota_00, e keccakf1600_state_pi_and_00, e keccakf1600_state_pi_and_01, e keccakf1600_state_pi_and_02, e keccakf1600_state_pi_and_03, e keccakf1600_state_pi_and_04, e keccakf1600_state_pi_and_10, e keccakf1600_state_pi_and_11, e keccakf1600_state_pi_and_12, e keccakf1600_state_pi_and_13, e keccakf1600_state_pi_and_14, e keccakf1600_state_pi_and_20, e keccakf1600_state_pi_and_21, e keccakf1600_state_pi_and_22, e keccakf1600_state_pi_and_23, e keccakf1600_state_pi_and_24, e keccakf1600_state_pi_and_30, e keccakf1600_state_pi_and_31, e keccakf1600_state_pi_and_32, e keccakf1600_state_pi_and_33, e keccakf1600_state_pi_and_34, e keccakf1600_state_pi_and_40, e keccakf1600_state_pi_and_41, e keccakf1600_state_pi_and_42, e keccakf1600_state_pi_and_43, e keccakf1600_state_pi_and_44, e keccakf1600_state_pi_not_00, e keccakf1600_state_pi_not_01, e keccakf1600_state_pi_not_02, e keccakf1600_state_pi_not_03, e keccakf1600_state_pi_not_04, e keccakf1600_state_pi_not_10, e keccakf1600_state_pi_not_11, e keccakf1600_state_pi_not_12, e keccakf1600_state_pi_not_13, e keccakf1600_state_pi_not_14, e keccakf1600_state_pi_not_20, e keccakf1600_state_pi_not_21, e keccakf1600_state_pi_not_22, e keccakf1600_state_pi_not_23, e keccakf1600_state_pi_not_24, e keccakf1600_state_pi_not_30, e keccakf1600_state_pi_not_31, e keccakf1600_state_pi_not_32, e keccakf1600_state_pi_not_33, e keccakf1600_state_pi_not_34, e keccakf1600_state_pi_not_40, e keccakf1600_state_pi_not_41, e keccakf1600_state_pi_not_42, e keccakf1600_state_pi_not_43, e keccakf1600_state_pi_not_44, e keccakf1600_state_rho_01, e keccakf1600_state_rho_02, e keccakf1600_state_rho_03, e keccakf1600_state_rho_04, e keccakf1600_state_rho_10, e keccakf1600_state_rho_11, e keccakf1600_state_rho_12, e keccakf1600_state_rho_13, e keccakf1600_state_rho_14, e keccakf1600_state_rho_20, e keccakf1600_state_rho_21, e keccakf1600_state_rho_22, e keccakf1600_state_rho_23, e keccakf1600_state_rho_24, e keccakf1600_state_rho_30, e keccakf1600_state_rho_31, e keccakf1600_state_rho_32, e keccakf1600_state_rho_33, e keccakf1600_state_rho_34, e keccakf1600_state_rho_40, e keccakf1600_state_rho_41, e keccakf1600_state_rho_42, e keccakf1600_state_rho_43, e keccakf1600_state_rho_44, e keccakf1600_state_theta_00, e keccakf1600_state_theta_01, e keccakf1600_state_theta_02, e keccakf1600_state_theta_03, e keccakf1600_state_theta_04, e keccakf1600_state_theta_10, e keccakf1600_state_theta_11, e keccakf1600_state_theta_12, e keccakf1600_state_theta_13, e keccakf1600_state_theta_14, e keccakf1600_state_theta_20, e keccakf1600_state_theta_21, e keccakf1600_state_theta_22, e keccakf1600_state_theta_23, e keccakf1600_state_theta_24, e keccakf1600_state_theta_30, e keccakf1600_state_theta_31, e keccakf1600_state_theta_32, e keccakf1600_state_theta_33, e keccakf1600_state_theta_34, e keccakf1600_state_theta_40, e keccakf1600_state_theta_41, e keccakf1600_state_theta_42, e keccakf1600_state_theta_43, e keccakf1600_state_theta_44, e keccakf1600_state_theta_hi_01, e keccakf1600_state_theta_hi_02, e keccakf1600_state_theta_hi_03, e keccakf1600_state_theta_hi_04, e keccakf1600_state_theta_hi_10, e keccakf1600_state_theta_hi_11, e keccakf1600_state_theta_hi_12, e keccakf1600_state_theta_hi_13, e keccakf1600_state_theta_hi_14, e keccakf1600_state_theta_hi_20, e keccakf1600_state_theta_hi_21, e keccakf1600_state_theta_hi_22, e keccakf1600_state_theta_hi_23, e keccakf1600_state_theta_hi_24, e keccakf1600_state_theta_hi_30, e keccakf1600_state_theta_hi_31, e keccakf1600_state_theta_hi_32, e keccakf1600_state_theta_hi_33, e keccakf1600_state_theta_hi_34, e keccakf1600_state_theta_hi_40, e keccakf1600_state_theta_hi_41, e keccakf1600_state_theta_hi_42, e keccakf1600_state_theta_hi_43, e keccakf1600_state_theta_hi_44, e keccakf1600_state_theta_low_01, e keccakf1600_state_theta_low_02, e keccakf1600_state_theta_low_03, e keccakf1600_state_theta_low_04, e keccakf1600_state_theta_low_10, e keccakf1600_state_theta_low_11, e keccakf1600_state_theta_low_12, e keccakf1600_state_theta_low_13, e keccakf1600_state_theta_low_14, e keccakf1600_state_theta_low_20, e keccakf1600_state_theta_low_21, e keccakf1600_state_theta_low_22, e keccakf1600_state_theta_low_23, e keccakf1600_state_theta_low_24, e keccakf1600_state_theta_low_30, e keccakf1600_state_theta_low_31, e keccakf1600_state_theta_low_32, e keccakf1600_state_theta_low_33, e keccakf1600_state_theta_low_34, e keccakf1600_state_theta_low_40, e keccakf1600_state_theta_low_41, e keccakf1600_state_theta_low_42, e keccakf1600_state_theta_low_43, e keccakf1600_state_theta_low_44, e keccakf1600_tag_error, e keccakf1600_tag_u64, e keccakf1600_theta_combined_xor_0, e keccakf1600_theta_combined_xor_1, e keccakf1600_theta_combined_xor_2, e keccakf1600_theta_combined_xor_3, e keccakf1600_theta_combined_xor_4, e keccakf1600_theta_xor_01, e keccakf1600_theta_xor_02, e keccakf1600_theta_xor_03, e keccakf1600_theta_xor_11, e keccakf1600_theta_xor_12, e keccakf1600_theta_xor_13, e keccakf1600_theta_xor_21, e keccakf1600_theta_xor_22, e keccakf1600_theta_xor_23, e keccakf1600_theta_xor_31, e keccakf1600_theta_xor_32, e keccakf1600_theta_xor_33, e keccakf1600_theta_xor_41, e keccakf1600_theta_xor_42, e keccakf1600_theta_xor_43, e keccakf1600_theta_xor_row_0, e keccakf1600_theta_xor_row_1, e keccakf1600_theta_xor_row_2, e keccakf1600_theta_xor_row_3, e keccakf1600_theta_xor_row_4, e keccakf1600_theta_xor_row_low63_0, e keccakf1600_theta_xor_row_low63_1, e keccakf1600_theta_xor_row_low63_2, e keccakf1600_theta_xor_row_low63_3, e keccakf1600_theta_xor_row_low63_4, e keccakf1600_theta_xor_row_msb_0, e keccakf1600_theta_xor_row_msb_1, e keccakf1600_theta_xor_row_msb_2, e keccakf1600_theta_xor_row_msb_3, e keccakf1600_theta_xor_row_msb_4, e keccakf1600_theta_xor_row_rotl1_0, e keccakf1600_theta_xor_row_rotl1_1, e keccakf1600_theta_xor_row_rotl1_2, e keccakf1600_theta_xor_row_rotl1_3, e keccakf1600_theta_xor_row_rotl1_4, e l1_to_l2_message_tree_check_exists, e l1_to_l2_message_tree_check_l1_to_l2_message_tree_height, e l1_to_l2_message_tree_check_leaf_index, e l1_to_l2_message_tree_check_leaf_value, e l1_to_l2_message_tree_check_leaf_value_msg_hash_diff_inv, e l1_to_l2_message_tree_check_msg_hash, e l1_to_l2_message_tree_check_root, e l1_to_l2_message_tree_check_sel, e memory_address, e memory_clk, e memory_diff, e memory_glob_addr_diff_inv, e memory_last_access, e memory_limb_0_, e memory_limb_1_, e memory_limb_2_, e memory_max_bits, e memory_sel_addressing_base, e memory_sel_addressing_indirect_0_, e memory_sel_addressing_indirect_1_, e memory_sel_addressing_indirect_2_, e memory_sel_addressing_indirect_3_, e memory_sel_addressing_indirect_4_, e memory_sel_addressing_indirect_5_, e memory_sel_addressing_indirect_6_, e memory_sel_data_copy_read, e memory_sel_data_copy_write, e memory_sel_ecc_write_0_, e memory_sel_ecc_write_1_, e memory_sel_ecc_write_2_, e memory_sel_get_contract_instance_exists_write, e memory_sel_get_contract_instance_member_write, e memory_sel_keccak, e memory_sel_poseidon2_read_0_, e memory_sel_poseidon2_read_1_, e memory_sel_poseidon2_read_2_, e memory_sel_poseidon2_read_3_, e memory_sel_poseidon2_write_0_, e memory_sel_poseidon2_write_1_, e memory_sel_poseidon2_write_2_, e memory_sel_poseidon2_write_3_, e memory_sel_register_op_0_, e memory_sel_register_op_1_, e memory_sel_register_op_2_, e memory_sel_register_op_3_, e memory_sel_register_op_4_, e memory_sel_register_op_5_, e memory_sel_rng_chk, e memory_sel_rng_write, e memory_sel_sha256_op_0_, e memory_sel_sha256_op_1_, e memory_sel_sha256_op_2_, e memory_sel_sha256_op_3_, e memory_sel_sha256_op_4_, e memory_sel_sha256_op_5_, e memory_sel_sha256_op_6_, e memory_sel_sha256_op_7_, e memory_sel_sha256_read, e memory_sel_tag_is_ff, e memory_sel_to_radix_write, e memory_sel_unencrypted_log_read, e memory_space_id, e memory_tag_ff_diff_inv, e merkle_check_end, e merkle_check_index_is_even, e merkle_check_path_len_min_one_inv, e merkle_check_read_left_node, e merkle_check_read_output_hash, e merkle_check_read_right_node, e merkle_check_sibling, e merkle_check_start, e merkle_check_write_left_node, e merkle_check_write_output_hash, e merkle_check_write_right_node, e note_hash_tree_check_address, e note_hash_tree_check_discard, e note_hash_tree_check_exists, e note_hash_tree_check_first_nullifier, e note_hash_tree_check_first_nullifier_pi_index, e note_hash_tree_check_leaf_index, e note_hash_tree_check_next_leaf_value, e note_hash_tree_check_next_root, e note_hash_tree_check_nonce, e note_hash_tree_check_nonce_separator, e note_hash_tree_check_note_hash, e note_hash_tree_check_note_hash_index, e note_hash_tree_check_note_hash_tree_height, e note_hash_tree_check_prev_leaf_value, e note_hash_tree_check_prev_leaf_value_unique_note_hash_diff_inv, e note_hash_tree_check_prev_root, e note_hash_tree_check_public_inputs_index, e note_hash_tree_check_sel, e note_hash_tree_check_should_silo, e note_hash_tree_check_should_unique, e note_hash_tree_check_should_write_to_public_inputs, e note_hash_tree_check_siloed_note_hash, e note_hash_tree_check_siloing_separator, e note_hash_tree_check_unique_note_hash, e note_hash_tree_check_unique_note_hash_separator, e note_hash_tree_check_write, e nullifier_check_address, e nullifier_check_discard, e nullifier_check_exists, e nullifier_check_intermediate_root, e nullifier_check_leaf_not_exists, e nullifier_check_low_leaf_hash, e nullifier_check_low_leaf_index, e nullifier_check_low_leaf_next_index, e nullifier_check_low_leaf_next_nullifier, e nullifier_check_low_leaf_nullifier, e nullifier_check_new_leaf_hash, e nullifier_check_next_nullifier_inv, e nullifier_check_next_nullifier_is_nonzero, e nullifier_check_nullifier, e nullifier_check_nullifier_index, e nullifier_check_nullifier_low_leaf_nullifier_diff_inv, e nullifier_check_public_inputs_index, e nullifier_check_root, e nullifier_check_sel, e nullifier_check_should_insert, e nullifier_check_should_silo, e nullifier_check_should_write_to_public_inputs, e nullifier_check_siloed_nullifier, e nullifier_check_siloing_separator, e nullifier_check_tree_height, e nullifier_check_tree_size_before_write, e nullifier_check_updated_low_leaf_hash, e nullifier_check_updated_low_leaf_next_index, e nullifier_check_updated_low_leaf_next_nullifier, e nullifier_check_write, e nullifier_check_write_root, e poseidon2_hash_b_0, e poseidon2_hash_b_1, e poseidon2_hash_b_2, e poseidon2_hash_b_3, e poseidon2_hash_end, e poseidon2_hash_input_len, e poseidon2_hash_num_perm_rounds_rem_inv, e poseidon2_hash_padding, e poseidon2_perm_B_10_0, e poseidon2_perm_B_10_1, e poseidon2_perm_B_10_2, e poseidon2_perm_B_10_3, e poseidon2_perm_B_11_0, e poseidon2_perm_B_11_1, e poseidon2_perm_B_11_2, e poseidon2_perm_B_11_3, e poseidon2_perm_B_12_0, e poseidon2_perm_B_12_1, e poseidon2_perm_B_12_2, e poseidon2_perm_B_12_3, e poseidon2_perm_B_13_0, e poseidon2_perm_B_13_1, e poseidon2_perm_B_13_2, e poseidon2_perm_B_13_3, e poseidon2_perm_B_14_0, e poseidon2_perm_B_14_1, e poseidon2_perm_B_14_2, e poseidon2_perm_B_14_3, e poseidon2_perm_B_15_0, e poseidon2_perm_B_15_1, e poseidon2_perm_B_15_2, e poseidon2_perm_B_15_3, e poseidon2_perm_B_16_0, e poseidon2_perm_B_16_1, e poseidon2_perm_B_16_2, e poseidon2_perm_B_16_3, e poseidon2_perm_B_17_0, e poseidon2_perm_B_17_1, e poseidon2_perm_B_17_2, e poseidon2_perm_B_17_3, e poseidon2_perm_B_18_0, e poseidon2_perm_B_18_1, e poseidon2_perm_B_18_2, e poseidon2_perm_B_18_3, e poseidon2_perm_B_19_0, e poseidon2_perm_B_19_1, e poseidon2_perm_B_19_2, e poseidon2_perm_B_19_3, e poseidon2_perm_B_20_0, e poseidon2_perm_B_20_1, e poseidon2_perm_B_20_2, e poseidon2_perm_B_20_3, e poseidon2_perm_B_21_0, e poseidon2_perm_B_21_1, e poseidon2_perm_B_21_2, e poseidon2_perm_B_21_3, e poseidon2_perm_B_22_0, e poseidon2_perm_B_22_1, e poseidon2_perm_B_22_2, e poseidon2_perm_B_22_3, e poseidon2_perm_B_23_0, e poseidon2_perm_B_23_1, e poseidon2_perm_B_23_2, e poseidon2_perm_B_23_3, e poseidon2_perm_B_24_0, e poseidon2_perm_B_24_1, e poseidon2_perm_B_24_2, e poseidon2_perm_B_24_3, e poseidon2_perm_B_25_0, e poseidon2_perm_B_25_1, e poseidon2_perm_B_25_2, e poseidon2_perm_B_25_3, e poseidon2_perm_B_26_0, e poseidon2_perm_B_26_1, e poseidon2_perm_B_26_2, e poseidon2_perm_B_26_3, e poseidon2_perm_B_27_0, e poseidon2_perm_B_27_1, e poseidon2_perm_B_27_2, e poseidon2_perm_B_27_3, e poseidon2_perm_B_28_0, e poseidon2_perm_B_28_1, e poseidon2_perm_B_28_2, e poseidon2_perm_B_28_3, e poseidon2_perm_B_29_0, e poseidon2_perm_B_29_1, e poseidon2_perm_B_29_2, e poseidon2_perm_B_29_3, e poseidon2_perm_B_30_0, e poseidon2_perm_B_30_1, e poseidon2_perm_B_30_2, e poseidon2_perm_B_30_3, e poseidon2_perm_B_31_0, e poseidon2_perm_B_31_1, e poseidon2_perm_B_31_2, e poseidon2_perm_B_31_3, e poseidon2_perm_B_32_0, e poseidon2_perm_B_32_1, e poseidon2_perm_B_32_2, e poseidon2_perm_B_32_3, e poseidon2_perm_B_33_0, e poseidon2_perm_B_33_1, e poseidon2_perm_B_33_2, e poseidon2_perm_B_33_3, e poseidon2_perm_B_34_0, e poseidon2_perm_B_34_1, e poseidon2_perm_B_34_2, e poseidon2_perm_B_34_3, e poseidon2_perm_B_35_0, e poseidon2_perm_B_35_1, e poseidon2_perm_B_35_2, e poseidon2_perm_B_35_3, e poseidon2_perm_B_36_0, e poseidon2_perm_B_36_1, e poseidon2_perm_B_36_2, e poseidon2_perm_B_36_3, e poseidon2_perm_B_37_0, e poseidon2_perm_B_37_1, e poseidon2_perm_B_37_2, e poseidon2_perm_B_37_3, e poseidon2_perm_B_38_0, e poseidon2_perm_B_38_1, e poseidon2_perm_B_38_2, e poseidon2_perm_B_38_3, e poseidon2_perm_B_39_0, e poseidon2_perm_B_39_1, e poseidon2_perm_B_39_2, e poseidon2_perm_B_39_3, e poseidon2_perm_B_40_0, e poseidon2_perm_B_40_1, e poseidon2_perm_B_40_2, e poseidon2_perm_B_40_3, e poseidon2_perm_B_41_0, e poseidon2_perm_B_41_1, e poseidon2_perm_B_41_2, e poseidon2_perm_B_41_3, e poseidon2_perm_B_42_0, e poseidon2_perm_B_42_1, e poseidon2_perm_B_42_2, e poseidon2_perm_B_42_3, e poseidon2_perm_B_43_0, e poseidon2_perm_B_43_1, e poseidon2_perm_B_43_2, e poseidon2_perm_B_43_3, e poseidon2_perm_B_44_0, e poseidon2_perm_B_44_1, e poseidon2_perm_B_44_2, e poseidon2_perm_B_44_3, e poseidon2_perm_B_45_0, e poseidon2_perm_B_45_1, e poseidon2_perm_B_45_2, e poseidon2_perm_B_45_3, e poseidon2_perm_B_46_0, e poseidon2_perm_B_46_1, e poseidon2_perm_B_46_2, e poseidon2_perm_B_46_3, e poseidon2_perm_B_47_0, e poseidon2_perm_B_47_1, e poseidon2_perm_B_47_2, e poseidon2_perm_B_47_3, e poseidon2_perm_B_48_0, e poseidon2_perm_B_48_1, e poseidon2_perm_B_48_2, e poseidon2_perm_B_48_3, e poseidon2_perm_B_49_0, e poseidon2_perm_B_49_1, e poseidon2_perm_B_49_2, e poseidon2_perm_B_49_3, e poseidon2_perm_B_4_0, e poseidon2_perm_B_4_1, e poseidon2_perm_B_4_2, e poseidon2_perm_B_4_3, e poseidon2_perm_B_50_0, e poseidon2_perm_B_50_1, e poseidon2_perm_B_50_2, e poseidon2_perm_B_50_3, e poseidon2_perm_B_51_0, e poseidon2_perm_B_51_1, e poseidon2_perm_B_51_2, e poseidon2_perm_B_51_3, e poseidon2_perm_B_52_0, e poseidon2_perm_B_52_1, e poseidon2_perm_B_52_2, e poseidon2_perm_B_52_3, e poseidon2_perm_B_53_0, e poseidon2_perm_B_53_1, e poseidon2_perm_B_53_2, e poseidon2_perm_B_53_3, e poseidon2_perm_B_54_0, e poseidon2_perm_B_54_1, e poseidon2_perm_B_54_2, e poseidon2_perm_B_54_3, e poseidon2_perm_B_55_0, e poseidon2_perm_B_55_1, e poseidon2_perm_B_55_2, e poseidon2_perm_B_55_3, e poseidon2_perm_B_56_0, e poseidon2_perm_B_56_1, e poseidon2_perm_B_56_2, e poseidon2_perm_B_56_3, e poseidon2_perm_B_57_0, e poseidon2_perm_B_57_1, e poseidon2_perm_B_57_2, e poseidon2_perm_B_57_3, e poseidon2_perm_B_58_0, e poseidon2_perm_B_58_1, e poseidon2_perm_B_58_2, e poseidon2_perm_B_58_3, e poseidon2_perm_B_59_0, e poseidon2_perm_B_59_1, e poseidon2_perm_B_59_2, e poseidon2_perm_B_59_3, e poseidon2_perm_B_5_0, e poseidon2_perm_B_5_1, e poseidon2_perm_B_5_2, e poseidon2_perm_B_5_3, e poseidon2_perm_B_6_0, e poseidon2_perm_B_6_1, e poseidon2_perm_B_6_2, e poseidon2_perm_B_6_3, e poseidon2_perm_B_7_0, e poseidon2_perm_B_7_1, e poseidon2_perm_B_7_2, e poseidon2_perm_B_7_3, e poseidon2_perm_B_8_0, e poseidon2_perm_B_8_1, e poseidon2_perm_B_8_2, e poseidon2_perm_B_8_3, e poseidon2_perm_B_9_0, e poseidon2_perm_B_9_1, e poseidon2_perm_B_9_2, e poseidon2_perm_B_9_3, e poseidon2_perm_EXT_LAYER_4, e poseidon2_perm_EXT_LAYER_5, e poseidon2_perm_EXT_LAYER_6, e poseidon2_perm_EXT_LAYER_7, e poseidon2_perm_T_0_4, e poseidon2_perm_T_0_5, e poseidon2_perm_T_0_6, e poseidon2_perm_T_0_7, e poseidon2_perm_T_1_4, e poseidon2_perm_T_1_5, e poseidon2_perm_T_1_6, e poseidon2_perm_T_1_7, e poseidon2_perm_T_2_4, e poseidon2_perm_T_2_5, e poseidon2_perm_T_2_6, e poseidon2_perm_T_2_7, e poseidon2_perm_T_3_4, e poseidon2_perm_T_3_5, e poseidon2_perm_T_3_6, e poseidon2_perm_T_3_7, e poseidon2_perm_T_60_4, e poseidon2_perm_T_60_5, e poseidon2_perm_T_60_6, e poseidon2_perm_T_60_7, e poseidon2_perm_T_61_4, e poseidon2_perm_T_61_5, e poseidon2_perm_T_61_6, e poseidon2_perm_T_61_7, e poseidon2_perm_T_62_4, e poseidon2_perm_T_62_5, e poseidon2_perm_T_62_6, e poseidon2_perm_T_62_7, e poseidon2_perm_T_63_4, e poseidon2_perm_T_63_5, e poseidon2_perm_T_63_6, e poseidon2_perm_T_63_7, e poseidon2_perm_a_0, e poseidon2_perm_a_1, e poseidon2_perm_a_2, e poseidon2_perm_a_3, e poseidon2_perm_b_0, e poseidon2_perm_b_1, e poseidon2_perm_b_2, e poseidon2_perm_b_3, e poseidon2_perm_mem_batch_tag_inv, e poseidon2_perm_mem_err, e poseidon2_perm_mem_execution_clk, e poseidon2_perm_mem_input_0_, e poseidon2_perm_mem_input_1_, e poseidon2_perm_mem_input_2_, e poseidon2_perm_mem_input_3_, e poseidon2_perm_mem_input_tag_0_, e poseidon2_perm_mem_input_tag_1_, e poseidon2_perm_mem_input_tag_2_, e poseidon2_perm_mem_input_tag_3_, e poseidon2_perm_mem_max_mem_addr, e poseidon2_perm_mem_output_0_, e poseidon2_perm_mem_output_1_, e poseidon2_perm_mem_output_2_, e poseidon2_perm_mem_output_3_, e poseidon2_perm_mem_read_address_0_, e poseidon2_perm_mem_read_address_1_, e poseidon2_perm_mem_read_address_2_, e poseidon2_perm_mem_read_address_3_, e poseidon2_perm_mem_sel, e poseidon2_perm_mem_sel_dst_out_of_range_err, e poseidon2_perm_mem_sel_invalid_tag_err, e poseidon2_perm_mem_sel_should_exec, e poseidon2_perm_mem_sel_should_read_mem, e poseidon2_perm_mem_sel_src_out_of_range_err, e poseidon2_perm_mem_space_id, e poseidon2_perm_mem_write_address_0_, e poseidon2_perm_mem_write_address_1_, e poseidon2_perm_mem_write_address_2_, e poseidon2_perm_mem_write_address_3_, e poseidon2_perm_sel, e public_data_check_address, e public_data_check_clk_diff_hi, e public_data_check_clk_diff_lo, e public_data_check_const_two, e public_data_check_discard, e public_data_check_end, e public_data_check_final_value, e public_data_check_intermediate_root, e public_data_check_leaf_not_exists, e public_data_check_leaf_slot, e public_data_check_leaf_slot_low_leaf_slot_diff_inv, e public_data_check_length_pi_idx, e public_data_check_low_leaf_hash, e public_data_check_low_leaf_index, e public_data_check_low_leaf_next_index, e public_data_check_low_leaf_next_slot, e public_data_check_low_leaf_slot, e public_data_check_low_leaf_value, e public_data_check_new_leaf_hash, e public_data_check_next_slot_inv, e public_data_check_next_slot_is_nonzero, e public_data_check_non_discarded_write, e public_data_check_non_protocol_write, e public_data_check_not_end, e public_data_check_protocol_write, e public_data_check_public_data_writes_length, e public_data_check_root, e public_data_check_should_insert, e public_data_check_should_write_to_public_inputs, e public_data_check_siloing_separator, e public_data_check_slot, e public_data_check_tree_height, e public_data_check_tree_size_after_write, e public_data_check_tree_size_before_write, e public_data_check_updated_low_leaf_hash, e public_data_check_updated_low_leaf_next_index, e public_data_check_updated_low_leaf_next_slot, e public_data_check_updated_low_leaf_value, e public_data_check_value, e public_data_check_write, e public_data_check_write_root, e public_data_squash_check_clock, e public_data_squash_clk_diff_hi, e public_data_squash_clk_diff_lo, e public_data_squash_leaf_slot_increase, e public_data_squash_value, e range_check_dyn_diff, e range_check_dyn_rng_chk_bits, e range_check_dyn_rng_chk_pow_2, e range_check_is_lte_u112, e range_check_is_lte_u128, e range_check_is_lte_u16, e range_check_is_lte_u32, e range_check_is_lte_u48, e range_check_is_lte_u64, e range_check_is_lte_u80, e range_check_is_lte_u96, e range_check_rng_chk_bits, e range_check_sel, e range_check_sel_alu, e range_check_sel_gt, e range_check_sel_keccak, e range_check_sel_memory, e range_check_sel_r0_16_bit_rng_lookup, e range_check_sel_r1_16_bit_rng_lookup, e range_check_sel_r2_16_bit_rng_lookup, e range_check_sel_r3_16_bit_rng_lookup, e range_check_sel_r4_16_bit_rng_lookup, e range_check_sel_r5_16_bit_rng_lookup, e range_check_sel_r6_16_bit_rng_lookup, e range_check_u16_r0, e range_check_u16_r1, e range_check_u16_r2, e range_check_u16_r3, e range_check_u16_r4, e range_check_u16_r5, e range_check_u16_r6, e range_check_u16_r7, e range_check_value, e retrieved_bytecodes_tree_check_class_id, e retrieved_bytecodes_tree_check_class_id_low_leaf_class_id_diff_inv, e retrieved_bytecodes_tree_check_intermediate_root, e retrieved_bytecodes_tree_check_leaf_not_exists, e retrieved_bytecodes_tree_check_low_leaf_class_id, e retrieved_bytecodes_tree_check_low_leaf_hash, e retrieved_bytecodes_tree_check_low_leaf_index, e retrieved_bytecodes_tree_check_low_leaf_next_class_id, e retrieved_bytecodes_tree_check_low_leaf_next_index, e retrieved_bytecodes_tree_check_new_leaf_hash, e retrieved_bytecodes_tree_check_next_class_id_inv, e retrieved_bytecodes_tree_check_next_class_id_is_nonzero, e retrieved_bytecodes_tree_check_root, e retrieved_bytecodes_tree_check_sel, e retrieved_bytecodes_tree_check_should_insert, e retrieved_bytecodes_tree_check_tree_height, e retrieved_bytecodes_tree_check_tree_size_after_write, e retrieved_bytecodes_tree_check_tree_size_before_write, e retrieved_bytecodes_tree_check_updated_low_leaf_hash, e retrieved_bytecodes_tree_check_updated_low_leaf_next_class_id, e retrieved_bytecodes_tree_check_updated_low_leaf_next_index, e retrieved_bytecodes_tree_check_write, e retrieved_bytecodes_tree_check_write_root, e scalar_mul_bit, e scalar_mul_bit_radix, e scalar_mul_end, e scalar_mul_not_end, e scalar_mul_should_add, e sha256_a_and_b, e sha256_a_and_b_xor_a_and_c, e sha256_a_and_c, e sha256_a_rotr_13, e sha256_a_rotr_2, e sha256_a_rotr_22, e sha256_a_rotr_2_xor_a_rotr_13, e sha256_and_sel, e sha256_b_and_c, e sha256_batch_tag_inv, e sha256_ch, e sha256_computed_w_lhs, e sha256_computed_w_rhs, e sha256_e_and_f, e sha256_e_rotr_11, e sha256_e_rotr_25, e sha256_e_rotr_6, e sha256_e_rotr_6_xor_e_rotr_11, e sha256_err, e sha256_input, e sha256_input_rounds_rem_inv, e sha256_input_tag, e sha256_input_tag_diff_inv, e sha256_last, e sha256_latch, e sha256_lhs_a_13, e sha256_lhs_a_2, e sha256_lhs_a_22, e sha256_lhs_e_11, e sha256_lhs_e_25, e sha256_lhs_e_6, e sha256_lhs_w_10, e sha256_lhs_w_17, e sha256_lhs_w_18, e sha256_lhs_w_19, e sha256_lhs_w_3, e sha256_lhs_w_7, e sha256_maj, e sha256_max_input_addr, e sha256_max_mem_addr, e sha256_max_output_addr, e sha256_max_state_addr, e sha256_mem_out_of_range_err, e sha256_memory_address_0_, e sha256_memory_address_1_, e sha256_memory_address_2_, e sha256_memory_address_3_, e sha256_memory_address_4_, e sha256_memory_address_5_, e sha256_memory_address_6_, e sha256_memory_address_7_, e sha256_memory_register_0_, e sha256_memory_register_1_, e sha256_memory_register_2_, e sha256_memory_register_3_, e sha256_memory_register_4_, e sha256_memory_register_5_, e sha256_memory_register_6_, e sha256_memory_register_7_, e sha256_memory_tag_0_, e sha256_memory_tag_1_, e sha256_memory_tag_2_, e sha256_memory_tag_3_, e sha256_memory_tag_4_, e sha256_memory_tag_5_, e sha256_memory_tag_6_, e sha256_memory_tag_7_, e sha256_next_a_lhs, e sha256_next_a_rhs, e sha256_next_e_lhs, e sha256_next_e_rhs, e sha256_not_e, e sha256_not_e_and_g, e sha256_output_a_lhs, e sha256_output_a_rhs, e sha256_output_b_lhs, e sha256_output_b_rhs, e sha256_output_c_lhs, e sha256_output_c_rhs, e sha256_output_d_lhs, e sha256_output_d_rhs, e sha256_output_e_lhs, e sha256_output_e_rhs, e sha256_output_f_lhs, e sha256_output_f_rhs, e sha256_output_g_lhs, e sha256_output_g_rhs, e sha256_output_h_lhs, e sha256_output_h_rhs, e sha256_perform_round, e sha256_rhs_a_13, e sha256_rhs_a_2, e sha256_rhs_a_22, e sha256_rhs_e_11, e sha256_rhs_e_25, e sha256_rhs_e_6, e sha256_rhs_w_10, e sha256_rhs_w_17, e sha256_rhs_w_18, e sha256_rhs_w_19, e sha256_rhs_w_3, e sha256_rhs_w_7, e sha256_round_constant, e sha256_round_count, e sha256_rounds_remaining_inv, e sha256_rw, e sha256_s_0, e sha256_s_1, e sha256_sel_compute_w, e sha256_sel_input_out_of_range_err, e sha256_sel_invalid_input_row_tag_err, e sha256_sel_invalid_state_tag_err, e sha256_sel_mem_state_or_output, e sha256_sel_output_out_of_range_err, e sha256_sel_read_input_from_memory, e sha256_sel_state_out_of_range_err, e sha256_state_addr, e sha256_two_pow_10, e sha256_two_pow_11, e sha256_two_pow_13, e sha256_two_pow_17, e sha256_two_pow_18, e sha256_two_pow_19, e sha256_two_pow_2, e sha256_two_pow_22, e sha256_two_pow_25, e sha256_two_pow_3, e sha256_two_pow_32, e sha256_two_pow_6, e sha256_two_pow_7, e sha256_u32_tag, e sha256_w, e sha256_w_15_rotr_18, e sha256_w_15_rotr_7, e sha256_w_15_rotr_7_xor_w_15_rotr_18, e sha256_w_15_rshift_3, e sha256_w_2_rotr_17, e sha256_w_2_rotr_17_xor_w_2_rotr_19, e sha256_w_2_rotr_19, e sha256_w_2_rshift_10, e sha256_w_s_0, e sha256_w_s_1, e sha256_xor_sel, e to_radix_end, e to_radix_found, e to_radix_is_unsafe_limb, e to_radix_limb_p_diff, e to_radix_limb_radix_diff, e to_radix_mem_err, e to_radix_mem_input_validation_error, e to_radix_mem_last, e to_radix_mem_limb_index_to_lookup, e to_radix_mem_limb_value, e to_radix_mem_max_mem_size, e to_radix_mem_num_limbs_inv, e to_radix_mem_num_limbs_minus_one_inv, e to_radix_mem_output_tag, e to_radix_mem_sel_dst_out_of_range_err, e to_radix_mem_sel_invalid_bitwise_radix, e to_radix_mem_sel_invalid_num_limbs_err, e to_radix_mem_sel_num_limbs_is_zero, e to_radix_mem_sel_radix_gt_256_err, e to_radix_mem_sel_radix_lt_2_err, e to_radix_mem_sel_truncation_error, e to_radix_mem_sel_value_is_zero, e to_radix_mem_two, e to_radix_mem_two_five_six, e to_radix_mem_value_found, e to_radix_mem_value_inv, e to_radix_mem_write_addr_upper_bound, e to_radix_not_end, e to_radix_p_limb, e to_radix_rem_inverse, e to_radix_safety_diff_inverse, e tx_array_length_l2_to_l1_messages_pi_offset, e tx_array_length_note_hashes_pi_offset, e tx_array_length_nullifiers_pi_offset, e tx_calldata_hash, e tx_calldata_size, e tx_contract_addr, e tx_effective_fee_per_da_gas, e tx_effective_fee_per_l2_gas, e tx_end_phase, e tx_fee_juice_balance_slot, e tx_fee_juice_balances_slot_constant, e tx_fee_juice_contract_address, e tx_fee_payer, e tx_fee_payer_balance, e tx_fee_payer_new_balance, e tx_fee_payer_pi_offset, e tx_fields_length_unencrypted_logs_pi_offset, e tx_gas_limit_pi_offset, e tx_gas_used_pi_offset, e tx_is_cleanup, e tx_is_collect_fee, e tx_is_padded, e tx_is_public_call_request, e tx_is_static, e tx_is_tree_insert_phase, e tx_is_tree_padding, e tx_l1_l2_pi_offset, e tx_l2_l1_msg_content, e tx_l2_l1_msg_contract_address, e tx_l2_l1_msg_recipient, e tx_leaf_value, e tx_msg_sender, e tx_next_da_gas_used, e tx_next_da_gas_used_sent_to_enqueued_call, e tx_next_l2_gas_used, e tx_next_l2_gas_used_sent_to_enqueued_call, e tx_next_note_hash_tree_root, e tx_next_note_hash_tree_size, e tx_next_nullifier_tree_root, e tx_next_nullifier_tree_size, e tx_next_num_l2_to_l1_messages, e tx_next_num_note_hashes_emitted, e tx_next_num_nullifiers_emitted, e tx_next_num_unencrypted_log_fields, e tx_next_phase_on_revert, e tx_next_public_data_tree_root, e tx_next_public_data_tree_size, e tx_next_retrieved_bytecodes_tree_root, e tx_next_retrieved_bytecodes_tree_size, e tx_next_written_public_data_slots_tree_root, e tx_next_written_public_data_slots_tree_size, e tx_note_hash_pi_offset, e tx_nullifier_limit_error, e tx_nullifier_pi_offset, e tx_prev_da_gas_used_sent_to_enqueued_call, e tx_prev_l2_gas_used_sent_to_enqueued_call, e tx_public_data_pi_offset, e tx_read_pi_length_offset, e tx_read_pi_start_offset, e tx_remaining_phase_inv, e tx_remaining_phase_minus_one_inv, e tx_remaining_side_effects_inv, e tx_reverted_pi_offset, e tx_sel_non_revertible_append_l2_l1_msg, e tx_sel_non_revertible_append_note_hash, e tx_sel_non_revertible_append_nullifier, e tx_sel_read_phase_length, e tx_sel_read_trees_and_gas_used, e tx_sel_revertible_append_l2_l1_msg, e tx_sel_revertible_append_note_hash, e tx_sel_revertible_append_nullifier, e tx_setup_phase_value, e tx_should_l2_l1_msg_append, e tx_should_note_hash_append, e tx_should_nullifier_append, e tx_should_process_call_request, e tx_should_read_gas_limit, e tx_should_try_l2_l1_msg_append, e tx_should_try_note_hash_append, e tx_should_try_nullifier_append, e tx_uint32_max, e tx_write_pi_offset, e update_check_address, e update_check_current_class_id, e update_check_delayed_public_mutable_hash_slot, e update_check_delayed_public_mutable_slot, e update_check_deployer_protocol_contract_address, e update_check_hash_not_zero, e update_check_original_class_id, e update_check_public_data_tree_root, e update_check_sel, e update_check_timestamp, e update_check_timestamp_is_lt_timestamp_of_change, e update_check_timestamp_of_change, e update_check_timestamp_of_change_bit_size, e update_check_timestamp_pi_offset, e update_check_update_hash, e update_check_update_hash_inv, e update_check_update_hi_metadata, e update_check_update_hi_metadata_bit_size, e update_check_update_post_class_id_is_zero, e update_check_update_post_class_inv, e update_check_update_pre_class_id_is_zero, e update_check_update_pre_class_inv, e update_check_update_preimage_metadata, e update_check_update_preimage_post_class_id, e update_check_update_preimage_pre_class_id, e update_check_updated_class_ids_slot, e written_public_data_slots_tree_check_address, e written_public_data_slots_tree_check_intermediate_root, e written_public_data_slots_tree_check_leaf_not_exists, e written_public_data_slots_tree_check_leaf_slot, e written_public_data_slots_tree_check_low_leaf_hash, e written_public_data_slots_tree_check_low_leaf_index, e written_public_data_slots_tree_check_low_leaf_next_index, e written_public_data_slots_tree_check_low_leaf_next_slot, e written_public_data_slots_tree_check_low_leaf_slot, e written_public_data_slots_tree_check_new_leaf_hash, e written_public_data_slots_tree_check_next_slot_inv, e written_public_data_slots_tree_check_next_slot_is_nonzero, e written_public_data_slots_tree_check_root, e written_public_data_slots_tree_check_sel, e written_public_data_slots_tree_check_should_insert, e written_public_data_slots_tree_check_siloing_separator, e written_public_data_slots_tree_check_slot, e written_public_data_slots_tree_check_slot_low_leaf_slot_diff_inv, e written_public_data_slots_tree_check_tree_height, e written_public_data_slots_tree_check_tree_size_after_write, e written_public_data_slots_tree_check_tree_size_before_write, e written_public_data_slots_tree_check_updated_low_leaf_hash, e written_public_data_slots_tree_check_updated_low_leaf_next_index, e written_public_data_slots_tree_check_updated_low_leaf_next_slot, e written_public_data_slots_tree_check_write, e written_public_data_slots_tree_check_write_root, e lookup_range_check_dyn_rng_chk_pow_2_counts, e lookup_range_check_dyn_diff_is_u16_counts, e lookup_range_check_r0_is_u16_counts, e lookup_range_check_r1_is_u16_counts, e lookup_range_check_r2_is_u16_counts, e lookup_range_check_r3_is_u16_counts, e lookup_range_check_r4_is_u16_counts, e lookup_range_check_r5_is_u16_counts, e lookup_range_check_r6_is_u16_counts, e lookup_range_check_r7_is_u16_counts, e lookup_ff_gt_a_lo_range_counts, e lookup_ff_gt_a_hi_range_counts, e lookup_gt_gt_range_counts, e lookup_alu_tag_max_bits_value_counts, e lookup_alu_range_check_decomposition_a_lo_counts, e lookup_alu_range_check_decomposition_a_hi_counts, e lookup_alu_range_check_decomposition_b_lo_counts, e lookup_alu_range_check_decomposition_b_hi_counts, e lookup_alu_range_check_mul_c_hi_counts, e lookup_alu_ff_gt_counts, e lookup_alu_int_gt_counts, e lookup_alu_shifts_two_pow_counts, e lookup_alu_large_trunc_canonical_dec_counts, e lookup_alu_range_check_trunc_mid_counts, e lookup_bitwise_integral_tag_length_counts, e lookup_bitwise_byte_operations_counts, e lookup_memory_range_check_limb_0_counts, e lookup_memory_range_check_limb_1_counts, e lookup_memory_range_check_limb_2_counts, e lookup_memory_tag_max_bits_counts, e lookup_memory_range_check_write_tagged_value_counts, e lookup_keccakf1600_theta_xor_01_counts, e lookup_keccakf1600_theta_xor_02_counts, e lookup_keccakf1600_theta_xor_03_counts, e lookup_keccakf1600_theta_xor_row_0_counts, e lookup_keccakf1600_theta_xor_11_counts, e lookup_keccakf1600_theta_xor_12_counts, e lookup_keccakf1600_theta_xor_13_counts, e lookup_keccakf1600_theta_xor_row_1_counts, e lookup_keccakf1600_theta_xor_21_counts, e lookup_keccakf1600_theta_xor_22_counts, e lookup_keccakf1600_theta_xor_23_counts, e lookup_keccakf1600_theta_xor_row_2_counts, e lookup_keccakf1600_theta_xor_31_counts, e lookup_keccakf1600_theta_xor_32_counts, e lookup_keccakf1600_theta_xor_33_counts, e lookup_keccakf1600_theta_xor_row_3_counts, e lookup_keccakf1600_theta_xor_41_counts, e lookup_keccakf1600_theta_xor_42_counts, e lookup_keccakf1600_theta_xor_43_counts, e lookup_keccakf1600_theta_xor_row_4_counts, e lookup_keccakf1600_theta_combined_xor_0_counts, e lookup_keccakf1600_theta_combined_xor_1_counts, e lookup_keccakf1600_theta_combined_xor_2_counts, e lookup_keccakf1600_theta_combined_xor_3_counts, e lookup_keccakf1600_theta_combined_xor_4_counts, e lookup_keccakf1600_state_theta_00_counts, e lookup_keccakf1600_state_theta_01_counts, e lookup_keccakf1600_state_theta_02_counts, e lookup_keccakf1600_state_theta_03_counts, e lookup_keccakf1600_state_theta_04_counts, e lookup_keccakf1600_state_theta_10_counts, e lookup_keccakf1600_state_theta_11_counts, e lookup_keccakf1600_state_theta_12_counts, e lookup_keccakf1600_state_theta_13_counts, e lookup_keccakf1600_state_theta_14_counts, e lookup_keccakf1600_state_theta_20_counts, e lookup_keccakf1600_state_theta_21_counts, e lookup_keccakf1600_state_theta_22_counts, e lookup_keccakf1600_state_theta_23_counts, e lookup_keccakf1600_state_theta_24_counts, e lookup_keccakf1600_state_theta_30_counts, e lookup_keccakf1600_state_theta_31_counts, e lookup_keccakf1600_state_theta_32_counts, e lookup_keccakf1600_state_theta_33_counts, e lookup_keccakf1600_state_theta_34_counts, e lookup_keccakf1600_state_theta_40_counts, e lookup_keccakf1600_state_theta_41_counts, e lookup_keccakf1600_state_theta_42_counts, e lookup_keccakf1600_state_theta_43_counts, e lookup_keccakf1600_state_theta_44_counts, e lookup_keccakf1600_theta_limb_02_range_counts, e lookup_keccakf1600_theta_limb_04_range_counts, e lookup_keccakf1600_theta_limb_10_range_counts, e lookup_keccakf1600_theta_limb_12_range_counts, e lookup_keccakf1600_theta_limb_14_range_counts, e lookup_keccakf1600_theta_limb_21_range_counts, e lookup_keccakf1600_theta_limb_23_range_counts, e lookup_keccakf1600_theta_limb_30_range_counts, e lookup_keccakf1600_theta_limb_32_range_counts, e lookup_keccakf1600_theta_limb_33_range_counts, e lookup_keccakf1600_theta_limb_40_range_counts, e lookup_keccakf1600_theta_limb_41_range_counts, e lookup_keccakf1600_theta_limb_43_range_counts, e lookup_keccakf1600_theta_limb_44_range_counts, e lookup_keccakf1600_theta_limb_01_range_counts, e lookup_keccakf1600_theta_limb_03_range_counts, e lookup_keccakf1600_theta_limb_11_range_counts, e lookup_keccakf1600_theta_limb_13_range_counts, e lookup_keccakf1600_theta_limb_20_range_counts, e lookup_keccakf1600_theta_limb_22_range_counts, e lookup_keccakf1600_theta_limb_24_range_counts, e lookup_keccakf1600_theta_limb_31_range_counts, e lookup_keccakf1600_theta_limb_34_range_counts, e lookup_keccakf1600_theta_limb_42_range_counts, e lookup_keccakf1600_state_pi_and_00_counts, e lookup_keccakf1600_state_pi_and_01_counts, e lookup_keccakf1600_state_pi_and_02_counts, e lookup_keccakf1600_state_pi_and_03_counts, e lookup_keccakf1600_state_pi_and_04_counts, e lookup_keccakf1600_state_pi_and_10_counts, e lookup_keccakf1600_state_pi_and_11_counts, e lookup_keccakf1600_state_pi_and_12_counts, e lookup_keccakf1600_state_pi_and_13_counts, e lookup_keccakf1600_state_pi_and_14_counts, e lookup_keccakf1600_state_pi_and_20_counts, e lookup_keccakf1600_state_pi_and_21_counts, e lookup_keccakf1600_state_pi_and_22_counts, e lookup_keccakf1600_state_pi_and_23_counts, e lookup_keccakf1600_state_pi_and_24_counts, e lookup_keccakf1600_state_pi_and_30_counts, e lookup_keccakf1600_state_pi_and_31_counts, e lookup_keccakf1600_state_pi_and_32_counts, e lookup_keccakf1600_state_pi_and_33_counts, e lookup_keccakf1600_state_pi_and_34_counts, e lookup_keccakf1600_state_pi_and_40_counts, e lookup_keccakf1600_state_pi_and_41_counts, e lookup_keccakf1600_state_pi_and_42_counts, e lookup_keccakf1600_state_pi_and_43_counts, e lookup_keccakf1600_state_pi_and_44_counts, e lookup_keccakf1600_state_chi_00_counts, e lookup_keccakf1600_state_chi_01_counts, e lookup_keccakf1600_state_chi_02_counts, e lookup_keccakf1600_state_chi_03_counts, e lookup_keccakf1600_state_chi_04_counts, e lookup_keccakf1600_state_chi_10_counts, e lookup_keccakf1600_state_chi_11_counts, e lookup_keccakf1600_state_chi_12_counts, e lookup_keccakf1600_state_chi_13_counts, e lookup_keccakf1600_state_chi_14_counts, e lookup_keccakf1600_state_chi_20_counts, e lookup_keccakf1600_state_chi_21_counts, e lookup_keccakf1600_state_chi_22_counts, e lookup_keccakf1600_state_chi_23_counts, e lookup_keccakf1600_state_chi_24_counts, e lookup_keccakf1600_state_chi_30_counts, e lookup_keccakf1600_state_chi_31_counts, e lookup_keccakf1600_state_chi_32_counts, e lookup_keccakf1600_state_chi_33_counts, e lookup_keccakf1600_state_chi_34_counts, e lookup_keccakf1600_state_chi_40_counts, e lookup_keccakf1600_state_chi_41_counts, e lookup_keccakf1600_state_chi_42_counts, e lookup_keccakf1600_state_chi_43_counts, e lookup_keccakf1600_state_chi_44_counts, e lookup_keccakf1600_round_cst_counts, e lookup_keccakf1600_state_iota_00_counts, e lookup_keccakf1600_src_out_of_range_toggle_counts, e lookup_keccakf1600_dst_out_of_range_toggle_counts, e lookup_sha256_range_comp_w_lhs_counts, e lookup_sha256_range_comp_w_rhs_counts, e lookup_sha256_range_rhs_w_7_counts, e lookup_sha256_range_rhs_w_18_counts, e lookup_sha256_range_rhs_w_3_counts, e lookup_sha256_w_s_0_xor_0_counts, e lookup_sha256_w_s_0_xor_1_counts, e lookup_sha256_range_rhs_w_17_counts, e lookup_sha256_range_rhs_w_19_counts, e lookup_sha256_range_rhs_w_10_counts, e lookup_sha256_w_s_1_xor_0_counts, e lookup_sha256_w_s_1_xor_1_counts, e lookup_sha256_range_rhs_e_6_counts, e lookup_sha256_range_rhs_e_11_counts, e lookup_sha256_range_rhs_e_25_counts, e lookup_sha256_s_1_xor_0_counts, e lookup_sha256_s_1_xor_1_counts, e lookup_sha256_ch_and_0_counts, e lookup_sha256_ch_and_1_counts, e lookup_sha256_ch_xor_counts, e lookup_sha256_round_constant_counts, e lookup_sha256_range_rhs_a_2_counts, e lookup_sha256_range_rhs_a_13_counts, e lookup_sha256_range_rhs_a_22_counts, e lookup_sha256_s_0_xor_0_counts, e lookup_sha256_s_0_xor_1_counts, e lookup_sha256_maj_and_0_counts, e lookup_sha256_maj_and_1_counts, e lookup_sha256_maj_and_2_counts, e lookup_sha256_maj_xor_0_counts, e lookup_sha256_maj_xor_1_counts, e lookup_sha256_range_comp_next_a_lhs_counts, e lookup_sha256_range_comp_next_a_rhs_counts, e lookup_sha256_range_comp_next_e_lhs_counts, e lookup_sha256_range_comp_next_e_rhs_counts, e lookup_sha256_range_comp_a_lhs_counts, e lookup_sha256_range_comp_a_rhs_counts, e lookup_sha256_range_comp_b_lhs_counts, e lookup_sha256_range_comp_b_rhs_counts, e lookup_sha256_range_comp_c_lhs_counts, e lookup_sha256_range_comp_c_rhs_counts, e lookup_sha256_range_comp_d_lhs_counts, e lookup_sha256_range_comp_d_rhs_counts, e lookup_sha256_range_comp_e_lhs_counts, e lookup_sha256_range_comp_e_rhs_counts, e lookup_sha256_range_comp_f_lhs_counts, e lookup_sha256_range_comp_f_rhs_counts, e lookup_sha256_range_comp_g_lhs_counts, e lookup_sha256_range_comp_g_rhs_counts, e lookup_sha256_range_comp_h_lhs_counts, e lookup_sha256_range_comp_h_rhs_counts, e lookup_sha256_mem_check_state_addr_in_range_counts, e lookup_sha256_mem_check_input_addr_in_range_counts, e lookup_sha256_mem_check_output_addr_in_range_counts, e lookup_ecc_mem_check_dst_addr_in_range_counts, e lookup_ecc_mem_input_output_ecc_add_counts, e lookup_poseidon2_mem_check_src_addr_in_range_counts, e lookup_poseidon2_mem_check_dst_addr_in_range_counts, e lookup_poseidon2_mem_input_output_poseidon2_perm_counts, e lookup_to_radix_limb_range_counts, e lookup_to_radix_limb_less_than_radix_range_counts, e lookup_to_radix_fetch_safe_limbs_counts, e lookup_to_radix_fetch_p_limb_counts, e lookup_to_radix_limb_p_diff_range_counts, e lookup_scalar_mul_to_radix_counts, e lookup_scalar_mul_double_counts, e lookup_scalar_mul_add_counts, e lookup_to_radix_mem_check_dst_addr_in_range_counts, e lookup_to_radix_mem_check_radix_lt_2_counts, e lookup_to_radix_mem_check_radix_gt_256_counts, e lookup_to_radix_mem_input_output_to_radix_counts, e lookup_context_ctx_stack_rollback_counts, e lookup_context_ctx_stack_return_counts, e lookup_poseidon2_hash_poseidon2_perm_counts, e lookup_calldata_hashing_get_calldata_field_0_counts, e lookup_calldata_hashing_get_calldata_field_1_counts, e lookup_calldata_hashing_get_calldata_field_2_counts, e lookup_calldata_hashing_check_final_size_counts, e lookup_calldata_hashing_poseidon2_hash_counts, e lookup_calldata_range_check_context_id_diff_counts, e lookup_data_copy_offset_plus_size_is_gt_data_size_counts, e lookup_data_copy_check_src_addr_in_range_counts, e lookup_data_copy_check_dst_addr_in_range_counts, e lookup_data_copy_data_index_upper_bound_gt_offset_counts, e lookup_data_copy_col_read_counts, e lookup_addressing_relative_overflow_result_0_counts, e lookup_addressing_relative_overflow_result_1_counts, e lookup_addressing_relative_overflow_result_2_counts, e lookup_addressing_relative_overflow_result_3_counts, e lookup_addressing_relative_overflow_result_4_counts, e lookup_addressing_relative_overflow_result_5_counts, e lookup_addressing_relative_overflow_result_6_counts, e lookup_gas_addressing_gas_read_counts, e lookup_gas_is_out_of_gas_l2_counts, e lookup_gas_is_out_of_gas_da_counts, e lookup_merkle_check_merkle_poseidon2_read_counts, e lookup_merkle_check_merkle_poseidon2_write_counts, e lookup_nullifier_check_silo_poseidon2_counts, e lookup_nullifier_check_low_leaf_poseidon2_counts, e lookup_nullifier_check_updated_low_leaf_poseidon2_counts, e lookup_nullifier_check_low_leaf_merkle_check_counts, e lookup_nullifier_check_low_leaf_nullifier_validation_counts, e lookup_nullifier_check_low_leaf_next_nullifier_validation_counts, e lookup_nullifier_check_new_leaf_poseidon2_counts, e lookup_nullifier_check_new_leaf_merkle_check_counts, e lookup_nullifier_check_write_nullifier_to_public_inputs_counts, e lookup_public_data_squash_leaf_slot_increase_ff_gt_counts, e lookup_public_data_squash_clk_diff_range_lo_counts, e lookup_public_data_squash_clk_diff_range_hi_counts, e lookup_public_data_check_clk_diff_range_lo_counts, e lookup_public_data_check_clk_diff_range_hi_counts, e lookup_public_data_check_silo_poseidon2_counts, e lookup_public_data_check_low_leaf_slot_validation_counts, e lookup_public_data_check_low_leaf_next_slot_validation_counts, e lookup_public_data_check_low_leaf_poseidon2_0_counts, e lookup_public_data_check_low_leaf_poseidon2_1_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_0_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_1_counts, e lookup_public_data_check_low_leaf_merkle_check_counts, e lookup_public_data_check_new_leaf_poseidon2_0_counts, e lookup_public_data_check_new_leaf_poseidon2_1_counts, e lookup_public_data_check_new_leaf_merkle_check_counts, e lookup_public_data_check_write_public_data_to_public_inputs_counts, e lookup_public_data_check_write_writes_length_to_public_inputs_counts, e lookup_written_public_data_slots_tree_check_silo_poseidon2_counts, e lookup_written_public_data_slots_tree_check_low_leaf_poseidon2_counts, e lookup_written_public_data_slots_tree_check_updated_low_leaf_poseidon2_counts, e lookup_written_public_data_slots_tree_check_low_leaf_merkle_check_counts, e lookup_written_public_data_slots_tree_check_low_leaf_slot_validation_counts, e lookup_written_public_data_slots_tree_check_low_leaf_next_slot_validation_counts, e lookup_written_public_data_slots_tree_check_new_leaf_poseidon2_counts, e lookup_written_public_data_slots_tree_check_new_leaf_merkle_check_counts, e lookup_l1_to_l2_message_tree_check_merkle_check_counts, e lookup_retrieved_bytecodes_tree_check_low_leaf_poseidon2_counts, e lookup_retrieved_bytecodes_tree_check_updated_low_leaf_poseidon2_counts, e lookup_retrieved_bytecodes_tree_check_low_leaf_merkle_check_counts, e lookup_retrieved_bytecodes_tree_check_low_leaf_class_id_validation_counts, e lookup_retrieved_bytecodes_tree_check_low_leaf_next_class_id_validation_counts, e lookup_retrieved_bytecodes_tree_check_new_leaf_poseidon2_counts, e lookup_retrieved_bytecodes_tree_check_new_leaf_merkle_check_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_counts, e lookup_address_derivation_partial_address_poseidon2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_0_counts, e lookup_address_derivation_public_keys_hash_poseidon2_1_counts, e lookup_address_derivation_public_keys_hash_poseidon2_2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_3_counts, e lookup_address_derivation_public_keys_hash_poseidon2_4_counts, e lookup_address_derivation_preaddress_poseidon2_counts, e lookup_address_derivation_preaddress_scalar_mul_counts, e lookup_address_derivation_address_ecadd_counts, e lookup_bc_decomposition_bytes_are_bytes_counts, e lookup_bc_hashing_check_final_bytes_remaining_counts, e lookup_bc_hashing_poseidon2_hash_counts, e lookup_update_check_timestamp_from_public_inputs_counts, e lookup_update_check_delayed_public_mutable_slot_poseidon2_counts, e lookup_update_check_update_hash_public_data_read_counts, e lookup_update_check_update_hash_poseidon2_counts, e lookup_update_check_update_hi_metadata_range_counts, e lookup_update_check_update_lo_metadata_range_counts, e lookup_update_check_timestamp_is_lt_timestamp_of_change_counts, e lookup_contract_instance_retrieval_check_protocol_address_range_counts, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_counts, e lookup_contract_instance_retrieval_deployment_nullifier_read_counts, e lookup_contract_instance_retrieval_address_derivation_counts, e lookup_contract_instance_retrieval_update_check_counts, e lookup_bc_retrieval_contract_instance_retrieval_counts, e lookup_bc_retrieval_is_new_class_check_counts, e lookup_bc_retrieval_class_id_derivation_counts, e lookup_bc_retrieval_retrieved_bytecodes_insertion_counts, e lookup_instr_fetching_pc_abs_diff_positive_counts, e lookup_instr_fetching_instr_abs_diff_positive_counts, e lookup_instr_fetching_tag_value_validation_counts, e lookup_instr_fetching_bytecode_size_from_bc_dec_counts, e lookup_instr_fetching_bytes_from_bc_dec_counts, e lookup_instr_fetching_wire_instruction_info_counts, e lookup_class_id_derivation_class_id_poseidon2_0_counts, e lookup_class_id_derivation_class_id_poseidon2_1_counts, e lookup_get_env_var_precomputed_info_counts, e lookup_get_env_var_read_from_public_inputs_col0_counts, e lookup_get_env_var_read_from_public_inputs_col1_counts, e lookup_get_contract_instance_precomputed_info_counts, e lookup_get_contract_instance_contract_instance_retrieval_counts, e lookup_internal_call_unwind_call_stack_counts, e lookup_external_call_is_l2_gas_left_gt_allocated_counts, e lookup_external_call_is_da_gas_left_gt_allocated_counts, e lookup_sload_storage_read_counts, e lookup_sstore_record_written_storage_slot_counts, e lookup_note_hash_tree_check_silo_poseidon2_counts, e lookup_note_hash_tree_check_read_first_nullifier_counts, e lookup_note_hash_tree_check_nonce_computation_poseidon2_counts, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_counts, e lookup_note_hash_tree_check_merkle_check_counts, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_counts, e lookup_notehash_exists_note_hash_leaf_index_in_range_counts, e lookup_notehash_exists_note_hash_read_counts, e lookup_emit_notehash_notehash_tree_write_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_counts, e lookup_nullifier_exists_nullifier_exists_check_counts, e lookup_emit_nullifier_write_nullifier_counts, e lookup_emit_unencrypted_log_check_memory_out_of_bounds_counts, e lookup_emit_unencrypted_log_check_log_fields_count_counts, e lookup_emit_unencrypted_log_write_data_to_public_inputs_counts, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_counts, e lookup_execution_bytecode_retrieval_result_counts, e lookup_execution_instruction_fetching_result_counts, e lookup_execution_instruction_fetching_body_counts, e lookup_execution_exec_spec_read_counts, e lookup_execution_dyn_l2_factor_bitwise_counts, e lookup_execution_check_radix_gt_256_counts, e lookup_execution_get_p_limbs_counts, e lookup_execution_get_max_limbs_counts, e lookup_execution_check_written_storage_slot_counts, e lookup_execution_dispatch_to_alu_counts, e lookup_execution_dispatch_to_bitwise_counts, e lookup_execution_dispatch_to_cast_counts, e lookup_execution_dispatch_to_set_counts, e lookup_tx_context_public_inputs_note_hash_tree_counts, e lookup_tx_context_public_inputs_nullifier_tree_counts, e lookup_tx_context_public_inputs_public_data_tree_counts, e lookup_tx_context_public_inputs_l1_l2_tree_counts, e lookup_tx_context_public_inputs_gas_used_counts, e lookup_tx_context_public_inputs_read_gas_limit_counts, e lookup_tx_context_public_inputs_read_reverted_counts, e lookup_tx_context_restore_state_on_revert_counts, e lookup_tx_context_public_inputs_write_note_hash_count_counts, e lookup_tx_context_public_inputs_write_nullifier_count_counts, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_counts, e lookup_tx_context_public_inputs_write_unencrypted_log_count_counts, e lookup_tx_read_phase_spec_counts, e lookup_tx_read_phase_length_counts, e lookup_tx_read_public_call_request_phase_counts, e lookup_tx_read_tree_insert_value_counts, e lookup_tx_note_hash_append_counts, e lookup_tx_nullifier_append_counts, e lookup_tx_read_l2_l1_msg_counts, e lookup_tx_write_l2_l1_msg_counts, e lookup_tx_read_effective_fee_public_inputs_counts, e lookup_tx_read_fee_payer_public_inputs_counts, e lookup_tx_balance_slot_poseidon2_counts, e lookup_tx_balance_read_counts, e lookup_tx_balance_validation_counts, e lookup_tx_write_fee_public_inputs_counts, 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_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_packed, e bc_decomposition_sel_windows_gt_remaining, e bc_hashing_bytecode_id, e bc_hashing_pc_index, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_start, e bc_retrieval_sel, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_sel_start, e data_copy_src_context_id, e emit_unencrypted_log_contract_address, e emit_unencrypted_log_correct_tag, e emit_unencrypted_log_error_out_of_bounds, e emit_unencrypted_log_error_tag_mismatch, e emit_unencrypted_log_execution_clk, e emit_unencrypted_log_is_write_contract_address, e emit_unencrypted_log_is_write_memory_value, e emit_unencrypted_log_log_address, e emit_unencrypted_log_public_inputs_index, e emit_unencrypted_log_remaining_rows, e emit_unencrypted_log_seen_wrong_tag, e emit_unencrypted_log_sel, e emit_unencrypted_log_sel_should_write_to_public_inputs, e emit_unencrypted_log_space_id, e emit_unencrypted_log_start, e execution_bytecode_id, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_unencrypted_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_space_id, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_global_addr, e memory_rw, e memory_sel, e memory_tag, e memory_timestamp, e memory_value, e merkle_check_index, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, 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 public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, 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_execution_clk, 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_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_sel_is_input_round, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_exponent, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_unencrypted_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted +#define AVM2_WIRE_ENTITIES_E(e) e public_inputs_cols_0_, e public_inputs_cols_1_, e public_inputs_cols_2_, e public_inputs_cols_3_, e address_derivation_address, e address_derivation_address_y, e address_derivation_class_id, e address_derivation_const_five, e address_derivation_const_four, e address_derivation_const_three, e address_derivation_const_two, e address_derivation_deployer_addr, e address_derivation_g1_x, e address_derivation_g1_y, e address_derivation_incoming_viewing_key_x, e address_derivation_incoming_viewing_key_y, e address_derivation_init_hash, e address_derivation_nullifier_key_x, e address_derivation_nullifier_key_y, e address_derivation_outgoing_viewing_key_x, e address_derivation_outgoing_viewing_key_y, e address_derivation_partial_address, e address_derivation_partial_address_domain_separator, e address_derivation_preaddress, e address_derivation_preaddress_domain_separator, e address_derivation_preaddress_public_key_x, e address_derivation_preaddress_public_key_y, e address_derivation_public_keys_hash, e address_derivation_public_keys_hash_domain_separator, e address_derivation_salt, e address_derivation_salted_init_hash, e address_derivation_sel, e address_derivation_tagging_key_x, e address_derivation_tagging_key_y, e alu_a_hi, e alu_a_hi_bits, e alu_a_lo, e alu_a_lo_bits, e alu_ab_diff_inv, e alu_ab_tags_diff_inv, e alu_b_hi, e alu_b_inv, e alu_b_lo, e alu_c_hi, e alu_cf, e alu_constant_64, e alu_gt_input_a, e alu_gt_input_b, e alu_gt_result_c, e alu_helper1, e alu_ia, e alu_ia_tag, e alu_ib, e alu_ib_tag, e alu_ic, e alu_ic_tag, e alu_max_bits, e alu_max_value, e alu_mid, e alu_mid_bits, e alu_op_id, e alu_sel, e alu_sel_ab_tag_mismatch, e alu_sel_decompose_a, e alu_sel_div_0_err, e alu_sel_div_no_err, e alu_sel_err, e alu_sel_ff_gt, e alu_sel_int_gt, e alu_sel_is_ff, e alu_sel_is_u128, e alu_sel_mul_div_u128, e alu_sel_mul_no_err_non_ff, e alu_sel_op_add, e alu_sel_op_div, e alu_sel_op_eq, e alu_sel_op_fdiv, e alu_sel_op_lt, e alu_sel_op_lte, e alu_sel_op_mul, e alu_sel_op_not, e alu_sel_op_shl, e alu_sel_op_shr, e alu_sel_op_sub, e alu_sel_op_truncate, e alu_sel_shift_ops_no_overflow, e alu_sel_tag_err, e alu_sel_trunc_gte_128, e alu_sel_trunc_lt_128, e alu_sel_trunc_non_trivial, e alu_sel_trunc_trivial, e alu_shift_lo_bits, e alu_tag_ff_diff_inv, e alu_tag_u128_diff_inv, e alu_two_pow_shift_lo_bits, e bc_decomposition_bytes_pc_plus_36, e bc_decomposition_bytes_rem_inv, e bc_decomposition_bytes_rem_min_one_inv, e bc_decomposition_bytes_to_read, e bc_decomposition_is_windows_eq_remaining, e bc_decomposition_last_of_contract, e bc_decomposition_next_packed_pc_min_pc_inv, e bc_decomposition_packed_field, e bc_decomposition_sel_packed_read_0_, e bc_decomposition_sel_packed_read_1_, e bc_decomposition_sel_packed_read_2_, e bc_decomposition_windows_min_remaining_inv, e bc_hashing_input_len, e bc_hashing_latch, e bc_hashing_output_hash, e bc_hashing_packed_fields_0, e bc_hashing_packed_fields_1, e bc_hashing_packed_fields_2, e bc_hashing_pc_at_final_field, e bc_hashing_pc_index_1, e bc_hashing_pc_index_2, e bc_hashing_sel_not_padding_1, e bc_hashing_sel_not_padding_2, e bc_hashing_sel_not_start, e bc_retrieval_address, e bc_retrieval_artifact_hash, e bc_retrieval_bytecode_id, e bc_retrieval_current_class_id, e bc_retrieval_error, e bc_retrieval_instance_exists, e bc_retrieval_is_new_class, e bc_retrieval_next_retrieved_bytecodes_tree_root, e bc_retrieval_next_retrieved_bytecodes_tree_size, e bc_retrieval_no_remaining_bytecodes, e bc_retrieval_nullifier_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_root, e bc_retrieval_prev_retrieved_bytecodes_tree_size, e bc_retrieval_private_functions_root, e bc_retrieval_public_data_tree_root, e bc_retrieval_remaining_bytecodes_inv, e bc_retrieval_should_retrieve, e bitwise_ctr_inv, e bitwise_ctr_min_one_inv, e bitwise_err, e bitwise_ia_byte, e bitwise_ib_byte, e bitwise_ic_byte, e bitwise_last, e bitwise_sel, e bitwise_sel_get_ctr, e bitwise_sel_tag_ff_err, e bitwise_sel_tag_mismatch_err, e bitwise_start, e bitwise_start_keccak, e bitwise_start_sha256, e bitwise_tag_a, e bitwise_tag_a_inv, e bitwise_tag_ab_diff_inv, e bitwise_tag_b, e bitwise_tag_c, e calldata_diff_context_id, e calldata_hashing_index_1_, e calldata_hashing_index_2_, e calldata_hashing_input_0_, e calldata_hashing_input_1_, e calldata_hashing_input_2_, e calldata_hashing_input_len, e calldata_hashing_latch, e calldata_hashing_sel_not_padding_1, e calldata_hashing_sel_not_padding_2, e calldata_hashing_sel_not_start, e calldata_latch, e calldata_value, e class_id_derivation_artifact_hash, e class_id_derivation_class_id, e class_id_derivation_const_two, e class_id_derivation_gen_index_contract_class_id, e class_id_derivation_private_functions_root, e class_id_derivation_public_bytecode_commitment, e class_id_derivation_sel, e context_stack_bytecode_id, e context_stack_context_id, e context_stack_contract_address, e context_stack_entered_context_id, e context_stack_is_static, e context_stack_msg_sender, e context_stack_next_pc, e context_stack_note_hash_tree_root, e context_stack_note_hash_tree_size, e context_stack_nullifier_tree_root, e context_stack_nullifier_tree_size, e context_stack_num_l2_to_l1_messages, e context_stack_num_note_hashes_emitted, e context_stack_num_nullifiers_emitted, e context_stack_num_unencrypted_log_fields, e context_stack_parent_calldata_addr, e context_stack_parent_calldata_size, e context_stack_parent_da_gas_limit, e context_stack_parent_da_gas_used, e context_stack_parent_id, e context_stack_parent_l2_gas_limit, e context_stack_parent_l2_gas_used, e context_stack_public_data_tree_root, e context_stack_public_data_tree_size, e context_stack_sel, e context_stack_written_public_data_slots_tree_root, e context_stack_written_public_data_slots_tree_size, e contract_instance_retrieval_address, e contract_instance_retrieval_address_sub_one, e contract_instance_retrieval_current_class_id, e contract_instance_retrieval_deployer_addr, e contract_instance_retrieval_deployer_protocol_contract_address, e contract_instance_retrieval_derived_address, e contract_instance_retrieval_derived_address_pi_index, e contract_instance_retrieval_exists, e contract_instance_retrieval_incoming_viewing_key_x, e contract_instance_retrieval_incoming_viewing_key_y, e contract_instance_retrieval_init_hash, e contract_instance_retrieval_is_protocol_contract, e contract_instance_retrieval_max_protocol_contracts, e contract_instance_retrieval_nullifier_key_x, e contract_instance_retrieval_nullifier_key_y, e contract_instance_retrieval_nullifier_tree_root, e contract_instance_retrieval_original_class_id, e contract_instance_retrieval_outgoing_viewing_key_x, e contract_instance_retrieval_outgoing_viewing_key_y, e contract_instance_retrieval_protocol_contract_derived_address_inv, e contract_instance_retrieval_public_data_tree_root, e contract_instance_retrieval_salt, e contract_instance_retrieval_sel, e contract_instance_retrieval_should_check_for_update, e contract_instance_retrieval_should_check_nullifier, e contract_instance_retrieval_tagging_key_x, e contract_instance_retrieval_tagging_key_y, e data_copy_cd_copy_col_read, e data_copy_data_index_upper_bound, e data_copy_data_index_upper_bound_gt_offset, e data_copy_dst_out_of_range_err, e data_copy_err, e data_copy_is_top_level, e data_copy_mem_size, e data_copy_offset, e data_copy_offset_plus_size, e data_copy_offset_plus_size_is_gt, e data_copy_parent_id_inv, e data_copy_read_addr_plus_one, e data_copy_read_addr_upper_bound, e data_copy_reads_left_inv, e data_copy_sel_cd_copy_start, e data_copy_sel_end, e data_copy_sel_mem_read, e data_copy_sel_mem_write, e data_copy_sel_rd_copy_start, e data_copy_sel_start_no_err, e data_copy_sel_write_count_is_zero, e data_copy_src_addr, e data_copy_src_data_size, e data_copy_src_out_of_range_err, e data_copy_tag, e data_copy_value, e data_copy_write_addr_upper_bound, e data_copy_write_count_minus_one_inv, e data_copy_write_count_zero_inv, e ecc_add_mem_dst_addr_0_, e ecc_add_mem_dst_addr_1_, e ecc_add_mem_dst_addr_2_, e ecc_add_mem_err, e ecc_add_mem_execution_clk, e ecc_add_mem_max_mem_addr, e ecc_add_mem_p_is_inf, e ecc_add_mem_p_is_on_curve_eqn, e ecc_add_mem_p_is_on_curve_eqn_inv, e ecc_add_mem_p_x, e ecc_add_mem_p_x_n, e ecc_add_mem_p_y, e ecc_add_mem_p_y_n, e ecc_add_mem_q_is_inf, e ecc_add_mem_q_is_on_curve_eqn, e ecc_add_mem_q_is_on_curve_eqn_inv, e ecc_add_mem_q_x, e ecc_add_mem_q_x_n, e ecc_add_mem_q_y, e ecc_add_mem_q_y_n, e ecc_add_mem_res_is_inf, e ecc_add_mem_res_x, e ecc_add_mem_res_y, e ecc_add_mem_sel, e ecc_add_mem_sel_dst_out_of_range_err, e ecc_add_mem_sel_p_not_on_curve_err, e ecc_add_mem_sel_q_not_on_curve_err, e ecc_add_mem_sel_should_exec, e ecc_add_mem_space_id, e ecc_add_op, e ecc_double_op, e ecc_inv_2_p_y, e ecc_inv_x_diff, e ecc_inv_y_diff, e ecc_lambda, e ecc_p_is_inf, e ecc_p_x, e ecc_p_y, e ecc_q_is_inf, e ecc_q_x, e ecc_q_y, e ecc_r_is_inf, e ecc_r_x, e ecc_r_y, e ecc_result_infinity, e ecc_sel, e ecc_use_computed_result, e ecc_x_match, e ecc_y_match, e emit_unencrypted_log_discard, e emit_unencrypted_log_end, e emit_unencrypted_log_end_log_address_upper_bound, e emit_unencrypted_log_error, e emit_unencrypted_log_error_too_many_log_fields, e emit_unencrypted_log_error_too_many_logs_wrong_tag_is_static, e emit_unencrypted_log_expected_next_log_fields, e emit_unencrypted_log_is_static, e emit_unencrypted_log_log_size, e emit_unencrypted_log_max_mem_size, e emit_unencrypted_log_next_num_unencrypted_log_fields, e emit_unencrypted_log_prev_num_unencrypted_log_fields, e emit_unencrypted_log_public_inputs_value, e emit_unencrypted_log_public_logs_payload_length, e emit_unencrypted_log_remaining_rows_inv, e emit_unencrypted_log_sel_should_read_memory, e emit_unencrypted_log_tag, e emit_unencrypted_log_tag_inv, e emit_unencrypted_log_value, e execution_addressing_error_collection_inv, e execution_addressing_gas, e execution_addressing_mode, e execution_base_address_tag, e execution_base_address_tag_diff_inv, e execution_base_address_val, e execution_base_da_gas, e execution_batched_tags_diff_inv, e execution_batched_tags_diff_inv_reg, e execution_da_gas_left, e execution_da_gas_used, e execution_dying_context_diff_inv, e execution_dying_context_id_inv, e execution_dyn_gas_id, e execution_dynamic_da_gas, e execution_dynamic_da_gas_factor, e execution_dynamic_l2_gas, e execution_dynamic_l2_gas_factor, e execution_enqueued_call_end, e execution_envvar_pi_row_idx, e execution_ex_opcode, e execution_expected_tag_reg_0_, e execution_expected_tag_reg_1_, e execution_expected_tag_reg_2_, e execution_expected_tag_reg_3_, e execution_expected_tag_reg_4_, e execution_expected_tag_reg_5_, e execution_has_parent_ctx, e execution_highest_address, e execution_instr_length, e execution_internal_call_return_id_inv, e execution_is_address, e execution_is_da_gas_left_gt_allocated, e execution_is_dagasleft, e execution_is_dying_context, e execution_is_isstaticcall, e execution_is_l2_gas_left_gt_allocated, e execution_is_l2gasleft, e execution_is_parent_id_inv, e execution_is_sender, e execution_is_transactionfee, e execution_l1_to_l2_msg_leaf_in_range, e execution_l1_to_l2_msg_tree_leaf_count, e execution_l2_gas_left, e execution_l2_gas_used, e execution_max_data_writes_reached, e execution_mem_tag_reg_0_, e execution_mem_tag_reg_1_, e execution_mem_tag_reg_2_, e execution_mem_tag_reg_3_, e execution_mem_tag_reg_4_, e execution_mem_tag_reg_5_, e execution_nested_failure, e execution_nested_return, e execution_next_pc, e execution_note_hash_leaf_in_range, e execution_note_hash_tree_leaf_count, e execution_note_hash_tree_root, e execution_note_hash_tree_size, e execution_nullifier_tree_root, e execution_nullifier_tree_size, e execution_num_l2_to_l1_messages, e execution_num_note_hashes_emitted, e execution_num_nullifiers_emitted, e execution_num_p_limbs, e execution_num_relative_operands_inv, e execution_num_unencrypted_log_fields, e execution_op_0_, e execution_op_1_, e execution_op_2_, e execution_op_3_, e execution_op_4_, e execution_op_5_, e execution_op_6_, e execution_op_after_relative_0_, e execution_op_after_relative_1_, e execution_op_after_relative_2_, e execution_op_after_relative_3_, e execution_op_after_relative_4_, e execution_op_after_relative_5_, e execution_op_after_relative_6_, e execution_opcode_gas, e execution_out_of_gas_da, e execution_out_of_gas_l2, e execution_public_data_tree_root, e execution_public_data_tree_size, e execution_public_inputs_index, e execution_register_0_, e execution_register_1_, e execution_register_2_, e execution_register_3_, e execution_register_4_, e execution_register_5_, e execution_remaining_data_writes_inv, e execution_remaining_l2_to_l1_msgs_inv, e execution_remaining_note_hashes_inv, e execution_remaining_nullifiers_inv, e execution_retrieved_bytecodes_tree_root, e execution_retrieved_bytecodes_tree_size, e execution_rop_0_, e execution_rop_1_, e execution_rop_2_, e execution_rop_3_, e execution_rop_4_, e execution_rop_5_, e execution_rop_6_, e execution_rop_tag_0_, e execution_rop_tag_1_, e execution_rop_tag_2_, e execution_rop_tag_3_, e execution_rop_tag_4_, e execution_rop_tag_5_, e execution_rop_tag_6_, e execution_rw_reg_0_, e execution_rw_reg_1_, e execution_rw_reg_2_, e execution_rw_reg_3_, e execution_rw_reg_4_, e execution_rw_reg_5_, e execution_sel_addressing_error, e execution_sel_base_address_failure, e execution_sel_bytecode_retrieval_failure, e execution_sel_bytecode_retrieval_success, e execution_sel_do_base_check, e execution_sel_enter_call, e execution_sel_envvar_pi_lookup_col0, e execution_sel_envvar_pi_lookup_col1, e execution_sel_error, e execution_sel_exec_dispatch_alu, e execution_sel_exec_dispatch_bitwise, e execution_sel_exec_dispatch_calldata_copy, e execution_sel_exec_dispatch_cast, e execution_sel_exec_dispatch_ecc_add, e execution_sel_exec_dispatch_emit_unencrypted_log, e execution_sel_exec_dispatch_execution, e execution_sel_exec_dispatch_get_contract_instance, e execution_sel_exec_dispatch_keccakf1600, e execution_sel_exec_dispatch_poseidon2_perm, e execution_sel_exec_dispatch_returndata_copy, e execution_sel_exec_dispatch_set, e execution_sel_exec_dispatch_sha256_compression, e execution_sel_exec_dispatch_to_radix, e execution_sel_execute_call, e execution_sel_execute_debug_log, e execution_sel_execute_emit_notehash, e execution_sel_execute_emit_nullifier, e execution_sel_execute_get_env_var, e execution_sel_execute_internal_call, e execution_sel_execute_internal_return, e execution_sel_execute_jump, e execution_sel_execute_jumpi, e execution_sel_execute_l1_to_l2_message_exists, e execution_sel_execute_mov, e execution_sel_execute_notehash_exists, e execution_sel_execute_nullifier_exists, e execution_sel_execute_return, e execution_sel_execute_returndata_size, e execution_sel_execute_revert, e execution_sel_execute_send_l2_to_l1_msg, e execution_sel_execute_sload, e execution_sel_execute_sstore, e execution_sel_execute_static_call, e execution_sel_execute_success_copy, e execution_sel_exit_call, e execution_sel_failure, e execution_sel_gas_bitwise, e execution_sel_gas_calldata_copy, e execution_sel_gas_emit_unencrypted_log, e execution_sel_gas_returndata_copy, e execution_sel_gas_sstore, e execution_sel_gas_to_radix, e execution_sel_instruction_fetching_failure, e execution_sel_instruction_fetching_success, e execution_sel_l2_to_l1_msg_limit_error, e execution_sel_lookup_num_p_limbs, e execution_sel_mem_op_reg_0_, e execution_sel_mem_op_reg_1_, e execution_sel_mem_op_reg_2_, e execution_sel_mem_op_reg_3_, e execution_sel_mem_op_reg_4_, e execution_sel_mem_op_reg_5_, e execution_sel_op_do_overflow_check_0_, e execution_sel_op_do_overflow_check_1_, e execution_sel_op_do_overflow_check_2_, e execution_sel_op_do_overflow_check_3_, e execution_sel_op_do_overflow_check_4_, e execution_sel_op_do_overflow_check_5_, e execution_sel_op_do_overflow_check_6_, e execution_sel_op_is_address_0_, e execution_sel_op_is_address_1_, e execution_sel_op_is_address_2_, e execution_sel_op_is_address_3_, e execution_sel_op_is_address_4_, e execution_sel_op_is_address_5_, e execution_sel_op_is_address_6_, e execution_sel_op_is_indirect_wire_0_, e execution_sel_op_is_indirect_wire_1_, e execution_sel_op_is_indirect_wire_2_, e execution_sel_op_is_indirect_wire_3_, e execution_sel_op_is_indirect_wire_4_, e execution_sel_op_is_indirect_wire_5_, e execution_sel_op_is_indirect_wire_6_, e execution_sel_op_is_indirect_wire_7_, e execution_sel_op_is_relative_wire_0_, e execution_sel_op_is_relative_wire_1_, e execution_sel_op_is_relative_wire_2_, e execution_sel_op_is_relative_wire_3_, e execution_sel_op_is_relative_wire_4_, e execution_sel_op_is_relative_wire_5_, e execution_sel_op_is_relative_wire_6_, e execution_sel_op_is_relative_wire_7_, e execution_sel_op_reg_effective_0_, e execution_sel_op_reg_effective_1_, e execution_sel_op_reg_effective_2_, e execution_sel_op_reg_effective_3_, e execution_sel_op_reg_effective_4_, e execution_sel_op_reg_effective_5_, e execution_sel_opcode_error, e execution_sel_out_of_gas, e execution_sel_radix_gt_256, e execution_sel_reached_max_note_hashes, e execution_sel_reached_max_nullifiers, e execution_sel_read_unwind_call_stack, e execution_sel_register_read_error, e execution_sel_relative_overflow_0_, e execution_sel_relative_overflow_1_, e execution_sel_relative_overflow_2_, e execution_sel_relative_overflow_3_, e execution_sel_relative_overflow_4_, e execution_sel_relative_overflow_5_, e execution_sel_relative_overflow_6_, e execution_sel_should_apply_indirection_0_, e execution_sel_should_apply_indirection_1_, e execution_sel_should_apply_indirection_2_, e execution_sel_should_apply_indirection_3_, e execution_sel_should_apply_indirection_4_, e execution_sel_should_apply_indirection_5_, e execution_sel_should_apply_indirection_6_, e execution_sel_should_check_gas, e execution_sel_should_execute_opcode, e execution_sel_should_read_registers, e execution_sel_should_write_registers, e execution_sel_some_final_check_failed, e execution_sel_tag_check_reg_0_, e execution_sel_tag_check_reg_1_, e execution_sel_tag_check_reg_2_, e execution_sel_tag_check_reg_3_, e execution_sel_tag_check_reg_4_, e execution_sel_tag_check_reg_5_, e execution_sel_use_num_limbs, e execution_sel_write_l2_to_l1_msg, e execution_sel_write_note_hash, e execution_sel_write_nullifier, e execution_sel_write_public_data, e execution_subtrace_id, e execution_subtrace_operation_id, e execution_total_gas_da, e execution_total_gas_l2, e execution_two_five_six, e execution_value_from_pi, e execution_written_public_data_slots_tree_root, e execution_written_public_data_slots_tree_size, e ff_gt_a, e ff_gt_b, e ff_gt_borrow, e ff_gt_cmp_rng_ctr_inv, e ff_gt_constant_128, e ff_gt_p_a_borrow, e ff_gt_p_b_borrow, e ff_gt_res_hi, e ff_gt_res_lo, e ff_gt_result, e ff_gt_sel_shift_rng, e get_contract_instance_clk, e get_contract_instance_contract_address, e get_contract_instance_dst_offset, e get_contract_instance_dst_offset_diff_max_inv, e get_contract_instance_exists_tag, e get_contract_instance_instance_exists, e get_contract_instance_is_class_id, e get_contract_instance_is_deployer, e get_contract_instance_is_init_hash, e get_contract_instance_is_valid_member_enum, e get_contract_instance_is_valid_writes_in_bounds, e get_contract_instance_member_enum, e get_contract_instance_member_tag, e get_contract_instance_member_write_offset, e get_contract_instance_nullifier_tree_root, e get_contract_instance_public_data_tree_root, e get_contract_instance_retrieved_class_id, e get_contract_instance_retrieved_deployer_addr, e get_contract_instance_retrieved_init_hash, e get_contract_instance_sel, e get_contract_instance_sel_error, e get_contract_instance_selected_member, e get_contract_instance_space_id, e gt_abs_diff, e gt_input_a, e gt_input_b, e gt_num_bits, e gt_res, e gt_sel, e gt_sel_addressing, e gt_sel_alu, e gt_sel_gas, e gt_sel_others, e gt_sel_sha256, e instr_fetching_addressing_mode, e instr_fetching_bd0, e instr_fetching_bd1, e instr_fetching_bd10, e instr_fetching_bd11, e instr_fetching_bd12, e instr_fetching_bd13, e instr_fetching_bd14, e instr_fetching_bd15, e instr_fetching_bd16, e instr_fetching_bd17, e instr_fetching_bd18, e instr_fetching_bd19, e instr_fetching_bd2, e instr_fetching_bd20, e instr_fetching_bd21, e instr_fetching_bd22, e instr_fetching_bd23, e instr_fetching_bd24, e instr_fetching_bd25, e instr_fetching_bd26, e instr_fetching_bd27, e instr_fetching_bd28, e instr_fetching_bd29, e instr_fetching_bd3, e instr_fetching_bd30, e instr_fetching_bd31, e instr_fetching_bd32, e instr_fetching_bd33, e instr_fetching_bd34, e instr_fetching_bd35, e instr_fetching_bd36, e instr_fetching_bd4, e instr_fetching_bd5, e instr_fetching_bd6, e instr_fetching_bd7, e instr_fetching_bd8, e instr_fetching_bd9, e instr_fetching_bytecode_id, e instr_fetching_bytecode_size, e instr_fetching_bytes_to_read, e instr_fetching_exec_opcode, e instr_fetching_instr_abs_diff, e instr_fetching_instr_out_of_range, e instr_fetching_instr_size, e instr_fetching_op1, e instr_fetching_op2, e instr_fetching_op3, e instr_fetching_op4, e instr_fetching_op5, e instr_fetching_op6, e instr_fetching_op7, e instr_fetching_opcode_out_of_range, e instr_fetching_pc, e instr_fetching_pc_abs_diff, e instr_fetching_pc_out_of_range, e instr_fetching_pc_size_in_bits, e instr_fetching_sel, e instr_fetching_sel_has_tag, e instr_fetching_sel_op_dc_0, e instr_fetching_sel_op_dc_1, e instr_fetching_sel_op_dc_10, e instr_fetching_sel_op_dc_11, e instr_fetching_sel_op_dc_12, e instr_fetching_sel_op_dc_13, e instr_fetching_sel_op_dc_14, e instr_fetching_sel_op_dc_15, e instr_fetching_sel_op_dc_16, e instr_fetching_sel_op_dc_2, e instr_fetching_sel_op_dc_3, e instr_fetching_sel_op_dc_4, e instr_fetching_sel_op_dc_5, e instr_fetching_sel_op_dc_6, e instr_fetching_sel_op_dc_7, e instr_fetching_sel_op_dc_8, e instr_fetching_sel_op_dc_9, e instr_fetching_sel_parsing_err, e instr_fetching_sel_pc_in_range, e instr_fetching_sel_tag_is_op2, e instr_fetching_tag_out_of_range, e instr_fetching_tag_value, e internal_call_stack_context_id, e internal_call_stack_entered_call_id, e internal_call_stack_id, e internal_call_stack_return_id, e internal_call_stack_return_pc, e internal_call_stack_sel, e keccak_memory_ctr_end, e keccak_memory_ctr_inv, e keccak_memory_last, e keccak_memory_num_rounds, e keccak_memory_single_tag_error, e keccak_memory_state_size_min_ctr_inv, e keccak_memory_tag, e keccak_memory_tag_min_u64_inv, e keccak_memory_val_24_, e keccakf1600_bitwise_and_op_id, e keccakf1600_bitwise_xor_op_id, e keccakf1600_dst_out_of_range_error, e keccakf1600_error, e keccakf1600_highest_slice_address, e keccakf1600_last, e keccakf1600_rot_64_min_len_01, e keccakf1600_rot_64_min_len_03, e keccakf1600_rot_64_min_len_11, e keccakf1600_rot_64_min_len_13, e keccakf1600_rot_64_min_len_20, e keccakf1600_rot_64_min_len_22, e keccakf1600_rot_64_min_len_24, e keccakf1600_rot_64_min_len_31, e keccakf1600_rot_64_min_len_34, e keccakf1600_rot_64_min_len_42, e keccakf1600_rot_len_02, e keccakf1600_rot_len_04, e keccakf1600_rot_len_10, e keccakf1600_rot_len_12, e keccakf1600_rot_len_14, e keccakf1600_rot_len_21, e keccakf1600_rot_len_23, e keccakf1600_rot_len_30, e keccakf1600_rot_len_32, e keccakf1600_rot_len_33, e keccakf1600_rot_len_40, e keccakf1600_rot_len_41, e keccakf1600_rot_len_43, e keccakf1600_rot_len_44, e keccakf1600_round_cst, e keccakf1600_round_inv, e keccakf1600_sel_slice_read, e keccakf1600_sel_slice_write, e keccakf1600_src_addr, e keccakf1600_src_out_of_range_error, e keccakf1600_state_chi_00, e keccakf1600_state_chi_01, e keccakf1600_state_chi_02, e keccakf1600_state_chi_03, e keccakf1600_state_chi_04, e keccakf1600_state_chi_10, e keccakf1600_state_chi_11, e keccakf1600_state_chi_12, e keccakf1600_state_chi_13, e keccakf1600_state_chi_14, e keccakf1600_state_chi_20, e keccakf1600_state_chi_21, e keccakf1600_state_chi_22, e keccakf1600_state_chi_23, e keccakf1600_state_chi_24, e keccakf1600_state_chi_30, e keccakf1600_state_chi_31, e keccakf1600_state_chi_32, e keccakf1600_state_chi_33, e keccakf1600_state_chi_34, e keccakf1600_state_chi_40, e keccakf1600_state_chi_41, e keccakf1600_state_chi_42, e keccakf1600_state_chi_43, e keccakf1600_state_chi_44, e keccakf1600_state_iota_00, e keccakf1600_state_pi_and_00, e keccakf1600_state_pi_and_01, e keccakf1600_state_pi_and_02, e keccakf1600_state_pi_and_03, e keccakf1600_state_pi_and_04, e keccakf1600_state_pi_and_10, e keccakf1600_state_pi_and_11, e keccakf1600_state_pi_and_12, e keccakf1600_state_pi_and_13, e keccakf1600_state_pi_and_14, e keccakf1600_state_pi_and_20, e keccakf1600_state_pi_and_21, e keccakf1600_state_pi_and_22, e keccakf1600_state_pi_and_23, e keccakf1600_state_pi_and_24, e keccakf1600_state_pi_and_30, e keccakf1600_state_pi_and_31, e keccakf1600_state_pi_and_32, e keccakf1600_state_pi_and_33, e keccakf1600_state_pi_and_34, e keccakf1600_state_pi_and_40, e keccakf1600_state_pi_and_41, e keccakf1600_state_pi_and_42, e keccakf1600_state_pi_and_43, e keccakf1600_state_pi_and_44, e keccakf1600_state_pi_not_00, e keccakf1600_state_pi_not_01, e keccakf1600_state_pi_not_02, e keccakf1600_state_pi_not_03, e keccakf1600_state_pi_not_04, e keccakf1600_state_pi_not_10, e keccakf1600_state_pi_not_11, e keccakf1600_state_pi_not_12, e keccakf1600_state_pi_not_13, e keccakf1600_state_pi_not_14, e keccakf1600_state_pi_not_20, e keccakf1600_state_pi_not_21, e keccakf1600_state_pi_not_22, e keccakf1600_state_pi_not_23, e keccakf1600_state_pi_not_24, e keccakf1600_state_pi_not_30, e keccakf1600_state_pi_not_31, e keccakf1600_state_pi_not_32, e keccakf1600_state_pi_not_33, e keccakf1600_state_pi_not_34, e keccakf1600_state_pi_not_40, e keccakf1600_state_pi_not_41, e keccakf1600_state_pi_not_42, e keccakf1600_state_pi_not_43, e keccakf1600_state_pi_not_44, e keccakf1600_state_rho_01, e keccakf1600_state_rho_02, e keccakf1600_state_rho_03, e keccakf1600_state_rho_04, e keccakf1600_state_rho_10, e keccakf1600_state_rho_11, e keccakf1600_state_rho_12, e keccakf1600_state_rho_13, e keccakf1600_state_rho_14, e keccakf1600_state_rho_20, e keccakf1600_state_rho_21, e keccakf1600_state_rho_22, e keccakf1600_state_rho_23, e keccakf1600_state_rho_24, e keccakf1600_state_rho_30, e keccakf1600_state_rho_31, e keccakf1600_state_rho_32, e keccakf1600_state_rho_33, e keccakf1600_state_rho_34, e keccakf1600_state_rho_40, e keccakf1600_state_rho_41, e keccakf1600_state_rho_42, e keccakf1600_state_rho_43, e keccakf1600_state_rho_44, e keccakf1600_state_theta_00, e keccakf1600_state_theta_01, e keccakf1600_state_theta_02, e keccakf1600_state_theta_03, e keccakf1600_state_theta_04, e keccakf1600_state_theta_10, e keccakf1600_state_theta_11, e keccakf1600_state_theta_12, e keccakf1600_state_theta_13, e keccakf1600_state_theta_14, e keccakf1600_state_theta_20, e keccakf1600_state_theta_21, e keccakf1600_state_theta_22, e keccakf1600_state_theta_23, e keccakf1600_state_theta_24, e keccakf1600_state_theta_30, e keccakf1600_state_theta_31, e keccakf1600_state_theta_32, e keccakf1600_state_theta_33, e keccakf1600_state_theta_34, e keccakf1600_state_theta_40, e keccakf1600_state_theta_41, e keccakf1600_state_theta_42, e keccakf1600_state_theta_43, e keccakf1600_state_theta_44, e keccakf1600_state_theta_hi_01, e keccakf1600_state_theta_hi_02, e keccakf1600_state_theta_hi_03, e keccakf1600_state_theta_hi_04, e keccakf1600_state_theta_hi_10, e keccakf1600_state_theta_hi_11, e keccakf1600_state_theta_hi_12, e keccakf1600_state_theta_hi_13, e keccakf1600_state_theta_hi_14, e keccakf1600_state_theta_hi_20, e keccakf1600_state_theta_hi_21, e keccakf1600_state_theta_hi_22, e keccakf1600_state_theta_hi_23, e keccakf1600_state_theta_hi_24, e keccakf1600_state_theta_hi_30, e keccakf1600_state_theta_hi_31, e keccakf1600_state_theta_hi_32, e keccakf1600_state_theta_hi_33, e keccakf1600_state_theta_hi_34, e keccakf1600_state_theta_hi_40, e keccakf1600_state_theta_hi_41, e keccakf1600_state_theta_hi_42, e keccakf1600_state_theta_hi_43, e keccakf1600_state_theta_hi_44, e keccakf1600_state_theta_low_01, e keccakf1600_state_theta_low_02, e keccakf1600_state_theta_low_03, e keccakf1600_state_theta_low_04, e keccakf1600_state_theta_low_10, e keccakf1600_state_theta_low_11, e keccakf1600_state_theta_low_12, e keccakf1600_state_theta_low_13, e keccakf1600_state_theta_low_14, e keccakf1600_state_theta_low_20, e keccakf1600_state_theta_low_21, e keccakf1600_state_theta_low_22, e keccakf1600_state_theta_low_23, e keccakf1600_state_theta_low_24, e keccakf1600_state_theta_low_30, e keccakf1600_state_theta_low_31, e keccakf1600_state_theta_low_32, e keccakf1600_state_theta_low_33, e keccakf1600_state_theta_low_34, e keccakf1600_state_theta_low_40, e keccakf1600_state_theta_low_41, e keccakf1600_state_theta_low_42, e keccakf1600_state_theta_low_43, e keccakf1600_state_theta_low_44, e keccakf1600_tag_error, e keccakf1600_tag_u64, e keccakf1600_theta_combined_xor_0, e keccakf1600_theta_combined_xor_1, e keccakf1600_theta_combined_xor_2, e keccakf1600_theta_combined_xor_3, e keccakf1600_theta_combined_xor_4, e keccakf1600_theta_xor_01, e keccakf1600_theta_xor_02, e keccakf1600_theta_xor_03, e keccakf1600_theta_xor_11, e keccakf1600_theta_xor_12, e keccakf1600_theta_xor_13, e keccakf1600_theta_xor_21, e keccakf1600_theta_xor_22, e keccakf1600_theta_xor_23, e keccakf1600_theta_xor_31, e keccakf1600_theta_xor_32, e keccakf1600_theta_xor_33, e keccakf1600_theta_xor_41, e keccakf1600_theta_xor_42, e keccakf1600_theta_xor_43, e keccakf1600_theta_xor_row_0, e keccakf1600_theta_xor_row_1, e keccakf1600_theta_xor_row_2, e keccakf1600_theta_xor_row_3, e keccakf1600_theta_xor_row_4, e keccakf1600_theta_xor_row_low63_0, e keccakf1600_theta_xor_row_low63_1, e keccakf1600_theta_xor_row_low63_2, e keccakf1600_theta_xor_row_low63_3, e keccakf1600_theta_xor_row_low63_4, e keccakf1600_theta_xor_row_msb_0, e keccakf1600_theta_xor_row_msb_1, e keccakf1600_theta_xor_row_msb_2, e keccakf1600_theta_xor_row_msb_3, e keccakf1600_theta_xor_row_msb_4, e keccakf1600_theta_xor_row_rotl1_0, e keccakf1600_theta_xor_row_rotl1_1, e keccakf1600_theta_xor_row_rotl1_2, e keccakf1600_theta_xor_row_rotl1_3, e keccakf1600_theta_xor_row_rotl1_4, e l1_to_l2_message_tree_check_exists, e l1_to_l2_message_tree_check_l1_to_l2_message_tree_height, e l1_to_l2_message_tree_check_leaf_index, e l1_to_l2_message_tree_check_leaf_value, e l1_to_l2_message_tree_check_leaf_value_msg_hash_diff_inv, e l1_to_l2_message_tree_check_msg_hash, e l1_to_l2_message_tree_check_root, e l1_to_l2_message_tree_check_sel, e memory_address, e memory_clk, e memory_diff, e memory_glob_addr_diff_inv, e memory_last_access, e memory_limb_0_, e memory_limb_1_, e memory_limb_2_, e memory_max_bits, e memory_sel_addressing_base, e memory_sel_addressing_indirect_0_, e memory_sel_addressing_indirect_1_, e memory_sel_addressing_indirect_2_, e memory_sel_addressing_indirect_3_, e memory_sel_addressing_indirect_4_, e memory_sel_addressing_indirect_5_, e memory_sel_addressing_indirect_6_, e memory_sel_data_copy_read, e memory_sel_data_copy_write, e memory_sel_ecc_write_0_, e memory_sel_ecc_write_1_, e memory_sel_ecc_write_2_, e memory_sel_get_contract_instance_exists_write, e memory_sel_get_contract_instance_member_write, e memory_sel_keccak, e memory_sel_poseidon2_read_0_, e memory_sel_poseidon2_read_1_, e memory_sel_poseidon2_read_2_, e memory_sel_poseidon2_read_3_, e memory_sel_poseidon2_write_0_, e memory_sel_poseidon2_write_1_, e memory_sel_poseidon2_write_2_, e memory_sel_poseidon2_write_3_, e memory_sel_register_op_0_, e memory_sel_register_op_1_, e memory_sel_register_op_2_, e memory_sel_register_op_3_, e memory_sel_register_op_4_, e memory_sel_register_op_5_, e memory_sel_rng_chk, e memory_sel_rng_write, e memory_sel_sha256_op_0_, e memory_sel_sha256_op_1_, e memory_sel_sha256_op_2_, e memory_sel_sha256_op_3_, e memory_sel_sha256_op_4_, e memory_sel_sha256_op_5_, e memory_sel_sha256_op_6_, e memory_sel_sha256_op_7_, e memory_sel_sha256_read, e memory_sel_tag_is_ff, e memory_sel_to_radix_write, e memory_sel_unencrypted_log_read, e memory_space_id, e memory_tag_ff_diff_inv, e merkle_check_end, e merkle_check_index_is_even, e merkle_check_path_len_min_one_inv, e merkle_check_read_left_node, e merkle_check_read_output_hash, e merkle_check_read_right_node, e merkle_check_sibling, e merkle_check_start, e merkle_check_write_left_node, e merkle_check_write_output_hash, e merkle_check_write_right_node, e note_hash_tree_check_address, e note_hash_tree_check_discard, e note_hash_tree_check_exists, e note_hash_tree_check_first_nullifier, e note_hash_tree_check_first_nullifier_pi_index, e note_hash_tree_check_leaf_index, e note_hash_tree_check_next_leaf_value, e note_hash_tree_check_next_root, e note_hash_tree_check_nonce, e note_hash_tree_check_nonce_separator, e note_hash_tree_check_note_hash, e note_hash_tree_check_note_hash_index, e note_hash_tree_check_note_hash_tree_height, e note_hash_tree_check_prev_leaf_value, e note_hash_tree_check_prev_leaf_value_unique_note_hash_diff_inv, e note_hash_tree_check_prev_root, e note_hash_tree_check_public_inputs_index, e note_hash_tree_check_sel, e note_hash_tree_check_should_silo, e note_hash_tree_check_should_unique, e note_hash_tree_check_should_write_to_public_inputs, e note_hash_tree_check_siloed_note_hash, e note_hash_tree_check_siloing_separator, e note_hash_tree_check_unique_note_hash, e note_hash_tree_check_unique_note_hash_separator, e note_hash_tree_check_write, e nullifier_check_address, e nullifier_check_discard, e nullifier_check_exists, e nullifier_check_intermediate_root, e nullifier_check_leaf_not_exists, e nullifier_check_low_leaf_hash, e nullifier_check_low_leaf_index, e nullifier_check_low_leaf_next_index, e nullifier_check_low_leaf_next_nullifier, e nullifier_check_low_leaf_nullifier, e nullifier_check_new_leaf_hash, e nullifier_check_next_nullifier_inv, e nullifier_check_next_nullifier_is_nonzero, e nullifier_check_nullifier, e nullifier_check_nullifier_index, e nullifier_check_nullifier_low_leaf_nullifier_diff_inv, e nullifier_check_public_inputs_index, e nullifier_check_root, e nullifier_check_sel, e nullifier_check_should_insert, e nullifier_check_should_silo, e nullifier_check_should_write_to_public_inputs, e nullifier_check_siloed_nullifier, e nullifier_check_siloing_separator, e nullifier_check_tree_height, e nullifier_check_tree_size_before_write, e nullifier_check_updated_low_leaf_hash, e nullifier_check_updated_low_leaf_next_index, e nullifier_check_updated_low_leaf_next_nullifier, e nullifier_check_write, e nullifier_check_write_root, e poseidon2_hash_b_0, e poseidon2_hash_b_1, e poseidon2_hash_b_2, e poseidon2_hash_b_3, e poseidon2_hash_end, e poseidon2_hash_input_len, e poseidon2_hash_num_perm_rounds_rem_inv, e poseidon2_hash_padding, e poseidon2_perm_B_10_0, e poseidon2_perm_B_10_1, e poseidon2_perm_B_10_2, e poseidon2_perm_B_10_3, e poseidon2_perm_B_11_0, e poseidon2_perm_B_11_1, e poseidon2_perm_B_11_2, e poseidon2_perm_B_11_3, e poseidon2_perm_B_12_0, e poseidon2_perm_B_12_1, e poseidon2_perm_B_12_2, e poseidon2_perm_B_12_3, e poseidon2_perm_B_13_0, e poseidon2_perm_B_13_1, e poseidon2_perm_B_13_2, e poseidon2_perm_B_13_3, e poseidon2_perm_B_14_0, e poseidon2_perm_B_14_1, e poseidon2_perm_B_14_2, e poseidon2_perm_B_14_3, e poseidon2_perm_B_15_0, e poseidon2_perm_B_15_1, e poseidon2_perm_B_15_2, e poseidon2_perm_B_15_3, e poseidon2_perm_B_16_0, e poseidon2_perm_B_16_1, e poseidon2_perm_B_16_2, e poseidon2_perm_B_16_3, e poseidon2_perm_B_17_0, e poseidon2_perm_B_17_1, e poseidon2_perm_B_17_2, e poseidon2_perm_B_17_3, e poseidon2_perm_B_18_0, e poseidon2_perm_B_18_1, e poseidon2_perm_B_18_2, e poseidon2_perm_B_18_3, e poseidon2_perm_B_19_0, e poseidon2_perm_B_19_1, e poseidon2_perm_B_19_2, e poseidon2_perm_B_19_3, e poseidon2_perm_B_20_0, e poseidon2_perm_B_20_1, e poseidon2_perm_B_20_2, e poseidon2_perm_B_20_3, e poseidon2_perm_B_21_0, e poseidon2_perm_B_21_1, e poseidon2_perm_B_21_2, e poseidon2_perm_B_21_3, e poseidon2_perm_B_22_0, e poseidon2_perm_B_22_1, e poseidon2_perm_B_22_2, e poseidon2_perm_B_22_3, e poseidon2_perm_B_23_0, e poseidon2_perm_B_23_1, e poseidon2_perm_B_23_2, e poseidon2_perm_B_23_3, e poseidon2_perm_B_24_0, e poseidon2_perm_B_24_1, e poseidon2_perm_B_24_2, e poseidon2_perm_B_24_3, e poseidon2_perm_B_25_0, e poseidon2_perm_B_25_1, e poseidon2_perm_B_25_2, e poseidon2_perm_B_25_3, e poseidon2_perm_B_26_0, e poseidon2_perm_B_26_1, e poseidon2_perm_B_26_2, e poseidon2_perm_B_26_3, e poseidon2_perm_B_27_0, e poseidon2_perm_B_27_1, e poseidon2_perm_B_27_2, e poseidon2_perm_B_27_3, e poseidon2_perm_B_28_0, e poseidon2_perm_B_28_1, e poseidon2_perm_B_28_2, e poseidon2_perm_B_28_3, e poseidon2_perm_B_29_0, e poseidon2_perm_B_29_1, e poseidon2_perm_B_29_2, e poseidon2_perm_B_29_3, e poseidon2_perm_B_30_0, e poseidon2_perm_B_30_1, e poseidon2_perm_B_30_2, e poseidon2_perm_B_30_3, e poseidon2_perm_B_31_0, e poseidon2_perm_B_31_1, e poseidon2_perm_B_31_2, e poseidon2_perm_B_31_3, e poseidon2_perm_B_32_0, e poseidon2_perm_B_32_1, e poseidon2_perm_B_32_2, e poseidon2_perm_B_32_3, e poseidon2_perm_B_33_0, e poseidon2_perm_B_33_1, e poseidon2_perm_B_33_2, e poseidon2_perm_B_33_3, e poseidon2_perm_B_34_0, e poseidon2_perm_B_34_1, e poseidon2_perm_B_34_2, e poseidon2_perm_B_34_3, e poseidon2_perm_B_35_0, e poseidon2_perm_B_35_1, e poseidon2_perm_B_35_2, e poseidon2_perm_B_35_3, e poseidon2_perm_B_36_0, e poseidon2_perm_B_36_1, e poseidon2_perm_B_36_2, e poseidon2_perm_B_36_3, e poseidon2_perm_B_37_0, e poseidon2_perm_B_37_1, e poseidon2_perm_B_37_2, e poseidon2_perm_B_37_3, e poseidon2_perm_B_38_0, e poseidon2_perm_B_38_1, e poseidon2_perm_B_38_2, e poseidon2_perm_B_38_3, e poseidon2_perm_B_39_0, e poseidon2_perm_B_39_1, e poseidon2_perm_B_39_2, e poseidon2_perm_B_39_3, e poseidon2_perm_B_40_0, e poseidon2_perm_B_40_1, e poseidon2_perm_B_40_2, e poseidon2_perm_B_40_3, e poseidon2_perm_B_41_0, e poseidon2_perm_B_41_1, e poseidon2_perm_B_41_2, e poseidon2_perm_B_41_3, e poseidon2_perm_B_42_0, e poseidon2_perm_B_42_1, e poseidon2_perm_B_42_2, e poseidon2_perm_B_42_3, e poseidon2_perm_B_43_0, e poseidon2_perm_B_43_1, e poseidon2_perm_B_43_2, e poseidon2_perm_B_43_3, e poseidon2_perm_B_44_0, e poseidon2_perm_B_44_1, e poseidon2_perm_B_44_2, e poseidon2_perm_B_44_3, e poseidon2_perm_B_45_0, e poseidon2_perm_B_45_1, e poseidon2_perm_B_45_2, e poseidon2_perm_B_45_3, e poseidon2_perm_B_46_0, e poseidon2_perm_B_46_1, e poseidon2_perm_B_46_2, e poseidon2_perm_B_46_3, e poseidon2_perm_B_47_0, e poseidon2_perm_B_47_1, e poseidon2_perm_B_47_2, e poseidon2_perm_B_47_3, e poseidon2_perm_B_48_0, e poseidon2_perm_B_48_1, e poseidon2_perm_B_48_2, e poseidon2_perm_B_48_3, e poseidon2_perm_B_49_0, e poseidon2_perm_B_49_1, e poseidon2_perm_B_49_2, e poseidon2_perm_B_49_3, e poseidon2_perm_B_4_0, e poseidon2_perm_B_4_1, e poseidon2_perm_B_4_2, e poseidon2_perm_B_4_3, e poseidon2_perm_B_50_0, e poseidon2_perm_B_50_1, e poseidon2_perm_B_50_2, e poseidon2_perm_B_50_3, e poseidon2_perm_B_51_0, e poseidon2_perm_B_51_1, e poseidon2_perm_B_51_2, e poseidon2_perm_B_51_3, e poseidon2_perm_B_52_0, e poseidon2_perm_B_52_1, e poseidon2_perm_B_52_2, e poseidon2_perm_B_52_3, e poseidon2_perm_B_53_0, e poseidon2_perm_B_53_1, e poseidon2_perm_B_53_2, e poseidon2_perm_B_53_3, e poseidon2_perm_B_54_0, e poseidon2_perm_B_54_1, e poseidon2_perm_B_54_2, e poseidon2_perm_B_54_3, e poseidon2_perm_B_55_0, e poseidon2_perm_B_55_1, e poseidon2_perm_B_55_2, e poseidon2_perm_B_55_3, e poseidon2_perm_B_56_0, e poseidon2_perm_B_56_1, e poseidon2_perm_B_56_2, e poseidon2_perm_B_56_3, e poseidon2_perm_B_57_0, e poseidon2_perm_B_57_1, e poseidon2_perm_B_57_2, e poseidon2_perm_B_57_3, e poseidon2_perm_B_58_0, e poseidon2_perm_B_58_1, e poseidon2_perm_B_58_2, e poseidon2_perm_B_58_3, e poseidon2_perm_B_59_0, e poseidon2_perm_B_59_1, e poseidon2_perm_B_59_2, e poseidon2_perm_B_59_3, e poseidon2_perm_B_5_0, e poseidon2_perm_B_5_1, e poseidon2_perm_B_5_2, e poseidon2_perm_B_5_3, e poseidon2_perm_B_6_0, e poseidon2_perm_B_6_1, e poseidon2_perm_B_6_2, e poseidon2_perm_B_6_3, e poseidon2_perm_B_7_0, e poseidon2_perm_B_7_1, e poseidon2_perm_B_7_2, e poseidon2_perm_B_7_3, e poseidon2_perm_B_8_0, e poseidon2_perm_B_8_1, e poseidon2_perm_B_8_2, e poseidon2_perm_B_8_3, e poseidon2_perm_B_9_0, e poseidon2_perm_B_9_1, e poseidon2_perm_B_9_2, e poseidon2_perm_B_9_3, e poseidon2_perm_EXT_LAYER_4, e poseidon2_perm_EXT_LAYER_5, e poseidon2_perm_EXT_LAYER_6, e poseidon2_perm_EXT_LAYER_7, e poseidon2_perm_T_0_4, e poseidon2_perm_T_0_5, e poseidon2_perm_T_0_6, e poseidon2_perm_T_0_7, e poseidon2_perm_T_1_4, e poseidon2_perm_T_1_5, e poseidon2_perm_T_1_6, e poseidon2_perm_T_1_7, e poseidon2_perm_T_2_4, e poseidon2_perm_T_2_5, e poseidon2_perm_T_2_6, e poseidon2_perm_T_2_7, e poseidon2_perm_T_3_4, e poseidon2_perm_T_3_5, e poseidon2_perm_T_3_6, e poseidon2_perm_T_3_7, e poseidon2_perm_T_60_4, e poseidon2_perm_T_60_5, e poseidon2_perm_T_60_6, e poseidon2_perm_T_60_7, e poseidon2_perm_T_61_4, e poseidon2_perm_T_61_5, e poseidon2_perm_T_61_6, e poseidon2_perm_T_61_7, e poseidon2_perm_T_62_4, e poseidon2_perm_T_62_5, e poseidon2_perm_T_62_6, e poseidon2_perm_T_62_7, e poseidon2_perm_T_63_4, e poseidon2_perm_T_63_5, e poseidon2_perm_T_63_6, e poseidon2_perm_T_63_7, e poseidon2_perm_a_0, e poseidon2_perm_a_1, e poseidon2_perm_a_2, e poseidon2_perm_a_3, e poseidon2_perm_b_0, e poseidon2_perm_b_1, e poseidon2_perm_b_2, e poseidon2_perm_b_3, e poseidon2_perm_mem_batch_tag_inv, e poseidon2_perm_mem_err, e poseidon2_perm_mem_execution_clk, e poseidon2_perm_mem_input_0_, e poseidon2_perm_mem_input_1_, e poseidon2_perm_mem_input_2_, e poseidon2_perm_mem_input_3_, e poseidon2_perm_mem_input_tag_0_, e poseidon2_perm_mem_input_tag_1_, e poseidon2_perm_mem_input_tag_2_, e poseidon2_perm_mem_input_tag_3_, e poseidon2_perm_mem_max_mem_addr, e poseidon2_perm_mem_output_0_, e poseidon2_perm_mem_output_1_, e poseidon2_perm_mem_output_2_, e poseidon2_perm_mem_output_3_, e poseidon2_perm_mem_read_address_0_, e poseidon2_perm_mem_read_address_1_, e poseidon2_perm_mem_read_address_2_, e poseidon2_perm_mem_read_address_3_, e poseidon2_perm_mem_sel, e poseidon2_perm_mem_sel_dst_out_of_range_err, e poseidon2_perm_mem_sel_invalid_tag_err, e poseidon2_perm_mem_sel_should_exec, e poseidon2_perm_mem_sel_should_read_mem, e poseidon2_perm_mem_sel_src_out_of_range_err, e poseidon2_perm_mem_space_id, e poseidon2_perm_mem_write_address_0_, e poseidon2_perm_mem_write_address_1_, e poseidon2_perm_mem_write_address_2_, e poseidon2_perm_mem_write_address_3_, e poseidon2_perm_sel, e public_data_check_address, e public_data_check_clk_diff_hi, e public_data_check_clk_diff_lo, e public_data_check_const_two, e public_data_check_discard, e public_data_check_end, e public_data_check_final_value, e public_data_check_intermediate_root, e public_data_check_leaf_not_exists, e public_data_check_leaf_slot, e public_data_check_leaf_slot_low_leaf_slot_diff_inv, e public_data_check_length_pi_idx, e public_data_check_low_leaf_hash, e public_data_check_low_leaf_index, e public_data_check_low_leaf_next_index, e public_data_check_low_leaf_next_slot, e public_data_check_low_leaf_slot, e public_data_check_low_leaf_value, e public_data_check_new_leaf_hash, e public_data_check_next_slot_inv, e public_data_check_next_slot_is_nonzero, e public_data_check_non_discarded_write, e public_data_check_non_protocol_write, e public_data_check_not_end, e public_data_check_protocol_write, e public_data_check_public_data_writes_length, e public_data_check_root, e public_data_check_should_insert, e public_data_check_should_write_to_public_inputs, e public_data_check_siloing_separator, e public_data_check_slot, e public_data_check_tree_height, e public_data_check_tree_size_after_write, e public_data_check_tree_size_before_write, e public_data_check_updated_low_leaf_hash, e public_data_check_updated_low_leaf_next_index, e public_data_check_updated_low_leaf_next_slot, e public_data_check_updated_low_leaf_value, e public_data_check_value, e public_data_check_write, e public_data_check_write_root, e public_data_squash_check_clock, e public_data_squash_clk_diff_hi, e public_data_squash_clk_diff_lo, e public_data_squash_leaf_slot_increase, e public_data_squash_value, e range_check_dyn_diff, e range_check_dyn_rng_chk_bits, e range_check_dyn_rng_chk_pow_2, e range_check_is_lte_u112, e range_check_is_lte_u128, e range_check_is_lte_u16, e range_check_is_lte_u32, e range_check_is_lte_u48, e range_check_is_lte_u64, e range_check_is_lte_u80, e range_check_is_lte_u96, e range_check_rng_chk_bits, e range_check_sel, e range_check_sel_alu, e range_check_sel_gt, e range_check_sel_keccak, e range_check_sel_memory, e range_check_sel_r0_16_bit_rng_lookup, e range_check_sel_r1_16_bit_rng_lookup, e range_check_sel_r2_16_bit_rng_lookup, e range_check_sel_r3_16_bit_rng_lookup, e range_check_sel_r4_16_bit_rng_lookup, e range_check_sel_r5_16_bit_rng_lookup, e range_check_sel_r6_16_bit_rng_lookup, e range_check_u16_r0, e range_check_u16_r1, e range_check_u16_r2, e range_check_u16_r3, e range_check_u16_r4, e range_check_u16_r5, e range_check_u16_r6, e range_check_u16_r7, e range_check_value, e retrieved_bytecodes_tree_check_class_id, e retrieved_bytecodes_tree_check_class_id_low_leaf_class_id_diff_inv, e retrieved_bytecodes_tree_check_intermediate_root, e retrieved_bytecodes_tree_check_leaf_not_exists, e retrieved_bytecodes_tree_check_low_leaf_class_id, e retrieved_bytecodes_tree_check_low_leaf_hash, e retrieved_bytecodes_tree_check_low_leaf_index, e retrieved_bytecodes_tree_check_low_leaf_next_class_id, e retrieved_bytecodes_tree_check_low_leaf_next_index, e retrieved_bytecodes_tree_check_new_leaf_hash, e retrieved_bytecodes_tree_check_next_class_id_inv, e retrieved_bytecodes_tree_check_next_class_id_is_nonzero, e retrieved_bytecodes_tree_check_root, e retrieved_bytecodes_tree_check_sel, e retrieved_bytecodes_tree_check_should_insert, e retrieved_bytecodes_tree_check_tree_height, e retrieved_bytecodes_tree_check_tree_size_after_write, e retrieved_bytecodes_tree_check_tree_size_before_write, e retrieved_bytecodes_tree_check_updated_low_leaf_hash, e retrieved_bytecodes_tree_check_updated_low_leaf_next_class_id, e retrieved_bytecodes_tree_check_updated_low_leaf_next_index, e retrieved_bytecodes_tree_check_write, e retrieved_bytecodes_tree_check_write_root, e scalar_mul_bit, e scalar_mul_bit_radix, e scalar_mul_end, e scalar_mul_not_end, e scalar_mul_should_add, e sha256_a_and_b, e sha256_a_and_b_xor_a_and_c, e sha256_a_and_c, e sha256_a_rotr_13, e sha256_a_rotr_2, e sha256_a_rotr_22, e sha256_a_rotr_2_xor_a_rotr_13, e sha256_and_sel, e sha256_b_and_c, e sha256_batch_tag_inv, e sha256_ch, e sha256_computed_w_lhs, e sha256_computed_w_rhs, e sha256_e_and_f, e sha256_e_rotr_11, e sha256_e_rotr_25, e sha256_e_rotr_6, e sha256_e_rotr_6_xor_e_rotr_11, e sha256_err, e sha256_input, e sha256_input_rounds_rem_inv, e sha256_input_tag, e sha256_input_tag_diff_inv, e sha256_last, e sha256_latch, e sha256_lhs_a_13, e sha256_lhs_a_2, e sha256_lhs_a_22, e sha256_lhs_e_11, e sha256_lhs_e_25, e sha256_lhs_e_6, e sha256_lhs_w_10, e sha256_lhs_w_17, e sha256_lhs_w_18, e sha256_lhs_w_19, e sha256_lhs_w_3, e sha256_lhs_w_7, e sha256_maj, e sha256_max_input_addr, e sha256_max_mem_addr, e sha256_max_output_addr, e sha256_max_state_addr, e sha256_mem_out_of_range_err, e sha256_memory_address_0_, e sha256_memory_address_1_, e sha256_memory_address_2_, e sha256_memory_address_3_, e sha256_memory_address_4_, e sha256_memory_address_5_, e sha256_memory_address_6_, e sha256_memory_address_7_, e sha256_memory_register_0_, e sha256_memory_register_1_, e sha256_memory_register_2_, e sha256_memory_register_3_, e sha256_memory_register_4_, e sha256_memory_register_5_, e sha256_memory_register_6_, e sha256_memory_register_7_, e sha256_memory_tag_0_, e sha256_memory_tag_1_, e sha256_memory_tag_2_, e sha256_memory_tag_3_, e sha256_memory_tag_4_, e sha256_memory_tag_5_, e sha256_memory_tag_6_, e sha256_memory_tag_7_, e sha256_next_a_lhs, e sha256_next_a_rhs, e sha256_next_e_lhs, e sha256_next_e_rhs, e sha256_not_e, e sha256_not_e_and_g, e sha256_output_a_lhs, e sha256_output_a_rhs, e sha256_output_b_lhs, e sha256_output_b_rhs, e sha256_output_c_lhs, e sha256_output_c_rhs, e sha256_output_d_lhs, e sha256_output_d_rhs, e sha256_output_e_lhs, e sha256_output_e_rhs, e sha256_output_f_lhs, e sha256_output_f_rhs, e sha256_output_g_lhs, e sha256_output_g_rhs, e sha256_output_h_lhs, e sha256_output_h_rhs, e sha256_perform_round, e sha256_rhs_a_13, e sha256_rhs_a_2, e sha256_rhs_a_22, e sha256_rhs_e_11, e sha256_rhs_e_25, e sha256_rhs_e_6, e sha256_rhs_w_10, e sha256_rhs_w_17, e sha256_rhs_w_18, e sha256_rhs_w_19, e sha256_rhs_w_3, e sha256_rhs_w_7, e sha256_round_constant, e sha256_round_count, e sha256_rounds_remaining_inv, e sha256_rw, e sha256_s_0, e sha256_s_1, e sha256_sel_compute_w, e sha256_sel_input_out_of_range_err, e sha256_sel_invalid_input_row_tag_err, e sha256_sel_invalid_state_tag_err, e sha256_sel_mem_state_or_output, e sha256_sel_output_out_of_range_err, e sha256_sel_read_input_from_memory, e sha256_sel_state_out_of_range_err, e sha256_state_addr, e sha256_two_pow_10, e sha256_two_pow_11, e sha256_two_pow_13, e sha256_two_pow_17, e sha256_two_pow_18, e sha256_two_pow_19, e sha256_two_pow_2, e sha256_two_pow_22, e sha256_two_pow_25, e sha256_two_pow_3, e sha256_two_pow_32, e sha256_two_pow_6, e sha256_two_pow_7, e sha256_u32_tag, e sha256_w, e sha256_w_15_rotr_18, e sha256_w_15_rotr_7, e sha256_w_15_rotr_7_xor_w_15_rotr_18, e sha256_w_15_rshift_3, e sha256_w_2_rotr_17, e sha256_w_2_rotr_17_xor_w_2_rotr_19, e sha256_w_2_rotr_19, e sha256_w_2_rshift_10, e sha256_w_s_0, e sha256_w_s_1, e sha256_xor_sel, e to_radix_end, e to_radix_found, e to_radix_is_unsafe_limb, e to_radix_limb_p_diff, e to_radix_limb_radix_diff, e to_radix_mem_err, e to_radix_mem_input_validation_error, e to_radix_mem_last, e to_radix_mem_limb_index_to_lookup, e to_radix_mem_limb_value, e to_radix_mem_max_mem_size, e to_radix_mem_num_limbs_inv, e to_radix_mem_num_limbs_minus_one_inv, e to_radix_mem_output_tag, e to_radix_mem_sel_dst_out_of_range_err, e to_radix_mem_sel_invalid_bitwise_radix, e to_radix_mem_sel_invalid_num_limbs_err, e to_radix_mem_sel_num_limbs_is_zero, e to_radix_mem_sel_radix_gt_256_err, e to_radix_mem_sel_radix_lt_2_err, e to_radix_mem_sel_truncation_error, e to_radix_mem_sel_value_is_zero, e to_radix_mem_two, e to_radix_mem_two_five_six, e to_radix_mem_value_found, e to_radix_mem_value_inv, e to_radix_mem_write_addr_upper_bound, e to_radix_not_end, e to_radix_p_limb, e to_radix_rem_inverse, e to_radix_safety_diff_inverse, e tx_array_length_l2_to_l1_messages_pi_offset, e tx_array_length_note_hashes_pi_offset, e tx_array_length_nullifiers_pi_offset, e tx_calldata_hash, e tx_calldata_size, e tx_contract_addr, e tx_effective_fee_per_da_gas, e tx_effective_fee_per_l2_gas, e tx_end_phase, e tx_fee_juice_balance_slot, e tx_fee_juice_balances_slot_constant, e tx_fee_juice_contract_address, e tx_fee_payer, e tx_fee_payer_balance, e tx_fee_payer_new_balance, e tx_fee_payer_pi_offset, e tx_fields_length_unencrypted_logs_pi_offset, e tx_gas_limit_pi_offset, e tx_gas_used_pi_offset, e tx_is_cleanup, e tx_is_collect_fee, e tx_is_padded, e tx_is_public_call_request, e tx_is_static, e tx_is_tree_insert_phase, e tx_is_tree_padding, e tx_l1_l2_pi_offset, e tx_l2_l1_msg_content, e tx_l2_l1_msg_contract_address, e tx_l2_l1_msg_recipient, e tx_leaf_value, e tx_msg_sender, e tx_next_da_gas_used, e tx_next_da_gas_used_sent_to_enqueued_call, e tx_next_l2_gas_used, e tx_next_l2_gas_used_sent_to_enqueued_call, e tx_next_note_hash_tree_root, e tx_next_note_hash_tree_size, e tx_next_nullifier_tree_root, e tx_next_nullifier_tree_size, e tx_next_num_l2_to_l1_messages, e tx_next_num_note_hashes_emitted, e tx_next_num_nullifiers_emitted, e tx_next_num_unencrypted_log_fields, e tx_next_phase_on_revert, e tx_next_public_data_tree_root, e tx_next_public_data_tree_size, e tx_next_retrieved_bytecodes_tree_root, e tx_next_retrieved_bytecodes_tree_size, e tx_next_written_public_data_slots_tree_root, e tx_next_written_public_data_slots_tree_size, e tx_note_hash_pi_offset, e tx_nullifier_limit_error, e tx_nullifier_pi_offset, e tx_prev_da_gas_used_sent_to_enqueued_call, e tx_prev_l2_gas_used_sent_to_enqueued_call, e tx_public_data_pi_offset, e tx_read_pi_length_offset, e tx_read_pi_start_offset, e tx_remaining_phase_inv, e tx_remaining_phase_minus_one_inv, e tx_remaining_side_effects_inv, e tx_reverted_pi_offset, e tx_sel_non_revertible_append_l2_l1_msg, e tx_sel_non_revertible_append_note_hash, e tx_sel_non_revertible_append_nullifier, e tx_sel_read_phase_length, e tx_sel_read_trees_and_gas_used, e tx_sel_revertible_append_l2_l1_msg, e tx_sel_revertible_append_note_hash, e tx_sel_revertible_append_nullifier, e tx_setup_phase_value, e tx_should_l2_l1_msg_append, e tx_should_note_hash_append, e tx_should_nullifier_append, e tx_should_process_call_request, e tx_should_read_gas_limit, e tx_should_try_l2_l1_msg_append, e tx_should_try_note_hash_append, e tx_should_try_nullifier_append, e tx_uint32_max, e tx_write_pi_offset, e update_check_address, e update_check_current_class_id, e update_check_delayed_public_mutable_hash_slot, e update_check_delayed_public_mutable_slot, e update_check_deployer_protocol_contract_address, e update_check_hash_not_zero, e update_check_original_class_id, e update_check_public_data_tree_root, e update_check_sel, e update_check_timestamp, e update_check_timestamp_is_lt_timestamp_of_change, e update_check_timestamp_of_change, e update_check_timestamp_of_change_bit_size, e update_check_timestamp_pi_offset, e update_check_update_hash, e update_check_update_hash_inv, e update_check_update_hi_metadata, e update_check_update_hi_metadata_bit_size, e update_check_update_post_class_id_is_zero, e update_check_update_post_class_inv, e update_check_update_pre_class_id_is_zero, e update_check_update_pre_class_inv, e update_check_update_preimage_metadata, e update_check_update_preimage_post_class_id, e update_check_update_preimage_pre_class_id, e update_check_updated_class_ids_slot, e written_public_data_slots_tree_check_address, e written_public_data_slots_tree_check_intermediate_root, e written_public_data_slots_tree_check_leaf_not_exists, e written_public_data_slots_tree_check_leaf_slot, e written_public_data_slots_tree_check_low_leaf_hash, e written_public_data_slots_tree_check_low_leaf_index, e written_public_data_slots_tree_check_low_leaf_next_index, e written_public_data_slots_tree_check_low_leaf_next_slot, e written_public_data_slots_tree_check_low_leaf_slot, e written_public_data_slots_tree_check_new_leaf_hash, e written_public_data_slots_tree_check_next_slot_inv, e written_public_data_slots_tree_check_next_slot_is_nonzero, e written_public_data_slots_tree_check_root, e written_public_data_slots_tree_check_sel, e written_public_data_slots_tree_check_should_insert, e written_public_data_slots_tree_check_siloing_separator, e written_public_data_slots_tree_check_slot, e written_public_data_slots_tree_check_slot_low_leaf_slot_diff_inv, e written_public_data_slots_tree_check_tree_height, e written_public_data_slots_tree_check_tree_size_after_write, e written_public_data_slots_tree_check_tree_size_before_write, e written_public_data_slots_tree_check_updated_low_leaf_hash, e written_public_data_slots_tree_check_updated_low_leaf_next_index, e written_public_data_slots_tree_check_updated_low_leaf_next_slot, e written_public_data_slots_tree_check_write, e written_public_data_slots_tree_check_write_root, e lookup_range_check_dyn_rng_chk_pow_2_counts, e lookup_range_check_dyn_diff_is_u16_counts, e lookup_range_check_r0_is_u16_counts, e lookup_range_check_r1_is_u16_counts, e lookup_range_check_r2_is_u16_counts, e lookup_range_check_r3_is_u16_counts, e lookup_range_check_r4_is_u16_counts, e lookup_range_check_r5_is_u16_counts, e lookup_range_check_r6_is_u16_counts, e lookup_range_check_r7_is_u16_counts, e lookup_ff_gt_a_lo_range_counts, e lookup_ff_gt_a_hi_range_counts, e lookup_gt_gt_range_counts, e lookup_alu_tag_max_bits_value_counts, e lookup_alu_range_check_decomposition_a_lo_counts, e lookup_alu_range_check_decomposition_a_hi_counts, e lookup_alu_range_check_decomposition_b_lo_counts, e lookup_alu_range_check_decomposition_b_hi_counts, e lookup_alu_range_check_mul_c_hi_counts, e lookup_alu_ff_gt_counts, e lookup_alu_int_gt_counts, e lookup_alu_shifts_two_pow_counts, e lookup_alu_large_trunc_canonical_dec_counts, e lookup_alu_range_check_trunc_mid_counts, e lookup_bitwise_integral_tag_length_counts, e lookup_bitwise_byte_operations_counts, e lookup_memory_range_check_limb_0_counts, e lookup_memory_range_check_limb_1_counts, e lookup_memory_range_check_limb_2_counts, e lookup_memory_tag_max_bits_counts, e lookup_memory_range_check_write_tagged_value_counts, e lookup_keccakf1600_theta_xor_01_counts, e lookup_keccakf1600_theta_xor_02_counts, e lookup_keccakf1600_theta_xor_03_counts, e lookup_keccakf1600_theta_xor_row_0_counts, e lookup_keccakf1600_theta_xor_11_counts, e lookup_keccakf1600_theta_xor_12_counts, e lookup_keccakf1600_theta_xor_13_counts, e lookup_keccakf1600_theta_xor_row_1_counts, e lookup_keccakf1600_theta_xor_21_counts, e lookup_keccakf1600_theta_xor_22_counts, e lookup_keccakf1600_theta_xor_23_counts, e lookup_keccakf1600_theta_xor_row_2_counts, e lookup_keccakf1600_theta_xor_31_counts, e lookup_keccakf1600_theta_xor_32_counts, e lookup_keccakf1600_theta_xor_33_counts, e lookup_keccakf1600_theta_xor_row_3_counts, e lookup_keccakf1600_theta_xor_41_counts, e lookup_keccakf1600_theta_xor_42_counts, e lookup_keccakf1600_theta_xor_43_counts, e lookup_keccakf1600_theta_xor_row_4_counts, e lookup_keccakf1600_theta_combined_xor_0_counts, e lookup_keccakf1600_theta_combined_xor_1_counts, e lookup_keccakf1600_theta_combined_xor_2_counts, e lookup_keccakf1600_theta_combined_xor_3_counts, e lookup_keccakf1600_theta_combined_xor_4_counts, e lookup_keccakf1600_state_theta_00_counts, e lookup_keccakf1600_state_theta_01_counts, e lookup_keccakf1600_state_theta_02_counts, e lookup_keccakf1600_state_theta_03_counts, e lookup_keccakf1600_state_theta_04_counts, e lookup_keccakf1600_state_theta_10_counts, e lookup_keccakf1600_state_theta_11_counts, e lookup_keccakf1600_state_theta_12_counts, e lookup_keccakf1600_state_theta_13_counts, e lookup_keccakf1600_state_theta_14_counts, e lookup_keccakf1600_state_theta_20_counts, e lookup_keccakf1600_state_theta_21_counts, e lookup_keccakf1600_state_theta_22_counts, e lookup_keccakf1600_state_theta_23_counts, e lookup_keccakf1600_state_theta_24_counts, e lookup_keccakf1600_state_theta_30_counts, e lookup_keccakf1600_state_theta_31_counts, e lookup_keccakf1600_state_theta_32_counts, e lookup_keccakf1600_state_theta_33_counts, e lookup_keccakf1600_state_theta_34_counts, e lookup_keccakf1600_state_theta_40_counts, e lookup_keccakf1600_state_theta_41_counts, e lookup_keccakf1600_state_theta_42_counts, e lookup_keccakf1600_state_theta_43_counts, e lookup_keccakf1600_state_theta_44_counts, e lookup_keccakf1600_theta_limb_02_range_counts, e lookup_keccakf1600_theta_limb_04_range_counts, e lookup_keccakf1600_theta_limb_10_range_counts, e lookup_keccakf1600_theta_limb_12_range_counts, e lookup_keccakf1600_theta_limb_14_range_counts, e lookup_keccakf1600_theta_limb_21_range_counts, e lookup_keccakf1600_theta_limb_23_range_counts, e lookup_keccakf1600_theta_limb_30_range_counts, e lookup_keccakf1600_theta_limb_32_range_counts, e lookup_keccakf1600_theta_limb_33_range_counts, e lookup_keccakf1600_theta_limb_40_range_counts, e lookup_keccakf1600_theta_limb_41_range_counts, e lookup_keccakf1600_theta_limb_43_range_counts, e lookup_keccakf1600_theta_limb_44_range_counts, e lookup_keccakf1600_theta_limb_01_range_counts, e lookup_keccakf1600_theta_limb_03_range_counts, e lookup_keccakf1600_theta_limb_11_range_counts, e lookup_keccakf1600_theta_limb_13_range_counts, e lookup_keccakf1600_theta_limb_20_range_counts, e lookup_keccakf1600_theta_limb_22_range_counts, e lookup_keccakf1600_theta_limb_24_range_counts, e lookup_keccakf1600_theta_limb_31_range_counts, e lookup_keccakf1600_theta_limb_34_range_counts, e lookup_keccakf1600_theta_limb_42_range_counts, e lookup_keccakf1600_state_pi_and_00_counts, e lookup_keccakf1600_state_pi_and_01_counts, e lookup_keccakf1600_state_pi_and_02_counts, e lookup_keccakf1600_state_pi_and_03_counts, e lookup_keccakf1600_state_pi_and_04_counts, e lookup_keccakf1600_state_pi_and_10_counts, e lookup_keccakf1600_state_pi_and_11_counts, e lookup_keccakf1600_state_pi_and_12_counts, e lookup_keccakf1600_state_pi_and_13_counts, e lookup_keccakf1600_state_pi_and_14_counts, e lookup_keccakf1600_state_pi_and_20_counts, e lookup_keccakf1600_state_pi_and_21_counts, e lookup_keccakf1600_state_pi_and_22_counts, e lookup_keccakf1600_state_pi_and_23_counts, e lookup_keccakf1600_state_pi_and_24_counts, e lookup_keccakf1600_state_pi_and_30_counts, e lookup_keccakf1600_state_pi_and_31_counts, e lookup_keccakf1600_state_pi_and_32_counts, e lookup_keccakf1600_state_pi_and_33_counts, e lookup_keccakf1600_state_pi_and_34_counts, e lookup_keccakf1600_state_pi_and_40_counts, e lookup_keccakf1600_state_pi_and_41_counts, e lookup_keccakf1600_state_pi_and_42_counts, e lookup_keccakf1600_state_pi_and_43_counts, e lookup_keccakf1600_state_pi_and_44_counts, e lookup_keccakf1600_state_chi_00_counts, e lookup_keccakf1600_state_chi_01_counts, e lookup_keccakf1600_state_chi_02_counts, e lookup_keccakf1600_state_chi_03_counts, e lookup_keccakf1600_state_chi_04_counts, e lookup_keccakf1600_state_chi_10_counts, e lookup_keccakf1600_state_chi_11_counts, e lookup_keccakf1600_state_chi_12_counts, e lookup_keccakf1600_state_chi_13_counts, e lookup_keccakf1600_state_chi_14_counts, e lookup_keccakf1600_state_chi_20_counts, e lookup_keccakf1600_state_chi_21_counts, e lookup_keccakf1600_state_chi_22_counts, e lookup_keccakf1600_state_chi_23_counts, e lookup_keccakf1600_state_chi_24_counts, e lookup_keccakf1600_state_chi_30_counts, e lookup_keccakf1600_state_chi_31_counts, e lookup_keccakf1600_state_chi_32_counts, e lookup_keccakf1600_state_chi_33_counts, e lookup_keccakf1600_state_chi_34_counts, e lookup_keccakf1600_state_chi_40_counts, e lookup_keccakf1600_state_chi_41_counts, e lookup_keccakf1600_state_chi_42_counts, e lookup_keccakf1600_state_chi_43_counts, e lookup_keccakf1600_state_chi_44_counts, e lookup_keccakf1600_round_cst_counts, e lookup_keccakf1600_state_iota_00_counts, e lookup_keccakf1600_src_out_of_range_toggle_counts, e lookup_keccakf1600_dst_out_of_range_toggle_counts, e lookup_sha256_range_comp_w_lhs_counts, e lookup_sha256_range_comp_w_rhs_counts, e lookup_sha256_range_rhs_w_7_counts, e lookup_sha256_range_rhs_w_18_counts, e lookup_sha256_range_rhs_w_3_counts, e lookup_sha256_w_s_0_xor_0_counts, e lookup_sha256_w_s_0_xor_1_counts, e lookup_sha256_range_rhs_w_17_counts, e lookup_sha256_range_rhs_w_19_counts, e lookup_sha256_range_rhs_w_10_counts, e lookup_sha256_w_s_1_xor_0_counts, e lookup_sha256_w_s_1_xor_1_counts, e lookup_sha256_range_rhs_e_6_counts, e lookup_sha256_range_rhs_e_11_counts, e lookup_sha256_range_rhs_e_25_counts, e lookup_sha256_s_1_xor_0_counts, e lookup_sha256_s_1_xor_1_counts, e lookup_sha256_ch_and_0_counts, e lookup_sha256_ch_and_1_counts, e lookup_sha256_ch_xor_counts, e lookup_sha256_round_constant_counts, e lookup_sha256_range_rhs_a_2_counts, e lookup_sha256_range_rhs_a_13_counts, e lookup_sha256_range_rhs_a_22_counts, e lookup_sha256_s_0_xor_0_counts, e lookup_sha256_s_0_xor_1_counts, e lookup_sha256_maj_and_0_counts, e lookup_sha256_maj_and_1_counts, e lookup_sha256_maj_and_2_counts, e lookup_sha256_maj_xor_0_counts, e lookup_sha256_maj_xor_1_counts, e lookup_sha256_range_comp_next_a_lhs_counts, e lookup_sha256_range_comp_next_a_rhs_counts, e lookup_sha256_range_comp_next_e_lhs_counts, e lookup_sha256_range_comp_next_e_rhs_counts, e lookup_sha256_range_comp_a_lhs_counts, e lookup_sha256_range_comp_a_rhs_counts, e lookup_sha256_range_comp_b_lhs_counts, e lookup_sha256_range_comp_b_rhs_counts, e lookup_sha256_range_comp_c_lhs_counts, e lookup_sha256_range_comp_c_rhs_counts, e lookup_sha256_range_comp_d_lhs_counts, e lookup_sha256_range_comp_d_rhs_counts, e lookup_sha256_range_comp_e_lhs_counts, e lookup_sha256_range_comp_e_rhs_counts, e lookup_sha256_range_comp_f_lhs_counts, e lookup_sha256_range_comp_f_rhs_counts, e lookup_sha256_range_comp_g_lhs_counts, e lookup_sha256_range_comp_g_rhs_counts, e lookup_sha256_range_comp_h_lhs_counts, e lookup_sha256_range_comp_h_rhs_counts, e lookup_sha256_mem_check_state_addr_in_range_counts, e lookup_sha256_mem_check_input_addr_in_range_counts, e lookup_sha256_mem_check_output_addr_in_range_counts, e lookup_ecc_mem_check_dst_addr_in_range_counts, e lookup_ecc_mem_input_output_ecc_add_counts, e lookup_poseidon2_mem_check_src_addr_in_range_counts, e lookup_poseidon2_mem_check_dst_addr_in_range_counts, e lookup_poseidon2_mem_input_output_poseidon2_perm_counts, e lookup_to_radix_limb_range_counts, e lookup_to_radix_limb_less_than_radix_range_counts, e lookup_to_radix_fetch_safe_limbs_counts, e lookup_to_radix_fetch_p_limb_counts, e lookup_to_radix_limb_p_diff_range_counts, e lookup_scalar_mul_to_radix_counts, e lookup_scalar_mul_double_counts, e lookup_scalar_mul_add_counts, e lookup_to_radix_mem_check_dst_addr_in_range_counts, e lookup_to_radix_mem_check_radix_lt_2_counts, e lookup_to_radix_mem_check_radix_gt_256_counts, e lookup_to_radix_mem_input_output_to_radix_counts, e lookup_context_ctx_stack_rollback_counts, e lookup_context_ctx_stack_return_counts, e lookup_poseidon2_hash_poseidon2_perm_counts, e lookup_calldata_hashing_get_calldata_field_0_counts, e lookup_calldata_hashing_get_calldata_field_1_counts, e lookup_calldata_hashing_get_calldata_field_2_counts, e lookup_calldata_hashing_check_final_size_counts, e lookup_calldata_hashing_poseidon2_hash_counts, e lookup_calldata_range_check_context_id_diff_counts, e lookup_data_copy_offset_plus_size_is_gt_data_size_counts, e lookup_data_copy_check_src_addr_in_range_counts, e lookup_data_copy_check_dst_addr_in_range_counts, e lookup_data_copy_data_index_upper_bound_gt_offset_counts, e lookup_data_copy_col_read_counts, e lookup_addressing_relative_overflow_result_0_counts, e lookup_addressing_relative_overflow_result_1_counts, e lookup_addressing_relative_overflow_result_2_counts, e lookup_addressing_relative_overflow_result_3_counts, e lookup_addressing_relative_overflow_result_4_counts, e lookup_addressing_relative_overflow_result_5_counts, e lookup_addressing_relative_overflow_result_6_counts, e lookup_gas_addressing_gas_read_counts, e lookup_gas_is_out_of_gas_l2_counts, e lookup_gas_is_out_of_gas_da_counts, e lookup_merkle_check_merkle_poseidon2_read_counts, e lookup_merkle_check_merkle_poseidon2_write_counts, e lookup_nullifier_check_silo_poseidon2_counts, e lookup_nullifier_check_low_leaf_poseidon2_counts, e lookup_nullifier_check_updated_low_leaf_poseidon2_counts, e lookup_nullifier_check_low_leaf_merkle_check_counts, e lookup_nullifier_check_low_leaf_nullifier_validation_counts, e lookup_nullifier_check_low_leaf_next_nullifier_validation_counts, e lookup_nullifier_check_new_leaf_poseidon2_counts, e lookup_nullifier_check_new_leaf_merkle_check_counts, e lookup_nullifier_check_write_nullifier_to_public_inputs_counts, e lookup_public_data_squash_leaf_slot_increase_ff_gt_counts, e lookup_public_data_squash_clk_diff_range_lo_counts, e lookup_public_data_squash_clk_diff_range_hi_counts, e lookup_public_data_check_clk_diff_range_lo_counts, e lookup_public_data_check_clk_diff_range_hi_counts, e lookup_public_data_check_silo_poseidon2_counts, e lookup_public_data_check_low_leaf_slot_validation_counts, e lookup_public_data_check_low_leaf_next_slot_validation_counts, e lookup_public_data_check_low_leaf_poseidon2_0_counts, e lookup_public_data_check_low_leaf_poseidon2_1_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_0_counts, e lookup_public_data_check_updated_low_leaf_poseidon2_1_counts, e lookup_public_data_check_low_leaf_merkle_check_counts, e lookup_public_data_check_new_leaf_poseidon2_0_counts, e lookup_public_data_check_new_leaf_poseidon2_1_counts, e lookup_public_data_check_new_leaf_merkle_check_counts, e lookup_public_data_check_write_public_data_to_public_inputs_counts, e lookup_public_data_check_write_writes_length_to_public_inputs_counts, e lookup_written_public_data_slots_tree_check_silo_poseidon2_counts, e lookup_written_public_data_slots_tree_check_low_leaf_poseidon2_counts, e lookup_written_public_data_slots_tree_check_updated_low_leaf_poseidon2_counts, e lookup_written_public_data_slots_tree_check_low_leaf_merkle_check_counts, e lookup_written_public_data_slots_tree_check_low_leaf_slot_validation_counts, e lookup_written_public_data_slots_tree_check_low_leaf_next_slot_validation_counts, e lookup_written_public_data_slots_tree_check_new_leaf_poseidon2_counts, e lookup_written_public_data_slots_tree_check_new_leaf_merkle_check_counts, e lookup_l1_to_l2_message_tree_check_merkle_check_counts, e lookup_retrieved_bytecodes_tree_check_low_leaf_poseidon2_counts, e lookup_retrieved_bytecodes_tree_check_updated_low_leaf_poseidon2_counts, e lookup_retrieved_bytecodes_tree_check_low_leaf_merkle_check_counts, e lookup_retrieved_bytecodes_tree_check_low_leaf_class_id_validation_counts, e lookup_retrieved_bytecodes_tree_check_low_leaf_next_class_id_validation_counts, e lookup_retrieved_bytecodes_tree_check_new_leaf_poseidon2_counts, e lookup_retrieved_bytecodes_tree_check_new_leaf_merkle_check_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_counts, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_counts, e lookup_address_derivation_partial_address_poseidon2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_0_counts, e lookup_address_derivation_public_keys_hash_poseidon2_1_counts, e lookup_address_derivation_public_keys_hash_poseidon2_2_counts, e lookup_address_derivation_public_keys_hash_poseidon2_3_counts, e lookup_address_derivation_public_keys_hash_poseidon2_4_counts, e lookup_address_derivation_preaddress_poseidon2_counts, e lookup_address_derivation_preaddress_scalar_mul_counts, e lookup_address_derivation_address_ecadd_counts, e lookup_bc_decomposition_bytes_are_bytes_counts, e lookup_bc_hashing_check_final_bytes_remaining_counts, e lookup_bc_hashing_poseidon2_hash_counts, e lookup_update_check_timestamp_from_public_inputs_counts, e lookup_update_check_delayed_public_mutable_slot_poseidon2_counts, e lookup_update_check_update_hash_public_data_read_counts, e lookup_update_check_update_hash_poseidon2_counts, e lookup_update_check_update_hi_metadata_range_counts, e lookup_update_check_update_lo_metadata_range_counts, e lookup_update_check_timestamp_is_lt_timestamp_of_change_counts, e lookup_contract_instance_retrieval_check_protocol_address_range_counts, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_counts, e lookup_contract_instance_retrieval_deployment_nullifier_read_counts, e lookup_contract_instance_retrieval_address_derivation_counts, e lookup_contract_instance_retrieval_update_check_counts, e lookup_bc_retrieval_contract_instance_retrieval_counts, e lookup_bc_retrieval_is_new_class_check_counts, e lookup_bc_retrieval_class_id_derivation_counts, e lookup_bc_retrieval_retrieved_bytecodes_insertion_counts, e lookup_instr_fetching_pc_abs_diff_positive_counts, e lookup_instr_fetching_instr_abs_diff_positive_counts, e lookup_instr_fetching_tag_value_validation_counts, e lookup_instr_fetching_bytecode_size_from_bc_dec_counts, e lookup_instr_fetching_bytes_from_bc_dec_counts, e lookup_instr_fetching_wire_instruction_info_counts, e lookup_class_id_derivation_class_id_poseidon2_0_counts, e lookup_class_id_derivation_class_id_poseidon2_1_counts, e lookup_get_env_var_precomputed_info_counts, e lookup_get_env_var_read_from_public_inputs_col0_counts, e lookup_get_env_var_read_from_public_inputs_col1_counts, e lookup_get_contract_instance_precomputed_info_counts, e lookup_get_contract_instance_contract_instance_retrieval_counts, e lookup_internal_call_unwind_call_stack_counts, e lookup_external_call_is_l2_gas_left_gt_allocated_counts, e lookup_external_call_is_da_gas_left_gt_allocated_counts, e lookup_sload_storage_read_counts, e lookup_sstore_record_written_storage_slot_counts, e lookup_note_hash_tree_check_silo_poseidon2_counts, e lookup_note_hash_tree_check_read_first_nullifier_counts, e lookup_note_hash_tree_check_nonce_computation_poseidon2_counts, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_counts, e lookup_note_hash_tree_check_merkle_check_counts, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_counts, e lookup_notehash_exists_note_hash_leaf_index_in_range_counts, e lookup_notehash_exists_note_hash_read_counts, e lookup_emit_notehash_notehash_tree_write_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_counts, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_counts, e lookup_nullifier_exists_nullifier_exists_check_counts, e lookup_emit_nullifier_write_nullifier_counts, e lookup_emit_unencrypted_log_check_memory_out_of_bounds_counts, e lookup_emit_unencrypted_log_check_log_fields_count_counts, e lookup_emit_unencrypted_log_write_data_to_public_inputs_counts, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_counts, e lookup_execution_bytecode_retrieval_result_counts, e lookup_execution_instruction_fetching_result_counts, e lookup_execution_instruction_fetching_body_counts, e lookup_execution_exec_spec_read_counts, e lookup_execution_dyn_l2_factor_bitwise_counts, e lookup_execution_check_radix_gt_256_counts, e lookup_execution_get_p_limbs_counts, e lookup_execution_get_max_limbs_counts, e lookup_execution_check_written_storage_slot_counts, e lookup_execution_dispatch_to_alu_counts, e lookup_execution_dispatch_to_bitwise_counts, e lookup_execution_dispatch_to_cast_counts, e lookup_execution_dispatch_to_set_counts, e lookup_tx_context_public_inputs_note_hash_tree_counts, e lookup_tx_context_public_inputs_nullifier_tree_counts, e lookup_tx_context_public_inputs_public_data_tree_counts, e lookup_tx_context_public_inputs_l1_l2_tree_counts, e lookup_tx_context_public_inputs_gas_used_counts, e lookup_tx_context_public_inputs_read_gas_limit_counts, e lookup_tx_context_public_inputs_read_reverted_counts, e lookup_tx_context_restore_state_on_revert_counts, e lookup_tx_context_public_inputs_write_note_hash_count_counts, e lookup_tx_context_public_inputs_write_nullifier_count_counts, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_counts, e lookup_tx_context_public_inputs_write_unencrypted_log_count_counts, e lookup_tx_read_phase_spec_counts, e lookup_tx_read_phase_length_counts, e lookup_tx_read_public_call_request_phase_counts, e lookup_tx_read_tree_insert_value_counts, e lookup_tx_note_hash_append_counts, e lookup_tx_nullifier_append_counts, e lookup_tx_read_l2_l1_msg_counts, e lookup_tx_write_l2_l1_msg_counts, e lookup_tx_read_effective_fee_public_inputs_counts, e lookup_tx_read_fee_payer_public_inputs_counts, e lookup_tx_balance_slot_poseidon2_counts, e lookup_tx_balance_read_counts, e lookup_tx_balance_validation_counts, e lookup_tx_write_fee_public_inputs_counts, 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_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_packed, e bc_decomposition_sel_windows_gt_remaining, e bc_hashing_bytecode_id, e bc_hashing_pc_index, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_start, e bc_retrieval_sel, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_sel_start, e data_copy_src_context_id, e emit_unencrypted_log_contract_address, e emit_unencrypted_log_correct_tag, e emit_unencrypted_log_error_out_of_bounds, e emit_unencrypted_log_error_tag_mismatch, e emit_unencrypted_log_execution_clk, e emit_unencrypted_log_is_write_contract_address, e emit_unencrypted_log_is_write_memory_value, e emit_unencrypted_log_log_address, e emit_unencrypted_log_public_inputs_index, e emit_unencrypted_log_remaining_rows, e emit_unencrypted_log_seen_wrong_tag, e emit_unencrypted_log_sel, e emit_unencrypted_log_sel_should_write_to_public_inputs, e emit_unencrypted_log_space_id, e emit_unencrypted_log_start, e execution_bytecode_id, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_unencrypted_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_sel, e keccak_memory_space_id, e keccak_memory_start_read, e keccak_memory_start_write, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_start, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_global_addr, e memory_rw, e memory_sel, e memory_tag, e memory_timestamp, e memory_value, e merkle_check_index, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, 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 public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, 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_execution_clk, 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_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_sel_is_input_round, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_exponent, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_unencrypted_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted #define AVM2_DERIVED_WITNESS_ENTITIES_E(e) e perm_keccak_memory_slice_to_mem_inv, e perm_keccakf1600_read_to_slice_inv, e perm_keccakf1600_write_to_slice_inv, e perm_sha256_mem_mem_op_0_inv, e perm_sha256_mem_mem_op_1_inv, e perm_sha256_mem_mem_op_2_inv, e perm_sha256_mem_mem_op_3_inv, e perm_sha256_mem_mem_op_4_inv, e perm_sha256_mem_mem_op_5_inv, e perm_sha256_mem_mem_op_6_inv, e perm_sha256_mem_mem_op_7_inv, e perm_sha256_mem_mem_input_read_inv, e perm_ecc_mem_write_mem_0_inv, e perm_ecc_mem_write_mem_1_inv, e perm_ecc_mem_write_mem_2_inv, e perm_poseidon2_mem_pos_read_mem_0_inv, e perm_poseidon2_mem_pos_read_mem_1_inv, e perm_poseidon2_mem_pos_read_mem_2_inv, e perm_poseidon2_mem_pos_read_mem_3_inv, e perm_poseidon2_mem_pos_write_mem_0_inv, e perm_poseidon2_mem_pos_write_mem_1_inv, e perm_poseidon2_mem_pos_write_mem_2_inv, e perm_poseidon2_mem_pos_write_mem_3_inv, e perm_to_radix_mem_write_mem_inv, e perm_context_ctx_stack_call_inv, e perm_data_copy_mem_write_inv, e perm_data_copy_mem_read_inv, e perm_addressing_base_address_from_memory_inv, e perm_addressing_indirect_from_memory_0_inv, e perm_addressing_indirect_from_memory_1_inv, e perm_addressing_indirect_from_memory_2_inv, e perm_addressing_indirect_from_memory_3_inv, e perm_addressing_indirect_from_memory_4_inv, e perm_addressing_indirect_from_memory_5_inv, e perm_addressing_indirect_from_memory_6_inv, e perm_registers_mem_op_0_inv, e perm_registers_mem_op_1_inv, e perm_registers_mem_op_2_inv, e perm_registers_mem_op_3_inv, e perm_registers_mem_op_4_inv, e perm_registers_mem_op_5_inv, e perm_public_data_check_squashing_inv, e perm_bc_hashing_get_packed_field_0_inv, e perm_bc_hashing_get_packed_field_1_inv, e perm_bc_hashing_get_packed_field_2_inv, e perm_get_contract_instance_mem_write_contract_instance_exists_inv, e perm_get_contract_instance_mem_write_contract_instance_member_inv, e perm_internal_call_push_call_stack_inv, e perm_sstore_storage_write_inv, e perm_emit_unencrypted_log_read_mem_inv, e perm_execution_dispatch_to_cd_copy_inv, e perm_execution_dispatch_to_rd_copy_inv, e perm_execution_dispatch_to_get_contract_instance_inv, e perm_execution_dispatch_to_emit_unencrypted_log_inv, e perm_execution_dispatch_to_poseidon2_perm_inv, e perm_execution_dispatch_to_sha256_compression_inv, e perm_execution_dispatch_to_keccakf1600_inv, e perm_execution_dispatch_to_ecc_add_inv, e perm_execution_dispatch_to_to_radix_inv, e perm_tx_read_calldata_hash_inv, e perm_tx_dispatch_exec_start_inv, e perm_tx_dispatch_exec_end_inv, e perm_tx_balance_update_inv, e lookup_range_check_dyn_rng_chk_pow_2_inv, e lookup_range_check_dyn_diff_is_u16_inv, e lookup_range_check_r0_is_u16_inv, e lookup_range_check_r1_is_u16_inv, e lookup_range_check_r2_is_u16_inv, e lookup_range_check_r3_is_u16_inv, e lookup_range_check_r4_is_u16_inv, e lookup_range_check_r5_is_u16_inv, e lookup_range_check_r6_is_u16_inv, e lookup_range_check_r7_is_u16_inv, e lookup_ff_gt_a_lo_range_inv, e lookup_ff_gt_a_hi_range_inv, e lookup_gt_gt_range_inv, e lookup_alu_tag_max_bits_value_inv, e lookup_alu_range_check_decomposition_a_lo_inv, e lookup_alu_range_check_decomposition_a_hi_inv, e lookup_alu_range_check_decomposition_b_lo_inv, e lookup_alu_range_check_decomposition_b_hi_inv, e lookup_alu_range_check_mul_c_hi_inv, e lookup_alu_ff_gt_inv, e lookup_alu_int_gt_inv, e lookup_alu_shifts_two_pow_inv, e lookup_alu_large_trunc_canonical_dec_inv, e lookup_alu_range_check_trunc_mid_inv, e lookup_bitwise_integral_tag_length_inv, e lookup_bitwise_byte_operations_inv, e lookup_memory_range_check_limb_0_inv, e lookup_memory_range_check_limb_1_inv, e lookup_memory_range_check_limb_2_inv, e lookup_memory_tag_max_bits_inv, e lookup_memory_range_check_write_tagged_value_inv, e lookup_keccakf1600_theta_xor_01_inv, e lookup_keccakf1600_theta_xor_02_inv, e lookup_keccakf1600_theta_xor_03_inv, e lookup_keccakf1600_theta_xor_row_0_inv, e lookup_keccakf1600_theta_xor_11_inv, e lookup_keccakf1600_theta_xor_12_inv, e lookup_keccakf1600_theta_xor_13_inv, e lookup_keccakf1600_theta_xor_row_1_inv, e lookup_keccakf1600_theta_xor_21_inv, e lookup_keccakf1600_theta_xor_22_inv, e lookup_keccakf1600_theta_xor_23_inv, e lookup_keccakf1600_theta_xor_row_2_inv, e lookup_keccakf1600_theta_xor_31_inv, e lookup_keccakf1600_theta_xor_32_inv, e lookup_keccakf1600_theta_xor_33_inv, e lookup_keccakf1600_theta_xor_row_3_inv, e lookup_keccakf1600_theta_xor_41_inv, e lookup_keccakf1600_theta_xor_42_inv, e lookup_keccakf1600_theta_xor_43_inv, e lookup_keccakf1600_theta_xor_row_4_inv, e lookup_keccakf1600_theta_combined_xor_0_inv, e lookup_keccakf1600_theta_combined_xor_1_inv, e lookup_keccakf1600_theta_combined_xor_2_inv, e lookup_keccakf1600_theta_combined_xor_3_inv, e lookup_keccakf1600_theta_combined_xor_4_inv, e lookup_keccakf1600_state_theta_00_inv, e lookup_keccakf1600_state_theta_01_inv, e lookup_keccakf1600_state_theta_02_inv, e lookup_keccakf1600_state_theta_03_inv, e lookup_keccakf1600_state_theta_04_inv, e lookup_keccakf1600_state_theta_10_inv, e lookup_keccakf1600_state_theta_11_inv, e lookup_keccakf1600_state_theta_12_inv, e lookup_keccakf1600_state_theta_13_inv, e lookup_keccakf1600_state_theta_14_inv, e lookup_keccakf1600_state_theta_20_inv, e lookup_keccakf1600_state_theta_21_inv, e lookup_keccakf1600_state_theta_22_inv, e lookup_keccakf1600_state_theta_23_inv, e lookup_keccakf1600_state_theta_24_inv, e lookup_keccakf1600_state_theta_30_inv, e lookup_keccakf1600_state_theta_31_inv, e lookup_keccakf1600_state_theta_32_inv, e lookup_keccakf1600_state_theta_33_inv, e lookup_keccakf1600_state_theta_34_inv, e lookup_keccakf1600_state_theta_40_inv, e lookup_keccakf1600_state_theta_41_inv, e lookup_keccakf1600_state_theta_42_inv, e lookup_keccakf1600_state_theta_43_inv, e lookup_keccakf1600_state_theta_44_inv, e lookup_keccakf1600_theta_limb_02_range_inv, e lookup_keccakf1600_theta_limb_04_range_inv, e lookup_keccakf1600_theta_limb_10_range_inv, e lookup_keccakf1600_theta_limb_12_range_inv, e lookup_keccakf1600_theta_limb_14_range_inv, e lookup_keccakf1600_theta_limb_21_range_inv, e lookup_keccakf1600_theta_limb_23_range_inv, e lookup_keccakf1600_theta_limb_30_range_inv, e lookup_keccakf1600_theta_limb_32_range_inv, e lookup_keccakf1600_theta_limb_33_range_inv, e lookup_keccakf1600_theta_limb_40_range_inv, e lookup_keccakf1600_theta_limb_41_range_inv, e lookup_keccakf1600_theta_limb_43_range_inv, e lookup_keccakf1600_theta_limb_44_range_inv, e lookup_keccakf1600_theta_limb_01_range_inv, e lookup_keccakf1600_theta_limb_03_range_inv, e lookup_keccakf1600_theta_limb_11_range_inv, e lookup_keccakf1600_theta_limb_13_range_inv, e lookup_keccakf1600_theta_limb_20_range_inv, e lookup_keccakf1600_theta_limb_22_range_inv, e lookup_keccakf1600_theta_limb_24_range_inv, e lookup_keccakf1600_theta_limb_31_range_inv, e lookup_keccakf1600_theta_limb_34_range_inv, e lookup_keccakf1600_theta_limb_42_range_inv, e lookup_keccakf1600_state_pi_and_00_inv, e lookup_keccakf1600_state_pi_and_01_inv, e lookup_keccakf1600_state_pi_and_02_inv, e lookup_keccakf1600_state_pi_and_03_inv, e lookup_keccakf1600_state_pi_and_04_inv, e lookup_keccakf1600_state_pi_and_10_inv, e lookup_keccakf1600_state_pi_and_11_inv, e lookup_keccakf1600_state_pi_and_12_inv, e lookup_keccakf1600_state_pi_and_13_inv, e lookup_keccakf1600_state_pi_and_14_inv, e lookup_keccakf1600_state_pi_and_20_inv, e lookup_keccakf1600_state_pi_and_21_inv, e lookup_keccakf1600_state_pi_and_22_inv, e lookup_keccakf1600_state_pi_and_23_inv, e lookup_keccakf1600_state_pi_and_24_inv, e lookup_keccakf1600_state_pi_and_30_inv, e lookup_keccakf1600_state_pi_and_31_inv, e lookup_keccakf1600_state_pi_and_32_inv, e lookup_keccakf1600_state_pi_and_33_inv, e lookup_keccakf1600_state_pi_and_34_inv, e lookup_keccakf1600_state_pi_and_40_inv, e lookup_keccakf1600_state_pi_and_41_inv, e lookup_keccakf1600_state_pi_and_42_inv, e lookup_keccakf1600_state_pi_and_43_inv, e lookup_keccakf1600_state_pi_and_44_inv, e lookup_keccakf1600_state_chi_00_inv, e lookup_keccakf1600_state_chi_01_inv, e lookup_keccakf1600_state_chi_02_inv, e lookup_keccakf1600_state_chi_03_inv, e lookup_keccakf1600_state_chi_04_inv, e lookup_keccakf1600_state_chi_10_inv, e lookup_keccakf1600_state_chi_11_inv, e lookup_keccakf1600_state_chi_12_inv, e lookup_keccakf1600_state_chi_13_inv, e lookup_keccakf1600_state_chi_14_inv, e lookup_keccakf1600_state_chi_20_inv, e lookup_keccakf1600_state_chi_21_inv, e lookup_keccakf1600_state_chi_22_inv, e lookup_keccakf1600_state_chi_23_inv, e lookup_keccakf1600_state_chi_24_inv, e lookup_keccakf1600_state_chi_30_inv, e lookup_keccakf1600_state_chi_31_inv, e lookup_keccakf1600_state_chi_32_inv, e lookup_keccakf1600_state_chi_33_inv, e lookup_keccakf1600_state_chi_34_inv, e lookup_keccakf1600_state_chi_40_inv, e lookup_keccakf1600_state_chi_41_inv, e lookup_keccakf1600_state_chi_42_inv, e lookup_keccakf1600_state_chi_43_inv, e lookup_keccakf1600_state_chi_44_inv, e lookup_keccakf1600_round_cst_inv, e lookup_keccakf1600_state_iota_00_inv, e lookup_keccakf1600_src_out_of_range_toggle_inv, e lookup_keccakf1600_dst_out_of_range_toggle_inv, e lookup_sha256_range_comp_w_lhs_inv, e lookup_sha256_range_comp_w_rhs_inv, e lookup_sha256_range_rhs_w_7_inv, e lookup_sha256_range_rhs_w_18_inv, e lookup_sha256_range_rhs_w_3_inv, e lookup_sha256_w_s_0_xor_0_inv, e lookup_sha256_w_s_0_xor_1_inv, e lookup_sha256_range_rhs_w_17_inv, e lookup_sha256_range_rhs_w_19_inv, e lookup_sha256_range_rhs_w_10_inv, e lookup_sha256_w_s_1_xor_0_inv, e lookup_sha256_w_s_1_xor_1_inv, e lookup_sha256_range_rhs_e_6_inv, e lookup_sha256_range_rhs_e_11_inv, e lookup_sha256_range_rhs_e_25_inv, e lookup_sha256_s_1_xor_0_inv, e lookup_sha256_s_1_xor_1_inv, e lookup_sha256_ch_and_0_inv, e lookup_sha256_ch_and_1_inv, e lookup_sha256_ch_xor_inv, e lookup_sha256_round_constant_inv, e lookup_sha256_range_rhs_a_2_inv, e lookup_sha256_range_rhs_a_13_inv, e lookup_sha256_range_rhs_a_22_inv, e lookup_sha256_s_0_xor_0_inv, e lookup_sha256_s_0_xor_1_inv, e lookup_sha256_maj_and_0_inv, e lookup_sha256_maj_and_1_inv, e lookup_sha256_maj_and_2_inv, e lookup_sha256_maj_xor_0_inv, e lookup_sha256_maj_xor_1_inv, e lookup_sha256_range_comp_next_a_lhs_inv, e lookup_sha256_range_comp_next_a_rhs_inv, e lookup_sha256_range_comp_next_e_lhs_inv, e lookup_sha256_range_comp_next_e_rhs_inv, e lookup_sha256_range_comp_a_lhs_inv, e lookup_sha256_range_comp_a_rhs_inv, e lookup_sha256_range_comp_b_lhs_inv, e lookup_sha256_range_comp_b_rhs_inv, e lookup_sha256_range_comp_c_lhs_inv, e lookup_sha256_range_comp_c_rhs_inv, e lookup_sha256_range_comp_d_lhs_inv, e lookup_sha256_range_comp_d_rhs_inv, e lookup_sha256_range_comp_e_lhs_inv, e lookup_sha256_range_comp_e_rhs_inv, e lookup_sha256_range_comp_f_lhs_inv, e lookup_sha256_range_comp_f_rhs_inv, e lookup_sha256_range_comp_g_lhs_inv, e lookup_sha256_range_comp_g_rhs_inv, e lookup_sha256_range_comp_h_lhs_inv, e lookup_sha256_range_comp_h_rhs_inv, e lookup_sha256_mem_check_state_addr_in_range_inv, e lookup_sha256_mem_check_input_addr_in_range_inv, e lookup_sha256_mem_check_output_addr_in_range_inv, e lookup_ecc_mem_check_dst_addr_in_range_inv, e lookup_ecc_mem_input_output_ecc_add_inv, e lookup_poseidon2_mem_check_src_addr_in_range_inv, e lookup_poseidon2_mem_check_dst_addr_in_range_inv, e lookup_poseidon2_mem_input_output_poseidon2_perm_inv, e lookup_to_radix_limb_range_inv, e lookup_to_radix_limb_less_than_radix_range_inv, e lookup_to_radix_fetch_safe_limbs_inv, e lookup_to_radix_fetch_p_limb_inv, e lookup_to_radix_limb_p_diff_range_inv, e lookup_scalar_mul_to_radix_inv, e lookup_scalar_mul_double_inv, e lookup_scalar_mul_add_inv, e lookup_to_radix_mem_check_dst_addr_in_range_inv, e lookup_to_radix_mem_check_radix_lt_2_inv, e lookup_to_radix_mem_check_radix_gt_256_inv, e lookup_to_radix_mem_input_output_to_radix_inv, e lookup_context_ctx_stack_rollback_inv, e lookup_context_ctx_stack_return_inv, e lookup_poseidon2_hash_poseidon2_perm_inv, e lookup_calldata_hashing_get_calldata_field_0_inv, e lookup_calldata_hashing_get_calldata_field_1_inv, e lookup_calldata_hashing_get_calldata_field_2_inv, e lookup_calldata_hashing_check_final_size_inv, e lookup_calldata_hashing_poseidon2_hash_inv, e lookup_calldata_range_check_context_id_diff_inv, e lookup_data_copy_offset_plus_size_is_gt_data_size_inv, e lookup_data_copy_check_src_addr_in_range_inv, e lookup_data_copy_check_dst_addr_in_range_inv, e lookup_data_copy_data_index_upper_bound_gt_offset_inv, e lookup_data_copy_col_read_inv, e lookup_addressing_relative_overflow_result_0_inv, e lookup_addressing_relative_overflow_result_1_inv, e lookup_addressing_relative_overflow_result_2_inv, e lookup_addressing_relative_overflow_result_3_inv, e lookup_addressing_relative_overflow_result_4_inv, e lookup_addressing_relative_overflow_result_5_inv, e lookup_addressing_relative_overflow_result_6_inv, e lookup_gas_addressing_gas_read_inv, e lookup_gas_is_out_of_gas_l2_inv, e lookup_gas_is_out_of_gas_da_inv, e lookup_merkle_check_merkle_poseidon2_read_inv, e lookup_merkle_check_merkle_poseidon2_write_inv, e lookup_nullifier_check_silo_poseidon2_inv, e lookup_nullifier_check_low_leaf_poseidon2_inv, e lookup_nullifier_check_updated_low_leaf_poseidon2_inv, e lookup_nullifier_check_low_leaf_merkle_check_inv, e lookup_nullifier_check_low_leaf_nullifier_validation_inv, e lookup_nullifier_check_low_leaf_next_nullifier_validation_inv, e lookup_nullifier_check_new_leaf_poseidon2_inv, e lookup_nullifier_check_new_leaf_merkle_check_inv, e lookup_nullifier_check_write_nullifier_to_public_inputs_inv, e lookup_public_data_squash_leaf_slot_increase_ff_gt_inv, e lookup_public_data_squash_clk_diff_range_lo_inv, e lookup_public_data_squash_clk_diff_range_hi_inv, e lookup_public_data_check_clk_diff_range_lo_inv, e lookup_public_data_check_clk_diff_range_hi_inv, e lookup_public_data_check_silo_poseidon2_inv, e lookup_public_data_check_low_leaf_slot_validation_inv, e lookup_public_data_check_low_leaf_next_slot_validation_inv, e lookup_public_data_check_low_leaf_poseidon2_0_inv, e lookup_public_data_check_low_leaf_poseidon2_1_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_0_inv, e lookup_public_data_check_updated_low_leaf_poseidon2_1_inv, e lookup_public_data_check_low_leaf_merkle_check_inv, e lookup_public_data_check_new_leaf_poseidon2_0_inv, e lookup_public_data_check_new_leaf_poseidon2_1_inv, e lookup_public_data_check_new_leaf_merkle_check_inv, e lookup_public_data_check_write_public_data_to_public_inputs_inv, e lookup_public_data_check_write_writes_length_to_public_inputs_inv, e lookup_written_public_data_slots_tree_check_silo_poseidon2_inv, e lookup_written_public_data_slots_tree_check_low_leaf_poseidon2_inv, e lookup_written_public_data_slots_tree_check_updated_low_leaf_poseidon2_inv, e lookup_written_public_data_slots_tree_check_low_leaf_merkle_check_inv, e lookup_written_public_data_slots_tree_check_low_leaf_slot_validation_inv, e lookup_written_public_data_slots_tree_check_low_leaf_next_slot_validation_inv, e lookup_written_public_data_slots_tree_check_new_leaf_poseidon2_inv, e lookup_written_public_data_slots_tree_check_new_leaf_merkle_check_inv, e lookup_l1_to_l2_message_tree_check_merkle_check_inv, e lookup_retrieved_bytecodes_tree_check_low_leaf_poseidon2_inv, e lookup_retrieved_bytecodes_tree_check_updated_low_leaf_poseidon2_inv, e lookup_retrieved_bytecodes_tree_check_low_leaf_merkle_check_inv, e lookup_retrieved_bytecodes_tree_check_low_leaf_class_id_validation_inv, e lookup_retrieved_bytecodes_tree_check_low_leaf_next_class_id_validation_inv, e lookup_retrieved_bytecodes_tree_check_new_leaf_poseidon2_inv, e lookup_retrieved_bytecodes_tree_check_new_leaf_merkle_check_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_0_inv, e lookup_address_derivation_salted_initialization_hash_poseidon2_1_inv, e lookup_address_derivation_partial_address_poseidon2_inv, e lookup_address_derivation_public_keys_hash_poseidon2_0_inv, e lookup_address_derivation_public_keys_hash_poseidon2_1_inv, e lookup_address_derivation_public_keys_hash_poseidon2_2_inv, e lookup_address_derivation_public_keys_hash_poseidon2_3_inv, e lookup_address_derivation_public_keys_hash_poseidon2_4_inv, e lookup_address_derivation_preaddress_poseidon2_inv, e lookup_address_derivation_preaddress_scalar_mul_inv, e lookup_address_derivation_address_ecadd_inv, e lookup_bc_decomposition_bytes_are_bytes_inv, e lookup_bc_hashing_check_final_bytes_remaining_inv, e lookup_bc_hashing_poseidon2_hash_inv, e lookup_update_check_timestamp_from_public_inputs_inv, e lookup_update_check_delayed_public_mutable_slot_poseidon2_inv, e lookup_update_check_update_hash_public_data_read_inv, e lookup_update_check_update_hash_poseidon2_inv, e lookup_update_check_update_hi_metadata_range_inv, e lookup_update_check_update_lo_metadata_range_inv, e lookup_update_check_timestamp_is_lt_timestamp_of_change_inv, e lookup_contract_instance_retrieval_check_protocol_address_range_inv, e lookup_contract_instance_retrieval_read_derived_address_from_public_inputs_inv, e lookup_contract_instance_retrieval_deployment_nullifier_read_inv, e lookup_contract_instance_retrieval_address_derivation_inv, e lookup_contract_instance_retrieval_update_check_inv, e lookup_bc_retrieval_contract_instance_retrieval_inv, e lookup_bc_retrieval_is_new_class_check_inv, e lookup_bc_retrieval_class_id_derivation_inv, e lookup_bc_retrieval_retrieved_bytecodes_insertion_inv, e lookup_instr_fetching_pc_abs_diff_positive_inv, e lookup_instr_fetching_instr_abs_diff_positive_inv, e lookup_instr_fetching_tag_value_validation_inv, e lookup_instr_fetching_bytecode_size_from_bc_dec_inv, e lookup_instr_fetching_bytes_from_bc_dec_inv, e lookup_instr_fetching_wire_instruction_info_inv, e lookup_class_id_derivation_class_id_poseidon2_0_inv, e lookup_class_id_derivation_class_id_poseidon2_1_inv, e lookup_get_env_var_precomputed_info_inv, e lookup_get_env_var_read_from_public_inputs_col0_inv, e lookup_get_env_var_read_from_public_inputs_col1_inv, e lookup_get_contract_instance_precomputed_info_inv, e lookup_get_contract_instance_contract_instance_retrieval_inv, e lookup_internal_call_unwind_call_stack_inv, e lookup_external_call_is_l2_gas_left_gt_allocated_inv, e lookup_external_call_is_da_gas_left_gt_allocated_inv, e lookup_sload_storage_read_inv, e lookup_sstore_record_written_storage_slot_inv, e lookup_note_hash_tree_check_silo_poseidon2_inv, e lookup_note_hash_tree_check_read_first_nullifier_inv, e lookup_note_hash_tree_check_nonce_computation_poseidon2_inv, e lookup_note_hash_tree_check_unique_note_hash_poseidon2_inv, e lookup_note_hash_tree_check_merkle_check_inv, e lookup_note_hash_tree_check_write_note_hash_to_public_inputs_inv, e lookup_notehash_exists_note_hash_leaf_index_in_range_inv, e lookup_notehash_exists_note_hash_read_inv, e lookup_emit_notehash_notehash_tree_write_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_leaf_index_in_range_inv, e lookup_l1_to_l2_message_exists_l1_to_l2_msg_read_inv, e lookup_nullifier_exists_nullifier_exists_check_inv, e lookup_emit_nullifier_write_nullifier_inv, e lookup_emit_unencrypted_log_check_memory_out_of_bounds_inv, e lookup_emit_unencrypted_log_check_log_fields_count_inv, e lookup_emit_unencrypted_log_write_data_to_public_inputs_inv, e lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_inv, e lookup_execution_bytecode_retrieval_result_inv, e lookup_execution_instruction_fetching_result_inv, e lookup_execution_instruction_fetching_body_inv, e lookup_execution_exec_spec_read_inv, e lookup_execution_dyn_l2_factor_bitwise_inv, e lookup_execution_check_radix_gt_256_inv, e lookup_execution_get_p_limbs_inv, e lookup_execution_get_max_limbs_inv, e lookup_execution_check_written_storage_slot_inv, e lookup_execution_dispatch_to_alu_inv, e lookup_execution_dispatch_to_bitwise_inv, e lookup_execution_dispatch_to_cast_inv, e lookup_execution_dispatch_to_set_inv, e lookup_tx_context_public_inputs_note_hash_tree_inv, e lookup_tx_context_public_inputs_nullifier_tree_inv, e lookup_tx_context_public_inputs_public_data_tree_inv, e lookup_tx_context_public_inputs_l1_l2_tree_inv, e lookup_tx_context_public_inputs_gas_used_inv, e lookup_tx_context_public_inputs_read_gas_limit_inv, e lookup_tx_context_public_inputs_read_reverted_inv, e lookup_tx_context_restore_state_on_revert_inv, e lookup_tx_context_public_inputs_write_note_hash_count_inv, e lookup_tx_context_public_inputs_write_nullifier_count_inv, e lookup_tx_context_public_inputs_write_l2_to_l1_message_count_inv, e lookup_tx_context_public_inputs_write_unencrypted_log_count_inv, e lookup_tx_read_phase_spec_inv, e lookup_tx_read_phase_length_inv, e lookup_tx_read_public_call_request_phase_inv, e lookup_tx_read_tree_insert_value_inv, e lookup_tx_note_hash_append_inv, e lookup_tx_nullifier_append_inv, e lookup_tx_read_l2_l1_msg_inv, e lookup_tx_write_l2_l1_msg_inv, e lookup_tx_read_effective_fee_public_inputs_inv, e lookup_tx_read_fee_payer_public_inputs_inv, e lookup_tx_balance_slot_poseidon2_inv, e lookup_tx_balance_read_inv, e lookup_tx_balance_validation_inv, e lookup_tx_write_fee_public_inputs_inv -#define AVM2_SHIFTED_ENTITIES_E(e) e bc_decomposition_bytes_shift, e bc_decomposition_bytes_pc_plus_1_shift, e bc_decomposition_bytes_pc_plus_10_shift, e bc_decomposition_bytes_pc_plus_11_shift, e bc_decomposition_bytes_pc_plus_12_shift, e bc_decomposition_bytes_pc_plus_13_shift, e bc_decomposition_bytes_pc_plus_14_shift, e bc_decomposition_bytes_pc_plus_15_shift, e bc_decomposition_bytes_pc_plus_16_shift, e bc_decomposition_bytes_pc_plus_17_shift, e bc_decomposition_bytes_pc_plus_18_shift, e bc_decomposition_bytes_pc_plus_19_shift, e bc_decomposition_bytes_pc_plus_2_shift, e bc_decomposition_bytes_pc_plus_20_shift, e bc_decomposition_bytes_pc_plus_21_shift, e bc_decomposition_bytes_pc_plus_22_shift, e bc_decomposition_bytes_pc_plus_23_shift, e bc_decomposition_bytes_pc_plus_24_shift, e bc_decomposition_bytes_pc_plus_25_shift, e bc_decomposition_bytes_pc_plus_26_shift, e bc_decomposition_bytes_pc_plus_27_shift, e bc_decomposition_bytes_pc_plus_28_shift, e bc_decomposition_bytes_pc_plus_29_shift, e bc_decomposition_bytes_pc_plus_3_shift, e bc_decomposition_bytes_pc_plus_30_shift, e bc_decomposition_bytes_pc_plus_31_shift, e bc_decomposition_bytes_pc_plus_32_shift, e bc_decomposition_bytes_pc_plus_33_shift, e bc_decomposition_bytes_pc_plus_34_shift, e bc_decomposition_bytes_pc_plus_35_shift, e bc_decomposition_bytes_pc_plus_4_shift, e bc_decomposition_bytes_pc_plus_5_shift, e bc_decomposition_bytes_pc_plus_6_shift, e bc_decomposition_bytes_pc_plus_7_shift, e bc_decomposition_bytes_pc_plus_8_shift, e bc_decomposition_bytes_pc_plus_9_shift, e bc_decomposition_bytes_remaining_shift, e bc_decomposition_id_shift, e bc_decomposition_next_packed_pc_shift, e bc_decomposition_pc_shift, e bc_decomposition_sel_shift, e bc_decomposition_sel_packed_shift, e bc_decomposition_sel_windows_gt_remaining_shift, e bc_hashing_bytecode_id_shift, e bc_hashing_pc_index_shift, e bc_hashing_rounds_rem_shift, e bc_hashing_sel_shift, e bc_hashing_start_shift, e bc_retrieval_sel_shift, e bitwise_acc_ia_shift, e bitwise_acc_ib_shift, e bitwise_acc_ic_shift, e bitwise_ctr_shift, e bitwise_op_id_shift, e calldata_context_id_shift, e calldata_hashing_calldata_size_shift, e calldata_hashing_context_id_shift, e calldata_hashing_index_0__shift, e calldata_hashing_output_hash_shift, e calldata_hashing_rounds_rem_shift, e calldata_hashing_sel_shift, e calldata_hashing_start_shift, e calldata_index_shift, e calldata_sel_shift, e data_copy_clk_shift, e data_copy_copy_size_shift, e data_copy_dst_addr_shift, e data_copy_dst_context_id_shift, e data_copy_padding_shift, e data_copy_read_addr_shift, e data_copy_reads_left_shift, e data_copy_sel_shift, e data_copy_sel_cd_copy_shift, e data_copy_sel_start_shift, e data_copy_src_context_id_shift, e emit_unencrypted_log_contract_address_shift, e emit_unencrypted_log_correct_tag_shift, e emit_unencrypted_log_error_out_of_bounds_shift, e emit_unencrypted_log_error_tag_mismatch_shift, e emit_unencrypted_log_execution_clk_shift, e emit_unencrypted_log_is_write_contract_address_shift, e emit_unencrypted_log_is_write_memory_value_shift, e emit_unencrypted_log_log_address_shift, e emit_unencrypted_log_public_inputs_index_shift, e emit_unencrypted_log_remaining_rows_shift, e emit_unencrypted_log_seen_wrong_tag_shift, e emit_unencrypted_log_sel_shift, e emit_unencrypted_log_sel_should_write_to_public_inputs_shift, e emit_unencrypted_log_space_id_shift, e emit_unencrypted_log_start_shift, e execution_bytecode_id_shift, e execution_context_id_shift, e execution_contract_address_shift, e execution_da_gas_limit_shift, e execution_discard_shift, e execution_dying_context_id_shift, e execution_enqueued_call_start_shift, e execution_internal_call_id_shift, e execution_internal_call_return_id_shift, e execution_is_static_shift, e execution_l1_l2_tree_root_shift, e execution_l2_gas_limit_shift, e execution_last_child_id_shift, e execution_last_child_returndata_addr_shift, e execution_last_child_returndata_size_shift, e execution_last_child_success_shift, e execution_msg_sender_shift, e execution_next_context_id_shift, e execution_next_internal_call_id_shift, e execution_parent_calldata_addr_shift, e execution_parent_calldata_size_shift, e execution_parent_da_gas_limit_shift, e execution_parent_da_gas_used_shift, e execution_parent_id_shift, e execution_parent_l2_gas_limit_shift, e execution_parent_l2_gas_used_shift, e execution_pc_shift, e execution_prev_da_gas_used_shift, e execution_prev_l2_gas_used_shift, e execution_prev_note_hash_tree_root_shift, e execution_prev_note_hash_tree_size_shift, e execution_prev_nullifier_tree_root_shift, e execution_prev_nullifier_tree_size_shift, e execution_prev_num_l2_to_l1_messages_shift, e execution_prev_num_note_hashes_emitted_shift, e execution_prev_num_nullifiers_emitted_shift, e execution_prev_num_unencrypted_log_fields_shift, e execution_prev_public_data_tree_root_shift, e execution_prev_public_data_tree_size_shift, e execution_prev_retrieved_bytecodes_tree_root_shift, e execution_prev_retrieved_bytecodes_tree_size_shift, e execution_prev_written_public_data_slots_tree_root_shift, e execution_prev_written_public_data_slots_tree_size_shift, e execution_sel_shift, e execution_sel_first_row_in_context_shift, e execution_transaction_fee_shift, e ff_gt_a_hi_shift, e ff_gt_a_lo_shift, e ff_gt_b_hi_shift, e ff_gt_b_lo_shift, e ff_gt_cmp_rng_ctr_shift, e ff_gt_p_sub_a_hi_shift, e ff_gt_p_sub_a_lo_shift, e ff_gt_p_sub_b_hi_shift, e ff_gt_p_sub_b_lo_shift, e ff_gt_sel_shift, e ff_gt_sel_dec_shift, e ff_gt_sel_gt_shift, e keccak_memory_addr_shift, e keccak_memory_clk_shift, e keccak_memory_ctr_shift, e keccak_memory_rw_shift, e keccak_memory_space_id_shift, e keccak_memory_tag_error_shift, e keccak_memory_val_0__shift, e keccak_memory_val_10__shift, e keccak_memory_val_11__shift, e keccak_memory_val_12__shift, e keccak_memory_val_13__shift, e keccak_memory_val_14__shift, e keccak_memory_val_15__shift, e keccak_memory_val_16__shift, e keccak_memory_val_17__shift, e keccak_memory_val_18__shift, e keccak_memory_val_19__shift, e keccak_memory_val_1__shift, e keccak_memory_val_20__shift, e keccak_memory_val_21__shift, e keccak_memory_val_22__shift, e keccak_memory_val_23__shift, e keccak_memory_val_2__shift, e keccak_memory_val_3__shift, e keccak_memory_val_4__shift, e keccak_memory_val_5__shift, e keccak_memory_val_6__shift, e keccak_memory_val_7__shift, e keccak_memory_val_8__shift, e keccak_memory_val_9__shift, e keccakf1600_clk_shift, e keccakf1600_dst_addr_shift, e keccakf1600_round_shift, e keccakf1600_sel_no_error_shift, e keccakf1600_space_id_shift, e keccakf1600_state_in_00_shift, e keccakf1600_state_in_01_shift, e keccakf1600_state_in_02_shift, e keccakf1600_state_in_03_shift, e keccakf1600_state_in_04_shift, e keccakf1600_state_in_10_shift, e keccakf1600_state_in_11_shift, e keccakf1600_state_in_12_shift, e keccakf1600_state_in_13_shift, e keccakf1600_state_in_14_shift, e keccakf1600_state_in_20_shift, e keccakf1600_state_in_21_shift, e keccakf1600_state_in_22_shift, e keccakf1600_state_in_23_shift, e keccakf1600_state_in_24_shift, e keccakf1600_state_in_30_shift, e keccakf1600_state_in_31_shift, e keccakf1600_state_in_32_shift, e keccakf1600_state_in_33_shift, e keccakf1600_state_in_34_shift, e keccakf1600_state_in_40_shift, e keccakf1600_state_in_41_shift, e keccakf1600_state_in_42_shift, e keccakf1600_state_in_43_shift, e keccakf1600_state_in_44_shift, e memory_global_addr_shift, e memory_rw_shift, e memory_sel_shift, e memory_tag_shift, e memory_timestamp_shift, e memory_value_shift, e merkle_check_index_shift, e merkle_check_path_len_shift, e merkle_check_read_node_shift, e merkle_check_read_root_shift, e merkle_check_sel_shift, e merkle_check_write_shift, e merkle_check_write_node_shift, e merkle_check_write_root_shift, e poseidon2_hash_a_0_shift, e poseidon2_hash_a_1_shift, e poseidon2_hash_a_2_shift, e poseidon2_hash_a_3_shift, e poseidon2_hash_input_0_shift, e poseidon2_hash_input_1_shift, e poseidon2_hash_input_2_shift, e poseidon2_hash_num_perm_rounds_rem_shift, e poseidon2_hash_output_shift, e poseidon2_hash_sel_shift, e poseidon2_hash_start_shift, e public_data_check_clk_shift, e public_data_check_sel_shift, e public_data_check_write_idx_shift, e public_data_squash_clk_shift, e public_data_squash_final_value_shift, e public_data_squash_leaf_slot_shift, e public_data_squash_sel_shift, e public_data_squash_write_to_public_inputs_shift, e scalar_mul_bit_idx_shift, e scalar_mul_point_inf_shift, e scalar_mul_point_x_shift, e scalar_mul_point_y_shift, e scalar_mul_res_inf_shift, e scalar_mul_res_x_shift, e scalar_mul_res_y_shift, e scalar_mul_scalar_shift, e scalar_mul_sel_shift, e scalar_mul_start_shift, e scalar_mul_temp_inf_shift, e scalar_mul_temp_x_shift, e scalar_mul_temp_y_shift, e sha256_a_shift, e sha256_b_shift, e sha256_c_shift, e sha256_d_shift, e sha256_e_shift, e sha256_execution_clk_shift, e sha256_f_shift, e sha256_g_shift, e sha256_h_shift, e sha256_helper_w0_shift, e sha256_helper_w1_shift, e sha256_helper_w10_shift, e sha256_helper_w11_shift, e sha256_helper_w12_shift, e sha256_helper_w13_shift, e sha256_helper_w14_shift, e sha256_helper_w15_shift, e sha256_helper_w2_shift, e sha256_helper_w3_shift, e sha256_helper_w4_shift, e sha256_helper_w5_shift, e sha256_helper_w6_shift, e sha256_helper_w7_shift, e sha256_helper_w8_shift, e sha256_helper_w9_shift, e sha256_init_a_shift, e sha256_init_b_shift, e sha256_init_c_shift, e sha256_init_d_shift, e sha256_init_e_shift, e sha256_init_f_shift, e sha256_init_g_shift, e sha256_init_h_shift, e sha256_input_addr_shift, e sha256_input_rounds_rem_shift, e sha256_output_addr_shift, e sha256_rounds_remaining_shift, e sha256_sel_shift, e sha256_sel_invalid_input_tag_err_shift, e sha256_sel_is_input_round_shift, e sha256_space_id_shift, e sha256_start_shift, e to_radix_acc_shift, e to_radix_acc_under_p_shift, e to_radix_exponent_shift, e to_radix_limb_shift, e to_radix_limb_eq_p_shift, e to_radix_limb_index_shift, e to_radix_limb_lt_p_shift, e to_radix_mem_dst_addr_shift, e to_radix_mem_execution_clk_shift, e to_radix_mem_is_output_bits_shift, e to_radix_mem_num_limbs_shift, e to_radix_mem_radix_shift, e to_radix_mem_sel_shift, e to_radix_mem_sel_should_decompose_shift, e to_radix_mem_sel_should_write_mem_shift, e to_radix_mem_space_id_shift, e to_radix_mem_start_shift, e to_radix_mem_value_to_decompose_shift, e to_radix_not_padding_limb_shift, e to_radix_radix_shift, e to_radix_safe_limbs_shift, e to_radix_sel_shift, e to_radix_start_shift, e to_radix_value_shift, e tx_da_gas_limit_shift, e tx_discard_shift, e tx_fee_shift, e tx_is_revertible_shift, e tx_is_teardown_shift, e tx_l1_l2_tree_root_shift, e tx_l1_l2_tree_size_shift, e tx_l2_gas_limit_shift, e tx_next_context_id_shift, e tx_phase_value_shift, e tx_prev_da_gas_used_shift, e tx_prev_l2_gas_used_shift, e tx_prev_note_hash_tree_root_shift, e tx_prev_note_hash_tree_size_shift, e tx_prev_nullifier_tree_root_shift, e tx_prev_nullifier_tree_size_shift, e tx_prev_num_l2_to_l1_messages_shift, e tx_prev_num_note_hashes_emitted_shift, e tx_prev_num_nullifiers_emitted_shift, e tx_prev_num_unencrypted_log_fields_shift, e tx_prev_public_data_tree_root_shift, e tx_prev_public_data_tree_size_shift, e tx_prev_retrieved_bytecodes_tree_root_shift, e tx_prev_retrieved_bytecodes_tree_size_shift, e tx_prev_written_public_data_slots_tree_root_shift, e tx_prev_written_public_data_slots_tree_size_shift, e tx_read_pi_offset_shift, e tx_remaining_phase_counter_shift, e tx_reverted_shift, e tx_sel_shift, e tx_start_phase_shift, e tx_start_tx_shift, e tx_tx_reverted_shift -#define AVM2_TO_BE_SHIFTED_E(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_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_packed, e bc_decomposition_sel_windows_gt_remaining, e bc_hashing_bytecode_id, e bc_hashing_pc_index, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_start, e bc_retrieval_sel, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_sel_start, e data_copy_src_context_id, e emit_unencrypted_log_contract_address, e emit_unencrypted_log_correct_tag, e emit_unencrypted_log_error_out_of_bounds, e emit_unencrypted_log_error_tag_mismatch, e emit_unencrypted_log_execution_clk, e emit_unencrypted_log_is_write_contract_address, e emit_unencrypted_log_is_write_memory_value, e emit_unencrypted_log_log_address, e emit_unencrypted_log_public_inputs_index, e emit_unencrypted_log_remaining_rows, e emit_unencrypted_log_seen_wrong_tag, e emit_unencrypted_log_sel, e emit_unencrypted_log_sel_should_write_to_public_inputs, e emit_unencrypted_log_space_id, e emit_unencrypted_log_start, e execution_bytecode_id, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_unencrypted_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_space_id, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_global_addr, e memory_rw, e memory_sel, e memory_tag, e memory_timestamp, e memory_value, e merkle_check_index, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, 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 public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, 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_execution_clk, 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_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_sel_is_input_round, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_exponent, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_unencrypted_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted +#define AVM2_SHIFTED_ENTITIES_E(e) e bc_decomposition_bytes_shift, e bc_decomposition_bytes_pc_plus_1_shift, e bc_decomposition_bytes_pc_plus_10_shift, e bc_decomposition_bytes_pc_plus_11_shift, e bc_decomposition_bytes_pc_plus_12_shift, e bc_decomposition_bytes_pc_plus_13_shift, e bc_decomposition_bytes_pc_plus_14_shift, e bc_decomposition_bytes_pc_plus_15_shift, e bc_decomposition_bytes_pc_plus_16_shift, e bc_decomposition_bytes_pc_plus_17_shift, e bc_decomposition_bytes_pc_plus_18_shift, e bc_decomposition_bytes_pc_plus_19_shift, e bc_decomposition_bytes_pc_plus_2_shift, e bc_decomposition_bytes_pc_plus_20_shift, e bc_decomposition_bytes_pc_plus_21_shift, e bc_decomposition_bytes_pc_plus_22_shift, e bc_decomposition_bytes_pc_plus_23_shift, e bc_decomposition_bytes_pc_plus_24_shift, e bc_decomposition_bytes_pc_plus_25_shift, e bc_decomposition_bytes_pc_plus_26_shift, e bc_decomposition_bytes_pc_plus_27_shift, e bc_decomposition_bytes_pc_plus_28_shift, e bc_decomposition_bytes_pc_plus_29_shift, e bc_decomposition_bytes_pc_plus_3_shift, e bc_decomposition_bytes_pc_plus_30_shift, e bc_decomposition_bytes_pc_plus_31_shift, e bc_decomposition_bytes_pc_plus_32_shift, e bc_decomposition_bytes_pc_plus_33_shift, e bc_decomposition_bytes_pc_plus_34_shift, e bc_decomposition_bytes_pc_plus_35_shift, e bc_decomposition_bytes_pc_plus_4_shift, e bc_decomposition_bytes_pc_plus_5_shift, e bc_decomposition_bytes_pc_plus_6_shift, e bc_decomposition_bytes_pc_plus_7_shift, e bc_decomposition_bytes_pc_plus_8_shift, e bc_decomposition_bytes_pc_plus_9_shift, e bc_decomposition_bytes_remaining_shift, e bc_decomposition_id_shift, e bc_decomposition_next_packed_pc_shift, e bc_decomposition_pc_shift, e bc_decomposition_sel_shift, e bc_decomposition_sel_packed_shift, e bc_decomposition_sel_windows_gt_remaining_shift, e bc_hashing_bytecode_id_shift, e bc_hashing_pc_index_shift, e bc_hashing_rounds_rem_shift, e bc_hashing_sel_shift, e bc_hashing_start_shift, e bc_retrieval_sel_shift, e bitwise_acc_ia_shift, e bitwise_acc_ib_shift, e bitwise_acc_ic_shift, e bitwise_ctr_shift, e bitwise_op_id_shift, e calldata_context_id_shift, e calldata_hashing_calldata_size_shift, e calldata_hashing_context_id_shift, e calldata_hashing_index_0__shift, e calldata_hashing_output_hash_shift, e calldata_hashing_rounds_rem_shift, e calldata_hashing_sel_shift, e calldata_hashing_start_shift, e calldata_index_shift, e calldata_sel_shift, e data_copy_clk_shift, e data_copy_copy_size_shift, e data_copy_dst_addr_shift, e data_copy_dst_context_id_shift, e data_copy_padding_shift, e data_copy_read_addr_shift, e data_copy_reads_left_shift, e data_copy_sel_shift, e data_copy_sel_cd_copy_shift, e data_copy_sel_start_shift, e data_copy_src_context_id_shift, e emit_unencrypted_log_contract_address_shift, e emit_unencrypted_log_correct_tag_shift, e emit_unencrypted_log_error_out_of_bounds_shift, e emit_unencrypted_log_error_tag_mismatch_shift, e emit_unencrypted_log_execution_clk_shift, e emit_unencrypted_log_is_write_contract_address_shift, e emit_unencrypted_log_is_write_memory_value_shift, e emit_unencrypted_log_log_address_shift, e emit_unencrypted_log_public_inputs_index_shift, e emit_unencrypted_log_remaining_rows_shift, e emit_unencrypted_log_seen_wrong_tag_shift, e emit_unencrypted_log_sel_shift, e emit_unencrypted_log_sel_should_write_to_public_inputs_shift, e emit_unencrypted_log_space_id_shift, e emit_unencrypted_log_start_shift, e execution_bytecode_id_shift, e execution_context_id_shift, e execution_contract_address_shift, e execution_da_gas_limit_shift, e execution_discard_shift, e execution_dying_context_id_shift, e execution_enqueued_call_start_shift, e execution_internal_call_id_shift, e execution_internal_call_return_id_shift, e execution_is_static_shift, e execution_l1_l2_tree_root_shift, e execution_l2_gas_limit_shift, e execution_last_child_id_shift, e execution_last_child_returndata_addr_shift, e execution_last_child_returndata_size_shift, e execution_last_child_success_shift, e execution_msg_sender_shift, e execution_next_context_id_shift, e execution_next_internal_call_id_shift, e execution_parent_calldata_addr_shift, e execution_parent_calldata_size_shift, e execution_parent_da_gas_limit_shift, e execution_parent_da_gas_used_shift, e execution_parent_id_shift, e execution_parent_l2_gas_limit_shift, e execution_parent_l2_gas_used_shift, e execution_pc_shift, e execution_prev_da_gas_used_shift, e execution_prev_l2_gas_used_shift, e execution_prev_note_hash_tree_root_shift, e execution_prev_note_hash_tree_size_shift, e execution_prev_nullifier_tree_root_shift, e execution_prev_nullifier_tree_size_shift, e execution_prev_num_l2_to_l1_messages_shift, e execution_prev_num_note_hashes_emitted_shift, e execution_prev_num_nullifiers_emitted_shift, e execution_prev_num_unencrypted_log_fields_shift, e execution_prev_public_data_tree_root_shift, e execution_prev_public_data_tree_size_shift, e execution_prev_retrieved_bytecodes_tree_root_shift, e execution_prev_retrieved_bytecodes_tree_size_shift, e execution_prev_written_public_data_slots_tree_root_shift, e execution_prev_written_public_data_slots_tree_size_shift, e execution_sel_shift, e execution_sel_first_row_in_context_shift, e execution_transaction_fee_shift, e ff_gt_a_hi_shift, e ff_gt_a_lo_shift, e ff_gt_b_hi_shift, e ff_gt_b_lo_shift, e ff_gt_cmp_rng_ctr_shift, e ff_gt_p_sub_a_hi_shift, e ff_gt_p_sub_a_lo_shift, e ff_gt_p_sub_b_hi_shift, e ff_gt_p_sub_b_lo_shift, e ff_gt_sel_shift, e ff_gt_sel_dec_shift, e ff_gt_sel_gt_shift, e keccak_memory_addr_shift, e keccak_memory_clk_shift, e keccak_memory_ctr_shift, e keccak_memory_rw_shift, e keccak_memory_sel_shift, e keccak_memory_space_id_shift, e keccak_memory_start_read_shift, e keccak_memory_start_write_shift, e keccak_memory_tag_error_shift, e keccak_memory_val_0__shift, e keccak_memory_val_10__shift, e keccak_memory_val_11__shift, e keccak_memory_val_12__shift, e keccak_memory_val_13__shift, e keccak_memory_val_14__shift, e keccak_memory_val_15__shift, e keccak_memory_val_16__shift, e keccak_memory_val_17__shift, e keccak_memory_val_18__shift, e keccak_memory_val_19__shift, e keccak_memory_val_1__shift, e keccak_memory_val_20__shift, e keccak_memory_val_21__shift, e keccak_memory_val_22__shift, e keccak_memory_val_23__shift, e keccak_memory_val_2__shift, e keccak_memory_val_3__shift, e keccak_memory_val_4__shift, e keccak_memory_val_5__shift, e keccak_memory_val_6__shift, e keccak_memory_val_7__shift, e keccak_memory_val_8__shift, e keccak_memory_val_9__shift, e keccakf1600_clk_shift, e keccakf1600_dst_addr_shift, e keccakf1600_round_shift, e keccakf1600_sel_shift, e keccakf1600_sel_no_error_shift, e keccakf1600_space_id_shift, e keccakf1600_start_shift, e keccakf1600_state_in_00_shift, e keccakf1600_state_in_01_shift, e keccakf1600_state_in_02_shift, e keccakf1600_state_in_03_shift, e keccakf1600_state_in_04_shift, e keccakf1600_state_in_10_shift, e keccakf1600_state_in_11_shift, e keccakf1600_state_in_12_shift, e keccakf1600_state_in_13_shift, e keccakf1600_state_in_14_shift, e keccakf1600_state_in_20_shift, e keccakf1600_state_in_21_shift, e keccakf1600_state_in_22_shift, e keccakf1600_state_in_23_shift, e keccakf1600_state_in_24_shift, e keccakf1600_state_in_30_shift, e keccakf1600_state_in_31_shift, e keccakf1600_state_in_32_shift, e keccakf1600_state_in_33_shift, e keccakf1600_state_in_34_shift, e keccakf1600_state_in_40_shift, e keccakf1600_state_in_41_shift, e keccakf1600_state_in_42_shift, e keccakf1600_state_in_43_shift, e keccakf1600_state_in_44_shift, e memory_global_addr_shift, e memory_rw_shift, e memory_sel_shift, e memory_tag_shift, e memory_timestamp_shift, e memory_value_shift, e merkle_check_index_shift, e merkle_check_path_len_shift, e merkle_check_read_node_shift, e merkle_check_read_root_shift, e merkle_check_sel_shift, e merkle_check_write_shift, e merkle_check_write_node_shift, e merkle_check_write_root_shift, e poseidon2_hash_a_0_shift, e poseidon2_hash_a_1_shift, e poseidon2_hash_a_2_shift, e poseidon2_hash_a_3_shift, e poseidon2_hash_input_0_shift, e poseidon2_hash_input_1_shift, e poseidon2_hash_input_2_shift, e poseidon2_hash_num_perm_rounds_rem_shift, e poseidon2_hash_output_shift, e poseidon2_hash_sel_shift, e poseidon2_hash_start_shift, e public_data_check_clk_shift, e public_data_check_sel_shift, e public_data_check_write_idx_shift, e public_data_squash_clk_shift, e public_data_squash_final_value_shift, e public_data_squash_leaf_slot_shift, e public_data_squash_sel_shift, e public_data_squash_write_to_public_inputs_shift, e scalar_mul_bit_idx_shift, e scalar_mul_point_inf_shift, e scalar_mul_point_x_shift, e scalar_mul_point_y_shift, e scalar_mul_res_inf_shift, e scalar_mul_res_x_shift, e scalar_mul_res_y_shift, e scalar_mul_scalar_shift, e scalar_mul_sel_shift, e scalar_mul_start_shift, e scalar_mul_temp_inf_shift, e scalar_mul_temp_x_shift, e scalar_mul_temp_y_shift, e sha256_a_shift, e sha256_b_shift, e sha256_c_shift, e sha256_d_shift, e sha256_e_shift, e sha256_execution_clk_shift, e sha256_f_shift, e sha256_g_shift, e sha256_h_shift, e sha256_helper_w0_shift, e sha256_helper_w1_shift, e sha256_helper_w10_shift, e sha256_helper_w11_shift, e sha256_helper_w12_shift, e sha256_helper_w13_shift, e sha256_helper_w14_shift, e sha256_helper_w15_shift, e sha256_helper_w2_shift, e sha256_helper_w3_shift, e sha256_helper_w4_shift, e sha256_helper_w5_shift, e sha256_helper_w6_shift, e sha256_helper_w7_shift, e sha256_helper_w8_shift, e sha256_helper_w9_shift, e sha256_init_a_shift, e sha256_init_b_shift, e sha256_init_c_shift, e sha256_init_d_shift, e sha256_init_e_shift, e sha256_init_f_shift, e sha256_init_g_shift, e sha256_init_h_shift, e sha256_input_addr_shift, e sha256_input_rounds_rem_shift, e sha256_output_addr_shift, e sha256_rounds_remaining_shift, e sha256_sel_shift, e sha256_sel_invalid_input_tag_err_shift, e sha256_sel_is_input_round_shift, e sha256_space_id_shift, e sha256_start_shift, e to_radix_acc_shift, e to_radix_acc_under_p_shift, e to_radix_exponent_shift, e to_radix_limb_shift, e to_radix_limb_eq_p_shift, e to_radix_limb_index_shift, e to_radix_limb_lt_p_shift, e to_radix_mem_dst_addr_shift, e to_radix_mem_execution_clk_shift, e to_radix_mem_is_output_bits_shift, e to_radix_mem_num_limbs_shift, e to_radix_mem_radix_shift, e to_radix_mem_sel_shift, e to_radix_mem_sel_should_decompose_shift, e to_radix_mem_sel_should_write_mem_shift, e to_radix_mem_space_id_shift, e to_radix_mem_start_shift, e to_radix_mem_value_to_decompose_shift, e to_radix_not_padding_limb_shift, e to_radix_radix_shift, e to_radix_safe_limbs_shift, e to_radix_sel_shift, e to_radix_start_shift, e to_radix_value_shift, e tx_da_gas_limit_shift, e tx_discard_shift, e tx_fee_shift, e tx_is_revertible_shift, e tx_is_teardown_shift, e tx_l1_l2_tree_root_shift, e tx_l1_l2_tree_size_shift, e tx_l2_gas_limit_shift, e tx_next_context_id_shift, e tx_phase_value_shift, e tx_prev_da_gas_used_shift, e tx_prev_l2_gas_used_shift, e tx_prev_note_hash_tree_root_shift, e tx_prev_note_hash_tree_size_shift, e tx_prev_nullifier_tree_root_shift, e tx_prev_nullifier_tree_size_shift, e tx_prev_num_l2_to_l1_messages_shift, e tx_prev_num_note_hashes_emitted_shift, e tx_prev_num_nullifiers_emitted_shift, e tx_prev_num_unencrypted_log_fields_shift, e tx_prev_public_data_tree_root_shift, e tx_prev_public_data_tree_size_shift, e tx_prev_retrieved_bytecodes_tree_root_shift, e tx_prev_retrieved_bytecodes_tree_size_shift, e tx_prev_written_public_data_slots_tree_root_shift, e tx_prev_written_public_data_slots_tree_size_shift, e tx_read_pi_offset_shift, e tx_remaining_phase_counter_shift, e tx_reverted_shift, e tx_sel_shift, e tx_start_phase_shift, e tx_start_tx_shift, e tx_tx_reverted_shift +#define AVM2_TO_BE_SHIFTED_E(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_next_packed_pc, e bc_decomposition_pc, e bc_decomposition_sel, e bc_decomposition_sel_packed, e bc_decomposition_sel_windows_gt_remaining, e bc_hashing_bytecode_id, e bc_hashing_pc_index, e bc_hashing_rounds_rem, e bc_hashing_sel, e bc_hashing_start, e bc_retrieval_sel, e bitwise_acc_ia, e bitwise_acc_ib, e bitwise_acc_ic, e bitwise_ctr, e bitwise_op_id, e calldata_context_id, e calldata_hashing_calldata_size, e calldata_hashing_context_id, e calldata_hashing_index_0_, e calldata_hashing_output_hash, e calldata_hashing_rounds_rem, e calldata_hashing_sel, e calldata_hashing_start, e calldata_index, e calldata_sel, e data_copy_clk, e data_copy_copy_size, e data_copy_dst_addr, e data_copy_dst_context_id, e data_copy_padding, e data_copy_read_addr, e data_copy_reads_left, e data_copy_sel, e data_copy_sel_cd_copy, e data_copy_sel_start, e data_copy_src_context_id, e emit_unencrypted_log_contract_address, e emit_unencrypted_log_correct_tag, e emit_unencrypted_log_error_out_of_bounds, e emit_unencrypted_log_error_tag_mismatch, e emit_unencrypted_log_execution_clk, e emit_unencrypted_log_is_write_contract_address, e emit_unencrypted_log_is_write_memory_value, e emit_unencrypted_log_log_address, e emit_unencrypted_log_public_inputs_index, e emit_unencrypted_log_remaining_rows, e emit_unencrypted_log_seen_wrong_tag, e emit_unencrypted_log_sel, e emit_unencrypted_log_sel_should_write_to_public_inputs, e emit_unencrypted_log_space_id, e emit_unencrypted_log_start, e execution_bytecode_id, e execution_context_id, e execution_contract_address, e execution_da_gas_limit, e execution_discard, e execution_dying_context_id, e execution_enqueued_call_start, e execution_internal_call_id, e execution_internal_call_return_id, e execution_is_static, e execution_l1_l2_tree_root, e execution_l2_gas_limit, e execution_last_child_id, e execution_last_child_returndata_addr, e execution_last_child_returndata_size, e execution_last_child_success, e execution_msg_sender, e execution_next_context_id, e execution_next_internal_call_id, e execution_parent_calldata_addr, e execution_parent_calldata_size, e execution_parent_da_gas_limit, e execution_parent_da_gas_used, e execution_parent_id, e execution_parent_l2_gas_limit, e execution_parent_l2_gas_used, e execution_pc, e execution_prev_da_gas_used, e execution_prev_l2_gas_used, e execution_prev_note_hash_tree_root, e execution_prev_note_hash_tree_size, e execution_prev_nullifier_tree_root, e execution_prev_nullifier_tree_size, e execution_prev_num_l2_to_l1_messages, e execution_prev_num_note_hashes_emitted, e execution_prev_num_nullifiers_emitted, e execution_prev_num_unencrypted_log_fields, e execution_prev_public_data_tree_root, e execution_prev_public_data_tree_size, e execution_prev_retrieved_bytecodes_tree_root, e execution_prev_retrieved_bytecodes_tree_size, e execution_prev_written_public_data_slots_tree_root, e execution_prev_written_public_data_slots_tree_size, e execution_sel, e execution_sel_first_row_in_context, e execution_transaction_fee, e ff_gt_a_hi, e ff_gt_a_lo, e ff_gt_b_hi, e ff_gt_b_lo, e ff_gt_cmp_rng_ctr, e ff_gt_p_sub_a_hi, e ff_gt_p_sub_a_lo, e ff_gt_p_sub_b_hi, e ff_gt_p_sub_b_lo, e ff_gt_sel, e ff_gt_sel_dec, e ff_gt_sel_gt, e keccak_memory_addr, e keccak_memory_clk, e keccak_memory_ctr, e keccak_memory_rw, e keccak_memory_sel, e keccak_memory_space_id, e keccak_memory_start_read, e keccak_memory_start_write, e keccak_memory_tag_error, e keccak_memory_val_0_, e keccak_memory_val_10_, e keccak_memory_val_11_, e keccak_memory_val_12_, e keccak_memory_val_13_, e keccak_memory_val_14_, e keccak_memory_val_15_, e keccak_memory_val_16_, e keccak_memory_val_17_, e keccak_memory_val_18_, e keccak_memory_val_19_, e keccak_memory_val_1_, e keccak_memory_val_20_, e keccak_memory_val_21_, e keccak_memory_val_22_, e keccak_memory_val_23_, e keccak_memory_val_2_, e keccak_memory_val_3_, e keccak_memory_val_4_, e keccak_memory_val_5_, e keccak_memory_val_6_, e keccak_memory_val_7_, e keccak_memory_val_8_, e keccak_memory_val_9_, e keccakf1600_clk, e keccakf1600_dst_addr, e keccakf1600_round, e keccakf1600_sel, e keccakf1600_sel_no_error, e keccakf1600_space_id, e keccakf1600_start, e keccakf1600_state_in_00, e keccakf1600_state_in_01, e keccakf1600_state_in_02, e keccakf1600_state_in_03, e keccakf1600_state_in_04, e keccakf1600_state_in_10, e keccakf1600_state_in_11, e keccakf1600_state_in_12, e keccakf1600_state_in_13, e keccakf1600_state_in_14, e keccakf1600_state_in_20, e keccakf1600_state_in_21, e keccakf1600_state_in_22, e keccakf1600_state_in_23, e keccakf1600_state_in_24, e keccakf1600_state_in_30, e keccakf1600_state_in_31, e keccakf1600_state_in_32, e keccakf1600_state_in_33, e keccakf1600_state_in_34, e keccakf1600_state_in_40, e keccakf1600_state_in_41, e keccakf1600_state_in_42, e keccakf1600_state_in_43, e keccakf1600_state_in_44, e memory_global_addr, e memory_rw, e memory_sel, e memory_tag, e memory_timestamp, e memory_value, e merkle_check_index, e merkle_check_path_len, e merkle_check_read_node, e merkle_check_read_root, e merkle_check_sel, e merkle_check_write, e merkle_check_write_node, e merkle_check_write_root, 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 public_data_check_clk, e public_data_check_sel, e public_data_check_write_idx, e public_data_squash_clk, e public_data_squash_final_value, e public_data_squash_leaf_slot, e public_data_squash_sel, e public_data_squash_write_to_public_inputs, 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_execution_clk, 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_init_a, e sha256_init_b, e sha256_init_c, e sha256_init_d, e sha256_init_e, e sha256_init_f, e sha256_init_g, e sha256_init_h, e sha256_input_addr, e sha256_input_rounds_rem, e sha256_output_addr, e sha256_rounds_remaining, e sha256_sel, e sha256_sel_invalid_input_tag_err, e sha256_sel_is_input_round, e sha256_space_id, e sha256_start, e to_radix_acc, e to_radix_acc_under_p, e to_radix_exponent, e to_radix_limb, e to_radix_limb_eq_p, e to_radix_limb_index, e to_radix_limb_lt_p, e to_radix_mem_dst_addr, e to_radix_mem_execution_clk, e to_radix_mem_is_output_bits, e to_radix_mem_num_limbs, e to_radix_mem_radix, e to_radix_mem_sel, e to_radix_mem_sel_should_decompose, e to_radix_mem_sel_should_write_mem, e to_radix_mem_space_id, e to_radix_mem_start, e to_radix_mem_value_to_decompose, e to_radix_not_padding_limb, e to_radix_radix, e to_radix_safe_limbs, e to_radix_sel, e to_radix_start, e to_radix_value, e tx_da_gas_limit, e tx_discard, e tx_fee, e tx_is_revertible, e tx_is_teardown, e tx_l1_l2_tree_root, e tx_l1_l2_tree_size, e tx_l2_gas_limit, e tx_next_context_id, e tx_phase_value, e tx_prev_da_gas_used, e tx_prev_l2_gas_used, e tx_prev_note_hash_tree_root, e tx_prev_note_hash_tree_size, e tx_prev_nullifier_tree_root, e tx_prev_nullifier_tree_size, e tx_prev_num_l2_to_l1_messages, e tx_prev_num_note_hashes_emitted, e tx_prev_num_nullifiers_emitted, e tx_prev_num_unencrypted_log_fields, e tx_prev_public_data_tree_root, e tx_prev_public_data_tree_size, e tx_prev_retrieved_bytecodes_tree_root, e tx_prev_retrieved_bytecodes_tree_size, e tx_prev_written_public_data_slots_tree_root, e tx_prev_written_public_data_slots_tree_size, e tx_read_pi_offset, e tx_remaining_phase_counter, e tx_reverted, e tx_sel, e tx_start_phase, e tx_start_tx, e tx_tx_reverted #define AVM2_ALL_ENTITIES_E(e) AVM2_PRECOMPUTED_ENTITIES_E(e), AVM2_WIRE_ENTITIES_E(e), AVM2_DERIVED_WITNESS_ENTITIES_E(e), AVM2_SHIFTED_ENTITIES_E(e) #define AVM2_PRECOMPUTED_ENTITIES AVM2_PRECOMPUTED_ENTITIES_E() @@ -36,16 +36,16 @@ enum class ColumnAndShifts { SENTINEL_DO_NOT_USE, }; -constexpr auto NUM_COLUMNS_WITH_SHIFTS = 3537; +constexpr auto NUM_COLUMNS_WITH_SHIFTS = 3542; constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 3184; constexpr auto NUM_PRECOMPUTED_ENTITIES = 123; constexpr auto NUM_WIRE_ENTITIES = 2595; constexpr auto NUM_DERIVED_ENTITIES = 466; constexpr auto NUM_WITNESS_ENTITIES = NUM_WIRE_ENTITIES + NUM_DERIVED_ENTITIES; -constexpr auto NUM_WIRES_TO_BE_SHIFTED = 353; -constexpr auto NUM_SHIFTED_ENTITIES = 353; +constexpr auto NUM_WIRES_TO_BE_SHIFTED = 358; +constexpr auto NUM_SHIFTED_ENTITIES = 358; constexpr auto NUM_UNSHIFTED_ENTITIES = NUM_COLUMNS_WITHOUT_SHIFTS; -constexpr auto NUM_ALL_ENTITIES = 3537; +constexpr auto NUM_ALL_ENTITIES = 3542; /* * Layout for all entities is: diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp index 0b277cf05488..da2e3ba92e1c 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp @@ -146,9 +146,9 @@ namespace bb::avm2 { struct AvmFlavorVariables { static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 123; static constexpr size_t NUM_WITNESS_ENTITIES = 3061; - static constexpr size_t NUM_SHIFTED_ENTITIES = 353; + static constexpr size_t NUM_SHIFTED_ENTITIES = 358; static constexpr size_t NUM_WIRES = 2595; - static constexpr size_t NUM_ALL_ENTITIES = 3537; + static constexpr size_t NUM_ALL_ENTITIES = 3542; // Need to be templated for recursive verifier template diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccak_memory.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccak_memory.hpp index f9315e8fb4a4..252bb9357d06 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccak_memory.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccak_memory.hpp @@ -14,10 +14,10 @@ template class keccak_memoryImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { - 3, 3, 3, 3, 3, 3, 4, 3, 5, 3, 4, 3, 3, 3, 3, 4, 3, 3, 3, 5, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 4, 3, 3, 3, 3, 3, 4, 3, 5, 3, 3, + 3, 4, 3, 3, 3, 3, 4, 3, 3, 3, 5, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; template inline static bool skip(const AllEntities& in) { @@ -38,50 +38,55 @@ template class keccak_memory : public Relation class keccak_memory : public Relation::accumulate(ContainerOverSubrelations& evals, const auto constants_MEM_TAG_U64 = FF(5); const auto constants_AVM_KECCAKF1600_NUM_ROUNDS = FF(24); const auto constants_AVM_KECCAKF1600_STATE_SIZE = FF(25); + const auto keccak_memory_LATCH_CONDITION = in.get(C::keccak_memory_last) + in.get(C::precomputed_first_row); const auto keccak_memory_TAG_MIN_U64 = (in.get(C::keccak_memory_tag) - constants_MEM_TAG_U64); { @@ -26,54 +27,61 @@ void keccak_memoryImpl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::keccak_memory_sel)) * (FF(1) - static_cast(in.get(C::keccak_memory_sel))); std::get<0>(evals) += (tmp * scaling_factor); } - { + { // TRACE_CONTINUITY using View = typename std::tuple_element_t<1, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::keccak_memory_start_read)) * - (FF(1) - static_cast(in.get(C::keccak_memory_start_read))); + auto tmp = (FF(1) - static_cast(in.get(C::precomputed_first_row))) * + (FF(1) - static_cast(in.get(C::keccak_memory_sel))) * + static_cast(in.get(C::keccak_memory_sel_shift)); std::get<1>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<2, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::keccak_memory_start_read)) * + (FF(1) - static_cast(in.get(C::keccak_memory_start_read))); + std::get<2>(evals) += (tmp * scaling_factor); + } + { + using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_start_write)) * (FF(1) - static_cast(in.get(C::keccak_memory_start_write))); - std::get<2>(evals) += (tmp * scaling_factor); + std::get<3>(evals) += (tmp * scaling_factor); } { // CTR_INIT - using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_start_read)) + static_cast(in.get(C::keccak_memory_start_write))) * (static_cast(in.get(C::keccak_memory_ctr)) - FF(1)); - std::get<3>(evals) += (tmp * scaling_factor); + std::get<4>(evals) += (tmp * scaling_factor); } { // RW_READ_INIT - using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_start_read)) * static_cast(in.get(C::keccak_memory_rw)); - std::get<4>(evals) += (tmp * scaling_factor); + std::get<5>(evals) += (tmp * scaling_factor); } { // RW_WRITE_INIT - using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_start_write)) * (FF(1) - static_cast(in.get(C::keccak_memory_rw))); - std::get<5>(evals) += (tmp * scaling_factor); + std::get<6>(evals) += (tmp * scaling_factor); } { // SEL_CTR_NON_ZERO - using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_ctr)) * ((FF(1) - static_cast(in.get(C::keccak_memory_sel))) * (FF(1) - static_cast(in.get(C::keccak_memory_ctr_inv))) + static_cast(in.get(C::keccak_memory_ctr_inv))) - static_cast(in.get(C::keccak_memory_sel))); - std::get<6>(evals) += (tmp * scaling_factor); + std::get<7>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_ctr_end)) * (FF(1) - static_cast(in.get(C::keccak_memory_ctr_end))); - std::get<7>(evals) += (tmp * scaling_factor); + std::get<8>(evals) += (tmp * scaling_factor); } { // CTR_END - using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_sel)) * (((CView(constants_AVM_KECCAKF1600_STATE_SIZE) - static_cast(in.get(C::keccak_memory_ctr))) * (static_cast(in.get(C::keccak_memory_ctr_end)) * @@ -81,263 +89,275 @@ void keccak_memoryImpl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::keccak_memory_state_size_min_ctr_inv))) + static_cast(in.get(C::keccak_memory_ctr_end))) - FF(1)); - std::get<8>(evals) += (tmp * scaling_factor); + std::get<9>(evals) += (tmp * scaling_factor); } { // LAST - using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_last)) - (FF(1) - (FF(1) - static_cast(in.get(C::keccak_memory_ctr_end))) * (FF(1) - static_cast(in.get(C::keccak_memory_single_tag_error))))); - std::get<9>(evals) += (tmp * scaling_factor); + std::get<10>(evals) += (tmp * scaling_factor); + } + { // LAST_HAS_SEL_ON + using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::keccak_memory_last)) * + (FF(1) - static_cast(in.get(C::keccak_memory_sel))); + std::get<11>(evals) += (tmp * scaling_factor); + } + { // START_AFTER_LATCH + using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::keccak_memory_sel_shift)) * + ((static_cast(in.get(C::keccak_memory_start_read_shift)) + + static_cast(in.get(C::keccak_memory_start_write_shift))) - + CView(keccak_memory_LATCH_CONDITION)); + std::get<12>(evals) += (tmp * scaling_factor); } { // CTR_INCREMENT - using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; auto tmp = - static_cast(in.get(C::keccak_memory_sel)) * - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + static_cast(in.get(C::keccak_memory_sel)) * (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * ((static_cast(in.get(C::keccak_memory_ctr_shift)) - static_cast(in.get(C::keccak_memory_ctr))) - FF(1)); - std::get<10>(evals) += (tmp * scaling_factor); + std::get<13>(evals) += (tmp * scaling_factor); } { // SINGLE_TAG_ERROR_BOOLEAN - using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_single_tag_error)) * (FF(1) - static_cast(in.get(C::keccak_memory_single_tag_error))); - std::get<11>(evals) += (tmp * scaling_factor); + std::get<14>(evals) += (tmp * scaling_factor); } { // NO_TAG_ERROR_ON_WRITE - using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_rw)) * static_cast(in.get(C::keccak_memory_single_tag_error)); - std::get<12>(evals) += (tmp * scaling_factor); + std::get<15>(evals) += (tmp * scaling_factor); } { // TAG_ERROR_INIT - using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<16, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_last)) * (static_cast(in.get(C::keccak_memory_tag_error)) - static_cast(in.get(C::keccak_memory_single_tag_error))); - std::get<13>(evals) += (tmp * scaling_factor); + std::get<16>(evals) += (tmp * scaling_factor); } { // TAG_ERROR_PROPAGATION - using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * (static_cast(in.get(C::keccak_memory_tag_error)) - static_cast(in.get(C::keccak_memory_tag_error_shift))); - std::get<14>(evals) += (tmp * scaling_factor); + std::get<17>(evals) += (tmp * scaling_factor); } { // MEM_ADDR_INCREMENT - using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::keccak_memory_sel)) * - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + using View = typename std::tuple_element_t<18, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::keccak_memory_sel)) * (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * ((static_cast(in.get(C::keccak_memory_addr)) + FF(1)) - static_cast(in.get(C::keccak_memory_addr_shift))); - std::get<15>(evals) += (tmp * scaling_factor); + std::get<18>(evals) += (tmp * scaling_factor); } { // SPACEID_PROPAGATION - using View = typename std::tuple_element_t<16, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + using View = typename std::tuple_element_t<19, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * (static_cast(in.get(C::keccak_memory_space_id)) - static_cast(in.get(C::keccak_memory_space_id_shift))); - std::get<16>(evals) += (tmp * scaling_factor); + std::get<19>(evals) += (tmp * scaling_factor); } { // CLK_PROPAGATION - using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<20, ContainerOverSubrelations>::View; auto tmp = - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * (static_cast(in.get(C::keccak_memory_clk_shift)) - static_cast(in.get(C::keccak_memory_clk))); - std::get<17>(evals) += (tmp * scaling_factor); + std::get<20>(evals) += (tmp * scaling_factor); } { // RW_PROPAGATION - using View = typename std::tuple_element_t<18, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<21, ContainerOverSubrelations>::View; auto tmp = - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * (static_cast(in.get(C::keccak_memory_rw_shift)) - static_cast(in.get(C::keccak_memory_rw))); - std::get<18>(evals) += (tmp * scaling_factor); + std::get<21>(evals) += (tmp * scaling_factor); } { // SINGLE_TAG_ERROR - using View = typename std::tuple_element_t<19, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<22, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_sel)) * (CView(keccak_memory_TAG_MIN_U64) * ((FF(1) - static_cast(in.get(C::keccak_memory_single_tag_error))) * (FF(1) - static_cast(in.get(C::keccak_memory_tag_min_u64_inv))) + static_cast(in.get(C::keccak_memory_tag_min_u64_inv))) - static_cast(in.get(C::keccak_memory_single_tag_error))); - std::get<19>(evals) += (tmp * scaling_factor); - } - { // VAL01 - using View = typename std::tuple_element_t<20, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_1_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_0__shift))); - std::get<20>(evals) += (tmp * scaling_factor); - } - { // VAL02 - using View = typename std::tuple_element_t<21, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_2_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_1__shift))); - std::get<21>(evals) += (tmp * scaling_factor); - } - { // VAL03 - using View = typename std::tuple_element_t<22, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_3_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_2__shift))); std::get<22>(evals) += (tmp * scaling_factor); } - { // VAL04 + { // VAL01 using View = typename std::tuple_element_t<23, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_4_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_3__shift))); + auto tmp = + (static_cast(in.get(C::keccak_memory_val_1_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_0__shift))); std::get<23>(evals) += (tmp * scaling_factor); } - { // VAL05 + { // VAL02 using View = typename std::tuple_element_t<24, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_5_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_4__shift))); + auto tmp = + (static_cast(in.get(C::keccak_memory_val_2_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_1__shift))); std::get<24>(evals) += (tmp * scaling_factor); } - { // VAL06 + { // VAL03 using View = typename std::tuple_element_t<25, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_6_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_5__shift))); + auto tmp = + (static_cast(in.get(C::keccak_memory_val_3_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_2__shift))); std::get<25>(evals) += (tmp * scaling_factor); } - { // VAL07 + { // VAL04 using View = typename std::tuple_element_t<26, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_7_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_6__shift))); + auto tmp = + (static_cast(in.get(C::keccak_memory_val_4_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_3__shift))); std::get<26>(evals) += (tmp * scaling_factor); } - { // VAL8 + { // VAL05 using View = typename std::tuple_element_t<27, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_8_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_7__shift))); + auto tmp = + (static_cast(in.get(C::keccak_memory_val_5_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_4__shift))); std::get<27>(evals) += (tmp * scaling_factor); } - { // VAL09 + { // VAL06 using View = typename std::tuple_element_t<28, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_9_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_8__shift))); + auto tmp = + (static_cast(in.get(C::keccak_memory_val_6_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_5__shift))); std::get<28>(evals) += (tmp * scaling_factor); } - { // VAL10 + { // VAL07 using View = typename std::tuple_element_t<29, ContainerOverSubrelations>::View; - auto tmp = (static_cast(in.get(C::keccak_memory_val_10_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * - static_cast(in.get(C::keccak_memory_val_9__shift))); + auto tmp = + (static_cast(in.get(C::keccak_memory_val_7_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_6__shift))); std::get<29>(evals) += (tmp * scaling_factor); } - { // VAL11 + { // VAL8 using View = typename std::tuple_element_t<30, ContainerOverSubrelations>::View; + auto tmp = + (static_cast(in.get(C::keccak_memory_val_8_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_7__shift))); + std::get<30>(evals) += (tmp * scaling_factor); + } + { // VAL09 + using View = typename std::tuple_element_t<31, ContainerOverSubrelations>::View; + auto tmp = + (static_cast(in.get(C::keccak_memory_val_9_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_8__shift))); + std::get<31>(evals) += (tmp * scaling_factor); + } + { // VAL10 + using View = typename std::tuple_element_t<32, ContainerOverSubrelations>::View; + auto tmp = + (static_cast(in.get(C::keccak_memory_val_10_)) - + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_9__shift))); + std::get<32>(evals) += (tmp * scaling_factor); + } + { // VAL11 + using View = typename std::tuple_element_t<33, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_11_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_10__shift))); - std::get<30>(evals) += (tmp * scaling_factor); + std::get<33>(evals) += (tmp * scaling_factor); } { // VAL12 - using View = typename std::tuple_element_t<31, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<34, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_12_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_11__shift))); - std::get<31>(evals) += (tmp * scaling_factor); + std::get<34>(evals) += (tmp * scaling_factor); } { // VAL13 - using View = typename std::tuple_element_t<32, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<35, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_13_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_12__shift))); - std::get<32>(evals) += (tmp * scaling_factor); + std::get<35>(evals) += (tmp * scaling_factor); } { // VAL14 - using View = typename std::tuple_element_t<33, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<36, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_14_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_13__shift))); - std::get<33>(evals) += (tmp * scaling_factor); + std::get<36>(evals) += (tmp * scaling_factor); } { // VAL15 - using View = typename std::tuple_element_t<34, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<37, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_15_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_14__shift))); - std::get<34>(evals) += (tmp * scaling_factor); + std::get<37>(evals) += (tmp * scaling_factor); } { // VAL16 - using View = typename std::tuple_element_t<35, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<38, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_16_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_15__shift))); - std::get<35>(evals) += (tmp * scaling_factor); + std::get<38>(evals) += (tmp * scaling_factor); } { // VAL17 - using View = typename std::tuple_element_t<36, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<39, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_17_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_16__shift))); - std::get<36>(evals) += (tmp * scaling_factor); + std::get<39>(evals) += (tmp * scaling_factor); } { // VAL18 - using View = typename std::tuple_element_t<37, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<40, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_18_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_17__shift))); - std::get<37>(evals) += (tmp * scaling_factor); + std::get<40>(evals) += (tmp * scaling_factor); } { // VAL19 - using View = typename std::tuple_element_t<38, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<41, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_19_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_18__shift))); - std::get<38>(evals) += (tmp * scaling_factor); + std::get<41>(evals) += (tmp * scaling_factor); } { // VAL20 - using View = typename std::tuple_element_t<39, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<42, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_20_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_19__shift))); - std::get<39>(evals) += (tmp * scaling_factor); + std::get<42>(evals) += (tmp * scaling_factor); } { // VAL21 - using View = typename std::tuple_element_t<40, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<43, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_21_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_20__shift))); - std::get<40>(evals) += (tmp * scaling_factor); + std::get<43>(evals) += (tmp * scaling_factor); } { // VAL22 - using View = typename std::tuple_element_t<41, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<44, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_22_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_21__shift))); - std::get<41>(evals) += (tmp * scaling_factor); + std::get<44>(evals) += (tmp * scaling_factor); } { // VAL23 - using View = typename std::tuple_element_t<42, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<45, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_23_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_22__shift))); - std::get<42>(evals) += (tmp * scaling_factor); + std::get<45>(evals) += (tmp * scaling_factor); } { // VAL24 - using View = typename std::tuple_element_t<43, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<46, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccak_memory_val_24_)) - - (FF(1) - static_cast(in.get(C::keccak_memory_last))) * + (FF(1) - CView(keccak_memory_LATCH_CONDITION)) * static_cast(in.get(C::keccak_memory_val_23__shift))); - std::get<43>(evals) += (tmp * scaling_factor); + std::get<46>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<44, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<47, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccak_memory_sel)) * (static_cast(in.get(C::keccak_memory_num_rounds)) - CView(constants_AVM_KECCAKF1600_NUM_ROUNDS)); - std::get<44>(evals) += (tmp * scaling_factor); + std::get<47>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccakf1600.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccakf1600.hpp index 1cb0770fc3c3..972048ce6071 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccakf1600.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccakf1600.hpp @@ -14,11 +14,11 @@ template class keccakf1600Impl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { - 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { + 3, 4, 3, 3, 3, 4, 3, 3, 3, 3, 4, 3, 3, 3, 3, 2, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, 3 }; @@ -41,137 +41,149 @@ template class keccakf1600 : public Relation> static constexpr const std::string_view NAME = "keccakf1600"; // Subrelation indices constants, to be used in tests. - static constexpr size_t SR_SEL_NO_ERROR = 1; - static constexpr size_t SR_KECCAK_SEL_ROUND_NON_ZERO = 4; - static constexpr size_t SR_KECCAK_ROUND_INCREMENT = 5; - static constexpr size_t SR_THETA_XOR_ROW_MSB_0_BOOLEAN = 10; - static constexpr size_t SR_THETA_XOR_ROW_0_DECOMPOSITION = 11; - static constexpr size_t SR_THETA_XOR_ROW_ROTL1_0 = 12; - static constexpr size_t SR_THETA_XOR_ROW_MSB_1_BOOLEAN = 13; - static constexpr size_t SR_THETA_XOR_ROW_1_DECOMPOSITION = 14; - static constexpr size_t SR_THETA_XOR_ROW_ROTL1_1 = 15; - static constexpr size_t SR_THETA_XOR_ROW_MSB_2_BOOLEAN = 16; - static constexpr size_t SR_THETA_XOR_ROW_2_DECOMPOSITION = 17; - static constexpr size_t SR_THETA_XOR_ROW_ROTL1_2 = 18; - static constexpr size_t SR_THETA_XOR_ROW_MSB_3_BOOLEAN = 19; - static constexpr size_t SR_THETA_XOR_ROW_3_DECOMPOSITION = 20; - static constexpr size_t SR_THETA_XOR_ROW_ROTL1_3 = 21; - static constexpr size_t SR_THETA_XOR_ROW_MSB_4_BOOLEAN = 22; - static constexpr size_t SR_THETA_XOR_ROW_4_DECOMPOSITION = 23; - static constexpr size_t SR_THETA_XOR_ROW_ROTL1_4 = 24; - static constexpr size_t SR_STATE_THETA_01_DECOMPOSE = 25; - static constexpr size_t SR_STATE_RHO_01 = 26; - static constexpr size_t SR_STATE_THETA_02_DECOMPOSE = 27; - static constexpr size_t SR_STATE_RHO_02 = 28; - static constexpr size_t SR_STATE_THETA_03_DECOMPOSE = 29; - static constexpr size_t SR_STATE_RHO_03 = 30; - static constexpr size_t SR_STATE_THETA_04_DECOMPOSE = 31; - static constexpr size_t SR_STATE_RHO_04 = 32; - static constexpr size_t SR_STATE_THETA_10_DECOMPOSE = 33; - static constexpr size_t SR_STATE_RHO_10 = 34; - static constexpr size_t SR_STATE_THETA_11_DECOMPOSE = 35; - static constexpr size_t SR_STATE_RHO_11 = 36; - static constexpr size_t SR_STATE_THETA_12_DECOMPOSE = 37; - static constexpr size_t SR_STATE_RHO_12 = 38; - static constexpr size_t SR_STATE_THETA_13_DECOMPOSE = 39; - static constexpr size_t SR_STATE_RHO_13 = 40; - static constexpr size_t SR_STATE_THETA_14_DECOMPOSE = 41; - static constexpr size_t SR_STATE_RHO_14 = 42; - static constexpr size_t SR_STATE_THETA_20_DECOMPOSE = 43; - static constexpr size_t SR_STATE_RHO_20 = 44; - static constexpr size_t SR_STATE_THETA_21_DECOMPOSE = 45; - static constexpr size_t SR_STATE_RHO_21 = 46; - static constexpr size_t SR_STATE_THETA_22_DECOMPOSE = 47; - static constexpr size_t SR_STATE_RHO_22 = 48; - static constexpr size_t SR_STATE_THETA_23_DECOMPOSE = 49; - static constexpr size_t SR_STATE_RHO_23 = 50; - static constexpr size_t SR_STATE_THETA_24_DECOMPOSE = 51; - static constexpr size_t SR_STATE_RHO_24 = 52; - static constexpr size_t SR_STATE_THETA_30_DECOMPOSE = 53; - static constexpr size_t SR_STATE_RHO_30 = 54; - static constexpr size_t SR_STATE_THETA_31_DECOMPOSE = 55; - static constexpr size_t SR_STATE_RHO_31 = 56; - static constexpr size_t SR_STATE_THETA_32_DECOMPOSE = 57; - static constexpr size_t SR_STATE_RHO_32 = 58; - static constexpr size_t SR_STATE_THETA_33_DECOMPOSE = 59; - static constexpr size_t SR_STATE_RHO_33 = 60; - static constexpr size_t SR_STATE_THETA_34_DECOMPOSE = 61; - static constexpr size_t SR_STATE_RHO_34 = 62; - static constexpr size_t SR_STATE_THETA_40_DECOMPOSE = 63; - static constexpr size_t SR_STATE_RHO_40 = 64; - static constexpr size_t SR_STATE_THETA_41_DECOMPOSE = 65; - static constexpr size_t SR_STATE_RHO_41 = 66; - static constexpr size_t SR_STATE_THETA_42_DECOMPOSE = 67; - static constexpr size_t SR_STATE_RHO_42 = 68; - static constexpr size_t SR_STATE_THETA_43_DECOMPOSE = 69; - static constexpr size_t SR_STATE_RHO_43 = 70; - static constexpr size_t SR_STATE_THETA_44_DECOMPOSE = 71; - static constexpr size_t SR_STATE_RHO_44 = 72; - static constexpr size_t SR_STATE_PI_NOT_00 = 97; - static constexpr size_t SR_STATE_PI_NOT_01 = 98; - static constexpr size_t SR_STATE_PI_NOT_02 = 99; - static constexpr size_t SR_STATE_PI_NOT_03 = 100; - static constexpr size_t SR_STATE_PI_NOT_04 = 101; - static constexpr size_t SR_STATE_PI_NOT_10 = 102; - static constexpr size_t SR_STATE_PI_NOT_11 = 103; - static constexpr size_t SR_STATE_PI_NOT_12 = 104; - static constexpr size_t SR_STATE_PI_NOT_13 = 105; - static constexpr size_t SR_STATE_PI_NOT_14 = 106; - static constexpr size_t SR_STATE_PI_NOT_20 = 107; - static constexpr size_t SR_STATE_PI_NOT_21 = 108; - static constexpr size_t SR_STATE_PI_NOT_22 = 109; - static constexpr size_t SR_STATE_PI_NOT_23 = 110; - static constexpr size_t SR_STATE_PI_NOT_24 = 111; - static constexpr size_t SR_STATE_PI_NOT_30 = 112; - static constexpr size_t SR_STATE_PI_NOT_31 = 113; - static constexpr size_t SR_STATE_PI_NOT_32 = 114; - static constexpr size_t SR_STATE_PI_NOT_33 = 115; - static constexpr size_t SR_STATE_PI_NOT_34 = 116; - static constexpr size_t SR_STATE_PI_NOT_40 = 117; - static constexpr size_t SR_STATE_PI_NOT_41 = 118; - static constexpr size_t SR_STATE_PI_NOT_42 = 119; - static constexpr size_t SR_STATE_PI_NOT_43 = 120; - static constexpr size_t SR_STATE_PI_NOT_44 = 121; - static constexpr size_t SR_NEXT_STATE_IN_00 = 122; - static constexpr size_t SR_NEXT_STATE_IN_01 = 123; - static constexpr size_t SR_NEXT_STATE_IN_02 = 124; - static constexpr size_t SR_NEXT_STATE_IN_03 = 125; - static constexpr size_t SR_NEXT_STATE_IN_04 = 126; - static constexpr size_t SR_NEXT_STATE_IN_10 = 127; - static constexpr size_t SR_NEXT_STATE_IN_11 = 128; - static constexpr size_t SR_NEXT_STATE_IN_12 = 129; - static constexpr size_t SR_NEXT_STATE_IN_13 = 130; - static constexpr size_t SR_NEXT_STATE_IN_14 = 131; - static constexpr size_t SR_NEXT_STATE_IN_20 = 132; - static constexpr size_t SR_NEXT_STATE_IN_21 = 133; - static constexpr size_t SR_NEXT_STATE_IN_22 = 134; - static constexpr size_t SR_NEXT_STATE_IN_23 = 135; - static constexpr size_t SR_NEXT_STATE_IN_24 = 136; - static constexpr size_t SR_NEXT_STATE_IN_30 = 137; - static constexpr size_t SR_NEXT_STATE_IN_31 = 138; - static constexpr size_t SR_NEXT_STATE_IN_32 = 139; - static constexpr size_t SR_NEXT_STATE_IN_33 = 140; - static constexpr size_t SR_NEXT_STATE_IN_34 = 141; - static constexpr size_t SR_NEXT_STATE_IN_40 = 142; - static constexpr size_t SR_NEXT_STATE_IN_41 = 143; - static constexpr size_t SR_NEXT_STATE_IN_42 = 144; - static constexpr size_t SR_NEXT_STATE_IN_43 = 145; - static constexpr size_t SR_NEXT_STATE_IN_44 = 146; - static constexpr size_t SR_ERROR = 148; - static constexpr size_t SR_DST_ADDR_PROPAGATION = 149; - static constexpr size_t SR_CLK_PROPAGATION = 150; - static constexpr size_t SR_SPACE_ID_PROPAGATION = 151; - static constexpr size_t SR_SEL_NO_ERROR_PROPAGATION = 152; - static constexpr size_t SR_SEL_SLICE_READ = 153; - static constexpr size_t SR_SEL_SLICE_WRITE = 154; + static constexpr size_t SR_TRACE_CONTINUITY = 1; + static constexpr size_t SR_SEL_NO_ERROR = 2; + static constexpr size_t SR_KECCAK_SEL_ROUND_NON_ZERO = 5; + static constexpr size_t SR_LAST_ON_ERROR = 7; + static constexpr size_t SR_START_AFTER_LATCH = 8; + static constexpr size_t SR_LAST_HAS_SEL_ON = 9; + static constexpr size_t SR_KECCAK_ROUND_INCREMENT = 10; + static constexpr size_t SR_THETA_XOR_ROW_MSB_0_BOOLEAN = 14; + static constexpr size_t SR_THETA_XOR_ROW_0_DECOMPOSITION = 15; + static constexpr size_t SR_THETA_XOR_ROW_ROTL1_0 = 16; + static constexpr size_t SR_THETA_XOR_ROW_MSB_1_BOOLEAN = 17; + static constexpr size_t SR_THETA_XOR_ROW_1_DECOMPOSITION = 18; + static constexpr size_t SR_THETA_XOR_ROW_ROTL1_1 = 19; + static constexpr size_t SR_THETA_XOR_ROW_MSB_2_BOOLEAN = 20; + static constexpr size_t SR_THETA_XOR_ROW_2_DECOMPOSITION = 21; + static constexpr size_t SR_THETA_XOR_ROW_ROTL1_2 = 22; + static constexpr size_t SR_THETA_XOR_ROW_MSB_3_BOOLEAN = 23; + static constexpr size_t SR_THETA_XOR_ROW_3_DECOMPOSITION = 24; + static constexpr size_t SR_THETA_XOR_ROW_ROTL1_3 = 25; + static constexpr size_t SR_THETA_XOR_ROW_MSB_4_BOOLEAN = 26; + static constexpr size_t SR_THETA_XOR_ROW_4_DECOMPOSITION = 27; + static constexpr size_t SR_THETA_XOR_ROW_ROTL1_4 = 28; + static constexpr size_t SR_STATE_THETA_01_DECOMPOSE = 29; + static constexpr size_t SR_STATE_RHO_01 = 30; + static constexpr size_t SR_STATE_THETA_02_DECOMPOSE = 31; + static constexpr size_t SR_STATE_RHO_02 = 32; + static constexpr size_t SR_STATE_THETA_03_DECOMPOSE = 33; + static constexpr size_t SR_STATE_RHO_03 = 34; + static constexpr size_t SR_STATE_THETA_04_DECOMPOSE = 35; + static constexpr size_t SR_STATE_RHO_04 = 36; + static constexpr size_t SR_STATE_THETA_10_DECOMPOSE = 37; + static constexpr size_t SR_STATE_RHO_10 = 38; + static constexpr size_t SR_STATE_THETA_11_DECOMPOSE = 39; + static constexpr size_t SR_STATE_RHO_11 = 40; + static constexpr size_t SR_STATE_THETA_12_DECOMPOSE = 41; + static constexpr size_t SR_STATE_RHO_12 = 42; + static constexpr size_t SR_STATE_THETA_13_DECOMPOSE = 43; + static constexpr size_t SR_STATE_RHO_13 = 44; + static constexpr size_t SR_STATE_THETA_14_DECOMPOSE = 45; + static constexpr size_t SR_STATE_RHO_14 = 46; + static constexpr size_t SR_STATE_THETA_20_DECOMPOSE = 47; + static constexpr size_t SR_STATE_RHO_20 = 48; + static constexpr size_t SR_STATE_THETA_21_DECOMPOSE = 49; + static constexpr size_t SR_STATE_RHO_21 = 50; + static constexpr size_t SR_STATE_THETA_22_DECOMPOSE = 51; + static constexpr size_t SR_STATE_RHO_22 = 52; + static constexpr size_t SR_STATE_THETA_23_DECOMPOSE = 53; + static constexpr size_t SR_STATE_RHO_23 = 54; + static constexpr size_t SR_STATE_THETA_24_DECOMPOSE = 55; + static constexpr size_t SR_STATE_RHO_24 = 56; + static constexpr size_t SR_STATE_THETA_30_DECOMPOSE = 57; + static constexpr size_t SR_STATE_RHO_30 = 58; + static constexpr size_t SR_STATE_THETA_31_DECOMPOSE = 59; + static constexpr size_t SR_STATE_RHO_31 = 60; + static constexpr size_t SR_STATE_THETA_32_DECOMPOSE = 61; + static constexpr size_t SR_STATE_RHO_32 = 62; + static constexpr size_t SR_STATE_THETA_33_DECOMPOSE = 63; + static constexpr size_t SR_STATE_RHO_33 = 64; + static constexpr size_t SR_STATE_THETA_34_DECOMPOSE = 65; + static constexpr size_t SR_STATE_RHO_34 = 66; + static constexpr size_t SR_STATE_THETA_40_DECOMPOSE = 67; + static constexpr size_t SR_STATE_RHO_40 = 68; + static constexpr size_t SR_STATE_THETA_41_DECOMPOSE = 69; + static constexpr size_t SR_STATE_RHO_41 = 70; + static constexpr size_t SR_STATE_THETA_42_DECOMPOSE = 71; + static constexpr size_t SR_STATE_RHO_42 = 72; + static constexpr size_t SR_STATE_THETA_43_DECOMPOSE = 73; + static constexpr size_t SR_STATE_RHO_43 = 74; + static constexpr size_t SR_STATE_THETA_44_DECOMPOSE = 75; + static constexpr size_t SR_STATE_RHO_44 = 76; + static constexpr size_t SR_STATE_PI_NOT_00 = 101; + static constexpr size_t SR_STATE_PI_NOT_01 = 102; + static constexpr size_t SR_STATE_PI_NOT_02 = 103; + static constexpr size_t SR_STATE_PI_NOT_03 = 104; + static constexpr size_t SR_STATE_PI_NOT_04 = 105; + static constexpr size_t SR_STATE_PI_NOT_10 = 106; + static constexpr size_t SR_STATE_PI_NOT_11 = 107; + static constexpr size_t SR_STATE_PI_NOT_12 = 108; + static constexpr size_t SR_STATE_PI_NOT_13 = 109; + static constexpr size_t SR_STATE_PI_NOT_14 = 110; + static constexpr size_t SR_STATE_PI_NOT_20 = 111; + static constexpr size_t SR_STATE_PI_NOT_21 = 112; + static constexpr size_t SR_STATE_PI_NOT_22 = 113; + static constexpr size_t SR_STATE_PI_NOT_23 = 114; + static constexpr size_t SR_STATE_PI_NOT_24 = 115; + static constexpr size_t SR_STATE_PI_NOT_30 = 116; + static constexpr size_t SR_STATE_PI_NOT_31 = 117; + static constexpr size_t SR_STATE_PI_NOT_32 = 118; + static constexpr size_t SR_STATE_PI_NOT_33 = 119; + static constexpr size_t SR_STATE_PI_NOT_34 = 120; + static constexpr size_t SR_STATE_PI_NOT_40 = 121; + static constexpr size_t SR_STATE_PI_NOT_41 = 122; + static constexpr size_t SR_STATE_PI_NOT_42 = 123; + static constexpr size_t SR_STATE_PI_NOT_43 = 124; + static constexpr size_t SR_STATE_PI_NOT_44 = 125; + static constexpr size_t SR_NEXT_STATE_IN_00 = 126; + static constexpr size_t SR_NEXT_STATE_IN_01 = 127; + static constexpr size_t SR_NEXT_STATE_IN_02 = 128; + static constexpr size_t SR_NEXT_STATE_IN_03 = 129; + static constexpr size_t SR_NEXT_STATE_IN_04 = 130; + static constexpr size_t SR_NEXT_STATE_IN_10 = 131; + static constexpr size_t SR_NEXT_STATE_IN_11 = 132; + static constexpr size_t SR_NEXT_STATE_IN_12 = 133; + static constexpr size_t SR_NEXT_STATE_IN_13 = 134; + static constexpr size_t SR_NEXT_STATE_IN_14 = 135; + static constexpr size_t SR_NEXT_STATE_IN_20 = 136; + static constexpr size_t SR_NEXT_STATE_IN_21 = 137; + static constexpr size_t SR_NEXT_STATE_IN_22 = 138; + static constexpr size_t SR_NEXT_STATE_IN_23 = 139; + static constexpr size_t SR_NEXT_STATE_IN_24 = 140; + static constexpr size_t SR_NEXT_STATE_IN_30 = 141; + static constexpr size_t SR_NEXT_STATE_IN_31 = 142; + static constexpr size_t SR_NEXT_STATE_IN_32 = 143; + static constexpr size_t SR_NEXT_STATE_IN_33 = 144; + static constexpr size_t SR_NEXT_STATE_IN_34 = 145; + static constexpr size_t SR_NEXT_STATE_IN_40 = 146; + static constexpr size_t SR_NEXT_STATE_IN_41 = 147; + static constexpr size_t SR_NEXT_STATE_IN_42 = 148; + static constexpr size_t SR_NEXT_STATE_IN_43 = 149; + static constexpr size_t SR_NEXT_STATE_IN_44 = 150; + static constexpr size_t SR_ERROR = 152; + static constexpr size_t SR_DST_ADDR_PROPAGATION = 153; + static constexpr size_t SR_CLK_PROPAGATION = 154; + static constexpr size_t SR_SPACE_ID_PROPAGATION = 155; + static constexpr size_t SR_SEL_NO_ERROR_PROPAGATION = 156; + static constexpr size_t SR_SEL_SLICE_READ = 157; + static constexpr size_t SR_SEL_SLICE_WRITE = 158; static std::string get_subrelation_label(size_t index) { switch (index) { + case SR_TRACE_CONTINUITY: + return "TRACE_CONTINUITY"; case SR_SEL_NO_ERROR: return "SEL_NO_ERROR"; case SR_KECCAK_SEL_ROUND_NON_ZERO: return "KECCAK_SEL_ROUND_NON_ZERO"; + case SR_LAST_ON_ERROR: + return "LAST_ON_ERROR"; + case SR_START_AFTER_LATCH: + return "START_AFTER_LATCH"; + case SR_LAST_HAS_SEL_ON: + return "LAST_HAS_SEL_ON"; case SR_KECCAK_ROUND_INCREMENT: return "KECCAK_ROUND_INCREMENT"; case SR_THETA_XOR_ROW_MSB_0_BOOLEAN: diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccakf1600_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccakf1600_impl.hpp index 6d4e85c1d976..76a5330a5191 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccakf1600_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/keccakf1600_impl.hpp @@ -20,6 +20,7 @@ void keccakf1600Impl::accumulate(ContainerOverSubrelations& evals, const auto constants_AVM_BITWISE_AND_OP_ID = FF(0); const auto constants_AVM_BITWISE_XOR_OP_ID = FF(2); const auto constants_AVM_KECCAKF1600_STATE_SIZE = FF(25); + const auto keccakf1600_LATCH_CONDITION = in.get(C::keccakf1600_last) + in.get(C::precomputed_first_row); const auto keccakf1600_ROT_LEN_01 = FF(36); const auto keccakf1600_POW_ROT_LEN_01 = FF(68719476736UL); const auto keccakf1600_POW_ROT_64_MIN_LEN_01 = FF(268435456); @@ -128,40 +129,39 @@ void keccakf1600Impl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::keccakf1600_sel)) * (FF(1) - static_cast(in.get(C::keccakf1600_sel))); std::get<0>(evals) += (tmp * scaling_factor); } - { // SEL_NO_ERROR + { // TRACE_CONTINUITY using View = typename std::tuple_element_t<1, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::keccakf1600_start)) * + auto tmp = (FF(1) - static_cast(in.get(C::precomputed_first_row))) * + (FF(1) - static_cast(in.get(C::keccakf1600_sel))) * + static_cast(in.get(C::keccakf1600_sel_shift)); + std::get<1>(evals) += (tmp * scaling_factor); + } + { // SEL_NO_ERROR + using View = typename std::tuple_element_t<2, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::keccakf1600_sel)) * ((static_cast(in.get(C::keccakf1600_sel_no_error)) - FF(1)) + static_cast(in.get(C::keccakf1600_error))); - std::get<1>(evals) += (tmp * scaling_factor); + std::get<2>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<2, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_start)) * (FF(1) - static_cast(in.get(C::keccakf1600_start))); - std::get<2>(evals) += (tmp * scaling_factor); + std::get<3>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_start)) * (static_cast(in.get(C::keccakf1600_round)) - FF(1)); - std::get<3>(evals) += (tmp * scaling_factor); + std::get<4>(evals) += (tmp * scaling_factor); } { // KECCAK_SEL_ROUND_NON_ZERO - using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_round)) * ((FF(1) - static_cast(in.get(C::keccakf1600_sel))) * (FF(1) - static_cast(in.get(C::keccakf1600_round_inv))) + static_cast(in.get(C::keccakf1600_round_inv))) - static_cast(in.get(C::keccakf1600_sel))); - std::get<4>(evals) += (tmp * scaling_factor); - } - { // KECCAK_ROUND_INCREMENT - using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; - auto tmp = - static_cast(in.get(C::keccakf1600_sel)) * (FF(1) - static_cast(in.get(C::keccakf1600_last))) * - ((static_cast(in.get(C::keccakf1600_round_shift)) - static_cast(in.get(C::keccakf1600_round))) - - FF(1)); std::get<5>(evals) += (tmp * scaling_factor); } { @@ -170,1052 +170,1077 @@ void keccakf1600Impl::accumulate(ContainerOverSubrelations& evals, static_cast(in.get(C::keccakf1600_last)) * (FF(1) - static_cast(in.get(C::keccakf1600_last))); std::get<6>(evals) += (tmp * scaling_factor); } - { + { // LAST_ON_ERROR using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; + auto tmp = + static_cast(in.get(C::keccakf1600_error)) * (static_cast(in.get(C::keccakf1600_last)) - FF(1)); + std::get<7>(evals) += (tmp * scaling_factor); + } + { // START_AFTER_LATCH + using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; + auto tmp = static_cast(in.get(C::keccakf1600_sel_shift)) * + (static_cast(in.get(C::keccakf1600_start_shift)) - CView(keccakf1600_LATCH_CONDITION)); + std::get<8>(evals) += (tmp * scaling_factor); + } + { // LAST_HAS_SEL_ON + using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; + auto tmp = + static_cast(in.get(C::keccakf1600_last)) * (FF(1) - static_cast(in.get(C::keccakf1600_sel))); + std::get<9>(evals) += (tmp * scaling_factor); + } + { // KECCAK_ROUND_INCREMENT + using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; + auto tmp = + static_cast(in.get(C::keccakf1600_sel)) * (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * + ((static_cast(in.get(C::keccakf1600_round_shift)) - static_cast(in.get(C::keccakf1600_round))) - + FF(1)); + std::get<10>(evals) += (tmp * scaling_factor); + } + { + using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_bitwise_xor_op_id)) - CView(constants_AVM_BITWISE_XOR_OP_ID)); - std::get<7>(evals) += (tmp * scaling_factor); + std::get<11>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_bitwise_and_op_id)) - CView(constants_AVM_BITWISE_AND_OP_ID)); - std::get<8>(evals) += (tmp * scaling_factor); + std::get<12>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_tag_u64)) - CView(constants_MEM_TAG_U64)); - std::get<9>(evals) += (tmp * scaling_factor); + std::get<13>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_MSB_0_BOOLEAN - using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_theta_xor_row_msb_0)) * (FF(1) - static_cast(in.get(C::keccakf1600_theta_xor_row_msb_0))); - std::get<10>(evals) += (tmp * scaling_factor); + std::get<14>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_0_DECOMPOSITION - using View = typename std::tuple_element_t<11, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_0)) - (FF(uint256_t{ 9223372036854775808UL, 0UL, 0UL, 0UL }) * static_cast(in.get(C::keccakf1600_theta_xor_row_msb_0)) + static_cast(in.get(C::keccakf1600_theta_xor_row_low63_0)))); - std::get<11>(evals) += (tmp * scaling_factor); + std::get<15>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_ROTL1_0 - using View = typename std::tuple_element_t<12, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<16, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_rotl1_0)) - (FF(2) * static_cast(in.get(C::keccakf1600_theta_xor_row_low63_0)) + static_cast(in.get(C::keccakf1600_theta_xor_row_msb_0)))); - std::get<12>(evals) += (tmp * scaling_factor); + std::get<16>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_MSB_1_BOOLEAN - using View = typename std::tuple_element_t<13, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_theta_xor_row_msb_1)) * (FF(1) - static_cast(in.get(C::keccakf1600_theta_xor_row_msb_1))); - std::get<13>(evals) += (tmp * scaling_factor); + std::get<17>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_1_DECOMPOSITION - using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<18, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_1)) - (FF(uint256_t{ 9223372036854775808UL, 0UL, 0UL, 0UL }) * static_cast(in.get(C::keccakf1600_theta_xor_row_msb_1)) + static_cast(in.get(C::keccakf1600_theta_xor_row_low63_1)))); - std::get<14>(evals) += (tmp * scaling_factor); + std::get<18>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_ROTL1_1 - using View = typename std::tuple_element_t<15, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<19, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_rotl1_1)) - (FF(2) * static_cast(in.get(C::keccakf1600_theta_xor_row_low63_1)) + static_cast(in.get(C::keccakf1600_theta_xor_row_msb_1)))); - std::get<15>(evals) += (tmp * scaling_factor); + std::get<19>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_MSB_2_BOOLEAN - using View = typename std::tuple_element_t<16, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<20, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_theta_xor_row_msb_2)) * (FF(1) - static_cast(in.get(C::keccakf1600_theta_xor_row_msb_2))); - std::get<16>(evals) += (tmp * scaling_factor); + std::get<20>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_2_DECOMPOSITION - using View = typename std::tuple_element_t<17, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<21, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_2)) - (FF(uint256_t{ 9223372036854775808UL, 0UL, 0UL, 0UL }) * static_cast(in.get(C::keccakf1600_theta_xor_row_msb_2)) + static_cast(in.get(C::keccakf1600_theta_xor_row_low63_2)))); - std::get<17>(evals) += (tmp * scaling_factor); + std::get<21>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_ROTL1_2 - using View = typename std::tuple_element_t<18, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<22, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_rotl1_2)) - (FF(2) * static_cast(in.get(C::keccakf1600_theta_xor_row_low63_2)) + static_cast(in.get(C::keccakf1600_theta_xor_row_msb_2)))); - std::get<18>(evals) += (tmp * scaling_factor); + std::get<22>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_MSB_3_BOOLEAN - using View = typename std::tuple_element_t<19, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<23, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_theta_xor_row_msb_3)) * (FF(1) - static_cast(in.get(C::keccakf1600_theta_xor_row_msb_3))); - std::get<19>(evals) += (tmp * scaling_factor); + std::get<23>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_3_DECOMPOSITION - using View = typename std::tuple_element_t<20, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<24, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_3)) - (FF(uint256_t{ 9223372036854775808UL, 0UL, 0UL, 0UL }) * static_cast(in.get(C::keccakf1600_theta_xor_row_msb_3)) + static_cast(in.get(C::keccakf1600_theta_xor_row_low63_3)))); - std::get<20>(evals) += (tmp * scaling_factor); + std::get<24>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_ROTL1_3 - using View = typename std::tuple_element_t<21, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<25, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_rotl1_3)) - (FF(2) * static_cast(in.get(C::keccakf1600_theta_xor_row_low63_3)) + static_cast(in.get(C::keccakf1600_theta_xor_row_msb_3)))); - std::get<21>(evals) += (tmp * scaling_factor); + std::get<25>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_MSB_4_BOOLEAN - using View = typename std::tuple_element_t<22, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<26, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_theta_xor_row_msb_4)) * (FF(1) - static_cast(in.get(C::keccakf1600_theta_xor_row_msb_4))); - std::get<22>(evals) += (tmp * scaling_factor); + std::get<26>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_4_DECOMPOSITION - using View = typename std::tuple_element_t<23, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<27, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_4)) - (FF(uint256_t{ 9223372036854775808UL, 0UL, 0UL, 0UL }) * static_cast(in.get(C::keccakf1600_theta_xor_row_msb_4)) + static_cast(in.get(C::keccakf1600_theta_xor_row_low63_4)))); - std::get<23>(evals) += (tmp * scaling_factor); + std::get<27>(evals) += (tmp * scaling_factor); } { // THETA_XOR_ROW_ROTL1_4 - using View = typename std::tuple_element_t<24, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<28, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_theta_xor_row_rotl1_4)) - (FF(2) * static_cast(in.get(C::keccakf1600_theta_xor_row_low63_4)) + static_cast(in.get(C::keccakf1600_theta_xor_row_msb_4)))); - std::get<24>(evals) += (tmp * scaling_factor); + std::get<28>(evals) += (tmp * scaling_factor); } { // STATE_THETA_01_DECOMPOSE - using View = typename std::tuple_element_t<25, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<29, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_01)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_01) * static_cast(in.get(C::keccakf1600_state_theta_hi_01)) + static_cast(in.get(C::keccakf1600_state_theta_low_01)))); - std::get<25>(evals) += (tmp * scaling_factor); + std::get<29>(evals) += (tmp * scaling_factor); } { // STATE_RHO_01 - using View = typename std::tuple_element_t<26, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<30, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_01)) - (CView(keccakf1600_POW_ROT_LEN_01) * static_cast(in.get(C::keccakf1600_state_theta_low_01)) + static_cast(in.get(C::keccakf1600_state_theta_hi_01)))); - std::get<26>(evals) += (tmp * scaling_factor); + std::get<30>(evals) += (tmp * scaling_factor); } { // STATE_THETA_02_DECOMPOSE - using View = typename std::tuple_element_t<27, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<31, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_02)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_02) * static_cast(in.get(C::keccakf1600_state_theta_hi_02)) + static_cast(in.get(C::keccakf1600_state_theta_low_02)))); - std::get<27>(evals) += (tmp * scaling_factor); + std::get<31>(evals) += (tmp * scaling_factor); } { // STATE_RHO_02 - using View = typename std::tuple_element_t<28, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<32, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_02)) - (CView(keccakf1600_POW_ROT_LEN_02) * static_cast(in.get(C::keccakf1600_state_theta_low_02)) + static_cast(in.get(C::keccakf1600_state_theta_hi_02)))); - std::get<28>(evals) += (tmp * scaling_factor); + std::get<32>(evals) += (tmp * scaling_factor); } { // STATE_THETA_03_DECOMPOSE - using View = typename std::tuple_element_t<29, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<33, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_03)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_03) * static_cast(in.get(C::keccakf1600_state_theta_hi_03)) + static_cast(in.get(C::keccakf1600_state_theta_low_03)))); - std::get<29>(evals) += (tmp * scaling_factor); + std::get<33>(evals) += (tmp * scaling_factor); } { // STATE_RHO_03 - using View = typename std::tuple_element_t<30, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<34, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_03)) - (CView(keccakf1600_POW_ROT_LEN_03) * static_cast(in.get(C::keccakf1600_state_theta_low_03)) + static_cast(in.get(C::keccakf1600_state_theta_hi_03)))); - std::get<30>(evals) += (tmp * scaling_factor); + std::get<34>(evals) += (tmp * scaling_factor); } { // STATE_THETA_04_DECOMPOSE - using View = typename std::tuple_element_t<31, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<35, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_04)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_04) * static_cast(in.get(C::keccakf1600_state_theta_hi_04)) + static_cast(in.get(C::keccakf1600_state_theta_low_04)))); - std::get<31>(evals) += (tmp * scaling_factor); + std::get<35>(evals) += (tmp * scaling_factor); } { // STATE_RHO_04 - using View = typename std::tuple_element_t<32, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<36, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_04)) - (CView(keccakf1600_POW_ROT_LEN_04) * static_cast(in.get(C::keccakf1600_state_theta_low_04)) + static_cast(in.get(C::keccakf1600_state_theta_hi_04)))); - std::get<32>(evals) += (tmp * scaling_factor); + std::get<36>(evals) += (tmp * scaling_factor); } { // STATE_THETA_10_DECOMPOSE - using View = typename std::tuple_element_t<33, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<37, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_10)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_10) * static_cast(in.get(C::keccakf1600_state_theta_hi_10)) + static_cast(in.get(C::keccakf1600_state_theta_low_10)))); - std::get<33>(evals) += (tmp * scaling_factor); + std::get<37>(evals) += (tmp * scaling_factor); } { // STATE_RHO_10 - using View = typename std::tuple_element_t<34, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<38, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_10)) - (CView(keccakf1600_POW_ROT_LEN_10) * static_cast(in.get(C::keccakf1600_state_theta_low_10)) + static_cast(in.get(C::keccakf1600_state_theta_hi_10)))); - std::get<34>(evals) += (tmp * scaling_factor); + std::get<38>(evals) += (tmp * scaling_factor); } { // STATE_THETA_11_DECOMPOSE - using View = typename std::tuple_element_t<35, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<39, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_11)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_11) * static_cast(in.get(C::keccakf1600_state_theta_hi_11)) + static_cast(in.get(C::keccakf1600_state_theta_low_11)))); - std::get<35>(evals) += (tmp * scaling_factor); + std::get<39>(evals) += (tmp * scaling_factor); } { // STATE_RHO_11 - using View = typename std::tuple_element_t<36, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<40, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_11)) - (CView(keccakf1600_POW_ROT_LEN_11) * static_cast(in.get(C::keccakf1600_state_theta_low_11)) + static_cast(in.get(C::keccakf1600_state_theta_hi_11)))); - std::get<36>(evals) += (tmp * scaling_factor); + std::get<40>(evals) += (tmp * scaling_factor); } { // STATE_THETA_12_DECOMPOSE - using View = typename std::tuple_element_t<37, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<41, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_12)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_12) * static_cast(in.get(C::keccakf1600_state_theta_hi_12)) + static_cast(in.get(C::keccakf1600_state_theta_low_12)))); - std::get<37>(evals) += (tmp * scaling_factor); + std::get<41>(evals) += (tmp * scaling_factor); } { // STATE_RHO_12 - using View = typename std::tuple_element_t<38, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<42, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_12)) - (CView(keccakf1600_POW_ROT_LEN_12) * static_cast(in.get(C::keccakf1600_state_theta_low_12)) + static_cast(in.get(C::keccakf1600_state_theta_hi_12)))); - std::get<38>(evals) += (tmp * scaling_factor); + std::get<42>(evals) += (tmp * scaling_factor); } { // STATE_THETA_13_DECOMPOSE - using View = typename std::tuple_element_t<39, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<43, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_13)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_13) * static_cast(in.get(C::keccakf1600_state_theta_hi_13)) + static_cast(in.get(C::keccakf1600_state_theta_low_13)))); - std::get<39>(evals) += (tmp * scaling_factor); + std::get<43>(evals) += (tmp * scaling_factor); } { // STATE_RHO_13 - using View = typename std::tuple_element_t<40, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<44, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_13)) - (CView(keccakf1600_POW_ROT_LEN_13) * static_cast(in.get(C::keccakf1600_state_theta_low_13)) + static_cast(in.get(C::keccakf1600_state_theta_hi_13)))); - std::get<40>(evals) += (tmp * scaling_factor); + std::get<44>(evals) += (tmp * scaling_factor); } { // STATE_THETA_14_DECOMPOSE - using View = typename std::tuple_element_t<41, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<45, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_14)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_14) * static_cast(in.get(C::keccakf1600_state_theta_hi_14)) + static_cast(in.get(C::keccakf1600_state_theta_low_14)))); - std::get<41>(evals) += (tmp * scaling_factor); + std::get<45>(evals) += (tmp * scaling_factor); } { // STATE_RHO_14 - using View = typename std::tuple_element_t<42, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<46, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_14)) - (CView(keccakf1600_POW_ROT_LEN_14) * static_cast(in.get(C::keccakf1600_state_theta_low_14)) + static_cast(in.get(C::keccakf1600_state_theta_hi_14)))); - std::get<42>(evals) += (tmp * scaling_factor); + std::get<46>(evals) += (tmp * scaling_factor); } { // STATE_THETA_20_DECOMPOSE - using View = typename std::tuple_element_t<43, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<47, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_20)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_20) * static_cast(in.get(C::keccakf1600_state_theta_hi_20)) + static_cast(in.get(C::keccakf1600_state_theta_low_20)))); - std::get<43>(evals) += (tmp * scaling_factor); + std::get<47>(evals) += (tmp * scaling_factor); } { // STATE_RHO_20 - using View = typename std::tuple_element_t<44, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<48, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_20)) - (CView(keccakf1600_POW_ROT_LEN_20) * static_cast(in.get(C::keccakf1600_state_theta_low_20)) + static_cast(in.get(C::keccakf1600_state_theta_hi_20)))); - std::get<44>(evals) += (tmp * scaling_factor); + std::get<48>(evals) += (tmp * scaling_factor); } { // STATE_THETA_21_DECOMPOSE - using View = typename std::tuple_element_t<45, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<49, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_21)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_21) * static_cast(in.get(C::keccakf1600_state_theta_hi_21)) + static_cast(in.get(C::keccakf1600_state_theta_low_21)))); - std::get<45>(evals) += (tmp * scaling_factor); + std::get<49>(evals) += (tmp * scaling_factor); } { // STATE_RHO_21 - using View = typename std::tuple_element_t<46, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<50, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_21)) - (CView(keccakf1600_POW_ROT_LEN_21) * static_cast(in.get(C::keccakf1600_state_theta_low_21)) + static_cast(in.get(C::keccakf1600_state_theta_hi_21)))); - std::get<46>(evals) += (tmp * scaling_factor); + std::get<50>(evals) += (tmp * scaling_factor); } { // STATE_THETA_22_DECOMPOSE - using View = typename std::tuple_element_t<47, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<51, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_22)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_22) * static_cast(in.get(C::keccakf1600_state_theta_hi_22)) + static_cast(in.get(C::keccakf1600_state_theta_low_22)))); - std::get<47>(evals) += (tmp * scaling_factor); + std::get<51>(evals) += (tmp * scaling_factor); } { // STATE_RHO_22 - using View = typename std::tuple_element_t<48, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<52, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_22)) - (CView(keccakf1600_POW_ROT_LEN_22) * static_cast(in.get(C::keccakf1600_state_theta_low_22)) + static_cast(in.get(C::keccakf1600_state_theta_hi_22)))); - std::get<48>(evals) += (tmp * scaling_factor); + std::get<52>(evals) += (tmp * scaling_factor); } { // STATE_THETA_23_DECOMPOSE - using View = typename std::tuple_element_t<49, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<53, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_23)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_23) * static_cast(in.get(C::keccakf1600_state_theta_hi_23)) + static_cast(in.get(C::keccakf1600_state_theta_low_23)))); - std::get<49>(evals) += (tmp * scaling_factor); + std::get<53>(evals) += (tmp * scaling_factor); } { // STATE_RHO_23 - using View = typename std::tuple_element_t<50, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<54, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_23)) - (CView(keccakf1600_POW_ROT_LEN_23) * static_cast(in.get(C::keccakf1600_state_theta_low_23)) + static_cast(in.get(C::keccakf1600_state_theta_hi_23)))); - std::get<50>(evals) += (tmp * scaling_factor); + std::get<54>(evals) += (tmp * scaling_factor); } { // STATE_THETA_24_DECOMPOSE - using View = typename std::tuple_element_t<51, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<55, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_24)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_24) * static_cast(in.get(C::keccakf1600_state_theta_hi_24)) + static_cast(in.get(C::keccakf1600_state_theta_low_24)))); - std::get<51>(evals) += (tmp * scaling_factor); + std::get<55>(evals) += (tmp * scaling_factor); } { // STATE_RHO_24 - using View = typename std::tuple_element_t<52, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<56, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_24)) - (CView(keccakf1600_POW_ROT_LEN_24) * static_cast(in.get(C::keccakf1600_state_theta_low_24)) + static_cast(in.get(C::keccakf1600_state_theta_hi_24)))); - std::get<52>(evals) += (tmp * scaling_factor); + std::get<56>(evals) += (tmp * scaling_factor); } { // STATE_THETA_30_DECOMPOSE - using View = typename std::tuple_element_t<53, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<57, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_30)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_30) * static_cast(in.get(C::keccakf1600_state_theta_hi_30)) + static_cast(in.get(C::keccakf1600_state_theta_low_30)))); - std::get<53>(evals) += (tmp * scaling_factor); + std::get<57>(evals) += (tmp * scaling_factor); } { // STATE_RHO_30 - using View = typename std::tuple_element_t<54, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<58, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_30)) - (CView(keccakf1600_POW_ROT_LEN_30) * static_cast(in.get(C::keccakf1600_state_theta_low_30)) + static_cast(in.get(C::keccakf1600_state_theta_hi_30)))); - std::get<54>(evals) += (tmp * scaling_factor); + std::get<58>(evals) += (tmp * scaling_factor); } { // STATE_THETA_31_DECOMPOSE - using View = typename std::tuple_element_t<55, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<59, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_31)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_31) * static_cast(in.get(C::keccakf1600_state_theta_hi_31)) + static_cast(in.get(C::keccakf1600_state_theta_low_31)))); - std::get<55>(evals) += (tmp * scaling_factor); + std::get<59>(evals) += (tmp * scaling_factor); } { // STATE_RHO_31 - using View = typename std::tuple_element_t<56, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<60, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_31)) - (CView(keccakf1600_POW_ROT_LEN_31) * static_cast(in.get(C::keccakf1600_state_theta_low_31)) + static_cast(in.get(C::keccakf1600_state_theta_hi_31)))); - std::get<56>(evals) += (tmp * scaling_factor); + std::get<60>(evals) += (tmp * scaling_factor); } { // STATE_THETA_32_DECOMPOSE - using View = typename std::tuple_element_t<57, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<61, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_32)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_32) * static_cast(in.get(C::keccakf1600_state_theta_hi_32)) + static_cast(in.get(C::keccakf1600_state_theta_low_32)))); - std::get<57>(evals) += (tmp * scaling_factor); + std::get<61>(evals) += (tmp * scaling_factor); } { // STATE_RHO_32 - using View = typename std::tuple_element_t<58, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<62, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_32)) - (CView(keccakf1600_POW_ROT_LEN_32) * static_cast(in.get(C::keccakf1600_state_theta_low_32)) + static_cast(in.get(C::keccakf1600_state_theta_hi_32)))); - std::get<58>(evals) += (tmp * scaling_factor); + std::get<62>(evals) += (tmp * scaling_factor); } { // STATE_THETA_33_DECOMPOSE - using View = typename std::tuple_element_t<59, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<63, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_33)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_33) * static_cast(in.get(C::keccakf1600_state_theta_hi_33)) + static_cast(in.get(C::keccakf1600_state_theta_low_33)))); - std::get<59>(evals) += (tmp * scaling_factor); + std::get<63>(evals) += (tmp * scaling_factor); } { // STATE_RHO_33 - using View = typename std::tuple_element_t<60, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<64, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_33)) - (CView(keccakf1600_POW_ROT_LEN_33) * static_cast(in.get(C::keccakf1600_state_theta_low_33)) + static_cast(in.get(C::keccakf1600_state_theta_hi_33)))); - std::get<60>(evals) += (tmp * scaling_factor); + std::get<64>(evals) += (tmp * scaling_factor); } { // STATE_THETA_34_DECOMPOSE - using View = typename std::tuple_element_t<61, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<65, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_34)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_34) * static_cast(in.get(C::keccakf1600_state_theta_hi_34)) + static_cast(in.get(C::keccakf1600_state_theta_low_34)))); - std::get<61>(evals) += (tmp * scaling_factor); + std::get<65>(evals) += (tmp * scaling_factor); } { // STATE_RHO_34 - using View = typename std::tuple_element_t<62, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<66, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_34)) - (CView(keccakf1600_POW_ROT_LEN_34) * static_cast(in.get(C::keccakf1600_state_theta_low_34)) + static_cast(in.get(C::keccakf1600_state_theta_hi_34)))); - std::get<62>(evals) += (tmp * scaling_factor); + std::get<66>(evals) += (tmp * scaling_factor); } { // STATE_THETA_40_DECOMPOSE - using View = typename std::tuple_element_t<63, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<67, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_40)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_40) * static_cast(in.get(C::keccakf1600_state_theta_hi_40)) + static_cast(in.get(C::keccakf1600_state_theta_low_40)))); - std::get<63>(evals) += (tmp * scaling_factor); + std::get<67>(evals) += (tmp * scaling_factor); } { // STATE_RHO_40 - using View = typename std::tuple_element_t<64, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<68, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_40)) - (CView(keccakf1600_POW_ROT_LEN_40) * static_cast(in.get(C::keccakf1600_state_theta_low_40)) + static_cast(in.get(C::keccakf1600_state_theta_hi_40)))); - std::get<64>(evals) += (tmp * scaling_factor); + std::get<68>(evals) += (tmp * scaling_factor); } { // STATE_THETA_41_DECOMPOSE - using View = typename std::tuple_element_t<65, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<69, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_41)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_41) * static_cast(in.get(C::keccakf1600_state_theta_hi_41)) + static_cast(in.get(C::keccakf1600_state_theta_low_41)))); - std::get<65>(evals) += (tmp * scaling_factor); + std::get<69>(evals) += (tmp * scaling_factor); } { // STATE_RHO_41 - using View = typename std::tuple_element_t<66, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<70, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_41)) - (CView(keccakf1600_POW_ROT_LEN_41) * static_cast(in.get(C::keccakf1600_state_theta_low_41)) + static_cast(in.get(C::keccakf1600_state_theta_hi_41)))); - std::get<66>(evals) += (tmp * scaling_factor); + std::get<70>(evals) += (tmp * scaling_factor); } { // STATE_THETA_42_DECOMPOSE - using View = typename std::tuple_element_t<67, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<71, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_42)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_42) * static_cast(in.get(C::keccakf1600_state_theta_hi_42)) + static_cast(in.get(C::keccakf1600_state_theta_low_42)))); - std::get<67>(evals) += (tmp * scaling_factor); + std::get<71>(evals) += (tmp * scaling_factor); } { // STATE_RHO_42 - using View = typename std::tuple_element_t<68, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<72, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_42)) - (CView(keccakf1600_POW_ROT_LEN_42) * static_cast(in.get(C::keccakf1600_state_theta_low_42)) + static_cast(in.get(C::keccakf1600_state_theta_hi_42)))); - std::get<68>(evals) += (tmp * scaling_factor); + std::get<72>(evals) += (tmp * scaling_factor); } { // STATE_THETA_43_DECOMPOSE - using View = typename std::tuple_element_t<69, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<73, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_43)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_43) * static_cast(in.get(C::keccakf1600_state_theta_hi_43)) + static_cast(in.get(C::keccakf1600_state_theta_low_43)))); - std::get<69>(evals) += (tmp * scaling_factor); + std::get<73>(evals) += (tmp * scaling_factor); } { // STATE_RHO_43 - using View = typename std::tuple_element_t<70, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<74, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_43)) - (CView(keccakf1600_POW_ROT_LEN_43) * static_cast(in.get(C::keccakf1600_state_theta_low_43)) + static_cast(in.get(C::keccakf1600_state_theta_hi_43)))); - std::get<70>(evals) += (tmp * scaling_factor); + std::get<74>(evals) += (tmp * scaling_factor); } { // STATE_THETA_44_DECOMPOSE - using View = typename std::tuple_element_t<71, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<75, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_theta_44)) - (CView(keccakf1600_POW_ROT_64_MIN_LEN_44) * static_cast(in.get(C::keccakf1600_state_theta_hi_44)) + static_cast(in.get(C::keccakf1600_state_theta_low_44)))); - std::get<71>(evals) += (tmp * scaling_factor); + std::get<75>(evals) += (tmp * scaling_factor); } { // STATE_RHO_44 - using View = typename std::tuple_element_t<72, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<76, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_rho_44)) - (CView(keccakf1600_POW_ROT_LEN_44) * static_cast(in.get(C::keccakf1600_state_theta_low_44)) + static_cast(in.get(C::keccakf1600_state_theta_hi_44)))); - std::get<72>(evals) += (tmp * scaling_factor); + std::get<76>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<73, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<77, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_02)) - CView(keccakf1600_ROT_LEN_02)); - std::get<73>(evals) += (tmp * scaling_factor); + std::get<77>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<74, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<78, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_04)) - CView(keccakf1600_ROT_LEN_04)); - std::get<74>(evals) += (tmp * scaling_factor); + std::get<78>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<75, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<79, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_10)) - CView(keccakf1600_ROT_LEN_10)); - std::get<75>(evals) += (tmp * scaling_factor); + std::get<79>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<76, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<80, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_12)) - CView(keccakf1600_ROT_LEN_12)); - std::get<76>(evals) += (tmp * scaling_factor); + std::get<80>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<77, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<81, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_14)) - CView(keccakf1600_ROT_LEN_14)); - std::get<77>(evals) += (tmp * scaling_factor); + std::get<81>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<78, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<82, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_21)) - CView(keccakf1600_ROT_LEN_21)); - std::get<78>(evals) += (tmp * scaling_factor); + std::get<82>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<79, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<83, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_23)) - CView(keccakf1600_ROT_LEN_23)); - std::get<79>(evals) += (tmp * scaling_factor); + std::get<83>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<80, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<84, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_30)) - CView(keccakf1600_ROT_LEN_30)); - std::get<80>(evals) += (tmp * scaling_factor); + std::get<84>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<81, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<85, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_32)) - CView(keccakf1600_ROT_LEN_32)); - std::get<81>(evals) += (tmp * scaling_factor); + std::get<85>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<82, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<86, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_33)) - CView(keccakf1600_ROT_LEN_33)); - std::get<82>(evals) += (tmp * scaling_factor); + std::get<86>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<83, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<87, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_40)) - CView(keccakf1600_ROT_LEN_40)); - std::get<83>(evals) += (tmp * scaling_factor); + std::get<87>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<84, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<88, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_41)) - CView(keccakf1600_ROT_LEN_41)); - std::get<84>(evals) += (tmp * scaling_factor); + std::get<88>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<85, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<89, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_43)) - CView(keccakf1600_ROT_LEN_43)); - std::get<85>(evals) += (tmp * scaling_factor); + std::get<89>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<86, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<90, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_len_44)) - CView(keccakf1600_ROT_LEN_44)); - std::get<86>(evals) += (tmp * scaling_factor); + std::get<90>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<87, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<91, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_01)) - (FF(64) - CView(keccakf1600_ROT_LEN_01))); - std::get<87>(evals) += (tmp * scaling_factor); + std::get<91>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<88, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<92, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_03)) - (FF(64) - CView(keccakf1600_ROT_LEN_03))); - std::get<88>(evals) += (tmp * scaling_factor); + std::get<92>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<89, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<93, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_11)) - (FF(64) - CView(keccakf1600_ROT_LEN_11))); - std::get<89>(evals) += (tmp * scaling_factor); + std::get<93>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<90, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<94, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_13)) - (FF(64) - CView(keccakf1600_ROT_LEN_13))); - std::get<90>(evals) += (tmp * scaling_factor); + std::get<94>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<91, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<95, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_20)) - (FF(64) - CView(keccakf1600_ROT_LEN_20))); - std::get<91>(evals) += (tmp * scaling_factor); + std::get<95>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<92, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<96, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_22)) - (FF(64) - CView(keccakf1600_ROT_LEN_22))); - std::get<92>(evals) += (tmp * scaling_factor); + std::get<96>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<93, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<97, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_24)) - (FF(64) - CView(keccakf1600_ROT_LEN_24))); - std::get<93>(evals) += (tmp * scaling_factor); + std::get<97>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<94, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<98, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_31)) - (FF(64) - CView(keccakf1600_ROT_LEN_31))); - std::get<94>(evals) += (tmp * scaling_factor); + std::get<98>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<95, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<99, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_34)) - (FF(64) - CView(keccakf1600_ROT_LEN_34))); - std::get<95>(evals) += (tmp * scaling_factor); + std::get<99>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<96, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<100, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_sel)) * (static_cast(in.get(C::keccakf1600_rot_64_min_len_42)) - (FF(64) - CView(keccakf1600_ROT_LEN_42))); - std::get<96>(evals) += (tmp * scaling_factor); + std::get<100>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_00 - using View = typename std::tuple_element_t<97, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<101, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_00)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_00))); - std::get<97>(evals) += (tmp * scaling_factor); + std::get<101>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_01 - using View = typename std::tuple_element_t<98, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<102, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_01)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_01))); - std::get<98>(evals) += (tmp * scaling_factor); + std::get<102>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_02 - using View = typename std::tuple_element_t<99, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<103, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_02)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_02))); - std::get<99>(evals) += (tmp * scaling_factor); + std::get<103>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_03 - using View = typename std::tuple_element_t<100, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<104, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_03)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_03))); - std::get<100>(evals) += (tmp * scaling_factor); + std::get<104>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_04 - using View = typename std::tuple_element_t<101, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<105, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_04)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_04))); - std::get<101>(evals) += (tmp * scaling_factor); + std::get<105>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_10 - using View = typename std::tuple_element_t<102, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<106, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_10)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_10))); - std::get<102>(evals) += (tmp * scaling_factor); + std::get<106>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_11 - using View = typename std::tuple_element_t<103, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<107, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_11)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_11))); - std::get<103>(evals) += (tmp * scaling_factor); + std::get<107>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_12 - using View = typename std::tuple_element_t<104, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<108, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_12)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_12))); - std::get<104>(evals) += (tmp * scaling_factor); + std::get<108>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_13 - using View = typename std::tuple_element_t<105, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<109, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_13)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_13))); - std::get<105>(evals) += (tmp * scaling_factor); + std::get<109>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_14 - using View = typename std::tuple_element_t<106, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<110, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_14)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_14))); - std::get<106>(evals) += (tmp * scaling_factor); + std::get<110>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_20 - using View = typename std::tuple_element_t<107, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<111, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_20)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_20))); - std::get<107>(evals) += (tmp * scaling_factor); + std::get<111>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_21 - using View = typename std::tuple_element_t<108, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<112, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_21)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_21))); - std::get<108>(evals) += (tmp * scaling_factor); + std::get<112>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_22 - using View = typename std::tuple_element_t<109, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<113, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_22)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_22))); - std::get<109>(evals) += (tmp * scaling_factor); + std::get<113>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_23 - using View = typename std::tuple_element_t<110, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<114, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_23)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_23))); - std::get<110>(evals) += (tmp * scaling_factor); + std::get<114>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_24 - using View = typename std::tuple_element_t<111, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<115, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_24)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_24))); - std::get<111>(evals) += (tmp * scaling_factor); + std::get<115>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_30 - using View = typename std::tuple_element_t<112, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<116, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_30)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_30))); - std::get<112>(evals) += (tmp * scaling_factor); + std::get<116>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_31 - using View = typename std::tuple_element_t<113, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<117, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_31)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_31))); - std::get<113>(evals) += (tmp * scaling_factor); + std::get<117>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_32 - using View = typename std::tuple_element_t<114, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<118, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_32)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_32))); - std::get<114>(evals) += (tmp * scaling_factor); + std::get<118>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_33 - using View = typename std::tuple_element_t<115, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<119, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_33)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_33))); - std::get<115>(evals) += (tmp * scaling_factor); + std::get<119>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_34 - using View = typename std::tuple_element_t<116, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<120, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_34)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_34))); - std::get<116>(evals) += (tmp * scaling_factor); + std::get<120>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_40 - using View = typename std::tuple_element_t<117, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<121, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_40)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_40))); - std::get<117>(evals) += (tmp * scaling_factor); + std::get<121>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_41 - using View = typename std::tuple_element_t<118, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<122, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_41)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_41))); - std::get<118>(evals) += (tmp * scaling_factor); + std::get<122>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_42 - using View = typename std::tuple_element_t<119, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<123, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_42)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_42))); - std::get<119>(evals) += (tmp * scaling_factor); + std::get<123>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_43 - using View = typename std::tuple_element_t<120, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<124, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_43)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_43))); - std::get<120>(evals) += (tmp * scaling_factor); + std::get<124>(evals) += (tmp * scaling_factor); } { // STATE_PI_NOT_44 - using View = typename std::tuple_element_t<121, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<125, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_state_pi_not_44)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * (CView(keccakf1600_POW_64_MIN_1) - CView(keccakf1600_STATE_PI_44))); - std::get<121>(evals) += (tmp * scaling_factor); + std::get<125>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_00 - using View = typename std::tuple_element_t<122, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<126, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_00_shift)) - static_cast(in.get(C::keccakf1600_state_iota_00))); - std::get<122>(evals) += (tmp * scaling_factor); + std::get<126>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_01 - using View = typename std::tuple_element_t<123, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<127, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_01_shift)) - static_cast(in.get(C::keccakf1600_state_chi_01))); - std::get<123>(evals) += (tmp * scaling_factor); + std::get<127>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_02 - using View = typename std::tuple_element_t<124, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<128, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_02_shift)) - static_cast(in.get(C::keccakf1600_state_chi_02))); - std::get<124>(evals) += (tmp * scaling_factor); + std::get<128>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_03 - using View = typename std::tuple_element_t<125, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<129, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_03_shift)) - static_cast(in.get(C::keccakf1600_state_chi_03))); - std::get<125>(evals) += (tmp * scaling_factor); + std::get<129>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_04 - using View = typename std::tuple_element_t<126, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<130, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_04_shift)) - static_cast(in.get(C::keccakf1600_state_chi_04))); - std::get<126>(evals) += (tmp * scaling_factor); + std::get<130>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_10 - using View = typename std::tuple_element_t<127, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<131, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_10_shift)) - static_cast(in.get(C::keccakf1600_state_chi_10))); - std::get<127>(evals) += (tmp * scaling_factor); + std::get<131>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_11 - using View = typename std::tuple_element_t<128, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<132, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_11_shift)) - static_cast(in.get(C::keccakf1600_state_chi_11))); - std::get<128>(evals) += (tmp * scaling_factor); + std::get<132>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_12 - using View = typename std::tuple_element_t<129, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<133, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_12_shift)) - static_cast(in.get(C::keccakf1600_state_chi_12))); - std::get<129>(evals) += (tmp * scaling_factor); + std::get<133>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_13 - using View = typename std::tuple_element_t<130, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<134, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_13_shift)) - static_cast(in.get(C::keccakf1600_state_chi_13))); - std::get<130>(evals) += (tmp * scaling_factor); + std::get<134>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_14 - using View = typename std::tuple_element_t<131, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<135, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_14_shift)) - static_cast(in.get(C::keccakf1600_state_chi_14))); - std::get<131>(evals) += (tmp * scaling_factor); + std::get<135>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_20 - using View = typename std::tuple_element_t<132, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<136, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_20_shift)) - static_cast(in.get(C::keccakf1600_state_chi_20))); - std::get<132>(evals) += (tmp * scaling_factor); + std::get<136>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_21 - using View = typename std::tuple_element_t<133, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<137, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_21_shift)) - static_cast(in.get(C::keccakf1600_state_chi_21))); - std::get<133>(evals) += (tmp * scaling_factor); + std::get<137>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_22 - using View = typename std::tuple_element_t<134, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<138, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_22_shift)) - static_cast(in.get(C::keccakf1600_state_chi_22))); - std::get<134>(evals) += (tmp * scaling_factor); + std::get<138>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_23 - using View = typename std::tuple_element_t<135, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<139, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_23_shift)) - static_cast(in.get(C::keccakf1600_state_chi_23))); - std::get<135>(evals) += (tmp * scaling_factor); + std::get<139>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_24 - using View = typename std::tuple_element_t<136, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<140, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_24_shift)) - static_cast(in.get(C::keccakf1600_state_chi_24))); - std::get<136>(evals) += (tmp * scaling_factor); + std::get<140>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_30 - using View = typename std::tuple_element_t<137, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<141, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_30_shift)) - static_cast(in.get(C::keccakf1600_state_chi_30))); - std::get<137>(evals) += (tmp * scaling_factor); + std::get<141>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_31 - using View = typename std::tuple_element_t<138, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<142, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_31_shift)) - static_cast(in.get(C::keccakf1600_state_chi_31))); - std::get<138>(evals) += (tmp * scaling_factor); + std::get<142>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_32 - using View = typename std::tuple_element_t<139, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<143, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_32_shift)) - static_cast(in.get(C::keccakf1600_state_chi_32))); - std::get<139>(evals) += (tmp * scaling_factor); + std::get<143>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_33 - using View = typename std::tuple_element_t<140, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<144, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_33_shift)) - static_cast(in.get(C::keccakf1600_state_chi_33))); - std::get<140>(evals) += (tmp * scaling_factor); + std::get<144>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_34 - using View = typename std::tuple_element_t<141, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<145, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_34_shift)) - static_cast(in.get(C::keccakf1600_state_chi_34))); - std::get<141>(evals) += (tmp * scaling_factor); + std::get<145>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_40 - using View = typename std::tuple_element_t<142, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<146, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_40_shift)) - static_cast(in.get(C::keccakf1600_state_chi_40))); - std::get<142>(evals) += (tmp * scaling_factor); + std::get<146>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_41 - using View = typename std::tuple_element_t<143, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<147, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_41_shift)) - static_cast(in.get(C::keccakf1600_state_chi_41))); - std::get<143>(evals) += (tmp * scaling_factor); + std::get<147>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_42 - using View = typename std::tuple_element_t<144, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<148, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_42_shift)) - static_cast(in.get(C::keccakf1600_state_chi_42))); - std::get<144>(evals) += (tmp * scaling_factor); + std::get<148>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_43 - using View = typename std::tuple_element_t<145, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<149, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_43_shift)) - static_cast(in.get(C::keccakf1600_state_chi_43))); - std::get<145>(evals) += (tmp * scaling_factor); + std::get<149>(evals) += (tmp * scaling_factor); } { // NEXT_STATE_IN_44 - using View = typename std::tuple_element_t<146, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<150, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_state_in_44_shift)) - static_cast(in.get(C::keccakf1600_state_chi_44))); - std::get<146>(evals) += (tmp * scaling_factor); + std::get<150>(evals) += (tmp * scaling_factor); } { - using View = typename std::tuple_element_t<147, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<151, ContainerOverSubrelations>::View; auto tmp = static_cast(in.get(C::keccakf1600_start)) * (static_cast(in.get(C::keccakf1600_highest_slice_address)) - CView(keccakf1600_HIGHEST_SLICE_ADDRESS)); - std::get<147>(evals) += (tmp * scaling_factor); + std::get<151>(evals) += (tmp * scaling_factor); } { // ERROR - using View = typename std::tuple_element_t<148, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<152, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_error)) - (FF(1) - (FF(1) - static_cast(in.get(C::keccakf1600_src_out_of_range_error))) * (FF(1) - static_cast(in.get(C::keccakf1600_dst_out_of_range_error))) * (FF(1) - static_cast(in.get(C::keccakf1600_tag_error))))); - std::get<148>(evals) += (tmp * scaling_factor); + std::get<152>(evals) += (tmp * scaling_factor); } { // DST_ADDR_PROPAGATION - using View = typename std::tuple_element_t<149, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * - (static_cast(in.get(C::keccakf1600_dst_addr_shift)) - - static_cast(in.get(C::keccakf1600_dst_addr))); - std::get<149>(evals) += (tmp * scaling_factor); + using View = typename std::tuple_element_t<153, ContainerOverSubrelations>::View; + auto tmp = + (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_dst_addr_shift)) - + static_cast(in.get(C::keccakf1600_dst_addr))); + std::get<153>(evals) += (tmp * scaling_factor); } { // CLK_PROPAGATION - using View = typename std::tuple_element_t<150, ContainerOverSubrelations>::View; - auto tmp = - (FF(1) - static_cast(in.get(C::keccakf1600_last))) * - (static_cast(in.get(C::keccakf1600_clk_shift)) - static_cast(in.get(C::keccakf1600_clk))); - std::get<150>(evals) += (tmp * scaling_factor); + using View = typename std::tuple_element_t<154, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_clk_shift)) - + static_cast(in.get(C::keccakf1600_clk))); + std::get<154>(evals) += (tmp * scaling_factor); } { // SPACE_ID_PROPAGATION - using View = typename std::tuple_element_t<151, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * - (static_cast(in.get(C::keccakf1600_space_id_shift)) - - static_cast(in.get(C::keccakf1600_space_id))); - std::get<151>(evals) += (tmp * scaling_factor); + using View = typename std::tuple_element_t<155, ContainerOverSubrelations>::View; + auto tmp = + (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_space_id_shift)) - + static_cast(in.get(C::keccakf1600_space_id))); + std::get<155>(evals) += (tmp * scaling_factor); } { // SEL_NO_ERROR_PROPAGATION - using View = typename std::tuple_element_t<152, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - static_cast(in.get(C::keccakf1600_last))) * + using View = typename std::tuple_element_t<156, ContainerOverSubrelations>::View; + auto tmp = (FF(1) - CView(keccakf1600_LATCH_CONDITION)) * (static_cast(in.get(C::keccakf1600_sel_no_error_shift)) - static_cast(in.get(C::keccakf1600_sel_no_error))); - std::get<152>(evals) += (tmp * scaling_factor); + std::get<156>(evals) += (tmp * scaling_factor); } { // SEL_SLICE_READ - using View = typename std::tuple_element_t<153, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<157, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_sel_slice_read)) - static_cast(in.get(C::keccakf1600_start)) * (FF(1) - static_cast(in.get(C::keccakf1600_src_out_of_range_error))) * (FF(1) - static_cast(in.get(C::keccakf1600_dst_out_of_range_error)))); - std::get<153>(evals) += (tmp * scaling_factor); + std::get<157>(evals) += (tmp * scaling_factor); } { // SEL_SLICE_WRITE - using View = typename std::tuple_element_t<154, ContainerOverSubrelations>::View; + using View = typename std::tuple_element_t<158, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::keccakf1600_sel_slice_write)) - static_cast(in.get(C::keccakf1600_sel_no_error)) * static_cast(in.get(C::keccakf1600_last))); - std::get<154>(evals) += (tmp * scaling_factor); + std::get<158>(evals) += (tmp * scaling_factor); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/sha256_mem.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/sha256_mem.hpp index 2fe2442926d8..d1a2eafaf3d5 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/sha256_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/sha256_mem.hpp @@ -14,10 +14,10 @@ template class sha256_memImpl { 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, 4, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 5, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 6, 4, 3, 3, - 5, 4, 3, 4, 5, 3, 3, 3, 5, 6, 3, 3, 4 }; + 5, 4, 3, 4, 5, 3, 3, 3, 5, 5, 3, 3, 4 }; template inline static bool skip(const AllEntities& in) { @@ -38,9 +38,9 @@ template class sha256_mem : public Relation> { static constexpr const std::string_view NAME = "sha256_mem"; // Subrelation indices constants, to be used in tests. - static constexpr size_t SR_LATCH_HAS_SEL_ON = 3; - static constexpr size_t SR_START_AFTER_LAST = 4; - static constexpr size_t SR_CONTINUITY_SEL = 5; + static constexpr size_t SR_TRACE_CONTINUITY = 1; + static constexpr size_t SR_LATCH_HAS_SEL_ON = 4; + static constexpr size_t SR_START_AFTER_LAST = 5; static constexpr size_t SR_CONTINUITY_EXEC_CLK = 6; static constexpr size_t SR_CONTINUITY_SPACE_ID = 7; static constexpr size_t SR_CONTINUITY_OUTPUT_ADDR = 8; @@ -60,12 +60,12 @@ template class sha256_mem : public Relation> { static std::string get_subrelation_label(size_t index) { switch (index) { + case SR_TRACE_CONTINUITY: + return "TRACE_CONTINUITY"; case SR_LATCH_HAS_SEL_ON: return "LATCH_HAS_SEL_ON"; case SR_START_AFTER_LAST: return "START_AFTER_LAST"; - case SR_CONTINUITY_SEL: - return "CONTINUITY_SEL"; case SR_CONTINUITY_EXEC_CLK: return "CONTINUITY_EXEC_CLK"; case SR_CONTINUITY_SPACE_ID: diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/sha256_mem_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/sha256_mem_impl.hpp index 247bd23ac227..5f38ada1dc62 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/sha256_mem_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/sha256_mem_impl.hpp @@ -45,31 +45,31 @@ void sha256_memImpl::accumulate(ContainerOverSubrelations& evals, auto tmp = static_cast(in.get(C::sha256_sel)) * (FF(1) - static_cast(in.get(C::sha256_sel))); std::get<0>(evals) += (tmp * scaling_factor); } - { + { // TRACE_CONTINUITY using View = typename std::tuple_element_t<1, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::sha256_start)) * (FF(1) - static_cast(in.get(C::sha256_sel))); + auto tmp = (FF(1) - static_cast(in.get(C::precomputed_first_row))) * + (FF(1) - static_cast(in.get(C::sha256_sel))) * static_cast(in.get(C::sha256_sel_shift)); std::get<1>(evals) += (tmp * scaling_factor); } { using View = typename std::tuple_element_t<2, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::sha256_latch)) * (FF(1) - static_cast(in.get(C::sha256_latch))); + auto tmp = static_cast(in.get(C::sha256_start)) * (FF(1) - static_cast(in.get(C::sha256_sel))); std::get<2>(evals) += (tmp * scaling_factor); } - { // LATCH_HAS_SEL_ON + { using View = typename std::tuple_element_t<3, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::sha256_latch)) * (FF(1) - static_cast(in.get(C::sha256_sel))); + auto tmp = static_cast(in.get(C::sha256_latch)) * (FF(1) - static_cast(in.get(C::sha256_latch))); std::get<3>(evals) += (tmp * scaling_factor); } - { // START_AFTER_LAST + { // LATCH_HAS_SEL_ON using View = typename std::tuple_element_t<4, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::sha256_sel_shift)) * - (static_cast(in.get(C::sha256_start_shift)) - CView(sha256_LATCH_CONDITION)); + auto tmp = static_cast(in.get(C::sha256_latch)) * (FF(1) - static_cast(in.get(C::sha256_sel))); std::get<4>(evals) += (tmp * scaling_factor); } - { // CONTINUITY_SEL + { // START_AFTER_LAST using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; - auto tmp = (FF(1) - CView(sha256_LATCH_CONDITION)) * - (static_cast(in.get(C::sha256_sel_shift)) - static_cast(in.get(C::sha256_sel))); + auto tmp = static_cast(in.get(C::sha256_sel_shift)) * + (static_cast(in.get(C::sha256_start_shift)) - CView(sha256_LATCH_CONDITION)); std::get<5>(evals) += (tmp * scaling_factor); } { // CONTINUITY_EXEC_CLK @@ -128,9 +128,10 @@ void sha256_memImpl::accumulate(ContainerOverSubrelations& evals, { using View = typename std::tuple_element_t<14, ContainerOverSubrelations>::View; auto tmp = (static_cast(in.get(C::sha256_mem_out_of_range_err)) - - (FF(1) - (FF(1) - static_cast(in.get(C::sha256_sel_state_out_of_range_err))) * - (FF(1) - static_cast(in.get(C::sha256_sel_input_out_of_range_err))) * - (FF(1) - static_cast(in.get(C::sha256_sel_output_out_of_range_err))))); + static_cast(in.get(C::sha256_start)) * + (FF(1) - (FF(1) - static_cast(in.get(C::sha256_sel_state_out_of_range_err))) * + (FF(1) - static_cast(in.get(C::sha256_sel_input_out_of_range_err))) * + (FF(1) - static_cast(in.get(C::sha256_sel_output_out_of_range_err))))); std::get<14>(evals) += (tmp * scaling_factor); } { @@ -371,8 +372,7 @@ void sha256_memImpl::accumulate(ContainerOverSubrelations& evals, } { using View = typename std::tuple_element_t<48, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::sha256_sel)) * CView(sha256_LATCH_ON_ERROR) * - (static_cast(in.get(C::sha256_latch)) - FF(1)); + auto tmp = CView(sha256_LATCH_ON_ERROR) * (static_cast(in.get(C::sha256_latch)) - FF(1)); std::get<48>(evals) += (tmp * scaling_factor); } { // TAG_ERROR_INIT diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/to_radix_mem.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/to_radix_mem.hpp index a1eefaff4bfa..049a44f29164 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/to_radix_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/to_radix_mem.hpp @@ -14,9 +14,9 @@ template class to_radix_memImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 3, 3, - 3, 3, 3, 5, 3, 5, 3, 5, 3, 6, 3, 4, 4, - 3, 3, 4, 4, 4, 4, 4, 4, 7, 4, 4, 3, 3 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 3, 5, 3, 5, 3, 6, 3, 4, 3, + 3, 3, 4, 4, 4, 4, 3, 4, 6, 4, 3, 3, 3 }; template inline static bool skip(const AllEntities& in) { @@ -39,7 +39,7 @@ template class to_radix_mem : public Relation // Subrelation indices constants, to be used in tests. static constexpr size_t SR_LAST_HAS_SEL_ON = 3; static constexpr size_t SR_START_AFTER_LAST = 4; - static constexpr size_t SR_SEL_CONTINUITY = 5; + static constexpr size_t SR_TRACE_CONTINUITY = 5; static constexpr size_t SR_EXEC_CLK_CONTINUITY = 6; static constexpr size_t SR_SPACE_ID_CONTINUITY = 7; static constexpr size_t SR_VALUE_CONTINUITY = 8; @@ -65,8 +65,8 @@ template class to_radix_mem : public Relation return "LAST_HAS_SEL_ON"; case SR_START_AFTER_LAST: return "START_AFTER_LAST"; - case SR_SEL_CONTINUITY: - return "SEL_CONTINUITY"; + case SR_TRACE_CONTINUITY: + return "TRACE_CONTINUITY"; case SR_EXEC_CLK_CONTINUITY: return "EXEC_CLK_CONTINUITY"; case SR_SPACE_ID_CONTINUITY: diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/to_radix_mem_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/to_radix_mem_impl.hpp index 882f57290f00..e0569eae59b6 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/to_radix_mem_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/to_radix_mem_impl.hpp @@ -21,7 +21,7 @@ void to_radix_memImpl::accumulate(ContainerOverSubrelations& evals, const auto to_radix_mem_LATCH_CONDITION = in.get(C::to_radix_mem_last) + in.get(C::precomputed_first_row); const auto to_radix_mem_NOT_LAST = in.get(C::to_radix_mem_sel) * (FF(1) - to_radix_mem_LATCH_CONDITION); const auto to_radix_mem_NO_ERR_NOR_NUM_LIMBS_ZERO = - in.get(C::to_radix_mem_start) * (FF(1) - in.get(C::to_radix_mem_err)) * + (in.get(C::to_radix_mem_start) - in.get(C::to_radix_mem_err)) * (FF(1) - in.get(C::to_radix_mem_sel_num_limbs_is_zero)) + (FF(1) - in.get(C::to_radix_mem_start)) * in.get(C::to_radix_mem_sel); const auto to_radix_mem_NUM_LIMBS_MINUS_ONE = (in.get(C::to_radix_mem_num_limbs) - FF(1)); @@ -56,7 +56,7 @@ void to_radix_memImpl::accumulate(ContainerOverSubrelations& evals, (static_cast(in.get(C::to_radix_mem_start_shift)) - CView(to_radix_mem_LATCH_CONDITION)); std::get<4>(evals) += (tmp * scaling_factor); } - { // SEL_CONTINUITY + { // TRACE_CONTINUITY using View = typename std::tuple_element_t<5, ContainerOverSubrelations>::View; auto tmp = (FF(1) - static_cast(in.get(C::precomputed_first_row))) * (FF(1) - static_cast(in.get(C::to_radix_mem_sel))) * @@ -65,32 +65,37 @@ void to_radix_memImpl::accumulate(ContainerOverSubrelations& evals, } { // EXEC_CLK_CONTINUITY using View = typename std::tuple_element_t<6, ContainerOverSubrelations>::View; - auto tmp = CView(to_radix_mem_NOT_LAST) * (static_cast(in.get(C::to_radix_mem_execution_clk_shift)) - - static_cast(in.get(C::to_radix_mem_execution_clk))); + auto tmp = (FF(1) - CView(to_radix_mem_LATCH_CONDITION)) * + (static_cast(in.get(C::to_radix_mem_execution_clk_shift)) - + static_cast(in.get(C::to_radix_mem_execution_clk))); std::get<6>(evals) += (tmp * scaling_factor); } { // SPACE_ID_CONTINUITY using View = typename std::tuple_element_t<7, ContainerOverSubrelations>::View; - auto tmp = CView(to_radix_mem_NOT_LAST) * (static_cast(in.get(C::to_radix_mem_space_id_shift)) - - static_cast(in.get(C::to_radix_mem_space_id))); + auto tmp = + (FF(1) - CView(to_radix_mem_LATCH_CONDITION)) * (static_cast(in.get(C::to_radix_mem_space_id_shift)) - + static_cast(in.get(C::to_radix_mem_space_id))); std::get<7>(evals) += (tmp * scaling_factor); } { // VALUE_CONTINUITY using View = typename std::tuple_element_t<8, ContainerOverSubrelations>::View; - auto tmp = CView(to_radix_mem_NOT_LAST) * (static_cast(in.get(C::to_radix_mem_value_to_decompose_shift)) - - static_cast(in.get(C::to_radix_mem_value_to_decompose))); + auto tmp = (FF(1) - CView(to_radix_mem_LATCH_CONDITION)) * + (static_cast(in.get(C::to_radix_mem_value_to_decompose_shift)) - + static_cast(in.get(C::to_radix_mem_value_to_decompose))); std::get<8>(evals) += (tmp * scaling_factor); } { // RADIX_CONTINUITY using View = typename std::tuple_element_t<9, ContainerOverSubrelations>::View; - auto tmp = CView(to_radix_mem_NOT_LAST) * (static_cast(in.get(C::to_radix_mem_radix_shift)) - - static_cast(in.get(C::to_radix_mem_radix))); + auto tmp = + (FF(1) - CView(to_radix_mem_LATCH_CONDITION)) * + (static_cast(in.get(C::to_radix_mem_radix_shift)) - static_cast(in.get(C::to_radix_mem_radix))); std::get<9>(evals) += (tmp * scaling_factor); } { // IS_OUTPUT_BITS_CONTINUITY using View = typename std::tuple_element_t<10, ContainerOverSubrelations>::View; - auto tmp = CView(to_radix_mem_NOT_LAST) * (static_cast(in.get(C::to_radix_mem_is_output_bits_shift)) - - static_cast(in.get(C::to_radix_mem_is_output_bits))); + auto tmp = (FF(1) - CView(to_radix_mem_LATCH_CONDITION)) * + (static_cast(in.get(C::to_radix_mem_is_output_bits_shift)) - + static_cast(in.get(C::to_radix_mem_is_output_bits))); std::get<10>(evals) += (tmp * scaling_factor); } { @@ -200,9 +205,9 @@ void to_radix_memImpl::accumulate(ContainerOverSubrelations& evals, } { // SEL_SHOULD_DECOMPOSE_CONTINUITY using View = typename std::tuple_element_t<25, ContainerOverSubrelations>::View; - auto tmp = - CView(to_radix_mem_NOT_LAST) * (static_cast(in.get(C::to_radix_mem_sel_should_decompose_shift)) - - static_cast(in.get(C::to_radix_mem_sel_should_decompose))); + auto tmp = (FF(1) - CView(to_radix_mem_LATCH_CONDITION)) * + (static_cast(in.get(C::to_radix_mem_sel_should_decompose_shift)) - + static_cast(in.get(C::to_radix_mem_sel_should_decompose))); std::get<25>(evals) += (tmp * scaling_factor); } { @@ -248,8 +253,8 @@ void to_radix_memImpl::accumulate(ContainerOverSubrelations& evals, } { // LAST_ROW_ERR_COMPUTATION using View = typename std::tuple_element_t<32, ContainerOverSubrelations>::View; - auto tmp = static_cast(in.get(C::to_radix_mem_start)) * static_cast(in.get(C::to_radix_mem_err)) * - (static_cast(in.get(C::to_radix_mem_last)) - FF(1)); + auto tmp = + static_cast(in.get(C::to_radix_mem_err)) * (static_cast(in.get(C::to_radix_mem_last)) - FF(1)); std::get<32>(evals) += (tmp * scaling_factor); } { // LAST_ROW_NUM_LIMBS_ZERO @@ -280,9 +285,9 @@ void to_radix_memImpl::accumulate(ContainerOverSubrelations& evals, } { // SEL_SHOULD_WRITE_MEM_CONTINUITY using View = typename std::tuple_element_t<36, ContainerOverSubrelations>::View; - auto tmp = - CView(to_radix_mem_NOT_LAST) * (static_cast(in.get(C::to_radix_mem_sel_should_write_mem_shift)) - - static_cast(in.get(C::to_radix_mem_sel_should_write_mem))); + auto tmp = (FF(1) - CView(to_radix_mem_LATCH_CONDITION)) * + (static_cast(in.get(C::to_radix_mem_sel_should_write_mem_shift)) - + static_cast(in.get(C::to_radix_mem_sel_should_write_mem))); std::get<36>(evals) += (tmp * scaling_factor); } { // SEL_SHOULD_WRITE_MEM_REQUIRES_SEL diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/keccakf1600_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/keccakf1600_trace.cpp index bff0ddeb0938..540b1397e652 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/keccakf1600_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/keccakf1600_trace.cpp @@ -480,13 +480,6 @@ void KeccakF1600TraceBuilder::process_single_slice(const simulation::KeccakF1600 void KeccakF1600TraceBuilder::process_permutation( const simulation::EventEmitterInterface::Container& events, TraceContainer& trace) { - // Important to not set last to 1 in the first row if there are no events. Otherwise, the skippable condition - // would be skipped wrongly as the sub-relation last * (1 - last) = 0 cannot be satisified (after the - // randomization process happening in the sumcheck protocol). - if (!events.empty()) { - trace.set(C::keccakf1600_last, 0, 1); - } - constexpr MemoryAddress HIGHEST_SLICE_ADDRESS = AVM_HIGHEST_MEM_ADDRESS - AVM_KECCAKF1600_STATE_SIZE + 1; uint32_t row = 1; @@ -652,17 +645,6 @@ void KeccakF1600TraceBuilder::process_permutation( void KeccakF1600TraceBuilder::process_memory_slices( const simulation::EventEmitterInterface::Container& events, TraceContainer& trace) { - // Important to not set last or ctr_end to 1 in the first row if there are no events. Otherwise, the skippable - // condition would be skipped wrongly as the sub-relation ctr_end * (1 - ctr_end) = 0 cannot be satisified (after - // the randomization process happening in the sumcheck protocol). - if (!events.empty()) { - trace.set(0, - { { - { C::keccak_memory_last, 1 }, - { C::keccak_memory_ctr_end, 1 }, - } }); - } - uint32_t row = 1; for (const auto& event : events) { // Skip the event if there is an out of range error. From 4fdfe228946c967f22723a41f792bf33411564e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Fri, 16 Jan 2026 12:41:50 +0100 Subject: [PATCH 09/15] fix(avm): Fix TS ECC add infinity handling (#19657) Fuzzer revealed issues in infinity handling in ts --- .../vm2/simulation/gadgets/ecc.test.cpp | 34 +++++ .../src/public/avm/opcodes/ec_add.test.ts | 141 ++++++++++++++++++ .../src/public/avm/opcodes/ec_add.ts | 13 +- 3 files changed, 186 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp index 136f442a4ed7..5b3bdc3b639e 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.test.cpp @@ -240,5 +240,39 @@ TEST(AvmSimulationEccTest, InfinityOnCurve) EXPECT_EQ(result, q); } +TEST(AvmSimulationEccTest, AddsUpToInfinity) +{ + EventEmitter ecc_event_emitter; + EventEmitter scalar_mul_event_emitter; + EventEmitter ecc_add_memory_event_emitter; + + StrictMock execution_id_manager; + StrictMock gt; + StrictMock to_radix; + MemoryStore memory; + + EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0)); + EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false)); + + Ecc ecc( + execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter); + + // Both points on the curve, q = -p + FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"); + FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"); + EmbeddedCurvePoint p(p_x, p_y, false); + + EmbeddedCurvePoint q = -p; + + uint32_t dst_address = 0x1000; + ecc.add(memory, p, q, dst_address); + + // Zero as coordinates + EXPECT_EQ(memory.get(dst_address).as_ff(), FF(0)); + EXPECT_EQ(memory.get(dst_address + 1).as_ff(), FF(0)); + // Infinity + EXPECT_EQ(memory.get(dst_address + 2).as_ff(), 1); +} + } // namespace } // namespace bb::avm2::simulation diff --git a/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts b/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts index 7db6fa83a904..8e144efaed91 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/ec_add.test.ts @@ -117,6 +117,147 @@ describe('EC Instructions', () => { expect(actual).toEqual(G3); expect(context.machineState.memory.get(8).toFr().equals(Fr.ZERO)).toBe(true); }); + + it('Should add correctly with rhs being infinity', async () => { + const zero = new Uint1(0); + const one = new Uint1(1); + + const x = new Field(Grumpkin.generator.x); + const y = new Field(Grumpkin.generator.y); + + // Point 1 is not infinity + context.machineState.memory.set(0, x); + context.machineState.memory.set(1, y); + context.machineState.memory.set(2, zero); + // Point 2 is infinity + context.machineState.memory.set(3, x); + context.machineState.memory.set(4, y); + context.machineState.memory.set(5, one); + context.machineState.memory.set(6, new Uint32(6)); + + await new EcAdd( + /*addressing_mode=*/ 0, + /*p1X=*/ 0, + /*p1Y=*/ 1, + /*p1IsInfinite=*/ 2, + /*p2X=*/ 3, + /*p2Y=*/ 4, + /*p2IsInfinite=*/ 5, + /*dstOffset=*/ 6, + ).execute(context); + + expect([ + context.machineState.memory.get(6).toFr(), + context.machineState.memory.get(7).toFr(), + context.machineState.memory.get(8).toNumber(), + ]).toEqual([x.toFr(), y.toFr(), 0]); + }); + + it('Should add correctly with lhs being infinity', async () => { + const zero = new Uint1(0); + const one = new Uint1(1); + + const x = new Field(Grumpkin.generator.x); + const y = new Field(Grumpkin.generator.y); + + // Point 1 is infinity + context.machineState.memory.set(0, x); + context.machineState.memory.set(1, y); + context.machineState.memory.set(2, one); + // Point 2 is not infinity + context.machineState.memory.set(3, x); + context.machineState.memory.set(4, y); + context.machineState.memory.set(5, zero); + context.machineState.memory.set(6, new Uint32(6)); + + await new EcAdd( + /*addressing_mode=*/ 0, + /*p1X=*/ 0, + /*p1Y=*/ 1, + /*p1IsInfinite=*/ 2, + /*p2X=*/ 3, + /*p2Y=*/ 4, + /*p2IsInfinite=*/ 5, + /*dstOffset=*/ 6, + ).execute(context); + + expect([ + context.machineState.memory.get(6).toFr(), + context.machineState.memory.get(7).toFr(), + context.machineState.memory.get(8).toNumber(), + ]).toEqual([x.toFr(), y.toFr(), 0]); + }); + + it('Should add correctly with both being infinity', async () => { + const one = new Uint1(1); + + const x = new Field(Grumpkin.generator.x); + const y = new Field(Grumpkin.generator.y); + + // Point 1 is infinity + context.machineState.memory.set(0, x); + context.machineState.memory.set(1, y); + context.machineState.memory.set(2, one); + // Point 2 is infinity + context.machineState.memory.set(3, x); + context.machineState.memory.set(4, y); + context.machineState.memory.set(5, one); + context.machineState.memory.set(6, new Uint32(6)); + + await new EcAdd( + /*addressing_mode=*/ 0, + /*p1X=*/ 0, + /*p1Y=*/ 1, + /*p1IsInfinite=*/ 2, + /*p2X=*/ 3, + /*p2Y=*/ 4, + /*p2IsInfinite=*/ 5, + /*dstOffset=*/ 6, + ).execute(context); + + expect([ + context.machineState.memory.get(6).toFr(), + context.machineState.memory.get(7).toFr(), + context.machineState.memory.get(8).toNumber(), + ]).toEqual([Fr.ZERO, Fr.ZERO, 1]); + }); + + it('Should add correctly with none infinity adding up to infinity', async () => { + const zero = new Uint1(0); + + // Point 1 is a "random" point on the curve + const x1 = new Field(2165030248772332382647339664685760681662697934905450801078761197378150920554n); + const y1 = new Field(1518479793551399970960577643223827307749147426195887130444945641264602004320n); + // Point 2 is negation of point 1 + const x2 = new Field(2165030248772332382647339664685760681662697934905450801078761197378150920554n); + const y2 = new Field(20369763078287875251285828102033447780799216974220147213253258545311206491297n); + + context.machineState.memory.set(0, x1); + context.machineState.memory.set(1, y1); + context.machineState.memory.set(2, zero); + + context.machineState.memory.set(3, x2); + context.machineState.memory.set(4, y2); + context.machineState.memory.set(5, zero); + context.machineState.memory.set(6, new Uint32(6)); + + await new EcAdd( + /*addressing_mode=*/ 0, + /*p1X=*/ 0, + /*p1Y=*/ 1, + /*p1IsInfinite=*/ 2, + /*p2X=*/ 3, + /*p2Y=*/ 4, + /*p2IsInfinite=*/ 5, + /*dstOffset=*/ 6, + ).execute(context); + + expect([ + context.machineState.memory.get(6).toFr(), + context.machineState.memory.get(7).toFr(), + context.machineState.memory.get(8).toNumber(), + ]).toEqual([Fr.ZERO, Fr.ZERO, 1]); + }); }); describe('EcAdd should throw an error when a point is not on the curve', () => { diff --git a/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts b/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts index 9dcdc4909c53..19e3c1adc6ca 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/ec_add.ts @@ -79,12 +79,21 @@ export class EcAdd extends Instruction { } let dest; - if (p1IsInfinite) { + if (p1IsInfinite && p2IsInfinite) { + dest = Point.ZERO; + } else if (p1IsInfinite) { dest = p2; } else if (p2IsInfinite) { dest = p1; } else { - dest = await Grumpkin.add(p1, p2); + // TS<>BB ecc add communication is broken for points that add up to infinity. + // However, here we know that both points are on the curve, and that none is infinity + // so we can check for the case where you add p + (-p) = infinity. + if (p1.x.equals(p2.x) && !p1.y.equals(p2.y)) { + dest = Point.ZERO; + } else { + dest = await Grumpkin.add(p1, p2); + } } // Important to use setSlice() and not set() in the two following statements as From cf01a416bc74f170ebde08107a31dfe49078ede9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Fri, 16 Jan 2026 13:27:39 +0100 Subject: [PATCH 10/15] fix(avm): Fix jumpif in fuzzer (#19655) Resolves https://linear.app/aztec-labs/issue/AVM-196/review-jumpif-in-fuzzer --- .../avm_fuzzer/fuzz_lib/control_flow.cpp | 18 +++--------------- .../avm_fuzzer/fuzz_lib/program_block.cpp | 9 +++++++++ .../avm_fuzzer/fuzz_lib/program_block.hpp | 1 + 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/control_flow.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/control_flow.cpp index 812670eca02e..ff97bef684fd 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/control_flow.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/control_flow.cpp @@ -250,22 +250,10 @@ int predict_block_size(ProgramBlock* block) case TerminatorType::JUMP: return bytecode_length + JMP_SIZE; // finalized with jump case TerminatorType::JUMP_IF: { - // if boolean condition is not set adding SET_8 instruction to the bytecode + // if boolean condition is not set add SET instruction to the bytecode if (!block->get_terminating_condition_value().has_value()) { - for (uint16_t address = 0; address < 65535; address++) { - // if the memory address is already in use, we skip it - if (block->is_memory_address_set(address)) { - continue; - } - auto set_16_instruction = - SET_16_Instruction{ .value_tag = bb::avm2::MemoryTag::U1, - .result_address = - AddressRef{ .address = address, .mode = AddressingMode::Direct }, - .value = 0 }; - block->process_instruction(set_16_instruction); - bytecode_length = static_cast(create_bytecode(block->get_instructions()).size()); - break; - } + block->process_write_terminating_condition_value(); + bytecode_length = static_cast(create_bytecode(block->get_instructions()).size()); } return bytecode_length + JMP_IF_SIZE + JMP_SIZE; // finalized with jumpi } diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp index f94f23164dfc..02354a2c1757 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp @@ -1633,6 +1633,15 @@ std::optional ProgramBlock::get_terminating_condition_value() return condition_addr; } +void ProgramBlock::process_write_terminating_condition_value() +{ + uint16_t value = condition_offset_index % 2; + process_set_16_instruction(SET_16_Instruction{ + .value_tag = bb::avm2::MemoryTag::U1, + .result_address = AddressRef{ .address = condition_offset_index, .mode = AddressingMode::Direct }, + .value = value }); +} + bool ProgramBlock::is_memory_address_set(uint16_t address) { return memory_manager.is_memory_address_set(address); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.hpp index a1665fde8395..e4adf49a53cd 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.hpp @@ -173,6 +173,7 @@ class ProgramBlock { void insert_internal_call(ProgramBlock* target_block); std::optional get_terminating_condition_value(); + void process_write_terminating_condition_value(); std::vector get_instructions(); bool is_memory_address_set(uint16_t address); From e80488dae9e6abefb2dbcd14469f943f3fb8c599 Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Fri, 16 Jan 2026 15:08:49 +0000 Subject: [PATCH 11/15] feat(avm): protocol contractg mutations (#19586) Protocol contract mutations turned out to be much more complex. Might've been easier to implement a hardcoded set. We need to ensure we re-validate the enqueued calls whenever we mutate the protocol contracts since we could have invalidated some addresses. Note: The TS simulation required a change to match the cpp simulator --- .../barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp | 18 ++++- .../avm_fuzzer/fuzz_lib/fuzz.test.cpp | 8 +- .../avm_fuzzer/fuzz_lib/simulator.cpp | 15 ++-- .../avm_fuzzer/fuzz_lib/simulator.hpp | 14 +++- .../barretenberg/avm_fuzzer/fuzzer_lib.cpp | 65 ++++++++++++--- .../barretenberg/avm_fuzzer/fuzzer_lib.hpp | 5 +- .../mutations/protocol_contracts.cpp | 79 +++++++++++++++++++ .../mutations/protocol_contracts.hpp | 28 +++++++ .../avm_fuzzer/mutations/tx_types/gas.hpp | 5 +- .../public/fuzzing/avm_fuzzer_simulator.ts | 45 ++++++++--- .../src/public/fuzzing/avm_simulator_bin.ts | 15 ++-- .../public_tx_simulator.ts | 6 +- .../src/public/state_manager/state_manager.ts | 18 +---- 13 files changed, 254 insertions(+), 67 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/protocol_contracts.cpp create mode 100644 barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/protocol_contracts.hpp diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp index 38b098d71fe8..a5da2e0c4d2d 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.cpp @@ -44,16 +44,26 @@ SimulatorResult fuzz_against_ts_simulator(FuzzerData& fuzzer_data, FuzzerContext try { ws_mgr->checkpoint(); - cpp_result = - cpp_simulator.simulate(*ws_mgr, contract_db, tx, globals, /*public_data_writes=*/{}, /*note_hashes=*/{}); + cpp_result = cpp_simulator.simulate(*ws_mgr, + contract_db, + tx, + globals, + /*public_data_writes=*/{}, + /*note_hashes=*/{}, + /*protocol_contracts=*/{}); ws_mgr->revert(); } catch (const std::exception& e) { throw std::runtime_error(std::string("CppSimulator threw an exception: ") + e.what()); } ws_mgr->checkpoint(); - auto js_result = - js_simulator->simulate(*ws_mgr, contract_db, tx, globals, /*public_data_writes=*/{}, /*note_hashes=*/{}); + auto js_result = js_simulator->simulate(*ws_mgr, + contract_db, + tx, + globals, + /*public_data_writes=*/{}, + /*note_hashes=*/{}, + /*protocol_contracts=*/{}); context.reset(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp index cab37e206251..cde4f5bcdc8d 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzz.test.cpp @@ -65,7 +65,13 @@ class FuzzTest : public ::testing::Test { auto cpp_simulator = CppSimulator(); auto globals = create_default_globals(); - auto result = cpp_simulator.simulate(*ws_mgr, contract_db, tx, globals, /*public_data_writes=*/{}, {}); + auto result = cpp_simulator.simulate(*ws_mgr, + contract_db, + tx, + globals, + /*public_data_writes=*/{}, + /*note_hashes=*/{}, + /*protocol_contracts=*/{}); ws_mgr->revert(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp index 010aa2cc35d6..90af762161f7 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp @@ -39,7 +39,8 @@ std::string serialize_simulation_request( const GlobalVariables& globals, const FuzzerContractDB& contract_db, const std::vector& public_data_writes, - const std::vector& note_hashes) + const std::vector& note_hashes, + const ProtocolContracts& protocol_contracts) { // Build vectors from contract_db std::vector classes_vec = contract_db.get_contract_classes(); @@ -54,6 +55,7 @@ std::string serialize_simulation_request( .contract_instances = std::move(instances_vec), .public_data_writes = public_data_writes, .note_hashes = note_hashes, + .protocol_contracts = protocol_contracts, }; auto [buffer, size] = msgpack_encode_buffer(request); @@ -83,7 +85,8 @@ SimulatorResult CppSimulator::simulate( const Tx& tx, const GlobalVariables& globals, [[maybe_unused]] const std::vector& public_data_writes, - [[maybe_unused]] const std::vector& note_hashes) + [[maybe_unused]] const std::vector& note_hashes, + const ProtocolContracts& protocol_contracts) { // Note: public_data_writes and note_hashes are already applied to C++ world state in setup_fuzzer_state @@ -96,8 +99,6 @@ SimulatorResult CppSimulator::simulate( }, }; - ProtocolContracts protocol_contracts{}; - WorldState& ws = ws_mgr.get_world_state(); WorldStateRevision ws_rev = ws_mgr.get_current_revision(); @@ -157,9 +158,11 @@ SimulatorResult JsSimulator::simulate( const Tx& tx, const GlobalVariables& globals, const std::vector& public_data_writes, - const std::vector& note_hashes) + const std::vector& note_hashes, + const ProtocolContracts& protocol_contracts) { - std::string serialized = serialize_simulation_request(tx, globals, contract_db, public_data_writes, note_hashes); + std::string serialized = + serialize_simulation_request(tx, globals, contract_db, public_data_writes, note_hashes, protocol_contracts); // Send the request process.write_line(serialized); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp index d9cd3c3bfd2e..78557b9582fc 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp @@ -29,6 +29,8 @@ struct FuzzerSimulationRequest { std::vector public_data_writes; // Note hashes to be applied before simulation std::vector note_hashes; + // Protocol contracts mapping (canonical address index -> derived address) + ProtocolContracts protocol_contracts; MSGPACK_CAMEL_CASE_FIELDS(ws_data_dir, ws_map_size_kb, @@ -37,7 +39,8 @@ struct FuzzerSimulationRequest { contract_classes, contract_instances, public_data_writes, - note_hashes); + note_hashes, + protocol_contracts); }; struct SimulatorResult { @@ -63,7 +66,8 @@ class Simulator { const Tx& tx, const GlobalVariables& globals, const std::vector& public_data_writes, - const std::vector& note_hashes) = 0; + const std::vector& note_hashes, + const ProtocolContracts& protocol_contracts) = 0; }; /// @brief uses barretenberg/vm2 to simulate the bytecode @@ -74,7 +78,8 @@ class CppSimulator : public Simulator { const Tx& tx, const GlobalVariables& globals, const std::vector& public_data_writes, - const std::vector& note_hashes) override; + const std::vector& note_hashes, + const ProtocolContracts& protocol_contracts) override; }; /// @brief uses the yarn-project/simulator to simulate the bytecode @@ -101,7 +106,8 @@ class JsSimulator : public Simulator { const Tx& tx, const GlobalVariables& globals, const std::vector& public_data_writes, - const std::vector& note_hashes) override; + const std::vector& note_hashes, + const ProtocolContracts& protocol_contracts) override; }; GlobalVariables create_default_globals(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp index 12d2d292d25e..0629a997fd7c 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp @@ -15,6 +15,7 @@ #include "barretenberg/avm_fuzzer/mutations/basic_types/uint64_t.hpp" #include "barretenberg/avm_fuzzer/mutations/configuration.hpp" #include "barretenberg/avm_fuzzer/mutations/fuzzer_data.hpp" +#include "barretenberg/avm_fuzzer/mutations/protocol_contracts.hpp" #include "barretenberg/avm_fuzzer/mutations/tx_data.hpp" #include "barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp" #include "barretenberg/common/log.hpp" @@ -49,6 +50,22 @@ void setup_fuzzer_state(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contr contract_db.add_contract_instance(contract_address, contract_instance); } + // For protocol contracts, also add instances keyed by canonical address (1-11). + // This is needed because protocol contracts are looked up by canonical address, + // but the derived address in protocol_contracts.derived_addresses maps to the actual instance. + for (size_t i = 0; i < tx_data.protocol_contracts.derived_addresses.size(); ++i) { + const auto& derived_address = tx_data.protocol_contracts.derived_addresses[i]; + if (!derived_address.is_zero()) { + // Canonical address is index + 1 (addresses 1-11 map to indices 0-10) + AztecAddress canonical_address(static_cast(i + 1)); + // Find the instance for this derived address and also add it by canonical address + auto maybe_instance = contract_db.get_contract_instance(derived_address); + if (maybe_instance.has_value()) { + contract_db.add_contract_instance(canonical_address, maybe_instance.value()); + } + } + } + // Register contract addresses in the world state for (const auto& addr : tx_data.contract_addresses) { ws_mgr.register_contract_address(addr); @@ -85,8 +102,13 @@ SimulatorResult fuzz_tx(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contr try { ws_mgr.checkpoint(); - cpp_result = cpp_simulator.simulate( - ws_mgr, contract_db, tx_data.tx, tx_data.global_variables, tx_data.public_data_writes, tx_data.note_hashes); + cpp_result = cpp_simulator.simulate(ws_mgr, + contract_db, + tx_data.tx, + tx_data.global_variables, + tx_data.public_data_writes, + tx_data.note_hashes, + tx_data.protocol_contracts); fuzz_info("CppSimulator completed without exception"); fuzz_info("CppSimulator result: ", cpp_result); ws_mgr.revert(); @@ -102,8 +124,13 @@ SimulatorResult fuzz_tx(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contr } ws_mgr.checkpoint(); - auto js_result = js_simulator->simulate( - ws_mgr, contract_db, tx_data.tx, tx_data.global_variables, tx_data.public_data_writes, tx_data.note_hashes); + auto js_result = js_simulator->simulate(ws_mgr, + contract_db, + tx_data.tx, + tx_data.global_variables, + tx_data.public_data_writes, + tx_data.note_hashes, + tx_data.protocol_contracts); // If the results do not match if (!compare_simulator_results(cpp_result, js_result)) { @@ -126,7 +153,7 @@ SimulatorResult fuzz_tx(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contr /// @throws An exception if simulation results differ or check_circuit fails int fuzz_prover(FuzzerWorldStateManager& ws_mgr, FuzzerContractDB& contract_db, FuzzerTxData& tx_data) { - ProtocolContracts protocol_contracts{}; + ProtocolContracts& protocol_contracts = tx_data.protocol_contracts; WorldState& ws = ws_mgr.get_world_state(); WorldStateRevision ws_rev = ws_mgr.get_current_revision(); AvmSimulationHelper helper; @@ -369,14 +396,21 @@ size_t mutate_tx_data(FuzzerContext& context, // This is just mutating the gas values and timestamp mutate_uint64_t(tx_data.global_variables.timestamp, rng, BASIC_UINT64_T_MUTATION_CONFIGURATION); mutate_gas_fees(tx_data.global_variables.gas_fees, rng); - // This must be less than or equal to the tx max fees per gas - tx_data.global_variables.gas_fees.fee_per_da_gas = std::min( - tx_data.global_variables.gas_fees.fee_per_da_gas, tx_data.tx.gas_settings.max_fees_per_gas.fee_per_da_gas); - tx_data.global_variables.gas_fees.fee_per_l2_gas = std::min( - tx_data.global_variables.gas_fees.fee_per_l2_gas, tx_data.tx.gas_settings.max_fees_per_gas.fee_per_l2_gas); break; - // case TxDataMutationType::ProtocolContractsMutation: - // break; + case FuzzerTxDataMutationType::ProtocolContractsMutation: + mutate_protocol_contracts(tx_data.protocol_contracts, tx_data.tx, tx_data.contract_addresses, rng); + break; + } + + // Clear any protocol contract derived addresses that reference addresses no longer in the contract set. + // This can happen when mutations (e.g., ContractClassMutation, ContractInstanceMutation) change contract addresses. + // Must run AFTER all mutations since some mutations modify contract_addresses. + std::unordered_set valid_addresses(tx_data.contract_addresses.begin(), + tx_data.contract_addresses.end()); + for (auto& derived_address : tx_data.protocol_contracts.derived_addresses) { + if (!derived_address.is_zero() && !valid_addresses.contains(derived_address)) { + derived_address = AztecAddress(0); + } } // todo: do we need to ensure this or are should we able to process 0 enqueued calls? @@ -393,6 +427,13 @@ size_t mutate_tx_data(FuzzerContext& context, .calldata = calldata }); } + // Ensure global gas_fees <= max_fees_per_gas (required for compute_effective_gas_fees) + // This must run after ANY mutation since TxMutation can reduce max_fees_per_gas + tx_data.global_variables.gas_fees.fee_per_da_gas = std::min( + tx_data.global_variables.gas_fees.fee_per_da_gas, tx_data.tx.gas_settings.max_fees_per_gas.fee_per_da_gas); + tx_data.global_variables.gas_fees.fee_per_l2_gas = std::min( + tx_data.global_variables.gas_fees.fee_per_l2_gas, tx_data.tx.gas_settings.max_fees_per_gas.fee_per_l2_gas); + // Compute effective gas fees matching TS computeEffectiveGasFees // This must be done after any mutation that could affect gas settings or global variables tx_data.tx.effective_gas_fees = diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp index f78e40e05bb7..93d33213fb2d 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp @@ -66,10 +66,10 @@ enum class FuzzerTxDataMutationType : uint8_t { ContractClassMutation, ContractInstanceMutation, GlobalVariablesMutation, - // ProtocolContractsMutation + ProtocolContractsMutation }; -using FuzzerTxDataMutationConfig = WeightedSelectionConfig; +using FuzzerTxDataMutationConfig = WeightedSelectionConfig; constexpr FuzzerTxDataMutationConfig FUZZER_TX_DATA_MUTATION_CONFIGURATION = FuzzerTxDataMutationConfig({ { FuzzerTxDataMutationType::TxMutation, 10 }, @@ -77,6 +77,7 @@ constexpr FuzzerTxDataMutationConfig FUZZER_TX_DATA_MUTATION_CONFIGURATION = Fuz { FuzzerTxDataMutationType::ContractClassMutation, 1 }, { FuzzerTxDataMutationType::ContractInstanceMutation, 1 }, { FuzzerTxDataMutationType::GlobalVariablesMutation, 4 }, + { FuzzerTxDataMutationType::ProtocolContractsMutation, 4 }, }); // Build bytecode and contract artifacts from fuzzer data diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/protocol_contracts.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/protocol_contracts.cpp new file mode 100644 index 000000000000..26f25f4a02f5 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/protocol_contracts.cpp @@ -0,0 +1,79 @@ +#include "barretenberg/avm_fuzzer/mutations/protocol_contracts.hpp" + +#include "barretenberg/vm2/common/aztec_constants.hpp" +#include "barretenberg/vm2/common/aztec_types.hpp" + +namespace bb::avm2::fuzzer { + +namespace { + +void update_enqueued_calls_for_protocol_contract(Tx& tx, + const AztecAddress& prev_address, + const AztecAddress& new_address) +{ + // Update setup_enqueued_calls + for (auto& call : tx.setup_enqueued_calls) { + if (call.request.contract_address == prev_address) { + call.request.contract_address = new_address; + } + } + // Update app_logic_enqueued_calls + for (auto& call : tx.app_logic_enqueued_calls) { + if (call.request.contract_address == prev_address) { + call.request.contract_address = new_address; + } + } + // Update teardown_enqueued_call + if (tx.teardown_enqueued_call.has_value() && tx.teardown_enqueued_call->request.contract_address == prev_address) { + tx.teardown_enqueued_call->request.contract_address = new_address; + } +} + +} // namespace + +void mutate_protocol_contracts(ProtocolContracts& protocol_contracts, + Tx& tx, + const std::vector& contract_addresses, + std::mt19937_64& rng) +{ + if (contract_addresses.empty()) { + return; + } + + auto choice = PROTOCOL_CONTRACTS_MUTATION_CONFIGURATION.select(rng); + switch (choice) { + case ProtocolContractsMutationOptions::Mutate: { + // Pick a random index and add a protocol contract + auto protocol_contract_index = std::uniform_int_distribution(0, MAX_PROTOCOL_CONTRACTS - 1)(rng); + auto contract_address_index = std::uniform_int_distribution(0, contract_addresses.size() - 1)(rng); + + AztecAddress derived_address = contract_addresses[contract_address_index]; + protocol_contracts.derived_addresses[protocol_contract_index] = derived_address; + + // The index of the protocol contracts array maps to canonical address. + // Add 1 because canonical addresses are 1-indexed + AztecAddress canonical_address(static_cast(protocol_contract_index + 1)); + + // todo(ilyas): there should be a more efficient way to do this + // Update any enqueued calls that reference the derived address to now use the canonical address + update_enqueued_calls_for_protocol_contract( + tx, /*prev_address=*/derived_address, /*new_address=*/canonical_address); + break; + } + case ProtocolContractsMutationOptions::Remove: { + // Pick an index, and zero it out, removing the protocol contract. It may already be zero but the fuzzer should + // figure out better mutations + size_t idx = std::uniform_int_distribution(0, MAX_PROTOCOL_CONTRACTS - 1)(rng); + AztecAddress canonical_address(static_cast(idx + 1)); + AztecAddress derived_address = protocol_contracts.derived_addresses[idx]; + // Update any enqueued calls that reference the canonical address to use the derived address + update_enqueued_calls_for_protocol_contract( + tx, /*prev_address=*/canonical_address, /*new_address=*/derived_address); + // Set the derived address to zero + protocol_contracts.derived_addresses[idx] = AztecAddress(0); + break; + } + } +} + +} // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/protocol_contracts.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/protocol_contracts.hpp new file mode 100644 index 000000000000..c95cfa2806bf --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/protocol_contracts.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "barretenberg/avm_fuzzer/common/weighted_selection.hpp" +#include "barretenberg/vm2/common/avm_io.hpp" +#include "barretenberg/vm2/common/aztec_types.hpp" + +#include + +namespace bb::avm2::fuzzer { + +enum class ProtocolContractsMutationOptions : uint8_t { + Mutate, + Remove, +}; + +using ProtocolContractsMutationConfig = WeightedSelectionConfig; + +constexpr ProtocolContractsMutationConfig PROTOCOL_CONTRACTS_MUTATION_CONFIGURATION = ProtocolContractsMutationConfig({ + { ProtocolContractsMutationOptions::Mutate, 3 }, + { ProtocolContractsMutationOptions::Remove, 1 }, +}); + +void mutate_protocol_contracts(bb::avm2::ProtocolContracts& protocol_contracts, + bb::avm2::Tx& tx, + const std::vector& contract_addresses, + std::mt19937_64& rng); + +} // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp index f9d3ee0b57fc..a369048f2073 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp @@ -9,9 +9,8 @@ namespace bb::avm2::fuzzer { // Fee bounds for mutation. -// MIN_FEE must be >= 1 to prevent underflow in compute_effective_gas_fees, since -// global_variables.gas_fees is hardcoded to {1, 1}. This can change once we enable -// smart mutations of global variables that maintain the invariant max_fees_per_gas >= gas_fees. +// MIN_FEE must be >= 1 to prevent underflow in compute_effective_gas_fees. +// The invariant max_fees_per_gas >= gas_fees is enforced in fuzzer_lib.cpp after mutations. constexpr uint128_t MIN_FEE = 1; constexpr uint128_t MAX_FEE = 1000; // diff --git a/yarn-project/simulator/src/public/fuzzing/avm_fuzzer_simulator.ts b/yarn-project/simulator/src/public/fuzzing/avm_fuzzer_simulator.ts index bac801cd87ad..a0eb39022a95 100644 --- a/yarn-project/simulator/src/public/fuzzing/avm_fuzzer_simulator.ts +++ b/yarn-project/simulator/src/public/fuzzing/avm_fuzzer_simulator.ts @@ -4,6 +4,7 @@ import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_LOGS_PER_TX, + MAX_PROTOCOL_CONTRACTS, } from '@aztec/constants'; import { padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -20,7 +21,16 @@ import { PrivateLog } from '@aztec/stdlib/logs'; import { ScopedL2ToL1Message } from '@aztec/stdlib/messaging'; import { ChonkProof } from '@aztec/stdlib/proofs'; import { MerkleTreeId, type MerkleTreeWriteOperations, PublicDataTreeLeaf } from '@aztec/stdlib/trees'; -import { BlockHeader, GlobalVariables, HashedValues, Tx, TxConstantData, TxContext, TxHash } from '@aztec/stdlib/tx'; +import { + BlockHeader, + GlobalVariables, + HashedValues, + ProtocolContracts, + Tx, + TxConstantData, + TxContext, + TxHash, +} from '@aztec/stdlib/tx'; import type { NativeWorldStateService } from '@aztec/world-state'; import { BaseAvmSimulationTester } from '../avm/fixtures/base_avm_simulation_tester.js'; @@ -42,6 +52,7 @@ export class FuzzerSimulationRequest { public readonly contractInstances: [any, any][], // Raw pairs [address, instance] public readonly publicDataWrites: any[], // Raw public data tree writes to apply before simulation public readonly noteHashes: any[], // Raw note hashes to apply before simulation + public readonly protocolContracts: ProtocolContracts, // Protocol contracts mapping from C++ ) {} static fromPlainObject(obj: any): FuzzerSimulationRequest { @@ -57,6 +68,7 @@ export class FuzzerSimulationRequest { obj.contractInstances, obj.publicDataWrites ?? [], obj.noteHashes ?? [], + ProtocolContracts.fromPlainObject(obj.protocolContracts), ); } } @@ -185,16 +197,23 @@ export class AvmFuzzerSimulator extends BaseAvmSimulationTester { merkleTrees: MerkleTreeWriteOperations, contractDataSource: SimpleContractDataSource, globals: GlobalVariables, + protocolContracts: ProtocolContracts, ) { super(contractDataSource, merkleTrees); const contractsDb = new PublicContractsDB(contractDataSource); - this.simulator = new PublicTxSimulator(merkleTrees, contractsDb, globals, { - skipFeeEnforcement: false, - collectDebugLogs: false, - collectHints: false, - collectStatistics: false, - collectCallMetadata: false, - }); + this.simulator = new PublicTxSimulator( + merkleTrees, + contractsDb, + globals, + { + skipFeeEnforcement: false, + collectDebugLogs: false, + collectHints: false, + collectStatistics: false, + collectCallMetadata: false, + }, + protocolContracts, + ); } /** @@ -203,10 +222,11 @@ export class AvmFuzzerSimulator extends BaseAvmSimulationTester { public static async create( worldStateService: NativeWorldStateService, globals: GlobalVariables, + protocolContracts: ProtocolContracts, ): Promise { const contractDataSource = new SimpleContractDataSource(); const merkleTrees = await worldStateService.fork(); - return new AvmFuzzerSimulator(merkleTrees, contractDataSource, globals); + return new AvmFuzzerSimulator(merkleTrees, contractDataSource, globals, protocolContracts); } /** @@ -234,12 +254,15 @@ export class AvmFuzzerSimulator extends BaseAvmSimulationTester { /** * Add a contract instance from C++ raw msgpack data. - * This also inserts the contract address nullifier into the nullifier tree. + * This also inserts the contract address nullifier into the nullifier tree, + * unless the address is a protocol canonical address (1-11). */ public async addContractInstanceFromCpp(rawAddress: any, rawInstance: any): Promise { const address = AztecAddress.fromPlainObject(rawAddress); const instance = contractInstanceWithAddressFromPlainObject(address, rawInstance); - await this.addContractInstance(instance); + // Protocol canonical addresses (1-11) should not have nullifiers inserted + const isProtocolCanonicalAddress = address.toBigInt() <= MAX_PROTOCOL_CONTRACTS && address.toBigInt() >= 1n; + await this.addContractInstance(instance, /* skipNullifierInsertion */ isProtocolCanonicalAddress); } /** diff --git a/yarn-project/simulator/src/public/fuzzing/avm_simulator_bin.ts b/yarn-project/simulator/src/public/fuzzing/avm_simulator_bin.ts index 423aeb9e95e0..8575ff0e261f 100644 --- a/yarn-project/simulator/src/public/fuzzing/avm_simulator_bin.ts +++ b/yarn-project/simulator/src/public/fuzzing/avm_simulator_bin.ts @@ -6,7 +6,7 @@ import { deserializeFromMessagePack, serializeWithMessagePack, } from '@aztec/stdlib/avm'; -import { GlobalVariables, TreeSnapshots } from '@aztec/stdlib/tx'; +import { GlobalVariables, ProtocolContracts, TreeSnapshots } from '@aztec/stdlib/tx'; import { NativeWorldStateService } from '@aztec/world-state'; import { createInterface } from 'readline'; @@ -57,17 +57,15 @@ async function simulateWithFuzzer( rawContractInstances: [any, any][], // Replace these when we are moving contract instances to TS rawPublicDataWrites: any[], // Public data tree writes to apply before simulation rawNoteHashes: any[], // Note hashes to apply before simulation + protocolContracts: ProtocolContracts, // Protocol contracts mapping from C++ ): Promise<{ reverted: boolean; output: Fr[]; revertReason?: string; publicInputs: AvmCircuitPublicInputs }> { const worldStateService = await openExistingWorldState(dataDir, mapSizeKb); - const simulator = await AvmFuzzerSimulator.create(worldStateService, globals); - - // Apply public data writes before simulation (e.g., for bytecode upgrades) - await simulator.applyPublicDataWrites(rawPublicDataWrites); + const simulator = await AvmFuzzerSimulator.create(worldStateService, globals, protocolContracts); await simulator.applyNoteHashes(rawNoteHashes); - // Register contract classes from C++ + // Register contract classes from C++ (must happen before public data writes to match C++ order) for (const rawClass of rawContractClasses) { await simulator.addContractClassFromCpp(rawClass); } @@ -77,6 +75,10 @@ async function simulateWithFuzzer( await simulator.addContractInstanceFromCpp(rawAddress, rawInstance); } + // Apply public data writes after contract registration (e.g., for bytecode upgrades) + // This must happen last to match C++ setup_fuzzer_state ordering + await simulator.applyPublicDataWrites(rawPublicDataWrites); + const result = await simulator.simulate(txHint); const output = result @@ -108,6 +110,7 @@ async function execute(base64Line: string): Promise { request.contractInstances, request.publicDataWrites, request.noteHashes, + request.protocolContracts, ); // Serialize the result to msgpack and encode it in base64 for output diff --git a/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.ts b/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.ts index d34d52229b93..0dd48ccaf342 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator/public_tx_simulator.ts @@ -10,6 +10,7 @@ import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees'; import { type GlobalVariables, NestedProcessReturnValues, + ProtocolContracts, PublicCallRequestWithCalldata, Tx, TxExecutionPhase, @@ -85,6 +86,7 @@ export class PublicTxSimulator implements PublicTxSimulatorInterface { protected contractsDB: PublicContractsDB, protected globalVariables: GlobalVariables, config?: Partial, + protected protocolContracts: ProtocolContracts = ProtocolContractsList, ) { this.config = PublicSimulatorConfig.from(config ?? {}); this.log = createLogger(`simulator:public_tx_simulator`); @@ -103,7 +105,7 @@ export class PublicTxSimulator implements PublicTxSimulatorInterface { const hints = new AvmExecutionHints( this.globalVariables, AvmTxHint.fromTx(tx, this.globalVariables.gasFees), - ProtocolContractsList, // imported from file + this.protocolContracts, ); const hintingMerkleTree = await HintingMerkleWriteOperations.create(this.merkleTree, hints); const hintingTreesDB = new PublicTreesDB(hintingMerkleTree); @@ -114,7 +116,7 @@ export class PublicTxSimulator implements PublicTxSimulatorInterface { hintingContractsDB, tx, this.globalVariables, - ProtocolContractsList, // imported from file + this.protocolContracts, this.config.proverId, ); diff --git a/yarn-project/simulator/src/public/state_manager/state_manager.ts b/yarn-project/simulator/src/public/state_manager/state_manager.ts index 7fa3cc6d855f..b798c8b675a2 100644 --- a/yarn-project/simulator/src/public/state_manager/state_manager.ts +++ b/yarn-project/simulator/src/public/state_manager/state_manager.ts @@ -1,11 +1,4 @@ -import { - CANONICAL_AUTH_REGISTRY_ADDRESS, - CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS, - CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, - FEE_JUICE_ADDRESS, - MULTI_CALL_ENTRYPOINT_ADDRESS, - ROUTER_ADDRESS, -} from '@aztec/constants'; +import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, MAX_PROTOCOL_CONTRACTS } from '@aztec/constants'; import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon'; import { Fr } from '@aztec/foundation/curves/bn254'; import { jsonStringify } from '@aztec/foundation/json-rpc'; @@ -549,12 +542,5 @@ export class PublicPersistableStateManager { } function contractAddressIsCanonical(contractAddress: AztecAddress): boolean { - return ( - contractAddress.equals(AztecAddress.fromNumber(CANONICAL_AUTH_REGISTRY_ADDRESS)) || - contractAddress.equals(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS)) || - contractAddress.equals(AztecAddress.fromNumber(CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS)) || - contractAddress.equals(AztecAddress.fromNumber(MULTI_CALL_ENTRYPOINT_ADDRESS)) || - contractAddress.equals(AztecAddress.fromNumber(FEE_JUICE_ADDRESS)) || - contractAddress.equals(AztecAddress.fromNumber(ROUTER_ADDRESS)) - ); + return contractAddress.toBigInt() >= 1 && contractAddress.toBigInt() <= MAX_PROTOCOL_CONTRACTS; } From d4ff0f2fd1917faba985f7d9288a32cd20c516d4 Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Fri, 16 Jan 2026 15:09:45 +0000 Subject: [PATCH 12/15] chore(avm): analyze fuzzer corpus distribution (#19614) running `./run_fuzzer.sh analyze` outputs some statistics about the current tx corpus ``` orpus directory: ../src/barretenberg/avm_fuzzer/corpus/tx Files processed: 836 Files failed: 0 Total input programs: 6408 === Opcode Histogram === SET_32 : 48847 ######################################## SET_8 : 23209 ################### SET_16 : 11977 ########## SET_FF : 6527 ##### RETURN : 6510 ##### SET_64 : 4418 #### SET_128 : 1743 # GETENVVAR_16 : 614 # SUCCESSCOPY : 538 RETURNDATACOPY : 522 RETURNDATASIZE : 522 XOR_8 : 498 POSEIDON2PERM : 471 SSTORE : 459 EMITNOTEHASH : 453 SENDL2TOL1MSG : 448 CALLDATACOPY : 434 SUB_16 : 398 ADD_8 : 392 OR_8 : 389 XOR_16 : 378 TORADIXBE : 374 EMITUNENCRYPTEDLOG : 366 DIV_8 : 363 SUB_8 : 360 AND_8 : 358 OR_16 : 352 GETCONTRACTINSTANCE: 351 MUL_8 : 333 MUL_16 : 318 FDIV_8 : 296 ADD_16 : 291 DIV_16 : 282 SLOAD : 276 AND_16 : 274 ECADD : 241 NOT_8 : 238 EMITNULLIFIER : 231 JUMP_32 : 213 KECCAKF1600 : 209 CAST_8 : 189 STATICCALL : 187 SHA256COMPRESSION : 187 CAST_16 : 186 NOT_16 : 181 NULLIFIEREXISTS : 171 MOV_8 : 158 MOV_16 : 151 SHR_16 : 142 EQ_16 : 138 CALL : 134 SHL_16 : 130 JUMPI_32 : 125 FDIV_16 : 122 LT_16 : 120 LT_8 : 111 LTE_16 : 105 LTE_8 : 105 SHL_8 : 102 L1TOL2MSGEXISTS : 100 EQ_8 : 93 SHR_8 : 92 DEBUGLOG : 60 INTERNALRETURN : 25 INTERNALCALL : 25 NOTEHASHEXISTS : 14 REVERT_16 : 13 === Opcode Statistics === Total instructions: 118639 Unique opcodes used: 67/68 Missing opcodes (1): REVERT_8 Most common: SET_32 (48847) Least common: REVERT_16 (13) === Enqueued Calls Statistics === Setup Calls: Mean: 0.28, Median: 0.00, Mode: 0 Histogram: 0(638) 1(178) 2(10) 3(6) 4(3) 5(1) App Logic Calls: Mean: 1.09, Median: 1.00, Mode: 1 Histogram: 1(789) 2(32) 3(7) 4(6) 5(2) Teardown Calls: Mean: 0.09, Median: 0.00, Mode: 0 Histogram: 0(761) 1(75) Multi-Phase Transactions: Txs with calls in multiple phases: 249 Txs with setup + app_logic only: 174 Txs with setup + teardown only: 0 Txs with app_logic + teardown only: 51 Txs with all three phases: 24 ``` --- .../barretenberg/avm_fuzzer/CMakeLists.txt | 4 + .../avm_fuzzer/avm_tx_corpus_analyzer.cpp | 349 ++++++++++++++++++ .../src/barretenberg/avm_fuzzer/run_fuzzer.sh | 28 ++ 3 files changed, 381 insertions(+) create mode 100644 barretenberg/cpp/src/barretenberg/avm_fuzzer/avm_tx_corpus_analyzer.cpp diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/avm_fuzzer/CMakeLists.txt index c3701c0bb0f8..0f0c5502ea32 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/CMakeLists.txt @@ -34,4 +34,8 @@ if(FUZZING_AVM) # Add the harness subdirectory which will create the alu_fuzzer target add_subdirectory(harness) + + # Corpus analyzer tool (not a fuzzer, a standalone binary) + add_executable(avm_tx_corpus_analyzer avm_tx_corpus_analyzer.cpp) + target_link_libraries(avm_tx_corpus_analyzer avm_fuzzer) endif() diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/avm_tx_corpus_analyzer.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/avm_tx_corpus_analyzer.cpp new file mode 100644 index 000000000000..01fc6fb97b98 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/avm_tx_corpus_analyzer.cpp @@ -0,0 +1,349 @@ +/** + * @file avm_tx_corpus_analyzer.cpp + * @brief Analyzes the AVM fuzzer corpus to produce statistics on opcodes and enqueued calls. + * + * Usage: ./avm_tx_corpus_analyzer [corpus_path] + * corpus_path: Path to the corpus directory (default: corpus/tx relative to current dir) + */ + +#include "barretenberg/avm_fuzzer/fuzz_lib/control_flow.hpp" +#include "barretenberg/avm_fuzzer/fuzzer_lib.hpp" +#include "barretenberg/serialize/msgpack_impl.hpp" +#include "barretenberg/vm2/common/opcodes.hpp" +#include "barretenberg/vm2/simulation/lib/serialization.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; +using namespace bb::avm2; +using namespace bb::avm2::fuzzer; + +// Statistics structure for a distribution +struct Stats { + double mean = 0.0; + double median = 0.0; + size_t mode = 0; + std::map histogram; // value -> count +}; + +// Compute mean, median, mode and histogram from a vector of values +Stats compute_stats(const std::vector& values) +{ + Stats stats; + + if (values.empty()) { + return stats; + } + + // Histogram + for (size_t v : values) { + stats.histogram[v]++; + } + + // Mean + double sum = std::accumulate(values.begin(), values.end(), 0.0); + stats.mean = sum / static_cast(values.size()); + + // Median + std::vector sorted = values; + std::sort(sorted.begin(), sorted.end()); + size_t n = sorted.size(); + if (n % 2 == 0) { + stats.median = (static_cast(sorted[n / 2 - 1]) + static_cast(sorted[n / 2])) / 2.0; + } else { + stats.median = static_cast(sorted[n / 2]); + } + + // Mode (value with highest count) + size_t max_count = 0; + for (const auto& [value, count] : stats.histogram) { + if (count > max_count) { + max_count = count; + stats.mode = value; + } + } + + return stats; +} + +// Count opcodes in bytecode +void count_opcodes(const std::vector& bytecode, std::map& opcode_counts) +{ + size_t pos = 0; + while (pos < bytecode.size()) { + try { + auto instruction = simulation::deserialize_instruction(bytecode, pos); + opcode_counts[instruction.opcode]++; + pos += instruction.size_in_bytes(); + } catch (const std::exception&) { + // Invalid bytecode, stop parsing + break; + } + } +} + +// Get opcode name as string +std::string opcode_name(WireOpCode opcode) +{ + std::ostringstream oss; + oss << opcode; + return oss.str(); +} + +// Print a visual histogram bar +std::string histogram_bar(size_t count, size_t max_count, size_t max_width = 40) +{ + if (max_count == 0) { + return ""; + } + size_t bar_len = static_cast( + std::round(static_cast(count) / static_cast(max_count) * static_cast(max_width))); + return std::string(bar_len, '#'); +} + +// Print opcode histogram +void print_opcode_histogram(const std::map& opcode_counts) +{ + std::cout << "\n=== Opcode Histogram ===\n"; + + if (opcode_counts.empty()) { + std::cout << "No opcodes found.\n"; + return; + } + + // Find max count for scaling bars + size_t max_count = 0; + size_t total_instructions = 0; + for (const auto& [opcode, count] : opcode_counts) { + max_count = std::max(max_count, count); + total_instructions += count; + } + + // Find max opcode name length for alignment + size_t max_name_len = 0; + for (const auto& [opcode, count] : opcode_counts) { + max_name_len = std::max(max_name_len, opcode_name(opcode).length()); + } + + // Sort by count (descending) + std::vector> sorted_counts(opcode_counts.begin(), opcode_counts.end()); + std::sort( + sorted_counts.begin(), sorted_counts.end(), [](const auto& a, const auto& b) { return a.second > b.second; }); + + for (const auto& [opcode, count] : sorted_counts) { + std::cout << std::setw(static_cast(max_name_len)) << std::left << opcode_name(opcode) << ": " + << std::setw(8) << std::right << count << " " << histogram_bar(count, max_count) << "\n"; + } + + // Summary stats + std::cout << "\n=== Opcode Statistics ===\n"; + std::cout << "Total instructions: " << total_instructions << "\n"; + + size_t total_opcodes = static_cast(WireOpCode::LAST_OPCODE_SENTINEL); + std::cout << "Unique opcodes used: " << opcode_counts.size() << "/" << total_opcodes << "\n"; + + // Find and display missing opcodes + std::vector missing_opcodes; + for (size_t i = 0; i < total_opcodes; i++) { + auto opcode = static_cast(i); + if (opcode_counts.find(opcode) == opcode_counts.end()) { + missing_opcodes.push_back(opcode); + } + } + + if (!missing_opcodes.empty()) { + std::cout << "Missing opcodes (" << missing_opcodes.size() << "): "; + for (size_t i = 0; i < missing_opcodes.size(); i++) { + if (i > 0) { + std::cout << ", "; + } + std::cout << opcode_name(missing_opcodes[i]); + } + std::cout << "\n"; + } + + if (!sorted_counts.empty()) { + std::cout << "Most common: " << opcode_name(sorted_counts.front().first) << " (" << sorted_counts.front().second + << ")\n"; + std::cout << "Least common: " << opcode_name(sorted_counts.back().first) << " (" << sorted_counts.back().second + << ")\n"; + } +} + +// Structure to track multi-phase transaction statistics +struct MultiPhaseStats { + size_t txs_with_setup_and_app_logic = 0; + size_t txs_with_setup_and_teardown = 0; + size_t txs_with_app_logic_and_teardown = 0; + size_t txs_with_all_three_phases = 0; + size_t txs_with_multiple_phases = 0; // Any combination of 2+ phases +}; + +// Print enqueued calls statistics +void print_enqueued_calls_stats(const Stats& setup, + const Stats& app_logic, + const Stats& teardown, + const MultiPhaseStats& multi_phase) +{ + std::cout << "\n=== Enqueued Calls Statistics ===\n"; + + auto print_stats = [](const std::string& name, const Stats& s) { + std::cout << "\n" << name << ":\n"; + std::cout << " Mean: " << std::fixed << std::setprecision(2) << s.mean << ", Median: " << s.median + << ", Mode: " << s.mode << "\n"; + std::cout << " Histogram: "; + for (const auto& [value, count] : s.histogram) { + std::cout << value << "(" << count << ") "; + } + std::cout << "\n"; + }; + + print_stats("Setup Calls", setup); + print_stats("App Logic Calls", app_logic); + print_stats("Teardown Calls", teardown); + + std::cout << "\nMulti-Phase Transactions:\n"; + std::cout << " Txs with calls in multiple phases: " << multi_phase.txs_with_multiple_phases << "\n"; + std::cout << " Txs with setup + app_logic only: " << multi_phase.txs_with_setup_and_app_logic << "\n"; + std::cout << " Txs with setup + teardown only: " << multi_phase.txs_with_setup_and_teardown << "\n"; + std::cout << " Txs with app_logic + teardown only: " << multi_phase.txs_with_app_logic_and_teardown << "\n"; + std::cout << " Txs with all three phases: " << multi_phase.txs_with_all_three_phases << "\n"; +} + +int main(int argc, char** argv) +{ + // Default corpus path (relative to where we run from) + std::string corpus_dir = "corpus/tx"; + if (argc > 1) { + corpus_dir = argv[1]; + } + + // Check if corpus directory exists + if (!fs::exists(corpus_dir)) { + std::cerr << "Error: Corpus directory does not exist: " << corpus_dir << "\n"; + return 1; + } + + if (!fs::is_directory(corpus_dir)) { + std::cerr << "Error: Not a directory: " << corpus_dir << "\n"; + return 1; + } + + std::cout << "=== AVM Fuzzer Corpus Analysis ===\n"; + std::cout << "Corpus directory: " << corpus_dir << "\n"; + + // Statistics accumulators + std::map total_opcode_counts; + std::vector setup_call_counts; + std::vector app_logic_call_counts; + std::vector teardown_call_counts; + MultiPhaseStats multi_phase_stats; + size_t files_processed = 0; + size_t files_failed = 0; + size_t total_input_programs = 0; + + // Iterate over all files in the corpus directory + for (const auto& entry : fs::directory_iterator(corpus_dir)) { + if (!entry.is_regular_file()) { + continue; + } + + const auto& path = entry.path(); + + // Read file contents + std::ifstream file(path, std::ios::binary); + if (!file) { + files_failed++; + continue; + } + + std::vector buffer((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + file.close(); + + // Deserialize FuzzerTxData + FuzzerTxData tx_data; + try { + msgpack::unpack(reinterpret_cast(buffer.data()), buffer.size()).get().convert(tx_data); + } catch (const std::exception& e) { + files_failed++; + continue; + } + + files_processed++; + + // Count enqueued calls + size_t setup_count = tx_data.tx.setup_enqueued_calls.size(); + size_t app_logic_count = tx_data.tx.app_logic_enqueued_calls.size(); + size_t teardown_count = tx_data.tx.teardown_enqueued_call.has_value() ? 1 : 0; + + setup_call_counts.push_back(setup_count); + app_logic_call_counts.push_back(app_logic_count); + teardown_call_counts.push_back(teardown_count); + + // Track multi-phase statistics + bool has_setup = setup_count > 0; + bool has_app_logic = app_logic_count > 0; + bool has_teardown = teardown_count > 0; + int phases_with_calls = (has_setup ? 1 : 0) + (has_app_logic ? 1 : 0) + (has_teardown ? 1 : 0); + + if (phases_with_calls >= 2) { + multi_phase_stats.txs_with_multiple_phases++; + } + if (has_setup && has_app_logic && !has_teardown) { + multi_phase_stats.txs_with_setup_and_app_logic++; + } + if (has_setup && has_teardown && !has_app_logic) { + multi_phase_stats.txs_with_setup_and_teardown++; + } + if (has_app_logic && has_teardown && !has_setup) { + multi_phase_stats.txs_with_app_logic_and_teardown++; + } + if (has_setup && has_app_logic && has_teardown) { + multi_phase_stats.txs_with_all_three_phases++; + } + + // Process each input program and build bytecode + for (auto& fuzzer_data : tx_data.input_programs) { + total_input_programs++; + + try { + // Build bytecode using ControlFlow + ControlFlow control_flow(fuzzer_data.instruction_blocks); + for (const auto& cfg_instruction : fuzzer_data.cfg_instructions) { + control_flow.process_cfg_instruction(cfg_instruction); + } + auto bytecode = control_flow.build_bytecode(fuzzer_data.return_options); + + // Count opcodes in the bytecode + count_opcodes(bytecode, total_opcode_counts); + } catch (const std::exception&) { + // Skip invalid bytecode generation + continue; + } + } + } + + // Print summary + std::cout << "\nFiles processed: " << files_processed << "\n"; + std::cout << "Files failed: " << files_failed << "\n"; + std::cout << "Total input programs: " << total_input_programs << "\n"; + + // Print opcode histogram + print_opcode_histogram(total_opcode_counts); + + // Print enqueued calls statistics + Stats setup_stats = compute_stats(setup_call_counts); + Stats app_logic_stats = compute_stats(app_logic_call_counts); + Stats teardown_stats = compute_stats(teardown_call_counts); + print_enqueued_calls_stats(setup_stats, app_logic_stats, teardown_stats, multi_phase_stats); + + return 0; +} diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/run_fuzzer.sh b/barretenberg/cpp/src/barretenberg/avm_fuzzer/run_fuzzer.sh index 4513c2dc7030..3576f6bebf0b 100755 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/run_fuzzer.sh +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/run_fuzzer.sh @@ -11,6 +11,7 @@ show_usage() { echo " build - Build the fuzzer binary" echo " fuzz [--log] [-- args...] - Run the fuzzer (--log to tail fuzz-0.log)" echo " coverage [type] - Generate coverage report (type: html or report, default: html)" + echo " analyze - Analyze corpus and show opcode/call statistics" echo " list-targets - List all available fuzzing targets" echo "" echo "Additional fuzzer arguments can be passed after '--'. For example:" @@ -44,6 +45,33 @@ if [ "$COMMAND" = "list-targets" ]; then exit 0 fi +# Handle analyze command +if [ "$COMMAND" = "analyze" ]; then + # Get the script directory and project root + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + BARRETENBERG_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)" + CPP_DIR="$BARRETENBERG_ROOT/cpp" + BUILD_DIR="$CPP_DIR/build-fuzzing-avm" + BUILD_PRESET="fuzzing-avm" + + cd "$CPP_DIR" + + # Configure if needed + if [ ! -f "$BUILD_DIR/CMakeCache.txt" ]; then + echo "Configuring cmake..." + cmake --preset "$BUILD_PRESET" + fi + + # Build the analyzer + echo "Building avm_tx_corpus_analyzer..." + cmake --build "$BUILD_DIR" --target avm_tx_corpus_analyzer + + echo "" + # Run analyzer on tx corpus + "$BUILD_DIR/bin/avm_tx_corpus_analyzer" "$SCRIPT_DIR/corpus/tx" + exit 0 +fi + FUZZER_ALIAS=$1 shift From a811a3c40ee4d4c16a9debcf0e301cc1c6673cc2 Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Fri, 16 Jan 2026 15:13:40 +0000 Subject: [PATCH 13/15] feat(avm): fuzzer treats enqueued call size as coverage (#19615) Incentivise the fuzzer to make more enqueued calls during each run by rewarding it with coverage progress --- .../src/barretenberg/avm_fuzzer/prover.fuzzer.cpp | 12 ++++++++++++ .../cpp/src/barretenberg/avm_fuzzer/tx.fuzzer.cpp | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/prover.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/prover.fuzzer.cpp index 2dbab4d1ecfa..1ad7262a0909 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/prover.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/prover.fuzzer.cpp @@ -11,6 +11,12 @@ using namespace bb::avm2::fuzzer; +// Extra counters to guide libfuzzer towards inputs with more enqueued calls. +// Index 0 = 1 call, index 1 = 2 calls, etc. When an input has N enqueued calls, +// we increment counter[N-1], signaling new coverage to libfuzzer. +constexpr size_t MAX_ENQUEUED_CALLS_COUNTER = 32; +__attribute__((section("__libfuzzer_extra_counters"))) uint8_t enqueued_calls_counter[MAX_ENQUEUED_CALLS_COUNTER]; + extern "C" int LLVMFuzzerInitialize(int*, char***) { FuzzerWorldStateManager::initialize(); @@ -45,6 +51,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) tx_data = create_default_tx_data(context); } + // Signal coverage for number of enqueued calls to guide fuzzer towards more calls + size_t num_calls = tx_data.tx.setup_enqueued_calls.size() + tx_data.tx.app_logic_enqueued_calls.size(); + if (num_calls > 0 && num_calls <= MAX_ENQUEUED_CALLS_COUNTER) { + enqueued_calls_counter[num_calls - 1]++; + } + // Setup contracts and fund fee payer // Fuzzer state is dependent on the tx data setup_fuzzer_state(*ws_mgr, contract_db, tx_data); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/tx.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/tx.fuzzer.cpp index 5343a0b5aea5..3b2f06e664be 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/tx.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/tx.fuzzer.cpp @@ -10,6 +10,12 @@ using namespace bb::avm2::fuzzer; using namespace bb::avm2::simulation; +// Extra counters to guide libfuzzer towards inputs with more enqueued calls. +// Index 0 = 1 call, index 1 = 2 calls, etc. When an input has N enqueued calls, +// we increment counter[N-1], signaling new coverage to libfuzzer. +constexpr size_t MAX_ENQUEUED_CALLS_COUNTER = 32; +__attribute__((section("__libfuzzer_extra_counters"))) uint8_t enqueued_calls_counter[MAX_ENQUEUED_CALLS_COUNTER]; + extern "C" int LLVMFuzzerInitialize(int*, char***) { const char* simulator_path = std::getenv("AVM_SIMULATOR_BIN"); @@ -49,6 +55,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) tx_data = create_default_tx_data(context); } + // Signal coverage for number of enqueued calls to guide fuzzer towards more calls + size_t num_calls = tx_data.tx.setup_enqueued_calls.size() + tx_data.tx.app_logic_enqueued_calls.size(); + if (num_calls > 0 && num_calls <= MAX_ENQUEUED_CALLS_COUNTER) { + enqueued_calls_counter[num_calls - 1]++; + } + // Setup contracts and fund fee payer setup_fuzzer_state(*ws_mgr, contract_db, tx_data); fund_fee_payer(*ws_mgr, tx_data.tx); From a50c937c52e8546e6a2abfdfe79bf4fe433d7914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Fri, 16 Jan 2026 16:49:05 +0100 Subject: [PATCH 14/15] refactor(avm): Refactor calldata copy and return data copy fuzzing (#19666) Resolves https://linear.app/aztec-labs/issue/AVM-195/refactor-returndatasize-and-returndatacopy-fuzzing --- .../avm_fuzzer/fuzz_lib/instruction.hpp | 46 ++++--- .../avm_fuzzer/fuzz_lib/program_block.cpp | 76 +++++------ .../avm_fuzzer/fuzz_lib/program_block.hpp | 4 +- .../avm_fuzzer/mutations/configuration.hpp | 38 +++--- .../mutations/instructions/instruction.cpp | 123 +++++++++++++----- .../mutations/instructions/instruction.hpp | 7 +- 6 files changed, 178 insertions(+), 116 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp index 1729dec60ec5..8b2698ec7e68 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/instruction.hpp @@ -508,15 +508,11 @@ struct NOTEHASHEXISTS_Instruction { MSGPACK_FIELDS(notehash_address, leaf_index_address, result_address); }; -/// @brief CALLDATACOPY: M[dstOffset:dstOffset+M[copySizeOffset]] = -/// calldata[M[cdStartOffset]:M[cdStartOffset]+M[copySizeOffset]] struct CALLDATACOPY_Instruction { + ParamRef copy_size_address; + ParamRef cd_offset_address; AddressRef dst_address; - uint8_t copy_size; - AddressRef copy_size_address; // where copy size will be stored - uint16_t cd_start; - AddressRef cd_start_address; // where cd start will be stored - MSGPACK_FIELDS(dst_address, copy_size, copy_size_address, cd_start, cd_start_address); + MSGPACK_FIELDS(copy_size_address, cd_offset_address, dst_address); }; struct SENDL2TOL1MSG_Instruction { @@ -552,17 +548,17 @@ struct CALL_Instruction { is_static_call); }; -/// @brief: RETURNDATASIZE + RETURNDATACOPY: -// M[copySizeOffset] = nestedReturndata.size() -// M[dstOffset:dstOffset+M[copySizeOffset]] = -/// nestedReturndata[M[rdStartOffset]:M[rdStartOffset]+M[copySizeOffset]] -/// All addresses are DIRECT -struct RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction { - uint16_t copy_size_offset; - uint16_t dst_address; - uint32_t rd_start; - uint16_t rd_start_offset; - MSGPACK_FIELDS(copy_size_offset, dst_address, rd_start, rd_start_offset); +struct RETURNDATASIZE_Instruction { + AddressRef dst_address; + MSGPACK_FIELDS(dst_address); +}; + +struct RETURNDATACOPY_Instruction { + ParamRef copy_size_address; + ParamRef rd_offset_address; + AddressRef dst_address; + + MSGPACK_FIELDS(copy_size_address, rd_offset_address, dst_address); }; struct GETCONTRACTINSTANCE_Instruction { @@ -685,7 +681,8 @@ using FuzzInstruction = std::variant(arg.copy_size) << " " - << arg.copy_size_address << " " << arg.cd_start_address << " " << arg.cd_start_address; + os << "CALLDATACOPY_Instruction " << arg.copy_size_address << " " << arg.cd_offset_address << " " + << arg.dst_address; }, [&](SENDL2TOL1MSG_Instruction arg) { os << "SENDL2TOL1MSG_Instruction " << arg.recipient << " " << arg.recipient_address << " " @@ -882,9 +879,10 @@ inline std::ostream& operator<<(std::ostream& os, const FuzzInstruction& instruc << arg.contract_address_address << " " << arg.calldata_size_address << " " << arg.calldata_address << " " << arg.is_static_call; }, - [&](RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction arg) { - os << "RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction " << arg.copy_size_offset << " " - << arg.dst_address << " " << arg.rd_start_offset; + [&](RETURNDATASIZE_Instruction arg) { os << "RETURNDATASIZE_Instruction " << arg.dst_address; }, + [&](RETURNDATACOPY_Instruction arg) { + os << "RETURNDATACOPY_Instruction " << arg.copy_size_address << " " << arg.rd_offset_address << " " + << arg.dst_address; }, [&](ECADD_Instruction arg) { os << "ECADD_Instruction " << arg.p1_x << " " << arg.p1_y << " " << arg.p1_infinite << " " << arg.p2_x diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp index 02354a2c1757..18c03379e843 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.cpp @@ -1103,39 +1103,23 @@ void ProgramBlock::process_calldatacopy_instruction(CALLDATACOPY_Instruction ins #ifdef DISABLE_CALLDATACOPY_INSTRUCTION return; #endif - auto copy_size_set_instruction = SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32, - .result_address = instruction.copy_size_address, - .value = instruction.copy_size }; - this->process_set_32_instruction(copy_size_set_instruction); - auto cd_start_set_instruction = SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32, - .result_address = instruction.cd_start_address, - .value = instruction.cd_start }; - this->process_set_32_instruction(cd_start_set_instruction); - // CALLDATACOPY expects UINT16 operands for all three addresses auto copy_size_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.copy_size_address); - auto cd_start_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.cd_start_address); + auto cd_offset_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.cd_offset_address); auto dst_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.dst_address); - if (!copy_size_address_operand.has_value() || !cd_start_address_operand.has_value() || + if (!copy_size_address_operand.has_value() || !cd_offset_address_operand.has_value() || !dst_address_operand.has_value()) { return; } preprocess_memory_addresses(copy_size_address_operand.value().first); - preprocess_memory_addresses(cd_start_address_operand.value().first); + preprocess_memory_addresses(cd_offset_address_operand.value().first); preprocess_memory_addresses(dst_address_operand.value().first); auto calldatacopy_instruction = bb::avm2::testing::InstructionBuilder(bb::avm2::WireOpCode::CALLDATACOPY) .operand(copy_size_address_operand.value().second) - .operand(cd_start_address_operand.value().second) + .operand(cd_offset_address_operand.value().second) .operand(dst_address_operand.value().second) .build(); instructions.push_back(calldatacopy_instruction); - - // setting calldata_addr to u32 to avoid overflows - uint32_t calldata_base_offset = dst_address_operand.value().first.absolute_address; - auto loop_upper_bound = static_cast(std::min((calldata_base_offset) + instruction.copy_size, 65535U)); - for (uint32_t calldata_addr = calldata_base_offset; calldata_addr < loop_upper_bound; calldata_addr++) { - memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, calldata_addr); - } } void ProgramBlock::process_sendl2tol1msg_instruction(SENDL2TOL1MSG_Instruction instruction) @@ -1224,29 +1208,44 @@ void ProgramBlock::process_call_instruction(CALL_Instruction instruction) instructions.push_back(call_instruction); } -void ProgramBlock::process_returndatasize_with_returndatacopy_instruction( - RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction instruction) +void ProgramBlock::process_returndatasize_instruction(RETURNDATASIZE_Instruction instruction) { -#ifdef DISABLE_RETURNDATASIZE_WITH_RETURNDATACOPY_INSTRUCTION +#ifdef DISABLE_RETURNDATASIZE_INSTRUCTION return; #endif + auto dst_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.dst_address); + if (!dst_address_operand.has_value()) { + return; + } + preprocess_memory_addresses(dst_address_operand.value().first); auto returndatasize_instruction = bb::avm2::testing::InstructionBuilder(bb::avm2::WireOpCode::RETURNDATASIZE) - .operand(instruction.copy_size_offset) + .operand(dst_address_operand.value().second) .build(); instructions.push_back(returndatasize_instruction); - auto rd_start_set_instruction = - SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32, - .result_address = - AddressRef{ .address = instruction.rd_start_offset, .mode = AddressingMode::Direct }, - .value = instruction.rd_start }; - this->process_set_32_instruction(rd_start_set_instruction); + memory_manager.set_memory_address(bb::avm2::MemoryTag::U32, dst_address_operand.value().first.absolute_address); +} + +void ProgramBlock::process_returndatacopy_instruction(RETURNDATACOPY_Instruction instruction) +{ +#ifdef DISABLE_RETURNDATACOPY_INSTRUCTION + return; +#endif + auto copy_size_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.copy_size_address); + auto rd_offset_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.rd_offset_address); + auto dst_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.dst_address); + if (!copy_size_address_operand.has_value() || !rd_offset_address_operand.has_value() || + !dst_address_operand.has_value()) { + return; + } + preprocess_memory_addresses(copy_size_address_operand.value().first); + preprocess_memory_addresses(rd_offset_address_operand.value().first); + preprocess_memory_addresses(dst_address_operand.value().first); + auto returndatacopy_instruction = bb::avm2::testing::InstructionBuilder(bb::avm2::WireOpCode::RETURNDATACOPY) - .operand(instruction.copy_size_offset) - .operand(instruction.rd_start_offset) - .operand(instruction.dst_address) + .operand(copy_size_address_operand.value().second) + .operand(rd_offset_address_operand.value().second) + .operand(dst_address_operand.value().second) .build(); - // TODO(defkit): function can return more than one value :D - memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, instruction.dst_address); instructions.push_back(returndatacopy_instruction); } @@ -1726,8 +1725,11 @@ void ProgramBlock::process_instruction(FuzzInstruction instruction) return this->process_emitunencryptedlog_instruction(instruction); }, [this](CALL_Instruction instruction) { return this->process_call_instruction(instruction); }, - [this](RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction instruction) { - return this->process_returndatasize_with_returndatacopy_instruction(instruction); + [this](RETURNDATASIZE_Instruction instruction) { + return this->process_returndatasize_instruction(instruction); + }, + [this](RETURNDATACOPY_Instruction instruction) { + return this->process_returndatacopy_instruction(instruction); }, [this](GETCONTRACTINSTANCE_Instruction instruction) { return this->process_getcontractinstance_instruction(instruction); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.hpp index e4adf49a53cd..2909041909bb 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/program_block.hpp @@ -106,8 +106,8 @@ class ProgramBlock { void process_sendl2tol1msg_instruction(SENDL2TOL1MSG_Instruction instruction); void process_emitunencryptedlog_instruction(EMITUNENCRYPTEDLOG_Instruction instruction); void process_call_instruction(CALL_Instruction instruction); - void process_returndatasize_with_returndatacopy_instruction( - RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction instruction); + void process_returndatasize_instruction(RETURNDATASIZE_Instruction instruction); + void process_returndatacopy_instruction(RETURNDATACOPY_Instruction instruction); void process_getcontractinstance_instruction(GETCONTRACTINSTANCE_Instruction instruction); void process_successcopy_instruction(SUCCESSCOPY_Instruction instruction); void process_ecadd_instruction(ECADD_Instruction instruction); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp index 27f2e2b4cb51..1983a98e03fe 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp @@ -265,7 +265,8 @@ enum class InstructionGenerationOptions { SENDL2TOL1MSG, EMITUNENCRYPTEDLOG, CALL, - RETURNDATASIZE_WITH_RETURNDATACOPY, + RETURNDATASIZE, + RETURNDATACOPY, GETCONTRACTINSTANCE, SUCCESSCOPY, ECADD, @@ -276,7 +277,7 @@ enum class InstructionGenerationOptions { DEBUGLOG, }; -using InstructionGenerationConfig = WeightedSelectionConfig; +using InstructionGenerationConfig = WeightedSelectionConfig; constexpr InstructionGenerationConfig BASIC_INSTRUCTION_GENERATION_CONFIGURATION = InstructionGenerationConfig({ { InstructionGenerationOptions::ADD_8, 1 }, @@ -329,7 +330,8 @@ constexpr InstructionGenerationConfig BASIC_INSTRUCTION_GENERATION_CONFIGURATION { InstructionGenerationOptions::SENDL2TOL1MSG, 1 }, { InstructionGenerationOptions::EMITUNENCRYPTEDLOG, 1 }, { InstructionGenerationOptions::CALL, 1 }, - { InstructionGenerationOptions::RETURNDATASIZE_WITH_RETURNDATACOPY, 1 }, + { InstructionGenerationOptions::RETURNDATASIZE, 1 }, + { InstructionGenerationOptions::RETURNDATACOPY, 1 }, { InstructionGenerationOptions::GETCONTRACTINSTANCE, 1 }, { InstructionGenerationOptions::SUCCESSCOPY, 1 }, { InstructionGenerationOptions::ECADD, 1 }, @@ -401,15 +403,17 @@ constexpr NoteHashExistsMutationConfig BASIC_NOTEHASHEXISTS_MUTATION_CONFIGURATI { NoteHashExistsMutationOptions::result_address, 1 }, }); -enum class CalldataCopyMutationOptions { dst_address, copy_size, copy_size_address, cd_start, cd_start_address }; -using CalldataCopyMutationConfig = WeightedSelectionConfig; +enum class CalldataCopyMutationOptions { + copy_size_address, + cd_offset_address, + dst_address, +}; +using CalldataCopyMutationConfig = WeightedSelectionConfig; constexpr CalldataCopyMutationConfig BASIC_CALLDATACOPY_MUTATION_CONFIGURATION = CalldataCopyMutationConfig({ - { CalldataCopyMutationOptions::dst_address, 1 }, - { CalldataCopyMutationOptions::copy_size, 1 }, { CalldataCopyMutationOptions::copy_size_address, 1 }, - { CalldataCopyMutationOptions::cd_start, 1 }, - { CalldataCopyMutationOptions::cd_start_address, 1 }, + { CalldataCopyMutationOptions::cd_offset_address, 1 }, + { CalldataCopyMutationOptions::dst_address, 1 }, }); enum class SendL2ToL1MsgMutationOptions { recipient, recipient_address, content, content_address }; @@ -452,16 +456,14 @@ constexpr CallMutationConfig BASIC_CALL_MUTATION_CONFIGURATION = CallMutationCon { CallMutationOptions::is_static_call, 1 }, }); -enum class ReturndatasizeWithReturndatacopyMutationOptions { copy_size_offset, dst_address, rd_start_offset }; -using ReturndatasizeWithReturndatacopyMutationConfig = - WeightedSelectionConfig; +enum class ReturndataCopyMutationOptions { copy_size_address, rd_offset_address, dst_address }; +using ReturndataCopyMutationConfig = WeightedSelectionConfig; -constexpr ReturndatasizeWithReturndatacopyMutationConfig - BASIC_RETURNDATASIZE_WITH_RETURNDATACOPY_MUTATION_CONFIGURATION = ReturndatasizeWithReturndatacopyMutationConfig({ - { ReturndatasizeWithReturndatacopyMutationOptions::copy_size_offset, 1 }, - { ReturndatasizeWithReturndatacopyMutationOptions::dst_address, 1 }, - { ReturndatasizeWithReturndatacopyMutationOptions::rd_start_offset, 1 }, - }); +constexpr ReturndataCopyMutationConfig BASIC_RETURNDATACOPY_MUTATION_CONFIGURATION = ReturndataCopyMutationConfig({ + { ReturndataCopyMutationOptions::copy_size_address, 1 }, + { ReturndataCopyMutationOptions::rd_offset_address, 1 }, + { ReturndataCopyMutationOptions::dst_address, 1 }, +}); enum class GetContractInstanceMutationOptions { contract_address_address, dst_address, member_enum }; using GetContractInstanceMutationConfig = WeightedSelectionConfig; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp index 81a3c55f6439..f3a598a33da0 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.cpp @@ -240,11 +240,7 @@ std::vector InstructionMutator::generate_instruction(std::mt199 case InstructionGenerationOptions::NOTEHASHEXISTS: return generate_notehashexists_instruction(rng); case InstructionGenerationOptions::CALLDATACOPY: - return { CALLDATACOPY_Instruction{ .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND), - .copy_size = generate_random_uint8(rng), - .copy_size_address = generate_address_ref(rng, MAX_16BIT_OPERAND), - .cd_start = generate_random_uint16(rng), - .cd_start_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } }; + return generate_calldatacopy_instruction(rng); case InstructionGenerationOptions::SENDL2TOL1MSG: return { SENDL2TOL1MSG_Instruction{ .recipient = generate_random_field(rng), .recipient_address = generate_address_ref(rng, MAX_16BIT_OPERAND), @@ -254,10 +250,10 @@ std::vector InstructionMutator::generate_instruction(std::mt199 return generate_emitunencryptedlog_instruction(rng); case InstructionGenerationOptions::CALL: return generate_call_instruction(rng); - case InstructionGenerationOptions::RETURNDATASIZE_WITH_RETURNDATACOPY: - return { RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction{ .copy_size_offset = generate_random_uint16(rng), - .dst_address = generate_random_uint16(rng), - .rd_start_offset = generate_random_uint16(rng) } }; + case InstructionGenerationOptions::RETURNDATASIZE: + return generate_returndatasize_instruction(rng); + case InstructionGenerationOptions::RETURNDATACOPY: + return generate_returndatacopy_instruction(rng); case InstructionGenerationOptions::GETCONTRACTINSTANCE: return generate_getcontractinstance_instruction(rng); case InstructionGenerationOptions::SUCCESSCOPY: @@ -336,9 +332,8 @@ void InstructionMutator::mutate_instruction(FuzzInstruction& instruction, std::m [&rng, this](SENDL2TOL1MSG_Instruction& instr) { mutate_sendl2tol1msg_instruction(instr, rng); }, [&rng, this](EMITUNENCRYPTEDLOG_Instruction& instr) { mutate_emitunencryptedlog_instruction(instr, rng); }, [&rng, this](CALL_Instruction& instr) { mutate_call_instruction(instr, rng); }, - [&rng, this](RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction& instr) { - mutate_returndatasize_with_returndatacopy_instruction(instr, rng); - }, + [&rng, this](RETURNDATASIZE_Instruction& instr) { mutate_returndatasize_instruction(instr, rng); }, + [&rng, this](RETURNDATACOPY_Instruction& instr) { mutate_returndatacopy_instruction(instr, rng); }, [&rng, this](GETCONTRACTINSTANCE_Instruction& instr) { mutate_getcontractinstance_instruction(instr, rng); }, @@ -907,6 +902,69 @@ std::vector InstructionMutator::generate_notehashexists_instruc return instructions; } +std::vector InstructionMutator::generate_returndatasize_instruction(std::mt19937_64& rng) +{ + return { RETURNDATASIZE_Instruction{ .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } }; +} + +std::vector InstructionMutator::generate_returndatacopy_instruction(std::mt19937_64& rng) +{ + bool use_backfill = std::uniform_int_distribution(0, 4)(rng) != 0; + if (!use_backfill) { + return { RETURNDATACOPY_Instruction{ .copy_size_address = generate_variable_ref(rng), + .rd_offset_address = generate_variable_ref(rng), + .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } }; + } + std::vector instructions; + instructions.reserve(3); + auto copy_size_address = generate_address_ref(rng, MAX_16BIT_OPERAND); + instructions.push_back(SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32, + .result_address = copy_size_address, + // We generate small sizes so we fail less often due to gas + // Mutations might change this to a larger value. + .value = generate_random_uint8(rng) }); + + auto rd_offset_address = generate_address_ref(rng, MAX_16BIT_OPERAND); + instructions.push_back(SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32, + .result_address = rd_offset_address, + .value = generate_random_uint8(rng) }); + + instructions.push_back(RETURNDATACOPY_Instruction{ .copy_size_address = copy_size_address, + .rd_offset_address = rd_offset_address, + .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) }); + + return instructions; +} + +std::vector InstructionMutator::generate_calldatacopy_instruction(std::mt19937_64& rng) +{ + bool use_backfill = std::uniform_int_distribution(0, 4)(rng) != 0; + if (!use_backfill) { + return { CALLDATACOPY_Instruction{ .copy_size_address = generate_variable_ref(rng), + .cd_offset_address = generate_variable_ref(rng), + .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } }; + } + std::vector instructions; + instructions.reserve(3); + auto copy_size_address = generate_address_ref(rng, MAX_16BIT_OPERAND); + instructions.push_back(SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32, + .result_address = copy_size_address, + // We generate small sizes so we fail less often due to gas + // Mutations might change this to a larger value. + .value = generate_random_uint8(rng) }); + + auto cd_offset_address = generate_address_ref(rng, MAX_16BIT_OPERAND); + instructions.push_back(SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32, + .result_address = cd_offset_address, + .value = generate_random_uint8(rng) }); + + instructions.push_back(CALLDATACOPY_Instruction{ .copy_size_address = copy_size_address, + .cd_offset_address = cd_offset_address, + .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) }); + + return instructions; +} + void InstructionMutator::mutate_param_ref(ParamRef& param, std::mt19937_64& rng, std::optional default_tag, @@ -1259,20 +1317,14 @@ void InstructionMutator::mutate_calldatacopy_instruction(CALLDATACOPY_Instructio { CalldataCopyMutationOptions option = BASIC_CALLDATACOPY_MUTATION_CONFIGURATION.select(rng); switch (option) { - case CalldataCopyMutationOptions::dst_address: - mutate_address_ref(instruction.dst_address, rng, MAX_16BIT_OPERAND); - break; - case CalldataCopyMutationOptions::copy_size: - mutate_uint8_t(instruction.copy_size, rng, BASIC_UINT8_T_MUTATION_CONFIGURATION); - break; case CalldataCopyMutationOptions::copy_size_address: - mutate_address_ref(instruction.copy_size_address, rng, MAX_16BIT_OPERAND); + mutate_param_ref(instruction.copy_size_address, rng, MemoryTag::U32, MAX_16BIT_OPERAND); break; - case CalldataCopyMutationOptions::cd_start: - mutate_uint16_t(instruction.cd_start, rng, BASIC_UINT16_T_MUTATION_CONFIGURATION); + case CalldataCopyMutationOptions::cd_offset_address: + mutate_param_ref(instruction.cd_offset_address, rng, MemoryTag::U32, MAX_16BIT_OPERAND); break; - case CalldataCopyMutationOptions::cd_start_address: - mutate_address_ref(instruction.cd_start_address, rng, MAX_16BIT_OPERAND); + case CalldataCopyMutationOptions::dst_address: + mutate_address_ref(instruction.dst_address, rng, MAX_16BIT_OPERAND); break; } } @@ -1338,20 +1390,25 @@ void InstructionMutator::mutate_call_instruction(CALL_Instruction& instruction, } } -void InstructionMutator::mutate_returndatasize_with_returndatacopy_instruction( - RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction& instruction, std::mt19937_64& rng) +void InstructionMutator::mutate_returndatasize_instruction(RETURNDATASIZE_Instruction& instruction, + std::mt19937_64& rng) { - ReturndatasizeWithReturndatacopyMutationOptions option = - BASIC_RETURNDATASIZE_WITH_RETURNDATACOPY_MUTATION_CONFIGURATION.select(rng); + mutate_address_ref(instruction.dst_address, rng, MAX_16BIT_OPERAND); +} + +void InstructionMutator::mutate_returndatacopy_instruction(RETURNDATACOPY_Instruction& instruction, + std::mt19937_64& rng) +{ + ReturndataCopyMutationOptions option = BASIC_RETURNDATACOPY_MUTATION_CONFIGURATION.select(rng); switch (option) { - case ReturndatasizeWithReturndatacopyMutationOptions::copy_size_offset: - mutate_uint16_t(instruction.copy_size_offset, rng, BASIC_UINT16_T_MUTATION_CONFIGURATION); + case ReturndataCopyMutationOptions::copy_size_address: + mutate_param_ref(instruction.copy_size_address, rng, MemoryTag::U32, MAX_16BIT_OPERAND); break; - case ReturndatasizeWithReturndatacopyMutationOptions::dst_address: - mutate_uint16_t(instruction.dst_address, rng, BASIC_UINT16_T_MUTATION_CONFIGURATION); + case ReturndataCopyMutationOptions::rd_offset_address: + mutate_param_ref(instruction.rd_offset_address, rng, MemoryTag::U32, MAX_16BIT_OPERAND); break; - case ReturndatasizeWithReturndatacopyMutationOptions::rd_start_offset: - mutate_uint16_t(instruction.rd_start_offset, rng, BASIC_UINT16_T_MUTATION_CONFIGURATION); + case ReturndataCopyMutationOptions::dst_address: + mutate_address_ref(instruction.dst_address, rng, MAX_16BIT_OPERAND); break; } } diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.hpp index e07bb9c53e58..2e77a383abbc 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/instructions/instruction.hpp @@ -47,6 +47,9 @@ class InstructionMutator { std::vector generate_call_instruction(std::mt19937_64& rng); std::vector generate_getcontractinstance_instruction(std::mt19937_64& rng); std::vector generate_notehashexists_instruction(std::mt19937_64& rng); + std::vector generate_returndatasize_instruction(std::mt19937_64& rng); + std::vector generate_returndatacopy_instruction(std::mt19937_64& rng); + std::vector generate_calldatacopy_instruction(std::mt19937_64& rng); void mutate_variable_ref(VariableRef& variable, std::mt19937_64& rng, std::optional default_tag); void mutate_address_ref(AddressRef& address, std::mt19937_64& rng, uint32_t max_operand_value); @@ -82,8 +85,8 @@ class InstructionMutator { void mutate_sendl2tol1msg_instruction(SENDL2TOL1MSG_Instruction& instruction, std::mt19937_64& rng); void mutate_emitunencryptedlog_instruction(EMITUNENCRYPTEDLOG_Instruction& instruction, std::mt19937_64& rng); void mutate_call_instruction(CALL_Instruction& instruction, std::mt19937_64& rng); - void mutate_returndatasize_with_returndatacopy_instruction( - RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction& instruction, std::mt19937_64& rng); + void mutate_returndatasize_instruction(RETURNDATASIZE_Instruction& instruction, std::mt19937_64& rng); + void mutate_returndatacopy_instruction(RETURNDATACOPY_Instruction& instruction, std::mt19937_64& rng); void mutate_getcontractinstance_instruction(GETCONTRACTINSTANCE_Instruction& instruction, std::mt19937_64& rng); void mutate_successcopy_instruction(SUCCESSCOPY_Instruction& instruction, std::mt19937_64& rng); void mutate_ecadd_instruction(ECADD_Instruction& instruction, std::mt19937_64& rng); From c4b054064ffce273b4a80119586b23c7f7b2b48e Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Fri, 16 Jan 2026 15:51:05 +0000 Subject: [PATCH 15/15] feat(avm): boundary values for mutations (#19617) Some claude-suggested boundary conditions for the fuzzer --- .../avm_fuzzer/fuzz_lib/fuzzer_context.cpp | 5 + .../avm_fuzzer/fuzz_lib/fuzzer_context.hpp | 2 + .../barretenberg/avm_fuzzer/fuzzer_lib.cpp | 25 ++--- .../barretenberg/avm_fuzzer/fuzzer_lib.hpp | 4 +- .../mutations/basic_types/field.cpp | 48 +++++++++ .../mutations/basic_types/uint_mutations.hpp | 100 ++++++++++++++++++ .../avm_fuzzer/mutations/configuration.hpp | 14 ++- .../avm_fuzzer/mutations/tx_data.cpp | 29 +++-- .../avm_fuzzer/mutations/tx_data.hpp | 11 +- .../tx_types/public_call_request.cpp | 2 +- 10 files changed, 205 insertions(+), 35 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp index c2b9121b17b3..b69cccff3231 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.cpp @@ -86,6 +86,11 @@ void FuzzerContext::set_existing_note_hashes(std::span contract_addresses) +{ + contract_addresses_.assign(contract_addresses.begin(), contract_addresses.end()); +} + void FuzzerContext::reset() { contract_addresses_.clear(); diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.hpp index 4c02d222cda5..4a95ba29ef4c 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/fuzzer_context.hpp @@ -57,6 +57,8 @@ class FuzzerContext { void set_existing_note_hashes(std::span> note_hashes); + void set_existing_contract_addresses(std::span contract_addresses); + private: std::vector contract_addresses_; std::unique_ptr contract_db_; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp index 0629a997fd7c..7c5c87f5be44 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp @@ -322,12 +322,6 @@ size_t mutate_tx_data(FuzzerContext& context, populate_context_from_tx_data(context, tx_data); - // Mutate the fuzzer data multiple times for better bytecode variety - auto num_mutations = std::uniform_int_distribution(1, 5)(rng); - for (uint8_t i = 0; i < num_mutations; i++) { - mutate_fuzzer_data_vec(context, tx_data.input_programs, rng, 64); - } - // Build up bytecodes, contract classes and instances from the fuzzer data tx_data.contract_classes.clear(); tx_data.contract_instances.clear(); @@ -357,8 +351,8 @@ size_t mutate_tx_data(FuzzerContext& context, // Ensure all enqueued calls have valid contract addresses (not placeholders) // We may add more advanced mutation to change contract addresses later, right now we just ensure they are valid - auto idx_dist = std::uniform_int_distribution(0, contract_addresses.size() - 1); if (!contract_addresses.empty()) { + auto idx_dist = std::uniform_int_distribution(0, contract_addresses.size() - 1); for (auto& call : tx_data.tx.setup_enqueued_calls) { call.request.contract_address = contract_addresses[idx_dist(rng)]; } @@ -371,23 +365,22 @@ size_t mutate_tx_data(FuzzerContext& context, FuzzerTxDataMutationType mutation_choice = FUZZER_TX_DATA_MUTATION_CONFIGURATION.select(rng); switch (mutation_choice) { + case FuzzerTxDataMutationType::TxFuzzerDataMutation: + mutate_fuzzer_data_vec(context, tx_data.input_programs, rng, 64); + break; case FuzzerTxDataMutationType::TxMutation: mutate_tx(tx_data.tx, contract_addresses, rng); break; - case FuzzerTxDataMutationType::BytecodeMutation: { - // Mutate bytecode and append public data writes for world state setup + case FuzzerTxDataMutationType::BytecodeMutation: mutate_bytecode(tx_data.contract_classes, tx_data.contract_instances, tx_data.contract_addresses, tx_data.public_data_writes, rng); break; - } + case FuzzerTxDataMutationType::ContractClassMutation: mutate_contract_classes(tx_data.contract_classes, tx_data.contract_instances, tx_data.contract_addresses, rng); - // The fuzzer (like the AVM) assumes that all triplets of contract classes, instances and addresses are in sync - // So when we mutate contract classes, we also need to update the corresponding artifacts - break; case FuzzerTxDataMutationType::ContractInstanceMutation: mutate_contract_instances(tx_data.contract_instances, tx_data.contract_addresses, rng); @@ -413,8 +406,8 @@ size_t mutate_tx_data(FuzzerContext& context, } } - // todo: do we need to ensure this or are should we able to process 0 enqueued calls? - // Ensure at least 1 app_logic enqueued call exists (mutations may have deleted all) + // Ensure at least 1 app_logic enqueued call exists (mutations may have deleted all), the public base kernel circuit + // guarantees that there is at least 1 enqueued call in an public tx (so this is a valid assumption) if (tx_data.tx.app_logic_enqueued_calls.empty() && !contract_addresses.empty()) { auto idx = std::uniform_int_distribution(0, contract_addresses.size() - 1)(rng); std::vector calldata = {}; @@ -473,4 +466,6 @@ void populate_context_from_tx_data(FuzzerContext& context, const FuzzerTxData& t } context.set_existing_note_hashes(note_hash_leaf_index_pairs); + + context.set_existing_contract_addresses(tx_data.contract_addresses); } diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp index 93d33213fb2d..95903bfb0475 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.hpp @@ -61,6 +61,7 @@ using FuzzerContext = bb::avm2::fuzzer::FuzzerContext; // Mutation configuration enum class FuzzerTxDataMutationType : uint8_t { + TxFuzzerDataMutation, TxMutation, BytecodeMutation, ContractClassMutation, @@ -69,9 +70,10 @@ enum class FuzzerTxDataMutationType : uint8_t { ProtocolContractsMutation }; -using FuzzerTxDataMutationConfig = WeightedSelectionConfig; +using FuzzerTxDataMutationConfig = WeightedSelectionConfig; constexpr FuzzerTxDataMutationConfig FUZZER_TX_DATA_MUTATION_CONFIGURATION = FuzzerTxDataMutationConfig({ + { FuzzerTxDataMutationType::TxFuzzerDataMutation, 20 }, { FuzzerTxDataMutationType::TxMutation, 10 }, { FuzzerTxDataMutationType::BytecodeMutation, 1 }, { FuzzerTxDataMutationType::ContractClassMutation, 1 }, diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/basic_types/field.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/basic_types/field.cpp index 442d60e50f10..218f46f5e2df 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/basic_types/field.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/basic_types/field.cpp @@ -4,6 +4,7 @@ /// 2. Increment by 1 /// 3. Decrement by 1 /// 4. Add a random value +/// 5. Boundary selection (pick from curated edge-case values) #include "barretenberg/avm_fuzzer/mutations/basic_types/field.hpp" @@ -17,6 +18,7 @@ #include "barretenberg/avm_fuzzer/mutations/basic_types/uint128_t.hpp" #include "barretenberg/avm_fuzzer/mutations/configuration.hpp" #include "barretenberg/numeric/random/engine.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" #include "barretenberg/vm2/common/field.hpp" using FF = bb::field; @@ -51,6 +53,49 @@ struct AddRandomValue { static void mutate(bb::avm2::FF& value, std::mt19937_64& rng) { value = value + generate_random_field(rng); } }; +// BN254 scalar field (bn254::fr) boundary values +// Modulus p = 21888242871839275222246405745257275088548364400416034343698204186575808495617 +// 4-limb Montgomery representation (64 bits per limb) +// These values exercise: +// - Zero/small values +// - Values near modulus p (exercise modular reduction) +// - Limb boundaries (4 x 64-bit limbs) +// - Values that cause reduction when doubled +// clang-format off +static const std::vector FIELD_BOUNDARY_VALUES = { + // === Zero/small values === + FF::zero(), // 0 + FF::one(), // 1 + FF(2), // 2 + + // === Values near modulus p (exercise modular reduction) === + FF::neg_one(), // p - 1 (max field element) + FF::neg_one() - FF::one(), // p - 2 + FF::neg_one() - FF(2), // p - 3 + FF::neg_one() / FF(2), // (p - 1) / 2 (midpoint) + FF::neg_one() / FF(2) + FF::one(), // (p + 1) / 2 + + // === Limb boundaries (4 x 64-bit limbs) === + FF(uint256_t(1) << 64), // 2^64 (limb 0/1 boundary) + FF(uint256_t(1) << 128), // 2^128 (limb 1/2 boundary) + FF(uint256_t(1) << 192), // 2^192 (limb 2/3 boundary) + FF((uint256_t(1) << 64) - 1), // 2^64 - 1 (limb 0 full) + FF((uint256_t(1) << 128) - 1), // 2^128 - 1 (limbs 0-1 full) + FF((uint256_t(1) << 192) - 1), // 2^192 - 1 (limbs 0-2 full) + + // === Montgomery form edge cases === + FF(uint256_t(1) << 253), // 2^253 (near R boundary, < p) +}; +// clang-format on + +/// @brief Select from curated boundary values +struct BoundarySelection { + static void mutate(std::mt19937_64& rng, FF& value) + { + value = FIELD_BOUNDARY_VALUES[std::uniform_int_distribution(0, FIELD_BOUNDARY_VALUES.size() - 1)(rng)]; + } +}; + void mutate_field(bb::avm2::FF& value, std::mt19937_64& rng, const FieldMutationConfig& config) { FieldMutationOptions option = config.select(rng); @@ -68,5 +113,8 @@ void mutate_field(bb::avm2::FF& value, std::mt19937_64& rng, const FieldMutation case FieldMutationOptions::AddRandomValue: AddRandomValue::mutate(value, rng); break; + case FieldMutationOptions::BoundarySelection: + BoundarySelection::mutate(rng, value); + break; } } diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/basic_types/uint_mutations.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/basic_types/uint_mutations.hpp index 6aaf1858d176..ab8899a3df0f 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/basic_types/uint_mutations.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/basic_types/uint_mutations.hpp @@ -4,6 +4,7 @@ /// 2. Increment by 1 /// 3. Decrement by 1 /// 4. Add a random value +/// 5. Boundary selection (pick from curated edge-case values) #pragma once @@ -47,6 +48,94 @@ template <> struct UintTraits { static constexpr bool has_mask = false; }; +// BoundaryValues: curated sets of edge-case values for each uint type +// These values exercise: +// - Zero/one edge cases +// - Power-of-2 midpoints (which trigger different code paths in multi-limb arithmetic) +// - Maximum value overflow detection +// - Cross-type boundaries (e.g., U8 max within U16) +template struct BoundaryValues; + +template <> struct BoundaryValues { + static constexpr std::array values = { + 0, // Zero + 1, // One + 2, // Small value + 127, // 2^7 - 1 (max value with high bit clear) + 128, // 2^7 (midpoint, high bit set) + 254, // Max - 1 + 255, // Max (2^8 - 1) + 0x55, // Alternating bits (01010101) + }; +}; + +template <> struct BoundaryValues { + static constexpr std::array values = { + 0, 1, 2, + 255, // U8 max (cross-type boundary) + 256, // U8 max + 1 + 32767, // 2^15 - 1 (max with high bit clear) + 32768, // 2^15 (midpoint, high bit set) + 65534, // Max - 1 + 65535, // Max (2^16 - 1) + 0x5555, // Alternating bits + }; +}; + +template <> struct BoundaryValues { + static constexpr std::array values = { + 0, 1, 2, 255, + 256, // U8 boundaries + 65535, + 65536, // U16 boundaries + 0x7FFFFFFF, // 2^31 - 1 (max with high bit clear) + 0x80000000, // 2^31 (midpoint, high bit set) + 0xFFFFFFFE, // Max - 1 + 0xFFFFFFFF, // Max (2^32 - 1) + 0x55555555, // Alternating bits + }; +}; + +template <> struct BoundaryValues { + static constexpr std::array values = { + 0, + 1, + 2, + 0xFF, + 0x100, // U8 boundaries + 0xFFFF, + 0x10000, // U16 boundaries + 0xFFFFFFFF, // U32 max + 0x100000000, // U32 max + 1 (exercises carry into high word) + 0x7FFFFFFFFFFFFFFF, // 2^63 - 1 (max with high bit clear) + 0x8000000000000000, // 2^63 (midpoint, high bit set) + 0xFFFFFFFFFFFFFFFE, // Max - 1 + 0xFFFFFFFFFFFFFFFF, // Max (2^64 - 1) + 0x5555555555555555, // Alternating bits + }; +}; + +template <> struct BoundaryValues { + // Critical for multi-limb arithmetic: values at limb boundaries + // U128 is stored as two 64-bit limbs, so 2^64 boundary is crucial + static inline const std::array values = { + uint128_t(0), + uint128_t(1), + uint128_t(2), + uint128_t(0xFFFFFFFFFFFFFFFFULL), // U64 max (low limb full) + uint128_t(0xFFFFFFFFFFFFFFFFULL) + 1, // 2^64 (carry into high limb) + uint128_t(1) << 64, // 2^64 (high limb = 1) + (uint128_t(0x7FFFFFFFFFFFFFFFULL) << 64) | 0xFFFFFFFFFFFFFFFFULL, // 2^127 - 1 + uint128_t(1) << 127, // 2^127 (midpoint) + (uint128_t(0xFFFFFFFFFFFFFFFFULL) << 64) | 0xFFFFFFFFFFFFFFFEULL, // Max - 1 + (uint128_t(0xFFFFFFFFFFFFFFFFULL) << 64) | 0xFFFFFFFFFFFFFFFFULL, // Max (2^128 - 1) + uint128_t(1) << 96, // 2^96 (3/4 point) + (uint128_t(1) << 96) - 1, // 2^96 - 1 + uint128_t(1) << 63, // 2^63 (quarter point) + (uint128_t(0x5555555555555555ULL) << 64) | 0x5555555555555555ULL, // Alternating bits + }; +}; + template typename std::enable_if::value && std::is_unsigned::value, T>::type generate_random_uint( std::mt19937_64& rng) @@ -99,6 +188,14 @@ template struct AddRandomValue { } } }; + +template struct BoundarySelection { + static void mutate(std::mt19937_64& rng, T& value) + { + const auto& bounds = BoundaryValues::values; + value = bounds[std::uniform_int_distribution(0, bounds.size() - 1)(rng)]; + } +}; } // namespace uint_mutation // Generic mutation function using WeightedSelectionConfig @@ -119,6 +216,9 @@ template void mutate_uint(T& value, std::mt199 case UintMutationOptions::AddRandomValue: uint_mutation::AddRandomValue::mutate(value, rng); break; + case UintMutationOptions::BoundarySelection: + uint_mutation::BoundarySelection::mutate(rng, value); + break; } } diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp index 1983a98e03fe..5e1b6a79b1cc 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/configuration.hpp @@ -18,7 +18,9 @@ constexpr VecMutationConfig BASIC_VEC_MUTATION_CONFIGURATION = VecMutationConfig }); // Generic uint mutation options (used by all uint types) -enum class UintMutationOptions { RandomSelection, IncrementBy1, DecrementBy1, AddRandomValue }; +// BoundarySelection picks from a curated set of edge-case values (0, 1, max, midpoint, etc.) +// to dramatically improve coverage of boundary conditions in arithmetic operations +enum class UintMutationOptions { RandomSelection, IncrementBy1, DecrementBy1, AddRandomValue, BoundarySelection }; // Type aliases for backward compatibility using Uint8MutationOptions = UintMutationOptions; @@ -38,6 +40,7 @@ constexpr Uint8MutationConfig BASIC_UINT8_T_MUTATION_CONFIGURATION = Uint8Mutati { UintMutationOptions::IncrementBy1, 22 }, { UintMutationOptions::DecrementBy1, 20 }, { UintMutationOptions::AddRandomValue, 10 }, + { UintMutationOptions::BoundarySelection, 25 }, // ~30% - picks boundary values (0, 1, max, midpoint, etc.) }); constexpr Uint16MutationConfig BASIC_UINT16_T_MUTATION_CONFIGURATION = Uint16MutationConfig({ @@ -45,6 +48,7 @@ constexpr Uint16MutationConfig BASIC_UINT16_T_MUTATION_CONFIGURATION = Uint16Mut { UintMutationOptions::IncrementBy1, 22 }, { UintMutationOptions::DecrementBy1, 20 }, { UintMutationOptions::AddRandomValue, 10 }, + { UintMutationOptions::BoundarySelection, 25 }, // ~30% - picks boundary values (0, 1, max, midpoint, etc.) }); constexpr Uint32MutationConfig BASIC_UINT32_T_MUTATION_CONFIGURATION = Uint32MutationConfig({ @@ -52,6 +56,7 @@ constexpr Uint32MutationConfig BASIC_UINT32_T_MUTATION_CONFIGURATION = Uint32Mut { UintMutationOptions::IncrementBy1, 22 }, { UintMutationOptions::DecrementBy1, 20 }, { UintMutationOptions::AddRandomValue, 10 }, + { UintMutationOptions::BoundarySelection, 25 }, // ~30% - picks boundary values (0, 1, max, midpoint, etc.) }); constexpr Uint64MutationConfig BASIC_UINT64_T_MUTATION_CONFIGURATION = Uint64MutationConfig({ @@ -59,6 +64,7 @@ constexpr Uint64MutationConfig BASIC_UINT64_T_MUTATION_CONFIGURATION = Uint64Mut { UintMutationOptions::IncrementBy1, 22 }, { UintMutationOptions::DecrementBy1, 20 }, { UintMutationOptions::AddRandomValue, 10 }, + { UintMutationOptions::BoundarySelection, 25 }, // ~30% - picks boundary values (0, 1, max, midpoint, etc.) }); constexpr Uint128MutationConfig BASIC_UINT128_T_MUTATION_CONFIGURATION = Uint128MutationConfig({ @@ -66,9 +72,12 @@ constexpr Uint128MutationConfig BASIC_UINT128_T_MUTATION_CONFIGURATION = Uint128 { UintMutationOptions::IncrementBy1, 22 }, { UintMutationOptions::DecrementBy1, 20 }, { UintMutationOptions::AddRandomValue, 10 }, + { UintMutationOptions::BoundarySelection, 25 }, // ~30% - picks boundary values (0, 1, max, midpoint, etc.) }); -enum class FieldMutationOptions { RandomSelection, IncrementBy1, DecrementBy1, AddRandomValue }; +// BoundarySelection picks from a curated set of edge-case values (0, 1, p-1, limb boundaries, etc.) +// to dramatically improve coverage of boundary conditions in field arithmetic +enum class FieldMutationOptions { RandomSelection, IncrementBy1, DecrementBy1, AddRandomValue, BoundarySelection }; using FieldMutationConfig = WeightedSelectionConfig; @@ -77,6 +86,7 @@ constexpr FieldMutationConfig BASIC_FIELD_MUTATION_CONFIGURATION = FieldMutation { FieldMutationOptions::IncrementBy1, 22 }, { FieldMutationOptions::DecrementBy1, 20 }, { FieldMutationOptions::AddRandomValue, 10 }, + { FieldMutationOptions::BoundarySelection, 25 }, // ~30% - picks boundary values (0, 1, p-1, limb boundaries) }); enum class MemoryTagOptions { U1, U8, U16, U32, U64, U128, FF }; diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp index b376828f655b..a78fe06b9f34 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp @@ -127,18 +127,18 @@ void mutate_fuzzer_data_vec(const FuzzerContext& context, std::mt19937_64& rng, size_t max_size) { - auto choice = std::uniform_int_distribution(0, 1)(rng); + auto choice = ENQUEUED_CALL_MUTATION_CONFIGURATION.select(rng); + switch (choice) { - case 0: { + case EnqueuedCallMutation::Add: fuzz_info("Adding a new enqueued call"); // Add a new enqueued call if (enqueued_calls.size() < max_size) { - FuzzerData new_enqueued_call = generate_fuzzer_data(rng, context); - enqueued_calls.push_back(new_enqueued_call); + enqueued_calls.push_back(generate_fuzzer_data(rng, context)); } break; - } - case 1: { + + case EnqueuedCallMutation::Mutate: { // Mutate an existing enqueued call fuzz_info("Mutating an existing enqueued call"); if (!enqueued_calls.empty()) { @@ -149,15 +149,14 @@ void mutate_fuzzer_data_vec(const FuzzerContext& context, } break; } - // case 2: { - // // Remove an existing enqueued call - // vinfo("Removing an existing enqueued call"); - // if (!enqueued_calls.empty()) { - // size_t idx = std::uniform_int_distribution(0, enqueued_calls.size() - 1)(rng); - // enqueued_calls.erase(enqueued_calls.begin() + static_cast(idx)); - // } - // break; - // } + case EnqueuedCallMutation::Remove: + // Remove an existing enqueued call + fuzz_info("Removing an existing enqueued call"); + if (!enqueued_calls.empty()) { + size_t idx = std::uniform_int_distribution(0, enqueued_calls.size() - 1)(rng); + enqueued_calls.erase(enqueued_calls.begin() + static_cast(idx)); + } + break; } } diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp index 1934d4bb7d27..41aa365838fa 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp @@ -35,6 +35,15 @@ constexpr TxMutationConfig TX_MUTATION_CONFIGURATION = TxMutationConfig({ { TxMutationOptions::FeePayer, 1 }, }); +enum class EnqueuedCallMutation { Add, Mutate, Remove }; + +using EnqueuedCallMutationConfig = WeightedSelectionConfig; +constexpr EnqueuedCallMutationConfig ENQUEUED_CALL_MUTATION_CONFIGURATION = EnqueuedCallMutationConfig({ + { EnqueuedCallMutation::Add, 30 }, + { EnqueuedCallMutation::Mutate, 50 }, + { EnqueuedCallMutation::Remove, 20 }, +}); + namespace bb::avm2::fuzzer { void mutate_tx(Tx& tx, std::vector& contract_addresses, std::mt19937_64& rng); @@ -42,6 +51,6 @@ void mutate_tx(Tx& tx, std::vector& contract_addresses, std::mt199 void mutate_fuzzer_data_vec(const FuzzerContext& context, std::vector& enqueued_calls, std::mt19937_64& rng, - size_t max_size = 10); + size_t max_size = 64); } // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.cpp index f88b7062b126..c413eb29dd10 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.cpp @@ -16,7 +16,7 @@ namespace { void mutate_contract_address(AztecAddress& address, std::vector& contract_addresses, std::mt19937_64& rng) { if (contract_addresses.empty()) { - address = generate_random_field(rng); + return; } // Most of the time we want to pick from the existing contract addresses, since a random address will fail early auto contract_address_choice = std::uniform_int_distribution(0, contract_addresses.size() - 1)(rng);