Skip to content

feat(circom): add optional Garaga Starknet calldata helper - #723

Open
rukafe0x wants to merge 7 commits into
zkmopro:mainfrom
rukafe0x:feat-garaga-adapter
Open

feat(circom): add optional Garaga Starknet calldata helper#723
rukafe0x wants to merge 7 commits into
zkmopro:mainfrom
rukafe0x:feat-garaga-adapter

Conversation

@rukafe0x

@rukafe0x rukafe0x commented Jul 27, 2026

Copy link
Copy Markdown

Summary

Adds an optional Circom helper to format Groth16 proofs as Starknet verifier calldata via Garaga get_groth16_calldata_felt, so apps can prove on-device and produce on-chain calldata without a backend. This is intentionally a side helper on the Circom template , not part of mopro-ffi core, so non-Starknet / non-Circom users stay unaffected unless they enable the feature

Closes #646

Changes

  • Optional UniFFI-exported helpers in the Circom init template:
    • generate_circom_groth16_garaga_calldata — from SnarkJS proof.json / public.json / verification_key.json
    • generate_circom_groth16_garaga_calldata_from_proof_result — from in-app CircomProofResult + VK JSON (recommended)
  • SnarkJS / Mopro proof → Garaga type conversion (garaga_rs v1.1.0, BN254 only)
  • Circom Cargo.toml wiring: optional garaga_rs + garaga feature
  • Docs + Flutter/starknet.dart usage notes in docs/docs/adapters/circom.md
  • Golden fixtures + garaga-calldata-tests workspace crate

Usage (sketch)

[features]
garaga = ["garaga_rs"]
let result = generate_circom_proof(zkey_path, circuit_inputs, ProofLib::Arkworks)?;
let calldata = generate_circom_groth16_garaga_calldata_from_proof_result(
    result,
    std::fs::read_to_string("verification_key.json")?,
)?;

## Test
cargo test -p garaga-calldata-tests

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added optional Garaga support (feature-gated) to generate Starknet-compatible Groth16 calldata from Circom proof results plus `verification_key.json` (BN254), returning decimal felt strings.
* **Bug Fixes**
  * Fixed the `Build` command’s `auto_update` flag parsing to behave as a proper boolean.
* **Documentation**
  * Expanded the Circom adapter guide with a “Starknet calldata (Garaga, optional)” section and example usage.
* **Tests**
  * Added/updated Garaga calldata integration tests with new BN254 fixtures and golden-output validation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

rukafe0x and others added 4 commits July 7, 2026 17:37
Expose generate_circom_groth16_garaga_calldata behind the optional garaga feature. Parses SnarkJS proof.json, public.json, and verification_key.json, then calls Garaga v1.1.0 get_groth16_calldata_felt to return Starknet felts as decimal strings.

Includes golden fixtures from Garaga v1.1.0 SnarkJS BN254 examples, a garaga-calldata-tests workspace crate, fixture generator binary, and Circom adapter documentation for starknet.dart usage outside Mopro.
Expose generate_circom_groth16_garaga_calldata_from_proof_result so mobile apps can build Starknet calldata directly from generate_circom_proof output using proof_result.inputs instead of a separate SnarkJS public.json file.

Co-authored-by: Cursor <cursoragent@cursor.com>
Nested mod declarations under circom.rs require helpers in src/circom/.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bb5119b1-0e5c-4b99-a66b-89675e9c19ca

📥 Commits

Reviewing files that changed from the base of the PR and between 5a8efe7 and 1de55b7.

📒 Files selected for processing (1)
  • docs/docs/adapters/circom.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/docs/adapters/circom.md

📝 Walkthrough

Walkthrough

Adds optional Garaga v1.1.0 support for converting Circom/SnarkJS BN254 Groth16 proof results into Starknet calldata, with feature-gated APIs, conversion helpers, fixtures, golden tests, regeneration tooling, and documentation.

Changes

Garaga calldata integration

Layer / File(s) Summary
Workspace and feature wiring
Cargo.toml, cli/src/init/*, cli/src/main.rs, cli/src/template/circom/lib.rs, cli/src/template/init/src/circom.rs, garaga-calldata-tests/*
Adds the workspace test crate, shared dependencies, generated garaga feature configuration, conditional exports, CLI flag adjustment, proof types, and test-crate wiring.
SnarkJS parsing and Garaga conversion
cli/src/template/init/src/circom/snarkjs_types.rs, cli/src/template/init/src/circom/garaga_convert.rs
Parses and validates Groth16 BN128 verification-key artifacts, then converts coordinates, public inputs, proofs, and verification keys into Garaga representations.
Calldata generation API
cli/src/template/init/src/circom/circom_garaga.rs
Adds an API accepting a CircomProofResult and verification-key JSON, returning Garaga-generated calldata as Vec<String>.
Fixtures, tests, and usage documentation
cli/src/template/init/test-vectors/circom/garaga/bn254/*, garaga-calldata-tests/src/*, docs/docs/adapters/circom.md
Adds BN254 fixtures, calldata regeneration tooling, parser/conversion tests, golden-vector assertions, and documented API usage.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant CalldataAPI
  participant SnarkJSParser
  participant GaragaConverter
  participant garaga_rs
  Caller->>CalldataAPI: Submit proof result and verification key JSON
  CalldataAPI->>SnarkJSParser: Parse and validate verification key
  CalldataAPI->>GaragaConverter: Convert proof inputs and verification key
  GaragaConverter->>garaga_rs: Generate Starknet calldata
  garaga_rs-->>CalldataAPI: Return calldata felts
  CalldataAPI-->>Caller: Return decimal felt strings
Loading

Possibly related PRs

  • zkmopro/mopro#717: Updates the shared uniffi dependency to the same pinned =0.32.0 version.
  • zkmopro/mopro#722: Adds closely related Garaga feature wiring, Circom calldata helpers, and BN254 fixture integration.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The Clap auto_update parser tweak in cli/src/main.rs is unrelated to the Garaga calldata integration. Remove or justify the unrelated CLI parsing change, or split it into a separate PR.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately highlights the new optional Garaga Starknet calldata helper.
Linked Issues check ✅ Passed The PR adds BN254 Groth16-to-Starknet calldata translation, Garaga-constrained helpers, and docs/examples for #646.
Docstring Coverage ✅ Passed Docstring coverage is 89.19% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cli/src/template/init/src/circom/circom_garaga.rs`:
- Around line 73-85: Validate the parsed public-input count against vk.n_public
immediately after parse_snarkjs_vk_json in both calldata APIs at
cli/src/template/init/src/circom/circom_garaga.rs lines 73-85 and 99-107,
returning MoproError::CircomError when inputs exceed the VK capacity before
calling to_groth16_proof or to_groth16_vk. Add regression tests covering
oversized public inputs for both APIs.

In `@cli/src/template/init/src/circom/garaga_convert.rs`:
- Around line 7-9: Update parse_biguint and the public_inputs_to_biguint
conversion flow to validate public-input values against the BN254 scalar-field
order before constructing the Garaga proof or calling get_groth16_calldata_felt.
Preserve existing decimal parsing errors, while returning an appropriate error
for values outside the scalar field; keep coordinate validation bounded to the
BN254 base field as already required.

In `@cli/src/template/init/src/circom/snarkjs_types.rs`:
- Around line 36-42: Allow zero-public-input proofs by removing the non-empty
validation from parse_snarkjs_public_json in
cli/src/template/init/src/circom/snarkjs_types.rs lines 36-42, and update the
public-input conversion in cli/src/template/init/src/circom/garaga_convert.rs
lines 34-42 to convert an empty slice into an empty Vec<BigUint>; leave
enforcement of input-count equality to the API layer against the verification
key’s n_public.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e6dbd06d-f337-455b-8df5-3f1fee1b572d

📥 Commits

Reviewing files that changed from the base of the PR and between 10871f0 and cf652c3.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (18)
  • Cargo.toml
  • cli/src/init/circom.rs
  • cli/src/init/write_toml.rs
  • cli/src/template/circom/lib.rs
  • cli/src/template/init/src/circom.rs
  • cli/src/template/init/src/circom/circom_garaga.rs
  • cli/src/template/init/src/circom/garaga_convert.rs
  • cli/src/template/init/src/circom/snarkjs_types.rs
  • cli/src/template/init/test-vectors/circom/garaga/bn254/README.md
  • cli/src/template/init/test-vectors/circom/garaga/bn254/expected_garaga_calldata.json
  • cli/src/template/init/test-vectors/circom/garaga/bn254/proof.json
  • cli/src/template/init/test-vectors/circom/garaga/bn254/public.json
  • cli/src/template/init/test-vectors/circom/garaga/bn254/verification_key.json
  • docs/docs/adapters/circom.md
  • garaga-calldata-tests/Cargo.toml
  • garaga-calldata-tests/src/bin/gen_garaga_calldata_fixture.rs
  • garaga-calldata-tests/src/circom/mod.rs
  • garaga-calldata-tests/src/lib.rs

Comment thread cli/src/template/init/src/circom/circom_garaga.rs Outdated
Comment thread cli/src/template/init/src/circom/garaga_convert.rs
Comment thread cli/src/template/init/src/circom/snarkjs_types.rs Outdated
…ecks.

Validate
public-input count field bounds (aicoderabbit suggestion) and fix rustfmt/clippy warnings.

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
garaga-calldata-tests/src/lib.rs (1)

45-82: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate fixture-loading logic vs. gen_garaga_calldata_fixture.rs.

load_fixture_proof_result reimplements the identical SnarkJS→CircomProofResult mapping (including z-coordinate fallbacks) that also exists in garaga-calldata-tests/src/bin/gen_garaga_calldata_fixture.rs::load_proof_result. Two independent copies of this mapping risk silently diverging, which would undermine the golden-test guarantee since the fixture generator and the test consumer could disagree on how a proof is parsed.

Consider extracting this into a shared test-utility function reused by both the test module and the fixture-generation binary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@garaga-calldata-tests/src/lib.rs` around lines 45 - 82, Extract the
SnarkJS-to-CircomProofResult mapping from load_fixture_proof_result and the
binary’s load_proof_result into a shared test utility, preserving the existing
proof field construction and z-coordinate fallbacks. Update both callers to
reuse that single helper so fixture generation and consumption cannot diverge.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/docs/adapters/circom.md`:
- Around line 395-398: Update the Flutter snippet surrounding
generateCircomGroth16GaragaCalldata to define vkJson before use by showing how
to load verification_key.json in Dart, or explicitly accept it as an input to
the example; ensure the snippet is copy-paste runnable.

---

Nitpick comments:
In `@garaga-calldata-tests/src/lib.rs`:
- Around line 45-82: Extract the SnarkJS-to-CircomProofResult mapping from
load_fixture_proof_result and the binary’s load_proof_result into a shared test
utility, preserving the existing proof field construction and z-coordinate
fallbacks. Update both callers to reuse that single helper so fixture generation
and consumption cannot diverge.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 43d64666-58cc-4905-87a8-c2d43853cab0

📥 Commits

Reviewing files that changed from the base of the PR and between cf652c3 and 27e1442.

📒 Files selected for processing (12)
  • cli/src/main.rs
  • cli/src/template/circom/lib.rs
  • cli/src/template/init/src/circom.rs
  • cli/src/template/init/src/circom/circom_garaga.rs
  • cli/src/template/init/src/circom/garaga_convert.rs
  • cli/src/template/init/src/circom/snarkjs_types.rs
  • cli/src/template/init/test-vectors/circom/garaga/bn254/README.md
  • docs/docs/adapters/circom.md
  • garaga-calldata-tests/build.rs
  • garaga-calldata-tests/src/bin/gen_garaga_calldata_fixture.rs
  • garaga-calldata-tests/src/circom/mod.rs
  • garaga-calldata-tests/src/lib.rs
💤 Files with no reviewable changes (2)
  • cli/src/template/init/src/circom/snarkjs_types.rs
  • cli/src/main.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • garaga-calldata-tests/src/circom/mod.rs
  • cli/src/template/init/src/circom.rs
  • garaga-calldata-tests/src/bin/gen_garaga_calldata_fixture.rs

Comment thread docs/docs/adapters/circom.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Explore Groth16 proof translation for Starknet verifier calldata integration

1 participant