Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Jun 19, 2024
1 parent 444d3f8 commit 24eaddf
Show file tree
Hide file tree
Showing 18 changed files with 59 additions and 49 deletions.
7 changes: 4 additions & 3 deletions noir-projects/aztec-nr/address-note/src/address_note.nr
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ struct AddressNote {

impl NoteInterface<ADDRESS_NOTE_LEN, ADDRESS_NOTE_BYTES_LEN> for AddressNote {

fn compute_nullifier(self, context: &mut PrivateContext) -> Field {
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2] {
let note_hash_for_nullify = compute_note_hash_for_consumption(self);
let secret = context.request_nsk_app(self.npk_m_hash);
poseidon2_hash([
let nullifier = poseidon2_hash([
note_hash_for_nullify,
secret,
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
])
]);
[note_hash_for_nullify, nullifier]
}

fn compute_nullifier_without_context(self) -> Field {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ mod test {

fn set_header(&mut self, header: NoteHeader) {self.header = header; }

fn compute_nullifier(self, context: &mut PrivateContext) -> Field {1}
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2] {
[1, 1]
}

fn compute_nullifier_without_context(self) -> Field {1}

Expand Down
12 changes: 7 additions & 5 deletions noir-projects/aztec-nr/aztec/src/note/lifecycle.nr
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,23 @@ pub fn destroy_note<Note, N, M>(
context: &mut PrivateContext,
note: Note
) where Note: NoteInterface<N, M> {
let mut nullifier = 0;
let mut consumed_note_hash: Field = 0;
nullifier = note.compute_nullifier(context);
// TODO(benesjan): try just directly setting the value to consumed_note_hash and not doing the if-else down
// let [note_hash, nullifier] = note.compute_note_hash_and_nullifier(context);
let result = note.compute_note_hash_and_nullifier(context);
let note_hash = result[0];
let nullifier = result[1];

// We also need the note hash corresponding to the "nullifier"
let header = note.get_header();

// A non-zero note hash counter implies that we're nullifying a transient note (i.e. one that has not yet been
// persisted in the trees and is instead in the pending new note hashes array). In such a case we compute its hash
// to inform the kernel which note we're nullifyng so that it can find it and squash both the note and the
// nullifier. This value is unused when nullifying non transient notes - in that case the kernel simply persists
// nullifier. This value is unused when nullifying non-transient notes - in that case the kernel simply persists
// the nullifier in the tree.
if (header.note_hash_counter != 0) {
// TODO(1718): Can we reuse the note hash computed in `compute_nullifier`?
consumed_note_hash = compute_note_hash_for_consumption(note);
consumed_note_hash = note_hash;
}

let nullifier_counter = context.side_effect_counter;
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/note/note_interface.nr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use dep::protocol_types::grumpkin_point::GrumpkinPoint;

// docs:start:note_interface
trait NoteInterface<N, M> {
fn compute_nullifier(self, context: &mut PrivateContext) -> Field;
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2];

fn compute_nullifier_without_context(self) -> Field;

Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/note/utils.nr
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn compute_siloed_nullifier<Note, N, M>(
context: &mut PrivateContext
) -> Field where Note: NoteInterface<N, M> {
let header = note_with_header.get_header();
let inner_nullifier = note_with_header.compute_nullifier(context);
let inner_nullifier = note_with_header.compute_note_hash_and_nullifier(context)[1];

let input = [header.contract_address.to_field(), inner_nullifier];
pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ impl<Note, Context> PrivateMutable<Note, Context> {
// Under such circumstances, such application developers might wish to _not_ use this state variable type.
// This is especially dangerous for initial assignment to elements of a `Map<AztecAddress, PrivateMutable>` type (for example), because the storage slot often also identifies an actor. e.g.
// the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.
// Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy.
// For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.
// Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_note_hash_and_nullifier()` method of the underlying note is designed to ensure privacy.
// For example, if the `compute_note_hash_and_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.
pub fn compute_initialization_nullifier(self) -> Field {
pedersen_hash(
[self.storage_slot],
Expand Down
4 changes: 2 additions & 2 deletions noir-projects/aztec-nr/aztec/src/test/mocks/mock_note.nr
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ impl NoteInterface<MOCK_NOTE_LENGTH, MOCK_NOTE_BYTES_LENGTH> for MockNote {
0
}

fn compute_nullifier(self, _context: &mut PrivateContext) -> Field {
0
fn compute_note_hash_and_nullifier(self, _context: &mut PrivateContext) -> [Field; 2] {
[0, 0]
}

fn compute_nullifier_without_context(self) -> Field {
Expand Down
7 changes: 4 additions & 3 deletions noir-projects/aztec-nr/value-note/src/value_note.nr
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ struct ValueNote {
impl NoteInterface<VALUE_NOTE_LEN, VALUE_NOTE_BYTES_LEN> for ValueNote {
// docs:start:nullifier

fn compute_nullifier(self, context: &mut PrivateContext) -> Field {
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2] {
let note_hash_for_nullify = compute_note_hash_for_consumption(self);
let secret = context.request_nsk_app(self.npk_m_hash);
poseidon2_hash([
let nullifier = poseidon2_hash([
note_hash_for_nullify,
secret,
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
])
]);
[note_hash_for_nullify, nullifier]
}

// docs:end:nullifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ struct SubscriptionNote {
}

impl NoteInterface<SUBSCRIPTION_NOTE_LEN, SUBSCRIPTION_NOTE_BYTES_LEN> for SubscriptionNote {
fn compute_nullifier(self, context: &mut PrivateContext) -> Field {
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2] {
let note_hash_for_nullify = compute_note_hash_for_consumption(self);
let secret = context.request_nsk_app(self.npk_m_hash);
poseidon2_hash([
let nullifier = poseidon2_hash([
note_hash_for_nullify,
secret,
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
])
]);
[note_hash_for_nullify, nullifier]
}

fn compute_nullifier_without_context(self) -> Field {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ contract Claim {
// Note: Only the owner of the npk_m will be able to produce the nsk_app and compute this nullifier.
// The nullifier is unique to the note and THIS contract because the protocol siloes all nullifiers with
// the address of a contract it was emitted from.
context.push_new_nullifier(proof_note.compute_nullifier(&mut context), 0);
let nullifier = proof_note.compute_note_hash_and_nullifier(&mut context)[1];
context.push_new_nullifier(nullifier, 0);

// 4) Finally we mint the reward token to the sender of the transaction
Token::at(storage.reward_token.read_private()).mint_public(recipient, proof_note.value).enqueue(&mut context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ impl CardNote {
}

impl NoteInterface<CARD_NOTE_LEN, CARD_NOTE_BYTES_LEN> for CardNote {
fn compute_nullifier(self, context: &mut PrivateContext) -> Field {
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2] {
let note_hash_for_nullify = compute_note_hash_for_consumption(self);
let secret = context.request_nsk_app(self.npk_m_hash);
poseidon2_hash([
let nullifier = poseidon2_hash([
note_hash_for_nullify,
secret,
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
])
]);
[note_hash_for_nullify, nullifier]
}

fn compute_nullifier_without_context(self) -> Field {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,15 @@ impl NoteInterface<ECDSA_PUBLIC_KEY_NOTE_LEN, ECDSA_PUBLIC_KEY_NOTE_BYTES_LEN> f
EcdsaPublicKeyNote { x, y, npk_m_hash: serialized_note[4], header: NoteHeader::empty() }
}

fn compute_nullifier(self, context: &mut PrivateContext) -> Field {
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2] {
let note_hash_for_nullify = compute_note_hash_for_consumption(self);
let secret = context.request_nsk_app(self.npk_m_hash);
poseidon2_hash([
let nullifier = poseidon2_hash([
note_hash_for_nullify,
secret,
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
])
]);
[note_hash_for_nullify, nullifier]
}

fn compute_nullifier_without_context(self) -> Field {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ struct PublicKeyNote {
}

impl NoteInterface<PUBLIC_KEY_NOTE_LEN, PUBLIC_KEY_NOTE_BYTES_LEN> for PublicKeyNote {
fn compute_nullifier(self, context: &mut PrivateContext) -> Field {
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2] {
let note_hash_for_nullify = compute_note_hash_for_consumption(self);
let secret = context.request_nsk_app(self.npk_m_hash);
poseidon2_hash([
let nullifier = poseidon2_hash([
note_hash_for_nullify,
secret,
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
])
]);
[note_hash_for_nullify, nullifier]
}

fn compute_nullifier_without_context(self) -> Field {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ struct TestNote {

impl NoteInterface<TEST_NOTE_LEN, TEST_NOTE_BYTES_LENGTH> for TestNote {

fn compute_nullifier(self, _context: &mut PrivateContext) -> Field {
fn compute_note_hash_and_nullifier(self, _context: &mut PrivateContext) -> [Field; 2] {
// This note is expected to be shared between users and for this reason can't be nullified using a secret.
0
[0, 0]
}

fn compute_nullifier_without_context(self) -> Field {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use dep::aztec::{
trait OwnedNote {
fn new(amount: U128, owner_npk_m_hash: Field) -> Self;
fn get_amount(self) -> U128;
fn get_owner_npk_m_hash(self) -> Field;
}

global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header.
Expand All @@ -27,14 +26,15 @@ struct TokenNote {

impl NoteInterface<TOKEN_NOTE_LEN, TOKEN_NOTE_BYTES_LEN> for TokenNote {
// docs:start:nullifier
fn compute_nullifier(self, context: &mut PrivateContext) -> Field {
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2] {
let note_hash_for_nullify = compute_note_hash_for_consumption(self);
let secret = context.request_nsk_app(self.npk_m_hash);
poseidon2_hash([
let nullifier = poseidon2_hash([
note_hash_for_nullify,
secret,
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
])
]);
[note_hash_for_nullify, nullifier]
}
// docs:end:nullifier

Expand Down Expand Up @@ -62,8 +62,4 @@ impl OwnedNote for TokenNote {
fn get_amount(self) -> U128 {
self.amount
}

fn get_owner_npk_m_hash(self) -> Field {
self.npk_m_hash
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ impl NoteInterface<TRANSPARENT_NOTE_LEN, TRANSPARENT_NOTE_BYTES_LEN> for Transpa
}

// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): Ensure nullifier collisions are prevented
fn compute_nullifier(self, _context: &mut PrivateContext) -> Field {
self.compute_nullifier_without_context()
fn compute_note_hash_and_nullifier(self, _context: &mut PrivateContext) -> [Field; 2] {
// TODO(benesjan): Can we really return 0 for note hash here? Try just asser(false) here.
[0, self.compute_nullifier_without_context()]
}

// Computing a nullifier in a transparent note is not guarded by making secret a part of the nullifier preimage (as
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use dep::aztec::{
prelude::{AztecAddress, NoteHeader, NoteInterface, PrivateContext},
protocol_types::{constants::GENERATOR_INDEX__NOTE_NULLIFIER, grumpkin_point::GrumpkinPoint, hash::poseidon2_hash},
note::utils::compute_note_hash_for_consumption, oracle::unsafe_rand::unsafe_rand,
note::note_emission::NoteEmission, keys::getters::get_nsk_app
keys::getters::get_nsk_app
};

trait OwnedNote {
Expand All @@ -26,14 +26,15 @@ struct TokenNote {

impl NoteInterface<TOKEN_NOTE_LEN, TOKEN_NOTE_BYTES_LEN> for TokenNote {
// docs:start:nullifier
fn compute_nullifier(self, context: &mut PrivateContext) -> Field {
fn compute_note_hash_and_nullifier(self, context: &mut PrivateContext) -> [Field; 2] {
let note_hash_for_nullify = compute_note_hash_for_consumption(self);
let secret = context.request_nsk_app(self.npk_m_hash);
poseidon2_hash([
let nullifier = poseidon2_hash([
note_hash_for_nullify,
secret,
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
])
]);
[note_hash_for_nullify, nullifier]
}
// docs:end:nullifier

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ impl NoteInterface<TRANSPARENT_NOTE_LEN, TRANSPARENT_NOTE_BYTES_LEN> for Transpa
}

// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): Ensure nullifier collisions are prevented
fn compute_nullifier(self, _context: &mut PrivateContext) -> Field {
self.compute_nullifier_without_context()
fn compute_note_hash_and_nullifier(self, _context: &mut PrivateContext) -> [Field; 2] {
// TODO(benesjan): Can we really return 0 for note hash here?
[0, self.compute_nullifier_without_context()]
}

// Computing a nullifier in a transparent note is not guarded by making secret a part of the nullifier preimage (as
Expand Down

0 comments on commit 24eaddf

Please sign in to comment.