groth16-zorch
A Groth16 prover implementation in Python using Zorch. This is the Python counterpart of RabbitSNARK, which implements the Groth16 proving scheme using HLO via PrimeIR and ZKX.
| Project | Language | Backend |
|---|---|---|
| rapidsnark | C++ | Native |
| RabbitSNARK | C++ | HLO (ZKIR/ZKX) |
| groth16-zorch | Python | FRX |
Features
- Parse circom proving key (
.zkey) files - Circom witness from a pre-computed
.wtnsfile (e.g. produced by snarkjs) - Load gnark binary exports for circuit proving
- Az/Bz evaluated in pure FRX (
frx.ops.segment_sumover the BN254 field dtype), so they run on the GPU alongside the prover — no native library needed - Groth16 proof generation with snarkjs-compatible JSON output
How to build
-
Clone the repository
git clone https://github.com/fractalyze/groth16-zorch.git
-
Navigate to the project directory
cd groth16-zorch
-
Install the package
pip install -e .
For development with test dependencies:
pip install -e ".[dev]"
How to run
CLI
Circom
# Witness is a pre-computed .wtns (e.g. `snarkjs wtns calculate`)
groth16-zorch circom prove <circuit.zkey> <witness.wtns> <proof.json> <public.json>
groth16-zorch circom verify <vkey.json> <public.json> <proof.json>
Gnark
groth16-zorch gnark prove <export_dir> <proof.json> <public.json> [--no-zk] [--deterministic]
groth16-zorch gnark verify <export_dir> <public.json> <proof.json>
Python API
Circom (.zkey + .wtns)
import numpy as np
from zk_dtypes import bn254_sf_mont
from groth16_zorch.circom.wtns import parse_wtns
from groth16_zorch.circom.zkey import parse_zkey
from groth16_zorch.circom.zkey_to_terms import zkey_to_terms
from groth16_zorch.groth16 import compile_circom, write_public_signals
from groth16_zorch.r1cs import compute_abc
zkey = parse_zkey("path/to/circuit.zkey")
compiled = compile_circom(zkey) # one-time: parse zkey, build term matrices + arrays
wtns = parse_wtns("path/to/circuit.wtns")
witness_mont = wtns.data._witnesses.view(np.dtype(bn254_sf_mont))
_terms, coefficients = zkey_to_terms(zkey)
az_mont, bz_mont = compute_abc(
witness_mont, compiled.terms, coefficients, compiled.domain_size
)
z_std = wtns.data._witnesses
public_signals = write_public_signals(wtns.witnesses, compiled.config.num_public)
proof, public_signals = compiled.prove(z_std, az_mont, bz_mont, public_signals)
Gnark binary export
import numpy as np
from frx import lax
from zk_dtypes import bn254_sf, bn254_sf_mont
from groth16_zorch.gnark import load_gnark_export
from groth16_zorch.groth16 import compile_gnark
# The export carries the solved witness and Az/Bz (solution_a/b), both
# produced by gnark's Go solver — nothing is recomputed here.
data = load_gnark_export("path/to/export/")
compiled = compile_gnark(data)
z_std = np.asarray(
lax.convert_element_type(data.witness_full.view(bn254_sf_mont), bn254_sf)
)
public_signals = [str(int(z_std[i])) for i in range(compiled.config.num_public)]
proof, public_signals = compiled.prove(
z_std, data.az_mont, data.bz_mont, public_signals
)
The output proof.json and public.json follow the same JSON schema as
snarkjs, so you can verify with:
snarkjs groth16 verify verification_key.json public.json proof.json
Compatibility
Circom / snarkjs
groth16-zorch is input/output compatible with the circom/snarkjs ecosystem:
| snarkjs | rapidsnark | groth16-zorch | |
|---|---|---|---|
Input .zkey |
yes | yes | yes |
Input .wtns |
yes | yes | yes |
Output proof.json |
snarkjs format | snarkjs format | snarkjs format |
Verify with snarkjs groth16 verify |
yes | yes | yes |
Gnark
groth16-zorch loads binary exports produced by a gnark Go program (see
tests/gnark/gen_fixture for a minimal example). The export must include
witness_full.bin and solution_a/b.bin — the witness and Az/Bz that gnark's
r1csTyped.Solve computes natively:
| gnark (Go) | groth16-zorch | |
|---|---|---|
Binary export (metadata.json + *.bin) |
produces | consumes |
| Proving key points | setup | loaded from export |
| Witness + Az/Bz | Go solver | loaded from export |
| Proof generation | groth16.Prove() |
compiled.prove() |
| Verification | groth16.Verify() |
verify(vk, proof, signals) |
Benchmark
Prove time for SP1's final Groth16 verifier circuit — BN254, 15,965,950
constraints, domain 2²⁴ — on an RTX 5090. The reference is gnark's
ICICLE GPU Groth16 prover on the same
circuit and GPU. groth16-zorch's proof verifys and is deterministic (fixed
output across runs).
Both provers consume the same gnark export, which already carries the solved witness and Az/Bz (gnark's Go solver produces them at export time). So this is a prove-only comparison — it excludes witness solving on both sides:
| prover | prove (median) | speedup |
|---|---|---|
| groth16-zorch (FRX, GPU) | 1573 ms | 1.50× |
| gnark ICICLE (GPU) | 2355 ms | 1.00× |
gnark's end-to-end run additionally re-solves the witness on every proof (~2.2 s), for ~4.5 s total; groth16-zorch loads that pre-solved witness/Az/Bz straight from the export. One-time setup for groth16-zorch (not counted in the prove time): ~4.4 s to load the 19 GB export and ~5.0 s to compile the 2²⁴ executable.
Reproduce with //benchmark:sp1_groth16 (see .github/workflows/benchmark.yml):
FRX_PLATFORMS=cuda,cpu bazel run //benchmark:sp1_groth16 -- \
--export_dir=<sp1-groth16-export> --deterministic --circuit=sp1
How to test
bazel test //...
Test organization:
//tests/circom:e2e_test— Circom prove/verify via.wtns//tests/gnark:e2e_test— Gnark export prove/verify//tests/circom:zkey_test—.zkeyparser unit tests//tests/circom:wtns_test—.wtnsparser unit tests
License
Licensed under the Apache License, Version 2.0 (see LICENSE).
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file groth16_zorch-0.1.0.tar.gz.
File metadata
- Download URL: groth16_zorch-0.1.0.tar.gz
- Upload date:
- Size: 32.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14059b62fa0762edef3092a32142d309f4d3598b6203038a36e53690b96f081f
|
|
| MD5 |
13dd458c85b4349b5f72bc5cc32ac22d
|
|
| BLAKE2b-256 |
34291e48a4e9676901f573ff45a5ae8f77140b2248773d706785bb95c4fe4688
|
Provenance
The following attestation bundles were made for groth16_zorch-0.1.0.tar.gz:
Publisher:
publish.yml on fractalyze/groth16-zorch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
groth16_zorch-0.1.0.tar.gz -
Subject digest:
14059b62fa0762edef3092a32142d309f4d3598b6203038a36e53690b96f081f - Sigstore transparency entry: 2248207065
- Sigstore integration time:
-
Permalink:
fractalyze/groth16-zorch@6a48ecb14ef61e2c106e63e8ef04785dfd4a5f14 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/fractalyze
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6a48ecb14ef61e2c106e63e8ef04785dfd4a5f14 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file groth16_zorch-0.1.0-py3-none-any.whl.
File metadata
- Download URL: groth16_zorch-0.1.0-py3-none-any.whl
- Upload date:
- Size: 45.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c57dae0b81bb80d60bec67a903191e049d721bdc74805123cebaa3a8c230e545
|
|
| MD5 |
37af92274bbd49f8333a17e549585b83
|
|
| BLAKE2b-256 |
0a66b7d0e9ffbe65f6df1ee06dcdc2174e44ce972cdd93944f715aee7e2f5ea7
|
Provenance
The following attestation bundles were made for groth16_zorch-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on fractalyze/groth16-zorch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
groth16_zorch-0.1.0-py3-none-any.whl -
Subject digest:
c57dae0b81bb80d60bec67a903191e049d721bdc74805123cebaa3a8c230e545 - Sigstore transparency entry: 2248207202
- Sigstore integration time:
-
Permalink:
fractalyze/groth16-zorch@6a48ecb14ef61e2c106e63e8ef04785dfd4a5f14 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/fractalyze
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6a48ecb14ef61e2c106e63e8ef04785dfd4a5f14 -
Trigger Event:
workflow_dispatch
-
Statement type: