### Bash: Install SP1 SDK Source: https://github.com/eth-act/ere/blob/master/README.md Provides the bash command to install the SP1 SDK. This is part of the setup process for using ERE with the SP1 zkVM, enabling local development and debugging. ```bash bash scripts/sdk_installers/install_sp1_sdk.sh ``` -------------------------------- ### SP1 zkVM Implementation Example (Rust) Source: https://context7.com/eth-act/ere/llms.txt Provides an example of using the SP1 zkVM backend, including compilation with different Rust toolchains, zkVM instantiation with various prover resources, and performing execution, proving (Groth16), and verification. Requires 'ere-sp1' and 'ere-zkvm-interface' crates. ```rust use ere_sp1::{ compiler::{RustRv64ima, RustRv64imaCustomized}, zkvm::EreSP1, program::SP1Program, }; use ere_zkvm_interface::zkvm::{Input, ProofKind, ProverResource, zkVM, zkVMProgramDigest}; fn sp1_example() -> Result<(), Box> { // Two compiler options for SP1: // - RustRv64imaCustomized: Uses SP1's custom toolchain with std support // - RustRv64ima: Stock Rust compiler for riscv64ima-unknown-none-elf let compiler = RustRv64imaCustomized; let program: SP1Program = compiler.compile(std::path::Path::new("guest"))?; // SP1 supports: Cpu, Gpu, Network let zkvm = EreSP1::new(program, ProverResource::Cpu)?; // Get program digest (verifying key) for on-chain verification let vk = zkvm.program_digest()?; let input = Input::new().with_prefixed_stdin(vec![1, 2, 3, 4]); // Execute let (output, report) = zkvm.execute(&input)?; println!("SP1 execution: {} cycles", report.total_num_cycles); // Prove with Groth16 for on-chain verification let (_, proof, _) = zkvm.prove(&input, ProofKind::Groth16)?; // Verify zkvm.verify(&proof)?; Ok(()) } ``` -------------------------------- ### Dockerized Guest Program Compilation (Rust) Source: https://context7.com/eth-act/ere/llms.txt The `DockerizedCompiler` from `ere_dockerized` allows compiling guest programs within Docker containers, eliminating the need for local zkVM SDK installations. It supports various `zkVMKind` and `CompilerKind` options and requires a `mount_dir` containing the guest program source. ```rust use ere_dockerized::{CompilerKind, DockerizedCompiler, zkVMKind}; use ere_zkvm_interface::compiler::Compiler; use std::path::Path; fn dockerized_compile() -> Result<(), Box> { // Available zkVM kinds: Airbender, Jolt, OpenVM, Pico, Risc0, SP1, Zisk let zkvm_kind = zkVMKind::SP1; // Available compiler kinds: Rust, RustCustomized, GoCustomized let compiler_kind = CompilerKind::RustCustomized; // Mount directory must contain the guest program let mount_dir = Path::new("/path/to/workspace"); // Creates compiler (builds Docker images if needed) let compiler = DockerizedCompiler::new(zkvm_kind, compiler_kind, mount_dir)?; // Compile guest (path must be relative to mount_dir) let guest_path = Path::new("guest"); let program = compiler.compile(guest_path)?; println!("Compiled program size: {} bytes", program.0.len()); Ok(()) } ``` -------------------------------- ### Unified zkVM Operations: Execute, Prove, Verify (Rust) Source: https://context7.com/eth-act/ere/llms.txt The `zkVM` trait from `ere-zkvm-interface` provides a unified interface for interacting with different zkVM backends. It abstracts operations like executing guest programs, generating cryptographic proofs, and verifying those proofs. This example showcases a complete workflow using the SP1 backend, including compilation, execution, proving, and verification. ```rust use ere_zkvm_interface::zkvm::{ Input, ProofKind, ProgramExecutionReport, ProgramProvingReport, Proof, ProverResource, PublicValues, zkVM, }; // The zkVM trait signature pub trait zkVM { fn execute(&self, input: &Input) -> anyhow::Result<(PublicValues, ProgramExecutionReport)>; fn prove(&self, input: &Input, proof_kind: ProofKind) -> anyhow::Result<(PublicValues, Proof, ProgramProvingReport)>; fn verify(&self, proof: &Proof) -> anyhow::Result; fn name(&self) -> &'static str; fn sdk_version(&self) -> &'static str; } // Example: Complete workflow with SP1 use ere_sp1::{compiler::RustRv64imaCustomized, zkvm::EreSP1}; use std::path::Path; fn zkvm_workflow() -> Result<(), Box> { // 1. Compile the guest program let compiler = RustRv64imaCustomized; let program = compiler.compile(Path::new("guest"))?; // 2. Create zkVM instance let zkvm = EreSP1::new(program, ProverResource::Cpu)?; // 3. Prepare input (use with_prefixed_stdin for Platform::read_whole_input) let input = Input::new().with_prefixed_stdin(10u64.to_le_bytes().to_vec()); // 4. Execute to get public values and cycle count let (public_values, report) = zkvm.execute(&input)?; println!("Execution cycles: {}", report.total_num_cycles); // 5. Generate proof let (public_values, proof, proving_report) = zkvm.prove(&input, ProofKind::Compressed)?; println!("Proving time: {:?}", proving_report.proving_time); // 6. Verify proof let verified_values = zkvm.verify(&proof)?; assert_eq!(public_values, verified_values); println!("Proof verified successfully!"); Ok(()) } ``` -------------------------------- ### Platform Trait for Guest-Host Communication (Rust) Source: https://context7.com/eth-act/ere/llms.txt The `Platform` trait defines methods for guest programs to communicate with the host environment. It allows reading input, writing output, printing messages, and tracking execution cycles. The `SP1Platform` is an example implementation used with the `ere_platform_sp1` crate. ```rust use core::ops::Deref; pub trait Platform { /// Reads the whole input at once from host (requires length-prefixed stdin) fn read_whole_input() -> impl Deref; /// Writes the whole output at once to host fn write_whole_output(output: &[u8]); /// Prints a message to the host environment fn print(message: &str); /// Returns the current cycle count (0 if not supported) fn cycle_count() -> u64 { 0 } /// Cycle tracking for profiling fn cycle_scope(name: &str, f: impl FnOnce() -> T) -> T; } // Example guest program using SP1Platform #![no_main] use ere_platform_sp1::{sp1_zkvm, Platform, SP1Platform}; sp1_zkvm::entrypoint!(main); type P = SP1Platform; pub fn main() { // Read input from host let input = P::read_whole_input(); let n = u64::from_le_bytes(input.as_slice().try_into().unwrap()); // Compute nth Fibonacci number let fib_n = fib(n); // Write output back to host let output = [input.to_vec(), fib_n.to_le_bytes().to_vec()].concat(); P::write_whole_output(&output); } fn fib(n: u64) -> u64 { let mut a = 0u64; let mut b = 1u64; for _ in 0..n { let c = a.wrapping_add(b); a = b; b = c; } a } ``` -------------------------------- ### Define Guest Program Compilation with Compiler Trait (Rust) Source: https://context7.com/eth-act/ere/llms.txt The `Compiler` trait in `ere-zkvm-interface` defines the contract for compiling guest programs into zkVM-specific binary artifacts. It requires implementations to provide methods for compilation, returning either a compiled `Program` or an error. This example demonstrates compiling a guest program using SP1's customized toolchain. ```rust use ere_zkvm_interface::compiler::Compiler; use std::path::Path; // The Compiler trait signature pub trait Compiler { type Error: std::error::Error + Send + Sync + 'static; type Program: Clone + Send + Sync + Serialize + DeserializeOwned; fn compile(&self, guest_directory: &Path) -> Result; } // Example: Compiling a guest program with SP1's customized toolchain use ere_sp1::compiler::RustRv64imaCustomized; fn compile_guest() -> Result<(), Box> { let compiler = RustRv64imaCustomized; let guest_directory = Path::new("path/to/guest"); let program = compiler.compile(guest_directory)?; // program is now ready to be executed or proved Ok(()) } ``` -------------------------------- ### Implement Host Execution and Proving Source: https://github.com/eth-act/ere/blob/master/README.md Demonstrates the host-side logic to compile, execute, prove, and verify a guest program using the Ere SP1 interface. ```toml [package] name = "host" edition = "2024" [dependencies] ere-zkvm-interface = { git = "https://github.com/eth-act/ere.git" } ere-sp1 = { git = "https://github.com/eth-act/ere.git" } ``` ```rust use ere_sp1::{compiler::RustRv32imaCustomized, zkvm::EreSP1}; use ere_zkvm_interface::{compiler::Compiler, zkvm::{Input, ProofKind, ProverResource, zkVM}}; use std::path::Path; fn main() -> Result<(), Box> { let guest_directory = Path::new("path/to/guest"); let compiler = RustRv32imaCustomized; let program = compiler.compile(guest_directory)?; let zkvm = EreSP1::new(program, ProverResource::Cpu)?; let input = Input::new().with_prefixed_stdin(10u64.to_le_bytes().to_vec()); let expected_output = [input.clone(), 55u64.to_le_bytes().to_vec()].concat(); let (public_values, report) = zkvm.execute(&input)?; assert_eq!(public_values, expected_output); let (public_values, proof, report) = zkvm.prove(&input, ProofKind::default())?; let public_values = zkvm.verify(&proof)?; Ok(()) } ``` -------------------------------- ### Serialize and Deserialize IO Types for Host-Guest Communication Source: https://context7.com/eth-act/ere/llms.txt Demonstrates how to use the ere-io crate to define shared data structures and perform serialization/deserialization between host and guest environments using bincode. ```rust use ere_io::{Io, serde::{IoSerde, Serde}}; use serde::{Serialize, Deserialize}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct MyInput { pub value: u64, pub data: Vec, } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct MyOutput { pub result: u64, } use ere_io::serde::bincode::BincodeLegacy; type MyIo = IoSerde; // Host side let input = MyInput { value: 42, data: vec![1, 2, 3] }; let bytes = MyIo::serialize_input(&input)?; let zkvm_input = Input::new().with_prefixed_stdin(bytes); let output: MyOutput = MyIo::deserialize_output(&public_values)?; // Guest side fn guest_main() { let input_bytes = P::read_whole_input(); let input: MyInput = MyIo::deserialize_input(&input_bytes).unwrap(); let output = MyOutput { result: input.value * 2 }; let output_bytes = MyIo::serialize_output(&output).unwrap(); P::write_whole_output(&output_bytes); } ``` -------------------------------- ### Define Guest Program for SP1 Source: https://github.com/eth-act/ere/blob/master/README.md Defines a guest program using the SP1 platform. It reads input, performs a computation (Fibonacci), and writes the output back to the platform. ```toml [package] name = "guest" edition = "2024" [dependencies] ere-platform-sp1 = { git = "https://github.com/eth-act/ere.git" } ``` ```rust #![no_main] use ere_platform_sp1::{sp1_zkvm, Platform, SP1Platform}; sp1_zkvm::entrypoint!(main); type P = SP1Platform; pub fn main() { let input = P::read_whole_input(); let n = u64::from_le_bytes(input.as_slice().try_into().unwrap()); let fib_n = fib(n); let output = [input, fib_n.to_le_bytes().to_vec()].concat(); P::write_whole_output(&output); } fn fib(n: u64) -> u64 { let mut a = 0; let mut b = 1; for _ in 0..n { let c = a + b; a = b; b = c; } a } ``` -------------------------------- ### Rust: Read whole input with length prefix for Platform Source: https://github.com/eth-act/ere/blob/master/README.md Demonstrates how to use `Input::new().with_prefixed_stdin(data)` to read the entire stdin with a length prefix. This method ensures compatibility with zkVMs that may not expose stdin length directly, automatically adding a LE u32 prefix. The `Platform::read_whole_input()` in the guest will then return only the actual data, preventing runtime panics. ```rust use ere_zkvm_interface::Input; // In the guest program: let data = Platform::read_whole_input(); // In the host program: let input_data = b"some data"; let input = Input::new().with_prefixed_stdin(input_data); // ... then execute the guest program with this input. ``` -------------------------------- ### Rust: Hash large outputs for cross-zkVM compatibility Source: https://github.com/eth-act/ere/blob/master/README.md Shows how to use `OutputHashedPlatform` to hash large outputs before writing them, ensuring compatibility across zkVMs with different public value size limits. This wrapper uses a specified hashing algorithm (e.g., `Sha256`) and calls the inner platform's `write_whole_output` method with the hashed data. ```rust use ere_platform_trait::OutputHashedPlatform; use sha2::{Sha256}; // Assuming OpenVMPlatform is defined elsewhere and implements the Platform trait // use crate::OpenVMPlatform; // In the guest program: let large_output = vec![0u8; 10000]; // Example large output // OutputHashedPlatform::::write_whole_output(&large_output); // Note: The actual implementation would involve instantiating the inner platform. ``` -------------------------------- ### Dockerized zkVM Workflow (Rust) Source: https://context7.com/eth-act/ere/llms.txt Demonstrates a complete workflow for executing, proving, and verifying computations using a Dockerized zkVM. It covers compilation, zkVM instantiation, input preparation, execution, proving, and verification steps. Requires the 'ere-dockerized', 'ere-zkvm-interface' crates. ```rust use ere_dockerized::{CompilerKind, DockerizedCompiler, DockerizedzkVM, zkVMKind}; use ere_zkvm_interface::{ compiler::Compiler, zkvm::{Input, ProofKind, ProverResource, zkVM}, }; use std::path::Path; fn dockerized_workflow() -> Result<(), Box> { let zkvm_kind = zkVMKind::SP1; let mount_dir = Path::new("/path/to/workspace"); // Compile using Docker let compiler = DockerizedCompiler::new(zkvm_kind, CompilerKind::RustCustomized, mount_dir)?; let program = compiler.compile(Path::new("guest"))?; // Create dockerized zkVM (spawns a gRPC server container) let zkvm = DockerizedzkVM::new(zkvm_kind, program, ProverResource::Cpu)?; // Prepare input let input = Input::new().with_prefixed_stdin(42u32.to_le_bytes().to_vec()); // Execute (runs inside Docker container) let (public_values, report) = zkvm.execute(&input)?; println!("Cycles: {}", report.total_num_cycles); // Prove (runs inside Docker container) let (public_values, proof, proving_report) = zkvm.prove(&input, ProofKind::Compressed)?; println!("Proving time: {:?}", proving_report.proving_time); // Verify let verified = zkvm.verify(&proof)?; assert_eq!(public_values, verified); println!("Verified successfully!"); Ok(()) } ``` -------------------------------- ### Dockerized zkVM Host Implementation Source: https://github.com/eth-act/ere/blob/master/README.md Implements the host logic using Dockerized containers to handle compilation and zkVM operations, abstracting away local SDK requirements. ```toml [package] name = "host" edition = "2024" [dependencies] ere-zkvm-interface = { git = "https://github.com/eth-act/ere.git" } ere-dockerized = { git = "https://github.com/eth-act/ere.git" } ``` ```rust use ere_dockerized::{CompilerKind, DockerizedCompiler, DockerizedzkVM, zkVMKind}; use ere_zkvm_interface::{compiler::Compiler, zkvm::{Input, ProofKind, ProverResource, zkVM}}; use std::path::Path; fn main() -> Result<(), Box> { let guest_directory = Path::new("path/to/guest"); let compiler = DockerizedCompiler::new(zkVMKind::SP1, CompilerKind::RustCustomized, guest_directory)?; let program = compiler.compile(guest_directory)?; let zkvm = DockerizedzkVM::new(zkVMKind::SP1, program, ProverResource::Cpu)?; let input = Input::new().with_prefixed_stdin(10u64.to_le_bytes().to_vec()); let (public_values, proof, report) = zkvm.prove(&input, ProofKind::default())?; let verified_values = zkvm.verify(&proof)?; Ok(()) } ``` -------------------------------- ### Input Structure for Guest Programs (Rust) Source: https://context7.com/eth-act/ere/llms.txt The `Input` structure from `ere_zkvm_interface::zkvm` is used to manage stdin data and optional proofs for guest programs. It supports length-prefixed stdin, raw stdin, and the inclusion of serialized proofs for proof composition. ```rust use ere_zkvm_interface::zkvm::Input; // Create input with length-prefixed stdin (recommended for Platform::read_whole_input) let data = vec![1u8, 2, 3, 4]; let input = Input::new().with_prefixed_stdin(data); // Create input with raw stdin (for zkVM-specific APIs) let raw_data = vec![1u8, 2, 3, 4]; let input = Input::new().with_stdin(raw_data); // Input with serialized proofs for proof composition use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize)] struct MyProof { /* ... */ } let proofs: Vec = vec![/* ... */]; let input = Input::new() .with_prefixed_stdin(data) .with_proofs(&proofs)?; // Access input data let stdin_bytes: &[u8] = input.stdin(); let deserialized_proofs: Option, _>> = input.proofs(); ``` -------------------------------- ### Prover Resource Configuration (Rust) Source: https://context7.com/eth-act/ere/llms.txt The `ProverResource` enum allows configuring where proving operations occur, including CPU, GPU, or remote network/cluster resources. `RemoteProverConfig` is used for specifying endpoints and API keys for network or cluster-based proving. ```rust use ere_zkvm_interface::zkvm::{ProverResource, RemoteProverConfig}; // CPU proving (default) let resource = ProverResource::Cpu; // GPU proving (requires CUDA) let resource = ProverResource::Gpu; // Remote network proving (e.g., Succinct Network for SP1) let resource = ProverResource::Network(RemoteProverConfig { endpoint: "https://network.succinct.xyz".to_string(), api_key: Some("your-api-key".to_string()), }); // Self-hosted cluster proving let resource = ProverResource::Cluster(RemoteProverConfig { endpoint: "http://your-cluster:3000".to_string(), api_key: None, }); // Create zkVM with specific resource let zkvm = EreSP1::new(program, resource)?; ``` -------------------------------- ### Retrieve Execution and Proving Metrics Source: https://context7.com/eth-act/ere/llms.txt Retrieves performance metrics including cycle counts, execution duration, and proving time from zkVM execution reports. ```rust use ere_zkvm_interface::zkvm::{ProgramExecutionReport, ProgramProvingReport}; // Execution metrics let (public_values, report) = zkvm.execute(&input)?; println!("Total cycles: {}", report.total_num_cycles); println!("Execution time: {:?}", report.execution_duration); // Proving metrics let (public_values, proof, report) = zkvm.prove(&input, ProofKind::Compressed)?; println!("Proving time: {:?}", report.proving_time); ``` -------------------------------- ### Rust: Read whole input without modification for Platform Source: https://github.com/eth-act/ere/blob/master/README.md Illustrates using `Input::new().with_stdin(data)` for direct access to zkVM-specific stdin APIs. This method sets the stdin without any modifications, making it suitable for scenarios requiring streaming reads or partial data consumption, such as `sp1_zkvm::io::read` or `risc0_zkvm::guest::env::read`. ```rust use ere_zkvm_interface::Input; // In the guest program: // Use zkVM-specific APIs like sp1_zkvm::io::read or risc0_zkvm::guest::env::read // In the host program: let input_data = b"some data"; let input = Input::new().with_stdin(input_data); // ... then execute the guest program with this input. ``` -------------------------------- ### zkVMKind Enumeration and Usage (Rust) Source: https://context7.com/eth-act/ere/llms.txt Defines the zkVMKind enumeration for supported zkVM backends and demonstrates parsing from strings and retrieving string representations. It lists characteristics of each supported backend. ```rust use ere_dockerized::zkVMKind; // Parse zkVM kind from string (case-insensitive) let kind: zkVMKind = "sp1".parse()?; let kind: zkVMKind = "SP1".parse()?; let kind: zkVMKind = "risc0".parse()?; // Get string representation let name: &str = kind.as_str(); // "sp1" // All supported zkVMs: // - Airbender: RV32IMA, GPU support, multi-GPU // - Jolt: RV64IMAC // - OpenVM: RV32IMA, GPU support // - Pico: RV32IMA // - Risc0: RV32IMA, GPU support, multi-GPU // - SP1: RV64IMA, GPU support, network proving // - Zisk: RV64IMA, GPU support, multi-GPU, cluster ``` -------------------------------- ### Docker Environment Variables Configuration (Bash) Source: https://context7.com/eth-act/ere/llms.txt Configures environment variables to control Docker image registry, force rebuilds, specify GPU devices, and set Docker networks for zkVM operations. These variables influence how Docker containers are built and run. ```bash # Use a specific Docker image registry (enables pulling pre-built images) export ERE_IMAGE_REGISTRY="ghcr.io/eth-act" # Force rebuild Docker images locally export ERE_FORCE_REBUILD_DOCKER_IMAGE=true # Specify GPU devices for Docker containers export ERE_GPU_DEVICES="device=0,1" # Use GPUs 0 and 1 export ERE_GPU_DEVICES="all" # Use all GPUs (default) export ERE_GPU_DEVICES="4" # Use any 4 available GPUs # Specify Docker network for spawned containers export ERE_DOCKER_NETWORK="my-network" ``` -------------------------------- ### Wrap Large Outputs with OutputHashedPlatform Source: https://context7.com/eth-act/ere/llms.txt Uses the OutputHashedPlatform wrapper to hash large outputs, ensuring compatibility with zkVMs that have strict public value size limits. ```rust use ere_platform_trait::{OutputHashedPlatform, Platform}; use sha2::{Sha256, Digest}; type HashedPlatform = OutputHashedPlatform; fn guest_main() { let input = SP1Platform::read_whole_input(); let large_output: Vec = compute_large_result(&input); HashedPlatform::write_whole_output(&large_output); } // Host side verification let (public_values, _) = zkvm.execute(&input)?; let expected_hash = Sha256::digest(&expected_output); assert_eq!(&public_values[..32], expected_hash.as_slice()); ``` -------------------------------- ### Proof Types in Ere (Rust) Source: https://context7.com/eth-act/ere/llms.txt Ere supports two proof types: `Compressed` (constant-size STARK proofs) and `Groth16` (SNARK proofs). The `ProofKind` enum is used to specify the desired proof type during generation. Proofs can be inspected for their type and byte content. ```rust use ere_zkvm_interface::zkvm::{Proof, ProofKind}; // Generate a compressed proof (default, faster) let (_, proof, _) = zkvm.prove(&input, ProofKind::Compressed)?; // Generate a Groth16 proof (smaller, verifiable on-chain) let (_, groth16_proof, _) = zkvm.prove(&input, ProofKind::Groth16)?; // Check proof type and access bytes match &proof { Proof::Compressed(bytes) => println!("Compressed proof: {} bytes", bytes.len()), Proof::Groth16(bytes) => println!("Groth16 proof: {} bytes", bytes.len()), } let proof_bytes: &[u8] = proof.as_bytes(); let proof_kind: ProofKind = proof.kind(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.