Skip to content

perf: twisted Edwards lattice-based double-base MSM - #1765

Merged
yelhousni merged 20 commits into
masterfrom
perf/tedwards-lattice-msm
Jul 15, 2026
Merged

perf: twisted Edwards lattice-based double-base MSM#1765
yelhousni merged 20 commits into
masterfrom
perf/tedwards-lattice-msm

Conversation

@yelhousni

@yelhousni yelhousni commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

This PR is stacked on #1763 and contains the native twisted Edwards MSM follow-up only. It adds lattice-based double-base scalar multiplication variants for native twisted Edwards curves:

  • DoubleBaseScalarMulNonZero as the optimized non-degenerate path.
  • MSM(3, 2n/3) for curves without a GLV endomorphism.
  • MSM(6, n/3) for curves with a GLV endomorphism, including Bandersnatch endomorphism parameters.
  • lattice reconstruction hints for the multi-scalar decomposition.
  • in-circuit scalar decomposition verification helpers.

DoubleBaseScalarMul remains complete for the public API and handles zero scalars / identity edge cases before dispatching to the optimized non-zero path. The branch also includes the review fixes that remove redundant hint outputs, wire scalar decomposition verification into the twisted Edwards scalar multiplication path, and bind the non-GLV MSM hint to a single result with the sound relation [x1]P1 + [x2]P2 - [z]R = O.

This PR intentionally does not include the emulated G2 GLV+FakeGLV work; that is split into #1764.

Type of change

  • New feature (non-breaking change which adds functionality)
  • Optimization / performance improvement
  • Bug fix (non-breaking change which fixes an issue)

How has this been tested?

Focused test run:

go test -short ./std/algebra/native/twistededwards ./internal/stats

Specifically covered:

  • native twisted Edwards scalar multiplication tests
  • native twisted Edwards double-base scalar multiplication tests
  • regression coverage for malicious trivial scalar decompositions
  • regression coverage for forged double-base MSM hint outputs
  • stats snippets compile and solve

How has this been benchmarked?

internal/stats/latest_stats.csv was regenerated with new MSM(2) snippets.

Snippet R1CS constraints / wires SCS constraints / wires
msm_G1_bn254_2 208925 / 312617 688811 / 658743
msm_P256_2 185846 / 288056 635297 / 608874
msm_secp256k1_2 208997 / 312737 689104 / 659028
msm_babyjubjub_2 5269 / 5683 12389 / 11848
msm_jubjub_2 5276 / 5754 12332 / 11855
msm_bandersnatch_2 5532 / 6301 13470 / 12918

Checklist:

  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • 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 focused tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules (gnark-crypto/algebra/lattice)

Note

High Risk
Changes in-circuit elliptic-curve arithmetic and hint verification (subgroup binding, torsion resistance); incorrect constraints would be a proof soundness bug, though coverage targets known attacks.

Overview
Adds fast lattice-based double-base scalar multiplication for native twisted Edwards curves while keeping DoubleBaseScalarMul complete by default; algopts.WithIncompleteArithmetic routes to DoubleBaseScalarMulNonZero (3-MSM + LogUp on non-GLV curves, 6-MSM + GLV φ on Bandersnatch).

Soundness hardening for hinted MSM/GLV paths: assertInSubgroup ([cofactor]S == R plus on-curve preimage S), extended scalarMulHint / new doubleBaseScalarMulHint and multi-rational reconstruction hints, and emulated-field decomposition checks in scalar_decomp.go (replacing redundant native checks and dropping the unused k output from rationalReconstruct).

Regression tests cover trivial decompositions, forged partial MSM hints, 2-torsion forgeries (scalar mul and double-base, BN254 and Bandersnatch), and off-curve subgroup preimages.

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

@yelhousni yelhousni changed the title perf: twisted Edwards lattice-based GLV+FakeGLV perf: twisted Edwards lattice-based GLV+FakeGLV scalar-mul May 8, 2026
@yelhousni yelhousni changed the title perf: twisted Edwards lattice-based GLV+FakeGLV scalar-mul perf: twisted Edwards lattice-based double-base MSM May 8, 2026
Comment thread std/algebra/native/twistededwards/point.go
Comment thread std/algebra/native/twistededwards/point.go Outdated
@yelhousni yelhousni self-assigned this May 8, 2026
@yelhousni yelhousni added dep: linea Issues affecting Linea downstream type: perf labels May 8, 2026
Comment thread std/algebra/native/twistededwards/point.go
@yelhousni

Copy link
Copy Markdown
Contributor Author

@ivokub this one is also ready for review (after #1763)

Comment thread std/algebra/native/twistededwards/scalar_decomp.go

@ivokub ivokub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Audit notes from the twisted Edwards double-base scalar multiplication review. The main concern is that the optimized DoubleBaseScalarMulNonZero relation appears to characterize the result only modulo the prime-order subgroup, while the interface currently accepts generic on-curve twisted Edwards points.

Comment thread std/algebra/native/twistededwards/curve.go Outdated
Comment thread std/algebra/native/twistededwards/point.go
Comment thread std/algebra/native/twistededwards/point.go
Comment thread std/algebra/native/twistededwards/curve_test.go
Comment thread std/algebra/native/twistededwards/curve.go
@yelhousni
yelhousni requested a review from ivokub July 1, 2026 20:38
@yelhousni

Copy link
Copy Markdown
Contributor Author

@ivokub Addressed the review + a related bug found while fixing:

  • Soundness (cofactor torsion): the scaled relation [z]R = [x1]P1+[x2]P2 only pinned R mod the z-torsion, so an even z let a prover return R+(0,-1). Fixed by binding the hinted result into the prime-order subgroup: hint a preimage S and assert R = [cofactor]·S (power-of-two cofactor ⇒ [cofactor]·E = ⟨G⟩). ~12–17 constraints.
  • GLV path: binding runs before φ, so φ(R)=[λ]R holds; documented the φ(identity) exception (result must be non-identity).
  • API: DoubleBaseScalarMul now takes ...algopts.AlgebraOption and routes to the fast path under WithIncompleteArithmetic; documented subgroup/non-identity/nonzero preconditions.
  • Tests: added torsion-rejection tests for the 3-MSM (even-z) and Bandersnatch 6-MSM paths; updated the forged-hint regression. Ablation-verified they catch the bug.
  • Same bug in scalarMulFakeGLV: confirmed ScalarMul accepted [s]P+(0,-1) for even s2; applied the same [cofactor]·S binding + regression test. Note: this tightens ScalarMul's contract to require prime-order-subgroup input.
  • Stats regenerated for the affected snippets; twistededwards/eddsa tests green.

Comment thread std/algebra/native/twistededwards/point.go

@ivokub ivokub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems the snippets also disappeared during merge commit:

It looks like the stats snippets added for this PR were dropped during the merge from master. In 55799fa49, internal/stats/snippet.go still registered msm_babyjubjub_2, msm_jubjub_2, and msm_bandersnatch_2, and internal/stats/latest_stats.csv had the corresponding rows. At current HEAD these registrations and CSV rows are gone. The merge commit 4842f113d modified both stats files, likely resolving to the master-side map-to-curve stats changes and accidentally losing the MSM snippets. Could you restore the twisted Edwards MSM snippets and regenerate/update latest_stats.csv?

And it also seems that the hinted result checking is not complete as assumes hinted result being on-curve.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 c5f1def. Configure here.

Comment thread std/algebra/native/twistededwards/point.go
@yelhousni
yelhousni requested a review from ivokub July 15, 2026 21:32

@ivokub ivokub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks! Looks good now!

@yelhousni
yelhousni merged commit 2ea1515 into master Jul 15, 2026
15 checks passed
@yelhousni
yelhousni deleted the perf/tedwards-lattice-msm branch July 15, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dep: linea Issues affecting Linea downstream type: perf

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants