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