#[jolt::advice] macro enables functions to compute values outside the zkVM and provide them as advice to the guest program. This allows expensive computations to run in native code while the guest only verifies the results.
Overview
Advice functions operate in two modes:- Compute mode (
compute_advicefeature enabled): Executes the function body and writes the result to the advice tape - Consume mode (default): Reads the pre-computed result from the advice tape
Basic Usage
Requirements
required
Must be
jolt::UntrustedAdvice<T> where T implements AdviceTapeIO.required
Must be immutable. No
mut bindings or &mut references allowed.required
The function body computes the advice value. Should return
UntrustedAdvice::new(value) or just value (automatic wrapping).Supported Types
Types that implementAdviceTapeIO can be used as advice:
Built-in Types
- Primitive integers:
u8,u16,u32,u64,usize,i8,i16,i32,i64 - Arrays:
[T; N]whereT: Pod - Tuples:
(A, B),(A, B, C), … up to 7 elements (where each implementsAdviceTapeIO) - Vectors:
Vec<T>whereT: Pod(requiresstdorguest-stdfeature)
Custom Types
ImplementAdviceTapeIO manually:
bytemuck for POD types:
Examples
Integer Factorization
Subset Index Finding
Custom Struct with Nested Types
How It Works
Two-Pass Compilation
The#[jolt::provable] macro compiles the guest program twice:
- First pass (
compute_advicefeature): Advice functions execute their bodies and populate the advice tape - Second pass (normal): Advice functions read pre-computed values from the tape
prove_* functions.
Macro Expansion
The#[jolt::advice] macro expands to:
Best Practices
Always Verify Advice
Advice is untrusted input from the prover. Always verify it satisfies the required constraints:Use References for Large Inputs
Advice functions can take references to avoid copying:Size Considerations
Setmax_untrusted_advice_size in #[jolt::provable] large enough for all advice values:
Limitations
- Parameters must be immutable (no
mutor&mut) - Return type must be
UntrustedAdvice<T>whereT: AdviceTapeIO - The function body is only executed during the first pass (with
compute_advicefeature) - Reading beyond the advice tape length causes a runtime error during proof generation
Related
- #[jolt::provable] - Mark functions as provable
- check_advice! macros - Verify advice correctness
- AdviceReader - Reading advice data from the advice tape
- AdviceWriter - Writing advice data to the advice tape