zkSync Airbender
A study of Airbender's prover architecture — how a production RISC-V zkVM turns the ideas I built from scratch (fields, AIR, FRI) into a system fast enough to prove real Ethereum-scale execution.
Why I studied it
After building a STARK prover and a KZG commitment scheme from scratch, the natural next question was how these same ideas hold up once proving speed, hardware, and real workloads enter the picture. Airbender is Matter Labs' RISC-V proving system — it serves as the proving layer for ZKsync OS, generating cryptographic proofs that a batch of RISC-V execution was carried out correctly. It's transparent, STARK-based, and open source: the same family of proof system I'd already built a small version of, just under very different performance constraints.
What Airbender proves
ZKsync's execution layer, ZKsync OS, is a Rust state-transition function compiled to two targets: an x86 build that runs in the sequencer for fast transaction processing, and a RISC-V build that feeds into Airbender. Both compilations execute the same code on the same inputs, so their results are deterministically identical — which is what lets a RISC-V replay of the batch stand in as something provable, without a second, hand-written circuit implementation of the VM.
Reading the architecture
The pieces that stood out, mapped against the fundamentals I'd already built:
Field choice
My own prover used a field chosen mostly for clarity while learning. Airbender is built over the Mersenne31 prime field, 2³¹−1, chosen specifically because it maps efficiently onto 32-bit RISC-V values and modern hardware arithmetic — a reminder that field selection is itself a performance decision, not just a correctness one. The constraint system itself is AIR with polynomial degree capped at 2, which keeps proving tractable.
Chunking and recursion
Long-running programs are automatically split into chunks of roughly four million cycles each, up to 2³⁶ cycles total per execution. Each chunk is proven independently and linked back to its neighbors through memory and delegation arguments, which is what makes chunk proving parallelizable in the first place.
After the base-layer proofs exist, Airbender applies recursive
compression: the verifier's own code is compiled to RISC-V and
proven recursively, folding many proofs into one at each layer.
A final pass through zkos_wrapper converts the
format and compresses further into a single SNARK suitable for
on-chain verification — so verification cost stays constant no
matter how long the original execution ran.
No exception handling, by design
Airbender's RISC-V environment runs bare-metal, in machine mode, and deliberately skips runtime exception handling. If a program attempts a misaligned memory access or an invalid instruction, there's no trap — the polynomial constraints simply become unsatisfiable, and proof generation fails. That trusted-code model is a very different way of enforcing correctness than the exception handling I'd assumed was necessary, and it simplifies the circuit considerably.
Delegation circuits
Heavy operations aren't proven inline. When a program needs something like 256-bit arithmetic or hashing, it triggers a delegation call through a custom control-status register, handing the work off to a specialized circuit — a BigInt delegation for U256 and elliptic-curve operations, a BLAKE2 delegation for the hashing behind Merkle commitments, and a non-determinism oracle for supplying external inputs. These delegated circuits still participate in the same memory consistency checks as ordinary execution, but they can be proven in parallel with the main trace.
Machine configurations
Rather than one fixed circuit, Airbender offers multiple machine configurations. A full RV32IM configuration — including signed multiplication and division — handles general-purpose kernel code like ZKsync OS itself, while stripped-down "minimal" machines drop byte-level memory operations and complex arithmetic to shrink circuit size for recursion layers, where the verifier code has simpler requirements. It's a modular take on constraint design: the AIR isn't one monolithic thing, it's assembled per use case.
Where the GPU actually helps
GPU acceleration currently speeds up proving at the base and recursion levels. The final wrapping step still runs on CPU, since it needs roughly 150GB of RAM — a reminder that "GPU proving" in a real system is usually a partial optimization applied where it pays off most, not a blanket rewrite of the whole pipeline.
Where it lands, practically
| Aspect | My from-scratch STARK | Airbender |
|---|---|---|
| Purpose | Learning the proving pipeline end to end | Proving ZKsync OS execution at production scale |
| Field | Chosen for simplicity | Mersenne31 (2³¹−1), chosen for hardware efficiency |
| Trace handling | One flat execution trace | ~4M-cycle chunks, linked via memory arguments |
| Circuit design | Fixed AIR | Configurable machine variants + delegation circuits |
| Error handling | Not modeled | Invalid ops make constraints unsatisfiable, not trapped |
| Hardware target | Single-threaded CPU | GPU for base/recursion proving, CPU for final wrap |
Takeaway
Building a STARK prover from scratch gave me the vocabulary. Reading Airbender's source showed me what that vocabulary looks like under real constraints — chunked, recursively compressed proofs instead of one flat pass, a field picked for hardware efficiency instead of convenience, delegation circuits that offload expensive operations, and a machine model where invalid execution doesn't error, it just becomes unprovable.
The gap between an educational prover and a production one isn't the theory. It's every decision made once speed, memory, and hardware stop being optional.