Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/risc0/risc0/llms.txt

Use this file to discover all available pages before exploring further.

risc0-binfmt

The risc0-binfmt crate manages formatted binaries used by the RISC Zero zkVM, including ELF parsing, memory image construction, and image ID computation.

Installation

[dependencies]
risc0-binfmt = "1.3.0"

Overview

This crate provides low-level utilities for working with zkVM binaries:
  • ELF file parsing and loading
  • Memory image construction
  • Image ID computation (program identity)
  • System state serialization
  • Exit code handling
Most users don’t need this crate directly. Use risc0-zkvm which handles binary formats automatically.

Feature Flags

std
feature
Enables standard library support (enabled by default).
rand
feature
Enables random number generation utilities.

Core Functions

compute_image_id

compute_image_id
function
Compute the image ID of a combined user + kernel ELF binary.
pub fn compute_image_id(blob: &[u8]) -> Result<Digest>
Parameters:
  • blob: Combined ELF binary (user program + kernel)
Returns: 256-bit image ID (program identity)Example:
let image_id = compute_image_id(elf_bytes)?;
println!("Image ID: {}", image_id);

compute_kernel_id

compute_kernel_id
function
Compute the kernel ID from a combined binary.
pub fn compute_kernel_id(blob: &[u8]) -> Result<Digest>
Parameters:
  • blob: Combined ELF binary
Returns: Kernel ID (constant for all programs using same kernel)Example:
let kernel_id = compute_kernel_id(elf_bytes)?;

Binary Types

Program

Program
struct
Represents a parsed ELF program.
pub struct Program {
    pub entry: u32,
    pub image: MemoryImage,
}
Fields:
  • entry: Program entry point address
  • image: Memory image with loaded segments

ProgramBinary

ProgramBinary
struct
Combined user program and kernel binary.
pub struct ProgramBinary {
    // ...
}

impl ProgramBinary {
    pub fn new(user_elf: &[u8], kernel_elf: &[u8]) -> Self;
    pub fn encode(&self) -> Vec<u8>;
    pub fn decode(blob: &[u8]) -> Result<Self>;
    pub fn compute_image_id(&self) -> Result<Digest>;
    pub fn kernel_id(&self) -> Result<Digest>;
}
ProgramBinary::new
method
Create a combined binary from user and kernel ELFs.
pub fn new(user_elf: &[u8], kernel_elf: &[u8]) -> Self
Example:
let binary = ProgramBinary::new(user_elf, kernel_elf);
let encoded = binary.encode();

ProgramBinaryHeader

ProgramBinaryHeader
struct
Header for combined binary format.Contains metadata about the binary including version and ABI information.

AbiKind

AbiKind
enum
ABI version for the binary.
pub enum AbiKind {
    V1,
    V2,
}

Memory Image

MemoryImage

MemoryImage
struct
Represents the zkVM memory layout.
pub struct MemoryImage {
    // ...
}

impl MemoryImage {
    pub fn new(
        program: &Program,
        page_size: u32,
    ) -> Result<Self>;
    
    pub fn load_page(
        &mut self,
        addr: u32,
        data: &[u8],
    ) -> Result<()>;
    
    pub fn hash(&self) -> Result<Digest>;
}
Page
struct
Represents a memory page.
pub struct Page {
    pub addr: u32,
    pub data: Vec<u8>,
}
KERNEL_START_ADDR
const
Start address for kernel code.
pub const KERNEL_START_ADDR: ByteAddr;

Address Types

ByteAddr

ByteAddr
struct
Byte-aligned address.
pub struct ByteAddr(pub u32);

impl ByteAddr {
    pub const fn new(addr: u32) -> Self;
    pub fn waddr(&self) -> WordAddr;
}

WordAddr

WordAddr
struct
Word-aligned address (4-byte alignment).
pub struct WordAddr(pub u32);

impl WordAddr {
    pub const fn new(addr: u32) -> Self;
    pub fn baddr(&self) -> ByteAddr;
}

Exit Codes

ExitCode

ExitCode
enum
Program exit status.
pub enum ExitCode {
    Halted(u32),
    Paused(u32),
    SystemSplit,
}
Variants:
  • Halted(code): Program terminated with exit code
  • Paused(code): Program paused (for host interaction)
  • SystemSplit: Segment boundary (internal)
InvalidExitCodeError
struct
Error when exit code is invalid.
pub struct InvalidExitCodeError {
    pub exit_code: u32,
}

System State

SystemState

SystemState
struct
Complete zkVM system state.
pub struct SystemState {
    pub pc: u32,
    pub merkle_root: Digest,
}

impl SystemState {
    pub fn encode(&self) -> Vec<u8>;
    pub fn decode(data: &[u8]) -> Result<Self, DecodeError>;
}
Fields:
  • pc: Program counter
  • merkle_root: Root of memory Merkle tree
DecodeError
enum
Error during state decoding.
pub enum DecodeError {
    InvalidLength,
    InvalidData,
}

SHA Half Encoding

write_sha_halfs
function
Write digest as 16-bit halves.
pub fn write_sha_halfs(digest: &Digest, writer: &mut impl Write) 
    -> Result<()>
read_sha_halfs
function
Read digest from 16-bit halves.
pub fn read_sha_halfs(reader: &mut impl Read) -> Result<Digest>

Hashing

Digestible

Digestible
trait
Trait for types that can be hashed.
pub trait Digestible {
    fn digest<S: Sha256>(&self) -> Digest;
}

Tagged Hashing

tagged_struct
macro
Create tagged hash of struct fields.
tagged_struct!("tag", field1, field2, ...)
tagged_list
macro
Create tagged hash of list items.
tagged_list!("tag", item1, item2, ...)
tagged_list_cons
function
Cons operation for building tagged lists.
pub fn tagged_list_cons(tag: &str, head: &Digest, tail: &Digest) 
    -> Digest
tagged_iter
function
Create tagged hash from iterator.
pub fn tagged_iter<I>(tag: &str, iter: I) -> Digest
where
    I: Iterator<Item = Digest>

Proof-of-Work

PovwNonce

PovwNonce
struct
Proof-of-work nonce.
pub struct PovwNonce([u32; 8]);

impl PovwNonce {
    pub fn from_u32s(words: [u32; 8]) -> Self;
    pub fn as_u32s(&self) -> &[u32; 8];
}
PovwJobId
struct
Proof-of-work job identifier.
pub struct PovwJobId(pub u64);
PovwLogId
struct
Proof-of-work log identifier.
pub struct PovwLogId(pub Digest);

Examples

Computing Image ID

use risc0_binfmt::compute_image_id;

fn get_program_id(elf_bytes: &[u8]) -> Result<String> {
    let image_id = compute_image_id(elf_bytes)?;
    Ok(hex::encode(image_id.as_bytes()))
}

Creating Combined Binary

use risc0_binfmt::ProgramBinary;

fn build_binary(
    user_elf: &[u8],
    kernel_elf: &[u8],
) -> Vec<u8> {
    let binary = ProgramBinary::new(user_elf, kernel_elf);
    binary.encode()
}

Working with Memory Images

use risc0_binfmt::{MemoryImage, Program};

fn load_program(elf: &[u8]) -> Result<MemoryImage> {
    let program = Program::load_elf(elf, 1024)?;
    let image = MemoryImage::new(&program, 1024)?;
    Ok(image)
}

Handling Exit Codes

use risc0_binfmt::ExitCode;

fn check_exit(exit_code: ExitCode) {
    match exit_code {
        ExitCode::Halted(0) => {
            println!("Program succeeded");
        }
        ExitCode::Halted(code) => {
            eprintln!("Program failed with code {}", code);
        }
        ExitCode::Paused(code) => {
            println!("Program paused at {}", code);
        }
        ExitCode::SystemSplit => {
            println!("Segment boundary");
        }
    }
}

System State Serialization

use risc0_binfmt::SystemState;
use risc0_zkp::core::digest::Digest;

fn serialize_state(pc: u32, root: Digest) -> Vec<u8> {
    let state = SystemState {
        pc,
        merkle_root: root,
    };
    state.encode()
}

fn deserialize_state(data: &[u8]) -> Result<SystemState> {
    SystemState::decode(data)
}

Tagged Hashing

use risc0_binfmt::{tagged_struct, Digestible};
use risc0_zkp::core::digest::Digest;

fn hash_claim(
    image_id: &Digest,
    input: &Digest,
    output: &Digest,
) -> Digest {
    tagged_struct!("risc0.Claim",
        image_id.digest(),
        input.digest(),
        output.digest()
    )
}

Address Conversion

use risc0_binfmt::{ByteAddr, WordAddr};

fn convert_addresses() {
    let byte_addr = ByteAddr::new(0x1000);
    let word_addr = byte_addr.waddr(); // 0x400
    
    let word_addr = WordAddr::new(0x400);
    let byte_addr = word_addr.baddr(); // 0x1000
}

Binary Format

The combined binary format:
  1. Header: Version, ABI kind, sizes
  2. User Program: User ELF binary
  3. Kernel: Kernel ELF binary
  4. Metadata: Additional program info

Image ID Computation

The image ID is computed by:
  1. Loading the user ELF into memory
  2. Computing Merkle tree of memory pages
  3. Hashing program metadata
  4. Combining into final digest
Properties:
  • Deterministic (same program = same ID)
  • Unique (different programs = different IDs)
  • 256-bit security