Skip to content

Commit 42fd086

Browse files
author
AztecBot
committed
Merge branch 'next' into merge-train/avm
2 parents 3d61281 + 6a61e11 commit 42fd086

File tree

45 files changed

+395
-204
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+395
-204
lines changed

noir-projects/aztec-nr/aztec/src/context/mod.nr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ pub mod gas;
2222

2323
mod note_existence_request;
2424
pub use note_existence_request::NoteExistenceRequest;
25+
26+
mod nullifier_existence_request;
27+
pub use nullifier_existence_request::NullifierExistenceRequest;

noir-projects/aztec-nr/aztec/src/context/note_existence_request.nr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ impl NoteExistenceRequest {
1515
/// requests are created using the unsiloed note hash (i.e. from
1616
/// [crate::note::note_interface::NoteHash::compute_note_hash]) and address of the contract that created the note.
1717
pub fn for_pending(unsiloed_note_hash: Field, contract_address: AztecAddress) -> Self {
18+
// The kernel doesn't take options; it takes a note_hash and an address, and infers whether the request is
19+
// siloed based on whether the address is zero or non-zero. When passing the value to the kernel, we use
20+
// `maybe_addr.unwrap_or(Address::ZERO)`. Therefore, passing a zero address to `for_pending` is not allowed
21+
// since it would be interpreted by the kernel as a settled request.
1822
assert(
1923
!contract_address.is_zero(),
2024
"Can't read a transient note with a zero contract address",
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use protocol_types::address::aztec_address::AztecAddress;
2+
3+
/// A request to assert the existence of a nullifier.
4+
///
5+
/// Used by [crate::context::private_context::PrivateContext::assert_nullifier_exists].
6+
pub struct NullifierExistenceRequest {
7+
nullifier: Field,
8+
maybe_contract_address: Option<AztecAddress>,
9+
}
10+
11+
impl NullifierExistenceRequest {
12+
/// Creates an existence request for a pending nullifier.
13+
///
14+
/// Pending nullifiers have not been siloed with the contract address. These requests are created using the unsiloed
15+
/// value and address of the contract that emitted the nullifier.
16+
pub fn for_pending(unsiloed_nullifier: Field, contract_address: AztecAddress) -> Self {
17+
// The kernel doesn't take options; it takes a nullifier and an address, and infers whether the request is
18+
// siloed based on whether the address is zero or non-zero. When passing the value to the kernel, we use
19+
// `maybe_addr.unwrap_or(Address::ZERO)`. Therefore, passing a zero address to `for_pending` is not allowed
20+
// since it would be interpreted by the kernel as a settled request.
21+
assert(
22+
!contract_address.is_zero(),
23+
"Can't read a pending nullifier with a zero contract address",
24+
);
25+
Self {
26+
nullifier: unsiloed_nullifier,
27+
maybe_contract_address: Option::some(contract_address),
28+
}
29+
}
30+
31+
/// Creates an existence request for a settled nullifier.
32+
///
33+
/// Unlike pending nullifiers, settled nullifiers have been siloed with their contract addresses before adding to
34+
/// the nullifier tree, and their existence request is created using the siloed value.
35+
pub fn for_settled(siloed_nullifier: Field) -> Self {
36+
Self { nullifier: siloed_nullifier, maybe_contract_address: Option::none() }
37+
}
38+
39+
pub(crate) fn nullifier(self) -> Field {
40+
self.nullifier
41+
}
42+
43+
pub(crate) fn maybe_contract_address(self) -> Option<AztecAddress> {
44+
self.maybe_contract_address
45+
}
46+
}

noir-projects/aztec-nr/aztec/src/context/private_context.nr

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::{
2-
context::{inputs::PrivateContextInputs, NoteExistenceRequest, ReturnsHash},
2+
context::{
3+
inputs::PrivateContextInputs, NoteExistenceRequest, NullifierExistenceRequest, ReturnsHash,
4+
},
35
hash::{hash_args, hash_calldata_array},
46
keys::constants::{NULLIFIER_INDEX, NUM_KEY_TYPES, OUTGOING_INDEX, sk_generators},
57
messaging::process_l1_to_l2_message,
@@ -13,7 +15,8 @@ use crate::{
1315
execution_cache,
1416
key_validation_request::get_key_validation_request,
1517
logs::notify_created_contract_class_log,
16-
notes::{notify_created_nullifier, notify_nullified_note},
18+
notes::notify_nullified_note,
19+
nullifiers::notify_created_nullifier,
1720
},
1821
};
1922
use dep::protocol_types::{
@@ -803,13 +806,17 @@ impl PrivateContext {
803806
/// an additional invocation of the kernel reset circuit.
804807
pub fn assert_nullifier_exists(
805808
&mut self,
806-
unsiloed_nullifier: Field,
807-
contract_address: AztecAddress,
809+
nullifier_existence_request: NullifierExistenceRequest,
808810
) {
811+
let nullifier = nullifier_existence_request.nullifier();
812+
let contract_address =
813+
nullifier_existence_request.maybe_contract_address().unwrap_or(AztecAddress::zero());
814+
809815
let request = Scoped::new(
810-
Counted::new(unsiloed_nullifier, self.next_counter()),
816+
Counted::new(nullifier, self.next_counter()),
811817
contract_address,
812818
);
819+
813820
self.nullifier_read_requests.push(request);
814821
}
815822

noir-projects/aztec-nr/aztec/src/history/nullifier_inclusion/test.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::history::{
33
nullifier_inclusion::{ProveNoteIsNullified, ProveNullifierInclusion},
44
test,
55
};
6-
use crate::oracle::{notes::notify_created_nullifier, random::random};
6+
use crate::oracle::{nullifiers::notify_created_nullifier, random::random};
77
use crate::test::helpers::test_environment::{PrivateContextOptions, TestEnvironment};
88
use dep::protocol_types::{
99
constants::DOM_SEP__OUTER_NULLIFIER, hash::poseidon2_hash_with_separator, traits::ToField,

noir-projects/aztec-nr/aztec/src/history/nullifier_non_inclusion/test.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::history::{
33
nullifier_non_inclusion::{ProveNoteNotNullified, ProveNullifierNonInclusion},
44
test,
55
};
6-
use crate::oracle::{notes::notify_created_nullifier, random::random};
6+
use crate::oracle::{nullifiers::notify_created_nullifier, random::random};
77
use crate::test::helpers::test_environment::{PrivateContextOptions, TestEnvironment};
88
use dep::protocol_types::{
99
constants::DOM_SEP__OUTER_NULLIFIER, hash::poseidon2_hash_with_separator, traits::ToField,

noir-projects/aztec-nr/aztec/src/lib.nr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub mod history;
3535
pub mod keys;
3636
mod messaging;
3737
pub mod note;
38+
pub mod nullifier;
3839
pub mod oracle;
3940
pub mod state_vars;
4041
mod capsules;

noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use dep::protocol_types::{
55

66
use crate::{
77
context::{PrivateContext, PublicContext},
8+
nullifier::utils::compute_nullifier_existence_request,
89
oracle::get_contract_instance::{
910
get_contract_instance, get_contract_instance_deployer_avm,
1011
get_contract_instance_initialization_hash_avm,
@@ -39,7 +40,9 @@ pub fn assert_is_initialized_public(context: PublicContext) {
3940
// Used by `create_init_check` (you won't find it through searching)
4041
pub fn assert_is_initialized_private(context: &mut PrivateContext) {
4142
let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());
42-
context.assert_nullifier_exists(init_nullifier, context.this_address());
43+
let nullifier_existence_request =
44+
compute_nullifier_existence_request(init_nullifier, context.this_address());
45+
context.assert_nullifier_exists(nullifier_existence_request);
4346
}
4447

4548
fn compute_unsiloed_contract_initialization_nullifier(address: AztecAddress) -> Field {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
//! Nullifier-related utilities.
2+
3+
pub mod utils;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use crate::{context::NullifierExistenceRequest, oracle::nullifiers::is_nullifier_pending};
2+
3+
use protocol_types::{address::aztec_address::AztecAddress, hash::compute_siloed_nullifier};
4+
5+
/// Returns the [NullifierExistenceRequest] used to prove a nullifier exists.
6+
pub fn compute_nullifier_existence_request(
7+
unsiloed_nullifier: Field,
8+
contract_address: AztecAddress,
9+
) -> NullifierExistenceRequest {
10+
let pending_read_request =
11+
NullifierExistenceRequest::for_pending(unsiloed_nullifier, contract_address);
12+
13+
let siloed_nullifier = compute_siloed_nullifier(contract_address, unsiloed_nullifier);
14+
let settled_read_request = NullifierExistenceRequest::for_settled(siloed_nullifier);
15+
16+
// Safety: This is a hint to check whether we are reading a pending or settled nullifier. The chosen read request
17+
// will be validated by the kernel. Failure to provide a correct hint will cause the read request validation to fail.
18+
let should_use_pending_read_request =
19+
unsafe { is_nullifier_pending(unsiloed_nullifier, contract_address) };
20+
21+
if should_use_pending_read_request {
22+
pending_read_request
23+
} else {
24+
settled_read_request
25+
}
26+
}

0 commit comments

Comments
 (0)