ark-curves-cherry-picked/ed_on_bls12_381_bandersnatch/src/curves/mod.rs
ed_on_bls12_381_bandersnatch/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::{Field, MontFp};
10
11use crate::{Fq, Fr};
12
13#[cfg(test)]
14mod tests;
15
16pub type EdwardsAffine = GroupAffine<BandersnatchParameters>;
17pub type EdwardsProjective = GroupProjective<BandersnatchParameters>;
18
19pub type SWAffine = SWGroupAffine<BandersnatchParameters>;
20pub type SWProjective = SWGroupProjective<BandersnatchParameters>;
21
22/// `bandersnatch` is a twisted Edwards curve. These curves have equations of
23/// the form: ax² + y² = 1 - dx²y².
24/// over some base finite field Fq.
25///
26/// bandersnatch's curve equation: -5x² + y² = 1 - dx²y²
27///
28/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513.
29///
30/// a = -5.
31/// d = (138827208126141220649022263972958607803/
32/// 171449701953573178309673572579671231137) mod q
33/// = 45022363124591815672509500913686876175488063829319466900776701791074614335719.
34///
35/// Sage script to calculate these:
36///
37/// ```text
38/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513
39/// Fq = GF(q)
40/// d = (Fq(138827208126141220649022263972958607803)/Fq(171449701953573178309673572579671231137))
41/// ```
42/// These parameters and the sage script obtained from:
43/// <https://github.com/asanso/Bandersnatch/>
44///
45/// bandersnatch also has a short Weierstrass curve form, following the
46/// form: y² = x³ + A * x + B
47/// where
48///
49/// A = 10773120815616481058602537765553212789256758185246796157495669123169359657269
50/// B = 29569587568322301171008055308580903175558631321415017492731745847794083609535
51///
52/// Script to transfer between different curves are available
53/// <https://github.com/zhenfeizhang/bandersnatch/blob/main/bandersnatch/script/bandersnatch.sage>
54#[derive(Clone, Default, PartialEq, Eq)]
55pub struct BandersnatchParameters;
56
57pub type EdwardsParameters = BandersnatchParameters;
58pub type SWParameters = BandersnatchParameters;
59
60impl ModelParameters for BandersnatchParameters {
61 type BaseField = Fq;
62 type ScalarField = Fr;
63
64 /// COFACTOR = 4
65 const COFACTOR: &'static [u64] = &[4];
66
67 /// COFACTOR^(-1) mod r =
68 /// 9831726595336160714896451345284868594481866920080427688839802480047265754601
69 const COFACTOR_INV: Fr = MontFp!(
70 Fr,
71 "9831726595336160714896451345284868594481866920080427688839802480047265754601"
72 );
73}
74
75impl TEModelParameters for BandersnatchParameters {
76 /// COEFF_A = -5
77 const COEFF_A: Fq = MontFp!(Fq, "-5");
78
79 /// COEFF_D = (138827208126141220649022263972958607803/
80 /// 171449701953573178309673572579671231137) mod q
81 const COEFF_D: Fq = MontFp!(
82 Fq,
83 "45022363124591815672509500913686876175488063829319466900776701791074614335719"
84 );
85
86 /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
87 const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
88 (TE_GENERATOR_X, TE_GENERATOR_Y);
89
90 type MontgomeryModelParameters = BandersnatchParameters;
91
92 /// Multiplication by `a` is multiply by `-5`.
93 #[inline(always)]
94 fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
95 let t = (*elem).double().double();
96 -(t + *elem)
97 }
98}
99
100impl MontgomeryModelParameters for BandersnatchParameters {
101 /// COEFF_A = 29978822694968839326280996386011761570173833766074948509196803838190355340952
102 const COEFF_A: Fq = MontFp!(
103 Fq,
104 "29978822694968839326280996386011761570173833766074948509196803838190355340952"
105 );
106
107 /// COEFF_B = 25465760566081946422412445027709227188579564747101592991722834452325077642517
108 const COEFF_B: Fq = MontFp!(
109 Fq,
110 "25465760566081946422412445027709227188579564747101592991722834452325077642517"
111 );
112
113 type TEModelParameters = BandersnatchParameters;
114}
115
116// The TE form generator is generated following Zcash's fashion:
117// "The generators of G1 and G2 are computed by finding the lexicographically
118// smallest valid x-coordinate, and its lexicographically smallest
119// y-coordinate and scaling it by the cofactor such that the result is not
120// the point at infinity."
121// The SW form generator is the same TE generator converted into SW form,
122// obtained from the scripts:
123// <https://github.com/zhenfeizhang/bandersnatch/blob/main/bandersnatch/script/bandersnatch.sage>
124
125/// x coordinate for TE curve generator
126const TE_GENERATOR_X: Fq = MontFp!(
127 Fq,
128 "18886178867200960497001835917649091219057080094937609519140440539760939937304"
129);
130
131/// y coordinate for TE curve generator
132const TE_GENERATOR_Y: Fq = MontFp!(
133 Fq,
134 "19188667384257783945677642223292697773471335439753913231509108946878080696678"
135);
136
137/// x coordinate for SW curve generator
138const SW_GENERATOR_X: Fq = MontFp!(
139 Fq,
140 "30900340493481298850216505686589334086208278925799850409469406976849338430199"
141);
142
143/// y coordinate for SW curve generator
144const SW_GENERATOR_Y: Fq = MontFp!(
145 Fq,
146 "12663882780877899054958035777720958383845500985908634476792678820121468453298"
147);
148
149impl SWModelParameters for BandersnatchParameters {
150 /// COEFF_A = 10773120815616481058602537765553212789256758185246796157495669123169359657269
151 const COEFF_A: Self::BaseField = MontFp!(
152 Fq,
153 "10773120815616481058602537765553212789256758185246796157495669123169359657269"
154 );
155
156 /// COEFF_B = 29569587568322301171008055308580903175558631321415017492731745847794083609535
157 const COEFF_B: Self::BaseField = MontFp!(
158 Fq,
159 "29569587568322301171008055308580903175558631321415017492731745847794083609535"
160 );
161
162 /// generators
163 const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
164 (SW_GENERATOR_X, SW_GENERATOR_Y);
165}