diff --git a/Cargo.toml b/Cargo.toml index 4a96390..69f4835 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,3 +63,4 @@ ark-ec = { git = "https://github.com/arkworks-rs/algebra" } ark-ff = { git = "https://github.com/arkworks-rs/algebra" } ark-serialize = { git = "https://github.com/arkworks-rs/algebra" } ark-algebra-test-templates = { git = "https://github.com/arkworks-rs/algebra" } +ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" } diff --git a/bls12_377/scripts/base_field.sage b/bls12_377/scripts/base_field.sage new file mode 100644 index 0000000..6d9f4a7 --- /dev/null +++ b/bls12_377/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/bls12_377/scripts/scalar_field.sage b/bls12_377/scripts/scalar_field.sage new file mode 100644 index 0000000..a4d06f0 --- /dev/null +++ b/bls12_377/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 8444461749428370424248824938781546531375899335154063827935233455917409239041 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 30): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/bls12_377/src/constraints/curves.rs b/bls12_377/src/constraints/curves.rs index b788831..f4c57d1 100644 --- a/bls12_377/src/constraints/curves.rs +++ b/bls12_377/src/constraints/curves.rs @@ -1,11 +1,11 @@ -use crate::Parameters; -use ark_ec::bls12::Bls12Parameters; -use ark_ec::ModelParameters; +use ark_ec::{bls12::Bls12Parameters, ModelParameters}; use ark_r1cs_std::{ fields::fp::FpVar, groups::{bls12, curves::twisted_edwards::AffineVar as TEAffineVar}, }; +use crate::Parameters; + /// An element of G1 in the BLS12-377 bilinear group. pub type G1Var = bls12::G1Var; /// An element of G2 in the BLS12-377 bilinear group. diff --git a/bls12_377/src/constraints/fields.rs b/bls12_377/src/constraints/fields.rs index 7a626e6..b3d883c 100644 --- a/bls12_377/src/constraints/fields.rs +++ b/bls12_377/src/constraints/fields.rs @@ -1,16 +1,16 @@ -use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters}; - use ark_r1cs_std::fields::{fp::FpVar, fp12::Fp12Var, fp2::Fp2Var, fp6_3over2::Fp6Var}; +use crate::{Fq, Fq12Config, Fq2Config, Fq6Config}; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FqVar = FpVar; /// A variable that is the R1CS equivalent of `crate::Fq2`. -pub type Fq2Var = Fp2Var; +pub type Fq2Var = Fp2Var; /// A variable that is the R1CS equivalent of `crate::Fq6`. -pub type Fq6Var = Fp6Var; +pub type Fq6Var = Fp6Var; /// A variable that is the R1CS equivalent of `crate::Fq12`. -pub type Fq12Var = Fp12Var; +pub type Fq12Var = Fp12Var; #[test] fn bls12_377_field_test() { diff --git a/bls12_377/src/constraints/pairing.rs b/bls12_377/src/constraints/pairing.rs index f659f29..cb4fed3 100644 --- a/bls12_377/src/constraints/pairing.rs +++ b/bls12_377/src/constraints/pairing.rs @@ -1,6 +1,7 @@ use crate::Parameters; -/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear group. +/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear +/// group. pub type PairingVar = ark_r1cs_std::pairing::bls12::PairingVar; #[test] diff --git a/bls12_377/src/curves/g1.rs b/bls12_377/src/curves/g1.rs index 7ed2171..de2f5c9 100644 --- a/bls12_377/src/curves/g1.rs +++ b/bls12_377/src/curves/g1.rs @@ -4,7 +4,7 @@ use ark_ec::models::{ }, ModelParameters, MontgomeryModelParameters, SWModelParameters, TEModelParameters, }; -use ark_ff::{field_new, Zero}; +use ark_ff::{MontFp, Zero}; use core::ops::Neg; use crate::{ @@ -24,8 +24,10 @@ impl ModelParameters for Parameters { /// COFACTOR_INV = COFACTOR^{-1} mod r /// = 5285428838741532253824584287042945485047145357130994810877 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "5285428838741532253824584287042945485047145357130994810877"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "5285428838741532253824584287042945485047145357130994810877" + ); } impl SWModelParameters for Parameters { @@ -33,7 +35,6 @@ impl SWModelParameters for Parameters { const COEFF_A: Fq = FQ_ZERO; /// COEFF_B = 1 - #[rustfmt::skip] const COEFF_B: Fq = FQ_ONE; /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) @@ -54,7 +55,6 @@ pub type G1TEProjective = TEGroupProjective; /// 1. SW -> Montgomery -> TE1 transformation: /// 2. TE1 -> TE2 normalization (enforcing `a = -1`) /// ``` sage -/// /// # modulus /// p = 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001 /// Fp = Zmod(p) @@ -96,15 +96,13 @@ pub type G1TEProjective = TEGroupProjective; /// TE2a = Fp(-1) /// # b = -TE1d/TE1a /// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179) -/// /// ``` impl TEModelParameters for Parameters { /// COEFF_A = -1 - const COEFF_A: Fq = field_new!(Fq, "-1"); + const COEFF_A: Fq = MontFp!(Fq, "-1"); /// COEFF_D = 122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179 mod q - #[rustfmt::skip] - const COEFF_D: Fq = field_new!(Fq, "122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179"); + const COEFF_D: Fq = MontFp!(Fq, "122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179"); /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -124,7 +122,6 @@ impl TEModelParameters for Parameters { // It can be obtained via the following script, implementing // SW -> Montgomery transformation: // ``` sage -// // # modulus // p=0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001 // Fp=Zmod(p) @@ -151,28 +148,25 @@ impl TEModelParameters for Parameters { // ``` impl MontgomeryModelParameters for Parameters { /// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384"); + const COEFF_A: Fq = MontFp!(Fq, "228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384"); /// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931"); + const COEFF_B: Fq = MontFp!(Fq, "10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931"); type TEModelParameters = Parameters; } /// G1_GENERATOR_X = /// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695 -#[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = field_new!(Fq, "81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695"); +pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695"); /// G1_GENERATOR_Y = /// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030 -#[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030"); +pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030"); -// The generator for twisted Edward form is the same SW generator converted into the normalized TE form (TE2). -// ``` sage +// The generator for twisted Edward form is the same SW generator converted into +// the normalized TE form (TE2). +//``` sage // # following scripts in previous section // ##################################################### // # Weierstrass curve generator @@ -216,10 +210,8 @@ pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "241266749859715473739788878240585 // ``` /// TE_GENERATOR_X = /// 71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393 -#[rustfmt::skip] -pub const TE_GENERATOR_X: Fq = field_new!(Fq, "71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393"); +pub const TE_GENERATOR_X: Fq = MontFp!(Fq, "71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393"); /// TE_GENERATOR_Y = /// 6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235 -#[rustfmt::skip] -pub const TE_GENERATOR_Y: Fq = field_new!(Fq, "6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235"); +pub const TE_GENERATOR_Y: Fq = MontFp!(Fq, "6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235"); diff --git a/bls12_377/src/curves/g2.rs b/bls12_377/src/curves/g2.rs index 6e7c0d7..84ecd2b 100644 --- a/bls12_377/src/curves/g2.rs +++ b/bls12_377/src/curves/g2.rs @@ -1,5 +1,5 @@ use ark_ec::models::{ModelParameters, SWModelParameters}; -use ark_ff::{field_new, Zero}; +use ark_ff::{MontFp, QuadExt, Zero}; use crate::{fields::FQ_ZERO, g1, Fq, Fq2, Fr}; @@ -26,17 +26,15 @@ impl ModelParameters for Parameters { /// COFACTOR_INV = COFACTOR^{-1} mod r /// = 6764900296503390671038341982857278410319949526107311149686707033187604810669 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "6764900296503390671038341982857278410319949526107311149686707033187604810669"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "6764900296503390671038341982857278410319949526107311149686707033187604810669" + ); } impl SWModelParameters for Parameters { /// COEFF_A = [0, 0] - #[rustfmt::skip] - const COEFF_A: Fq2 = field_new!(Fq2, - g1::Parameters::COEFF_A, - g1::Parameters::COEFF_A, - ); + const COEFF_A: Fq2 = QuadExt!(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,); // As per https://eprint.iacr.org/2012/072.pdf, // this curve has b' = b/i, where b is the COEFF_B of G1, and x^6 -i is @@ -44,10 +42,9 @@ impl SWModelParameters for Parameters { // In our case, i = u (App A.3, T_6). /// COEFF_B = [0, /// 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906] - #[rustfmt::skip] - const COEFF_B: Fq2 = field_new!(Fq2, + const COEFF_B: Fq2 = QuadExt!( FQ_ZERO, - field_new!(Fq, "155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906"), + MontFp!(Fq, "155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906"), ); /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) @@ -60,27 +57,21 @@ impl SWModelParameters for Parameters { } } -#[rustfmt::skip] -pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); -#[rustfmt::skip] -pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1); +pub const G2_GENERATOR_X: Fq2 = QuadExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); +pub const G2_GENERATOR_Y: Fq2 = QuadExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1); /// G2_GENERATOR_X_C0 = /// 233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294 -#[rustfmt::skip] -pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294"); +pub const G2_GENERATOR_X_C0: Fq = MontFp!(Fq, "233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294"); /// G2_GENERATOR_X_C1 = /// 140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118 -#[rustfmt::skip] -pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118"); +pub const G2_GENERATOR_X_C1: Fq = MontFp!(Fq, "140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118"); /// G2_GENERATOR_Y_C0 = /// 63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423 -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423"); +pub const G2_GENERATOR_Y_C0: Fq = MontFp!(Fq, "63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423"); /// G2_GENERATOR_Y_C1 = /// 149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491 -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491"); +pub const G2_GENERATOR_Y_C1: Fq = MontFp!(Fq, "149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491"); diff --git a/bls12_377/src/curves/mod.rs b/bls12_377/src/curves/mod.rs index babdb32..6173f1d 100644 --- a/bls12_377/src/curves/mod.rs +++ b/bls12_377/src/curves/mod.rs @@ -1,9 +1,10 @@ -use crate::*; use ark_ec::{ bls12, bls12::{Bls12, Bls12Parameters, TwistType}, }; +use crate::*; + pub mod g1; pub mod g2; @@ -18,9 +19,9 @@ impl Bls12Parameters for Parameters { const X_IS_NEGATIVE: bool = false; const TWIST_TYPE: TwistType = TwistType::D; type Fp = Fq; - type Fp2Params = Fq2Parameters; - type Fp6Params = Fq6Parameters; - type Fp12Params = Fq12Parameters; + type Fp2Config = Fq2Config; + type Fp6Config = Fq6Config; + type Fp12Config = Fq12Config; type G1Parameters = g1::Parameters; type G2Parameters = g2::Parameters; } diff --git a/bls12_377/src/curves/tests.rs b/bls12_377/src/curves/tests.rs old mode 100644 new mode 100755 index be6cc60..89244c3 --- a/bls12_377/src/curves/tests.rs +++ b/bls12_377/src/curves/tests.rs @@ -1,25 +1,19 @@ -#![allow(unused_imports)] -use crate::{ - g1, g2, Bls12_377, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G1TEProjective, G2Affine, - G2Projective, -}; -use ark_ec::{ - models::SWModelParameters, short_weierstrass_jacobian, AffineCurve, PairingEngine, - ProjectiveCurve, +use ark_algebra_test_templates::{ + curves::{curve_tests, edwards_tests, sw_tests}, + generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test, generate_g2_test, + groups::group_test, + msm::test_var_base_msm, }; +use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine}; use ark_ff::{ - fields::{Field, FpParameters, PrimeField, SquareRootField}, + fields::{Field, PrimeField, SquareRootField}, One, Zero, }; -use ark_serialize::CanonicalSerialize; use ark_std::{rand::Rng, test_rng}; use core::ops::{AddAssign, MulAssign}; -use ark_algebra_test_templates::{ - curves::{curve_tests, edwards_tests, sw_tests}, - generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test, generate_g2_test, - groups::group_test, - msm::test_var_base_msm, +use crate::{ + g1, g2, Bls12_377, Fq, Fq12, Fr, G1Affine, G1Projective, G1TEProjective, G2Affine, G2Projective, }; generate_g1_test!(bls12_377; curve_tests; sw_tests; edwards_tests; te_group_tests;); diff --git a/bls12_377/src/fields/fq.rs b/bls12_377/src/fields/fq.rs index de41a4b..6128f8b 100644 --- a/bls12_377/src/fields/fq.rs +++ b/bls12_377/src/fields/fq.rs @@ -1,121 +1,10 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger384 as BigInteger}, - fields::*, -}; +use ark_ff::fields::{Fp384, MontBackend, MontConfig, MontFp}; -pub type Fq = Fp384; +#[derive(MontConfig)] +#[modulus = "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177"] +#[generator = "15"] +pub struct FqConfig; +pub type Fq = Fp384>; -pub struct FqParameters; - -impl Fp384Parameters for FqParameters {} -impl FftParameters for FqParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 46u32; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 2022196864061697551u64, - 17419102863309525423u64, - 8564289679875062096u64, - 17152078065055548215u64, - 17966377291017729567u64, - 68610905582439508u64, - ]); -} -impl FpParameters for FqParameters { - /// MODULUS = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0x8508c00000000001, - 0x170b5d4430000000, - 0x1ef3622fba094800, - 0x1a22d9f300f5138f, - 0xc63b05c06ca1493b, - 0x1ae3a4617c510ea, - ]); - - const MODULUS_BITS: u32 = 377; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 7; - - /// R = 85013442423176922659824578519796707547925331718418265885885478904210582549405549618995257669764901891699128663912 - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 202099033278250856u64, - 5854854902718660529u64, - 11492539364873682930u64, - 8885205928937022213u64, - 5545221690922665192u64, - 39800542322357402u64, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 0xb786686c9400cd22, - 0x329fcaab00431b1, - 0x22a5f11162d6b46d, - 0xbfdf7d03827dc3ac, - 0x837e92f041790bf9, - 0x6dfccb1e914b88, - ]); - - const INV: u64 = 9586122913090633727u64; - - /// GENERATOR = -5 - /// Encoded in Montgomery form, so the value here is - /// (-5 * R) % q = 92261639910053574722182574790803529333160366917737991650341130812388023949653897454961487930322210790384999596794 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 0xfc0b8000000002fa, - 0x97d39cf6e000018b, - 0x2072420fbfa05044, - 0xcbbcbd50d97c3802, - 0xbaf1ec35813f9eb, - 0x9974a2c0945ad2, - ]); - - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x4284600000000000, - 0xb85aea218000000, - 0x8f79b117dd04a400, - 0x8d116cf9807a89c7, - 0x631d82e03650a49d, - 0xd71d230be28875, - ]); - - // T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T - // For T coprime to 2 - - // T = (MODULUS - 1) // 2^S = - // 3675842578061421676390135839012792950148785745837396071634149488243117337281387659330802195819009059 - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0x7510c00000021423, - 0x88bee82520005c2d, - 0x67cc03d44e3c7bcd, - 0x1701b28524ec688b, - 0xe9185f1443ab18ec, - 0x6b8, - ]); - - // (T - 1) // 2 = - // 1837921289030710838195067919506396475074392872918698035817074744121558668640693829665401097909504529 - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xba88600000010a11, - 0xc45f741290002e16, - 0xb3e601ea271e3de6, - 0xb80d94292763445, - 0x748c2f8a21d58c76, - 0x35c, - ]); -} - -#[allow(dead_code)] -pub const FQ_ONE: Fq = Fq::new(FqParameters::R); -#[allow(dead_code)] -pub const FQ_ZERO: Fq = Fq::new(BigInt::new([0, 0, 0, 0, 0, 0])); +pub const FQ_ONE: Fq = Fq::new(FqConfig::R); +pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); diff --git a/bls12_377/src/fields/fq12.rs b/bls12_377/src/fields/fq12.rs index 20ea206..b81f84d 100644 --- a/bls12_377/src/fields/fq12.rs +++ b/bls12_377/src/fields/fq12.rs @@ -1,73 +1,73 @@ -use super::*; -use ark_ff::{field_new, fields::*}; +use ark_ff::{fields::*, CubicExt, MontFp, QuadExt}; -pub type Fq12 = Fp12; +use crate::*; + +pub type Fq12 = Fp12; #[derive(Clone, Copy)] -pub struct Fq12Parameters; +pub struct Fq12Config; -impl Fp12Parameters for Fq12Parameters { - type Fp6Params = Fq6Parameters; +impl Fp12Config for Fq12Config { + type Fp6Config = Fq6Config; - const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO); + const NONRESIDUE: Fq6 = CubicExt!(FQ2_ZERO, FQ2_ONE, FQ2_ZERO); - #[rustfmt::skip] const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[ // Fp2::NONRESIDUE^(((q^0) - 1) / 6) - field_new!(Fq2, FQ_ONE, FQ_ZERO), + QuadExt!(FQ_ONE, FQ_ZERO), // Fp2::NONRESIDUE^(((q^1) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353"), + QuadExt!( + MontFp!(Fq, "92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^2) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"), + QuadExt!( + MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^3) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499"), + QuadExt!( + MontFp!(Fq, "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^4) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"), + QuadExt!( + MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^5) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146"), + QuadExt!( + MontFp!(Fq, "123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^6) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "-1"), + QuadExt!( + MontFp!(Fq, "-1"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^7) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "165715080792691229252027773188420350858440463845631411558924158284924566418821255823372982649037525009328560463824"), + QuadExt!( + MontFp!(Fq, "165715080792691229252027773188420350858440463845631411558924158284924566418821255823372982649037525009328560463824"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^8) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"), + QuadExt!( + MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^9) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678"), + QuadExt!( + MontFp!(Fq, "42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^10) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"), + QuadExt!( + MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^11) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "135148009893022339379906188398761468584194992116912126664040619889416147222474808140862391813728516072597320238031"), + QuadExt!( + MontFp!(Fq, "135148009893022339379906188398761468584194992116912126664040619889416147222474808140862391813728516072597320238031"), FQ_ZERO, ), ]; diff --git a/bls12_377/src/fields/fq2.rs b/bls12_377/src/fields/fq2.rs index 75f09ed..fe059c8 100644 --- a/bls12_377/src/fields/fq2.rs +++ b/bls12_377/src/fields/fq2.rs @@ -1,28 +1,26 @@ -use super::*; -use ark_ff::{field_new, fields::*}; +use ark_ff::{fields::*, MontFp, QuadExt}; -pub type Fq2 = Fp2; +use crate::*; -pub struct Fq2Parameters; +pub type Fq2 = Fp2; -impl Fp2Parameters for Fq2Parameters { +pub struct Fq2Config; + +impl Fp2Config for Fq2Config { type Fp = Fq; /// NONRESIDUE = -5 - #[rustfmt::skip] - const NONRESIDUE: Fq = field_new!(Fq, "-5"); + const NONRESIDUE: Fq = MontFp!(Fq, "-5"); /// QUADRATIC_NONRESIDUE = U - #[rustfmt::skip] - const QUADRATIC_NONRESIDUE: (Fq, Fq) = (FQ_ZERO, FQ_ONE); + const QUADRATIC_NONRESIDUE: Fq2 = QuadExt!(FQ_ZERO, FQ_ONE); /// Coefficients for the Frobenius automorphism. - #[rustfmt::skip] const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[ // NONRESIDUE**(((q^0) - 1) / 2) FQ_ONE, // NONRESIDUE**(((q^1) - 1) / 2) - field_new!(Fq, "-1"), + MontFp!(Fq, "-1"), ]; #[inline(always)] @@ -34,5 +32,5 @@ impl Fp2Parameters for Fq2Parameters { } } -pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO); -pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO); +pub const FQ2_ZERO: Fq2 = QuadExt!(FQ_ZERO, FQ_ZERO); +pub const FQ2_ONE: Fq2 = QuadExt!(FQ_ONE, FQ_ZERO); diff --git a/bls12_377/src/fields/fq6.rs b/bls12_377/src/fields/fq6.rs index 83a9ead..9b4454d 100644 --- a/bls12_377/src/fields/fq6.rs +++ b/bls12_377/src/fields/fq6.rs @@ -1,69 +1,68 @@ -use super::*; -use ark_ff::{field_new, fields::*}; +use ark_ff::{fields::*, MontFp, QuadExt}; -pub type Fq6 = Fp6; +use crate::*; + +pub type Fq6 = Fp6; #[derive(Clone, Copy)] -pub struct Fq6Parameters; +pub struct Fq6Config; -impl Fp6Parameters for Fq6Parameters { - type Fp2Params = Fq2Parameters; +impl Fp6Config for Fq6Config { + type Fp2Config = Fq2Config; /// NONRESIDUE = U - #[rustfmt::skip] - const NONRESIDUE: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ONE); + const NONRESIDUE: Fq2 = QuadExt!(FQ_ZERO, FQ_ONE); - #[rustfmt::skip] const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[ // Fp2::NONRESIDUE^(((q^0) - 1) / 3) - field_new!(Fq2, FQ_ONE, FQ_ZERO), + QuadExt!(FQ_ONE, FQ_ZERO), // Fp2::NONRESIDUE^(((q^1) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"), + QuadExt!( + MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^2) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"), + QuadExt!( + MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^3) - 1) / 3) - field_new!(Fq2, field_new!(Fq, "-1"), FQ_ZERO), + QuadExt!(MontFp!(Fq, "-1"), FQ_ZERO), // Fp2::NONRESIDUE^(((q^4) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"), + QuadExt!( + MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"), FQ_ZERO, ), // Fp2::NONRESIDUE^(((q^5) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"), + QuadExt!( + MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232"), FQ_ZERO, ), ]; - #[rustfmt::skip] + const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[ // Fp2::NONRESIDUE^((2*(q^0) - 2) / 3) - field_new!(Fq2, FQ_ONE, FQ_ZERO), + QuadExt!(FQ_ONE, FQ_ZERO), // Fp2::NONRESIDUE^((2*(q^1) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"), + QuadExt!( + MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"), FQ_ZERO ), // Fp2::NONRESIDUE^((2*(q^2) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"), + QuadExt!( + MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"), FQ_ZERO, ), // Fp2::NONRESIDUE^((2*(q^3) - 2) / 3) - field_new!(Fq2, FQ_ONE, FQ_ZERO), + QuadExt!(FQ_ONE, FQ_ZERO), // Fp2::NONRESIDUE^((2*(q^4) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"), + QuadExt!( + MontFp!(Fq, "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945"), FQ_ZERO, ), // Fp2::NONRESIDUE^((2*(q^5) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"), + QuadExt!( + MontFp!(Fq, "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"), FQ_ZERO, ), ]; @@ -71,8 +70,8 @@ impl Fp6Parameters for Fq6Parameters { #[inline(always)] fn mul_fp2_by_nonresidue(fe: &Fq2) -> Fq2 { // Karatsuba multiplication with constant other = u. - let c0 = Fq2Parameters::mul_fp_by_nonresidue(&fe.c1); + let c0 = Fq2Config::mul_fp_by_nonresidue(&fe.c1); let c1 = fe.c0; - field_new!(Fq2, c0, c1) + QuadExt!(c0, c1) } } diff --git a/bls12_377/src/fields/fr.rs b/bls12_377/src/fields/fr.rs index 1d5b761..7fb498c 100644 --- a/bls12_377/src/fields/fr.rs +++ b/bls12_377/src/fields/fr.rs @@ -1,5 +1,4 @@ //! Bls12-377 scalar field. -/// /// Roots of unity computed from modulus and R using this sage code: /// /// ```ignore @@ -19,105 +18,10 @@ /// print("Gen: ", into_chunks(g * R % q, 64, 4)) /// print("2-adic gen: ", into_chunks(g2 * R % q, 64, 4)) /// ``` -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - fields::*, -}; -pub type Fr = Fp256; - -pub struct FrParameters; - -impl Fp256Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 47; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 12646347781564978760u64, - 6783048705277173164u64, - 268534165941069093u64, - 1121515446318641358u64, - ]); -} -impl FpParameters for FrParameters { - /// MODULUS = 8444461749428370424248824938781546531375899335154063827935233455917409239041 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 725501752471715841u64, - 6461107452199829505u64, - 6968279316240510977u64, - 1345280370688173398u64, - ]); - - const MODULUS_BITS: u32 = 253; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 3; - - /// R = 6014086494747379908336260804527802945383293308637734276299549080986809532403 - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 9015221291577245683u64, - 8239323489949974514u64, - 1646089257421115374u64, - 958099254763297437u64, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 2726216793283724667u64, - 14712177743343147295u64, - 12091039717619697043u64, - 81024008013859129u64, - ]); - - const INV: u64 = 725501752471715839u64; - - /// GENERATOR = 22 - /// Encoded in Montgomery form, so the value is - /// (22 * R) % q = - /// 5642976643016801619665363617888466827793962762719196659561577942948671127251 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 2984901390528151251u64, - 10561528701063790279u64, - 5476750214495080041u64, - 898978044469942640u64, - ]); - - /// (r - 1)/2 = - /// 4222230874714185212124412469390773265687949667577031913967616727958704619520 - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x8508c00000000000, - 0xacd53b7f68000000, - 0x305a268f2e1bd800, - 0x955b2af4d1652ab, - ]); - - // T and T_MINUS_ONE_DIV_TWO, where r - 1 = 2^s * t - // For T coprime to 2 - - /// t = (r - 1) / 2^s = - /// 60001509534603559531609739528203892656505753216962260608619555 - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0xedfda00000021423, - 0x9a3cb86f6002b354, - 0xcabd34594aacc168, - 0x2556, - ]); +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; - /// (t - 1) / 2 = - /// 30000754767301779765804869764101946328252876608481130304309777 - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x76fed00000010a11, - 0x4d1e5c37b00159aa, - 0x655e9a2ca55660b4, - 0x12ab, - ]); -} +#[derive(MontConfig)] +#[modulus = "8444461749428370424248824938781546531375899335154063827935233455917409239041"] +#[generator = "22"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/bls12_377/src/fields/tests.rs b/bls12_377/src/fields/tests.rs index 56f1cd9..e2a8df7 100644 --- a/bls12_377/src/fields/tests.rs +++ b/bls12_377/src/fields/tests.rs @@ -1,9 +1,9 @@ +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{ biginteger::{BigInt, BigInteger, BigInteger384}, - fields::{ - fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, Fp2Parameters, FpParameters, - PrimeField, SquareRootField, - }, + fields::{FftField, Field, Fp2Config, Fp6Config, PrimeField, SquareRootField}, One, UniformRand, Zero, }; use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; @@ -13,13 +13,9 @@ use core::{ ops::{AddAssign, MulAssign, SubAssign}, }; -use crate::{Fq, Fq12, Fq2, Fq2Parameters, Fq6, Fq6Parameters, FqParameters, Fr}; - -use ark_algebra_test_templates::{ - fields::*, generate_field_serialization_test, generate_field_test, -}; +use crate::{Fq, Fq12, Fq2, Fq2Config, Fq6, Fq6Config, FqConfig, Fr, FrConfig}; -generate_field_test!(bls12_377; fq2; fq6; fq12;); +generate_field_test!(bls12_377; fq2; fq6; fq12; mont(6, 4); ); generate_field_serialization_test!(bls12_377; fq2; fq6; fq12;); #[test] @@ -29,14 +25,14 @@ fn test_fq_repr_from() { #[test] fn test_fq_repr_is_odd() { - assert!(!BigInteger384::from(0).is_odd()); - assert!(BigInteger384::from(0).is_even()); - assert!(BigInteger384::from(1).is_odd()); - assert!(!BigInteger384::from(1).is_even()); - assert!(!BigInteger384::from(324834872).is_odd()); - assert!(BigInteger384::from(324834872).is_even()); - assert!(BigInteger384::from(324834873).is_odd()); - assert!(!BigInteger384::from(324834873).is_even()); + assert!(!BigInteger384::from(0u64).is_odd()); + assert!(BigInteger384::from(0u64).is_even()); + assert!(BigInteger384::from(1u64).is_odd()); + assert!(!BigInteger384::from(1u64).is_even()); + assert!(!BigInteger384::from(324834872u64).is_odd()); + assert!(BigInteger384::from(324834872u64).is_even()); + assert!(BigInteger384::from(324834873u64).is_odd()); + assert!(!BigInteger384::from(324834873u64).is_even()); } #[test] @@ -48,9 +44,9 @@ fn test_fq_repr_is_zero() { #[test] fn test_fq_repr_num_bits() { - let mut a = BigInteger384::from(0); + let mut a = BigInteger384::from(0u64); assert_eq!(0, a.num_bits()); - a = BigInteger384::from(1); + a = BigInteger384::from(1u64); for i in 1..385 { assert_eq!(i, a.num_bits()); a.mul2(); @@ -60,15 +56,14 @@ fn test_fq_repr_num_bits() { #[test] fn test_fq_num_bits() { - assert_eq!(FqParameters::MODULUS_BITS, 377); - assert_eq!(FqParameters::CAPACITY, 376); + assert_eq!(Fq::MODULUS_BIT_SIZE, 377); } #[test] fn test_fq_root_of_unity() { - assert_eq!(FqParameters::TWO_ADICITY, 46); + assert_eq!(Fq::TWO_ADICITY, 46); assert_eq!( - Fq::multiplicative_generator().pow([ + Fq::GENERATOR.pow([ 0x7510c00000021423, 0x88bee82520005c2d, 0x67cc03d44e3c7bcd, @@ -76,20 +71,20 @@ fn test_fq_root_of_unity() { 0xe9185f1443ab18ec, 0x6b8 ]), - Fq::two_adic_root_of_unity() + Fq::TWO_ADIC_ROOT_OF_UNITY ); assert_eq!( - Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]), + Fq::TWO_ADIC_ROOT_OF_UNITY.pow([1 << Fq::TWO_ADICITY]), Fq::one() ); - assert!(Fq::multiplicative_generator().sqrt().is_none()); + assert!(Fq::GENERATOR.sqrt().is_none()); } #[test] fn test_fq_ordering() { // BigInteger384's ordering is well-tested, but we still need to make sure the // Fq elements aren't being compared in Montgomery form. - for i in 0..100 { + for i in 0..100u64 { assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i))); } } @@ -102,11 +97,11 @@ fn test_fq_legendre() { assert_eq!(Zero, Fq::zero().legendre()); assert_eq!( QuadraticResidue, - Fq::from(BigInteger384::from(4)).legendre() + Fq::from(BigInteger384::from(4u64)).legendre() ); assert_eq!( QuadraticNonResidue, - Fq::from(BigInteger384::from(5)).legendre() + Fq::from(BigInteger384::from(5u64)).legendre() ); } @@ -147,7 +142,7 @@ fn test_fq2_legendre() { // i^2 = -1 let mut m1 = -Fq2::one(); assert_eq!(QuadraticResidue, m1.legendre()); - m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1); + m1 = Fq6Config::mul_fp2_by_nonresidue(&m1); assert_eq!(QuadraticNonResidue, m1.legendre()); } @@ -158,8 +153,8 @@ fn test_fq2_mul_nonresidue() { let nqr = Fq2::new(Fq::zero(), Fq::one()); let quadratic_non_residue = Fq2::new( - Fq2Parameters::QUADRATIC_NONRESIDUE.0, - Fq2Parameters::QUADRATIC_NONRESIDUE.1, + Fq2Config::QUADRATIC_NONRESIDUE.c0, + Fq2Config::QUADRATIC_NONRESIDUE.c1, ); for _ in 0..1000 { let mut a = Fq2::rand(&mut rng); diff --git a/bls12_377/src/lib.rs b/bls12_377/src/lib.rs old mode 100644 new mode 100755 index 2659771..207e08d --- a/bls12_377/src/lib.rs +++ b/bls12_377/src/lib.rs @@ -9,15 +9,17 @@ #![forbid(unsafe_code)] //! This library implements the BLS12_377 curve generated in [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). -//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12, -//! defined over a 377-bit (prime) field. The main feature of this curve is that -//! both the scalar field and the base field are highly 2-adic. -//! (This is in contrast to the BLS12_381 curve for which only the scalar field is highly 2-adic.) +//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree +//! 12, defined over a 377-bit (prime) field. The main feature of this curve is +//! that both the scalar field and the base field are highly 2-adic. +//! (This is in contrast to the BLS12_381 curve for which only the scalar field +//! is highly 2-adic.) //! //! //! Curve information: //! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 -//! * Scalar field: r = 8444461749428370424248824938781546531375899335154063827935233455917409239041 +//! * Scalar field: r = +//! 8444461749428370424248824938781546531375899335154063827935233455917409239041 //! * valuation(q - 1, 2) = 46 //! * valuation(r - 1, 2) = 47 //! * G1 curve equation: y^2 = x^3 + 1 diff --git a/bls12_381/scripts/base_field.sage b/bls12_381/scripts/base_field.sage new file mode 100644 index 0000000..c714b9a --- /dev/null +++ b/bls12_381/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/bls12_381/scripts/scalar_field.sage b/bls12_381/scripts/scalar_field.sage new file mode 100644 index 0000000..fb96ea8 --- /dev/null +++ b/bls12_381/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 52435875175126190479447740508185965837690552500527637822603658699938581184513 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/bls12_381/src/curves/g1.rs b/bls12_381/src/curves/g1.rs index 2b7795c..b6adc9d 100644 --- a/bls12_381/src/curves/g1.rs +++ b/bls12_381/src/curves/g1.rs @@ -1,4 +1,3 @@ -use crate::*; use ark_ec::{ bls12, bls12::Bls12Parameters, @@ -6,9 +5,11 @@ use ark_ec::{ short_weierstrass_jacobian::GroupAffine, AffineCurve, ProjectiveCurve, }; -use ark_ff::{biginteger::BigInteger256, field_new, Zero}; +use ark_ff::{biginteger::BigInteger256, MontFp, Zero}; use ark_std::ops::Neg; +use crate::*; + pub type G1Affine = bls12::G1Affine; pub type G1Projective = bls12::G1Projective; @@ -24,17 +25,18 @@ impl ModelParameters for Parameters { /// COFACTOR_INV = COFACTOR^{-1} mod r /// = 52435875175126190458656871551744051925719901746859129887267498875565241663483 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "52435875175126190458656871551744051925719901746859129887267498875565241663483"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "52435875175126190458656871551744051925719901746859129887267498875565241663483" + ); } impl SWModelParameters for Parameters { /// COEFF_A = 0 - const COEFF_A: Fq = field_new!(Fq, "0"); + const COEFF_A: Fq = MontFp!(Fq, "0"); /// COEFF_B = 4 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "4"); + const COEFF_B: Fq = MontFp!(Fq, "4"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -54,7 +56,8 @@ impl SWModelParameters for Parameters { let x = BigInteger256::new([crate::Parameters::X[0], 0, 0, 0]); // An early-out optimization described in Section 6. - // If uP == P but P != point of infinity, then the point is not in the right subgroup. + // If uP == P but P != point of infinity, then the point is not in the right + // subgroup. let x_times_p = p.mul(x); if x_times_p.eq(p) && !p.infinity { return false; @@ -68,20 +71,19 @@ impl SWModelParameters for Parameters { /// G1_GENERATOR_X = /// 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 -#[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = field_new!(Fq, "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507"); +pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507"); /// G1_GENERATOR_Y = /// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569 -#[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569"); +pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569"); /// BETA is a non-trivial cubic root of unity in Fq. -pub const BETA: Fq = field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"); +pub const BETA: Fq = MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"); pub fn endomorphism(p: &GroupAffine) -> GroupAffine { // Endomorphism of the points on the curve. - // endomorphism_p(x,y) = (BETA * x, y) where BETA is a non-trivial cubic root of unity in Fq. + // endomorphism_p(x,y) = (BETA * x, y) + // where BETA is a non-trivial cubic root of unity in Fq. let mut res = (*p).clone(); res.x *= BETA; res diff --git a/bls12_381/src/curves/g2.rs b/bls12_381/src/curves/g2.rs index 971f376..485fcfe 100644 --- a/bls12_381/src/curves/g2.rs +++ b/bls12_381/src/curves/g2.rs @@ -1,12 +1,13 @@ -use crate::*; -use ark_ec::bls12::Bls12Parameters; use ark_ec::{ bls12, + bls12::Bls12Parameters, models::{ModelParameters, SWModelParameters}, short_weierstrass_jacobian::GroupAffine, AffineCurve, }; -use ark_ff::{field_new, BigInt, Field, Zero}; +use ark_ff::{BigInt, Field, MontFp, QuadExt, Zero}; + +use crate::*; pub type G2Affine = bls12::G2Affine; pub type G2Projective = bls12::G2Projective; @@ -35,16 +36,18 @@ impl ModelParameters for Parameters { /// COFACTOR_INV = COFACTOR^{-1} mod r /// 26652489039290660355457965112010883481355318854675681319708643586776743290055 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "26652489039290660355457965112010883481355318854675681319708643586776743290055"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "26652489039290660355457965112010883481355318854675681319708643586776743290055" + ); } impl SWModelParameters for Parameters { /// COEFF_A = [0, 0] - const COEFF_A: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,); + const COEFF_A: Fq2 = QuadExt!(g1::Parameters::COEFF_A, g1::Parameters::COEFF_A,); /// COEFF_B = [4, 4] - const COEFF_B: Fq2 = field_new!(Fq2, g1::Parameters::COEFF_B, g1::Parameters::COEFF_B,); + const COEFF_B: Fq2 = QuadExt!(g1::Parameters::COEFF_B, g1::Parameters::COEFF_B,); /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -71,59 +74,55 @@ impl SWModelParameters for Parameters { } } -pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); -pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1); +pub const G2_GENERATOR_X: Fq2 = QuadExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); +pub const G2_GENERATOR_Y: Fq2 = QuadExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1); /// G2_GENERATOR_X_C0 = /// 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160 -#[rustfmt::skip] -pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160"); +pub const G2_GENERATOR_X_C0: Fq = MontFp!(Fq, "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160"); /// G2_GENERATOR_X_C1 = /// 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758 -#[rustfmt::skip] -pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758"); +pub const G2_GENERATOR_X_C1: Fq = MontFp!(Fq, "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758"); /// G2_GENERATOR_Y_C0 = /// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905 -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905"); +pub const G2_GENERATOR_Y_C0: Fq = MontFp!(Fq, "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905"); /// G2_GENERATOR_Y_C1 = /// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582 -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582"); +pub const G2_GENERATOR_Y_C1: Fq = MontFp!(Fq, "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582"); // psi(x,y) = (x**p * PSI_X, y**p * PSI_Y) is the Frobenius composed // with the quadratic twist and its inverse // PSI_X = 1/(u+1)^((p-1)/3) -pub const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = field_new!( - Fq2, +pub const P_POWER_ENDOMORPHISM_COEFF_0 : Fq2 = QuadExt!( FQ_ZERO, - field_new!( - Fq, - "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437" + MontFp!( + Fq, + "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437" ) ); // PSI_Y = 1/(u+1)^((p-1)/2) -pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = field_new!( - Fq2, - field_new!( - Fq, - "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), - field_new!( - Fq, - "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257") +pub const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = QuadExt!( + MontFp!( + Fq, + "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), + MontFp!( + Fq, + "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257") ); pub fn p_power_endomorphism(p: &GroupAffine) -> GroupAffine { // The p-power endomorphism for G2 is defined as follows: - // 1. Note that G2 is defined on curve E': y^2 = x^3 + 4(u+1). To map a point (x, y) in E' to (s, t) in E, - // one set s = x / ((u+1) ^ (1/3)), t = y / ((u+1) ^ (1/2)), because E: y^2 = x^3 + 4. - // 2. Apply the Frobenius endomorphism (s, t) => (s', t'), another point on curve E, - // where s' = s^p, t' = t^p. + // 1. Note that G2 is defined on curve E': y^2 = x^3 + 4(u+1). + // To map a point (x, y) in E' to (s, t) in E, + // one set s = x / ((u+1) ^ (1/3)), t = y / ((u+1) ^ (1/2)), + // because E: y^2 = x^3 + 4. + // 2. Apply the Frobenius endomorphism (s, t) => (s', t'), + // another point on curve E, where s' = s^p, t' = t^p. // 3. Map the point from E back to E'; that is, // one set x' = s' * ((u+1) ^ (1/3)), y' = t' * ((u+1) ^ (1/2)). // diff --git a/bls12_381/src/curves/mod.rs b/bls12_381/src/curves/mod.rs index ffa7ed1..2df846d 100644 --- a/bls12_381/src/curves/mod.rs +++ b/bls12_381/src/curves/mod.rs @@ -1,6 +1,6 @@ use ark_ec::bls12::{Bls12, Bls12Parameters, TwistType}; -use crate::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters}; +use crate::{Fq, Fq12Config, Fq2Config, Fq6Config}; pub mod g1; pub mod g2; @@ -22,9 +22,9 @@ impl Bls12Parameters for Parameters { const X_IS_NEGATIVE: bool = true; const TWIST_TYPE: TwistType = TwistType::M; type Fp = Fq; - type Fp2Params = Fq2Parameters; - type Fp6Params = Fq6Parameters; - type Fp12Params = Fq12Parameters; + type Fp2Config = Fq2Config; + type Fp6Config = Fq6Config; + type Fp12Config = Fq12Config; type G1Parameters = self::g1::Parameters; type G2Parameters = self::g2::Parameters; } diff --git a/bls12_381/src/curves/tests.rs b/bls12_381/src/curves/tests.rs old mode 100644 new mode 100755 index e974c8a..2c5da8d --- a/bls12_381/src/curves/tests.rs +++ b/bls12_381/src/curves/tests.rs @@ -1,23 +1,16 @@ -#![allow(unused_imports)] -use ark_ec::{ - models::SWModelParameters, - short_weierstrass_jacobian::{GroupAffine, GroupProjective}, - AffineCurve, PairingEngine, ProjectiveCurve, +use ark_algebra_test_templates::{ + curves::*, generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test, + generate_g2_test, groups::*, msm::*, }; +use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve}; use ark_ff::{ - fields::{Field, FpParameters, PrimeField, SquareRootField}, - BitIteratorBE, One, UniformRand, Zero, + fields::{Field, PrimeField, SquareRootField}, + One, UniformRand, Zero, }; -use ark_serialize::CanonicalSerialize; use ark_std::{rand::Rng, test_rng}; use core::ops::{AddAssign, MulAssign}; use crate::{g1, g2, Bls12_381, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective}; -use ark_algebra_test_templates::{ - curves::*, generate_bilinearity_test, generate_g1_generator_raw_test, generate_g1_test, - generate_g2_test, groups::*, msm::*, -}; -use ark_ec::group::Group; generate_g1_test!(bls12_381; curve_tests; sw_tests;); generate_g2_test!(bls12_381; curve_tests; sw_tests;); diff --git a/bls12_381/src/fields/fq.rs b/bls12_381/src/fields/fq.rs index 525733c..0fe7333 100644 --- a/bls12_381/src/fields/fq.rs +++ b/bls12_381/src/fields/fq.rs @@ -1,115 +1,10 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger384 as BigInteger}, - field_new, - fields::{FftParameters, Fp384, Fp384Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp384, MontBackend, MontConfig, MontFp}; -pub type Fq = Fp384; +#[derive(MontConfig)] +#[modulus = "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787"] +#[generator = "2"] +pub struct FqConfig; +pub type Fq = Fp384>; -pub struct FqParameters; - -impl Fp384Parameters for FqParameters {} -impl FftParameters for FqParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 1; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 0x43f5fffffffcaaae, - 0x32b7fff2ed47fffd, - 0x7e83a49a2e99d69, - 0xeca8f3318332bb7a, - 0xef148d1ea0f4c069, - 0x40ab3263eff0206, - ]); -} -impl FpParameters for FqParameters { - /// MODULUS = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0xb9feffffffffaaab, - 0x1eabfffeb153ffff, - 0x6730d2a0f6b0f624, - 0x64774b84f38512bf, - 0x4b1ba7b6434bacd7, - 0x1a0111ea397fe69a, - ]); - - const MODULUS_BITS: u32 = 381; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 3; - - /// R = 3380320199399472671518931668520476396067793891014375699959770179129436917079669831430077592723774664465579537268733 - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 0x760900000002fffd, - 0xebf4000bc40c0002, - 0x5f48985753c758ba, - 0x77ce585370525745, - 0x5c071a97a256ec6d, - 0x15f65ec3fa80e493, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 0xf4df1f341c341746, - 0xa76e6a609d104f1, - 0x8de5476c4c95b6d5, - 0x67eb88a9939d83c0, - 0x9a793e85b519952d, - 0x11988fe592cae3aa, - ]); - - const INV: u64 = 0x89f3fffcfffcfffd; - - /// GENERATOR = 2 - /// Encoded in Montgomery form, so the value is - /// 2 * R % q = 2758230843577277949620073511305048635578704962089743514587482222134842183668501798417467556318533664893264801977679 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 0x321300000006554f, - 0xb93c0018d6c40005, - 0x57605e0db0ddbb51, - 0x8b256521ed1f9bcb, - 0x6cf28d7901622c03, - 0x11ebab9dbb81e28c, - ]); - - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xdcff7fffffffd555, - 0xf55ffff58a9ffff, - 0xb39869507b587b12, - 0xb23ba5c279c2895f, - 0x258dd3db21a5d66b, - 0xd0088f51cbff34d, - ]); - - /// T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T - /// For T coprime to 2 - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0xdcff7fffffffd555, - 0xf55ffff58a9ffff, - 0xb39869507b587b12, - 0xb23ba5c279c2895f, - 0x258dd3db21a5d66b, - 0xd0088f51cbff34d, - ]); - - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xee7fbfffffffeaaa, - 0x7aaffffac54ffff, - 0xd9cc34a83dac3d89, - 0xd91dd2e13ce144af, - 0x92c6e9ed90d2eb35, - 0x680447a8e5ff9a6, - ]); -} - -pub const FQ_ONE: Fq = field_new!(Fq, "1"); -pub const FQ_ZERO: Fq = field_new!(Fq, "0"); +pub const FQ_ONE: Fq = MontFp!(Fq, "1"); +pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); diff --git a/bls12_381/src/fields/fq12.rs b/bls12_381/src/fields/fq12.rs index b21d563..e94f8b1 100644 --- a/bls12_381/src/fields/fq12.rs +++ b/bls12_381/src/fields/fq12.rs @@ -1,76 +1,77 @@ +use ark_ff::{fields::*, CubicExt, MontFp, QuadExt}; + use crate::*; -use ark_ff::{field_new, fields::*}; -pub type Fq12 = Fp12; +pub type Fq12 = Fp12; #[derive(Clone, Copy)] -pub struct Fq12Parameters; +pub struct Fq12Config; -impl Fp12Parameters for Fq12Parameters { - type Fp6Params = Fq6Parameters; +impl Fp12Config for Fq12Config { + type Fp6Config = Fq6Config; - const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO); + const NONRESIDUE: Fq6 = CubicExt!(FQ2_ZERO, FQ2_ONE, FQ2_ZERO); const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[ // Fp2::NONRESIDUE^(((q^0) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "1"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "1"), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^1) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"), - field_new!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"), + QuadExt!( + MontFp!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"), + MontFp!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"), ), // Fp2::NONRESIDUE^(((q^2) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^3) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), - field_new!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"), + QuadExt!( + MontFp!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), + MontFp!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"), ), // Fp2::NONRESIDUE^(((q^4) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^5) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"), - field_new!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"), + QuadExt!( + MontFp!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"), + MontFp!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"), ), // Fp2::NONRESIDUE^(((q^6) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "-1"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "-1"), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^7) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"), - field_new!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"), + QuadExt!( + MontFp!(Fq, "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027"), + MontFp!(Fq, "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760"), ), // Fp2::NONRESIDUE^(((q^8) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^9) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"), - field_new!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), + QuadExt!( + MontFp!(Fq, "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257"), + MontFp!(Fq, "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530"), ), // Fp2::NONRESIDUE^(((q^10) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^11) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"), - field_new!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"), + QuadExt!( + MontFp!(Fq, "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230"), + MontFp!(Fq, "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557"), ), ]; } diff --git a/bls12_381/src/fields/fq2.rs b/bls12_381/src/fields/fq2.rs index 917c136..5f24dc1 100644 --- a/bls12_381/src/fields/fq2.rs +++ b/bls12_381/src/fields/fq2.rs @@ -1,28 +1,26 @@ +use ark_ff::{fields::*, MontFp, QuadExt}; + use crate::*; -use ark_ff::{field_new, fields::*}; -pub type Fq2 = Fp2; +pub type Fq2 = Fp2; -pub struct Fq2Parameters; +pub struct Fq2Config; -impl Fp2Parameters for Fq2Parameters { +impl Fp2Config for Fq2Config { type Fp = Fq; /// NONRESIDUE = -1 - #[rustfmt::skip] - const NONRESIDUE: Fq = field_new!(Fq, "-1"); + const NONRESIDUE: Fq = MontFp!(Fq, "-1"); /// QUADRATIC_NONRESIDUE = (U + 1) - #[rustfmt::skip] - const QUADRATIC_NONRESIDUE: (Fq, Fq) = (FQ_ONE, FQ_ONE); + const QUADRATIC_NONRESIDUE: Fq2 = QuadExt!(FQ_ONE, FQ_ONE); /// Coefficients for the Frobenius automorphism. - #[rustfmt::skip] const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[ // Fq(-1)**(((q^0) - 1) / 2) - field_new!(Fq, "1"), + MontFp!(Fq, "1"), // Fq(-1)**(((q^1) - 1) / 2) - field_new!(Fq, "-1"), + MontFp!(Fq, "-1"), ]; #[inline(always)] @@ -31,5 +29,5 @@ impl Fp2Parameters for Fq2Parameters { } } -pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO); -pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO); +pub const FQ2_ZERO: Fq2 = QuadExt!(FQ_ZERO, FQ_ZERO); +pub const FQ2_ONE: Fq2 = QuadExt!(FQ_ONE, FQ_ZERO); diff --git a/bls12_381/src/fields/fq6.rs b/bls12_381/src/fields/fq6.rs index 8adb477..3a649e0 100644 --- a/bls12_381/src/fields/fq6.rs +++ b/bls12_381/src/fields/fq6.rs @@ -1,86 +1,82 @@ +use ark_ff::{fields::*, MontFp, QuadExt}; + use crate::*; -use ark_ff::{field_new, fields::*}; -pub type Fq6 = Fp6; +pub type Fq6 = Fp6; #[derive(Clone, Copy)] -pub struct Fq6Parameters; +pub struct Fq6Config; -impl Fp6Parameters for Fq6Parameters { - type Fp2Params = Fq2Parameters; +impl Fp6Config for Fq6Config { + type Fp2Config = Fq2Config; /// NONRESIDUE = (U + 1) - #[rustfmt::skip] - const NONRESIDUE: Fq2 = field_new!(Fq2, - field_new!(Fq, "1"), - field_new!(Fq, "1"), - ); + const NONRESIDUE: Fq2 = QuadExt!(FQ_ONE, FQ_ONE); - #[rustfmt::skip] const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[ // Fp2::NONRESIDUE^(((q^0) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "1"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "1"), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^1) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "0"), - field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), + QuadExt!( + MontFp!(Fq, "0"), + MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), ), // Fp2::NONRESIDUE^(((q^2) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^3) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "0"), - field_new!(Fq, "1"), + QuadExt!( + MontFp!(Fq, "0"), + MontFp!(Fq, "1"), ), // Fp2::NONRESIDUE^(((q^4) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^5) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "0"), - field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), + QuadExt!( + MontFp!(Fq, "0"), + MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), ), ]; #[rustfmt::skip] const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[ // Fq2(u + 1)**(((2q^0) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "1"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "1"), + MontFp!(Fq, "0"), ), // Fq2(u + 1)**(((2q^1) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437"), + MontFp!(Fq, "0"), ), // Fq2(u + 1)**(((2q^2) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436"), + MontFp!(Fq, "0"), ), // Fq2(u + 1)**(((2q^3) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "-1"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "-1"), + MontFp!(Fq, "0"), ), // Fq2(u + 1)**(((2q^4) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"), + MontFp!(Fq, "0"), ), // Fq2(u + 1)**(((2q^5) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351"), + MontFp!(Fq, "0"), ), ]; diff --git a/bls12_381/src/fields/fr.rs b/bls12_381/src/fields/fr.rs index 543a864..721bc6d 100644 --- a/bls12_381/src/fields/fr.rs +++ b/bls12_381/src/fields/fr.rs @@ -1,100 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - fields::{FftParameters, Fp256, Fp256Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; -pub type Fr = Fp256; - -pub struct FrParameters; - -impl Fp256Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 32; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 0xb9b58d8c5f0e466a, - 0x5b1b4c801819d7ec, - 0xaf53ae352a31e64, - 0x5bf3adda19e9b27b, - ]); -} -impl FpParameters for FrParameters { - /// MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0xffffffff00000001, - 0x53bda402fffe5bfe, - 0x3339d80809a1d805, - 0x73eda753299d7d48, - ]); - - const MODULUS_BITS: u32 = 255; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 1; - - /// R = 10920338887063814464675503992315976177888879664585288394250266608035967270910 - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 0x1fffffffe, - 0x5884b7fa00034802, - 0x998c4fefecbc4ff5, - 0x1824b159acc5056f, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 0xc999e990f3f29c6d, - 0x2b6cedcb87925c23, - 0x5d314967254398f, - 0x748d9d99f59ff11, - ]); - - const INV: u64 = 0xfffffffeffffffff; - - /// GENERATOR = 7 - /// Encoded in Montgomery form, so the value here is - /// 7 * R % q = 24006497034320510773280787438025867407531605151569380937148207556313189711857 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 0xefffffff1, - 0x17e363d300189c0f, - 0xff9c57876f8457b0, - 0x351332208fc5a8c4, - ]); - - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x7fffffff80000000, - 0xa9ded2017fff2dff, - 0x199cec0404d0ec02, - 0x39f6d3a994cebea4, - ]); - - // T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T - // For T coprime to 2 - - // T = (MODULUS - 1) / 2^S = - // 12208678567578594777604504606729831043093128246378069236549469339647 - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0xfffe5bfeffffffff, - 0x9a1d80553bda402, - 0x299d7d483339d808, - 0x73eda753, - ]); - - // (T - 1) / 2 = - // 6104339283789297388802252303364915521546564123189034618274734669823 - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x7fff2dff7fffffff, - 0x4d0ec02a9ded201, - 0x94cebea4199cec04, - 0x39f6d3a9, - ]); -} +#[derive(MontConfig)] +#[modulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"] +#[generator = "7"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/bls12_381/src/fields/mod.rs b/bls12_381/src/fields/mod.rs index c9c69eb..030e938 100644 --- a/bls12_381/src/fields/mod.rs +++ b/bls12_381/src/fields/mod.rs @@ -23,5 +23,5 @@ pub mod fq12; #[cfg(feature = "curve")] pub use self::fq12::*; -#[cfg(all(feature = "curve", feature = "std", test))] +#[cfg(all(feature = "curve", test))] mod tests; diff --git a/bls12_381/src/fields/tests.rs b/bls12_381/src/fields/tests.rs index 7b667af..d684f06 100644 --- a/bls12_381/src/fields/tests.rs +++ b/bls12_381/src/fields/tests.rs @@ -1,22 +1,23 @@ +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{ biginteger::{BigInt, BigInteger, BigInteger384}, - fields::{ - FftField, FftParameters, Field, Fp12Parameters, Fp2Parameters, Fp6Parameters, FpParameters, - SquareRootField, - }, + fields::{FftField, Field, Fp12Config, Fp2Config, Fp6Config, PrimeField, SquareRootField}, One, UniformRand, Zero, }; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; use ark_std::{ cmp::Ordering, ops::{AddAssign, MulAssign, SubAssign}, rand::Rng, - test_rng, + test_rng, vec, }; -use crate::{Fq, Fq12, Fq12Parameters, Fq2, Fq2Parameters, Fq6, Fq6Parameters, FqParameters, Fr}; -use ark_algebra_test_templates::{fields::*, generate_field_test}; +use crate::{Fq, Fq12, Fq12Config, Fq2, Fq2Config, Fq6, Fq6Config, FqConfig, Fr, FrConfig}; -generate_field_test!(bls12_381; fq2; fq6; fq12;); +generate_field_test!(bls12_381; fq2; fq6; fq12; mont(6, 4); ); +generate_field_serialization_test!(bls12_381; fq2; fq6; fq12;); #[test] fn test_negative_one() { @@ -35,9 +36,9 @@ fn test_negative_one() { fn test_frob_coeffs() { let nqr = -Fq::one(); - assert_eq!(Fq2Parameters::FROBENIUS_COEFF_FP2_C1[0], Fq::one()); + assert_eq!(Fq2Config::FROBENIUS_COEFF_FP2_C1[0], Fq::one()); assert_eq!( - Fq2Parameters::FROBENIUS_COEFF_FP2_C1[1], + Fq2Config::FROBENIUS_COEFF_FP2_C1[1], nqr.pow([ 0xdcff7fffffffd555, 0xf55ffff58a9ffff, @@ -50,9 +51,9 @@ fn test_frob_coeffs() { let nqr = Fq2::new(Fq::one(), Fq::one()); - assert_eq!(Fq6Parameters::FROBENIUS_COEFF_FP6_C1[0], Fq2::one()); + assert_eq!(Fq6Config::FROBENIUS_COEFF_FP6_C1[0], Fq2::one()); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C1[1], + Fq6Config::FROBENIUS_COEFF_FP6_C1[1], nqr.pow([ 0x9354ffffffffe38e, 0xa395554e5c6aaaa, @@ -63,7 +64,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C1[2], + Fq6Config::FROBENIUS_COEFF_FP6_C1[2], nqr.pow([ 0xb78e0000097b2f68, 0xd44f23b47cbd64e3, @@ -80,7 +81,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C1[3], + Fq6Config::FROBENIUS_COEFF_FP6_C1[3], nqr.pow([ 0xdbc6fcd6f35b9e06, 0x997dead10becd6aa, @@ -103,7 +104,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C1[4], + Fq6Config::FROBENIUS_COEFF_FP6_C1[4], nqr.pow([ 0x4649add3c71c6d90, 0x43caa6528972a865, @@ -132,7 +133,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C1[5], + Fq6Config::FROBENIUS_COEFF_FP6_C1[5], nqr.pow([ 0xf896f792732eb2be, 0x49c86a6d1dc593a1, @@ -167,9 +168,9 @@ fn test_frob_coeffs() { ]) ); - assert_eq!(Fq6Parameters::FROBENIUS_COEFF_FP6_C2[0], Fq2::one()); + assert_eq!(Fq6Config::FROBENIUS_COEFF_FP6_C2[0], Fq2::one()); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C2[1], + Fq6Config::FROBENIUS_COEFF_FP6_C2[1], nqr.pow([ 0x26a9ffffffffc71c, 0x1472aaa9cb8d5555, @@ -180,7 +181,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C2[2], + Fq6Config::FROBENIUS_COEFF_FP6_C2[2], nqr.pow([ 0x6f1c000012f65ed0, 0xa89e4768f97ac9c7, @@ -197,7 +198,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C2[3], + Fq6Config::FROBENIUS_COEFF_FP6_C2[3], nqr.pow([ 0xb78df9ade6b73c0c, 0x32fbd5a217d9ad55, @@ -220,7 +221,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C2[4], + Fq6Config::FROBENIUS_COEFF_FP6_C2[4], nqr.pow([ 0x8c935ba78e38db20, 0x87954ca512e550ca, @@ -249,7 +250,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq6Parameters::FROBENIUS_COEFF_FP6_C2[5], + Fq6Config::FROBENIUS_COEFF_FP6_C2[5], nqr.pow([ 0xf12def24e65d657c, 0x9390d4da3b8b2743, @@ -284,9 +285,9 @@ fn test_frob_coeffs() { ]) ); - assert_eq!(Fq12Parameters::FROBENIUS_COEFF_FP12_C1[0], Fq2::one()); + assert_eq!(Fq12Config::FROBENIUS_COEFF_FP12_C1[0], Fq2::one()); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[1], + Fq12Config::FROBENIUS_COEFF_FP12_C1[1], nqr.pow([ 0x49aa7ffffffff1c7, 0x51caaaa72e35555, @@ -297,7 +298,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[2], + Fq12Config::FROBENIUS_COEFF_FP12_C1[2], nqr.pow([ 0xdbc7000004bd97b4, 0xea2791da3e5eb271, @@ -314,7 +315,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[3], + Fq12Config::FROBENIUS_COEFF_FP12_C1[3], nqr.pow(vec![ 0x6de37e6b79adcf03, 0x4cbef56885f66b55, @@ -337,7 +338,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[4], + Fq12Config::FROBENIUS_COEFF_FP12_C1[4], nqr.pow(vec![ 0xa324d6e9e38e36c8, 0xa1e5532944b95432, @@ -366,7 +367,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[5], + Fq12Config::FROBENIUS_COEFF_FP12_C1[5], nqr.pow(vec![ 0xfc4b7bc93997595f, 0xa4e435368ee2c9d0, @@ -401,7 +402,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[6], + Fq12Config::FROBENIUS_COEFF_FP12_C1[6], nqr.pow(vec![ 0x21219610a012ba3c, 0xa5c19ad35375325, @@ -442,7 +443,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[7], + Fq12Config::FROBENIUS_COEFF_FP12_C1[7], nqr.pow(vec![ 0x742754a1f22fdb, 0x2a1955c2dec3a702, @@ -489,7 +490,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[8], + Fq12Config::FROBENIUS_COEFF_FP12_C1[8], nqr.pow(vec![ 0x802f5720d0b25710, 0x6714f0a258b85c7c, @@ -542,7 +543,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[9], + Fq12Config::FROBENIUS_COEFF_FP12_C1[9], nqr.pow(vec![ 0x4af4accf7de0b977, 0x742485e21805b4ee, @@ -601,7 +602,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[10], + Fq12Config::FROBENIUS_COEFF_FP12_C1[10], nqr.pow(vec![ 0xe5953a4f96cdda44, 0x336b2d734cbc32bb, @@ -666,7 +667,7 @@ fn test_frob_coeffs() { ]) ); assert_eq!( - Fq12Parameters::FROBENIUS_COEFF_FP12_C1[11], + Fq12Config::FROBENIUS_COEFF_FP12_C1[11], nqr.pow(vec![ 0x107db680942de533, 0x6262b24d2052393b, @@ -750,7 +751,6 @@ fn test_neg_one() { 0xef148d1ea0f4c069, 0x40ab3263eff0206, ]; - println!("{:?}", thing); let negative_one = Fq::new(BigInt::new(thing)); assert_eq!(negative_one, o); @@ -763,14 +763,14 @@ fn test_fq_repr_from() { #[test] fn test_fq_repr_is_odd() { - assert!(!BigInteger384::from(0).is_odd()); - assert!(BigInteger384::from(0).is_even()); - assert!(BigInteger384::from(1).is_odd()); - assert!(!BigInteger384::from(1).is_even()); - assert!(!BigInteger384::from(324834872).is_odd()); - assert!(BigInteger384::from(324834872).is_even()); - assert!(BigInteger384::from(324834873).is_odd()); - assert!(!BigInteger384::from(324834873).is_even()); + assert!(!BigInteger384::from(0u64).is_odd()); + assert!(BigInteger384::from(0u64).is_even()); + assert!(BigInteger384::from(1u64).is_odd()); + assert!(!BigInteger384::from(1u64).is_even()); + assert!(!BigInteger384::from(324834872u64).is_odd()); + assert!(BigInteger384::from(324834872u64).is_even()); + assert!(BigInteger384::from(324834873u64).is_odd()); + assert!(!BigInteger384::from(324834873u64).is_even()); } #[test] @@ -902,7 +902,7 @@ fn test_fq_repr_divn() { #[test] fn test_fq_repr_mul2() { - let mut a = BigInteger384::from(23712937547); + let mut a = BigInteger384::from(23712937547u64); a.mul2(); assert_eq!(a, BigInt::new([0xb0acd6c96, 0x0, 0x0, 0x0, 0x0, 0x0])); for _ in 0..60 { @@ -934,9 +934,9 @@ fn test_fq_repr_mul2() { #[test] fn test_fq_repr_num_bits() { - let mut a = BigInteger384::from(0); + let mut a = BigInteger384::from(0u64); assert_eq!(0, a.num_bits()); - a = BigInteger384::from(1); + a = BigInteger384::from(1u64); for i in 1..385 { assert_eq!(i, a.num_bits()); a.mul2(); @@ -956,7 +956,7 @@ fn test_fq_repr_sub_noborrow() { 0xad0eb3948a5c34fd, 0xd56f7b5ab8b5ce8, ]); - t.sub_noborrow(&BigInt::new([ + t.sub_with_borrow(&BigInt::new([ 0xc7867917187ca02b, 0x5d75679d4911ffef, 0x8c5b3e48b1a71c15, @@ -991,12 +991,12 @@ fn test_fq_repr_sub_noborrow() { assert!(b < c); let mut csub_ba = c; - csub_ba.sub_noborrow(&b); - csub_ba.sub_noborrow(&a); + csub_ba.sub_with_borrow(&b); + csub_ba.sub_with_borrow(&a); let mut csub_ab = c; - csub_ab.sub_noborrow(&a); - csub_ab.sub_noborrow(&b); + csub_ab.sub_with_borrow(&a); + csub_ab.sub_with_borrow(&b); assert_eq!(csub_ab, csub_ba); } @@ -1010,7 +1010,7 @@ fn test_fq_repr_sub_noborrow() { 0x4b1ba7b6434bacd7, 0x1a0111ea397fe69a, ]); - qplusone.sub_noborrow(&BigInt::new([ + qplusone.sub_with_borrow(&BigInt::new([ 0xb9feffffffffaaac, 0x1eabfffeb153ffff, 0x6730d2a0f6b0f624, @@ -1043,7 +1043,7 @@ fn test_fq_repr_add_nocarry() { 0xad0eb3948a5c34fd, 0xd56f7b5ab8b5ce8, ]); - t.add_nocarry(&BigInt::new([ + t.add_with_carry(&BigInt::new([ 0xc7867917187ca02b, 0x5d75679d4911ffef, 0x8c5b3e48b1a71c15, @@ -1074,28 +1074,28 @@ fn test_fq_repr_add_nocarry() { c.0[5] >>= 3; let mut abc = a; - abc.add_nocarry(&b); - abc.add_nocarry(&c); + abc.add_with_carry(&b); + abc.add_with_carry(&c); let mut acb = a; - acb.add_nocarry(&c); - acb.add_nocarry(&b); + acb.add_with_carry(&c); + acb.add_with_carry(&b); let mut bac = b; - bac.add_nocarry(&a); - bac.add_nocarry(&c); + bac.add_with_carry(&a); + bac.add_with_carry(&c); let mut bca = b; - bca.add_nocarry(&c); - bca.add_nocarry(&a); + bca.add_with_carry(&c); + bca.add_with_carry(&a); let mut cab = c; - cab.add_nocarry(&a); - cab.add_nocarry(&b); + cab.add_with_carry(&a); + cab.add_with_carry(&b); let mut cba = c; - cba.add_nocarry(&b); - cba.add_nocarry(&a); + cba.add_with_carry(&b); + cba.add_with_carry(&a); assert_eq!(abc, acb); assert_eq!(abc, bac); @@ -1113,7 +1113,7 @@ fn test_fq_repr_add_nocarry() { 0xffffffffffffffff, 0xffffffffffffffff, ]); - x.add_nocarry(&BigInteger384::from(1)); + x.add_with_carry(&BigInteger384::from(1u64)); assert!(x.is_zero()); } @@ -1132,19 +1132,15 @@ fn test_fq2_sqrt() { #[test] fn test_fq_num_bits() { - assert_eq!(FqParameters::MODULUS_BITS, 381); - assert_eq!(FqParameters::CAPACITY, 380); + assert_eq!(Fq::MODULUS_BIT_SIZE, 381); } #[test] fn test_fq_root_of_unity() { - assert_eq!(FqParameters::TWO_ADICITY, 1); - assert_eq!( - Fq::multiplicative_generator(), - Fq::from(BigInteger384::from(2)) - ); + assert_eq!(Fq::TWO_ADICITY, 1); + assert_eq!(Fq::GENERATOR, Fq::from(BigInteger384::from(2u64))); assert_eq!( - Fq::multiplicative_generator().pow([ + Fq::GENERATOR.pow([ 0xdcff7fffffffd555, 0xf55ffff58a9ffff, 0xb39869507b587b12, @@ -1152,13 +1148,13 @@ fn test_fq_root_of_unity() { 0x258dd3db21a5d66b, 0xd0088f51cbff34d, ]), - Fq::two_adic_root_of_unity() + Fq::TWO_ADIC_ROOT_OF_UNITY ); assert_eq!( - Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]), + Fq::TWO_ADIC_ROOT_OF_UNITY.pow([1 << Fq::TWO_ADICITY]), Fq::one() ); - assert!(Fq::multiplicative_generator().sqrt().is_none()); + assert!(Fq::GENERATOR.sqrt().is_none()); } // #[test] @@ -1173,7 +1169,7 @@ fn test_fq_root_of_unity() { fn test_fq_ordering() { // BigInteger384's ordering is well-tested, but we still need to make sure the // Fq elements aren't being compared in Montgomery form. - for i in 0..100 { + for i in 0..100u64 { assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i))); } } @@ -1192,11 +1188,11 @@ fn test_fq_legendre() { assert_eq!( QuadraticNonResidue, - Fq::from(BigInteger384::from(2)).legendre() + Fq::from(BigInteger384::from(2u64)).legendre() ); assert_eq!( QuadraticResidue, - Fq::from(BigInteger384::from(4)).legendre() + Fq::from(BigInteger384::from(4u64)).legendre() ); let e = BigInt::new([ @@ -1252,7 +1248,10 @@ fn test_fq2_basics() { #[test] fn test_fq2_squaring() { let a = Fq2::new(Fq::one(), Fq::one()).square(); // u + 1 - assert_eq!(a, Fq2::new(Fq::zero(), Fq::from(BigInteger384::from(2)),)); // 2u + assert_eq!( + a, + Fq2::new(Fq::zero(), Fq::from(BigInteger384::from(2u64)),) + ); // 2u let a = Fq2::new(Fq::zero(), Fq::one()).square(); // u assert_eq!(a, { @@ -1737,7 +1736,7 @@ fn test_fq2_legendre() { // i^2 = -1 let mut m1 = -Fq2::one(); assert_eq!(QuadraticResidue, m1.legendre()); - m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1); + m1 = Fq6Config::mul_fp2_by_nonresidue(&m1); assert_eq!(QuadraticNonResidue, m1.legendre()); } @@ -1750,7 +1749,7 @@ fn test_fq2_mul_nonresidue() { for _ in 0..1000 { let mut a = Fq2::rand(&mut rng); let mut b = a; - a = Fq6Parameters::mul_fp2_by_nonresidue(&a); + a = Fq6Config::mul_fp2_by_nonresidue(&a); b.mul_assign(&nqr); assert_eq!(a, b); @@ -1766,7 +1765,7 @@ fn test_fq6_mul_nonresidue() { for _ in 0..1000 { let mut a = Fq6::rand(&mut rng); let mut b = a; - a = Fq12Parameters::mul_fp6_by_nonresidue(&a); + a = Fq12Config::mul_fp6_by_nonresidue(&a); b.mul_assign(&nqr); assert_eq!(a, b); diff --git a/bls12_381/src/lib.rs b/bls12_381/src/lib.rs old mode 100644 new mode 100755 index a9142c2..9d60dbb --- a/bls12_381/src/lib.rs +++ b/bls12_381/src/lib.rs @@ -9,15 +9,16 @@ #![forbid(unsafe_code)] //! This library implements the BLS12_381 curve generated by [Sean Bowe](https://electriccoin.co/blog/new-snark-curve/). -//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree 12, -//! defined over a 381-bit (prime) field. -//! This curve was intended to replace the BN254 curve to provide a higher security -//! level without incurring a large performance overhead. +//! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree +//! 12, defined over a 381-bit (prime) field. +//! This curve was intended to replace the BN254 curve to provide a higher +//! security level without incurring a large performance overhead. //! //! //! Curve information: //! * Base field: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 -//! * Scalar field: r = 52435875175126190479447740508185965837690552500527637822603658699938581184513 +//! * Scalar field: r = +//! 52435875175126190479447740508185965837690552500527637822603658699938581184513 //! * valuation(q - 1, 2) = 1 //! * valuation(r - 1, 2) = 32 //! * G1 curve equation: y^2 = x^3 + 4 diff --git a/bn254/scripts/base_field.sage b/bn254/scripts/base_field.sage new file mode 100644 index 0000000..cf47baf --- /dev/null +++ b/bn254/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 21888242871839275222246405745257275088696311157297823662689037894645226208583 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/bn254/scripts/scalar_field.sage b/bn254/scripts/scalar_field.sage new file mode 100644 index 0000000..a8a4b5c --- /dev/null +++ b/bn254/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 21888242871839275222246405745257275088548364400416034343698204186575808495617 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/bn254/src/curves/g1.rs b/bn254/src/curves/g1.rs index 6640dc1..5a1cd36 100644 --- a/bn254/src/curves/g1.rs +++ b/bn254/src/curves/g1.rs @@ -1,5 +1,5 @@ use ark_ec::models::{ModelParameters, SWModelParameters}; -use ark_ff::{field_new, Zero}; +use ark_ff::{MontFp, Zero}; use crate::{Fq, Fr}; @@ -14,15 +14,15 @@ impl ModelParameters for Parameters { const COFACTOR: &'static [u64] = &[0x1]; /// COFACTOR_INV = COFACTOR^{-1} mod r = 1 - const COFACTOR_INV: Fr = field_new!(Fr, "1"); + const COFACTOR_INV: Fr = MontFp!(Fr, "1"); } impl SWModelParameters for Parameters { /// COEFF_A = 0 - const COEFF_A: Fq = field_new!(Fq, "0"); + const COEFF_A: Fq = MontFp!(Fq, "0"); /// COEFF_B = 3 - const COEFF_B: Fq = field_new!(Fq, "3"); + const COEFF_B: Fq = MontFp!(Fq, "3"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -35,7 +35,7 @@ impl SWModelParameters for Parameters { } /// G1_GENERATOR_X = 1 -pub const G1_GENERATOR_X: Fq = field_new!(Fq, "1"); +pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "1"); /// G1_GENERATOR_Y = 2 -pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "2"); +pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "2"); diff --git a/bn254/src/curves/g2.rs b/bn254/src/curves/g2.rs index 7dc0a61..290c78a 100644 --- a/bn254/src/curves/g2.rs +++ b/bn254/src/curves/g2.rs @@ -1,5 +1,5 @@ use ark_ec::models::{ModelParameters, SWModelParameters}; -use ark_ff::{field_new, Zero}; +use ark_ff::{MontFp, QuadExt, Zero}; use crate::{Fq, Fq2, Fr}; @@ -11,7 +11,7 @@ impl ModelParameters for Parameters { type ScalarField = Fr; /// COFACTOR = (36 * X^4) + (36 * X^3) + (30 * X^2) + 6*X + 1 - /// = 21888242871839275222246405745257275088844257914179612981679871602714643921549 + /// 21888242871839275222246405745257275088844257914179612981679871602714643921549 #[rustfmt::skip] const COFACTOR: &'static [u64] = &[ 0x345f2299c0f9fa8d, @@ -21,21 +21,27 @@ impl ModelParameters for Parameters { ]; /// COFACTOR_INV = COFACTOR^{-1} mod r - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "10944121435919637613327163357776759465618812564592884533313067514031822496649"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "10944121435919637613327163357776759465618812564592884533313067514031822496649" + ); } impl SWModelParameters for Parameters { /// COEFF_A = [0, 0] - #[rustfmt::skip] - const COEFF_A: Fq2 = field_new!(Fq2, field_new!(Fq, "0"), field_new!(Fq, "0")); + const COEFF_A: Fq2 = QuadExt!(MontFp!(Fq, "0"), MontFp!(Fq, "0")); /// COEFF_B = 3/(u+9) - /// = (19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690) - #[rustfmt::skip] - const COEFF_B: Fq2 = field_new!(Fq2, - field_new!(Fq, "19485874751759354771024239261021720505790618469301721065564631296452457478373"), - field_new!(Fq, "266929791119991161246907387137283842545076965332900288569378510910307636690"), + /// (19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690) + const COEFF_B: Fq2 = QuadExt!( + MontFp!( + Fq, + "19485874751759354771024239261021720505790618469301721065564631296452457478373" + ), + MontFp!( + Fq, + "266929791119991161246907387137283842545076965332900288569378510910307636690" + ), ); /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) @@ -48,27 +54,33 @@ impl SWModelParameters for Parameters { } } -#[rustfmt::skip] -pub const G2_GENERATOR_X: Fq2 = field_new!(Fq2, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); -#[rustfmt::skip] -pub const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1); +pub const G2_GENERATOR_X: Fq2 = QuadExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); +pub const G2_GENERATOR_Y: Fq2 = QuadExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1); /// G2_GENERATOR_X_C0 = /// 10857046999023057135944570762232829481370756359578518086990519993285655852781 -#[rustfmt::skip] -pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "10857046999023057135944570762232829481370756359578518086990519993285655852781"); +pub const G2_GENERATOR_X_C0: Fq = MontFp!( + Fq, + "10857046999023057135944570762232829481370756359578518086990519993285655852781" +); /// G2_GENERATOR_X_C1 = /// 11559732032986387107991004021392285783925812861821192530917403151452391805634 -#[rustfmt::skip] -pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "11559732032986387107991004021392285783925812861821192530917403151452391805634"); +pub const G2_GENERATOR_X_C1: Fq = MontFp!( + Fq, + "11559732032986387107991004021392285783925812861821192530917403151452391805634" +); /// G2_GENERATOR_Y_C0 = /// 8495653923123431417604973247489272438418190587263600148770280649306958101930 -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "8495653923123431417604973247489272438418190587263600148770280649306958101930"); +pub const G2_GENERATOR_Y_C0: Fq = MontFp!( + Fq, + "8495653923123431417604973247489272438418190587263600148770280649306958101930" +); /// G2_GENERATOR_Y_C1 = /// 4082367875863433681332203403145435568316851327593401208105741076214120093531 -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "4082367875863433681332203403145435568316851327593401208105741076214120093531"); +pub const G2_GENERATOR_Y_C1: Fq = MontFp!( + Fq, + "4082367875863433681332203403145435568316851327593401208105741076214120093531" +); diff --git a/bn254/src/curves/mod.rs b/bn254/src/curves/mod.rs index 8d09267..873bcab 100644 --- a/bn254/src/curves/mod.rs +++ b/bn254/src/curves/mod.rs @@ -1,9 +1,11 @@ -use crate::*; use ark_ec::{ bn, bn::{Bn, BnParameters, TwistType}, }; -use ark_ff::field_new; +use ark_ff::{MontFp, QuadExt}; + +use crate::*; + pub mod g1; pub mod g2; @@ -22,33 +24,31 @@ impl BnParameters for Parameters { -1, 0, 0, 1, 0, 1, 1, ]; - const TWIST_MUL_BY_Q_X: Fq2 = field_new!( - Fq2, - field_new!( + const TWIST_MUL_BY_Q_X: Fq2 = QuadExt!( + MontFp!( Fq, "21575463638280843010398324269430826099269044274347216827212613867836435027261" ), - field_new!( + MontFp!( Fq, "10307601595873709700152284273816112264069230130616436755625194854815875713954" ), ); - const TWIST_MUL_BY_Q_Y: Fq2 = field_new!( - Fq2, - field_new!( + const TWIST_MUL_BY_Q_Y: Fq2 = QuadExt!( + MontFp!( Fq, "2821565182194536844548159561693502659359617185244120367078079554186484126554" ), - field_new!( + MontFp!( Fq, "3505843767911556378687030309984248845540243509899259641013678093033130930403" ), ); const TWIST_TYPE: TwistType = TwistType::D; type Fp = Fq; - type Fp2Params = Fq2Parameters; - type Fp6Params = Fq6Parameters; - type Fp12Params = Fq12Parameters; + type Fp2Config = Fq2Config; + type Fp6Config = Fq6Config; + type Fp12Config = Fq12Config; type G1Parameters = g1::Parameters; type G2Parameters = g2::Parameters; } diff --git a/bn254/src/curves/tests.rs b/bn254/src/curves/tests.rs old mode 100644 new mode 100755 index 51693b6..5f540f0 --- a/bn254/src/curves/tests.rs +++ b/bn254/src/curves/tests.rs @@ -1,18 +1,15 @@ -#![allow(unused_imports)] -use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve}; +use ark_algebra_test_templates::{ + curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*, +}; +use ark_ec::{AffineCurve, PairingEngine}; use ark_ff::{ - fields::{Field, FpParameters, PrimeField, SquareRootField}, - One, Zero, + fields::{Field, PrimeField}, + One, }; -use ark_serialize::CanonicalSerialize; use ark_std::{rand::Rng, test_rng}; -use core::ops::{AddAssign, MulAssign}; - -use crate::{g1, g2, Bn254, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective}; +use core::ops::MulAssign; -use ark_algebra_test_templates::{ - curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*, -}; +use crate::{g1, g2, Bn254, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective}; generate_g1_test!(bn254; curve_tests; sw_tests;); generate_g2_test!(bn254; curve_tests; sw_tests;); diff --git a/bn254/src/fields/fq.rs b/bn254/src/fields/fq.rs index 7694e22..a2f0cb6 100644 --- a/bn254/src/fields/fq.rs +++ b/bn254/src/fields/fq.rs @@ -1,100 +1,10 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - field_new, - fields::*, -}; +use ark_ff::fields::{Fp256, MontBackend, MontConfig, MontFp}; -pub type Fq = Fp256; +#[derive(MontConfig)] +#[modulus = "21888242871839275222246405745257275088696311157297823662689037894645226208583"] +#[generator = "3"] +pub struct FqConfig; +pub type Fq = Fp256>; -pub struct FqParameters; - -impl Fp256Parameters for FqParameters {} -impl FftParameters for FqParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 1; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 0x68c3488912edefaa, - 0x8d087f6872aabf4f, - 0x51e1a24709081231, - 0x2259d6b14729c0fa, - ]); -} -impl FpParameters for FqParameters { - /// MODULUS = 21888242871839275222246405745257275088696311157297823662689037894645226208583 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0x3c208c16d87cfd47, - 0x97816a916871ca8d, - 0xb85045b68181585d, - 0x30644e72e131a029, - ]); - - const MODULUS_BITS: u32 = 254; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 2; - - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 0xd35d438dc58f0d9d, - 0x0a78eb28f5c70b3d, - 0x666ea36f7879462c, - 0xe0a77c19a07df2f, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 0xf32cfc5b538afa89, - 0xb5e71911d44501fb, - 0x47ab1eff0a417ff6, - 0x6d89f71cab8351f, - ]); - - const INV: u64 = 9786893198990664585u64; - - // GENERATOR = 3 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 0x7a17caa950ad28d7, - 0x1f6ac17ae15521b9, - 0x334bea4e696bd284, - 0x2a1f6744ce179d8e, - ]); - - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x9e10460b6c3e7ea3, - 0xcbc0b548b438e546, - 0xdc2822db40c0ac2e, - 0x183227397098d014, - ]); - - // T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T - - // T = (MODULUS - 1) // 2^S = - // 10944121435919637611123202872628637544348155578648911831344518947322613104291 - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0x9e10460b6c3e7ea3, - 0xcbc0b548b438e546, - 0xdc2822db40c0ac2e, - 0x183227397098d014, - ]); - - // (T - 1) // 2 = - // 5472060717959818805561601436314318772174077789324455915672259473661306552145 - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x4f082305b61f3f51, - 0x65e05aa45a1c72a3, - 0x6e14116da0605617, - 0xc19139cb84c680a, - ]); -} - -pub const FQ_ONE: Fq = field_new!(Fq, "1"); -pub const FQ_ZERO: Fq = field_new!(Fq, "0"); +pub const FQ_ONE: Fq = MontFp!(Fq, "1"); +pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); diff --git a/bn254/src/fields/fq12.rs b/bn254/src/fields/fq12.rs index 9dcc521..fcc9649 100644 --- a/bn254/src/fields/fq12.rs +++ b/bn254/src/fields/fq12.rs @@ -1,77 +1,119 @@ -use super::*; -use ark_ff::{field_new, fields::*}; +use ark_ff::{fields::*, CubicExt, MontFp, QuadExt}; -pub type Fq12 = Fp12; +use crate::*; + +pub type Fq12 = Fp12; #[derive(Clone, Copy)] -pub struct Fq12Parameters; +pub struct Fq12Config; -impl Fp12Parameters for Fq12Parameters { - type Fp6Params = Fq6Parameters; +impl Fp12Config for Fq12Config { + type Fp6Config = Fq6Config; - const NONRESIDUE: Fq6 = field_new!(Fq6, FQ2_ZERO, FQ2_ONE, FQ2_ZERO); + const NONRESIDUE: Fq6 = CubicExt!(FQ2_ZERO, FQ2_ONE, FQ2_ZERO); - #[rustfmt::skip] const FROBENIUS_COEFF_FP12_C1: &'static [Fq2] = &[ // Fp2::NONRESIDUE^(((q^0) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "1"), - field_new!(Fq, "0"), - ), + QuadExt!(MontFp!(Fq, "1"), MontFp!(Fq, "0"),), // Fp2::NONRESIDUE^(((q^1) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "8376118865763821496583973867626364092589906065868298776909617916018768340080"), - field_new!(Fq, "16469823323077808223889137241176536799009286646108169935659301613961712198316"), + QuadExt!( + MontFp!( + Fq, + "8376118865763821496583973867626364092589906065868298776909617916018768340080" + ), + MontFp!( + Fq, + "16469823323077808223889137241176536799009286646108169935659301613961712198316" + ), ), // Fp2::NONRESIDUE^(((q^2) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556617"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!( + Fq, + "21888242871839275220042445260109153167277707414472061641714758635765020556617" + ), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^3) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "11697423496358154304825782922584725312912383441159505038794027105778954184319"), - field_new!(Fq, "303847389135065887422783454877609941456349188919719272345083954437860409601"), + QuadExt!( + MontFp!( + Fq, + "11697423496358154304825782922584725312912383441159505038794027105778954184319" + ), + MontFp!( + Fq, + "303847389135065887422783454877609941456349188919719272345083954437860409601" + ), ), // Fp2::NONRESIDUE^(((q^4) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!( + Fq, + "21888242871839275220042445260109153167277707414472061641714758635765020556616" + ), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^5) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "3321304630594332808241809054958361220322477375291206261884409189760185844239"), - field_new!(Fq, "5722266937896532885780051958958348231143373700109372999374820235121374419868"), + QuadExt!( + MontFp!( + Fq, + "3321304630594332808241809054958361220322477375291206261884409189760185844239" + ), + MontFp!( + Fq, + "5722266937896532885780051958958348231143373700109372999374820235121374419868" + ), ), // Fp2::NONRESIDUE^(((q^6) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "-1"), - field_new!(Fq, "0"), - ), + QuadExt!(MontFp!(Fq, "-1"), MontFp!(Fq, "0"),), // Fp2::NONRESIDUE^(((q^7) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "13512124006075453725662431877630910996106405091429524885779419978626457868503"), - field_new!(Fq, "5418419548761466998357268504080738289687024511189653727029736280683514010267"), + QuadExt!( + MontFp!( + Fq, + "13512124006075453725662431877630910996106405091429524885779419978626457868503" + ), + MontFp!( + Fq, + "5418419548761466998357268504080738289687024511189653727029736280683514010267" + ), ), // Fp2::NONRESIDUE^(((q^8) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!( + Fq, + "2203960485148121921418603742825762020974279258880205651966" + ), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^9) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "10190819375481120917420622822672549775783927716138318623895010788866272024264"), - field_new!(Fq, "21584395482704209334823622290379665147239961968378104390343953940207365798982"), + QuadExt!( + MontFp!( + Fq, + "10190819375481120917420622822672549775783927716138318623895010788866272024264" + ), + MontFp!( + Fq, + "21584395482704209334823622290379665147239961968378104390343953940207365798982" + ), ), // Fp2::NONRESIDUE^(((q^10) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "2203960485148121921418603742825762020974279258880205651967"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!( + Fq, + "2203960485148121921418603742825762020974279258880205651967" + ), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^11) - 1) / 6) - field_new!(Fq2, - field_new!(Fq, "18566938241244942414004596690298913868373833782006617400804628704885040364344"), - field_new!(Fq, "16165975933942742336466353786298926857552937457188450663314217659523851788715"), + QuadExt!( + MontFp!( + Fq, + "18566938241244942414004596690298913868373833782006617400804628704885040364344" + ), + MontFp!( + Fq, + "16165975933942742336466353786298926857552937457188450663314217659523851788715" + ), ), ]; } diff --git a/bn254/src/fields/fq2.rs b/bn254/src/fields/fq2.rs index 8231c56..2c1d38f 100644 --- a/bn254/src/fields/fq2.rs +++ b/bn254/src/fields/fq2.rs @@ -1,31 +1,26 @@ -use super::*; -use ark_ff::{field_new, fields::*}; +use ark_ff::{fields::*, MontFp, QuadExt}; -pub type Fq2 = Fp2; +use crate::*; -pub struct Fq2Parameters; +pub type Fq2 = Fp2; -impl Fp2Parameters for Fq2Parameters { +pub struct Fq2Config; + +impl Fp2Config for Fq2Config { type Fp = Fq; /// NONRESIDUE = -1 - #[rustfmt::skip] - const NONRESIDUE: Fq = field_new!(Fq, "-1"); + const NONRESIDUE: Fq = MontFp!(Fq, "-1"); /// QUADRATIC_NONRESIDUE = U+2 - #[rustfmt::skip] - const QUADRATIC_NONRESIDUE: (Fq, Fq) = ( - field_new!(Fq, "2"), - field_new!(Fq, "1"), - ); + const QUADRATIC_NONRESIDUE: Fq2 = QuadExt!(MontFp!(Fq, "2"), MontFp!(Fq, "1")); /// Coefficients for the Frobenius automorphism. - #[rustfmt::skip] const FROBENIUS_COEFF_FP2_C1: &'static [Fq] = &[ // NONRESIDUE**(((q^0) - 1) / 2) - field_new!(Fq, "1"), + MontFp!(Fq, "1"), // NONRESIDUE**(((q^1) - 1) / 2) - field_new!(Fq, "-1"), + MontFp!(Fq, "-1"), ]; #[inline(always)] @@ -34,5 +29,5 @@ impl Fp2Parameters for Fq2Parameters { } } -pub const FQ2_ZERO: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ZERO); -pub const FQ2_ONE: Fq2 = field_new!(Fq2, FQ_ONE, FQ_ZERO); +pub const FQ2_ZERO: Fq2 = QuadExt!(FQ_ZERO, FQ_ZERO); +pub const FQ2_ONE: Fq2 = QuadExt!(FQ_ONE, FQ_ZERO); diff --git a/bn254/src/fields/fq6.rs b/bn254/src/fields/fq6.rs index 09777a4..92747f1 100644 --- a/bn254/src/fields/fq6.rs +++ b/bn254/src/fields/fq6.rs @@ -1,82 +1,123 @@ -use super::*; -use ark_ff::{field_new, fields::*}; +use ark_ff::{fields::*, MontFp, QuadExt}; -pub type Fq6 = Fp6; +use crate::*; + +pub type Fq6 = Fp6; #[derive(Clone, Copy)] -pub struct Fq6Parameters; +pub struct Fq6Config; -impl Fp6Parameters for Fq6Parameters { - type Fp2Params = Fq2Parameters; +impl Fp6Config for Fq6Config { + type Fp2Config = Fq2Config; /// NONRESIDUE = U+9 - #[rustfmt::skip] - const NONRESIDUE: Fq2 = field_new!(Fq2, field_new!(Fq, "9"), field_new!(Fq, "1")); + const NONRESIDUE: Fq2 = QuadExt!(MontFp!(Fq, "9"), MontFp!(Fq, "1")); - #[rustfmt::skip] const FROBENIUS_COEFF_FP6_C1: &'static [Fq2] = &[ // Fp2::NONRESIDUE^(((q^0) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "1"), - field_new!(Fq, "0"), - ), + QuadExt!(MontFp!(Fq, "1"), MontFp!(Fq, "0"),), // Fp2::NONRESIDUE^(((q^1) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "21575463638280843010398324269430826099269044274347216827212613867836435027261"), - field_new!(Fq, "10307601595873709700152284273816112264069230130616436755625194854815875713954"), + QuadExt!( + MontFp!( + Fq, + "21575463638280843010398324269430826099269044274347216827212613867836435027261" + ), + MontFp!( + Fq, + "10307601595873709700152284273816112264069230130616436755625194854815875713954" + ), ), // Fp2::NONRESIDUE^(((q^2) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!( + Fq, + "21888242871839275220042445260109153167277707414472061641714758635765020556616" + ), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^3) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "3772000881919853776433695186713858239009073593817195771773381919316419345261"), - field_new!(Fq, "2236595495967245188281701248203181795121068902605861227855261137820944008926"), + QuadExt!( + MontFp!( + Fq, + "3772000881919853776433695186713858239009073593817195771773381919316419345261" + ), + MontFp!( + Fq, + "2236595495967245188281701248203181795121068902605861227855261137820944008926" + ), ), // Fp2::NONRESIDUE^(((q^4) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!( + Fq, + "2203960485148121921418603742825762020974279258880205651966" + ), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^(((q^5) - 1) / 3) - field_new!(Fq2, - field_new!(Fq, "18429021223477853657660792034369865839114504446431234726392080002137598044644"), - field_new!(Fq, "9344045779998320333812420223237981029506012124075525679208581902008406485703"), + QuadExt!( + MontFp!( + Fq, + "18429021223477853657660792034369865839114504446431234726392080002137598044644" + ), + MontFp!( + Fq, + "9344045779998320333812420223237981029506012124075525679208581902008406485703" + ), ), ]; - #[rustfmt::skip] + const FROBENIUS_COEFF_FP6_C2: &'static [Fq2] = &[ // Fp2::NONRESIDUE^((2*(q^0) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "1"), - field_new!(Fq, "0"), - ), + QuadExt!(MontFp!(Fq, "1"), MontFp!(Fq, "0"),), // Fp2::NONRESIDUE^((2*(q^1) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "2581911344467009335267311115468803099551665605076196740867805258568234346338"), - field_new!(Fq, "19937756971775647987995932169929341994314640652964949448313374472400716661030"), + QuadExt!( + MontFp!( + Fq, + "2581911344467009335267311115468803099551665605076196740867805258568234346338" + ), + MontFp!( + Fq, + "19937756971775647987995932169929341994314640652964949448313374472400716661030" + ), ), // Fp2::NONRESIDUE^((2*(q^2) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "2203960485148121921418603742825762020974279258880205651966"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!( + Fq, + "2203960485148121921418603742825762020974279258880205651966" + ), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^((2*(q^3) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "5324479202449903542726783395506214481928257762400643279780343368557297135718"), - field_new!(Fq, "16208900380737693084919495127334387981393726419856888799917914180988844123039"), + QuadExt!( + MontFp!( + Fq, + "5324479202449903542726783395506214481928257762400643279780343368557297135718" + ), + MontFp!( + Fq, + "16208900380737693084919495127334387981393726419856888799917914180988844123039" + ), ), // Fp2::NONRESIDUE^((2*(q^4) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "21888242871839275220042445260109153167277707414472061641714758635765020556616"), - field_new!(Fq, "0"), + QuadExt!( + MontFp!( + Fq, + "21888242871839275220042445260109153167277707414472061641714758635765020556616" + ), + MontFp!(Fq, "0"), ), // Fp2::NONRESIDUE^((2*(q^5) - 2) / 3) - field_new!(Fq2, - field_new!(Fq, "13981852324922362344252311234282257507216387789820983642040889267519694726527"), - field_new!(Fq, "7629828391165209371577384193250820201684255241773809077146787135900891633097"), + QuadExt!( + MontFp!( + Fq, + "13981852324922362344252311234282257507216387789820983642040889267519694726527" + ), + MontFp!( + Fq, + "7629828391165209371577384193250820201684255241773809077146787135900891633097" + ), ), ]; @@ -85,8 +126,8 @@ impl Fp6Parameters for Fq6Parameters { // (c0+u*c1)*(9+u) = (9*c0-c1)+u*(9*c1+c0) let mut f = *fe; f.double_in_place().double_in_place().double_in_place(); - let c0 = f.c0 + fe.c0 + Fq2Parameters::mul_fp_by_nonresidue(&fe.c1); + let c0 = f.c0 + fe.c0 + Fq2Config::mul_fp_by_nonresidue(&fe.c1); let c1 = f.c1 + fe.c1 + fe.c0; - field_new!(Fq2, c0, c1) + QuadExt!(c0, c1) } } diff --git a/bn254/src/fields/fr.rs b/bn254/src/fields/fr.rs index 6761aed..b79e33f 100644 --- a/bn254/src/fields/fr.rs +++ b/bn254/src/fields/fr.rs @@ -1,103 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - fields::*, -}; +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; -pub type Fr = Fp256; - -pub struct FrParameters; - -impl Fp256Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 28; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 7164790868263648668u64, - 11685701338293206998u64, - 6216421865291908056u64, - 1756667274303109607u64, - ]); -} -impl FpParameters for FrParameters { - /// MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 4891460686036598785u64, - 2896914383306846353u64, - 13281191951274694749u64, - 3486998266802970665u64, - ]); - - const MODULUS_BITS: u32 = 254; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 2; - - /// R = pow(2, 256) % MODULUS - /// = 6350874878119819312338956282401532410528162663560392320966563075034087161851 - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 12436184717236109307u64, - 3962172157175319849u64, - 7381016538464732718u64, - 1011752739694698287u64, - ]); - - /// R2 = R * R % MODULUS - /// = 944936681149208446651664254269745548490766851729442924617792859073125903783 - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 1997599621687373223u64, - 6052339484930628067u64, - 10108755138030829701u64, - 150537098327114917u64, - ]); - - /// INV = (-MODULUS) ^ {-1} % pow(2, 64) = 14042775128853446655 - const INV: u64 = 14042775128853446655u64; - - /// GENERATOR = 5 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 1949230679015292902u64, - 16913946402569752895u64, - 5177146667339417225u64, - 1571765431670520771u64, - ]); - - /// (MODULUS - 1)/2 = - /// 10944121435919637611123202872628637544274182200208017171849102093287904247808 - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xa1f0fac9f8000000, - 0x9419f4243cdcb848, - 0xdc2822db40c0ac2e, - 0x183227397098d014, - ]); - - // T and T_MINUS_ONE_DIV_TWO, where r - 1 = 2^s * t - - /// T = (MODULUS - 1) / 2^s = - /// 81540058820840996586704275553141814055101440848469862132140264610111 - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0x9b9709143e1f593f, - 0x181585d2833e8487, - 0x131a029b85045b68, - 0x30644e72e, - ]); - - /// (T - 1) / 2 = - /// 40770029410420498293352137776570907027550720424234931066070132305055 - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xcdcb848a1f0fac9f, - 0x0c0ac2e9419f4243, - 0x098d014dc2822db4, - 0x183227397, - ]); -} +#[derive(MontConfig)] +#[modulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"] +#[generator = "5"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/bn254/src/fields/tests.rs b/bn254/src/fields/tests.rs index 1376294..7db7426 100644 --- a/bn254/src/fields/tests.rs +++ b/bn254/src/fields/tests.rs @@ -1,9 +1,9 @@ +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{ biginteger::{BigInt, BigInteger, BigInteger256}, - fields::{ - fp6_3over2::Fp6Parameters, FftField, FftParameters, Field, FpParameters, PrimeField, - SquareRootField, - }, + fields::{FftField, Field, Fp6Config, PrimeField, SquareRootField}, One, UniformRand, Zero, }; use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; @@ -13,12 +13,9 @@ use core::{ ops::{AddAssign, MulAssign, SubAssign}, }; -use crate::{Fq, Fq12, Fq2, Fq6, Fq6Parameters, FqParameters, Fr}; -use ark_algebra_test_templates::{ - fields::*, generate_field_serialization_test, generate_field_test, -}; +use crate::{Fq, Fq12, Fq2, Fq6, Fq6Config, FqConfig, Fr, FrConfig}; -generate_field_test!(bn254; fq2; fq6; fq12;); +generate_field_test!(bn254; fq2; fq6; fq12; mont(4, 4); ); generate_field_serialization_test!(bn254; fq2; fq6; fq12;); #[test] @@ -28,14 +25,14 @@ fn test_fq_repr_from() { #[test] fn test_fq_repr_is_odd() { - assert!(!BigInteger256::from(0).is_odd()); - assert!(BigInteger256::from(0).is_even()); - assert!(BigInteger256::from(1).is_odd()); - assert!(!BigInteger256::from(1).is_even()); - assert!(!BigInteger256::from(324834872).is_odd()); - assert!(BigInteger256::from(324834872).is_even()); - assert!(BigInteger256::from(324834873).is_odd()); - assert!(!BigInteger256::from(324834873).is_even()); + assert!(!BigInteger256::from(0u64).is_odd()); + assert!(BigInteger256::from(0u64).is_even()); + assert!(BigInteger256::from(1u64).is_odd()); + assert!(!BigInteger256::from(1u64).is_even()); + assert!(!BigInteger256::from(324834872u64).is_odd()); + assert!(BigInteger256::from(324834872u64).is_even()); + assert!(BigInteger256::from(324834873u64).is_odd()); + assert!(!BigInteger256::from(324834873u64).is_even()); } #[test] @@ -47,9 +44,9 @@ fn test_fq_repr_is_zero() { #[test] fn test_fq_repr_num_bits() { - let mut a = BigInteger256::from(0); + let mut a = BigInteger256::from(0u64); assert_eq!(0, a.num_bits()); - a = BigInteger256::from(1); + a = BigInteger256::from(1u64); for i in 1..257 { assert_eq!(i, a.num_bits()); a.mul2(); @@ -59,34 +56,33 @@ fn test_fq_repr_num_bits() { #[test] fn test_fq_num_bits() { - assert_eq!(FqParameters::MODULUS_BITS, 254); - assert_eq!(FqParameters::CAPACITY, 253); + assert_eq!(Fq::MODULUS_BIT_SIZE, 254); } #[test] fn test_fq_root_of_unity() { - assert_eq!(FqParameters::TWO_ADICITY, 1); + assert_eq!(Fq::TWO_ADICITY, 1); assert_eq!( - Fq::multiplicative_generator().pow([ + Fq::GENERATOR.pow([ 0x9e10460b6c3e7ea3, 0xcbc0b548b438e546, 0xdc2822db40c0ac2e, 0x183227397098d014, ]), - Fq::two_adic_root_of_unity() + Fq::TWO_ADIC_ROOT_OF_UNITY ); assert_eq!( - Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]), + Fq::TWO_ADIC_ROOT_OF_UNITY.pow([1 << Fq::TWO_ADICITY]), Fq::one() ); - assert!(Fq::multiplicative_generator().sqrt().is_none()); + assert!(Fq::GENERATOR.sqrt().is_none()); } #[test] fn test_fq_ordering() { // BigInteger256's ordering is well-tested, but we still need to make sure the // Fq elements aren't being compared in Montgomery form. - for i in 0..100 { + for i in 0..100u64 { assert!(Fq::from(BigInteger256::from(i + 1)) > Fq::from(BigInteger256::from(i))); } } @@ -99,11 +95,11 @@ fn test_fq_legendre() { assert_eq!(Zero, Fq::zero().legendre()); assert_eq!( QuadraticResidue, - Fq::from(BigInteger256::from(4)).legendre() + Fq::from(BigInteger256::from(4u64)).legendre() ); assert_eq!( QuadraticNonResidue, - Fq::from(BigInteger256::from(5)).legendre() + Fq::from(BigInteger256::from(5u64)).legendre() ); } @@ -144,7 +140,7 @@ fn test_fq2_legendre() { // i^2 = -1 let mut m1 = -Fq2::one(); assert_eq!(QuadraticResidue, m1.legendre()); - m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1); + m1 = Fq6Config::mul_fp2_by_nonresidue(&m1); assert_eq!(QuadraticNonResidue, m1.legendre()); } diff --git a/bn254/src/lib.rs b/bn254/src/lib.rs old mode 100644 new mode 100755 index a2374f0..731193d --- a/bn254/src/lib.rs +++ b/bn254/src/lib.rs @@ -20,14 +20,17 @@ //! //! //! Curve information: -//! * Base field: q = 21888242871839275222246405745257275088696311157297823662689037894645226208583 -//! * Scalar field: r = 21888242871839275222246405745257275088548364400416034343698204186575808495617 +//! * Base field: q = +//! 21888242871839275222246405745257275088696311157297823662689037894645226208583 +//! * Scalar field: r = +//! 21888242871839275222246405745257275088548364400416034343698204186575808495617 //! * valuation(q - 1, 2) = 1 //! * valuation(r - 1, 2) = 28 //! * G1 curve equation: y^2 = x^3 + 3 //! * G2 curve equation: y^2 = x^3 + B, where -//! * B = 3/(u+9) where Fq2 is represented as Fq\[u\]/(u^2+1) -//! = Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373, 266929791119991161246907387137283842545076965332900288569378510910307636690) +//! * B = 3/(u+9) where Fq2 is represented as Fq\[u\]/(u^2+1) = +//! Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373, +//! 266929791119991161246907387137283842545076965332900288569378510910307636690) #[cfg(feature = "curve")] mod curves; diff --git a/bw6_761/scripts/base_field.sage b/bw6_761/scripts/base_field.sage new file mode 100644 index 0000000..a44fafb --- /dev/null +++ b/bw6_761/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/bw6_761/scripts/scalar_field.sage b/bw6_761/scripts/scalar_field.sage new file mode 100644 index 0000000..6d9f4a7 --- /dev/null +++ b/bw6_761/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/bw6_761/src/curves/g1.rs b/bw6_761/src/curves/g1.rs index 4d40d12..c35a9a5 100644 --- a/bw6_761/src/curves/g1.rs +++ b/bw6_761/src/curves/g1.rs @@ -1,9 +1,10 @@ -use crate::{Fq, Fr}; use ark_ec::{ models::{ModelParameters, SWModelParameters}, short_weierstrass_jacobian::{GroupAffine, GroupProjective}, }; -use ark_ff::field_new; +use ark_ff::MontFp; + +use crate::{Fq, Fr}; pub type G1Affine = GroupAffine; pub type G1Projective = GroupProjective; @@ -29,19 +30,15 @@ impl ModelParameters for Parameters { /// COFACTOR^(-1) mod r = /// 91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804"); + const COFACTOR_INV: Fr = MontFp!(Fr, "91141326767669940707819291241958318717982251277713150053234367522357946997763584490607453720072232540829942217804"); } impl SWModelParameters for Parameters { /// COEFF_A = 0 - #[rustfmt::skip] - - const COEFF_A: Fq = field_new!(Fq, "0"); + const COEFF_A: Fq = MontFp!(Fq, "0"); /// COEFF_B = -1 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "-1"); + const COEFF_B: Fq = MontFp!(Fq, "-1"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -55,10 +52,8 @@ impl SWModelParameters for Parameters { /// G1_GENERATOR_X = /// 6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237 -#[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = field_new!(Fq, "6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237"); +pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237"); /// G1_GENERATOR_Y = /// 2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099 -#[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099"); +pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099"); diff --git a/bw6_761/src/curves/g2.rs b/bw6_761/src/curves/g2.rs index 7fe2e17..7bd0205 100644 --- a/bw6_761/src/curves/g2.rs +++ b/bw6_761/src/curves/g2.rs @@ -1,9 +1,10 @@ -use crate::{Fq, Fr}; use ark_ec::{ models::{ModelParameters, SWModelParameters}, short_weierstrass_jacobian::{GroupAffine, GroupProjective}, }; -use ark_ff::field_new; +use ark_ff::MontFp; + +use crate::{Fq, Fr}; pub type G2Affine = GroupAffine; pub type G2Projective = GroupProjective; @@ -29,23 +30,20 @@ impl ModelParameters for Parameters { /// COFACTOR^(-1) mod r = /// 214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124"); + const COFACTOR_INV: Fr = MontFp!(Fr, "214911522365886453591244899095480747723790054550866810551297776298664428889000553861210287833206024638187939842124"); } impl SWModelParameters for Parameters { /// COEFF_A = 0 - #[rustfmt::skip] - - const COEFF_A: Fq = field_new!(Fq, "0"); + const COEFF_A: Fq = MontFp!(Fq, "0"); /// COEFF_B = 4 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "4"); + const COEFF_B: Fq = MontFp!(Fq, "4"); /// 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(_elem: &Self::BaseField) -> Self::BaseField { use ark_ff::Zero; @@ -55,10 +53,8 @@ impl SWModelParameters for Parameters { /// G2_GENERATOR_X = /// 6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428 -#[rustfmt::skip] -pub const G2_GENERATOR_X: Fq = field_new!(Fq, "6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428"); +pub const G2_GENERATOR_X: Fq = MontFp!(Fq, "6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428"); /// G2_GENERATOR_Y = /// 562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041 -#[rustfmt::skip] -pub const G2_GENERATOR_Y: Fq = field_new!(Fq, "562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041"); +pub const G2_GENERATOR_Y: Fq = MontFp!(Fq, "562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041"); diff --git a/bw6_761/src/curves/mod.rs b/bw6_761/src/curves/mod.rs index ee80983..d178e31 100644 --- a/bw6_761/src/curves/mod.rs +++ b/bw6_761/src/curves/mod.rs @@ -1,10 +1,11 @@ -use crate::*; use ark_ec::{ bw6, bw6::{BW6Parameters, TwistType, BW6}, }; use ark_ff::{biginteger::BigInteger768 as BigInteger, BigInt}; +use crate::*; + pub mod g1; pub mod g2; @@ -47,8 +48,8 @@ impl BW6Parameters for Parameters { const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = false; const TWIST_TYPE: TwistType = TwistType::M; type Fp = Fq; - type Fp3Params = Fq3Parameters; - type Fp6Params = Fq6Parameters; + type Fp3Config = Fq3Config; + type Fp6Config = Fq6Config; type G1Parameters = g1::Parameters; type G2Parameters = g2::Parameters; } diff --git a/bw6_761/src/curves/tests.rs b/bw6_761/src/curves/tests.rs index 295c268..063d603 100644 --- a/bw6_761/src/curves/tests.rs +++ b/bw6_761/src/curves/tests.rs @@ -1,15 +1,13 @@ +use ark_algebra_test_templates::{ + curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*, +}; use ark_ec::{AffineCurve, PairingEngine}; use ark_ff::{Field, One, PrimeField}; use ark_std::{rand::Rng, test_rng}; +use core::ops::MulAssign; use crate::*; -use ark_algebra_test_templates::{ - curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*, -}; - -use core::ops::MulAssign; - generate_g1_test!(bw6_761; curve_tests; sw_tests;); generate_g2_test!(bw6_761; curve_tests; sw_tests;); generate_bilinearity_test!(BW6_761, Fq6); diff --git a/bw6_761/src/fields/fq.rs b/bw6_761/src/fields/fq.rs index d3b30b8..365e8d9 100644 --- a/bw6_761/src/fields/fq.rs +++ b/bw6_761/src/fields/fq.rs @@ -1,175 +1,10 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger768 as BigInteger}, - field_new, - fields::{FftParameters, Fp768, Fp768Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp768, MontBackend, MontConfig, MontFp}; -pub type Fq = Fp768; +#[derive(MontConfig)] +#[modulus = "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299"] +#[generator = "2"] +pub struct FqConfig; +pub type Fq = Fp768>; -pub struct FqParameters; - -pub const FQ_ONE: Fq = field_new!(Fq, "1"); -pub const FQ_ZERO: Fq = field_new!(Fq, "0"); - -impl Fp768Parameters for FqParameters {} -impl FftParameters for FqParameters { - type BigInt = BigInteger; - - // The internal representation of this type is six 64-bit unsigned - // integers in little-endian order. Values are always in - // Montgomery form; i.e., Scalar(a) = aR mod p, with R=2^768. - - // (MODULUS - 1) % 2^TWO_ADICITY == 0 - const TWO_ADICITY: u32 = 1; - - // least_quadratic_nonresidue(MODULUS) in Sage. - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 17481284903592032950u64, - 10104133845767975835u64, - 8607375506753517913u64, - 13706168424391191299u64, - 9580010308493592354u64, - 14241333420363995524u64, - 6665632285037357566u64, - 5559902898979457045u64, - 15504799981718861253u64, - 8332096944629367896u64, - 18005297320867222879u64, - 58811391084848524u64, - ]); -} -impl FpParameters for FqParameters { - /// MODULUS = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0xf49d00000000008b, - 0xe6913e6870000082, - 0x160cf8aeeaf0a437, - 0x98a116c25667a8f8, - 0x71dcd3dc73ebff2e, - 0x8689c8ed12f9fd90, - 0x03cebaff25b42304, - 0x707ba638e584e919, - 0x528275ef8087be41, - 0xb926186a81d14688, - 0xd187c94004faff3e, - 0x122e824fb83ce0a - ]); - - const MODULUS_BITS: u32 = 761; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - // gap to 64-bit machine word - const REPR_SHAVE_BITS: u32 = 7; - - // 2^768 % MODULUS - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 144959613005956565u64, - 6509995272855063783u64, - 11428286765660613342u64, - 15738672438262922740u64, - 17071399330169272331u64, - 13899911246788437003u64, - 12055474021000362245u64, - 2545351818702954755u64, - 8887388221587179644u64, - 5009280847225881135u64, - 15539704305423854047u64, - 23071597697427581u64, - ]); - - // R^2 - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 14305184132582319705u64, - 8868935336694416555u64, - 9196887162930508889u64, - 15486798265448570248u64, - 5402985275949444416u64, - 10893197322525159598u64, - 3204916688966998390u64, - 12417238192559061753u64, - 12426306557607898622u64, - 1305582522441154384u64, - 10311846026977660324u64, - 48736111365249031u64, - ]); - - // (-1/MODULUS) % 2^64 - const INV: u64 = 744663313386281181u64; - - /// GENERATOR = 2 - // primitive_root(MODULUS) - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 289919226011913130u64, - 13019990545710127566u64, - 4409829457611675068u64, - 13030600802816293865u64, - 15696054586628993047u64, - 9353078419867322391u64, - 5664203968291172875u64, - 5090703637405909511u64, - 17774776443174359288u64, - 10018561694451762270u64, - 12632664537138156478u64, - 46143195394855163u64, - ]); - - // (MODULUS - 1) / 2 - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x7a4e800000000045, - 0xf3489f3438000041, - 0x0b067c577578521b, - 0x4c508b612b33d47c, - 0x38ee69ee39f5ff97, - 0x4344e476897cfec8, - 0x81e75d7f92da1182, - 0xb83dd31c72c2748c, - 0x29413af7c043df20, - 0x5c930c3540e8a344, - 0x68c3e4a0027d7f9f, - 0x9174127dc1e705, - ]); - - // T = - // 3445725192157866269698394841137828771239834456268075054756895080104811711121745868043841591644705843820432283876893306725580879560277123879674755849562650799475802549689254425186271815711798397975949850214984556421382456559534149 - // (MODULUS - 1) / 2 ^ TWO_ADICITY - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0x7a4e800000000045, - 0xf3489f3438000041, - 0x0b067c577578521b, - 0x4c508b612b33d47c, - 0x38ee69ee39f5ff97, - 0x4344e476897cfec8, - 0x81e75d7f92da1182, - 0xb83dd31c72c2748c, - 0x29413af7c043df20, - 0x5c930c3540e8a344, - 0x68c3e4a0027d7f9f, - 0x9174127dc1e705, - ]); - - // (T - 1)/2 = - // 1722862596078933134849197420568914385619917228134037527378447540052405855560872934021920795822352921910216141938446653362790439780138561939837377924781325399737901274844627212593135907855899198987974925107492278210691228279767074 - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xbd27400000000022, - 0xf9a44f9a1c000020, - 0x05833e2bbabc290d, - 0xa62845b09599ea3e, - 0x1c7734f71cfaffcb, - 0x21a2723b44be7f64, - 0x40f3aebfc96d08c1, - 0x5c1ee98e39613a46, - 0x14a09d7be021ef90, - 0xae49861aa07451a2, - 0xb461f250013ebfcf, - 0x48ba093ee0f382, - ]); -} +pub const FQ_ONE: Fq = MontFp!(Fq, "1"); +pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); diff --git a/bw6_761/src/fields/fq3.rs b/bw6_761/src/fields/fq3.rs index 0c49955..91037d8 100644 --- a/bw6_761/src/fields/fq3.rs +++ b/bw6_761/src/fields/fq3.rs @@ -1,6 +1,6 @@ use ark_ff::{ - field_new, - fields::fp3::{Fp3, Fp3Parameters}, + fields::fp3::{Fp3, Fp3Config}, + CubicExt, MontFp, }; use crate::{ @@ -8,24 +8,23 @@ use crate::{ Fq, }; -pub type Fq3 = Fp3; +pub type Fq3 = Fp3; -pub struct Fq3Parameters; +pub struct Fq3Config; -impl Fp3Parameters for Fq3Parameters { +impl Fp3Config for Fq3Config { type Fp = Fq; /// NONRESIDUE = -4 // Fq3 = Fq\[u\]/u^3+4 - #[rustfmt::skip] - const NONRESIDUE: Fq = field_new!(Fq, "-4"); + const NONRESIDUE: Fq = MontFp!(Fq, "-4"); // (MODULUS^3 - 1) % 2^TWO_ADICITY == 0 const TWO_ADICITY: u32 = 1; // (T-1)/2 with T = (MODULUS^3-1) / 2^TWO_ADICITY #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[ + const TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[ 0xb5e7c000000a3eac, 0xf79b99dbf41cf4ab, 0xe9372b1919e55ee5, @@ -65,27 +64,24 @@ impl Fp3Parameters for Fq3Parameters { ]; // NONRESIDUE^T % q - #[rustfmt::skip] - const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = ( - field_new!(Fq, "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068298"), + const QUADRATIC_NONRESIDUE_TO_T: Fq3 = CubicExt!( + MontFp!(Fq, "6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068298"), FQ_ZERO, FQ_ZERO, ); // NQR ^ (MODULUS^i - 1)/3, i=0,1,2 with NQR = u = (0,1,0) - #[rustfmt::skip] const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[ FQ_ONE, - field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"), - field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"), + MontFp!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"), + MontFp!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"), ]; // NQR ^ (2*MODULUS^i - 2)/3, i=0,1,2 with NQR = u = (0,1,0) - #[rustfmt::skip] const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[ FQ_ONE, - field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"), - field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"), + MontFp!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"), + MontFp!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"), ]; #[inline(always)] diff --git a/bw6_761/src/fields/fq6.rs b/bw6_761/src/fields/fq6.rs index f9351b5..e3f1cab 100644 --- a/bw6_761/src/fields/fq6.rs +++ b/bw6_761/src/fields/fq6.rs @@ -1,27 +1,26 @@ -use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO}; use ark_ff::{ - field_new, - fields::fp6_2over3::{Fp6, Fp6Parameters}, + fields::fp6_2over3::{Fp6, Fp6Config}, + CubicExt, MontFp, }; -pub type Fq6 = Fp6; +use crate::{Fq, Fq3, Fq3Config, FQ_ONE, FQ_ZERO}; -pub struct Fq6Parameters; +pub type Fq6 = Fp6; -impl Fp6Parameters for Fq6Parameters { - type Fp3Params = Fq3Parameters; +pub struct Fq6Config; + +impl Fp6Config for Fq6Config { + type Fp3Config = Fq3Config; /// NONRESIDUE = (0, 1, 0) - #[rustfmt::skip] - const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO); + const NONRESIDUE: Fq3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO); - #[rustfmt::skip] const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[ - field_new!(Fq, "1"), - field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775649"), - field_new!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"), - field_new!(Fq, "-1"), - field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"), - field_new!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292651"), + MontFp!(Fq, "1"), + MontFp!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775649"), + MontFp!(Fq, "4922464560225523242118178942575080391082002530232324381063048548642823052024664478336818169867474395270858391911405337707247735739826664939444490469542109391530482826728203582549674992333383150446779312029624171857054392282775648"), + MontFp!(Fq, "-1"), + MontFp!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650"), + MontFp!(Fq, "1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292651"), ]; } diff --git a/bw6_761/src/fields/fr.rs b/bw6_761/src/fields/fr.rs index 63c94bb..bc1fc31 100644 --- a/bw6_761/src/fields/fr.rs +++ b/bw6_761/src/fields/fr.rs @@ -1 +1 @@ -pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters}; +pub use ark_bls12_377::{Fq as Fr, FqConfig as FrConfig}; diff --git a/bw6_761/src/fields/tests.rs b/bw6_761/src/fields/tests.rs index d0de0bd..b1dc786 100644 --- a/bw6_761/src/fields/tests.rs +++ b/bw6_761/src/fields/tests.rs @@ -1,14 +1,12 @@ +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; use crate::*; -use ark_algebra_test_templates::{ - fields::*, generate_field_serialization_test, generate_field_test, -}; - -use core::ops::{AddAssign, MulAssign, SubAssign}; - -generate_field_test!(bw6_761; fq3; fq6;); +generate_field_test!(bw6_761; fq3; fq6; mont(12, 6); ); generate_field_serialization_test!(bw6_761;); diff --git a/bw6_761/src/lib.rs b/bw6_761/src/lib.rs old mode 100644 new mode 100755 index 117bab1..a45f46c --- a/bw6_761/src/lib.rs +++ b/bw6_761/src/lib.rs @@ -9,9 +9,10 @@ #![forbid(unsafe_code)] //! This library implements the BW6_761 curve generated in [\[EG20\]](https://eprint.iacr.org/2020/351). -//! The name denotes that it is a curve generated using the Brezing--Weng method, and that -//! its embedding degree is 6. -//! The main feature of this curve is that the scalar field equals the base field of the BLS12_377 curve. +//! The name denotes that it is a curve generated using the Brezing--Weng +//! method, and that its embedding degree is 6. +//! The main feature of this curve is that the scalar field equals the base +//! field of the BLS12_377 curve. //! //! Curve information: //! * Base field: q = 6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299 diff --git a/cp6_782/scripts/base_field.sage b/cp6_782/scripts/base_field.sage new file mode 100644 index 0000000..9e8cadb --- /dev/null +++ b/cp6_782/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/cp6_782/scripts/scalar_field.sage b/cp6_782/scripts/scalar_field.sage new file mode 100644 index 0000000..6d9f4a7 --- /dev/null +++ b/cp6_782/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/cp6_782/src/curves/g1.rs b/cp6_782/src/curves/g1.rs index bb42478..c920a3f 100644 --- a/cp6_782/src/curves/g1.rs +++ b/cp6_782/src/curves/g1.rs @@ -2,7 +2,7 @@ use ark_ec::{ models::{ModelParameters, SWModelParameters}, short_weierstrass_jacobian::{GroupAffine, GroupProjective}, }; -use ark_ff::field_new; +use ark_ff::MontFp; use crate::{Fq, Fr}; @@ -31,18 +31,15 @@ impl ModelParameters for Parameters { /// COFACTOR^(-1) mod r = /// 163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788"); + const COFACTOR_INV: Fr = MontFp!(Fr, "163276846538158998893990986356139314746223949404500031940624325017036397274793417940375498603127780919653358641788"); } impl SWModelParameters for Parameters { /// COEFF_A = 5 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "5"); + const COEFF_A: Fq = MontFp!(Fq, "5"); /// COEFF_B = 17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414"); + const COEFF_B: Fq = MontFp!(Fq, "17764315118651679038286329069295091506801468118146712649886336045535808055361274148466772191243305528312843236347777260247138934336850548243151534538734724191505953341403463040067571652261229308333392040104884438208594329793895206056414"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -51,10 +48,8 @@ impl SWModelParameters for Parameters { /// G1_GENERATOR_X = /// 5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646 -#[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = field_new!(Fq, "5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646"); +pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "5511163824921585887915590525772884263960974614921003940645351443740084257508990841338974915037175497689287870585840954231884082785026301437744745393958283053278991955159266640440849940136976927372133743626748847559939620888818486853646"); /// G1_GENERATOR_Y = /// 7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443 -#[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443"); +pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "7913123550914612057135582061699117755797758113868200992327595317370485234417808273674357776714522052694559358668442301647906991623400754234679697332299689255516547752391831738454121261248793568285885897998257357202903170202349380518443"); diff --git a/cp6_782/src/curves/g2.rs b/cp6_782/src/curves/g2.rs index 419ece5..1b345f7 100644 --- a/cp6_782/src/curves/g2.rs +++ b/cp6_782/src/curves/g2.rs @@ -2,7 +2,7 @@ use ark_ec::{ models::{ModelParameters, SWModelParameters}, short_weierstrass_jacobian::{GroupAffine, GroupProjective}, }; -use ark_ff::field_new; +use ark_ff::{CubicExt, MontFp}; use crate::{Fq, Fq3, Fr, FQ_ZERO}; @@ -55,25 +55,18 @@ impl ModelParameters for Parameters { /// COFACTOR^(-1) mod r = /// 45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598"); + const COFACTOR_INV: Fr = MontFp!(Fr, "45586359457219724873147353901735745013467692594291916855200979604570630929674383405372210802279573887880950375598"); } impl SWModelParameters for Parameters { /// COEFF_A = (0, 0, COEFF_A * TWIST^2) = (0, 0, 5) - #[rustfmt::skip] - const COEFF_A: Fq3 = field_new!(Fq3, - FQ_ZERO, - FQ_ZERO, - field_new!(Fq, "5"), - ); + const COEFF_A: Fq3 = CubicExt!(FQ_ZERO, FQ_ZERO, MontFp!(Fq, "5"),); /// COEFF_B = (G1::COEFF_B * TWIST^3, 0, 0) = /// (7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612, /// 0, 0) - #[rustfmt::skip] - const COEFF_B: Fq3 = field_new!(Fq3, - field_new!(Fq, "7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612"), + const COEFF_B: Fq3 = CubicExt!( + MontFp!(Fq, "7237353553714858194254855835825640240663090882935418626687402315497764195116318527743248304684159666286416318482685337633828994152723793439622384740540789612754127688659139509552568164770448654259255628317166934203899992395064470477612"), FQ_ZERO, FQ_ZERO, ); @@ -83,37 +76,29 @@ impl SWModelParameters for Parameters { (G2_GENERATOR_X, G2_GENERATOR_Y); } -const G2_GENERATOR_X: Fq3 = - field_new!(Fq3, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2); -const G2_GENERATOR_Y: Fq3 = - field_new!(Fq3, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2); +const G2_GENERATOR_X: Fq3 = CubicExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2); +const G2_GENERATOR_Y: Fq3 = CubicExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2); /// G2_GENERATOR_X_C0 = /// 13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338 -#[rustfmt::skip] -pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338"); +pub const G2_GENERATOR_X_C0: Fq = MontFp!(Fq, "13426761183630949215425595811885033211332897733228446437546263564078445562454176776915160094418980045665397361295624472103734543457352048745726512354895954850428989867542989474136256025045975283415690491751906307188562464175510373683338"); /// G2_GENERATOR_X_C1 = /// 20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610 -#[rustfmt::skip] -pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610"); +pub const G2_GENERATOR_X_C1: Fq = MontFp!(Fq, "20471601555918880743198170952645906008198510944268658573129351735028343217532386920456705632337352161031960990613816401042894531220068552819818037605513359562118363589199569321421558696125646867661360498323171027455638052943806292028610"); /// G2_GENERATOR_X_C2 = /// 3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980 -#[rustfmt::skip] -pub const G2_GENERATOR_X_C2: Fq = field_new!(Fq, "3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980"); +pub const G2_GENERATOR_X_C2: Fq = MontFp!(Fq, "3905053196875761830053608605277158152930144841844497593936739534395003062685449846381431331169369910535935138116320442345524758217411779027270883193856999691582831339845600938304719916501940381093815781408183227875600753651697934495980"); /// G2_GENERATOR_Y_C0 = /// 8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243 -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243"); +pub const G2_GENERATOR_Y_C0: Fq = MontFp!(Fq, "8567517639523571619872938228644013584947463594196306323477160496987712111576624702939472765993995586889532559039169098780892505598589581147768095093536988446010255611523736706017580686335404469207486594272103717837888228343074699140243"); /// G2_GENERATOR_Y_C1 = /// 3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752 -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752"); +pub const G2_GENERATOR_Y_C1: Fq = MontFp!(Fq, "3890537069205870914984502594450293167889863914413852788876350245583932846980126025043974070704295857226211547108005650399870458089721518559480870503159804530091559886149680718531004778697982910253701559194337987238111062202037698927752"); /// G2_GENERATOR_Y_C2 = /// 10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721 -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C2: Fq = field_new!(Fq, "10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721"); +pub const G2_GENERATOR_Y_C2: Fq = MontFp!(Fq, "10936269922612615564271188303104593362724754284143779051599749016735041389483971486958818324356025479751246744831831158558101688599198721653921723013062333636402617118847009085485166284126970598561393411916461254016145116183331671450721"); diff --git a/cp6_782/src/curves/mod.rs b/cp6_782/src/curves/mod.rs index 69350ea..712e665 100644 --- a/cp6_782/src/curves/mod.rs +++ b/cp6_782/src/curves/mod.rs @@ -1,9 +1,8 @@ use ark_ec::{models::SWModelParameters, PairingEngine}; use ark_ff::{ biginteger::BigInteger832, - field_new, fields::{BitIteratorBE, Field}, - BigInt, One, + BigInt, CubicExt, One, }; use crate::{Fq, Fq3, Fq6, Fr, FQ_ONE, FQ_ZERO}; @@ -154,7 +153,7 @@ impl CP6_782 { } /// TWIST = (0, 1, 0) -pub const TWIST: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO); +pub const TWIST: Fq3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO); /// ATE_IS_LOOP_COUNT_NEG = false pub const ATE_IS_LOOP_COUNT_NEG: bool = false; diff --git a/cp6_782/src/curves/tests.rs b/cp6_782/src/curves/tests.rs index 8121153..f96607f 100644 --- a/cp6_782/src/curves/tests.rs +++ b/cp6_782/src/curves/tests.rs @@ -1,15 +1,13 @@ +use ark_algebra_test_templates::{ + curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*, +}; use ark_ec::{AffineCurve, PairingEngine}; use ark_ff::{Field, One, PrimeField}; use ark_std::{rand::Rng, test_rng}; +use core::ops::MulAssign; use crate::*; -use ark_algebra_test_templates::{ - curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, groups::*, msm::*, -}; - -use core::ops::MulAssign; - generate_g1_test!(cp6_782; curve_tests; sw_tests;); generate_g2_test!(cp6_782; curve_tests; sw_tests;); generate_bilinearity_test!(CP6_782, Fq6); diff --git a/cp6_782/src/fields/fq.rs b/cp6_782/src/fields/fq.rs index 82368fc..d5d1e5b 100644 --- a/cp6_782/src/fields/fq.rs +++ b/cp6_782/src/fields/fq.rs @@ -1,169 +1,10 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger832 as BigInteger}, - fields::{FftParameters, Fp832, Fp832Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp832, MontBackend, MontConfig, MontFp}; -pub type Fq = Fp832; +#[derive(MontConfig)] +#[modulus = "22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577"] +#[generator = "13"] +pub struct FqConfig; +pub type Fq = Fp832>; -pub struct FqParameters; - -pub const FQ_ONE: Fq = ark_ff::field_new!(Fq, "1"); -pub const FQ_ZERO: Fq = ark_ff::field_new!(Fq, "0"); - -impl Fp832Parameters for FqParameters {} -impl FftParameters for FqParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 3; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 18044746167194862600u64, - 63590321303744709u64, - 5009346151370959890u64, - 2859114157767503991u64, - 8301813204852325413u64, - 5629414263664332594u64, - 2637340888701394641u64, - 17433538052687852753u64, - 2230763098934759248u64, - 3785382115983092023u64, - 8895511354022222370u64, - 15792083141709071785u64, - 1328u64, - ]); -} -impl FpParameters for FqParameters { - /// MODULUS = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0xdace79b57b942ae9, - 0x545d85c16dfd424a, - 0xee135c065f4d26b7, - 0x9c2f764a12c4024b, - 0x1ad533049cfe6a39, - 0x52a3fb77c79c1320, - 0xab3596c8617c5792, - 0x830c728d80f9d78b, - 0x6a7223ee72023d07, - 0xbc5d176b746af026, - 0xe959283d8f526663, - 0xc4d2263babf8941f, - 0x3848, - ]); - - const MODULUS_BITS: u32 = 782; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 50; - - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 11190988450819017841u64, - 16170411717126802030u64, - 2265463223430229059u64, - 16946880912571045974u64, - 11155248462028513229u64, - 12855672356664541314u64, - 8489376931127408159u64, - 2655797810825538098u64, - 9648483887143916718u64, - 17514963461276738952u64, - 16777089214204267338u64, - 15649035958020076168u64, - 8659u64, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 13983406830510863714u64, - 17863856572171232656u64, - 1698388424046564526u64, - 1773634430448388392u64, - 8684647957094413275u64, - 3992637317298078843u64, - 18420879196616862245u64, - 3238482510270583127u64, - 7928200707794018216u64, - 10024831010452223910u64, - 9613847725664942650u64, - 15361265984156787358u64, - 7833u64, - ]); - - const INV: u64 = 14469047335842394791u64; - - /// GENERATOR = 13 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 16669393626057438558u64, - 1640520694378723217u64, - 1598646156981121135u64, - 12401834967100173388u64, - 2356467520877704673u64, - 14759118825104212161u64, - 5556628239575210651u64, - 5317520392768798654u64, - 16398429955031064995u64, - 3556102264904210145u64, - 8166834915717907988u64, - 11926665585800594452u64, - 11716u64, - ]); - - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x6d673cdabdca1574, - 0xaa2ec2e0b6fea125, - 0xf709ae032fa6935b, - 0xce17bb2509620125, - 0xd6a99824e7f351c, - 0x2951fdbbe3ce0990, - 0xd59acb6430be2bc9, - 0xc1863946c07cebc5, - 0x353911f739011e83, - 0xde2e8bb5ba357813, - 0xf4ac941ec7a93331, - 0x6269131dd5fc4a0f, - 0x1c24, - ]); - - // (T - 1)/2 = - // 1398117143679731058146671387906315933423474966581074036386468539227923378278626533764529938634242576261128410962740119034868607201414583335758422276643816405480145410934911750070786645716409577212967755581539567265673914343284832551598 - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xadace79b57b942ae, - 0x7545d85c16dfd424, - 0xbee135c065f4d26b, - 0x99c2f764a12c4024, - 0x1ad533049cfe6a3, - 0x252a3fb77c79c132, - 0xbab3596c8617c579, - 0x7830c728d80f9d78, - 0x66a7223ee72023d0, - 0x3bc5d176b746af02, - 0xfe959283d8f52666, - 0x8c4d2263babf8941, - 0x384, - ]); - - // T = - // 2796234287359462116293342775812631866846949933162148072772937078455846756557253067529059877268485152522256821925480238069737214402829166671516844553287632810960290821869823500141573291432819154425935511163079134531347828686569665103197 - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0x5b59cf36af72855d, - 0xea8bb0b82dbfa849, - 0x7dc26b80cbe9a4d6, - 0x3385eec942588049, - 0x35aa660939fcd47, - 0x4a547f6ef8f38264, - 0x7566b2d90c2f8af2, - 0xf0618e51b01f3af1, - 0xcd4e447dce4047a0, - 0x778ba2ed6e8d5e04, - 0xfd2b2507b1ea4ccc, - 0x189a44c7757f1283, - 0x709, - ]); -} +pub const FQ_ONE: Fq = MontFp!(Fq, "1"); +pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); diff --git a/cp6_782/src/fields/fq3.rs b/cp6_782/src/fields/fq3.rs index eb24287..116a4ae 100644 --- a/cp6_782/src/fields/fq3.rs +++ b/cp6_782/src/fields/fq3.rs @@ -1,25 +1,24 @@ -use crate::{fields::FQ_ZERO, Fq}; use ark_ff::{ - field_new, - fields::fp3::{Fp3, Fp3Parameters}, - Field, + fields::fp3::{Fp3, Fp3Config}, + CubicExt, Field, MontFp, }; -pub type Fq3 = Fp3; +use crate::{fields::FQ_ZERO, Fq}; + +pub type Fq3 = Fp3; -pub struct Fq3Parameters; +pub struct Fq3Config; -impl Fp3Parameters for Fq3Parameters { +impl Fp3Config for Fq3Config { type Fp = Fq; /// NONRESIDUE = 13 - #[rustfmt::skip] - const NONRESIDUE: Fq = field_new!(Fq, "13"); + const NONRESIDUE: Fq = MontFp!(Fq, "13"); const TWO_ADICITY: u32 = 3; #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[ + const TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[ 0x62730e2cd2029617, 0x660647f735cb88cf, 0x274359d60784f69d, @@ -59,25 +58,22 @@ impl Fp3Parameters for Fq3Parameters { 0x2b87fda171, ]; - #[rustfmt::skip] - const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = ( - field_new!(Fq, "5759691735434357221228070840130186543101559976323700017469395641639510585333061695996665166662748527158637897523704071820491869715512532675375604262649010727161924084052120196921150869218319839231115277876207074651754402338718419191428"), + const QUADRATIC_NONRESIDUE_TO_T: Fq3 = CubicExt!( + MontFp!(Fq, "5759691735434357221228070840130186543101559976323700017469395641639510585333061695996665166662748527158637897523704071820491869715512532675375604262649010727161924084052120196921150869218319839231115277876207074651754402338718419191428"), FQ_ZERO, FQ_ZERO, ); - #[rustfmt::skip] const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[ - field_new!(Fq, "1"), - field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"), - field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"), + MontFp!(Fq, "1"), + MontFp!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"), + MontFp!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"), ]; - #[rustfmt::skip] const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[ - field_new!(Fq, "1"), - field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"), - field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"), + MontFp!(Fq, "1"), + MontFp!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"), + MontFp!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"), ]; #[inline(always)] diff --git a/cp6_782/src/fields/fq6.rs b/cp6_782/src/fields/fq6.rs index 07b25ab..bd6f229 100644 --- a/cp6_782/src/fields/fq6.rs +++ b/cp6_782/src/fields/fq6.rs @@ -1,27 +1,26 @@ -use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO}; use ark_ff::{ - field_new, - fields::fp6_2over3::{Fp6, Fp6Parameters}, + fields::fp6_2over3::{Fp6, Fp6Config}, + CubicExt, MontFp, }; -pub type Fq6 = Fp6; +use crate::{Fq, Fq3, Fq3Config, FQ_ONE, FQ_ZERO}; -pub struct Fq6Parameters; +pub type Fq6 = Fp6; -impl Fp6Parameters for Fq6Parameters { - type Fp3Params = Fq3Parameters; +pub struct Fq6Config; + +impl Fp6Config for Fq6Config { + type Fp3Config = Fq3Config; /// NONRESIDUE = (0, 1, 0). - #[rustfmt::skip] - const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO); + const NONRESIDUE: Fq3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO); - #[rustfmt::skip] const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[ - field_new!(Fq, "1"), - field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756862"), - field_new!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"), - field_new!(Fq, "22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825576"), - field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"), - field_new!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068716"), + MontFp!(Fq, "1"), + MontFp!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756862"), + MontFp!(Fq, "2416169158604010336818399199316106389588878314690767988978701685873498866746813334102117883272276610365242925950967572554030909749205624998805208910209389668659757274773858916683688639755413288353778854399286396639505385648830027756861"), + MontFp!(Fq, "22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825576"), + MontFp!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068715"), + MontFp!(Fq, "19953705140271686593528343007184948545186721150606416593204794941773275185711211206130361134875604609812811649452874332003866805473427708373329547516091672819022569300184729084448897691707139947053705234905346679611277243843727293068716"), ]; } diff --git a/cp6_782/src/fields/fr.rs b/cp6_782/src/fields/fr.rs index 63c94bb..bc1fc31 100644 --- a/cp6_782/src/fields/fr.rs +++ b/cp6_782/src/fields/fr.rs @@ -1 +1 @@ -pub use ark_bls12_377::{Fq as Fr, FqParameters as FrParameters}; +pub use ark_bls12_377::{Fq as Fr, FqConfig as FrConfig}; diff --git a/cp6_782/src/fields/mod.rs b/cp6_782/src/fields/mod.rs index 2da6aa6..7bfd333 100644 --- a/cp6_782/src/fields/mod.rs +++ b/cp6_782/src/fields/mod.rs @@ -10,5 +10,5 @@ pub use self::fq3::*; pub mod fq6; pub use self::fq6::*; -#[cfg(all(feature = "cp6_782", test))] +#[cfg(test)] mod tests; diff --git a/cp6_782/src/fields/tests.rs b/cp6_782/src/fields/tests.rs index eb60f6c..01aa430 100644 --- a/cp6_782/src/fields/tests.rs +++ b/cp6_782/src/fields/tests.rs @@ -1,14 +1,12 @@ +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; use crate::*; -use ark_algebra_test_templates::{ - fields::*, generate_field_serialization_test, generate_field_test, -}; - -use core::ops::{AddAssign, MulAssign, SubAssign}; - -generate_field_test!(cp6_782; fq3; fq6;); +generate_field_test!(cp6_782; fq3; fq6; mont(13, 6); ); generate_field_serialization_test!(cp6_782;); diff --git a/cp6_782/src/lib.rs b/cp6_782/src/lib.rs old mode 100644 new mode 100755 index 2163fb7..bef4c04 --- a/cp6_782/src/lib.rs +++ b/cp6_782/src/lib.rs @@ -9,8 +9,9 @@ #![forbid(unsafe_code)] //! This library implements the CP6_782 curve generated in [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). -//! The name denotes that it was generated using the Cocks--Pinch method for the embedding degree 6. -//! The main feature of this curve is that the scalar field equals the base field of the BLS12_377 curve. +//! The name denotes that it was generated using the Cocks--Pinch method for the +//! embedding degree 6. The main feature of this curve is that the scalar field +//! equals the base field of the BLS12_377 curve. //! //! Curve information: //! * Base field: q = 22369874298875696930346742206501054934775599465297184582183496627646774052458024540232479018147881220178054575403841904557897715222633333372134756426301062487682326574958588001132586331462553235407484089304633076250782629492557320825577 diff --git a/curve-benches/benches/bn254.rs b/curve-benches/benches/bn254.rs index de9249a..2ee31fe 100644 --- a/curve-benches/benches/bn254.rs +++ b/curve-benches/benches/bn254.rs @@ -7,8 +7,8 @@ use ark_bn254::{ }; use ark_ec::{PairingEngine, ProjectiveCurve}; use ark_ff::{ - biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr}, - BigInteger, Field, PrimeField, SquareRootField, UniformRand, + biginteger::BigInteger256 as FrRepr, BigInteger, Field, PrimeField, SquareRootField, + UniformRand, }; mod g1 { diff --git a/curve-benches/benches/ed_on_bls12_381.rs b/curve-benches/benches/ed_on_bls12_381.rs index c3a58ba..3cb1db2 100644 --- a/curve-benches/benches/ed_on_bls12_381.rs +++ b/curve-benches/benches/ed_on_bls12_381.rs @@ -4,8 +4,8 @@ use ark_std::ops::{AddAssign, MulAssign, SubAssign}; use ark_ec::ProjectiveCurve; use ark_ed_on_bls12_381::{fq::Fq, fr::Fr, EdwardsAffine as GAffine, EdwardsProjective as G}; use ark_ff::{ - biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr}, - BigInteger, Field, PrimeField, SquareRootField, UniformRand, + biginteger::BigInteger256 as FrRepr, BigInteger, Field, PrimeField, SquareRootField, + UniformRand, }; mod g { diff --git a/curve-benches/benches/pallas.rs b/curve-benches/benches/pallas.rs index adbb392..effbe6f 100644 --- a/curve-benches/benches/pallas.rs +++ b/curve-benches/benches/pallas.rs @@ -3,8 +3,8 @@ use ark_std::ops::{AddAssign, MulAssign, SubAssign}; use ark_ec::ProjectiveCurve; use ark_ff::{ - biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr}, - BigInteger, Field, PrimeField, SquareRootField, UniformRand, + biginteger::BigInteger256 as FrRepr, BigInteger, Field, PrimeField, SquareRootField, + UniformRand, }; use ark_pallas::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G}; diff --git a/curve-benches/benches/vesta.rs b/curve-benches/benches/vesta.rs index 11a0fd4..9628fbe 100644 --- a/curve-benches/benches/vesta.rs +++ b/curve-benches/benches/vesta.rs @@ -3,8 +3,8 @@ use ark_std::ops::{AddAssign, MulAssign, SubAssign}; use ark_ec::ProjectiveCurve; use ark_ff::{ - biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr}, - BigInteger, Field, PrimeField, SquareRootField, UniformRand, + biginteger::BigInteger256 as FrRepr, BigInteger, Field, PrimeField, SquareRootField, + UniformRand, }; use ark_vesta::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G}; diff --git a/curve-benches/src/macros/ec.rs b/curve-benches/src/macros/ec.rs index 5711d01..fc37503 100644 --- a/curve-benches/src/macros/ec.rs +++ b/curve-benches/src/macros/ec.rs @@ -231,7 +231,7 @@ macro_rules! ec_bench { let g = <$projective>::rand(&mut rng).into_affine(); let v: Vec<_> = (0..SAMPLES).map(|_| g).collect(); let scalars: Vec<_> = (0..SAMPLES) - .map(|_| Fr::rand(&mut rng).into_repr()) + .map(|_| Fr::rand(&mut rng).into_bigint()) .collect(); b.bench_n(1, |b| { b.iter(|| ark_ec::msm::VariableBase::msm(&v, &scalars)); diff --git a/curve-benches/src/macros/field.rs b/curve-benches/src/macros/field.rs index a0c82fa..23de5d7 100644 --- a/curve-benches/src/macros/field.rs +++ b/curve-benches/src/macros/field.rs @@ -343,7 +343,7 @@ macro_rules! prime_field { let mut count = 0; b.iter(|| { let mut tmp = v[count].0; - n_fold!(tmp, v, add_nocarry, count); + n_fold!(tmp, v, add_with_carry, count); count = (count + 1) % SAMPLES; tmp }); @@ -369,7 +369,7 @@ macro_rules! prime_field { let mut count = 0; b.iter(|| { let mut tmp = v[count].0; - n_fold!(tmp, v, sub_noborrow, count); + n_fold!(tmp, v, sub_with_borrow, count); count = (count + 1) % SAMPLES; tmp; }); @@ -432,7 +432,7 @@ macro_rules! prime_field { let mut count = 0; b.iter(|| { count = (count + 1) % SAMPLES; - v[count].into_repr(); + v[count].into_bigint(); }); } @@ -442,7 +442,7 @@ macro_rules! prime_field { let mut rng = ark_std::test_rng(); let v: Vec<$f_repr_type> = (0..SAMPLES) - .map(|_| $f::rand(&mut rng).into_repr()) + .map(|_| $f::rand(&mut rng).into_bigint()) .collect(); let mut count = 0; diff --git a/curve-constraint-tests/src/lib.rs b/curve-constraint-tests/src/lib.rs old mode 100644 new mode 100755 index ed2c59d..349844d --- a/curve-constraint-tests/src/lib.rs +++ b/curve-constraint-tests/src/lib.rs @@ -5,8 +5,7 @@ pub mod fields { use ark_ff::{BitIteratorLE, Field, UniformRand}; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::{ConstraintSystem, SynthesisError}; - use ark_std::test_rng; - use ark_std::vec::Vec; + use ark_std::{test_rng, vec::Vec}; pub fn field_test() -> Result<(), SynthesisError> where @@ -235,7 +234,7 @@ pub mod curves { short_weierstrass_jacobian::GroupProjective as SWProjective, twisted_edwards_extended::GroupProjective as TEProjective, ProjectiveCurve, }; - use ark_ff::{BitIteratorLE, Field, FpParameters, One, PrimeField}; + use ark_ff::{BitIteratorLE, Field, One, PrimeField}; use ark_relations::r1cs::{ConstraintSystem, SynthesisError}; use ark_std::{test_rng, vec::Vec, UniformRand}; @@ -323,23 +322,22 @@ pub mod curves { } assert!(cs.is_satisfied().unwrap()); - let modulus = ::Params::MODULUS - .as_ref() - .to_vec(); + let modulus = ::MODULUS.as_ref().to_vec(); let mut max = modulus.clone(); for limb in &mut max { *limb = u64::MAX; } - let modulus_last_limb_bits = ::Params::MODULUS_BITS % 64; + let modulus_last_limb_bits = ::MODULUS_BIT_SIZE % 64; *max.last_mut().unwrap() >>= 64 - modulus_last_limb_bits; let scalars = [ - C::ScalarField::rand(&mut rng).into_repr().as_ref().to_vec(), - vec![u64::rand(&mut rng)], - (-C::ScalarField::one()).into_repr().as_ref().to_vec(), - ::Params::MODULUS + C::ScalarField::rand(&mut rng) + .into_bigint() .as_ref() .to_vec(), + vec![u64::rand(&mut rng)], + (-C::ScalarField::one()).into_bigint().as_ref().to_vec(), + ::MODULUS.as_ref().to_vec(), max, vec![0; 50], vec![1000012341233u64; 36], @@ -585,13 +583,13 @@ pub mod pairing { }; let (ans3_g, ans3_n) = { - let s_iter = BitIteratorLE::without_trailing_zeros(s.into_repr()) + let s_iter = BitIteratorLE::without_trailing_zeros(s.into_bigint()) .map(Boolean::constant) .collect::>(); let mut ans_g = P::pairing(a_prep_g, b_prep_g)?; let mut ans_n = E::pairing(a, b); - ans_n = ans_n.pow(s.into_repr()); + ans_n = ans_n.pow(s.into_bigint()); ans_g = ans_g.pow_le(&s_iter)?; (ans_g, ans_n) diff --git a/ed_on_bls12_377/scripts/base_field.sage b/ed_on_bls12_377/scripts/base_field.sage new file mode 100644 index 0000000..a4d06f0 --- /dev/null +++ b/ed_on_bls12_377/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 8444461749428370424248824938781546531375899335154063827935233455917409239041 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 30): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_bls12_377/scripts/scalar_field.sage b/ed_on_bls12_377/scripts/scalar_field.sage new file mode 100644 index 0000000..7810c05 --- /dev/null +++ b/ed_on_bls12_377/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 2111115437357092606062206234695386632838870926408408195193685246394721360383 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 30): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_bls12_377/src/constraints/curves.rs b/ed_on_bls12_377/src/constraints/curves.rs index 4b15106..7401d17 100644 --- a/ed_on_bls12_377/src/constraints/curves.rs +++ b/ed_on_bls12_377/src/constraints/curves.rs @@ -1,7 +1,6 @@ -use crate::*; use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar; -use crate::constraints::FqVar; +use crate::{constraints::FqVar, *}; /// A variable that is the R1CS equivalent of `crate::EdwardsAffine`. pub type EdwardsVar = AffineVar; diff --git a/ed_on_bls12_377/src/constraints/fields.rs b/ed_on_bls12_377/src/constraints/fields.rs index f25fa33..aa806e3 100644 --- a/ed_on_bls12_377/src/constraints/fields.rs +++ b/ed_on_bls12_377/src/constraints/fields.rs @@ -1,6 +1,7 @@ -use crate::fq::Fq; use ark_r1cs_std::fields::fp::FpVar; +use crate::fq::Fq; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FqVar = FpVar; diff --git a/ed_on_bls12_377/src/curves/mod.rs b/ed_on_bls12_377/src/curves/mod.rs index 7734435..8210521 100644 --- a/ed_on_bls12_377/src/curves/mod.rs +++ b/ed_on_bls12_377/src/curves/mod.rs @@ -1,9 +1,10 @@ -use crate::{fq::Fq, fr::Fr}; use ark_ec::{ models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, twisted_edwards_extended::{GroupAffine, GroupProjective}, }; -use ark_ff::field_new; +use ark_ff::MontFp; + +use crate::{fq::Fq, fr::Fr}; #[cfg(test)] mod tests; @@ -23,18 +24,18 @@ impl ModelParameters for EdwardsParameters { /// COFACTOR_INV = /// 527778859339273151515551558673846658209717731602102048798421311598680340096 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "527778859339273151515551558673846658209717731602102048798421311598680340096"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "527778859339273151515551558673846658209717731602102048798421311598680340096" + ); } impl TEModelParameters for EdwardsParameters { /// COEFF_A = -1 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "-1"); + const COEFF_A: Fq = MontFp!(Fq, "-1"); /// COEFF_D = 3021 - #[rustfmt::skip] - const COEFF_D: Fq = field_new!(Fq, "3021"); + const COEFF_D: Fq = MontFp!(Fq, "3021"); /// Generated randomly const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y); @@ -52,22 +53,31 @@ impl TEModelParameters for EdwardsParameters { impl MontgomeryModelParameters for EdwardsParameters { /// COEFF_A = 0x8D26E3FADA9010A26949031ECE3971B93952AD84D4753DDEDB748DA37E8F552 /// = 3990301581132929505568273333084066329187552697088022219156688740916631500114 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "3990301581132929505568273333084066329187552697088022219156688740916631500114"); + const COEFF_A: Fq = MontFp!( + Fq, + "3990301581132929505568273333084066329187552697088022219156688740916631500114" + ); + /// COEFF_B = 0x9D8F71EEC83A44C3A1FBCEC6F5418E5C6154C2682B8AC231C5A3725C8170AAD /// = 4454160168295440918680551605697480202188346638066041608778544715000777738925 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "4454160168295440918680551605697480202188346638066041608778544715000777738925"); + const COEFF_B: Fq = MontFp!( + Fq, + "4454160168295440918680551605697480202188346638066041608778544715000777738925" + ); type TEModelParameters = EdwardsParameters; } /// GENERATOR_X = /// 4497879464030519973909970603271755437257548612157028181994697785683032656389, -#[rustfmt::skip] -const GENERATOR_X: Fq = field_new!(Fq, "4497879464030519973909970603271755437257548612157028181994697785683032656389"); +const GENERATOR_X: Fq = MontFp!( + Fq, + "4497879464030519973909970603271755437257548612157028181994697785683032656389" +); /// GENERATOR_Y = /// 4357141146396347889246900916607623952598927460421559113092863576544024487809 -#[rustfmt::skip] -const GENERATOR_Y: Fq = field_new!(Fq, "4357141146396347889246900916607623952598927460421559113092863576544024487809"); +const GENERATOR_Y: Fq = MontFp!( + Fq, + "4357141146396347889246900916607623952598927460421559113092863576544024487809" +); diff --git a/ed_on_bls12_377/src/curves/tests.rs b/ed_on_bls12_377/src/curves/tests.rs index 58db359..fe10970 100644 --- a/ed_on_bls12_377/src/curves/tests.rs +++ b/ed_on_bls12_377/src/curves/tests.rs @@ -1,11 +1,9 @@ +use ark_algebra_test_templates::{curves::*, groups::*}; use ark_ec::{AffineCurve, ProjectiveCurve}; -use ark_std::rand::Rng; -use ark_std::test_rng; +use ark_std::{rand::Rng, test_rng}; use crate::*; -use ark_algebra_test_templates::{curves::*, groups::*}; - #[test] fn test_projective_curve() { curve_tests::(); diff --git a/ed_on_bls12_377/src/fields/fq.rs b/ed_on_bls12_377/src/fields/fq.rs index b743999..ace13c2 100644 --- a/ed_on_bls12_377/src/fields/fq.rs +++ b/ed_on_bls12_377/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_bls12_377::{Fr as Fq, FrParameters as FqParameters}; +pub use ark_bls12_377::{Fr as Fq, FrConfig as FqConfig}; diff --git a/ed_on_bls12_377/src/fields/fr.rs b/ed_on_bls12_377/src/fields/fr.rs index 5373fcf..7ba26a7 100644 --- a/ed_on_bls12_377/src/fields/fr.rs +++ b/ed_on_bls12_377/src/fields/fr.rs @@ -1,83 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - fields::{FftParameters, Fp256, Fp256Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; -pub type Fr = Fp256; - -pub struct FrParameters; - -impl Fp256Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 1; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 15170730761708361161u64, - 13670723686578117817u64, - 12803492266614043665u64, - 50861023252832611u64, - ]); -} -impl FpParameters for FrParameters { - /// MODULUS = 2111115437357092606062206234695386632838870926408408195193685246394721360383 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 13356249993388743167u64, - 5950279507993463550u64, - 10965441865914903552u64, - 336320092672043349u64, - ]); - - const MODULUS_BITS: u32 = 251; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 5; - - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 16632263305389933622u64, - 10726299895124897348u64, - 16608693673010411502u64, - 285459069419210737u64, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 3987543627614508126u64, - 17742427666091596403u64, - 14557327917022607905u64, - 322810149704226881u64, - ]); - - const INV: u64 = 9659935179256617473u64; - - // 70865795004005329077606947863872807680085016823885970091001235374859923341923 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 11289572479685143826u64, - 11383637369941080925u64, - 2288212753973340071u64, - 82014976407880291u64, - ]); - - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 6678124996694371583u64, - 2975139753996731775u64, - 14706092969812227584u64, - 168160046336021674u64, - ]); - - const T: BigInteger = Self::MODULUS_MINUS_ONE_DIV_TWO; - - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xae56bba6b0cff67f, - 0x14a4e8ebf10f22bf, - 0x660b44d1e5c37b00, - 0x12ab655e9a2ca55, - ]); -} +#[derive(MontConfig)] +#[modulus = "2111115437357092606062206234695386632838870926408408195193685246394721360383"] +#[generator = "5"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/ed_on_bls12_377/src/fields/mod.rs b/ed_on_bls12_377/src/fields/mod.rs index 10e71c5..7afba55 100644 --- a/ed_on_bls12_377/src/fields/mod.rs +++ b/ed_on_bls12_377/src/fields/mod.rs @@ -4,5 +4,5 @@ pub mod fr; pub use fq::*; pub use fr::*; -#[cfg(all(feature = "ed_on_bls12_377", test))] +#[cfg(test)] mod tests; diff --git a/ed_on_bls12_377/src/fields/tests.rs b/ed_on_bls12_377/src/fields/tests.rs index 173b5ee..ebcf9e7 100644 --- a/ed_on_bls12_377/src/fields/tests.rs +++ b/ed_on_bls12_377/src/fields/tests.rs @@ -1,24 +1,15 @@ -use ark_std::rand::Rng; -use ark_std::test_rng; - -use crate::{Fq, Fr}; - -use ark_algebra_test_templates::fields::*; - -#[test] -fn test_fr() { - let mut rng = test_rng(); - let a: Fr = rng.gen(); - let b: Fr = rng.gen(); - field_test(a, b); - primefield_test::(); -} - -#[test] -fn test_fq() { - let mut rng = test_rng(); - let a: Fq = rng.gen(); - let b: Fq = rng.gen(); - field_test(a, b); - primefield_test::(); -} +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; +use ark_ff::{ + fields::{Field, PrimeField, SquareRootField}, + One, UniformRand, Zero, +}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; + +use crate::{Fq, FqConfig, Fr, FrConfig}; + +generate_field_test!(ed_on_bls12_377; mont(4, 4); ); +generate_field_serialization_test!(ed_on_bls12_377;); diff --git a/ed_on_bls12_377/src/lib.rs b/ed_on_bls12_377/src/lib.rs old mode 100644 new mode 100755 index 8912279..3188132 --- a/ed_on_bls12_377/src/lib.rs +++ b/ed_on_bls12_377/src/lib.rs @@ -8,14 +8,16 @@ )] #![forbid(unsafe_code)] -//! This library implements a twisted Edwards curve whose base field is the scalar field of the -//! curve BLS12-377. This allows defining cryptographic primitives that use elliptic curves over -//! the scalar field of the latter curve. This curve was generated as part of the paper -//! [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). +//! This library implements a twisted Edwards curve whose base field is the +//! scalar field of the curve BLS12-377. This allows defining cryptographic +//! primitives that use elliptic curves over the scalar field of the latter +//! curve. This curve was generated as part of the paper [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). //! //! Curve information: -//! * Base field: q = 8444461749428370424248824938781546531375899335154063827935233455917409239041 -//! * Scalar field: r = 2111115437357092606062206234695386632838870926408408195193685246394721360383 +//! * Base field: q = +//! 8444461749428370424248824938781546531375899335154063827935233455917409239041 +//! * Scalar field: r = +//! 2111115437357092606062206234695386632838870926408408195193685246394721360383 //! * Valuation(q - 1, 2) = 47 //! * Valuation(r - 1, 2) = 1 //! * Curve equation: ax^2 + y^2 =1 + dx^2y^2, where diff --git a/ed_on_bls12_381/scripts/base_field.sage b/ed_on_bls12_381/scripts/base_field.sage new file mode 100644 index 0000000..fb96ea8 --- /dev/null +++ b/ed_on_bls12_381/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 52435875175126190479447740508185965837690552500527637822603658699938581184513 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_bls12_381/scripts/scalar_field.sage b/ed_on_bls12_381/scripts/scalar_field.sage new file mode 100644 index 0000000..36af7a5 --- /dev/null +++ b/ed_on_bls12_381/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 6554484396890773809930967563523245729705921265872317281365359162392183254199 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_bls12_381/src/constraints/curves.rs b/ed_on_bls12_381/src/constraints/curves.rs index f392a01..13b386a 100644 --- a/ed_on_bls12_381/src/constraints/curves.rs +++ b/ed_on_bls12_381/src/constraints/curves.rs @@ -1,7 +1,6 @@ -use crate::*; use ark_r1cs_std::groups::curves::{short_weierstrass::ProjectiveVar, twisted_edwards::AffineVar}; -use crate::constraints::FqVar; +use crate::{constraints::FqVar, *}; /// A variable that is the R1CS equivalent of `crate::EdwardsAffine`. pub type EdwardsVar = AffineVar; diff --git a/ed_on_bls12_381/src/curves/mod.rs b/ed_on_bls12_381/src/curves/mod.rs index abfa1fd..b8ebaec 100644 --- a/ed_on_bls12_381/src/curves/mod.rs +++ b/ed_on_bls12_381/src/curves/mod.rs @@ -1,4 +1,3 @@ -use crate::{Fq, Fr}; use ark_ec::{ models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, short_weierstrass_jacobian::{ @@ -7,7 +6,9 @@ use ark_ec::{ twisted_edwards_extended::{GroupAffine, GroupProjective}, SWModelParameters, }; -use ark_ff::field_new; +use ark_ff::MontFp; + +use crate::{Fq, Fr}; #[cfg(test)] mod tests; @@ -64,18 +65,21 @@ impl ModelParameters for JubjubParameters { /// COFACTOR^(-1) mod r = /// 819310549611346726241370945440405716213240158234039660170669895299022906775 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "819310549611346726241370945440405716213240158234039660170669895299022906775"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "819310549611346726241370945440405716213240158234039660170669895299022906775" + ); } impl TEModelParameters for JubjubParameters { /// COEFF_A = -1 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "-1"); + const COEFF_A: Fq = MontFp!(Fq, "-1"); /// COEFF_D = (10240/10241) mod q - #[rustfmt::skip] - const COEFF_D: Fq = field_new!(Fq, "19257038036680949359750312669786877991949435402254120286184196891950884077233"); + const COEFF_D: Fq = MontFp!( + Fq, + "19257038036680949359750312669786877991949435402254120286184196891950884077233" + ); /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y); @@ -91,28 +95,36 @@ impl TEModelParameters for JubjubParameters { impl MontgomeryModelParameters for JubjubParameters { /// COEFF_A = 40962 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "40962"); + const COEFF_A: Fq = MontFp!(Fq, "40962"); + /// COEFF_B = -40964 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "-40964"); + const COEFF_B: Fq = MontFp!(Fq, "-40964"); type TEModelParameters = JubjubParameters; } -#[rustfmt::skip] -const GENERATOR_X: Fq = field_new!(Fq, "8076246640662884909881801758704306714034609987455869804520522091855516602923"); -#[rustfmt::skip] -const GENERATOR_Y: Fq = field_new!(Fq, "13262374693698910701929044844600465831413122818447359594527400194675274060458"); +const GENERATOR_X: Fq = MontFp!( + Fq, + "8076246640662884909881801758704306714034609987455869804520522091855516602923" +); + +const GENERATOR_Y: Fq = MontFp!( + Fq, + "13262374693698910701929044844600465831413122818447359594527400194675274060458" +); impl SWModelParameters for JubjubParameters { /// COEFF_A = 52296097456646850916096512823759002727550416093741407922227928430486925478210 - #[rustfmt::skip] - const COEFF_A: Self::BaseField = field_new!(Fq, "52296097456646850916096512823759002727550416093741407922227928430486925478210"); + const COEFF_A: Self::BaseField = MontFp!( + Fq, + "52296097456646850916096512823759002727550416093741407922227928430486925478210" + ); /// COEFF_B = 48351165704696163914533707656614864561753505123260775585269522553028192119009 - #[rustfmt::skip] - const COEFF_B: Self::BaseField = field_new!(Fq, "48351165704696163914533707656614864561753505123260775585269522553028192119009"); + const COEFF_B: Self::BaseField = MontFp!( + Fq, + "48351165704696163914533707656614864561753505123260775585269522553028192119009" + ); /// generators const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -120,8 +132,13 @@ impl SWModelParameters for JubjubParameters { } /// x coordinate for SW curve generator -#[rustfmt::skip] -const SW_GENERATOR_X: Fq = field_new!(Fq, "33835869156188682335217394949746694649676633840125476177319971163079011318731"); +const SW_GENERATOR_X: Fq = MontFp!( + Fq, + "33835869156188682335217394949746694649676633840125476177319971163079011318731" +); + /// y coordinate for SW curve generator -#[rustfmt::skip] -const SW_GENERATOR_Y: Fq = field_new!(Fq, "43777270878440091394432848052353307184915192688165709016756678962558652055320"); +const SW_GENERATOR_Y: Fq = MontFp!( + Fq, + "43777270878440091394432848052353307184915192688165709016756678962558652055320" +); diff --git a/ed_on_bls12_381/src/curves/tests.rs b/ed_on_bls12_381/src/curves/tests.rs index 7f7f00e..c96802d 100644 --- a/ed_on_bls12_381/src/curves/tests.rs +++ b/ed_on_bls12_381/src/curves/tests.rs @@ -1,11 +1,10 @@ +use ark_algebra_test_templates::{curves::*, groups::*}; use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_ff::{bytes::FromBytes, Zero}; use ark_std::{rand::Rng, str::FromStr, test_rng}; use crate::*; -use ark_algebra_test_templates::{curves::*, groups::*}; - #[test] fn test_projective_curve() { curve_tests::(); diff --git a/ed_on_bls12_381/src/fields/fq.rs b/ed_on_bls12_381/src/fields/fq.rs index 46c052b..3eca3b9 100644 --- a/ed_on_bls12_381/src/fields/fq.rs +++ b/ed_on_bls12_381/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_bls12_381::{Fr as Fq, FrParameters as FqParameters}; +pub use ark_bls12_381::{Fr as Fq, FrConfig as FqConfig}; diff --git a/ed_on_bls12_381/src/fields/fr.rs b/ed_on_bls12_381/src/fields/fr.rs index 4c367fb..e23e398 100644 --- a/ed_on_bls12_381/src/fields/fr.rs +++ b/ed_on_bls12_381/src/fields/fr.rs @@ -1,81 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - fields::{FftParameters, Fp256, Fp256Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; -pub type Fr = Fp256; - -pub struct FrParameters; - -impl Fp256Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 1; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 0xaa9f02ab1d6124de, - 0xb3524a6466112932, - 0x7342261215ac260b, - 0x4d6b87b1da259e2, - ]); -} -impl FpParameters for FrParameters { - /// MODULUS = 6554484396890773809930967563523245729705921265872317281365359162392183254199. - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0xd0970e5ed6f72cb7, - 0xa6682093ccc81082, - 0x6673b0101343b00, - 0xe7db4ea6533afa9, - ]); - - const MODULUS_BITS: u32 = 252; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 4; - - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 0x25f80bb3b99607d9, - 0xf315d62f66b6e750, - 0x932514eeeb8814f4, - 0x9a6fc6f479155c6, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 0x67719aa495e57731, - 0x51b0cef09ce3fc26, - 0x69dab7fac026e9a5, - 0x4f6547b8d127688, - ]); - - const INV: u64 = 0x1ba3a358ef788ef9; - - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 0x720b1b19d49ea8f1, - 0xbf4aa36101f13a58, - 0x5fa8cc968193ccbb, - 0xe70cbdc7dccf3ac, - ]); - - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 7515249040934278747, - 5995434913520945217, - 9454073218019761536, - 522094803716528084, - ]); - - const T: BigInteger = Self::MODULUS_MINUS_ONE_DIV_TWO; - - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 12980996557321915181, - 2997717456760472608, - 4727036609009880768, - 261047401858264042, - ]); -} +#[derive(MontConfig)] +#[modulus = "6554484396890773809930967563523245729705921265872317281365359162392183254199"] +#[generator = "6"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/ed_on_bls12_381/src/fields/mod.rs b/ed_on_bls12_381/src/fields/mod.rs index 6e99b4b..7afba55 100644 --- a/ed_on_bls12_381/src/fields/mod.rs +++ b/ed_on_bls12_381/src/fields/mod.rs @@ -4,5 +4,5 @@ pub mod fr; pub use fq::*; pub use fr::*; -#[cfg(all(feature = "ed_on_bls12_381", test))] +#[cfg(test)] mod tests; diff --git a/ed_on_bls12_381/src/fields/tests.rs b/ed_on_bls12_381/src/fields/tests.rs index caf55fc..f267fa2 100644 --- a/ed_on_bls12_381/src/fields/tests.rs +++ b/ed_on_bls12_381/src/fields/tests.rs @@ -1,33 +1,20 @@ -use crate::{Fq, Fr}; +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{ biginteger::BigInteger256 as BigInteger, bytes::{FromBytes, ToBytes}, - fields::{Field, LegendreSymbol::*, SquareRootField}, - One, Zero, + fields::{Field, LegendreSymbol::*, PrimeField, SquareRootField}, + One, UniformRand, Zero, }; -use ark_std::test_rng; - -use ark_algebra_test_templates::fields::*; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, str::FromStr, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; -use ark_std::{rand::Rng, str::FromStr}; - -#[test] -fn test_fr() { - let mut rng = test_rng(); - let a: Fr = rng.gen(); - let b: Fr = rng.gen(); - field_test(a, b); - primefield_test::(); -} +use crate::{Fq, FqConfig, Fr, FrConfig}; -#[test] -fn test_fq() { - let mut rng = test_rng(); - let a: Fq = rng.gen(); - let b: Fq = rng.gen(); - field_test(a, b); - primefield_test::(); -} +generate_field_test!(ed_on_bls12_381; mont(4, 4); ); +generate_field_serialization_test!(ed_on_bls12_381;); #[test] fn test_fq_add() { @@ -148,22 +135,6 @@ fn test_fq_sub() { assert_eq!(f1 - &f2, f3); } -#[test] -fn test_fq_double_in_place() { - let mut f1 = Fq::from_str( - "29729289787452206300641229002276778748586801323231253291984198106063944136114", - ) - .unwrap(); - let f3 = Fq::from_str( - "7022704399778222121834717496367591659483050145934868761364737512189307087715", - ) - .unwrap(); - assert!(!f1.is_zero()); - assert!(!f3.is_zero()); - f1.double_in_place(); - assert_eq!(f1, f3); -} - #[test] fn test_fq_double_in_place_thrice() { let mut f1 = Fq::from_str( @@ -280,22 +251,9 @@ fn test_fq_square_in_place() { assert_eq!(f1, f3); } -#[test] -fn test_fq_sqrt() { - let f1 = Fq::from_str( - "10875927553327821418567659853801220899541454800710193788767706167237535308235", - ) - .unwrap(); - let f3 = Fq::from_str( - "10816221372957505053219354782681292880545918527618367765651802809826238616708", - ) - .unwrap(); - assert_eq!(f1.sqrt().unwrap(), f3); -} - #[test] fn test_fq_from_str() { - let f1_from_repr = Fq::from(BigInteger([ + let f1_from_repr = Fq::from(BigInteger::new([ 0xab8a2535947d1a77, 0x9ba74cbfda0bbcda, 0xe928b59724d60baf, @@ -305,7 +263,7 @@ fn test_fq_from_str() { "13026376210409056429264774981357153555336288129100724591327877625017068755575", ) .unwrap(); - let f2_from_repr = Fq::from(BigInteger([ + let f2_from_repr = Fq::from(BigInteger::new([ 0x97e9103775d2f35c, 0xbe6756b6c587544b, 0x6ee38c3afd88ef4b, @@ -324,14 +282,14 @@ fn test_fq_legendre() { assert_eq!(QuadraticResidue, Fq::one().legendre()); assert_eq!(Zero, Fq::zero().legendre()); - let e = BigInteger([ + let e = BigInteger::new([ 0x0dbc5349cd5664da, 0x8ac5b6296e3ae29d, 0x127cb819feceaa3b, 0x3a6b21fb03867191, ]); assert_eq!(QuadraticResidue, Fq::from(e).legendre()); - let e = BigInteger([ + let e = BigInteger::new([ 0x96341aefd047c045, 0x9b5f4254500a4d65, 0x1ee08223b68ac240, @@ -342,7 +300,7 @@ fn test_fq_legendre() { #[test] fn test_fq_bytes() { - let f1_from_repr = Fq::from(BigInteger([ + let f1_from_repr = Fq::from(BigInteger::new([ 0xab8a2535947d1a77, 0x9ba74cbfda0bbcda, 0xe928b59724d60baf, @@ -358,19 +316,19 @@ fn test_fq_bytes() { #[test] fn test_fr_add() { - let f1 = Fr::from(BigInteger([ + let f1 = Fr::from(BigInteger::new([ 0xc81265fb4130fe0c, 0xb308836c14e22279, 0x699e887f96bff372, 0x84ecc7e76c11ad, ])); - let f2 = Fr::from(BigInteger([ + let f2 = Fr::from(BigInteger::new([ 0x71875719b422efb8, 0x43658e68a93612, 0x9fa756be2011e833, 0xaa2b2cb08dac497, ])); - let f3 = Fr::from(BigInteger([ + let f3 = Fr::from(BigInteger::new([ 0x3999bd14f553edc4, 0xb34be8fa7d8b588c, 0x945df3db6d1dba5, @@ -381,19 +339,19 @@ fn test_fr_add() { #[test] fn test_fr_mul() { - let f1 = Fr::from(BigInteger([ + let f1 = Fr::from(BigInteger::new([ 0xc81265fb4130fe0c, 0xb308836c14e22279, 0x699e887f96bff372, 0x84ecc7e76c11ad, ])); - let f2 = Fr::from(BigInteger([ + let f2 = Fr::from(BigInteger::new([ 0x71875719b422efb8, 0x43658e68a93612, 0x9fa756be2011e833, 0xaa2b2cb08dac497, ])); - let f3 = Fr::from(BigInteger([ + let f3 = Fr::from(BigInteger::new([ 0x6d6618ac6b4a8381, 0x5b9eb35d711ee1da, 0xce83310e6ac4105d, @@ -404,7 +362,7 @@ fn test_fr_mul() { #[test] fn test_fr_bytes() { - let f1_from_repr = Fr::from(BigInteger([ + let f1_from_repr = Fr::from(BigInteger::new([ 0xc81265fb4130fe0c, 0xb308836c14e22279, 0x699e887f96bff372, @@ -420,7 +378,7 @@ fn test_fr_bytes() { #[test] fn test_fr_from_str() { - let f100_from_repr = Fr::from(BigInteger([0x64, 0, 0, 0])); + let f100_from_repr = Fr::from(BigInteger::new([0x64, 0, 0, 0])); let f100 = Fr::from_str("100").unwrap(); assert_eq!(f100_from_repr, f100); } diff --git a/ed_on_bls12_381_bandersnatch/Cargo.toml b/ed_on_bls12_381_bandersnatch/Cargo.toml index 51e17be..1f1092b 100644 --- a/ed_on_bls12_381_bandersnatch/Cargo.toml +++ b/ed_on_bls12_381_bandersnatch/Cargo.toml @@ -25,10 +25,10 @@ ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-featu [features] default = [] -std = [ - "ark-std/std", - "ark-ff/std", - "ark-ec/std", - "ark-bls12-381/std" +std = [ + "ark-std/std", + "ark-ff/std", + "ark-ec/std", + "ark-bls12-381/std" ] r1cs = ["ark-r1cs-std"] diff --git a/ed_on_bls12_381_bandersnatch/scripts/base_field.sage b/ed_on_bls12_381_bandersnatch/scripts/base_field.sage new file mode 100644 index 0000000..fb96ea8 --- /dev/null +++ b/ed_on_bls12_381_bandersnatch/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 52435875175126190479447740508185965837690552500527637822603658699938581184513 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_bls12_381_bandersnatch/scripts/scalar_field.sage b/ed_on_bls12_381_bandersnatch/scripts/scalar_field.sage new file mode 100644 index 0000000..8d039fb --- /dev/null +++ b/ed_on_bls12_381_bandersnatch/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 13108968793781547619861935127046491459309155893440570251786403306729687672801 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_bls12_381_bandersnatch/src/constraints/curves.rs b/ed_on_bls12_381_bandersnatch/src/constraints/curves.rs index c563839..073e154 100644 --- a/ed_on_bls12_381_bandersnatch/src/constraints/curves.rs +++ b/ed_on_bls12_381_bandersnatch/src/constraints/curves.rs @@ -1,6 +1,7 @@ -use crate::{constraints::FqVar, *}; use ark_r1cs_std::groups::curves::{short_weierstrass::ProjectiveVar, twisted_edwards::AffineVar}; +use crate::{constraints::FqVar, *}; + /// A variable that is the R1CS equivalent of `crate::BandersnatchParameters`. pub type EdwardsVar = AffineVar; diff --git a/ed_on_bls12_381_bandersnatch/src/curves/mod.rs b/ed_on_bls12_381_bandersnatch/src/curves/mod.rs index 8638033..6cb033e 100644 --- a/ed_on_bls12_381_bandersnatch/src/curves/mod.rs +++ b/ed_on_bls12_381_bandersnatch/src/curves/mod.rs @@ -1,4 +1,3 @@ -use crate::{Fq, Fr}; use ark_ec::{ models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, short_weierstrass_jacobian::{ @@ -7,7 +6,9 @@ use ark_ec::{ twisted_edwards_extended::{GroupAffine, GroupProjective}, SWModelParameters, }; -use ark_ff::{field_new, Field}; +use ark_ff::{Field, MontFp}; + +use crate::{Fq, Fr}; #[cfg(test)] mod tests; @@ -18,8 +19,8 @@ pub type EdwardsProjective = GroupProjective; pub type SWAffine = SWGroupAffine; pub type SWProjective = SWGroupProjective; -/// `bandersnatch` is a twisted Edwards curve. These curves have equations of the -/// form: ax² + y² = 1 - dx²y². +/// `bandersnatch` is a twisted Edwards curve. These curves have equations of +/// the form: ax² + y² = 1 - dx²y². /// over some base finite field Fq. /// /// bandersnatch's curve equation: -5x² + y² = 1 - dx²y² @@ -50,7 +51,6 @@ pub type SWProjective = SWGroupProjective; /// /// Script to transfer between different curves are available /// -/// #[derive(Clone, Default, PartialEq, Eq)] pub struct BandersnatchParameters; @@ -66,18 +66,22 @@ impl ModelParameters for BandersnatchParameters { /// COFACTOR^(-1) mod r = /// 9831726595336160714896451345284868594481866920080427688839802480047265754601 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "9831726595336160714896451345284868594481866920080427688839802480047265754601"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "9831726595336160714896451345284868594481866920080427688839802480047265754601" + ); } impl TEModelParameters for BandersnatchParameters { /// COEFF_A = -5 - const COEFF_A: Fq = field_new!(Fq, "-5"); + const COEFF_A: Fq = MontFp!(Fq, "-5"); /// COEFF_D = (138827208126141220649022263972958607803/ /// 171449701953573178309673572579671231137) mod q - #[rustfmt::skip] - const COEFF_D: Fq = field_new!(Fq, "45022363124591815672509500913686876175488063829319466900776701791074614335719"); + const COEFF_D: Fq = MontFp!( + Fq, + "45022363124591815672509500913686876175488063829319466900776701791074614335719" + ); /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -95,44 +99,65 @@ impl TEModelParameters for BandersnatchParameters { impl MontgomeryModelParameters for BandersnatchParameters { /// COEFF_A = 29978822694968839326280996386011761570173833766074948509196803838190355340952 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "29978822694968839326280996386011761570173833766074948509196803838190355340952"); + const COEFF_A: Fq = MontFp!( + Fq, + "29978822694968839326280996386011761570173833766074948509196803838190355340952" + ); /// COEFF_B = 25465760566081946422412445027709227188579564747101592991722834452325077642517 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "25465760566081946422412445027709227188579564747101592991722834452325077642517"); + const COEFF_B: Fq = MontFp!( + Fq, + "25465760566081946422412445027709227188579564747101592991722834452325077642517" + ); type TEModelParameters = BandersnatchParameters; } // The TE form generator is generated following Zcash's fashion: -// "The generators of G1 and G2 are computed by finding the lexicographically smallest -// valid x-coordinate, and its lexicographically smallest y-coordinate and scaling it -// by the cofactor such that the result is not the point at infinity." -// The SW form generator is the same TE generator converted into SW form, obtained from the scripts: +// "The generators of G1 and G2 are computed by finding the lexicographically +// smallest valid x-coordinate, and its lexicographically smallest +// y-coordinate and scaling it by the cofactor such that the result is not +// the point at infinity." +// The SW form generator is the same TE generator converted into SW form, +// obtained from the scripts: // /// x coordinate for TE curve generator -#[rustfmt::skip] -const TE_GENERATOR_X: Fq = field_new!(Fq, "18886178867200960497001835917649091219057080094937609519140440539760939937304"); +const TE_GENERATOR_X: Fq = MontFp!( + Fq, + "18886178867200960497001835917649091219057080094937609519140440539760939937304" +); + /// y coordinate for TE curve generator -#[rustfmt::skip] -const TE_GENERATOR_Y: Fq = field_new!(Fq, "19188667384257783945677642223292697773471335439753913231509108946878080696678"); +const TE_GENERATOR_Y: Fq = MontFp!( + Fq, + "19188667384257783945677642223292697773471335439753913231509108946878080696678" +); + /// x coordinate for SW curve generator -#[rustfmt::skip] -const SW_GENERATOR_X: Fq = field_new!(Fq, "30900340493481298850216505686589334086208278925799850409469406976849338430199"); +const SW_GENERATOR_X: Fq = MontFp!( + Fq, + "30900340493481298850216505686589334086208278925799850409469406976849338430199" +); + /// y coordinate for SW curve generator -#[rustfmt::skip] -const SW_GENERATOR_Y: Fq = field_new!(Fq, "12663882780877899054958035777720958383845500985908634476792678820121468453298"); +const SW_GENERATOR_Y: Fq = MontFp!( + Fq, + "12663882780877899054958035777720958383845500985908634476792678820121468453298" +); impl SWModelParameters for BandersnatchParameters { /// COEFF_A = 10773120815616481058602537765553212789256758185246796157495669123169359657269 - #[rustfmt::skip] - const COEFF_A: Self::BaseField = field_new!(Fq, "10773120815616481058602537765553212789256758185246796157495669123169359657269"); + const COEFF_A: Self::BaseField = MontFp!( + Fq, + "10773120815616481058602537765553212789256758185246796157495669123169359657269" + ); /// COEFF_B = 29569587568322301171008055308580903175558631321415017492731745847794083609535 - #[rustfmt::skip] - const COEFF_B: Self::BaseField = field_new!(Fq, "29569587568322301171008055308580903175558631321415017492731745847794083609535"); + const COEFF_B: Self::BaseField = MontFp!( + Fq, + "29569587568322301171008055308580903175558631321415017492731745847794083609535" + ); /// generators const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = diff --git a/ed_on_bls12_381_bandersnatch/src/curves/tests.rs b/ed_on_bls12_381_bandersnatch/src/curves/tests.rs index e1829c4..d031700 100644 --- a/ed_on_bls12_381_bandersnatch/src/curves/tests.rs +++ b/ed_on_bls12_381_bandersnatch/src/curves/tests.rs @@ -1,9 +1,10 @@ -use crate::*; use ark_algebra_test_templates::{curves::*, groups::*}; use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_ff::{bytes::FromBytes, Zero}; use ark_std::{rand::Rng, str::FromStr, test_rng}; +use crate::*; + #[test] fn test_projective_curve() { curve_tests::(); diff --git a/ed_on_bls12_381_bandersnatch/src/fields/fq.rs b/ed_on_bls12_381_bandersnatch/src/fields/fq.rs index 46c052b..3eca3b9 100644 --- a/ed_on_bls12_381_bandersnatch/src/fields/fq.rs +++ b/ed_on_bls12_381_bandersnatch/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_bls12_381::{Fr as Fq, FrParameters as FqParameters}; +pub use ark_bls12_381::{Fr as Fq, FrConfig as FqConfig}; diff --git a/ed_on_bls12_381_bandersnatch/src/fields/fr.rs b/ed_on_bls12_381_bandersnatch/src/fields/fr.rs index c583727..74721ae 100644 --- a/ed_on_bls12_381_bandersnatch/src/fields/fr.rs +++ b/ed_on_bls12_381_bandersnatch/src/fields/fr.rs @@ -1,115 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - fields::{FftParameters, Fp256, Fp256Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; -pub type Fr = Fp256; - -pub struct FrParameters; - -impl Fp256Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - /// Let `N` be the size of the multiplicative group defined by the field. - /// Then `TWO_ADICITY` is the two-adicity of `N`, i.e. the integer `s` - /// such that `N = 2^s * t` for some odd integer `t`. - const TWO_ADICITY: u32 = 5; - - /// 2^s root of unity computed by GENERATOR^t - /// 4740934665446857387895054948191089665295030226009829406950782728666658007874 - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 0xa4dcdba087826b42, - 0x6e4ab162f57f862a, - 0xabc5492749348d6a, - 0xa7b462035f8c169, - ]); -} -impl FpParameters for FrParameters { - /// The modulus of the field. - /// MODULUS = 13108968793781547619861935127046491459309155893440570251786403306729687672801. - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0x74fd06b52876e7e1, - 0xff8f870074190471, - 0x0cce760202687600, - 0x1cfb69d4ca675f52, - ]); - - /// The number of bits needed to represent the `Self::MODULUS`. - const MODULUS_BITS: u32 = 253; - - /// The number of bits that can be reliably stored. - /// (Should equal `SELF::MODULUS_BITS - 1`) - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - /// The number of bits that must be shaved from the beginning of - /// the representation when randomly sampling. - const REPR_SHAVE_BITS: u32 = 4; - - /// Let `M` be the power of 2^64 nearest to `Self::MODULUS_BITS`. Then - /// `R = M % Self::MODULUS`. - /// R = 10920338887063814464675503992315976178796737518116002025166357554075628257528 - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 0x5817ca56bc48c0f8, - 0x0383c7fc5f37dc74, - 0x998c4fefecbc4ff8, - 0x1824b159acc5056f, - ]); - - /// R2 = R^2 % Self::MODULUS - /// R2 = 4932290691328759802879919559207542894238895193980447506221046538067943049163 - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 0xdbb4f5d658db47cb, - 0x40fa7ca27fecb938, - 0xaa9e6daec0055cea, - 0xae793ddb14aec7d - ]); - - /// INV = -MODULUS^{-1} mod 2^64 - /// INV = 17410672245482742751 - const INV: u64 = 0xf19f22295cc063df; - - /// A multiplicative generator of the field. - /// `Self::GENERATOR` is an element having multiplicative order - /// `Self::MODULUS - 1`. - /// n = 9962557815892774795293348142308860067333132192265356416788884706064406244838 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 0x56b6f3ab7b616de6, - 0x114f419d6c9083e5, - 0xbf518d217780c4b9, - 0x16069b9f45dbce7f, - ]); - - /// (Self::MODULUS - 1) / 2 - /// 6554484396890773809930967563523245729654577946720285125893201653364843836400 - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xba7e835a943b73f0, - 0x7fc7c3803a0c8238, - 0x06673b0101343b00, - 0xe7db4ea6533afa9, - ]); - - /// t for 2^s * t = MODULUS - 1, and t coprime to 2. - /// t = 409655274805673363120685472720202858103411121670017820368325103335302739775 - /// = (modulus-1)/2^5 - const T: BigInteger = BigInt::new([ - 0x8ba7e835a943b73f, - 0x07fc7c3803a0c823, - 0x906673b0101343b0, - 0xe7db4ea6533afa, - ]); - - /// (t - 1) / 2 - /// = 204827637402836681560342736360101429051705560835008910184162551667651369887 - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xc5d3f41ad4a1db9f, - 0x03fe3e1c01d06411, - 0x483339d80809a1d8, - 0x73eda753299d7d, - ]); -} +#[derive(MontConfig)] +#[modulus = "13108968793781547619861935127046491459309155893440570251786403306729687672801"] +#[generator = "7"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/ed_on_bls12_381_bandersnatch/src/fields/mod.rs b/ed_on_bls12_381_bandersnatch/src/fields/mod.rs index 63d081e..7afba55 100644 --- a/ed_on_bls12_381_bandersnatch/src/fields/mod.rs +++ b/ed_on_bls12_381_bandersnatch/src/fields/mod.rs @@ -4,5 +4,5 @@ pub mod fr; pub use fq::*; pub use fr::*; -#[cfg(all(feature = "ed_on_bls12_381_bandersnatch", test))] +#[cfg(test)] mod tests; diff --git a/ed_on_bls12_381_bandersnatch/src/fields/tests.rs b/ed_on_bls12_381_bandersnatch/src/fields/tests.rs index b971721..245d02b 100644 --- a/ed_on_bls12_381_bandersnatch/src/fields/tests.rs +++ b/ed_on_bls12_381_bandersnatch/src/fields/tests.rs @@ -1,30 +1,20 @@ -use crate::{Fq, Fr}; -use ark_algebra_test_templates::fields::*; +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{ biginteger::BigInteger256 as BigInteger, bytes::{FromBytes, ToBytes}, - fields::{Field, LegendreSymbol::*, SquareRootField}, - One, Zero, + fields::{Field, LegendreSymbol::*, PrimeField, SquareRootField}, + One, UniformRand, Zero, }; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; use ark_std::{rand::Rng, str::FromStr, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; -#[test] -fn test_fr() { - let mut rng = test_rng(); - let a: Fr = rng.gen(); - let b: Fr = rng.gen(); - field_test(a, b); - primefield_test::(); -} +use crate::{Fq, FqConfig, Fr, FrConfig}; -#[test] -fn test_fq() { - let mut rng = test_rng(); - let a: Fq = rng.gen(); - let b: Fq = rng.gen(); - field_test(a, b); - primefield_test::(); -} +generate_field_test!(ed_on_bls12_381_bandersnatch; mont(4, 4); ); +generate_field_serialization_test!(ed_on_bls12_381_bandersnatch;); #[test] fn test_fq_add() { @@ -145,22 +135,6 @@ fn test_fq_sub() { assert_eq!(f1 - &f2, f3); } -#[test] -fn test_fq_double_in_place() { - let mut f1 = Fq::from_str( - "29729289787452206300641229002276778748586801323231253291984198106063944136114", - ) - .unwrap(); - let f3 = Fq::from_str( - "7022704399778222121834717496367591659483050145934868761364737512189307087715", - ) - .unwrap(); - assert!(!f1.is_zero()); - assert!(!f3.is_zero()); - f1.double_in_place(); - assert_eq!(f1, f3); -} - #[test] fn test_fq_double_in_place_thrice() { let mut f1 = Fq::from_str( @@ -277,22 +251,9 @@ fn test_fq_square_in_place() { assert_eq!(f1, f3); } -#[test] -fn test_fq_sqrt() { - let f1 = Fq::from_str( - "10875927553327821418567659853801220899541454800710193788767706167237535308235", - ) - .unwrap(); - let f3 = Fq::from_str( - "10816221372957505053219354782681292880545918527618367765651802809826238616708", - ) - .unwrap(); - assert_eq!(f1.sqrt().unwrap(), f3); -} - #[test] fn test_fq_from_str() { - let f1_from_repr = Fq::from(BigInteger([ + let f1_from_repr = Fq::from(BigInteger::new([ 0xab8a2535947d1a77, 0x9ba74cbfda0bbcda, 0xe928b59724d60baf, @@ -302,7 +263,7 @@ fn test_fq_from_str() { "13026376210409056429264774981357153555336288129100724591327877625017068755575", ) .unwrap(); - let f2_from_repr = Fq::from(BigInteger([ + let f2_from_repr = Fq::from(BigInteger::new([ 0x97e9103775d2f35c, 0xbe6756b6c587544b, 0x6ee38c3afd88ef4b, @@ -321,14 +282,14 @@ fn test_fq_legendre() { assert_eq!(QuadraticResidue, Fq::one().legendre()); assert_eq!(Zero, Fq::zero().legendre()); - let e = BigInteger([ + let e = BigInteger::new([ 0x0dbc5349cd5664da, 0x8ac5b6296e3ae29d, 0x127cb819feceaa3b, 0x3a6b21fb03867191, ]); assert_eq!(QuadraticResidue, Fq::from(e).legendre()); - let e = BigInteger([ + let e = BigInteger::new([ 0x96341aefd047c045, 0x9b5f4254500a4d65, 0x1ee08223b68ac240, @@ -339,7 +300,7 @@ fn test_fq_legendre() { #[test] fn test_fq_bytes() { - let f1_from_repr = Fq::from(BigInteger([ + let f1_from_repr = Fq::from(BigInteger::new([ 0xab8a2535947d1a77, 0x9ba74cbfda0bbcda, 0xe928b59724d60baf, @@ -355,19 +316,19 @@ fn test_fq_bytes() { #[test] fn test_fr_add() { - let f1 = Fr::from(BigInteger([ + let f1 = Fr::from(BigInteger::new([ 0xc81265fb4130fe0c, 0xb308836c14e22279, 0x699e887f96bff372, 0x84ecc7e76c11ad, ])); - let f2 = Fr::from(BigInteger([ + let f2 = Fr::from(BigInteger::new([ 0x71875719b422efb8, 0x0043658e68a93612, 0x9fa756be2011e833, 0xaa2b2cb08dac497, ])); - let f3 = Fr::from(BigInteger([ + let f3 = Fr::from(BigInteger::new([ 0x3999bd14f553edc4, 0xb34be8fa7d8b588c, 0x0945df3db6d1dba5, @@ -378,19 +339,19 @@ fn test_fr_add() { #[test] fn test_fr_mul() { - let f1 = Fr::from(BigInteger([ + let f1 = Fr::from(BigInteger::new([ 0xc81265fb4130fe0c, 0xb308836c14e22279, 0x699e887f96bff372, 0x84ecc7e76c11ad, ])); - let f2 = Fr::from(BigInteger([ + let f2 = Fr::from(BigInteger::new([ 0x71875719b422efb8, 0x43658e68a93612, 0x9fa756be2011e833, 0xaa2b2cb08dac497, ])); - let f3 = Fr::from(BigInteger([ + let f3 = Fr::from(BigInteger::new([ 0xbe3e50c164fe3381, 0x5ac45bc180974585, 0x1c234ad6dcdc70c9, @@ -401,7 +362,7 @@ fn test_fr_mul() { #[test] fn test_fr_bytes() { - let f1_from_repr = Fr::from(BigInteger([ + let f1_from_repr = Fr::from(BigInteger::new([ 0xc81265fb4130fe0c, 0xb308836c14e22279, 0x699e887f96bff372, @@ -417,7 +378,7 @@ fn test_fr_bytes() { #[test] fn test_fr_from_str() { - let f100_from_repr = Fr::from(BigInteger([0x64, 0, 0, 0])); + let f100_from_repr = Fr::from(BigInteger::new([0x64, 0, 0, 0])); let f100 = Fr::from_str("100").unwrap(); assert_eq!(f100_from_repr, f100); } diff --git a/ed_on_bn254/scripts/base_field.sage b/ed_on_bn254/scripts/base_field.sage new file mode 100644 index 0000000..a8a4b5c --- /dev/null +++ b/ed_on_bn254/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 21888242871839275222246405745257275088548364400416034343698204186575808495617 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_bn254/scripts/scalar_field.sage b/ed_on_bn254/scripts/scalar_field.sage new file mode 100644 index 0000000..e18586d --- /dev/null +++ b/ed_on_bn254/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 2736030358979909402780800718157159386076813972158567259200215660948447373041 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 40): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_bn254/src/constraints/curves.rs b/ed_on_bn254/src/constraints/curves.rs index 9c9f783..df411c0 100644 --- a/ed_on_bn254/src/constraints/curves.rs +++ b/ed_on_bn254/src/constraints/curves.rs @@ -1,7 +1,6 @@ -use crate::*; use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar; -use crate::constraints::FqVar; +use crate::{constraints::FqVar, *}; /// A variable that is the R1CS equivalent of `crate::EdwardsAffine`. pub type EdwardsVar = AffineVar; diff --git a/ed_on_bn254/src/curves/mod.rs b/ed_on_bn254/src/curves/mod.rs index 9762b88..eb475e4 100644 --- a/ed_on_bn254/src/curves/mod.rs +++ b/ed_on_bn254/src/curves/mod.rs @@ -1,9 +1,10 @@ -use crate::{Fq, Fr}; use ark_ec::{ models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, twisted_edwards_extended::{GroupAffine, GroupProjective}, }; -use ark_ff::field_new; +use ark_ff::MontFp; + +use crate::{Fq, Fr}; #[cfg(test)] mod tests; @@ -18,7 +19,6 @@ pub type EdwardsProjective = GroupProjective; /// Baby-JubJub's curve equation: x² + y² = 1 + (168696/168700)x²y² /// /// q = 21888242871839275222246405745257275088548364400416034343698204186575808495617 -/// #[derive(Clone, Default, PartialEq, Eq)] pub struct EdwardsParameters; @@ -31,14 +31,15 @@ impl ModelParameters for EdwardsParameters { /// COFACTOR^(-1) mod r = /// 2394026564107420727433200628387514462817212225638746351800188703329891451411 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "2394026564107420727433200628387514462817212225638746351800188703329891451411"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "2394026564107420727433200628387514462817212225638746351800188703329891451411" + ); } impl TEModelParameters for EdwardsParameters { /// COEFF_A = 1 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "1"); + const COEFF_A: Fq = MontFp!(Fq, "1"); #[inline(always)] fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField { @@ -47,8 +48,10 @@ impl TEModelParameters for EdwardsParameters { /// COEFF_D = 168696/168700 mod q /// = 9706598848417545097372247223557719406784115219466060233080913168975159366771 - #[rustfmt::skip] - const COEFF_D: Fq = field_new!(Fq, "9706598848417545097372247223557719406784115219466060233080913168975159366771"); + const COEFF_D: Fq = MontFp!( + Fq, + "9706598848417545097372247223557719406784115219466060233080913168975159366771" + ); /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y); @@ -58,16 +61,19 @@ impl TEModelParameters for EdwardsParameters { impl MontgomeryModelParameters for EdwardsParameters { /// COEFF_A = 168698 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "168698"); + const COEFF_A: Fq = MontFp!(Fq, "168698"); /// COEFF_B = 168700 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "168700"); + const COEFF_B: Fq = MontFp!(Fq, "168700"); type TEModelParameters = EdwardsParameters; } -#[rustfmt::skip] -const GENERATOR_X: Fq = field_new!(Fq, "19698561148652590122159747500897617769866003486955115824547446575314762165298"); -#[rustfmt::skip] -const GENERATOR_Y: Fq = field_new!(Fq, "19298250018296453272277890825869354524455968081175474282777126169995084727839"); +const GENERATOR_X: Fq = MontFp!( + Fq, + "19698561148652590122159747500897617769866003486955115824547446575314762165298" +); + +const GENERATOR_Y: Fq = MontFp!( + Fq, + "19298250018296453272277890825869354524455968081175474282777126169995084727839" +); diff --git a/ed_on_bn254/src/curves/tests.rs b/ed_on_bn254/src/curves/tests.rs index 358d89a..f3d220e 100644 --- a/ed_on_bn254/src/curves/tests.rs +++ b/ed_on_bn254/src/curves/tests.rs @@ -1,13 +1,10 @@ +use ark_algebra_test_templates::{curves::*, groups::*}; use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_ff::{bytes::FromBytes, Zero}; -use ark_std::rand::Rng; -use ark_std::str::FromStr; -use ark_std::test_rng; +use ark_std::{rand::Rng, str::FromStr, test_rng}; use crate::*; -use ark_algebra_test_templates::{curves::*, groups::*}; - #[test] fn test_projective_curve() { curve_tests::(); diff --git a/ed_on_bn254/src/fields/fq.rs b/ed_on_bn254/src/fields/fq.rs index 800a203..e4ae199 100644 --- a/ed_on_bn254/src/fields/fq.rs +++ b/ed_on_bn254/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_bn254::{Fr as Fq, FrParameters as FqParameters}; +pub use ark_bn254::{Fr as Fq, FrConfig as FqConfig}; diff --git a/ed_on_bn254/src/fields/fr.rs b/ed_on_bn254/src/fields/fr.rs index 63b3ba5..143577f 100644 --- a/ed_on_bn254/src/fields/fr.rs +++ b/ed_on_bn254/src/fields/fr.rs @@ -1,87 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - fields::{FftParameters, Fp256, Fp256Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; -pub type Fr = Fp256; - -pub struct FrParameters; - -impl Fp256Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 4; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 0x1721ada8d4d27255, - 0xcda0f5264e0e35bb, - 0x961a936922086fe6, - 0x1ab00857387dd52, - ]); -} -impl FpParameters for FrParameters { - /// MODULUS = 2736030358979909402780800718157159386076813972158567259200215660948447373041 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0x677297dc392126f1, - 0xab3eedb83920ee0a, - 0x370a08b6d0302b0b, - 0x60c89ce5c263405, - ]); - - const MODULUS_BITS: u32 = 251; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 5; - - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 0x073315dea08f9c76, - 0xe7acffc6a098f24b, - 0xf85a9201d818f015, - 0x1f16424e1bb7724, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 0x35e44abee7ecb21e, - 0x74646cacf5f84ec4, - 0xe472df203faa158f, - 0x445b524f1ba50a8, - ]); - - const INV: u64 = 0x532ce5aebc48f5ef; - - #[rustfmt::skip] - /// GENERATOR = 31 - const GENERATOR: BigInteger = BigInt::new([ - 0x3c284f376f3993d1, - 0x08bc9d93705cf8b8, - 0x239d5fcbd9538f3e, - 0x5ca4836185b994b, - ]); - - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x33b94bee1c909378, - 0xd59f76dc1c907705, - 0x9b85045b68181585, - 0x30644e72e131a02, - ]); - - const T: BigInteger = BigInt::new([ - 0xa677297dc392126f, - 0xbab3eedb83920ee0, - 0x5370a08b6d0302b0, - 0x60c89ce5c26340, - ]); - - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x533b94bee1c90937, - 0x5d59f76dc1c90770, - 0x29b85045b6818158, - 0x30644e72e131a0, - ]); -} +#[derive(MontConfig)] +#[modulus = "2736030358979909402780800718157159386076813972158567259200215660948447373041"] +#[generator = "31"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/ed_on_bn254/src/fields/mod.rs b/ed_on_bn254/src/fields/mod.rs index 9e3fbaa..7afba55 100644 --- a/ed_on_bn254/src/fields/mod.rs +++ b/ed_on_bn254/src/fields/mod.rs @@ -4,5 +4,5 @@ pub mod fr; pub use fq::*; pub use fr::*; -#[cfg(all(feature = "ed_on_bn254", test))] +#[cfg(test)] mod tests; diff --git a/ed_on_bn254/src/fields/tests.rs b/ed_on_bn254/src/fields/tests.rs index e392987..861a07b 100644 --- a/ed_on_bn254/src/fields/tests.rs +++ b/ed_on_bn254/src/fields/tests.rs @@ -1,34 +1,20 @@ -use crate::{Fq, Fr}; +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{ biginteger::BigInteger256 as BigInteger, bytes::{FromBytes, ToBytes}, - fields::{Field, LegendreSymbol::*, SquareRootField}, - One, Zero, + fields::{Field, LegendreSymbol::*, PrimeField, SquareRootField}, + One, UniformRand, Zero, }; -use ark_std::test_rng; - -use ark_algebra_test_templates::fields::*; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, str::FromStr, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; -use ark_std::rand::Rng; -use ark_std::str::FromStr; - -#[test] -fn test_fr() { - let mut rng = test_rng(); - let a: Fr = rng.gen(); - let b: Fr = rng.gen(); - field_test(a, b); - primefield_test::(); -} +use crate::{Fq, FqConfig, Fr, FrConfig}; -#[test] -fn test_fq() { - let mut rng = test_rng(); - let a: Fq = rng.gen(); - let b: Fq = rng.gen(); - field_test(a, b); - primefield_test::(); -} +generate_field_test!(ed_on_bn254; mont(4, 4); ); +generate_field_serialization_test!(ed_on_bn254;); #[test] fn test_fq_add() { @@ -149,22 +135,6 @@ fn test_fq_sub() { assert_eq!(f1 - &f2, f3); } -#[test] -fn test_fq_double_in_place() { - let mut f1 = Fq::from_str( - "29729289787452206300641229002276778748586801323231253291984198106063944136114", - ) - .unwrap(); - let f3 = Fq::from_str( - "15682093831225862156789646514039007320076873845630437896571987838976271280994", - ) - .unwrap(); - assert!(!f1.is_zero()); - assert!(!f3.is_zero()); - f1.double_in_place(); - assert_eq!(f1, f3); -} - #[test] fn test_fq_double_in_place_thrice() { let mut f1 = Fq::from_str( @@ -276,22 +246,9 @@ fn test_fq_square_in_place() { assert_eq!(f1, f3); } -#[test] -fn test_fq_sqrt() { - let f1 = Fq::from_str( - "5830207146824777307592559303161432403393380070279905260050870500920682305217", - ) - .unwrap(); - let f3 = Fq::from_str( - "2108183130040740552565127577293974960058698876185401671087892009247563211475", - ) - .unwrap(); - assert_eq!(f1.sqrt().unwrap(), f3); -} - #[test] fn test_fq_from_str() { - let f1_from_repr = Fq::from(BigInteger([ + let f1_from_repr = Fq::from(BigInteger::new([ 0xab8a2535947d1a77, 0x9ba74cbfda0bbcda, 0xe928b59724d60baf, @@ -301,7 +258,7 @@ fn test_fq_from_str() { "13026376210409056429264774981357153555336288129100724591327877625017068755575", ) .unwrap(); - let f2_from_repr = Fq::from(BigInteger([ + let f2_from_repr = Fq::from(BigInteger::new([ 0x97e9103775d2f35c, 0xbe6756b6c587544b, 0x6ee38c3afd88ef4b, @@ -320,14 +277,14 @@ fn test_fq_legendre() { assert_eq!(QuadraticResidue, Fq::one().legendre()); assert_eq!(Zero, Fq::zero().legendre()); - let e = BigInteger([ + let e = BigInteger::new([ 0x2e8de1a676c03be8, 0x73350d34fe25a560, 0x7ea085919029688e, 0x1d0868cb993cf28, ]); assert_eq!(QuadraticResidue, Fq::from(e).legendre()); - let e = BigInteger([ + let e = BigInteger::new([ 0x891d8cc23c8d0706, 0xe91800e007db2698, 0xfff380321e9ac7a7, @@ -338,7 +295,7 @@ fn test_fq_legendre() { #[test] fn test_fq_bytes() { - let f1_from_repr = Fq::from(BigInteger([ + let f1_from_repr = Fq::from(BigInteger::new([ 0xab8a2535947d1a77, 0x9ba74cbfda0bbcda, 0xe928b59724d60baf, @@ -354,19 +311,19 @@ fn test_fq_bytes() { #[test] fn test_fr_add() { - let f1 = Fr::from(BigInteger([ + let f1 = Fr::from(BigInteger::new([ 0xccfc9a195e0f5c46, 0xaed4874d13fb1285, 0x27368f86ca2848eb, 0x4f8adcfeb44fccc, ])); - let f2 = Fr::from(BigInteger([ + let f2 = Fr::from(BigInteger::new([ 0x661ff05bf8570851, 0x1b171f4c59be97ef, 0x5d2ce7f9b4d701f3, 0x1e0e794623e0f68, ])); - let f3 = Fr::from(BigInteger([ + let f3 = Fr::from(BigInteger::new([ 0xcba9f2991d453da6, 0x1eacb8e13498bc6a, 0x4d596ec9aecf1fd3, @@ -377,19 +334,19 @@ fn test_fr_add() { #[test] fn test_fr_mul() { - let f1 = Fr::from(BigInteger([ + let f1 = Fr::from(BigInteger::new([ 0xc2964d2dd5fb980f, 0xbab64d599c57e496, 0x39cae13e7d1d4f78, 0x1aa995aa4de205c, ])); - let f2 = Fr::from(BigInteger([ + let f2 = Fr::from(BigInteger::new([ 0xc256e720cd43533b, 0x3bfbadf6247e13bb, 0x94c3d63a53714f63, 0x10f8a7bf74efd57, ])); - let f3 = Fr::from(BigInteger([ + let f3 = Fr::from(BigInteger::new([ 0x5eac88be41e0e1fd, 0x57aab36675b11e24, 0x835582d896b4d13f, @@ -399,7 +356,7 @@ fn test_fr_mul() { } #[test] fn test_fr_bytes() { - let f1_from_repr = Fr::from(BigInteger([ + let f1_from_repr = Fr::from(BigInteger::new([ 0xc81265fb4130fe0c, 0xb308836c14e22279, 0x699e887f96bff372, @@ -415,7 +372,7 @@ fn test_fr_bytes() { #[test] fn test_fr_from_str() { - let f100_from_repr = Fr::from(BigInteger([0x64, 0, 0, 0])); + let f100_from_repr = Fr::from(BigInteger::new([0x64, 0, 0, 0])); let f100 = Fr::from_str("100").unwrap(); assert_eq!(f100_from_repr, f100); } diff --git a/ed_on_bn254/src/lib.rs b/ed_on_bn254/src/lib.rs index 37f5a3f..53c0811 100644 --- a/ed_on_bn254/src/lib.rs +++ b/ed_on_bn254/src/lib.rs @@ -8,19 +8,21 @@ )] #![forbid(unsafe_code)] -//! This library implements a twisted Edwards curve whose base field is the scalar field of the -//! curve BN254. This allows defining cryptographic primitives that use elliptic curves over -//! the scalar field of the latter curve. This curve is also known as [Baby-Jubjub](https://github.com/barryWhiteHat/baby_jubjub). +//! This library implements a twisted Edwards curve whose base field is the +//! scalar field of the curve BN254. This allows defining cryptographic +//! primitives that use elliptic curves over the scalar field of the latter curve. This curve is also known as [Baby-Jubjub](https://github.com/barryWhiteHat/baby_jubjub). //! //! Curve information: -//! * Base field: q = 21888242871839275222246405745257275088548364400416034343698204186575808495617 -//! * Scalar field: r = 2736030358979909402780800718157159386076813972158567259200215660948447373041 +//! * Base field: q = +//! 21888242871839275222246405745257275088548364400416034343698204186575808495617 +//! * Scalar field: r = +//! 2736030358979909402780800718157159386076813972158567259200215660948447373041 //! * Valuation(q - 1, 2) = 28 //! * Valuation(r - 1, 2) = 4 //! * Curve equation: ax^2 + y^2 =1 + dx^2y^2, where //! * a = 1 -//! * d = 168696/168700 mod q -//! = 9706598848417545097372247223557719406784115219466060233080913168975159366771 +//! * d = 168696/168700 mod q = +//! 9706598848417545097372247223557719406784115219466060233080913168975159366771 #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/ed_on_bw6_761/src/lib.rs b/ed_on_bw6_761/src/lib.rs index 1b9c604..324065a 100644 --- a/ed_on_bw6_761/src/lib.rs +++ b/ed_on_bw6_761/src/lib.rs @@ -1,10 +1,10 @@ #![cfg_attr(not(feature = "std"), no_std)] #![forbid(unsafe_code)] -//! This library implements a twisted Edwards curve whose base field is the scalar field of the -//! curve BW6_761. *It is the same curve as that in `ark-ed_on_cp6_782`.* -//! This allows defining cryptographic primitives that use elliptic curves over the scalar field of -//! the latter curve. This curve was generated as part of the paper -//! [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). +//! This library implements a twisted Edwards curve whose base field is the +//! scalar field of the curve BW6_761. *It is the same curve as that in +//! `ark-ed_on_cp6_782`.* This allows defining cryptographic primitives that use +//! elliptic curves over the scalar field of the latter curve. This curve was +//! generated as part of the paper [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). //! //! Curve information: //! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 diff --git a/ed_on_cp6_782/scripts/base_field.sage b/ed_on_cp6_782/scripts/base_field.sage new file mode 100644 index 0000000..6d9f4a7 --- /dev/null +++ b/ed_on_cp6_782/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_cp6_782/scripts/scalar_field.sage b/ed_on_cp6_782/scripts/scalar_field.sage new file mode 100644 index 0000000..c5e2fbd --- /dev/null +++ b/ed_on_cp6_782/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 32333053251621136751331591711861691692049189094364332567435817881934511297123972799646723302813083835942624121493 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_cp6_782/src/constraints/curves.rs b/ed_on_cp6_782/src/constraints/curves.rs index 4b15106..7401d17 100644 --- a/ed_on_cp6_782/src/constraints/curves.rs +++ b/ed_on_cp6_782/src/constraints/curves.rs @@ -1,7 +1,6 @@ -use crate::*; use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar; -use crate::constraints::FqVar; +use crate::{constraints::FqVar, *}; /// A variable that is the R1CS equivalent of `crate::EdwardsAffine`. pub type EdwardsVar = AffineVar; diff --git a/ed_on_cp6_782/src/constraints/fields.rs b/ed_on_cp6_782/src/constraints/fields.rs index f25fa33..aa806e3 100644 --- a/ed_on_cp6_782/src/constraints/fields.rs +++ b/ed_on_cp6_782/src/constraints/fields.rs @@ -1,6 +1,7 @@ -use crate::fq::Fq; use ark_r1cs_std::fields::fp::FpVar; +use crate::fq::Fq; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FqVar = FpVar; diff --git a/ed_on_cp6_782/src/curves/mod.rs b/ed_on_cp6_782/src/curves/mod.rs index 4ed1198..ec8a16d 100644 --- a/ed_on_cp6_782/src/curves/mod.rs +++ b/ed_on_cp6_782/src/curves/mod.rs @@ -2,9 +2,9 @@ use ark_ec::{ models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, twisted_edwards_extended::{GroupAffine, GroupProjective}, }; -use ark_ff::field_new; +use ark_ff::MontFp; -use crate::{fq::Fq, fr::Fr}; +use crate::{Fq, Fr}; #[cfg(test)] mod tests; @@ -24,18 +24,15 @@ impl ModelParameters for EdwardsParameters { /// COFACTOR^(-1) mod r = /// 12124894969357926281749346891948134384518445910386624712788431705725441736421489799867521238554906438478484045560 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "12124894969357926281749346891948134384518445910386624712788431705725441736421489799867521238554906438478484045560"); + const COFACTOR_INV: Fr = MontFp!(Fr, "12124894969357926281749346891948134384518445910386624712788431705725441736421489799867521238554906438478484045560"); } impl TEModelParameters for EdwardsParameters { /// COEFF_A = -1 = - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "-1"); + const COEFF_A: Fq = MontFp!(Fq, "-1"); /// COEFF_D = 79743 - #[rustfmt::skip] - const COEFF_D: Fq = field_new!(Fq, "79743"); + const COEFF_D: Fq = MontFp!(Fq, "79743"); /// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y); @@ -51,21 +48,18 @@ impl TEModelParameters for EdwardsParameters { impl MontgomeryModelParameters for EdwardsParameters { /// COEFF_A = 0x95D53EB3F6AC3F7A53C26020144439DC6073BCAE513E03FD06B6B3BAA390F25E51534B26719E33F4CD906D4DA9B535 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "90083623084271891037116870487743067984710080209539149685414147055329063590616489392386084989619674926965747987765"); + const COEFF_A: Fq = MontFp!(Fq, "90083623084271891037116870487743067984710080209539149685414147055329063590616489392386084989619674926965747987765"); + /// COEFF_B = 0x118650763CE64AB4BE743604C8D05013DC2663652A3D58B21ECAB7BFF65B70DB8BA09F9098E61CC903B2F92B2564ACA - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "168580802928697202973535863207150465551683432545375510854470115611391404757724333382582803149953685197474573470410"); + const COEFF_B: Fq = MontFp!(Fq, "168580802928697202973535863207150465551683432545375510854470115611391404757724333382582803149953685197474573470410"); type TEModelParameters = EdwardsParameters; } /// GENERATOR_X = /// 174701772324485506941690903512423551998294352968833659960042362742684869862495746426366187462669992073196420267127 -#[rustfmt::skip] -const GENERATOR_X: Fq = field_new!(Fq, "174701772324485506941690903512423551998294352968833659960042362742684869862495746426366187462669992073196420267127"); +const GENERATOR_X: Fq = MontFp!(Fq, "174701772324485506941690903512423551998294352968833659960042362742684869862495746426366187462669992073196420267127"); /// GENERATOR_Y = /// 208487200052258845495340374451540775445408439654930191324011635560142523886549663106522691296420655144190624954833 -#[rustfmt::skip] -const GENERATOR_Y: Fq = field_new!(Fq, "208487200052258845495340374451540775445408439654930191324011635560142523886549663106522691296420655144190624954833"); +const GENERATOR_Y: Fq = MontFp!(Fq, "208487200052258845495340374451540775445408439654930191324011635560142523886549663106522691296420655144190624954833"); diff --git a/ed_on_cp6_782/src/curves/tests.rs b/ed_on_cp6_782/src/curves/tests.rs index 58db359..fe10970 100644 --- a/ed_on_cp6_782/src/curves/tests.rs +++ b/ed_on_cp6_782/src/curves/tests.rs @@ -1,11 +1,9 @@ +use ark_algebra_test_templates::{curves::*, groups::*}; use ark_ec::{AffineCurve, ProjectiveCurve}; -use ark_std::rand::Rng; -use ark_std::test_rng; +use ark_std::{rand::Rng, test_rng}; use crate::*; -use ark_algebra_test_templates::{curves::*, groups::*}; - #[test] fn test_projective_curve() { curve_tests::(); diff --git a/ed_on_cp6_782/src/fields/fq.rs b/ed_on_cp6_782/src/fields/fq.rs index 4361a41..01d1bd0 100644 --- a/ed_on_cp6_782/src/fields/fq.rs +++ b/ed_on_cp6_782/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_bls12_377::{Fq, FqParameters}; +pub use ark_bls12_377::{Fq, FqConfig}; diff --git a/ed_on_cp6_782/src/fields/fr.rs b/ed_on_cp6_782/src/fields/fr.rs index 3055a35..2613159 100644 --- a/ed_on_cp6_782/src/fields/fr.rs +++ b/ed_on_cp6_782/src/fields/fr.rs @@ -1,106 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger384 as BigInteger}, - fields::{FftParameters, Fp384, Fp384Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp384, MontBackend, MontConfig}; -pub type Fr = Fp384; - -pub struct FrParameters; - -impl Fp384Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 2u32; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 12119792640622387781u64, - 8318439284650634613u64, - 6931324077796168275u64, - 12851391603681523141u64, - 6881015057611215092u64, - 1893962574900431u64, - ]); -} -impl FpParameters for FrParameters { - /// MODULUS = 32333053251621136751331591711861691692049189094364332567435817881934511297123972799646723302813083835942624121493 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 4684667634276979349u64, - 3748803659444032385u64, - 16273581227874629698u64, - 7152942431629910641u64, - 6397188139321141543u64, - 15137289088311837u64, - ]); - - const MODULUS_BITS: u32 = 374; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 10; - - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 12565484300600153878u64, - 8749673077137355528u64, - 9027943686469014788u64, - 13026065139386752555u64, - 11197589485989933721u64, - 9525964145733727u64, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 17257035094703902127u64, - 16096159112880350050u64, - 3498553494623421763u64, - 333405339929360058u64, - 1125865524035793947u64, - 1586246138566285u64, - ]); - - const INV: u64 = 16242011933465909059u64; - - // 2 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 1999556893213776791u64, - 13750542494830678672u64, - 1782306145063399878u64, - 452443773434042853u64, - 15997990832658725900u64, - 3914639203155617u64, - ]); - - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 11565705853993265482u64, - 1874401829722016192u64, - 17360162650792090657u64, - 12799843252669731128u64, - 12421966106515346579u64, - 7568644544155918u64, - ]); - - /// 8083263312905284187832897927965422923012297273591083141858954470483627824280993199911680825703270958985656030373 - const T: BigInteger = BigInt::new([ - 5782852926996632741, - 10160572951715783904, - 8680081325396045328, - 15623293663189641372, - 6210983053257673289, - 3784322272077959, - ]); - - /// 4041631656452642093916448963982711461506148636795541570929477235241813912140496599955840412851635479492828015186 - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 2891426463498316370, - 5080286475857891952, - 4340040662698022664, - 17035018868449596494, - 12328863563483612452, - 1892161136038979, - ]); -} +#[derive(MontConfig)] +#[modulus = "32333053251621136751331591711861691692049189094364332567435817881934511297123972799646723302813083835942624121493"] +#[generator = "13"] +pub struct FrConfig; +pub type Fr = Fp384>; diff --git a/ed_on_cp6_782/src/fields/mod.rs b/ed_on_cp6_782/src/fields/mod.rs index 208333f..7afba55 100644 --- a/ed_on_cp6_782/src/fields/mod.rs +++ b/ed_on_cp6_782/src/fields/mod.rs @@ -4,5 +4,5 @@ pub mod fr; pub use fq::*; pub use fr::*; -#[cfg(all(feature = "ed_on_cp6_782", test))] +#[cfg(test)] mod tests; diff --git a/ed_on_cp6_782/src/fields/tests.rs b/ed_on_cp6_782/src/fields/tests.rs index 173b5ee..c1a208b 100644 --- a/ed_on_cp6_782/src/fields/tests.rs +++ b/ed_on_cp6_782/src/fields/tests.rs @@ -1,24 +1,12 @@ -use ark_std::rand::Rng; -use ark_std::test_rng; - -use crate::{Fq, Fr}; - -use ark_algebra_test_templates::fields::*; - -#[test] -fn test_fr() { - let mut rng = test_rng(); - let a: Fr = rng.gen(); - let b: Fr = rng.gen(); - field_test(a, b); - primefield_test::(); -} - -#[test] -fn test_fq() { - let mut rng = test_rng(); - let a: Fq = rng.gen(); - let b: Fq = rng.gen(); - field_test(a, b); - primefield_test::(); -} +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; +use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; + +use crate::{Fq, FqConfig, Fr, FrConfig}; + +generate_field_test!(ed_on_cp6_782; mont(6, 6); ); +generate_field_serialization_test!(ed_on_cp6_782;); diff --git a/ed_on_cp6_782/src/lib.rs b/ed_on_cp6_782/src/lib.rs index 2879a94..79c06ba 100644 --- a/ed_on_cp6_782/src/lib.rs +++ b/ed_on_cp6_782/src/lib.rs @@ -8,9 +8,9 @@ )] #![forbid(unsafe_code)] -//! This library implements a twisted Edwards curve whose base field is the scalar field of the curve CP6. -//! This allows defining cryptographic primitives that use elliptic curves over the scalar field of the latter curve. -//! This curve was generated as part of the paper [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). +//! This library implements a twisted Edwards curve whose base field is the +//! scalar field of the curve CP6. This allows defining cryptographic primitives +//! that use elliptic curves over the scalar field of the latter curve. This curve was generated as part of the paper [\[BCGMMW20, “Zexe”\]](https://eprint.iacr.org/2018/962). //! //! Curve information: //! * Base field: q = 258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 diff --git a/ed_on_mnt4_298/scripts/base_field.sage b/ed_on_mnt4_298/scripts/base_field.sage new file mode 100644 index 0000000..05e4af4 --- /dev/null +++ b/ed_on_mnt4_298/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_mnt4_298/scripts/scalar_field.sage b/ed_on_mnt4_298/scripts/scalar_field.sage new file mode 100644 index 0000000..aa8303d --- /dev/null +++ b/ed_on_mnt4_298/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 118980571542315331438337312413262112886281219744507561120271964887686106682370032123932631 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_mnt4_298/src/constraints/curves.rs b/ed_on_mnt4_298/src/constraints/curves.rs index 3ceded4..88bac55 100644 --- a/ed_on_mnt4_298/src/constraints/curves.rs +++ b/ed_on_mnt4_298/src/constraints/curves.rs @@ -1,7 +1,6 @@ -use crate::*; use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar; -use crate::constraints::fields::FqVar; +use crate::{constraints::fields::FqVar, *}; /// A variable that is the R1CS equivalent of `crate::EdwardsAffine`. pub type EdwardsVar = AffineVar; diff --git a/ed_on_mnt4_298/src/constraints/fields.rs b/ed_on_mnt4_298/src/constraints/fields.rs index f25fa33..aa806e3 100644 --- a/ed_on_mnt4_298/src/constraints/fields.rs +++ b/ed_on_mnt4_298/src/constraints/fields.rs @@ -1,6 +1,7 @@ -use crate::fq::Fq; use ark_r1cs_std::fields::fp::FpVar; +use crate::fq::Fq; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FqVar = FpVar; diff --git a/ed_on_mnt4_298/src/curves/mod.rs b/ed_on_mnt4_298/src/curves/mod.rs index 29f6110..9066d3b 100644 --- a/ed_on_mnt4_298/src/curves/mod.rs +++ b/ed_on_mnt4_298/src/curves/mod.rs @@ -2,7 +2,7 @@ use ark_ec::{ models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, twisted_edwards_extended::{GroupAffine, GroupProjective}, }; -use ark_ff::field_new; +use ark_ff::MontFp; use crate::{fq::Fq, fr::Fr}; @@ -24,8 +24,10 @@ impl ModelParameters for EdwardsParameters { /// COFACTOR_INV (mod r) = /// 29745142885578832859584328103315528221570304936126890280067991221921526670592508030983158 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "29745142885578832859584328103315528221570304936126890280067991221921526670592508030983158"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "29745142885578832859584328103315528221570304936126890280067991221921526670592508030983158" + ); } // Many parameters need to be written down in the Montgomery residue form, @@ -38,15 +40,13 @@ impl TEModelParameters for EdwardsParameters { /// Needs to be in the Montgomery residue form in Fq /// I.e., -1 * R for Fq /// = 252557637842979910814547544293825421990201153003031094870216460866964386803867699028196261 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "-1"); + const COEFF_A: Fq = MontFp!(Fq, "-1"); /// COEFF_D = 4212 /// Needs to be in the Montgomery residue form in Fq /// I.e., 4212 * R for Fq /// = 389461279836940033614665658623660232171971995346409183754923941118154161474636585314923000 - #[rustfmt::skip] - const COEFF_D: Fq = field_new!(Fq, "4212"); + const COEFF_D: Fq = MontFp!(Fq, "4212"); /// Generated randomly const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y); @@ -62,21 +62,24 @@ impl TEModelParameters for EdwardsParameters { impl MontgomeryModelParameters for EdwardsParameters { /// COEFF_A = 203563247015667910991582090642011229452721346107806307863040223071914240315202967004285204 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "203563247015667910991582090642011229452721346107806307863040223071914240315202967004285204"); + const COEFF_A: Fq = MontFp!(Fq, "203563247015667910991582090642011229452721346107806307863040223071914240315202967004285204"); + /// COEFF_B = 272359039153593414761767159011037222092403532445017207690227512667250406992205523555677931 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "272359039153593414761767159011037222092403532445017207690227512667250406992205523555677931"); + const COEFF_B: Fq = MontFp!(Fq, "272359039153593414761767159011037222092403532445017207690227512667250406992205523555677931"); type TEModelParameters = EdwardsParameters; } /// GENERATOR_X = /// 282406820114868156776872298252698015906762052916420164316497572033519876761239463633892227 -#[rustfmt::skip] -const GENERATOR_X: Fq = field_new!(Fq, "282406820114868156776872298252698015906762052916420164316497572033519876761239463633892227"); +const GENERATOR_X: Fq = MontFp!( + Fq, + "282406820114868156776872298252698015906762052916420164316497572033519876761239463633892227" +); /// GENERATOR_Y = /// 452667754940241021433619311795265643711152068500301853535337412655162600774122192283142703 -#[rustfmt::skip] -const GENERATOR_Y: Fq = field_new!(Fq, "452667754940241021433619311795265643711152068500301853535337412655162600774122192283142703"); +const GENERATOR_Y: Fq = MontFp!( + Fq, + "452667754940241021433619311795265643711152068500301853535337412655162600774122192283142703" +); diff --git a/ed_on_mnt4_298/src/curves/tests.rs b/ed_on_mnt4_298/src/curves/tests.rs index dae0ba2..02a0b15 100644 --- a/ed_on_mnt4_298/src/curves/tests.rs +++ b/ed_on_mnt4_298/src/curves/tests.rs @@ -1,11 +1,9 @@ +use ark_algebra_test_templates::{curves::*, groups::*}; use ark_ec::{AffineCurve, ProjectiveCurve}; -use ark_std::rand::Rng; -use ark_std::test_rng; +use ark_std::{rand::Rng, test_rng}; use crate::*; -use ark_algebra_test_templates::{curves::*, groups::*}; - #[test] fn test_projective_curve() { curve_tests::(); diff --git a/ed_on_mnt4_298/src/fields/fq.rs b/ed_on_mnt4_298/src/fields/fq.rs index f587b1a..6397898 100644 --- a/ed_on_mnt4_298/src/fields/fq.rs +++ b/ed_on_mnt4_298/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_mnt4_298::{Fr as Fq, FrParameters as FqParameters}; +pub use ark_mnt4_298::{Fr as Fq, FrConfig as FqConfig}; diff --git a/ed_on_mnt4_298/src/fields/fr.rs b/ed_on_mnt4_298/src/fields/fr.rs index f1f377d..20e5c1e 100644 --- a/ed_on_mnt4_298/src/fields/fr.rs +++ b/ed_on_mnt4_298/src/fields/fr.rs @@ -1,127 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger320 as BigInteger}, - fields::{FftParameters, Fp320, Fp320Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp320, MontBackend, MontConfig}; -pub type Fr = Fp320; - -pub struct FrParameters; - -impl Fp320Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 1u32; - - // ROOT_OF_UNITY = GENERATOR ^ t = - // 118980571542315331438337312413262112886281219744507561120271964887686106682370032123932630 - // t is defined below - // This number needs to be in the Montgomery residue form. - // I.e., write - // 118980571542315331438337312413262112886281219744507561120271964887686106682370032123932630 - // * R - // = 14596494758349247937872919467301196219547084259323651055171406111196152579418790325693086 - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 4913018085921565342u64, - 18164325898792356216u64, - 11499902056485864693u64, - 12113224729248979119u64, - 126057789046u64, - ]); -} -impl FpParameters for FrParameters { - // MODULUS = 118980571542315331438337312413262112886281219744507561120271964887686106682370032123932631 - // Factors of MODULUS - 1: - // 2 - // 5 - // 17 - // 47 - // 3645289 - // 42373926857 - // 96404785755712297250936212793128201320333033128042968811755970858369 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 15535567651727634391u64, - 14992835038329117496u64, - 12879083654034347181u64, - 16760578290609820963u64, - 1027536270620u64, - ]); - - const MODULUS_BITS: u32 = 296; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 24; - - // see ark-ff/src/fields/mod.rs for more information - // R = pow(2,320) % - // 118980571542315331438337312413262112886281219744507561120271964887686106682370032123932631 - // R = 104384076783966083500464392945960916666734135485183910065100558776489954102951241798239545 - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 10622549565806069049u64, - 15275253213246312896u64, - 1379181597548482487u64, - 4647353561360841844u64, - 901478481574u64 - ]); - - // R2 = R * R % - // 118980571542315331438337312413262112886281219744507561120271964887686106682370032123932631 - // R2 = 64940318866745953005690402896764745514897573584912026577721076893188083397226247459368768 - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 16858329796171722560u64, - 12060416575249219689u64, - 17034911964548502611u64, - 14718631438675169669u64, - 560835539754u64 - ]); - - // INV = -(118980571542315331438337312413262112886281219744507561120271964887686106682370032123932631)^(-1) % 2^64 - const INV: u64 = 9223688842165816345u64; - - // GENERATOR = 7 - // This number needs to be in the Montgomery residue form. - // I.e., write 7 * R = - // 16805108233870595873226876142153739349451629929242003734072122109313038626438499844081029 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 18037929197695780229u64, - 16969762262749485294u64, - 6166745553471500787u64, - 5754981480705173590u64, - 145131747294u64, - ]); - - // (n-1)/2 = 59490285771157665719168656206631056443140609872253780560135982443843053341185016061966315 - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 7767783825863817195u64, - 16719789556019334556u64, - 15662913863871949398u64, - 8380289145304910481u64, - 513768135310u64, - ]); - - // t = (n - 1) / 2^{TWO_ADICITY} = - // 59490285771157665719168656206631056443140609872253780560135982443843053341185016061966315 - const T: BigInteger = BigInt::new([ - 7767783825863817195u64, - 16719789556019334556u64, - 15662913863871949398u64, - 8380289145304910481u64, - 513768135310u64, - ]); - - // (t-1)/2 = 29745142885578832859584328103315528221570304936126890280067991221921526670592508030983157 - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 3883891912931908597u64, - 8359894778009667278u64, - 17054828968790750507u64, - 4190144572652455240u64, - 256884067655u64, - ]); -} +#[derive(MontConfig)] +#[modulus = "118980571542315331438337312413262112886281219744507561120271964887686106682370032123932631"] +#[generator = "7"] +pub struct FrConfig; +pub type Fr = Fp320>; diff --git a/ed_on_mnt4_298/src/fields/mod.rs b/ed_on_mnt4_298/src/fields/mod.rs index 2b2e27c..7afba55 100644 --- a/ed_on_mnt4_298/src/fields/mod.rs +++ b/ed_on_mnt4_298/src/fields/mod.rs @@ -4,5 +4,5 @@ pub mod fr; pub use fq::*; pub use fr::*; -#[cfg(all(feature = "ed_on_mnt4_298", test))] +#[cfg(test)] mod tests; diff --git a/ed_on_mnt4_298/src/fields/tests.rs b/ed_on_mnt4_298/src/fields/tests.rs index cc0fbb1..83af9f5 100644 --- a/ed_on_mnt4_298/src/fields/tests.rs +++ b/ed_on_mnt4_298/src/fields/tests.rs @@ -1,24 +1,12 @@ -use ark_std::rand::Rng; -use ark_std::test_rng; - -use crate::fields::*; - -use ark_algebra_test_templates::fields::*; - -#[test] -fn test_fr() { - let mut rng = test_rng(); - let a: Fr = rng.gen(); - let b: Fr = rng.gen(); - field_test(a, b); - primefield_test::(); -} - -#[test] -fn test_fq() { - let mut rng = test_rng(); - let a: Fq = rng.gen(); - let b: Fq = rng.gen(); - field_test(a, b); - primefield_test::(); -} +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; +use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; + +use crate::{Fq, FqConfig, Fr, FrConfig}; + +generate_field_test!(ed_on_mnt4_298; mont(5, 5); ); +generate_field_serialization_test!(ed_on_mnt4_298;); diff --git a/ed_on_mnt4_298/src/lib.rs b/ed_on_mnt4_298/src/lib.rs index 8fabdf0..5c5afae 100644 --- a/ed_on_mnt4_298/src/lib.rs +++ b/ed_on_mnt4_298/src/lib.rs @@ -8,13 +8,16 @@ )] #![forbid(unsafe_code)] -//! This library implements a twisted Edwards curve whose base field is the scalar field of the -//! curve MNT4-298. This allows defining cryptographic primitives that use elliptic curves over -//! the scalar field of the latter curve. +//! This library implements a twisted Edwards curve whose base field is the +//! scalar field of the curve MNT4-298. This allows defining cryptographic +//! primitives that use elliptic curves over the scalar field of the latter +//! curve. //! //! Curve information: -//! * Base field: q = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 -//! * Scalar field: r = 118980571542315331438337312413262112886281219744507561120271964887686106682370032123932631 +//! * Base field: q = +//! 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 +//! * Scalar field: r = +//! 118980571542315331438337312413262112886281219744507561120271964887686106682370032123932631 //! * Valuation(q - 1, 2) = 30 //! * Valuation(r - 1, 2) = 1 //! * Curve equation: ax^2 + y^2 =1 + dx^2y^2, where diff --git a/ed_on_mnt4_753/scripts/base_field.sage b/ed_on_mnt4_753/scripts/base_field.sage new file mode 100644 index 0000000..b91ade8 --- /dev/null +++ b/ed_on_mnt4_753/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_mnt4_753/scripts/scalar_field.sage b/ed_on_mnt4_753/scripts/scalar_field.sage new file mode 100644 index 0000000..aab26a9 --- /dev/null +++ b/ed_on_mnt4_753/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 5237311370989869175293026848905079641021338739994243633972937865128169101571388346632361720473792365177258871486054600656048925740061347509722287043067341250552640264308621296888446513816907173362124418513727200975392177480577 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/ed_on_mnt4_753/src/constraints/curves.rs b/ed_on_mnt4_753/src/constraints/curves.rs index 3ceded4..88bac55 100644 --- a/ed_on_mnt4_753/src/constraints/curves.rs +++ b/ed_on_mnt4_753/src/constraints/curves.rs @@ -1,7 +1,6 @@ -use crate::*; use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar; -use crate::constraints::fields::FqVar; +use crate::{constraints::fields::FqVar, *}; /// A variable that is the R1CS equivalent of `crate::EdwardsAffine`. pub type EdwardsVar = AffineVar; diff --git a/ed_on_mnt4_753/src/constraints/fields.rs b/ed_on_mnt4_753/src/constraints/fields.rs index f25fa33..aa806e3 100644 --- a/ed_on_mnt4_753/src/constraints/fields.rs +++ b/ed_on_mnt4_753/src/constraints/fields.rs @@ -1,6 +1,7 @@ -use crate::fq::Fq; use ark_r1cs_std::fields::fp::FpVar; +use crate::fq::Fq; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FqVar = FpVar; diff --git a/ed_on_mnt4_753/src/curves/mod.rs b/ed_on_mnt4_753/src/curves/mod.rs index cf56d87..1926b53 100644 --- a/ed_on_mnt4_753/src/curves/mod.rs +++ b/ed_on_mnt4_753/src/curves/mod.rs @@ -2,7 +2,7 @@ use ark_ec::{ models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, twisted_edwards_extended::{GroupAffine, GroupProjective}, }; -use ark_ff::field_new; +use ark_ff::MontFp; use crate::{fq::Fq, fr::Fr}; @@ -24,18 +24,15 @@ impl ModelParameters for EdwardsParameters { /// COFACTOR_INV (mod r) = /// 4582647449616135528381398492791944685893671397494963179726320631987147963874964803303316505414568319530101512550297775574042810022553679071007001162683923594233560231270043634777390699589793776691858866199511300853468155295505 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "4582647449616135528381398492791944685893671397494963179726320631987147963874964803303316505414568319530101512550297775574042810022553679071007001162683923594233560231270043634777390699589793776691858866199511300853468155295505"); + const COFACTOR_INV: Fr = MontFp!(Fr, "4582647449616135528381398492791944685893671397494963179726320631987147963874964803303316505414568319530101512550297775574042810022553679071007001162683923594233560231270043634777390699589793776691858866199511300853468155295505"); } impl TEModelParameters for EdwardsParameters { /// COEFF_A = -1 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "-1"); + const COEFF_A: Fq = MontFp!(Fq, "-1"); /// COEFF_D = 317690 - #[rustfmt::skip] - const COEFF_D: Fq = field_new!(Fq, "317690"); + const COEFF_D: Fq = MontFp!(Fq, "317690"); /// Generated randomly const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y); @@ -51,22 +48,18 @@ impl TEModelParameters for EdwardsParameters { impl MontgomeryModelParameters for EdwardsParameters { /// COEFF_A = 40212480635445336270302172549278415015971955924352275480357619589919378421241453024646804979794897776496091377551124233752850182852486874251193367187677349266115879541798515219680194853352256809837126277708211496794264654247419 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "40212480635445336270302172549278415015971955924352275480357619589919378421241453024646804979794897776496091377551124233752850182852486874251193367187677349266115879541798515219680194853352256809837126277708211496794264654247419"); + const COEFF_A: Fq = MontFp!(Fq, "40212480635445336270302172549278415015971955924352275480357619589919378421241453024646804979794897776496091377551124233752850182852486874251193367187677349266115879541798515219680194853352256809837126277708211496794264654247419"); /// COEFF_B = 1686010332473617132042042241962222112198753995601673591425883331105974391329653748412088783995441144921979594337334243570322874639106980818502874667119046899605536783551549221790223284494141659774809441351696667426519821912580 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "1686010332473617132042042241962222112198753995601673591425883331105974391329653748412088783995441144921979594337334243570322874639106980818502874667119046899605536783551549221790223284494141659774809441351696667426519821912580"); + const COEFF_B: Fq = MontFp!(Fq, "1686010332473617132042042241962222112198753995601673591425883331105974391329653748412088783995441144921979594337334243570322874639106980818502874667119046899605536783551549221790223284494141659774809441351696667426519821912580"); type TEModelParameters = EdwardsParameters; } /// GENERATOR_X = /// 41126137307536311801428235632419266329480236393691483739251051053325519918069469184425962602019877935619960143044210127218431046103600632347238890180171944971817510488009355627861577881883236134824745174469522277738875418206826 -#[rustfmt::skip] -const GENERATOR_X: Fq = field_new!(Fq, "41126137307536311801428235632419266329480236393691483739251051053325519918069469184425962602019877935619960143044210127218431046103600632347238890180171944971817510488009355627861577881883236134824745174469522277738875418206826"); +const GENERATOR_X: Fq = MontFp!(Fq, "41126137307536311801428235632419266329480236393691483739251051053325519918069469184425962602019877935619960143044210127218431046103600632347238890180171944971817510488009355627861577881883236134824745174469522277738875418206826"); /// GENERATOR_Y = /// 18249602579663240810999977712212098844157230095713722119136881953011435881503578209163288529034825612841855863913294174196656077002578342108932925693640046298989762289691399012056048139253937882385653600831389370198228562812681 -#[rustfmt::skip] -const GENERATOR_Y: Fq = field_new!(Fq, "18249602579663240810999977712212098844157230095713722119136881953011435881503578209163288529034825612841855863913294174196656077002578342108932925693640046298989762289691399012056048139253937882385653600831389370198228562812681"); +const GENERATOR_Y: Fq = MontFp!(Fq, "18249602579663240810999977712212098844157230095713722119136881953011435881503578209163288529034825612841855863913294174196656077002578342108932925693640046298989762289691399012056048139253937882385653600831389370198228562812681"); diff --git a/ed_on_mnt4_753/src/curves/tests.rs b/ed_on_mnt4_753/src/curves/tests.rs index dae0ba2..02a0b15 100644 --- a/ed_on_mnt4_753/src/curves/tests.rs +++ b/ed_on_mnt4_753/src/curves/tests.rs @@ -1,11 +1,9 @@ +use ark_algebra_test_templates::{curves::*, groups::*}; use ark_ec::{AffineCurve, ProjectiveCurve}; -use ark_std::rand::Rng; -use ark_std::test_rng; +use ark_std::{rand::Rng, test_rng}; use crate::*; -use ark_algebra_test_templates::{curves::*, groups::*}; - #[test] fn test_projective_curve() { curve_tests::(); diff --git a/ed_on_mnt4_753/src/fields/fq.rs b/ed_on_mnt4_753/src/fields/fq.rs index 33f3df1..05302cd 100644 --- a/ed_on_mnt4_753/src/fields/fq.rs +++ b/ed_on_mnt4_753/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_mnt4_753::{Fr as Fq, FrParameters as FqParameters}; +pub use ark_mnt4_753::{Fr as Fq, FrConfig as FqConfig}; diff --git a/ed_on_mnt4_753/src/fields/fr.rs b/ed_on_mnt4_753/src/fields/fr.rs index ae6ee88..d305053 100644 --- a/ed_on_mnt4_753/src/fields/fr.rs +++ b/ed_on_mnt4_753/src/fields/fr.rs @@ -1,182 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger768 as BigInteger}, - fields::{FftParameters, Fp768, Fp768Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp768, MontBackend, MontConfig}; -pub type Fr = Fp768; - -pub struct FrParameters; - -impl Fp768Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 7u32; - - // ROOT_OF_UNITY = GENERATOR ^ t = - // 5051348772165646558710889803432238607797392809516000790038615454406641638798360636639094562941749878118669420392611632754442159525900729019616828636182878045303562497793780656635901271279409699078868658041674335385318499053954 - // t is defined below - // This number needs to be in the Montgomery residue form. - // I.e., write - // 5051348772165646558710889803432238607797392809516000790038615454406641638798360636639094562941749878118669420392611632754442159525900729019616828636182878045303562497793780656635901271279409699078868658041674335385318499053954 - // * R - // = 3163945077843586747114473523156080008349200300253316071422414259389979351386670787753361998953450578171951209600907861296956453653582402723399808696724060539858637307706671971132333536614595846054039300191656599533885935499352 - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 17630237153019476056u64, - 13843632041501582123u64, - 8277579215948731020u64, - 16543319700733887487u64, - 17904443422768964556u64, - 4398189354108552378u64, - 15178824470536352826u64, - 5393472405610595666u64, - 9815530206026813666u64, - 9111703519527971535u64, - 9880873531994141485u64, - 37593433148184u64, - ]); -} -impl FpParameters for FrParameters { - // MODULUS = 5237311370989869175293026848905079641021338739994243633972937865128169101571388346632361720473792365177258871486054600656048925740061347509722287043067341250552640264308621296888446513816907173362124418513727200975392177480577 - // Factors of MODULUS - 1: - // 2^7 - // 3 - // 67 - // 193189 - // 5324381 - // 20502324317011 - // 12991385268608969143 - // 743005941432538001939136029613828619428586060274612824031793373798492678674419102414979927623550862639644071557313558044209469997283394306590808303316688123808776073253386140931 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 1918157353135465345u64, - 963476667289301255u64, - 6719983938249379016u64, - 3655897403342429413u64, - 14998997414201165002u64, - 13135040821375901270u64, - 12914675130452106995u64, - 6989506515121216945u64, - 12382362535852178190u64, - 13186314214759855613u64, - 2451174275904461237u64, - 62228802984066u64, - ]); - - const MODULUS_BITS: u32 = 750; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 18; - - // see ark_ff/src/fields/mod.rs for more information - // R = pow(2,768) % MODULUS - // R = 933352698056040166367534174176950366489065242993745918174914647273231163953185260894581718311971532174387033963715296372791285468903747270837716556902938133611910788060028435531754797383796835009316018259656953442114538695438 - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 13829252738394483470u64, - 3696102008259415033u64, - 13727024804350215797u64, - 13923468026436718769u64, - 5924604905079742862u64, - 10708002647109138222u64, - 14670460945619011269u64, - 10920055614013427454u64, - 16773322069409968132u64, - 11648025004657998992u64, - 5853759956175613481u64, - 11089930891582u64, - ]); - - // R2 = R * R % MODULUS - // R2 = 2468731867191023344597744941938926307216338526282824416880609839804154918771848044056240157551420210981962520047623686977567450338290776997282473798413876535168711321018336215486289519735826959884564283681071791441993286279295 - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 10440129917231554687u64, - 8797934528693354276u64, - 14378434434829994158u64, - 7755707164286885667u64, - 16206546501540671680u64, - 8674228973811871262u64, - 12794601382709871071u64, - 17194287857269754157u64, - 2120600029739364160u64, - 15454005187782655500u64, - 18107041519543174727u64, - 29333033326005u64, - ]); - - // INV = -(MODULUS)^(-1) % 2^64 - const INV: u64 = 3079018560679650175u64; - - // GENERATOR = 5 - // This number needs to be in the Montgomery residue form. - // I.e., write 5 * R = - // 4666763490280200831837670870884751832445326214968729590874573236366155819765926304472908591559857660871935169818576481863956427344518736354188582784514690668059553940300142177658773986918984175046580091298284767210572693477190 - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 13806031470843762502u64, - 33765967587523552u64, - 13294891800622424138u64, - 14277107911054939000u64, - 11176280451689162697u64, - 16646525088126587879u64, - 18012072506966401499u64, - 17706789922648034041u64, - 10079634052211634198u64, - 2899892802161340116u64, - 10822055707168515792u64, - 55449654457911u64, - ]); - - // (n-1)/2 = 2618655685494934587646513424452539820510669369997121816986468932564084550785694173316180860236896182588629435743027300328024462870030673754861143521533670625276320132154310648444223256908453586681062209256863600487696088740288 - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 10182450713422508480u64, - 481738333644650627u64, - 12583364005979465316u64, - 1827948701671214706u64, - 7499498707100582501u64, - 15790892447542726443u64, - 15680709602080829305u64, - 3494753257560608472u64, - 15414553304780864903u64, - 15816529144234703614u64, - 1225587137952230618u64, - 31114401492033u64, - ]); - - // t = (n - 1) / 2^{TWO_ADICITY} = - // 40916495085858352931976772257070934695479208906205028390413577071313821106026471458065325941201502852947334933484801567625382232344229277419705367523963603519942502064911103881940988389194587291891597019638493757620251386567 - const T: BigInteger = BigInt::new([ - 1023791920852361927u64, - 10383820702924820450u64, - 14608133870179016345u64, - 10693085616076947257u64, - 12511085841822051593u64, - 16675864135140424508u64, - 7162540115173594813u64, - 2072218152711366715u64, - 18111135716793329142u64, - 7741123047823172587u64, - 307380175182215347u64, - 486162523313u64, - ]); - - // (t-1)/2 = 20458247542929176465988386128535467347739604453102514195206788535656910553013235729032662970600751426473667466742400783812691116172114638709852683761981801759971251032455551940970494194597293645945798509819246878810125693283 - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 511895960426180963u64, - 14415282388317186033u64, - 16527438971944283980u64, - 14569914844893249436u64, - 6255542920911025796u64, - 17561304104424988062u64, - 12804642094441573214u64, - 1036109076355683357u64, - 18278939895251440379u64, - 13093933560766362101u64, - 9377062124445883481u64, - 243081261656u64, - ]); -} +#[derive(MontConfig)] +#[modulus = "5237311370989869175293026848905079641021338739994243633972937865128169101571388346632361720473792365177258871486054600656048925740061347509722287043067341250552640264308621296888446513816907173362124418513727200975392177480577"] +#[generator = "5"] +pub struct FrConfig; +pub type Fr = Fp768>; diff --git a/ed_on_mnt4_753/src/fields/mod.rs b/ed_on_mnt4_753/src/fields/mod.rs index e20037a..7afba55 100644 --- a/ed_on_mnt4_753/src/fields/mod.rs +++ b/ed_on_mnt4_753/src/fields/mod.rs @@ -4,5 +4,5 @@ pub mod fr; pub use fq::*; pub use fr::*; -#[cfg(all(feature = "ed_on_mnt4_753", test))] +#[cfg(test)] mod tests; diff --git a/ed_on_mnt4_753/src/fields/tests.rs b/ed_on_mnt4_753/src/fields/tests.rs index b976d39..e0a079d 100644 --- a/ed_on_mnt4_753/src/fields/tests.rs +++ b/ed_on_mnt4_753/src/fields/tests.rs @@ -1,23 +1,12 @@ -use ark_std::rand::Rng; -use ark_std::test_rng; +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; +use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; -use crate::{Fq, Fr}; -use ark_algebra_test_templates::fields::*; +use crate::{Fq, FqConfig, Fr, FrConfig}; -#[test] -fn test_fr() { - let mut rng = test_rng(); - let a: Fr = rng.gen(); - let b: Fr = rng.gen(); - field_test(a, b); - primefield_test::(); -} - -#[test] -fn test_fq() { - let mut rng = test_rng(); - let a: Fq = rng.gen(); - let b: Fq = rng.gen(); - field_test(a, b); - primefield_test::(); -} +generate_field_test!(ed_on_mnt4_753; mont(12, 12); ); +generate_field_serialization_test!(ed_on_mnt4_753;); diff --git a/ed_on_mnt4_753/src/lib.rs b/ed_on_mnt4_753/src/lib.rs index b42f563..5fd9a36 100644 --- a/ed_on_mnt4_753/src/lib.rs +++ b/ed_on_mnt4_753/src/lib.rs @@ -8,9 +8,10 @@ )] #![forbid(unsafe_code)] -//! This library implements a twisted Edwards curve whose base field is the scalar field of the -//! curve MNT4-753. This allows defining cryptographic primitives that use elliptic curves over -//! the scalar field of the latter curve. +//! This library implements a twisted Edwards curve whose base field is the +//! scalar field of the curve MNT4-753. This allows defining cryptographic +//! primitives that use elliptic curves over the scalar field of the latter +//! curve. //! //! Curve information: //! * Base field: q = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001 diff --git a/mnt4_298/scripts/base_field.sage b/mnt4_298/scripts/base_field.sage new file mode 100644 index 0000000..003f4c3 --- /dev/null +++ b/mnt4_298/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/mnt4_298/scripts/scalar_field.sage b/mnt4_298/scripts/scalar_field.sage new file mode 100644 index 0000000..05e4af4 --- /dev/null +++ b/mnt4_298/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/mnt4_298/src/constraints/curves.rs b/mnt4_298/src/constraints/curves.rs index 4640116..8804e39 100644 --- a/mnt4_298/src/constraints/curves.rs +++ b/mnt4_298/src/constraints/curves.rs @@ -1,6 +1,7 @@ -use crate::Parameters; use ark_r1cs_std::groups::mnt4; +use crate::Parameters; + /// An element of G1 in the MNT4-298 bilinear group. pub type G1Var = mnt4::G1Var; /// An element of G2 in the MNT4-298 bilinear group. diff --git a/mnt4_298/src/constraints/fields.rs b/mnt4_298/src/constraints/fields.rs index 32f2946..e2e7b70 100644 --- a/mnt4_298/src/constraints/fields.rs +++ b/mnt4_298/src/constraints/fields.rs @@ -1,13 +1,13 @@ -use crate::{Fq, Fq2Parameters, Fq4Parameters}; - use ark_r1cs_std::fields::{fp::FpVar, fp2::Fp2Var, fp4::Fp4Var}; +use crate::{Fq, Fq2Config, Fq4Config}; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FqVar = FpVar; /// A variable that is the R1CS equivalent of `crate::Fq2`. -pub type Fq2Var = Fp2Var; +pub type Fq2Var = Fp2Var; /// A variable that is the R1CS equivalent of `crate::Fq4`. -pub type Fq4Var = Fp4Var; +pub type Fq4Var = Fp4Var; #[test] fn mnt4_298_field_gadgets_test() { diff --git a/mnt4_298/src/constraints/pairing.rs b/mnt4_298/src/constraints/pairing.rs index 7941ad0..faa77a0 100644 --- a/mnt4_298/src/constraints/pairing.rs +++ b/mnt4_298/src/constraints/pairing.rs @@ -1,6 +1,7 @@ use crate::Parameters; -/// Specifies the constraints for computing a pairing in the MNT4-298 bilinear group. +/// Specifies the constraints for computing a pairing in the MNT4-298 bilinear +/// group. pub type PairingVar = ark_r1cs_std::pairing::mnt4::PairingVar; #[test] diff --git a/mnt4_298/src/curves/g1.rs b/mnt4_298/src/curves/g1.rs index a555122..9f03943 100644 --- a/mnt4_298/src/curves/g1.rs +++ b/mnt4_298/src/curves/g1.rs @@ -1,9 +1,10 @@ -use crate::{Fq, Fr, FR_ONE}; use ark_ec::{ mnt4, models::{ModelParameters, SWModelParameters}, }; -use ark_ff::field_new; +use ark_ff::MontFp; + +use crate::{Fq, Fr, FR_ONE}; pub type G1Affine = mnt4::G1Affine; pub type G1Projective = mnt4::G1Projective; @@ -21,20 +22,17 @@ impl ModelParameters for Parameters { /// COFACTOR^(-1) mod r = /// 1 - #[rustfmt::skip] const COFACTOR_INV: Fr = FR_ONE; } impl SWModelParameters for Parameters { /// COEFF_A = 2 /// Reference: - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "2"); + const COEFF_A: Fq = MontFp!(Fq, "2"); /// COEFF_B = 423894536526684178289416011533888240029318103673896002803341544124054745019340795360841685 /// Reference: - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "423894536526684178289416011533888240029318103673896002803341544124054745019340795360841685"); + const COEFF_B: Fq = MontFp!(Fq, "423894536526684178289416011533888240029318103673896002803341544124054745019340795360841685"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -46,10 +44,14 @@ impl SWModelParameters for Parameters { // Y = 363732850702582978263902770815145784459747722357071843971107674179038674942891694705904306, /// G1_GENERATOR_X /// Reference: -#[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = field_new!(Fq, "60760244141852568949126569781626075788424196370144486719385562369396875346601926534016838"); +pub const G1_GENERATOR_X: Fq = MontFp!( + Fq, + "60760244141852568949126569781626075788424196370144486719385562369396875346601926534016838" +); /// G1_GENERATOR_Y /// Reference: -#[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "363732850702582978263902770815145784459747722357071843971107674179038674942891694705904306"); +pub const G1_GENERATOR_Y: Fq = MontFp!( + Fq, + "363732850702582978263902770815145784459747722357071843971107674179038674942891694705904306" +); diff --git a/mnt4_298/src/curves/g2.rs b/mnt4_298/src/curves/g2.rs index 779da10..bda9a7d 100644 --- a/mnt4_298/src/curves/g2.rs +++ b/mnt4_298/src/curves/g2.rs @@ -1,10 +1,11 @@ -use crate::{Fq, Fq2, Fr, FQ_ZERO, G1_COEFF_A_NON_RESIDUE}; use ark_ec::{ mnt4, mnt4::MNT4Parameters, models::{ModelParameters, SWModelParameters}, }; -use ark_ff::field_new; +use ark_ff::{MontFp, QuadExt}; + +use crate::{Fq, Fq2, Fr, FQ_ZERO, G1_COEFF_A_NON_RESIDUE}; pub type G2Affine = mnt4::G2Affine; pub type G2Projective = mnt4::G2Projective; @@ -30,16 +31,13 @@ impl ModelParameters for Parameters { /// COFACTOR^(-1) mod r = /// 475922286169261325753349249653048451545124878207887910632124039320641839552134835598065665 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "475922286169261325753349249653048451545124878207887910632124039320641839552134835598065665"); + const COFACTOR_INV: Fr = MontFp!(Fr, "475922286169261325753349249653048451545124878207887910632124039320641839552134835598065665"); } /// 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 { @@ -53,10 +51,9 @@ impl SWModelParameters for Parameters { // = // (0, 67372828414711144619833451280373307321534573815811166723479321465776723059456513877937430) // ``` - #[rustfmt::skip] - const COEFF_B: Fq2 = field_new!(Fq2, + const COEFF_B: Fq2 = QuadExt!( FQ_ZERO, - field_new!(Fq, "67372828414711144619833451280373307321534573815811166723479321465776723059456513877937430"), + MontFp!(Fq, "67372828414711144619833451280373307321534573815811166723479321465776723059456513877937430"), ); /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) @@ -65,12 +62,12 @@ impl SWModelParameters for Parameters { #[inline(always)] fn mul_by_a(elt: &Fq2) -> Fq2 { - field_new!(Fq2, MUL_BY_A_C0 * &elt.c0, MUL_BY_A_C1 * &elt.c1,) + QuadExt!(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); +const G2_GENERATOR_X: Fq2 = QuadExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); +const G2_GENERATOR_Y: Fq2 = QuadExt!(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 @@ -78,14 +75,22 @@ const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1 // 37620953615500480110935514360923278605464476459712393277679280819942849043649216370485641, // Y = 37437409008528968268352521034936931842973546441370663118543015118291998305624025037512482, // 424621479598893882672393190337420680597584695892317197646113820787463109735345923009077489, -#[rustfmt::skip] -pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "438374926219350099854919100077809681842783509163790991847867546339851681564223481322252708"); +pub const G2_GENERATOR_X_C0: Fq = MontFp!( + Fq, + "438374926219350099854919100077809681842783509163790991847867546339851681564223481322252708" +); -#[rustfmt::skip] -pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "37620953615500480110935514360923278605464476459712393277679280819942849043649216370485641"); +pub const G2_GENERATOR_X_C1: Fq = MontFp!( + Fq, + "37620953615500480110935514360923278605464476459712393277679280819942849043649216370485641" +); -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "37437409008528968268352521034936931842973546441370663118543015118291998305624025037512482"); +pub const G2_GENERATOR_Y_C0: Fq = MontFp!( + Fq, + "37437409008528968268352521034936931842973546441370663118543015118291998305624025037512482" +); -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "424621479598893882672393190337420680597584695892317197646113820787463109735345923009077489"); +pub const G2_GENERATOR_Y_C1: Fq = MontFp!( + Fq, + "424621479598893882672393190337420680597584695892317197646113820787463109735345923009077489" +); diff --git a/mnt4_298/src/curves/mod.rs b/mnt4_298/src/curves/mod.rs index 408fe09..ac02e6f 100644 --- a/mnt4_298/src/curves/mod.rs +++ b/mnt4_298/src/curves/mod.rs @@ -1,7 +1,7 @@ use ark_ec::models::mnt4::{MNT4Parameters, MNT4}; -use ark_ff::{biginteger::BigInteger320, field_new, BigInt, Fp2}; +use ark_ff::{biginteger::BigInteger320, BigInt, Fp2, MontFp, QuadExt}; -use crate::{Fq, Fq2, Fq2Parameters, Fq4Parameters, Fr}; +use crate::{Fq, Fq2Config, Fq4Config, Fr}; pub mod g1; pub mod g2; @@ -19,18 +19,14 @@ pub type MNT4_298 = MNT4; pub struct Parameters; impl MNT4Parameters for Parameters { - const TWIST: Fp2 = field_new!(Fq2, FQ_ZERO, FQ_ONE); + const TWIST: Fp2 = QuadExt!(FQ_ZERO, FQ_ONE); // A coefficient of MNT4-298 G2 = // ``` // mnt4298_twist_coeff_a = mnt4298_Fq2(mnt4298_G1::coeff_a * non_residue, mnt6298_Fq::zero()); // = (A_COEFF * NONRESIDUE, ZERO) // = (34, ZERO) // ``` - #[rustfmt::skip] - const TWIST_COEFF_A: Fp2 = field_new!(Fq2, - G1_COEFF_A_NON_RESIDUE, - FQ_ZERO, - ); + const TWIST_COEFF_A: Fp2 = QuadExt!(G1_COEFF_A_NON_RESIDUE, FQ_ZERO); const ATE_LOOP_COUNT: &'static [u64] = &[993502997770534912, 5071219579242586943, 2027349]; const ATE_IS_LOOP_COUNT_NEG: bool = false; @@ -40,15 +36,15 @@ impl MNT4Parameters for Parameters { BigInt::new([993502997770534913, 5071219579242586943, 2027349, 0, 0]); type Fp = Fq; type Fr = Fr; - type Fp2Params = Fq2Parameters; - type Fp4Params = Fq4Parameters; + type Fp2Config = Fq2Config; + type Fp4Config = Fq4Config; type G1Parameters = self::g1::Parameters; type G2Parameters = self::g2::Parameters; } // 34 -pub const G1_COEFF_A_NON_RESIDUE: Fq = field_new!(Fq, "34"); -pub const FQ_ZERO: Fq = field_new!(Fq, "0"); -pub const FQ_ONE: Fq = field_new!(Fq, "1"); -pub const FR_ZERO: Fr = field_new!(Fr, "0"); -pub const FR_ONE: Fr = field_new!(Fr, "1"); +pub const G1_COEFF_A_NON_RESIDUE: Fq = MontFp!(Fq, "34"); +pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); +pub const FQ_ONE: Fq = MontFp!(Fq, "1"); +pub const FR_ZERO: Fr = MontFp!(Fr, "0"); +pub const FR_ONE: Fr = MontFp!(Fr, "1"); diff --git a/mnt4_298/src/curves/tests.rs b/mnt4_298/src/curves/tests.rs index ed730a4..45311f7 100644 --- a/mnt4_298/src/curves/tests.rs +++ b/mnt4_298/src/curves/tests.rs @@ -1,16 +1,14 @@ -use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{Field, One, PrimeField, UniformRand}; -use ark_std::{rand::Rng, test_rng}; - -use crate::*; - use ark_algebra_test_templates::{ curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, generate_product_of_pairings_test, groups::*, msm::*, }; - +use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; +use ark_ff::{Field, One, PrimeField, UniformRand}; +use ark_std::{rand::Rng, test_rng}; use core::ops::MulAssign; +use crate::*; + generate_g1_test!(mnt4_298; curve_tests; sw_tests;); generate_g2_test!(mnt4_298; curve_tests; sw_tests;); generate_bilinearity_test!(MNT4_298, Fq4); diff --git a/mnt4_298/src/fields/fq.rs b/mnt4_298/src/fields/fq.rs index 317aa09..3663cc0 100644 --- a/mnt4_298/src/fields/fq.rs +++ b/mnt4_298/src/fields/fq.rs @@ -1,115 +1,9 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger320 as BigInteger}, - fields::{FftParameters, Fp320, Fp320Parameters, FpParameters}, -}; - -pub type Fq = Fp320; - -pub struct FqParameters; - -impl Fp320Parameters for FqParameters {} -impl FftParameters for FqParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 17; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 9821480371597472441u64, - 9468346035609379175u64, - 9963748368231707135u64, - 14865337659602750405u64, - 3984815592673u64, - ]); - - const SMALL_SUBGROUP_BASE: Option = Some(7); - const SMALL_SUBGROUP_BASE_ADICITY: Option = Some(2); - - /// LARGE_SUBGROUP_ROOT_OF_UNITY = x * g - /// where x = (n - 1) / 2^17 / 7^2 - /// and represent this value in the Montgomery residue form. - /// I.e., write - /// 381811485921190977554243339163030148371175054922689353173385941180422489253833691237722982 - /// * R - /// = 260534023778902228073198316993669317435810479439368306496187170459125001342456918103569322 - const LARGE_SUBGROUP_ROOT_OF_UNITY: Option = Some(BigInt::new([ - 7711798843682337706u64, - 16456007754393011187u64, - 7470854640069402569u64, - 10767969225751706229u64, - 2250015743691u64, - ])); -} -impl FpParameters for FqParameters { - /// MODULUS = 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 14487189785281953793u64, - 4731562877756902930u64, - 14622846468719063274u64, - 11702080941310629006u64, - 4110145082483u64, - ]); - - const MODULUS_BITS: u32 = 298; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 22; - - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 1784298994435064924u64, - 16852041090100268533u64, - 14258261760832875328u64, - 2961187778261111191u64, - 1929014752195u64, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 28619103704175136u64, - 11702218449377544339u64, - 7403203599591297249u64, - 2248105543421449339u64, - 2357678148148u64, - ]); - - const INV: u64 = 12714121028002250751u64; - - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 2709730703260633621u64, - 13556085429182073539u64, - 10903316137158576359u64, - 5319113788683590444u64, - 4022235209932u64, - ]); - - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0x70964866b2d38b3, - 0x987520d4f1af2890, - 0x2a47657764b1ae89, - 0x6a39d133124ed3d8, - 0x1de7bde, - ]); - - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x384b24335969c59, - 0xcc3a906a78d79448, - 0x1523b2bbb258d744, - 0x351ce899892769ec, - 0xef3def, - ]); - - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x64866b2d38b30000, - 0x20d4f1af28900709, - 0x657764b1ae899875, - 0xd133124ed3d82a47, - 0x1de7bde6a39, - ]); -} +use ark_ff::fields::{Fp320, MontBackend, MontConfig}; + +#[derive(MontConfig)] +#[modulus = "475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081"] +#[generator = "17"] +#[small_subgroup_base = "7"] +#[small_subgroup_power = "2"] +pub struct FqConfig; +pub type Fq = Fp320>; diff --git a/mnt4_298/src/fields/fq2.rs b/mnt4_298/src/fields/fq2.rs index 46b9d42..d4162c5 100644 --- a/mnt4_298/src/fields/fq2.rs +++ b/mnt4_298/src/fields/fq2.rs @@ -1,30 +1,30 @@ -use crate::{Fq, FQ_ONE}; use ark_ff::{ - field_new, - fields::fp2::{Fp2, Fp2Parameters}, + fields::fp2::{Fp2, Fp2Config}, + MontFp, QuadExt, }; -pub type Fq2 = Fp2; +use crate::{Fq, FQ_ONE}; + +pub type Fq2 = Fp2; -pub struct Fq2Parameters; +pub struct Fq2Config; -impl Fp2Parameters for Fq2Parameters { +impl Fp2Config for Fq2Config { type Fp = Fq; /// The quadratic non-residue (17) used to construct the extension is /// the same as that used in [`libff`](https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L102). - #[rustfmt::skip] - const NONRESIDUE: Fq = field_new!(Fq, "17"); + const NONRESIDUE: Fq = MontFp!(Fq, "17"); /// The quadratic non-residue in Fp2 that is used /// in the computation of square roots is (8, 1), the same as that in /// [`libff`](https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L103) - const QUADRATIC_NONRESIDUE: (Self::Fp, Self::Fp) = (field_new!(Fq, "8"), FQ_ONE); + const QUADRATIC_NONRESIDUE: Fq2 = QuadExt!(MontFp!(Fq, "8"), FQ_ONE); /// Precomputed coefficients: /// `[1, 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758080]` const FROBENIUS_COEFF_FP2_C1: &'static [Self::Fp] = &[ FQ_ONE, - field_new!(Fq, "475922286169261325753349249653048451545124879242694725395555128576210262817955800483758080"), + MontFp!(Fq, "475922286169261325753349249653048451545124879242694725395555128576210262817955800483758080"), ]; } diff --git a/mnt4_298/src/fields/fq4.rs b/mnt4_298/src/fields/fq4.rs index 7485336..6417d7c 100644 --- a/mnt4_298/src/fields/fq4.rs +++ b/mnt4_298/src/fields/fq4.rs @@ -1,17 +1,18 @@ -use crate::{Fq, Fq2, Fq2Parameters, FQ_ONE, FQ_ZERO}; use ark_ff::{ - field_new, - fields::fp4::{Fp4, Fp4Parameters}, + fields::fp4::{Fp4, Fp4Config}, + MontFp, QuadExt, }; -pub type Fq4 = Fp4; +use crate::{Fq, Fq2, Fq2Config, FQ_ONE, FQ_ZERO}; -pub struct Fq4Parameters; +pub type Fq4 = Fp4; -impl Fp4Parameters for Fq4Parameters { - type Fp2Params = Fq2Parameters; +pub struct Fq4Config; - const NONRESIDUE: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ONE); +impl Fp4Config for Fq4Config { + type Fp2Config = Fq2Config; + + const NONRESIDUE: Fq2 = QuadExt!(FQ_ZERO, FQ_ONE); // Coefficients for the Frobenius automorphism. // c1[0] = 1, @@ -19,12 +20,12 @@ impl Fp4Parameters for Fq4Parameters { // c1[2] = 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758080 // c1[3] = 468238122923807824137727898100575114475823797181717920390930116882062371863914936316755773 // - // These are calculated as `FROBENIUS_COEFF_FP4_C1[i] = Fp2Params::NONRESIDUE^((q^i - 1) / 4)`. - #[rustfmt::skip] + // These are calculated as + // `FROBENIUS_COEFF_FP4_C1[i] = Fp2Config::NONRESIDUE^((q^i - 1) / 4)`. const FROBENIUS_COEFF_FP4_C1: &'static [Fq] = &[ FQ_ONE, - field_new!(Fq, "7684163245453501615621351552473337069301082060976805004625011694147890954040864167002308"), - field_new!(Fq, "475922286169261325753349249653048451545124879242694725395555128576210262817955800483758080"), - field_new!(Fq, "468238122923807824137727898100575114475823797181717920390930116882062371863914936316755773"), + MontFp!(Fq, "7684163245453501615621351552473337069301082060976805004625011694147890954040864167002308"), + MontFp!(Fq, "475922286169261325753349249653048451545124879242694725395555128576210262817955800483758080"), + MontFp!(Fq, "468238122923807824137727898100575114475823797181717920390930116882062371863914936316755773"), ]; } diff --git a/mnt4_298/src/fields/fr.rs b/mnt4_298/src/fields/fr.rs index fdc99a4..7f0c305 100644 --- a/mnt4_298/src/fields/fr.rs +++ b/mnt4_298/src/fields/fr.rs @@ -1,99 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger320 as BigInteger}, - fields::{FftParameters, Fp320, Fp320Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp320, MontBackend, MontConfig}; -pub type Fr = Fp320; - -pub struct FrParameters; - -impl Fp320Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 34; - - #[rustfmt::skip] - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 0x818b361df1af7be4, - 0x2ae2750d46a53957, - 0x5784a8fe792c5f8a, - 0xf9bd39c0cdcf1bb6, - 0x6a24a0f8a8, - ]); -} -impl FpParameters for FrParameters { - /// MODULUS = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 - #[rustfmt::skip] - const MODULUS: BigInteger = BigInt::new([ - 0xbb4334a400000001, - 0xfb494c07925d6ad3, - 0xcaeec9635cf44194, - 0xa266249da7b0548e, - 0x3bcf7bcd473, - ]); - - const MODULUS_BITS: u32 = 298; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 22; - - #[rustfmt::skip] - const R: BigInteger = BigInt::new([ - 0xc3177aefffbb845c, - 0x9b80c702f9961788, - 0xc5df8dcdac70a85a, - 0x29184098647b5197, - 0x1c1223d33c3, - ]); - - #[rustfmt::skip] - const R2: BigInteger = BigInt::new([ - 0x465a743c68e0596b, - 0x34f9102adb68371, - 0x4bbd6dcf1e3a8386, - 0x2ff00dced8e4b6d, - 0x149bb44a342, - ]); - - const INV: u64 = 0xbb4334a3ffffffff; - - #[rustfmt::skip] - const GENERATOR: BigInteger = BigInt::new([ - 0xb1ddfacffd532b94, - 0x25e295ff76674008, - 0x8f00647b48958d36, - 0x1159f37d4e0fddb2, - 0x2977770b3d1, - ]); - - #[rustfmt::skip] - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xdda19a5200000000, - 0x7da4a603c92eb569, - 0x657764b1ae7a20ca, - 0xd133124ed3d82a47, - 0x1de7bde6a39, - ]); - - // T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T - - #[rustfmt::skip] - const T: BigInteger = BigInt::new([ - 0xe4975ab4eed0cd29, - 0xd73d10653ed25301, - 0x69ec1523b2bbb258, - 0x3def351ce8998927, - 0xef, - ]); - - #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xf24bad5a77686694, - 0x6b9e88329f692980, - 0xb4f60a91d95dd92c, - 0x9ef79a8e744cc493, - 0x77, - ]); -} +#[derive(MontConfig)] +#[modulus = "475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137"] +#[generator = "10"] +pub struct FrConfig; +pub type Fr = Fp320>; diff --git a/mnt4_298/src/fields/tests.rs b/mnt4_298/src/fields/tests.rs index de271b3..45a18c3 100644 --- a/mnt4_298/src/fields/tests.rs +++ b/mnt4_298/src/fields/tests.rs @@ -1,9 +1,12 @@ -use ark_ff::{Field, One, SquareRootField, UniformRand, Zero}; -use ark_std::test_rng; +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; +use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; use crate::*; -use ark_algebra_test_templates::{fields::*, generate_field_test}; - -use core::ops::{AddAssign, MulAssign, SubAssign}; -generate_field_test!(mnt4_298; fq2; fq4;); +generate_field_test!(mnt4_298; fq2; fq4; mont(5, 5); ); +generate_field_serialization_test!(mnt4_298;); diff --git a/mnt4_298/src/lib.rs b/mnt4_298/src/lib.rs index 4797d30..e4eefa7 100644 --- a/mnt4_298/src/lib.rs +++ b/mnt4_298/src/lib.rs @@ -10,14 +10,17 @@ //! This library implements the MNT4_298 curve generated by //! [\[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 298-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_298. +//! Miyaji--Nakabayashi--Takano curve of embedding degree 4, defined over a +//! 298-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_298. //! //! //! Curve information: -//! * Base field: q = 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081 -//! * Scalar field: r = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 +//! * Base field: q = +//! 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081 +//! * Scalar field: r = +//! 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 //! * valuation(q - 1, 2) = 17 //! * valuation(r - 1, 2) = 34 //! * G1 curve equation: y^2 = x^3 + ax + b, where @@ -26,7 +29,8 @@ //! * G2 curve equation: y^2 = x^3 + Ax + B, where //! * A = Fq2 = (a * NON_RESIDUE, 0) //! * B = Fq2(0, b * NON_RESIDUE) -//! * NON_RESIDUE = 17 is the quadratic non-residue used for constructing the extension field Fq2 +//! * NON_RESIDUE = 17 is the quadratic non-residue used for constructing the +//! extension field Fq2 #[cfg(feature = "curve")] mod curves; diff --git a/mnt4_753/scripts/base_field.sage b/mnt4_753/scripts/base_field.sage new file mode 100644 index 0000000..6828995 --- /dev/null +++ b/mnt4_753/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689601 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/mnt4_753/scripts/scalar_field.sage b/mnt4_753/scripts/scalar_field.sage new file mode 100644 index 0000000..b91ade8 --- /dev/null +++ b/mnt4_753/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/mnt4_753/src/constraints/curves.rs b/mnt4_753/src/constraints/curves.rs index febfeed..fd96848 100644 --- a/mnt4_753/src/constraints/curves.rs +++ b/mnt4_753/src/constraints/curves.rs @@ -1,6 +1,7 @@ -use crate::Parameters; use ark_r1cs_std::groups::mnt4; +use crate::Parameters; + /// An element of G1 in the MNT4-753 bilinear group. pub type G1Var = mnt4::G1Var; /// An element of G2 in the MNT4-753 bilinear group. diff --git a/mnt4_753/src/constraints/fields.rs b/mnt4_753/src/constraints/fields.rs index d99ed86..549df25 100644 --- a/mnt4_753/src/constraints/fields.rs +++ b/mnt4_753/src/constraints/fields.rs @@ -1,13 +1,13 @@ -use crate::{Fq, Fq2Parameters, Fq4Parameters}; - use ark_r1cs_std::fields::{fp::FpVar, fp2::Fp2Var, fp4::Fp4Var}; +use crate::{Fq, Fq2Config, Fq4Config}; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FqVar = FpVar; /// A variable that is the R1CS equivalent of `crate::Fq2`. -pub type Fq2Var = Fp2Var; +pub type Fq2Var = Fp2Var; /// A variable that is the R1CS equivalent of `crate::Fq4`. -pub type Fq4Var = Fp4Var; +pub type Fq4Var = Fp4Var; #[test] fn mnt4_753_field_gadgets_test() { diff --git a/mnt4_753/src/constraints/pairing.rs b/mnt4_753/src/constraints/pairing.rs index 3e00df4..1fbd8d0 100644 --- a/mnt4_753/src/constraints/pairing.rs +++ b/mnt4_753/src/constraints/pairing.rs @@ -1,6 +1,7 @@ use crate::Parameters; -/// Specifies the constraints for computing a pairing in the MNT4-753 bilinear group. +/// Specifies the constraints for computing a pairing in the MNT4-753 bilinear +/// group. pub type PairingVar = ark_r1cs_std::pairing::mnt4::PairingVar; #[test] diff --git a/mnt4_753/src/curves/g1.rs b/mnt4_753/src/curves/g1.rs index 567f64c..78d30da 100644 --- a/mnt4_753/src/curves/g1.rs +++ b/mnt4_753/src/curves/g1.rs @@ -2,7 +2,7 @@ use ark_ec::{ mnt4, models::{ModelParameters, SWModelParameters}, }; -use ark_ff::field_new; +use ark_ff::MontFp; use crate::{Fq, Fr, FR_ONE}; @@ -21,18 +21,15 @@ impl ModelParameters for Parameters { const COFACTOR: &'static [u64] = &[1]; /// COFACTOR^(-1) mod r = 1 - #[rustfmt::skip] const COFACTOR_INV: Fr = FR_ONE; } impl SWModelParameters for Parameters { /// COEFF_A = 2 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "2"); + const COEFF_A: Fq = MontFp!(Fq, "2"); /// COEFF_B = 0x01373684A8C9DCAE7A016AC5D7748D3313CD8E39051C596560835DF0C9E50A5B59B882A92C78DC537E51A16703EC9855C77FC3D8BB21C8D68BB8CFB9DB4B8C8FBA773111C36C8B1B4E8F1ECE940EF9EAAD265458E06372009C9A0491678EF4 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "28798803903456388891410036793299405764940372360099938340752576406393880372126970068421383312482853541572780087363938442377933706865252053507077543420534380486492786626556269083255657125025963825610840222568694137138741554679540"); + const COEFF_B: Fq = MontFp!(Fq, "28798803903456388891410036793299405764940372360099938340752576406393880372126970068421383312482853541572780087363938442377933706865252053507077543420534380486492786626556269083255657125025963825610840222568694137138741554679540"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -42,10 +39,10 @@ impl SWModelParameters for Parameters { // Generator of G1 // X = 7790163481385331313124631546957228376128961350185262705123068027727518350362064426002432450801002268747950550964579198552865939244360469674540925037890082678099826733417900510086646711680891516503232107232083181010099241949569, // Y = 6913648190367314284606685101150155872986263667483624713540251048208073654617802840433842931301128643140890502238233930290161632176167186761333725658542781350626799660920481723757654531036893265359076440986158843531053720994648, -/// G1_GENERATOR_X = 7790163481385331313124631546957228376128961350185262705123068027727518350362064426002432450801002268747950550964579198552865939244360469674540925037890082678099826733417900510086646711680891516503232107232083181010099241949569 -#[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = field_new!(Fq, "7790163481385331313124631546957228376128961350185262705123068027727518350362064426002432450801002268747950550964579198552865939244360469674540925037890082678099826733417900510086646711680891516503232107232083181010099241949569"); +/// G1_GENERATOR_X = +/// 7790163481385331313124631546957228376128961350185262705123068027727518350362064426002432450801002268747950550964579198552865939244360469674540925037890082678099826733417900510086646711680891516503232107232083181010099241949569 +pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "7790163481385331313124631546957228376128961350185262705123068027727518350362064426002432450801002268747950550964579198552865939244360469674540925037890082678099826733417900510086646711680891516503232107232083181010099241949569"); -/// G1_GENERATOR_Y = 6913648190367314284606685101150155872986263667483624713540251048208073654617802840433842931301128643140890502238233930290161632176167186761333725658542781350626799660920481723757654531036893265359076440986158843531053720994648 -#[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "6913648190367314284606685101150155872986263667483624713540251048208073654617802840433842931301128643140890502238233930290161632176167186761333725658542781350626799660920481723757654531036893265359076440986158843531053720994648"); +/// G1_GENERATOR_Y = +/// 6913648190367314284606685101150155872986263667483624713540251048208073654617802840433842931301128643140890502238233930290161632176167186761333725658542781350626799660920481723757654531036893265359076440986158843531053720994648 +pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "6913648190367314284606685101150155872986263667483624713540251048208073654617802840433842931301128643140890502238233930290161632176167186761333725658542781350626799660920481723757654531036893265359076440986158843531053720994648"); diff --git a/mnt4_753/src/curves/g2.rs b/mnt4_753/src/curves/g2.rs index 829b21a..4216b9a 100644 --- a/mnt4_753/src/curves/g2.rs +++ b/mnt4_753/src/curves/g2.rs @@ -3,7 +3,7 @@ use ark_ec::{ mnt4::MNT4Parameters, models::{ModelParameters, SWModelParameters}, }; -use ark_ff::field_new; +use ark_ff::{MontFp, QuadExt}; use crate::{Fq, Fq2, Fr, FQ_ZERO, G1_COEFF_A_NON_RESIDUE}; @@ -38,16 +38,13 @@ impl ModelParameters for Parameters { /// COFACTOR^(-1) mod r = /// 102345604409665481004734934052318066391634848395005988700111949231215905051467807945653833683883449458834877235200 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "102345604409665481004734934052318066391634848395005988700111949231215905051467807945653833683883449458834877235200"); + const COFACTOR_INV: Fr = MontFp!(Fr, "102345604409665481004734934052318066391634848395005988700111949231215905051467807945653833683883449458834877235200"); } /// 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 { @@ -61,10 +58,9 @@ impl SWModelParameters for Parameters { // = // (0, 39196523001581428369576759982967177918859161321667605855515469914917622337081756705006832951954384669101573360625169461998308377011601613979275218690841934572954991361632773738259652003389826903175898479855893660378722437317212) // ``` - #[rustfmt::skip] - const COEFF_B: Fq2 = field_new!(Fq2, + const COEFF_B: Fq2 = QuadExt!( FQ_ZERO, - field_new!(Fq, "39196523001581428369576759982967177918859161321667605855515469914917622337081756705006832951954384669101573360625169461998308377011601613979275218690841934572954991361632773738259652003389826903175898479855893660378722437317212") + MontFp!(Fq, "39196523001581428369576759982967177918859161321667605855515469914917622337081756705006832951954384669101573360625169461998308377011601613979275218690841934572954991361632773738259652003389826903175898479855893660378722437317212") ); /// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y) @@ -73,12 +69,12 @@ impl SWModelParameters for Parameters { #[inline(always)] fn mul_by_a(elt: &Fq2) -> Fq2 { - field_new!(Fq2, MUL_BY_A_C0 * &elt.c0, MUL_BY_A_C1 * &elt.c1,) + QuadExt!(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); +const G2_GENERATOR_X: Fq2 = QuadExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1); +const G2_GENERATOR_Y: Fq2 = QuadExt!(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 @@ -86,14 +82,10 @@ const G2_GENERATOR_Y: Fq2 = field_new!(Fq2, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1 // 19706011319630172391076079624799753948158506771222147486237995321925443331396169656568431378974558350664383559981183980668976846806019030432389169137953988990802000581078994008283967768348275973921598166274857631001635633631000, // Y = 39940152670760519653940320314827327941993141403708338666925204282084477074754642625849927569427860786384998614863651207257467076192649385174108085803168743803491780568503369317093191101779534035377266300185099318717465441820654, // 17608637424964395737041291373756657139607306440193731804102457011726690702169238966996114255971643893157857311132388792357391583164125870757541009035041469463366528798593952884745987697403056488744603829437448927398468360797245, -#[rustfmt::skip] -pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "29483965110843144675703364744708836524643960105538608078862508397502447349913068434941060515343254862580437318493682762113105361632548148204806052114008731372757389645383891982211245013965175213456066452587869519098351487925167"); +pub const G2_GENERATOR_X_C0: Fq = MontFp!(Fq, "29483965110843144675703364744708836524643960105538608078862508397502447349913068434941060515343254862580437318493682762113105361632548148204806052114008731372757389645383891982211245013965175213456066452587869519098351487925167"); -#[rustfmt::skip] -pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "19706011319630172391076079624799753948158506771222147486237995321925443331396169656568431378974558350664383559981183980668976846806019030432389169137953988990802000581078994008283967768348275973921598166274857631001635633631000"); +pub const G2_GENERATOR_X_C1: Fq = MontFp!(Fq, "19706011319630172391076079624799753948158506771222147486237995321925443331396169656568431378974558350664383559981183980668976846806019030432389169137953988990802000581078994008283967768348275973921598166274857631001635633631000"); -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "39940152670760519653940320314827327941993141403708338666925204282084477074754642625849927569427860786384998614863651207257467076192649385174108085803168743803491780568503369317093191101779534035377266300185099318717465441820654"); +pub const G2_GENERATOR_Y_C0: Fq = MontFp!(Fq, "39940152670760519653940320314827327941993141403708338666925204282084477074754642625849927569427860786384998614863651207257467076192649385174108085803168743803491780568503369317093191101779534035377266300185099318717465441820654"); -#[rustfmt::skip] -pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "17608637424964395737041291373756657139607306440193731804102457011726690702169238966996114255971643893157857311132388792357391583164125870757541009035041469463366528798593952884745987697403056488744603829437448927398468360797245"); +pub const G2_GENERATOR_Y_C1: Fq = MontFp!(Fq, "17608637424964395737041291373756657139607306440193731804102457011726690702169238966996114255971643893157857311132388792357391583164125870757541009035041469463366528798593952884745987697403056488744603829437448927398468360797245"); diff --git a/mnt4_753/src/curves/mod.rs b/mnt4_753/src/curves/mod.rs index 727c7bf..b8239e8 100644 --- a/mnt4_753/src/curves/mod.rs +++ b/mnt4_753/src/curves/mod.rs @@ -1,10 +1,10 @@ use ark_ec::models::mnt4::{MNT4Parameters, MNT4}; use ark_ff::{ biginteger::{BigInt, BigInteger768}, - field_new, Fp2, + Fp2, MontFp, QuadExt, }; -use crate::{Fq, Fq2, Fq2Parameters, Fq4Parameters, Fr}; +use crate::{Fq, Fq2Config, Fq4Config, Fr}; pub mod g1; pub mod g2; @@ -22,18 +22,14 @@ pub type MNT4_753 = MNT4; pub struct Parameters; impl MNT4Parameters for Parameters { - const TWIST: Fp2 = field_new!(Fq2, FQ_ZERO, FQ_ONE); + const TWIST: Fp2 = QuadExt!(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 = field_new!(Fq2, - G1_COEFF_A_NON_RESIDUE, - FQ_ZERO, - ); + const TWIST_COEFF_A: Fp2 = QuadExt!(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, @@ -63,16 +59,16 @@ impl MNT4Parameters for Parameters { ]); type Fp = Fq; type Fr = Fr; - type Fp2Params = Fq2Parameters; - type Fp4Params = Fq4Parameters; + type Fp2Config = Fq2Config; + type Fp4Config = Fq4Config; type G1Parameters = self::g1::Parameters; type G2Parameters = self::g2::Parameters; } // 26 -pub const G1_COEFF_A_NON_RESIDUE: Fq = field_new!(Fq, "26"); +pub const G1_COEFF_A_NON_RESIDUE: Fq = MontFp!(Fq, "26"); -pub const FQ_ZERO: Fq = field_new!(Fq, "0"); -pub const FQ_ONE: Fq = field_new!(Fq, "1"); -pub const FR_ZERO: Fr = field_new!(Fr, "0"); -pub const FR_ONE: Fr = field_new!(Fr, "1"); +pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); +pub const FQ_ONE: Fq = MontFp!(Fq, "1"); +pub const FR_ZERO: Fr = MontFp!(Fr, "0"); +pub const FR_ONE: Fr = MontFp!(Fr, "1"); diff --git a/mnt4_753/src/curves/tests.rs b/mnt4_753/src/curves/tests.rs index fab5e73..8003b8c 100644 --- a/mnt4_753/src/curves/tests.rs +++ b/mnt4_753/src/curves/tests.rs @@ -1,15 +1,14 @@ -use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{Field, One, PrimeField, UniformRand}; -use ark_std::{rand::Rng, test_rng}; - -use crate::*; use ark_algebra_test_templates::{ curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, generate_product_of_pairings_test, groups::*, msm::*, }; - +use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; +use ark_ff::{Field, One, PrimeField, UniformRand}; +use ark_std::{rand::Rng, test_rng}; use core::ops::MulAssign; +use crate::*; + generate_g1_test!(mnt4_753; curve_tests; sw_tests;); generate_g2_test!(mnt4_753; curve_tests; sw_tests;); generate_bilinearity_test!(MNT4_753, Fq4); diff --git a/mnt4_753/src/fields/fq.rs b/mnt4_753/src/fields/fq.rs index 7159dce..cabc9ce 100644 --- a/mnt4_753/src/fields/fq.rs +++ b/mnt4_753/src/fields/fq.rs @@ -1,170 +1,9 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger768 as BigInteger}, - fields::{FftParameters, Fp768, Fp768Parameters, FpParameters}, -}; - -pub type Fq = Fp768; - -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 = BigInt::new([ - 0x3b079c7556ac378, - 0x2c8c74d04a3f00d4, - 0xd3b001061b90d4cf, - 0x946e77514891b0e6, - 0x79caec8ad6dc9ea1, - 0xbefd780edc81435d, - 0xe093d4dca630b154, - 0x43a0f673199f1c12, - 0x92276c78436253ff, - 0xe249d1cf014fcd24, - 0x96f36471fb7c3ec5, - 0x1080b8906b7c4, - ]); - - const SMALL_SUBGROUP_BASE: Option = Some(5); - const SMALL_SUBGROUP_BASE_ADICITY: Option = Some(2); - /// LARGE_SUBGROUP_ROOT_OF_UNITY = - /// 12249458902762217747626832919710926618510011455364963726393752854649914979954138109976331601455448780251166045203053508523342111624583986869301658366625356826888785691823710598470775453742133593634524619429629803955083254436531 - const LARGE_SUBGROUP_ROOT_OF_UNITY: Option = Some(BigInt::new([ - 8926681816978929800, - 10873079436792120119, - 6519893728366769435, - 7899277225737766970, - 8416573500933450083, - 12951641800297678468, - 7093775028595490583, - 14327009285082556021, - 18228411097456927576, - 2823658094446565457, - 1708328092507553067, - 109589007594791, - ])); -} -impl FpParameters for FqParameters { - /// MODULUS = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689601 - const MODULUS: BigInteger = BigInt::new([ - 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 = BigInt::new([ - 0x98a8ecabd9dc6f42, - 0x91cd31c65a034686, - 0x97c3e4a0cd14572e, - 0x79589819c788b601, - 0xed269c942108976f, - 0x1e0f4d8acf031d68, - 0x320c3bb713338559, - 0x598b4302d2f00a62, - 0x4074c9cbfd8ca621, - 0xfa47edb3865e88c, - 0x95455fb31ff9a195, - 0x7b479ec8e242, - ]); - - const R2: BigInteger = BigInt::new([ - 0x84717088cfd190c8, - 0xc7d9ff8e7df03c0a, - 0xa24bea56242b3507, - 0xa896a656a0714c7d, - 0x80a46659ff6f3ddf, - 0x2f47839ef88d7ce8, - 0xa8c86d4604a3b597, - 0xe03c79cac4f7ef07, - 0x2505daf1f4a81245, - 0x8e4605754c381723, - 0xb081f15bcbfdacaf, - 0x2a33e89cb485, - ]); - - const INV: u64 = 0xf2044cfbe45e7fff; - - const GENERATOR: BigInteger = BigInt::new([ - 0xa8f627f0e629635e, - 0x202afce346c36872, - 0x85e1ece733493254, - 0x6d76e610664ac389, - 0xdf542f3f04441585, - 0x3aa4885bf6d4dd80, - 0xeb8b63c1c0fffc74, - 0xd2488e985f6cfa4e, - 0xcce1c2a623f7a66a, - 0x2a060f4d5085b19a, - 0xa9111a596408842f, - 0x11ca8d50bf627, - ]); - - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 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 = BigInt::new([ - 0x233ebd20c7bc48bd, - 0x4be1c73aa8a459ba, - 0xa948c71020e33588, - 0xfc70d0b599d2ece4, - 0xb3b701e1b4b96a6, - 0xef3b622fceede430, - 0xdb1b33a249b342b5, - 0xb0e60ffb724bd141, - 0x5fdabd6fd1f2d92f, - 0x9b5b6ff32ea0b71f, - 0x882220452045ddc5, - 0x3898c5b25, - ]); - - /// (T - 1) / 2 = - /// 639320235716536764562137066516733354616862639159453568600212141739278454781663616532270717831273482077302108335697231843785915016625738299584832850982866309645559758727261971176269322627921491298227356745790729756212077662 - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x119f5e9063de245e, - 0x25f0e39d54522cdd, - 0x54a4638810719ac4, - 0x7e38685acce97672, - 0x59db80f0da5cb53, - 0xf79db117e776f218, - 0xed8d99d124d9a15a, - 0xd87307fdb925e8a0, - 0xafed5eb7e8f96c97, - 0xcdadb7f997505b8f, - 0xc41110229022eee2, - 0x1c4c62d92, - ]); -} +use ark_ff::fields::{Fp768, MontBackend, MontConfig}; + +#[derive(MontConfig)] +#[modulus = "41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689601"] +#[generator = "17"] +#[small_subgroup_base = "5"] +#[small_subgroup_power = "2"] +pub struct FqConfig; +pub type Fq = Fp768>; diff --git a/mnt4_753/src/fields/fq2.rs b/mnt4_753/src/fields/fq2.rs index 00a5664..825c927 100644 --- a/mnt4_753/src/fields/fq2.rs +++ b/mnt4_753/src/fields/fq2.rs @@ -1,28 +1,28 @@ -use crate::{Fq, FQ_ONE}; use ark_ff::{ - field_new, - fields::fp2::{Fp2, Fp2Parameters}, + fields::fp2::{Fp2, Fp2Config}, + MontFp, QuadExt, }; -pub type Fq2 = Fp2; +use crate::{Fq, FQ_ONE}; + +pub type Fq2 = Fp2; -pub struct Fq2Parameters; +pub struct Fq2Config; -impl Fp2Parameters for Fq2Parameters { +impl Fp2Config for Fq2Config { type Fp = Fq; // non_residue = 13 - #[rustfmt::skip] - const NONRESIDUE: Fq = field_new!(Fq, "13"); + const NONRESIDUE: Fq = MontFp!(Fq, "13"); // qnr = (8, 1) - const QUADRATIC_NONRESIDUE: (Self::Fp, Self::Fp) = (field_new!(Fq, "8"), FQ_ONE); + const QUADRATIC_NONRESIDUE: Fq2 = QuadExt!(MontFp!(Fq, "8"), 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, "41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689600"), + MontFp!(Fq, "41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689600"), ]; } diff --git a/mnt4_753/src/fields/fq4.rs b/mnt4_753/src/fields/fq4.rs index 0d14138..c6585ac 100644 --- a/mnt4_753/src/fields/fq4.rs +++ b/mnt4_753/src/fields/fq4.rs @@ -1,17 +1,18 @@ -use crate::{Fq, Fq2, Fq2Parameters, FQ_ONE, FQ_ZERO}; use ark_ff::{ - field_new, - fields::fp4::{Fp4, Fp4Parameters}, + fields::fp4::{Fp4, Fp4Config}, + MontFp, QuadExt, }; -pub type Fq4 = Fp4; +use crate::{Fq, Fq2, Fq2Config, FQ_ONE, FQ_ZERO}; -pub struct Fq4Parameters; +pub type Fq4 = Fp4; -impl Fp4Parameters for Fq4Parameters { - type Fp2Params = Fq2Parameters; +pub struct Fq4Config; - const NONRESIDUE: Fq2 = field_new!(Fq2, FQ_ZERO, FQ_ONE); +impl Fp4Config for Fq4Config { + type Fp2Config = Fq2Config; + + const NONRESIDUE: Fq2 = QuadExt!(FQ_ZERO, FQ_ONE); // Coefficients for the Frobenius automorphism. // c1[0] = 1, @@ -19,12 +20,12 @@ impl Fp4Parameters for Fq4Parameters { // c1[2] = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689600 // c1[3] = 23206834398115182106100160267808784663211750120934935212776243228483231604266504233503543246714830633588317039329677309362453490879357004638891161288350364891904062489821230132228897943262725174047727280881395973788104254381611 // - // These are calculated as `FROBENIUS_COEFF_FP4_C1[i] = Fp2Params::NONRESIDUE^((q^i - 1) / 4)`. - #[rustfmt::skip] + // These are calculated as `FROBENIUS_COEFF_FP4_C1[i] = + // Fp2Config::NONRESIDUE^((q^i - 1) / 4)`. const FROBENIUS_COEFF_FP4_C1: &'static [Fq] = &[ FQ_ONE, - field_new!(Fq, "18691656569803771296244054523431852464958959799019013859007259692542121208304602539555350517075508287829753932558576476751900235650227380562700444433662761577027341858128610410779088384480737679672900770810745291515010467307990"), - field_new!(Fq, "41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689600"), - field_new!(Fq, "23206834398115182106100160267808784663211750120934935212776243228483231604266504233503543246714830633588317039329677309362453490879357004638891161288350364891904062489821230132228897943262725174047727280881395973788104254381611"), + MontFp!(Fq, "18691656569803771296244054523431852464958959799019013859007259692542121208304602539555350517075508287829753932558576476751900235650227380562700444433662761577027341858128610410779088384480737679672900770810745291515010467307990"), + MontFp!(Fq, "41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689600"), + MontFp!(Fq, "23206834398115182106100160267808784663211750120934935212776243228483231604266504233503543246714830633588317039329677309362453490879357004638891161288350364891904062489821230132228897943262725174047727280881395973788104254381611"), ]; } diff --git a/mnt4_753/src/fields/fr.rs b/mnt4_753/src/fields/fr.rs index ac874ee..d5f16bc 100644 --- a/mnt4_753/src/fields/fr.rs +++ b/mnt4_753/src/fields/fr.rs @@ -1,151 +1,9 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger768 as BigInteger}, - fields::{FftParameters, Fp768, Fp768Parameters, FpParameters}, -}; - -pub type Fr = Fp768; - -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 = BigInt::new([ - 0x307f66b297671883, - 0xd72a7f2b1e645f4e, - 0x67079daa9a902283, - 0xf33f7620a86c668b, - 0x8878570d66464c12, - 0xa557af5b524f522b, - 0x5fafa3f6ef19319d, - 0x1eb9e04110a65629, - 0x3f96feb3c639a0b0, - 0x4d4fe37df3ffd732, - 0xadc831bd55bcf3e9, - 0x1b9f32a8bd6ab, - ]); -} -impl FpParameters for FrParameters { - /// MODULUS = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001 - const MODULUS: BigInteger = BigInt::new([ - 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 = BigInt::new([ - 0xb99680147fff6f42, - 0x4eb16817b589cea8, - 0xa1ebd2d90c79e179, - 0xf725caec549c0da, - 0xab0c4ee6d3e6dad4, - 0x9fbca908de0ccb62, - 0x320c3bb713338498, - 0x598b4302d2f00a62, - 0x4074c9cbfd8ca621, - 0xfa47edb3865e88c, - 0x95455fb31ff9a195, - 0x7b479ec8e242, - ]); - - const R2: BigInteger = BigInt::new([ - 0x3f9c69c7b7f4c8d1, - 0x70a50fa9ee48d127, - 0xcdbe6702009569cb, - 0x6bd8c6c6c49edc38, - 0x7955876cc35ee94e, - 0xc7285529be54a3f4, - 0xded52121ecec77cf, - 0x99be80f2ee12ee8e, - 0xc8a0ff01493bdcef, - 0xacc27988f3d9a316, - 0xd9e817a8fb44b3c9, - 0x5b58037e0e4, - ]); - - const INV: u64 = 0xc90776e23fffffff; - - const GENERATOR: BigInteger = BigInt::new([ - 0xeee0a5d37ff6635e, - 0xff458536cfa1cff4, - 0x659af978d8169ab0, - 0x1f1841c24780e3f1, - 0x602213036dcfef3a, - 0xd1d5c8f39d72db20, - 0xeb8b63c1c0ffefab, - 0xd2488e985f6cfa4e, - 0xcce1c2a623f7a66a, - 0x2a060f4d5085b19a, - 0xa9111a596408842f, - 0x11ca8d50bf627, - ]); - - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 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 = BigInt::new([ - 0x3e84e93f641ddb89, - 0xfc015e5d3a82645c, - 0xd264ea935b0e06f0, - 0xa48498dae77fe5d8, - 0x2166a66cfbaf2a50, - 0x856bde76c9b170a3, - 0xa283b63667449366, - 0xb25f61cc1ff6e497, - 0x6e3ebfb57adfa3e5, - 0xbb8b36b6dfe65d41, - 0xb64b1044408a408b, - 0x71318, - ]); - - /// (T - 1) / 2 = - /// 19510505240372826066959749344382731769313435032942308612067020927102003624928699234993613215065719057534854380361949315910773844221417724653005712598001768889707241358864151146947600942964851143589213359663220198927812 - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x1f42749fb20eedc4, - 0x7e00af2e9d41322e, - 0x69327549ad870378, - 0x52424c6d73bff2ec, - 0x90b353367dd79528, - 0x42b5ef3b64d8b851, - 0xd141db1b33a249b3, - 0xd92fb0e60ffb724b, - 0xb71f5fdabd6fd1f2, - 0xddc59b5b6ff32ea0, - 0x5b25882220452045, - 0x3898c, - ]); -} +use ark_ff::fields::{Fp768, MontBackend, MontConfig}; + +#[derive(MontConfig)] +#[modulus = "41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001"] +#[generator = "17"] +#[small_subgroup_base = "5"] +#[small_subgroup_power = "2"] +pub struct FrConfig; +pub type Fr = Fp768>; diff --git a/mnt4_753/src/fields/tests.rs b/mnt4_753/src/fields/tests.rs index 890afff..4fc5717 100644 --- a/mnt4_753/src/fields/tests.rs +++ b/mnt4_753/src/fields/tests.rs @@ -1,9 +1,12 @@ -use ark_ff::{Field, One, SquareRootField, UniformRand, Zero}; -use ark_std::test_rng; +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; +use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; use crate::*; -use ark_algebra_test_templates::{fields::*, generate_field_test}; - -use core::ops::{AddAssign, MulAssign, SubAssign}; -generate_field_test!(mnt4_753; fq2; fq4;); +generate_field_test!(mnt4_753; fq2; fq4; mont(12, 12); ); +generate_field_serialization_test!(mnt4_753;); diff --git a/mnt4_753/src/lib.rs b/mnt4_753/src/lib.rs index f7d0bb6..bcf7438 100644 --- a/mnt4_753/src/lib.rs +++ b/mnt4_753/src/lib.rs @@ -10,9 +10,10 @@ //! 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. +//! 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 @@ -25,7 +26,8 @@ //! * 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 +//! * NON_RESIDUE = 13 is the quadratic non-residue used to construct the +//! extension field Fq2 #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/mnt6_298/scripts/base_field.sage b/mnt6_298/scripts/base_field.sage new file mode 100644 index 0000000..05e4af4 --- /dev/null +++ b/mnt6_298/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/mnt6_298/scripts/scalar_field.sage b/mnt6_298/scripts/scalar_field.sage new file mode 100644 index 0000000..003f4c3 --- /dev/null +++ b/mnt6_298/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/mnt6_298/src/constraints/curves.rs b/mnt6_298/src/constraints/curves.rs index 069ee9e..0f529d1 100644 --- a/mnt6_298/src/constraints/curves.rs +++ b/mnt6_298/src/constraints/curves.rs @@ -1,6 +1,7 @@ -use crate::Parameters; use ark_r1cs_std::groups::mnt6; +use crate::Parameters; + /// An element of G1 in the MNT6-298 bilinear group. pub type G1Var = mnt6::G1Var; /// An element of G2 in the MNT6-298 bilinear group. diff --git a/mnt6_298/src/constraints/fields.rs b/mnt6_298/src/constraints/fields.rs index 045db64..675e052 100644 --- a/mnt6_298/src/constraints/fields.rs +++ b/mnt6_298/src/constraints/fields.rs @@ -1,13 +1,13 @@ -use crate::{Fq, Fq3Parameters, Fq6Parameters}; - use ark_r1cs_std::fields::{fp::FpVar, fp3::Fp3Var, fp6_2over3::Fp6Var}; +use crate::{Fq, Fq3Config, Fq6Config}; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FqVar = FpVar; /// A variable that is the R1CS equivalent of `crate::Fq3`. -pub type Fq3Var = Fp3Var; +pub type Fq3Var = Fp3Var; /// A variable that is the R1CS equivalent of `crate::Fq6`. -pub type Fq6Var = Fp6Var; +pub type Fq6Var = Fp6Var; #[test] fn mnt6_298_field_gadgets_test() { diff --git a/mnt6_298/src/constraints/pairing.rs b/mnt6_298/src/constraints/pairing.rs index 14641be..bce6277 100644 --- a/mnt6_298/src/constraints/pairing.rs +++ b/mnt6_298/src/constraints/pairing.rs @@ -1,6 +1,7 @@ use crate::Parameters; -/// Specifies the constraints for computing a pairing in the MNT6-298 bilinear group. +/// Specifies the constraints for computing a pairing in the MNT6-298 bilinear +/// group. pub type PairingVar = ark_r1cs_std::pairing::mnt6::PairingVar; #[test] diff --git a/mnt6_298/src/curves/g1.rs b/mnt6_298/src/curves/g1.rs index df9c94d..3cd49ef 100644 --- a/mnt6_298/src/curves/g1.rs +++ b/mnt6_298/src/curves/g1.rs @@ -2,7 +2,7 @@ use ark_ec::{ mnt6, models::{ModelParameters, SWModelParameters}, }; -use ark_ff::field_new; +use ark_ff::MontFp; use crate::{Fq, Fr}; @@ -21,18 +21,15 @@ impl ModelParameters for Parameters { const COFACTOR: &'static [u64] = &[1]; /// COFACTOR^(-1) mod r = 1 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "1"); + const COFACTOR_INV: Fr = MontFp!(Fr, "1"); } impl SWModelParameters for Parameters { /// COEFF_A = 11 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "11"); + const COEFF_A: Fq = MontFp!(Fq, "11"); /// COEFF_B = 106700080510851735677967319632585352256454251201367587890185989362936000262606668469523074 - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "106700080510851735677967319632585352256454251201367587890185989362936000262606668469523074"); + const COEFF_B: Fq = MontFp!(Fq, "106700080510851735677967319632585352256454251201367587890185989362936000262606668469523074"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -41,8 +38,8 @@ impl SWModelParameters for Parameters { /// G1_GENERATOR_X = #[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = field_new!(Fq, "336685752883082228109289846353937104185698209371404178342968838739115829740084426881123453"); +pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "336685752883082228109289846353937104185698209371404178342968838739115829740084426881123453"); /// G1_GENERATOR_Y = #[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "402596290139780989709332707716568920777622032073762749862342374583908837063963736098549800"); +pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "402596290139780989709332707716568920777622032073762749862342374583908837063963736098549800"); diff --git a/mnt6_298/src/curves/g2.rs b/mnt6_298/src/curves/g2.rs index 111bb3c..1822c3b 100644 --- a/mnt6_298/src/curves/g2.rs +++ b/mnt6_298/src/curves/g2.rs @@ -3,7 +3,7 @@ use ark_ec::{ mnt6::MNT6Parameters, models::{ModelParameters, SWModelParameters}, }; -use ark_ff::field_new; +use ark_ff::{CubicExt, MontFp}; use crate::{g1, Fq, Fq3, Fr, FQ_ZERO}; @@ -36,27 +36,26 @@ impl ModelParameters for Parameters { /// COFACTOR^(-1) mod r = /// 79320381028210220958891541608841408590854146655427655872973753568875979721417185067925504 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "79320381028210220958891541608841408590854146655427655872973753568875979721417185067925504"); + const COFACTOR_INV: Fr = MontFp!( + Fr, + "79320381028210220958891541608841408590854146655427655872973753568875979721417185067925504" + ); } /// MUL_BY_A_C0 = NONRESIDUE * COEFF_A = 5 * 11 - #[rustfmt::skip] -pub const MUL_BY_A_C0: Fq = field_new!(Fq, "55"); +pub const MUL_BY_A_C0: Fq = MontFp!(Fq, "55"); /// MUL_BY_A_C1 = NONRESIDUE * COEFF_A - #[rustfmt::skip] -pub const MUL_BY_A_C1: Fq = field_new!(Fq, "55"); +pub const MUL_BY_A_C1: Fq = MontFp!(Fq, "55"); /// MUL_BY_A_C2 = COEFF_A pub const MUL_BY_A_C2: Fq = g1::Parameters::COEFF_A; impl SWModelParameters for Parameters { const COEFF_A: Fq3 = crate::Parameters::TWIST_COEFF_A; - #[rustfmt::skip] - const COEFF_B: Fq3 = field_new!(Fq3, + const COEFF_B: Fq3 = CubicExt!( // 5 * G1::COEFF_B - field_new!(Fq, "57578116384997352636487348509878309737146377454014423897662211075515354005624851787652233"), + MontFp!(Fq, "57578116384997352636487348509878309737146377454014423897662211075515354005624851787652233"), FQ_ZERO, FQ_ZERO, ); @@ -67,8 +66,7 @@ impl SWModelParameters for Parameters { #[inline(always)] fn mul_by_a(elt: &Fq3) -> Fq3 { - field_new!( - Fq3, + CubicExt!( MUL_BY_A_C0 * &elt.c1, MUL_BY_A_C1 * &elt.c2, MUL_BY_A_C2 * &elt.c0, @@ -76,33 +74,31 @@ impl SWModelParameters for Parameters { } } -const G2_GENERATOR_X: Fq3 = - field_new!(Fq3, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2); -const G2_GENERATOR_Y: Fq3 = - field_new!(Fq3, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2); +const G2_GENERATOR_X: Fq3 = CubicExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2); +const G2_GENERATOR_Y: Fq3 = CubicExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2); -pub const G2_GENERATOR_X_C0: Fq = field_new!( +pub const G2_GENERATOR_X_C0: Fq = MontFp!( Fq, "421456435772811846256826561593908322288509115489119907560382401870203318738334702321297427" ); -pub const G2_GENERATOR_X_C1: Fq = field_new!( +pub const G2_GENERATOR_X_C1: Fq = MontFp!( Fq, "103072927438548502463527009961344915021167584706439945404959058962657261178393635706405114" ); -pub const G2_GENERATOR_X_C2: Fq = field_new!( +pub const G2_GENERATOR_X_C2: Fq = MontFp!( Fq, "143029172143731852627002926324735183809768363301149009204849580478324784395590388826052558" ); -pub const G2_GENERATOR_Y_C0: Fq = field_new!( +pub const G2_GENERATOR_Y_C0: Fq = MontFp!( Fq, "464673596668689463130099227575639512541218133445388869383893594087634649237515554342751377" ); -pub const G2_GENERATOR_Y_C1: Fq = field_new!( +pub const G2_GENERATOR_Y_C1: Fq = MontFp!( Fq, "100642907501977375184575075967118071807821117960152743335603284583254620685343989304941678" ); -pub const G2_GENERATOR_Y_C2: Fq = field_new!( +pub const G2_GENERATOR_Y_C2: Fq = MontFp!( Fq, "123019855502969896026940545715841181300275180157288044663051565390506010149881373807142903" ); diff --git a/mnt6_298/src/curves/mod.rs b/mnt6_298/src/curves/mod.rs index 021db9f..0ed900c 100644 --- a/mnt6_298/src/curves/mod.rs +++ b/mnt6_298/src/curves/mod.rs @@ -1,11 +1,10 @@ -use ark_ff::{biginteger::BigInteger320, field_new, BigInt, Fp3}; - use ark_ec::{ models::mnt6::{MNT6Parameters, MNT6}, SWModelParameters, }; +use ark_ff::{biginteger::BigInteger320, BigInt, CubicExt, Fp3, MontFp}; -use crate::{Fq, Fq3, Fq3Parameters, Fq6Parameters, Fr}; +use crate::{Fq, Fq3Config, Fq6Config, Fr}; pub mod g1; pub mod g2; @@ -23,13 +22,9 @@ pub type MNT6_298 = MNT6; pub struct Parameters; impl MNT6Parameters for Parameters { - const TWIST: Fp3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO); - #[rustfmt::skip] - const TWIST_COEFF_A: Fp3 = field_new!(Fq3, - FQ_ZERO, - FQ_ZERO, - g1::Parameters::COEFF_A, - ); + const TWIST: Fp3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO); + const TWIST_COEFF_A: Fp3 = + CubicExt!(FQ_ZERO, FQ_ZERO, g1::Parameters::COEFF_A,); const ATE_LOOP_COUNT: &'static [u64] = &[0xdc9a1b671660000, 0x46609756bec2a33f, 0x1eef55]; const ATE_IS_LOOP_COUNT_NEG: bool = true; const FINAL_EXPONENT_LAST_CHUNK_1: BigInteger320 = BigInt::new([0x1, 0x0, 0x0, 0x0, 0x0]); @@ -38,11 +33,11 @@ impl MNT6Parameters for Parameters { BigInt::new([0xdc9a1b671660000, 0x46609756bec2a33f, 0x1eef55, 0x0, 0x0]); type Fp = Fq; type Fr = Fr; - type Fp3Params = Fq3Parameters; - type Fp6Params = Fq6Parameters; + type Fp3Config = Fq3Config; + type Fp6Config = Fq6Config; type G1Parameters = self::g1::Parameters; type G2Parameters = self::g2::Parameters; } -pub const FQ_ZERO: Fq = field_new!(Fq, "0"); -pub const FQ_ONE: Fq = field_new!(Fq, "1"); +pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); +pub const FQ_ONE: Fq = MontFp!(Fq, "1"); diff --git a/mnt6_298/src/curves/tests.rs b/mnt6_298/src/curves/tests.rs index 23b731e..e5986c4 100644 --- a/mnt6_298/src/curves/tests.rs +++ b/mnt6_298/src/curves/tests.rs @@ -1,16 +1,14 @@ -use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{Field, One, PrimeField, UniformRand}; -use ark_std::{rand::Rng, test_rng}; - -use crate::*; - use ark_algebra_test_templates::{ curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, generate_product_of_pairings_test, groups::*, msm::*, }; - +use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; +use ark_ff::{Field, One, PrimeField, UniformRand}; +use ark_std::{rand::Rng, test_rng}; use core::ops::MulAssign; +use crate::*; + generate_g1_test!(mnt6_298; curve_tests; sw_tests;); generate_g2_test!(mnt6_298; curve_tests; sw_tests;); generate_bilinearity_test!(MNT6_298, Fq6); diff --git a/mnt6_298/src/fields/fq.rs b/mnt6_298/src/fields/fq.rs index f587b1a..6397898 100644 --- a/mnt6_298/src/fields/fq.rs +++ b/mnt6_298/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_mnt4_298::{Fr as Fq, FrParameters as FqParameters}; +pub use ark_mnt4_298::{Fr as Fq, FrConfig as FqConfig}; diff --git a/mnt6_298/src/fields/fq3.rs b/mnt6_298/src/fields/fq3.rs index 671688b..9e14a82 100644 --- a/mnt6_298/src/fields/fq3.rs +++ b/mnt6_298/src/fields/fq3.rs @@ -1,23 +1,23 @@ -use crate::{fq::Fq, FQ_ZERO}; use ark_ff::{ - field_new, - fields::fp3::{Fp3, Fp3Parameters}, + fields::fp3::{Fp3, Fp3Config}, + CubicExt, MontFp, }; -pub type Fq3 = Fp3; +use crate::{fq::Fq, FQ_ZERO}; + +pub type Fq3 = Fp3; -pub struct Fq3Parameters; +pub struct Fq3Config; -impl Fp3Parameters for Fq3Parameters { +impl Fp3Config for Fq3Config { type Fp = Fq; - #[rustfmt::skip] - const NONRESIDUE: Fq = field_new!(Fq, "5"); + const NONRESIDUE: Fq = MontFp!(Fq, "5"); const TWO_ADICITY: u32 = 34; #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[ + const TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[ 0x69232b75663933bd, 0xca650efcfc00ee0, 0x77ca3963fe36f720, @@ -34,21 +34,18 @@ impl Fp3Parameters for Fq3Parameters { 0x6878f58, ]; - #[rustfmt::skip] - const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = ( - field_new!(Fq, "154361449678783505076984156275977937654331103361174469632346230549735979552469642799720052"), + const QUADRATIC_NONRESIDUE_TO_T: Fq3 = CubicExt!( + MontFp!(Fq, "154361449678783505076984156275977937654331103361174469632346230549735979552469642799720052"), FQ_ZERO, FQ_ZERO, ); - #[rustfmt::skip] const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[ - field_new!(Fq, "1"), - field_new!(Fq, "471738898967521029133040851318449165997304108729558973770077319830005517129946578866686956"), - field_new!(Fq, "4183387201740296620308398334599285547820769823264541783190415909159130177461911693276180"), + MontFp!(Fq, "1"), + MontFp!(Fq, "471738898967521029133040851318449165997304108729558973770077319830005517129946578866686956"), + MontFp!(Fq, "4183387201740296620308398334599285547820769823264541783190415909159130177461911693276180"), ]; - #[rustfmt::skip] const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[ Self::FROBENIUS_COEFF_FP3_C1[0], Self::FROBENIUS_COEFF_FP3_C1[2], diff --git a/mnt6_298/src/fields/fq6.rs b/mnt6_298/src/fields/fq6.rs index 0879380..d35fa11 100644 --- a/mnt6_298/src/fields/fq6.rs +++ b/mnt6_298/src/fields/fq6.rs @@ -1,24 +1,25 @@ -use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO}; use ark_ff::{ - field_new, - fields::fp6_2over3::{Fp6, Fp6Parameters}, + fields::fp6_2over3::{Fp6, Fp6Config}, + CubicExt, MontFp, }; -pub type Fq6 = Fp6; +use crate::{Fq, Fq3, Fq3Config, FQ_ONE, FQ_ZERO}; -pub struct Fq6Parameters; +pub type Fq6 = Fp6; -impl Fp6Parameters for Fq6Parameters { - type Fp3Params = Fq3Parameters; +pub struct Fq6Config; - const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO); +impl Fp6Config for Fq6Config { + type Fp3Config = Fq3Config; + + const NONRESIDUE: Fq3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO); const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[ - field_new!(Fq, "1"), - field_new!(Fq, "471738898967521029133040851318449165997304108729558973770077319830005517129946578866686957"), - field_new!(Fq, "471738898967521029133040851318449165997304108729558973770077319830005517129946578866686956"), - field_new!(Fq, "475922286169261325753349249653048451545124878552823515553267735739164647307408490559963136"), - field_new!(Fq, "4183387201740296620308398334599285547820769823264541783190415909159130177461911693276180"), - field_new!(Fq, "4183387201740296620308398334599285547820769823264541783190415909159130177461911693276181"), + MontFp!(Fq, "1"), + MontFp!(Fq, "471738898967521029133040851318449165997304108729558973770077319830005517129946578866686957"), + MontFp!(Fq, "471738898967521029133040851318449165997304108729558973770077319830005517129946578866686956"), + MontFp!(Fq, "475922286169261325753349249653048451545124878552823515553267735739164647307408490559963136"), + MontFp!(Fq, "4183387201740296620308398334599285547820769823264541783190415909159130177461911693276180"), + MontFp!(Fq, "4183387201740296620308398334599285547820769823264541783190415909159130177461911693276181"), ]; } diff --git a/mnt6_298/src/fields/fr.rs b/mnt6_298/src/fields/fr.rs index 274bfe3..257ce31 100644 --- a/mnt6_298/src/fields/fr.rs +++ b/mnt6_298/src/fields/fr.rs @@ -1 +1 @@ -pub use ark_mnt4_298::{Fq as Fr, FqParameters as FrParameters}; +pub use ark_mnt4_298::{Fq as Fr, FqConfig as FrConfig}; diff --git a/mnt6_298/src/fields/mod.rs b/mnt6_298/src/fields/mod.rs index bf9cff7..7bfd333 100644 --- a/mnt6_298/src/fields/mod.rs +++ b/mnt6_298/src/fields/mod.rs @@ -10,5 +10,5 @@ pub use self::fq3::*; pub mod fq6; pub use self::fq6::*; -#[cfg(all(feature = "mnt6_298", test))] +#[cfg(test)] mod tests; diff --git a/mnt6_298/src/fields/tests.rs b/mnt6_298/src/fields/tests.rs index 099590c..96fd342 100644 --- a/mnt6_298/src/fields/tests.rs +++ b/mnt6_298/src/fields/tests.rs @@ -1,18 +1,21 @@ +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{ - fields::{models::fp6_2over3::*, quadratic_extension::QuadExtParameters}, - Field, + fields::{models::fp6_2over3::*, quadratic_extension::QuadExtConfig, SquareRootField}, + Field, PrimeField, }; -use ark_std::{rand::Rng, test_rng}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng, One, UniformRand, Zero}; +use core::ops::{AddAssign, MulAssign, SubAssign}; use crate::*; -use ark_algebra_test_templates::{fields::*, generate_field_test}; -use core::ops::{AddAssign, MulAssign, SubAssign}; - -generate_field_test!(mnt6_298;); +generate_field_test!(mnt6_298; fq3; fq6; mont(5, 5); ); +generate_field_serialization_test!(mnt6_298;); #[test] -fn test_fq3() { +fn test_fq3_more() { let mut rng = test_rng(); let a: Fq3 = rng.gen(); let b: Fq3 = rng.gen(); @@ -20,16 +23,7 @@ fn test_fq3() { sqrt_field_test(a); frobenius_test::(Fq::characteristic(), 13); assert_eq!( - a * Fq6Parameters::NONRESIDUE, - >::mul_base_field_by_nonresidue(&a) + a * Fq6Config::NONRESIDUE, + >::mul_base_field_by_nonresidue(&a) ); } - -#[test] -fn test_fq6() { - let mut rng = test_rng(); - let a: Fq6 = rng.gen(); - let b: Fq6 = rng.gen(); - field_test(a, b); - frobenius_test::(Fq::characteristic(), 13); -} diff --git a/mnt6_298/src/lib.rs b/mnt6_298/src/lib.rs index 1effbd9..39b1ea8 100644 --- a/mnt6_298/src/lib.rs +++ b/mnt6_298/src/lib.rs @@ -10,14 +10,17 @@ //! This library implements the MNT6_298 curve generated in //! [\[BCTV14\]](https://eprint.iacr.org/2014/595). The name denotes that it is a -//! Miyaji--Nakabayashi--Takano curve of embedding degree 6, defined over a 298-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 MNT4_298. +//! Miyaji--Nakabayashi--Takano curve of embedding degree 6, defined over a +//! 298-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 +//! MNT4_298. //! //! //! Curve information: -//! * Base field: q = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 -//! * Scalar field: r = 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081 +//! * Base field: q = +//! 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 +//! * Scalar field: r = +//! 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081 //! * valuation(q - 1, 2) = 34 //! * valuation(r - 1, 2) = 17 //! * G1 curve equation: y^2 = x^3 + ax + b, where @@ -26,7 +29,8 @@ //! * G2 curve equation: y^2 = x^3 + Ax + B, where //! * A = Fq2 = (0, 0, a) //! * B = Fq2(b * NON_RESIDUE, 0, 0) -//! * NON_RESIDUE = 5 is the cubic non-residue used to construct the field extension Fq3 +//! * NON_RESIDUE = 5 is the cubic non-residue used to construct the field +//! extension Fq3 #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/mnt6_753/scripts/base_field.sage b/mnt6_753/scripts/base_field.sage new file mode 100644 index 0000000..b91ade8 --- /dev/null +++ b/mnt6_753/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/mnt6_753/scripts/scalar_field.sage b/mnt6_753/scripts/scalar_field.sage new file mode 100644 index 0000000..6828995 --- /dev/null +++ b/mnt6_753/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689601 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/mnt6_753/src/constraints/curves.rs b/mnt6_753/src/constraints/curves.rs index e747fd2..c35a921 100644 --- a/mnt6_753/src/constraints/curves.rs +++ b/mnt6_753/src/constraints/curves.rs @@ -1,6 +1,7 @@ -use crate::Parameters; use ark_r1cs_std::groups::mnt6; +use crate::Parameters; + /// An element of G1 in the MNT6-753 bilinear group. pub type G1Var = mnt6::G1Var; /// An element of G2 in the MNT6-753 bilinear group. diff --git a/mnt6_753/src/constraints/fields.rs b/mnt6_753/src/constraints/fields.rs index de156ee..49e5c9e 100644 --- a/mnt6_753/src/constraints/fields.rs +++ b/mnt6_753/src/constraints/fields.rs @@ -1,13 +1,13 @@ -use crate::{Fq, Fq3Parameters, Fq6Parameters}; - use ark_r1cs_std::fields::{fp::FpVar, fp3::Fp3Var, fp6_2over3::Fp6Var}; +use crate::{Fq, Fq3Config, Fq6Config}; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FqVar = FpVar; /// A variable that is the R1CS equivalent of `crate::Fq3`. -pub type Fq3Var = Fp3Var; +pub type Fq3Var = Fp3Var; /// A variable that is the R1CS equivalent of `crate::Fq6`. -pub type Fq6Var = Fp6Var; +pub type Fq6Var = Fp6Var; #[test] fn mnt6_753_field_gadgets_test() { diff --git a/mnt6_753/src/constraints/pairing.rs b/mnt6_753/src/constraints/pairing.rs index 8979aec..de4d6fe 100644 --- a/mnt6_753/src/constraints/pairing.rs +++ b/mnt6_753/src/constraints/pairing.rs @@ -1,6 +1,7 @@ use crate::Parameters; -/// Specifies the constraints for computing a pairing in the MNT6-753 bilinear group. +/// Specifies the constraints for computing a pairing in the MNT6-753 bilinear +/// group. pub type PairingVar = ark_r1cs_std::pairing::mnt6::PairingVar; #[test] diff --git a/mnt6_753/src/curves/g1.rs b/mnt6_753/src/curves/g1.rs index b26470f..f13aad6 100644 --- a/mnt6_753/src/curves/g1.rs +++ b/mnt6_753/src/curves/g1.rs @@ -2,7 +2,7 @@ use ark_ec::{ mnt6, models::{ModelParameters, SWModelParameters}, }; -use ark_ff::field_new; +use ark_ff::MontFp; use crate::{Fq, Fr, FR_ONE}; @@ -21,18 +21,15 @@ impl ModelParameters for Parameters { const COFACTOR: &'static [u64] = &[1]; /// COFACTOR^(-1) mod r = 1 - #[rustfmt::skip] const COFACTOR_INV: Fr = FR_ONE; } impl SWModelParameters for Parameters { /// COEFF_A = 11 - #[rustfmt::skip] - const COEFF_A: Fq = field_new!(Fq, "11"); + const COEFF_A: Fq = MontFp!(Fq, "11"); /// COEFF_B = 0x7DA285E70863C79D56446237CE2E1468D14AE9BB64B2BB01B10E60A5D5DFE0A25714B7985993F62F03B22A9A3C737A1A1E0FCF2C43D7BF847957C34CCA1E3585F9A80A95F401867C4E80F4747FDE5ABA7505BA6FCF2485540B13DFC8468A - #[rustfmt::skip] - const COEFF_B: Fq = field_new!(Fq, "11625908999541321152027340224010374716841167701783584648338908235410859267060079819722747939267925389062611062156601938166010098747920378738927832658133625454260115409075816187555055859490253375704728027944315501122723426879114"); + const COEFF_B: Fq = MontFp!(Fq, "11625908999541321152027340224010374716841167701783584648338908235410859267060079819722747939267925389062611062156601938166010098747920378738927832658133625454260115409075816187555055859490253375704728027944315501122723426879114"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -44,10 +41,8 @@ impl SWModelParameters for Parameters { // Y = 27460508402331965149626600224382137254502975979168371111640924721589127725376473514838234361114855175488242007431439074223827742813911899817930728112297763448010814764117701403540298764970469500339646563344680868495474127850569, /// G1_GENERATOR_X = /// 3458420969484235708806261200128850544017070333833944116801482064540723268149235477762870414664917360605949659630933184751526227993647030875167687492714052872195770088225183259051403087906158701786758441889742618916006546636728, -#[rustfmt::skip] -pub const G1_GENERATOR_X: Fq = field_new!(Fq, "3458420969484235708806261200128850544017070333833944116801482064540723268149235477762870414664917360605949659630933184751526227993647030875167687492714052872195770088225183259051403087906158701786758441889742618916006546636728"); +pub const G1_GENERATOR_X: Fq = MontFp!(Fq, "3458420969484235708806261200128850544017070333833944116801482064540723268149235477762870414664917360605949659630933184751526227993647030875167687492714052872195770088225183259051403087906158701786758441889742618916006546636728"); /// G1_GENERATOR_Y = /// 27460508402331965149626600224382137254502975979168371111640924721589127725376473514838234361114855175488242007431439074223827742813911899817930728112297763448010814764117701403540298764970469500339646563344680868495474127850569, -#[rustfmt::skip] -pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "27460508402331965149626600224382137254502975979168371111640924721589127725376473514838234361114855175488242007431439074223827742813911899817930728112297763448010814764117701403540298764970469500339646563344680868495474127850569"); +pub const G1_GENERATOR_Y: Fq = MontFp!(Fq, "27460508402331965149626600224382137254502975979168371111640924721589127725376473514838234361114855175488242007431439074223827742813911899817930728112297763448010814764117701403540298764970469500339646563344680868495474127850569"); diff --git a/mnt6_753/src/curves/g2.rs b/mnt6_753/src/curves/g2.rs index bdf71e0..56fdebe 100644 --- a/mnt6_753/src/curves/g2.rs +++ b/mnt6_753/src/curves/g2.rs @@ -3,7 +3,7 @@ use ark_ec::{ mnt6::MNT6Parameters, models::{ModelParameters, SWModelParameters}, }; -use ark_ff::field_new; +use ark_ff::{CubicExt, MontFp}; use crate::{g1, Fq, Fq3, Fr, FQ_ZERO}; @@ -50,21 +50,18 @@ impl ModelParameters for Parameters { /// COFACTOR^(-1) mod r = /// 6983081827986492233724035798540106188028451653325658178630583820170892135428517795509815627298389820236345161981341515817589065927929152555581161598204976128690232061758269440757592419606754539638220064054062394397574161203200 - #[rustfmt::skip] - const COFACTOR_INV: Fr = field_new!(Fr, "6983081827986492233724035798540106188028451653325658178630583820170892135428517795509815627298389820236345161981341515817589065927929152555581161598204976128690232061758269440757592419606754539638220064054062394397574161203200"); + const COFACTOR_INV: Fr = MontFp!(Fr, "6983081827986492233724035798540106188028451653325658178630583820170892135428517795509815627298389820236345161981341515817589065927929152555581161598204976128690232061758269440757592419606754539638220064054062394397574161203200"); } /// MUL_BY_A_C0 = NONRESIDUE * COEFF_A /// = 11 * 11 /// = 121 -#[rustfmt::skip] -pub const MUL_BY_A_C0: Fq = field_new!(Fq, "121"); +pub const MUL_BY_A_C0: Fq = MontFp!(Fq, "121"); /// MUL_BY_A_C1 = NONRESIDUE * COEFF_A /// = 11 * 11 /// = 121 -#[rustfmt::skip] -pub const MUL_BY_A_C1: Fq = field_new!(Fq, "121"); +pub const MUL_BY_A_C1: Fq = MontFp!(Fq, "121"); /// MUL_BY_A_C2 = COEFF_A pub const MUL_BY_A_C2: Fq = g1::Parameters::COEFF_A; @@ -81,10 +78,8 @@ impl SWModelParameters for Parameters { // (2189526091197672465268098090392210500740714959757583916377481826443393499947557697773546040576162515434508768057245887856591913752342600919117433675080691499697020523783784738694360040853591723916201150207746019687604267190251, // 0, 0) // ``` - #[rustfmt::skip] - const COEFF_B: Fq3 = field_new!( - Fq3, - field_new!(Fq, "2189526091197672465268098090392210500740714959757583916377481826443393499947557697773546040576162515434508768057245887856591913752342600919117433675080691499697020523783784738694360040853591723916201150207746019687604267190251"), + const COEFF_B: Fq3 = CubicExt!( + MontFp!(Fq, "2189526091197672465268098090392210500740714959757583916377481826443393499947557697773546040576162515434508768057245887856591913752342600919117433675080691499697020523783784738694360040853591723916201150207746019687604267190251"), FQ_ZERO, FQ_ZERO, ); @@ -95,8 +90,7 @@ impl SWModelParameters for Parameters { #[inline(always)] fn mul_by_a(elt: &Fq3) -> Fq3 { - field_new!( - Fq3, + CubicExt!( MUL_BY_A_C0 * &elt.c1, MUL_BY_A_C1 * &elt.c2, MUL_BY_A_C2 * &elt.c0, @@ -104,10 +98,8 @@ impl SWModelParameters for Parameters { } } -const G2_GENERATOR_X: Fq3 = - field_new!(Fq3, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2); -const G2_GENERATOR_Y: Fq3 = - field_new!(Fq3, G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2); +const G2_GENERATOR_X: Fq3 = CubicExt!(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_X_C2); +const G2_GENERATOR_Y: Fq3 = CubicExt!(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1, G2_GENERATOR_Y_C2); // Generator of G2 // These are three Fq elements each because X and Y (and Z) are elements of Fq^3 @@ -117,10 +109,10 @@ const G2_GENERATOR_Y: Fq3 = // Y = 2540920530670785421282147216459500299597350984927286541981768941513322907384197363939300669100157141915897390694710534916701460991329498878429407641200901974650893207493883271892985923686300670742888673128384350189165542294615, // 7768974215205248225654340523113146529854477025417883273460270519532499370133542215655437897583245920162220909271982265882784840026754554720358946490360213245668334549692889019612343620295335698052097726325099648573158597797497, // 21014872727619291834131369222699267167761185012487859171850226473555446863681002782100371394603357586906967186931035615146288030444598977758226767063525819170917389755555854704165900869058188909090444447822088242504281789869689, -pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, "27250797394340459586637772414334383652934225310678303542554641987990991970766156209996739240400887081904395745019996048910447071686918567661896491214767494514394154061111870331668445455228882471000120574964265209669155206168252"); -pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, "35762481056967998715733586393399457882827322353696313323665483142561285210083843314423554450886956650265947502285422529615273790981238406393402603210224104850580302463396274854098657541573494421834514772635884262388058080180368"); -pub const G2_GENERATOR_X_C2: Fq = field_new!(Fq, "36955296703808958167583270646821654948157955258947892285629161090141878438357164213613114995903637211606408001037026832604054121847388692538440756596264746452765613740820430501353237866984394057660379098674983614861254438847846"); +pub const G2_GENERATOR_X_C0: Fq = MontFp!(Fq, "27250797394340459586637772414334383652934225310678303542554641987990991970766156209996739240400887081904395745019996048910447071686918567661896491214767494514394154061111870331668445455228882471000120574964265209669155206168252"); +pub const G2_GENERATOR_X_C1: Fq = MontFp!(Fq, "35762481056967998715733586393399457882827322353696313323665483142561285210083843314423554450886956650265947502285422529615273790981238406393402603210224104850580302463396274854098657541573494421834514772635884262388058080180368"); +pub const G2_GENERATOR_X_C2: Fq = MontFp!(Fq, "36955296703808958167583270646821654948157955258947892285629161090141878438357164213613114995903637211606408001037026832604054121847388692538440756596264746452765613740820430501353237866984394057660379098674983614861254438847846"); -pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, "2540920530670785421282147216459500299597350984927286541981768941513322907384197363939300669100157141915897390694710534916701460991329498878429407641200901974650893207493883271892985923686300670742888673128384350189165542294615"); -pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, "7768974215205248225654340523113146529854477025417883273460270519532499370133542215655437897583245920162220909271982265882784840026754554720358946490360213245668334549692889019612343620295335698052097726325099648573158597797497"); -pub const G2_GENERATOR_Y_C2: Fq = field_new!(Fq, "21014872727619291834131369222699267167761185012487859171850226473555446863681002782100371394603357586906967186931035615146288030444598977758226767063525819170917389755555854704165900869058188909090444447822088242504281789869689"); +pub const G2_GENERATOR_Y_C0: Fq = MontFp!(Fq, "2540920530670785421282147216459500299597350984927286541981768941513322907384197363939300669100157141915897390694710534916701460991329498878429407641200901974650893207493883271892985923686300670742888673128384350189165542294615"); +pub const G2_GENERATOR_Y_C1: Fq = MontFp!(Fq, "7768974215205248225654340523113146529854477025417883273460270519532499370133542215655437897583245920162220909271982265882784840026754554720358946490360213245668334549692889019612343620295335698052097726325099648573158597797497"); +pub const G2_GENERATOR_Y_C2: Fq = MontFp!(Fq, "21014872727619291834131369222699267167761185012487859171850226473555446863681002782100371394603357586906967186931035615146288030444598977758226767063525819170917389755555854704165900869058188909090444447822088242504281789869689"); diff --git a/mnt6_753/src/curves/mod.rs b/mnt6_753/src/curves/mod.rs index 2c7f7ff..783b037 100644 --- a/mnt6_753/src/curves/mod.rs +++ b/mnt6_753/src/curves/mod.rs @@ -2,9 +2,9 @@ use ark_ec::models::{ mnt6::{MNT6Parameters, MNT6}, SWModelParameters, }; -use ark_ff::{biginteger::BigInteger768, field_new, BigInt, Fp3}; +use ark_ff::{biginteger::BigInteger768, BigInt, CubicExt, Fp3, MontFp}; -use crate::{Fq, Fq3, Fq3Parameters, Fq6Parameters, Fr}; +use crate::{Fq, Fq3Config, Fq6Config, Fr}; pub mod g1; pub mod g2; @@ -22,19 +22,16 @@ pub type MNT6_753 = MNT6; pub struct Parameters; impl MNT6Parameters for Parameters { - const TWIST: Fp3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO); + const TWIST: Fp3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO); // A coefficient of MNT6-753 G2 = // ``` // mnt6753_twist_coeff_a = mnt6753_Fq3(mnt6753_Fq::zero(), mnt6753_Fq::zero(), // mnt6753_G1::coeff_a); // = (ZERO, ZERO, A_COEFF); // ``` - #[rustfmt::skip] - const TWIST_COEFF_A: Fp3 = field_new!(Fq3, - FQ_ZERO, - FQ_ZERO, - g1::Parameters::COEFF_A, - ); + const TWIST_COEFF_A: Fp3 = + CubicExt!(FQ_ZERO, FQ_ZERO, g1::Parameters::COEFF_A,); + // https://github.com/o1-labs/snarky/blob/9c21ab2bb23874604640740d646a932e813432c3/snarkette/mnt6753.ml const ATE_LOOP_COUNT: &'static [u64] = &[ 8824542903220142080, @@ -64,13 +61,13 @@ impl MNT6Parameters for Parameters { ]); type Fp = Fq; type Fr = Fr; - type Fp3Params = Fq3Parameters; - type Fp6Params = Fq6Parameters; + type Fp3Config = Fq3Config; + type Fp6Config = Fq6Config; type G1Parameters = self::g1::Parameters; type G2Parameters = self::g2::Parameters; } -pub const FQ_ZERO: Fq = field_new!(Fq, "0"); -pub const FQ_ONE: Fq = field_new!(Fq, "1"); -pub const FR_ZERO: Fr = field_new!(Fr, "0"); -pub const FR_ONE: Fr = field_new!(Fr, "1"); +pub const FQ_ZERO: Fq = MontFp!(Fq, "0"); +pub const FQ_ONE: Fq = MontFp!(Fq, "1"); +pub const FR_ZERO: Fr = MontFp!(Fr, "0"); +pub const FR_ONE: Fr = MontFp!(Fr, "1"); diff --git a/mnt6_753/src/curves/tests.rs b/mnt6_753/src/curves/tests.rs index 8f2e5bd..97a0916 100644 --- a/mnt6_753/src/curves/tests.rs +++ b/mnt6_753/src/curves/tests.rs @@ -1,16 +1,14 @@ -use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{Field, One, PrimeField, UniformRand}; -use ark_std::{rand::Rng, test_rng}; - -use crate::*; - use ark_algebra_test_templates::{ curves::*, generate_bilinearity_test, generate_g1_test, generate_g2_test, generate_product_of_pairings_test, groups::*, msm::*, }; - +use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; +use ark_ff::{Field, One, PrimeField, UniformRand}; +use ark_std::{rand::Rng, test_rng}; use core::ops::MulAssign; +use crate::*; + generate_g1_test!(mnt6_753; curve_tests; sw_tests;); generate_g2_test!(mnt6_753; curve_tests; sw_tests;); generate_bilinearity_test!(MNT6_753, Fq6); diff --git a/mnt6_753/src/fields/fq.rs b/mnt6_753/src/fields/fq.rs index 33f3df1..05302cd 100644 --- a/mnt6_753/src/fields/fq.rs +++ b/mnt6_753/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_mnt4_753::{Fr as Fq, FrParameters as FqParameters}; +pub use ark_mnt4_753::{Fr as Fq, FrConfig as FqConfig}; diff --git a/mnt6_753/src/fields/fq3.rs b/mnt6_753/src/fields/fq3.rs index 7235b3b..308f1fa 100644 --- a/mnt6_753/src/fields/fq3.rs +++ b/mnt6_753/src/fields/fq3.rs @@ -1,23 +1,23 @@ -use crate::{fq::Fq, FQ_ONE, FQ_ZERO}; use ark_ff::{ - field_new, - fields::fp3::{Fp3, Fp3Parameters}, + fields::fp3::{Fp3, Fp3Config}, + CubicExt, MontFp, }; -pub type Fq3 = Fp3; +use crate::{fq::Fq, FQ_ONE, FQ_ZERO}; + +pub type Fq3 = Fp3; -pub struct Fq3Parameters; +pub struct Fq3Config; -impl Fp3Parameters for Fq3Parameters { +impl Fp3Config for Fq3Config { type Fp = Fq; - #[rustfmt::skip] - const NONRESIDUE: Fq = field_new!(Fq, "11"); + const NONRESIDUE: Fq = MontFp!(Fq, "11"); const TWO_ADICITY: u32 = 30; #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[ + const TRACE_MINUS_ONE_DIV_TWO: &'static [u64] = &[ 15439605736802142541, 18190868848461853149, 6220121510046940818, @@ -56,9 +56,8 @@ impl Fp3Parameters for Fq3Parameters { ]; /// (11^T, 0, 0) - #[rustfmt::skip] - const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = ( - field_new!(Fq, "22168644070733283197994897338612733221095941481265408161807376791727499343083607817089033595478370212662133368413166734396127674284827734481031659015434501966360165723728649019457855887066657739809176476252080335185730833468062"), + const QUADRATIC_NONRESIDUE_TO_T: Fq3 = CubicExt!( + MontFp!(Fq, "22168644070733283197994897338612733221095941481265408161807376791727499343083607817089033595478370212662133368413166734396127674284827734481031659015434501966360165723728649019457855887066657739809176476252080335185730833468062"), FQ_ZERO, FQ_ZERO, ); @@ -67,15 +66,13 @@ impl Fp3Parameters for Fq3Parameters { // c1[0] = 1, // c1[1] = 24129022407817241407134263419936114379815707076943508280977368156625538709102831814843582780138963119807143081677569721953561801075623741378629346409604471234573396989178424163772589090105392407118197799904755622897541183052132 // c1[2] = 17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107868, - #[rustfmt::skip] const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[ FQ_ONE, - field_new!(Fq, "24129022407817241407134263419936114379815707076943508280977368156625538709102831814843582780138963119807143081677569721953561801075623741378629346409604471234573396989178424163772589090105392407118197799904755622897541183052132"), - field_new!(Fq, "17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107868"), + MontFp!(Fq, "24129022407817241407134263419936114379815707076943508280977368156625538709102831814843582780138963119807143081677569721953561801075623741378629346409604471234573396989178424163772589090105392407118197799904755622897541183052132"), + MontFp!(Fq, "17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107868"), ]; // c2 = {c1[0], c1[2], c1[1]} - #[rustfmt::skip] const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[ FQ_ONE, Self::FROBENIUS_COEFF_FP3_C1[2], diff --git a/mnt6_753/src/fields/fq6.rs b/mnt6_753/src/fields/fq6.rs index d5c872b..72ea558 100644 --- a/mnt6_753/src/fields/fq6.rs +++ b/mnt6_753/src/fields/fq6.rs @@ -1,18 +1,18 @@ -use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO}; use ark_ff::{ - field_new, - fields::fp6_2over3::{Fp6, Fp6Parameters}, + fields::fp6_2over3::{Fp6, Fp6Config}, + CubicExt, MontFp, }; -pub type Fq6 = Fp6; +use crate::{Fq, Fq3, Fq3Config, FQ_ONE, FQ_ZERO}; -pub struct Fq6Parameters; +pub type Fq6 = Fp6; -impl Fp6Parameters for Fq6Parameters { - type Fp3Params = Fq3Parameters; +pub struct Fq6Config; - #[rustfmt::skip] - const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO); +impl Fp6Config for Fq6Config { + type Fp3Config = Fq3Config; + + const NONRESIDUE: Fq3 = CubicExt!(FQ_ZERO, FQ_ONE, FQ_ZERO); // Coefficients for the Frobenius automorphism. // c1[0] = 1, @@ -21,13 +21,12 @@ impl Fp6Parameters for Fq6Parameters { // c1[3] = 41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160000 // c1[4] = 17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107868 // c1[5] = 17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107869 - #[rustfmt::skip] const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[ FQ_ONE, - field_new!(Fq, "24129022407817241407134263419936114379815707076943508280977368156625538709102831814843582780138963119807143081677569721953561801075623741378629346409604471234573396989178424163772589090105392407118197799904755622897541183052133"), - field_new!(Fq, "24129022407817241407134263419936114379815707076943508280977368156625538709102831814843582780138963119807143081677569721953561801075623741378629346409604471234573396989178424163772589090105392407118197799904755622897541183052132"), - field_new!(Fq, "41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160000"), - field_new!(Fq, "17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107868"), - field_new!(Fq, "17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107869"), + MontFp!(Fq, "24129022407817241407134263419936114379815707076943508280977368156625538709102831814843582780138963119807143081677569721953561801075623741378629346409604471234573396989178424163772589090105392407118197799904755622897541183052133"), + MontFp!(Fq, "24129022407817241407134263419936114379815707076943508280977368156625538709102831814843582780138963119807143081677569721953561801075623741378629346409604471234573396989178424163772589090105392407118197799904755622897541183052132"), + MontFp!(Fq, "41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160000"), + MontFp!(Fq, "17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107868"), + MontFp!(Fq, "17769468560101711995209951371304522748355002843010440790806134764399814103468274958215310983651375801610927890210888755369611256415970113691066895445191924931148019336171640277697829047741006062493737919155152541323243293107869"), ]; } diff --git a/mnt6_753/src/fields/fr.rs b/mnt6_753/src/fields/fr.rs index 5f91ca2..2820ca1 100644 --- a/mnt6_753/src/fields/fr.rs +++ b/mnt6_753/src/fields/fr.rs @@ -1 +1 @@ -pub use ark_mnt4_753::{Fq as Fr, FqParameters as FrParameters}; +pub use ark_mnt4_753::{Fq as Fr, FqConfig as FrConfig}; diff --git a/mnt6_753/src/fields/mod.rs b/mnt6_753/src/fields/mod.rs index f394204..7bfd333 100644 --- a/mnt6_753/src/fields/mod.rs +++ b/mnt6_753/src/fields/mod.rs @@ -10,5 +10,5 @@ pub use self::fq3::*; pub mod fq6; pub use self::fq6::*; -#[cfg(all(feature = "mnt6_753", test))] +#[cfg(test)] mod tests; diff --git a/mnt6_753/src/fields/tests.rs b/mnt6_753/src/fields/tests.rs index 4298950..3cf0167 100644 --- a/mnt6_753/src/fields/tests.rs +++ b/mnt6_753/src/fields/tests.rs @@ -1,19 +1,21 @@ +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; use ark_ff::{ - fields::{models::fp6_2over3::*, quadratic_extension::QuadExtParameters}, - Field, + fields::{models::fp6_2over3::*, quadratic_extension::QuadExtConfig, SquareRootField}, + Field, PrimeField, }; -use ark_std::{rand::Rng, test_rng}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng, One, UniformRand, Zero}; +use core::ops::{AddAssign, MulAssign, SubAssign}; use crate::*; -use ark_algebra_test_templates::{fields::*, generate_field_test}; - -use core::ops::{AddAssign, MulAssign, SubAssign}; - -generate_field_test!(mnt6_753;); +generate_field_test!(mnt6_753; fq3; fq6; mont(12, 12); ); +generate_field_serialization_test!(mnt6_753;); #[test] -fn test_fq3() { +fn test_fq3_more() { let mut rng = test_rng(); let a: Fq3 = rng.gen(); let b: Fq3 = rng.gen(); @@ -21,16 +23,7 @@ fn test_fq3() { sqrt_field_test(a); frobenius_test::(Fq::characteristic(), 13); assert_eq!( - a * Fq6Parameters::NONRESIDUE, - >::mul_base_field_by_nonresidue(&a) + a * Fq6Config::NONRESIDUE, + >::mul_base_field_by_nonresidue(&a) ); } - -#[test] -fn test_fq6() { - let mut rng = test_rng(); - let a: Fq6 = rng.gen(); - let b: Fq6 = rng.gen(); - field_test(a, b); - frobenius_test::(Fq::characteristic(), 13); -} diff --git a/mnt6_753/src/lib.rs b/mnt6_753/src/lib.rs index 0555999..e0d9c6e 100644 --- a/mnt6_753/src/lib.rs +++ b/mnt6_753/src/lib.rs @@ -10,9 +10,10 @@ //! This library implements the MNT6_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 6, 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 MNT4_753. +//! Miyaji--Nakabayashi--Takano curve of embedding degree 6, 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 +//! MNT4_753. //! //! Curve information: //! * Base field: q = 0x01C4C62D92C41110229022EEE2CDADB7F997505B8FAFED5EB7E8F96C97D87307FDB925E8A0ED8D99D124D9A15AF79DB26C5C28C859A99B3EEBCA9429212636B9DFF97634993AA4D6C381BC3F0057974EA099170FA13A4FD90776E240000001 @@ -25,7 +26,8 @@ //! * G2 curve equation: y^2 = x^3 + Ax + B, where //! * A = Fq3(0, 0, a) //! * B = Fq3(b * NON_RESIDUE, 0, 0) -//! * NON_RESIDUE = 11 is the cubic non-residue used to construct the extension field Fq3 +//! * NON_RESIDUE = 11 is the cubic non-residue used to construct the +//! extension field Fq3 #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/pallas/scripts/base_field.sage b/pallas/scripts/base_field.sage new file mode 100644 index 0000000..3aea849 --- /dev/null +++ b/pallas/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 28948022309329048855892746252171976963363056481941560715954676764349967630337 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/pallas/scripts/scalar_field.sage b/pallas/scripts/scalar_field.sage new file mode 100644 index 0000000..f3c8c60 --- /dev/null +++ b/pallas/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 28948022309329048855892746252171976963363056481941647379679742748393362948097 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/pallas/src/constraints/curves.rs b/pallas/src/constraints/curves.rs index 4f839b1..8fa5bdf 100644 --- a/pallas/src/constraints/curves.rs +++ b/pallas/src/constraints/curves.rs @@ -1,7 +1,6 @@ -use crate::*; use ark_r1cs_std::groups::curves::short_weierstrass::ProjectiveVar; -use crate::constraints::FBaseVar; +use crate::{constraints::FBaseVar, *}; /// A group element in the Pallas prime-order group. pub type GVar = ProjectiveVar; diff --git a/pallas/src/constraints/fields.rs b/pallas/src/constraints/fields.rs index e2f08b0..6956735 100644 --- a/pallas/src/constraints/fields.rs +++ b/pallas/src/constraints/fields.rs @@ -1,6 +1,7 @@ -use crate::fq::Fq; use ark_r1cs_std::fields::fp::FpVar; +use crate::fq::Fq; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FBaseVar = FpVar; diff --git a/pallas/src/curves/mod.rs b/pallas/src/curves/mod.rs index 213e7c8..bb2c61a 100644 --- a/pallas/src/curves/mod.rs +++ b/pallas/src/curves/mod.rs @@ -1,9 +1,10 @@ -use crate::{fq::Fq, fr::Fr}; use ark_ec::{ models::{ModelParameters, SWModelParameters}, short_weierstrass_jacobian::{GroupAffine, GroupProjective}, }; -use ark_ff::{field_new, Zero}; +use ark_ff::{MontFp, Zero}; + +use crate::{fq::Fq, fr::Fr}; #[cfg(test)] mod tests; @@ -19,7 +20,7 @@ impl ModelParameters for PallasParameters { const COFACTOR: &'static [u64] = &[0x1]; /// COFACTOR_INV = 1 - const COFACTOR_INV: Fr = field_new!(Fr, "1"); + const COFACTOR_INV: Fr = MontFp!(Fr, "1"); } pub type Affine = GroupAffine; @@ -27,10 +28,10 @@ pub type Projective = GroupProjective; impl SWModelParameters for PallasParameters { /// COEFF_A = 0 - const COEFF_A: Fq = field_new!(Fq, "0"); + const COEFF_A: Fq = MontFp!(Fq, "0"); /// COEFF_B = 5 - const COEFF_B: Fq = field_new!(Fq, "5"); + const COEFF_B: Fq = MontFp!(Fq, "5"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -43,7 +44,7 @@ impl SWModelParameters for PallasParameters { } /// G_GENERATOR_X = -1 -pub const G_GENERATOR_X: Fq = field_new!(Fq, "-1"); +pub const G_GENERATOR_X: Fq = MontFp!(Fq, "-1"); /// G_GENERATOR_Y = 2 -pub const G_GENERATOR_Y: Fq = field_new!(Fq, "2"); +pub const G_GENERATOR_Y: Fq = MontFp!(Fq, "2"); diff --git a/pallas/src/curves/tests.rs b/pallas/src/curves/tests.rs old mode 100644 new mode 100755 index ec59e77..f99a052 --- a/pallas/src/curves/tests.rs +++ b/pallas/src/curves/tests.rs @@ -1,21 +1,11 @@ -#![allow(unused_imports)] -use ark_ff::{ - fields::{Field, FpParameters, PrimeField, SquareRootField}, - One, Zero, -}; -use ark_serialize::CanonicalSerialize; -use ark_std::test_rng; - -use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_std::ops::{AddAssign, MulAssign}; -use ark_std::rand::Rng; - -use crate::{Affine, PallasParameters, Projective}; - use ark_algebra_test_templates::{ curves::{curve_tests, sw_tests}, groups::group_test, }; +use ark_ec::AffineCurve; +use ark_std::{rand::Rng, test_rng}; + +use crate::{Affine, PallasParameters, Projective}; #[test] fn test_projective_curve() { diff --git a/pallas/src/fields/fq.rs b/pallas/src/fields/fq.rs index 57203b5..5ddecd3 100644 --- a/pallas/src/fields/fq.rs +++ b/pallas/src/fields/fq.rs @@ -1,89 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - fields::{FftParameters, Fp256, Fp256Parameters}, -}; -pub type Fq = Fp256; +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; -pub struct FqParameters; - -impl Fp256Parameters for FqParameters {} -impl FftParameters for FqParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 32; - - // TWO_ADIC_ROOT_OF_UNITY = GENERATOR^T - // Encoded in Montgomery form, so the value here is (5^T)R mod p. - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 0xa28db849bad6dbf0, - 0x9083cd03d3b539df, - 0xfba6b9ca9dc8448e, - 0x3ec928747b89c6da, - ]); -} - -impl ark_ff::fields::FpParameters for FqParameters { - // 28948022309329048855892746252171976963363056481941560715954676764349967630337 - const MODULUS: BigInteger = BigInt::new([ - 0x992d30ed00000001, - 0x224698fc094cf91b, - 0x0000000000000000, - 0x4000000000000000, - ]); - - // R = 2^256 mod p - const R: BigInteger = BigInt::new([ - 0x34786d38fffffffd, - 0x992c350be41914ad, - 0xffffffffffffffff, - 0x3fffffffffffffff, - ]); - - // R2 = (2^256)^2 mod p - const R2: BigInteger = BigInt::new([ - 0x8c78ecb30000000f, - 0xd7d30dbd8b0de0e7, - 0x7797a99bc3c95d18, - 0x096d41af7b9cb714, - ]); - - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xcc96987680000000, - 0x11234c7e04a67c8d, - 0x0000000000000000, - 0x2000000000000000, - ]); - - // T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T - const T: BigInteger = BigInt::new([ - 0x094cf91b992d30ed, - 0x00000000224698fc, - 0x0000000000000000, - 0x0000000040000000, - ]); - - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x04a67c8dcc969876, - 0x0000000011234c7e, - 0x0000000000000000, - 0x0000000020000000, - ]); - - // GENERATOR = 5 - // Encoded in Montgomery form, so the value here is 5R mod p. - const GENERATOR: BigInteger = BigInt::new([ - 0xa1a55e68ffffffed, - 0x74c2a54b4f4982f3, - 0xfffffffffffffffd, - 0x3fffffffffffffff, - ]); - - const MODULUS_BITS: u32 = 255; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 1; - - // INV = -p^{-1} (mod 2^64) - const INV: u64 = 11037532056220336127; -} +#[derive(MontConfig)] +#[modulus = "28948022309329048855892746252171976963363056481941560715954676764349967630337"] +#[generator = "5"] +pub struct FqConfig; +pub type Fq = Fp256>; diff --git a/pallas/src/fields/fr.rs b/pallas/src/fields/fr.rs index 9561c42..88783b3 100644 --- a/pallas/src/fields/fr.rs +++ b/pallas/src/fields/fr.rs @@ -1,91 +1,7 @@ -use ark_ff::{ - biginteger::{BigInt, BigInteger256 as BigInteger}, - fields::{FftParameters, Fp256, Fp256Parameters, FpParameters}, -}; +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; -pub struct FrParameters; - -pub type Fr = Fp256; - -impl Fp256Parameters for FrParameters {} -impl FftParameters for FrParameters { - type BigInt = BigInteger; - - const TWO_ADICITY: u32 = 32; - - // TWO_ADIC_ROOT_OF_UNITY = GENERATOR^T - // Encoded in Montgomery form, so the value here is (5^T)R mod q. - const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInt::new([ - 0x218077428c9942de, - 0xcc49578921b60494, - 0xac2e5d27b2efbee2, - 0x0b79fa897f2db056, - ]); -} - -impl FpParameters for FrParameters { - // 28948022309329048855892746252171976963363056481941647379679742748393362948097 - const MODULUS: BigInteger = BigInt::new([ - 0x8c46eb2100000001, - 0x224698fc0994a8dd, - 0x0000000000000000, - 0x4000000000000000, - ]); - - // R = 2^256 mod q - const R: BigInteger = BigInt::new([ - 0x5b2b3e9cfffffffd, - 0x992c350be3420567, - 0xffffffffffffffff, - 0x3fffffffffffffff, - ]); - - // R2 = (2^256)^2 mod q - const R2: BigInteger = BigInt::new([ - 0xfc9678ff0000000f, - 0x67bb433d891a16e3, - 0x7fae231004ccf590, - 0x096d41af7ccfdaa9, - ]); - - const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0xc623759080000000, - 0x11234c7e04ca546e, - 0x0000000000000000, - 0x2000000000000000, - ]); - - // T and T_MINUS_ONE_DIV_TWO, where MODULUS - 1 = 2^S * T - - const T: BigInteger = BigInt::new([ - 0x0994a8dd8c46eb21, - 0x00000000224698fc, - 0x0000000000000000, - 0x0000000040000000, - ]); - - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInt::new([ - 0x04ca546ec6237590, - 0x0000000011234c7e, - 0x0000000000000000, - 0x0000000020000000, - ]); - - // GENERATOR = 5 - // Encoded in Montgomery form, so the value here is 5R mod q. - const GENERATOR: BigInteger = BigInt::new([ - 0x96bc8c8cffffffed, - 0x74c2a54b49f7778e, - 0xfffffffffffffffd, - 0x3fffffffffffffff, - ]); - - const MODULUS_BITS: u32 = 255; - - const CAPACITY: u32 = Self::MODULUS_BITS - 1; - - const REPR_SHAVE_BITS: u32 = 1; - - // INV = -q^{-1} (mod 2^64) - const INV: u64 = 10108024940646105087; -} +#[derive(MontConfig)] +#[modulus = "28948022309329048855892746252171976963363056481941647379679742748393362948097"] +#[generator = "5"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/pallas/src/fields/tests.rs b/pallas/src/fields/tests.rs index 26807e2..90ec6e4 100644 --- a/pallas/src/fields/tests.rs +++ b/pallas/src/fields/tests.rs @@ -1,26 +1,12 @@ -use ark_std::rand::Rng; -use ark_std::test_rng; - -use crate::*; - -use ark_algebra_test_templates::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::(); -} - -#[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::(); -} +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; +use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; + +use crate::{Fq, FqConfig, Fr, FrConfig}; + +generate_field_test!(pallas; mont(4, 4); ); +generate_field_serialization_test!(pallas;); diff --git a/rustfmt.toml b/rustfmt.toml index 7171213..6a424ff 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -6,4 +6,4 @@ match_block_trailing_comma = true use_field_init_shorthand = true edition = "2018" condense_wildcard_suffixes = true -merge_imports = true +imports_granularity="Crate" diff --git a/vesta/scripts/base_field.sage b/vesta/scripts/base_field.sage new file mode 100644 index 0000000..f3c8c60 --- /dev/null +++ b/vesta/scripts/base_field.sage @@ -0,0 +1,28 @@ +modulus = 28948022309329048855892746252171976963363056481941647379679742748393362948097 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/vesta/scripts/scalar_field.sage b/vesta/scripts/scalar_field.sage new file mode 100644 index 0000000..3aea849 --- /dev/null +++ b/vesta/scripts/scalar_field.sage @@ -0,0 +1,28 @@ +modulus = 28948022309329048855892746252171976963363056481941560715954676764349967630337 + +assert(modulus.is_prime()) + +Fp = GF(modulus) + +generator = Fp(0); +for i in range(0, 20): + i = Fp(i); + neg_i = Fp(-i) + if not(i.is_primitive_root() or neg_i.is_primitive_root()): + continue + elif i.is_primitive_root(): + assert(i.is_primitive_root()); + print("Generator: %d" % i) + generator = i + break + else: + assert(neg_i.is_primitive_root()); + print("Generator: %d" % neg_i) + generator = neg_i + break + + +two_adicity = valuation(modulus - 1, 2); +trace = (modulus - 1) / 2**two_adicity; +two_adic_root_of_unity = generator^trace +print("2-adic Root of Unity: %d " % two_adic_root_of_unity) diff --git a/vesta/src/constraints/curves.rs b/vesta/src/constraints/curves.rs index fac522a..b959458 100644 --- a/vesta/src/constraints/curves.rs +++ b/vesta/src/constraints/curves.rs @@ -1,7 +1,6 @@ -use crate::*; use ark_r1cs_std::groups::curves::short_weierstrass::ProjectiveVar; -use crate::constraints::FBaseVar; +use crate::{constraints::FBaseVar, *}; /// A group element in the Vesta prime-order group. pub type GVar = ProjectiveVar; diff --git a/vesta/src/constraints/fields.rs b/vesta/src/constraints/fields.rs index e2f08b0..6956735 100644 --- a/vesta/src/constraints/fields.rs +++ b/vesta/src/constraints/fields.rs @@ -1,6 +1,7 @@ -use crate::fq::Fq; use ark_r1cs_std::fields::fp::FpVar; +use crate::fq::Fq; + /// A variable that is the R1CS equivalent of `crate::Fq`. pub type FBaseVar = FpVar; diff --git a/vesta/src/curves/mod.rs b/vesta/src/curves/mod.rs index d92e74f..1c0f229 100644 --- a/vesta/src/curves/mod.rs +++ b/vesta/src/curves/mod.rs @@ -3,7 +3,7 @@ use ark_ec::{ models::{ModelParameters, SWModelParameters}, short_weierstrass_jacobian::{GroupAffine, GroupProjective}, }; -use ark_ff::{field_new, Zero}; +use ark_ff::{MontFp, Zero}; #[cfg(test)] mod tests; @@ -19,7 +19,7 @@ impl ModelParameters for VestaParameters { const COFACTOR: &'static [u64] = &[0x1]; /// COFACTOR_INV = 1 - const COFACTOR_INV: Fr = field_new!(Fr, "1"); + const COFACTOR_INV: Fr = MontFp!(Fr, "1"); } pub type Affine = GroupAffine; @@ -27,10 +27,10 @@ pub type Projective = GroupProjective; impl SWModelParameters for VestaParameters { /// COEFF_A = 0 - const COEFF_A: Fq = field_new!(Fq, "0"); + const COEFF_A: Fq = MontFp!(Fq, "0"); /// COEFF_B = 5 - const COEFF_B: Fq = field_new!(Fq, "5"); + const COEFF_B: Fq = MontFp!(Fq, "5"); /// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = @@ -44,8 +44,8 @@ impl SWModelParameters for VestaParameters { /// G_GENERATOR_X = -1 /// Encoded in Montgomery form, so the value here is -R mod p. -pub const G_GENERATOR_X: Fq = field_new!(Fq, "-1"); +pub const G_GENERATOR_X: Fq = MontFp!(Fq, "-1"); /// G_GENERATOR_Y = 2 /// Encoded in Montgomery form, so the value here is 2R mod p. -pub const G_GENERATOR_Y: Fq = field_new!(Fq, "2"); +pub const G_GENERATOR_Y: Fq = MontFp!(Fq, "2"); diff --git a/vesta/src/curves/tests.rs b/vesta/src/curves/tests.rs old mode 100644 new mode 100755 index 7522a79..d632dd7 --- a/vesta/src/curves/tests.rs +++ b/vesta/src/curves/tests.rs @@ -1,21 +1,11 @@ -#![allow(unused_imports)] -use ark_ff::{ - fields::{Field, FpParameters, PrimeField, SquareRootField}, - One, Zero, -}; -use ark_serialize::CanonicalSerialize; -use ark_std::test_rng; - -use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_std::ops::{AddAssign, MulAssign}; -use ark_std::rand::Rng; - -use crate::{Affine, Projective, VestaParameters}; - use ark_algebra_test_templates::{ curves::{curve_tests, sw_tests}, groups::group_test, }; +use ark_ec::AffineCurve; +use ark_std::{rand::Rng, test_rng}; + +use crate::{Affine, Projective, VestaParameters}; #[test] fn test_projective_curve() { diff --git a/vesta/src/fields/fq.rs b/vesta/src/fields/fq.rs index 1346b1a..b83eac8 100644 --- a/vesta/src/fields/fq.rs +++ b/vesta/src/fields/fq.rs @@ -1 +1 @@ -pub use ark_pallas::{Fr as Fq, FrParameters as FqParameters}; +pub use ark_pallas::{Fr as Fq, FrConfig as FqConfig}; diff --git a/vesta/src/fields/fr.rs b/vesta/src/fields/fr.rs index b8207ec..4d6d439 100644 --- a/vesta/src/fields/fr.rs +++ b/vesta/src/fields/fr.rs @@ -1 +1 @@ -pub use ark_pallas::{Fq as Fr, FqParameters as FrParameters}; +pub use ark_pallas::{Fq as Fr, FqConfig as FrConfig}; diff --git a/vesta/src/fields/tests.rs b/vesta/src/fields/tests.rs index 26807e2..c572b2d 100644 --- a/vesta/src/fields/tests.rs +++ b/vesta/src/fields/tests.rs @@ -1,26 +1,12 @@ -use ark_std::rand::Rng; -use ark_std::test_rng; - -use crate::*; - -use ark_algebra_test_templates::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::(); -} - -#[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::(); -} +use ark_algebra_test_templates::{ + fields::*, generate_field_serialization_test, generate_field_test, +}; +use ark_ff::{Field, One, PrimeField, SquareRootField, UniformRand, Zero}; +use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; +use ark_std::{rand::Rng, test_rng}; +use core::ops::{AddAssign, MulAssign, SubAssign}; + +use crate::{Fq, FqConfig, Fr, FrConfig}; + +generate_field_test!(vesta; mont(4, 4); ); +generate_field_serialization_test!(vesta;);