Overview
Spartan is a sumcheck-based Interactive Oracle Proof (IOP) that proves R1CS constraint satisfaction without trusted setup. Jolt uses a customized version of Spartan with univariate-skip optimization and product virtualization to efficiently prove the zkVM’s uniform constraints.Role in the Proving System
Spartan is the first major proving stage after witness generation:- Stage 1: Outer sumcheck with univariate-skip first round
- Stage 2: Product virtual sumcheck for deferred products
- Stages 3-7: Instruction lookups, bytecode, RAM/register checking, claim reductions
- Stage 8: Batched opening proofs
Spartan Protocol Structure
Outer Sumcheck (Stage 1)
The outer sumcheck reduces R1CS satisfaction to polynomial evaluations: Claim:τ: Random challenge from Fiat-Shamireq(τ, x): Equality polynomial (1 when τ=x, 0 otherwise)Az(x),Bz(x): R1CS constraint polynomials at step xm:log₂(trace_length)
-
Prover evaluates the first-round polynomial on an extended domain:
- Standard domain: constraint evaluations at 0 and 1
- Extended domain: evaluations at points {-D, …, D} for degree D
- Interpolates to obtain univariate polynomial
s₁(Y) - Multiplies by Lagrange basis
L(τ_high, Y)evaluated at challengeτ_high
-
Verifier samples challenge
r₀from the univariate polynomial - Benefit: Amortizes first-round cost across multiple constraints in parallel
Product Virtual Sumcheck (Stage 2)
Some R1CS constraints reference virtual products computed via a second sumcheck: Purpose: Prove that deferred products (e.g., complex instruction outputs) match their claimed values without materializing dense polynomials. Protocol:- Outer sumcheck opens virtual products at challenge point
r - Product sumcheck reduces each product to its factors via another sumcheck
- Factor evaluations are verified in later stages
Spartan Submodules
outer.rs - Outer Sumcheck
OuterUniSkipProver:- Computes first-round univariate polynomial via extended evaluation
- Performs streaming sumcheck for subsequent rounds
- Binds R1CS constraint polynomials by challenge bits
- Handles rounds after univariate-skip first round
- Uses streaming window optimization for memory efficiency
- Degree bound: 3 (cubic round polynomials)
product.rs - Product Virtualization
ProductVirtualUniSkipProver:- Proves deferred products via second sumcheck
- Uses univariate-skip for first round (like outer sumcheck)
- Opens factor polynomials at challenge point
shift.rs - Shift Polynomials
Purpose: Handle instructions that reference “next step” state (e.g., branch targets). Mechanism:- Shift polynomials represent
witness[i+1]in constraints - Proved via explicit polynomial openings
- Used sparingly (most constraints use within-step state)
instruction_input.rs - Instruction Constraints
Purpose: Enforce correct instruction operand extraction from bytecode. Constraints:- Immediate value extraction (from encoded instruction)
- Register index decoding
- Opcode consistency checks
Sumcheck Instance Parameters
Each sumcheck instance implementsSumcheckInstanceParams:
- Input claim: How the sumcheck claim is computed from prior openings
- Output claim: What polynomial evaluations the sumcheck produces
- Constraints: BlindFold R1CS encoding (for ZK mode)
Streaming Sumcheck Optimization
Jolt uses streaming sumcheck to reduce memory usage: Standard Sumcheck:- Materializes all polynomial coefficients in memory
- Memory: O(2^m · poly_count · field_size)
- Processes polynomials in chunks (“windows”)
- Recomputes coefficients on-the-fly for each round
- Memory: O(window_size · poly_count · field_size)
- Tradeoff: ~2x more computation for 10-100x less memory
- Outer sumcheck (Stage 1): Streams over R1CS constraint polynomials
- Register checking (Stage 3): Streams over register state
- RAM checking (Stage 4): Streams over memory accesses
ZK Mode: BlindFold Integration
In ZK mode (with--features zk), Spartan integrates with BlindFold:
Standard mode:
- Round polynomials sent in the clear
- Verifier checks claims directly
- Round polynomials Pedersen-committed (hidden)
- BlindFold R1CS proves verifier checks without revealing polynomials
- No trusted setup required (unlike Groth16)
Opening Claims
Spartan produces opening claims for polynomial evaluations:- Which polynomial (e.g.,
RamInc,InstructionRa[0]) - Evaluation point (derived from sumcheck challenges)
- Expected evaluation result
Performance Characteristics
Prover Time
Outer Sumcheck (Stage 1):- Dominates overall proving time (~40-50% of total)
- Cost: O(trace_length · num_constraints · m) field operations
- Univariate-skip reduces first-round cost by ~30%
- Much cheaper (~5-10% of Stage 1)
- Only processes virtual products (small subset of witness)
Verifier Time
- O(num_constraints · m) field operations
- Logarithmic in trace length (verifies sumcheck round polynomials)
- Spartan verification ~1-10ms for typical zkVM traces
Memory Usage
- Streaming sumcheck: ~100MB for 10⁶ cycles with 64GB trace materialized
- Without streaming: ~10GB for same trace
- Tradeoff configurable via
ReadWriteConfig
Key Types
UniformSpartanKey:Key Files
jolt-core/src/zkvm/spartan/outer.rs: Outer sumcheck prover/verifierjolt-core/src/zkvm/spartan/product.rs: Product virtualizationjolt-core/src/zkvm/spartan/shift.rs: Shift polynomial handlingjolt-core/src/zkvm/spartan/instruction_input.rs: Instruction constraint checkingjolt-core/src/zkvm/r1cs/key.rs: UniformSpartanKey definition
Next Steps
- R1CS Constraints: Understanding the constraint system
- RAM Checking: Memory consistency verification
- Opening Proofs: Batched polynomial commitments