Skip to content

Commit

Permalink
feat: typing return values of embedded_curve_ops (#7413)
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan authored Jul 10, 2024
1 parent d3ee63c commit db96077
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use std::{hash::sha256, embedded_curve_ops::multi_scalar_mul};
// TODO(#5726): This function is called deriveAESSecret in TS. I don't like point_to_symmetric_key name much since
// point is not the only input of the function. Unify naming with TS once we have a better name.
pub fn point_to_symmetric_key(secret: Scalar, point: Point) -> [u8; 32] {
let shared_secret_fields = multi_scalar_mul([point], [secret]);
let shared_secret: Point = multi_scalar_mul([point], [secret]);
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6061): make the func return Point struct directly
let shared_secret = pub_key_to_bytes(Point::new(shared_secret_fields[0], shared_secret_fields[1], false));
let shared_secret = pub_key_to_bytes(shared_secret);
let mut shared_secret_bytes_with_separator = [0 as u8; 65];
shared_secret_bytes_with_separator = arr_copy_slice(shared_secret, shared_secret_bytes_with_separator, 0);
shared_secret_bytes_with_separator[64] = GENERATOR_INDEX__SYMMETRIC_KEY;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ contract AvmTest {
}

#[aztec(public)]
fn variable_base_msm() -> [Field; 3] {
fn variable_base_msm() -> Point {
let g = Point { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false };
let scalar = Scalar { lo: 3, hi: 0 };
let scalar2 = Scalar { lo: 20, hi: 0 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl NoteInterface<TOKEN_NOTE_LEN, TOKEN_NOTE_BYTES_LEN> for TokenNote {
lo: random_lo,
hi: random_hi,
}]
)[0]
).x
}
}

Expand Down Expand Up @@ -238,34 +238,21 @@ impl PrivatelyRefundable for TokenNote {
);

// 5. At last we represent the points as Points and return them.
(Point {
x: incomplete_fee_payer_point[0],
y: incomplete_fee_payer_point[1],
is_infinite: incomplete_fee_payer_point[2] == 1
}, Point {
x: incomplete_user_point[0],
y: incomplete_user_point[1],
is_infinite: incomplete_user_point[2] == 1
})
(incomplete_fee_payer_point, incomplete_user_point)
}

fn complete_refund(incomplete_fee_payer_point: Point, incomplete_user_point: Point, transaction_fee: Field) -> (Field, Field) {
// 1. We convert the transaction fee to high and low limbs to be able to use BB API.
let (transaction_fee_lo, transaction_fee_hi) = decompose(transaction_fee);

// 2. We compute the fee point as `G ^ transaction_fee`
let fee_point_raw = multi_scalar_mul(
let fee_point = multi_scalar_mul(
[G1],
[Scalar {
lo: transaction_fee_lo,
hi: transaction_fee_hi,
}]
);
let fee_point = Point {
x: fee_point_raw[0],
y: fee_point_raw[1],
is_infinite: fee_point_raw[2] == 1
};

// 3. Now we leverage homomorphism to privately add the fee to fee payer point and subtract it from
// the sponsored user point in public.
Expand Down
20 changes: 10 additions & 10 deletions noir/noir-repo/noir_stdlib/src/embedded_curve_ops.nr
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ impl EmbeddedCurveScalar {
}

pub fn derive_public_key(self) -> EmbeddedCurvePoint {
let public_key = fixed_base_scalar_mul(self.lo, self.hi);
EmbeddedCurvePoint { x: public_key[0], y: public_key[1], is_infinite: false }
fixed_base_scalar_mul(self)
}

#[field(bn254)]
Expand All @@ -84,24 +83,25 @@ impl Eq for EmbeddedCurveScalar {
//
// The embedded curve being used is decided by the
// underlying proof system.
#[foreign(multi_scalar_mul)]
// docs:start:multi_scalar_mul
pub fn multi_scalar_mul<let N: u32>(
points: [EmbeddedCurvePoint; N],
scalars: [EmbeddedCurveScalar; N]
) -> [Field; 3]
) -> EmbeddedCurvePoint
// docs:end:multi_scalar_mul
{}
{
let point_array = multi_scalar_mul_array_return(points, scalars);
EmbeddedCurvePoint { x: point_array[0], y: point_array[1], is_infinite: point_array[2] as bool }
}

#[foreign(multi_scalar_mul)]
fn multi_scalar_mul_array_return<let N: u32>(points: [EmbeddedCurvePoint; N], scalars: [EmbeddedCurveScalar; N]) -> [Field; 3] {}

// docs:start:fixed_base_scalar_mul
pub fn fixed_base_scalar_mul(
scalar_low: Field,
scalar_high: Field
) -> [Field; 3]
pub fn fixed_base_scalar_mul(scalar: EmbeddedCurveScalar) -> EmbeddedCurvePoint
// docs:end:fixed_base_scalar_mul
{
let g1 = EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false };
let scalar = EmbeddedCurveScalar { lo: scalar_low, hi: scalar_high };
multi_scalar_mul([g1], [scalar])
}

Expand Down
5 changes: 2 additions & 3 deletions noir/noir-repo/noir_stdlib/src/hash/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ fn pedersen_commitment_with_separator_noir<let N: u32>(input: [Field; N], separa
points[i] = EmbeddedCurveScalar::from_field(input[i]);
}
let generators = derive_generators("DEFAULT_DOMAIN_SEPARATOR".as_bytes(), separator);
let values = multi_scalar_mul(generators, points);
EmbeddedCurvePoint { x: values[0], y: values[1], is_infinite: values[2] as bool }
multi_scalar_mul(generators, points)
}

#[no_predicates]
Expand Down Expand Up @@ -80,7 +79,7 @@ fn pedersen_hash_with_separator_noir<let N: u32>(input: [Field; N], separator: u
multi_scalar_mul(
[length_generator[0], v1],
[EmbeddedCurveScalar { lo: N as Field, hi: 0 }, EmbeddedCurveScalar { lo: 1, hi: 0 }]
)[0]
).x
}

#[foreign(pedersen_hash)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ fn main(priv_key: Field, pub_x: pub Field, pub_y: pub Field) {
let scalar = std::embedded_curve_ops::EmbeddedCurveScalar { lo: priv_key, hi: 0 };
// Test that multi_scalar_mul correctly derives the public key
let res = std::embedded_curve_ops::multi_scalar_mul([g1], [scalar]);
assert(res[0] == pub_x);
assert(res[1] == pub_y);
assert(res.x == pub_x);
assert(res.y == pub_y);

// Test that double function calling embedded_curve_add works as expected
let pub_point = std::embedded_curve_ops::EmbeddedCurvePoint { x: pub_x, y: pub_y, is_infinite: false };
Expand All @@ -18,5 +18,5 @@ fn main(priv_key: Field, pub_x: pub Field, pub_y: pub Field) {
let res = std::embedded_curve_ops::multi_scalar_mul([g1, g1], [scalar, scalar]);

// The results should be double the g1 point because the scalars are 1 and we pass in g1 twice
assert(double.x == res[0]);
assert(double.x == res.x);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ fn main(is_active: bool) {
[a, bad],
[EmbeddedCurveScalar { lo: 1, hi: 0 }, EmbeddedCurveScalar { lo: 1, hi: 0 }]
);
assert(e[0] != d.x);
assert(e.x != d.x);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub fn verify_signature_noir<M>(public_key: embedded_curve_ops::EmbeddedCurvePoi
let g1 = embedded_curve_ops::EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false };
let r = embedded_curve_ops::multi_scalar_mul([g1, public_key], [sig_s, sig_e]);
// compare the _hashes_ rather than field elements modulo r
let pedersen_hash = std::hash::pedersen_hash([r[0], public_key.x, public_key.y]);
let pedersen_hash = std::hash::pedersen_hash([r.x, public_key.x, public_key.y]);
let mut hash_input = [0; M];
let pde = pedersen_hash.to_be_bytes(32);

Expand All @@ -62,7 +62,7 @@ pub fn verify_signature_noir<M>(public_key: embedded_curve_ops::EmbeddedCurvePoi
}
let result = std::hash::blake2s(hash_input);

is_ok = (r[2] == 0);
is_ok = !r.is_infinite;
for i in 0..32 {
if result[i] != signature[32 + i] {
is_ok = false;
Expand Down Expand Up @@ -101,7 +101,7 @@ pub fn assert_valid_signature<M>(public_key: embedded_curve_ops::EmbeddedCurvePo
let g1 = embedded_curve_ops::EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false };
let r = embedded_curve_ops::multi_scalar_mul([g1, public_key], [sig_s, sig_e]);
// compare the _hashes_ rather than field elements modulo r
let pedersen_hash = std::hash::pedersen_hash([r[0], public_key.x, public_key.y]);
let pedersen_hash = std::hash::pedersen_hash([r.x, public_key.x, public_key.y]);
let mut hash_input = [0; M];
let pde = pedersen_hash.to_be_bytes(32);

Expand All @@ -113,7 +113,7 @@ pub fn assert_valid_signature<M>(public_key: embedded_curve_ops::EmbeddedCurvePo
}
let result = std::hash::blake2s(hash_input);

assert(r[2] == 0);
assert(!r.is_infinite);
for i in 0..32 {
assert(result[i] == signature[32 + i]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ fn main(
to_pubkey_x: Field,
to_pubkey_y: Field
) -> pub [Field; 2] {
let priv_key_as_scalar = std::embedded_curve_ops::EmbeddedCurveScalar::new(priv_key, 0);
// Compute public key from private key to show ownership
let pubkey = std::embedded_curve_ops::fixed_base_scalar_mul(priv_key, 0);
let pubkey_x = pubkey[0];
let pubkey_y = pubkey[1];
let pubkey = std::embedded_curve_ops::fixed_base_scalar_mul(priv_key_as_scalar);
// Compute input note commitment
let note_commitment = std::hash::pedersen_commitment([pubkey_x, pubkey_y]);
let note_commitment = std::hash::pedersen_commitment([pubkey.x, pubkey.y]);
// Compute input note nullifier
let nullifier = std::hash::pedersen_commitment([note_commitment.x, index, priv_key]);
// Compute output note nullifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@ use std::embedded_curve_ops::{EmbeddedCurvePoint, EmbeddedCurveScalar, multi_sca

let s1 = EmbeddedCurveScalar { lo: 1, hi: 0 };
let a = multi_scalar_mul([g1], [s1]);
assert(a[2] == 0);
assert(!a.is_infinite);
assert(g1 + zero == g1);
assert(g1 - g1 == zero);
assert(g1 - zero == g1);
assert(zero + zero == zero);
assert(
multi_scalar_mul([g1], [s1])
== [1, 17631683881184975370165255887551781615748388533673675138860, 0]
== EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false }
);
assert(multi_scalar_mul([g1, g1], [s1, s1]) == [g2.x, g2.y, 0]);
assert(multi_scalar_mul([g1, g1], [s1, s1]) == g2);
assert(
multi_scalar_mul(
[g1, zero],
[EmbeddedCurveScalar { lo: 2, hi: 0 }, EmbeddedCurveScalar { lo: 42, hi: 25 }]
)
== [g2.x, g2.y, 0]
== g2
);
assert(
multi_scalar_mul(
[g1, g1, zero],
[s1, s1, EmbeddedCurveScalar { lo: 42, hi: 25 }]
)
== [g2.x, g2.y, 0]
== g2
);
}

0 comments on commit db96077

Please sign in to comment.