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
32 changes: 16 additions & 16 deletions avm-transpiler/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions noir-projects/aztec-nr/aztec/src/event/event_interface.nr
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use crate::{
context::{PrivateContext, PublicContext},
event::event_selector::EventSelector,
messages::{
logs::{event::to_encrypted_private_event_message, utils::prefix_with_tag},
logs::{event::to_encrypted_private_event_message_unconstrained, utils::prefix_with_tag},
offchain_messages::emit_offchain_message,
},
utils::remove_constraints::{remove_constraints, remove_constraints_if},
utils::remove_constraints::remove_constraints_if,
};
use dep::protocol_types::{
address::AztecAddress,
Expand Down Expand Up @@ -53,9 +53,15 @@ where
// usage is requested. If `constraints` were a runtime value then performance would suffer.
assert_constant(constraints);

crate::oracle::debug_log::debug_log_format("constraints: {0}", [constraints as Field]);
let (ciphertext, randomness) = remove_constraints_if(
constraints == PrivateLogContent.NO_CONSTRAINTS,
|| to_encrypted_private_event_message(event, recipient),
|| {
// Safety: testing
unsafe {
to_encrypted_private_event_message_unconstrained(event, recipient)
}
},
);
let log_content = prefix_with_tag(ciphertext, recipient);

Expand Down Expand Up @@ -93,7 +99,7 @@ where
{
// Safety: as explained above, this function places no constraints on the content of the message.
let (message_ciphertext, randomness) =
unsafe { remove_constraints(|| to_encrypted_private_event_message(event, recipient)) };
unsafe { to_encrypted_private_event_message_unconstrained(event, recipient) };

// We generate a cryptographic commitment to the event to ensure its authenticity during out-of-band delivery. Note
// that the commitment is made from the (constrained) event content, and not the (unconstrained) ciphertext.
Expand Down
31 changes: 31 additions & 0 deletions noir-projects/aztec-nr/aztec/src/messages/logs/event.nr
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,34 @@ where

(AES128::encrypt_log(plaintext, recipient), randomness)
}

/// Creates an encrypted private event message (i.e. one of type `PRIVATE_EVENT_MSG_TYPE_ID`) by encoding the contents
/// of the event and then encrypting them for `recipient`.
pub unconstrained fn to_encrypted_private_event_message_unconstrained<Event>(
event: Event,
recipient: AztecAddress,
) -> ([Field; PRIVATE_LOG_CIPHERTEXT_LEN], Field)
where
Event: EventInterface + Serialize,
{
// In private events, we automatically inject randomness to prevent event commitment preimage attacks and event
// commitment collisions (the commitments are included in the nullifier tree and duplicate nullifiers are by
// definition not allowed).
// Safety: We use the randomness to preserve the privacy of the event recipient by preventing brute-forcing,
// so a malicious sender could use non-random values to make the event less private. But they already know
// the full event pre-image anyway, and so the recipient already trusts them to not disclose this information.
// We can therefore assume that the sender will cooperate in the random value generation.
let randomness = random();

// TODO(#11571): with decryption happening in Noir we can now use the Packable trait instead.
let serialized_event_with_randomness = [randomness].concat(event.serialize());

// Private events are encoded by placing the event type id (which is expected to fit in 32 bits) in the metadata.
let plaintext = encode_message(
PRIVATE_EVENT_MSG_TYPE_ID,
Event::get_event_type_id().to_field() as u64,
serialized_event_with_randomness,
);

(AES128::encrypt_log(plaintext, recipient), randomness)
}
48 changes: 45 additions & 3 deletions noir-projects/aztec-nr/aztec/src/messages/logs/note.nr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
offchain_messages::emit_offchain_message,
},
note::{note_emission::NoteEmission, note_interface::NoteType},
utils::{array::subarray::subarray, remove_constraints::remove_constraints},
utils::array::subarray::subarray,
};
use protocol_types::{
abis::note_hash::NoteHash,
Expand Down Expand Up @@ -36,6 +36,17 @@ where
compute_log(note, storage_slot, recipient, PRIVATE_NOTE_MSG_TYPE_ID)
}

pub unconstrained fn compute_note_log_unconstrained<Note>(
note: Note,
storage_slot: Field,
recipient: AztecAddress,
) -> [Field; PRIVATE_LOG_SIZE_IN_FIELDS]
where
Note: NoteType + Packable,
{
compute_log_unconstrained(note, storage_slot, recipient, PRIVATE_NOTE_MSG_TYPE_ID)
}

pub fn compute_partial_note_log<Note>(
note: Note,
storage_slot: Field,
Expand Down Expand Up @@ -67,6 +78,37 @@ where
let mut msg_content = [0; 1 + <Note as Packable>::N];
msg_content[0] = storage_slot;
for i in 0..packed_note.len() {
crate::oracle::debug_log::debug_log_format("packed note field: {0}", [packed_note[i]]);
msg_content[1 + i] = packed_note[i];
}

// Notes use the note type id for metadata
let plaintext = encode_message(msg_type, Note::get_id() as u64, msg_content);

let ciphertext = AES128::encrypt_log(plaintext, recipient);

let log = prefix_with_tag(ciphertext, recipient);

log
}

unconstrained fn compute_log_unconstrained<Note>(
note: Note,
storage_slot: Field,
recipient: AztecAddress,
msg_type: u64,
) -> [Field; PRIVATE_LOG_SIZE_IN_FIELDS]
where
Note: NoteType + Packable,
{
let packed_note = note.pack();

crate::oracle::debug_log::debug_log("hello");
// A note message's content is the storage slot followed by the packed note representation
let mut msg_content = [0; 1 + <Note as Packable>::N];
msg_content[0] = storage_slot;
for i in 0..packed_note.len() {
crate::oracle::debug_log::debug_log_format("packed note field: {0}", [packed_note[i]]);
msg_content[1 + i] = packed_note[i];
}

Expand Down Expand Up @@ -124,7 +166,7 @@ where

// Safety: this function does not constrain the encryption of the log, as explained on its description.
let encrypted_log =
unsafe { remove_constraints(|| compute_note_log(note, storage_slot, recipient)) };
unsafe { compute_note_log_unconstrained(note, storage_slot, recipient) };
// Regardless of the original note size `N`, the log is padded with random bytes up to
// `PRIVATE_LOG_SIZE_IN_FIELDS` to prevent leaking information about the actual size.
let length = encrypted_log.len();
Expand Down Expand Up @@ -158,7 +200,7 @@ where

// Safety: this function does not constrain the encryption of the log, as explained on its description.
let encrypted_log =
unsafe { remove_constraints(|| compute_note_log(note, storage_slot, recipient)) };
unsafe { compute_note_log_unconstrained(note, storage_slot, recipient) };

// Remove the tag from the log
// TODO: This is a tech debt. We should refactor this file such that the log is by default computed without
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ pub fn remove_constraints_if<Env, T>(condition: bool, f: fn[Env]() -> T) -> T {
// If `condition` is not a compile-time constant, then the compiler won't optimize away the branch not taken in the
// if statement below, and we may end up with constraints for `f` regardless of the runtime value of `condition`.
assert_constant(condition);

crate::oracle::debug_log::debug_log_format("condition: {0}", [condition as Field]);
let is_unconstrained = std::runtime::is_unconstrained();
crate::oracle::debug_log::debug_log_format(
"is_unconstrained: {0}",
[is_unconstrained as Field],
);
if condition {
// Safety: the purpose of this function is to execute `f` with no constraints when `condition` is true.
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion noir/noir-repo-ref
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b28776c8a68dbc319e2ffcee350b8e2a71b20096
9b53a79a5fe552092181348c52938732535b82cf
16 changes: 8 additions & 8 deletions yarn-project/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@aztec/noir-noir_codegen@portal:../noir/packages/noir_codegen::locator=%40aztec%2Faztec3-packages%40workspace%3A."
dependencies:
"@aztec/noir-types": "npm:1.0.0-beta.8"
"@aztec/noir-types": "npm:1.0.0-beta.9"
glob: "npm:^11.0.2"
ts-command-line-args: "npm:^2.5.1"
bin:
Expand All @@ -960,22 +960,22 @@ __metadata:
linkType: soft

"@aztec/noir-noir_js@file:../noir/packages/noir_js::locator=%40aztec%2Faztec3-packages%40workspace%3A.":
version: 1.0.0-beta.8
resolution: "@aztec/noir-noir_js@file:../noir/packages/noir_js#../noir/packages/noir_js::hash=0b938a&locator=%40aztec%2Faztec3-packages%40workspace%3A."
version: 1.0.0-beta.9
resolution: "@aztec/noir-noir_js@file:../noir/packages/noir_js#../noir/packages/noir_js::hash=6d22a4&locator=%40aztec%2Faztec3-packages%40workspace%3A."
dependencies:
"@aztec/noir-acvm_js": "npm:1.0.0-beta.8"
"@aztec/noir-noirc_abi": "npm:1.0.0-beta.8"
"@aztec/noir-types": "npm:1.0.0-beta.8"
"@aztec/noir-acvm_js": "npm:1.0.0-beta.9"
"@aztec/noir-noirc_abi": "npm:1.0.0-beta.9"
"@aztec/noir-types": "npm:1.0.0-beta.9"
pako: "npm:^2.1.0"
checksum: 10/95686ffa46786c421f2f632d0993967ade29ba4af068c352b76a6ad5fc72bd45d50b7d35c06531b8e937e345765e2307e3eb382076cf8659fe58c776717e25dd
checksum: 10/8dae123556c3119c1f8959f2ebcbe00986dbf9b2a25b9c4b6b2a11482aed1f1a07ddd554afdfaac0cd6479d19f91485974ecca6949ef663938bb30e5c2f671da
languageName: node
linkType: hard

"@aztec/noir-noirc_abi@portal:../noir/packages/noirc_abi::locator=%40aztec%2Faztec3-packages%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/noir-noirc_abi@portal:../noir/packages/noirc_abi::locator=%40aztec%2Faztec3-packages%40workspace%3A."
dependencies:
"@aztec/noir-types": "npm:1.0.0-beta.8"
"@aztec/noir-types": "npm:1.0.0-beta.9"
languageName: node
linkType: soft

Expand Down
Loading