forked from sec-bit/ckb-zkp
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request sec-bit#20 from sunhuachuang/master
Add curve: baby_jubjub
- Loading branch information
Showing
9 changed files
with
779 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
use crate::baby_jubjub::{Fq, Fr}; | ||
use math::{ | ||
biginteger::BigInteger256, | ||
curves::{ | ||
models::{ModelParameters, MontgomeryModelParameters, TEModelParameters}, | ||
twisted_edwards_extended::{GroupAffine, GroupProjective}, | ||
}, | ||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
use math::{ | ||
bytes::{FromBytes, ToBytes}, | ||
curves::{AffineCurve, ProjectiveCurve}, | ||
test_rng, Zero, | ||
}; | ||
use core::str::FromStr; | ||
use rand::Rng; | ||
|
||
use crate::baby_jubjub::*; | ||
|
||
use crate::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 crate::groups::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() { | ||
println!("Started getting field elements"); | ||
let f1 = Fr::from_str( | ||
"4691331900926794624732159288782398864809513177368446695323460897088210774597", | ||
) | ||
.unwrap(); | ||
let f2 = Fr::from_str( | ||
"1305028103380024953477151132159456965337646722479526711736847301646466538045", | ||
) | ||
.unwrap(); | ||
|
||
println!("Finished getting field elements"); | ||
let g = EdwardsAffine::from_str( | ||
"(15863623088992515880085393097393553694825975317405843389771115419751650972659, \ | ||
16950150798460657717958625567821834550301663161624707787222815936182638968203)", | ||
) | ||
.unwrap(); | ||
let f1f2g = EdwardsAffine::from_str( | ||
"(20773645713088336957786354488799297695596635653208610804806657050882264237947, \ | ||
19987327827845206670850937090314462639017692512983955920885166014935289314257)", | ||
) | ||
.unwrap(); | ||
|
||
println!("Finished getting group elements"); | ||
|
||
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 = math::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>(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub use crate::bn_256::{Fr as Fq, FrParameters as FqParameters}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
use math::{ | ||
biginteger::BigInteger256 as BigInteger, | ||
fields::{Fp256, Fp256Parameters, FpParameters}, | ||
}; | ||
|
||
pub type Fr = Fp256<FrParameters>; | ||
|
||
pub struct FrParameters; | ||
|
||
impl Fp256Parameters for FrParameters {} | ||
|
||
impl FpParameters for FrParameters { | ||
type BigInt = BigInteger; | ||
|
||
/// 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 TWO_ADICITY: u32 = 4; | ||
|
||
const ROOT_OF_UNITY: BigInteger = BigInteger([ | ||
0x1721ada8d4d27255, | ||
0xcda0f5264e0e35bb, | ||
0x961a936922086fe6, | ||
0x1ab00857387dd52, | ||
]); | ||
|
||
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, | ||
]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
pub mod fq; | ||
pub mod fr; | ||
|
||
pub use fq::*; | ||
pub use fr::*; | ||
|
||
#[cfg(all(feature = "baby_jubjub", test))] | ||
mod tests; |
Oops, something went wrong.