Skip to content

feat: add subgroup membership tests for all twistededwards curves#833

Open
yelhousni wants to merge 9 commits intomasterfrom
feat/tEd-smt
Open

feat: add subgroup membership tests for all twistededwards curves#833
yelhousni wants to merge 9 commits intomasterfrom
feat/tEd-smt

Conversation

@yelhousni
Copy link
Copy Markdown
Collaborator

@yelhousni yelhousni commented Apr 20, 2026

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

  • New feature (non-breaking change which adds functionality)

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/twistededwards

The tests check that:

  • the identity point is accepted
  • random scalar multiples of the base point are accepted
  • the rational 2-torsion point (0,-1) is rejected

How has this been benchmarked?

Benchmarks were run with:

go test -run '^$' -bench IsInSubGroup \
  ./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/twistededwards
  • BenchmarkIsInSubGroup, on Apple M5, macOS arm64

Representative results on Apple M5 / macOS arm64:

  • bn254: is_in_subgroup ~5.4µs vs mul_by_order ~29.8µs
  • bls12-381/twistededwards: is_in_subgroup ~5.2µs vs mul_by_order ~29.9µs
  • bandersnatch: is_in_subgroup ~1.3µs vs mul_by_order ~31.9µs
  • bw6-761: is_in_subgroup ~11.1µs vs mul_by_order ~80.9µs

Checklist:

  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • I did not modify files generated from templates
  • golangci-lint does not output errors locally
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Note

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-split twistededwards curves (new subgroup.go per 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_order baseline). Also tightens field generation by rejecting unsupported moduli (must be odd and >2) with a new unit test, and updates .gitignore for generated addchain artifacts.

Reviewed by Cursor Bugbot for commit 0b7114b. Bugbot is set up for automated code reviews on this repo. Configure here.

@yelhousni yelhousni added this to the v0.19.N milestone Apr 20, 2026
@yelhousni yelhousni self-assigned this Apr 20, 2026
@yelhousni yelhousni changed the title perf: add subgroup membership test for all twistededwards curve feat: add subgroup membership test for all twistededwards curve Apr 20, 2026
@yelhousni yelhousni changed the title feat: add subgroup membership test for all twistededwards curve feat: add subgroup membership tests for all twistededwards curve Apr 20, 2026
@yelhousni yelhousni changed the title feat: add subgroup membership tests for all twistededwards curve feat: add subgroup membership tests for all twistededwards curves Apr 20, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 generate subgroup.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).

Comment thread internal/generator/edwards/template/curve.go.tmpl Outdated
Comment thread internal/generator/edwards/template/curve.go.tmpl Outdated
Comment thread internal/generator/edwards/template/curve.go.tmpl Outdated
Comment thread internal/generator/edwards/template/curve.go.tmpl
Copy link
Copy Markdown
Collaborator

@ivokub ivokub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread ecc/bls12-377/twistededwards/subgroup.go
Comment thread ecc/bls12-377/twistededwards/subgroup.go
Comment thread internal/generator/edwards/template/curve.go.tmpl Outdated
Comment thread internal/generator/edwards/generate.go Outdated
Comment thread internal/generator/edwards/template/curve.go.tmpl Outdated
@gbotrel
Copy link
Copy Markdown
Collaborator

gbotrel commented May 7, 2026

Review pass from 2026-05-07.

Findings:

  • Blocking: hosted test CI is red. The failing package/test reported by the Actions log is github.com/consensys/gnark-crypto/internal/generator/field/config / TestIntToMont on the Go 1.25.x job. I could not reproduce it locally on go1.26.2 with either go test ./internal/generator/field/config -run TestIntToMont -v or go test ./internal/generator/field/config -run TestIntToMont -count=2 -timeout 60s -v, but the PR should not merge with the required test job red. Please rerun with better verbose output or investigate whether the property generator is exposing a Go-version/platform-sensitive case.

Verification run locally:

  • 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/twistededwards
  • go test ./internal/generator/field/config -run TestIntToMont -v
  • go test ./internal/generator/field/config -run TestIntToMont -count=2 -timeout 60s -v

Comment thread internal/generator/edwards/template/subgroup.go.tmpl Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 40 changed files in this pull request and generated 1 comment.

Comment thread internal/generator/edwards/generate.go
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread internal/generator/config/curve.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants