A command-line interface for executing, proving, and verifying RISC-V ELF programs using the Lambda VM zkVM.
cargo build --release -p cliThe binary will be available at target/release/cli.
The CLI consumes RISC-V ELF binaries. The repo ships ready-to-use guest programs that you can compile with:
# RISC-V assembly tests → executor/program_artifacts/asm/*.elf
make compile-programs-asm
# Rust guest programs → executor/program_artifacts/rust/*.elf (needs the sysroot + nightly toolchain)
make compile-programs-rust
# Benchmark programs → executor/program_artifacts/bench/*.elf (needs the sysroot + nightly toolchain)
make compile-benchSee the root README.md for the toolchain setup.
Run a RISC-V ELF program without generating a proof. Useful for testing and debugging.
cargo run -p cli --release -- execute <PROGRAM.elf> [--private-input <FILE>] [--flamegraph <FILE>] [--cycles]| Flag | Description |
|---|---|
--private-input <FILE> |
Pass private input bytes to the guest (read via get_private_input()). |
--flamegraph <FILE> |
Generate folded-stack flamegraph output. See Guest Program Flamegraphs. |
--cycles |
Count instructions during execution and print the dynamic instruction count. Also reports Keccak calls / Ecsm calls / Dma calls (accelerator syscall invocations), plus Dma bytes copied and the Dma rows those copies add to the trace before its power-of-two padding. One guest memcpy is chunked into several DMA ecalls, so the byte and row lines, not the call count, are what the copies cost. The lines cover memcpy, memmove and memset, which share one ecall path and one table; the commit byte loop lives in that same table but is not tallied here. Combined with --flamegraph, the accelerator lines are omitted (the flamegraph path exposes no per-log data). |
Generate a STARK proof for a RISC-V ELF program execution.
cargo run -p cli --release -- prove <PROGRAM.elf> -o proof.bin [flags]| Flag | Description |
|---|---|
-o, --output <FILE> |
Output path for the serialized proof bundle. Required. |
--private-input <FILE> |
Pass private input bytes to the guest. |
--blowup <N> |
FRI blowup factor (power of 2). Higher = fewer queries, smaller proof, slower proving. [default: 2] |
--time |
Print total proving time. |
--cycles |
Run one extra execution outside the timer and print the dynamic instruction count. Also supported with --continuations. |
--elements |
Build traces and print main-trace and aux-trace field element counts. Monolithic proving only; conflicts with --continuations. |
--continuations |
Prove as a continuation bundle split into fixed-size epochs. |
--epoch-size-log2 <N> |
Continuation epoch size as 2^N cycles. Requires --continuations. Defaults to 20; values below 18 are rejected. |
Verify a proof generated by prove.
cargo run -p cli --release -- verify <PROOF> <PROGRAM.elf> [flags]| Flag | Description |
|---|---|
--blowup <N> |
FRI blowup factor used during proving. Must match. [default: 2] |
--time |
Print verification time. |
--continuations |
Verify a continuation proof bundle produced by prove --continuations. |
Returns exit code 0 on successful verification, 1 on failure. --blowup must
match the value used during proving.
Build traces and print main-trace and aux-trace field element counts without running the proof step. Useful for sizing.
cargo run -p cli --release -- count-elements <PROGRAM.elf> [--private-input <FILE>]# Compile the bundled assembly tests
make compile-programs-asm
# Execute a simple program
cargo run -p cli --release -- execute executor/program_artifacts/asm/add.elf
# Generate and verify a proof
cargo run -p cli --release -- prove executor/program_artifacts/asm/add.elf -o /tmp/proof.bin
cargo run -p cli --release -- verify /tmp/proof.bin executor/program_artifacts/asm/add.elf
# Generate and verify a continuation proof
cargo run -p cli --release -- prove program.elf -o /tmp/cont.bin --continuations --epoch-size-log2 20
cargo run -p cli --release -- verify /tmp/cont.bin program.elf --continuations
# Generate a continuation proof and print total dynamic instruction count
cargo run -p cli --release -- prove program.elf -o /tmp/cont.bin --continuations --cycles
# Prove with private input and print metrics
cargo run -p cli --release -- prove program.elf -o /tmp/proof.bin --private-input input.bin --time --cyclesFor continuation proofs, --epoch-size-log2 is the power in 2^N cycles. Larger
values reduce epoch count and fixed per-epoch overhead, but increase peak memory.
As rough ethrex 10-transfer distinct-account reference points from a local sweep:
19 used about 6.9 GB peak heap, 20 about 9.5 GB, 21 about 15.8 GB, and 22
about 26.8 GB. For a new workload, use the highest value the machine can run
without swapping.
Continuation proof bundles are self-contained for standalone verification: the
verifier needs only the proof file and the ELF. When --private-input is used,
the serialized proof does not include the raw private input bytes — it
carries only the private-input page count; the private genesis lives in
committed, bus-enforced columns the verifier never recomputes (see
docs/continuations_design.md §3.6). This is not a zero-knowledge guarantee,
though: committed columns are still opened at STARK query positions, so do not
treat proof files as cryptographically hiding the private input.
Generate flamegraphs showing where the guest RISC-V program spends its execution time (by instruction count).
cargo run -p cli --release -- execute <PROGRAM.elf> --flamegraph folded.txtRequires inferno or flamegraph.pl:
# Install inferno (one-time)
cargo install inferno
# Generate SVG
cat folded.txt | inferno-flamegraph > flamegraph.svg# Generate flamegraph for quicksort benchmark
cargo run -p cli --release -- execute executor/program_artifacts/bench/quicksort.elf --flamegraph /tmp/quicksort.txt
cat /tmp/quicksort.txt | inferno-flamegraph --title "quicksort" > quicksort_flamegraph.svg- The flamegraph shows instruction count per function, not wall-clock time
- Function names are demangled from Rust symbols
- Inlined functions won't appear (they're merged into their caller)
- Syscalls using
ecallare not tracked as separate function calls