Skip to content

Commit

Permalink
refactor: add uint (U128) note to aztec-nr and remove OwnedNote from …
Browse files Browse the repository at this point in the history
…ValueNote (#8142)

In this PR we are just adding a new note type to aztec-nr. This is
simply tokennote, but we are doing the addition of this note and the
removal of tokennote in two steps to make the diffs easier to
understand. This also removes `OwnedNote` from `ValueNote`.

Sets up resolving of #8107.
  • Loading branch information
sklppy88 authored Sep 6, 2024
1 parent e8e0907 commit 225b6d3
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 20 deletions.
1 change: 1 addition & 0 deletions noir-projects/aztec-nr/Nargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ members = [
"compressed-string",
"easy-private-state",
"value-note",
"uint-note",
]
8 changes: 8 additions & 0 deletions noir-projects/aztec-nr/uint-note/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "uint_note"
authors = ["aztec-labs"]
compiler_version = ">=0.18.0"
type = "lib"

[dependencies]
aztec = { path = "../aztec" }
1 change: 1 addition & 0 deletions noir-projects/aztec-nr/uint-note/src/lib.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod uint_note;
110 changes: 110 additions & 0 deletions noir-projects/aztec-nr/uint-note/src/uint_note.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use dep::aztec::{
generators::{Ga1 as G_amt, Ga2 as G_npk, Ga3 as G_rnd, G_slot},
prelude::{NoteHeader, NoteInterface, PrivateContext},
protocol_types::{
constants::GENERATOR_INDEX__NOTE_NULLIFIER, point::{Point, POINT_LENGTH}, scalar::Scalar,
hash::poseidon2_hash_with_separator, traits::Serialize
},
note::utils::compute_note_hash_for_nullify, oracle::unsafe_rand::unsafe_rand,
keys::getters::get_nsk_app
};
use dep::std::{embedded_curve_ops::multi_scalar_mul, hash::from_field_unsafe};

global UINT_NOTE_LEN: Field = 3; // 3 plus a header.
global UINT_NOTE_BYTES_LEN: Field = 3 * 32 + 64;

#[aztec(note)]
struct UintNote {
// The integer stored by the note
value: U128,
// The nullifying public key hash is used with the nsk_app to ensure that the note can be privately spent.
npk_m_hash: Field,
// Randomness of the note to hide its contents
randomness: Field,
}

impl NoteInterface<UINT_NOTE_LEN, UINT_NOTE_BYTES_LEN> for UintNote {
fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field {
let secret = context.request_nsk_app(self.npk_m_hash);
poseidon2_hash_with_separator([
note_hash_for_nullify,
secret
],
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
)
}

fn compute_nullifier_without_context(self) -> Field {
let note_hash_for_nullify = compute_note_hash_for_nullify(self);
let secret = get_nsk_app(self.npk_m_hash);
poseidon2_hash_with_separator([note_hash_for_nullify, secret],GENERATOR_INDEX__NOTE_NULLIFIER)
}

fn compute_note_hiding_point(self) -> Point {
// We use the unsafe version because the multi_scalar_mul will constrain the scalars.
let amount_scalar = from_field_unsafe(self.value.to_integer());
let npk_m_hash_scalar = from_field_unsafe(self.npk_m_hash);
let randomness_scalar = from_field_unsafe(self.randomness);
let slot_scalar = from_field_unsafe(self.header.storage_slot);
// We compute the note hiding point as:
// `G_amt * amount + G_npk * npk_m_hash + G_rnd * randomness + G_slot * slot`
// instead of using pedersen or poseidon2 because it allows us to privately add and subtract from amount
// in public by leveraging homomorphism.
multi_scalar_mul(
[G_amt, G_npk, G_rnd, G_slot],
[amount_scalar, npk_m_hash_scalar, randomness_scalar, slot_scalar]
)
}
}

impl UintNote {
// TODO: Merge this func with `compute_note_hiding_point`. I (benesjan) didn't do it in the initial PR to not have
// to modify macros and all the related funcs in it.
fn to_note_hiding_point(self) -> UintNoteHidingPoint {
UintNoteHidingPoint::new(self.compute_note_hiding_point())
}
}

struct UintNoteHidingPoint {
inner: Point
}

impl UintNoteHidingPoint {
fn new(point: Point) -> Self {
Self { inner: point }
}

fn add_amount(&mut self, amount: U128) {
self.inner = multi_scalar_mul([G_amt], [from_field_unsafe(amount.to_integer())]) + self.inner;
}

fn add_npk_m_hash(&mut self, npk_m_hash: Field) {
self.inner = multi_scalar_mul([G_npk], [from_field_unsafe(npk_m_hash)]) + self.inner;
}

fn add_randomness(&mut self, randomness: Field) {
self.inner = multi_scalar_mul([G_rnd], [from_field_unsafe(randomness)]) + self.inner;
}

fn add_slot(&mut self, slot: Field) {
self.inner = multi_scalar_mul([G_slot], [from_field_unsafe(slot)]) + self.inner;
}

fn finalize(self) -> Field {
self.inner.x
}
}

impl Serialize<POINT_LENGTH> for UintNoteHidingPoint {
fn serialize(self) -> [Field; POINT_LENGTH] {
self.inner.serialize()
}
}

impl Eq for UintNote {
fn eq(self, other: Self) -> bool {
(self.value == other.value) &
(self.npk_m_hash == other.npk_m_hash) &
(self.randomness == other.randomness)
}
}
20 changes: 0 additions & 20 deletions noir-projects/aztec-nr/value-note/src/value_note.nr
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ global VALUE_NOTE_LEN: Field = 3; // 3 plus a header.
// VALUE_NOTE_LEN * 32 + 32(storage_slot as bytes) + 32(note_type_id as bytes)
global VALUE_NOTE_BYTES_LEN: Field = 3 * 32 + 64;

trait OwnedNote {
fn new(amount: U128, owner_npk_m_hash: Field) -> Self;
fn get_amount(self) -> U128;
}

// docs:start:value-note-def
#[aztec(note)]
struct ValueNote {
Expand Down Expand Up @@ -105,21 +100,6 @@ impl Eq for ValueNote {
}
}

impl OwnedNote for ValueNote {
fn new(value: U128, owner_npk_m_hash: Field) -> Self {
Self {
value: value.to_field(),
npk_m_hash: owner_npk_m_hash,
randomness: unsafe_rand(),
header: NoteHeader::empty(),
}
}

fn get_amount(self) -> U128 {
U128::from_field(self.value)
}
}

struct ValueNoteHidingPoint {
inner: Point
}
Expand Down

0 comments on commit 225b6d3

Please sign in to comment.