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

GLV implementation for BLS12_377, BLS12_381 and BN254 #158

Merged
merged 47 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
07442c1
test bench glv bls12_381
simonmasson Jan 5, 2023
d81a5a2
bls12_377 glv works
simonmasson Jan 5, 2023
2e09d0d
bn254 g1 g2 glv works
simonmasson Jan 5, 2023
59d024d
move endomorphism in Projective and WIP with bandersnatch
simonmasson Jan 6, 2023
17cecc3
bw6_761 params
simonmasson Jan 9, 2023
c4ed4d7
bandersnatch is not efficient
simonmasson Jan 9, 2023
e221e4d
pallas glv
simonmasson Jan 10, 2023
6a5468d
vesta glv
simonmasson Jan 10, 2023
b016544
test and bench work
simonmasson Jan 11, 2023
2dc0951
tests pasta
simonmasson Jan 23, 2023
53f9ba3
bls12_381 fix
simonmasson Jan 25, 2023
6a51e3b
bls12_377 fix
simonmasson Jan 25, 2023
8140778
bn254 fix
simonmasson Jan 25, 2023
800b550
bw6_761 fox
simonmasson Jan 25, 2023
3c8898e
bandersnatch fix
simonmasson Jan 25, 2023
375bed3
pallas fix
simonmasson Jan 25, 2023
2646ecc
vesta fix
simonmasson Jan 25, 2023
192056f
merge conflicts
simonmasson Jan 25, 2023
71b3f5d
fmt
simonmasson Jan 25, 2023
fa24c6f
fix bugs
simonmasson Jan 25, 2023
a3340a8
fix imports
simonmasson Jan 25, 2023
aecc663
merge issue
simonmasson Jan 26, 2023
8a39f14
bls12377 nostd
simonmasson Feb 8, 2023
b02bf20
bls12381 nostd
simonmasson Feb 8, 2023
4d9c1cf
bn254 nostd
simonmasson Feb 8, 2023
7f5be70
bw761 nostd
simonmasson Feb 8, 2023
645b83d
bandersnatch nostd
simonmasson Feb 8, 2023
bcf85ce
pasta nostd
simonmasson Feb 8, 2023
cc0790e
Merge branch 'master' into glv
mmagician Apr 27, 2023
62549cc
update manifest file with arkworks-rs repos
mmagician Apr 27, 2023
59a9a4f
Replace all MontFp macros by BigInt macros
mmagician Apr 27, 2023
50c095a
change the type of `SCALAR_DECOMP_COEFFS` and remove `SGN_N`
mmagician Apr 27, 2023
99a2065
Merge branch 'master' into glv-2
mmagician Sep 3, 2023
8e640e8
enable GLV as default for BLS12-381
mmagician Sep 3, 2023
f7c68ae
enable GLV as default for BLS12-377
mmagician Sep 3, 2023
358231f
enable GLV as default for BN254
mmagician Sep 3, 2023
693f7b3
add benches for Bandersnatch
mmagician Sep 3, 2023
a39aa84
enable GLV as default for Bandersnatch
mmagician Sep 3, 2023
eb09425
update changelog
mmagician Sep 3, 2023
12ac2c7
Merge branch 'master' into glv-2
mmagician Sep 5, 2023
9f31b81
move the hash-to-curve test suite back
mmagician Sep 5, 2023
66db16c
temp remove Bandersnatch changes from PR
mmagician Sep 7, 2023
2778607
Merge branch 'master' into glv-2
mmagician Sep 9, 2023
b7d0f22
remove benches and scripts that were not on master
mmagician Sep 9, 2023
05db67c
tests modules were duplicated - move glv tests to `tests` directory
mmagician Sep 9, 2023
62b4981
adapt changelog - Bandersnatch not included ATM
mmagician Sep 9, 2023
4db729b
Merge branch 'master' into glv-2
mmagician Sep 11, 2023
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
### Improvements

- [\#156](https://github.com/arkworks-rs/curves/pull/156) The hard part of the final exponentiation for bw6-761 relocated from arkworks/algebra.
- [\#158](https://github.com/arkworks-rs/curves/pull/158) Enabled GLV as the default scalar multiplication for BLS12-377, BLS12-381 and BN254.

### Bugfixes

Expand Down
39 changes: 37 additions & 2 deletions bls12_377/src/curves/g1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ use ark_ec::{
bls12::Bls12Config,
hashing::curve_maps::wb::{IsogenyMap, WBConfig},
models::{
short_weierstrass::{Affine as SWAffine, SWCurveConfig},
short_weierstrass::{Affine as SWAffine, Projective as SWProjective, SWCurveConfig},
twisted_edwards::{
Affine as TEAffine, MontCurveConfig, Projective as TEProjective, TECurveConfig,
},
},
scalar_mul::glv::GLVConfig,
CurveConfig,
};
use ark_ff::{AdditiveGroup, Field, MontFp, PrimeField, Zero};
use ark_ff::{AdditiveGroup, BigInt, Field, MontFp, PrimeField, Zero};
use ark_std::{ops::Neg, One};

use super::g1_swu_iso::{SwuIsoConfig, ISOGENY_MAP_TO_G1};
Expand Down Expand Up @@ -49,6 +50,12 @@ impl SWCurveConfig for Config {
Self::BaseField::zero()
}

#[inline]
fn mul_projective(p: &G1Projective, scalar: &[u64]) -> G1Projective {
let s = Self::ScalarField::from_sign_and_limbs(true, scalar);
GLVConfig::glv_mul_projective(*p, s)
}

#[inline]
fn clear_cofactor(p: &G1SWAffine) -> G1SWAffine {
// Using the effective cofactor.
Expand All @@ -59,6 +66,34 @@ impl SWCurveConfig for Config {
}
}

impl GLVConfig for Config {
const ENDO_COEFFS: &'static[Self::BaseField] = &[
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231")
];

const LAMBDA: Self::ScalarField =
MontFp!("8444461749428370424248824938781546531284005582649182570233710176290576793600");

const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
(true, BigInt!("91893752504881257701523279626832445441")),
(true, BigInt!("1")),
(false, BigInt!("1")),
(true, BigInt!("91893752504881257701523279626832445440")),
];

fn endomorphism(p: &SWProjective<Self>) -> SWProjective<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}

fn endomorphism_affine(p: &SWAffine<Self>) -> SWAffine<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}
}

fn x_minus_one() -> Fr {
const X: Fr = Fr::from_sign_and_limbs(!crate::Config::X_IS_NEGATIVE, crate::Config::X);
X - Fr::one()
Expand Down
36 changes: 33 additions & 3 deletions bls12_377/src/curves/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use ark_ec::{
bls12,
bls12::Bls12Config,
hashing::curve_maps::wb::{IsogenyMap, WBConfig},
models::CurveConfig,
scalar_mul::glv::GLVConfig,
short_weierstrass::{Affine, Projective, SWCurveConfig},
AffineRepr, CurveGroup, PrimeGroup,
AffineRepr, CurveConfig, CurveGroup, PrimeGroup,
};

use ark_ff::{AdditiveGroup, Field, MontFp, Zero};
use ark_ff::{AdditiveGroup, BigInt, Field, MontFp, PrimeField, Zero};
use ark_std::ops::Neg;

use crate::*;
Expand Down Expand Up @@ -98,6 +98,36 @@ impl SWCurveConfig for Config {
}
}

impl GLVConfig for Config {
const ENDO_COEFFS: &'static[Self::BaseField] = &[
Fq2::new(
MontFp!("258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231"),
Fq::ZERO
)
];

const LAMBDA: Self::ScalarField = MontFp!("91893752504881257701523279626832445440");

const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
(false, BigInt!("91893752504881257701523279626832445440")),
(true, BigInt!("1")),
(false, BigInt!("1")),
(false, BigInt!("91893752504881257701523279626832445441")),
];

fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}

fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}
}

pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);

Expand Down
2 changes: 2 additions & 0 deletions bls12_377/src/curves/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ test_group!(g1; G1Projective; sw);
test_group!(g2; G2Projective; sw);
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bls12_377>; msm);
test_pairing!(pairing; crate::Bls12_377);
test_group!(g1_glv; G1Projective; glv);
test_group!(g2_glv; G2Projective; glv);
test_h2c!(g1_h2c; "./src/curves/tests"; "BLS12377G1"; crate::g1::Config; crate::Fq; crate::Fq; 1);
test_h2c!(g2_hc2; "./src/curves/tests"; "BLS12377G2"; crate::g2::Config; crate::Fq2; crate::Fq; 2);

Expand Down
37 changes: 36 additions & 1 deletion bls12_381/src/curves/g1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ use ark_ec::{
bls12::Bls12Config,
hashing::curve_maps::wb::{IsogenyMap, WBConfig},
models::CurveConfig,
scalar_mul::glv::GLVConfig,
short_weierstrass::{Affine, SWCurveConfig},
AffineRepr, PrimeGroup,
};
use ark_ff::{AdditiveGroup, MontFp, PrimeField, Zero};
use ark_ff::{AdditiveGroup, BigInt, MontFp, PrimeField, Zero};
use ark_serialize::{Compress, SerializationError};
use ark_std::{ops::Neg, One};

Expand Down Expand Up @@ -52,6 +53,12 @@ impl SWCurveConfig for Config {
Self::BaseField::zero()
}

#[inline]
fn mul_projective(p: &G1Projective, scalar: &[u64]) -> G1Projective {
let s = Self::ScalarField::from_sign_and_limbs(true, scalar);
GLVConfig::glv_mul_projective(*p, s)
}

#[inline]
fn is_in_correct_subgroup_assuming_on_curve(p: &G1Affine) -> bool {
// Algorithm from Section 6 of https://eprint.iacr.org/2021/1130.
Expand Down Expand Up @@ -142,6 +149,34 @@ impl SWCurveConfig for Config {
}
}

impl GLVConfig for Config {
const ENDO_COEFFS: &'static[Self::BaseField] = &[
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350")
];

const LAMBDA: Self::ScalarField =
MontFp!("52435875175126190479447740508185965837461563690374988244538805122978187051009");

const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
(true, BigInt!("228988810152649578064853576960394133504")),
(true, BigInt!("1")),
(false, BigInt!("1")),
(true, BigInt!("228988810152649578064853576960394133503")),
];

fn endomorphism(p: &G1Projective) -> G1Projective {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}

fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}
}

fn one_minus_x() -> Fr {
const X: Fr = Fr::from_sign_and_limbs(!crate::Config::X_IS_NEGATIVE, crate::Config::X);
Fr::one() - X
Expand Down
33 changes: 32 additions & 1 deletion bls12_381/src/curves/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ use ark_ec::{
bls12::Bls12Config,
hashing::curve_maps::wb::{IsogenyMap, WBConfig},
models::CurveConfig,
scalar_mul::glv::GLVConfig,
short_weierstrass::{Affine, Projective, SWCurveConfig},
AffineRepr, CurveGroup, PrimeGroup,
};
use ark_ff::{AdditiveGroup, Field, MontFp, Zero};
use ark_ff::{AdditiveGroup, BigInt, Field, MontFp, PrimeField, Zero};
use ark_serialize::{Compress, SerializationError};

use super::{
Expand Down Expand Up @@ -185,6 +186,36 @@ impl SWCurveConfig for Config {
}
}

impl GLVConfig for Config {
const ENDO_COEFFS: &'static[Self::BaseField] = &[
Fq2::new(
MontFp!("793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350"),
Fq::ZERO
)
];

const LAMBDA: Self::ScalarField = MontFp!("228988810152649578064853576960394133503");

const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
(false, BigInt!("228988810152649578064853576960394133503")),
(true, BigInt!("1")),
(false, BigInt!("1")),
(false, BigInt!("228988810152649578064853576960394133504")),
];

fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}

fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}
}

pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);

Expand Down
2 changes: 2 additions & 0 deletions bls12_381/src/curves/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use crate::{Bls12_381, Fq, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projecti

test_group!(g1; G1Projective; sw);
test_group!(g2; G2Projective; sw);
test_group!(g1_glv; G1Projective; glv);
test_group!(g2_glv; G2Projective; glv);
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bls12_381>; msm);
test_pairing!(pairing; crate::Bls12_381);
test_h2c!(g1_h2c; "./src/curves/tests"; "BLS12381G1"; crate::g1::Config; crate::Fq; crate::Fq; 1);
Expand Down
42 changes: 40 additions & 2 deletions bn254/src/curves/g1.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use ark_ec::{
bn,
models::{short_weierstrass::SWCurveConfig, CurveConfig},
short_weierstrass::Affine,
scalar_mul::glv::GLVConfig,
short_weierstrass::{Affine, Projective},
};
use ark_ff::{AdditiveGroup, Field, MontFp, Zero};
use ark_ff::{AdditiveGroup, BigInt, Field, MontFp, PrimeField, Zero};

use crate::{Fq, Fr};

Expand Down Expand Up @@ -36,6 +38,42 @@ impl SWCurveConfig for Config {
fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
Self::BaseField::zero()
}

#[inline]
fn mul_projective(
p: &bn::G1Projective<crate::Config>,
scalar: &[u64],
) -> bn::G1Projective<crate::Config> {
let s = Self::ScalarField::from_sign_and_limbs(true, scalar);
GLVConfig::glv_mul_projective(*p, s)
}
}

impl GLVConfig for Config {
const ENDO_COEFFS: &'static [Self::BaseField] = &[MontFp!(
"21888242871839275220042445260109153167277707414472061641714758635765020556616"
)];

const LAMBDA: Self::ScalarField =
MontFp!("21888242871839275217838484774961031246154997185409878258781734729429964517155");

const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
(false, BigInt!("147946756881789319000765030803803410728")),
(true, BigInt!("9931322734385697763")),
(false, BigInt!("9931322734385697763")),
(false, BigInt!("147946756881789319010696353538189108491")),
];

fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}
fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}
}

/// G1_GENERATOR_X = 1
Expand Down
34 changes: 32 additions & 2 deletions bn254/src/curves/g2.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use ark_ec::{
models::{short_weierstrass::SWCurveConfig, CurveConfig},
short_weierstrass::Affine,
scalar_mul::glv::GLVConfig,
short_weierstrass::{Affine, Projective},
};
use ark_ff::{AdditiveGroup, MontFp, Zero};
use ark_ff::{AdditiveGroup, BigInt, MontFp, PrimeField, Zero};

use crate::{Fq, Fq2, Fr};

Expand Down Expand Up @@ -50,6 +51,35 @@ impl SWCurveConfig for Config {
}
}

impl GLVConfig for Config {
const ENDO_COEFFS: &'static [Self::BaseField] = &[Fq2::new(
MontFp!("21888242871839275220042445260109153167277707414472061641714758635765020556616"),
Fq::ZERO,
)];

const LAMBDA: Self::ScalarField =
MontFp!("4407920970296243842393367215006156084916469457145843978461");

const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
(false, BigInt!("147946756881789319010696353538189108491")),
(false, BigInt!("9931322734385697763")),
(true, BigInt!("9931322734385697763")),
(false, BigInt!("147946756881789319000765030803803410728")),
];

fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}

fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
let mut res = (*p).clone();
res.x *= Self::ENDO_COEFFS[0];
res
}
}

pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);

Expand Down
2 changes: 2 additions & 0 deletions bn254/src/curves/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ test_group!(g1; G1Projective; sw);
test_group!(g2; G2Projective; sw);
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bn254>; msm);
test_pairing!(pairing; crate::Bn254);
test_group!(g1_glv; G1Projective; glv);
test_group!(g2_glv; G2Projective; glv);
Loading
Loading