Skip to content

feat(p256): add e2 and cardano solver#831

Open
yelhousni wants to merge 6 commits intomasterfrom
feat/cardano-p256
Open

feat(p256): add e2 and cardano solver#831
yelhousni wants to merge 6 commits intomasterfrom
feat/cardano-p256

Conversation

@yelhousni
Copy link
Copy Markdown
Collaborator

@yelhousni yelhousni commented Apr 3, 2026

Description

Add Fp2 arithmetic and Cardano cubic solver for secp256r1 (P-256), used by the increment-and-check map-to-curve construction in gnark.

P-256 has a ≠ 0 (y² = x³ − 3x + b), so the y-increment method requires solving the depressed cubic x³ − 3x + c = 0 to recover x from a candidate y. This PR implements:

  • ecc/secp256r1/internal/fptower/: Fp2 = Fp[u]/(u²+1) arithmetic (valid since q ≡ 3 mod 4), including:

    • Basic operations: Add, Sub, Mul (Karatsuba), Square (complex squaring), Inverse, Conjugate, Double, Neg, Exp
    • Sqrt via Scott method with optimized addition chain for x^{(q-3)/4} following https://eprint.iacr.org/2020/1497.pdf.
    • Cbrt via algebraic torus T₂(Fp) with Lucas V-sequence following https://eprint.iacr.org/2026/392.
    • The Fp exponentiation expByCbrtHelper for x^{(q-4)/9} reuses fp.ExpByCbrtHelperQMinus4Div9
  • ecc/secp256r1/cardano.go: CardanoRoots(c) — solves x³ − 3x + c = 0 over Fp handling all three discriminant cases:

    • Δ = 0: repeated roots via direct formula
    • Δ non-square: one real root via Fp2 cube root
    • Δ square: up to 3 roots via Fp cube root and primitive cube root of unity

Companion PR in gnark: gnark uses CardanoRoots in the map-to-curve hint for P-256 y-increment witness generation.

Type of change

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

How has this been tested?

  • TestCardanoRoots — verifies roots satisfy x³ − 3x + c = 0 for 256 test values derived from P-256 curve points
  • TestE2ReceiverIsOperand — aliasing safety for all E2 operations (Add, Sub, Mul, Square, Neg, Double, Inverse, Conjugate, MulByElement, Sqrt)
  • TestE2Ops — algebraic identity tests via gopter property-based fuzzing (50 random inputs each): add/sub inverse, mul/inverse, double inverse, neg inverse, square==mul, MulByElement inverse, conjugate properties, Legendre on squares, sqrt correctness, cbrt correctness
go test -v ./ecc/secp256r1/...
go test -v ./ecc/secp256r1/internal/fptower/

How has this been benchmarked?

  • E2 operation benchmarks (Add, Sub, Mul, Square, Inverse, Sqrt, Cbrt, Exp), on Macbook Pro M5
go test -bench=. ./ecc/secp256r1/internal/fptower/

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

Medium Risk
Adds new finite-field extension arithmetic and a cubic root/solver used in elliptic-curve mapping; subtle math or corner-case bugs could break correctness even though changes are additive and well-tested.

Overview
Adds a new ecc/secp256r1/internal/fptower Fp2 implementation (E2) for P-256, including core arithmetic plus Sqrt and Cbrt routines needed for higher-level algebra.

Introduces CardanoRoots in ecc/secp256r1/cardano.go to compute roots of x³ − 3x + c = 0 over Fp, handling discriminant cases (including an Fp2 fallback when the discriminant is a non-square) and precomputing a cube root of unity for the 3-root case.

Adds property-based tests for both E2 operations and CardanoRoots (including checks derived from real curve points), plus micro-benchmarks for E2 primitives.

Written by Cursor Bugbot for commit 2c33f2d. This will update automatically on new commits. Configure here.

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

Adds missing P-256-specific algebra needed for increment-and-check map-to-curve by introducing an internal Fp² tower implementation and a Cardano depressed-cubic solver over secp256r1/fp.

Changes:

  • Introduce internal/fptower Fp² type (E2) with core arithmetic plus Sqrt/Cbrt helpers.
  • Add CardanoRoots(c) to solve x³ − 3x + c = 0 over the P-256 base field.
  • Add property-based tests/benchmarks for the new Fp² ops and Cardano solver.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
ecc/secp256r1/internal/fptower/e2.go New Fp² element type and arithmetic, including sqrt/cbrt helpers used by Cardano.
ecc/secp256r1/internal/fptower/e2_test.go Property tests for algebraic identities + microbenchmarks for E2 ops.
ecc/secp256r1/internal/fptower/generators_test.go Gopter generators for Fp and E2 test inputs.
ecc/secp256r1/cardano.go New Cardano solver returning Fp roots of x³ − 3x + c = 0.
ecc/secp256r1/cardano_test.go Property tests for CardanoRoots correctness.

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.

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.

2 participants