Abstract
Zero-knowledge virtual machines (zkVMs) represent a fundamental shift in how we think about computational integrity. Rather than writing circuits by hand for every program we want to prove, a zkVM lets you compile arbitrary code — written in Rust, C, or any RISC-V-targeting language — and generate a succinct proof that the computation was executed correctly. This paper explores the architecture of SP1 and Jolt, two leading zkVMs, and examines how they enable a workflow where a full Ethereum execution layer client like Reth can be compiled to RISC-V, executed inside a prover, and have its output — a verified block or transaction trace — attested to cryptographically without a verifier re-executing anything.
1. The Problem: Trustless Execution at Scale
Blockchains like Ethereum separate consensus (agreeing on what happened) from execution (computing the result of what happened). The execution layer (EL) processes transactions, updates state, and produces a new world state root after each block. Every full node re-executes every transaction to verify this — a model that is correct but expensive to scale.
The question zkVMs answer is: can a single prover execute a block and produce a proof so compact that any verifier can check it in milliseconds, without re-executing?
This is the core idea behind Type-1 zkEVMs, zkRollups, and emerging zkEL clients. The proof attests to the correctness of the state transition:
prove( block_n, world_state_n ) → ( world_state_{n+1}, proof )
verify( proof, block_n, world_state_n, world_state_{n+1} ) → true | false
2. The RISC-V Bridge
RISC-V is an open, minimal instruction set architecture (ISA). It is the compilation target that makes zkVMs general-purpose. The insight is straightforward:
- RISC-V has a small, well-defined instruction set (~50 base instructions).
- Any language with an LLVM backend (Rust, C, C++) can target RISC-V.
- A zkVM that can prove RISC-V execution can therefore prove any program compiled from those languages.
This eliminates the previous bottleneck where teams had to hand-write arithmetic circuits for every computation they wanted to prove. With a zkVM, you write normal Rust code, compile with --target riscv32im-succinct-zkvm-elf (SP1) or similar, and hand the ELF binary to the prover.
2.1 Reth as a Proving Target
Reth is an Ethereum execution layer client written in Rust. It implements the full Ethereum state transition function (STF): it takes a block and a pre-state, applies every transaction, and produces a post-state. Because it is Rust, it compiles to RISC-V cleanly.
The proving workflow looks like this:
reth (Rust)
→ rustc + LLVM
→ RISC-V ELF
→ zkVM prover (SP1 / Jolt)
→ ZK proof of correct block execution
The prover feeds the ELF binary the block data and pre-state as input, executes it inside the zkVM, and produces a proof. The verifier checks the proof against the pre-state root, block hash, and claimed post-state root — all in constant time.
3. SP1
SP1 is a zkVM developed by Succinct Labs. It proves the execution of RISC-V programs using a combination of STARKs (for the main execution trace) and a SNARK recursion layer (Groth16 or PLONK) that compresses the STARK proof into something cheap to verify on-chain.
3.1 Architecture
SP1’s proof system consists of three layers:
Core STARK — The execution of the RISC-V program is broken into shards, segments of the full trace that can be proven in parallel. Each shard covers a fixed number of cycles of the RISC-V CPU. The STARK proves the correct transition of registers, memory, and program counter across the shard.
Recursive aggregation — Individual shard proofs are recursively combined. SP1 uses a custom recursion circuit that verifies one or more STARK proofs inside another STARK. This compresses arbitrarily large traces into a single proof.
Wrapping (Groth16 / PLONK) — The final aggregated STARK is wrapped in a Groth16 or PLONK proof, which has a constant verification cost (~250k gas on Ethereum). This is what gets posted on-chain.
3.2 Precompiles
One of SP1’s most important engineering decisions is its precompile system. Certain operations — SHA-256, Keccak-256, elliptic curve operations, Blake3 — are extremely expensive to prove in raw RISC-V because they involve many cycles. SP1 exposes these as precompiles: accelerated circuits that handle the operation in far fewer constraints.
For Ethereum execution proving, this matters enormously. The EVM uses Keccak for nearly everything (state trie hashing, transaction hashing, address derivation). Without a Keccak precompile, proving a single block would be impractical. SP1’s Keccak precompile reduces its cost by roughly two orders of magnitude.
3.3 SP1 and Reth
The sp1-reth project (maintained by Succinct) demonstrates the full pipeline. It:
- Takes an Ethereum block as input
- Runs Reth’s STF inside SP1’s zkVM
- Produces a Groth16 proof that the block was executed correctly
The proof can be verified by a smart contract on Ethereum, enabling trustless light clients and bridging without a trusted committee.
4. Jolt
Jolt (Joint Lookup Table) is a zkVM developed by a16z crypto research. It takes a different cryptographic approach to proving RISC-V execution, prioritizing prover speed and simplicity of implementation over minimizing proof size.
4.1 The Lasso/Jolt Framework
Jolt is built on top of Lasso, a new lookup argument. The key insight behind Lasso is that you can decompose a lookup over a large table into lookups over smaller subtables, and use a multilinear polynomial commitment scheme (Spartan + Hyrax/Zeromorph) to prove these lookups efficiently.
RISC-V instructions naturally decompose into lookups: the ADD instruction, for example, can be expressed as a lookup into an addition table. Jolt encodes every RISC-V instruction this way, including the memory/register access model.
This approach — proving instruction execution via structured lookups rather than arithmetic gates — leads to:
- Simpler circuits: No custom constraint per instruction. The same lookup machinery handles all 50+ RISC-V instructions.
- Parallelizable proving: Lookup proofs for different instructions are largely independent.
- Fast prover times: Benchmarks show Jolt’s prover operating at ~1M cycles/second on commodity hardware for small programs.
4.2 Continuations
Like SP1, Jolt needs to handle programs that run for more cycles than fit in a single proof. It achieves this through continuations — splitting execution at checkpoint boundaries and linking proofs together. This is an active development area; long-running programs (like a full Reth block execution, which may run for hundreds of millions of cycles) require robust continuation support.
4.3 Trade-offs vs SP1
| Property | SP1 | Jolt |
|---|---|---|
| Proof system | STARKs + Groth16 wrap | Spartan (multilinear) |
| On-chain verification cost | ~250k gas (Groth16) | Larger, no wrap yet |
| Prover speed | Moderate, GPU-accelerated | Fast on CPU |
| Precompile system | Mature | Early stage |
| Reth integration | Production (sp1-reth) | Research stage |
| Recursion/aggregation | Mature | In development |
5. Proving a Block: End-to-End Walkthrough
Here is a concrete walkthrough of what happens when you prove an Ethereum block using SP1 + Reth:
Step 1 — Fetch inputs
// The prover host fetches the block and pre-state from an RPC node
let block: Block = provider.get_block(block_number).await?;
let pre_state: StateWitness = provider.get_witness(block_number).await?;
The StateWitness contains all the account and storage slots touched by the block — the minimum state needed to re-execute without a full archive node.
Step 2 — Execute inside SP1
let client = ProverClient::new();
let mut stdin = SP1Stdin::new();
stdin.write(&block);
stdin.write(&pre_state);
// This runs Reth's STF inside the RISC-V zkVM
let (output, report) = client.execute(RETH_ELF, stdin).run().unwrap();
RETH_ELF is the Reth binary compiled to RISC-V. The prover executes it, recording the full execution trace.
Step 3 — Generate proof
let (proof, vk) = client.prove(RETH_ELF, stdin).groth16().run().unwrap();
SP1 takes the execution trace, breaks it into shards, proves each shard, recursively aggregates, and wraps in Groth16. This is the expensive step — proving a mainnet Ethereum block currently takes minutes on a high-end machine or seconds on a GPU cluster.
Step 4 — Verify on-chain
// Solidity verifier (generated by SP1)
ISP1Verifier.verifyProof(
vkey, // verification key for the Reth ELF
publicValues, // pre-state root, post-state root, block hash
proofBytes // the Groth16 proof
);
The on-chain verifier checks the proof in ~250k gas. If it passes, the contract knows — with cryptographic certainty — that the claimed post-state root is the correct result of applying the block to the pre-state.
6. Transaction-Level Proofs
Block-level proofs prove the full STF. But sometimes you need finer granularity — for example, proving a single transaction executed correctly (useful for bridges, fraud proofs, or per-user receipts).
This is achievable by modifying the program passed to the zkVM. Instead of running the full block through Reth, you:
- Construct a minimal state witness containing only the accounts touched by the target transaction.
- Run only that transaction through the EVM inside the zkVM.
- Prove the output: sender balance delta, contract storage changes, logs emitted.
The proof attests to a partial state transition — that given the specific pre-state slots, the transaction produced the claimed output. This is cheaper to prove and useful for cross-chain verification where you only care about a specific event.
7. Open Challenges
Prover cost — Proving a full Ethereum mainnet block at 30M gas takes significant compute. Current estimates range from ~5 minutes on a high-end GPU to several hours on CPU. The industry target is sub-second proving for real-time block production.
Memory constraints — RISC-V programs have a flat memory model. Proving large memory accesses (Reth’s state trie operations touch significant RAM) requires efficient offline memory checking, which adds proving overhead.
Precompile coverage — Ethereum’s precompiles (BN254 pairing, ECDSA recovery, modexp) all need accelerated zkVM precompiles to be practical. SP1 has most of these; completeness is an ongoing effort.
Formal verification of the STF — The zkVM proves that Reth executed correctly, not that Reth implements the Ethereum spec correctly. A bug in Reth would produce a valid proof of an incorrect result. Formal verification of the STF itself remains an open research problem.
Continuation overhead — Splitting long executions across multiple proof shards and linking them adds overhead both in prover time and proof size. Better continuation schemes are an active research area in both SP1 and Jolt.
8. Conclusion
zkVMs have transformed zero-knowledge proofs from a domain requiring deep cryptographic expertise into a general-purpose engineering tool. By targeting RISC-V as a common ISA, SP1 and Jolt allow production Rust codebases — including full Ethereum EL clients like Reth — to be compiled, executed, and proven without any circuit-specific code.
The resulting proofs are succinct enough to verify on-chain, enabling a future where Ethereum’s execution layer can be verified by a smart contract rather than re-executed by every node. This unlocks trustless light clients, ZK-based bridges, and eventually a fully proven execution layer that brings Ethereum’s security guarantees to any environment that can run a Groth16 verifier.
The tooling is still maturing — prover speed, memory efficiency, and precompile coverage remain active engineering problems — but the architectural foundation is sound. The RISC-V zkVM is the proving primitive that the next generation of verifiable infrastructure will be built on.
References
- Succinct Labs. SP1: A performant, 100% open-source zkVM. https://github.com/succinctlabs/sp1
- Arun Kannan et al. Jolt: SNARKs for Virtual Machines via Lookups. a16z crypto research, 2023.
- Setty, S. Spartan: Efficient and general-purpose zkSNARKs without trusted setup. CRYPTO 2020.
- Paradigm. Reth: Modular, contributor-friendly Ethereum execution client in Rust. https://github.com/paradigmxyz/reth
- Succinct Labs. sp1-reth: Proving Ethereum blocks with SP1. https://github.com/succinctlabs/sp1-reth
- Ethereum Foundation. The Merge and the execution/consensus layer split. ethereum.org
Comments