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

View File

@@ -0,0 +1,139 @@
use ark_ec::{
models::{ModelParameters, MontgomeryModelParameters, TEModelParameters},
twisted_edwards_extended::{GroupAffine, GroupProjective},
};
use ark_ff::{biginteger::BigInteger320, field_new};
use crate::{fq::Fq, fr::Fr};
#[cfg(test)]
mod tests;
pub type EdwardsAffine = GroupAffine<EdwardsParameters>;
pub type EdwardsProjective = GroupProjective<EdwardsParameters>;
#[derive(Clone, Default, PartialEq, Eq)]
pub struct EdwardsParameters;
impl ModelParameters for EdwardsParameters {
type BaseField = Fq;
type ScalarField = Fr;
}
// Many parameters need to be written down in the Montgomery residue form,
// discussed below. Some useful numbers:
// R for Fq: 223364648326281414938801705359223029554923725549792420683051274872200260503540791531766876
// R for Fr: 104384076783966083500464392945960916666734135485183910065100558776489954102951241798239545
impl TEModelParameters for EdwardsParameters {
/// COEFF_A = -1
/// 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, BigInteger320([
17882590928154426277u64,
6901912683734848330u64,
364575608937879866u64,
8740893163049517815u64,
2181130330288u64,
]));
/// 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, BigInteger320([
8040159930071495160u64,
16503302848883893212u64,
4541498709509651666u64,
11429056610118256373u64,
3363453258354u64,
]));
/// COFACTOR = 4
const COFACTOR: &'static [u64] = &[4];
/// COFACTOR_INV (mod r) =
/// 29745142885578832859584328103315528221570304936126890280067991221921526670592508030983158
/// Needs to be in the Montgomery residue form in Fr
/// I.e., 29745142885578832859584328103315528221570304936126890280067991221921526670592508030983158 * R for Fr
/// = 55841162081570353734700426339805757388253838807422867796343130916044015196330318480543044
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger320([
6539529304383425860u64,
7567022062893857598u64,
17399624368177871129u64,
14575354999847441509u64,
482253688048u64,
]));
/// Generated randomly
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y);
type MontgomeryModelParameters = EdwardsParameters;
/// Multiplication by `a` is just negation.
#[inline(always)]
fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
-*elem
}
}
impl MontgomeryModelParameters for EdwardsParameters {
/// COEFF_A = 203563247015667910991582090642011229452721346107806307863040223071914240315202967004285204
/// Needs to be in the Montgomery residue form in Fq
/// I.e., 203563247015667910991582090642011229452721346107806307863040223071914240315202967004285204 * R for Fq
/// = 184958108588233737086787169006685138672129232027042887479256778022373554352621152610883766
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, BigInteger320([
13866101745789245622u64,
14126297534943667090u64,
11307578615387704385u64,
8263080598809044705u64,
1597329401399u64,
]));
/// COEFF_B = 272359039153593414761767159011037222092403532445017207690227512667250406992205523555677931
/// Needs to be in the Montgomery residue form in Fq
// I.e., 272359039153593414761767159011037222092403532445017207690227512667250406992205523555677931 * R for Fq
// = 320157167097726084542307919580965705308273073979019302261176143711555219255114245445508756
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, BigInteger320([
3452336036810055316u64,
18124271906235581187u64,
7868316676197606962u64,
9218705727289990924u64,
2764931259177u64,
]));
type TEModelParameters = EdwardsParameters;
}
/// GENERATOR_X =
/// 282406820114868156776872298252698015906762052916420164316497572033519876761239463633892227
/// Needs to be in the Montgomery residue form in Fq
/// I.e., 282406820114868156776872298252698015906762052916420164316497572033519876761239463633892227 * R for Fq
/// = 6917556742108450905978293995070573074174231920036503115659104908111915200040057661385715
#[rustfmt::skip]
const GENERATOR_X: Fq = field_new!(Fq, BigInteger320([
797921980254612467u64,
14323677897559322103u64,
16879595040064082265u64,
5138786402348661261u64,
59741186014u64,
]));
/// GENERATOR_Y =
/// 452667754940241021433619311795265643711152068500301853535337412655162600774122192283142703
/// Needs to be in the Montgomery residue form in Fq
/// I.e., 452667754940241021433619311795265643711152068500301853535337412655162600774122192283142703 * R for Fq
/// = 411219337323952690830344109182130393590959634960952808951091963301565250764467583592890490
#[rustfmt::skip]
const GENERATOR_Y: Fq = field_new!(Fq, BigInteger320([
16522567711648317562u64,
4273808507945498262u64,
17459848913470201097u64,
16519670308098023011u64,
3551359510243u64,
]));

View File

@@ -0,0 +1,63 @@
use ark_ec::{AffineCurve, ProjectiveCurve};
use ark_ff::test_rng;
use rand::Rng;
use crate::*;
use ark_curve_tests::{curves::*, groups::*};
#[test]
fn test_projective_curve() {
curve_tests::<EdwardsProjective>();
edwards_tests::<EdwardsParameters>();
}
#[test]
fn test_projective_group() {
let mut rng = test_rng();
let a = rng.gen();
let b = rng.gen();
for _i in 0..100 {
group_test::<EdwardsProjective>(a, b);
}
}
#[test]
fn test_affine_group() {
let mut rng = test_rng();
let a: EdwardsAffine = rng.gen();
let b: EdwardsAffine = rng.gen();
for _i in 0..100 {
group_test::<EdwardsAffine>(a, b);
}
}
#[test]
fn test_generator() {
let generator = EdwardsAffine::prime_subgroup_generator();
assert!(generator.is_on_curve());
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
}
#[test]
fn test_conversion() {
let mut rng = test_rng();
let a: EdwardsAffine = rng.gen();
let b: EdwardsAffine = rng.gen();
let a_b = {
use ark_ec::group::Group;
(a + &b).double().double()
};
let a_b2 = (a.into_projective() + &b.into_projective())
.double()
.double();
assert_eq!(a_b, a_b2.into_affine());
assert_eq!(a_b.into_projective(), a_b2);
}
#[test]
fn test_montgomery_conversion() {
montgomery_conversion_test::<EdwardsParameters>();
}

View File

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

View File

@@ -0,0 +1,127 @@
use ark_ff::{
biginteger::BigInteger320 as BigInteger,
fields::{FftParameters, Fp320, Fp320Parameters, FpParameters},
};
pub type Fr = Fp320<FrParameters>;
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 = BigInteger([
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 = BigInteger([
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 = BigInteger([
10622549565806069049u64,
15275253213246312896u64,
1379181597548482487u64,
4647353561360841844u64,
901478481574u64
]);
// R2 = R * R %
// 118980571542315331438337312413262112886281219744507561120271964887686106682370032123932631
// R2 = 64940318866745953005690402896764745514897573584912026577721076893188083397226247459368768
#[rustfmt::skip]
const R2: BigInteger = BigInteger([
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 = BigInteger([
18037929197695780229u64,
16969762262749485294u64,
6166745553471500787u64,
5754981480705173590u64,
145131747294u64,
]);
// (n-1)/2 = 59490285771157665719168656206631056443140609872253780560135982443843053341185016061966315
#[rustfmt::skip]
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
7767783825863817195u64,
16719789556019334556u64,
15662913863871949398u64,
8380289145304910481u64,
513768135310u64,
]);
// t = (n - 1) / 2^{TWO_ADICITY} =
// 59490285771157665719168656206631056443140609872253780560135982443843053341185016061966315
const T: BigInteger = BigInteger([
7767783825863817195u64,
16719789556019334556u64,
15662913863871949398u64,
8380289145304910481u64,
513768135310u64,
]);
// (t-1)/2 = 29745142885578832859584328103315528221570304936126890280067991221921526670592508030983157
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
3883891912931908597u64,
8359894778009667278u64,
17054828968790750507u64,
4190144572652455240u64,
256884067655u64,
]);
}

View File

@@ -0,0 +1,8 @@
pub mod fq;
pub mod fr;
pub use fq::*;
pub use fr::*;
#[cfg(all(feature = "ed_on_mnt4_298", test))]
mod tests;

View File

@@ -0,0 +1,24 @@
use ark_ff::test_rng;
use rand::Rng;
use crate::fields::*;
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);
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);
primefield_test::<Fq>();
}

28
ed_on_mnt4_298/src/lib.rs Normal file
View File

@@ -0,0 +1,28 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(
warnings,
unused,
future_incompatible,
nonstandard_style,
rust_2018_idioms
)]
#![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.
//!
//! Curve information:
//! * 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
//! * a = -1
//! * d = 4212 mod q
mod curves;
mod fields;
pub use curves::*;
pub use fields::*;

View File

@@ -0,0 +1,5 @@
mod curves;
mod fields;
pub use curves::*;
pub use fields::*;