Browse Source

Twisted Edwards parameters for BLS12-377 (#76)

Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
sjoseph/big_integer_documentation
zhenfei 3 years ago
committed by GitHub
parent
commit
5fe1862c9a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 224 additions and 14 deletions
  1. +2
    -0
      CHANGELOG.md
  2. +17
    -1
      bls12_377/src/constraints/curves.rs
  3. +183
    -1
      bls12_377/src/curves/g1.rs
  4. +2
    -0
      bls12_377/src/curves/mod.rs
  5. +15
    -7
      bls12_377/src/curves/tests.rs
  6. +3
    -2
      bls12_377/src/fields/fr.rs
  7. +1
    -2
      bls12_377/src/fields/tests.rs
  8. +1
    -1
      curve-benches/src/macros/field.rs

+ 2
- 0
CHANGELOG.md

@ -2,6 +2,8 @@
## Pending ## Pending
- [\#76](https://github.com/arkworks-rs/curves/pull/76) twisted Edwards parameters for bls12-377
### Breaking changes ### Breaking changes
### Features ### Features

+ 17
- 1
bls12_377/src/constraints/curves.rs

@ -1,11 +1,22 @@
use crate::Parameters; use crate::Parameters;
use ark_r1cs_std::groups::bls12;
use ark_ec::bls12::Bls12Parameters;
use ark_ec::ModelParameters;
use ark_r1cs_std::{
fields::fp::FpVar,
groups::{bls12, curves::twisted_edwards::AffineVar as TEAffineVar},
};
/// An element of G1 in the BLS12-377 bilinear group. /// An element of G1 in the BLS12-377 bilinear group.
pub type G1Var = bls12::G1Var<Parameters>; pub type G1Var = bls12::G1Var<Parameters>;
/// An element of G2 in the BLS12-377 bilinear group. /// An element of G2 in the BLS12-377 bilinear group.
pub type G2Var = bls12::G2Var<Parameters>; pub type G2Var = bls12::G2Var<Parameters>;
/// An element of G1 (in TE Affine form) in the BLS12-377 bilinear group.
pub type G1TEAffineVar = TEAffineVar<
<Parameters as Bls12Parameters>::G1Parameters,
FpVar<<<Parameters as Bls12Parameters>::G1Parameters as ModelParameters>::BaseField>,
>;
/// Represents the cached precomputation that can be performed on a G1 element /// Represents the cached precomputation that can be performed on a G1 element
/// which enables speeding up pairing computation. /// which enables speeding up pairing computation.
pub type G1PreparedVar = bls12::G1PreparedVar<Parameters>; pub type G1PreparedVar = bls12::G1PreparedVar<Parameters>;
@ -21,6 +32,11 @@ fn test() {
G1Var, G1Var,
>() >()
.unwrap(); .unwrap();
ark_curve_constraint_tests::curves::te_test::<
<Parameters as Bls12Parameters>::G1Parameters,
G1TEAffineVar,
>()
.unwrap();
ark_curve_constraint_tests::curves::sw_test::< ark_curve_constraint_tests::curves::sw_test::<
<Parameters as Bls12Parameters>::G2Parameters, <Parameters as Bls12Parameters>::G2Parameters,
G2Var, G2Var,

+ 183
- 1
bls12_377/src/curves/g1.rs

@ -1,5 +1,11 @@
use ark_ec::models::{ModelParameters, SWModelParameters};
use ark_ec::models::{
twisted_edwards_extended::{
GroupAffine as TEGroupAffine, GroupProjective as TEGroupProjective,
},
ModelParameters, MontgomeryModelParameters, SWModelParameters, TEModelParameters,
};
use ark_ff::{field_new, Zero}; use ark_ff::{field_new, Zero};
use core::ops::Neg;
use crate::{ use crate::{
fields::{FQ_ONE, FQ_ZERO}, fields::{FQ_ONE, FQ_ZERO},
@ -40,6 +46,129 @@ impl SWModelParameters for Parameters {
} }
} }
pub type G1TEAffine = TEGroupAffine<Parameters>;
pub type G1TEProjective = TEGroupProjective<Parameters>;
/// Bls12_377::G1 also has a twisted Edwards form.
/// It can be obtained via the following script, implementing
/// 1. SW -> Montgomery -> TE1 transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
/// 2. TE1 -> TE2 normalization (enforcing `a = -1`)
/// ``` sage
///
/// # modulus
/// p = 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
/// Fp = Zmod(p)
///
/// #####################################################
/// # Weierstrass curve: y² = x³ + A * x + B
/// #####################################################
/// # curve y^2 = x^3 + 1
/// WA = Fp(0)
/// WB = Fp(1)
///
/// #####################################################
/// # Montgomery curve: By² = x³ + A * x² + x
/// #####################################################
/// # root for x^3 + 1 = 0
/// alpha = -1
/// # s = 1 / (sqrt(3alpha^2 + a))
/// s = 1/(Fp(3).sqrt())
///
/// # MA = 3 * alpha * s
/// MA = Fp(228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384)
/// # MB = s
/// MB = Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
///
/// # #####################################################
/// # # Twisted Edwards curve 1: a * x² + y² = 1 + d * x² * y²
/// # #####################################################
/// # We first convert to TE form obtaining a curve with a != -1, and then
/// # apply a transformation to obtain a TE curve with a = -1.
/// # a = (MA+2)/MB
/// TE1a = Fp(61134141799337779744243169579317764548490943457438569789767076791016838392692895365021181670618017873462480451583)
/// # b = (MA-2)/MB
/// TE1d = Fp(197530284213631314266409564115575768987902569297476090750117185875703629955647927409947706468955342250977841006588)
///
/// # #####################################################
/// # # Twisted Edwards curve 2: a * x² + y² = 1 + d * x² * y²
/// # #####################################################
/// # a = -1
/// TE2a = Fp(-1)
/// # b = -TE1d/TE1a
/// TE2d = Fp(122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179)
///
/// ```
impl TEModelParameters for Parameters {
/// COEFF_A = -1
const COEFF_A: Fq = field_new!(Fq, "-1");
/// COEFF_D = 122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179 mod q
#[rustfmt::skip]
const COEFF_D: Fq = field_new!(Fq, "122268283598675559488486339158635529096981886914877139579534153582033676785385790730042363341236035746924960903179");
/// COFACTOR = (x - 1)^2 / 3 = 30631250834960419227450344600217059328
const COFACTOR: &'static [u64] = &[0x0, 0x170b5d4430000000];
/// COFACTOR_INV = COFACTOR^{-1} mod r
/// = 5285428838741532253824584287042945485047145357130994810877
#[rustfmt::skip]
const COFACTOR_INV: Fr = field_new!(Fr, "5285428838741532253824584287042945485047145357130994810877");
/// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
(TE_GENERATOR_X, TE_GENERATOR_Y);
type MontgomeryModelParameters = Parameters;
/// Multiplication by `a` is multiply by `-1`.
#[inline(always)]
fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
elem.neg()
}
}
// BLS12-377::G1 also has a Montgomery form.
// BLS12-377::G1 also has a twisted Edwards form.
// It can be obtained via the following script, implementing
// SW -> Montgomery transformation: <https://en.wikipedia.org/wiki/Montgomery_curve>
// ``` sage
//
// # modulus
// p=0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
// Fp=Zmod(p)
//
// #####################################################
// # Weierstrass curve: y² = x³ + A * x + B
// #####################################################
// # curve y^2 = x^3 + 1
// WA=Fp(0)
// WB=Fp(1)
//
// #####################################################
// # Montgomery curve: By² = x³ + A * x² + x
// #####################################################
// # root for x^3 + 1 = 0
// alpha = -1
// # s = 1 / (sqrt(3alpha^2 + a))
// s = 1/(Fp(3).sqrt())
//
// # MA = 3 * alpha * s
// MA=Fp(228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384)
// # MB = s
// MB=Fp(10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931)
// ```
impl MontgomeryModelParameters for Parameters {
/// COEFF_A = 228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384
#[rustfmt::skip]
const COEFF_A: Fq = field_new!(Fq, "228097355113300204138531148905234651262148041026195375645000724271212049151994375092458297304264351187709081232384");
/// COEFF_B = 10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931
#[rustfmt::skip]
const COEFF_B: Fq = field_new!(Fq, "10189023633222963290707194929886294091415157242906428298294512798502806398782149227503530278436336312243746741931");
type TEModelParameters = Parameters;
}
/// G1_GENERATOR_X = /// G1_GENERATOR_X =
/// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695 /// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695
#[rustfmt::skip] #[rustfmt::skip]
@ -49,3 +178,56 @@ pub const G1_GENERATOR_X: Fq = field_new!(Fq, "819379993731509642399382555734659
/// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030 /// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
#[rustfmt::skip] #[rustfmt::skip]
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030"); pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030");
// The generator for twisted Edward form is the same SW generator converted into the normalized TE form (TE2).
// ``` sage
// # following scripts in previous section
// #####################################################
// # Weierstrass curve generator
// #####################################################
// Wx = Fp(81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695)
// Wy = Fp(241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030)
//
// assert(Wy^2 - Wx^3 - WA * Wx - WB == 0)
//
// #####################################################
// # Montgomery curve generator
// #####################################################
// # x = s * (x - alpha)
// Mx = Fp(251803586774461569862800610331871502335378228972505599912537082323947581271784390797244487924068052270360793200630)
// # y = s * y
// My = Fp(77739247071951651095607889637653357561348174979132042929587539214321586851215673796661346812932566642719051699820)
//
// assert(MB * My^2 == Mx^3+ MA * Mx^2 + Mx)
//
// # #####################################################
// # # Twisted Edwards curve 1 generator
// # #####################################################
// # x = Mx/My
// TE1x = Fp(82241236807150726090333472814441006963902378430536027612759193445733851062772474760677400112551677454953925168208)
// # y = (Mx - 1)/(Mx+1)
// TE1y = Fp(6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235)
//
// assert( TE1a * TE1x^2 + TE1y^2 == 1 + TE1d * TE1x^2 * TE1y^2 )
//
//
// # #####################################################
// # # Twisted Edwards curve 2 generator
// # #####################################################
// beta = (-TE1a).sqrt()
// # x = TE1x * sqrt(-TE1a)
// TE2x = Fp(71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393)
// # y = TE1y
// TE2y = Fp(6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235)
//
// assert( TE2a * TE2x^2 + TE2y^2 == 1 + TE2d * TE2x^2 * TE2y^2 )
// ```
/// TE_GENERATOR_X =
/// 71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393
#[rustfmt::skip]
pub const TE_GENERATOR_X: Fq = field_new!(Fq, "71222569531709137229370268896323705690285216175189308202338047559628438110820800641278662592954630774340654489393");
/// TE_GENERATOR_Y =
/// 6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235
#[rustfmt::skip]
pub const TE_GENERATOR_Y: Fq = field_new!(Fq, "6177051365529633638563236407038680211609544222665285371549726196884440490905471891908272386851767077598415378235");

+ 2
- 0
bls12_377/src/curves/mod.rs

@ -31,3 +31,5 @@ pub type G1Affine = bls12::G1Affine;
pub type G1Projective = bls12::G1Projective<Parameters>; pub type G1Projective = bls12::G1Projective<Parameters>;
pub type G2Affine = bls12::G2Affine<Parameters>; pub type G2Affine = bls12::G2Affine<Parameters>;
pub type G2Projective = bls12::G2Projective<Parameters>; pub type G2Projective = bls12::G2Projective<Parameters>;
pub use g1::{G1TEAffine, G1TEProjective};

+ 15
- 7
bls12_377/src/curves/tests.rs

@ -1,19 +1,22 @@
#![allow(unused_imports)] #![allow(unused_imports)]
use crate::{
g1, g2, Bls12_377, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G1TEProjective, G2Affine,
G2Projective,
};
use ark_ec::{
models::SWModelParameters, short_weierstrass_jacobian, AffineCurve, PairingEngine,
ProjectiveCurve,
};
use ark_ff::{ use ark_ff::{
fields::{Field, FpParameters, PrimeField, SquareRootField}, fields::{Field, FpParameters, PrimeField, SquareRootField},
One, Zero, One, Zero,
}; };
use ark_serialize::CanonicalSerialize; use ark_serialize::CanonicalSerialize;
use ark_std::test_rng;
use ark_ec::{models::SWModelParameters, AffineCurve, PairingEngine, ProjectiveCurve};
use ark_std::rand::Rng;
use ark_std::{rand::Rng, test_rng};
use core::ops::{AddAssign, MulAssign}; use core::ops::{AddAssign, MulAssign};
use crate::{g1, g2, Bls12_377, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
use ark_algebra_test_templates::{ use ark_algebra_test_templates::{
curves::{curve_tests, sw_tests},
curves::{curve_tests, edwards_tests, sw_tests},
groups::group_test, groups::group_test,
}; };
@ -22,6 +25,7 @@ fn test_g1_projective_curve() {
curve_tests::<G1Projective>(); curve_tests::<G1Projective>();
sw_tests::<g1::Parameters>(); sw_tests::<g1::Parameters>();
edwards_tests::<g1::Parameters>();
} }
#[test] #[test]
@ -30,6 +34,10 @@ fn test_g1_projective_group() {
let a: G1Projective = rng.gen(); let a: G1Projective = rng.gen();
let b: G1Projective = rng.gen(); let b: G1Projective = rng.gen();
group_test(a, b); group_test(a, b);
let c = rng.gen();
let d = rng.gen();
group_test::<G1TEProjective>(c, d);
} }
#[test] #[test]

+ 3
- 2
bls12_377/src/fields/fr.rs

@ -1,4 +1,4 @@
///! Bls12-377 scalar field.
//! Bls12-377 scalar field.
/// ///
/// Roots of unity computed from modulus and R using this sage code: /// Roots of unity computed from modulus and R using this sage code:
/// ///
@ -76,7 +76,8 @@ impl FpParameters for FrParameters {
/// GENERATOR = 22 /// GENERATOR = 22
/// Encoded in Montgomery form, so the value is /// Encoded in Montgomery form, so the value is
/// (22 * R) % q = 5642976643016801619665363617888466827793962762719196659561577942948671127251
/// (22 * R) % q =
/// 5642976643016801619665363617888466827793962762719196659561577942948671127251
#[rustfmt::skip] #[rustfmt::skip]
const GENERATOR: BigInteger = BigInteger([ const GENERATOR: BigInteger = BigInteger([
2984901390528151251u64, 2984901390528151251u64,

+ 1
- 2
bls12_377/src/fields/tests.rs

@ -7,8 +7,7 @@ use ark_ff::{
One, UniformRand, Zero, One, UniformRand, Zero,
}; };
use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize}; use ark_serialize::{buffer_bit_byte_size, CanonicalSerialize};
use ark_std::rand::Rng;
use ark_std::test_rng;
use ark_std::{rand::Rng, test_rng};
use core::{ use core::{
cmp::Ordering, cmp::Ordering,
ops::{AddAssign, MulAssign, SubAssign}, ops::{AddAssign, MulAssign, SubAssign},

+ 1
- 1
curve-benches/src/macros/field.rs

@ -448,7 +448,7 @@ macro_rules! prime_field {
let mut count = 0; let mut count = 0;
b.iter(|| { b.iter(|| {
count = (count + 1) % SAMPLES; count = (count + 1) % SAMPLES;
$f::from(v[count]);
let _ = $f::from(v[count]);
}); });
} }
}; };

Loading…
Cancel
Save