Skip to content
This repository has been archived by the owner on Dec 18, 2023. It is now read-only.

Twisted Edwards parameters for BLS12-377 #76

Merged
merged 9 commits into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Pending

- [\#76](https://github.com/arkworks-rs/curves/pull/76) twisted Edwards parameters for bls12-377

### Breaking changes

### Features
Expand Down
18 changes: 17 additions & 1 deletion bls12_377/src/constraints/curves.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
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.
pub type G1Var = bls12::G1Var<Parameters>;
/// An element of G2 in the BLS12-377 bilinear group.
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
/// which enables speeding up pairing computation.
pub type G1PreparedVar = bls12::G1PreparedVar<Parameters>;
Expand All @@ -21,6 +32,11 @@ fn test() {
G1Var,
>()
.unwrap();
ark_curve_constraint_tests::curves::te_test::<
Pratyush marked this conversation as resolved.
Show resolved Hide resolved
<Parameters as Bls12Parameters>::G1Parameters,
G1TEAffineVar,
>()
.unwrap();
ark_curve_constraint_tests::curves::sw_test::<
<Parameters as Bls12Parameters>::G2Parameters,
G2Var,
Expand Down
184 changes: 183 additions & 1 deletion bls12_377/src/curves/g1.rs
Original file line number Diff line number Diff line change
@@ -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 core::ops::Neg;

use crate::{
fields::{FQ_ONE, FQ_ZERO},
Expand Down Expand Up @@ -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];
Pratyush marked this conversation as resolved.
Show resolved Hide resolved

/// 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 =
/// 81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695
#[rustfmt::skip]
Expand All @@ -49,3 +178,56 @@ pub const G1_GENERATOR_X: Fq = field_new!(Fq, "819379993731509642399382555734659
/// 241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030
#[rustfmt::skip]
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 changes: 2 additions & 0 deletions bls12_377/src/curves/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ pub type G1Affine = bls12::G1Affine<Parameters>;
pub type G1Projective = bls12::G1Projective<Parameters>;
pub type G2Affine = bls12::G2Affine<Parameters>;
pub type G2Projective = bls12::G2Projective<Parameters>;

pub use g1::{G1TEAffine, G1TEProjective};
22 changes: 15 additions & 7 deletions bls12_377/src/curves/tests.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
#![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::{
fields::{Field, FpParameters, PrimeField, SquareRootField},
One, Zero,
};
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 crate::{g1, g2, Bls12_377, Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};

use ark_algebra_test_templates::{
curves::{curve_tests, sw_tests},
curves::{curve_tests, edwards_tests, sw_tests},
groups::group_test,
};

Expand All @@ -22,6 +25,7 @@ fn test_g1_projective_curve() {
curve_tests::<G1Projective>();

sw_tests::<g1::Parameters>();
edwards_tests::<g1::Parameters>();
}

#[test]
Expand All @@ -30,6 +34,10 @@ fn test_g1_projective_group() {
let a: G1Projective = rng.gen();
let b: G1Projective = rng.gen();
group_test(a, b);

let c = rng.gen();
let d = rng.gen();
group_test::<G1TEProjective>(c, d);
}

#[test]
Expand Down
5 changes: 3 additions & 2 deletions bls12_377/src/fields/fr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
///! Bls12-377 scalar field.
//! Bls12-377 scalar field.
///
/// Roots of unity computed from modulus and R using this sage code:
///
Expand Down Expand Up @@ -76,7 +76,8 @@ impl FpParameters for FrParameters {

/// GENERATOR = 22
/// Encoded in Montgomery form, so the value is
/// (22 * R) % q = 5642976643016801619665363617888466827793962762719196659561577942948671127251
/// (22 * R) % q =
/// 5642976643016801619665363617888466827793962762719196659561577942948671127251
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInteger([
2984901390528151251u64,
Expand Down
3 changes: 1 addition & 2 deletions bls12_377/src/fields/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use ark_ff::{
One, UniformRand, Zero,
};
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::{
cmp::Ordering,
ops::{AddAssign, MulAssign, SubAssign},
Expand Down
2 changes: 1 addition & 1 deletion curve-benches/src/macros/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ macro_rules! prime_field {
let mut count = 0;
b.iter(|| {
count = (count + 1) % SAMPLES;
$f::from(v[count]);
let _ = $f::from(v[count]);
});
}
};
Expand Down