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