BlindFold Zero-Knowledge Protocol
BlindFold is Jolt’s zero-knowledge protocol that makes all sumcheck proofs zero-knowledge without requiring SNARK composition. Instead of revealing sumcheck round polynomial coefficients in the clear, BlindFold commits to them and proves correctness through a compact verifier R1CS.Overview
Traditional zkSNARKs for virtual machines either:- Reveal partial information through sumcheck round polynomials (not fully zero-knowledge)
- Use recursive SNARK composition to hide round polynomials (expensive and complex)
How BlindFold Works
High-Level Protocol
- Committed sumchecks (Stages 1-7): During Jolt’s seven sumcheck stages, the prover commits to each round polynomial’s coefficients using Pedersen commitments instead of revealing them
- R1CS construction (Stage 8): Both prover and verifier build the same
VerifierR1CSthat encodes all sumcheck verification checks - Nova folding: The real R1CS instance is folded with a random satisfying instance to hide the witness
- Spartan proof: A Spartan outer sumcheck proves the folded relaxed R1CS is satisfied
- Hyrax opening: Final polynomial openings verify the witness commitment
Key Innovation
Rather than proving “the sumcheck verifier accepts” using a full SNARK recursion (which would require proving Jolt inside another SNARK), BlindFold exploits the fact that the sumcheck verifier is already arithmetic and can be encoded directly as R1CS constraints.Architecture
BlindFold is implemented injolt-core/subprotocols/blindfold/ with the following modules:
Core Modules
mod.rs: R1CS primitives (Variable,LinearCombination,Constraint), stage configuration, and public inputsprotocol.rs:BlindFoldProver,BlindFoldVerifier,BlindFoldProof- main protocol implementationr1cs.rs:VerifierR1CS,VerifierR1CSBuilder- sparse R1CS encoding of sumcheck verificationwitness.rs:BlindFoldWitness- witness assignment from sumcheck stage datafolding.rs: Nova folding - cross-term computation and random instance samplingspartan.rs: Spartan outer/inner sumcheck over folded R1CSrelaxed_r1cs.rs: Relaxed R1CS instance/witness with Hyrax grid layoutoutput_constraint.rs: Constraint types for claim binding (InputClaimConstraint,OutputClaimConstraint)layout.rs: Witness grid layout computation for Hyrax commitment structure
Integration with Jolt
Feature Flag: zk
BlindFold is activated via the zk Cargo feature flag. The Jolt prover operates in two modes:
| Aspect | Standard (--features host) | ZK (--features host,zk) |
|---|---|---|
| Sumcheck proving | prove() - cleartext round polynomials | prove_zk() - Pedersen-committed |
| Univariate skip | prove_uniskip_round() | prove_uniskip_round_zk() |
| Proof structure | Contains Claims<F> (opening claims) | Contains BlindFoldProof |
| Input claims | Appended to Fiat-Shamir transcript | Skipped; used in R1CS |
| Opening proof | Raw evaluation binding | Committed evaluation binding |
Prover Pipeline
In zero-knowledge mode (featurezk enabled), the Jolt prover executes:
- Trace execution: Same as standard mode
- Witness generation: Same polynomial structure
- Streaming commitment: Same Dory commitments
- Spartan stage: Standard R1CS proof
- Sumcheck stages 1-7: Use
prove_zkvariants that commit round polynomials via Pedersen - Opening proofs: Use
bind_opening_inputs_zkfor committed evaluations - BlindFold stage 8: Generate
BlindFoldProofproving all sumcheck verifications are correct
Supporting Components
BlindFold required several additions to Jolt’s cryptographic toolkit:- Pedersen commitments (
poly/commitment/pedersen.rs): Commit to small vectors (round polynomials) - Curve abstractions (
curve.rs):JoltCurveandJoltGroupElementtraits for elliptic curve operations - ZK Dory openings (
poly/commitment/dory/commitment_scheme.rs): Committed evaluation proofs (y_com) - ZK sumcheck variants (
sumcheck.rs,univariate_skip.rs):prove_zkandverify_zkmethods
Critical Invariant: Claim/Constraint Synchronization
The most important correctness requirement for BlindFold is that every sumcheck’s claim computation must exactly match its R1CS constraint. Every sumcheck instance implementsSumcheckInstanceParams with paired methods:
input_claim() must have a matching update to input_claim_constraint(). If these become desynchronized:
- The R1CS becomes unsatisfiable
- BlindFold proof generation fails
- The
muldivend-to-end test catches this error
output_claim_constraint().
Concrete Implementations
Claim/constraint pairs are implemented in:spartan/outer.rs:OuterRemainingSumcheckParamsram/read_write_checking.rs:RamReadWriteCheckingParamsinstruction_lookups/ra_virtual.rs:InstructionRaSumcheckParamsclaim_reductions/*.rs: All claim reduction parameter types
Verification
The BlindFold verifier:- Detects ZK mode from the proof structure:
proof.stage1_sumcheck_proof.is_zk() - Builds the same
VerifierR1CSfrom staged configurations and public inputs - Verifies the Nova folding was performed correctly
- Verifies the Spartan proof of the folded R1CS
- Verifies the Hyrax opening proofs for witness commitments
Verifier Mode Consistency
The verifier must support both standard and ZK modes from the same binary. This creates a subtle requirement:- In ZK mode,
input_claim()is never called (claims are verified inside BlindFold R1CS) - In standard mode,
input_claim()is called (claims must match prover exactly)
new_from_verifier must reconstruct the full value for standard mode using helpers like ram::reconstruct_full_eval().
Performance Characteristics
BlindFold’s overhead compared to non-ZK mode:- Prover time: Additional Pedersen commitments per sumcheck round (~5-10% overhead)
- Proof size: Adds
BlindFoldProofstructure (Nova + Spartan + Hyrax openings) - Verifier time: Additional R1CS verification (~minimal overhead)
Memory Efficiency
BlindFold uses Hyrax-style grid layout for witness commitments to balance:- Row commitment cost (fewer rows = fewer commitments)
- Opening proof size (fewer columns = smaller proofs per opening)
layout.rs via compute_witness_layout().
Configuration
Stage Configuration
Each sumcheck stage provides aStageConfig describing:
- Number of instances in the stage
- Number of rounds per instance
- Degree of round polynomials
- Claim constraints (input and output)
Baked Public Inputs
Fiat-Shamir challenges and other public values are “baked” directly into the R1CS matrix coefficients, avoiding the need for public input wires. This is implemented viaBakedPublicInputs.
Hyrax Parameters
HyraxParams controls the witness grid dimensions, balancing commitment cost and opening proof size.
Testing
BlindFold correctness is verified through:muldive2e test: Run in both modes (--features hostand--features host,zk)- Advice tests: Exercise non-ZK mode with advice polynomials to catch verifier reconstruction bugs
- Unit tests: Individual sumcheck constraint satisfaction tests
Academic Context
BlindFold draws on several lines of research:- Nova folding: Nova: Recursive Zero-Knowledge Arguments from Folding Schemes
- Spartan: Spartan: Efficient and general-purpose zkSNARKs without trusted setup
- Hyrax: Doubly-efficient zkSNARKs without trusted setup
Future Directions
Potential improvements to BlindFold:- Optimized folding schemes (e.g., SuperNova for non-uniform computation)
- Alternative commitment schemes for round polynomials
- Further R1CS optimization via constraint sharing across stages