Memory checking and lookup arguments are fundamental techniques in zkVM design. They allow efficient verification that memory accesses are consistent (reads return previously written values) and that operations correctly reference precomputed tables.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/a16z/jolt/llms.txt
Use this file to discover all available pages before exploring further.
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/.