Skip to content

Commit

Permalink
feat: separate nullfier_inclusion checks for private/public/avm (#5657)
Browse files Browse the repository at this point in the history
* Public stops using/accepting a Header or blockNumber.
* I'm repurposing a `checkNullifierExists` oracle that was already defined in private/public.
  • Loading branch information
fcarreiro committed Apr 10, 2024
1 parent 413a4e0 commit e4d2df6
Show file tree
Hide file tree
Showing 9 changed files with 25 additions and 13 deletions.
7 changes: 4 additions & 3 deletions noir-projects/aztec-nr/aztec/src/context/avm_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ impl AvmContext {
pub fn l1_to_l2_msg_exists(self, msg_hash: Field, msg_leaf_index: Field) -> bool {
l1_to_l2_msg_exists(msg_hash, msg_leaf_index) == 1
}
pub fn nullifier_exists(self, nullifier: Field) -> bool {
nullifier_exists(nullifier) == 1
}

fn call_public_function_raw<ARGS_COUNT, RET_COUNT>(
self: &mut Self,
Expand Down Expand Up @@ -106,6 +103,10 @@ impl PublicContextInterface for AvmContext {
AztecAddress::zero()
}

fn nullifier_exists(self, nullifier: Field) -> bool {
nullifier_exists(nullifier) == 1
}

fn push_nullifier_read_request(&mut self, nullifier: Field) {
assert(false, "'push_nullifier_read_request' not implemented!");
}
Expand Down
1 change: 1 addition & 0 deletions noir-projects/aztec-nr/aztec/src/context/interface.nr
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ trait PublicContextInterface {
function_selector: FunctionSelector,
args: [Field; ARGS_COUNT]
) -> [Field; RETURN_VALUES_LENGTH];
fn nullifier_exists(self, nullifier: Field) -> bool;
}
7 changes: 7 additions & 0 deletions noir-projects/aztec-nr/aztec/src/context/public_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ impl PublicContextInterface for PublicContext {
self.inputs.public_global_variables.fee_recipient
}

fn nullifier_exists(self, nullifier: Field) -> bool {
nullifier_exists_oracle(nullifier) == 1
}

fn push_nullifier_read_request(&mut self, nullifier: Field) {
let request = ReadRequest { value: nullifier, counter: self.side_effect_counter };
self.nullifier_read_requests.push(request);
Expand Down Expand Up @@ -302,3 +306,6 @@ impl PublicContextInterface for PublicContext {
self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false, true)
}
}

#[oracle(checkNullifierExists)]
fn nullifier_exists_oracle(nullifier: Field) -> Field {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use dep::std::merkle::compute_merkle_root;
use dep::protocol_types::header::Header;

use crate::{
context::{PrivateContext, ContextInterface},
oracle::get_nullifier_membership_witness::get_nullifier_membership_witness,
context::PrivateContext, oracle::get_nullifier_membership_witness::get_nullifier_membership_witness,
note::{utils::compute_siloed_nullifier, note_interface::NoteInterface}
};

Expand All @@ -26,10 +25,7 @@ fn _nullifier_inclusion(nullifier: Field, header: Header) {
// was included in the nullifier tree.
}

pub fn prove_nullifier_inclusion<TContext>(
nullifier: Field,
context: TContext
) where TContext: ContextInterface {
pub fn prove_nullifier_inclusion(nullifier: Field, context: PrivateContext) {
_nullifier_inclusion(nullifier, context.get_header());
}

Expand Down
4 changes: 2 additions & 2 deletions noir-projects/aztec-nr/aztec/src/initializer.nr
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ fn mark_as_initialized<TContext>(context: &mut TContext) where TContext: Context

pub fn assert_is_initialized_public(context: &mut PublicContext) {
let init_nullifier = compute_contract_initialization_nullifier(context.this_address());
prove_nullifier_inclusion(init_nullifier, *context);
assert(context.nullifier_exists(init_nullifier), "Not initialized");
}

pub fn assert_is_initialized_avm(context: &mut AvmContext) {
// WARNING: the AVM always expects UNSILOED nullifiers!
// TODO(fcarreiro@): Change current private/public to take unsiloed nullifiers and an address.
let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());
assert(context.nullifier_exists(init_nullifier));
assert(context.nullifier_exists(init_nullifier), "Not initialized");
}

pub fn assert_is_initialized_private(context: &mut PrivateContext) {
Expand Down
2 changes: 2 additions & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/notes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,11 @@ unconstrained pub fn get_notes<Note, N, M, S, NS>(
placeholder_opt_notes
}

// Only ever use this in private!
#[oracle(checkNullifierExists)]
fn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}

// Only ever use this in private!
unconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {
check_nullifier_exists_oracle(inner_nullifier) == 1
}
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ contract AvmTest {
fn assert_unsiloed_nullifier_acvm(nullifier: Field) {
// ACVM requires siloed nullifier.
let siloed_nullifier = silo_nullifier(context.this_address(), nullifier);
prove_nullifier_inclusion(siloed_nullifier, context);
assert(context.nullifier_exists(siloed_nullifier));
}

#[aztec(public-vm)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ contract InclusionProofs {
// Proves nullifier existed at latest block
#[aztec(public)]
fn test_nullifier_inclusion_from_public(nullifier: Field) {
prove_nullifier_inclusion(nullifier, context);
assert(context.nullifier_exists(nullifier));
}

#[aztec(private)]
Expand Down
5 changes: 5 additions & 0 deletions yarn-project/simulator/src/public/public_execution_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ export class PublicExecutionContext extends TypedOracle {
return await this.commitmentsDb.getNullifierMembershipWitnessAtLatestBlock(nullifier);
}

public async checkNullifierExists(nullifier: Fr): Promise<boolean> {
const witness = await this.commitmentsDb.getNullifierMembershipWitnessAtLatestBlock(nullifier);
return !!witness;
}

public async getContractInstance(address: AztecAddress): Promise<ContractInstance> {
// Note to AVM implementor: The wrapper of the oracle call get_contract_instance in aztec-nr
// automatically checks that the returned instance is correct, by hashing it together back
Expand Down

0 comments on commit e4d2df6

Please sign in to comment.