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    twisted_edwards_extended::{GroupAffine, GroupProjective},
 5};
 6use ark_ff::{field_new, Field};
 7#[cfg(test)]
 8mod tests;
 9
10pub type EdwardsAffine = GroupAffine<EdwardsParameters>;
11pub type EdwardsProjective = GroupProjective<EdwardsParameters>;
12
13/// `banersnatch` is a twisted Edwards curve. These curves have equations of the
14/// form: ax² + y² = 1 - dx²y².
15/// over some base finite field Fq.
16///
17/// banersnatch's curve equation: -5x² + y² = 1 - dx²y²
18///
19/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513.
20///
21/// a = 52435875175126190479447740508185965837690552500527637822603658699938581184508.
22/// d = (138827208126141220649022263972958607803/
23/// 171449701953573178309673572579671231137) mod q
24///   = 45022363124591815672509500913686876175488063829319466900776701791074614335719.
25///
26/// Sage script to calculate these:
27///
28/// ```text
29/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513
30/// Fq = GF(q)
31/// d = (Fq(138827208126141220649022263972958607803)/Fq(171449701953573178309673572579671231137))
32/// ```
33/// These parameters and the sage script obtained from:
34/// <https://github.com/asanso/Bandersnatch/>
35#[derive(Clone, Default, PartialEq, Eq)]
36pub struct EdwardsParameters;
37
38impl ModelParameters for EdwardsParameters {
39    type BaseField = Fq;
40    type ScalarField = Fr;
41}
42
43impl TEModelParameters for EdwardsParameters {
44    /// COEFF_A = -1
45    #[rustfmt::skip]
46    const COEFF_A: Fq = field_new!(Fq, "-5");
47
48    /// COEFF_D = (138827208126141220649022263972958607803/
49    /// 171449701953573178309673572579671231137) mod q
50    #[rustfmt::skip]
51    const COEFF_D: Fq = field_new!(Fq, "45022363124591815672509500913686876175488063829319466900776701791074614335719");
52
53    /// COFACTOR = 4
54    const COFACTOR: &'static [u64] = &[4];
55
56    /// COFACTOR^(-1) mod r =
57    /// 9831726595336160714896451345284868594481866920080427688839802480047265754601
58    #[rustfmt::skip]
59    const COFACTOR_INV: Fr = field_new!(Fr, "9831726595336160714896451345284868594481866920080427688839802480047265754601");
60
61    /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
62    const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y);
63
64    type MontgomeryModelParameters = EdwardsParameters;
65
66    /// Multiplication by `a` is multiply by `-5`.
67    #[inline(always)]
68    fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
69        let t = (*elem).double().double();
70        -(t + *elem)
71    }
72}
73
74impl MontgomeryModelParameters for EdwardsParameters {
75    /// COEFF_A = 29978822694968839326280996386011761570173833766074948509196803838190355340952
76    #[rustfmt::skip]
77    const COEFF_A: Fq = field_new!(Fq, "29978822694968839326280996386011761570173833766074948509196803838190355340952");
78    /// COEFF_B = 25465760566081946422412445027709227188579564747101592991722834452325077642517
79    #[rustfmt::skip]
80    const COEFF_B: Fq = field_new!(Fq, "25465760566081946422412445027709227188579564747101592991722834452325077642517");
81
82    type TEModelParameters = EdwardsParameters;
83}
84
85// using the generator from bench.py (in affine form)
86// P = BandersnatchPoint(
87//      13738737789055671334382939318077718462576533426798874551591468520593954805549,
88//      11575885077368931610486103676191793534029821920164915325066801506752632626968,
89//      14458123306641001284399433086015669988340559992755622870694102351476334505845,
90//      C)
91#[rustfmt::skip]
92const GENERATOR_X: Fq = field_new!(Fq, "29627151942733444043031429156003786749302466371339015363120350521834195802525");
93#[rustfmt::skip]
94const GENERATOR_Y: Fq = field_new!(Fq, "27488387519748396681411951718153463804682561779047093991696427532072116857978");