openzeppelin_crypto/curve/te/instance/
baby_jubjub.rs1use crate::{
6 arithmetic::uint::U256,
7 curve::{
8 te::{Affine, MontCurveConfig, TECurveConfig},
9 CurveConfig,
10 },
11 field::fp::{Fp256, FpParams, LIMBS_256},
12 fp_from_num, from_num,
13};
14
15const G_GENERATOR_X: Fq = fp_from_num!("995203441582195749578291179787384436505546430278305826713579947235728471134");
16
17const G_GENERATOR_Y: Fq = fp_from_num!("5472060717959818805561601436314318772137091100104008585924551046643952123905");
18
19pub type Fq = Fp256<BabyJubjubFqParam>;
21pub struct BabyJubjubFqParam;
23
24impl FpParams<LIMBS_256> for BabyJubjubFqParam {
25 const GENERATOR: Fp256<Self> = fp_from_num!("2");
26 const MODULUS: U256 = from_num!("21888242871839275222246405745257275088548364400416034343698204186575808495617");
27}
28
29pub type Fr = Fp256<BabyJubjubFrParam>;
31pub struct BabyJubjubFrParam;
33
34impl FpParams<LIMBS_256> for BabyJubjubFrParam {
35 const GENERATOR: Fp256<Self> = fp_from_num!("2");
36 const MODULUS: U256 = from_num!("2736030358979909402780800718157159386076813972158567259200215660948447373041");
37}
38
39#[derive(Clone, Default, PartialEq, Eq)]
41pub struct BabyJubjubConfig;
42
43impl CurveConfig for BabyJubjubConfig {
44 type BaseField = Fq;
45 type ScalarField = Fr;
46
47 const COFACTOR: &'static [u64] = &[8];
48 const COFACTOR_INV: Fr = fp_from_num!("2394026564107420727433200628387514462817212225638746351800188703329891451411");
49}
50
51impl TECurveConfig for BabyJubjubConfig {
52 type MontCurveConfig = Self;
53
54 const COEFF_A: Self::BaseField = fp_from_num!("168700");
55 const COEFF_D: Self::BaseField = fp_from_num!("168696");
56 const GENERATOR: Affine<Self> =
57 Affine::new_unchecked(G_GENERATOR_X, G_GENERATOR_Y);
58}
59
60impl MontCurveConfig for BabyJubjubConfig {
61 type TECurveConfig = Self;
62
63 const COEFF_A: Self::BaseField = fp_from_num!("168698");
64 const COEFF_B: Self::BaseField = fp_from_num!("1");
65}
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use crate::curve::{AffineRepr, CurveGroup, PrimeGroup};
70
71 #[test]
74 fn test_addition() {
75 let x1 = fp_from_num!("17777552123799933955779906779655732241715742912184938656739573121738514868268");
77 let y1 = fp_from_num!("2626589144620713026669568689430873010625803728049924121243784502389097019475");
78 let p1 = Affine::<BabyJubjubConfig>::new_unchecked(x1, y1);
79
80 let x2 = fp_from_num!("16540640123574156134436876038791482806971768689494387082833631921987005038935");
81 let y2 = fp_from_num!("20819045374670962167435360035096875258406992893633759881276124905556507972311");
82 let p2 = Affine::<BabyJubjubConfig>::new_unchecked(x2, y2);
83
84 let expected_x = fp_from_num!("7916061937171219682591368294088513039687205273691143098332585753343424131937");
85 let expected_y = fp_from_num!("14035240266687799601661095864649209771790948434046947201833777492504781204499");
86 let expected =
87 Affine::<BabyJubjubConfig>::new_unchecked(expected_x, expected_y);
88
89 let result = (p1 + p2).into_affine();
90 assert_eq!(result, expected);
91 }
92
93 #[test]
94 fn test_doubling() {
95 let x1 = fp_from_num!("17777552123799933955779906779655732241715742912184938656739573121738514868268");
97 let y1 = fp_from_num!("2626589144620713026669568689430873010625803728049924121243784502389097019475");
98 let p1 = Affine::<BabyJubjubConfig>::new_unchecked(x1, y1);
99
100 let expected_x = fp_from_num!("6890855772600357754907169075114257697580319025794532037257385534741338397365");
101 let expected_y = fp_from_num!("4338620300185947561074059802482547481416142213883829469920100239455078257889");
102 let expected =
103 Affine::<BabyJubjubConfig>::new_unchecked(expected_x, expected_y);
104
105 let result = (p1 + p1).into_affine();
106 assert_eq!(result, expected);
107 }
108
109 #[test]
110 fn test_identity_doubling() {
111 let x1 = fp_from_num!("0");
113 let y1 = fp_from_num!("1");
114 let identity = Affine::<BabyJubjubConfig>::new_unchecked(x1, y1);
115
116 let result = (identity + identity).into_affine();
117 assert_eq!(result, identity);
118 }
119 #[test]
120 fn test_curve_membership() {
121 let x1 = fp_from_num!("0");
124 let y1 = fp_from_num!("1");
125 let p1 = Affine::<BabyJubjubConfig>::new_unchecked(x1, y1);
126 assert!(p1.is_on_curve());
127
128 let x2 = fp_from_num!("1");
130 let y2 = fp_from_num!("0");
131 let p2 = Affine::<BabyJubjubConfig>::new_unchecked(x2, y2);
132 assert!(!p2.is_on_curve());
133 }
134
135 #[test]
136 #[allow(clippy::similar_names)]
137 fn test_base_point_choice() {
138 let gx = fp_from_num!("995203441582195749578291179787384436505546430278305826713579947235728471134");
141 let gy = fp_from_num!("5472060717959818805561601436314318772137091100104008585924551046643952123905");
142 let g = Affine::<BabyJubjubConfig>::new_unchecked(gx, gy);
143
144 let expected_bx = fp_from_num!("5299619240641551281634865583518297030282874472190772894086521144482721001553");
145 let expected_by = fp_from_num!("16950150798460657717958625567821834550301663161624707787222815936182638968203");
146 let expected_b =
147 Affine::<BabyJubjubConfig>::new_unchecked(expected_bx, expected_by);
148
149 let b = g.into_group().mul_bigint(8u64).into_affine();
151 assert_eq!(b, expected_b);
152 }
153
154 #[test]
155 fn test_base_point_order() {
156 let bx = fp_from_num!("5299619240641551281634865583518297030282874472190772894086521144482721001553");
158 let by = fp_from_num!("16950150798460657717958625567821834550301663161624707787222815936182638968203");
159 let b = Affine::<BabyJubjubConfig>::new_unchecked(bx, by);
160
161 let l = fp_from_num!("2736030358979909402780800718157159386076813972158567259200215660948447373041");
163
164 let result = (b.into_group() * l).into_affine();
166
167 let identity_x = fp_from_num!("0");
168 let identity_y = fp_from_num!("1");
169 let identity =
170 Affine::<BabyJubjubConfig>::new_unchecked(identity_x, identity_y);
171
172 assert_eq!(result, identity);
173 }
174}