Skip to main content
The check_advice! and check_advice_eq! macros enforce constraints on untrusted advice values. They generate efficient virtual assertions that are proved within the zkVM.

Overview

Advice values are provided by the prover and must be verified for correctness. These macros generate VirtualAssertEQ RISC-V custom instructions that the Jolt prover includes in the proof. On RISC-V targets (guest code): Generates custom instruction for ZK proof On non-RISC-V targets (native execution): Falls back to standard assert! / assert_eq!

check_advice!

Asserts that a boolean condition holds.

Syntax

bool
required
Boolean expression that must evaluate to true.
&str
Optional error message. Only used in native mode; not included in guest binary.

Examples

Basic Validation

With Error Message

Range Checks

Capacity Checks

check_advice_eq!

Asserts that two register-sized values are equal. More efficient than check_advice! for equality checks.

Syntax

register-sized
required
First value. Must fit in a RISC-V register (u8, u16, u32, u64, usize, or signed equivalents).
register-sized
required
Second value. Must fit in a RISC-V register.
&str
Optional error message. Only used in native mode.

Examples

Verify Multiplication

Verify Array Length

Verify Struct Fields

With Custom Message

Differences

When to Use

Use check_advice! for:

  • Complex boolean conditions
  • Multiple conditions with && / ||
  • Range checks and comparisons
  • Conditions involving non-register types (e.g., u128)

Use check_advice_eq! for:

  • Simple equality checks
  • Verifying computed values against expected values
  • Register-sized comparisons (u8, u16, u32, u64, usize)

Implementation Details

RISC-V Custom Instruction

On riscv32 or riscv64 targets, both macros generate a VirtualAssertEQ instruction:
The instruction asserts rs1 == rs2. If the assertion fails, the proof generation fails.

Native Fallback

On non-RISC-V targets (e.g., during native testing or host execution):

Error Messages

Error messages are only active in native mode. When compiling for RISC-V:
  • The error message string is not included in the guest binary
  • Only the assertion logic is preserved
  • This keeps the guest code size minimal
For debugging, run your guest function natively first:

Common Patterns

Verify Factorization

Verify Subset Membership

Verify Sorted Indices

Verify Geometric Properties

Best Practices

1. Always Verify Advice

Every piece of advice must be constrained:

2. Widen Types to Avoid Overflow

When multiplying advice values, widen to prevent overflow:

3. Check Bounds Before Indexing

4. Verify Lengths Match

When advice provides parallel arrays:

Limitations

Register Size Constraint

check_advice_eq! requires both values fit in a RISC-V register:

Compile-Time vs Runtime

The macros check conditions at runtime during proof generation, not at compile time: