Recursive Proving
RISC Zero's zkVM uses recursive proving in order to achieve unbounded computation size, constant proof size, proof aggregation, and proof composition.
Prover::prove_with_opts allows users to choose between composite, succinct or groth16 receipts.
The rest of this page describes lowlevel details that are not necessary for users.
Recursive Proving Process
The endtoend process for proof generation is shown in the following diagram.
To summarize the diagram:
 The program is executed, resulting in a collection of Segments.
 Each Segment is proven, resulting in a SegmentReceipt.
 Each SegmentReceipt is lifted, resulting in a SuccinctReceipt.
 Pairs of SuccinctReceipts are joined, resulting in another SuccinctReceipt. This continues until a single SuccinctReceipt remains.
 The final SuccinctReceipt is passed through identity_p254, which prepares for Groth16 proving.
 The SuccinctReceipt is compressed, generating a Groth16Receipt.
The Groth16Receipt can now be posted onchain and verified by the RISC Zero Verifier Contract.
Recursive Circuit Architecture
RISC Zero's zkVM consists of three circuits.
 The RISCV Circuit is a STARK circuit that proves correct execution of RISCV programs.
 The Recursion Circuit is a separate STARK circuit, that's designed to efficiently generate proofs for the verification of STARK proofs and to support the integration of custom accelerator circuits into the zkVM. This circuit has a similar architecture to the RISCV Circuit, but with fewer columns and an instruction set optimized for cryptography. The same proof system is used for both the RISCV Circuit and the Recursion Circuit.
 The STARKtoSNARK Circuit is an R1CS circuit that verifies proofs from the Recursion Circuit.
Recursion Programs
The Recursion Circuit supports a number of programs, including lift
, join
, resolve
, and identity_p254
.
These are using internally to the Prover implementations to produce SuccinctReceipt and Groth16Receipt.

The
lift
program verifies a STARK proof from the RISCV Prover, using the Recursion Prover. This recursion proof has a single constanttime verification procedure, with respect to the original segment length, and is then used as the input to all other recursion programs (e.g. join, resolve, and identity_p254). 
The
join
program verifies two proofs from the Recursion Prover, using the Recursion Prover. By repeated application ofjoin
, any number of receipts for execution spans within the same session can be compressed into a single receipt for the entire session. 
The
identity_p254
program verifies a proof from the Recursion Prover using the Recursion Prover with the Poseidon254 hash function. The identity_p254 program is used as the last step in the prover pipeline before running the Groth16 prover.
STARKtoSNARK Wrapping
All of the recursion programs in the previous section output a SuccinctReceipt, which is a STARK proof (~200kB)
The final step in the recursion process is compress()
, which outputs a Groth16Receipt, which can be verified onchain using the RISC Zero Verifier Contract.