| name | risc0-developer |
| description | This skill should be used when the user asks to "create a risc0 project", "create a zkVM project", "scaffold risc0 app", "generate a proof", "create proof script", "setup proof generation", "verify proof", "verify risc0 proof", "load and verify proof", "write risc0 guest code", "write zkVM guest program", "setup GPU proving", or mentions RISC Zero zkVM development, zero-knowledge proofs with RISC Zero, or zkSTARK proving. |
| version | 0.1.0 |
RISC Zero Developer Skill
Purpose
This skill provides comprehensive guidance for developing zero-knowledge applications with RISC Zero, a zkSTARK-based verifiable computing platform built on the RISC-V microarchitecture. Enable developers to create zkVM projects, generate cryptographic proofs, verify computation, and integrate with blockchain systems.
RISC Zero allows proving correct execution of arbitrary Rust code, producing receipts that cryptographically verify computation without revealing private inputs. This skill covers the complete development lifecycle from project scaffolding to production deployment.
When to Use This Skill
Invoke this skill when working with:
- Project Creation: Scaffolding new RISC Zero zkVM applications
- Proof Generation: Setting up local proving workflows
- Proof Verification: Writing verifier code for receipts and journals
- Blockchain Integration: Deploying verifier contracts on Ethereum and other chains
- Performance Optimization: Tuning guest code and leveraging GPU acceleration
Core Concepts
Architecture Overview
RISC Zero applications separate concerns into two components:
Guest Program: The code executed inside the zkVM that gets proven. Compiles to a RISC-V ELF binary. Guest code is constrained (no file I/O, no OS features) and typically uses #![no_std] for performance optimization, focusing on computation that needs verification.
Host Program: The untrusted orchestrator that sets up the execution environment, provides inputs to the guest, invokes the prover, and handles the resulting receipt.
Receipt: The cryptographic proof of execution containing:
- Journal: Public outputs committed by the guest
- Seal: Encrypted proof data
- ImageID: Cryptographic hash of the guest ELF binary
Development Workflow
- Write guest code defining the computation to prove
- Write host code to execute the guest and generate proofs
- Build the project (compiles guest to ELF, generates ImageID)
- Run in dev mode for fast iteration without proof generation
- Generate production proofs locally or remotely
- Verify receipts independently using the ImageID
Getting Started
Installation and Version Management
This skill is trained for RISC Zero zkVM version 3.x. Before starting any work, perform version checks.
Step 1: Check if RISC Zero is Installed
cargo risczero --version
If not installed, install the toolchain:
curl -L https://risczero.com/install | bash
rzup install
Step 2: Check Installed and Available Versions
rzup show
rzup check
Step 3: Version Decision (Ask User)
Before proceeding, present version information to the user and ask which version to use:
-
If no version installed: "RISC Zero is not installed. This skill is trained for version 3.x. Would you like to install the latest 3.x version?"
-
If version 3.x installed: Proceed with current version. Optionally ask: "You have RISC Zero [version] installed. Would you like to update to the latest 3.x release?"
-
If version 2.x or older installed: "You have RISC Zero [version] installed, but this skill is trained for version 3.x. Would you like to upgrade to 3.x? Note: This may require code changes for existing projects."
-
If version 4.x or newer installed: "You have RISC Zero [version] installed. This skill is trained for version 3.x and version 4.x may have breaking changes. Would you like to: (a) Continue with version 4.x, (b) Install version 3.x alongside, or (c) Check the migration guide first?"
Step 4: Install or Update as Needed
rzup install cargo-risczero 3.0.0
rzup install r0vm 3.0.0
rzup update
Creating a New Project
Pre-Creation Checks
Before creating a project, perform these checks:
Check if --no-git is supported:
cargo risczero new --help | grep -q "no-git"
If --no-git is NOT supported, check if inside a git repository:
git rev-parse --is-inside-work-tree 2>/dev/null
If inside a git repo without --no-git support:
- Create the project in a temporary directory
- Move files to the target location, preserving original git files
- Handle potential conflicts carefully
cargo risczero new /tmp/my_project
rsync -av --exclude='.git' --exclude='.gitignore' /tmp/my_project/ ./
Important: When merging into existing git repositories:
- Never overwrite
.git/ directory
- Ask user before overwriting
.gitignore, README.md, Cargo.toml if they exist
- Show diff of conflicting files and let user decide
- If uncertain about any file conflict, ask the user
Project Creation Commands
cargo risczero new my_project
cargo risczero new my_project --guest-name my_computation
cargo risczero new my_project --no-std
cargo risczero new my_project --no-git
Project Structure
Generated projects follow this structure:
my_project/
├── Cargo.toml # Workspace configuration
├── host/
│ ├── Cargo.toml # Host dependencies
│ └── src/
│ └── main.rs # Host program entry point
└── methods/
├── Cargo.toml # Methods workspace
├── build.rs # Build script (generates ELF and ImageID)
├── guest/
│ ├── Cargo.toml # Guest dependencies
│ └── src/
│ └── main.rs # Guest program code
└── src/
└── lib.rs # Generated METHOD_NAME_ELF and METHOD_NAME_ID
Build Process: The methods/build.rs script uses risc0-build to compile guest code to a RISC-V ELF binary and generate the ImageID. These are exposed as constants (e.g., MULTIPLY_ELF, MULTIPLY_ID) for use in the host.
Writing Guest Code
Guest programs execute inside the zkVM and must follow specific constraints:
Required Boilerplate
#![no_std]
#![no_main]
risc0_zkvm_guest::entry!(main);
pub fn main() {
}
About #![no_std]: This attribute is a performance optimization that excludes the standard library to minimize cycle counts and binary size. Use when OS features (file I/O, threads, networking) are not needed. Heap allocation (Vec, HashMap) remains available via the alloc crate. Set default-features = false for risc0-zkvm in Cargo.toml when using no_std.
Using std in Guest Code: If guest code depends on crate libraries that require std, use standard library with regular Rust entry point:
use risc0_zkvm::guest::env;
fn main() {
let input: SomeType = env::read();
env::commit(&result);
}
Configure risc0-zkvm with default features (std is included by default):
[dependencies]
risc0-zkvm = "3.0"
some-std-crate = "1.0"
Important: The attributes #![no_std], #![no_main], and risc0_zkvm_guest::entry!(main); are always used together as a bundle for no_std guest programs. When using std, remove ALL three and use a standard Rust fn main() entry point instead.
When to use std vs no_std:
- Use
no_std: For maximum performance, minimal cycle counts, and when all dependencies support no_std. Use all three attributes: #![no_std], #![no_main], and risc0_zkvm_guest::entry!(main);
- Use
std: When dependencies require standard library features. Remove all three attributes and use regular fn main()
I/O Operations
Reading Inputs from the host:
use risc0_zkvm::guest::env;
let input: u32 = env::read();
let data: Vec<u8> = env::read();
let value: u32 = env::stdin().read();
Writing Private Output to the host (not part of proof):
env::write(&result);
env::stdout().write(&data);
Committing Public Output to the journal (verified by proof):
env::commit(&public_result);
env::commit_slice(&public_data);
Key Distinction: Use commit for data that verifiers need to see and verify. Use write for private data only the host needs.
Debugging and Performance
let start = env::cycle_count();
let end = env::cycle_count();
env::log(&format!("Cycles: {}", end - start));
env::log("Debug message");
Writing Host Code
The host program sets up execution, runs the prover, and handles receipts:
Basic Prover Setup
use risc0_zkvm::{default_prover, ExecutorEnv};
use methods::{METHOD_NAME_ELF, METHOD_NAME_ID};
fn main() {
let input_data = 42u32;
let env = ExecutorEnv::builder()
.write(&input_data).unwrap()
.build()
.unwrap();
let prover = default_prover();
let prove_info = prover.prove(env, METHOD_NAME_ELF).unwrap();
let receipt = prove_info.receipt;
let output: u32 = receipt.journal.decode().unwrap();
println!("Verified output: {}", output);
receipt.verify(METHOD_NAME_ID).unwrap();
println!("Proof verified successfully!");
}
Dev Mode for Fast Iteration
During development, bypass proof generation for faster testing:
RISC0_DEV_MODE=1 cargo run --release
RISC0_DEV_MODE=1 RUST_LOG=info RISC0_INFO=1 cargo run --release
Dev mode skips cryptographic proof generation, dramatically speeding up the development cycle. Always test with RISC0_DEV_MODE=0 before production deployment.
Generating Production Proofs
RISC0_DEV_MODE=0 cargo run --release
Proof Generation Options
Local Proving
Generate proofs on your own hardware. Supports CPU and GPU acceleration.
Hardware Requirements:
- CPU: Any modern x86 or ARM processor
- RAM: Minimum 16GB recommended
- GPU (optional): NVIDIA GPU with CUDA support or Apple Silicon with Metal
GPU Acceleration significantly improves proving performance. See references/proof-generation.md for detailed setup instructions.
Verification
Receipts can be verified independently by any party with the ImageID:
use risc0_zkvm::Receipt;
use methods::METHOD_NAME_ID;
fn verify_receipt(receipt: &Receipt) -> Result<(), Error> {
receipt.verify(METHOD_NAME_ID)?;
let output: MyOutputType = receipt.journal.decode()?;
Ok(())
}
Separation of Concerns: The prover (host) generates receipts. Verifiers only need the receipt and ImageID—no access to inputs or the execution environment required.
Blockchain Integration
RISC Zero supports on-chain verification of proofs across multiple blockchain platforms.
Ethereum and EVM Chains
Deploy Solidity verifier contracts to verify RISC Zero proofs on-chain:
- Generate a Groth16-wrapped receipt (smaller proof size for on-chain verification)
- Deploy the
RiscZeroVerifierRouter contract
- Call the verifier contract from your smart contract
import {IRiscZeroVerifier} from "risc0/IRiscZeroVerifier.sol";
import {ImageID} from "./ImageID.sol"; // Generated ImageID
contract MyContract {
IRiscZeroVerifier public verifier;
function verifyProof(bytes calldata seal, bytes calldata journal) external {
verifier.verify(seal, ImageID.METHOD_NAME_ID, journal);
// Proof verified, proceed with on-chain logic
}
}
Note: The STARK-to-SNARK wrapper reduces proof size from hundreds of kilobytes to hundreds of bytes, enabling cost-effective on-chain verification.
See references/blockchain-integration.md for detailed multi-chain integration patterns, deployment workflows, and production considerations.
Performance and Optimization
Monitoring Execution Metrics
Track cycle count and performance:
RISC0_DEV_MODE=1 RUST_LOG=info RISC0_INFO=1 cargo run --release
Metrics include:
- Total cycles: Computational cost of guest execution
- Session cycles: Cycles per execution session
- Segment count: Number of proof segments
- Execution duration: Wall-clock time
Lower cycle counts = faster and cheaper proving. Optimize guest code to minimize cycles.
Best Practices
- Minimize guest code complexity: Keep computation in the guest focused and efficient
- Choose std vs no_std appropriately:
- Use
no_std for maximum performance when all dependencies support it. Requires all three: #![no_std], #![no_main], and risc0_zkvm_guest::entry!(main);. Benefits: minimizes cycle counts by 10-30%, reduces binary size, still supports heap allocation via alloc crate
- Use
std when dependencies require standard library. Remove all three attributes and use regular fn main(). Use default risc0-zkvm = "3.0" (std included by default)
- Profile with dev mode: Identify bottlenecks before generating expensive proofs
- Batch operations: Process multiple inputs in a single proof when possible
- Leverage GPU acceleration: For local proving, GPU is 10-100x faster than CPU
- Use cryptographic precompiles: Hardware-accelerated cryptographic operations (SHA-256, ECDSA, EdDSA, Keccak) provide 25-50x cycle reduction. Apply Cargo patches for
sha2, k256, curve25519-dalek, and other crypto crates to automatically use precompiles
See references/guest-optimization.md for comprehensive guest code optimization techniques including cycle reduction strategies, memory optimization, profiling methods, and zkVM-specific performance patterns. See references/advanced-patterns.md for production deployment patterns.
Additional Resources
Reference Files
For detailed information beyond core concepts:
references/proof-generation.md - Comprehensive proving workflows, GPU setup, hardware optimization, and performance tuning
references/blockchain-integration.md - Multi-chain integration patterns, Solidity verifier contracts, deployment strategies for Ethereum, Base, and other blockchains
references/guest-optimization.md - Guest code optimization techniques, cycle reduction strategies, memory optimization, profiling methods, operation costs, and zkVM-specific performance patterns
references/cryptographic-precompiles.md - Hardware-accelerated cryptographic operations, patched crate setup, performance benefits, security considerations for SHA-256, ECDSA, EdDSA, Keccak, and other crypto primitives
references/advanced-patterns.md - Production best practices, debugging strategies, security considerations, and CI/CD integration
Example Files
Working code examples in examples/:
guest-basic.rs - Basic guest program with I/O operations
host-basic.rs - Host program with prover setup and verification
proof-verification.rs - Standalone proof verification example
Utility Scripts
Helper scripts in scripts/:
setup-project.sh - Automated project scaffolding with common configurations
benchmark-proof.sh - Performance benchmarking for guest execution and proving
verify-receipt.sh - Receipt verification testing utility
Quick Reference
Common Commands
curl -L https://risczero.com/install | bash
rzup install
rzup update
cargo risczero new my_project
cargo build --release
RISC0_DEV_MODE=1 cargo run --release
RISC0_DEV_MODE=0 cargo run --release
RISC0_DEV_MODE=1 RUST_LOG=info RISC0_INFO=1 cargo run --release
Development Workflow
- Setup: Install rzup and cargo-risczero
- Create: Scaffold project with
cargo risczero new
- Write: Implement guest logic (computation to prove)
- Write: Implement host logic (prover orchestration)
- Iterate: Use dev mode for rapid testing
- Profile: Measure cycle counts and optimize
- Prove: Generate production proofs (local or remote)
- Verify: Test receipt verification
- Deploy: Integrate with applications or blockchains
Community and Support
Notes
- RISC Zero uses zkSTARKs (not zkSNARKs by default), providing post-quantum security
- Guest programs must be deterministic for proof generation
- Receipts are portable and can be verified anywhere with the ImageID
- Local proving requires significant RAM (16GB+) and benefits from GPU acceleration
- Groth16 wrapping enables efficient on-chain verification but requires trusted setup