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

# The

> Learn how to use the provable macro to generate proving and verification functions

The `#[jolt::provable]` macro is the primary way to create provable functions in Jolt. It transforms a regular Rust function into a full zkVM program with generated host-side proving and verification infrastructure.

## Basic Usage

```rust theme={null}
#![cfg_attr(feature = "guest", no_std)]

#[jolt::provable]
fn fibonacci(n: u32) -> u128 {
    let mut a = 0u128;
    let mut b = 1u128;
    for _ in 1..n {
        let sum = a + b;
        a = b;
        b = sum;
    }
    b
}
```

This generates several host-side functions:

* `compile_fibonacci(target_dir)` - Compiles guest to RISC-V
* `preprocess_shared_fibonacci(program)` - Shared preprocessing
* `preprocess_prover_fibonacci(shared)` - Prover-specific preprocessing
* `preprocess_verifier_fibonacci(shared, generators)` - Verifier-specific preprocessing
* `build_prover_fibonacci(program, preprocessing)` - Returns proving closure
* `build_verifier_fibonacci(preprocessing)` - Returns verification closure
* `prove_fibonacci(...)` - Direct proof generation
* `analyze_fibonacci(...)` - Program analysis without proving

## Parameters

The macro accepts configuration parameters:

### Memory Configuration

```rust theme={null}
#[jolt::provable(
    heap_size = 1048576,              // 1 MB heap (default: 4096)
    stack_size = 4096,                // 4 KB stack (default: 4096)
    max_input_size = 4096,            // Max input bytes (default: 4096)
    max_output_size = 4096,           // Max output bytes (default: 4096)
    max_untrusted_advice_size = 0,    // Untrusted advice (default: 0)
    max_trusted_advice_size = 0,      // Trusted advice (default: 0)
)]
fn my_function(input: Vec<u8>) -> Vec<u8> {
    // Function body
}
```

<Note>
  Memory sizes must be powers of 2 or the linker will fail. These values determine the guest's memory layout.
</Note>

### Trace Configuration

```rust theme={null}
#[jolt::provable(
    max_trace_length = 1048576  // Max execution steps (default: 1048576)
)]
fn compute(x: u64) -> u64 {
    // Complex computation
}
```

The trace length affects:

* Maximum program complexity
* Preprocessing time
* Proof generation time

### Development Features

```rust theme={null}
#[jolt::provable(
    backtrace = "full",  // Enable backtraces: "full" or "simple"
    profile = "release"  // Build profile: "release" or "dev"
)]
fn debug_function(x: u32) -> u32 {
    x * 2
}
```

<Warning>
  Backtraces and debug profiles increase guest binary size and execution time. Use only during development.
</Warning>

## Function Signatures

### Public Inputs

Regular parameters become public inputs to the proof:

```rust theme={null}
#[jolt::provable]
fn verify_hash(data: Vec<u8>, expected_hash: [u8; 32]) -> bool {
    let computed = sha256(&data);
    computed == expected_hash
}
```

Both `data` and `expected_hash` are public inputs that must be provided by both prover and verifier.

### Trusted Advice

Wrap parameters in `TrustedAdvice<T>` to mark them as committed advice:

```rust theme={null}
#[jolt::provable]
fn prove_knowledge(
    public_key: [u8; 32],
    secret_key: jolt::TrustedAdvice<[u8; 32]>
) -> bool {
    derive_public_key(&secret_key) == public_key
}
```

The prover commits to trusted advice before seeing the challenge. The verifier receives only the commitment.

### Untrusted Advice

Wrap parameters in `UntrustedAdvice<T>` for witness data:

```rust theme={null}
#[jolt::provable]
fn verify_membership(
    root: [u8; 32],
    leaf: [u8; 32],
    proof: jolt::UntrustedAdvice<Vec<[u8; 32]>>
) -> bool {
    // Verify Merkle proof
    verify_merkle_proof(root, leaf, &proof)
}
```

Untrusted advice is provided by the prover but must be verified by the guest.

<Info>
  See [Runtime Advice](/concepts/runtime-advice) for the difference between trusted and untrusted advice.
</Info>

### Return Values

Return values become public outputs:

```rust theme={null}
#[jolt::provable]
fn compute_hash(data: Vec<u8>) -> [u8; 32] {
    sha256(&data)
}
```

Both prover and verifier know the output value. For private outputs, write to trusted advice instead.

## Generated Functions

The macro generates a complete proving/verification workflow:

### Compilation

```rust theme={null}
let mut program = compile_my_function("/tmp/jolt-guest");
```

Compiles the guest function to RISC-V ELF binary. The binary is cached in the target directory.

### Preprocessing

Preprocessing happens in phases:

```rust theme={null}
// Phase 1: Shared preprocessing (used by both prover and verifier)
let shared = preprocess_shared_my_function(&mut program);

// Phase 2: Prover preprocessing
let prover_preprocessing = preprocess_prover_my_function(shared.clone());

// Phase 2: Verifier preprocessing
let verifier_generators = /* commitment scheme setup */;
let verifier_preprocessing = preprocess_verifier_my_function(
    shared,
    verifier_generators
);
```

See [Preprocessing](/concepts/preprocessing) for details.

### Building Closures

Create reusable proving/verification closures:

```rust theme={null}
// Build prover
let prove = build_prover_my_function(program, prover_preprocessing);

// Build verifier
let verify = build_verifier_my_function(verifier_preprocessing);

// Use multiple times
let (output1, proof1, _io1) = prove(input1);
let (output2, proof2, _io2) = prove(input2);

let valid1 = verify(input1, output1, false, proof1);
let valid2 = verify(input2, output2, false, proof2);
```

### Direct Proving

For one-off proofs:

```rust theme={null}
let (output, proof, program_io) = prove_my_function(
    program,
    preprocessing,
    public_input,
    untrusted_advice,
);
```

### Analysis

Analyze program execution without generating a proof:

```rust theme={null}
let summary = analyze_my_function(input);
println!("Cycles: {}", summary.total_cycles);
println!("Memory used: {}", summary.memory_used);
```

## Complete Example

**Guest (`guest/src/lib.rs`):**

```rust theme={null}
#![cfg_attr(feature = "guest", no_std)]

#[jolt::provable(
    heap_size = 32768,
    max_trace_length = 65536,
    max_input_size = 8192,
    max_output_size = 32
)]
fn hash_chain(data: Vec<u8>, iterations: u32) -> [u8; 32] {
    let mut hash = sha256(&data);
    for _ in 0..iterations {
        hash = sha256(&hash);
    }
    hash
}
```

**Host (`src/main.rs`):**

```rust theme={null}
use guest::*;

fn main() {
    // Compile
    let mut program = compile_hash_chain("/tmp/jolt");
    
    // Preprocess (once per program)
    let shared = preprocess_shared_hash_chain(&mut program);
    let preprocessing = preprocess_prover_hash_chain(shared);
    
    // Build prover
    let prove = build_prover_hash_chain(program, preprocessing);
    
    // Prove
    let data = b"Hello, Jolt!".to_vec();
    let iterations = 100;
    let (hash, proof, _) = prove(data.clone(), iterations);
    
    // Verify
    let verifier_preprocessing = /* ... */;
    let verify = build_verifier_hash_chain(verifier_preprocessing);
    assert!(verify(data, iterations, hash, false, proof));
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Set memory limits appropriately">
    Overallocation wastes proving time. Measure actual usage with `analyze_*` before finalizing limits.
  </Accordion>

  <Accordion title="Minimize public inputs">
    Large public inputs increase verification time. Use advice for large witness data.
  </Accordion>

  <Accordion title="Use trusted advice for secrets">
    Don't pass secrets as public inputs. Use `TrustedAdvice<T>` instead.
  </Accordion>

  <Accordion title="Reuse preprocessing">
    Preprocessing is expensive. Reuse the same preprocessing for multiple proofs of the same program.
  </Accordion>
</AccordionGroup>

## Limitations

* Function must have a determinate signature (no generics in macro itself)
* All types must implement `Serialize` + `Deserialize` (via `postcard`)
* Advice types must implement `AdviceTapeIO`
* Function cannot be `async` or have special ABIs

## Related Concepts

* [Guest and Host Architecture](/concepts/guests-and-hosts)
* [Runtime Advice](/concepts/runtime-advice)
* [Preprocessing](/concepts/preprocessing)
