Overview
In a zkVM like Jolt, the prover must convince the verifier of two key properties:- Memory consistency: Every read from memory (RAM or registers) returns the value from the most recent write to that address
- Lookup correctness: Instruction outputs correctly reference precomputed lookup tables
Memory Consistency Problem
Consider an execution trace with memory operations (reads and writes) across an address space of size . The verifier must ensure:- For each read at address at time , the value read equals the value from the most recent write to before time
- If no prior write exists, the read returns the initial value at address
Offline Memory Checking
Offline memory checking (introduced by Blum et al.) uses a simple observation: if we sort all memory accesses by address and timestamp, consistency can be verified locally.High-Level Approach
- For each memory operation, record a tuple
- Sort tuples by
- Check that for consecutive accesses to the same address:
- A read returns the value from the previous write
- The first access to an address reads the initial value
Challenge in SNARKs
Sorting is expensive in a SNARK. Instead, Jolt uses multiset equality checks via polynomial commitments.Multiset Equality via Grand Product
To prove two multisets and are equal without sorting:- Represent each multiset as the roots of a polynomial:
- corresponds to
- corresponds to
- Evaluate both products at a random challenge point
- If the products are equal, the multisets are equal (except with negligible probability)
Read-Write Memory Checking in Jolt
Jolt implements memory checking for both RAM and registers using a variant of the offline memory checking technique.Memory Tuples
For each memory operation, Jolt tracks:- Address: Which memory location is accessed
- Timestamp: When the access occurs (cycle number)
- Value: The data read or written
- Operation type: Read or write
Grand Product Argument
The prover constructs two multisets:- Read set: All memory reads, each tagged with
- Write set: All memory writes (plus initial values), tagged similarly
Implementation
The memory checking implementation lives injolt-core/src/zkvm/:
ram/read_write_checking.rs: RAM consistency verificationregisters/: Register read-write checkinginstruction_lookups/: Instruction table lookups
Lookup Arguments
Lookup arguments prove that values appear in a precomputed table. This is critical for Jolt’s instruction execution model.Lasso and Jolt’s Lookup Argument
Jolt uses the Lasso lookup argument, which:- Decomposes large table lookups into smaller subtable lookups
- Uses offline memory checking on the subtables
- Achieves prover time linear in the trace length (not table size)
Twist and Shout
Jolt’s implementation uses the “Twist and Shout” optimization:- Twist: Decompose large lookups into small chunks
- Shout: Use one-hot encodings for read addresses to avoid materializing full polynomials
Read-After-Write (RAF) Polynomials
Jolt uses RAF polynomials to encode lookup operations:- : Read address (one-hot encoding of which table entry is accessed)
- : Read data (the value returned from the lookup)
Increment Counters
Jolt also tracks increment counters for registers and RAM:- RdInc: Counts writes to each destination register
- RamInc: Counts writes to each RAM address
Polynomial Representations
Jolt uses specialized polynomial representations for memory checking:- OneHotPolynomial: Stores only indices of nonzero entries instead of full vectors
- RaPolynomial: Lazily materializes read address polynomials across sumcheck rounds
- SharedRaPolynomials: Shares equality tables across multiple polynomials for memory efficiency
Further Reading
For more details on memory checking and lookup arguments:- Lasso paper - Linear-time lookup arguments
- Jolt paper - Complete Jolt zkVM design
- Offline memory checking - Original Blum et al. technique
- Chapter 5 of Proofs, Arguments, and Zero Knowledge - GKR protocol and memory checking
This page provides a high-level overview of memory checking in Jolt. For detailed implementation specifics, refer to the source code in
jolt-core/src/zkvm/ram/ and jolt-core/src/zkvm/instruction_lookups/.