mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-09 23:41:30 +01:00
Initial commit
This commit is contained in:
104
mnt4_753/src/curves/g1.rs
Normal file
104
mnt4_753/src/curves/g1.rs
Normal file
@@ -0,0 +1,104 @@
|
||||
use ark_ec::{
|
||||
mnt4,
|
||||
models::{ModelParameters, SWModelParameters},
|
||||
};
|
||||
use ark_ff::{biginteger::BigInteger768, field_new};
|
||||
|
||||
use crate::{Fq, Fr, FR_ONE};
|
||||
|
||||
pub type G1Affine = mnt4::G1Affine<crate::Parameters>;
|
||||
pub type G1Projective = mnt4::G1Projective<crate::Parameters>;
|
||||
pub type G1Prepared = mnt4::G1Prepared<crate::Parameters>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
/// COEFF_A = 2
|
||||
#[rustfmt::skip]
|
||||
const COEFF_A: Fq = field_new!(Fq, BigInteger768([
|
||||
3553860551672651396,
|
||||
2565472393707818253,
|
||||
3424927325234966109,
|
||||
17487811826058095619,
|
||||
15730291918544907998,
|
||||
4332070408724822737,
|
||||
7212646118208244402,
|
||||
12904649141092619460,
|
||||
9289117987390442562,
|
||||
2254330573517213976,
|
||||
3065472942259520298,
|
||||
271095073719429,
|
||||
]));
|
||||
|
||||
/// COEFF_B = 0x01373684A8C9DCAE7A016AC5D7748D3313CD8E39051C596560835DF0C9E50A5B59B882A92C78DC537E51A16703EC9855C77FC3D8BB21C8D68BB8CFB9DB4B8C8FBA773111C36C8B1B4E8F1ECE940EF9EAAD265458E06372009C9A0491678EF4
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, BigInteger768([
|
||||
2672638521926201442,
|
||||
17587766986973859626,
|
||||
1309143029066506763,
|
||||
1756412671449422902,
|
||||
5395165286423163724,
|
||||
589638022240022974,
|
||||
7360845090332416697,
|
||||
9829497896347590557,
|
||||
9341553552113883496,
|
||||
5888515763059971584,
|
||||
10173739464651404689,
|
||||
456607542322059,
|
||||
]));
|
||||
|
||||
/// COFACTOR = 1
|
||||
const COFACTOR: &'static [u64] = &[1];
|
||||
|
||||
/// COFACTOR^(-1) mod r =
|
||||
/// 1
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = FR_ONE;
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G1_GENERATOR_X, G1_GENERATOR_Y);
|
||||
}
|
||||
|
||||
// Generator of G1
|
||||
// X = 7790163481385331313124631546957228376128961350185262705123068027727518350362064426002432450801002268747950550964579198552865939244360469674540925037890082678099826733417900510086646711680891516503232107232083181010099241949569,
|
||||
// Y = 6913648190367314284606685101150155872986263667483624713540251048208073654617802840433842931301128643140890502238233930290161632176167186761333725658542781350626799660920481723757654531036893265359076440986158843531053720994648,
|
||||
/// G1_GENERATOR_X =
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, BigInteger768([
|
||||
9433494781491502420,
|
||||
373642694095780604,
|
||||
7974079134466535382,
|
||||
15325904219470166885,
|
||||
16825705122208020751,
|
||||
898733863352481713,
|
||||
3802318585082797759,
|
||||
14417069684372068941,
|
||||
4332882897981414838,
|
||||
15138727514183191816,
|
||||
16850594895992448907,
|
||||
30598511593902
|
||||
]));
|
||||
|
||||
/// G1_GENERATOR_Y =
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, BigInteger768([
|
||||
15710199097794077134,
|
||||
3645667958306606136,
|
||||
8298269426007169475,
|
||||
5277073422205725562,
|
||||
10451808582969862130,
|
||||
14392820246664025579,
|
||||
4365987620174557815,
|
||||
14007263953321073101,
|
||||
1355600847400958219,
|
||||
3872959105252355444,
|
||||
18016882244107198324,
|
||||
424779036457857
|
||||
]));
|
||||
177
mnt4_753/src/curves/g2.rs
Normal file
177
mnt4_753/src/curves/g2.rs
Normal file
@@ -0,0 +1,177 @@
|
||||
use ark_ec::{
|
||||
mnt4,
|
||||
mnt4::MNT4Parameters,
|
||||
models::{ModelParameters, SWModelParameters},
|
||||
};
|
||||
use ark_ff::{biginteger::BigInteger768, field_new};
|
||||
|
||||
use crate::{Fq, Fq2, Fr, FQ_ZERO, G1_COEFF_A_NON_RESIDUE};
|
||||
|
||||
pub type G2Affine = mnt4::G2Affine<crate::Parameters>;
|
||||
pub type G2Projective = mnt4::G2Projective<crate::Parameters>;
|
||||
pub type G2Prepared = mnt4::G2Prepared<crate::Parameters>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Parameters;
|
||||
|
||||
impl ModelParameters for Parameters {
|
||||
type BaseField = Fq2;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
/// MUL_BY_A_C0 = NONRESIDUE * COEFF_A
|
||||
#[rustfmt::skip]
|
||||
pub const MUL_BY_A_C0: Fq = G1_COEFF_A_NON_RESIDUE;
|
||||
|
||||
/// MUL_BY_A_C1 = NONRESIDUE * COEFF_A
|
||||
#[rustfmt::skip]
|
||||
pub const MUL_BY_A_C1: Fq = G1_COEFF_A_NON_RESIDUE;
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
const COEFF_A: Fq2 = crate::Parameters::TWIST_COEFF_A;
|
||||
// B coefficient of MNT4-753 G2 =
|
||||
// ```
|
||||
// mnt4753_twist_coeff_b = mnt4753_Fq2(mnt4753_Fq::zero(),
|
||||
// mnt4753_G1::coeff_b * mnt4753_Fq2::non_residue);
|
||||
// non_residue = mnt4753_Fq2::non_residue = mnt4753_Fq("13");
|
||||
// = (ZERO, G1_B_COEFF * NON_RESIDUE);
|
||||
// =
|
||||
// (0, 39196523001581428369576759982967177918859161321667605855515469914917622337081756705006832951954384669101573360625169461998308377011601613979275218690841934572954991361632773738259652003389826903175898479855893660378722437317212)
|
||||
// ```
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq2 = field_new!(Fq2,
|
||||
FQ_ZERO,
|
||||
field_new!(Fq, BigInteger768([
|
||||
15129916544657421551,
|
||||
11332543254671606602,
|
||||
11913830318987286849,
|
||||
13905314883394440110,
|
||||
16479690325073358448,
|
||||
14869098639251228898,
|
||||
10663986895980443550,
|
||||
10768989312009479656,
|
||||
9469728929095040349,
|
||||
4512954369775881939,
|
||||
8788997129423430122,
|
||||
459763387588954,
|
||||
])),
|
||||
);
|
||||
|
||||
/// COFACTOR =
|
||||
/// 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888049094905534395567574915333486969589229856772141392370549616644545554517640527237829320384324374366385444967219201
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR: &'static [u64] = &[
|
||||
16436257212445032449,
|
||||
8690275530472745198,
|
||||
17315389657026393162,
|
||||
1645397558963170979,
|
||||
3544984605440726586,
|
||||
12665092767997125024,
|
||||
11083680675069097885,
|
||||
575819899841080717,
|
||||
6825179918269667443,
|
||||
13256793349531086829,
|
||||
1162650133526138285,
|
||||
497830423872529,
|
||||
];
|
||||
|
||||
/// COFACTOR^(-1) mod r =
|
||||
/// 102345604409665481004734934052318066391634848395005988700111949231215905051467807945653833683883449458834877235200
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger768([
|
||||
1879390364380281898,
|
||||
7926794171490610432,
|
||||
6437239504245874253,
|
||||
16688141022047191858,
|
||||
17059416847145768464,
|
||||
15065047661241262516,
|
||||
16537575340937777321,
|
||||
3324411942044534547,
|
||||
3878293904770657570,
|
||||
18116939243856833744,
|
||||
7557533897589069385,
|
||||
78370361203778,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
|
||||
(G2_GENERATOR_X, G2_GENERATOR_Y);
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_by_a(elt: &Fq2) -> Fq2 {
|
||||
field_new!(Fq2, MUL_BY_A_C0 * &elt.c0, MUL_BY_A_C1 * &elt.c1,)
|
||||
}
|
||||
}
|
||||
|
||||
const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
|
||||
const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
|
||||
|
||||
// Generator of G2
|
||||
// These are two Fq elements each because X and Y (and Z) are elements of Fq^2
|
||||
// X = 29483965110843144675703364744708836524643960105538608078862508397502447349913068434941060515343254862580437318493682762113105361632548148204806052114008731372757389645383891982211245013965175213456066452587869519098351487925167,
|
||||
// 19706011319630172391076079624799753948158506771222147486237995321925443331396169656568431378974558350664383559981183980668976846806019030432389169137953988990802000581078994008283967768348275973921598166274857631001635633631000,
|
||||
// Y = 39940152670760519653940320314827327941993141403708338666925204282084477074754642625849927569427860786384998614863651207257467076192649385174108085803168743803491780568503369317093191101779534035377266300185099318717465441820654,
|
||||
// 17608637424964395737041291373756657139607306440193731804102457011726690702169238966996114255971643893157857311132388792357391583164125870757541009035041469463366528798593952884745987697403056488744603829437448927398468360797245,
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, BigInteger768([
|
||||
7263636080534048301,
|
||||
7643227961769035653,
|
||||
15787777614640869937,
|
||||
17661317895964274771,
|
||||
4142647779394287783,
|
||||
15064949873659932676,
|
||||
4579259080596351332,
|
||||
2207443675339702626,
|
||||
5738725620118622838,
|
||||
4338467638707299712,
|
||||
6558861849926282439,
|
||||
341078935870328
|
||||
]));
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, BigInteger768([
|
||||
13073882729051113867,
|
||||
195909455108318710,
|
||||
10527070038778509320,
|
||||
16605710222187477118,
|
||||
10442518358308209073,
|
||||
7776589986153052354,
|
||||
16034091384000651523,
|
||||
17429232381273855185,
|
||||
512853344493546034,
|
||||
7982076214836075255,
|
||||
3601416800138513610,
|
||||
399028695285184
|
||||
]));
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, BigInteger768([
|
||||
4867672648970469422,
|
||||
2453112364260322863,
|
||||
11918672197974895143,
|
||||
3923647310180624143,
|
||||
12707123323825700670,
|
||||
15781895092544451511,
|
||||
17747112377690960911,
|
||||
16511994611001933567,
|
||||
15360620366665804029,
|
||||
10252080383738480571,
|
||||
5722654046339742760,
|
||||
316853130349807
|
||||
]));
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, BigInteger768([
|
||||
17322957246732430708,
|
||||
11825815087694023697,
|
||||
7654216682602683900,
|
||||
13544637981229618042,
|
||||
17057060382219081849,
|
||||
4038731408172002692,
|
||||
6631723222530012253,
|
||||
10585926166286435412,
|
||||
16050667328028620117,
|
||||
16598483946296156500,
|
||||
11771818132648686020,
|
||||
1230430296095
|
||||
]));
|
||||
90
mnt4_753/src/curves/mod.rs
Normal file
90
mnt4_753/src/curves/mod.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
use ark_ec::models::mnt4::{MNT4Parameters, MNT4};
|
||||
use ark_ff::{biginteger::BigInteger768, field_new, fields::FpParameters, Fp2};
|
||||
|
||||
use crate::{Fq, Fq2, Fq2Parameters, Fq4Parameters, FqParameters, Fr, FrParameters};
|
||||
|
||||
pub mod g1;
|
||||
pub mod g2;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use self::{
|
||||
g1::{G1Affine, G1Prepared, G1Projective},
|
||||
g2::{G2Affine, G2Prepared, G2Projective},
|
||||
};
|
||||
|
||||
pub type MNT4_753 = MNT4<Parameters>;
|
||||
|
||||
pub struct Parameters;
|
||||
|
||||
impl MNT4Parameters for Parameters {
|
||||
const TWIST: Fp2<Self::Fp2Params> = field_new!(Fq2, FQ_ZERO, FQ_ONE);
|
||||
// A coefficient of MNT4-753 G2 =
|
||||
// ```
|
||||
// mnt4753_twist_coeff_a = mnt4753_Fq2(mnt4753_G1::coeff_a * non_residue, mnt6753_Fq::zero());
|
||||
// = (A_COEFF * NONRESIDUE, ZERO)
|
||||
// = (26, ZERO)
|
||||
// ```
|
||||
#[rustfmt::skip]
|
||||
const TWIST_COEFF_A: Fp2<Self::Fp2Params> = field_new!(Fq2,
|
||||
G1_COEFF_A_NON_RESIDUE,
|
||||
FQ_ZERO,
|
||||
);
|
||||
// https://github.com/o1-labs/snarky/blob/9c21ab2bb23874604640740d646a932e813432c3/snarkette/mnt4753.ml
|
||||
const ATE_LOOP_COUNT: &'static [u64] = &[
|
||||
8824542903220142080,
|
||||
7711082599397206192,
|
||||
8303354903384568230,
|
||||
5874150271971943936,
|
||||
9717849827920685054,
|
||||
95829799234282493,
|
||||
];
|
||||
const ATE_IS_LOOP_COUNT_NEG: bool = true;
|
||||
const FINAL_EXPONENT_LAST_CHUNK_1: BigInteger768 =
|
||||
BigInteger768([0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);
|
||||
const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool = true;
|
||||
const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: BigInteger768 = BigInteger768([
|
||||
8824542903220142079,
|
||||
7711082599397206192,
|
||||
8303354903384568230,
|
||||
5874150271971943936,
|
||||
9717849827920685054,
|
||||
95829799234282493,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
]);
|
||||
type Fp = Fq;
|
||||
type Fr = Fr;
|
||||
type Fp2Params = Fq2Parameters;
|
||||
type Fp4Params = Fq4Parameters;
|
||||
type G1Parameters = self::g1::Parameters;
|
||||
type G2Parameters = self::g2::Parameters;
|
||||
}
|
||||
|
||||
// 26
|
||||
pub const G1_COEFF_A_NON_RESIDUE: Fq = field_new!(
|
||||
Fq,
|
||||
BigInteger768([
|
||||
16948538951764659373,
|
||||
10775354577659735631,
|
||||
12766795894854242596,
|
||||
8684022258823474090,
|
||||
973489465296612807,
|
||||
3883945490221946200,
|
||||
16178634811223492029,
|
||||
16155746945640075033,
|
||||
17642042187059426365,
|
||||
10295720303844380352,
|
||||
13265853240981244259,
|
||||
39422991244875,
|
||||
])
|
||||
);
|
||||
pub const FQ_ZERO: Fq = field_new!(Fq, BigInteger768([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
|
||||
pub const FQ_ONE: Fq = field_new!(Fq, FqParameters::R);
|
||||
pub const FR_ZERO: Fr = field_new!(Fr, BigInteger768([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
|
||||
pub const FR_ONE: Fr = field_new!(Fr, FrParameters::R);
|
||||
90
mnt4_753/src/curves/tests.rs
Normal file
90
mnt4_753/src/curves/tests.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{test_rng, Field, One, PrimeField, UniformRand};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::*;
|
||||
|
||||
use ark_curve_tests::{curves::*, groups::*};
|
||||
|
||||
#[test]
|
||||
fn test_g1_projective_curve() {
|
||||
curve_tests::<G1Projective>();
|
||||
|
||||
sw_tests::<g1::Parameters>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g1_projective_group() {
|
||||
let mut rng = test_rng();
|
||||
let a: G1Projective = rng.gen();
|
||||
let b: G1Projective = rng.gen();
|
||||
group_test(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g1_generator() {
|
||||
let generator = G1Affine::prime_subgroup_generator();
|
||||
assert!(generator.is_on_curve());
|
||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2_projective_curve() {
|
||||
curve_tests::<G2Projective>();
|
||||
|
||||
sw_tests::<g2::Parameters>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2_projective_group() {
|
||||
let mut rng = test_rng();
|
||||
let a: G2Projective = rng.gen();
|
||||
let b: G2Projective = rng.gen();
|
||||
group_test(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2_generator() {
|
||||
let generator = G2Affine::prime_subgroup_generator();
|
||||
assert!(generator.is_on_curve());
|
||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bilinearity() {
|
||||
let mut rng = test_rng();
|
||||
let a: G1Projective = rng.gen();
|
||||
let b: G2Projective = rng.gen();
|
||||
let s: Fr = rng.gen();
|
||||
|
||||
let sa = a.mul(s);
|
||||
let sb = b.mul(s);
|
||||
|
||||
let ans1 = MNT4_753::pairing(sa, b);
|
||||
let ans2 = MNT4_753::pairing(a, sb);
|
||||
let ans3 = MNT4_753::pairing(a, b).pow(s.into_repr());
|
||||
|
||||
assert_eq!(ans1, ans2);
|
||||
assert_eq!(ans2, ans3);
|
||||
|
||||
assert_ne!(ans1, Fq4::one());
|
||||
assert_ne!(ans2, Fq4::one());
|
||||
assert_ne!(ans3, Fq4::one());
|
||||
|
||||
assert_eq!(ans1.pow(Fr::characteristic()), Fq4::one());
|
||||
assert_eq!(ans2.pow(Fr::characteristic()), Fq4::one());
|
||||
assert_eq!(ans3.pow(Fr::characteristic()), Fq4::one());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_product_of_pairings() {
|
||||
let rng = &mut test_rng();
|
||||
|
||||
let a = G1Projective::rand(rng).into_affine();
|
||||
let b = G2Projective::rand(rng).into_affine();
|
||||
let c = G1Projective::rand(rng).into_affine();
|
||||
let d = G2Projective::rand(rng).into_affine();
|
||||
let ans1 = MNT4_753::pairing(a, b) * &MNT4_753::pairing(c, d);
|
||||
let ans2 = MNT4_753::product_of_pairings(&[(a.into(), b.into()), (c.into(), d.into())]);
|
||||
assert_eq!(ans1, ans2);
|
||||
}
|
||||
170
mnt4_753/src/fields/fq.rs
Normal file
170
mnt4_753/src/fields/fq.rs
Normal file
@@ -0,0 +1,170 @@
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger768 as BigInteger,
|
||||
fields::{FftParameters, Fp768, Fp768Parameters, FpParameters},
|
||||
};
|
||||
|
||||
pub type Fq = Fp768<FqParameters>;
|
||||
|
||||
pub struct FqParameters;
|
||||
|
||||
impl Fp768Parameters for FqParameters {}
|
||||
impl FftParameters for FqParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
const TWO_ADICITY: u32 = 15;
|
||||
|
||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
||||
0x3b079c7556ac378,
|
||||
0x2c8c74d04a3f00d4,
|
||||
0xd3b001061b90d4cf,
|
||||
0x946e77514891b0e6,
|
||||
0x79caec8ad6dc9ea1,
|
||||
0xbefd780edc81435d,
|
||||
0xe093d4dca630b154,
|
||||
0x43a0f673199f1c12,
|
||||
0x92276c78436253ff,
|
||||
0xe249d1cf014fcd24,
|
||||
0x96f36471fb7c3ec5,
|
||||
0x1080b8906b7c4,
|
||||
]);
|
||||
|
||||
const SMALL_SUBGROUP_BASE: Option<u32> = Some(5);
|
||||
const SMALL_SUBGROUP_BASE_ADICITY: Option<u32> = Some(2);
|
||||
/// LARGE_SUBGROUP_ROOT_OF_UNITY =
|
||||
/// 12249458902762217747626832919710926618510011455364963726393752854649914979954138109976331601455448780251166045203053508523342111624583986869301658366625356826888785691823710598470775453742133593634524619429629803955083254436531
|
||||
const LARGE_SUBGROUP_ROOT_OF_UNITY: Option<BigInteger> = Some(BigInteger([
|
||||
8926681816978929800,
|
||||
10873079436792120119,
|
||||
6519893728366769435,
|
||||
7899277225737766970,
|
||||
8416573500933450083,
|
||||
12951641800297678468,
|
||||
7093775028595490583,
|
||||
14327009285082556021,
|
||||
18228411097456927576,
|
||||
2823658094446565457,
|
||||
1708328092507553067,
|
||||
109589007594791,
|
||||
]));
|
||||
}
|
||||
impl FpParameters for FqParameters {
|
||||
/// MODULUS = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689601
|
||||
const MODULUS: BigInteger = BigInteger([
|
||||
0x5e9063de245e8001,
|
||||
0xe39d54522cdd119f,
|
||||
0x638810719ac425f0,
|
||||
0x685acce9767254a4,
|
||||
0xb80f0da5cb537e38,
|
||||
0xb117e776f218059d,
|
||||
0x99d124d9a15af79d,
|
||||
0x7fdb925e8a0ed8d,
|
||||
0x5eb7e8f96c97d873,
|
||||
0xb7f997505b8fafed,
|
||||
0x10229022eee2cdad,
|
||||
0x1c4c62d92c411,
|
||||
]);
|
||||
|
||||
const MODULUS_BITS: u32 = 753;
|
||||
|
||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
||||
|
||||
const REPR_SHAVE_BITS: u32 = 15;
|
||||
|
||||
const R: BigInteger = BigInteger([
|
||||
0x98a8ecabd9dc6f42,
|
||||
0x91cd31c65a034686,
|
||||
0x97c3e4a0cd14572e,
|
||||
0x79589819c788b601,
|
||||
0xed269c942108976f,
|
||||
0x1e0f4d8acf031d68,
|
||||
0x320c3bb713338559,
|
||||
0x598b4302d2f00a62,
|
||||
0x4074c9cbfd8ca621,
|
||||
0xfa47edb3865e88c,
|
||||
0x95455fb31ff9a195,
|
||||
0x7b479ec8e242,
|
||||
]);
|
||||
|
||||
const R2: BigInteger = BigInteger([
|
||||
0x84717088cfd190c8,
|
||||
0xc7d9ff8e7df03c0a,
|
||||
0xa24bea56242b3507,
|
||||
0xa896a656a0714c7d,
|
||||
0x80a46659ff6f3ddf,
|
||||
0x2f47839ef88d7ce8,
|
||||
0xa8c86d4604a3b597,
|
||||
0xe03c79cac4f7ef07,
|
||||
0x2505daf1f4a81245,
|
||||
0x8e4605754c381723,
|
||||
0xb081f15bcbfdacaf,
|
||||
0x2a33e89cb485,
|
||||
]);
|
||||
|
||||
const INV: u64 = 0xf2044cfbe45e7fff;
|
||||
|
||||
const GENERATOR: BigInteger = BigInteger([
|
||||
0xa8f627f0e629635e,
|
||||
0x202afce346c36872,
|
||||
0x85e1ece733493254,
|
||||
0x6d76e610664ac389,
|
||||
0xdf542f3f04441585,
|
||||
0x3aa4885bf6d4dd80,
|
||||
0xeb8b63c1c0fffc74,
|
||||
0xd2488e985f6cfa4e,
|
||||
0xcce1c2a623f7a66a,
|
||||
0x2a060f4d5085b19a,
|
||||
0xa9111a596408842f,
|
||||
0x11ca8d50bf627,
|
||||
]);
|
||||
|
||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0xaf4831ef122f4000,
|
||||
0x71ceaa29166e88cf,
|
||||
0x31c40838cd6212f8,
|
||||
0x342d6674bb392a52,
|
||||
0xdc0786d2e5a9bf1c,
|
||||
0xd88bf3bb790c02ce,
|
||||
0xcce8926cd0ad7bce,
|
||||
0x83fedc92f45076c6,
|
||||
0xaf5bf47cb64bec39,
|
||||
0xdbfccba82dc7d7f6,
|
||||
0x88114811777166d6,
|
||||
0xe26316c96208,
|
||||
]);
|
||||
|
||||
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
|
||||
|
||||
/// T = (MODULUS - 1) / 2^S =
|
||||
/// 1278640471433073529124274133033466709233725278318907137200424283478556909563327233064541435662546964154604216671394463687571830033251476599169665701965732619291119517454523942352538645255842982596454713491581459512424155325
|
||||
const T: BigInteger = BigInteger([
|
||||
0x233ebd20c7bc48bd,
|
||||
0x4be1c73aa8a459ba,
|
||||
0xa948c71020e33588,
|
||||
0xfc70d0b599d2ece4,
|
||||
0xb3b701e1b4b96a6,
|
||||
0xef3b622fceede430,
|
||||
0xdb1b33a249b342b5,
|
||||
0xb0e60ffb724bd141,
|
||||
0x5fdabd6fd1f2d92f,
|
||||
0x9b5b6ff32ea0b71f,
|
||||
0x882220452045ddc5,
|
||||
0x3898c5b25,
|
||||
]);
|
||||
|
||||
/// (T - 1) / 2 =
|
||||
/// 639320235716536764562137066516733354616862639159453568600212141739278454781663616532270717831273482077302108335697231843785915016625738299584832850982866309645559758727261971176269322627921491298227356745790729756212077662
|
||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0x119f5e9063de245e,
|
||||
0x25f0e39d54522cdd,
|
||||
0x54a4638810719ac4,
|
||||
0x7e38685acce97672,
|
||||
0x59db80f0da5cb53,
|
||||
0xf79db117e776f218,
|
||||
0xed8d99d124d9a15a,
|
||||
0xd87307fdb925e8a0,
|
||||
0xafed5eb7e8f96c97,
|
||||
0xcdadb7f997505b8f,
|
||||
0xc41110229022eee2,
|
||||
0x1c4c62d92,
|
||||
]);
|
||||
}
|
||||
77
mnt4_753/src/fields/fq2.rs
Normal file
77
mnt4_753/src/fields/fq2.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use crate::{Fq, FQ_ONE};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger768 as BigInteger,
|
||||
field_new,
|
||||
fields::fp2::{Fp2, Fp2Parameters},
|
||||
};
|
||||
|
||||
pub type Fq2 = Fp2<Fq2Parameters>;
|
||||
|
||||
pub struct Fq2Parameters;
|
||||
|
||||
impl Fp2Parameters for Fq2Parameters {
|
||||
type Fp = Fq;
|
||||
|
||||
// non_residue = 13
|
||||
#[rustfmt::skip]
|
||||
const NONRESIDUE: Fq = field_new!(Fq, BigInteger([
|
||||
11881297496860141143,
|
||||
13588356353764843511,
|
||||
9969398190777826186,
|
||||
17325157081734070311,
|
||||
16341533986183788031,
|
||||
8322434028726676858,
|
||||
13631157743146294957,
|
||||
8365783422740577875,
|
||||
3010239015809771096,
|
||||
11776256826687733591,
|
||||
7214251687253691272,
|
||||
268626707558702
|
||||
]));
|
||||
|
||||
// qnr = (8, 1)
|
||||
const QUADRATIC_NONRESIDUE: (Self::Fp, Self::Fp) = (
|
||||
field_new!(
|
||||
Fq,
|
||||
BigInteger([
|
||||
587330122779359758,
|
||||
14352661462510473462,
|
||||
17802452401246596498,
|
||||
18018663494943049411,
|
||||
17948754733747257098,
|
||||
10253180574146027531,
|
||||
6683223122694781837,
|
||||
13573468617269213174,
|
||||
5059368039312883748,
|
||||
950479668716233863,
|
||||
9936591501985804621,
|
||||
88719447132658
|
||||
])
|
||||
),
|
||||
FQ_ONE,
|
||||
);
|
||||
|
||||
// Coefficients:
|
||||
// [1, 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689600]
|
||||
// see https://github.com/o1-labs/snarky/blob/2cf5ef3a14989e57c17518832b3c52590068fc48/src/camlsnark_c/libsnark-caml/depends/libff/libff/algebra/curves/mnt753/mnt4753/mnt4753_init.cpp
|
||||
const FROBENIUS_COEFF_FP2_C1: &'static [Self::Fp] = &[
|
||||
FQ_ONE,
|
||||
field_new!(
|
||||
Fq,
|
||||
BigInteger([
|
||||
14260497802974073023,
|
||||
5895249896161266456,
|
||||
14682908860938702530,
|
||||
17222385991615618722,
|
||||
14621060510943733448,
|
||||
10594887362868996148,
|
||||
7477357615964975684,
|
||||
12570239403004322603,
|
||||
2180620924574446161,
|
||||
12129628062772479841,
|
||||
8853285699251153944,
|
||||
362282887012814
|
||||
])
|
||||
),
|
||||
];
|
||||
}
|
||||
68
mnt4_753/src/fields/fq4.rs
Normal file
68
mnt4_753/src/fields/fq4.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use crate::{Fq, Fq2, Fq2Parameters, FQ_ONE, FQ_ZERO};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger768 as BigInteger,
|
||||
field_new,
|
||||
fields::fp4::{Fp4, Fp4Parameters},
|
||||
};
|
||||
|
||||
pub type Fq4 = Fp4<Fq4Parameters>;
|
||||
|
||||
pub struct Fq4Parameters;
|
||||
|
||||
impl Fp4Parameters for Fq4Parameters {
|
||||
type Fp2Params = Fq2Parameters;
|
||||
|
||||
const NONRESIDUE: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ONE);
|
||||
|
||||
// Coefficients for the Frobenius automorphism.
|
||||
// c1[0] = 1,
|
||||
// c1[1] = 18691656569803771296244054523431852464958959799019013859007259692542121208304602539555350517075508287829753932558576476751900235650227380562700444433662761577027341858128610410779088384480737679672900770810745291515010467307990
|
||||
// c1[2] = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689600
|
||||
// c1[3] = 23206834398115182106100160267808784663211750120934935212776243228483231604266504233503543246714830633588317039329677309362453490879357004638891167538350364891904062489821230132228897943262725174047727280881395973788104254381611
|
||||
#[rustfmt::skip]
|
||||
const FROBENIUS_COEFF_FP4_C1: &'static [Fq] = &[
|
||||
FQ_ONE,
|
||||
field_new!(Fq, BigInteger([
|
||||
2732208433323581659,
|
||||
2172983777736624684,
|
||||
14351170316343013496,
|
||||
6345300643186282385,
|
||||
3197292113538174065,
|
||||
1887663496013421009,
|
||||
16627860175048929982,
|
||||
1842296636815120666,
|
||||
13463717484107308085,
|
||||
721000253033730237,
|
||||
1214767992212094798,
|
||||
163570781165682,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
14260497802974073023,
|
||||
5895249896161266456,
|
||||
14682908860938702530,
|
||||
17222385991615618722,
|
||||
14621060510943733448,
|
||||
10594887362868996148,
|
||||
7477357615964975684,
|
||||
12570239403004322603,
|
||||
2180620924574446161,
|
||||
12129628062772479841,
|
||||
8853285699251153944,
|
||||
362282887012814,
|
||||
])),
|
||||
field_new!(Fq, BigInteger([
|
||||
4081847608632041254,
|
||||
14228374352133326707,
|
||||
11267574244067947896,
|
||||
1174247187748832530,
|
||||
10065542319823237575,
|
||||
10873259071217986508,
|
||||
12902564573729719519,
|
||||
17180267336735511666,
|
||||
11808206507871910973,
|
||||
12535793096497356591,
|
||||
18394626215023595103,
|
||||
334259642706846,
|
||||
])),
|
||||
];
|
||||
}
|
||||
151
mnt4_753/src/fields/fr.rs
Normal file
151
mnt4_753/src/fields/fr.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger768 as BigInteger,
|
||||
fields::{FftParameters, Fp768, Fp768Parameters, FpParameters},
|
||||
};
|
||||
|
||||
pub type Fr = Fp768<FrParameters>;
|
||||
|
||||
pub struct FrParameters;
|
||||
|
||||
impl Fp768Parameters for FrParameters {}
|
||||
impl FftParameters for FrParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
const TWO_ADICITY: u32 = 30;
|
||||
|
||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
||||
0x307f66b297671883,
|
||||
0xd72a7f2b1e645f4e,
|
||||
0x67079daa9a902283,
|
||||
0xf33f7620a86c668b,
|
||||
0x8878570d66464c12,
|
||||
0xa557af5b524f522b,
|
||||
0x5fafa3f6ef19319d,
|
||||
0x1eb9e04110a65629,
|
||||
0x3f96feb3c639a0b0,
|
||||
0x4d4fe37df3ffd732,
|
||||
0xadc831bd55bcf3e9,
|
||||
0x1b9f32a8bd6ab,
|
||||
]);
|
||||
}
|
||||
impl FpParameters for FrParameters {
|
||||
/// MODULUS = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001
|
||||
const MODULUS: BigInteger = BigInteger([
|
||||
0xd90776e240000001,
|
||||
0x4ea099170fa13a4f,
|
||||
0xd6c381bc3f005797,
|
||||
0xb9dff97634993aa4,
|
||||
0x3eebca9429212636,
|
||||
0xb26c5c28c859a99b,
|
||||
0x99d124d9a15af79d,
|
||||
0x7fdb925e8a0ed8d,
|
||||
0x5eb7e8f96c97d873,
|
||||
0xb7f997505b8fafed,
|
||||
0x10229022eee2cdad,
|
||||
0x1c4c62d92c411,
|
||||
]);
|
||||
|
||||
const MODULUS_BITS: u32 = 753;
|
||||
|
||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
||||
|
||||
const REPR_SHAVE_BITS: u32 = 15;
|
||||
|
||||
const R: BigInteger = BigInteger([
|
||||
0xb99680147fff6f42,
|
||||
0x4eb16817b589cea8,
|
||||
0xa1ebd2d90c79e179,
|
||||
0xf725caec549c0da,
|
||||
0xab0c4ee6d3e6dad4,
|
||||
0x9fbca908de0ccb62,
|
||||
0x320c3bb713338498,
|
||||
0x598b4302d2f00a62,
|
||||
0x4074c9cbfd8ca621,
|
||||
0xfa47edb3865e88c,
|
||||
0x95455fb31ff9a195,
|
||||
0x7b479ec8e242,
|
||||
]);
|
||||
|
||||
const R2: BigInteger = BigInteger([
|
||||
0x3f9c69c7b7f4c8d1,
|
||||
0x70a50fa9ee48d127,
|
||||
0xcdbe6702009569cb,
|
||||
0x6bd8c6c6c49edc38,
|
||||
0x7955876cc35ee94e,
|
||||
0xc7285529be54a3f4,
|
||||
0xded52121ecec77cf,
|
||||
0x99be80f2ee12ee8e,
|
||||
0xc8a0ff01493bdcef,
|
||||
0xacc27988f3d9a316,
|
||||
0xd9e817a8fb44b3c9,
|
||||
0x5b58037e0e4,
|
||||
]);
|
||||
|
||||
const INV: u64 = 0xc90776e23fffffff;
|
||||
|
||||
const GENERATOR: BigInteger = BigInteger([
|
||||
0xeee0a5d37ff6635e,
|
||||
0xff458536cfa1cff4,
|
||||
0x659af978d8169ab0,
|
||||
0x1f1841c24780e3f1,
|
||||
0x602213036dcfef3a,
|
||||
0xd1d5c8f39d72db20,
|
||||
0xeb8b63c1c0ffefab,
|
||||
0xd2488e985f6cfa4e,
|
||||
0xcce1c2a623f7a66a,
|
||||
0x2a060f4d5085b19a,
|
||||
0xa9111a596408842f,
|
||||
0x11ca8d50bf627,
|
||||
]);
|
||||
|
||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0xec83bb7120000000,
|
||||
0xa7504c8b87d09d27,
|
||||
0x6b61c0de1f802bcb,
|
||||
0x5ceffcbb1a4c9d52,
|
||||
0x9f75e54a1490931b,
|
||||
0xd9362e14642cd4cd,
|
||||
0xcce8926cd0ad7bce,
|
||||
0x83fedc92f45076c6,
|
||||
0xaf5bf47cb64bec39,
|
||||
0xdbfccba82dc7d7f6,
|
||||
0x88114811777166d6,
|
||||
0xe26316c96208,
|
||||
]);
|
||||
|
||||
// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T
|
||||
|
||||
/// T = (MODULUS - 1) / 2^S =
|
||||
/// 39021010480745652133919498688765463538626870065884617224134041854204007249857398469987226430131438115069708760723898631821547688442835449306011425196003537779414482717728302293895201885929702287178426719326440397855625
|
||||
const T: BigInteger = BigInteger([
|
||||
0x3e84e93f641ddb89,
|
||||
0xfc015e5d3a82645c,
|
||||
0xd264ea935b0e06f0,
|
||||
0xa48498dae77fe5d8,
|
||||
0x2166a66cfbaf2a50,
|
||||
0x856bde76c9b170a3,
|
||||
0xa283b63667449366,
|
||||
0xb25f61cc1ff6e497,
|
||||
0x6e3ebfb57adfa3e5,
|
||||
0xbb8b36b6dfe65d41,
|
||||
0xb64b1044408a408b,
|
||||
0x71318,
|
||||
]);
|
||||
|
||||
/// (T - 1) / 2 =
|
||||
/// 19510505240372826066959749344382731769313435032942308612067020927102003624928699234993613215065719057534854380361949315910773844221417724653005712598001768889707241358864151146947600942964851143589213359663220198927812
|
||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0x1f42749fb20eedc4,
|
||||
0x7e00af2e9d41322e,
|
||||
0x69327549ad870378,
|
||||
0x52424c6d73bff2ec,
|
||||
0x90b353367dd79528,
|
||||
0x42b5ef3b64d8b851,
|
||||
0xd141db1b33a249b3,
|
||||
0xd92fb0e60ffb724b,
|
||||
0xb71f5fdabd6fd1f2,
|
||||
0xddc59b5b6ff32ea0,
|
||||
0x5b25882220452045,
|
||||
0x3898c,
|
||||
]);
|
||||
}
|
||||
22
mnt4_753/src/fields/mod.rs
Normal file
22
mnt4_753/src/fields/mod.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
#[cfg(feature = "scalar_field")]
|
||||
pub mod fr;
|
||||
#[cfg(feature = "scalar_field")]
|
||||
pub use self::fr::*;
|
||||
|
||||
#[cfg(feature = "base_field")]
|
||||
pub mod fq;
|
||||
#[cfg(feature = "base_field")]
|
||||
pub use self::fq::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq2;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq2::*;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub mod fq4;
|
||||
#[cfg(feature = "curve")]
|
||||
pub use self::fq4::*;
|
||||
|
||||
#[cfg(all(feature = "curve", test))]
|
||||
mod tests;
|
||||
45
mnt4_753/src/fields/tests.rs
Normal file
45
mnt4_753/src/fields/tests.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use ark_ff::{test_rng, Field};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::*;
|
||||
|
||||
use ark_curve_tests::fields::*;
|
||||
|
||||
#[test]
|
||||
fn test_fr() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fr = rng.gen();
|
||||
let b: Fr = rng.gen();
|
||||
field_test(a, b);
|
||||
sqrt_field_test(a);
|
||||
primefield_test::<Fr>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq = rng.gen();
|
||||
let b: Fq = rng.gen();
|
||||
field_test(a, b);
|
||||
sqrt_field_test(a);
|
||||
primefield_test::<Fq>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq2 = rng.gen();
|
||||
let b: Fq2 = rng.gen();
|
||||
field_test(a, b);
|
||||
sqrt_field_test(a);
|
||||
frobenius_test::<Fq2, _>(Fq::characteristic(), 13);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq4() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq4 = rng.gen();
|
||||
let b: Fq4 = rng.gen();
|
||||
field_test(a, b);
|
||||
frobenius_test::<Fq4, _>(Fq::characteristic(), 13);
|
||||
}
|
||||
38
mnt4_753/src/lib.rs
Normal file
38
mnt4_753/src/lib.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![deny(
|
||||
warnings,
|
||||
unused,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
rust_2018_idioms
|
||||
)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
//! This library implements the MNT4_753 curve generated in
|
||||
//! [[BCTV14]](https://eprint.iacr.org/2014/595). The name denotes that it is a
|
||||
//! Miyaji--Nakabayashi--Takano curve of embedding degree 4, defined over a 753-bit (prime) field.
|
||||
//! The main feature of this curve is that its scalar field and base field respectively equal the
|
||||
//! base field and scalar field of MNT6_753.
|
||||
//!
|
||||
//! Curve information:
|
||||
//! * Base field: q = 0x01C4C62D92C41110229022EEE2CDADB7F997505B8FAFED5EB7E8F96C97D87307FDB925E8A0ED8D99D124D9A15AF79DB117E776F218059DB80F0DA5CB537E38685ACCE9767254A4638810719AC425F0E39D54522CDD119F5E9063DE245E8001
|
||||
//! * Scalar field: r = 0x01C4C62D92C41110229022EEE2CDADB7F997505B8FAFED5EB7E8F96C97D87307FDB925E8A0ED8D99D124D9A15AF79DB26C5C28C859A99B3EEBCA9429212636B9DFF97634993AA4D6C381BC3F0057974EA099170FA13A4FD90776E240000001
|
||||
//! * valuation(q - 1, 2) = 15
|
||||
//! * valuation(r - 1, 2) = 30
|
||||
//! * G1 curve equation: y^2 = x^3 + ax + b, where
|
||||
//! * a = 2
|
||||
//! * b = 0x01373684A8C9DCAE7A016AC5D7748D3313CD8E39051C596560835DF0C9E50A5B59B882A92C78DC537E51A16703EC9855C77FC3D8BB21C8D68BB8CFB9DB4B8C8FBA773111C36C8B1B4E8F1ECE940EF9EAAD265458E06372009C9A0491678EF4
|
||||
//! * G2 curve equation: y^2 = x^3 + Ax + B, where
|
||||
//! * A = Fq2 = (a * NON_RESIDUE, 0)
|
||||
//! * B = Fq2(0, b * NON_RESIDUE)
|
||||
//! * NON_RESIDUE = 13 is the quadratic non-residue used to construct the extension field Fq2
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
mod curves;
|
||||
#[cfg(any(feature = "scalar_field", feature = "base_field"))]
|
||||
mod fields;
|
||||
|
||||
#[cfg(feature = "curve")]
|
||||
pub use curves::*;
|
||||
#[cfg(any(feature = "scalar_field", feature = "base_field"))]
|
||||
pub use fields::*;
|
||||
Reference in New Issue
Block a user