feat: add subgroup membership tests for all twistededwards curves#833
feat: add subgroup membership tests for all twistededwards curves#833
twistededwards curves#833Conversation
twistededwards curve
twistededwards curvetwistededwards curves
There was a problem hiding this comment.
Pull request overview
This PR adds generated, faster subgroup-membership tests (IsInSubGroup) for twisted Edwards curves (cofactor 4/8) by extending the Edwards generator to emit divide-and-pair / Tate-style subgroup checks plus addchain-based residue-test exponentiations, along with corresponding tests and benchmarks.
Changes:
- Extend twisted-Edwards generator/config to compute subgroup-structure metadata (
Split2Torsion, exponent addchains) and generatesubgroup.go. - Generate new
IsInSubGroup()implementations for supported twisted Edwards curves and update curve parameter initialization accordingly. - Add/expand property tests and benchmarks (including baseline “mul by order”) for subgroup membership checks.
Reviewed changes
Copilot reviewed 29 out of 54 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/generator/edwards/template/tests/point.go.tmpl | Enables subgroup tests/benchmarks for cofactor 4/8 curves; adds explicit 2-torsion negative test and benchmark subcases. |
| internal/generator/edwards/template/subgroup.go.tmpl | New template generating SMT subgroup checks + addchain-based quartic/octic residue exponentiation helpers. |
| internal/generator/edwards/template/point.go.tmpl | Narrows existing cofactor-4 subgroup check emission to Split2Torsion case. |
| internal/generator/edwards/template/curve.go.tmpl | Adds subgroup-test parameters into curve init/params and wires initialization for non-split cofactor 4/8 curves. |
| internal/generator/edwards/generate.go | Registers addchain template funcs and adds generation of subgroup.go. |
| internal/generator/config/curve.go | Computes subgroup metadata (Split2Torsion, quartic/octic exponent addchains) for twisted Edwards curves. |
| internal/generator/addchain/e7db4ea6533afa906673b0101343b00aa77b4805fffcb7fdfffffffe0000000 | Added serialized addchain program data used by generator. |
| internal/generator/addchain/98474056b0daca1a7ee9317d2f8bd5fbd83a03544f435c0843dcbb4a57bca04dfd005fe8060000 | Added serialized addchain program data used by generator. |
| internal/generator/addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 | Added serialized addchain program data used by generator. |
| internal/generator/addchain/60c89ce5c263405370a08b6d0302b0ba5067d090f372e12287c3eb27e000000 | Added serialized addchain program data used by generator. |
| internal/generator/addchain/4aad957a68b2955982d1347970dec00566a9dbfb40000004284600000000000 | Added serialized addchain program data used by generator. |
| internal/generator/addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 | Added serialized addchain program data used by generator. |
| internal/generator/addchain/32dbd584953b42564bf8fd939f24f531918901d9cc89c6c833a18bfa0180000 | Added serialized addchain program data used by generator. |
| ecc/bw6-761/twistededwards/subgroup.go | Generated subgroup SMT + octic exponentiation implementation for bw6-761 Edwards curve. |
| ecc/bw6-761/twistededwards/point_test.go | Adds subgroup membership property tests and comparative benchmarks. |
| ecc/bw6-761/twistededwards/curve.go | Adds subgroup precomputation fields and initializes subgroup params. |
| ecc/bw6-633/twistededwards/subgroup.go | Generated subgroup SMT + octic exponentiation implementation for bw6-633 Edwards curve. |
| ecc/bw6-633/twistededwards/point_test.go | Adds subgroup membership property tests and comparative benchmarks. |
| ecc/bw6-633/twistededwards/curve.go | Adds subgroup precomputation fields and initializes subgroup params. |
| ecc/bn254/twistededwards/subgroup.go | Generated subgroup SMT + octic exponentiation implementation for bn254 Edwards curve. |
| ecc/bn254/twistededwards/point_test.go | Adds subgroup membership property tests and comparative benchmarks. |
| ecc/bn254/twistededwards/curve.go | Adds subgroup precomputation fields and initializes subgroup params. |
| ecc/bls24-317/twistededwards/subgroup.go | Generated subgroup SMT + octic exponentiation implementation for bls24-317 Edwards curve. |
| ecc/bls24-317/twistededwards/point_test.go | Adds subgroup membership property tests and comparative benchmarks. |
| ecc/bls24-317/twistededwards/curve.go | Adds subgroup precomputation fields and initializes subgroup params. |
| ecc/bls24-315/twistededwards/subgroup.go | Generated subgroup SMT + octic exponentiation implementation for bls24-315 Edwards curve. |
| ecc/bls24-315/twistededwards/point_test.go | Adds subgroup membership property tests and comparative benchmarks. |
| ecc/bls24-315/twistededwards/curve.go | Adds subgroup precomputation fields and initializes subgroup params. |
| ecc/bls12-381/twistededwards/subgroup.go | Generated subgroup SMT + octic exponentiation implementation for bls12-381 Edwards curve. |
| ecc/bls12-381/twistededwards/point_test.go | Adds subgroup membership property tests and comparative benchmarks. |
| ecc/bls12-381/twistededwards/curve.go | Adds subgroup precomputation fields and initializes subgroup params. |
| ecc/bls12-381/bandersnatch/subgroup.go | Adds generated stub subgroup.go file for bandersnatch package. |
| ecc/bls12-381/bandersnatch/point_test.go | Adds 2-torsion negative test and benchmark comparison subcases. |
| ecc/bls12-377/twistededwards/subgroup.go | Generated subgroup SMT + quartic exponentiation implementation for bls12-377 Edwards curve. |
| ecc/bls12-377/twistededwards/point_test.go | Adds subgroup membership property tests and comparative benchmarks. |
| ecc/bls12-377/twistededwards/curve.go | Adds subgroup precomputation fields and initializes subgroup params. |
| addchain/e7db4ea6533afa906673b0101343b00aa77b4805fffcb7fdfffffffe0000000 | Added serialized addchain program data (non-internal copy). |
| addchain/d555555 | Added serialized addchain program data (non-internal copy). |
| addchain/98474056b0daca1a7ee9317d2f8bd5fbd83a03544f435c0843dcbb4a57bca04dfd005fe8060000 | Added serialized addchain program data (non-internal copy). |
| addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 | Added serialized addchain program data (non-internal copy). |
| addchain/7fffffff80000000 | Added serialized addchain program data (non-internal copy). |
| addchain/7fffffff | Added serialized addchain program data (non-internal copy). |
| addchain/7 | Added serialized addchain program data (non-internal copy). |
| addchain/60c89ce5c263405370a08b6d0302b0ba5067d090f372e12287c3eb27e000000 | Added serialized addchain program data (non-internal copy). |
| addchain/54aaaaab | Added serialized addchain program data (non-internal copy). |
| addchain/4aad957a68b2955982d1347970dec00566a9dbfb40000004284600000000000 | Added serialized addchain program data (non-internal copy). |
| addchain/3f800000 | Added serialized addchain program data (non-internal copy). |
| addchain/3f | Added serialized addchain program data (non-internal copy). |
| addchain/3c000000 | Added serialized addchain program data (non-internal copy). |
| addchain/38e38e38aaaaaaab | Added serialized addchain program data (non-internal copy). |
| addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 | Added serialized addchain program data (non-internal copy). |
| addchain/32dbd584953b42564bf8fd939f24f531918901d9cc89c6c833a18bfa0180000 | Added serialized addchain program data (non-internal copy). |
| addchain/1c71c71c55555555 | Added serialized addchain program data (non-internal copy). |
| addchain/1aaaaaab | Added serialized addchain program data (non-internal copy). |
ivokub
left a comment
There was a problem hiding this comment.
In general looks good, but I'd make it a bit more documented as the subgroup check uses generally not known algorithm :) Helps later reviews to have references.
Also, please consider refactoring some constants from the templates to configuration and perhaps also make template generation property-based.
|
Review pass from 2026-05-07. Findings:
Verification run locally:
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1e4a3c6. Configure here.

Description
This PR adds divide-and-pair subgroup membership tests (SMT) for all twisted Edwards curves in
gnark-crypto, following the https://eprint.iacr.org/2026/749 and https://hackmd.io/@yelhousni/divide-and-pair. The implementation uses generated Tate-style subgroup checks together with addchain-generated exponentiations for quartic and octic residue tests.The generator was extended to derive the relevant subgroup structure metadata from the curve parameters, emit the appropriate subgroup-check code, and generate tests and benchmarks for all supported twisted Edwards curves. This also adds benchmarks comparing
IsInSubGroup()against multiplication by the subgroup order, so the new method can be measured directly against the previous baseline on each curve.Type of change
How has this been tested?
go test ./ecc/bn254/twistededwards \ ./ecc/bls12-377/twistededwards \ ./ecc/bls12-381/twistededwards \ ./ecc/bls12-381/bandersnatch \ ./ecc/bls24-315/twistededwards \ ./ecc/bls24-317/twistededwards \ ./ecc/bw6-633/twistededwards \ ./ecc/bw6-761/twistededwardsThe tests check that:
2-torsion point(0,-1)is rejectedHow has this been benchmarked?
Benchmarks were run with:
BenchmarkIsInSubGroup, on Apple M5, macOS arm64Representative results on Apple M5 / macOS arm64:
bn254:is_in_subgroup~5.4µsvsmul_by_order~29.8µsbls12-381/twistededwards:is_in_subgroup~5.2µsvsmul_by_order~29.9µsbandersnatch:is_in_subgroup~1.3µsvsmul_by_order~31.9µsbw6-761:is_in_subgroup~11.1µsvsmul_by_order~80.9µsChecklist:
golangci-lintdoes not output errors locallyNote
High Risk
Adds and wires in new prime-subgroup membership logic across multiple curve implementations; subtle arithmetic or mapping bugs could cause invalid-point acceptance/rejection and impact cryptographic correctness.
Overview
Adds generated divide-and-pair subgroup membership tests for
PointAffine.IsInSubGroup()on all non-splittwistededwardscurves (newsubgroup.goper curve), including precomputed torsion data, Edwards→Weierstrass mapping, and addchain-based exponentiation for quartic/octic residue checks.Extends the code generator to derive subgroup-check strategy from curve parameters (split vs non-split 2-torsion), generate the needed constants/addchains, and emit consistent property tests and benchmarks (including a direct
mul_by_orderbaseline). Also tightens field generation by rejecting unsupported moduli (must be odd and >2) with a new unit test, and updates.gitignorefor generated addchain artifacts.Reviewed by Cursor Bugbot for commit 0b7114b. Bugbot is set up for automated code reviews on this repo. Configure here.