# `riscv32im-risc0-zkvm-elf`

**Tier: 3**

RISC Zero's Zero Knowledge Virtual Machine (zkVM) implementing the RV32IM instruction set.

## Target maintainers

[@flaub](https://github.com/flaub)
[@jbruestle](https://github.com/jbruestle)

## Background

This target is an execution environment to produce a proof of execution of
a RISC-V ELF binary and any output that the developer of the binary wishes to
display publicly. In order to do this, the target will execute the ELF to
generate a receipt containing the output of the computation along with a
cryptographic seal. This receipt can be verified to ensure the integrity of the
computation and its result. This target is implemented as software only; it has
no hardware implementation.

We have a cargo extension called [cargo-risczero] that allow users to generate
project templates, install tools for improved user experience, build the binary
using a docker environment and test programs.

## Requirements

The target only supports cross compilation and no host tools. The target
supports `alloc` with a default allocator and has experimental support for
`std`. The target expects the binaries to be in ELF.

The target's execution environment is single threaded, non-preemptive, and does
not support any privileged instructions, nor unaligned accesses. At the time of
writing the VM has 192 MB of memory and text/data, heap, and stack need to be
with in the address range `0x400` - `0x0C000000`. The binaries themselves expect
no operating system and can be thought of as running on bare-metal. The target
does not use `#[target_feature(...)]` or `-C target-feature=` values.

Calling `extern "C"` on the target uses the C calling convention outlined in the
[RISC-V specification].

## Building for the zkVM

Programs for the zkVM could be built by adding it to the `target` list in
`bootstrap.toml`. However, we recommend building programs in our starter template
generated by the [cargo-risczero] utility and the [risc0-build] crate. This
crate calls `rustc` with `-C "link-arg=-Ttext=` so that it maps the text in the
appropriate location as well as generating variables that represent the ELF and
a unique ID associated with the ELF. The starter template provides developers
with system calls that are useful to zero knowledge computing such as writing to
the public output, hashing using sha256, and multiply big integers.

## Building Rust programs

Rust does not yet ship pre-compiled artifacts for this target. To compile for
this target, you will either need to build Rust with the target enabled (see
"Building the target" above). We do not recommend using `build-std` as we have
run into issues building core in the past on our starter template. An alternate
solution is to download the risc0 tool chain by running `cargo risczero install`.

## Testing

Note: the target is implemented as a software emulator called the zkVM and there
is no hardware implementation of the target.

The most practical way to test the target program is to use our starter template
that can be generated by using the `cargo risczero new` command. The template
generates a sample "host" and "guest" code. The guest code compiled to the
target (which is RV32IM) whereas the "host" code is compiled to run on the
programmer's machine running either a Linux distribution or macOS. The host
program is responsible for running the guest binary on the zkVM and retrieving
its public output.

The target currently does not support running the Rust test suite.

## Cross-compilation toolchains and C code

Compatible C code can be built for this target on any compiler that has a RV32IM
target.  On clang and ld.lld linker, it can be generated using the
`-march=rv32im`, `-mabi=ilp32` with llvm features flag `features=+m` and llvm
target `riscv32-unknown-none`.

[RISC-V specification]: https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf
[cargo-risczero]: https://docs.rs/cargo-risczero/latest/cargo_risczero/
[risc0-build]: https://crates.io/crates/risc0-build
