Skip to main content

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 .wtns file (e.g. produced by snarkjs)
  • Load gnark binary exports for circuit proving
  • Az/Bz evaluated in pure FRX (frx.ops.segment_sum over 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

  1. Clone the repository

    git clone https://github.com/fractalyze/groth16-zorch.git
    
  2. Navigate to the project directory

    cd groth16-zorch
    
  3. 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.zkey parser unit tests
  • //tests/circom:wtns_test.wtns parser 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

groth16_zorch-0.1.1.tar.gz (32.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

groth16_zorch-0.1.1-py3-none-any.whl (45.4 kB view details)

Uploaded Python 3

File details

Details for the file groth16_zorch-0.1.1.tar.gz.

File metadata

  • Download URL: groth16_zorch-0.1.1.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

Hashes for groth16_zorch-0.1.1.tar.gz
Algorithm Hash digest
SHA256 00518b7b1c2fd69b37f37180e84f02bd2bb3f66b08569c4bd0fc874625fbb1a4
MD5 b58d6518e691259eefcbf31a6a87c5e5
BLAKE2b-256 342fcfdfb4aa1ecc6a2a37b25aa3d56823c588ad2cd738b687659950bd652335

See more details on using hashes here.

Provenance

The following attestation bundles were made for groth16_zorch-0.1.1.tar.gz:

Publisher: release.yml on fractalyze/groth16-zorch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file groth16_zorch-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: groth16_zorch-0.1.1-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

Hashes for groth16_zorch-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 03da754f1f0db007d6e1317ab7b4fa12f89deaa49d20bc0a40380b08c4867298
MD5 6b4ba65eb33aad4f5c4c1afd2d1abb28
BLAKE2b-256 fb69101a94e5aaa1f715ef62e24f60825edcb8ab46ce26b6b4c49424e9462de6

See more details on using hashes here.

Provenance

The following attestation bundles were made for groth16_zorch-0.1.1-py3-none-any.whl:

Publisher: release.yml on fractalyze/groth16-zorch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page