Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add succinct-zkvm os and target #138463

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
@@ -1954,6 +1954,7 @@ supported_targets! {

("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
("riscv32im-risc0-zkvm-elf", riscv32im_risc0_zkvm_elf),
("riscv32im-succinct-zkvm-elf", riscv32im_succinct_zkvm_elf),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By putting a dash in the target OS, you make it look like it's vendor:succinct, os:zkvm. I would recommend calling it riscv32im-succinct_zkvm-elf or even just rustc32im-succinct-elf instead

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

("riscv32im-unknown-none-elf", riscv32im_unknown_none_elf),
("riscv32ima-unknown-none-elf", riscv32ima_unknown_none_elf),
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::spec::{
Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions,
};

pub(crate) fn target() -> Target {
Target {
data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
llvm_target: "riscv32".into(),
metadata: TargetMetadata {
description: Some("Succinct's zero-knowledge Virtual Machine (RV32IM ISA)".into()),
tier: Some(3),
host_tools: Some(false),
std: None,
},
pointer_width: 32,
arch: "riscv32".into(),

options: TargetOptions {
os: "succinct-zkvm".into(),
vendor: "succinct".into(),
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),
cpu: "generic-rv32".into(),

// The zkvm is singlethreaded and all operations are atomic.
// The std-lib is compiled with lowered atomicsa and the default Succinct build tools
// enforce this on programs.
max_atomic_width: Some(64),
atomic_cas: true,

features: "+m".into(),
llvm_abiname: "ilp32".into(),
executables: true,
panic_strategy: PanicStrategy::Abort,
relocation_model: RelocModel::Static,
emit_debug_gdb_scripts: false,
eh_frame_header: false,
singlethread: true,
..Default::default()
},
}
}
1 change: 1 addition & 0 deletions src/bootstrap/src/core/sanity.rs
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@ pub struct Finder {
const STAGE0_MISSING_TARGETS: &[&str] = &[
// just a dummy comment so the list doesn't get onelined
"wasm32-wali-linux-musl",
"riscv32im-succinct-zkvm-elf",
];

/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -77,6 +77,7 @@
- [riscv32e\*-unknown-none-elf](platform-support/riscv32e-unknown-none-elf.md)
- [riscv32i\*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
- [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md)
- [riscv32im-succinct-zkvm-elf](platform-support/riscv32im-succinct-zkvm-elf.md)
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
- [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md)
- [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md)
83 changes: 83 additions & 0 deletions src/doc/rustc/src/platform-support/riscv32im-succinct-zkvm-elf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# `riscv32im-risc0-zkvm-elf`

**Tier: 3**

Succinct's ISA for the SP1 zkVM (Zero Knowledge Virtual Machine).

## Target maintainers

- John Guibas, `john@succinct.xyz`, https://github.com/jtguibas
- Nathan Bustamante, `nathan@succinct.xyz`, https://github.com/nhtyy

## 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 and
create a cryptographic proof of the "trace" of the programs runtime.

We have a cargo extension called [cargo-prove] that allow users to generate
project templates, install tools for improved user experience and build binaries.

## Requirements

The target only supports cross compilation and no host tools. The target
supports `alloc` with a default allocator and will have support for std soon.

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
`config.toml`. However, we recommend building programs in our starter template
generated by the [cargo-prove] utility and the [sp1-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 prove install-toolchain`.

## 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 prove 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-prove]: https://docs.succinct.xyz/docs/sp1/getting-started/install
[sp1-build]: https://crates.io/crates/sp1-build
1 change: 1 addition & 0 deletions src/tools/build-manifest/src/main.rs
Original file line number Diff line number Diff line change
@@ -138,6 +138,7 @@ static TARGETS: &[&str] = &[
"powerpc64le-unknown-linux-musl",
"riscv32i-unknown-none-elf",
"riscv32im-risc0-zkvm-elf",
"riscv32im-succinct-zkvm-elf",
"riscv32im-unknown-none-elf",
"riscv32ima-unknown-none-elf",
"riscv32imc-unknown-none-elf",
3 changes: 3 additions & 0 deletions tests/assembly/targets/targets-elf.rs
Original file line number Diff line number Diff line change
@@ -421,6 +421,9 @@
//@ revisions: riscv32im_risc0_zkvm_elf
//@ [riscv32im_risc0_zkvm_elf] compile-flags: --target riscv32im-risc0-zkvm-elf
//@ [riscv32im_risc0_zkvm_elf] needs-llvm-components: riscv
//@ revisions: riscv32im_succinct_zkvm_elf
//@ [riscv32im_succinct_zkvm_elf] compile-flags: --target riscv32im-succinct-zkvm-elf
//@ [riscv32im_succinct_zkvm_elf] needs-llvm-components: riscv
//@ revisions: riscv32im_unknown_none_elf
//@ [riscv32im_unknown_none_elf] compile-flags: --target riscv32im-unknown-none-elf
//@ [riscv32im_unknown_none_elf] needs-llvm-components: riscv
Loading