Skip to content

Commit

Permalink
refactor: add partial note support for value note (#8141)
Browse files Browse the repository at this point in the history
We are simply adding partial note support for value note.

We do it by simply porting the logic from tokennote to value note and
adapting what needs to be adapted.

Resolves #8105.
  • Loading branch information
sklppy88 authored Aug 28, 2024
1 parent 1d129c7 commit daa57cc
Showing 1 changed file with 81 additions and 1 deletion.
82 changes: 81 additions & 1 deletion noir-projects/aztec-nr/value-note/src/value_note.nr
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
use dep::aztec::{
generators::{Ga1 as G_amt, Ga2 as G_npk, Ga3 as G_rnd, G_slot},
protocol_types::{
address::AztecAddress, traits::{Deserialize, Serialize}, constants::GENERATOR_INDEX__NOTE_NULLIFIER,
hash::poseidon2_hash_with_separator
hash::poseidon2_hash_with_separator, point::{Point, POINT_LENGTH}
},
note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_nullify},
oracle::unsafe_rand::unsafe_rand, keys::getters::get_nsk_app, context::PrivateContext
};
use dep::std::{embedded_curve_ops::multi_scalar_mul, hash::from_field_unsafe};

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 @@ -46,6 +53,22 @@ impl NoteInterface<VALUE_NOTE_LEN, VALUE_NOTE_BYTES_LEN> for ValueNote {
GENERATOR_INDEX__NOTE_NULLIFIER as Field,
)
}

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);
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 ValueNote {
Expand All @@ -54,6 +77,12 @@ impl ValueNote {
let header = NoteHeader::empty();
ValueNote { value, npk_m_hash, randomness, header }
}

// 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) -> ValueNoteHidingPoint {
ValueNoteHidingPoint::new(self.compute_note_hiding_point())
}
}

impl Serialize<7> for ValueNote {
Expand All @@ -75,3 +104,54 @@ impl Eq for ValueNote {
(self.randomness == other.randomness)
}
}

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
}

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

fn add_value(&mut self, value: U128) {
self.inner = multi_scalar_mul([G_amt], [from_field_unsafe(value.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 ValueNoteHidingPoint {
fn serialize(self) -> [Field; POINT_LENGTH] {
self.inner.serialize()
}
}

0 comments on commit daa57cc

Please sign in to comment.