mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-08 23:11:29 +01:00
Initial commit
This commit is contained in:
29
ed_on_mnt4_298/Cargo.toml
Normal file
29
ed_on_mnt4_298/Cargo.toml
Normal file
@@ -0,0 +1,29 @@
|
||||
[package]
|
||||
name = "ark-ed-on-mnt4-298"
|
||||
version = "0.1.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "A Twisted Edwards curve defined over the scalar field of the MNT4-298 curve"
|
||||
homepage = "https://arworks.rs"
|
||||
repository = "https://github.com/arkworks/algebra"
|
||||
documentation = "https://docs.rs/ark-ed-on-mnt4-298/"
|
||||
keywords = ["cryptography", "finite fields", "elliptic curves" ]
|
||||
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" ] }
|
||||
|
||||
[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", "ark-mnt4-298/std" ]
|
||||
139
ed_on_mnt4_298/src/curves/mod.rs
Normal file
139
ed_on_mnt4_298/src/curves/mod.rs
Normal 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,
|
||||
]));
|
||||
63
ed_on_mnt4_298/src/curves/tests.rs
Normal file
63
ed_on_mnt4_298/src/curves/tests.rs
Normal 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>();
|
||||
}
|
||||
1
ed_on_mnt4_298/src/fields/fq.rs
Normal file
1
ed_on_mnt4_298/src/fields/fq.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub use ark_mnt4_298::{Fr as Fq, FrParameters as FqParameters};
|
||||
127
ed_on_mnt4_298/src/fields/fr.rs
Normal file
127
ed_on_mnt4_298/src/fields/fr.rs
Normal 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,
|
||||
]);
|
||||
}
|
||||
8
ed_on_mnt4_298/src/fields/mod.rs
Normal file
8
ed_on_mnt4_298/src/fields/mod.rs
Normal 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;
|
||||
24
ed_on_mnt4_298/src/fields/tests.rs
Normal file
24
ed_on_mnt4_298/src/fields/tests.rs
Normal 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
28
ed_on_mnt4_298/src/lib.rs
Normal 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::*;
|
||||
5
ed_on_mnt4_298/src/mod.rs
Normal file
5
ed_on_mnt4_298/src/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
Reference in New Issue
Block a user