Initial commit

This commit is contained in:
Pratyush Mishra
2020-10-11 19:50:41 -07:00
commit 43ca2132fd
209 changed files with 18825 additions and 0 deletions

29
mnt6_298/Cargo.toml Normal file
View File

@@ -0,0 +1,29 @@
[package]
name = "ark-mnt6-298"
version = "0.1.0"
authors = [ "arkworks contributors" ]
description = "The MNT6-298 pairing-friendly elliptic curve"
homepage = "https://arworks.rs"
repository = "https://github.com/arkworks/algebra"
documentation = "https://docs.rs/ark-mnt6-298/"
keywords = ["cryptography", "finite fields" ]
categories = ["cryptography"]
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
license = "MIT/Apache-2.0"
edition = "2018"
[dependencies]
ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false }
ark-mnt4-298 = { path = "../mnt4_298", default-features = false, features = [ "scalar_field", "base_field" ] }
[dev-dependencies]
ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
ark-curve-tests = { path = "../curve-tests", default-features = false }
rand = { version = "0.7", default-features = false }
rand_xorshift = "0.2"
[features]
default = []
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]

79
mnt6_298/src/curves/g1.rs Normal file
View File

@@ -0,0 +1,79 @@
use ark_ec::{
mnt6,
models::{ModelParameters, SWModelParameters},
};
use ark_ff::{biginteger::BigInteger320, field_new};
use crate::{Fq, Fr};
pub type G1Affine = mnt6::G1Affine<crate::Parameters>;
pub type G1Projective = mnt6::G1Projective<crate::Parameters>;
pub type G1Prepared = mnt6::G1Prepared<crate::Parameters>;
#[derive(Clone, Default, PartialEq, Eq)]
pub struct Parameters;
impl ModelParameters for Parameters {
type BaseField = Fq;
type ScalarField = Fr;
}
impl SWModelParameters for Parameters {
/// COEFF_A =
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, BigInteger320([
0xb9b2411bfd0eafef,
0xc61a10fadd9fecbd,
0x89f128e59811f3fb,
0x980c0f780adadabb,
0x9ba1f11320,
]));
/// COEFF_B =
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, BigInteger320([
0xa94cb16ed8e733b,
0xe1ed15e8119bae6,
0xae927592157c8121,
0x990dbcbc6661cf95,
0xecff0892ef,
]));
/// COFACTOR = 1
const COFACTOR: &'static [u64] = &[1];
/// COFACTOR^(-1) mod r =
/// 1
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger320([
1784298994435064924,
16852041090100268533,
14258261760832875328,
2961187778261111191,
1929014752195,
]));
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
(G1_GENERATOR_X, G1_GENERATOR_Y);
}
/// G1_GENERATOR_X =
#[rustfmt::skip]
pub const G1_GENERATOR_X: Fq = field_new!(Fq, BigInteger320([
0x1a663562f74e1d24,
0xc1d1d583fccd1b79,
0xda077538a9763df2,
0x70c4a4ea36aa01d9,
0x86537578a8,
]));
/// G1_GENERATOR_Y =
#[rustfmt::skip]
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, BigInteger320([
0x7ad5bfd16dcfffb2,
0x88dd739252215070,
0x43f137a8b517b339,
0x9a7fac709a8c463c,
0x3140fbc3593,
]));

159
mnt6_298/src/curves/g2.rs Normal file
View File

@@ -0,0 +1,159 @@
use ark_ec::{
mnt6,
mnt6::MNT6Parameters,
models::{ModelParameters, SWModelParameters},
};
use ark_ff::{biginteger::BigInteger320, field_new};
use crate::{g1, Fq, Fq3, Fr};
pub type G2Affine = mnt6::G2Affine<crate::Parameters>;
pub type G2Projective = mnt6::G2Projective<crate::Parameters>;
pub type G2Prepared = mnt6::G2Prepared<crate::Parameters>;
#[derive(Clone, Default, PartialEq, Eq)]
pub struct Parameters;
impl ModelParameters for Parameters {
type BaseField = Fq3;
type ScalarField = Fr;
}
/// MUL_BY_A_C0 = NONRESIDUE * COEFF_A
#[rustfmt::skip]
pub const MUL_BY_A_C0: Fq = field_new!(Fq, BigInteger320([
0xa07b458bf1496fab,
0xde8254e6541f9fb4,
0xb1b5cc7bf859c3ea,
0xf83c4d58364645a9,
0x30a29b55fa2,
]));
/// MUL_BY_A_C1 = NONRESIDUE * COEFF_A
#[rustfmt::skip]
pub const MUL_BY_A_C1: Fq = field_new!(Fq, BigInteger320([
0xa07b458bf1496fab,
0xde8254e6541f9fb4,
0xb1b5cc7bf859c3ea,
0xf83c4d58364645a9,
0x30a29b55fa2,
]));
/// 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,
field_new!(Fq, BigInteger320([
0x79a4c2cea3c84026,
0x4b50cad0f3233baa,
0x9ded82770e7a4410,
0x5ade8b105838b95d,
0xe4036e0a3a,
])),
field_new!(Fq, BigInteger320([0, 0, 0, 0, 0])),
field_new!(Fq, BigInteger320([0, 0, 0, 0, 0])),
);
/// COFACTOR =
/// 226502022472576270196498690498308461791828762732602586162207535351960270082712694977333372361549082214519252261735048131889018501404377856786623430385820659037970876666767495659520
#[rustfmt::skip]
const COFACTOR: &'static [u64] = &[
15308190245346869248,
10669098443577192943,
4561413759929581409,
3680089780298582849,
17336300687782721465,
10745756320947240891,
17479264233688728128,
16828697388537672097,
4184034152442024798,
915787,
];
/// COFACTOR^(-1) mod r =
/// 79320381028210220958891541608841408590854146655427655872973753568875979721417185067925504
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger320([
5837598184463018016,
7845868194417674836,
12170332588914158076,
6950611683754678431,
102280178745,
]));
/// AFFINE_GENERATOR_COEFFS = (G2_GENERATOR_X, G2_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
(G2_GENERATOR_X, G2_GENERATOR_Y);
#[inline(always)]
fn mul_by_a(elt: &Fq3) -> Fq3 {
field_new!(
Fq3,
MUL_BY_A_C0 * &elt.c1,
MUL_BY_A_C1 * &elt.c2,
MUL_BY_A_C2 * &elt.c0,
)
}
}
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);
#[rustfmt::skip]
pub const G2_GENERATOR_X_C0: Fq = field_new!(Fq, BigInteger320([
0x15ca12fc5d551ea7,
0x9e0b2b2b2bb8b979,
0xe6e66283ad5a786a,
0x46ba0aedcc383c07,
0x243853463ed,
]));
#[rustfmt::skip]
pub const G2_GENERATOR_X_C1: Fq = field_new!(Fq, BigInteger320([
0x2c0e3dd7be176130,
0x27a15d879495904b,
0x6f1f0d2dd1502a82,
0x9782ee3c70834da,
0x2c28bb71862,
]));
#[rustfmt::skip]
pub const G2_GENERATOR_X_C2: Fq = field_new!(Fq, BigInteger320([
0xf3e5f4eb9631e1f1,
0x657801e80c50778,
0x2d2abb128fee90f3,
0x72e58e4c3aa3598c,
0x100b8026b9d,
]));
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C0: Fq = field_new!(Fq, BigInteger320([
0xb1cddd6c64a67c5f,
0xa01e90d89aa5d2ba,
0x39e9a733be49ed1,
0x9438f46f63d3264f,
0x12cc928ef10,
]));
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C1: Fq = field_new!(Fq, BigInteger320([
0xa1529b7265ad4be7,
0x21c5e827cf309306,
0x9b3d647bd8c70b22,
0x42835bf373e4b213,
0xd3c77c9ff9,
]));
#[rustfmt::skip]
pub const G2_GENERATOR_Y_C2: Fq = field_new!(Fq, BigInteger320([
0x610557ec4b58b8df,
0x51a23865b52045f1,
0x9dcfd915a09da608,
0x6d65c95f69adb700,
0x2d3c3d195a1,
]));

View File

@@ -0,0 +1,51 @@
use ark_ff::{biginteger::BigInteger320, field_new, fields::FpParameters, Fp3};
use ark_ec::models::mnt6::{MNT6Parameters, MNT6};
use crate::{Fq, Fq3, Fq3Parameters, Fq6Parameters, FqParameters, Fr};
pub mod g1;
pub mod g2;
#[cfg(test)]
mod tests;
pub use self::{
g1::{G1Affine, G1Prepared, G1Projective},
g2::{G2Affine, G2Prepared, G2Projective},
};
pub type MNT6_298 = MNT6<Parameters>;
pub struct Parameters;
impl MNT6Parameters for Parameters {
const TWIST: Fp3<Self::Fp3Params> = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
#[rustfmt::skip]
const TWIST_COEFF_A: Fp3<Self::Fp3Params> = field_new!(Fq3,
FQ_ZERO,
FQ_ZERO,
field_new!(Fq, BigInteger320([
0xb9b2411bfd0eafef,
0xc61a10fadd9fecbd,
0x89f128e59811f3fb,
0x980c0f780adadabb,
0x9ba1f11320,
])),
);
const ATE_LOOP_COUNT: &'static [u64] = &[0xdc9a1b671660000, 0x46609756bec2a33f, 0x1eef55];
const ATE_IS_LOOP_COUNT_NEG: bool = true;
const FINAL_EXPONENT_LAST_CHUNK_1: BigInteger320 = BigInteger320([0x1, 0x0, 0x0, 0x0, 0x0]);
const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool = true;
const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: BigInteger320 =
BigInteger320([0xdc9a1b671660000, 0x46609756bec2a33f, 0x1eef55, 0x0, 0x0]);
type Fp = Fq;
type Fr = Fr;
type Fp3Params = Fq3Parameters;
type Fp6Params = Fq6Parameters;
type G1Parameters = self::g1::Parameters;
type G2Parameters = self::g2::Parameters;
}
pub const FQ_ZERO: Fq = field_new!(Fq, BigInteger320([0, 0, 0, 0, 0]));
pub const FQ_ONE: Fq = field_new!(Fq, FqParameters::R);

View File

@@ -0,0 +1,90 @@
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
use ark_ff::{test_rng, Field, One, PrimeField, UniformRand};
use rand::Rng;
use crate::*;
use ark_curve_tests::{curves::*, groups::*};
#[test]
fn test_g1_projective_curve() {
curve_tests::<G1Projective>();
sw_tests::<g1::Parameters>();
}
#[test]
fn test_g1_projective_group() {
let mut rng = test_rng();
let a: G1Projective = rng.gen();
let b: G1Projective = rng.gen();
group_test(a, b);
}
#[test]
fn test_g1_generator() {
let generator = G1Affine::prime_subgroup_generator();
assert!(generator.is_on_curve());
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
}
#[test]
fn test_g2_projective_curve() {
curve_tests::<G2Projective>();
sw_tests::<g2::Parameters>();
}
#[test]
fn test_g2_projective_group() {
let mut rng = test_rng();
let a: G2Projective = rng.gen();
let b: G2Projective = rng.gen();
group_test(a, b);
}
#[test]
fn test_g2_generator() {
let generator = G2Affine::prime_subgroup_generator();
assert!(generator.is_on_curve());
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
}
#[test]
fn test_bilinearity() {
let mut rng = test_rng();
let a: G1Projective = rng.gen();
let b: G2Projective = rng.gen();
let s: Fr = rng.gen();
let sa = a.mul(s);
let sb = b.mul(s);
let ans1 = MNT6_298::pairing(sa, b);
let ans2 = MNT6_298::pairing(a, sb);
let ans3 = MNT6_298::pairing(a, b).pow(s.into_repr());
assert_eq!(ans1, ans2);
assert_eq!(ans2, ans3);
assert_ne!(ans1, Fq6::one());
assert_ne!(ans2, Fq6::one());
assert_ne!(ans3, Fq6::one());
assert_eq!(ans1.pow(Fr::characteristic()), Fq6::one());
assert_eq!(ans2.pow(Fr::characteristic()), Fq6::one());
assert_eq!(ans3.pow(Fr::characteristic()), Fq6::one());
}
#[test]
fn test_product_of_pairings() {
let rng = &mut test_rng();
let a = G1Projective::rand(rng).into_affine();
let b = G2Projective::rand(rng).into_affine();
let c = G1Projective::rand(rng).into_affine();
let d = G2Projective::rand(rng).into_affine();
let ans1 = MNT6_298::pairing(a, b) * &MNT6_298::pairing(c, d);
let ans2 = MNT6_298::product_of_pairings(&[(a.into(), b.into()), (c.into(), d.into())]);
assert_eq!(ans1, ans2);
}

View File

@@ -0,0 +1 @@
pub use ark_mnt4_298::{Fr as Fq, FrParameters as FqParameters};

106
mnt6_298/src/fields/fq3.rs Normal file
View File

@@ -0,0 +1,106 @@
use crate::fq::Fq;
use ark_ff::{
biginteger::BigInteger320 as BigInteger,
field_new,
fields::fp3::{Fp3, Fp3Parameters},
};
pub type Fq3 = Fp3<Fq3Parameters>;
pub struct Fq3Parameters;
impl Fp3Parameters for Fq3Parameters {
type Fp = Fq;
#[rustfmt::skip]
const NONRESIDUE: Fq = field_new!(Fq, BigInteger([
0x58eefd67fea995ca,
0x12f14affbb33a004,
0x4780323da44ac69b,
0x88acf9bea707eed9,
0x14bbbb859e8,
]));
const TWO_ADICITY: u32 = 34;
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: &'static [u64] = &[
0x69232b75663933bd,
0xca650efcfc00ee0,
0x77ca3963fe36f720,
0xe4cb46632f9bcf7e,
0xef510453f08f9f30,
0x9dd5b8fc72f02d83,
0x7f8d017ed86608ab,
0xeb2219b3697c97a4,
0xc8663846ab96996f,
0x833cd532053eac7d,
0x1d5b73dfb20bd3cc,
0x6f5f6da606b59873,
0x62e990f43dfc42d6,
0x6878f58,
];
#[rustfmt::skip]
const QUADRATIC_NONRESIDUE_TO_T: (Fq, Fq, Fq) = (
field_new!(Fq, BigInteger([
0x44a4178610a3a4e6,
0x49321e4d00f35073,
0xbbc01b9c400c07a1,
0xd0127c4589095738,
0x3730de2a45d,
])),
field_new!(Fq, BigInteger([0, 0, 0, 0, 0])),
field_new!(Fq, BigInteger([0, 0, 0, 0, 0])),
);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP3_C1: &'static [Fq] = &[
field_new!(Fq, BigInteger([
0xc3177aefffbb845c,
0x9b80c702f9961788,
0xc5df8dcdac70a85a,
0x29184098647b5197,
0x1c1223d33c3,
])),
field_new!(Fq, BigInteger([
0x1c17bb7477085b6a,
0x2621629c22e83dbb,
0x21c062106d949dd8,
0x9d5b981062164ba,
0x84ad703207,
])),
field_new!(Fq, BigInteger([
0xdc13fe3f893c203b,
0x39a7226875df158f,
0xe34ed98542eefb62,
0x6f782a843d139e3c,
0x177280f6ea9,
])),
];
#[rustfmt::skip]
const FROBENIUS_COEFF_FP3_C2: &'static [Fq] = &[
field_new!(Fq, BigInteger([
0xc3177aefffbb845c,
0x9b80c702f9961788,
0xc5df8dcdac70a85a,
0x29184098647b5197,
0x1c1223d33c3,
])),
field_new!(Fq, BigInteger([
0xdc13fe3f893c203b,
0x39a7226875df158f,
0xe34ed98542eefb62,
0x6f782a843d139e3c,
0x177280f6ea9,
])),
field_new!(Fq, BigInteger([
0x1c17bb7477085b6a,
0x2621629c22e83dbb,
0x21c062106d949dd8,
0x9d5b981062164ba,
0x84ad703207,
])),
];
}

View File

@@ -0,0 +1,63 @@
use crate::{Fq, Fq3, Fq3Parameters, FQ_ONE, FQ_ZERO};
use ark_ff::{
biginteger::BigInteger320 as BigInteger,
field_new,
fields::fp6_2over3::{Fp6, Fp6Parameters},
};
pub type Fq6 = Fp6<Fq6Parameters>;
pub struct Fq6Parameters;
impl Fp6Parameters for Fq6Parameters {
type Fp3Params = Fq3Parameters;
#[rustfmt::skip]
const NONRESIDUE: Fq3 = field_new!(Fq3, FQ_ZERO, FQ_ONE, FQ_ZERO);
#[rustfmt::skip]
const FROBENIUS_COEFF_FP6_C1: &'static [Fq] = &[
field_new!(Fq, BigInteger([
0xc3177aefffbb845c,
0x9b80c702f9961788,
0xc5df8dcdac70a85a,
0x29184098647b5197,
0x1c1223d33c3,
])),
field_new!(Fq, BigInteger([
0xdf2f366476c3dfc6,
0xc1a2299f1c7e5543,
0xe79fefde1a054632,
0x32edfa196a9cb651,
0x245cfad65ca,
])),
field_new!(Fq, BigInteger([
0x1c17bb7477085b6a,
0x2621629c22e83dbb,
0x21c062106d949dd8,
0x9d5b981062164ba,
0x84ad703207,
])),
field_new!(Fq, BigInteger([
0xf82bb9b400447ba5,
0x5fc8850498c7534a,
0x50f3b95b083993a,
0x794de405433502f7,
0x1fbd57fa0b0,
])),
field_new!(Fq, BigInteger([
0xdc13fe3f893c203b,
0x39a7226875df158f,
0xe34ed98542eefb62,
0x6f782a843d139e3c,
0x177280f6ea9,
])),
field_new!(Fq, BigInteger([
0x9f2b792f88f7a497,
0xd527e96b6f752d18,
0xa92e6752ef5fa3bc,
0x98906b1ca18eefd4,
0x3384a4ca26c,
])),
];
}

View File

@@ -0,0 +1 @@
pub use ark_mnt4_298::{Fq as Fr, FqParameters as FrParameters};

View File

@@ -0,0 +1,14 @@
pub mod fr;
pub use self::fr::*;
pub mod fq;
pub use self::fq::*;
pub mod fq3;
pub use self::fq3::*;
pub mod fq6;
pub use self::fq6::*;
#[cfg(all(feature = "mnt6_298", test))]
mod tests;

View File

@@ -0,0 +1,52 @@
use ark_ff::{
fields::{models::fp6_2over3::*, quadratic_extension::QuadExtParameters},
test_rng, Field,
};
use rand::Rng;
use crate::*;
use ark_curve_tests::fields::*;
#[test]
fn test_fr() {
let mut rng = test_rng();
let a: Fr = rng.gen();
let b: Fr = rng.gen();
field_test(a, b);
sqrt_field_test(a);
primefield_test::<Fr>();
}
#[test]
fn test_fq() {
let mut rng = test_rng();
let a: Fq = rng.gen();
let b: Fq = rng.gen();
field_test(a, b);
sqrt_field_test(a);
primefield_test::<Fq>();
}
#[test]
fn test_fq3() {
let mut rng = test_rng();
let a: Fq3 = rng.gen();
let b: Fq3 = rng.gen();
field_test(a, b);
sqrt_field_test(a);
frobenius_test::<Fq3, _>(Fq::characteristic(), 13);
assert_eq!(
a * Fq6Parameters::NONRESIDUE,
<Fp6ParamsWrapper<Fq6Parameters>>::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::<Fq6, _>(Fq::characteristic(), 13);
}

35
mnt6_298/src/lib.rs Normal file
View File

@@ -0,0 +1,35 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(
warnings,
unused,
future_incompatible,
nonstandard_style,
rust_2018_idioms
)]
#![forbid(unsafe_code)]
//! 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.
//!
//!
//! Curve information:
//! * Scalar field: q = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137
//! * Base field: r = 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081
//! * valuation(q - 1, 2) = 34
//! * valuation(r - 1, 2) = 17
//! * G1 curve equation: y^2 = x^3 + ax + b, where
//! * a = 11
//! * b = 106700080510851735677967319632585352256454251201367587890185989362936000262606668469523074
//! * 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
mod curves;
mod fields;
pub use curves::*;
pub use fields::*;