arnaucube
arnaucube/ark-curves-cherry-pickedPublic Self-hosted repository
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}