From 2109768848f1880ccd9ca547bf0ad632cad92e5b Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Fri, 7 Mar 2025 12:51:27 -0500 Subject: [PATCH 1/5] test(bn254, bls12-381): test points intentionally not on sugroups G1/2 --- ecc/bls12-377/g1_test.go | 10 +-- ecc/bls12-377/g2_test.go | 10 +-- ecc/bls12-381/g1_test.go | 29 +++++++-- ecc/bls12-381/g2_test.go | 28 +++++++-- ecc/bls24-315/g1_test.go | 10 +-- ecc/bls24-315/g2_test.go | 10 +-- ecc/bls24-317/g1_test.go | 10 +-- ecc/bls24-317/g2_test.go | 10 +-- ecc/bn254/g1_test.go | 8 +-- ecc/bn254/g2_test.go | 27 ++++++-- ecc/bw6-633/g1_test.go | 10 +-- ecc/bw6-633/g2_test.go | 10 +-- ecc/bw6-761/g1_test.go | 10 +-- ecc/bw6-761/g2_test.go | 10 +-- ecc/grumpkin/g1_test.go | 8 +-- ecc/secp256k1/g1_test.go | 8 +-- .../ecc/template/tests/point.go.tmpl | 63 +++++++++++++++++-- 17 files changed, 189 insertions(+), 82 deletions(-) diff --git a/ecc/bls12-377/g1_test.go b/ecc/bls12-377/g1_test.go index f32180292..442b68e74 100644 --- a/ecc/bls12-377/g1_test.go +++ b/ecc/bls12-377/g1_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG1AffineEndomorphism(t *testing.T) { +func TestG1Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG1AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineIsOnCurve(t *testing.T) { +func TestIsOnG1(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -109,7 +109,7 @@ func TestG1AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineConversions(t *testing.T) { +func TestG1Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -499,7 +499,7 @@ func TestG1AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineCofactorCleaning(t *testing.T) { +func TestG1CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -538,7 +538,7 @@ func TestG1AffineCofactorCleaning(t *testing.T) { } -func TestG1AffineBatchScalarMultiplication(t *testing.T) { +func TestG1BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bls12-377/g2_test.go b/ecc/bls12-377/g2_test.go index eba5190a5..32ca456e7 100644 --- a/ecc/bls12-377/g2_test.go +++ b/ecc/bls12-377/g2_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG2AffineEndomorphism(t *testing.T) { +func TestG2Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -74,7 +74,7 @@ func TestG2AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineIsOnCurve(t *testing.T) { +func TestIsOnG2(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -123,7 +123,7 @@ func TestG2AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineConversions(t *testing.T) { +func TestG2Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -491,7 +491,7 @@ func TestG2AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineCofactorCleaning(t *testing.T) { +func TestG2CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -527,7 +527,7 @@ func TestG2AffineCofactorCleaning(t *testing.T) { } -func TestG2AffineBatchScalarMultiplication(t *testing.T) { +func TestG2BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bls12-381/g1_test.go b/ecc/bls12-381/g1_test.go index c705b7a67..e0fc16777 100644 --- a/ecc/bls12-381/g1_test.go +++ b/ecc/bls12-381/g1_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG1AffineEndomorphism(t *testing.T) { +func TestG1Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG1AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineIsOnCurve(t *testing.T) { +func TestIsOnG1(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -105,11 +105,18 @@ func TestG1AffineIsOnCurve(t *testing.T) { }, GenFp(), )) + properties.Property("[BLS12-381] IsInSubGroup should return false for a point on the cofactor-torsion", prop.ForAll( + func(a fp.Element) bool { + op := fuzzCofactorOfG1Jac(a) + return op.IsOnCurve() && !op.IsInSubGroup() + }, + GenFp(), + )) properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineConversions(t *testing.T) { +func TestG1Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -499,7 +506,7 @@ func TestG1AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineCofactorCleaning(t *testing.T) { +func TestG1CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -538,7 +545,7 @@ func TestG1AffineCofactorCleaning(t *testing.T) { } -func TestG1AffineBatchScalarMultiplication(t *testing.T) { +func TestG1BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -852,6 +859,18 @@ func BenchmarkG1AffineDouble(b *testing.B) { a.Double(&a) } } +func fuzzCofactorOfG1Jac(f fp.Element) G1Jac { + var res, jac G1Jac + aff := MapToCurve1(&f) + g1Isogeny(&aff) + jac.FromAffine(&aff) + // p+x²ϕ(p) = [r]p + res.phi(&jac). + mulBySeed(&res). + mulBySeed(&res). + AddAssign(&jac) + return res +} func fuzzG1Jac(p *G1Jac, f fp.Element) G1Jac { var res G1Jac diff --git a/ecc/bls12-381/g2_test.go b/ecc/bls12-381/g2_test.go index 45753354c..d3c4c5fdf 100644 --- a/ecc/bls12-381/g2_test.go +++ b/ecc/bls12-381/g2_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG2AffineEndomorphism(t *testing.T) { +func TestG2Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -74,7 +74,7 @@ func TestG2AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineIsOnCurve(t *testing.T) { +func TestIsOnG2(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -119,11 +119,18 @@ func TestG2AffineIsOnCurve(t *testing.T) { }, GenE2(), )) + properties.Property("[BLS12-381] IsInSubGroup should return false for a point on the cofactor-torsion", prop.ForAll( + func(a fptower.E2) bool { + op := fuzzCofactorOfG2Jac(a) + return op.IsOnCurve() && !op.IsInSubGroup() + }, + GenE2(), + )) properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineConversions(t *testing.T) { +func TestG2Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -491,7 +498,7 @@ func TestG2AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineCofactorCleaning(t *testing.T) { +func TestG2CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -527,7 +534,7 @@ func TestG2AffineCofactorCleaning(t *testing.T) { } -func TestG2AffineBatchScalarMultiplication(t *testing.T) { +func TestG2BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -841,6 +848,17 @@ func BenchmarkG2AffineDouble(b *testing.B) { a.Double(&a) } } +func fuzzCofactorOfG2Jac(f fptower.E2) G2Jac { + var res, jac G2Jac + aff := MapToCurve2(&f) + g2Isogeny(&aff) + jac.FromAffine(&aff) + // ψ(p)-[x₀]P = [r]p + res.mulBySeed(&jac) + jac.psi(&jac) + res.AddAssign(&jac) + return res +} func fuzzG2Jac(p *G2Jac, f fptower.E2) G2Jac { var res G2Jac diff --git a/ecc/bls24-315/g1_test.go b/ecc/bls24-315/g1_test.go index 8cfd54e14..9a5003907 100644 --- a/ecc/bls24-315/g1_test.go +++ b/ecc/bls24-315/g1_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG1AffineEndomorphism(t *testing.T) { +func TestG1Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG1AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineIsOnCurve(t *testing.T) { +func TestIsOnG1(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -109,7 +109,7 @@ func TestG1AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineConversions(t *testing.T) { +func TestG1Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -499,7 +499,7 @@ func TestG1AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineCofactorCleaning(t *testing.T) { +func TestG1CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -538,7 +538,7 @@ func TestG1AffineCofactorCleaning(t *testing.T) { } -func TestG1AffineBatchScalarMultiplication(t *testing.T) { +func TestG1BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bls24-315/g2_test.go b/ecc/bls24-315/g2_test.go index b748c00f6..1dec0cd03 100644 --- a/ecc/bls24-315/g2_test.go +++ b/ecc/bls24-315/g2_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG2AffineEndomorphism(t *testing.T) { +func TestG2Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -74,7 +74,7 @@ func TestG2AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineIsOnCurve(t *testing.T) { +func TestIsOnG2(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -123,7 +123,7 @@ func TestG2AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineConversions(t *testing.T) { +func TestG2Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -491,7 +491,7 @@ func TestG2AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineCofactorCleaning(t *testing.T) { +func TestG2CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -527,7 +527,7 @@ func TestG2AffineCofactorCleaning(t *testing.T) { } -func TestG2AffineBatchScalarMultiplication(t *testing.T) { +func TestG2BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bls24-317/g1_test.go b/ecc/bls24-317/g1_test.go index 647f6a6c4..8ff80d660 100644 --- a/ecc/bls24-317/g1_test.go +++ b/ecc/bls24-317/g1_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG1AffineEndomorphism(t *testing.T) { +func TestG1Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG1AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineIsOnCurve(t *testing.T) { +func TestIsOnG1(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -109,7 +109,7 @@ func TestG1AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineConversions(t *testing.T) { +func TestG1Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -499,7 +499,7 @@ func TestG1AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineCofactorCleaning(t *testing.T) { +func TestG1CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -538,7 +538,7 @@ func TestG1AffineCofactorCleaning(t *testing.T) { } -func TestG1AffineBatchScalarMultiplication(t *testing.T) { +func TestG1BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bls24-317/g2_test.go b/ecc/bls24-317/g2_test.go index 8d4e7aca3..ffb56ab7e 100644 --- a/ecc/bls24-317/g2_test.go +++ b/ecc/bls24-317/g2_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG2AffineEndomorphism(t *testing.T) { +func TestG2Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -74,7 +74,7 @@ func TestG2AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineIsOnCurve(t *testing.T) { +func TestIsOnG2(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -123,7 +123,7 @@ func TestG2AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineConversions(t *testing.T) { +func TestG2Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -491,7 +491,7 @@ func TestG2AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineCofactorCleaning(t *testing.T) { +func TestG2CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -527,7 +527,7 @@ func TestG2AffineCofactorCleaning(t *testing.T) { } -func TestG2AffineBatchScalarMultiplication(t *testing.T) { +func TestG2BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bn254/g1_test.go b/ecc/bn254/g1_test.go index a489fec09..d97c98dd6 100644 --- a/ecc/bn254/g1_test.go +++ b/ecc/bn254/g1_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG1AffineEndomorphism(t *testing.T) { +func TestG1Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG1AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineIsOnCurve(t *testing.T) { +func TestIsOnG1(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -109,7 +109,7 @@ func TestG1AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineConversions(t *testing.T) { +func TestG1Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -499,7 +499,7 @@ func TestG1AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineBatchScalarMultiplication(t *testing.T) { +func TestG1BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bn254/g2_test.go b/ecc/bn254/g2_test.go index eb6b67164..0e37bb478 100644 --- a/ecc/bn254/g2_test.go +++ b/ecc/bn254/g2_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG2AffineEndomorphism(t *testing.T) { +func TestG2Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -73,7 +73,7 @@ func TestG2AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineIsOnCurve(t *testing.T) { +func TestIsOnG2(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -122,7 +122,7 @@ func TestG2AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineConversions(t *testing.T) { +func TestG2Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -490,7 +490,7 @@ func TestG2AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineCofactorCleaning(t *testing.T) { +func TestG2CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -526,7 +526,7 @@ func TestG2AffineCofactorCleaning(t *testing.T) { } -func TestG2AffineBatchScalarMultiplication(t *testing.T) { +func TestG2BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -840,6 +840,23 @@ func BenchmarkG2AffineDouble(b *testing.B) { a.Double(&a) } } +func fuzzCofactorOfG2Jac(f fptower.E2) G2Jac { + var res, jac, a, b, c G2Jac + aff := MapToCurve2(&f) + jac.FromAffine(&aff) + // [x₀+1]P + ψ([x₀]P) + ψ²([x₀]P) - ψ³([2x₀]P) = [r]P + a.mulBySeed(&jac) + b.psi(&a) + a.AddAssign(&jac) + res.psi(&b) + c.Set(&res). + AddAssign(&b). + AddAssign(&a) + res.psi(&res). + Double(&res). + SubAssign(&c) + return res +} func fuzzG2Jac(p *G2Jac, f fptower.E2) G2Jac { var res G2Jac diff --git a/ecc/bw6-633/g1_test.go b/ecc/bw6-633/g1_test.go index 59d10ffea..4a33d0362 100644 --- a/ecc/bw6-633/g1_test.go +++ b/ecc/bw6-633/g1_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG1AffineEndomorphism(t *testing.T) { +func TestG1Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG1AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineIsOnCurve(t *testing.T) { +func TestIsOnG1(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -109,7 +109,7 @@ func TestG1AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineConversions(t *testing.T) { +func TestG1Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -499,7 +499,7 @@ func TestG1AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineCofactorCleaning(t *testing.T) { +func TestG1CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -538,7 +538,7 @@ func TestG1AffineCofactorCleaning(t *testing.T) { } -func TestG1AffineBatchScalarMultiplication(t *testing.T) { +func TestG1BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bw6-633/g2_test.go b/ecc/bw6-633/g2_test.go index 0d3ca6317..f957217a6 100644 --- a/ecc/bw6-633/g2_test.go +++ b/ecc/bw6-633/g2_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG2AffineEndomorphism(t *testing.T) { +func TestG2Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG2AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineIsOnCurve(t *testing.T) { +func TestIsOnG2(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -109,7 +109,7 @@ func TestG2AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineConversions(t *testing.T) { +func TestG2Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -469,7 +469,7 @@ func TestG2AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineCofactorCleaning(t *testing.T) { +func TestG2CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -508,7 +508,7 @@ func TestG2AffineCofactorCleaning(t *testing.T) { } -func TestG2AffineBatchScalarMultiplication(t *testing.T) { +func TestG2BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bw6-761/g1_test.go b/ecc/bw6-761/g1_test.go index fd81b0ffe..55374561f 100644 --- a/ecc/bw6-761/g1_test.go +++ b/ecc/bw6-761/g1_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG1AffineEndomorphism(t *testing.T) { +func TestG1Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG1AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineIsOnCurve(t *testing.T) { +func TestIsOnG1(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -109,7 +109,7 @@ func TestG1AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineConversions(t *testing.T) { +func TestG1Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -499,7 +499,7 @@ func TestG1AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineCofactorCleaning(t *testing.T) { +func TestG1CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -538,7 +538,7 @@ func TestG1AffineCofactorCleaning(t *testing.T) { } -func TestG1AffineBatchScalarMultiplication(t *testing.T) { +func TestG1BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/bw6-761/g2_test.go b/ecc/bw6-761/g2_test.go index 92555681b..d4fb02f4d 100644 --- a/ecc/bw6-761/g2_test.go +++ b/ecc/bw6-761/g2_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG2AffineEndomorphism(t *testing.T) { +func TestG2Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG2AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineIsOnCurve(t *testing.T) { +func TestIsOnG2(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -109,7 +109,7 @@ func TestG2AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineConversions(t *testing.T) { +func TestG2Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -469,7 +469,7 @@ func TestG2AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG2AffineCofactorCleaning(t *testing.T) { +func TestG2CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -508,7 +508,7 @@ func TestG2AffineCofactorCleaning(t *testing.T) { } -func TestG2AffineBatchScalarMultiplication(t *testing.T) { +func TestG2BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/grumpkin/g1_test.go b/ecc/grumpkin/g1_test.go index bb1111e97..0f311a21e 100644 --- a/ecc/grumpkin/g1_test.go +++ b/ecc/grumpkin/g1_test.go @@ -18,7 +18,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG1AffineEndomorphism(t *testing.T) { +func TestG1Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -60,7 +60,7 @@ func TestG1AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineIsOnCurve(t *testing.T) { +func TestIsOnG1(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -109,7 +109,7 @@ func TestG1AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineConversions(t *testing.T) { +func TestG1Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -499,7 +499,7 @@ func TestG1AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineBatchScalarMultiplication(t *testing.T) { +func TestG1BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/ecc/secp256k1/g1_test.go b/ecc/secp256k1/g1_test.go index aee07c948..2800422c2 100644 --- a/ecc/secp256k1/g1_test.go +++ b/ecc/secp256k1/g1_test.go @@ -20,7 +20,7 @@ import ( "github.com/leanovate/gopter/prop" ) -func TestG1AffineEndomorphism(t *testing.T) { +func TestG1Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -62,7 +62,7 @@ func TestG1AffineEndomorphism(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineIsOnCurve(t *testing.T) { +func TestIsOnG1(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -111,7 +111,7 @@ func TestG1AffineIsOnCurve(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineConversions(t *testing.T) { +func TestG1Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -501,7 +501,7 @@ func TestG1AffineOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func TestG1AffineBatchScalarMultiplication(t *testing.T) { +func TestG1BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { diff --git a/internal/generator/ecc/template/tests/point.go.tmpl b/internal/generator/ecc/template/tests/point.go.tmpl index 1cbc95303..ea4d50d34 100644 --- a/internal/generator/ecc/template/tests/point.go.tmpl +++ b/internal/generator/ecc/template/tests/point.go.tmpl @@ -36,7 +36,7 @@ import ( ) {{if .GLV}} - func Test{{ $TAffine }}Endomorphism(t *testing.T) { + func Test{{ toUpper .PointName }}Endomorphism(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -104,7 +104,7 @@ import ( } {{end}} -func Test{{ $TAffine }}IsOnCurve(t *testing.T) { +func TestIsOn{{ toUpper .PointName }}(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -150,11 +150,21 @@ func Test{{ $TAffine }}IsOnCurve(t *testing.T) { {{$fuzzer}}, )) + {{- if eq .Name "bls12-381"}} + properties.Property("[{{ toUpper .Name }}] IsInSubGroup should return false for a point on the cofactor-torsion", prop.ForAll( + func(a {{ .CoordType}}) bool { + op := fuzzCofactorOf{{ $TJacobian }}(a) + return op.IsOnCurve() && !op.IsInSubGroup() + }, + {{$fuzzer}}, + )) + {{- end}} + properties.TestingRun(t, gopter.ConsoleReporter(false)) } -func Test{{ $TAffine }}Conversions(t *testing.T) { +func Test{{ toUpper .PointName }}Conversions(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -569,7 +579,7 @@ func Test{{ $TAffine }}Ops(t *testing.T) { {{if .CofactorCleaning }} -func Test{{ $TAffine }}CofactorCleaning(t *testing.T) { +func Test{{ toUpper .PointName }}CofactorClearing(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -621,7 +631,7 @@ func Test{{ $TAffine }}CofactorCleaning(t *testing.T) { } {{end}} -func Test{{ $TAffine }}BatchScalarMultiplication(t *testing.T) { +func Test{{ toUpper .PointName }}BatchScalarMultiplication(t *testing.T) { parameters := gopter.DefaultTestParameters() if testing.Short() { @@ -941,6 +951,49 @@ func Benchmark{{ toUpper .PointName}}AffineDouble(b *testing.B) { } } +{{- if eq .Name "bls12-381"}} +func fuzzCofactorOf{{ $TJacobian }}(f {{ .CoordType}}) {{ $TJacobian }} { + var res, jac {{ $TJacobian }} + {{- if eq .PointName "g1" }} + aff := MapToCurve1(&f) + g1Isogeny(&aff) + jac.FromAffine(&aff) + // p+x²ϕ(p) = [r]p + res.phi(&jac). + mulBySeed(&res). + mulBySeed(&res). + AddAssign(&jac) + {{- else}} + aff := MapToCurve2(&f) + g2Isogeny(&aff) + jac.FromAffine(&aff) + // ψ(p)-[x₀]P = [r]p + res.mulBySeed(&jac) + jac.psi(&jac) + res.AddAssign(&jac) + {{- end}} + return res +} +{{- else if and (eq .Name "bn254") (eq .PointName "g2")}} +func fuzzCofactorOf{{ $TJacobian }}(f {{ .CoordType}}) {{ $TJacobian }} { + var res, jac, a, b, c {{ $TJacobian }} + aff := MapToCurve2(&f) + jac.FromAffine(&aff) + // [x₀+1]P + ψ([x₀]P) + ψ²([x₀]P) - ψ³([2x₀]P) = [r]P + a.mulBySeed(&jac) + b.psi(&a) + a.AddAssign(&jac) + res.psi(&b) + c.Set(&res). + AddAssign(&b). + AddAssign(&a) + res.psi(&res). + Double(&res). + SubAssign(&c) + return res +} +{{- end}} + func fuzz{{ $TJacobian }}(p *{{ $TJacobian }}, f {{ .CoordType}}) {{ $TJacobian }} { var res {{ $TJacobian }} res.X.Mul(&p.X, &f).Mul(&res.X, &f) From 9748d142ccf95ba5e4d275dd446bb923467611cb Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Fri, 7 Mar 2025 13:05:42 -0500 Subject: [PATCH 2/5] test(bn254): test points intentionally not on sugroups G2 --- ecc/bn254/g2_test.go | 7 +++++++ internal/generator/ecc/template/tests/point.go.tmpl | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ecc/bn254/g2_test.go b/ecc/bn254/g2_test.go index 0e37bb478..361e20179 100644 --- a/ecc/bn254/g2_test.go +++ b/ecc/bn254/g2_test.go @@ -118,6 +118,13 @@ func TestIsOnG2(t *testing.T) { }, GenE2(), )) + properties.Property("[BN254] IsInSubGroup should return false for a point on the cofactor-torsion", prop.ForAll( + func(a fptower.E2) bool { + op := fuzzCofactorOfG2Jac(a) + return op.IsOnCurve() && !op.IsInSubGroup() + }, + GenE2(), + )) properties.TestingRun(t, gopter.ConsoleReporter(false)) } diff --git a/internal/generator/ecc/template/tests/point.go.tmpl b/internal/generator/ecc/template/tests/point.go.tmpl index ea4d50d34..1a6e17aee 100644 --- a/internal/generator/ecc/template/tests/point.go.tmpl +++ b/internal/generator/ecc/template/tests/point.go.tmpl @@ -150,7 +150,7 @@ func TestIsOn{{ toUpper .PointName }}(t *testing.T) { {{$fuzzer}}, )) - {{- if eq .Name "bls12-381"}} + {{- if or (eq .Name "bls12-381") (and (eq .Name "bn254") (eq .PointName "g2"))}} properties.Property("[{{ toUpper .Name }}] IsInSubGroup should return false for a point on the cofactor-torsion", prop.ForAll( func(a {{ .CoordType}}) bool { op := fuzzCofactorOf{{ $TJacobian }}(a) From 5e222a62ec13e95cb5063465ebc635b56dfb3635 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Sat, 8 Mar 2025 14:20:41 -0500 Subject: [PATCH 3/5] refactor: export GeneratePointNotInG1/2 method --- ecc/bls12-381/g1_test.go | 8 ++++++-- ecc/bls12-381/g2_test.go | 8 ++++++-- ecc/bn254/g2_test.go | 8 ++++++-- .../generator/ecc/template/tests/point.go.tmpl | 16 +++++++++++++--- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/ecc/bls12-381/g1_test.go b/ecc/bls12-381/g1_test.go index e0fc16777..4c313b7e3 100644 --- a/ecc/bls12-381/g1_test.go +++ b/ecc/bls12-381/g1_test.go @@ -107,7 +107,7 @@ func TestIsOnG1(t *testing.T) { )) properties.Property("[BLS12-381] IsInSubGroup should return false for a point on the cofactor-torsion", prop.ForAll( func(a fp.Element) bool { - op := fuzzCofactorOfG1Jac(a) + op := fuzzCofactorOfG1(a) return op.IsOnCurve() && !op.IsInSubGroup() }, GenFp(), @@ -859,7 +859,7 @@ func BenchmarkG1AffineDouble(b *testing.B) { a.Double(&a) } } -func fuzzCofactorOfG1Jac(f fp.Element) G1Jac { +func fuzzCofactorOfG1(f fp.Element) G1Jac { var res, jac G1Jac aff := MapToCurve1(&f) g1Isogeny(&aff) @@ -872,6 +872,10 @@ func fuzzCofactorOfG1Jac(f fp.Element) G1Jac { return res } +func GeneratePointNotInG1(f fp.Element) G1Jac { + return fuzzCofactorOfG1(f) +} + func fuzzG1Jac(p *G1Jac, f fp.Element) G1Jac { var res G1Jac res.X.Mul(&p.X, &f).Mul(&res.X, &f) diff --git a/ecc/bls12-381/g2_test.go b/ecc/bls12-381/g2_test.go index d3c4c5fdf..51c2f61a1 100644 --- a/ecc/bls12-381/g2_test.go +++ b/ecc/bls12-381/g2_test.go @@ -121,7 +121,7 @@ func TestIsOnG2(t *testing.T) { )) properties.Property("[BLS12-381] IsInSubGroup should return false for a point on the cofactor-torsion", prop.ForAll( func(a fptower.E2) bool { - op := fuzzCofactorOfG2Jac(a) + op := fuzzCofactorOfG2(a) return op.IsOnCurve() && !op.IsInSubGroup() }, GenE2(), @@ -848,7 +848,7 @@ func BenchmarkG2AffineDouble(b *testing.B) { a.Double(&a) } } -func fuzzCofactorOfG2Jac(f fptower.E2) G2Jac { +func fuzzCofactorOfG2(f fptower.E2) G2Jac { var res, jac G2Jac aff := MapToCurve2(&f) g2Isogeny(&aff) @@ -860,6 +860,10 @@ func fuzzCofactorOfG2Jac(f fptower.E2) G2Jac { return res } +func GeneratePointNotInG2(f fptower.E2) G2Jac { + return fuzzCofactorOfG2(f) +} + func fuzzG2Jac(p *G2Jac, f fptower.E2) G2Jac { var res G2Jac res.X.Mul(&p.X, &f).Mul(&res.X, &f) diff --git a/ecc/bn254/g2_test.go b/ecc/bn254/g2_test.go index 361e20179..c08ab887d 100644 --- a/ecc/bn254/g2_test.go +++ b/ecc/bn254/g2_test.go @@ -120,7 +120,7 @@ func TestIsOnG2(t *testing.T) { )) properties.Property("[BN254] IsInSubGroup should return false for a point on the cofactor-torsion", prop.ForAll( func(a fptower.E2) bool { - op := fuzzCofactorOfG2Jac(a) + op := fuzzCofactorOfG2(a) return op.IsOnCurve() && !op.IsInSubGroup() }, GenE2(), @@ -847,7 +847,7 @@ func BenchmarkG2AffineDouble(b *testing.B) { a.Double(&a) } } -func fuzzCofactorOfG2Jac(f fptower.E2) G2Jac { +func fuzzCofactorOfG2(f fptower.E2) G2Jac { var res, jac, a, b, c G2Jac aff := MapToCurve2(&f) jac.FromAffine(&aff) @@ -865,6 +865,10 @@ func fuzzCofactorOfG2Jac(f fptower.E2) G2Jac { return res } +func GeneratePointNotInG2(f fptower.E2) G2Jac { + return fuzzCofactorOfG2(f) +} + func fuzzG2Jac(p *G2Jac, f fptower.E2) G2Jac { var res G2Jac res.X.Mul(&p.X, &f).Mul(&res.X, &f) diff --git a/internal/generator/ecc/template/tests/point.go.tmpl b/internal/generator/ecc/template/tests/point.go.tmpl index 1a6e17aee..cfcf37852 100644 --- a/internal/generator/ecc/template/tests/point.go.tmpl +++ b/internal/generator/ecc/template/tests/point.go.tmpl @@ -153,7 +153,7 @@ func TestIsOn{{ toUpper .PointName }}(t *testing.T) { {{- if or (eq .Name "bls12-381") (and (eq .Name "bn254") (eq .PointName "g2"))}} properties.Property("[{{ toUpper .Name }}] IsInSubGroup should return false for a point on the cofactor-torsion", prop.ForAll( func(a {{ .CoordType}}) bool { - op := fuzzCofactorOf{{ $TJacobian }}(a) + op := fuzzCofactorOf{{ toUpper .PointName}}(a) return op.IsOnCurve() && !op.IsInSubGroup() }, {{$fuzzer}}, @@ -952,7 +952,7 @@ func Benchmark{{ toUpper .PointName}}AffineDouble(b *testing.B) { } {{- if eq .Name "bls12-381"}} -func fuzzCofactorOf{{ $TJacobian }}(f {{ .CoordType}}) {{ $TJacobian }} { +func fuzzCofactorOf{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { var res, jac {{ $TJacobian }} {{- if eq .PointName "g1" }} aff := MapToCurve1(&f) @@ -974,8 +974,13 @@ func fuzzCofactorOf{{ $TJacobian }}(f {{ .CoordType}}) {{ $TJacobian }} { {{- end}} return res } + +func GeneratePointNotIn{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { + return fuzzCofactorOf{{ toUpper .PointName}}(f) +} + {{- else if and (eq .Name "bn254") (eq .PointName "g2")}} -func fuzzCofactorOf{{ $TJacobian }}(f {{ .CoordType}}) {{ $TJacobian }} { +func fuzzCofactorOf{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { var res, jac, a, b, c {{ $TJacobian }} aff := MapToCurve2(&f) jac.FromAffine(&aff) @@ -992,6 +997,11 @@ func fuzzCofactorOf{{ $TJacobian }}(f {{ .CoordType}}) {{ $TJacobian }} { SubAssign(&c) return res } + +func GeneratePointNotIn{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { + return fuzzCofactorOf{{ toUpper .PointName}}(f) +} + {{- end}} func fuzz{{ $TJacobian }}(p *{{ $TJacobian }}, f {{ .CoordType}}) {{ $TJacobian }} { From 23667265485e3d03b68a9729a292712d95c4c0fd Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Tue, 11 Mar 2025 10:49:46 -0400 Subject: [PATCH 4/5] refactor: export GeneratePointNotInG1/2 method --- ecc/bls12-381/g1.go | 13 ++++++ ecc/bls12-381/g1_test.go | 4 -- ecc/bls12-381/g2.go | 12 +++++ ecc/bls12-381/g2_test.go | 4 -- ecc/bn254/g2.go | 18 ++++++++ internal/generator/ecc/template/point.go.tmpl | 45 +++++++++++++++++++ .../ecc/template/tests/point.go.tmpl | 4 -- 7 files changed, 88 insertions(+), 12 deletions(-) diff --git a/ecc/bls12-381/g1.go b/ecc/bls12-381/g1.go index 6f3e639d1..5f5a94311 100644 --- a/ecc/bls12-381/g1.go +++ b/ecc/bls12-381/g1.go @@ -506,6 +506,19 @@ func (p *G1Jac) IsInSubGroup() bool { } +func GeneratePointNotInG1(f fp.Element) G1Jac { + var res, jac G1Jac + aff := MapToCurve1(&f) + g1Isogeny(&aff) + jac.FromAffine(&aff) + // p+x²ϕ(p) = [r]p + res.phi(&jac). + mulBySeed(&res). + mulBySeed(&res). + AddAssign(&jac) + return res +} + // mulWindowed computes the 2-bits windowed double-and-add scalar // multiplication p=[s]q in Jacobian coordinates. func (p *G1Jac) mulWindowed(q *G1Jac, s *big.Int) *G1Jac { diff --git a/ecc/bls12-381/g1_test.go b/ecc/bls12-381/g1_test.go index 4c313b7e3..5f50bd339 100644 --- a/ecc/bls12-381/g1_test.go +++ b/ecc/bls12-381/g1_test.go @@ -872,10 +872,6 @@ func fuzzCofactorOfG1(f fp.Element) G1Jac { return res } -func GeneratePointNotInG1(f fp.Element) G1Jac { - return fuzzCofactorOfG1(f) -} - func fuzzG1Jac(p *G1Jac, f fp.Element) G1Jac { var res G1Jac res.X.Mul(&p.X, &f).Mul(&res.X, &f) diff --git a/ecc/bls12-381/g2.go b/ecc/bls12-381/g2.go index b92fcbadb..7c8551d70 100644 --- a/ecc/bls12-381/g2.go +++ b/ecc/bls12-381/g2.go @@ -503,6 +503,18 @@ func (p *G2Jac) IsInSubGroup() bool { return res.Equal(&img) } +func GeneratePointNotInG2(f E2) G2Jac { + var res, jac G2Jac + aff := MapToCurve2(&f) + g2Isogeny(&aff) + jac.FromAffine(&aff) + // ψ(p)-[x₀]P = [r]p + res.mulBySeed(&jac) + jac.psi(&jac) + res.AddAssign(&jac) + return res +} + // mulWindowed computes the 2-bits windowed double-and-add scalar // multiplication p=[s]q in Jacobian coordinates. func (p *G2Jac) mulWindowed(q *G2Jac, s *big.Int) *G2Jac { diff --git a/ecc/bls12-381/g2_test.go b/ecc/bls12-381/g2_test.go index 51c2f61a1..4ae25ba8f 100644 --- a/ecc/bls12-381/g2_test.go +++ b/ecc/bls12-381/g2_test.go @@ -860,10 +860,6 @@ func fuzzCofactorOfG2(f fptower.E2) G2Jac { return res } -func GeneratePointNotInG2(f fptower.E2) G2Jac { - return fuzzCofactorOfG2(f) -} - func fuzzG2Jac(p *G2Jac, f fptower.E2) G2Jac { var res G2Jac res.X.Mul(&p.X, &f).Mul(&res.X, &f) diff --git a/ecc/bn254/g2.go b/ecc/bn254/g2.go index 50fd2806c..c8f31ad92 100644 --- a/ecc/bn254/g2.go +++ b/ecc/bn254/g2.go @@ -516,6 +516,24 @@ func (p *G2Jac) IsInSubGroup() bool { return res.Equal(&c) } +func GeneratePointNotInG2(f E2) G2Jac { + var res, jac, a, b, c G2Jac + aff := MapToCurve2(&f) + jac.FromAffine(&aff) + // [x₀+1]P + ψ([x₀]P) + ψ²([x₀]P) - ψ³([2x₀]P) = [r]P + a.mulBySeed(&jac) + b.psi(&a) + a.AddAssign(&jac) + res.psi(&b) + c.Set(&res). + AddAssign(&b). + AddAssign(&a) + res.psi(&res). + Double(&res). + SubAssign(&c) + return res +} + // mulWindowed computes the 2-bits windowed double-and-add scalar // multiplication p=[s]q in Jacobian coordinates. func (p *G2Jac) mulWindowed(q *G2Jac, s *big.Int) *G2Jac { diff --git a/internal/generator/ecc/template/point.go.tmpl b/internal/generator/ecc/template/point.go.tmpl index fd7a4f3db..b10f3ac67 100644 --- a/internal/generator/ecc/template/point.go.tmpl +++ b/internal/generator/ecc/template/point.go.tmpl @@ -810,6 +810,51 @@ func (p *{{ $TJacobian }}) IsOnCurve() bool { {{- end}} +{{- if eq .Name "bls12-381"}} + {{- if eq .PointName "g1" }} +func GeneratePointNotIn{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { + var res, jac {{ $TJacobian }} + aff := MapToCurve1(&f) + g1Isogeny(&aff) + jac.FromAffine(&aff) + // p+x²ϕ(p) = [r]p + res.phi(&jac). + mulBySeed(&res). + mulBySeed(&res). + AddAssign(&jac) + {{- else}} +func GeneratePointNotIn{{ toUpper .PointName}}(f E2) {{ $TJacobian }} { + var res, jac {{ $TJacobian }} + aff := MapToCurve2(&f) + g2Isogeny(&aff) + jac.FromAffine(&aff) + // ψ(p)-[x₀]P = [r]p + res.mulBySeed(&jac) + jac.psi(&jac) + res.AddAssign(&jac) + {{- end}} + return res +} +{{- else if and (eq .Name "bn254") (eq .PointName "g2")}} +func GeneratePointNotIn{{ toUpper .PointName}}(f E2) {{ $TJacobian }} { + var res, jac, a, b, c {{ $TJacobian }} + aff := MapToCurve2(&f) + jac.FromAffine(&aff) + // [x₀+1]P + ψ([x₀]P) + ψ²([x₀]P) - ψ³([2x₀]P) = [r]P + a.mulBySeed(&jac) + b.psi(&a) + a.AddAssign(&jac) + res.psi(&b) + c.Set(&res). + AddAssign(&b). + AddAssign(&a) + res.psi(&res). + Double(&res). + SubAssign(&c) + return res +} +{{- end}} + // mulWindowed computes the 2-bits windowed double-and-add scalar // multiplication p=[s]q in Jacobian coordinates. func (p *{{ $TJacobian }}) mulWindowed(q *{{ $TJacobian }}, s *big.Int) *{{ $TJacobian }} { diff --git a/internal/generator/ecc/template/tests/point.go.tmpl b/internal/generator/ecc/template/tests/point.go.tmpl index cfcf37852..5ee9550ad 100644 --- a/internal/generator/ecc/template/tests/point.go.tmpl +++ b/internal/generator/ecc/template/tests/point.go.tmpl @@ -975,10 +975,6 @@ func fuzzCofactorOf{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { return res } -func GeneratePointNotIn{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { - return fuzzCofactorOf{{ toUpper .PointName}}(f) -} - {{- else if and (eq .Name "bn254") (eq .PointName "g2")}} func fuzzCofactorOf{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { var res, jac, a, b, c {{ $TJacobian }} From c49070cad7a774aeea7d76ffd05fc47051148fa8 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Tue, 11 Mar 2025 10:52:27 -0400 Subject: [PATCH 5/5] refactor: clean template --- ecc/bn254/g2_test.go | 4 ---- internal/generator/ecc/template/tests/point.go.tmpl | 5 ----- 2 files changed, 9 deletions(-) diff --git a/ecc/bn254/g2_test.go b/ecc/bn254/g2_test.go index c08ab887d..6737ce4d3 100644 --- a/ecc/bn254/g2_test.go +++ b/ecc/bn254/g2_test.go @@ -865,10 +865,6 @@ func fuzzCofactorOfG2(f fptower.E2) G2Jac { return res } -func GeneratePointNotInG2(f fptower.E2) G2Jac { - return fuzzCofactorOfG2(f) -} - func fuzzG2Jac(p *G2Jac, f fptower.E2) G2Jac { var res G2Jac res.X.Mul(&p.X, &f).Mul(&res.X, &f) diff --git a/internal/generator/ecc/template/tests/point.go.tmpl b/internal/generator/ecc/template/tests/point.go.tmpl index 5ee9550ad..5d763a066 100644 --- a/internal/generator/ecc/template/tests/point.go.tmpl +++ b/internal/generator/ecc/template/tests/point.go.tmpl @@ -993,11 +993,6 @@ func fuzzCofactorOf{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { SubAssign(&c) return res } - -func GeneratePointNotIn{{ toUpper .PointName}}(f {{ .CoordType}}) {{ $TJacobian }} { - return fuzzCofactorOf{{ toUpper .PointName}}(f) -} - {{- end}} func fuzz{{ $TJacobian }}(p *{{ $TJacobian }}, f {{ .CoordType}}) {{ $TJacobian }} {