> ## 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.

# BlindFold

> Zero-knowledge protocol for sumcheck proofs without SNARK composition

# 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:

1. Reveal partial information through sumcheck round polynomials (not fully zero-knowledge)
2. Use recursive SNARK composition to hide round polynomials (expensive and complex)

BlindFold provides a third approach: encode the sumcheck verifier computation as a small R1CS constraint system, and prove its satisfaction using Nova folding and Spartan.

## How BlindFold Works

### High-Level Protocol

1. **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
2. **R1CS construction (Stage 8)**: Both prover and verifier build the same `VerifierR1CS` that encodes all sumcheck verification checks
3. **Nova folding**: The real R1CS instance is folded with a random satisfying instance to hide the witness
4. **Spartan proof**: A Spartan outer sumcheck proves the folded relaxed R1CS is satisfied
5. **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 in `jolt-core/subprotocols/blindfold/` with the following modules:

### Core Modules

* **`mod.rs`**: R1CS primitives (`Variable`, `LinearCombination`, `Constraint`), stage configuration, and public inputs
* **`protocol.rs`**: `BlindFoldProver`, `BlindFoldVerifier`, `BlindFoldProof` - main protocol implementation
* **`r1cs.rs`**: `VerifierR1CS`, `VerifierR1CSBuilder` - sparse R1CS encoding of sumcheck verification
* **`witness.rs`**: `BlindFoldWitness` - witness assignment from sumcheck stage data
* **`folding.rs`**: Nova folding - cross-term computation and random instance sampling
* **`spartan.rs`**: Spartan outer/inner sumcheck over folded R1CS
* **`relaxed_r1cs.rs`**: Relaxed R1CS instance/witness with Hyrax grid layout
* **`output_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 (feature `zk` enabled), the Jolt prover executes:

1. **Trace execution**: Same as standard mode
2. **Witness generation**: Same polynomial structure
3. **Streaming commitment**: Same Dory commitments
4. **Spartan stage**: Standard R1CS proof
5. **Sumcheck stages 1-7**: Use `prove_zk` variants that commit round polynomials via Pedersen
6. **Opening proofs**: Use `bind_opening_inputs_zk` for committed evaluations
7. **BlindFold stage 8**: Generate `BlindFoldProof` proving 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`): `JoltCurve` and `JoltGroupElement` traits 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_zk` and `verify_zk` methods

## 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 implements `SumcheckInstanceParams` with paired methods:

```rust theme={null}
// Compute claim value from polynomial openings
fn input_claim(&self, accumulator: &mut Accumulator) -> F;

// Describe the same computation as R1CS constraints
fn input_claim_constraint(&self) -> InputClaimConstraint;

// Provide challenge values used in the constraint
fn input_constraint_challenge_values(&self, accumulator: &Accumulator) -> Vec<F>;
```

**Any change to `input_claim()` must have a matching update to `input_claim_constraint()`**. If these become desynchronized:

* The R1CS becomes unsatisfiable
* BlindFold proof generation fails
* The `muldiv` end-to-end test catches this error

The same synchronization requirement applies to output claims via `output_claim_constraint()`.

### Concrete Implementations

Claim/constraint pairs are implemented in:

* `spartan/outer.rs`: `OuterRemainingSumcheckParams`
* `ram/read_write_checking.rs`: `RamReadWriteCheckingParams`
* `instruction_lookups/ra_virtual.rs`: `InstructionRaSumcheckParams`
* `claim_reductions/*.rs`: All claim reduction parameter types

## Verification

The BlindFold verifier:

1. Detects ZK mode from the proof structure: `proof.stage1_sumcheck_proof.is_zk()`
2. Builds the same `VerifierR1CS` from staged configurations and public inputs
3. Verifies the Nova folding was performed correctly
4. Verifies the Spartan proof of the folded R1CS
5. 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)

When witness values are decomposed for BlindFold constraints (e.g., splitting into public and advice components), the verifier's `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 `BlindFoldProof` structure (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 optimization is handled in `layout.rs` via `compute_witness_layout()`.

## Configuration

### Stage Configuration

Each sumcheck stage provides a `StageConfig` 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 via `BakedPublicInputs`.

### Hyrax Parameters

`HyraxParams` controls the witness grid dimensions, balancing commitment cost and opening proof size.

## Testing

BlindFold correctness is verified through:

* **`muldiv` e2e test**: Run in both modes (`--features host` and `--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](https://eprint.iacr.org/2021/370)
* **Spartan**: [Spartan: Efficient and general-purpose zkSNARKs without trusted setup](https://eprint.iacr.org/2019/550)
* **Hyrax**: [Doubly-efficient zkSNARKs without trusted setup](https://eprint.iacr.org/2017/1132)

The specific application to making sumcheck protocols zero-knowledge is novel to Jolt.

## 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
