diff --git a/avm-transpiler/src/instructions.rs b/avm-transpiler/src/instructions.rs index 91f3f05527e..74318b0b5ac 100644 --- a/avm-transpiler/src/instructions.rs +++ b/avm-transpiler/src/instructions.rs @@ -88,14 +88,13 @@ impl Default for AvmInstruction { #[allow(clippy::upper_case_acronyms, dead_code)] #[derive(Copy, Clone, Debug)] pub enum AvmTypeTag { - UNINITIALIZED, + FIELD, UINT1, UINT8, UINT16, UINT32, UINT64, UINT128, - FIELD, INVALID, } diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 1b48fa90b7d..d3244f6363d 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -1497,6 +1497,5 @@ fn tag_from_bit_size(bit_size: BitSize) -> AvmTypeTag { BitSize::Integer(IntegerBitSize::U64) => AvmTypeTag::UINT64, BitSize::Integer(IntegerBitSize::U128) => AvmTypeTag::UINT128, BitSize::Field => AvmTypeTag::FIELD, - _ => panic!("The AVM doesn't support integer bit size {:?}", bit_size), } } diff --git a/barretenberg/cpp/pil/avm/alu.pil b/barretenberg/cpp/pil/avm/alu.pil index 392a49d8f04..4462161e917 100644 --- a/barretenberg/cpp/pil/avm/alu.pil +++ b/barretenberg/cpp/pil/avm/alu.pil @@ -13,7 +13,7 @@ namespace alu(256); pol commit ic; pol commit sel_alu; // Predicate to activate the copy of intermediate registers to ALU table. - // Instruction tag (1: u1, 2: u8, 3: u16, 4: u32, 5: u64, 6: u128, 7: field) copied from Main table + // Instruction tag copied from Main table (MEM_TAG enum defined in constants) pol commit in_tag; // Flattened boolean instruction tags diff --git a/barretenberg/cpp/pil/avm/constants_gen.pil b/barretenberg/cpp/pil/avm/constants_gen.pil index 074be64de12..8eab33c0234 100644 --- a/barretenberg/cpp/pil/avm/constants_gen.pil +++ b/barretenberg/cpp/pil/avm/constants_gen.pil @@ -11,13 +11,13 @@ namespace constants(256); pol MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL = 16; pol MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL = 16; pol MAX_UNENCRYPTED_LOGS_PER_CALL = 4; + pol MEM_TAG_FF = 0; pol MEM_TAG_U1 = 1; pol MEM_TAG_U8 = 2; pol MEM_TAG_U16 = 3; pol MEM_TAG_U32 = 4; pol MEM_TAG_U64 = 5; pol MEM_TAG_U128 = 6; - pol MEM_TAG_FF = 7; pol SENDER_KERNEL_INPUTS_COL_OFFSET = 0; pol ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; pol STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; diff --git a/barretenberg/cpp/pil/avm/main.pil b/barretenberg/cpp/pil/avm/main.pil index 1ea776c0490..4e395413142 100644 --- a/barretenberg/cpp/pil/avm/main.pil +++ b/barretenberg/cpp/pil/avm/main.pil @@ -152,7 +152,7 @@ namespace main(256); // Helper selector to characterize a Binary chiplet selector pol commit sel_bin; - // Instruction memory tags read/write (1: u1, 2: u8, 3: u16, 4: u32, 5: u64, 6: u128, 7: field) + // Instruction memory tags read/write (enum defined in constants) pol commit r_in_tag; pol commit w_in_tag; pol commit alu_in_tag; // Copy of r_in_tag or w_in_tag depending of the operation. It is sent to ALU trace. diff --git a/barretenberg/cpp/pil/avm/mem.pil b/barretenberg/cpp/pil/avm/mem.pil index ddf89ea9884..5c265440924 100644 --- a/barretenberg/cpp/pil/avm/mem.pil +++ b/barretenberg/cpp/pil/avm/mem.pil @@ -9,7 +9,7 @@ namespace mem(256); pol commit addr; pol commit space_id; pol commit glob_addr; - pol commit tag; // Memory tag (0: uninitialized, 1: u1, 2: u8, 3: u16, 4: u32, 5: u64, 6: u128, 7:field) + pol commit tag; // Memory tag (MEM_TAG enum defined in constants) pol commit val; pol commit rw; // Enum: 0 (read), 1 (write) pol commit lastAccess; // Boolean (1 when this row is the last of a given address) @@ -175,13 +175,16 @@ namespace mem(256); #[MEM_READ_WRITE_TAG_CONSISTENCY] (1 - lastAccess) * (1 - rw') * (tag' - tag) = 0; + // If this is the last row that an address is accessed, the next row must be the first access of another address. // Constrain that the first load from a given address has value 0. (Consistency of memory initialization.) - // We do not constrain that the tag == 0 as the 0 value is compatible with any memory type. // As we enforce lastAccess = 1 on the first row, the following condition applies also for the first memory entry: #[MEM_ZERO_INIT] lastAccess * (1 - rw') * val' = 0; + // Constrain that reading an uninitialized cell creates tag error unless it is expected to be of type FF. + #[MEM_ZERO_INIT_TAG_FF] + lastAccess * (1 - rw') * (tag' - constants.MEM_TAG_FF) = 0; - // TODO: Verfiy that skip_check_tag cannot be enabled maliciously by the prover. + // TODO: Verify that skip_check_tag cannot be enabled maliciously by the prover. // Skip check tag enabled for some MOV opcodes and RETURN opcode (sel_op_slice) #[SKIP_CHECK_TAG] skip_check_tag = sel_op_slice; @@ -199,14 +202,13 @@ namespace mem(256); // instead of (r_in_tag - tag)^(-1) as this allows to store zero by default (i.e., when tag_err == 0). // The new column one_min_inv is set to 1 - (r_in_tag - tag)^(-1) when tag_err == 1 // but must be set to 0 when tags are matching and tag_err = 0 - // Relaxation: This relation is relaxed when skip_check_tag is enabled or for - // uninitialized memory, i.e. tag == 0. + // Relaxation: This relation is relaxed when skip_check_tag is enabled #[MEM_IN_TAG_CONSISTENCY_1] - tag * (1 - skip_check_tag) * (1 - rw) * ((r_in_tag - tag) * (1 - one_min_inv) - tag_err) = 0; + (1 - skip_check_tag) * (1 - rw) * ((r_in_tag - tag) * (1 - one_min_inv) - tag_err) = 0; // TODO: Try to decrease the degree of the above relation, e.g., skip_check_tag might be consolidated // with tag == 0 and rw == 1. #[MEM_IN_TAG_CONSISTENCY_2] - tag * (1 - tag_err) * one_min_inv = 0; + (1 - tag_err) * one_min_inv = 0; #[NO_TAG_ERR_WRITE_OR_SKIP] (skip_check_tag + rw) * tag_err = 0; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index b781f4000e4..973303b385a 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -145,12 +145,6 @@ struct BinaryIntOp { struct IntegerBitSize { - struct U0 { - friend bool operator==(const U0&, const U0&); - std::vector bincodeSerialize() const; - static U0 bincodeDeserialize(std::vector); - }; - struct U1 { friend bool operator==(const U1&, const U1&); std::vector bincodeSerialize() const; @@ -187,7 +181,7 @@ struct IntegerBitSize { static U128 bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const IntegerBitSize&, const IntegerBitSize&); std::vector bincodeSerialize() const; @@ -8061,46 +8055,6 @@ Program::IntegerBitSize serde::Deserializable::deserial namespace Program { -inline bool operator==(const IntegerBitSize::U0& lhs, const IntegerBitSize::U0& rhs) -{ - return true; -} - -inline std::vector IntegerBitSize::U0::bincodeSerialize() const -{ - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); -} - -inline IntegerBitSize::U0 IntegerBitSize::U0::bincodeDeserialize(std::vector input) -{ - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw_or_abort("Some input bytes were not read"); - } - return value; -} - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::IntegerBitSize::U0& obj, - Serializer& serializer) -{} - -template <> -template -Program::IntegerBitSize::U0 serde::Deserializable::deserialize(Deserializer& deserializer) -{ - Program::IntegerBitSize::U0 obj; - return obj; -} - -namespace Program { - inline bool operator==(const IntegerBitSize::U1& lhs, const IntegerBitSize::U1& rhs) { return true; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/alu.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/alu.hpp index 266fca913ec..abc0a44ddb7 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/alu.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/alu.hpp @@ -21,13 +21,13 @@ template class aluImpl { [[maybe_unused]] const RelationParameters&, [[maybe_unused]] const FF& scaling_factor) { + const auto constants_MEM_TAG_FF = FF(0); const auto constants_MEM_TAG_U1 = FF(1); const auto constants_MEM_TAG_U8 = FF(2); const auto constants_MEM_TAG_U16 = FF(3); const auto constants_MEM_TAG_U32 = FF(4); const auto constants_MEM_TAG_U64 = FF(5); const auto constants_MEM_TAG_U128 = FF(6); - const auto constants_MEM_TAG_FF = FF(7); const auto alu_MAX_BITS = ((((((new_term.alu_u1_tag * FF(1)) + (new_term.alu_u8_tag * FF(8))) + (new_term.alu_u16_tag * FF(16))) + (new_term.alu_u32_tag * FF(32))) + diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp index 963b2b0895d..b601cb9a36f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp @@ -23,8 +23,8 @@ template class mainImpl { [[maybe_unused]] const RelationParameters&, [[maybe_unused]] const FF& scaling_factor) { + const auto constants_MEM_TAG_FF = FF(0); const auto constants_MEM_TAG_U1 = FF(1); - const auto constants_MEM_TAG_FF = FF(7); const auto constants_misc_INTERNAL_CALL_SPACE_ID = FF(255); const auto main_KERNEL_INPUT_SELECTORS = (((((((((((new_term.main_sel_op_address + new_term.main_sel_op_storage_address) + diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/mem.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/mem.hpp index 160a8876b0b..5ee5785375f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/mem.hpp @@ -10,10 +10,10 @@ template class 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, - 2, 3, 4, 3, 4, 3, 3, 2, 3, 3, 4, 4, 4, - 4, 2, 6, 4, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 3, 4, 3, 4, 3, 3, 2, 3, 3, 4, 4, 4, 4, 4, + 2, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; template void static accumulate(ContainerOverSubrelations& evals, @@ -21,8 +21,8 @@ template class memImpl { [[maybe_unused]] const RelationParameters&, [[maybe_unused]] const FF& scaling_factor) { + const auto constants_MEM_TAG_FF = FF(0); const auto constants_MEM_TAG_U32 = FF(4); - const auto constants_MEM_TAG_FF = FF(7); const auto mem_SEL_DIRECT_MEM_OP_A = ((new_term.mem_sel_op_a + new_term.mem_sel_op_poseidon_read_a) + new_term.mem_sel_op_poseidon_write_a); const auto mem_SEL_DIRECT_MEM_OP_B = @@ -218,156 +218,163 @@ template class memImpl { } { using Accumulator = typename std::tuple_element_t<27, ContainerOverSubrelations>; - auto tmp = (new_term.mem_skip_check_tag - new_term.mem_sel_op_slice); + auto tmp = ((new_term.mem_lastAccess * (FF(1) - new_term.mem_rw_shift)) * + (new_term.mem_tag_shift - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<27>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<28, ContainerOverSubrelations>; - auto tmp = (((new_term.mem_tag * (FF(1) - new_term.mem_skip_check_tag)) * (FF(1) - new_term.mem_rw)) * - (((new_term.mem_r_in_tag - new_term.mem_tag) * (FF(1) - new_term.mem_one_min_inv)) - - new_term.mem_tag_err)); + auto tmp = (new_term.mem_skip_check_tag - new_term.mem_sel_op_slice); tmp *= scaling_factor; std::get<28>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<29, ContainerOverSubrelations>; - auto tmp = ((new_term.mem_tag * (FF(1) - new_term.mem_tag_err)) * new_term.mem_one_min_inv); + auto tmp = (((FF(1) - new_term.mem_skip_check_tag) * (FF(1) - new_term.mem_rw)) * + (((new_term.mem_r_in_tag - new_term.mem_tag) * (FF(1) - new_term.mem_one_min_inv)) - + new_term.mem_tag_err)); tmp *= scaling_factor; std::get<29>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<30, ContainerOverSubrelations>; - auto tmp = ((new_term.mem_skip_check_tag + new_term.mem_rw) * new_term.mem_tag_err); + auto tmp = ((FF(1) - new_term.mem_tag_err) * new_term.mem_one_min_inv); tmp *= scaling_factor; std::get<30>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<31, ContainerOverSubrelations>; - auto tmp = (new_term.mem_rw * (new_term.mem_w_in_tag - new_term.mem_tag)); + auto tmp = ((new_term.mem_skip_check_tag + new_term.mem_rw) * new_term.mem_tag_err); tmp *= scaling_factor; std::get<31>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<32, ContainerOverSubrelations>; - auto tmp = (new_term.mem_rw * new_term.mem_tag_err); + auto tmp = (new_term.mem_rw * (new_term.mem_w_in_tag - new_term.mem_tag)); tmp *= scaling_factor; std::get<32>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<33, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_a * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); + auto tmp = (new_term.mem_rw * new_term.mem_tag_err); tmp *= scaling_factor; std::get<33>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<34, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_b * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); + auto tmp = (new_term.mem_sel_resolve_ind_addr_a * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); tmp *= scaling_factor; std::get<34>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<35, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_c * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); + auto tmp = (new_term.mem_sel_resolve_ind_addr_b * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); tmp *= scaling_factor; std::get<35>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<36, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_d * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); + auto tmp = (new_term.mem_sel_resolve_ind_addr_c * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); tmp *= scaling_factor; std::get<36>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<37, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_a * new_term.mem_rw); + auto tmp = (new_term.mem_sel_resolve_ind_addr_d * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); tmp *= scaling_factor; std::get<37>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<38, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_b * new_term.mem_rw); + auto tmp = (new_term.mem_sel_resolve_ind_addr_a * new_term.mem_rw); tmp *= scaling_factor; std::get<38>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<39, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_c * new_term.mem_rw); + auto tmp = (new_term.mem_sel_resolve_ind_addr_b * new_term.mem_rw); tmp *= scaling_factor; std::get<39>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<40, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_d * new_term.mem_rw); + auto tmp = (new_term.mem_sel_resolve_ind_addr_c * new_term.mem_rw); tmp *= scaling_factor; std::get<40>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<41, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_slice * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_resolve_ind_addr_d * new_term.mem_rw); tmp *= scaling_factor; std::get<41>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<42, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_slice * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_op_slice * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<42>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<43, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_read_a * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_op_slice * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<43>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<44, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_read_b * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_op_poseidon_read_a * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<44>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<45, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_read_c * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_op_poseidon_read_b * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<45>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<46, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_read_d * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_op_poseidon_read_c * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<46>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<47, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_write_a * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_op_poseidon_read_d * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<47>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<48, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_write_b * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_op_poseidon_write_a * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<48>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<49, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_write_c * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_op_poseidon_write_b * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<49>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<50, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_write_d * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.mem_sel_op_poseidon_write_c * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<50>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<51, ContainerOverSubrelations>; - auto tmp = ((new_term.mem_sel_mov_ia_to_ic + new_term.mem_sel_mov_ib_to_ic) * new_term.mem_tag_err); + auto tmp = (new_term.mem_sel_op_poseidon_write_d * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<51>(evals) += typename Accumulator::View(tmp); } + { + using Accumulator = typename std::tuple_element_t<52, ContainerOverSubrelations>; + auto tmp = ((new_term.mem_sel_mov_ia_to_ic + new_term.mem_sel_mov_ib_to_ic) * new_term.mem_tag_err); + tmp *= scaling_factor; + std::get<52>(evals) += typename Accumulator::View(tmp); + } } }; @@ -399,16 +406,18 @@ template class mem : public Relation> { case 26: return "MEM_ZERO_INIT"; case 27: - return "SKIP_CHECK_TAG"; + return "MEM_ZERO_INIT_TAG_FF"; case 28: - return "MEM_IN_TAG_CONSISTENCY_1"; + return "SKIP_CHECK_TAG"; case 29: - return "MEM_IN_TAG_CONSISTENCY_2"; + return "MEM_IN_TAG_CONSISTENCY_1"; case 30: + return "MEM_IN_TAG_CONSISTENCY_2"; + case 31: return "NO_TAG_ERR_WRITE_OR_SKIP"; - case 32: + case 33: return "NO_TAG_ERR_WRITE"; - case 51: + case 52: return "MOV_SAME_TAG"; } return std::to_string(index); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp index 3e157d4b917..0e4b9316ca9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp @@ -64,9 +64,6 @@ void common_validate_op_not(std::vector const& trace, switch (tag) { // Handle the different mem_tags here since this is part of a // parameterised test - case AvmMemoryTag::U0: - FAIL() << "Unintialized Mem Tags Disallowed"; - break; case AvmMemoryTag::U1: EXPECT_EQ(alu_row->alu_u1_tag, FF(1)); break; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/kernel.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/kernel.test.cpp index 3fa89646fbb..0faf3e1f66e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/kernel.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/kernel.test.cpp @@ -1131,7 +1131,7 @@ TEST_F(AvmKernelOutputPositiveTests, kernelSload) /*ib=*/slot, /*mem_addr_b=*/0, /*ind_b=*/false, - /*r_in_tag=*/AvmMemoryTag::U0, // Kernel Sload is writing to memory + /*r_in_tag=*/AvmMemoryTag::FF, // Kernel Sload is writing to memory /*side_effect_counter=*/0, /*rwa=*/1, /*no_b=*/true); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/mem_opcodes.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/mem_opcodes.test.cpp index b6523c4624e..f218f873053 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/mem_opcodes.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/mem_opcodes.test.cpp @@ -164,10 +164,10 @@ class AvmMemOpcodeTests : public ::testing::Test { if (indirect) { auto const& mem_ind_a_row = trace.at(mem_ind_a_row_idx); EXPECT_THAT(mem_ind_a_row, - AllOf(MEM_ROW_FIELD_EQ(tag_err, 0), + AllOf(MEM_ROW_FIELD_EQ(tag_err, indirect_uninitialized ? 1 : 0), MEM_ROW_FIELD_EQ(r_in_tag, static_cast(AvmMemoryTag::U32)), MEM_ROW_FIELD_EQ(tag, - indirect_uninitialized ? static_cast(AvmMemoryTag::U0) + indirect_uninitialized ? static_cast(AvmMemoryTag::FF) : static_cast(AvmMemoryTag::U32)), MEM_ROW_FIELD_EQ(addr, src_offset), MEM_ROW_FIELD_EQ(val, dir_src_offset), @@ -221,7 +221,7 @@ TEST_F(AvmMemOpcodeTests, uninitializedValueMov) trace_builder.op_return(0, 0, 0); trace = trace_builder.finalize(); - validate_mov_trace(false, 0, 0, 1, AvmMemoryTag::U0); + validate_mov_trace(false, 0, 0, 1, AvmMemoryTag::FF); } TEST_F(AvmMemOpcodeTests, indUninitializedValueMov) @@ -229,13 +229,28 @@ TEST_F(AvmMemOpcodeTests, indUninitializedValueMov) // TODO(#9131): Re-enable once we have error handling on wrong address resolution GTEST_SKIP(); + trace_builder.op_set(0, 1, 3, AvmMemoryTag::U32); + trace_builder.op_set(0, 4, 1, AvmMemoryTag::U32); + trace_builder.op_set(0, 5, 2, AvmMemoryTag::U32); + trace_builder.op_mov(3, 2, 3); + trace_builder.op_return(0, 0, 0); + trace = trace_builder.finalize(); + + validate_mov_trace(true, 0, 2, 3, AvmMemoryTag::FF, 5, 1); +} + +TEST_F(AvmMemOpcodeTests, indUninitializedAddrMov) +{ + // TODO(#9131): Re-enable once we have error handling on wrong address resolution + GTEST_SKIP(); + trace_builder.op_set(0, 1, 3, AvmMemoryTag::U32); trace_builder.op_set(0, 4, 1, AvmMemoryTag::U32); trace_builder.op_mov(3, 2, 3); trace_builder.op_return(0, 0, 0); trace = trace_builder.finalize(); - validate_mov_trace(true, 0, 2, 3, AvmMemoryTag::U0, 0, 1, true); + validate_mov_trace(true, 0, 2, 3, AvmMemoryTag::FF, 0, 1, true); } TEST_F(AvmMemOpcodeTests, indirectMov) diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp index b9776ee44ef..0d9f7b4caf0 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp @@ -39,8 +39,6 @@ uint8_t mem_tag_bits(AvmMemoryTag in_tag) return 128; case AvmMemoryTag::FF: return 254; - case AvmMemoryTag::U0: - return 0; } return 0; } @@ -61,11 +59,9 @@ FF cast_to_mem_tag(uint256_t input, AvmMemoryTag in_tag) case AvmMemoryTag::U64: return FF{ static_cast(input) }; case AvmMemoryTag::U128: - return FF{ uint256_t::from_uint128(uint128_t(input)) }; + return FF{ uint256_t::from_uint128(static_cast(input)) }; case AvmMemoryTag::FF: return input; - case AvmMemoryTag::U0: - return FF{ 0 }; } // Need this for gcc compilation even though we fully handle the switch cases // We should never reach this point diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/binary_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/binary_trace.cpp index d5efd069775..5967c68fee3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/binary_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/binary_trace.cpp @@ -107,7 +107,7 @@ void AvmBinaryTraceBuilder::entry_builder( */ FF AvmBinaryTraceBuilder::op_and(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk) { - if (instr_tag == AvmMemoryTag::FF || instr_tag == AvmMemoryTag::U0) { + if (instr_tag == AvmMemoryTag::FF) { return FF::zero(); } // Cast to bits and perform AND operation @@ -131,7 +131,7 @@ FF AvmBinaryTraceBuilder::op_and(FF const& a, FF const& b, AvmMemoryTag instr_ta */ FF AvmBinaryTraceBuilder::op_or(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk) { - if (instr_tag == AvmMemoryTag::FF || instr_tag == AvmMemoryTag::U0) { + if (instr_tag == AvmMemoryTag::FF) { return FF::zero(); } // Cast to bits and perform OR operation @@ -155,7 +155,7 @@ FF AvmBinaryTraceBuilder::op_or(FF const& a, FF const& b, AvmMemoryTag instr_tag */ FF AvmBinaryTraceBuilder::op_xor(FF const& a, FF const& b, AvmMemoryTag instr_tag, uint32_t clk) { - if (instr_tag == AvmMemoryTag::FF || instr_tag == AvmMemoryTag::U0) { + if (instr_tag == AvmMemoryTag::FF) { return FF::zero(); } // Cast to bits and perform XOR operation diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp index 9796b79eb2a..fd5de470550 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp @@ -38,17 +38,16 @@ enum class IndirectRegister : uint32_t { IND_A = 0, IND_B = 1, IND_C = 2, IND_D // Keep following enum in sync with MAX_MEM_TAG below enum class AvmMemoryTag : uint32_t { - U0 = 0, + FF = MEM_TAG_FF, U1 = MEM_TAG_U1, U8 = MEM_TAG_U8, U16 = MEM_TAG_U16, U32 = MEM_TAG_U32, U64 = MEM_TAG_U64, U128 = MEM_TAG_U128, - FF = MEM_TAG_FF, }; -static const uint32_t MAX_MEM_TAG = MEM_TAG_FF; +static const uint32_t MAX_MEM_TAG = MEM_TAG_U128; static const size_t NUM_MEM_SPACES = 256; static const uint8_t INTERNAL_CALL_SPACE_ID = 255; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp index 8486677b365..81360626bfc 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp @@ -247,7 +247,7 @@ std::vector Deserialization::parse(std::vector const& byte switch (opType) { case OperandType::TAG: { uint8_t tag_u8 = bytecode.at(pos); - if (tag_u8 == static_cast(AvmMemoryTag::U0) || tag_u8 > MAX_MEM_TAG) { + if (tag_u8 > MAX_MEM_TAG) { throw_or_abort("Instruction tag is invalid at position " + std::to_string(pos) + " value: " + std::to_string(tag_u8) + " for opcode: " + to_string(opcode)); } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/mem_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/mem_trace.cpp index 03bbb724e84..11c35c14343 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/mem_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/mem_trace.cpp @@ -151,9 +151,9 @@ bool AvmMemTraceBuilder::load_from_mem_trace(uint8_t space_id, MemOpOwner mem_op_owner) { auto& mem_space = memory.at(space_id); - AvmMemoryTag m_tag = mem_space.contains(addr) ? mem_space.at(addr).tag : AvmMemoryTag::U0; + AvmMemoryTag m_tag = mem_space.contains(addr) ? mem_space.at(addr).tag : AvmMemoryTag::FF; - if (m_tag == AvmMemoryTag::U0 || m_tag == r_in_tag) { + if (m_tag == r_in_tag) { insert_in_mem_trace(space_id, clk, sub_clk, addr, val, m_tag, r_in_tag, w_in_tag, false, mem_op_owner); return true; } @@ -380,7 +380,7 @@ AvmMemTraceBuilder::MemRead AvmMemTraceBuilder::indirect_read_and_load_from_memo auto& mem_space = memory.at(space_id); FF val = mem_space.contains(addr) ? mem_space.at(addr).val : 0; - bool tagMatch = load_from_mem_trace(space_id, clk, sub_clk, addr, val, AvmMemoryTag::U32, AvmMemoryTag::U0); + bool tagMatch = load_from_mem_trace(space_id, clk, sub_clk, addr, val, AvmMemoryTag::U32, AvmMemoryTag::FF); return MemRead{ .tag_match = tagMatch, @@ -448,7 +448,7 @@ std::vector AvmMemTraceBuilder::read_return_opcode(uint32_t clk, auto addr = direct_ret_offset + i; auto& mem_space = memory.at(space_id); FF val = mem_space.contains(addr) ? mem_space.at(addr).val : 0; - AvmMemoryTag tag = mem_space.contains(addr) ? mem_space.at(addr).tag : AvmMemoryTag::U0; + AvmMemoryTag tag = mem_space.contains(addr) ? mem_space.at(addr).tag : AvmMemoryTag::FF; // No tag checking is performed for RETURN opcode. insert_in_mem_trace(space_id, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/mem_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/mem_trace.hpp index 8ab846c317a..16424000a35 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/mem_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/mem_trace.hpp @@ -56,7 +56,7 @@ class AvmMemTraceBuilder { // Structure representing an entry for the memory used in the simulation (not the trace). struct MemEntry { FF val{}; - AvmMemoryTag tag = AvmMemoryTag::U0; + AvmMemoryTag tag = AvmMemoryTag::FF; }; // Structure to return value and tag matching boolean after a memory read. diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index 0f638ca0811..6332ff3dbc3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -1239,7 +1239,7 @@ Row AvmTraceBuilder::create_kernel_lookup_opcode(uint8_t indirect, uint32_t dst_ auto [resolved_dst] = Addressing<1>::fromWire(indirect, call_ptr).resolve({ dst_offset }, mem_trace_builder); auto write_dst = - constrained_write_to_memory(call_ptr, clk, resolved_dst, value, AvmMemoryTag::U0, w_tag, IntermRegister::IA); + constrained_write_to_memory(call_ptr, clk, resolved_dst, value, AvmMemoryTag::FF, w_tag, IntermRegister::IA); return Row{ .main_clk = clk, @@ -1566,7 +1566,7 @@ void AvmTraceBuilder::execute_gasleft(EnvironmentVariable var, uint8_t indirect, // Write into memory from intermediate register ia. // TODO: probably will be U32 in final version auto write_dst = constrained_write_to_memory( - call_ptr, clk, resolved_dst, gas_remaining, AvmMemoryTag::U0, AvmMemoryTag::FF, IntermRegister::IA); + call_ptr, clk, resolved_dst, gas_remaining, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); main_trace.push_back(Row{ .main_clk = clk, @@ -1576,7 +1576,6 @@ void AvmTraceBuilder::execute_gasleft(EnvironmentVariable var, uint8_t indirect, .main_internal_return_ptr = FF(internal_return_ptr), .main_mem_addr_a = FF(write_dst.direct_address), .main_pc = FF(pc++), - .main_r_in_tag = FF(static_cast(AvmMemoryTag::U0)), .main_rwa = FF(1), .main_sel_mem_op_a = FF(1), .main_sel_op_dagasleft = (var == EnvironmentVariable::DAGASLEFT) ? FF(1) : FF(0), @@ -1706,7 +1705,7 @@ void AvmTraceBuilder::op_internal_call(uint32_t jmp_dest) IntermRegister::IB, internal_return_ptr, FF(pc + 1), - AvmMemoryTag::U0, + AvmMemoryTag::FF, AvmMemoryTag::U32); // Constrain gas cost @@ -1749,7 +1748,7 @@ void AvmTraceBuilder::op_internal_return() // Internal return pointer is decremented // We want to load the value pointed by the internal pointer auto read_a = mem_trace_builder.read_and_load_from_memory( - INTERNAL_CALL_SPACE_ID, clk, IntermRegister::IA, internal_return_ptr - 1, AvmMemoryTag::U32, AvmMemoryTag::U0); + INTERNAL_CALL_SPACE_ID, clk, IntermRegister::IA, internal_return_ptr - 1, AvmMemoryTag::U32, AvmMemoryTag::FF); // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::INTERNALRETURN); @@ -1796,7 +1795,7 @@ void AvmTraceBuilder::op_set(uint8_t indirect, FF val_ff, uint32_t dst_offset, A auto [resolved_dst_offset] = Addressing<1>::fromWire(indirect, call_ptr).resolve({ dst_offset }, mem_trace_builder); auto write_c = constrained_write_to_memory( - call_ptr, clk, resolved_dst_offset, val_ff, AvmMemoryTag::U0, in_tag, IntermRegister::IC); + call_ptr, clk, resolved_dst_offset, val_ff, AvmMemoryTag::FF, in_tag, IntermRegister::IC); // Constrain gas cost // FIXME: not great that we are having to choose one specific opcode here! @@ -1888,7 +1887,7 @@ Row AvmTraceBuilder::create_kernel_output_opcode(uint8_t indirect, uint32_t clk, auto [resolved_data] = Addressing<1>::fromWire(indirect, call_ptr).resolve({ data_offset }, mem_trace_builder); auto read_a = constrained_read_from_memory( - call_ptr, clk, resolved_data, AvmMemoryTag::FF, AvmMemoryTag::U0, IntermRegister::IA); + call_ptr, clk, resolved_data, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); bool tag_match = read_a.tag_match; return Row{ @@ -1930,9 +1929,9 @@ Row AvmTraceBuilder::create_kernel_output_opcode_with_metadata(uint8_t indirect, Addressing<2>::fromWire(indirect, call_ptr).resolve({ data_offset, metadata_offset }, mem_trace_builder); auto read_a = - constrained_read_from_memory(call_ptr, clk, resolved_data, data_r_tag, AvmMemoryTag::U0, IntermRegister::IA); + constrained_read_from_memory(call_ptr, clk, resolved_data, data_r_tag, AvmMemoryTag::FF, IntermRegister::IA); auto read_b = constrained_read_from_memory( - call_ptr, clk, resolved_metadata, metadata_r_tag, AvmMemoryTag::U0, IntermRegister::IB); + call_ptr, clk, resolved_metadata, metadata_r_tag, AvmMemoryTag::FF, IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; return Row{ @@ -2116,7 +2115,7 @@ void AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t // otherwise everything falls apart since this is a fake row. // // auto read_slot = constrained_read_from_memory( - // call_ptr, clk, resolved_slot, AvmMemoryTag::FF, AvmMemoryTag::U0, IntermRegister::IA); + // call_ptr, clk, resolved_slot, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); // // Read the slot value that we will write hints to in a row // main_trace.push_back(Row{ @@ -2141,7 +2140,7 @@ void AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t FF value = execution_hints.get_side_effect_hints().at(side_effect_counter); auto write_a = constrained_write_to_memory( - call_ptr, clk, write_dst, value, AvmMemoryTag::U0, AvmMemoryTag::FF, IntermRegister::IA); + call_ptr, clk, write_dst, value, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); auto row = Row{ .main_clk = clk, @@ -2221,7 +2220,7 @@ void AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t auto old_pc = pc; for (uint32_t i = 0; i < size; i++) { auto read_a = constrained_read_from_memory( - call_ptr, clk, read_src, AvmMemoryTag::FF, AvmMemoryTag::U0, IntermRegister::IA); + call_ptr, clk, read_src, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); Row row = Row{ .main_clk = clk, @@ -2382,7 +2381,7 @@ void AvmTraceBuilder::op_get_contract_instance(uint8_t indirect, uint32_t addres Addressing<2>::fromWire(indirect, call_ptr).resolve({ address_offset, dst_offset }, mem_trace_builder); auto read_address = constrained_read_from_memory( - call_ptr, clk, resolved_address_offset, AvmMemoryTag::FF, AvmMemoryTag::U0, IntermRegister::IA); + call_ptr, clk, resolved_address_offset, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); bool tag_match = read_address.tag_match; // Constrain gas cost @@ -2549,13 +2548,13 @@ void AvmTraceBuilder::constrain_external_call(OpCode opcode, // Should read the address next to read_gas as well (tuple of gas values (l2Gas, daGas)) auto read_gas_l2 = constrained_read_from_memory( - call_ptr, clk, resolved_gas_offset, AvmMemoryTag::FF, AvmMemoryTag::U0, IntermRegister::IA); + call_ptr, clk, resolved_gas_offset, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); auto read_gas_da = mem_trace_builder.read_and_load_from_memory( - call_ptr, clk, IntermRegister::IB, read_gas_l2.direct_address + 1, AvmMemoryTag::FF, AvmMemoryTag::U0); + call_ptr, clk, IntermRegister::IB, read_gas_l2.direct_address + 1, AvmMemoryTag::FF, AvmMemoryTag::FF); auto read_addr = constrained_read_from_memory( - call_ptr, clk, resolved_addr_offset, AvmMemoryTag::FF, AvmMemoryTag::U0, IntermRegister::IC); + call_ptr, clk, resolved_addr_offset, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IC); auto read_args = constrained_read_from_memory( - call_ptr, clk, resolved_args_offset, AvmMemoryTag::FF, AvmMemoryTag::U0, IntermRegister::ID); + call_ptr, clk, resolved_args_offset, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::ID); bool tag_match = read_gas_l2.tag_match && read_gas_da.tag_match && read_addr.tag_match && read_args.tag_match; // TODO: constrain this @@ -2785,7 +2784,7 @@ void AvmTraceBuilder::op_keccak(uint8_t indirect, // Read the input length first auto input_length_read = constrained_read_from_memory( - call_ptr, clk, resolved_input_size_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IB); + call_ptr, clk, resolved_input_size_offset, AvmMemoryTag::U32, AvmMemoryTag::FF, IntermRegister::IB); // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::KECCAK, static_cast(input_length_read.val)); @@ -2953,11 +2952,11 @@ void AvmTraceBuilder::op_pedersen_hash(uint8_t indirect, .resolve({ gen_ctx_offset, output_offset, input_offset, input_size_offset }, mem_trace_builder); auto input_read = constrained_read_from_memory( - call_ptr, clk, resolved_input_offset, AvmMemoryTag::FF, AvmMemoryTag::U0, IntermRegister::IA); + call_ptr, clk, resolved_input_offset, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); // auto input_size_read = constrained_read_from_memory( - // call_ptr, clk, resolved_input_size_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IB); + // call_ptr, clk, resolved_input_size_offset, AvmMemoryTag::U32, AvmMemoryTag::FF, IntermRegister::IB); // auto gen_ctx_read = constrained_read_from_memory( - // call_ptr, clk, resolved_gen_ctx_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IC); + // call_ptr, clk, resolved_gen_ctx_offset, AvmMemoryTag::U32, AvmMemoryTag::FF, IntermRegister::IC); auto input_size_read = unconstrained_read_from_memory(resolved_input_size_offset); auto gen_ctx_read = unconstrained_read_from_memory(resolved_gen_ctx_offset); @@ -3284,9 +3283,9 @@ void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, .resolve({ output_offset, state_offset, inputs_offset }, mem_trace_builder); auto read_a = constrained_read_from_memory( - call_ptr, clk, resolved_state_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IA); + call_ptr, clk, resolved_state_offset, AvmMemoryTag::U32, AvmMemoryTag::FF, IntermRegister::IA); auto read_b = constrained_read_from_memory( - call_ptr, clk, resolved_inputs_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IB); + call_ptr, clk, resolved_inputs_offset, AvmMemoryTag::U32, AvmMemoryTag::FF, IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; // Constrain gas cost @@ -3372,9 +3371,9 @@ void AvmTraceBuilder::op_keccakf1600(uint8_t indirect, auto [resolved_output_offset, resolved_input_offset] = Addressing<2>::fromWire(indirect, call_ptr).resolve({ output_offset, input_offset }, mem_trace_builder); auto input_read = constrained_read_from_memory( - call_ptr, clk, resolved_input_offset, AvmMemoryTag::U64, AvmMemoryTag::U0, IntermRegister::IA); + call_ptr, clk, resolved_input_offset, AvmMemoryTag::U64, AvmMemoryTag::FF, IntermRegister::IA); auto output_read = constrained_read_from_memory( - call_ptr, clk, resolved_output_offset, AvmMemoryTag::U64, AvmMemoryTag::U0, IntermRegister::IC); + call_ptr, clk, resolved_output_offset, AvmMemoryTag::U64, AvmMemoryTag::FF, IntermRegister::IC); bool tag_match = input_read.tag_match && output_read.tag_match; // Constrain gas cost diff --git a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp index e86b21518a8..e80e5ae7faa 100644 --- a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp @@ -38,13 +38,13 @@ #define AVM_PROOF_LENGTH_IN_FIELDS 3848 #define AVM_PUBLIC_COLUMN_MAX_SIZE 1024 #define AVM_PUBLIC_INPUTS_FLATTENED_SIZE 2739 +#define MEM_TAG_FF 0 #define MEM_TAG_U1 1 #define MEM_TAG_U8 2 #define MEM_TAG_U16 3 #define MEM_TAG_U32 4 #define MEM_TAG_U64 5 #define MEM_TAG_U128 6 -#define MEM_TAG_FF 7 #define SENDER_KERNEL_INPUTS_COL_OFFSET 0 #define ADDRESS_KERNEL_INPUTS_COL_OFFSET 1 #define STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET 1 diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index e5763b7bb53..97ec479bea3 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -231,13 +231,13 @@ library Constants { uint256 internal constant TUBE_PROOF_LENGTH = 463; uint256 internal constant HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS = 128; uint256 internal constant CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS = 145; + uint256 internal constant MEM_TAG_FF = 0; uint256 internal constant MEM_TAG_U1 = 1; uint256 internal constant MEM_TAG_U8 = 2; uint256 internal constant MEM_TAG_U16 = 3; uint256 internal constant MEM_TAG_U32 = 4; uint256 internal constant MEM_TAG_U64 = 5; uint256 internal constant MEM_TAG_U128 = 6; - uint256 internal constant MEM_TAG_FF = 7; uint256 internal constant SENDER_KERNEL_INPUTS_COL_OFFSET = 0; uint256 internal constant ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; uint256 internal constant STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 56498fd6f80..1e6937a133c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -405,13 +405,13 @@ global GENERATOR_INDEX__NOTE_HIDING_POINT: u32 = 54; global GENERATOR_INDEX__SYMMETRIC_KEY: u8 = 55; // AVM memory tags +global MEM_TAG_FF = 0; global MEM_TAG_U1 = 1; global MEM_TAG_U8 = 2; global MEM_TAG_U16 = 3; global MEM_TAG_U32 = 4; global MEM_TAG_U64 = 5; global MEM_TAG_U128 = 6; -global MEM_TAG_FF = 7; // AVM CIRCUIT - PUBLIC KERNEL INPUTS COLUMN OFFSETS // Keep the number of offsets aligned with KERNEL_INPUTS_LENGTH defined in constants.hpp diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index 07e05904165..31a1d04880e 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -145,12 +145,6 @@ namespace Program { struct IntegerBitSize { - struct U0 { - friend bool operator==(const U0&, const U0&); - std::vector bincodeSerialize() const; - static U0 bincodeDeserialize(std::vector); - }; - struct U1 { friend bool operator==(const U1&, const U1&); std::vector bincodeSerialize() const; @@ -187,7 +181,7 @@ namespace Program { static U128 bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const IntegerBitSize&, const IntegerBitSize&); std::vector bincodeSerialize() const; @@ -6685,41 +6679,6 @@ Program::IntegerBitSize serde::Deserializable::deserial return obj; } -namespace Program { - - inline bool operator==(const IntegerBitSize::U0 &lhs, const IntegerBitSize::U0 &rhs) { - return true; - } - - inline std::vector IntegerBitSize::U0::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline IntegerBitSize::U0 IntegerBitSize::U0::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::IntegerBitSize::U0 &obj, Serializer &serializer) { -} - -template <> -template -Program::IntegerBitSize::U0 serde::Deserializable::deserialize(Deserializer &deserializer) { - Program::IntegerBitSize::U0 obj; - return obj; -} - namespace Program { inline bool operator==(const IntegerBitSize::U1 &lhs, const IntegerBitSize::U1 &rhs) { diff --git a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs index 947df96387a..599cf9212b3 100644 --- a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs +++ b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs @@ -214,12 +214,12 @@ fn simple_brillig_foreign_call() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 79, 73, 10, 128, 48, 12, 204, 136, 91, 193, 155, - 31, 137, 63, 240, 51, 30, 188, 120, 16, 241, 253, 22, 76, 32, 148, 182, 30, 204, 64, 200, - 100, 66, 150, 1, 189, 24, 99, 64, 120, 39, 89, 107, 11, 213, 86, 201, 252, 15, 11, 252, - 118, 177, 253, 183, 73, 9, 172, 72, 21, 103, 234, 62, 100, 250, 173, 163, 243, 144, 220, - 117, 222, 207, 3, 213, 161, 119, 167, 24, 189, 240, 253, 184, 183, 243, 194, 199, 68, 169, - 46, 233, 115, 166, 247, 0, 1, 178, 238, 151, 120, 2, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 79, 73, 10, 128, 48, 12, 204, 40, 46, 5, 111, 126, + 36, 254, 192, 207, 120, 240, 226, 65, 196, 247, 91, 48, 129, 80, 218, 122, 48, 3, 33, 147, + 9, 89, 6, 244, 98, 140, 1, 225, 157, 100, 173, 45, 84, 91, 37, 243, 63, 44, 240, 219, 197, + 246, 223, 38, 37, 176, 34, 85, 156, 169, 251, 144, 233, 183, 142, 206, 67, 114, 215, 121, + 63, 15, 84, 135, 222, 157, 98, 244, 194, 247, 227, 222, 206, 11, 31, 19, 165, 186, 164, + 207, 153, 222, 3, 91, 101, 84, 220, 120, 2, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -344,17 +344,17 @@ fn complex_brillig_foreign_call() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 93, 10, 194, 48, 12, 78, 127, 116, 27, 248, - 230, 5, 4, 61, 64, 167, 23, 240, 46, 226, 155, 162, 143, 30, 95, 203, 18, 150, 197, 226, - 132, 37, 176, 125, 48, 178, 182, 201, 215, 252, 82, 7, 29, 234, 207, 231, 240, 127, 133, - 210, 163, 204, 251, 1, 134, 32, 221, 51, 202, 52, 13, 173, 211, 227, 74, 86, 62, 250, 5, - 248, 24, 12, 124, 4, 86, 255, 25, 214, 91, 179, 46, 170, 249, 11, 133, 249, 137, 208, 205, - 215, 26, 215, 21, 202, 90, 38, 58, 27, 121, 248, 30, 188, 1, 168, 123, 26, 33, 249, 121, - 212, 139, 232, 212, 136, 123, 149, 249, 19, 101, 99, 7, 255, 197, 107, 19, 231, 49, 17, - 127, 48, 225, 79, 45, 241, 71, 163, 58, 85, 34, 95, 60, 22, 126, 239, 6, 250, 14, 188, 60, - 238, 207, 219, 245, 21, 10, 166, 210, 60, 99, 47, 214, 135, 66, 202, 198, 56, 8, 252, 161, - 249, 165, 239, 10, 250, 99, 54, 91, 232, 219, 137, 30, 182, 55, 110, 54, 167, 171, 245, 6, - 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 93, 10, 194, 48, 12, 78, 155, 233, 54, 240, + 205, 11, 8, 122, 128, 76, 47, 176, 187, 136, 111, 138, 62, 122, 124, 45, 75, 88, 23, 139, + 19, 76, 64, 63, 24, 89, 75, 242, 229, 159, 6, 24, 208, 60, 191, 192, 255, 11, 150, 145, + 101, 186, 71, 152, 66, 116, 123, 150, 244, 29, 186, 96, 199, 69, 94, 49, 198, 63, 136, 17, + 29, 98, 132, 172, 255, 63, 216, 111, 203, 190, 152, 214, 15, 11, 251, 83, 193, 176, 95, 75, + 62, 215, 44, 27, 93, 232, 100, 20, 225, 117, 241, 38, 144, 233, 105, 149, 4, 229, 185, 183, + 201, 232, 208, 42, 191, 198, 252, 36, 213, 216, 192, 103, 249, 250, 228, 185, 39, 225, 71, + 23, 126, 234, 132, 191, 114, 234, 83, 173, 234, 149, 231, 146, 251, 93, 193, 56, 129, 199, + 235, 229, 118, 62, 221, 177, 96, 170, 205, 19, 182, 234, 188, 43, 148, 108, 142, 67, 144, + 63, 52, 239, 244, 67, 65, 127, 206, 102, 13, 227, 56, 201, 195, 246, 0, 155, 0, 46, 128, + 245, 6, 0, 0, ]; assert_eq!(bytes, expected_serialization) diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts index 2bf406edb23..3048b74e51f 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts @@ -1,7 +1,7 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `complex_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. -export const bytecode = Uint8Array.from([31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 93, 10, 194, 48, 12, 78, 127, 116, 27, 248, 230, 5, 4, 61, 64, 167, 23, 240, 46, 226, 155, 162, 143, 30, 95, 203, 18, 150, 197, 226, 132, 37, 176, 125, 48, 178, 182, 201, 215, 252, 82, 7, 29, 234, 207, 231, 240, 127, 133, 210, 163, 204, 251, 1, 134, 32, 221, 51, 202, 52, 13, 173, 211, 227, 74, 86, 62, 250, 5, 248, 24, 12, 124, 4, 86, 255, 25, 214, 91, 179, 46, 170, 249, 11, 133, 249, 137, 208, 205, 215, 26, 215, 21, 202, 90, 38, 58, 27, 121, 248, 30, 188, 1, 168, 123, 26, 33, 249, 121, 212, 139, 232, 212, 136, 123, 149, 249, 19, 101, 99, 7, 255, 197, 107, 19, 231, 49, 17, 127, 48, 225, 79, 45, 241, 71, 163, 58, 85, 34, 95, 60, 22, 126, 239, 6, 250, 14, 188, 60, 238, 207, 219, 245, 21, 10, 166, 210, 60, 99, 47, 214, 135, 66, 202, 198, 56, 8, 252, 161, 249, 165, 239, 10, 250, 99, 54, 91, 232, 219, 137, 30, 182, 55, 110, 54, 167, 171, 245, 6, 0, 0]); +export const bytecode = Uint8Array.from([31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 93, 10, 194, 48, 12, 78, 155, 233, 54, 240, 205, 11, 8, 122, 128, 76, 47, 176, 187, 136, 111, 138, 62, 122, 124, 45, 75, 88, 23, 139, 19, 76, 64, 63, 24, 89, 75, 242, 229, 159, 6, 24, 208, 60, 191, 192, 255, 11, 150, 145, 101, 186, 71, 152, 66, 116, 123, 150, 244, 29, 186, 96, 199, 69, 94, 49, 198, 63, 136, 17, 29, 98, 132, 172, 255, 63, 216, 111, 203, 190, 152, 214, 15, 11, 251, 83, 193, 176, 95, 75, 62, 215, 44, 27, 93, 232, 100, 20, 225, 117, 241, 38, 144, 233, 105, 149, 4, 229, 185, 183, 201, 232, 208, 42, 191, 198, 252, 36, 213, 216, 192, 103, 249, 250, 228, 185, 39, 225, 71, 23, 126, 234, 132, 191, 114, 234, 83, 173, 234, 149, 231, 146, 251, 93, 193, 56, 129, 199, 235, 229, 118, 62, 221, 177, 96, 170, 205, 19, 182, 234, 188, 43, 148, 108, 142, 67, 144, 63, 52, 239, 244, 67, 65, 127, 206, 102, 13, 227, 56, 201, 195, 246, 0, 155, 0, 46, 128, 245, 6, 0, 0]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], [2, '0x0000000000000000000000000000000000000000000000000000000000000002'], diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts index e03e3222883..08123c01c2f 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts @@ -1,7 +1,7 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `simple_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. -export const bytecode = Uint8Array.from([31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 79, 73, 10, 128, 48, 12, 204, 136, 91, 193, 155, 31, 137, 63, 240, 51, 30, 188, 120, 16, 241, 253, 22, 76, 32, 148, 182, 30, 204, 64, 200, 100, 66, 150, 1, 189, 24, 99, 64, 120, 39, 89, 107, 11, 213, 86, 201, 252, 15, 11, 252, 118, 177, 253, 183, 73, 9, 172, 72, 21, 103, 234, 62, 100, 250, 173, 163, 243, 144, 220, 117, 222, 207, 3, 213, 161, 119, 167, 24, 189, 240, 253, 184, 183, 243, 194, 199, 68, 169, 46, 233, 115, 166, 247, 0, 1, 178, 238, 151, 120, 2, 0, 0]); +export const bytecode = Uint8Array.from([31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 79, 73, 10, 128, 48, 12, 204, 40, 46, 5, 111, 126, 36, 254, 192, 207, 120, 240, 226, 65, 196, 247, 91, 48, 129, 80, 218, 122, 48, 3, 33, 147, 9, 89, 6, 244, 98, 140, 1, 225, 157, 100, 173, 45, 84, 91, 37, 243, 63, 44, 240, 219, 197, 246, 223, 38, 37, 176, 34, 85, 156, 169, 251, 144, 233, 183, 142, 206, 67, 114, 215, 121, 63, 15, 84, 135, 222, 157, 98, 244, 194, 247, 227, 222, 206, 11, 31, 19, 165, 186, 164, 207, 153, 222, 3, 91, 101, 84, 220, 120, 2, 0, 0]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000005'], ]); diff --git a/noir/noir-repo/acvm-repo/brillig/src/opcodes.rs b/noir/noir-repo/acvm-repo/brillig/src/opcodes.rs index bc0ec941443..69ca9ed379a 100644 --- a/noir/noir-repo/acvm-repo/brillig/src/opcodes.rs +++ b/noir/noir-repo/acvm-repo/brillig/src/opcodes.rs @@ -102,7 +102,6 @@ pub struct HeapVector { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Copy, PartialOrd, Ord)] pub enum IntegerBitSize { - U0, // Uninitialized U1, U8, U16, @@ -114,7 +113,6 @@ pub enum IntegerBitSize { impl From for u32 { fn from(bit_size: IntegerBitSize) -> u32 { match bit_size { - IntegerBitSize::U0 => 0, IntegerBitSize::U1 => 1, IntegerBitSize::U8 => 8, IntegerBitSize::U16 => 16, @@ -130,7 +128,6 @@ impl TryFrom for IntegerBitSize { fn try_from(value: u32) -> Result { match value { - 0 => Ok(IntegerBitSize::U0), 1 => Ok(IntegerBitSize::U1), 8 => Ok(IntegerBitSize::U8), 16 => Ok(IntegerBitSize::U16), @@ -145,7 +142,6 @@ impl TryFrom for IntegerBitSize { impl std::fmt::Display for IntegerBitSize { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - IntegerBitSize::U0 => write!(f, "null"), IntegerBitSize::U1 => write!(f, "bool"), IntegerBitSize::U8 => write!(f, "u8"), IntegerBitSize::U16 => write!(f, "u16"), diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/memory.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/memory.rs index 81e35ab696e..2bf45f77b54 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/memory.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/memory.rs @@ -136,7 +136,7 @@ impl std::fmt::Display for MemoryValue { impl Default for MemoryValue { fn default() -> Self { - MemoryValue::new_integer(0, IntegerBitSize::U0) + MemoryValue::new_field(F::zero()) } } diff --git a/noir/noir-repo/tooling/debugger/src/repl.rs b/noir/noir-repo/tooling/debugger/src/repl.rs index 1a7c2d6c7a8..012af0e88e8 100644 --- a/noir/noir-repo/tooling/debugger/src/repl.rs +++ b/noir/noir-repo/tooling/debugger/src/repl.rs @@ -1,11 +1,10 @@ use crate::context::{DebugCommandResult, DebugContext, DebugLocation}; -use acvm::acir::brillig::{BitSize, IntegerBitSize}; +use acvm::acir::brillig::BitSize; use acvm::acir::circuit::brillig::{BrilligBytecode, BrilligFunctionId}; use acvm::acir::circuit::{Circuit, Opcode, OpcodeLocation}; use acvm::acir::native_types::{Witness, WitnessMap, WitnessStack}; use acvm::brillig_vm::brillig::Opcode as BrilligOpcode; -use acvm::brillig_vm::MemoryValue; use acvm::{BlackBoxFunctionSolver, FieldElement}; use nargo::NargoError; use noirc_driver::CompiledProgram; @@ -369,11 +368,7 @@ impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { return; }; - for (index, value) in memory - .iter() - .enumerate() - .filter(|(_, value)| !matches!(value, MemoryValue::Integer(_, IntegerBitSize::U0))) - { + for (index, value) in memory.iter().enumerate() { println!("{index} = {}", value); } } diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 393289635a6..c8827126195 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -220,13 +220,13 @@ export const AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS = 86; export const AVM_PROOF_LENGTH_IN_FIELDS = 3848; export const AVM_PUBLIC_COLUMN_MAX_SIZE = 1024; export const AVM_PUBLIC_INPUTS_FLATTENED_SIZE = 2739; +export const MEM_TAG_FF = 0; export const MEM_TAG_U1 = 1; export const MEM_TAG_U8 = 2; export const MEM_TAG_U16 = 3; export const MEM_TAG_U32 = 4; export const MEM_TAG_U64 = 5; export const MEM_TAG_U128 = 6; -export const MEM_TAG_FF = 7; export const SENDER_KERNEL_INPUTS_COL_OFFSET = 0; export const ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; export const STORAGE_ADDRESS_KERNEL_INPUTS_COL_OFFSET = 1; diff --git a/yarn-project/simulator/src/avm/avm_gas.ts b/yarn-project/simulator/src/avm/avm_gas.ts index ea3e955517c..fead5ed3320 100644 --- a/yarn-project/simulator/src/avm/avm_gas.ts +++ b/yarn-project/simulator/src/avm/avm_gas.ts @@ -180,6 +180,7 @@ export function getGasCostForTypeTag(tag: TypeTag, baseCost: Gas) { function getGasCostMultiplierFromTypeTag(tag: TypeTag) { switch (tag) { case TypeTag.UINT1: // same as u8 + return 1; case TypeTag.UINT8: return 1; case TypeTag.UINT16: @@ -193,7 +194,6 @@ function getGasCostMultiplierFromTypeTag(tag: TypeTag) { case TypeTag.FIELD: return 32; case TypeTag.INVALID: - case TypeTag.UNINITIALIZED: throw new InstructionExecutionError(`Invalid tag type for gas cost multiplier: ${TypeTag[tag]}`); } } diff --git a/yarn-project/simulator/src/avm/avm_memory_types.test.ts b/yarn-project/simulator/src/avm/avm_memory_types.test.ts index c122a05aab6..18c3651a2ed 100644 --- a/yarn-project/simulator/src/avm/avm_memory_types.test.ts +++ b/yarn-project/simulator/src/avm/avm_memory_types.test.ts @@ -11,9 +11,9 @@ import { } from './avm_memory_types.js'; describe('TaggedMemory', () => { - it('Elements should be undefined after construction', () => { + it('Elements should be Field(0) after construction', () => { const mem = new TaggedMemory(); - expect(mem.get(10)).toBe(undefined); + expect(mem.get(10)).toStrictEqual(new Field(0)); }); it(`Should set and get integral types`, () => { diff --git a/yarn-project/simulator/src/avm/avm_memory_types.ts b/yarn-project/simulator/src/avm/avm_memory_types.ts index a951e4c0a7e..3831d92ad9a 100644 --- a/yarn-project/simulator/src/avm/avm_memory_types.ts +++ b/yarn-project/simulator/src/avm/avm_memory_types.ts @@ -208,21 +208,19 @@ export class Field extends MemoryValue { } export enum TypeTag { - UNINITIALIZED, + FIELD = MEM_TAG_FF, UINT1 = MEM_TAG_U1, UINT8 = MEM_TAG_U8, UINT16 = MEM_TAG_U16, UINT32 = MEM_TAG_U32, UINT64 = MEM_TAG_U64, UINT128 = MEM_TAG_U128, - FIELD = MEM_TAG_FF, INVALID, } // Lazy interface definition for tagged memory export type TaggedMemoryInterface = FunctionsOf; -// TODO: Consider automatic conversion when getting undefined values. export class TaggedMemory implements TaggedMemoryInterface { static readonly log: DebugLogger = createDebugLogger('aztec:avm_simulator:memory'); @@ -255,6 +253,7 @@ export class TaggedMemory implements TaggedMemoryInterface { TaggedMemory.log.debug(`get(${offset}) = ${word}`); if (word === undefined) { TaggedMemory.log.debug(`WARNING: Memory at offset ${offset} is undefined!`); + return new Field(0) as T; } return word as T; } @@ -264,7 +263,11 @@ export class TaggedMemory implements TaggedMemoryInterface { assert(offset + size < TaggedMemory.MAX_MEMORY_SIZE); const value = this._mem.slice(offset, offset + size); TaggedMemory.log.debug(`getSlice(${offset}, ${size}) = ${value}`); - assert(!value.some(e => e === undefined), 'Memory slice contains undefined values.'); + for (let i = 0; i < value.length; i++) { + if (value[i] === undefined) { + value[i] = new Field(0); + } + } assert(value.length === size, `Expected slice of size ${size}, got ${value.length}.`); return value; } @@ -357,7 +360,9 @@ export class TaggedMemory implements TaggedMemoryInterface { let tag = TypeTag.INVALID; if (v === undefined) { - tag = TypeTag.UNINITIALIZED; + tag = TypeTag.FIELD; // uninitialized memory is Field(0) + } else if (v instanceof Field) { + tag = TypeTag.FIELD; } else if (v instanceof Uint1) { tag = TypeTag.UINT1; } else if (v instanceof Uint8) { @@ -370,8 +375,6 @@ export class TaggedMemory implements TaggedMemoryInterface { tag = TypeTag.UINT64; } else if (v instanceof Uint128) { tag = TypeTag.UINT128; - } else if (v instanceof Field) { - tag = TypeTag.FIELD; } return tag; @@ -381,6 +384,8 @@ export class TaggedMemory implements TaggedMemoryInterface { public static buildFromTagTruncating(v: bigint | number, tag: TypeTag): MemoryValue { v = BigInt(v); switch (tag) { + case TypeTag.FIELD: + return new Field(v); case TypeTag.UINT1: return new Uint1(v & 1n); case TypeTag.UINT8: @@ -393,8 +398,6 @@ export class TaggedMemory implements TaggedMemoryInterface { return new Uint64(v & ((1n << 64n) - 1n)); case TypeTag.UINT128: return new Uint128(v & ((1n << 128n) - 1n)); - case TypeTag.FIELD: - return new Field(v); default: throw new Error(`${TypeTag[tag]} is not a valid tag.`); } @@ -403,6 +406,8 @@ export class TaggedMemory implements TaggedMemoryInterface { // Does not truncate. Type constructor will check that it fits. public static buildFromTagOrDie(v: bigint | number, tag: TypeTag): MemoryValue { switch (tag) { + case TypeTag.FIELD: + return new Field(v); case TypeTag.UINT1: return new Uint1(v); case TypeTag.UINT8: @@ -415,8 +420,6 @@ export class TaggedMemory implements TaggedMemoryInterface { return new Uint64(v); case TypeTag.UINT128: return new Uint128(v); - case TypeTag.FIELD: - return new Field(v); default: throw new Error(`${TypeTag[tag]} is not a valid integral type.`); } diff --git a/yarn-project/simulator/src/avm/opcodes/memory.test.ts b/yarn-project/simulator/src/avm/opcodes/memory.test.ts index f96d3f3f134..e466cbe46c5 100644 --- a/yarn-project/simulator/src/avm/opcodes/memory.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/memory.test.ts @@ -348,7 +348,7 @@ describe('Memory instructions', () => { const addressing = new Addressing([/*srcOffset*/ AddressingMode.DIRECT, /*dstOffset*/ AddressingMode.INDIRECT]); await new Mov(/*indirect=*/ addressing.toWire(), /*srcOffset=*/ 0, /*dstOffset=*/ 10).execute(context); - expect(context.machineState.memory.get(1)).toBeUndefined(); + expect(context.machineState.memory.get(1)).toEqual(new Field(0)); expect(context.machineState.memory.get(20)).toEqual(new Uint16(55n)); });