Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
"noirc",
"noirup",
"nullifer",
"Nullifiable",
"offchain",
"onchain",
"opentelemetry",
Expand Down
73 changes: 43 additions & 30 deletions noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,26 @@ comptime global NOTE_HEADER_TYPE: Type = type_of(NoteHeader::empty());
pub comptime mut global NOTES: UHashMap<Type, (StructDefinition, u32, Field, [(Quoted, u32, bool)]), BuildHasherDefault<Poseidon2Hasher>> =
UHashMap::default();

/// Computes a note type id by hashing a note name (e.g. `TokenNote`), getting the first 4 bytes of the hash
/// and returning it as a `Field`.
comptime fn compute_note_type_id(name: Quoted) -> Field {
let (name_as_str_quote, _) = name.as_str_quote();
pub comptime mut global NOTE_TYPE_ID_COUNTER: u32 = 0;

/// The note type id is set by enumerating the note types.
comptime fn get_next_note_type_id() -> Field {
// We assert that the note type id fits within 7 bits
assert(
NOTE_TYPE_ID_COUNTER < 128 as u32,
"A contract can contain at most 128 different note types",
);

unquote!(
quote {
let bytes = $name_as_str_quote.as_bytes();
let hash = protocol_types::hash::poseidon2_hash_bytes(bytes);
let hash_bytes = hash.to_be_bytes::<4>();
protocol_types::utils::field::field_from_bytes(hash_bytes, true)
},
)
let note_type_id = NOTE_TYPE_ID_COUNTER as Field;
NOTE_TYPE_ID_COUNTER += 1;
note_type_id
}

/// Generates default `NoteInterface` implementation for a given note struct `s` and returns it as quote along with
/// the length of the serialized note.
///
/// impl NoteInterface<N> for NoteStruct {
/// fn to_be_bytes(self, storage_slot: Field) -> [u8; N * 32 + 64] {
/// fn to_be_bytes(self, storage_slot: Field) -> [u8; N * 32 + 34] {
/// ...
/// }
///
Expand Down Expand Up @@ -117,23 +117,27 @@ comptime fn generate_note_interface(
(
quote {
impl aztec::note::note_interface::NoteInterface<$content_len> for $name {
fn to_be_bytes(self, storage_slot: Field) -> [u8; $content_len * 32 + 64] {
let serialized_note = self.serialize_content();

let mut buffer: [u8; $content_len * 32 + 64] = [0; $content_len * 32 + 64];
fn to_be_bytes(self, storage_slot: Field) -> [u8; $content_len * 32 + 34] {
let mut buffer: [u8; $content_len * 32 + 34] = [0; $content_len * 32 + 34];

let storage_slot_bytes: [u8; 32] = storage_slot.to_be_bytes();
let note_type_id_bytes: [u8; 32] = $name::get_note_type_id().to_be_bytes();
// TODO(#10724): Since `note_type_id` is 7 bits long in the 2 bytes there is a space for a 1 bit
// partial note flag.
let note_type_id_bytes: [u8; 2] = $name::get_note_type_id().to_be_bytes();
let serialized_note = self.serialize_content();

for i in 0..32 {
buffer[i] = storage_slot_bytes[i];
}

for i in 0..2 {
buffer[32 + i] = note_type_id_bytes[i];
}

for i in 0..serialized_note.len() {
let bytes: [u8; 32] = serialized_note[i].to_be_bytes();
for j in 0..32 {
buffer[64 + i * 32 + j] = bytes[j];
buffer[34 + i * 32 + j] = bytes[j];
}
}
buffer
Expand Down Expand Up @@ -370,18 +374,21 @@ comptime fn generate_multi_scalar_mul(
///
/// let let storage_slot_bytes = storage_slot.to_be_bytes();
/// let let note_type_id_bytes = TokenNote::get_note_type_id().to_be_bytes();
/// let serialized_note = [npk_m_hash as Field, randomness as Field];
///
/// for i in 0..32 {
/// log_plaintext[i] = storage_slot_bytes[i];
/// }
///
/// for i in 0..2 {
/// log_plaintext[32 + i] = note_type_id_bytes[i];
/// }
///
/// let serialized_note = [npk_m_hash as Field, randomness as Field];
///
/// for i in 0..serialized_note.len() {
/// let bytes: [u8; 32] = serialized_note[i].to_be_bytes();
/// for j in 0..32 {
/// log_plaintext[64 + i * 32 + j] = bytes[j];
/// log_plaintext[34 + i * 32 + j] = bytes[j];
/// }
/// }
///
Expand Down Expand Up @@ -430,7 +437,7 @@ comptime fn generate_setup_payload(
.join(quote {,});

// Then the log plaintext ones
let log_plaintext_length = indexed_fixed_fields.len() * 32 + 64;
let log_plaintext_length = indexed_fixed_fields.len() * 32 + 34;
let setup_log_plaintext =
get_setup_log_plaintext_body(s, log_plaintext_length, indexed_nullable_fields);

Expand All @@ -441,7 +448,7 @@ comptime fn generate_setup_payload(
+ 2 /* log_plaintext_length */
+ 14 /* AES padding */;
// Each field contains 31 bytes so the length in fields is computed as ceil(encrypted_log_byte_length / 31)
// --> we achieve rouding by adding 30 and then dividing without remainder
// --> we achieve rounding by adding 30 and then dividing without remainder
let encrypted_log_field_length = (encrypted_log_byte_length + 30) / 31;

(
Expand Down Expand Up @@ -519,10 +526,15 @@ comptime fn get_setup_log_plaintext_body(
let mut log_plaintext: [u8; $log_plaintext_length] = [0; $log_plaintext_length];

let storage_slot_bytes: [u8; 32] = storage_slot.to_be_bytes();
let note_type_id_bytes: [u8; 32] = $name::get_note_type_id().to_be_bytes();
// TODO(#10724): Since `note_type_id` is 7 bits long in the 2 bytes there is a space for a 1 bit partial note
// flag.
let note_type_id_bytes: [u8; 2] = $name::get_note_type_id().to_be_bytes();

for i in 0..32 {
log_plaintext[i] = storage_slot_bytes[i];
}

for i in 0..2 {
log_plaintext[32 + i] = note_type_id_bytes[i];
}

Expand All @@ -532,7 +544,7 @@ comptime fn get_setup_log_plaintext_body(
for i in 0..serialized_note.len() {
let bytes: [u8; 32] = serialized_note[i].to_be_bytes();
for j in 0..32 {
log_plaintext[64 + i * 32 + j] = bytes[j];
log_plaintext[34 + i * 32 + j] = bytes[j];
}
}
}
Expand Down Expand Up @@ -654,14 +666,14 @@ comptime fn generate_finalization_payload(
let args = args_list.join(quote {,});

// Then we compute values for `encrypt_log(...)` function
let setup_log_plaintext_length = indexed_fixed_fields.len() * 32 + 64;
let setup_log_plaintext_length = indexed_fixed_fields.len() * 32 + 34;
let setup_log_byte_length = 32 /* tag */
+ OVERHEAD_SIZE
+ setup_log_plaintext_length
+ 2 /* log_plaintext_length */
+ 14 /* AES padding */;
// Each field contains 31 bytes so the length in fields is computed as ceil(setup_log_byte_length / 31)
// --> we achieve rouding by adding 30 and then dividing without remainder
// --> we achieve rounding by adding 30 and then dividing without remainder
let setup_log_field_length = (setup_log_byte_length + 30) / 31;
let public_values_field_length = public_values_length * 32;
let finalization_log_byte_length =
Expand Down Expand Up @@ -871,7 +883,7 @@ pub comptime fn partial_note(s: StructDefinition, nullable_fields: [Quoted]) ->
inject_note_header(s);

let note_properties = generate_note_properties(s);
let note_type_id = compute_note_type_id(s.name());
let note_type_id = get_next_note_type_id();
let (setup_payload_impl, setup_payload_name) =
generate_setup_payload(s, indexed_fixed_fields, indexed_nullable_fields);
let (finalization_payload_impl, finalization_payload_name) =
Expand All @@ -893,6 +905,7 @@ pub comptime fn partial_note(s: StructDefinition, nullable_fields: [Quoted]) ->
);

quote {
l
$note_properties
$setup_payload_impl
$finalization_payload_impl
Expand All @@ -914,7 +927,7 @@ pub comptime fn note(s: StructDefinition) -> Quoted {
inject_note_header(s);

let note_properties = generate_note_properties(s);
let note_type_id = compute_note_type_id(s.name());
let note_type_id = get_next_note_type_id();
let (note_interface_impl, note_serialized_len) = generate_note_interface(
s,
note_type_id,
Expand Down Expand Up @@ -944,7 +957,7 @@ pub comptime fn note_custom_interface(s: StructDefinition) -> Quoted {
inject_note_header(s);

let note_properties = generate_note_properties(s);
let note_type_id = compute_note_type_id(s.name());
let note_type_id = get_next_note_type_id();
let serialized_len_type = fresh_type_variable();
let note_interface_impl = s.as_type().get_trait_impl(
quote { crate::note::note_interface::NoteInterface<$serialized_len_type> }
Expand Down
1 change: 0 additions & 1 deletion noir-projects/aztec-nr/aztec/src/note/note_type_id.nr

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ contract Token {
fn _store_payload_in_transient_storage_unsafe(
slot: Field,
point: Point,
setup_log: [Field; 9],
setup_log: [Field; 8],
) {
context.storage_write(slot, point);
context.storage_write(slot + aztec::protocol_types::point::POINT_LENGTH as Field, setup_log);
Expand Down
Binary file modified noir-projects/noir-protocol-circuits/.yarn/install-state.gz
Binary file not shown.
3 changes: 2 additions & 1 deletion noir-projects/noir-protocol-circuits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"main": "index.js",
"dependencies": {
"@iarna/toml": "^2.2.5"
}
},
"packageManager": "yarn@4.5.2+sha512.570504f67349ef26d2d86a768dc5ec976ead977aa086b0bb4237e97d5db7ae5c620f9f0e0edf3ea5047205063faff102bf2a2d778664a94eaaa1085ad483fe2e"
}
2 changes: 1 addition & 1 deletion yarn-project/circuit-types/src/interfaces/pxe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ export interface PXE {
isContractInitialized(address: AztecAddress): Promise<boolean>;

/**
* Returns the enctypred events given search parameters.
* Returns the encrypted events given search parameters.
* @param eventMetadata - Metadata of the event. This should be the class generated from the contract. e.g. Contract.events.Event
* @param from - The block number to search from.
* @param limit - The amount of blocks to search.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ export class L1NotePayload {
): L1NotePayload | undefined {
try {
const reader = BufferReader.asReader(plaintext);
const fields = reader.readArray(plaintext.length / Fr.SIZE_IN_BYTES, Fr);

const storageSlot = fields[0];
const noteTypeId = NoteSelector.fromField(fields[1]);
const storageSlot = reader.readObject(Fr);
// TODO(#10724): Since `note_type_id` is 7 bits long in the 2 bytes there is a space for a 1 bit partial note
// flag.
const noteTypeId = new NoteSelector(reader.readUInt16());

const privateNoteValues = fields.slice(2);
const privateNoteValues = reader.readArray(reader.remainingBytes() / Fr.SIZE_IN_BYTES, Fr);

return new L1NotePayload(contractAddress, storageSlot, noteTypeId, privateNoteValues, publicNoteValues);
} catch (e) {
Expand Down