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

Installation

Python 3.11 on Linux x86_64 only.

CPU

pip install groth16-zorch

GPU (CUDA 12)

pip install groth16-zorch 'frx[cuda12]' \
    --extra-index-url https://fractalyze.github.io/pypi/simple/

The extra index carries the CUDA plugin wheels, which are too large for PyPI's per-file limit. It is not needed for the CPU tier.

Verify

python -c "import frx, groth16_zorch; print(frx.devices()); print(groth16_zorch.__version__)"

[CpuDevice(id=0)] means the CPU tier; a CUDA install prints the GPU devices.

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

Metadata

Release files for groth16-zorch 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for groth16-zorch 0.1.2
File Size Uploaded
groth16_zorch-0.1.2.tar.gz 33.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for groth16-zorch 0.1.2
File Interpreter ABI Platform
groth16_zorch-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 78.8 kB

Release files / groth16_zorch-0.1.2.tar.gz

Download URL groth16_zorch-0.1.2.tar.gz
Size 33.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3128b8430588eaebf0d7fda306f9b22e0ec87cb5f2d88c338ae145d32c52540c
BLAKE2b-256 checksum
How to use checksums
80c549955782c281b8ee88a53fbb38ca06093a2c1be7b18131e2a22a87db84fc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release files / groth16_zorch-0.1.2-py3-none-any.whl

Download URL groth16_zorch-0.1.2-py3-none-any.whl
Size 45.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
001a9eba36902b347b7327df4de056abd2ec382337e53ccbabc92abbfc801e0b
BLAKE2b-256 checksum
How to use checksums
ad6aaacc6c9b580172f79f8f453b9ccfc284797e9b85115ddcbf221082064596
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page