From 098b7d6bb6c363f16d2d45725ed44baa9ef58680 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Wed, 3 Jul 2024 08:30:51 +0000 Subject: [PATCH 1/3] Remove note hash nullifier counter. --- .../components/previous_kernel_validator.nr | 7 +- ...private_kernel_circuit_output_validator.nr | 41 +-- ...e_kernel_circuit_public_inputs_composer.nr | 13 +- .../src/private_kernel_init.nr | 19 +- .../src/private_kernel_inner.nr | 19 +- .../src/private_kernel_reset.nr | 58 ++-- .../validate_note_logs.nr | 2 +- ...kernel_circuit_output_validator_builder.nr | 9 +- .../validate_propagated_from_private_call.nr | 91 ------ ..._circuit_public_inputs_composer_builder.nr | 9 +- ..._from_previous_kernel_with_private_call.nr | 61 ---- .../propagate_from_private_call.nr | 49 ---- .../crates/reset-kernel-lib/src/lib.nr | 8 +- .../src/note_hash_read_request_reset.nr | 23 +- .../src/reset/transient_data.nr | 271 +++++++++++------- .../transient_data_reset_hints.nr | 28 ++ .../src/tests/squash_transient_data.nr | 37 +-- .../rollup-lib/src/base/base_rollup_inputs.nr | 2 +- .../crates/types/src/abis/note_hash.nr | 13 +- .../crates/types/src/constants.nr | 2 +- .../crates/types/src/tests/fixture_builder.nr | 14 +- ...build_note_hash_read_request_hints.test.ts | 2 +- .../build_note_hash_read_request_hints.ts | 3 +- .../hints/build_transient_data_hints.test.ts | 33 +-- .../src/hints/build_transient_data_hints.ts | 33 +-- ...vate_kernel_init_circuit_private_inputs.ts | 25 +- ...ate_kernel_inner_circuit_private_inputs.ts | 20 +- ...ate_kernel_reset_circuit_private_inputs.ts | 7 - .../circuits.js/src/structs/note_hash.ts | 24 +- .../src/type_conversion.ts | 21 -- .../src/kernel_prover/kernel_prover.test.ts | 1 - .../pxe/src/kernel_prover/kernel_prover.ts | 19 +- .../build_private_kernel_init_hints.ts | 17 -- .../build_private_kernel_inner_hints.ts | 17 -- .../build_private_kernel_reset_hints.ts | 17 +- .../private_inputs_builders/index.ts | 2 - 36 files changed, 314 insertions(+), 703 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data/transient_data_reset_hints.nr delete mode 100644 yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts delete mode 100644 yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_inner_hints.ts diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator.nr index 27d7ce6d667..7ffc8575e9c 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator.nr @@ -63,11 +63,8 @@ impl PreviousKernelValidator { } fn verify_no_transient_data(self) { - // Currently all the transient note hashes and nullifiers must be cleared in the reset circuits. - // Check that the propagated note hashes don't link to a nullifier, and vice versa. - for note_hash in self.previous_kernel.end.new_note_hashes { - assert_eq(note_hash.nullifier_counter, 0, "Unresolved transient note hash"); - } + // Currently all the transient nullifiers must be cleared in the reset circuits. + // When a transient nullifier is removed, the linked note hash and all the associated note logs will also be removed. for new_nullifier in self.previous_kernel.end.new_nullifiers { assert_eq(new_nullifier.nullified_note_hash(), 0, "Unresolved transient nullifier"); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr index 898486eb8d9..13a0dc52330 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr @@ -3,7 +3,7 @@ use dep::types::{ abis::{ call_request::CallRequest, kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths}, - max_block_number::MaxBlockNumber, note_hash::ScopedNoteHash, + max_block_number::MaxBlockNumber, private_circuit_public_inputs::{PrivateCircuitPublicInputs, PrivateCircuitPublicInputsArrayLengths}, private_kernel::private_call_data::PrivateCallData, side_effect::Scoped }, @@ -103,28 +103,6 @@ fn validate_array_appended_reversed_scoped( } } -fn validate_note_hash_nullifier_counters( - dest: [ScopedNoteHash; N], - note_hash_nullifier_counters: [u32; M], - num_source_items: u32, - num_prepended_items: u32 -) { - let mut is_non_empty_item = true; - for i in 0..M { - is_non_empty_item &= i != num_source_items; - if is_non_empty_item { - let nullifier_counter = note_hash_nullifier_counters[i]; - let note_hash = dest[i + num_prepended_items]; - assert( - (nullifier_counter == 0) | (nullifier_counter > note_hash.counter()), "invalid nullifier counter" - ); - assert_eq( - note_hash.nullifier_counter, nullifier_counter, "incorrect nullifier counter assigned to dest" - ); - } - } -} - struct PrivateKernelCircuitOutputValidator { output: PrivateKernelCircuitPublicInputs, } @@ -134,13 +112,12 @@ impl PrivateKernelCircuitOutputValidator { PrivateKernelCircuitOutputValidator { output } } - pub fn validate_as_first_call( + pub fn validate_as_first_call( self, tx_request: TxRequest, private_call: PrivateCircuitPublicInputs, private_call_array_lengths: PrivateCircuitPublicInputsArrayLengths, contract_address: AztecAddress, - note_hash_nullifier_counters: [u32; NOTE_HASH_NULLIFIER_COUNTERS_LEN], public_call_requests: [CallRequest; PUBLIC_CALL_REQUESTS_LEN], public_teardown_call_request: CallRequest ) { @@ -153,19 +130,17 @@ impl PrivateKernelCircuitOutputValidator { offsets, 0, // num_popped_call contract_address, - note_hash_nullifier_counters, public_call_requests ); } - pub fn validate_as_inner_call( + pub fn validate_as_inner_call( self, previous_kernel: PrivateKernelCircuitPublicInputs, previous_kernel_array_lengths: PrivateKernelCircuitPublicInputsArrayLengths, private_call: PrivateCircuitPublicInputs, private_call_array_lengths: PrivateCircuitPublicInputsArrayLengths, contract_address: AztecAddress, - note_hash_nullifier_counters: [u32; NOTE_HASH_NULLIFIER_COUNTERS_LEN], public_call_requests: [CallRequest; PUBLIC_CALL_REQUESTS_LEN], public_teardown_call_request: CallRequest ) { @@ -177,7 +152,6 @@ impl PrivateKernelCircuitOutputValidator { previous_kernel_array_lengths, 1, // num_popped_call contract_address, - note_hash_nullifier_counters, public_call_requests ); } @@ -336,14 +310,13 @@ impl PrivateKernelCircuitOutputValidator { ); } - fn validate_propagated_from_private_call( + fn validate_propagated_from_private_call( self, private_call: PrivateCircuitPublicInputs, array_lengths: PrivateCircuitPublicInputsArrayLengths, offsets: PrivateKernelCircuitPublicInputsArrayLengths, num_popped_call: u32, contract_address: AztecAddress, - note_hash_nullifier_counters: [u32; NOTE_HASH_NULLIFIER_COUNTERS_LEN], public_call_requests: [CallRequest; PUBLIC_CALL_REQUESTS_LEN] ) { let storage_contract_address = private_call.call_context.storage_contract_address; @@ -375,12 +348,6 @@ impl PrivateKernelCircuitOutputValidator { offsets.new_note_hashes, storage_contract_address ); - validate_note_hash_nullifier_counters( - self.output.end.new_note_hashes, - note_hash_nullifier_counters, - array_lengths.new_note_hashes, - offsets.new_note_hashes - ); validate_array_appended_scoped( self.output.end.new_nullifiers, private_call.new_nullifiers, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr index 2a0c27b2393..0caf63b4b01 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr @@ -7,7 +7,7 @@ use dep::types::{ }, address::AztecAddress, constants::{ - MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_TX, + MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL }, hash::{ @@ -22,7 +22,6 @@ struct DataSource { private_call_public_inputs: PrivateCircuitPublicInputs, contract_address: AztecAddress, storage_contract_address: AztecAddress, - note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], public_call_requests: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], public_teardown_call_request: CallRequest, } @@ -91,7 +90,6 @@ impl PrivateKernelCircuitPublicInputsComposer { &mut self, private_call_public_inputs: PrivateCircuitPublicInputs, contract_address: AztecAddress, - note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], public_call_requests: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], public_teardown_call_request: CallRequest ) -> Self { @@ -100,7 +98,6 @@ impl PrivateKernelCircuitPublicInputsComposer { private_call_public_inputs, contract_address, storage_contract_address, - note_hash_nullifier_counters, public_call_requests, public_teardown_call_request }; @@ -183,13 +180,9 @@ impl PrivateKernelCircuitPublicInputsComposer { fn propagate_note_hashes(&mut self, source: DataSource) { let note_hashes = source.private_call_public_inputs.new_note_hashes; for i in 0..note_hashes.len() { - let mut note_hash = note_hashes[i]; + let note_hash = note_hashes[i]; if note_hash.value != 0 { - let nullifier_counter = source.note_hash_nullifier_counters[i]; - assert( - (nullifier_counter == 0) | (nullifier_counter > note_hash.counter), "Invalid nullifier counter" - ); - self.public_inputs.end.new_note_hashes.push(note_hash.scope(nullifier_counter, source.storage_contract_address)); + self.public_inputs.end.new_note_hashes.push(note_hash.scope(source.storage_contract_address)); } } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index 738e05833cb..ca8518d33f7 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -10,19 +10,13 @@ use dep::types::{ kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, private_kernel::private_call_data::PrivateCallData }, - constants::MAX_NEW_NOTE_HASHES_PER_CALL, transaction::tx_request::TxRequest + transaction::tx_request::TxRequest }; -struct PrivateKernelInitHints { - // TODO: Remove note_hash_nullifier_counters. - note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], -} - // Initialization struct for private inputs to the private kernel struct PrivateKernelInitCircuitPrivateInputs { tx_request: TxRequest, private_call: PrivateCallData, - hints: PrivateKernelInitHints, } impl PrivateKernelInitCircuitPrivateInputs { @@ -31,7 +25,6 @@ impl PrivateKernelInitCircuitPrivateInputs { PrivateKernelCircuitPublicInputsComposer::new_from_tx_request(self.tx_request, private_call_public_inputs).with_private_call( private_call_public_inputs, self.private_call.call_stack_item.contract_address, - self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, self.private_call.public_teardown_call_request ).finish() @@ -58,7 +51,6 @@ impl PrivateKernelInitCircuitPrivateInputs { self.private_call.call_stack_item.public_inputs, private_call_data_validator.array_lengths, self.private_call.call_stack_item.contract_address, - self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, self.private_call.public_teardown_call_request ); @@ -68,10 +60,9 @@ impl PrivateKernelInitCircuitPrivateInputs { } mod tests { - use crate::private_kernel_init::{PrivateKernelInitHints, PrivateKernelInitCircuitPrivateInputs}; + use crate::private_kernel_init::PrivateKernelInitCircuitPrivateInputs; use dep::types::{ abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs}, - constants::MAX_NEW_NOTE_HASHES_PER_CALL, tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq}, transaction::tx_request::TxRequest }; @@ -79,20 +70,18 @@ mod tests { struct PrivateKernelInitInputsBuilder { tx_request: TxRequest, private_call: FixtureBuilder, - hints: PrivateKernelInitHints, } impl PrivateKernelInitInputsBuilder { pub fn new() -> Self { let private_call = FixtureBuilder::new(); let tx_request = private_call.build_tx_request(); - let hints = PrivateKernelInitHints { note_hash_nullifier_counters: [0; MAX_NEW_NOTE_HASHES_PER_CALL] }; - PrivateKernelInitInputsBuilder { tx_request, private_call, hints } + PrivateKernelInitInputsBuilder { tx_request, private_call } } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { let private_call = self.private_call.to_private_call_data(); - PrivateKernelInitCircuitPrivateInputs { tx_request: self.tx_request, private_call, hints: self.hints }.execute() + PrivateKernelInitCircuitPrivateInputs { tx_request: self.tx_request, private_call }.execute() } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index c46cec8a4b1..4141769edf2 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -9,18 +9,12 @@ use dep::types::{ abis::{ kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths}, private_kernel_data::PrivateKernelData, private_kernel::private_call_data::PrivateCallData -}, - constants::MAX_NEW_NOTE_HASHES_PER_CALL -}; - -struct PrivateKernelInnerHints { - note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], } +}; struct PrivateKernelInnerCircuitPrivateInputs { previous_kernel: PrivateKernelData, private_call: PrivateCallData, - hints: PrivateKernelInnerHints, } impl PrivateKernelInnerCircuitPrivateInputs { @@ -28,7 +22,6 @@ impl PrivateKernelInnerCircuitPrivateInputs { PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).pop_top_call_request().with_private_call( self.private_call.call_stack_item.public_inputs, self.private_call.call_stack_item.contract_address, - self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, self.private_call.public_teardown_call_request ).finish() @@ -61,7 +54,6 @@ impl PrivateKernelInnerCircuitPrivateInputs { self.private_call.call_stack_item.public_inputs, private_call_data_validator.array_lengths, self.private_call.call_stack_item.contract_address, - self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, self.private_call.public_teardown_call_request ); @@ -71,29 +63,26 @@ impl PrivateKernelInnerCircuitPrivateInputs { } mod tests { - use crate::private_kernel_inner::{PrivateKernelInnerCircuitPrivateInputs, PrivateKernelInnerHints}; + use crate::private_kernel_inner::PrivateKernelInnerCircuitPrivateInputs; use dep::types::{ abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs}, - constants::MAX_NEW_NOTE_HASHES_PER_CALL, tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq} }; struct PrivateKernelInnerInputsBuilder { previous_kernel: FixtureBuilder, private_call: FixtureBuilder, - hints: PrivateKernelInnerHints, } impl PrivateKernelInnerInputsBuilder { pub fn new() -> Self { let mut previous_kernel = FixtureBuilder::new_from_counter(15).as_parent_contract(); let private_call = FixtureBuilder::new_from_counter(200); - let hints = PrivateKernelInnerHints { note_hash_nullifier_counters: [0; MAX_NEW_NOTE_HASHES_PER_CALL] }; // 0th nullifier must be non-zero. previous_kernel.append_new_nullifiers(1); - PrivateKernelInnerInputsBuilder { previous_kernel, private_call, hints } + PrivateKernelInnerInputsBuilder { previous_kernel, private_call } } pub fn execute(&mut self) -> PrivateKernelCircuitPublicInputs { @@ -104,7 +93,7 @@ mod tests { self.previous_kernel.add_private_call_request(hash, is_delegate_call); let previous_kernel = self.previous_kernel.to_private_kernel_data(); - let kernel = PrivateKernelInnerCircuitPrivateInputs { previous_kernel, private_call, hints: self.hints }; + let kernel = PrivateKernelInnerCircuitPrivateInputs { previous_kernel, private_call }; kernel.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr index e9179e7ce8d..d3bf68d5ff6 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr @@ -1,22 +1,17 @@ use dep::reset_kernel_lib::{ - NoteHashReadRequestHints, NullifierReadRequestHints, PrivateValidationRequestProcessor, - verify_squashed_transient_note_hashes_and_nullifiers, reset::key_validation_hint::KeyValidationHint + get_transient_or_propagated_note_hash_indexes_for_logs, KeyValidationHint, NoteHashReadRequestHints, + NullifierReadRequestHints, PrivateValidationRequestProcessor, verify_squashed_transient_data }; use dep::types::{ abis::{ private_kernel_data::PrivateKernelData, kernel_circuit_public_inputs::KernelCircuitPublicInputs, note_hash::ScopedNoteHash, nullifier::ScopedNullifier, log_hash::NoteLogHash }, - constants::{ - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_KEY_VALIDATION_REQUESTS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX, - MAX_NOTE_ENCRYPTED_LOGS_PER_TX -}, + constants::{MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX}, grumpkin_private_key::GrumpkinPrivateKey, utils::arrays::array_length, traits::is_empty, PrivateKernelCircuitPublicInputs }; -// Can just be KernelCircuitPublicInputs. struct PrivateKernelResetOutputs { note_hashes: [ScopedNoteHash; MAX_NEW_NOTE_HASHES_PER_TX], nullifiers: [ScopedNullifier; MAX_NEW_NULLIFIERS_PER_TX], @@ -26,7 +21,6 @@ struct PrivateKernelResetOutputs { struct PrivateKernelResetHints { transient_nullifier_indexes_for_note_hashes: [u32; MAX_NEW_NOTE_HASHES_PER_TX], transient_note_hash_indexes_for_nullifiers: [u32; MAX_NEW_NULLIFIERS_PER_TX], - transient_note_hash_indexes_for_logs: [u32; MAX_NOTE_ENCRYPTED_LOGS_PER_TX], note_hash_read_request_hints: NoteHashReadRequestHints, nullifier_read_request_hints: NullifierReadRequestHints, key_validation_hints: [KeyValidationHint; KEY_VALIDATION_REQUESTS], @@ -34,6 +28,7 @@ struct PrivateKernelResetHints { previous_kernel: PrivateKernelData, + // TODO: Construct output in an unconstrained function. outputs: PrivateKernelResetOutputs, hints: PrivateKernelResetHints, } @@ -56,7 +51,12 @@ impl PrivateKernelCircuitPublicInputs { - let outputs = PrivateKernelResetOutputs { - note_hashes: squash_transient_note_hashes(self.previous_kernel.new_note_hashes.storage), - nullifiers: squash_transient_nullifiers(self.previous_kernel.new_nullifiers.storage), - note_encrypted_log_hashes: squash_transient_logs( - self.previous_kernel.note_encrypted_logs_hashes.storage, - self.previous_kernel.new_note_hashes.storage - ) - }; + let (note_hashes, nullifiers, note_encrypted_log_hashes) = squash_transient_data( + self.previous_kernel.new_note_hashes.storage, + self.previous_kernel.new_nullifiers.storage, + self.previous_kernel.note_encrypted_logs_hashes.storage + ); + let outputs = PrivateKernelResetOutputs { note_hashes, nullifiers, note_encrypted_log_hashes }; let hints = PrivateKernelResetHints { transient_nullifier_indexes_for_note_hashes: self.transient_nullifier_indexes_for_note_hashes, transient_note_hash_indexes_for_nullifiers: self.transient_note_hash_indexes_for_nullifiers, - transient_note_hash_indexes_for_logs: self.transient_note_hash_indexes_for_logs, note_hash_read_request_hints: self.note_hash_read_request_hints_builder.to_hints(), nullifier_read_request_hints: self.nullifier_read_request_hints_builder.to_hints(), key_validation_hints: [KeyValidationHint::empty(); MAX_KEY_VALIDATION_REQUESTS_PER_TX] diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_note_logs.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_note_logs.nr index 958157529fd..05f0c55e702 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_note_logs.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_note_logs.nr @@ -38,7 +38,7 @@ fn validate_note_logs_mismatch_contract_address_fails() { // Create a note hash emitted from a different contract. let another_contract_address = AztecAddress::from_field(9999); - let previous_note_hash = NoteHash { value: 1, counter: 17 }.scope(0, another_contract_address); + let previous_note_hash = NoteHash { value: 1, counter: 17 }.scope(another_contract_address); builder.previous_note_hashes.push(previous_note_hash); // Add a not log linked to the previous note hash. diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr index d52c6cf82b1..b845856d277 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr @@ -15,14 +15,12 @@ use dep::types::{ kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, private_circuit_public_inputs::PrivateCircuitPublicInputsArrayLengths }, - constants::MAX_NEW_NOTE_HASHES_PER_CALL, tests::{fixture_builder::FixtureBuilder}, - transaction::tx_request::TxRequest + tests::{fixture_builder::FixtureBuilder}, transaction::tx_request::TxRequest }; struct PrivateKernelCircuitOutputValidatorBuilder { previous_kernel: FixtureBuilder, private_call: FixtureBuilder, - note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], output: FixtureBuilder, tx_request: TxRequest, } @@ -31,13 +29,12 @@ impl PrivateKernelCircuitOutputValidatorBuilder { pub fn new() -> Self { let mut previous_kernel = FixtureBuilder::new(); let private_call = FixtureBuilder::new(); - let note_hash_nullifier_counters = [0; MAX_NEW_NOTE_HASHES_PER_CALL]; let mut output = FixtureBuilder::new(); let tx_request = output.build_tx_request(); let first_nullifier = create_first_nullifier(tx_request); output.new_nullifiers.push(first_nullifier); previous_kernel.new_nullifiers.push(first_nullifier); - PrivateKernelCircuitOutputValidatorBuilder { previous_kernel, private_call, note_hash_nullifier_counters, output, tx_request } + PrivateKernelCircuitOutputValidatorBuilder { previous_kernel, private_call, output, tx_request } } pub fn offset_values(&mut self, num_prepended_items: Field) { @@ -57,7 +54,6 @@ impl PrivateKernelCircuitOutputValidatorBuilder { private_call.call_stack_item.public_inputs, array_lengths, private_call.call_stack_item.contract_address, - self.note_hash_nullifier_counters, private_call.public_call_stack, private_call.public_teardown_call_request ); @@ -80,7 +76,6 @@ impl PrivateKernelCircuitOutputValidatorBuilder { private_call.call_stack_item.public_inputs, private_call_array_lengths, private_call.call_stack_item.contract_address, - self.note_hash_nullifier_counters, private_call.public_call_stack, private_call.public_teardown_call_request ); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr index 710714c5756..440991c5424 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr @@ -259,97 +259,6 @@ fn validate_propagated_from_private_call_new_note_hashes_output_one_more_fails() builder.validate_as_inner_call(); } -/** - * new_note_hashes - * With nullifier counters. - */ - -#[test] -fn validate_propagated_from_private_call_new_note_hashes_non_zero_nullifier_counters_succeeds() { - let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - - builder.private_call.append_new_note_hashes(2); - let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; - builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; - builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() + 35; - builder.output.add_new_note_hash( - note_hashes[0].value(), - builder.note_hash_nullifier_counters[0] - ); - builder.output.add_new_note_hash( - note_hashes[1].value(), - builder.note_hash_nullifier_counters[1] - ); - - builder.validate_as_inner_call(); -} - -#[test] -fn validate_propagated_from_private_call_new_note_hashes_with_previous_non_zero_nullifier_counters_succeeds() { - let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - - builder.previous_kernel.append_new_note_hashes(2); - builder.output.append_new_note_hashes(2); - builder.offset_values(2); // Offset the first 2 note hashes. - - builder.private_call.append_new_note_hashes(2); - let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; - builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; - builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() + 35; - builder.output.add_new_note_hash( - note_hashes[0].value(), - builder.note_hash_nullifier_counters[0] - ); - builder.output.add_new_note_hash( - note_hashes[1].value(), - builder.note_hash_nullifier_counters[1] - ); - - builder.validate_as_inner_call(); -} - -#[test(should_fail_with="invalid nullifier counter")] -fn validate_propagated_from_private_call_new_note_hashes_nullifier_counters_too_small_fails() { - let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - - builder.private_call.append_new_note_hashes(2); - let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; - builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; - // Tweak the nullifier counter to be less than the counter of the note hash. - builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() - 1; - builder.output.add_new_note_hash( - note_hashes[0].value(), - builder.note_hash_nullifier_counters[0] - ); - builder.output.add_new_note_hash( - note_hashes[1].value(), - builder.note_hash_nullifier_counters[1] - ); - - builder.validate_as_inner_call(); -} - -#[test(should_fail_with="incorrect nullifier counter assigned to dest")] -fn validate_propagated_from_private_call_new_note_hashes_nullifier_counters_mismatch_fails() { - let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - - builder.private_call.append_new_note_hashes(2); - let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; - builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; - builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() + 35; - builder.output.add_new_note_hash( - note_hashes[0].value(), - builder.note_hash_nullifier_counters[0] - ); - // Tweak the nullifier counter to be different. - builder.output.add_new_note_hash( - note_hashes[1].value(), - builder.note_hash_nullifier_counters[1] + 1 - ); - - builder.validate_as_inner_call(); -} - /** * new_nullifiers */ diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr index 6a41dba5af6..84b73931906 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr @@ -8,15 +8,13 @@ use dep::types::{ kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, private_call_request::ScopedPrivateCallRequest }, - constants::MAX_NEW_NOTE_HASHES_PER_CALL, tests::fixture_builder::FixtureBuilder, - transaction::tx_request::TxRequest + tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest }; struct PrivateKernelCircuitPublicInputsComposerBuilder { tx_request: TxRequest, previous_kernel: FixtureBuilder, private_call: FixtureBuilder, - note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], } impl PrivateKernelCircuitPublicInputsComposerBuilder { @@ -28,8 +26,7 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { private_call.value_offset = 9999; let tx_request = private_call.build_tx_request(); - let note_hash_nullifier_counters = [0; MAX_NEW_NOTE_HASHES_PER_CALL]; - PrivateKernelCircuitPublicInputsComposerBuilder { tx_request, previous_kernel, private_call, note_hash_nullifier_counters } + PrivateKernelCircuitPublicInputsComposerBuilder { tx_request, previous_kernel, private_call } } pub fn new_from_tx_request(self) -> PrivateKernelCircuitPublicInputsComposer { @@ -47,7 +44,6 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { self.new_from_tx_request().with_private_call( private_call.call_stack_item.public_inputs, private_call.call_stack_item.contract_address, - self.note_hash_nullifier_counters, private_call.public_call_stack, private_call.public_teardown_call_request ).finish() @@ -65,7 +61,6 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel).pop_top_call_request().with_private_call( private_call.call_stack_item.public_inputs, private_call.call_stack_item.contract_address, - self.note_hash_nullifier_counters, private_call.public_call_stack, private_call.public_teardown_call_request ).finish() diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr index eb2421ac767..87adb36b6e8 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr @@ -165,67 +165,6 @@ fn new_from_previous_kernel_with_private_call_new_note_hashes_succeeds() { ); } -#[test] -fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_counters_succeeds() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.previous_kernel.append_new_note_hashes(2); - let prev = builder.previous_kernel.new_note_hashes.storage; - builder.private_call.append_new_note_hashes(2); - let mut curr = builder.private_call.new_note_hashes.storage; - builder.note_hash_nullifier_counters[0] = curr[0].counter() + 10; - builder.note_hash_nullifier_counters[1] = curr[1].counter() + 75; - - let output = builder.compose_from_previous_kernel(); - - curr[0].nullifier_counter = curr[0].counter() + 10; - curr[1].nullifier_counter = curr[1].counter() + 75; - assert_array_eq( - output.end.new_note_hashes, - [prev[0], prev[1], curr[0], curr[1]] - ); -} - -#[test] -fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_counters_more_hints_succeeds() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.previous_kernel.append_new_note_hashes(2); - let prev = builder.previous_kernel.new_note_hashes.storage; - builder.private_call.append_new_note_hashes(2); - let mut curr = builder.private_call.new_note_hashes.storage; - builder.note_hash_nullifier_counters[0] = curr[0].counter() + 10; - builder.note_hash_nullifier_counters[1] = curr[1].counter() + 75; - // Add a random nullifier counter for a non-existent note hash to the hints. - builder.note_hash_nullifier_counters[2] = 323; - - let output = builder.compose_from_previous_kernel(); - - curr[0].nullifier_counter = curr[0].counter() + 10; - curr[1].nullifier_counter = curr[1].counter() + 75; - assert_array_eq( - output.end.new_note_hashes, - [prev[0], prev[1], curr[0], curr[1]] - ); - // The extra counter won't be propagated. - assert_eq(output.end.new_note_hashes[4].nullifier_counter, 0); -} - -#[test(should_fail_with="Invalid nullifier counter")] -fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_counters_less_than_fails() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.previous_kernel.append_new_note_hashes(2); - let _ = builder.previous_kernel.new_note_hashes.storage; - builder.private_call.append_new_note_hashes(2); - let curr = builder.private_call.new_note_hashes.storage; - builder.note_hash_nullifier_counters[0] = curr[0].counter() + 10; - // Tweak the nullifier counter to be less than the note hash counter. - builder.note_hash_nullifier_counters[1] = curr[1].counter() - 1; - - let _ = builder.compose_from_previous_kernel(); -} - #[test] fn new_from_previous_kernel_with_private_call_new_nullifiers_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr index 613cd104cf1..8cdb65e69e7 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr @@ -109,55 +109,6 @@ fn propagate_from_private_call_new_note_hashes_succeeds() { assert_array_eq(output.end.new_note_hashes, [res[0], res[1]]); } -#[test] -fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_succeeds() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.private_call.append_new_note_hashes(2); - let mut res = builder.private_call.new_note_hashes.storage; - builder.note_hash_nullifier_counters[0] = res[0].counter() + 10; - builder.note_hash_nullifier_counters[1] = res[1].counter() + 75; - - let output = builder.compose_from_tx_request(); - - res[0].nullifier_counter = res[0].counter() + 10; - res[1].nullifier_counter = res[1].counter() + 75; - assert_array_eq(output.end.new_note_hashes, [res[0], res[1]]); -} - -#[test] -fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_more_hints_succeeds() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.private_call.append_new_note_hashes(2); - let mut res = builder.private_call.new_note_hashes.storage; - builder.note_hash_nullifier_counters[0] = res[0].counter() + 10; - builder.note_hash_nullifier_counters[1] = res[1].counter() + 75; - // Add a random nullifier counter for a non-existent note hash to the hints. - builder.note_hash_nullifier_counters[2] = 323; - - let output = builder.compose_from_tx_request(); - - res[0].nullifier_counter = res[0].counter() + 10; - res[1].nullifier_counter = res[1].counter() + 75; - assert_array_eq(output.end.new_note_hashes, [res[0], res[1]]); - // The extra counter won't be propagated. - assert_eq(output.end.new_note_hashes[2].nullifier_counter, 0); -} - -#[test(should_fail_with="Invalid nullifier counter")] -fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_less_than_fails() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.private_call.append_new_note_hashes(2); - let mut res = builder.private_call.new_note_hashes.storage; - builder.note_hash_nullifier_counters[0] = res[0].counter() + 10; - // Tweak the nullifier counter to be less than the note hash counter. - builder.note_hash_nullifier_counters[1] = res[1].counter() - 1; - - let _ = builder.compose_from_tx_request(); -} - #[test] fn propagate_from_private_call_new_nullifiers_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr index 814741e995b..b7212a17419 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr @@ -4,7 +4,13 @@ use nullifier_read_request_reset::NullifierReadRequestHints; use private_validation_request_processor::PrivateValidationRequestProcessor; use public_data_read_request_reset::PublicDataReadRequestHints; use public_validation_request_processor::PublicValidationRequestProcessor; -use reset::transient_data::verify_squashed_transient_note_hashes_and_nullifiers; +use reset::{ + key_validation_hint::KeyValidationHint, + transient_data::{ + transient_data_reset_hints::get_transient_or_propagated_note_hash_indexes_for_logs, + verify_squashed_transient_data +} +}; use dep::types::data::public_data_hint::PublicDataHint; mod note_hash_read_request_reset; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr index 2e159da2dd3..7513a0e3a02 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr @@ -68,8 +68,8 @@ mod tests { ]; global pending_values = [ - NoteHash { value: inner_note_hashes[2], counter: 2, }.scope(0, contract_address), - NoteHash { value: inner_note_hashes[3], counter: 8, }.scope(0, contract_address), + NoteHash { value: inner_note_hashes[2], counter: 2, }.scope(contract_address), + NoteHash { value: inner_note_hashes[3], counter: 8, }.scope(contract_address), ]; global pending_read_hints = [ PendingReadHint { read_request_index: 1, pending_value_index: 1 }, @@ -189,25 +189,6 @@ mod tests { ); } - #[test(should_fail_with="Read request counter must be less than the nullifier counter of the note hash")] - fn test_reset_note_hash_read_requests_invalid_nullifier_counter() { - let hint = pending_read_hints[0]; - let pending_read = read_requests[hint.read_request_index]; - let mut tainted_pending_values = pending_values; - // Tweak the nullifier counter to be less than the read request. - tainted_pending_values[hint.pending_value_index].nullifier_counter = pending_read.counter() - 1; - - let (settled_read_hints, tree_root) = get_settled_read_hints(); - let _ = reset_read_requests( - read_requests, - tainted_pending_values, - read_request_statuses(), - pending_read_hints, - settled_read_hints, - tree_root - ); - } - #[test(should_fail_with="Value of the note hash leaf does not match read request")] fn test_reset_note_hash_read_requests_invalid_leaf() { let (settled_read_hints, tree_root) = get_settled_read_hints(); diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data.nr index bc0354dd72c..84f175da5b6 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data.nr @@ -1,9 +1,11 @@ +mod transient_data_reset_hints; + use dep::types::{ abis::{note_hash::ScopedNoteHash, nullifier::ScopedNullifier, log_hash::NoteLogHash}, traits::is_empty }; -pub fn verify_squashed_transient_note_hashes_and_nullifiers( +pub fn verify_squashed_transient_data( note_hashes: [ScopedNoteHash; NUM_NOTE_HASHES], nullifiers: [ScopedNullifier; NUM_NULLIFIERS], note_logs: [NoteLogHash; NUM_LOGS], @@ -12,7 +14,7 @@ pub fn verify_squashed_transient_note_hashes_and_nullifiers note_hash.counter()); note_hashes_removed += 1; @@ -70,8 +65,14 @@ pub fn verify_squashed_transient_note_hashes_and_nullifiers { - num_note_hashes: u32, - num_nullifiers: u32, note_hashes: [ScopedNoteHash; NUM_NOTE_HASHES], nullifiers: [ScopedNullifier; NUM_NULLIFIERS], note_logs: [NoteLogHash; NUM_LOGS], @@ -121,41 +116,44 @@ mod tests { expected_note_logs: [NoteLogHash; NUM_LOGS], transient_nullifier_indexes_for_note_hashes: [u32; NUM_NOTE_HASHES], transient_note_hash_indexes_for_nullifiers: [u32; NUM_NULLIFIERS], - transient_note_hash_indexes_for_logs: [u32; NUM_LOGS] + transient_or_propagated_note_hash_indexes_for_logs: [u32; NUM_LOGS] } impl TestDataBuilder { - pub fn default() -> TestDataBuilder<3, 3, 2> { - let contract_address = AztecAddress::from_field(987654); - + pub fn new() -> TestDataBuilder<5, 4, 3> { let note_hashes = [ - NoteHash { value: 11, counter: 100 }.scope(500, contract_address), - NoteHash { value: 22, counter: 200 }.scope(0, contract_address), - NoteHash { value: 33, counter: 300 }.scope(400, contract_address) + NoteHash { value: 11, counter: 100 }.scope(contract_address), + NoteHash { value: 22, counter: 200 }.scope(contract_address), + NoteHash { value: 33, counter: 300 }.scope(contract_address), + ScopedNoteHash::empty(), + ScopedNoteHash::empty() ]; let nullifiers = [ Nullifier { value: 44, counter: 400, note_hash: 33 }.scope(contract_address), Nullifier { value: 55, counter: 500, note_hash: 11 }.scope(contract_address), - Nullifier { value: 66, counter: 600, note_hash: 0 }.scope(contract_address) + Nullifier { value: 66, counter: 600, note_hash: 0 }.scope(contract_address), + ScopedNullifier::empty() ]; let note_logs = [ NoteLogHash { value: 77, counter: 700, length: 70, note_hash_counter: 100 }, - NoteLogHash { value: 88, counter: 800, length: 80, note_hash_counter: 200 } + NoteLogHash { value: 88, counter: 800, length: 80, note_hash_counter: 200 }, + NoteLogHash::empty() ]; - let expected_note_hashes = [note_hashes[1], ScopedNoteHash::empty(), ScopedNoteHash::empty()]; - let expected_nullifiers = [nullifiers[2], ScopedNullifier::empty(), ScopedNullifier::empty()]; - let expected_note_logs = [note_logs[1], NoteLogHash::empty()]; + let mut expected_note_hashes = [ScopedNoteHash::empty(); 5]; + expected_note_hashes[0] = note_hashes[1]; + let mut expected_nullifiers = [ScopedNullifier::empty(); 4]; + expected_nullifiers[0] = nullifiers[2]; + let mut expected_note_logs = [NoteLogHash::empty(); 3]; + expected_note_logs[0] = note_logs[1]; - let transient_nullifier_indexes_for_note_hashes = [1, 3, 0]; - let transient_note_hash_indexes_for_nullifiers = [2, 0, 3]; - let transient_note_hash_indexes_for_logs = [0, 3]; + let transient_nullifier_indexes_for_note_hashes = [1, 4, 0, 4, 4]; + let transient_note_hash_indexes_for_nullifiers = [2, 0, 5, 5]; + let transient_or_propagated_note_hash_indexes_for_logs = [0, 0, 1]; TestDataBuilder { - num_note_hashes: 3, - num_nullifiers: 3, note_hashes, nullifiers, note_logs, @@ -164,17 +162,15 @@ mod tests { expected_note_logs, transient_nullifier_indexes_for_note_hashes, transient_note_hash_indexes_for_nullifiers, - transient_note_hash_indexes_for_logs + transient_or_propagated_note_hash_indexes_for_logs } } - pub fn default_all_clear() -> TestDataBuilder<3, 3, 4> { - let contract_address = AztecAddress::from_field(987654); - + pub fn new_clear_all() -> TestDataBuilder<3, 3, 4> { let note_hashes = [ - NoteHash { value: 11, counter: 100 }.scope(500, contract_address), - NoteHash { value: 22, counter: 200 }.scope(600, contract_address), - NoteHash { value: 33, counter: 300 }.scope(400, contract_address) + NoteHash { value: 11, counter: 100 }.scope(contract_address), + NoteHash { value: 22, counter: 200 }.scope(contract_address), + NoteHash { value: 33, counter: 300 }.scope(contract_address) ]; let nullifiers = [ @@ -197,11 +193,9 @@ mod tests { let transient_nullifier_indexes_for_note_hashes = [1, 2, 0]; let transient_note_hash_indexes_for_nullifiers = [2, 0, 1]; - let transient_note_hash_indexes_for_logs = [0, 2, 1, 2]; + let transient_or_propagated_note_hash_indexes_for_logs = [0, 2, 1, 2]; TestDataBuilder { - num_note_hashes: 3, - num_nullifiers: 3, note_hashes, nullifiers, note_logs, @@ -210,12 +204,53 @@ mod tests { expected_note_logs, transient_nullifier_indexes_for_note_hashes, transient_note_hash_indexes_for_nullifiers, - transient_note_hash_indexes_for_logs + transient_or_propagated_note_hash_indexes_for_logs + } + } + + pub fn new_identical_note_hashes() -> TestDataBuilder<3, 3, 4> { + let note_hashes = [ + NoteHash { value: 11, counter: 100 }.scope(contract_address), + NoteHash { value: 11, counter: 200 }.scope(contract_address), + NoteHash { value: 11, counter: 600 }.scope(contract_address) + ]; + + let nullifiers = [ + Nullifier { value: 33, counter: 300, note_hash: 11 }.scope(contract_address), + Nullifier { value: 44, counter: 400, note_hash: 0 }.scope(contract_address), + Nullifier { value: 55, counter: 500, note_hash: 11 }.scope(contract_address) + ]; + + let note_logs = [ + NoteLogHash { value: 77, counter: 701, length: 70, note_hash_counter: 200 }, + NoteLogHash { value: 77, counter: 702, length: 70, note_hash_counter: 200 }, + NoteLogHash { value: 77, counter: 703, length: 70, note_hash_counter: 200 }, + NoteLogHash { value: 88, counter: 800, length: 80, note_hash_counter: 600 } + ]; + + let expected_note_hashes = [note_hashes[2], ScopedNoteHash::empty(), ScopedNoteHash::empty()]; + let expected_nullifiers = [nullifiers[1], ScopedNullifier::empty(), ScopedNullifier::empty()]; + let expected_note_logs = [note_logs[3], NoteLogHash::empty(), NoteLogHash::empty(), NoteLogHash::empty()]; + + let transient_nullifier_indexes_for_note_hashes = [0, 2, 3]; + let transient_note_hash_indexes_for_nullifiers = [0, 3, 1]; + let transient_or_propagated_note_hash_indexes_for_logs = [1, 1, 1, 0]; + + TestDataBuilder { + note_hashes, + nullifiers, + note_logs, + expected_note_hashes, + expected_nullifiers, + expected_note_logs, + transient_nullifier_indexes_for_note_hashes, + transient_note_hash_indexes_for_nullifiers, + transient_or_propagated_note_hash_indexes_for_logs } } pub fn verify(self) { - let _void = verify_squashed_transient_note_hashes_and_nullifiers( + let _void = verify_squashed_transient_data( self.note_hashes, self.nullifiers, self.note_logs, @@ -224,43 +259,48 @@ mod tests { self.expected_note_logs, self.transient_nullifier_indexes_for_note_hashes, self.transient_note_hash_indexes_for_nullifiers, - self.transient_note_hash_indexes_for_logs + self.transient_or_propagated_note_hash_indexes_for_logs ); } } #[test] - fn verify_squashed_transient_note_hashes_and_nullifiers_with_propagated_values() { - TestDataBuilder::default().verify(); + fn succeeds_clear_all() { + TestDataBuilder::new_clear_all().verify(); } #[test] - fn verify_full_transient_note_hashes_and_nullifiers() { - TestDataBuilder::default_all_clear().verify(); + fn succeeds_with_propagated_values() { + TestDataBuilder::new().verify(); } #[test] - fn verify_partial_transient_note_hashes_and_nullifiers() { - let mut builder = TestDataBuilder::default_all_clear(); + fn succeeds_partially_propagated() { + let mut builder = TestDataBuilder::new_clear_all(); // Keep the note at index 1. - builder.transient_nullifier_indexes_for_note_hashes[1] = builder.num_nullifiers; + builder.transient_nullifier_indexes_for_note_hashes[1] = builder.nullifiers.len(); builder.expected_note_hashes[0] = builder.note_hashes[1]; // Keep the nullifier at index 2. - builder.transient_note_hash_indexes_for_nullifiers[2] = builder.num_note_hashes; + builder.transient_note_hash_indexes_for_nullifiers[2] = builder.note_hashes.len(); builder.expected_nullifiers[0] = builder.nullifiers[2]; // Keep the log at index 2. - builder.transient_note_hash_indexes_for_logs[2] = builder.num_note_hashes; + builder.transient_or_propagated_note_hash_indexes_for_logs[2] = 0; // Point it to the expected not hash at index 0. builder.expected_note_logs[0] = builder.note_logs[2]; builder.verify(); } + #[test] + fn succeeds_identical_note_hashes() { + TestDataBuilder::new_identical_note_hashes().verify(); + } + #[test(should_fail_with="Value of the hinted transient note hash does not match")] - fn mismatch_note_hash_value() { - let mut builder = TestDataBuilder::default_all_clear(); + fn fails_mismatch_note_hash_value() { + let mut builder = TestDataBuilder::new_clear_all(); builder.note_hashes[1].note_hash.value += 1; @@ -268,26 +308,17 @@ mod tests { } #[test(should_fail_with="Contract address of the hinted transient note hash does not match")] - fn mismatch_contract_address() { - let mut builder = TestDataBuilder::default_all_clear(); + fn fails_mismatch_contract_address() { + let mut builder = TestDataBuilder::new_clear_all(); builder.note_hashes[1].contract_address.inner += 1; builder.verify(); } - #[test(should_fail_with="Nullifier counter of the hinted transient note hash does not match")] - fn mismatch_nullifier_counter() { - let mut builder = TestDataBuilder::default_all_clear(); - - builder.note_hashes[1].nullifier_counter += 1; - - builder.verify(); - } - #[test(should_fail_with="Empty note hash must be padded to the right")] - fn unexpected_note_hash_value() { - let mut builder = TestDataBuilder::default_all_clear(); + fn fails_unexpected_note_hash_value() { + let mut builder = TestDataBuilder::new_clear_all(); builder.expected_note_hashes[2].note_hash.value = 11; @@ -295,8 +326,8 @@ mod tests { } #[test(should_fail_with="Propagated note hash does not match")] - fn wrong_expected_note_hash_value() { - let mut builder = TestDataBuilder::default(); + fn fails_wrong_expected_note_hash_value() { + let mut builder = TestDataBuilder::new(); builder.expected_note_hashes[0].note_hash.value += 1; @@ -304,8 +335,8 @@ mod tests { } #[test(should_fail_with="Propagated note hash does not match")] - fn wrong_expected_note_hash_counter() { - let mut builder = TestDataBuilder::default(); + fn fails_wrong_expected_note_hash_counter() { + let mut builder = TestDataBuilder::new(); builder.expected_note_hashes[0].note_hash.counter += 1; @@ -313,8 +344,8 @@ mod tests { } #[test(should_fail_with="Invalid transient nullifier index hint")] - fn wrong_hint_for_transient_nullifier_index() { - let mut builder = TestDataBuilder::default_all_clear(); + fn fails_wrong_hint_for_transient_nullifier_index() { + let mut builder = TestDataBuilder::new_clear_all(); builder.transient_note_hash_indexes_for_nullifiers[0] = 1; @@ -322,8 +353,8 @@ mod tests { } #[test(should_fail_with="Empty nullifier must be padded to the right")] - fn unexpected_nullifier_value() { - let mut builder = TestDataBuilder::default_all_clear(); + fn fails_unexpected_nullifier_value() { + let mut builder = TestDataBuilder::new_clear_all(); builder.expected_nullifiers[2].nullifier.value = 11; @@ -331,8 +362,8 @@ mod tests { } #[test(should_fail_with="Propagated nullifier does not match")] - fn wrong_expected_nullifier_value() { - let mut builder = TestDataBuilder::default(); + fn fails_wrong_expected_nullifier_value() { + let mut builder = TestDataBuilder::new(); builder.expected_nullifiers[0].nullifier.value += 1; @@ -340,8 +371,8 @@ mod tests { } #[test(should_fail_with="Propagated nullifier does not match")] - fn wrong_expected_nullifier_counter() { - let mut builder = TestDataBuilder::default(); + fn fails_wrong_expected_nullifier_counter() { + let mut builder = TestDataBuilder::new(); builder.expected_nullifiers[0].nullifier.counter += 1; @@ -349,8 +380,8 @@ mod tests { } #[test(should_fail_with="Empty log must be padded to the right")] - fn unexpected_log_value() { - let mut builder = TestDataBuilder::default_all_clear(); + fn fails_unexpected_log_value() { + let mut builder = TestDataBuilder::new_clear_all(); builder.expected_note_logs[2].value = 1; @@ -358,8 +389,8 @@ mod tests { } #[test(should_fail_with="Propagated note log does not match")] - fn wrong_expected_log_value() { - let mut builder = TestDataBuilder::default(); + fn fails_wrong_expected_log_value() { + let mut builder = TestDataBuilder::new(); builder.expected_note_logs[0].value += 1; @@ -367,8 +398,8 @@ mod tests { } #[test(should_fail_with="Propagated note log does not match")] - fn wrong_expected_log_counter() { - let mut builder = TestDataBuilder::default(); + fn fails_wrong_expected_log_counter() { + let mut builder = TestDataBuilder::new(); builder.expected_note_logs[0].counter += 1; @@ -376,51 +407,73 @@ mod tests { } #[test(should_fail_with="Hinted transient note log not nullified")] - fn log_not_nullified() { - let mut builder = TestDataBuilder::default(); + fn fails_log_not_nullified() { + let mut builder = TestDataBuilder::new(); - builder.transient_note_hash_indexes_for_logs[1] = 1; + builder.transient_or_propagated_note_hash_indexes_for_logs[1] = 1; builder.verify(); } #[test(should_fail_with="Value of the hinted transient note hash does not match log")] - fn wrong_log_note_hash() { - let mut builder = TestDataBuilder::default(); + fn fails_wrong_log_note_hash() { + let mut builder = TestDataBuilder::new(); builder.note_logs[0].note_hash_counter += 1; builder.verify(); } + #[test(should_fail_with="Empty log must be padded to the right")] + fn fails_propagate_too_many_logs() { + let mut builder = TestDataBuilder::new_clear_all(); + + // Keep the log. + builder.expected_note_logs[0] = builder.note_logs[1]; + + builder.verify(); + } + + #[test(should_fail_with="Value of the hinted transient note hash does not match log")] + fn fails_propagate_log_whose_note_hash_has_been_nullified() { + let mut builder = TestDataBuilder::new_clear_all(); + + // Keep the log. + builder.expected_note_logs[0] = builder.note_logs[1]; + // Point the log to index 0, which is empty in expected_note_hashes, and does not match the transient_note_hash. + builder.transient_or_propagated_note_hash_indexes_for_logs[1] = 0; + + builder.verify(); + } + #[test(should_fail_with="Invalid transient nullifier index hint")] - fn propagate_more_note_hashes_than_nullifiers() { - let mut builder = TestDataBuilder::default_all_clear(); + fn fails_propagate_more_note_hashes_than_nullifiers() { + let mut builder = TestDataBuilder::new_clear_all(); // Keep the note at index 1. - builder.transient_nullifier_indexes_for_note_hashes[1] = builder.num_nullifiers; + builder.transient_nullifier_indexes_for_note_hashes[1] = builder.nullifiers.len(); builder.expected_note_hashes[0] = builder.note_hashes[1]; builder.verify(); } #[test(should_fail_with="Inconsistent number of note hashes and nullifiers removed")] - fn propagate_more_nullifiers_than_note_hashes() { - let mut builder = TestDataBuilder::default_all_clear(); + fn fails_propagate_more_nullifiers_than_note_hashes() { + let mut builder = TestDataBuilder::new_clear_all(); // Keep the nullifier at index 2. - builder.transient_note_hash_indexes_for_nullifiers[2] = builder.num_note_hashes; + builder.transient_note_hash_indexes_for_nullifiers[2] = builder.note_hashes.len(); builder.expected_nullifiers[0] = builder.nullifiers[2]; builder.verify(); } - #[test(should_fail_with="Empty log must be padded to the right")] - fn remove_too_many_logs() { - let mut builder = TestDataBuilder::default(); - // Remove the log at index 1, but don't remove from expected_logs - builder.note_logs[1].note_hash_counter = 300; - builder.transient_note_hash_indexes_for_logs[1] = 2; + #[test(should_fail_with="Invalid transient nullifier index hint")] + fn fails_identical_note_hashes_nullify_same_note_hash() { + let mut builder = TestDataBuilder::new_identical_note_hashes(); + + // Make the nullifier at index 2 to also nullify the note hash at index 0. + builder.transient_note_hash_indexes_for_nullifiers[2] = 0; builder.verify(); } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data/transient_data_reset_hints.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data/transient_data_reset_hints.nr new file mode 100644 index 00000000000..c41015551bd --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data/transient_data_reset_hints.nr @@ -0,0 +1,28 @@ +use dep::types::{abis::{note_hash::ScopedNoteHash, log_hash::NoteLogHash}}; + +unconstrained pub fn get_transient_or_propagated_note_hash_indexes_for_logs( + note_logs: [NoteLogHash; NUM_LOGS], + note_hashes: [ScopedNoteHash; NUM_NOTE_HASHES], + expected_note_hashes: [ScopedNoteHash; NUM_NOTE_HASHES] +) -> [u32; NUM_LOGS] { + let mut indexes = [0; NUM_LOGS]; + for i in 0..note_logs.len() { + let log_note_hash_counter = note_logs[i].note_hash_counter; + let mut propagated = false; + for j in 0..expected_note_hashes.len() { + if !propagated & (expected_note_hashes[j].counter() == log_note_hash_counter) { + indexes[i] = j; + propagated = true; + } + } + if !propagated { + for j in 0..note_hashes.len() { + if note_hashes[j].counter() == log_note_hash_counter { + indexes[i] = j; + } + } + } + } + + indexes +} diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/squash_transient_data.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/squash_transient_data.nr index faf9bb69102..02e69069bf9 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/squash_transient_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/squash_transient_data.nr @@ -1,23 +1,22 @@ use dep::types::abis::{note_hash::ScopedNoteHash, nullifier::ScopedNullifier, log_hash::NoteLogHash}; -pub fn squash_transient_note_hashes(note_hashes: [ScopedNoteHash; N]) -> [ScopedNoteHash; N] { - let mut final_note_hashes = [ScopedNoteHash::empty(); N]; - +unconstrained pub fn squash_transient_data( + note_hashes: [ScopedNoteHash; M], + nullifiers: [ScopedNullifier; N], + logs: [NoteLogHash; P] +) -> ([ScopedNoteHash; M], [ScopedNullifier; N], [NoteLogHash; P]) { + let mut final_note_hashes = [ScopedNoteHash::empty(); M]; let mut num_note_hashes = 0; - for i in 0..N { + for i in 0..note_hashes.len() { let note_hash = note_hashes[i]; - if note_hash.nullifier_counter == 0 { + let nullified = nullifiers.any(|n: ScopedNullifier| (n.nullified_note_hash() == note_hash.note_hash.value)); + if !nullified { final_note_hashes[num_note_hashes] = note_hash; num_note_hashes += 1; } } - final_note_hashes -} - -pub fn squash_transient_nullifiers(nullifiers: [ScopedNullifier; N]) -> [ScopedNullifier; N] { let mut final_nullifiers = [ScopedNullifier::empty(); N]; - let mut num_nullifiers = 0; for i in 0..N { let nullifier = nullifiers[i]; @@ -27,24 +26,16 @@ pub fn squash_transient_nullifiers(nullifiers: [ScopedNullifier; N]) -> [Scop } } - final_nullifiers -} - -pub fn squash_transient_logs( - logs: [NoteLogHash; N], - note_hashes: [ScopedNoteHash; M] -) -> [NoteLogHash; N] { - let mut final_logs = [NoteLogHash::empty(); N]; - + let mut final_logs = [NoteLogHash::empty(); P]; let mut num_logs = 0; - for i in 0..N { + for i in 0..logs.len() { let mut log = logs[i]; - let is_nullified = note_hashes.any(|n: ScopedNoteHash| (n.counter() == log.note_hash_counter) & (n.nullifier_counter != 0)); - if !is_nullified { + let found_matching_note_hash = final_note_hashes.any(|n: ScopedNoteHash| (n.counter() == log.note_hash_counter)); + if found_matching_note_hash { final_logs[num_logs] = log; num_logs += 1; } } - final_logs + (final_note_hashes, final_nullifiers, final_logs) } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr index e9317e56105..834d7932f2f 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -853,7 +853,7 @@ mod tests { let new_note_hashes = [27, 28, 29, 30, 31, 32]; for i in 0..new_note_hashes.len() { - builder.kernel_data.add_new_note_hash(new_note_hashes[i], 0); + builder.kernel_data.add_new_note_hash(new_note_hashes[i]); } let mut expected_commitments_tree = NonEmptyMerkleTree::new( [0; MAX_NEW_NOTE_HASHES_PER_TX * 2], diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr index 4ac04a4f2ee..c557c317343 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr @@ -48,14 +48,13 @@ impl Deserialize for NoteHash { } impl NoteHash { - pub fn scope(self, nullifier_counter: u32, contract_address: AztecAddress) -> ScopedNoteHash { - ScopedNoteHash { note_hash: self, nullifier_counter, contract_address } + pub fn scope(self, contract_address: AztecAddress) -> ScopedNoteHash { + ScopedNoteHash { note_hash: self, contract_address } } } struct ScopedNoteHash { note_hash: NoteHash, - nullifier_counter: u32, contract_address: AztecAddress, } @@ -86,7 +85,6 @@ impl OrderedValue for ScopedNoteHash { impl Eq for ScopedNoteHash { fn eq(self, other: ScopedNoteHash) -> bool { (self.note_hash == other.note_hash) - & (self.nullifier_counter == other.nullifier_counter) & (self.contract_address == other.contract_address) } } @@ -95,7 +93,6 @@ impl Empty for ScopedNoteHash { fn empty() -> Self { ScopedNoteHash { note_hash: NoteHash::empty(), - nullifier_counter: 0, contract_address: AztecAddress::zero(), } } @@ -103,7 +100,7 @@ impl Empty for ScopedNoteHash { impl Serialize for ScopedNoteHash { fn serialize(self) -> [Field; SCOPED_NOTE_HASH_LENGTH] { - array_concat(self.note_hash.serialize(), [self.nullifier_counter as Field, self.contract_address.to_field()]) + array_concat(self.note_hash.serialize(), [self.contract_address.to_field()]) } } @@ -112,7 +109,6 @@ impl Deserialize for ScopedNoteHash { let mut reader = Reader::new(values); let res = Self { note_hash: reader.read_struct(NoteHash::deserialize), - nullifier_counter: reader.read_u32(), contract_address: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); @@ -127,9 +123,6 @@ impl Readable for ScopedNoteHash { assert( read_request.counter() > self.note_hash.counter, "Read request counter must be greater than the counter of the note hash" ); - assert( - (self.nullifier_counter == 0) | (read_request.counter() < self.nullifier_counter), "Read request counter must be less than the nullifier counter of the note hash" - ); } } 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 b7aa2f9faea..78045e17322 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -181,7 +181,7 @@ global ENCRYPTED_LOG_HASH_LENGTH = 4; global SCOPED_ENCRYPTED_LOG_HASH_LENGTH = ENCRYPTED_LOG_HASH_LENGTH + 1; global NOTE_LOG_HASH_LENGTH = 4; global NOTE_HASH_LENGTH = 2; -global SCOPED_NOTE_HASH_LENGTH = NOTE_HASH_LENGTH + 2; +global SCOPED_NOTE_HASH_LENGTH = NOTE_HASH_LENGTH + 1; global NULLIFIER_LENGTH = 3; global SCOPED_NULLIFIER_LENGTH = NULLIFIER_LENGTH + 1; global CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH + 1; 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 bf4a9151288..324ed42e7ad 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 @@ -475,19 +475,17 @@ impl FixtureBuilder { } } - pub fn add_new_note_hash(&mut self, value: Field, nullifier_counter: u32) { - self.new_note_hashes.push( - NoteHash { value, counter: self.next_counter() }.scope(nullifier_counter, self.storage_contract_address) - ); + pub fn add_new_note_hash(&mut self, value: Field) { + self.new_note_hashes.push(NoteHash { value, counter: self.next_counter() }.scope(self.storage_contract_address)); } pub fn add_siloed_note_hash(&mut self, value: Field) { // 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 note_hash = NoteHash { value, counter: 0 }.scope(self.storage_contract_address); let siloed_value = silo_note_hash(note_hash, tx_hash, index); - self.add_new_note_hash(siloed_value, 0); + self.add_new_note_hash(siloed_value); } pub fn append_new_note_hashes(&mut self, num_new_note_hashes: u32) { @@ -495,7 +493,7 @@ impl FixtureBuilder { for i in 0..self.new_note_hashes.max_len() { if i < num_new_note_hashes { let value = self.mock_note_hash_value(index_offset + i); - self.add_new_note_hash(value, 0); + self.add_new_note_hash(value); } } } @@ -515,7 +513,7 @@ impl FixtureBuilder { for i in 0..self.new_note_hashes.max_len() { if i < num_new_note_hashes { let value = self.mock_note_hash_value(index_offset + i); - self.add_new_note_hash(value, 0); + self.add_new_note_hash(value); let (log_hash, length) = self.mock_note_encrypted_log(index_offset + i); self.add_note_encrypted_log_hash(log_hash, length, self.counter - 1); } diff --git a/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.test.ts b/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.test.ts index 26d871b060e..32c0ee1ca81 100644 --- a/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.test.ts +++ b/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.test.ts @@ -44,7 +44,7 @@ describe('buildNoteHashReadRequestHints', () => { const makeReadRequest = (value: number, counter = 2) => new ReadRequest(new Fr(value), counter).scope(contractAddress); - const makeNoteHash = (value: number, counter = 1) => new NoteHash(new Fr(value), counter).scope(0, contractAddress); + const makeNoteHash = (value: number, counter = 1) => new NoteHash(new Fr(value), counter).scope(contractAddress); const readPendingNoteHash = (noteHashIndex: number) => { const readRequestIndex = numReadRequests; diff --git a/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.ts b/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.ts index c065e0d422d..9a18229292d 100644 --- a/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.ts +++ b/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.ts @@ -19,8 +19,7 @@ export function isValidNoteHashReadRequest(readRequest: ScopedReadRequest, noteH return ( noteHash.value.equals(readRequest.value) && noteHash.contractAddress.equals(readRequest.contractAddress) && - readRequest.counter > noteHash.counter && - (noteHash.nullifierCounter === 0 || noteHash.nullifierCounter > readRequest.counter) + readRequest.counter > noteHash.counter ); } diff --git a/yarn-project/circuits.js/src/hints/build_transient_data_hints.test.ts b/yarn-project/circuits.js/src/hints/build_transient_data_hints.test.ts index c775bad8ec4..933c377636e 100644 --- a/yarn-project/circuits.js/src/hints/build_transient_data_hints.test.ts +++ b/yarn-project/circuits.js/src/hints/build_transient_data_hints.test.ts @@ -2,7 +2,6 @@ import { AztecAddress, Fr, NoteHash, - NoteLogHash, Nullifier, ReadRequest, type ScopedNoteHash, @@ -17,17 +16,17 @@ describe('buildTransientDataHints', () => { let noteHashes: ScopedNoteHash[]; let nullifiers: ScopedNullifier[]; - let logs: NoteLogHash[]; let futureNoteHashReads: ScopedReadRequest[]; let futureNullifierReads: ScopedReadRequest[]; + let noteHashNullifierCounterMap: Map; beforeEach(() => { noteHashes = [ - new NoteHash(new Fr(11), 100).scope(700, contractAddress), - new NoteHash(new Fr(22), 200).scope(0, contractAddress), // Not linked to a nullifier - new NoteHash(new Fr(33), 300).scope(500, contractAddress), // Linked to a nullifier that will be read - new NoteHash(new Fr(44), 350).scope(600, contractAddress), // Linked to a nullifier, but the note hash will be read - new NoteHash(new Fr(50), 375).scope(800, contractAddress), // Linked to a nullifier not yet known + new NoteHash(new Fr(11), 100).scope(contractAddress), + new NoteHash(new Fr(22), 200).scope(contractAddress), + new NoteHash(new Fr(33), 300).scope(contractAddress), + new NoteHash(new Fr(44), 350).scope(contractAddress), + new NoteHash(new Fr(50), 375).scope(contractAddress), ]; nullifiers = [ new Nullifier(new Fr(55), 400, new Fr(0)).scope(contractAddress), @@ -35,23 +34,22 @@ describe('buildTransientDataHints', () => { new Nullifier(new Fr(77), 600, new Fr(44)).scope(contractAddress), new Nullifier(new Fr(88), 700, new Fr(11)).scope(contractAddress), ]; - logs = [ - new NoteLogHash(new Fr(99), 350, new Fr(64), 300), - new NoteLogHash(new Fr(111), 375, new Fr(64), 300), - new NoteLogHash(new Fr(122), 150, new Fr(64), 100), - new NoteLogHash(new Fr(133), 250, new Fr(64), 200), - ]; futureNoteHashReads = [new ScopedReadRequest(new ReadRequest(new Fr(44), 351), contractAddress)]; futureNullifierReads = [new ScopedReadRequest(new ReadRequest(new Fr(66), 502), contractAddress)]; + noteHashNullifierCounterMap = new Map(); + noteHashNullifierCounterMap.set(100, 700); // Linked to a nullifier. + noteHashNullifierCounterMap.set(300, 500); // Linked to a nullifier that will be read. + noteHashNullifierCounterMap.set(350, 600); // Linked to a nullifier, but the note hash will be read. + noteHashNullifierCounterMap.set(375, 800); // Linked to a nullifier not yet known. }); it('builds index hints that link transient note hashes and nullifiers', () => { - const [nullifierIndexes, noteHashIndexesForNullifiers, noteHashIndexesForLogs] = buildTransientDataHints( + const [nullifierIndexes, noteHashIndexesForNullifiers] = buildTransientDataHints( noteHashes, nullifiers, - logs, futureNoteHashReads, futureNullifierReads, + noteHashNullifierCounterMap, ); // Only first one is squashed, since: // second one is not linked to a nullifier @@ -59,19 +57,18 @@ describe('buildTransientDataHints', () => { // and fourth note hash will be read. expect(nullifierIndexes).toEqual([3, 4, 4, 4, 4]); expect(noteHashIndexesForNullifiers).toEqual([5, 5, 5, 0]); - expect(noteHashIndexesForLogs).toEqual([5, 5, 0, 5]); }); it('throws if note hash does not match', () => { nullifiers[1].nullifier.noteHash = new Fr(11); - expect(() => buildTransientDataHints(noteHashes, nullifiers, logs, [], [])).toThrow( + expect(() => buildTransientDataHints(noteHashes, nullifiers, [], [], noteHashNullifierCounterMap)).toThrow( 'Hinted note hash does not match.', ); }); it('throws if contract address does not match', () => { nullifiers[1].contractAddress = AztecAddress.fromBigInt(123456n); - expect(() => buildTransientDataHints(noteHashes, nullifiers, logs, [], [])).toThrow( + expect(() => buildTransientDataHints(noteHashes, nullifiers, [], [], noteHashNullifierCounterMap)).toThrow( 'Contract address of hinted note hash does not match.', ); }); diff --git a/yarn-project/circuits.js/src/hints/build_transient_data_hints.ts b/yarn-project/circuits.js/src/hints/build_transient_data_hints.ts index c9dc400b528..99daa29e7d1 100644 --- a/yarn-project/circuits.js/src/hints/build_transient_data_hints.ts +++ b/yarn-project/circuits.js/src/hints/build_transient_data_hints.ts @@ -1,5 +1,4 @@ import { - type NoteLogHash, type ScopedNoteHash, type ScopedNullifier, type ScopedReadRequest, @@ -12,31 +11,21 @@ import { type Tuple } from '@aztec/foundation/serialize'; import { ScopedValueCache } from './scoped_value_cache.js'; -export function buildTransientDataHints< - NOTE_HASHES_LEN extends number, - NULLIFIERS_LEN extends number, - LOGS_LEN extends number, ->( +export function buildTransientDataHints( noteHashes: Tuple, nullifiers: Tuple, - noteLogs: Tuple, futureNoteHashReads: ScopedReadRequest[], futureNullifierReads: ScopedReadRequest[], + noteHashNullifierCounterMap: Map, noteHashesLength: NOTE_HASHES_LEN = noteHashes.length as NOTE_HASHES_LEN, nullifiersLength: NULLIFIERS_LEN = nullifiers.length as NULLIFIERS_LEN, - logsLength: LOGS_LEN = noteLogs.length as LOGS_LEN, -): [Tuple, Tuple, Tuple] { +): [Tuple, Tuple] { const futureNoteHashReadsMap = new ScopedValueCache(futureNoteHashReads); const futureNullifierReadsMap = new ScopedValueCache(futureNullifierReads); const nullifierIndexMap: Map = new Map(); nullifiers.forEach((n, i) => nullifierIndexMap.set(n.counter, i)); - const logNoteHashMap: Map = new Map(); - noteLogs.forEach((n, i) => { - logNoteHashMap.set(n.noteHashCounter, (logNoteHashMap.get(n.noteHashCounter) || []).concat([i])); - }); - const nullifierIndexesForNoteHashes: Tuple = makeTuple( noteHashesLength, () => nullifiersLength, @@ -47,20 +36,19 @@ export function buildTransientDataHints< () => noteHashesLength, ); - const noteHashIndexesForLogs: Tuple = makeTuple(logsLength, () => noteHashesLength); - const numNoteHashes = countAccumulatedItems(noteHashes); for (let i = 0; i < numNoteHashes; i++) { const noteHash = noteHashes[i]; + const noteHashNullifierCounter = noteHashNullifierCounterMap.get(noteHash.counter); // The note hash might not be linked to a nullifier or it might be read in the future if ( - noteHash.nullifierCounter == 0 || + !noteHashNullifierCounter || futureNoteHashReadsMap.get(noteHash).find(read => isValidNoteHashReadRequest(read, noteHash)) ) { continue; } - const nullifierIndex = nullifierIndexMap.get(noteHash.nullifierCounter); + const nullifierIndex = nullifierIndexMap.get(noteHashNullifierCounter); // We might not have the corresponding nullifier yet if (nullifierIndex === undefined) { continue; @@ -80,16 +68,9 @@ export function buildTransientDataHints< continue; } - const logIndices = logNoteHashMap.get(noteHash.counter); - if (logIndices) { - logIndices.forEach(logIndex => { - noteHashIndexesForLogs[logIndex] = i; - }); - } - nullifierIndexesForNoteHashes[i] = nullifierIndex; noteHashIndexesForNullifiers[nullifierIndex] = i; } - return [nullifierIndexesForNoteHashes, noteHashIndexesForNullifiers, noteHashIndexesForLogs]; + return [nullifierIndexesForNoteHashes, noteHashIndexesForNullifiers]; } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_init_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_init_circuit_private_inputs.ts index 57d1a88ddfe..9cb9adbd836 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_init_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_init_circuit_private_inputs.ts @@ -1,22 +1,8 @@ -import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { MAX_NEW_NOTE_HASHES_PER_CALL } from '../../constants.gen.js'; import { TxRequest } from '../tx_request.js'; import { PrivateCallData } from './private_call_data.js'; -export class PrivateKernelInitHints { - constructor(public noteHashNullifierCounters: Tuple) {} - - toBuffer() { - return serializeToBuffer(this.noteHashNullifierCounters); - } - - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new PrivateKernelInitHints(reader.readNumbers(MAX_NEW_NOTE_HASHES_PER_CALL)); - } -} - /** * Input to the private kernel circuit - initial call. */ @@ -30,7 +16,6 @@ export class PrivateKernelInitCircuitPrivateInputs { * Private calldata corresponding to this iteration of the kernel. */ public privateCall: PrivateCallData, - public hints: PrivateKernelInitHints, ) {} /** @@ -38,7 +23,7 @@ export class PrivateKernelInitCircuitPrivateInputs { * @returns The buffer. */ toBuffer() { - return serializeToBuffer(this.txRequest, this.privateCall, this.hints); + return serializeToBuffer(this.txRequest, this.privateCall); } /** @@ -48,10 +33,6 @@ export class PrivateKernelInitCircuitPrivateInputs { */ static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelInitCircuitPrivateInputs { const reader = BufferReader.asReader(buffer); - return new PrivateKernelInitCircuitPrivateInputs( - reader.readObject(TxRequest), - reader.readObject(PrivateCallData), - reader.readObject(PrivateKernelInitHints), - ); + return new PrivateKernelInitCircuitPrivateInputs(reader.readObject(TxRequest), reader.readObject(PrivateCallData)); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_private_inputs.ts index 877263c6f4c..88496556684 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_private_inputs.ts @@ -1,22 +1,8 @@ -import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { MAX_NEW_NOTE_HASHES_PER_CALL } from '../../constants.gen.js'; import { PrivateCallData } from './private_call_data.js'; import { PrivateKernelData } from './private_kernel_data.js'; -export class PrivateKernelInnerHints { - constructor(public noteHashNullifierCounters: Tuple) {} - - toBuffer() { - return serializeToBuffer(this.noteHashNullifierCounters); - } - - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new PrivateKernelInnerHints(reader.readNumbers(MAX_NEW_NOTE_HASHES_PER_CALL)); - } -} - /** * Input to the private kernel circuit - Inner call. */ @@ -30,7 +16,6 @@ export class PrivateKernelInnerCircuitPrivateInputs { * Private calldata corresponding to this iteration of the kernel. */ public privateCall: PrivateCallData, - public hints: PrivateKernelInnerHints, ) {} /** @@ -38,7 +23,7 @@ export class PrivateKernelInnerCircuitPrivateInputs { * @returns The buffer. */ toBuffer() { - return serializeToBuffer(this.previousKernel, this.privateCall, this.hints); + return serializeToBuffer(this.previousKernel, this.privateCall); } /** @@ -51,7 +36,6 @@ export class PrivateKernelInnerCircuitPrivateInputs { return new PrivateKernelInnerCircuitPrivateInputs( reader.readObject(PrivateKernelData), reader.readObject(PrivateCallData), - reader.readObject(PrivateKernelInnerHints), ); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_reset_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_reset_circuit_private_inputs.ts index a35c33f9730..7e8b476aed7 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_reset_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_reset_circuit_private_inputs.ts @@ -55,10 +55,6 @@ export class PrivateKernelResetHints< * Contains hints for the transient nullifiers to locate corresponding note hashes. */ public transientNoteHashIndexesForNullifiers: Tuple, - /** - * Contains hints for the transient logs to locate corresponding note hashes. - */ - public transientNoteHashIndexesForLogs: Tuple, /** * Contains hints for the transient read requests to localize corresponding commitments. */ @@ -77,7 +73,6 @@ export class PrivateKernelResetHints< return serializeToBuffer( this.transientNullifierIndexesForNoteHashes, this.transientNoteHashIndexesForNullifiers, - this.transientNoteHashIndexesForLogs, this.noteHashReadRequestHints, this.nullifierReadRequestHints, this.keyValidationHints, @@ -106,7 +101,6 @@ export class PrivateKernelResetHints< return new PrivateKernelResetHints( this.transientNullifierIndexesForNoteHashes, this.transientNoteHashIndexesForNullifiers, - this.transientNoteHashIndexesForLogs, this.noteHashReadRequestHints.trimToSizes(numNoteHashReadRequestPending, numNoteHashReadRequestSettled), this.nullifierReadRequestHints.trimToSizes(numNullifierReadRequestPending, numNullifierReadRequestSettled), this.keyValidationHints.slice(0, numKeyValidationRequests) as Tuple< @@ -138,7 +132,6 @@ export class PrivateKernelResetHints< return new PrivateKernelResetHints( reader.readNumbers(MAX_NEW_NOTE_HASHES_PER_TX), reader.readNumbers(MAX_NEW_NULLIFIERS_PER_TX), - reader.readNumbers(MAX_NOTE_ENCRYPTED_LOGS_PER_TX), reader.readObject({ fromBuffer: buf => noteHashReadRequestHintsFromBuffer(buf, numNoteHashReadRequestPending, numNoteHashReadRequestSettled), diff --git a/yarn-project/circuits.js/src/structs/note_hash.ts b/yarn-project/circuits.js/src/structs/note_hash.ts index 824b788e275..0ddd44a8021 100644 --- a/yarn-project/circuits.js/src/structs/note_hash.ts +++ b/yarn-project/circuits.js/src/structs/note_hash.ts @@ -37,13 +37,13 @@ export class NoteHash { return `value=${this.value} counter=${this.counter}`; } - scope(nullifierCounter: number, contractAddress: AztecAddress) { - return new ScopedNoteHash(this, nullifierCounter, contractAddress); + scope(contractAddress: AztecAddress) { + return new ScopedNoteHash(this, contractAddress); } } export class ScopedNoteHash implements Ordered { - constructor(public noteHash: NoteHash, public nullifierCounter: number, public contractAddress: AztecAddress) {} + constructor(public noteHash: NoteHash, public contractAddress: AztecAddress) {} get counter() { return this.noteHash.counter; @@ -54,36 +54,32 @@ export class ScopedNoteHash implements Ordered { } toFields(): Fr[] { - return [...this.noteHash.toFields(), new Fr(this.nullifierCounter), this.contractAddress.toField()]; + return [...this.noteHash.toFields(), this.contractAddress.toField()]; } static fromFields(fields: Fr[] | FieldReader) { const reader = FieldReader.asReader(fields); - return new ScopedNoteHash( - reader.readObject(NoteHash), - reader.readU32(), - AztecAddress.fromField(reader.readField()), - ); + return new ScopedNoteHash(reader.readObject(NoteHash), AztecAddress.fromField(reader.readField())); } isEmpty() { - return this.noteHash.isEmpty() && !this.nullifierCounter && this.contractAddress.isZero(); + return this.noteHash.isEmpty() && this.contractAddress.isZero(); } static empty() { - return new ScopedNoteHash(NoteHash.empty(), 0, AztecAddress.ZERO); + return new ScopedNoteHash(NoteHash.empty(), AztecAddress.ZERO); } toBuffer(): Buffer { - return serializeToBuffer(this.noteHash, this.nullifierCounter, this.contractAddress); + return serializeToBuffer(this.noteHash, this.contractAddress); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - return new ScopedNoteHash(NoteHash.fromBuffer(reader), reader.readNumber(), AztecAddress.fromBuffer(reader)); + return new ScopedNoteHash(NoteHash.fromBuffer(reader), AztecAddress.fromBuffer(reader)); } toString(): string { - return `noteHash=${this.noteHash} nullifierCounter=${this.nullifierCounter} contractAddress=${this.contractAddress}`; + return `noteHash=${this.noteHash} contractAddress=${this.contractAddress}`; } } diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 3cfd493bbe8..db65263e40e 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -81,9 +81,7 @@ import { type PrivateKernelData, type PrivateKernelEmptyInputs, type PrivateKernelInitCircuitPrivateInputs, - type PrivateKernelInitHints, type PrivateKernelInnerCircuitPrivateInputs, - type PrivateKernelInnerHints, type PrivateKernelResetCircuitPrivateInputs, type PrivateKernelResetHints, type PrivateKernelResetOutputs, @@ -197,9 +195,7 @@ import type { PrivateKernelData as PrivateKernelDataNoir, PrivateKernelEmptyPrivateInputs as PrivateKernelEmptyPrivateInputsNoir, PrivateKernelInitCircuitPrivateInputs as PrivateKernelInitCircuitPrivateInputsNoir, - PrivateKernelInitHints as PrivateKernelInitHintsNoir, PrivateKernelInnerCircuitPrivateInputs as PrivateKernelInnerCircuitPrivateInputsNoir, - PrivateKernelInnerHints as PrivateKernelInnerHintsNoir, PrivateKernelResetCircuitPrivateInputs as PrivateKernelResetCircuitPrivateInputsNoir, PrivateKernelResetHints as PrivateKernelResetHintsNoir, PrivateKernelResetOutputs as PrivateKernelResetOutputsNoir, @@ -613,7 +609,6 @@ function mapNoteHashFromNoir(noteHash: NoteHashNoir) { function mapScopedNoteHashToNoir(noteHash: ScopedNoteHash): ScopedNoteHashNoir { return { note_hash: mapNoteHashToNoir(noteHash.noteHash), - nullifier_counter: mapNumberToNoir(noteHash.nullifierCounter), contract_address: mapAztecAddressToNoir(noteHash.contractAddress), }; } @@ -621,7 +616,6 @@ function mapScopedNoteHashToNoir(noteHash: ScopedNoteHash): ScopedNoteHashNoir { function mapScopedNoteHashFromNoir(noteHash: ScopedNoteHashNoir) { return new ScopedNoteHash( mapNoteHashFromNoir(noteHash.note_hash), - mapNumberFromNoir(noteHash.nullifier_counter), mapAztecAddressFromNoir(noteHash.contract_address), ); } @@ -1596,25 +1590,12 @@ export function mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir( ); } -function mapPrivateKernelInitHintsToNoir(inputs: PrivateKernelInitHints): PrivateKernelInitHintsNoir { - return { - note_hash_nullifier_counters: mapTuple(inputs.noteHashNullifierCounters, mapNumberToNoir), - }; -} - -function mapPrivateKernelInnerHintsToNoir(inputs: PrivateKernelInnerHints): PrivateKernelInnerHintsNoir { - return { - note_hash_nullifier_counters: mapTuple(inputs.noteHashNullifierCounters, mapNumberToNoir), - }; -} - export function mapPrivateKernelInitCircuitPrivateInputsToNoir( inputs: PrivateKernelInitCircuitPrivateInputs, ): PrivateKernelInitCircuitPrivateInputsNoir { return { tx_request: mapTxRequestToNoir(inputs.txRequest), private_call: mapPrivateCallDataToNoir(inputs.privateCall), - hints: mapPrivateKernelInitHintsToNoir(inputs.hints), }; } @@ -1624,7 +1605,6 @@ export function mapPrivateKernelInnerCircuitPrivateInputsToNoir( return { previous_kernel: mapPrivateKernelDataToNoir(inputs.previousKernel), private_call: mapPrivateCallDataToNoir(inputs.privateCall), - hints: mapPrivateKernelInnerHintsToNoir(inputs.hints), }; } @@ -1657,7 +1637,6 @@ function mapPrivateKernelResetHintsToNoir< mapNumberToNoir, ), transient_note_hash_indexes_for_nullifiers: mapTuple(inputs.transientNoteHashIndexesForNullifiers, mapNumberToNoir), - transient_note_hash_indexes_for_logs: mapTuple(inputs.transientNoteHashIndexesForLogs, mapNumberToNoir), note_hash_read_request_hints: mapNoteHashReadRequestHintsToNoir(inputs.noteHashReadRequestHints), nullifier_read_request_hints: mapNullifierReadRequestHintsToNoir(inputs.nullifierReadRequestHints), key_validation_hints: inputs.keyValidationHints.map(mapKeyValidationHintToNoir) as FixedLengthArray< diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index e60353cd405..de672aa964d 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -89,7 +89,6 @@ describe('Kernel Prover', () => { const noteHashes = makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, ScopedNoteHash.empty); for (let i = 0; i < newNoteIndices.length; i++) { noteHashes[i] = new NoteHash(generateFakeSiloedCommitment(notesAndSlots[newNoteIndices[i]]), 0).scope( - 0, contractAddress, ); } diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 33d62677e6c..7835cb99239 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -31,11 +31,7 @@ import { assertLength } from '@aztec/foundation/serialize'; import { pushTestData } from '@aztec/foundation/testing'; import { type ExecutionResult, collectNoteHashLeafIndexMap, collectNullifiedNoteHashCounters } from '@aztec/simulator'; -import { - buildPrivateKernelInitHints, - buildPrivateKernelInnerHints, - buildPrivateKernelResetInputs, -} from './private_inputs_builders/index.js'; +import { buildPrivateKernelResetInputs } from './private_inputs_builders/index.js'; import { type ProvingDataOracle } from './proving_data_oracle.js'; /** @@ -107,18 +103,10 @@ export class KernelProver { ); if (firstIteration) { - const hints = buildPrivateKernelInitHints( - currentExecution.callStackItem.publicInputs, - noteHashNullifierCounterMap, - ); - const proofInput = new PrivateKernelInitCircuitPrivateInputs(txRequest, privateCallData, hints); + const proofInput = new PrivateKernelInitCircuitPrivateInputs(txRequest, privateCallData); pushTestData('private-kernel-inputs-init', proofInput); output = await this.proofCreator.createProofInit(proofInput); } else { - const hints = buildPrivateKernelInnerHints( - currentExecution.callStackItem.publicInputs, - noteHashNullifierCounterMap, - ); const previousVkMembershipWitness = await this.oracle.getVkMembershipWitness(output.verificationKey); const previousKernelData = new PrivateKernelData( output.publicInputs, @@ -127,7 +115,7 @@ export class KernelProver { Number(previousVkMembershipWitness.leafIndex), assertLength(previousVkMembershipWitness.siblingPath, VK_TREE_HEIGHT), ); - const proofInput = new PrivateKernelInnerCircuitPrivateInputs(previousKernelData, privateCallData, hints); + const proofInput = new PrivateKernelInnerCircuitPrivateInputs(previousKernelData, privateCallData); pushTestData('private-kernel-inputs-inner', proofInput); output = await this.proofCreator.createProofInner(proofInput); } @@ -185,7 +173,6 @@ export class KernelProver { getNonEmptyItems(output.publicInputs.validationRequests.noteHashReadRequests).length > 0 || getNonEmptyItems(output.publicInputs.validationRequests.nullifierReadRequests).length > 0 || getNonEmptyItems(output.publicInputs.validationRequests.scopedKeyValidationRequestsAndGenerators).length > 0 || - output.publicInputs.end.newNoteHashes.find(noteHash => noteHash.nullifierCounter !== 0) || output.publicInputs.end.newNullifiers.find(nullifier => !nullifier.nullifiedNoteHash.equals(Fr.zero())) ); } diff --git a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts deleted file mode 100644 index bd5e305cede..00000000000 --- a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { - type MAX_NEW_NOTE_HASHES_PER_CALL, - type PrivateCircuitPublicInputs, - PrivateKernelInitHints, -} from '@aztec/circuits.js'; -import { type Tuple } from '@aztec/foundation/serialize'; - -export function buildPrivateKernelInitHints( - publicInputs: PrivateCircuitPublicInputs, - noteHashNullifierCounterMap: Map, -) { - const nullifierCounters = publicInputs.newNoteHashes.map( - n => noteHashNullifierCounterMap.get(n.counter) ?? 0, - ) as Tuple; - - return new PrivateKernelInitHints(nullifierCounters); -} diff --git a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_inner_hints.ts b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_inner_hints.ts deleted file mode 100644 index a03ac365947..00000000000 --- a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_inner_hints.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { - type MAX_NEW_NOTE_HASHES_PER_CALL, - type PrivateCircuitPublicInputs, - PrivateKernelInnerHints, -} from '@aztec/circuits.js'; -import { type Tuple } from '@aztec/foundation/serialize'; - -export function buildPrivateKernelInnerHints( - publicInputs: PrivateCircuitPublicInputs, - noteHashNullifierCounterMap: Map, -) { - const nullifierCounters = publicInputs.newNoteHashes.map( - n => noteHashNullifierCounterMap.get(n.counter) ?? 0, - ) as Tuple; - - return new PrivateKernelInnerHints(nullifierCounters); -} diff --git a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts index 9f60dbbbf8e..28d68eb926d 100644 --- a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts +++ b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts @@ -4,7 +4,6 @@ import { MAX_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, MembershipWitness, @@ -102,11 +101,7 @@ export async function buildPrivateKernelResetInputs( const nonEmptyNoteHashes = getNonEmptyItems(executionResult.callStackItem.publicInputs.newNoteHashes); return nonEmptyNoteHashes.map( noteHash => - new ScopedNoteHash( - noteHash, - noteHashNullifierCounterMap.get(noteHash.counter) ?? 0, - executionResult.callStackItem.publicInputs.callContext.storageContractAddress, - ), + new ScopedNoteHash(noteHash, executionResult.callStackItem.publicInputs.callContext.storageContractAddress), ); }); @@ -159,19 +154,14 @@ export async function buildPrivateKernelResetInputs( executionResult => executionResult.callStackItem.publicInputs.nullifierReadRequests, ); - const [ - transientNullifierIndexesForNoteHashes, - transientNoteHashIndexesForNullifiers, - transientNoteHashIndexesForLogs, - ] = buildTransientDataHints( + const [transientNullifierIndexesForNoteHashes, transientNoteHashIndexesForNullifiers] = buildTransientDataHints( publicInputs.end.newNoteHashes, publicInputs.end.newNullifiers, - publicInputs.end.noteEncryptedLogsHashes, futureNoteHashReads, futureNullifierReads, + noteHashNullifierCounterMap, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NOTE_ENCRYPTED_LOGS_PER_TX, ); const expectedOutputs = buildPrivateKernelResetOutputs( @@ -198,7 +188,6 @@ export async function buildPrivateKernelResetInputs( new PrivateKernelResetHints( transientNullifierIndexesForNoteHashes, transientNoteHashIndexesForNullifiers, - transientNoteHashIndexesForLogs, noteHashReadRequestHints, nullifierReadRequestHints, keysHints, diff --git a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/index.ts b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/index.ts index 56b9765bf9c..762d6b2615b 100644 --- a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/index.ts +++ b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/index.ts @@ -1,4 +1,2 @@ -export { buildPrivateKernelInitHints } from './build_private_kernel_init_hints.js'; -export { buildPrivateKernelInnerHints } from './build_private_kernel_inner_hints.js'; export { buildPrivateKernelResetInputs } from './build_private_kernel_reset_hints.js'; export { buildPrivateKernelResetOutputs } from './build_private_kernel_reset_outputs.js'; From db28db7e42f2f27efb3c0931f2dab045d6213608 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Wed, 3 Jul 2024 19:42:51 +0000 Subject: [PATCH 2/3] Build private reset circuit output in noir. --- .../private-kernel-lib/src/components/mod.nr | 1 + .../src/components/reset_output_composer.nr | 42 ++++++++++ .../squash_transient_data.nr | 34 ++++++++ .../src/private_kernel_reset.nr | 78 +++++++++---------- .../crates/reset-kernel-lib/src/tests/mod.nr | 1 - .../src/tests/squash_transient_data.nr | 41 ---------- ...ate_kernel_reset_circuit_private_inputs.ts | 30 +------ .../src/type_conversion.ts | 11 --- .../build_private_kernel_reset_hints.ts | 10 --- .../build_private_kernel_reset_outputs.ts | 45 ----------- .../private_inputs_builders/index.ts | 1 - 11 files changed, 116 insertions(+), 178 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer/squash_transient_data.nr delete mode 100644 noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/squash_transient_data.nr delete mode 100644 yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.ts diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/mod.nr index b61366e753c..49a01195740 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/mod.nr @@ -2,6 +2,7 @@ mod previous_kernel_validator; mod private_call_data_validator; mod private_kernel_circuit_output_validator; mod private_kernel_circuit_public_inputs_composer; +mod reset_output_composer; mod tail_output_composer; mod tail_output_validator; mod tail_to_public_output_composer; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer.nr new file mode 100644 index 00000000000..0283674772e --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer.nr @@ -0,0 +1,42 @@ +mod squash_transient_data; + +use crate::components::reset_output_composer::squash_transient_data::squash_transient_data; +use dep::types::{ + abis::{ + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, log_hash::NoteLogHash, + note_hash::ScopedNoteHash, nullifier::ScopedNullifier +}, + constants::{MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX} +}; + +struct PrivateKernelResetOutputs { + note_hashes: [ScopedNoteHash; MAX_NOTE_HASHES_PER_TX], + nullifiers: [ScopedNullifier; MAX_NULLIFIERS_PER_TX], + note_encrypted_log_hashes: [NoteLogHash; MAX_NOTE_ENCRYPTED_LOGS_PER_TX], +} + +struct ResetOutputComposer { + output: PrivateKernelResetOutputs, +} + +impl ResetOutputComposer { + pub fn new( + previous_kernel: PrivateKernelCircuitPublicInputs, + transient_nullifier_indexes_for_note_hashes: [u32; MAX_NOTE_HASHES_PER_TX], + transient_note_hash_indexes_for_nullifiers: [u32; MAX_NULLIFIERS_PER_TX] + ) -> Self { + let (note_hashes, nullifiers, note_encrypted_log_hashes) = squash_transient_data( + previous_kernel.end.note_hashes, + previous_kernel.end.nullifiers, + previous_kernel.end.note_encrypted_logs_hashes, + transient_nullifier_indexes_for_note_hashes, + transient_note_hash_indexes_for_nullifiers + ); + let output = PrivateKernelResetOutputs { note_hashes, nullifiers, note_encrypted_log_hashes }; + ResetOutputComposer { output } + } + + pub fn finish(self) -> PrivateKernelResetOutputs { + self.output + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer/squash_transient_data.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer/squash_transient_data.nr new file mode 100644 index 00000000000..5cd5ed47657 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer/squash_transient_data.nr @@ -0,0 +1,34 @@ +use dep::types::abis::{note_hash::ScopedNoteHash, nullifier::ScopedNullifier, log_hash::NoteLogHash}; + +unconstrained pub fn squash_transient_data( + note_hashes: [ScopedNoteHash; M], + nullifiers: [ScopedNullifier; N], + logs: [NoteLogHash; P], + transient_nullifier_indexes_for_note_hashes: [u32; M], + transient_note_hash_indexes_for_nullifiers: [u32; N] +) -> ([ScopedNoteHash; M], [ScopedNullifier; N], [NoteLogHash; P]) { + let mut propagated_note_hashes = BoundedVec::new(); + for i in 0..note_hashes.len() { + if transient_nullifier_indexes_for_note_hashes[i] == N { + propagated_note_hashes.push(note_hashes[i]); + } + } + + let mut propagated_nullifiers = BoundedVec::new(); + for i in 0..N { + if transient_note_hash_indexes_for_nullifiers[i] == M { + propagated_nullifiers.push(nullifiers[i]); + } + } + + let mut propagated_logs = BoundedVec::new(); + for i in 0..logs.len() { + let log = logs[i]; + let linked_note_hash_propagated = propagated_note_hashes.storage.any(|n: ScopedNoteHash| (n.counter() == log.note_hash_counter)); + if linked_note_hash_propagated { + propagated_logs.push(log); + } + } + + (propagated_note_hashes.storage, propagated_nullifiers.storage, propagated_logs.storage) +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr index f9e714be137..d3f27f69c35 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr @@ -1,23 +1,13 @@ +use crate::components::reset_output_composer::{PrivateKernelResetOutputs, ResetOutputComposer}; use dep::reset_kernel_lib::{ get_transient_or_propagated_note_hash_indexes_for_logs, KeyValidationHint, NoteHashReadRequestHints, NullifierReadRequestHints, PrivateValidationRequestProcessor, verify_squashed_transient_data }; use dep::types::{ - abis::{ - private_kernel_data::PrivateKernelData, kernel_circuit_public_inputs::KernelCircuitPublicInputs, - note_hash::ScopedNoteHash, nullifier::ScopedNullifier, log_hash::NoteLogHash -}, - constants::{MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX}, - grumpkin_private_key::GrumpkinPrivateKey, utils::arrays::array_length, traits::is_empty, - PrivateKernelCircuitPublicInputs + abis::private_kernel_data::PrivateKernelData, + constants::{MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX}, PrivateKernelCircuitPublicInputs }; -struct PrivateKernelResetOutputs { - note_hashes: [ScopedNoteHash; MAX_NOTE_HASHES_PER_TX], - nullifiers: [ScopedNullifier; MAX_NULLIFIERS_PER_TX], - note_encrypted_log_hashes: [NoteLogHash; MAX_NOTE_ENCRYPTED_LOGS_PER_TX], -} - struct PrivateKernelResetHints { transient_nullifier_indexes_for_note_hashes: [u32; MAX_NOTE_HASHES_PER_TX], transient_note_hash_indexes_for_nullifiers: [u32; MAX_NULLIFIERS_PER_TX], @@ -28,19 +18,30 @@ struct PrivateKernelResetHints { previous_kernel: PrivateKernelData, - // TODO: Construct output in an unconstrained function. - outputs: PrivateKernelResetOutputs, hints: PrivateKernelResetHints, } impl PrivateKernelResetCircuitPrivateInputs { + unconstrained fn generate_output(self) -> PrivateKernelResetOutputs { + ResetOutputComposer::new( + self.previous_kernel.public_inputs, + self.hints.transient_nullifier_indexes_for_note_hashes, + self.hints.transient_note_hash_indexes_for_nullifiers + ).finish() + } + pub fn execute(self) -> PrivateKernelCircuitPublicInputs { - let mut previous_public_inputs = self.previous_kernel.public_inputs; + // Generate output. + let output = self.generate_output(); - // verify/aggregate the previous kernel - self.previous_kernel.verify(); + // Validate inputs. + if !std::runtime::is_unconstrained() { + // verify/aggregate the previous kernel + self.previous_kernel.verify(); + } - previous_public_inputs.validation_requests = PrivateValidationRequestProcessor { + let previous_public_inputs = self.previous_kernel.public_inputs; + let updated_validation_requests = PrivateValidationRequestProcessor { validation_requests: previous_public_inputs.validation_requests, note_hash_read_request_hints: self.hints.note_hash_read_request_hints, pending_note_hashes: previous_public_inputs.end.note_hashes, @@ -48,41 +49,44 @@ impl PrivateKernelCircuitPublicInputs { - let (note_hashes, nullifiers, note_encrypted_log_hashes) = squash_transient_data( - self.previous_kernel.note_hashes.storage, - self.previous_kernel.nullifiers.storage, - self.previous_kernel.note_encrypted_logs_hashes.storage - ); - let outputs = PrivateKernelResetOutputs { note_hashes, nullifiers, note_encrypted_log_hashes }; - let hints = PrivateKernelResetHints { transient_nullifier_indexes_for_note_hashes: self.transient_nullifier_indexes_for_note_hashes, transient_note_hash_indexes_for_nullifiers: self.transient_note_hash_indexes_for_nullifiers, @@ -167,7 +163,7 @@ mod tests { key_validation_hints: [KeyValidationHint::empty(); MAX_KEY_VALIDATION_REQUESTS_PER_TX] }; - let kernel = PrivateKernelResetCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_data(), outputs, hints }; + let kernel = PrivateKernelResetCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_data(), hints }; kernel.execute() } @@ -181,7 +177,7 @@ mod tests { } #[test] - unconstrained fn execution_succeeded() { + fn execution_succeeded() { let mut builder = PrivateKernelResetInputsBuilder::new(); let _public_inputs = builder.execute(); } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/mod.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/mod.nr index b4656ea4016..def4fcea6aa 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/mod.nr @@ -2,4 +2,3 @@ mod note_hash_read_request_hints_builder; mod nullifier_non_existent_read_request_hints_builder; mod nullifier_read_request_hints_builder; mod public_data_read_request_hints_builder; -mod squash_transient_data; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/squash_transient_data.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/squash_transient_data.nr deleted file mode 100644 index 02e69069bf9..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/squash_transient_data.nr +++ /dev/null @@ -1,41 +0,0 @@ -use dep::types::abis::{note_hash::ScopedNoteHash, nullifier::ScopedNullifier, log_hash::NoteLogHash}; - -unconstrained pub fn squash_transient_data( - note_hashes: [ScopedNoteHash; M], - nullifiers: [ScopedNullifier; N], - logs: [NoteLogHash; P] -) -> ([ScopedNoteHash; M], [ScopedNullifier; N], [NoteLogHash; P]) { - let mut final_note_hashes = [ScopedNoteHash::empty(); M]; - let mut num_note_hashes = 0; - for i in 0..note_hashes.len() { - let note_hash = note_hashes[i]; - let nullified = nullifiers.any(|n: ScopedNullifier| (n.nullified_note_hash() == note_hash.note_hash.value)); - if !nullified { - final_note_hashes[num_note_hashes] = note_hash; - num_note_hashes += 1; - } - } - - let mut final_nullifiers = [ScopedNullifier::empty(); N]; - let mut num_nullifiers = 0; - for i in 0..N { - let nullifier = nullifiers[i]; - if nullifier.nullified_note_hash() == 0 { - final_nullifiers[num_nullifiers] = nullifier; - num_nullifiers += 1; - } - } - - let mut final_logs = [NoteLogHash::empty(); P]; - let mut num_logs = 0; - for i in 0..logs.len() { - let mut log = logs[i]; - let found_matching_note_hash = final_note_hashes.any(|n: ScopedNoteHash| (n.counter() == log.note_hash_counter)); - if found_matching_note_hash { - final_logs[num_logs] = log; - num_logs += 1; - } - } - - (final_note_hashes, final_nullifiers, final_logs) -} diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_reset_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_reset_circuit_private_inputs.ts index fed54658846..75d863ed186 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_reset_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_reset_circuit_private_inputs.ts @@ -1,10 +1,7 @@ import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; -import { MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '../../constants.gen.js'; +import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '../../constants.gen.js'; import { countAccumulatedItems } from '../../utils/index.js'; -import { NoteLogHash } from '../log_hash.js'; -import { ScopedNoteHash } from '../note_hash.js'; -import { ScopedNullifier } from '../nullifier.js'; import { KeyValidationHint, type NoteHashReadRequestHints, @@ -14,27 +11,6 @@ import { } from '../read_request_hints/index.js'; import { PrivateKernelData } from './private_kernel_data.js'; -export class PrivateKernelResetOutputs { - constructor( - public noteHashes: Tuple, - public nullifiers: Tuple, - public noteEncryptedLogHashes: Tuple, - ) {} - - toBuffer() { - return serializeToBuffer(this.noteHashes, this.nullifiers, this.noteEncryptedLogHashes); - } - - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new PrivateKernelResetOutputs( - reader.readArray(MAX_NOTE_HASHES_PER_TX, ScopedNoteHash), - reader.readArray(MAX_NULLIFIERS_PER_TX, ScopedNullifier), - reader.readArray(MAX_NOTE_ENCRYPTED_LOGS_PER_TX, NoteLogHash), - ); - } -} - export class PrivateKernelResetHints< NH_RR_PENDING extends number, NH_RR_SETTLED extends number, @@ -157,7 +133,6 @@ export class PrivateKernelResetCircuitPrivateInputs< * The previous kernel data */ public previousKernel: PrivateKernelData, - public outputs: PrivateKernelResetOutputs, public hints: PrivateKernelResetHints< NH_RR_PENDING, NH_RR_SETTLED, @@ -177,7 +152,7 @@ export class PrivateKernelResetCircuitPrivateInputs< * @returns The buffer. */ toBuffer() { - return serializeToBuffer(this.previousKernel, this.outputs, this.hints); + return serializeToBuffer(this.previousKernel, this.hints); } /** @@ -211,7 +186,6 @@ export class PrivateKernelResetCircuitPrivateInputs< const reader = BufferReader.asReader(buffer); return new PrivateKernelResetCircuitPrivateInputs( reader.readObject(PrivateKernelData), - reader.readObject(PrivateKernelResetOutputs), reader.readObject({ fromBuffer: buf => PrivateKernelResetHints.fromBuffer( diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 285c2139b72..163df4f5e43 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -84,7 +84,6 @@ import { type PrivateKernelInnerCircuitPrivateInputs, type PrivateKernelResetCircuitPrivateInputs, type PrivateKernelResetHints, - type PrivateKernelResetOutputs, type PrivateKernelTailCircuitPrivateInputs, PrivateKernelTailCircuitPublicInputs, PublicAccumulatedData, @@ -198,7 +197,6 @@ import type { PrivateKernelInnerCircuitPrivateInputs as PrivateKernelInnerCircuitPrivateInputsNoir, PrivateKernelResetCircuitPrivateInputs as PrivateKernelResetCircuitPrivateInputsNoir, PrivateKernelResetHints as PrivateKernelResetHintsNoir, - PrivateKernelResetOutputs as PrivateKernelResetOutputsNoir, PrivateKernelTailCircuitPrivateInputs as PrivateKernelTailCircuitPrivateInputsNoir, PrivateKernelTailToPublicCircuitPrivateInputs as PrivateKernelTailToPublicCircuitPrivateInputsNoir, PublicAccumulatedData as PublicAccumulatedDataNoir, @@ -1604,14 +1602,6 @@ export function mapPrivateKernelInnerCircuitPrivateInputsToNoir( }; } -function mapPrivateKernelResetOutputsToNoir(inputs: PrivateKernelResetOutputs): PrivateKernelResetOutputsNoir { - return { - note_hashes: mapTuple(inputs.noteHashes, mapScopedNoteHashToNoir), - nullifiers: mapTuple(inputs.nullifiers, mapScopedNullifierToNoir), - note_encrypted_log_hashes: mapTuple(inputs.noteEncryptedLogHashes, mapNoteLogHashToNoir), - }; -} - function mapPrivateKernelResetHintsToNoir< NH_RR_PENDING extends number, NH_RR_SETTLED extends number, @@ -1667,7 +1657,6 @@ export function mapPrivateKernelResetCircuitPrivateInputsToNoir< > { return { previous_kernel: mapPrivateKernelDataToNoir(inputs.previousKernel), - outputs: mapPrivateKernelResetOutputsToNoir(inputs.outputs), hints: mapPrivateKernelResetHintsToNoir(inputs.hints), }; } diff --git a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts index de16e2c6c0c..e46d1497a2d 100644 --- a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts +++ b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts @@ -28,7 +28,6 @@ import { type Tuple } from '@aztec/foundation/serialize'; import type { ExecutionResult } from '@aztec/simulator'; import { type ProvingDataOracle } from '../proving_data_oracle.js'; -import { buildPrivateKernelResetOutputs } from './build_private_kernel_reset_outputs.js'; function getNullifierReadRequestHints( nullifierReadRequests: Tuple, @@ -164,14 +163,6 @@ export async function buildPrivateKernelResetInputs( MAX_NULLIFIERS_PER_TX, ); - const expectedOutputs = buildPrivateKernelResetOutputs( - previousKernelData.publicInputs.end.noteHashes, - previousKernelData.publicInputs.end.nullifiers, - previousKernelData.publicInputs.end.noteEncryptedLogsHashes, - transientNullifierIndexesForNoteHashes, - transientNoteHashIndexesForNullifiers, - ); - let privateInputs; for (const [sizeTag, hintSizes] of Object.entries(PRIVATE_RESET_VARIANTS)) { @@ -184,7 +175,6 @@ export async function buildPrivateKernelResetInputs( ) { privateInputs = new PrivateKernelResetCircuitPrivateInputs( previousKernelData, - expectedOutputs, new PrivateKernelResetHints( transientNullifierIndexesForNoteHashes, transientNoteHashIndexesForNullifiers, diff --git a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.ts b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.ts deleted file mode 100644 index a6426532f39..00000000000 --- a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - MAX_NOTE_ENCRYPTED_LOGS_PER_TX, - MAX_NOTE_HASHES_PER_TX, - MAX_NULLIFIERS_PER_TX, - NoteLogHash, - PrivateKernelResetOutputs, - ScopedNoteHash, - ScopedNullifier, -} from '@aztec/circuits.js'; -import { padArrayEnd } from '@aztec/foundation/collection'; -import { type Tuple } from '@aztec/foundation/serialize'; - -export function buildPrivateKernelResetOutputs( - prevNoteHashes: Tuple, - prevNullifiers: Tuple, - prevLogs: Tuple, - transientNullifierIndexesForNoteHashes: Tuple, - transientNoteHashIndexesForNullifiers: Tuple, -) { - // Propagate note hashes that are not going to be squashed in the transient arrays. - // A value isn't going to be squashed if the symmetrical index in the corresponding array is the length of the array. - const noteHashes = padArrayEnd( - prevNoteHashes.filter((_, index) => transientNullifierIndexesForNoteHashes[index] === MAX_NULLIFIERS_PER_TX), - ScopedNoteHash.empty(), - MAX_NOTE_HASHES_PER_TX, - ); - - const nullifiers = padArrayEnd( - prevNullifiers.filter((_, index) => transientNoteHashIndexesForNullifiers[index] === MAX_NOTE_HASHES_PER_TX), - ScopedNullifier.empty(), - MAX_NULLIFIERS_PER_TX, - ); - - const nullifiedNotes = prevNoteHashes - .filter((_, index) => transientNullifierIndexesForNoteHashes[index] < MAX_NULLIFIERS_PER_TX) - .map(n => n.counter); - - const logs = padArrayEnd( - prevLogs.filter(l => !l.isEmpty() && !nullifiedNotes.includes(l.noteHashCounter)), - NoteLogHash.empty(), - MAX_NOTE_ENCRYPTED_LOGS_PER_TX, - ); - - return new PrivateKernelResetOutputs(noteHashes, nullifiers, logs); -} diff --git a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/index.ts b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/index.ts index 762d6b2615b..e63ee6b45bb 100644 --- a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/index.ts +++ b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/index.ts @@ -1,2 +1 @@ export { buildPrivateKernelResetInputs } from './build_private_kernel_reset_hints.js'; -export { buildPrivateKernelResetOutputs } from './build_private_kernel_reset_outputs.js'; From b859d303febe58f53927f925229db3ea92d4312a Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Thu, 4 Jul 2024 11:02:17 +0000 Subject: [PATCH 3/3] Validate output of reset only when constrained. --- .../src/private_kernel_reset.nr | 76 ++++++++++--------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr index d3f27f69c35..02af30ae549 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr @@ -53,31 +53,33 @@ impl