diff --git a/ecc/bls12-377/g1.go b/ecc/bls12-377/g1.go index f1af624908..6ea356afd5 100644 --- a/ecc/bls12-377/g1.go +++ b/ecc/bls12-377/g1.go @@ -138,7 +138,7 @@ func (p *G1Affine) IsOnCurve() bool { func (p *G1Affine) IsInSubGroup() bool { var _p G1Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bls12-377/g2.go b/ecc/bls12-377/g2.go index eee7d706ea..ad1d9137b8 100644 --- a/ecc/bls12-377/g2.go +++ b/ecc/bls12-377/g2.go @@ -143,7 +143,7 @@ func (p *G2Affine) IsOnCurve() bool { func (p *G2Affine) IsInSubGroup() bool { var _p G2Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bls12-381/g1.go b/ecc/bls12-381/g1.go index 57840c4453..3b1b93ac6d 100644 --- a/ecc/bls12-381/g1.go +++ b/ecc/bls12-381/g1.go @@ -138,7 +138,7 @@ func (p *G1Affine) IsOnCurve() bool { func (p *G1Affine) IsInSubGroup() bool { var _p G1Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bls12-381/g2.go b/ecc/bls12-381/g2.go index d737adcff0..8931a993b5 100644 --- a/ecc/bls12-381/g2.go +++ b/ecc/bls12-381/g2.go @@ -143,7 +143,7 @@ func (p *G2Affine) IsOnCurve() bool { func (p *G2Affine) IsInSubGroup() bool { var _p G2Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bls24-315/g1.go b/ecc/bls24-315/g1.go index 45f4065127..5e0060fd22 100644 --- a/ecc/bls24-315/g1.go +++ b/ecc/bls24-315/g1.go @@ -138,7 +138,7 @@ func (p *G1Affine) IsOnCurve() bool { func (p *G1Affine) IsInSubGroup() bool { var _p G1Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bls24-315/g2.go b/ecc/bls24-315/g2.go index 5884e171a6..7cdf2cc571 100644 --- a/ecc/bls24-315/g2.go +++ b/ecc/bls24-315/g2.go @@ -143,7 +143,7 @@ func (p *G2Affine) IsOnCurve() bool { func (p *G2Affine) IsInSubGroup() bool { var _p G2Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bn254/bn254.go b/ecc/bn254/bn254.go index ed5a3f0011..c476c70ab0 100644 --- a/ecc/bn254/bn254.go +++ b/ecc/bn254/bn254.go @@ -66,6 +66,9 @@ var endo struct { // generator of the curve var xGen big.Int +// fixefCoeff t-1 = 6*xGen^2 +var fixedCoeff big.Int + func init() { bCurveCoeff.SetUint64(3) @@ -109,6 +112,8 @@ func init() { xGen.SetString("4965661367192848881", 10) + fixedCoeff.SetString("147946756881789318990833708069417712966", 10) + } // Generators return the generators of the r-torsion group, resp. in ker(pi-id), ker(Tr) diff --git a/ecc/bn254/g1.go b/ecc/bn254/g1.go index 36c2533ec0..bfd5f762ec 100644 --- a/ecc/bn254/g1.go +++ b/ecc/bn254/g1.go @@ -138,7 +138,7 @@ func (p *G1Affine) IsOnCurve() bool { func (p *G1Affine) IsInSubGroup() bool { var _p G1Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bn254/g2.go b/ecc/bn254/g2.go index 5dfda316e9..dd2eafa81f 100644 --- a/ecc/bn254/g2.go +++ b/ecc/bn254/g2.go @@ -143,7 +143,7 @@ func (p *G2Affine) IsOnCurve() bool { func (p *G2Affine) IsInSubGroup() bool { var _p G2Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- @@ -372,20 +372,15 @@ func (p *G2Jac) IsOnCurve() bool { } // IsInSubGroup returns true if p is on the r-torsion, false otherwise. -// Z[r,0]+Z[-lambdaG2Affine, 1] is the kernel -// of (u,v)->u+lambdaG2Affinev mod r. Expressing r, lambdaG2Affine as -// polynomials in x, a short vector of this Zmodule is -// (4x+2), (-12x**2+4*x). So we check that (4x+2)p+(-12x**2+4*x)phi(p) -// is the infinity. +// [r]P == 0 <==> Frob(P) == [6x^2]P func (p *G2Jac) IsInSubGroup() bool { + var a, res G2Jac + a.X.Conjugate(&p.X).MulByNonResidue1Power2(&a.X) + a.Y.Conjugate(&p.Y).MulByNonResidue1Power3(&a.Y) + a.Z.Conjugate(&p.Z) - var res, xphip, phip G2Jac - phip.phi(p) - xphip.ScalarMultiplication(&phip, &xGen) // x*phi(p) - res.Double(&xphip).AddAssign(&xphip) // 3x*phi(p) - res.AddAssign(&phip).SubAssign(p) // 3x*phi(p)+phi(p)-p - res.Double(&res).ScalarMultiplication(&res, &xGen) // 6x**2*phi(p)+2x*phi(p)-2x*p - res.SubAssign(p).Double(&res) // 12x**2*phi(p)+4x*phi(p)-4x*p-2p + res.ScalarMultiplication(p, &fixedCoeff). + SubAssign(&a) return res.IsOnCurve() && res.Z.IsZero() diff --git a/ecc/bw6-633/g1.go b/ecc/bw6-633/g1.go index 0e4b490ba4..331595b877 100644 --- a/ecc/bw6-633/g1.go +++ b/ecc/bw6-633/g1.go @@ -143,7 +143,7 @@ func (p *G1Affine) IsOnCurve() bool { func (p *G1Affine) IsInSubGroup() bool { var _p G1Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bw6-633/g2.go b/ecc/bw6-633/g2.go index 9cfdf85893..58b26377bd 100644 --- a/ecc/bw6-633/g2.go +++ b/ecc/bw6-633/g2.go @@ -138,7 +138,7 @@ func (p *G2Affine) IsOnCurve() bool { func (p *G2Affine) IsInSubGroup() bool { var _p G2Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bw6-761/g1.go b/ecc/bw6-761/g1.go index 92be70bd2c..fe109dfd7c 100644 --- a/ecc/bw6-761/g1.go +++ b/ecc/bw6-761/g1.go @@ -143,7 +143,7 @@ func (p *G1Affine) IsOnCurve() bool { func (p *G1Affine) IsInSubGroup() bool { var _p G1Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/ecc/bw6-761/g2.go b/ecc/bw6-761/g2.go index 90e6fadaec..5e4e0370e7 100644 --- a/ecc/bw6-761/g2.go +++ b/ecc/bw6-761/g2.go @@ -138,7 +138,7 @@ func (p *G2Affine) IsOnCurve() bool { func (p *G2Affine) IsInSubGroup() bool { var _p G2Jac _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } // ------------------------------------------------------------------------------------------------- diff --git a/internal/generator/ecc/template/point.go.tmpl b/internal/generator/ecc/template/point.go.tmpl index 647f7832e9..502148b598 100644 --- a/internal/generator/ecc/template/point.go.tmpl +++ b/internal/generator/ecc/template/point.go.tmpl @@ -147,7 +147,7 @@ func (p *{{ $TAffine }}) IsOnCurve() bool { func (p *{{ $TAffine }}) IsInSubGroup() bool { var _p {{ $TJacobian }} _p.FromAffine(p) - return _p.IsOnCurve() && _p.IsInSubGroup() + return _p.IsInSubGroup() } @@ -402,20 +402,15 @@ func (p *{{ $TJacobian }}) IsOnCurve() bool { } {{else if eq .PointName "g2"}} // IsInSubGroup returns true if p is on the r-torsion, false otherwise. - // Z[r,0]+Z[-lambda{{ $TAffine }}, 1] is the kernel - // of (u,v)->u+lambda{{ $TAffine }}v mod r. Expressing r, lambda{{ $TAffine }} as - // polynomials in x, a short vector of this Zmodule is - // (4x+2), (-12x**2+4*x). So we check that (4x+2)p+(-12x**2+4*x)phi(p) - // is the infinity. + // [r]P == 0 <==> Frob(P) == [6x^2]P func (p *{{ $TJacobian }}) IsInSubGroup() bool { + var a, res G2Jac + a.X.Conjugate(&p.X).MulByNonResidue1Power2(&a.X) + a.Y.Conjugate(&p.Y).MulByNonResidue1Power3(&a.Y) + a.Z.Conjugate(&p.Z) - var res, xphip, phip {{ $TJacobian }} - phip.phi(p) - xphip.ScalarMultiplication(&phip, &xGen) // x*phi(p) - res.Double(&xphip).AddAssign(&xphip) // 3x*phi(p) - res.AddAssign(&phip).SubAssign(p) // 3x*phi(p)+phi(p)-p - res.Double(&res).ScalarMultiplication(&res, &xGen) // 6x**2*phi(p)+2x*phi(p)-2x*p - res.SubAssign(p).Double(&res) // 12x**2*phi(p)+4x*phi(p)-4x*p-2p + res.ScalarMultiplication(p, &fixedCoeff). + SubAssign(&a) return res.IsOnCurve() && res.Z.IsZero()