zk-proven judge

Each verdict in a proven batch carries a succinct zero-knowledge proof (SP1, Groth16) that verdict = judge(trace) for the judge program registered on-chain. A contract checks it. You do not have to trust Karatum's servers or any TEE vendor for the judging step.

What is proven, and what is not

  • Proven. For every trace in the batch, the Karatum judge (ported to Rust, run in the SP1 RISC-V zkVM) parses the trace, applies the verdict rules of its task type and computes the trace hash and the verdict hash. The proof commits to a Merkle root over keccak256(keccak256(traceHash ‖ verdictHash)). A malformed trace makes the program abort, so no proof exists for it.
  • Not proven. That the trace is honest: the evidence in it (transfers, balances, approvals) was collected by the runner from the Mirror fork. Pair the proof with a TEE-run runner or a Flight Record for that part. The Rust port is checked against the published TypeScript evaluator by differential tests, not by a proof of equivalence.

Full method, costs and how to reproduce: docs/methodology/zk-judge.md. Re-execution path: verifiable judge.

Rust port vs the published evaluator

Run zkdiff-2026-10-16-seed7: 21,744 / 21,744 cases identical (same accept/reject decision, same verdict, checks and reason, same verdict, trace and task-spec hashes), against bundle 0x6f1b3cdd70…2adcbe. Includes all 134 stored traces; 10,107 cases judged by both, 11,637 rejected by both.

Proven batches

BatchVerdictsCyclesProving (CPU)On-chain
judge-sample-2049:all:134
root 0xe34d4ed032…622983
13491.8 M54.4 min0xc8884bd2…775860 · 812,888 gas

Contracts (Ethereum Sepolia)

ZkJudgeVerifier
0x5b03cf51e29F91DEAc8A129d5373fF6D28b4B823 (no owner; submitBatch is permissionless)
SP1 verifier
Succinct gateway 0x397A5f7f3d…48dA9B → Groth16 v6.1.0 0xb69f2584CB…a6f4e2
Program allow-list
EvaluatorRegistry (revoking the vkey there invalidates every batch of that program)