Skip to content

feat(groth16): support export of verification key and proof to snarkjs-compatible JSON#1584

Open
mysteryon88 wants to merge 11 commits into
Consensys:masterfrom
mysteryon88-forks:master
Open

feat(groth16): support export of verification key and proof to snarkjs-compatible JSON#1584
mysteryon88 wants to merge 11 commits into
Consensys:masterfrom
mysteryon88-forks:master

Conversation

@mysteryon88

@mysteryon88 mysteryon88 commented Aug 21, 2025

Copy link
Copy Markdown

Description

Issue: #1582

  • added snarkjs backend
  • added ExportVerifyingKey(io.Writer) for VerifyingKey
  • added ExportProof([]string, io.Writer) for Proof
  • supported curves: BLS12-381 and BN254

Type of change

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

How has this been tested?

For testing, I’m using the package: https://github.com/mysteryon88/gnark-to-snarkjs.

To verify the changes I implemented the following integration test workflow:

  1. Clone the demo repository
git clone https://github.com/mysteryon88/gnark-example
  1. Install npm dependencies (for snarkjs tests)
npm install
  1. Replace gnark with the updated version (containing the new export methods). (only for branch gnark-fork)

Either by using the fork/branch directly in go.mod:

replace github.com/consensys/gnark => github.com/<your-username>/gnark
  1. Run Go tests to generate JSON files
go test ./cubic -v -run TestCubicBLS12_381
go test ./cubic -v -run TestCubicBN254

After this step, the following files are produced:

  • keys/verification_key_.json
  • proofs/proof_.json
  1. Run npm test to verify proofs with snarkjs
npm test

How has this been benchmarked?

The newly added export functions are only used when explicitly called and do not affect the core proving or verification logic. They perform simple serialization to JSON and therefore should not impact the overall performance of the library.

Environment:

  • Windows 10 Pro (64-bit)
  • Intel i7-12700H
  • 32 GB RAM

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

Low Risk
Changes are opt-in serialization only; core prove/verify paths are untouched, though exported JSON must match snarkjs expectations for off-chain verification to succeed.

Overview
Adds optional snarkjs-compatible JSON export for Groth16 proofs and verifying keys, wired through a new backend/snarkjs package and embedded on the public groth16.Proof / groth16.VerifyingKey interfaces.

BN254 and BLS12-381 get real implementations: ExportProof writes pi_a / pi_b / pi_c (and optional publicSignals), and ExportVerifyingKey writes VK fields including vk_alphabeta_12 from a pairing of α and β. Proofs that include Pedersen commitments are rejected at export time because snarkjs cannot verify them.

BLS12-377 and BW6-761 only add stubs that return not implemented, so every curve still satisfies the new interfaces.

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

@cursor

cursor Bot commented Aug 21, 2025

Copy link
Copy Markdown

🚨 Bugbot Trial Expired

Your team's Bugbot trial has expired. Please contact your team administrator to turn on the paid plan to continue using Bugbot.

A team admin can activate the plan in the Cursor dashboard.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@ivokub

ivokub commented Sep 11, 2025

Copy link
Copy Markdown
Collaborator

Thanks for the submission.

@ivokub ivokub self-requested a review September 11, 2025 10:48
@ivokub ivokub added the src: community Community originating PRs and issues label Sep 11, 2025
Comment thread backend/groth16/bls12-377/prove.go

enc := json.NewEncoder(w)
enc.SetIndent("", " ")
return enc.Encode(out)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ExportVerifyingKey silently exports incorrect data with commitments

Medium Severity

ExportVerifyingKey lacks the commitment check that ExportProof has. When vk.PublicAndCommitmentCommitted is non-empty, NbPublicWitness() returns a count that includes commitment hash elements, and the IC array includes extra commitment-related points. This silently produces an incorrect snarkjs-incompatible verification key with no error.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1f3423a. Configure here.

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

There are 2 total unresolved issues (including 1 from previous review).

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


out := map[string]any{
"protocol": "groth16",
"curve": "bn254",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

BN254 curve name incompatible with snarkjs format

High Severity

The curve name is set to "bn254", but snarkjs uses "bn128" as the curve identifier for this curve. snarkjs's own verification_key.json output uses "curve": "bn128", and its getCurveFromName function references bn128 (e.g., globalThis.curve_bn128). Since this PR's goal is to produce snarkjs-compatible JSON, using "bn254" may cause snarkjs verification to fail or produce output that isn't interoperable with other snarkjs-based tools.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c40b866. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

src: community Community originating PRs and issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants