arnaucube
arnaucube/ark-curves-cherry-pickedPublic Self-hosted repository
ark-curves-cherry-picked/ed_on_bls12_381/src/curves/mod.rs
ed_on_bls12_381/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;
 11
 12#[cfg(test)]
 13mod tests;
 14
 15pub type EdwardsAffine = GroupAffine<JubjubParameters>;
 16pub type EdwardsProjective = GroupProjective<JubjubParameters>;
 17pub type SWAffine = SWGroupAffine<JubjubParameters>;
 18pub type SWProjective = SWGroupProjective<JubjubParameters>;
 19
 20/// `JubJub` is a twisted Edwards curve. These curves have equations of the
 21/// form: ax² + y² = 1 - dx²y².
 22/// over some base finite field Fq.
 23///
 24/// JubJub's curve equation: -x² + y² = 1 - (10240/10241)x²y²
 25///
 26/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513.
 27///
 28/// a = -1.
 29/// d = (10240/10241) mod q
 30///   = 19257038036680949359750312669786877991949435402254120286184196891950884077233.
 31///
 32/// Sage script to calculate these:
 33///
 34/// ```text
 35/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513
 36/// Fq = GF(q)
 37/// d = -(Fq(10240)/Fq(10241))
 38/// ```
 39/// These parameters and the sage script obtained from:
 40/// <https://github.com/zcash/zcash/issues/2230#issuecomment-317182190>
 41///
 42///
 43/// `jubjub` also has a short Weierstrass curve form, following the
 44/// form: y² = x³ + A * x + B
 45/// where
 46///
 47/// A = 52296097456646850916096512823759002727550416093741407922227928430486925478210
 48/// B = 48351165704696163914533707656614864561753505123260775585269522553028192119009
 49///
 50/// We can use the script available
 51/// [here](https://github.com/zhenfeizhang/bandersnatch/blob/main/bandersnatch/script/jubjub.sage)
 52/// to convert between the different representations.
 53#[derive(Clone, Default, PartialEq, Eq)]
 54pub struct JubjubParameters;
 55pub type EdwardsParameters = JubjubParameters;
 56pub type SWParameters = JubjubParameters;
 57
 58impl ModelParameters for JubjubParameters {
 59    type BaseField = Fq;
 60    type ScalarField = Fr;
 61}
 62
 63impl TEModelParameters for JubjubParameters {
 64    /// COEFF_A = -1
 65    #[rustfmt::skip]
 66    const COEFF_A: Fq = field_new!(Fq, "-1");
 67
 68    /// COEFF_D = (10240/10241) mod q
 69    #[rustfmt::skip]
 70    const COEFF_D: Fq = field_new!(Fq, "19257038036680949359750312669786877991949435402254120286184196891950884077233");
 71
 72    /// COFACTOR = 8
 73    const COFACTOR: &'static [u64] = &[8];
 74
 75    /// COFACTOR^(-1) mod r =
 76    /// 819310549611346726241370945440405716213240158234039660170669895299022906775
 77    #[rustfmt::skip]
 78    const COFACTOR_INV: Fr = field_new!(Fr, "819310549611346726241370945440405716213240158234039660170669895299022906775");
 79
 80    /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
 81    const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y);
 82
 83    type MontgomeryModelParameters = JubjubParameters;
 84
 85    /// Multiplication by `a` is simply negation here.
 86    #[inline(always)]
 87    fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
 88        -(*elem)
 89    }
 90}
 91
 92impl MontgomeryModelParameters for JubjubParameters {
 93    /// COEFF_A = 40962
 94    #[rustfmt::skip]
 95    const COEFF_A: Fq = field_new!(Fq, "40962");
 96    /// COEFF_B = -40964
 97    #[rustfmt::skip]
 98    const COEFF_B: Fq = field_new!(Fq, "-40964");
 99
100    type TEModelParameters = JubjubParameters;
101}
102
103#[rustfmt::skip]
104const GENERATOR_X: Fq = field_new!(Fq, "8076246640662884909881801758704306714034609987455869804520522091855516602923");
105#[rustfmt::skip]
106const GENERATOR_Y: Fq = field_new!(Fq, "13262374693698910701929044844600465831413122818447359594527400194675274060458");
107
108impl SWModelParameters for JubjubParameters {
109    /// COEFF_A = 52296097456646850916096512823759002727550416093741407922227928430486925478210
110    #[rustfmt::skip]
111    const COEFF_A: Self::BaseField = field_new!(Fq, "52296097456646850916096512823759002727550416093741407922227928430486925478210");
112
113    /// COEFF_B = 48351165704696163914533707656614864561753505123260775585269522553028192119009
114    #[rustfmt::skip]
115    const COEFF_B: Self::BaseField = field_new!(Fq, "48351165704696163914533707656614864561753505123260775585269522553028192119009");
116
117    /// COFACTOR = 8
118    const COFACTOR: &'static [u64] = &[8];
119
120    /// COFACTOR^(-1) mod r =
121    /// 819310549611346726241370945440405716213240158234039660170669895299022906775
122    #[rustfmt::skip]
123    const COFACTOR_INV: Fr = field_new!(Fr, "819310549611346726241370945440405716213240158234039660170669895299022906775");
124
125    /// generators
126    const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
127        (SW_GENERATOR_X, SW_GENERATOR_Y);
128}
129
130/// x coordinate for SW curve generator
131#[rustfmt::skip]
132const SW_GENERATOR_X: Fq = field_new!(Fq, "33835869156188682335217394949746694649676633840125476177319971163079011318731");
133/// y coordinate for SW curve generator
134#[rustfmt::skip]
135const SW_GENERATOR_Y: Fq = field_new!(Fq, "43777270878440091394432848052353307184915192688165709016756678962558652055320");