Skip to content

feat: add grumpkin curve support#1729

Merged
yelhousni merged 8 commits intomasterfrom
feat/grumpkin
Mar 16, 2026
Merged

feat: add grumpkin curve support#1729
yelhousni merged 8 commits intomasterfrom
feat/grumpkin

Conversation

@yelhousni
Copy link
Copy Markdown
Contributor

@yelhousni yelhousni commented Mar 10, 2026

Description

This PR adds support for the Grumpkin curve (ecc.GRUMPKIN) in gnark. Grumpkin is an elliptic curve defined over the BN254 base field, commonly used in folding schemes (e.g. Nova, HyperNova) and cycle-of-curves constructions.

Changes

Constraint System

New curve-typed constraint system implementation (R1CS and SparseR1CS):

  • constraint/grumpkin/ — coefficient table, marshal, solver, system backed by gnark-crypto/ecc/grumpkin/fr

Frontend Builders

frontend/cs/r1cs/builder.go and frontend/cs/scs/builder.go dispatch to the new Grumpkin constraint system when the target field matches ecc.GRUMPKIN.

Witness

backend/witness/vector.go handles Grumpkin field elements in witness encoding/decoding.

Curves Registry

doc.goecc.GRUMPKIN added to gnark.Curves().

Type of change

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

How has this been tested?

go test -short ./constraint/grumpkin/...
go test -short ./frontend/...
go test -short ./backend/witness/...

Also tested end-to-end with a circuit compiled over ecc.GRUMPKIN (native BN254 map-to-curve).

Checklist

  • I have performed a self-review of my code
  • golangci-lint does not output errors locally
  • New and existing unit tests pass locally with my changes
  • Dependent gnark-crypto Grumpkin packages are available

Note

Medium Risk
Adds a new curve-typed constraint system and solver/serialization path for ecc.GRUMPKIN, which touches core proving inputs (witness encoding) and constraint solving logic. Risk is mainly around correctness/compatibility of the new field-specific implementations and dispatching by modulus.

Overview
Adds Grumpkin (ecc.GRUMPKIN) support end-to-end by introducing a new constraint/grumpkin implementation (coeff table, solver, and marshal/system glue) backed by gnark-crypto/ecc/grumpkin/fr.

Updates witness handling (backend/witness) and frontend builders (frontend/cs/r1cs and frontend/cs/scs) to recognize the Grumpkin scalar field modulus and route vector allocation/serialization and constraint-system construction accordingly.

Extends generic field-type selection (constraint/FitsElement) to accept the Grumpkin modulus, and updates the backend generator to include Grumpkin codegen metadata while skipping autogenerated tests via a new NoTests flag.

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

@yelhousni yelhousni added this to the v0.14.N milestone Mar 10, 2026
@yelhousni yelhousni requested review from gbotrel and ivokub March 10, 2026 18:33
@yelhousni yelhousni added the type: consolidate strengthen an existing feature label Mar 10, 2026
Comment thread backend/witness/vector.go Outdated
Comment thread doc.go Outdated
@ivokub
Copy link
Copy Markdown
Collaborator

ivokub commented Mar 10, 2026

@yelhousni - can you explain why we would need these frontend implementations in gnark? Usually for large-field case (i.e. grumpkin) we want to be able to prove the circuit in PLONK/Groth16, but afaik Grumpkin is not proving friendly?

And Goldilocks would just be super inefficient, our constraint.U64 is actually [6]uint64 to fit all supported scalar fields of the supported backend curves. And again, we wouldn't have a backend for it. For other small field backends the goal is that we can compile the circuit and then embed it in Vortex circuit which works over small fields, but Vortex is not configurable to work with Goldilocks.

Unless you have some interesting ideas using folding etc. to have new backends, then I don't currently see the benefit of adding support for new curves for compiling the circuits.

@yelhousni
Copy link
Copy Markdown
Contributor Author

Member

@yelhousni - can you explain why we would need these frontend implementations in gnark? Usually for large-field case (i.e. grumpkin) we want to be able to prove the circuit in PLONK/Groth16, but afaik Grumpkin is not proving friendly?

And Goldilocks would just be super inefficient, our constraint.U64 is actually [6]uint64 to fit all supported scalar fields of the supported backend curves. And again, we wouldn't have a backend for it. For other small field backends the goal is that we can compile the circuit and then embed it in Vortex circuit which works over small fields, but Vortex is not configurable to work with Goldilocks.

Unless you have some interesting ideas using folding etc. to have new backends, then I don't currently see the benefit of adding support for new curves for compiling the circuits.

I need this for some bn254/grumpkin constraints benchmarks, but I'll how I can do that cleanly.

yelhousni and others added 2 commits March 11, 2026 13:44
# Conflicts:
#	internal/gkr/test_vectors/testdata/gkr_circuit_bn254.scs
Remove goldilocks and unrelated changes, keeping only the minimal
Grumpkin curve support needed for witness/compile.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread backend/witness/vector.go Outdated
@yelhousni yelhousni changed the title Feat: add support to grumpkin curve and goldilocks field feat: add grumpkin curve support Mar 11, 2026
Comment thread doc.go Outdated
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.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Comment thread constraint/field.go
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 principle looks good. But why not use code generation in internal/generator/backend? For example following configuration would work and generate the same thing:

	grumpkin := templateData{
		CSPath:      "../../../constraint/grumpkin/",
		Curve:       "Grumpkin",
		CurveID:     "GRUMPKIN",
		noBackend:   true,
		NoGKR:       true,
		ElementType: "U64",
	}

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.

To avoid generating the tests which would fail imo we could just check if the curve is in gnark.Curves() and then omit generating the test file. Imo that list is a good list of "supported curves" and we could consider everything out of that as experimental.

@yelhousni yelhousni requested a review from ivokub March 12, 2026 18:05
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.

Looks good now! Thanks!

@yelhousni yelhousni merged commit 14fa7e6 into master Mar 16, 2026
13 checks passed
@yelhousni yelhousni deleted the feat/grumpkin branch March 16, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: consolidate strengthen an existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants