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 twisted_edwards_extended::{GroupAffine, GroupProjective},
5};
6use ark_ff::{biginteger::BigInteger256, field_new};
7
8#[cfg(test)]
9mod tests;
10
11pub type EdwardsAffine = GroupAffine<EdwardsParameters>;
12pub type EdwardsProjective = GroupProjective<EdwardsParameters>;
13
14#[rustfmt::skip]
15const GENERATOR_X: Fq = field_new!(Fq, BigInteger256([
16 14080349899812819339,
17 4104857150246327429,
18 8293216003873356624,
19 7400363483732984990,
20]));
21#[rustfmt::skip]
22const GENERATOR_Y: Fq = field_new!(Fq, BigInteger256([
23 13388310974700241893,
24 7654361511478576605,
25 8037907163910805792,
26 5188938133920569885,
27]));
28
29/// `JubJub` is a twisted Edwards curve. These curves have equations of the
30/// form: ax² + y² = 1 - dx²y².
31/// over some base finite field Fq.
32///
33/// JubJub's curve equation: -x² + y² = 1 - (10240/10241)x²y²
34///
35/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513.
36///
37/// a = -1.
38/// d = (10240/10241) mod q
39/// = 19257038036680949359750312669786877991949435402254120286184196891950884077233.
40///
41/// Sage script to calculate these:
42///
43/// ```text
44/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513
45/// Fq = GF(q)
46/// d = -(Fq(10240)/Fq(10241))
47/// ```
48/// These parameters and the sage script obtained from:
49/// <https://github.com/zcash/zcash/issues/2230#issuecomment-317182190>
50#[derive(Clone, Default, PartialEq, Eq)]
51pub struct EdwardsParameters;
52
53impl ModelParameters for EdwardsParameters {
54 type BaseField = Fq;
55 type ScalarField = Fr;
56}
57
58impl TEModelParameters for EdwardsParameters {
59 /// COEFF_A = -1
60 #[rustfmt::skip]
61 const COEFF_A: Fq = field_new!(Fq, BigInteger256([
62 18446744060824649731,
63 18102478225614246908,
64 11073656695919314959,
65 6613806504683796440,
66 ]));
67
68 /// COEFF_D = (10240/10241) mod q
69 #[rustfmt::skip]
70 const COEFF_D: Fq = field_new!(Fq, BigInteger256([
71 3049539848285517488,
72 18189135023605205683,
73 8793554888777148625,
74 6339087681201251886,
75 ]));
76
77 /// COFACTOR = 8
78 const COFACTOR: &'static [u64] = &[8];
79
80 /// COFACTOR^(-1) mod r =
81 /// 819310549611346726241370945440405716213240158234039660170669895299022906775
82 #[rustfmt::skip]
83 const COFACTOR_INV: Fr = field_new!(Fr, BigInteger256([
84 6832491983681988242,
85 12911748493335322362,
86 17523939349049608702,
87 217463794347581613,
88 ]));
89
90 /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
91 const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y);
92
93 type MontgomeryModelParameters = EdwardsParameters;
94
95 /// Multiplication by `a` is simply negation here.
96 #[inline(always)]
97 fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
98 -(*elem)
99 }
100}
101
102impl MontgomeryModelParameters for EdwardsParameters {
103 /// COEFF_A = 0xA002
104 #[rustfmt::skip]
105 const COEFF_A: Fq = field_new!(Fq, BigInteger256([
106 388496971701930u64,
107 6855257088226130262u64,
108 553476580979119549u64,
109 6516741293351590684u64,
110 ]));
111 /// COEFF_B = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFEFFFF5FFD
112 #[rustfmt::skip]
113 const COEFF_B: Fq = field_new!(Fq, BigInteger256([
114 18446355550968045916u64,
115 10902955289292811939u64,
116 3147092737149958754u64,
117 6710871716016002197u64,
118 ]));
119
120 type TEModelParameters = EdwardsParameters;
121}