Improve crates ere-platform-{zkvm} a bit (#228)

This commit is contained in:
Han
2025-11-28 10:10:23 +09:00
committed by GitHub
parent db064be839
commit 1f51e736a2
15 changed files with 50 additions and 18 deletions

1
Cargo.lock generated
View File

@@ -3844,6 +3844,7 @@ version = "0.0.15"
dependencies = [
"ere-platform-trait",
"risc0-zkvm",
"risc0-zkvm-platform",
]
[[package]]

View File

@@ -120,6 +120,7 @@ risc0-binfmt = { version = "3.0.2", default-features = false }
risc0-build = "3.0.3"
risc0-zkp = { version = "3.0.2", default-features = false }
risc0-zkvm = { version = "3.0.3", default-features = false }
risc0-zkvm-platform = { version = "2.2.1", default-features = false }
# SP1 dependencies
sp1-sdk = "5.2.2"

View File

@@ -493,7 +493,7 @@ mod test {
Zisk,
RustCustomized,
"basic_rust",
[BasicProgramInput::valid().into_output_sha256()],
[BasicProgramInput::valid()],
[Vec::new(), BasicProgramInput::invalid().serialized_input()]
);
}

View File

@@ -12,6 +12,13 @@ pub use ere_platform_trait::{
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum::U32},
};
/// Airbender [`Platform`] implementation.
///
/// Because Airbender only support public values up to 32 bytes, so
/// - If the guest has output bytes more than 32 bytes, it should use a
/// cryptographic hash function for the generic `H` (for example `Sha256`).
/// - If the guest has output bytes less than 32 bytes, it should use
/// [`PaddedOutput`] for the generic `H`
pub struct AirbenderPlatform<H>(PhantomData<H>);
impl<H: FixedOutputHasher<OutputSize = U32>> Platform for AirbenderPlatform<H> {

View File

@@ -69,6 +69,7 @@ impl JoltMemoryConfig for DefaulJoltMemoryConfig {
const MEMORY_SIZE: u64 = DEFAULT_MEMORY_SIZE;
}
/// Jolt [`Platform`] implementation.
pub struct JoltPlatform<C = DefaulJoltMemoryConfig, H = IdentityOutput>(PhantomData<(C, H)>);
impl<C: JoltMemoryConfig, H: OutputHasher> Platform for JoltPlatform<C, H> {
@@ -87,7 +88,12 @@ impl<C: JoltMemoryConfig, H: OutputHasher> Platform for JoltPlatform<C, H> {
let output_ptr = memory_layout.output_start as *mut u8;
let max_output_len = memory_layout.max_output_size as usize;
let output_slice = unsafe { core::slice::from_raw_parts_mut(output_ptr, max_output_len) };
jolt::postcard::to_slice(&*hash, output_slice).unwrap();
jolt::postcard::to_slice(&*hash, output_slice).unwrap_or_else(|err| match err {
jolt::postcard::Error::SerializeBufferFull => {
panic!("Maximum output size is {max_output_len} bytes")
}
err => panic!("`postcard::to_slice` failed: {err:?}"),
});
}
fn print(message: &str) {

View File

@@ -12,6 +12,7 @@ pub use ere_platform_trait::{
};
pub use nexus_rt;
/// Nexus [`Platform`] implementation.
pub struct NexusPlatform<H = IdentityOutput>(PhantomData<H>);
impl<H: OutputHasher> Platform for NexusPlatform<H> {

View File

@@ -12,6 +12,13 @@ pub use ere_platform_trait::{
};
pub use openvm;
/// OpenVM [`Platform`] implementation.
///
/// Because OpenVM only support public values up to 32 bytes, so
/// - If the guest has output bytes more than 32 bytes, it should use a
/// cryptographic hash function for the generic `H` (for example `Sha256`).
/// - If the guest has output bytes less than 32 bytes, it should use
/// [`PaddedOutput`] for the generic `H`
pub struct OpenVMPlatform<H>(PhantomData<H>);
impl<H: FixedOutputHasher<OutputSize = U32>> Platform for OpenVMPlatform<H> {

View File

@@ -12,6 +12,7 @@ pub use ere_platform_trait::{
};
pub use pico_sdk;
/// Pico [`Platform`] implementation.
pub struct PicoPlatform<H = IdentityOutput>(PhantomData<H>);
impl<H: OutputHasher> Platform for PicoPlatform<H> {

View File

@@ -8,6 +8,7 @@ license.workspace = true
[dependencies]
# Risc0 dependencies
risc0-zkvm.workspace = true
risc0-zkvm-platform.workspace = true
# Local dependencies
ere-platform-trait.workspace = true
@@ -18,6 +19,7 @@ getrandom = ["risc0-zkvm/getrandom"]
heap-embedded-alloc = ["risc0-zkvm/heap-embedded-alloc"]
std = ["risc0-zkvm/std"]
unstable = ["risc0-zkvm/unstable"]
sys-getenv = ["risc0-zkvm-platform/sys-getenv"]
[lints]
workspace = true

View File

@@ -13,6 +13,7 @@ pub use ere_platform_trait::{
};
pub use risc0_zkvm;
/// Risc0 [`Platform`] implementation.
pub struct Risc0Platform<H = IdentityOutput>(PhantomData<H>);
impl<H: OutputHasher> Platform for Risc0Platform<H> {

View File

@@ -12,6 +12,7 @@ pub use ere_platform_trait::{
};
pub use sp1_zkvm;
/// SP1 [`Platform`] implementation.
pub struct SP1Platform<H = IdentityOutput>(PhantomData<H>);
impl<H: OutputHasher> Platform for SP1Platform<H> {

View File

@@ -12,6 +12,7 @@ pub use ere_platform_trait::{
};
pub use zkm_zkvm;
/// Ziren [`Platform`] implementation.
pub struct ZirenPlatform<H = IdentityOutput>(PhantomData<H>);
impl<H: OutputHasher> Platform for ZirenPlatform<H> {

View File

@@ -3,35 +3,41 @@
extern crate alloc;
use alloc::vec::Vec;
use core::marker::PhantomData;
use ere_platform_trait::output_hasher::FixedOutputHasher;
use core::{array::from_fn, marker::PhantomData};
use ere_platform_trait::output_hasher::OutputHasher;
use ziskos::ziskos_definitions::ziskos_config::UART_ADDR;
pub use ere_platform_trait::{
Platform,
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum::U32},
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum},
};
pub use ziskos;
pub struct ZiskPlatform<H>(PhantomData<H>);
/// ZisK [`Platform`] implementation.
///
/// Note that the maximum output size is 256 bytes, and output size will be
/// padded to multiple of 4.
pub struct ZiskPlatform<H = IdentityOutput>(PhantomData<H>);
impl<H: FixedOutputHasher<OutputSize = U32>> Platform for ZiskPlatform<H> {
impl<H: OutputHasher> Platform for ZiskPlatform<H> {
fn read_whole_input() -> Vec<u8> {
ziskos::read_input()
}
fn write_whole_output(output: &[u8]) {
let hash = H::output_hash(output);
hash.chunks_exact(4).enumerate().for_each(|(idx, bytes)| {
ziskos::set_output(idx, u32::from_le_bytes(bytes.try_into().unwrap()))
assert!(hash.len() <= 256, "Maximum output size is 256 bytes");
hash.chunks(4).enumerate().for_each(|(idx, chunk)| {
let value = u32::from_le_bytes(from_fn(|i| chunk.get(i).copied().unwrap_or_default()));
ziskos::set_output(idx, value)
});
}
fn print(message: &str) {
let bytes = message.as_bytes();
for i in 0..bytes.len() {
for byte in bytes {
unsafe {
core::ptr::write_volatile(UART_ADDR as *mut u8, bytes[i]);
core::ptr::write_volatile(UART_ADDR as *mut u8, *byte);
}
}
}

View File

@@ -170,7 +170,7 @@ mod tests {
let program = basic_program();
let zkvm = EreZisk::new(program, ProverResourceType::Cpu).unwrap();
let test_case = BasicProgramInput::valid().into_output_sha256();
let test_case = BasicProgramInput::valid();
run_zkvm_execute(&zkvm, &test_case);
}
@@ -191,7 +191,7 @@ mod tests {
let _guard = PROVE_LOCK.lock().unwrap();
let test_case = BasicProgramInput::valid().into_output_sha256();
let test_case = BasicProgramInput::valid();
run_zkvm_prove(&zkvm, &test_case);
}

View File

@@ -1,13 +1,10 @@
#![no_main]
use ere_platform_zisk::{ziskos, ZiskPlatform};
use ere_test_utils::{
guest::Sha256,
program::{basic::BasicProgram, Program},
};
use ere_test_utils::program::{basic::BasicProgram, Program};
ziskos::entrypoint!(main);
fn main() {
BasicProgram::run::<ZiskPlatform<Sha256>>();
BasicProgram::run::<ZiskPlatform>();
}