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.0.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.0-py3-none-any.whl (45.4 kB view details)

Uploaded Python 3

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

Hashes for groth16_zorch-0.1.0.tar.gz
Algorithm Hash digest
SHA256 14059b62fa0762edef3092a32142d309f4d3598b6203038a36e53690b96f081f
MD5 13dd458c85b4349b5f72bc5cc32ac22d
BLAKE2b-256 34291e48a4e9676901f573ff45a5ae8f77140b2248773d706785bb95c4fe4688

See more details on using hashes here.

Provenance

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

Publisher: publish.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.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

Hashes for groth16_zorch-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c57dae0b81bb80d60bec67a903191e049d721bdc74805123cebaa3a8c230e545
MD5 37af92274bbd49f8333a17e549585b83
BLAKE2b-256 0a66b7d0e9ffbe65f6df1ee06dcdc2174e44ce972cdd93944f715aee7e2f5ea7

See more details on using hashes here.

Provenance

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

Publisher: publish.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

0.1.1

2 files

This release

0.1.0 This release

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