Succinct zero-knowledge proofs of trading-strategy backtests.
zkBacktest lets a prover run a trading strategy against a committed historical price dataset and produce a STARK proof that the reported performance metrics are the correct, causal execution of that strategy on that data — with no look-ahead and no post-hoc cherry-picking.
The accompanying paper is available in paper/zkbacktest-spec.pdf.
Two independent proof backends exist:
| Backend | Phases | Strategy | Data | What the verifier sees |
|---|---|---|---|---|
| Winterfell AIR | 1–2 | Public | Public | All parameters, total return, Sharpe, drawdown |
| RISC Zero zkVM | 3 | Private | Private | Only the performance metrics + Blake3 commitments |
crates/
zkbacktest-core/ # AIR prover/verifier, Fp arithmetic, BacktestBackend trait
src/
shared/ # Fp, Bar/Dataset, error types, proof options
v1/ # Phase 1: hardwired MAC strategy (AIR, trace, prover, verifier)
v2/ # Phase 2: generic Strategy trait + MacV2 + RSI
v3/ # Phase 3: BacktestBackend trait + Risc0Backend (feature-gated)
zkbacktest-data/ # Synthetic GBM price-series generator
zkbacktest-cli/ # CLI: prove / verify / bench subcommands + bench_paper / bench_v3 / bench_all
zkbacktest-pine/ # Phase 3: Pine-subset interpreter (no zkVM dep; compiles on host + RISC-V)
zkbacktest-guest-io/ # Phase 3: GuestInput / GuestOutput types (shared host/guest)
zkbacktest-guest-methods/ # Phase 3: host crate embedding the compiled guest ELF constants
zkbacktest-guest/ # └─ RISC-V guest binary (isolated workspace; cross-compiled by risc0-build)
paper/ # Compiled specification PDF
benchmarks/ # Benchmark scripts, dataset, results, and figures
examples/ # Example strategy files (.pine and .json AST)
See crates/README.md for a full per-module breakdown.
You only need a standard Rust toolchain:
# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shThe zkVM backend is feature-gated (--features risc0) and requires the RISC Zero toolchain:
# 1. Install rzup (the RISC Zero toolchain manager)
curl -L https://risczero.com/install | bash
source ~/.risc0/.env # or open a new terminal
# 2. Install the RISC Zero Rust toolchain (downloads ~500 MB)
rzup install rust
# Verify installation:
rustup toolchain list | grep risc0 # should print a line containing "risc0"# Clone
git clone https://github.com/aryaethn/zkBacktest.git
cd zkBacktest
# Build and test — Phase 1 & 2 only, no RISC Zero required.
# zkbacktest-guest-methods cross-compiles to RISC-V via build.rs.
cargo build --workspace --exclude zkbacktest-guest-methods
cargo test --workspace --exclude zkbacktest-guest-methods
# Build with the RISC Zero backend enabled (requires rzup install rust above)
cargo build --workspace --features zkbacktest-core/risc0# Prove a MAC(5,20) backtest on 200 synthetic GBM bars (production security)
cargo run --release --bin zkbacktest -- prove \
--bars 200 --k-fast 5 --k-slow 20 --out proof.bin
# Prove with fast/low-security options (development only)
cargo run --release --bin zkbacktest -- prove \
--bars 200 --k-fast 5 --k-slow 20 --fast
# Prove the RSI strategy
cargo run --release --bin zkbacktest -- prove \
--air-strategy rsi --bars 200 --k-rsi 14 --rsi-upper 0.7 --rsi-lower 0.3
# Verify a saved proof
cargo run --release --bin zkbacktest -- verify proof.bin
# Benchmark (3 trials, median reported)
cargo run --release --bin zkbacktest -- bench \
--bars 512 --k-fast 10 --k-slow 40 --trials 3Strategies can be written as Pine Script v5 (.pine) or serialised JSON (.json).
# Prove from a Pine Script source file (strategy stays private in the proof)
cargo run --release --features risc0 --bin zkbacktest -- prove \
--backend risc0 --strategy examples/bollinger_breakout.pine --bars 200 --out proof_r0.bin
# Prove from a JSON AST strategy file
cargo run --release --features risc0 --bin zkbacktest -- prove \
--backend risc0 --strategy examples/mac_strategy.json --bars 200 --out proof_r0.bin
# Verify a RISC Zero receipt (shows public metrics only)
cargo run --release --features risc0 --bin zkbacktest -- verify-risc0 proof_r0.bin
# Benchmark (RISC0_DEV_MODE=1 uses fake proofs for speed; omit for real proofs)
cargo build --release --features risc0 --bin bench_v3
RISC0_DEV_MODE=1 ./target/release/bench_v3 examples/bollinger_breakout.pine
./target/release/bench_v3 examples/bollinger_breakout.pine > benchmarks/results_v3.csvThe interpreter parses a Pine Script v5 subset directly — the same syntax used in TradingView:
//@version=5
strategy("MAC Crossover", initial_capital=10000, slippage=1)
kFast = input.int(5, title="Fast period")
kSlow = input.int(20, title="Slow period")
fast = ta.sma(close, kFast)
slow = ta.sma(close, kSlow)
if ta.crossover(fast, slow)
strategy.entry("L", strategy.long)
if ta.crossunder(fast, slow)
strategy.close("L")
Supported indicators: ta.sma, ta.ema, ta.rma, ta.rsi, ta.atr, ta.stdev,
ta.highest, ta.lowest, ta.wma, ta.macd, ta.bb (Bollinger Bands),
ta.crossover, ta.crossunder, math.floor, math.ceil, math.round,
math.abs, math.sqrt, math.pow.
See examples/mac_strategy.json and examples/bollinger_breakout.json.
| Property | How enforced |
|---|---|
| No look-ahead | AIR buffer-slide constraints / zkVM causal bar ordering |
| Dataset integrity | Blake3 commitment checked in-circuit |
| Strategy correctness | AIR constraint system / zkVM guest execution |
| Strategy privacy (Phase 3) | Strategy and bar data are private zkVM witness; only metrics are public |
| Bars | Strategy | Prove | Verify | Proof size |
|---|---|---|---|---|
| 32 | MAC(5,20) | ~10 ms | ~0.3 ms | ~36 KB |
| 256 | MAC(5,20) | ~13 ms | ~0.7 ms | ~53 KB |
| 512 | MAC(10,40) | ~38 ms | ~1.3 ms | ~62 KB |
| Bars | Prove | Verify | Journal size |
|---|---|---|---|
| 32 | ~686 s (~11 min) | ~78 ms | ~1.8 KB |
| 64 | ~1378 s (~23 min) | ~100 ms | ~3.4 KB |
| 256 | ~5230 s (~87 min) | ~360 ms | ~12 KB |
Prover time scales near-linearly with bar count (α ≈ 0.98). The zkVM overhead relative to the AIR backend is approximately 20,000× at the same bar count — the cost of general-purpose execution privacy. See the paper for full benchmarks and scaling analysis.
# All Phase 1 & 2 tests (no RISC Zero required)
cargo test --workspace --exclude zkbacktest-guest-methods
# Per-crate
cargo test -p zkbacktest-core # unit + integration tests
cargo test -p zkbacktest-pine # SMA, EMA, RSI, OMS, crossover, Pine parser
# Individual integration suites
cargo test -p zkbacktest-core --test round_trip
cargo test -p zkbacktest-core --test negative
cargo test -p zkbacktest-core --test generic_round_trip
cargo test -p zkbacktest-core --test generic_negativeThe full specification and cryptographic analysis is in
paper/zkbacktest-spec.pdf.
It covers the ZK relation definitions, AIR constraint correctness,
security argument (soundness and zero-knowledge), and benchmark methodology.
MIT. See LICENSE for details.