Skip to content

feat: map-to-curve relations#1746

Open
yelhousni wants to merge 19 commits into
masterfrom
feat/map-to-curve
Open

feat: map-to-curve relations#1746
yelhousni wants to merge 19 commits into
masterfrom
feat/map-to-curve

Conversation

@yelhousni

@yelhousni yelhousni commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Description

Add increment-and-check map-to-curve gadgets for short Weierstrass curves, implementing the constructions from https://eprint.iacr.org/2026/590.pdf.

Two methods are provided:

  • X-increment: encodes X = M·256 + K, verifies Y² = X³ + aX + b, and checks a 2^S-th root witness for inverse-exclusion. Only practical for low 2-adicity fields (S ≤ 4).
  • Y-increment: encodes Y = M·256 + K, verifies Y² = X³ + aX + b. Simpler (no inverse-exclusion witness), works for any 2-adicity, recommended for j=0 curves to avoid the algebraic attack from the paper.

Packages

std/algebra/emulated/sw_emulated/maptocurve_increment/

Generic emulated map-to-curve for any supported curve;

  • BN254 (y² = x³ + 3): x-increment and y-increment
  • secp256k1 (y² = x³ + 7): x-increment and y-increment
  • P-256/secp256r1 (y² = x³ − 3x + b): x-increment and y-increment (y-increment uses Cardano cubic solver from feat(p256): add e2 and cardano solver gnark-crypto#831)

std/algebra/native/sw_grumpkin/maptocurve_increment/

Native y-increment for Grumpkin (y² = x³ − 17), compiled over BN254.

std/algebra/native/sw_bls12377/maptocurve_increment/

Native y-increment for BLS12-377 (y² = x³ + 1), compiled over BW6-761.

Constraint counts

Curve Method R1CS SCS (PLONK)
Emulated
BN254 x-increment 862 3,135
BN254 y-increment 673 2,527
secp256k1 x-increment 854 3,111
secp256k1 y-increment 673 2,509
P-256 x-increment 858 3,124
P-256 y-increment 677 2,522
Native
Grumpkin y-increment 15 37
BLS12-377 y-increment 15 37

Type of change

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

How has this been tested?

All tests verify circuit satisfiability via test.CheckCircuit (both Groth16 and PLONK backends):

  • TestXIncrementEmulatedBN254 — x-increment on BN254
  • TestXIncrementEmulatedSecp256k1 — x-increment on secp256k1
  • TestXIncrementEmulatedP256 — x-increment on P-256
  • TestYIncrementEmulatedBN254 — y-increment on BN254
  • TestYIncrementEmulatedSecp256k1 — y-increment on secp256k1
  • TestYIncrementEmulatedP256 — y-increment on P-256 (Cardano solver)
  • TestYIncrement (maptocurve_grumpkin) — native y-increment on Grumpkin
  • TestYIncrement (maptocurve_bls12377) — native y-increment on BLS12-377
go test ./std/algebra/emulated/sw_emulated/maptocurve_increment/...
go test ./std/algebra/native/sw_grumpkin/maptocurve_increment/...
go test ./std/algebra/native/sw_bls12377/maptocurve_increment/...

How has this been benchmarked?

  • Constraint count benchmarks for all curves and methods (R1CS + SCS), on Macbook Pro M5
go test ./internal/stats/...
# regenerate the reference CSV:
go run ./internal/stats/generate -s -run maptocurve_increment

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
New curve-mapping gadgets rely on hints and documented non-uniqueness/cofactor caveats; misuse as hash-to-curve could break protocol assumptions, though changes are additive with extensive tests.

Overview
Adds increment-and-check map-to-curve circuits (eprint 2026/590): search K ∈ [0,256) so a message maps to an on-curve point via X-increment (curve eq + optional 2^S root witness) or Y-increment (curve eq + cubic root witness).

Emulated Mapper covers BN254, secp256k1, and P-256 (XIncrement / YIncrement / Increment dispatch). Native YIncrement covers Grumpkin and BLS12-377. Hints are wired through std/hints.go; constraint stats/snippets record per-curve costs.

gnark-crypto is bumped (pre-release) for field Cbrt used in y-increment witnesses; tinyfield gains Cbrt/Cube, uses parallel.Execute, and picks up minor Go style fixes. Package docs stress this is not a canonical hash-to-curve and points are not cofactor-cleared.

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

@socket-security

socket-security Bot commented Apr 3, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedgolang/​github.com/​consensys/​gnark-crypto@​v0.20.1 ⏵ v0.20.2-0.20260528194156-c4f71c9600c176 +1100100100100
Updatedgolang/​golang.org/​x/​sync@​v0.19.0 ⏵ v0.20.099100100100100

View full report

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds increment-and-check map-to-curve gadgets (from the referenced paper) for short Weierstrass curves, with both emulated and native implementations, plus tests/benchmarks and a dependency bump to support required crypto primitives.

Changes:

  • Introduces a generic emulated maptocurve package supporting X-increment and Y-increment for BN254, secp256k1, and P-256 (incl. Cardano solver path).
  • Adds native Y-increment gadgets for Grumpkin (over BN254) and BLS12-377 (over BW6-761), including hint plumbing and basic tests/benchmarks.
  • Updates go.mod / go.sum (notably gnark-crypto) to pull in required functionality.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
std/algebra/native/maptocurve_grumpkin/maptocurve.go Native Grumpkin Y-increment gadget (constraints: curve equation + k range).
std/algebra/native/maptocurve_grumpkin/hints.go Hint to search k ∈ [0,256) and compute cube root witness.
std/algebra/native/maptocurve_grumpkin/maptocurve_test.go Satisfiability + benchmark harness for the native gadget.
std/algebra/native/maptocurve_grumpkin/doc.go Package documentation / compilation curve notes.
std/algebra/native/maptocurve_bls12377/maptocurve.go Native BLS12-377 Y-increment gadget (over BW6-761 scalar field).
std/algebra/native/maptocurve_bls12377/hints.go Hint to search k ∈ [0,256) and compute cube root witness.
std/algebra/native/maptocurve_bls12377/maptocurve_test.go Satisfiability + benchmark harness for the native gadget.
std/algebra/native/maptocurve_bls12377/doc.go Package documentation / compilation curve notes.
std/algebra/emulated/maptocurve/maptocurve.go Generic emulated Mapper implementing X-increment and Y-increment gadgets.
std/algebra/emulated/maptocurve/hints.go Emulated hints for BN254, secp256k1, and P-256 (x/y increment).
std/algebra/emulated/maptocurve/maptocurve_test.go Satisfiability tests + benchmarks for emulated gadgets.
std/algebra/emulated/maptocurve/doc.go Package-level documentation describing both methods and tradeoffs.
go.mod Bumps deps (incl. gnark-crypto) needed for curve operations/solvers.
go.sum Corresponding checksum updates.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread std/algebra/emulated/maptocurve/maptocurve.go Outdated
Comment thread std/algebra/emulated/maptocurve/maptocurve.go Outdated
Comment thread std/algebra/emulated/maptocurve/maptocurve.go Outdated
Comment thread std/algebra/emulated/maptocurve/maptocurve.go Outdated
Comment thread std/algebra/emulated/maptocurve/hints.go Outdated
Comment thread std/algebra/emulated/maptocurve/hints.go Outdated
Comment thread std/algebra/emulated/maptocurve/maptocurve_test.go Outdated
Comment thread go.mod Outdated
Comment thread std/algebra/native/maptocurve_bls12377/maptocurve.go Outdated
@gbotrel

gbotrel commented May 7, 2026

Copy link
Copy Markdown
Collaborator

Review pass from 2026-05-07.

I did not find blocking issues in this pass. The gnark-crypto dependency PR #831 is already merged, and the map-to-curve gadgets compile and solve in the targeted native/emulated packages I checked.

Verification run locally:

  • go test ./std/algebra/emulated/maptocurve/... ./std/algebra/native/maptocurve_grumpkin/... ./std/algebra/native/maptocurve_bls12377/...
  • go test ./internal/smallfields/tinyfield

@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 820d389. Configure here.

Comment thread internal/smallfields/tinyfield/element.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.

Please see comments. I currently reviewed only emulated/maptocurve, not bls12377/grumpkin.

Imo we should also reconsider the package structure - for BLS12-381 curve we already have the MapToCurve (and also MapToG1/MapToG2) implemented. Imo having a separate package maptocurve is confusing.

I'd recommend instead:

  • std/algebra/emulated/sw_emulated/maptocurve_increment
  • std/algebra/native/sw_bls12377/maptocurve_increment
  • std/algebra/native/sw_grumpkin/maptocurve_increment

And we should be clear in the documentation that these are very fast non-unique algorithm.

Comment thread std/algebra/emulated/maptocurve/maptocurve_test.go Outdated
Comment thread std/algebra/emulated/maptocurve/hints.go Outdated
Comment thread std/algebra/emulated/maptocurve/hints.go Outdated
Comment thread std/algebra/emulated/maptocurve/maptocurve.go Outdated
Comment thread std/algebra/emulated/maptocurve/hints.go Outdated
Comment thread std/algebra/emulated/maptocurve/maptocurve.go Outdated
Comment thread std/algebra/emulated/maptocurve/maptocurve_test.go Outdated
Comment thread std/algebra/emulated/maptocurve/hints.go Outdated
Comment thread std/algebra/emulated/maptocurve/doc.go Outdated
Comment thread std/algebra/emulated/maptocurve/doc.go Outdated
Comment thread std/algebra/emulated/maptocurve/maptocurve_test.go Outdated
@socket-security

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: golang golang.org/x/tools is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ?golang/golang.org/x/tools@v0.43.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore golang/golang.org/x/tools@v0.43.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 17 out of 22 changed files in this pull request and generated 4 comments.

Files not reviewed (4)
  • internal/smallfields/tinyfield/element.go: Generated file
  • internal/smallfields/tinyfield/element_test.go: Generated file
  • internal/smallfields/tinyfield/vector.go: Generated file
  • internal/smallfields/tinyfield/vector_test.go: Generated file

Comment on lines +35 to +40
// - The 256-element search is NOT guaranteed to converge. For
// well-distributed inputs the probability that every K ∈ [0,256) yields
// a quadratic non-residue (XIncrement) or a non-cube (YIncrement) is
// bounded by ≈ 2^-256 (independent quadratic-residue heuristic), but
// adversarial inputs could in principle push this higher. Treat the
// probabilistic failure as part of the protocol's soundness budget.
Comment on lines +19 to +21
// - The 256-element search is NOT guaranteed to converge; the failure
// probability is bounded by ≈ 2^-256 for well-distributed inputs but
// adversarial inputs may have a worse bound.
Comment on lines +19 to +21
// - The 256-element search is NOT guaranteed to converge; the failure
// probability is bounded by ≈ 2^-256 for well-distributed inputs but
// adversarial inputs may have a worse bound.
Comment on lines +915 to +918
// Cbrt z = ∛x (mod q)
// if the cube root doesn't exist (x is not a cube mod q)
// Cbrt leaves z unchanged and returns nil
func (z *Element) Cbrt(x *Element) *Element {
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