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