ark-curves-cherry-picked/ed_on_bls12_381/src/curves/mod.rs
ed_on_bls12_381/src/curves/mod.rsRaw
1use ark_ec::{
2 models::CurveConfig,
3 short_weierstrass::{self, SWCurveConfig},
4 twisted_edwards::{Affine, MontCurveConfig, Projective, TECurveConfig},
5};
6use ark_ff::MontFp;
7
8use crate::{Fq, Fr};
9
10#[cfg(test)]
11mod tests;
12
13pub type EdwardsAffine = Affine<JubjubParameters>;
14pub type EdwardsProjective = Projective<JubjubParameters>;
15pub type SWAffine = short_weierstrass::Affine<JubjubParameters>;
16pub type SWProjective = short_weierstrass::Projective<JubjubParameters>;
17
18/// `JubJub` is a twisted Edwards curve. These curves have equations of the
19/// form: ax² + y² = 1 - dx²y².
20/// over some base finite field Fq.
21///
22/// JubJub's curve equation: -x² + y² = 1 - (10240/10241)x²y²
23///
24/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513.
25///
26/// a = -1.
27/// d = -(10240/10241) mod q
28/// = 19257038036680949359750312669786877991949435402254120286184196891950884077233.
29///
30/// Sage script to calculate these:
31///
32/// ```text
33/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513
34/// Fq = GF(q)
35/// d = -(Fq(10240)/Fq(10241))
36/// ```
37/// These parameters and the sage script obtained from:
38/// <https://github.com/zcash/zcash/issues/2230#issuecomment-317182190>
39///
40///
41/// `jubjub` also has a short Weierstrass curve form, following the
42/// form: y² = x³ + A * x + B
43/// where
44///
45/// A = 52296097456646850916096512823759002727550416093741407922227928430486925478210
46/// B = 48351165704696163914533707656614864561753505123260775585269522553028192119009
47///
48/// We can use the script available
49/// [here](https://github.com/zhenfeizhang/bandersnatch/blob/main/bandersnatch/script/jubjub.sage)
50/// to convert between the different representations.
51#[derive(Clone, Default, PartialEq, Eq)]
52pub struct JubjubParameters;
53pub type EdwardsParameters = JubjubParameters;
54pub type SWParameters = JubjubParameters;
55
56impl CurveConfig for JubjubParameters {
57 type BaseField = Fq;
58 type ScalarField = Fr;
59
60 /// COFACTOR = 8
61 const COFACTOR: &'static [u64] = &[8];
62
63 /// COFACTOR^(-1) mod r =
64 /// 819310549611346726241370945440405716213240158234039660170669895299022906775
65 const COFACTOR_INV: Fr =
66 MontFp!("819310549611346726241370945440405716213240158234039660170669895299022906775");
67}
68
69impl TECurveConfig for JubjubParameters {
70 /// COEFF_A = -1
71 const COEFF_A: Fq = MontFp!("-1");
72
73 /// COEFF_D = (10240/10241) mod q
74 const COEFF_D: Fq =
75 MontFp!("19257038036680949359750312669786877991949435402254120286184196891950884077233");
76
77 /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
78 const GENERATOR: EdwardsAffine = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);
79
80 type MontCurveConfig = JubjubParameters;
81
82 /// Multiplication by `a` is simply negation here.
83 #[inline(always)]
84 fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
85 -(*elem)
86 }
87}
88
89impl MontCurveConfig for JubjubParameters {
90 /// COEFF_A = 40962
91 const COEFF_A: Fq = MontFp!("40962");
92
93 /// COEFF_B = -40964
94 const COEFF_B: Fq = MontFp!("-40964");
95
96 type TECurveConfig = JubjubParameters;
97}
98
99const GENERATOR_X: Fq =
100 MontFp!("8076246640662884909881801758704306714034609987455869804520522091855516602923");
101
102const GENERATOR_Y: Fq =
103 MontFp!("13262374693698910701929044844600465831413122818447359594527400194675274060458");
104
105impl SWCurveConfig for JubjubParameters {
106 /// COEFF_A = 52296097456646850916096512823759002727550416093741407922227928430486925478210
107 const COEFF_A: Self::BaseField =
108 MontFp!("52296097456646850916096512823759002727550416093741407922227928430486925478210");
109
110 /// COEFF_B = 48351165704696163914533707656614864561753505123260775585269522553028192119009
111 const COEFF_B: Self::BaseField =
112 MontFp!("48351165704696163914533707656614864561753505123260775585269522553028192119009");
113
114 /// generators
115 const GENERATOR: SWAffine = SWAffine::new_unchecked(SW_GENERATOR_X, SW_GENERATOR_Y);
116}
117
118/// x coordinate for SW curve generator
119const SW_GENERATOR_X: Fq =
120 MontFp!("33835869156188682335217394949746694649676633840125476177319971163079011318731");
121
122/// y coordinate for SW curve generator
123const SW_GENERATOR_Y: Fq =
124 MontFp!("43777270878440091394432848052353307184915192688165709016756678962558652055320");