arnaucube
arnaucube/ark-curves-cherry-pickedPublic Self-hosted repository
ark-curves-cherry-picked/bls12_377/src/curves/g1.rs
bls12_377/src/curves/g1.rsRaw
  1use ark_ec::{
  2    bls12,
  3    bls12::Bls12Config,
  4    hashing::curve_maps::wb::{IsogenyMap, WBConfig},
  5    models::{
  6        short_weierstrass::{Affine as SWAffine, SWCurveConfig},
  7        twisted_edwards::{
  8            Affine as TEAffine, MontCurveConfig, Projective as TEProjective, TECurveConfig,
  9        },
 10    },
 11    CurveConfig,
 12};
 13use ark_ff::{Field, MontFp, PrimeField, Zero};
 14use ark_std::{ops::Neg, One};
 15
 16use super::g1_swu_iso::{SwuIsoConfig, ISOGENY_MAP_TO_G1};
 17use crate::{Fq, Fr};
 18
 19pub type G1Affine = bls12::G1Affine<crate::Config>;
 20pub type G1Projective = bls12::G1Projective<crate::Config>;
 21
 22#[derive(Clone, Default, PartialEq, Eq)]
 23pub struct Config;
 24
 25impl CurveConfig for Config {
 26    type BaseField = Fq;
 27    type ScalarField = Fr;
 28
 29    /// COFACTOR = (x - 1)^2 / 3  = 30631250834960419227450344600217059328
 30    const COFACTOR: &'static [u64] = &[0x0, 0x170b5d4430000000];
 31
 32    /// COFACTOR_INV = COFACTOR^{-1} mod r
 33    /// = 5285428838741532253824584287042945485047145357130994810877
 34    const COFACTOR_INV: Fr = MontFp!("5285428838741532253824584287042945485047145357130994810877");
 35}
 36
 37impl SWCurveConfig for Config {
 38    /// COEFF_A = 0
 39    const COEFF_A: Fq = Fq::ZERO;
 40
 41    /// COEFF_B = 1
 42    const COEFF_B: Fq = Fq::ONE;
 43
 44    /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
 45    const GENERATOR: G1SWAffine = G1SWAffine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
 46
 47    #[inline(always)]
 48    fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
 49        Self::BaseField::zero()
 50    }
 51
 52    #[inline]
 53    fn clear_cofactor(p: &G1SWAffine) -> G1SWAffine {
 54        // Using the effective cofactor.
 55        //
 56        // It is enough to multiply by (x - 1), instead of (x - 1)^2 / 3
 57        let h_eff = x_minus_one().into_bigint();
 58        <Config as SWCurveConfig>::mul_affine(p, h_eff.as_ref()).into()
 59    }
 60}
 61
 62fn x_minus_one() -> Fr {
 63    const X: Fr = Fr::from_sign_and_limbs(!crate::Config::X_IS_NEGATIVE, crate::Config::X);
 64    X - Fr::one()
 65}
 66
 67pub type G1SWAffine = SWAffine<Config>;
 68pub type G1TEAffine = TEAffine<Config>;
 69pub type G1TEProjective = TEProjective<Config>;
 70
 71/// Bls12_377::G1 also has a twisted Edwards form.
 72/// It can be obtained via the following script, implementing
 73/// 1. SW -> Montgomery -> TE1 transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
 74/// 2. TE1 -> TE2 normalization (enforcing `a = -1`)
 75/// ``` sage
 76/// # modulus
 77/// p = 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
 78/// Fp = Zmod(p)
 79///
 80/// #####################################################
 81/// # Weierstrass curve: y² = x³ + A * x + B
 82/// #####################################################
 83/// # curve y^2 = x^3 + 1
 84/// WA = Fp(0)
 85/// WB = Fp(1)
 86///
 87/// #####################################################
 88/// # Montgomery curve: By² = x³ + A * x² + x
 89/// #####################################################
 90/// # root for x^3 + 1 = 0
 91/// alpha = -1
 92/// # s = 1 / (sqrt(3alpha^2 + a))
 93/// s = 1/(Fp(3).sqrt())
 94///
 95/// # MA = 3 * alpha * s
 96/// MA = Fp(228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384)
 97/// # MB = s
 98/// MB = Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
 99///
100/// # #####################################################
101/// # # Twisted Edwards curve 1: a * x² + y² = 1 + d * x² * y²
102/// # #####################################################
103/// # We first convert to TE form obtaining a curve with a != -1, and then
104/// # apply a transformation to obtain a TE curve with a = -1.
105/// # a = (MA+2)/MB
106/// TE1a = Fp(61134141799337779744243169579317764548490943457438569789767076791016838392692895365021181670618017873462480451583)
107/// # b = (MA-2)/MB
108/// TE1d = Fp(197530284213631314266409564115575768987902569297476090750117185875703629955647927409947706468955342250977841006588)
109///
110/// # #####################################################
111/// # # Twisted Edwards curve 2: a * x² + y² = 1 + d * x² * y²
112/// # #####################################################
113/// # a = -1
114/// TE2a = Fp(-1)
115/// # b = -TE1d/TE1a
116/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
117/// ```
118impl TECurveConfig for Config {
119    /// COEFF_A = -1
120    const COEFF_A: Fq = MontFp!("-1");
121
122    /// COEFF_D = 122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179 mod q
123    const COEFF_D: Fq = MontFp!("122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179");
124
125    /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
126    const GENERATOR: G1TEAffine = G1TEAffine::new_unchecked(TE_GENERATOR_X, TE_GENERATOR_Y);
127
128    type MontCurveConfig = Config;
129
130    /// Multiplication by `a` is multiply by `-1`.
131    #[inline(always)]
132    fn mul_by_a(elem: Self::BaseField) -> Self::BaseField {
133        elem.neg()
134    }
135}
136
137// BLS12-377::G1 also has a Montgomery form.
138// BLS12-377::G1 also has a twisted Edwards form.
139// It can be obtained via the following script, implementing
140// SW -> Montgomery transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
141// ``` sage
142// # modulus
143// p=0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
144// Fp=Zmod(p)
145//
146// #####################################################
147// # Weierstrass curve: y² = x³ + A * x + B
148// #####################################################
149// # curve y^2 = x^3 + 1
150// WA=Fp(0)
151// WB=Fp(1)
152//
153// #####################################################
154// # Montgomery curve: By² = x³ + A * x² + x
155// #####################################################
156// # root for x^3 + 1 = 0
157// alpha = -1
158// # s = 1 / (sqrt(3alpha^2 + a))
159// s = 1/(Fp(3).sqrt())
160//
161// # MA = 3 * alpha * s
162// MA=Fp(228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384)
163// # MB = s
164// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
165// ```
166impl MontCurveConfig for Config {
167    /// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384
168    const COEFF_A: Fq = MontFp!("228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
169
170    /// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931
171    const COEFF_B: Fq = MontFp!("10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
172
173    type TECurveConfig = Config;
174}
175
176/// G1_GENERATOR_X =
177/// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695
178pub const G1_GENERATOR_X: Fq = MontFp!("81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695");
179
180/// G1_GENERATOR_Y =
181/// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
182pub const G1_GENERATOR_Y: Fq = MontFp!("241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030");
183
184impl WBConfig for Config {
185    type IsogenousCurve = SwuIsoConfig;
186
187    const ISOGENY_MAP: IsogenyMap<'static, Self::IsogenousCurve, Self> = ISOGENY_MAP_TO_G1;
188}
189
190// The generator for twisted Edward form is the same SW generator converted into
191// the normalized TE form (TE2).
192//``` sage
193// # following scripts in previous section
194// #####################################################
195// # Weierstrass curve generator
196// #####################################################
197// Wx = Fp(81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695)
198// Wy = Fp(241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030)
199//
200// assert(Wy^2 - Wx^3 - WA * Wx - WB == 0)
201//
202// #####################################################
203// # Montgomery curve generator
204// #####################################################
205// # x = s * (x - alpha)
206// Mx = Fp(251803586774461569862800610331871502335378228972505599912537082323947581271784390797244487924068052270360793200630)
207// # y = s * y
208// My = Fp(77739247071951651095607889637653357561348174979132042929587539214321586851215673796661346812932566642719051699820)
209//
210// assert(MB * My^2 == Mx^3+ MA * Mx^2 + Mx)
211//
212// # #####################################################
213// # # Twisted Edwards curve 1 generator
214// # #####################################################
215// # x = Mx/My
216// TE1x = Fp(82241236807150726090333472814441006963902378430536027612759193445733851062772474760677400112551677454953925168208)
217// # y = (Mx - 1)/(Mx+1)
218// TE1y = Fp(6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235)
219//
220// assert( TE1a * TE1x^2 + TE1y^2 == 1 + TE1d * TE1x^2 * TE1y^2 )
221//
222//
223// # #####################################################
224// # # Twisted Edwards curve 2 generator
225// # #####################################################
226// beta = (-TE1a).sqrt()
227// # x = TE1x * sqrt(-TE1a)
228// TE2x = Fp(71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393)
229// # y = TE1y
230// TE2y = Fp(6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235)
231//
232// assert( TE2a * TE2x^2 + TE2y^2 == 1 + TE2d * TE2x^2 * TE2y^2 )
233// ```
234/// TE_GENERATOR_X =
235/// 71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393
236pub const TE_GENERATOR_X: Fq = MontFp!("71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393");
237
238/// TE_GENERATOR_Y =
239/// 6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235
240pub const TE_GENERATOR_Y: Fq = MontFp!("6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235");
241
242#[cfg(test)]
243mod test {
244
245    use super::*;
246    use crate::g1;
247    use ark_std::{rand::Rng, UniformRand};
248
249    fn sample_unchecked() -> SWAffine<g1::Config> {
250        let mut rng = ark_std::test_rng();
251        loop {
252            let x = Fq::rand(&mut rng);
253            let greatest = rng.gen();
254
255            if let Some(p) = SWAffine::get_point_from_x_unchecked(x, greatest) {
256                return p;
257            }
258        }
259    }
260
261    #[test]
262    fn test_cofactor_clearing() {
263        const SAMPLES: usize = 100;
264        for _ in 0..SAMPLES {
265            let p: SWAffine<g1::Config> = sample_unchecked();
266            let p = <Config as SWCurveConfig>::clear_cofactor(&p);
267            assert!(p.is_on_curve());
268            assert!(p.is_in_correct_subgroup_assuming_on_curve());
269        }
270    }
271}