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