Skip to content

Commit 6f00c4b

Browse files
authored
Merge pull request #6 from brech1/restructure/crate
restructure: crate
2 parents 43f28ae + 9f2713e commit 6f00c4b

File tree

10 files changed

+1488
-1703
lines changed

10 files changed

+1488
-1703
lines changed

Cargo.lock

Lines changed: 207 additions & 1438 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,30 @@
11
[package]
22
name = "semaphore-rs"
33
version = "0.1.0"
4-
edition = "2021"
4+
edition = "2024"
55

66
[dependencies]
7-
anyhow = "1.0.95"
8-
ethers-core = "2.0.14"
7+
blake = "2.0.2"
98
light-poseidon = "0.3.0"
109
num-bigint = "0.4.6"
11-
ruint = "1.12.4"
12-
leanimt-rs = { git = "https://github.com/vplasencia/leanimt-rs" }
13-
ark-bn254 = "0.5.0"
10+
thiserror = "2.0.12"
11+
12+
# arkworks
13+
ark-ec = { version = "=0.5.0", default-features = false }
14+
ark-ed-on-bn254 = { version = "=0.5.0", default-features = false }
15+
ark-ff = { version = "=0.5.0", default-features = false }
16+
17+
# zk-kit
18+
zk-kit-lean-imt = { git = "https://github.com/brech1/zk-kit.rust", package = "zk-kit-lean-imt", branch = "feat/generic-tree" }
19+
20+
# serde
21+
serde = { version = "1", features = ["derive"], optional = true }
22+
serde_json = { version = "1", optional = true }
23+
24+
[features]
25+
default = []
26+
serde = [
27+
"dep:serde",
28+
"serde_json",
29+
"zk-kit-lean-imt/serde"
30+
]

src/baby_jubjub.rs

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
//! EIP-2494 Baby Jubjub Curve
2+
//!
3+
//! This is an append to the the `ark-ed-on-bn254` crate to use the EIP-2494 defined Baby Jubjub curve parameters.
4+
//!
5+
//! - https://eips.ethereum.org/EIPS/eip-2494
6+
//!
7+
//! - Base field: q = 21888242871839275222246405745257275088548364400416034343698204186575808495617
8+
//! - Scalar field: r = 2736030358979909402780800718157159386076813972158567259200215660948447373041
9+
//! - Order: n = l * cofactor = 21888242871839275222246405745257275088614511777268538073601725287587578984328
10+
//! - Cofactor: 8
11+
//! - Subgroup order: l = 2736030358979909402780800718157159386076813972158567259200215660948447373041
12+
//! - Curve equation: ax² + y² = 1 + d·x²y², where
13+
//! - a = 168700
14+
//! - d = 168696
15+
//! - Generator point:
16+
//! (995203441582195749578291179787384436505546430278305826713579947235728471134,
17+
//! 5472060717959818805561601436314318772137091100104008585924551046643952123905)
18+
//! - Base point:
19+
//! (5299619240641551281634865583518297030282874472190772894086521144482721001553,
20+
//! 16950150798460657717958625567821834550301663161624707787222815936182638968203)
21+
22+
use ark_ec::{
23+
models::CurveConfig,
24+
twisted_edwards::{Affine, MontCurveConfig, Projective, TECurveConfig},
25+
};
26+
use ark_ed_on_bn254::{Fq, Fr};
27+
use ark_ff::{Field, MontFp};
28+
29+
pub type EdwardsAffine = Affine<BabyJubjubConfig>;
30+
pub type EdwardsProjective = Projective<BabyJubjubConfig>;
31+
32+
#[derive(Clone, Default, PartialEq, Eq)]
33+
pub struct BabyJubjubConfig;
34+
35+
impl CurveConfig for BabyJubjubConfig {
36+
type BaseField = Fq;
37+
type ScalarField = Fr;
38+
39+
// h = 8
40+
const COFACTOR: &'static [u64] = &[8];
41+
42+
// h^(-1) (mod r)
43+
const COFACTOR_INV: Fr =
44+
MontFp!("2394026564107420727433200628387514462817212225638746351800188703329891451411");
45+
}
46+
47+
// Twisted Edwards form
48+
// ax^2 + y^2 = 1 + dx^2y^2
49+
impl TECurveConfig for BabyJubjubConfig {
50+
// a = 168700
51+
const COEFF_A: Fq = MontFp!("168700");
52+
53+
#[inline(always)]
54+
fn mul_by_a(elem: Self::BaseField) -> Self::BaseField {
55+
elem * <BabyJubjubConfig as TECurveConfig>::COEFF_A
56+
}
57+
58+
// d = 168696
59+
const COEFF_D: Fq = MontFp!("168696");
60+
61+
// Base point is used as generator to operate in subgroup
62+
const GENERATOR: EdwardsAffine = EdwardsAffine::new_unchecked(BASE_X, BASE_Y);
63+
64+
type MontCurveConfig = BabyJubjubConfig;
65+
}
66+
67+
// Montgomery form
68+
// By^2 = x^3 + A x^2 + x
69+
impl MontCurveConfig for BabyJubjubConfig {
70+
// A = 168698
71+
const COEFF_A: Fq = MontFp!("168698");
72+
// B = 1
73+
const COEFF_B: Fq = Fq::ONE;
74+
75+
type TECurveConfig = BabyJubjubConfig;
76+
}
77+
78+
/// Generator point x-coordinate
79+
pub const GENERATOR_X: Fq =
80+
MontFp!("995203441582195749578291179787384436505546430278305826713579947235728471134");
81+
/// Generator point y-coordinate
82+
pub const GENERATOR_Y: Fq =
83+
MontFp!("5472060717959818805561601436314318772137091100104008585924551046643952123905");
84+
85+
/// Subgroup order `l`
86+
pub const SUBGROUP_ORDER: Fr =
87+
MontFp!("2736030358979909402780800718157159386076813972158567259200215660948447373041");
88+
89+
// Subgroup generator
90+
// Generates subgroup l * P = O
91+
92+
/// Base point x-coordinate
93+
pub const BASE_X: Fq =
94+
MontFp!("5299619240641551281634865583518297030282874472190772894086521144482721001553");
95+
/// Base point y-coordinate
96+
pub const BASE_Y: Fq =
97+
MontFp!("16950150798460657717958625567821834550301663161624707787222815936182638968203");
98+
99+
#[cfg(test)]
100+
mod tests {
101+
//! Implementation of the tests presented in the EIP-2494
102+
103+
use super::*;
104+
use ark_ec::CurveGroup;
105+
use ark_ff::{PrimeField, Zero};
106+
107+
#[test]
108+
fn test_addition() {
109+
let p1 = EdwardsAffine::new_unchecked(
110+
MontFp!(
111+
"17777552123799933955779906779655732241715742912184938656739573121738514868268"
112+
),
113+
MontFp!("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
114+
);
115+
116+
let p2 = EdwardsAffine::new_unchecked(
117+
MontFp!(
118+
"16540640123574156134436876038791482806971768689494387082833631921987005038935"
119+
),
120+
MontFp!(
121+
"20819045374670962167435360035096875258406992893633759881276124905556507972311"
122+
),
123+
);
124+
125+
let result = (p1 + p2).into_affine();
126+
127+
assert_eq!(
128+
result,
129+
EdwardsAffine::new_unchecked(
130+
MontFp!(
131+
"7916061937171219682591368294088513039687205273691143098332585753343424131937"
132+
),
133+
MontFp!(
134+
"14035240266687799601661095864649209771790948434046947201833777492504781204499"
135+
)
136+
)
137+
);
138+
}
139+
140+
#[test]
141+
fn test_doubling() {
142+
let p1 = EdwardsAffine::new_unchecked(
143+
MontFp!(
144+
"17777552123799933955779906779655732241715742912184938656739573121738514868268"
145+
),
146+
MontFp!("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
147+
);
148+
149+
let result = (p1 + p1).into_affine();
150+
151+
assert_eq!(
152+
result,
153+
EdwardsAffine::new_unchecked(
154+
MontFp!(
155+
"6890855772600357754907169075114257697580319025794532037257385534741338397365"
156+
),
157+
MontFp!(
158+
"4338620300185947561074059802482547481416142213883829469920100239455078257889"
159+
)
160+
)
161+
);
162+
}
163+
164+
#[test]
165+
fn test_doubling_identity() {
166+
let identity = EdwardsAffine::new_unchecked(Fq::zero(), Fq::ONE);
167+
let result = (identity + identity).into_affine();
168+
169+
assert_eq!(result, identity);
170+
}
171+
172+
#[test]
173+
fn test_curve_membership() {
174+
let valid_point = EdwardsAffine::new_unchecked(Fq::zero(), Fq::ONE);
175+
assert!(valid_point.is_on_curve());
176+
177+
let invalid_point = EdwardsAffine::new_unchecked(Fq::ONE, Fq::zero());
178+
assert!(!invalid_point.is_on_curve());
179+
}
180+
181+
#[test]
182+
fn test_base_point_choice() {
183+
let g = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);
184+
185+
let expected_base_point = EdwardsAffine::new_unchecked(BASE_X, BASE_Y);
186+
let cofactor = Fr::from_be_bytes_mod_order(&[BabyJubjubConfig::COFACTOR[0] as u8]);
187+
let calculated_base_point = (g * cofactor).into_affine();
188+
189+
assert_eq!(calculated_base_point, expected_base_point);
190+
}
191+
192+
#[test]
193+
fn test_base_point_order() {
194+
let base_point = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);
195+
196+
let result = (base_point * SUBGROUP_ORDER).into_affine();
197+
let identity = EdwardsAffine::new_unchecked(Fq::zero(), Fq::ONE);
198+
199+
assert_eq!(result, identity);
200+
}
201+
}

src/error.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//! Error Module
2+
3+
use thiserror::Error;
4+
use zk_kit_lean_imt::lean_imt::LeanIMTError;
5+
6+
#[derive(Error, Debug, PartialEq, Eq)]
7+
pub enum SemaphoreError {
8+
#[error("Member already removed")]
9+
AlreadyRemovedMember,
10+
#[error("Member value is empty")]
11+
EmptyLeaf,
12+
#[error("Input array of size {0} exceeds maximum allowed length of 32 bytes")]
13+
InputSizeExceeded(usize),
14+
#[error("LeanIMT error: {0}")]
15+
LeanIMTError(LeanIMTError),
16+
#[error("Message of size {0} exceeds maximum allowed length of 32 bytes")]
17+
MessageSizeExceeded(usize),
18+
#[error("Public key validation failed: point is not on curve")]
19+
PublicKeyNotOnCurve,
20+
#[error("Member has been removed")]
21+
RemovedMember,
22+
#[error("Signature point R is not on curve")]
23+
SignaturePointNotOnCurve,
24+
#[error("Signature verification failed")]
25+
SignatureVerificationFailed,
26+
#[error("Serialization error: {0}")]
27+
SerializationError(String),
28+
}
29+
30+
impl From<LeanIMTError> for SemaphoreError {
31+
fn from(error: LeanIMTError) -> Self {
32+
SemaphoreError::LeanIMTError(error)
33+
}
34+
}

0 commit comments

Comments
 (0)