mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-11 08:21:33 +01:00
Initial commit
This commit is contained in:
108
ed_on_bn254/src/curves/mod.rs
Normal file
108
ed_on_bn254/src/curves/mod.rs
Normal file
@@ -0,0 +1,108 @@
|
||||
use crate::{Fq, Fr};
|
||||
use ark_ec::{
|
||||
models::{ModelParameters, MontgomeryModelParameters, TEModelParameters},
|
||||
twisted_edwards_extended::{GroupAffine, GroupProjective},
|
||||
};
|
||||
use ark_ff::{biginteger::BigInteger256, field_new};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub type EdwardsAffine = GroupAffine<EdwardsParameters>;
|
||||
pub type EdwardsProjective = GroupProjective<EdwardsParameters>;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const GENERATOR_X: Fq = field_new!(Fq, BigInteger256([
|
||||
0x3db6612c2863cc99,
|
||||
0x8a9e4521b36347dc,
|
||||
0x310a1a625c16a534,
|
||||
0x23ceae2710df4a14,
|
||||
]));
|
||||
#[rustfmt::skip]
|
||||
const GENERATOR_Y: Fq = field_new!(Fq, BigInteger256([
|
||||
0xb83342d20d0201aa,
|
||||
0x2ffef2f7cdcfeac7,
|
||||
0xbfa79a9425a6e625,
|
||||
0xdfb859dc3a44b70,
|
||||
]));
|
||||
|
||||
/// `Baby-JubJub` is a twisted Edwards curve. These curves have equations of the
|
||||
/// form: ax² + y² = 1 + dx²y².
|
||||
/// over some base finite field Fq.
|
||||
///
|
||||
/// Baby-JubJub's curve equation: x² + y² = 1 + (168696/168700)x²y²
|
||||
///
|
||||
/// q = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
///
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct EdwardsParameters;
|
||||
|
||||
impl ModelParameters for EdwardsParameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl TEModelParameters for EdwardsParameters {
|
||||
/// COEFF_A = 1
|
||||
#[rustfmt::skip]
|
||||
const COEFF_A: Fq = field_new!(Fq, BigInteger256([
|
||||
0xac96341c4ffffffb,
|
||||
0x36fc76959f60cd29,
|
||||
0x666ea36f7879462e,
|
||||
0xe0a77c19a07df2f,
|
||||
]));
|
||||
|
||||
#[inline(always)]
|
||||
fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
|
||||
*elem
|
||||
}
|
||||
|
||||
/// COEFF_D = 168696/168700 mod q
|
||||
/// = 9706598848417545097372247223557719406784115219466060233080913168975159366771
|
||||
#[rustfmt::skip]
|
||||
const COEFF_D: Fq = field_new!(Fq, BigInteger256([
|
||||
0xe7a66d1d9fb08e74,
|
||||
0xd775bbd5e17629dc,
|
||||
0x70ccd097286ef1e7,
|
||||
0x45809398fdf98,
|
||||
]));
|
||||
|
||||
/// COFACTOR = 8
|
||||
const COFACTOR: &'static [u64] = &[8];
|
||||
|
||||
/// COFACTOR^(-1) mod r =
|
||||
/// 2394026564107420727433200628387514462817212225638746351800188703329891451411
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger256([
|
||||
0xfac308b2e25a3d4b,
|
||||
0xa7c55b66e25b59cb,
|
||||
0xeccdd46def0f28c5,
|
||||
0x1c14ef83340fbe5,
|
||||
]));
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y);
|
||||
|
||||
type MontgomeryModelParameters = EdwardsParameters;
|
||||
}
|
||||
|
||||
impl MontgomeryModelParameters for EdwardsParameters {
|
||||
/// COEFF_A = 168698
|
||||
#[rustfmt::skip]
|
||||
const COEFF_A: Fq = field_new!(Fq, BigInteger256([
|
||||
9251058552732279275u64,
|
||||
16047179255329565110u64,
|
||||
14708493084570629864u64,
|
||||
2559515811206512830u64,
|
||||
]));
|
||||
/// COEFF_B = 168700
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, BigInteger256([
|
||||
10785223227458347488u64,
|
||||
2627865112663806840u64,
|
||||
16189334210225400552u64,
|
||||
1096023023792938739u64,
|
||||
]));
|
||||
|
||||
type TEModelParameters = EdwardsParameters;
|
||||
}
|
||||
106
ed_on_bn254/src/curves/tests.rs
Normal file
106
ed_on_bn254/src/curves/tests.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
use ark_ec::{AffineCurve, ProjectiveCurve};
|
||||
use ark_ff::{bytes::FromBytes, test_rng, Zero};
|
||||
use core::str::FromStr;
|
||||
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_scalar_multiplication() {
|
||||
let f1 = Fr::from_str(
|
||||
"4691331900926794624732159288782398864809513177368446695323460897088210774597",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fr::from_str(
|
||||
"1305028103380024953477151132159456965337646722479526711736847301646466538045",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let g = EdwardsAffine::from_str(
|
||||
"(15863623088992515880085393097393553694825975317405843389771115419751650972659, \
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203)",
|
||||
)
|
||||
.unwrap();
|
||||
let f1f2g = EdwardsAffine::from_str(
|
||||
"(20773645713088336957786354488799297695596635653208610804806657050882264237947, \
|
||||
19987327827845206670850937090314462639017692512983955920885166014935289314257)",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(!g.is_zero());
|
||||
assert!(!f1f2g.is_zero());
|
||||
|
||||
let f1g = g.mul(f1).into_affine();
|
||||
assert_eq!(g.mul(f1 * &f2).into_affine(), f1f2g);
|
||||
assert_eq!(f1g.mul(f2).into_affine(), f1f2g);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytes() {
|
||||
let g_from_repr = EdwardsAffine::from_str(
|
||||
"(15863623088992515880085393097393553694825975317405843389771115419751650972659, \
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203)",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let g_bytes = ark_ff::to_bytes![g_from_repr].unwrap();
|
||||
let g = EdwardsAffine::read(g_bytes.as_slice()).unwrap();
|
||||
assert_eq!(g_from_repr, g);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_montgomery_conversion() {
|
||||
montgomery_conversion_test::<EdwardsParameters>();
|
||||
}
|
||||
1
ed_on_bn254/src/fields/fq.rs
Normal file
1
ed_on_bn254/src/fields/fq.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub use ark_bn254::{Fr as Fq, FrParameters as FqParameters};
|
||||
87
ed_on_bn254/src/fields/fr.rs
Normal file
87
ed_on_bn254/src/fields/fr.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger256 as BigInteger,
|
||||
fields::{FftParameters, Fp256, Fp256Parameters, FpParameters},
|
||||
};
|
||||
|
||||
pub type Fr = Fp256<FrParameters>;
|
||||
|
||||
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 = BigInteger([
|
||||
0x1721ada8d4d27255,
|
||||
0xcda0f5264e0e35bb,
|
||||
0x961a936922086fe6,
|
||||
0x1ab00857387dd52,
|
||||
]);
|
||||
}
|
||||
impl FpParameters for FrParameters {
|
||||
/// MODULUS = 2736030358979909402780800718157159386076813972158567259200215660948447373041
|
||||
#[rustfmt::skip]
|
||||
const MODULUS: BigInteger = BigInteger([
|
||||
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 = BigInteger([
|
||||
0x073315dea08f9c76,
|
||||
0xe7acffc6a098f24b,
|
||||
0xf85a9201d818f015,
|
||||
0x1f16424e1bb7724,
|
||||
]);
|
||||
|
||||
#[rustfmt::skip]
|
||||
const R2: BigInteger = BigInteger([
|
||||
0x35e44abee7ecb21e,
|
||||
0x74646cacf5f84ec4,
|
||||
0xe472df203faa158f,
|
||||
0x445b524f1ba50a8,
|
||||
]);
|
||||
|
||||
const INV: u64 = 0x532ce5aebc48f5ef;
|
||||
|
||||
#[rustfmt::skip]
|
||||
/// GENERATOR = 31
|
||||
const GENERATOR: BigInteger = BigInteger([
|
||||
0x3c284f376f3993d1,
|
||||
0x08bc9d93705cf8b8,
|
||||
0x239d5fcbd9538f3e,
|
||||
0x5ca4836185b994b,
|
||||
]);
|
||||
|
||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0x33b94bee1c909378,
|
||||
0xd59f76dc1c907705,
|
||||
0x9b85045b68181585,
|
||||
0x30644e72e131a02,
|
||||
]);
|
||||
|
||||
const T: BigInteger = BigInteger([
|
||||
0xa677297dc392126f,
|
||||
0xbab3eedb83920ee0,
|
||||
0x5370a08b6d0302b0,
|
||||
0x60c89ce5c26340,
|
||||
]);
|
||||
|
||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0x533b94bee1c90937,
|
||||
0x5d59f76dc1c90770,
|
||||
0x29b85045b6818158,
|
||||
0x30644e72e131a0,
|
||||
]);
|
||||
}
|
||||
8
ed_on_bn254/src/fields/mod.rs
Normal file
8
ed_on_bn254/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_bn254", test))]
|
||||
mod tests;
|
||||
420
ed_on_bn254/src/fields/tests.rs
Normal file
420
ed_on_bn254/src/fields/tests.rs
Normal file
@@ -0,0 +1,420 @@
|
||||
use crate::{Fq, Fr};
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger256 as BigInteger,
|
||||
bytes::{FromBytes, ToBytes},
|
||||
fields::{Field, LegendreSymbol::*, SquareRootField},
|
||||
test_rng, One, Zero,
|
||||
};
|
||||
|
||||
use ark_curve_tests::fields::*;
|
||||
|
||||
use core::str::FromStr;
|
||||
use rand::Rng;
|
||||
|
||||
#[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>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_add() {
|
||||
let f1 = Fq::from_str(
|
||||
"18386742314266644595564329008376577163854043021652781768352795308532764650733",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"39786307610986038981023499868190793548353538256264351797285876981647142458383",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"14396564181574133132095017386052820535110852477085064878242263917028290117882",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
assert_eq!(f1 + &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_add_one() {
|
||||
let f1 = Fq::from_str(
|
||||
"4946875394261337176810256604189376311946643975348516311606738923340201185904",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"4946875394261337176810256604189376311946643975348516311606738923340201185905",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert_eq!(f1 + &Fq::one(), f2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_mul() {
|
||||
let f1 = Fq::from_str(
|
||||
"24703123148064348394273033316595937198355721297494556079070134653139656190956",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"38196797080882758914424853878212529985425118523754343117256179679117054302131",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"1321267396236123309645330145349353750536542060403774171357889269349508194307",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
assert_eq!(f1 * &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_triple_mul() {
|
||||
let f1 = Fq::from_str(
|
||||
"23834398828139479510988224171342199299644042568628082836691700490363123893905",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"48343809612844640454129919255697536258606705076971130519928764925719046689317",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"22704845471524346880579660022678666462201713488283356385810726260959369106033",
|
||||
)
|
||||
.unwrap();
|
||||
let f4 = Fq::from_str(
|
||||
"7747776931431194635550680695131420638163057297019399136408144301550822179875",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
assert_eq!(f1 * &f2 * &f3, f4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_div() {
|
||||
let f1 = Fq::from_str(
|
||||
"31892744363926593013886463524057935370302352424137349660481695792871889573091",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"47695868328933459965610498875668250916462767196500056002116961816137113470902",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"7301086967624450577859019086314322648061398679982346993011603220910508457334",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
assert_eq!(f1 / &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_sub() {
|
||||
let f1 = Fq::from_str(
|
||||
"18695869713129401390241150743745601908470616448391638969502807001833388904079",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"10105476028534616828778879109836101003805485072436929139123765141153277007373",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"8590393684594784561462271633909500904665131375954709830379041860680111896706",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
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(
|
||||
"32768907806651393940832831055386272949401004221411141755415956893066040832473",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"21380590862979124081952185245260157621176025366712756262647409092194433207997",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
f1.double_in_place();
|
||||
f1.double_in_place();
|
||||
f1.double_in_place();
|
||||
assert_eq!(f1, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_generate_random_ed_on_bn254_point() {
|
||||
let a = Fq::from_str("168700").unwrap();
|
||||
|
||||
let d = Fq::from_str("168696").unwrap();
|
||||
let y = Fq::from_str(
|
||||
"19987327827845206670850937090314462639017692512983955920885166014935289314257",
|
||||
)
|
||||
.unwrap();
|
||||
let x2 = Fq::from_str(
|
||||
"2144239075372598103060889495211040948751593385312551803225522963913923559328",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let computed_y2 = y.square();
|
||||
let y2 = Fq::from_str(
|
||||
"11134206686211572308995578277928848431421308813024790181507137950838333998633",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(y2, computed_y2);
|
||||
|
||||
let computed_dy2 = d * &computed_y2;
|
||||
let dy2 =
|
||||
Fq::from_str("345576003677591687256955722467813448317229128849323754147891993737799010947")
|
||||
.unwrap();
|
||||
assert_eq!(dy2, computed_dy2);
|
||||
|
||||
let computed_divisor = computed_dy2 - a;
|
||||
let divisor =
|
||||
Fq::from_str("345576003677591687256955722467813448317229128849323754147891993737798842247")
|
||||
.unwrap();
|
||||
assert_eq!(divisor, computed_divisor);
|
||||
|
||||
let computed_x2 = (computed_y2 - &Fq::one()) / &computed_divisor;
|
||||
assert_eq!(x2, computed_x2);
|
||||
|
||||
let x = Fq::from_str(
|
||||
"4801447892755635304907919953550459075619191823587157449340656925102682829025",
|
||||
)
|
||||
.unwrap();
|
||||
let computed_x = computed_x2.sqrt().unwrap();
|
||||
assert_eq!(computed_x.square(), x2);
|
||||
assert_eq!(x, computed_x);
|
||||
|
||||
fn add<'a>(curr: (Fq, Fq), other: &'a (Fq, Fq)) -> (Fq, Fq) {
|
||||
let y1y2 = curr.1 * &other.1;
|
||||
let x1x2 = curr.0 * &other.0;
|
||||
let a = Fq::from_str("168700").unwrap();
|
||||
let d = Fq::from_str("168696").unwrap();
|
||||
let dx1x2y1y2 = d * &y1y2 * &x1x2;
|
||||
|
||||
let d1 = Fq::one() + &dx1x2y1y2;
|
||||
let d2 = Fq::one() - &dx1x2y1y2;
|
||||
|
||||
let x1y2 = curr.0 * &other.1;
|
||||
let y1x2 = curr.1 * &other.0;
|
||||
|
||||
let x = (x1y2 + &y1x2) / &d1;
|
||||
let y = (y1y2 - a * &x1x2) / &d2;
|
||||
|
||||
(x, y)
|
||||
}
|
||||
|
||||
let result = add((x, y), &(x, y));
|
||||
let result = add(result, &result);
|
||||
let result = add(result, &result);
|
||||
|
||||
let point_x =
|
||||
Fq::from_str("380676173762867192861894055350059333852732198308367125138259398265363727587")
|
||||
.unwrap();
|
||||
let point_y = Fq::from_str(
|
||||
"8435074244857818446059206728316702149733931432112984450960434710303841866985",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!((point_x, point_y), result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_square_in_place() {
|
||||
let mut f1 = Fq::from_str(
|
||||
"6060110850233386730847324622937480088943976359504617699731744947670229990461",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"17018926051730832095053393285350575966874590491719897015583930476179087429684",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
f1.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([
|
||||
0xab8a2535947d1a77,
|
||||
0x9ba74cbfda0bbcda,
|
||||
0xe928b59724d60baf,
|
||||
0x1cccaaeb9bb1680a,
|
||||
]));
|
||||
let f1 = Fq::from_str(
|
||||
"13026376210409056429264774981357153555336288129100724591327877625017068755575",
|
||||
)
|
||||
.unwrap();
|
||||
let f2_from_repr = Fq::from(BigInteger([
|
||||
0x97e9103775d2f35c,
|
||||
0xbe6756b6c587544b,
|
||||
0x6ee38c3afd88ef4b,
|
||||
0x2bacd150f540c677,
|
||||
]));
|
||||
let f2 = Fq::from_str(
|
||||
"19754794831832707859764530223239420866832328728734160755396495950822165902172",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(f1_from_repr, f1);
|
||||
assert_eq!(f2_from_repr, f2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_legendre() {
|
||||
assert_eq!(QuadraticResidue, Fq::one().legendre());
|
||||
assert_eq!(Zero, Fq::zero().legendre());
|
||||
|
||||
let e = BigInteger([
|
||||
0x2e8de1a676c03be8,
|
||||
0x73350d34fe25a560,
|
||||
0x7ea085919029688e,
|
||||
0x1d0868cb993cf28,
|
||||
]);
|
||||
assert_eq!(QuadraticResidue, Fq::from(e).legendre());
|
||||
let e = BigInteger([
|
||||
0x891d8cc23c8d0706,
|
||||
0xe91800e007db2698,
|
||||
0xfff380321e9ac7a7,
|
||||
0x2659e28bd17eab6,
|
||||
]);
|
||||
assert_eq!(QuadraticNonResidue, Fq::from(e).legendre());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_bytes() {
|
||||
let f1_from_repr = Fq::from(BigInteger([
|
||||
0xab8a2535947d1a77,
|
||||
0x9ba74cbfda0bbcda,
|
||||
0xe928b59724d60baf,
|
||||
0x1cccaaeb9bb1680a,
|
||||
]));
|
||||
|
||||
let mut f1_bytes = [0u8; 32];
|
||||
f1_from_repr.write(f1_bytes.as_mut()).unwrap();
|
||||
|
||||
let f1 = Fq::read(f1_bytes.as_ref()).unwrap();
|
||||
assert_eq!(f1_from_repr, f1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_add() {
|
||||
let f1 = Fr::from(BigInteger([
|
||||
0xccfc9a195e0f5c46,
|
||||
0xaed4874d13fb1285,
|
||||
0x27368f86ca2848eb,
|
||||
0x4f8adcfeb44fccc,
|
||||
]));
|
||||
let f2 = Fr::from(BigInteger([
|
||||
0x661ff05bf8570851,
|
||||
0x1b171f4c59be97ef,
|
||||
0x5d2ce7f9b4d701f3,
|
||||
0x1e0e794623e0f68,
|
||||
]));
|
||||
let f3 = Fr::from(BigInteger([
|
||||
0xcba9f2991d453da6,
|
||||
0x1eacb8e13498bc6a,
|
||||
0x4d596ec9aecf1fd3,
|
||||
0xcd0b95f15cd82f,
|
||||
]));
|
||||
assert_eq!(f1 + &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_mul() {
|
||||
let f1 = Fr::from(BigInteger([
|
||||
0xc2964d2dd5fb980f,
|
||||
0xbab64d599c57e496,
|
||||
0x39cae13e7d1d4f78,
|
||||
0x1aa995aa4de205c,
|
||||
]));
|
||||
let f2 = Fr::from(BigInteger([
|
||||
0xc256e720cd43533b,
|
||||
0x3bfbadf6247e13bb,
|
||||
0x94c3d63a53714f63,
|
||||
0x10f8a7bf74efd57,
|
||||
]));
|
||||
let f3 = Fr::from(BigInteger([
|
||||
0x5eac88be41e0e1fd,
|
||||
0x57aab36675b11e24,
|
||||
0x835582d896b4d13f,
|
||||
0x4808736e213036e,
|
||||
]));
|
||||
assert_eq!(f1 * &f2, f3);
|
||||
}
|
||||
#[test]
|
||||
fn test_fr_bytes() {
|
||||
let f1_from_repr = Fr::from(BigInteger([
|
||||
0xc81265fb4130fe0c,
|
||||
0xb308836c14e22279,
|
||||
0x699e887f96bff372,
|
||||
0x84ecc7e76c11ad,
|
||||
]));
|
||||
|
||||
let mut f1_bytes = [0u8; 32];
|
||||
f1_from_repr.write(f1_bytes.as_mut()).unwrap();
|
||||
|
||||
let f1 = Fr::read(f1_bytes.as_ref()).unwrap();
|
||||
assert_eq!(f1_from_repr, f1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_from_str() {
|
||||
let f100_from_repr = Fr::from(BigInteger([0x64, 0, 0, 0]));
|
||||
let f100 = Fr::from_str("100").unwrap();
|
||||
assert_eq!(f100_from_repr, f100);
|
||||
}
|
||||
29
ed_on_bn254/src/lib.rs
Normal file
29
ed_on_bn254/src/lib.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
#![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 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
|
||||
//! * 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
|
||||
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
Reference in New Issue
Block a user