Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore!: remove eddsa from stdlib #6591

Merged
merged 3 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,5 @@ fn bjj_pub_key(priv_key: Field) -> Point
This would come in handy in a Merkle proof.

- EdDSA signature verification: This is a matter of combining these primitives with a suitable hash
function. See
[feat(stdlib): EdDSA sig verification noir#1136](https://github.com/noir-lang/noir/pull/1136) for
the case of Baby Jubjub and the Poseidon hash function.
function. See the [eddsa](https://github.com/noir-lang/eddsa) library an example of eddsa signature verification
over the Baby Jubjub curve.
37 changes: 0 additions & 37 deletions docs/docs/noir/standard_library/cryptographic_primitives/eddsa.mdx

This file was deleted.

76 changes: 0 additions & 76 deletions noir_stdlib/src/eddsa.nr

This file was deleted.

1 change: 0 additions & 1 deletion noir_stdlib/src/lib.nr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub mod merkle;
pub mod schnorr;
pub mod ecdsa_secp256k1;
pub mod ecdsa_secp256r1;
pub mod eddsa;
pub mod embedded_curve_ops;
pub mod sha256;
pub mod sha512;
Expand Down
55 changes: 52 additions & 3 deletions test_programs/benchmarks/bench_eddsa_poseidon/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,12 +1,61 @@
use std::eddsa::eddsa_poseidon_verify;
use std::default::Default;
use std::ec::consts::te::baby_jubjub;
use std::ec::tecurve::affine::Point as TEPoint;
use std::hash::Hasher;
use std::hash::poseidon::PoseidonHasher;

fn main(
msg: pub Field,
pub_key_x: Field,
pub_key_y: Field,
r8_x: Field,
r8_y: Field,
s: Field
s: Field,
) -> pub bool {
eddsa_poseidon_verify(pub_key_x, pub_key_y, s, r8_x, r8_y, msg)
eddsa_verify::<PoseidonHasher>(pub_key_x, pub_key_y, s, r8_x, r8_y, msg)
}

pub fn eddsa_verify<H>(
pub_key_x: Field,
pub_key_y: Field,
signature_s: Field,
signature_r8_x: Field,
signature_r8_y: Field,
message: Field,
) -> bool
where
H: Hasher + Default,
{
// Verifies by testing:
// S * B8 = R8 + H(R8, A, m) * A8
let bjj = baby_jubjub();

let pub_key = TEPoint::new(pub_key_x, pub_key_y);
assert(bjj.curve.contains(pub_key));

let signature_r8 = TEPoint::new(signature_r8_x, signature_r8_y);
assert(bjj.curve.contains(signature_r8));
// Ensure S < Subgroup Order
assert(signature_s.lt(bjj.suborder));
// Calculate the h = H(R, A, msg)
let mut hasher = H::default();
hasher.write(signature_r8_x);
hasher.write(signature_r8_y);
hasher.write(pub_key_x);
hasher.write(pub_key_y);
hasher.write(message);
let hash: Field = hasher.finish();
// Calculate second part of the right side: right2 = h*8*A
// Multiply by 8 by doubling 3 times. This also ensures that the result is in the subgroup.
let pub_key_mul_2 = bjj.curve.add(pub_key, pub_key);
let pub_key_mul_4 = bjj.curve.add(pub_key_mul_2, pub_key_mul_2);
let pub_key_mul_8 = bjj.curve.add(pub_key_mul_4, pub_key_mul_4);
// We check that A8 is not zero.
assert(!pub_key_mul_8.is_zero());
// Compute the right side: R8 + h * A8
let right = bjj.curve.add(signature_r8, bjj.curve.mul(hash, pub_key_mul_8));
// Calculate left side of equation left = S * B8
let left = bjj.curve.mul(signature_s, bjj.base8);

left.eq(right)
}
74 changes: 73 additions & 1 deletion test_programs/execution_success/eddsa/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::compat;
use std::ec::consts::te::baby_jubjub;
use std::ec::tecurve::affine::Point as TEPoint;
use std::eddsa::{eddsa_poseidon_verify, eddsa_to_pub, eddsa_verify};
use std::hash::Hasher;
use std::hash::poseidon::PoseidonHasher;
use std::hash::poseidon2::Poseidon2Hasher;

fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) {
Expand Down Expand Up @@ -54,3 +55,74 @@ fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) {
);
}
}

// Returns true if signature is valid
pub fn eddsa_poseidon_verify(
pub_key_x: Field,
pub_key_y: Field,
signature_s: Field,
signature_r8_x: Field,
signature_r8_y: Field,
message: Field,
) -> bool {
eddsa_verify::<PoseidonHasher>(
pub_key_x,
pub_key_y,
signature_s,
signature_r8_x,
signature_r8_y,
message,
)
}

pub fn eddsa_verify<H>(
pub_key_x: Field,
pub_key_y: Field,
signature_s: Field,
signature_r8_x: Field,
signature_r8_y: Field,
message: Field,
) -> bool
where
H: Hasher + Default,
{
// Verifies by testing:
// S * B8 = R8 + H(R8, A, m) * A8
let bjj = baby_jubjub();

let pub_key = TEPoint::new(pub_key_x, pub_key_y);
assert(bjj.curve.contains(pub_key));

let signature_r8 = TEPoint::new(signature_r8_x, signature_r8_y);
assert(bjj.curve.contains(signature_r8));
// Ensure S < Subgroup Order
assert(signature_s.lt(bjj.suborder));
// Calculate the h = H(R, A, msg)
let mut hasher = H::default();
hasher.write(signature_r8_x);
hasher.write(signature_r8_y);
hasher.write(pub_key_x);
hasher.write(pub_key_y);
hasher.write(message);
let hash: Field = hasher.finish();
// Calculate second part of the right side: right2 = h*8*A
// Multiply by 8 by doubling 3 times. This also ensures that the result is in the subgroup.
let pub_key_mul_2 = bjj.curve.add(pub_key, pub_key);
let pub_key_mul_4 = bjj.curve.add(pub_key_mul_2, pub_key_mul_2);
let pub_key_mul_8 = bjj.curve.add(pub_key_mul_4, pub_key_mul_4);
// We check that A8 is not zero.
assert(!pub_key_mul_8.is_zero());
// Compute the right side: R8 + h * A8
let right = bjj.curve.add(signature_r8, bjj.curve.mul(hash, pub_key_mul_8));
// Calculate left side of equation left = S * B8
let left = bjj.curve.mul(signature_s, bjj.base8);

left.eq(right)
}

// Returns the public key of the given secret key as (pub_key_x, pub_key_y)
pub fn eddsa_to_pub(secret: Field) -> (Field, Field) {
let bjj = baby_jubjub();
let pub_key = bjj.curve.mul(secret, bjj.curve.gen);
(pub_key.x, pub_key.y)
}
Loading