Why Advice?
Some computations are easy to verify but hard to compute:- Factoring: Given
n = a * b, computing(a, b)is hard, but verifying is trivial - Path finding: Finding a path is hard, verifying a path is easy
- Merkle proofs: Computing the proof path is non-trivial, verification is simple
- Preimages: Finding
xsuch thathash(x) = yis hard, checking is easy
Types of Advice
TrustedAdvice
TrustedAdvice<T> is committed before the prover sees any challenges:
- Secret keys
- Private witness data
- Data that must be hidden from the verifier
secret, never the value itself.
UntrustedAdvice
UntrustedAdvice<T> is provided by the prover but must be verified:
- Witness data
- Intermediate computation results
- Optimization hints
Runtime Advice Functions
The#[jolt::advice] macro creates dual-mode advice functions:
Basic Advice Function
-
During advice computation phase (feature
compute_advice):- Function body executes
- Result is written to advice tape via
AdviceTapeIO
-
During proof generation (without
compute_advice):- Function body is skipped
- Result is read from advice tape
Using Advice in Guests
Verification Macros
check_advice!
Verifies a boolean condition:- On RISC-V: Emits
VirtualAssertEQcustom instruction - On native: Regular
assert!
check_advice_eq!
Verifies equality directly (more efficient):check_advice_eq! requires values that fit in registers. For u128, use check_advice! instead.AdviceTapeIO Trait
Custom types need to implementAdviceTapeIO to work with advice:
Automatic Implementation (Pod Types)
Manual Implementation
Built-in Implementations
- Primitives:
u8,u16,u32,u64,i8,i16,i32,i64,usize - Arrays:
[T; N]whereT: Pod - Tuples: Up to 7 elements where each implements
AdviceTapeIO - Vectors:
Vec<T>whereT: Pod(requiresstdorguest-std)
Advanced Example: Subset Verification
Low-Level Advice API
For advanced use cases, use the raw advice tape API:AdviceWriter (Compute Advice Phase)
AdviceReader (Proof Generation Phase)
Two-Pass Execution
Jolt uses a two-pass strategy for advice:Pass 1: Compute Advice
Guest builds withcompute_advice feature:
- Advice functions execute their bodies
- Results written to advice tape
- Tape is saved
Pass 2: Generate Proof
Guest builds withoutcompute_advice:
- Advice functions read from tape
- Bodies are not executed
- Proof is generated
#[jolt::provable] macro.
Best Practices
Always Verify
Use
check_advice! for all UntrustedAdvice. Never trust prover-provided data.Use Trusted for Secrets
Secrets should be
TrustedAdvice, never public inputs or UntrustedAdvice.Optimize Advice Computation
Advice functions run outside the proof. Use efficient native algorithms.
Minimize Advice Size
Large advice increases memory usage. Provide minimal witness data.
Common Patterns
Pattern: Factorization Witness
Pattern: Merkle Proof Verification
Pattern: Search Result
Related Concepts
- Provable Macro - Configure advice memory sizes
- Guest and Host Architecture - Understanding guest/host separation