Use Scott's subgroup membership tests for G1 and G2 of BLS12-381. (#74)

* implementation of the fast subgroup check for bls12_381

* add a bench

* subgroup check for g1

* subgroup check modifications

* remove useless test

* fmt

* need the last version of arkworks/algebra

* remove Parameters0

* using projective points is more efficient

* use of projective coordinates in G2

* fmt

* documentation on the constants and the psi function

* references for algorithms of eprint 2021/1130

* fmt

* sed ^ **

* minor improvement

* fmt

* fix Cargo toml

* nits

* some cleanup for g1

* add the beta test back

* fmt

* g2

* changelog

* add a  note on the Cargo.toml

* nits

* avoid variable name conflicts

* add the early-out optimization

Co-authored-by: weikeng <w.k@berkeley.edu>
This commit is contained in:
Simon Masson
2021-09-25 19:34:13 +02:00
committed by GitHub
parent b5c2d8eba3
commit 2118e14b6a
6 changed files with 196 additions and 4 deletions

View File

@@ -1,9 +1,13 @@
use crate::*;
use ark_ec::{
bls12,
bls12::Bls12Parameters,
models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::GroupAffine,
AffineCurve, ProjectiveCurve,
};
use ark_ff::{field_new, Zero};
use ark_ff::{biginteger::BigInteger256, field_new, Zero};
use ark_std::ops::Neg;
pub type G1Affine = bls12::G1Affine<crate::Parameters>;
pub type G1Projective = bls12::G1Projective<crate::Parameters>;
@@ -40,6 +44,25 @@ impl SWModelParameters for Parameters {
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
Self::BaseField::zero()
}
fn is_in_correct_subgroup_assuming_on_curve(p: &GroupAffine<Parameters>) -> bool {
// Algorithm from Section 6 of https://eprint.iacr.org/2021/1130.
//
// Check that endomorphism_p(P) == -[X^2]P
let x = BigInteger256::new([crate::Parameters::X[0], 0, 0, 0]);
// An early-out optimization described in Section 6.
// If uP == P but P != point of infinity, then the point is not in the right subgroup.
let x_times_p = p.mul(x);
if x_times_p.eq(p) && !p.infinity {
return false;
}
let minus_x_squared_times_p = x_times_p.mul(x).neg();
let endomorphism_p = endomorphism(p);
minus_x_squared_times_p.eq(&endomorphism_p)
}
}
/// G1_GENERATOR_X =
@@ -51,3 +74,14 @@ pub const G1_GENERATOR_X: Fq = field_new!(Fq, "368541675371338701678108831518307
/// 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
#[rustfmt::skip]
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569");
/// BETA is a non-trivial cubic root of unity in Fq.
pub const BETA: Fq = field_new!(Fq, "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350");
pub fn endomorphism(p: &GroupAffine<Parameters>) -> GroupAffine<Parameters> {
// Endomorphism of the points on the curve.
// endomorphism_p(x,y) = (BETA * x, y) where BETA is a non-trivial cubic root of unity in Fq.
let mut res = (*p).clone();
res.x *= BETA;
res
}