From b136c1f8ad0ac2033cde9c4b9a81762cf97ec894 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 21 Jun 2024 09:13:51 +0000 Subject: [PATCH 1/2] feat: injecting nonce in pub kernel --- .../src/components/kernel_circuit_output_hints.nr | 6 ++++-- .../components/kernel_circuit_output_validator.nr | 6 +++--- .../kernel_circuit_public_inputs_composer.nr | 7 +++---- .../private-kernel-lib/src/private_kernel_tail.nr | 5 +++-- .../src/private_kernel_tail_to_public.nr | 5 +++-- .../crates/types/src/hash.nr | 14 +++++++------- .../crates/types/src/tests/fixture_builder.nr | 5 +++-- 7 files changed, 26 insertions(+), 22 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_output_hints.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_output_hints.nr index c5f8b18a72a..96d57d0783c 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_output_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_output_hints.nr @@ -44,10 +44,12 @@ unconstrained pub fn generate_hints(previous_kernel: PrivateKernelCircuitPublicI let sorted_note_hash_hints = sort_get_order_hints_asc(previous_kernel.end.new_note_hashes); let mut siloed_note_hashes = [0; MAX_NEW_NOTE_HASHES_PER_TX]; - let first_nullifier = previous_kernel.end.new_nullifiers[0].value(); + + // First nullifier is tx hash. + let tx_hash = previous_kernel.end.new_nullifiers[0].value(); let unsiloed_note_hashes = previous_kernel.end.new_note_hashes; for i in 0..unsiloed_note_hashes.len() { - siloed_note_hashes[i] = silo_note_hash(unsiloed_note_hashes[i], first_nullifier, i); + siloed_note_hashes[i] = silo_note_hash(unsiloed_note_hashes[i], tx_hash, i); } // nullifiers diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_output_validator.nr index 5d8b0495237..ee69034e025 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_output_validator.nr @@ -70,11 +70,11 @@ impl KernelCircuitOutputValidator { } fn validate_propagated_sorted_siloed_values(self, hints: Hints) { - // new_note_hashes - let first_nullifier = self.output.end.new_nullifiers[0]; + // First nullifier is tx hash. + let tx_hash = self.output.end.new_nullifiers[0]; let unsiloed_note_hashes = self.previous_kernel.end.new_note_hashes; for i in 0..unsiloed_note_hashes.len() { - let siloed_note_hash = silo_note_hash(unsiloed_note_hashes[i], first_nullifier, i); + let siloed_note_hash = silo_note_hash(unsiloed_note_hashes[i], tx_hash, i); assert_eq(hints.siloed_note_hashes[i], siloed_note_hash, "mismatch siloed note hashes"); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_public_inputs_composer.nr index f06b4c02ef2..6e2fc4d4c0e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_public_inputs_composer.nr @@ -129,15 +129,14 @@ impl KernelCircuitPublicInputsComposer { } fn silo_note_hashes(&mut self) { - let first_nullifier = self.public_inputs.end.new_nullifiers.get_unchecked(0).value(); - // This check is unnecessary. The 0th nullifier will always be set a non-zero value in private_kernel_init. - // assert(first_nullifier != 0, "The 0th nullifier in the accumulated nullifier array is zero"); + // First nullifier is tx hash. + let tx_hash = self.public_inputs.end.new_nullifiers.get_unchecked(0).value(); let note_hashes = self.public_inputs.end.new_note_hashes.storage; for i in 0..note_hashes.len() { self.public_inputs.end.new_note_hashes.storage[i].note_hash.value = silo_note_hash( note_hashes[i], - first_nullifier, + tx_hash, i ); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr index 67d88eed6fd..ded0f5dbba9 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -123,10 +123,11 @@ mod tests { // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed // note_hashes for the given note_hashes. pub fn compute_output_note_hashes(self, note_hashes: [ScopedNoteHash; N]) -> [Field; N] { - let first_nullifier = self.previous_kernel.new_nullifiers.get_unchecked(0).value(); + // First nullifier is tx hash. + let tx_hash = self.previous_kernel.new_nullifiers.get_unchecked(0).value(); let mut output = [0; N]; for i in 0..N { - output[i] = silo_note_hash(note_hashes[i], first_nullifier, i); + output[i] = silo_note_hash(note_hashes[i], tx_hash, i); } output } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr index 442031e11f2..f7fd4b498ad 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr @@ -109,11 +109,12 @@ mod tests { // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed // note_hashes for the given note_hashes. pub fn compute_output_note_hashes(self, note_hashes: [ScopedNoteHash; N]) -> [NoteHash; N] { - let first_nullifier = self.previous_kernel.new_nullifiers.get_unchecked(0).value(); + // First nullifier is tx hash. + let tx_hash = self.previous_kernel.new_nullifiers.get_unchecked(0).value(); let mut output = [NoteHash::empty(); N]; for i in 0..N { output[i] = NoteHash { - value: silo_note_hash(note_hashes[i], first_nullifier, i), + value: silo_note_hash(note_hashes[i], tx_hash, i), counter: 0, // Counter is cleared so it's not exposed to the public. }; } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr index 561c3d1029b..9bb49144aa5 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr @@ -10,10 +10,9 @@ use crate::{ GENERATOR_INDEX__VK, GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__UNIQUE_NOTE_HASH, MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX }, - contract_class_id::ContractClassId, merkle_tree::root::root_from_sibling_path, - messaging::l2_to_l1_message::{L2ToL1Message, ScopedL2ToL1Message}, - recursion::verification_key::VerificationKey, traits::{Hash, is_empty}, - utils::{uint256::U256, field::field_from_bytes_32_trunc} + merkle_tree::root::root_from_sibling_path, messaging::l2_to_l1_message::ScopedL2ToL1Message, + recursion::verification_key::VerificationKey, traits::is_empty, + utils::field::field_from_bytes_32_trunc }; use dep::std::hash::{pedersen_hash_with_separator, sha256}; @@ -35,7 +34,7 @@ pub fn private_functions_root_from_siblings( root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path) } -pub fn compute_note_hash_nonce(first_nullifier: Field, note_hash_index: u32) -> Field { +fn compute_note_hash_nonce(first_nullifier: Field, note_hash_index: u32) -> Field { pedersen_hash( [ first_nullifier, @@ -60,11 +59,12 @@ pub fn compute_siloed_note_hash(app: AztecAddress, unique_note_hash: Field) -> F ) } -pub fn silo_note_hash(note_hash: ScopedNoteHash, first_nullifier: Field, index: u32) -> Field { +pub fn silo_note_hash(note_hash: ScopedNoteHash, tx_hash: Field, note_index_in_tx: u32) -> Field { if note_hash.contract_address.is_zero() { 0 } else { - let nonce = compute_note_hash_nonce(first_nullifier, index); + // Hashing tx hash with note index in tx is guaranteed to be unique + let nonce = compute_note_hash_nonce(tx_hash, note_index_in_tx); let unique_note_hash = compute_unique_note_hash(nonce, note_hash.value()); compute_siloed_note_hash(note_hash.contract_address, unique_note_hash) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index a0fbb0dacec..34d249c9c12 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -430,10 +430,11 @@ impl FixtureBuilder { } pub fn add_siloed_note_hash(&mut self, value: Field) { - let first_nullifier = self.new_nullifiers.get(0).value(); + // First nullifier is tx hash. + let tx_hash = self.new_nullifiers.get(0).value(); let index = self.new_note_hashes.len(); let note_hash = NoteHash { value, counter: 0 }.scope(0, self.storage_contract_address); - let siloed_value = silo_note_hash(note_hash, first_nullifier, index); + let siloed_value = silo_note_hash(note_hash, tx_hash, index); self.add_new_note_hash(siloed_value, 0); } From 16220f29e6891bb597e99b9ad1b04c8e7c021f40 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 21 Jun 2024 09:15:52 +0000 Subject: [PATCH 2/2] naming fix --- .../noir-protocol-circuits/crates/types/src/hash.nr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr index 9bb49144aa5..9c7a88080e0 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr @@ -34,11 +34,12 @@ pub fn private_functions_root_from_siblings( root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path) } -fn compute_note_hash_nonce(first_nullifier: Field, note_hash_index: u32) -> Field { +fn compute_note_hash_nonce(tx_hash: Field, note_index_in_tx: u32) -> Field { + // Hashing tx hash with note index in tx is guaranteed to be unique pedersen_hash( [ - first_nullifier, - note_hash_index as Field + tx_hash, + note_index_in_tx as Field ], GENERATOR_INDEX__NOTE_HASH_NONCE ) @@ -63,7 +64,6 @@ pub fn silo_note_hash(note_hash: ScopedNoteHash, tx_hash: Field, note_index_in_t if note_hash.contract_address.is_zero() { 0 } else { - // Hashing tx hash with note index in tx is guaranteed to be unique let nonce = compute_note_hash_nonce(tx_hash, note_index_in_tx); let unique_note_hash = compute_unique_note_hash(nonce, note_hash.value()); compute_siloed_note_hash(note_hash.contract_address, unique_note_hash)