From 1bc1f0b7d1bfe16cf60f590b5121314a339c1191 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Fri, 1 Aug 2025 20:43:35 +0000 Subject: [PATCH 1/3] explicitly duplicate uncosntrained logging funcs rather than using --- avm-transpiler/Cargo.lock | 32 ++++++------- .../aztec/src/event/event_interface.nr | 14 ++++-- .../aztec-nr/aztec/src/messages/logs/event.nr | 31 ++++++++++++ .../aztec-nr/aztec/src/messages/logs/note.nr | 48 +++++++++++++++++-- .../aztec/src/utils/remove_constraints.nr | 7 ++- noir/noir-repo-ref | 2 +- yarn-project/yarn.lock | 16 +++---- 7 files changed, 117 insertions(+), 33 deletions(-) diff --git a/avm-transpiler/Cargo.lock b/avm-transpiler/Cargo.lock index ea813e0a8115..d1d1b897b32a 100644 --- a/avm-transpiler/Cargo.lock +++ b/avm-transpiler/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "acir" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acir_field", "base64 0.22.1", @@ -27,7 +27,7 @@ dependencies = [ [[package]] name = "acir_field" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "ark-bn254", "ark-ff", @@ -40,7 +40,7 @@ dependencies = [ [[package]] name = "acvm" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acir", "acvm_blackbox_solver", @@ -54,7 +54,7 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acir", "blake2", @@ -467,7 +467,7 @@ dependencies = [ [[package]] name = "bn254_blackbox_solver" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acir", "acvm_blackbox_solver", @@ -491,7 +491,7 @@ dependencies = [ [[package]] name = "brillig" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acir_field", "serde", @@ -499,7 +499,7 @@ dependencies = [ [[package]] name = "brillig_vm" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acir", "acvm_blackbox_solver", @@ -922,7 +922,7 @@ dependencies = [ [[package]] name = "fm" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "codespan-reporting", "iter-extended", @@ -1122,7 +1122,7 @@ checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" [[package]] name = "iter-extended" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" [[package]] name = "itertools" @@ -1224,7 +1224,7 @@ checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "noir_protobuf" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "color-eyre", "prost", @@ -1232,7 +1232,7 @@ dependencies = [ [[package]] name = "noirc_abi" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acvm", "iter-extended", @@ -1247,11 +1247,11 @@ dependencies = [ [[package]] name = "noirc_arena" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" [[package]] name = "noirc_errors" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acvm", "base64 0.22.1", @@ -1268,7 +1268,7 @@ dependencies = [ [[package]] name = "noirc_evaluator" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acvm", "bn254_blackbox_solver", @@ -1297,7 +1297,7 @@ dependencies = [ [[package]] name = "noirc_frontend" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acvm", "bn254_blackbox_solver", @@ -1326,7 +1326,7 @@ dependencies = [ [[package]] name = "noirc_printable_type" -version = "1.0.0-beta.8" +version = "1.0.0-beta.9" dependencies = [ "acvm", "iter-extended", diff --git a/noir-projects/aztec-nr/aztec/src/event/event_interface.nr b/noir-projects/aztec-nr/aztec/src/event/event_interface.nr index da325e3be94d..680060c83f68 100644 --- a/noir-projects/aztec-nr/aztec/src/event/event_interface.nr +++ b/noir-projects/aztec-nr/aztec/src/event/event_interface.nr @@ -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, @@ -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); @@ -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. diff --git a/noir-projects/aztec-nr/aztec/src/messages/logs/event.nr b/noir-projects/aztec-nr/aztec/src/messages/logs/event.nr index c6788ae07c76..1e4b74d9ca18 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/logs/event.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/logs/event.nr @@ -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, + 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) +} diff --git a/noir-projects/aztec-nr/aztec/src/messages/logs/note.nr b/noir-projects/aztec-nr/aztec/src/messages/logs/note.nr index 5c84fce086c3..efad4a0f5192 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/logs/note.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/logs/note.nr @@ -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, @@ -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, + 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, storage_slot: Field, @@ -67,6 +78,37 @@ where let mut msg_content = [0; 1 + ::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, + 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 + ::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]; } @@ -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(); @@ -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 diff --git a/noir-projects/aztec-nr/aztec/src/utils/remove_constraints.nr b/noir-projects/aztec-nr/aztec/src/utils/remove_constraints.nr index 3e0f22da78a7..23480a8e0eb1 100644 --- a/noir-projects/aztec-nr/aztec/src/utils/remove_constraints.nr +++ b/noir-projects/aztec-nr/aztec/src/utils/remove_constraints.nr @@ -12,7 +12,12 @@ pub fn remove_constraints_if(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 { diff --git a/noir/noir-repo-ref b/noir/noir-repo-ref index 384f72beed4e..af0f8729eafc 100644 --- a/noir/noir-repo-ref +++ b/noir/noir-repo-ref @@ -1 +1 @@ -b28776c8a68dbc319e2ffcee350b8e2a71b20096 +2a0b7686dbbe73404a16c7d4f3cf930207a1f28f diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 71fcda350fc8..74632da40c00 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -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: @@ -960,14 +960,14 @@ __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 @@ -975,7 +975,7 @@ __metadata: 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 From 28e5c4a76a89a48dbe15f51c2100c3b8236ec14e Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Fri, 1 Aug 2025 21:33:46 +0000 Subject: [PATCH 2/3] update ref with passing noir test --- noir/noir-repo-ref | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir/noir-repo-ref b/noir/noir-repo-ref index af0f8729eafc..8f910589dc9d 100644 --- a/noir/noir-repo-ref +++ b/noir/noir-repo-ref @@ -1 +1 @@ -2a0b7686dbbe73404a16c7d4f3cf930207a1f28f +52e104a75538bcd8e856477aa7f99ef69d9d1b34 From b1960e0eafc99c1e4a5d71700d1b7801e6695b97 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Mon, 4 Aug 2025 13:49:08 +0000 Subject: [PATCH 3/3] bump noir ref --- noir/noir-repo-ref | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir/noir-repo-ref b/noir/noir-repo-ref index 8f910589dc9d..b7badad1d41d 100644 --- a/noir/noir-repo-ref +++ b/noir/noir-repo-ref @@ -1 +1 @@ -52e104a75538bcd8e856477aa7f99ef69d9d1b34 +9b53a79a5fe552092181348c52938732535b82cf