Zero-knowledge proof system for PDF417 barcode decoding.
zk-barcodes/
├── zokrates/ # ZoKrates circuits and supporting files
│ ├── *.zok # Circuit source files
│ ├── bin/ # Compiled circuit artifacts (prover/verifier keys)
│ ├── for-measurement/ # Benchmark circuit variants (bench_*.zok)
│ └── tests/ # Python/pytest circuit test suite (see tests/README.md)
│
├── measurements/ # Benchmark results
│ ├── raw/ # Raw timing output files (one per benchmark run)
│ ├── measurements.csv # Parsed aggregate data
│ ├── plots/ # Generated plots
│ └── benchmark_table.tex # LaTeX summary table
│
├── python-scripts/ # Helper scripts for witness generation, plotting, etc.
├── sp1-pdf417/ # Alternative SP1 zkVM pipeline for PDF417 decoding
├── test-witness/ # Test witness data (generated by param-generation.sh)
├── external/
│ ├── circ/ # CirC compiler infrastructure (git submodule)
│ └── rxing/ # Modified rxing barcode library with witness output (git submodule)
│
├── generate-r1cs.sh # Compile a .zok circuit to R1CS and generate keys
├── generate-proof.sh # Compile, generate a proof, and verify
├── param-generation.sh # Generate params.zok and witness files from a barcode image or parameters
├── generate-test-witness.sh # Generate witness image, decode and extract augmented witness data, and put witness data in the correct format for CirC
├── run-benchmark.sh # Run benchmarks for a circuit
└── run-sweep.sh # Sweep benchmark over a grid of parameters
The main proof pipeline uses ZoKrates circuits compiled by CirC to R1CS, with the Dorian proof system over Curve25519. The sp1-pdf417/ directory contains an independent SP1 zkVM approach to the same problem.
System dependencies:
-
Rust (stable toolchain) — required for CirC and rxing
-
cvc5 — SMT solver used by CirC
# macOS brew install --cask cvc5/cvc5/cvc5 # Ubuntu apt-get install cvc5 libssl-dev
-
Python 3 with a virtual environment and dependencies installed:
cd python-scripts python3 -m venv venv source venv/bin/activate pip install -r requirements.txt
Submodules:
git submodule update --init --recursiveBuild rxing (needed for witness generation):
cd external/rxing
cargo build --release -p rxing-cliBuild CirC (needed for circuit compilation):
cd external/circ
./driver.py -F zok zokc r1cs spartan bellman smt
./driver.py -bThe quickest way to run a proof is to edit the top of run-sweep.sh to have the parameters you want and then run that. This will generate all necessary witness files, compile the right thing, run the proof, and verify it.
For more fine-tuned parameter control, there is a two-step process: generate params and a witness, then compile, prove, and verify.
param-generation.sh takes a barcode image (or generates one from parameters) and produces both a params.zok file with the circuit constants and the .pin/.vin witness files needed for proving:
source python-scripts/venv/bin/activate
# Generate a barcode, params, and witness at 1080×720
./param-generation.sh -r 10 -c 5 -e 2 -W 1080 -H 720
# Use an existing barcode image, auto-detecting dimensions
./param-generation.sh -i path/to/barcode.png --chunk-size 10 --max-rows 30 --max-cols 10 --max-ec-level 2Output lands in test-witness/ by default (-d DIR to override).
generate-proof.sh handles circuit compilation, proof generation, and verification in one step. Use the corresponding bench_ wrapper in zokrates/for-measurement/ rather than the circuit directly — the bench files import params.zok from test-witness/:
./generate-proof.sh test-witness/<witness>.json zokrates/for-measurement/bench_full_circuit.zokPass --commit-input image if the circuit has image as an input to generate an external commitment to the image.
run-benchmark.sh compiles circuits, generates witnesses, and measures prove/verify time. All parameters can be set via environment variables:
# Run with default parameters (HD image, full circuit suite)
./run-benchmark.sh
# Override specific parameters
IMG_WIDTH=640 IMG_HEIGHT=480 MAX_ROWS=21 MAX_COLS=13 ./run-benchmark.sh
# Dry run (skips actual proving, useful to check setup)
DRY_RUN=1 ./run-benchmark.shRaw results are written to measurements/raw/<circuit>/<timestamp>.txt.
run-sweep.sh runs run-benchmark.sh over a grid of image sizes, max row/column counts, and error correction levels defined at the top of the script:
./run-sweep.sh
# Dry run to preview the sweep without running proofs
DRY_RUN=1 ./run-sweep.shsource python-scripts/venv/bin/activate
# Parse raw files into measurements.csv
python python-scripts/parse_measurements.py
# Generate plots into measurements/plots/
python python-scripts/plot_measurements.py
# Generate LaTeX table into measurements/benchmark_table.tex
python python-scripts/generate_latex_table.py