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

# verify (build_verifier)

> Verify a zero-knowledge proof for a provable function

## Overview

The verification functions allow you to verify that a zero-knowledge proof is valid. The `#[jolt::provable]` macro generates two verification-related functions:

1. `build_verifier_<function_name>` - Creates a reusable verifier closure (recommended)
2. Internal verification logic used by the verifier closure

## Function Signature

### build\_verifier

```rust theme={null}
pub fn build_verifier_<function_name>(
    preprocessing: jolt::JoltVerifierPreprocessing<jolt::F, jolt::PCS>,
) -> impl Fn(
    // ... public inputs
    output: ReturnType,
    panic: bool,
    // Optional: trusted_advice_commitment (if function has trusted advice)
    proof: jolt::RV64IMACProof,
) -> bool + Sync + Send
```

### Parameters

**Preprocessing:**

* `preprocessing` - Verifier preprocessing data (obtained from `preprocess_verifier_<function_name>`)

**Verifier Closure Parameters:**

* **Public inputs** - The same public inputs provided to the prover
* `output` - The claimed output value
* `panic` - Whether the program panicked during execution
* `trusted_advice_commitment` (optional) - Commitment to trusted advice, if present
* `proof` - The zero-knowledge proof to verify

### Return Value

Returns `true` if the proof is valid, `false` otherwise.

## Verification Process

The verifier:

1. Reconstructs the expected I/O device state from public inputs and claimed outputs
2. Verifies the proof against the preprocessing data
3. Checks that all constraints are satisfied
4. Returns a boolean indicating validity

## Usage Examples

### Basic Verification

```rust theme={null}
use std::time::Instant;

// Setup: compile and preprocess (typically done once)
let target_dir = "/tmp/jolt-guest-targets";
let mut program = guest::compile_fib(target_dir);
let shared_preprocessing = guest::preprocess_shared_fib(&mut program);
let prover_preprocessing = guest::preprocess_prover_fib(shared_preprocessing.clone());
let verifier_setup = prover_preprocessing.generators.to_verifier_setup();
let verifier_preprocessing = guest::preprocess_verifier_fib(
    shared_preprocessing,
    verifier_setup,
);

// Build verifier and prover
let prove_fib = guest::build_prover_fib(program, prover_preprocessing);
let verify_fib = guest::build_verifier_fib(verifier_preprocessing);

// Prove
let input = 50;
let (output, proof, io_device) = prove_fib(input);

// Verify
let is_valid = verify_fib(input, output, io_device.panic, proof);
println!("Proof is valid: {}", is_valid);
assert!(is_valid);
```

### With Multiple Inputs

```rust theme={null}
let a = vec![1usize, 2, 3, 4, 5];
let b = vec![0usize, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let n = 221u8;

// Generate proof
let (output, proof, io_device) = prove_advice_demo(n, a.clone(), b.clone());

// Verify with the same inputs
let is_valid = verify_advice_demo(
    n,
    a,
    b,
    output,
    io_device.panic,
    proof,
);
assert!(is_valid);
```

### With Trusted Advice

```rust theme={null}
let public_input = 42;
let trusted_data = vec![1, 2, 3, 4, 5];

// Prover commits to trusted advice
let (commitment, hint) = guest::commit_trusted_advice_my_function(
    trusted_data.clone(),
    &prover_preprocessing,
);

// Generate proof
let (output, proof, io_device) = prove_my_function(
    program,
    prover_preprocessing,
    public_input,
    trusted_data,
    commitment,
    hint,
);

// Verifier only needs the commitment (not the trusted data)
let is_valid = verify_my_function(
    public_input,
    output,
    io_device.panic,
    commitment,
    proof,
);
assert!(is_valid);
```

## Preprocessing Conversion

You can obtain verifier preprocessing from prover preprocessing:

```rust theme={null}
// From prover preprocessing
let verifier_preprocessing = guest::verifier_preprocessing_from_prover_fib(
    &prover_preprocessing
);

// Or from shared preprocessing + verifier setup
let verifier_setup = prover_preprocessing.generators.to_verifier_setup();
let verifier_preprocessing = guest::preprocess_verifier_fib(
    shared_preprocessing,
    verifier_setup,
);
```

## Generated From

For a function annotated with `#[jolt::provable]`:

```rust theme={null}
#[jolt::provable]
fn fib(n: u32) -> u32 {
    // implementation
}
```

The macro generates `build_verifier_fib` that creates verification closures.

## Important Notes

* The verifier is **deterministic** - the same inputs and proof always produce the same result
* The verifier is **thread-safe** (`Sync + Send`) and can be used concurrently
* Verification is typically **much faster** than proof generation
* The verifier **does not** need access to trusted advice data, only its commitment
* The `panic` flag from `io_device.panic` must be passed to the verifier

## Related Functions

* [`prove`](/api/functions/prove) - Generates proofs that can be verified
* [`preprocess`](/api/functions/preprocess) - Generates preprocessing data for verification
* [`analyze`](/api/functions/analyze) - Analyzes execution without generating a proof
