Skip to content

Commit

Permalink
Merge 87bde1a into 2507b6f
Browse files Browse the repository at this point in the history
  • Loading branch information
sirasistant authored Jan 14, 2025
2 parents 2507b6f + 87bde1a commit 9d891ae
Show file tree
Hide file tree
Showing 66 changed files with 3,031 additions and 2,670 deletions.
6 changes: 5 additions & 1 deletion noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
},
execution_cache,
key_validation_request::get_key_validation_request,
notes::{notify_created_nullifier, notify_nullified_note},
},
};
use dep::protocol_types::{
Expand Down Expand Up @@ -147,17 +148,20 @@ impl PrivateContext {
}

pub fn push_nullifier(&mut self, nullifier: Field) {
notify_created_nullifier(nullifier);
self.nullifiers.push(
Nullifier { value: nullifier, note_hash: 0, counter: self.next_counter() },
);
}

pub fn push_nullifier_for_note_hash(&mut self, nullifier: Field, nullified_note_hash: Field) {
let nullifier_counter = self.next_counter();
notify_nullified_note(nullifier, nullified_note_hash, nullifier_counter);
self.nullifiers.push(
Nullifier {
value: nullifier,
note_hash: nullified_note_hash,
counter: self.next_counter(),
counter: nullifier_counter,
},
);
}
Expand Down
5 changes: 1 addition & 4 deletions noir-projects/aztec-nr/aztec/src/note/lifecycle.nr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::note::{
note_interface::{NoteInterface, NullifiableNote},
utils::{compute_note_hash_for_nullify_internal, compute_note_hash_for_read_request},
};
use crate::oracle::notes::{notify_created_note, notify_nullified_note};
use crate::oracle::notes::notify_created_note;

pub fn create_note<Note, let N: u32>(
context: &mut PrivateContext,
Expand Down Expand Up @@ -88,8 +88,5 @@ where
note_hash_for_nullify
};

let nullifier_counter = context.side_effect_counter;
notify_nullified_note(nullifier, notification_note_hash, nullifier_counter);

context.push_nullifier_for_note_hash(nullifier, notification_note_hash)
}
13 changes: 13 additions & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/notes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ pub fn notify_nullified_note(nullifier: Field, note_hash: Field, counter: u32) {
unsafe { notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) };
}

/// Notifies the simulator that a non-note nullifier has been created, so that it can be used for note nonces.
pub fn notify_created_nullifier(nullifier: Field) {
// This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.
unsafe { notify_created_nullifier_oracle_wrapper(nullifier) };
}

unconstrained fn notify_created_note_oracle_wrapper<let N: u32>(
storage_slot: Field,
note_type_id: Field,
Expand Down Expand Up @@ -74,6 +80,13 @@ unconstrained fn notify_nullified_note_oracle(
_counter: u32,
) -> Field {}

unconstrained fn notify_created_nullifier_oracle_wrapper(nullifier: Field) {
let _ = notify_created_nullifier_oracle(nullifier);
}

#[oracle(notifyCreatedNullifier)]
unconstrained fn notify_created_nullifier_oracle(_nullifier: Field) -> Field {}

#[oracle(getNotes)]
unconstrained fn get_notes_oracle<let N: u32, let S: u32>(
_storage_slot: Field,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ mod tests {
let mut tx_data = FixtureBuilder::new();
// Add some random bits of state
tx_data.append_note_hashes(50);
tx_data.set_first_nullifier();
tx_data.set_protocol_nullifier();
tx_data.append_nullifiers(50);
tx_data.append_l2_to_l1_msgs(5);
tx_data.append_unencrypted_log_hashes(5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ unconstrained fn main(
private_call: PrivateCallDataWithoutPublicInputs,
app_public_inputs: PrivateCircuitPublicInputs,
is_private_only: bool,
first_nullifier_hint: Field,
) -> pub PrivateKernelCircuitPublicInputs {
let private_inputs = PrivateKernelInitCircuitPrivateInputs::new(
tx_request,
Expand All @@ -19,6 +20,7 @@ unconstrained fn main(
private_call,
app_public_inputs,
is_private_only,
first_nullifier_hint,
);
private_inputs.execute()
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ fn main(
protocol_contract_tree_root: Field,
private_call: PrivateCallDataWithoutPublicInputs,
is_private_only: bool,
first_nullifier_hint: Field,
app_public_inputs: call_data(1) PrivateCircuitPublicInputs,
) -> return_data PrivateKernelCircuitPublicInputs {
let private_inputs = PrivateKernelInitCircuitPrivateInputs::new(
Expand All @@ -19,6 +20,7 @@ fn main(
private_call,
app_public_inputs,
is_private_only,
first_nullifier_hint,
);
private_inputs.execute()
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ impl PreviousKernelValidator {
);
self.validate_common();
self.validate_empty_data();
self.validate_first_nullifier(false);
}

pub fn validate_for_private_tail_to_public(self) {
Expand All @@ -42,6 +43,23 @@ impl PreviousKernelValidator {
);
self.validate_common();
self.validate_non_empty_data();
self.validate_first_nullifier(true);
}

fn validate_first_nullifier(self, tx_can_revert: bool) {
let first_nullifier = self.previous_kernel.public_inputs.end.nullifiers[0];
assert_eq(
first_nullifier.value(),
self.previous_kernel.public_inputs.claimed_first_nullifier,
"First nullifier claim was not satisfied",
);
if tx_can_revert {
assert(
first_nullifier.nullifier.counter()
< self.previous_kernel.public_inputs.min_revertible_side_effect_counter,
"First nullifier must be non revertible",
);
}
}

fn validate_common(self) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::components::private_kernel_circuit_public_inputs_composer::create_first_nullifier;
use crate::components::private_kernel_circuit_public_inputs_composer::create_protocol_nullifier;
use dep::types::{
abis::{
kernel_circuit_public_inputs::{
Expand Down Expand Up @@ -35,16 +35,20 @@ impl PrivateKernelCircuitOutputValidator {
vk_tree_root: Field,
protocol_contract_tree_root: Field,
is_private_only: bool,
first_nullifier_hint: Field,
) {
self.validate_initial_values(
tx_request,
private_call,
vk_tree_root,
protocol_contract_tree_root,
is_private_only,
first_nullifier_hint,
);
let mut offsets = PrivateKernelCircuitPublicInputsArrayLengths::empty();
offsets.nullifiers = 1; // The first nullifier is not propagated from the private call.
if first_nullifier_hint == 0 {
offsets.nullifiers = 1; // The protocol nullifier is not propagated from the private call.
}
self.validate_propagated_from_private_call(
private_call,
private_call_array_lengths,
Expand Down Expand Up @@ -80,6 +84,7 @@ impl PrivateKernelCircuitOutputValidator {
vk_tree_root: Field,
protocol_contract_tree_root: Field,
is_private_only: bool,
first_nullifier_hint: Field,
) {
// Constants.
assert_eq(self.output.is_private_only, is_private_only, "mismatch is_private_only");
Expand All @@ -96,13 +101,16 @@ impl PrivateKernelCircuitOutputValidator {
"mismatch protocol_contract_tree_root",
);

// First nullifier.
let first_nullifier = create_first_nullifier(tx_request);
assert_eq(
self.output.end.nullifiers[0],
first_nullifier,
"first nullifier must be the tx request nullifier",
);
let protocol_nullifier = create_protocol_nullifier(tx_request);
// No need to check claimed_first_nullifier if the hint is nonzero, since it's just a prover hint that will be verified in tail.
// Also, a first_nullifier_hint of 0 with a manipulated claimed_first_nullifier will result in an always failing check in tail.
if first_nullifier_hint == 0 {
assert_eq(
self.output.end.nullifiers[0],
protocol_nullifier,
"protocol nullifier must be the tx request nullifier",
);
}

// Others.
assert_eq(
Expand Down Expand Up @@ -202,6 +210,11 @@ impl PrivateKernelCircuitOutputValidator {
previous_kernel.is_private_only,
"mismatch is_private_only",
);
assert_eq(
self.output.claimed_first_nullifier,
previous_kernel.claimed_first_nullifier,
"mismatch claimed_first_nullifier",
);
assert_eq(self.output.constants, previous_kernel.constants, "mismatch constants");

assert_eq(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use dep::types::{
utils::arrays::{array_length, array_to_bounded_vec, sort_by_counter_asc, sort_by_counter_desc},
};

pub fn create_first_nullifier(tx_request: TxRequest) -> ScopedNullifier {
pub fn create_protocol_nullifier(tx_request: TxRequest) -> ScopedNullifier {
Nullifier { value: tx_request.hash(), note_hash: 0, counter: 0 }.scope(AztecAddress::zero())
}

Expand Down Expand Up @@ -48,6 +48,7 @@ impl PrivateKernelCircuitPublicInputsComposer {
vk_tree_root: Field,
protocol_contract_tree_root: Field,
is_private_only: bool,
first_nullifier_hint: Field,
) -> Self {
let mut public_inputs = PrivateKernelCircuitPublicInputsBuilder::empty();
public_inputs.is_private_only = is_private_only;
Expand All @@ -59,8 +60,15 @@ impl PrivateKernelCircuitPublicInputsComposer {
protocol_contract_tree_root,
};

// Since it's the first iteration, we need to push the tx hash nullifier into the `nullifiers` array
public_inputs.end.nullifiers.push(create_first_nullifier(tx_request));
// If no non revertible nullifiers are created, the PXE can instruct the protocol to create a nullifier
// The existence of at least 1 non revertible nullifier will be checked in tail.
if first_nullifier_hint == 0 {
let protocol_nullifier = create_protocol_nullifier(tx_request);
public_inputs.end.nullifiers.push(protocol_nullifier);
public_inputs.claimed_first_nullifier = protocol_nullifier.value();
} else {
public_inputs.claimed_first_nullifier = first_nullifier_hint;
}
// Note that we do not need to nullify the transaction request nonce anymore.
// Should an account want to additionally use nonces for replay protection or handling cancellations,
// they will be able to do so in the account contract logic:
Expand All @@ -74,6 +82,8 @@ impl PrivateKernelCircuitPublicInputsComposer {
let mut public_inputs = PrivateKernelCircuitPublicInputsBuilder::empty();

public_inputs.is_private_only = previous_kernel_public_inputs.is_private_only;
public_inputs.claimed_first_nullifier =
previous_kernel_public_inputs.claimed_first_nullifier;
public_inputs.constants = previous_kernel_public_inputs.constants;
public_inputs.min_revertible_side_effect_counter =
previous_kernel_public_inputs.min_revertible_side_effect_counter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,15 @@ impl<let NH_RR_PENDING: u32, let NH_RR_SETTLED: u32, let NLL_RR_PENDING: u32, le
let is_private_only = self.previous_kernel.is_private_only;
let min_revertible_side_effect_counter =
self.previous_kernel.min_revertible_side_effect_counter;
let first_nullifier = self.previous_kernel.end.nullifiers[0].value();
let mut note_hashes = sort_by_counter_asc(self.hints.kept_note_hashes);
for i in 0..note_hashes.len() {
let note_hash = note_hashes[i];
let siloed_note_hash = silo_note_hash(note_hash);
let unique_note_hash =
compute_unique_siloed_note_hash(siloed_note_hash, first_nullifier, i);
let unique_note_hash = compute_unique_siloed_note_hash(
siloed_note_hash,
self.previous_kernel.claimed_first_nullifier,
i,
);
// We don't silo with nonce revertible note hashes, since we don't know their final position in the tx
note_hashes[i].note_hash.value = if is_private_only
| (note_hash.counter() < min_revertible_side_effect_counter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ impl<let NH_RR_PENDING: u32, let NH_RR_SETTLED: u32, let NLL_RR_PENDING: u32, le

fn validate_unchanged_data(self) {
assert_eq(self.output.is_private_only, self.previous_kernel.is_private_only);
assert_eq(
self.output.claimed_first_nullifier,
self.previous_kernel.claimed_first_nullifier,
);
assert_eq(self.output.constants, self.previous_kernel.constants);

assert_eq(
Expand Down Expand Up @@ -190,7 +194,6 @@ impl<let NH_RR_PENDING: u32, let NH_RR_SETTLED: u32, let NLL_RR_PENDING: u32, le
let kept_note_hashes = self.hints.kept_note_hashes;
let output_note_hashes = self.output.end.note_hashes;
let sorted_indexes = self.hints.sorted_note_hash_indexes;
let first_nullifier = self.output.end.nullifiers[0].value();
let is_private_only = self.output.is_private_only;
let min_revertible_side_effect_counter = self.output.min_revertible_side_effect_counter;

Expand All @@ -202,7 +205,7 @@ impl<let NH_RR_PENDING: u32, let NH_RR_SETTLED: u32, let NLL_RR_PENDING: u32, le
let siloed_note_hash = silo_note_hash(note_hash);
let siloed_unique_note_hash = compute_unique_siloed_note_hash(
siloed_note_hash,
first_nullifier,
self.output.claimed_first_nullifier,
sorted_index,
);
// We don't silo with nonce revertible note hashes, since we don't know their final position in the tx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct PrivateKernelInitCircuitPrivateInputs {
protocol_contract_tree_root: Field,
private_call: PrivateCallData,
is_private_only: bool,
first_nullifier_hint: Field,
}

impl PrivateKernelInitCircuitPrivateInputs {
Expand All @@ -29,13 +30,15 @@ impl PrivateKernelInitCircuitPrivateInputs {
private_call: PrivateCallDataWithoutPublicInputs,
app_public_inputs: PrivateCircuitPublicInputs,
is_private_only: bool,
first_nullifier_hint: Field,
) -> Self {
Self {
tx_request,
vk_tree_root,
protocol_contract_tree_root,
private_call: private_call.to_private_call_data(app_public_inputs),
is_private_only,
first_nullifier_hint,
}
}

Expand All @@ -47,6 +50,7 @@ impl PrivateKernelInitCircuitPrivateInputs {
self.vk_tree_root,
self.protocol_contract_tree_root,
self.is_private_only,
self.first_nullifier_hint,
)
.with_private_call(private_call_public_inputs)
.finish()
Expand Down Expand Up @@ -78,6 +82,7 @@ impl PrivateKernelInitCircuitPrivateInputs {
self.vk_tree_root,
self.protocol_contract_tree_root,
self.is_private_only,
self.first_nullifier_hint,
);
}
output
Expand Down Expand Up @@ -112,6 +117,7 @@ mod tests {
vk_tree_root: FixtureBuilder::vk_tree_root(),
protocol_contract_tree_root: 0,
is_private_only: false,
first_nullifier_hint: 0,
}
.execute()
}
Expand Down
Loading

0 comments on commit 9d891ae

Please sign in to comment.