mirror of
https://github.com/eth-act/ere.git
synced 2026-02-19 11:54:42 -05:00
Support OutputHasher for all platform crate (#205)
This commit is contained in:
@@ -6,11 +6,10 @@ rust-version.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
digest = { workspace = true, optional = true }
|
||||
digest.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
output-hasher = ["dep:digest"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -4,7 +4,6 @@ extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
#[cfg(feature = "output-hasher")]
|
||||
pub mod output_hasher;
|
||||
|
||||
/// Platform dependent methods.
|
||||
|
||||
@@ -1,23 +1,50 @@
|
||||
use core::marker::PhantomData;
|
||||
use digest::{Digest, Output, OutputSizeUser, generic_array::ArrayLength};
|
||||
use core::{marker::PhantomData, ops::Deref};
|
||||
use digest::{
|
||||
Digest, Output, OutputSizeUser,
|
||||
generic_array::{ArrayLength, GenericArray},
|
||||
};
|
||||
|
||||
pub use digest;
|
||||
|
||||
/// A hasher that given the output, returns a fixed size hash of it.
|
||||
pub trait OutputHasher: OutputSizeUser {
|
||||
fn output_hash(output: &[u8]) -> Output<Self>;
|
||||
/// A hasher that given the output, returns a hash of it.
|
||||
pub trait OutputHasher {
|
||||
type Hash<'a>: Deref<Target = [u8]>;
|
||||
|
||||
fn output_hash(output: &[u8]) -> Self::Hash<'_>;
|
||||
}
|
||||
|
||||
/// [`OutputHasher`] implementation that expects the output size to be equal to
|
||||
/// the fixed size, and returns it as is.
|
||||
pub struct IdentityOutput<S>(PhantomData<S>);
|
||||
/// A hasher that given the output, returns a fixed-size hash of it.
|
||||
pub trait FixedOutputHasher: OutputHasher + OutputSizeUser {}
|
||||
|
||||
impl<S: ArrayLength<u8> + 'static> OutputSizeUser for IdentityOutput<S> {
|
||||
type OutputSize = S;
|
||||
impl<T: OutputHasher + OutputSizeUser> FixedOutputHasher for T {}
|
||||
|
||||
/// A marker used to mark [`IdentityOutput`] to accept unsized output.
|
||||
pub struct Unsized;
|
||||
|
||||
/// [`OutputHasher`] implementation that returns output as is.
|
||||
///
|
||||
/// By setting generic `U = Unsized` it takes output with any size.
|
||||
///
|
||||
/// By setting generic `U = typenum::U{SIZE}` it expects the output to match
|
||||
/// the `SIZE`.
|
||||
pub struct IdentityOutput<U = Unsized>(PhantomData<U>);
|
||||
|
||||
impl OutputHasher for IdentityOutput<Unsized> {
|
||||
type Hash<'a> = &'a [u8];
|
||||
|
||||
fn output_hash(output: &[u8]) -> Self::Hash<'_> {
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ArrayLength<u8> + 'static> OutputHasher for IdentityOutput<S> {
|
||||
fn output_hash(output: &[u8]) -> Output<Self> {
|
||||
impl<U: ArrayLength<u8> + 'static> OutputSizeUser for IdentityOutput<U> {
|
||||
type OutputSize = U;
|
||||
}
|
||||
|
||||
impl<U: ArrayLength<u8> + 'static> OutputHasher for IdentityOutput<U> {
|
||||
type Hash<'a> = GenericArray<u8, U>;
|
||||
|
||||
fn output_hash(output: &[u8]) -> Self::Hash<'_> {
|
||||
assert!(
|
||||
output.len() == Self::output_size(),
|
||||
"output length should be equal to {}",
|
||||
@@ -29,16 +56,20 @@ impl<S: ArrayLength<u8> + 'static> OutputHasher for IdentityOutput<S> {
|
||||
}
|
||||
}
|
||||
|
||||
/// [`OutputHasher`] implementation that expects the output size to be less than
|
||||
/// or equal to the fixed size, and returns it with 0s padding.
|
||||
pub struct PaddedOutput<S>(PhantomData<S>);
|
||||
/// [`OutputHasher`] implementation that returns output with 0s padding.
|
||||
///
|
||||
/// By setting generic `U = typenum::U{SIZE}` it expects the output to be less
|
||||
/// than or equal to the `SIZE`.
|
||||
pub struct PaddedOutput<U>(PhantomData<U>);
|
||||
|
||||
impl<S: ArrayLength<u8> + 'static> OutputSizeUser for PaddedOutput<S> {
|
||||
type OutputSize = S;
|
||||
impl<U: ArrayLength<u8> + 'static> OutputSizeUser for PaddedOutput<U> {
|
||||
type OutputSize = U;
|
||||
}
|
||||
|
||||
impl<S: ArrayLength<u8> + 'static> OutputHasher for PaddedOutput<S> {
|
||||
fn output_hash(output: &[u8]) -> Output<Self> {
|
||||
impl<U: ArrayLength<u8> + 'static> OutputHasher for PaddedOutput<U> {
|
||||
type Hash<'a> = GenericArray<u8, U>;
|
||||
|
||||
fn output_hash(output: &[u8]) -> Self::Hash<'_> {
|
||||
assert!(
|
||||
output.len() <= Self::output_size(),
|
||||
"output length should be less than or equal to {}",
|
||||
@@ -51,7 +82,9 @@ impl<S: ArrayLength<u8> + 'static> OutputHasher for PaddedOutput<S> {
|
||||
}
|
||||
|
||||
impl<D: Digest> OutputHasher for D {
|
||||
fn output_hash(output: &[u8]) -> Output<Self> {
|
||||
type Hash<'a> = Output<D>;
|
||||
|
||||
fn output_hash(output: &[u8]) -> Self::Hash<'_> {
|
||||
D::digest(output)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ license.workspace = true
|
||||
airbender_riscv_common.workspace = true
|
||||
|
||||
# Local dependencies
|
||||
ere-platform-trait = { workspace = true, features = ["output-hasher"] }
|
||||
ere-platform-trait.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@@ -4,17 +4,17 @@ extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::{array, iter::repeat_with, marker::PhantomData};
|
||||
use ere_platform_trait::output_hasher::{OutputHasher, digest::typenum::U32};
|
||||
use ere_platform_trait::output_hasher::FixedOutputHasher;
|
||||
|
||||
pub use airbender_riscv_common as riscv_common;
|
||||
pub use ere_platform_trait::{
|
||||
Platform,
|
||||
output_hasher::{IdentityOutput, PaddedOutput},
|
||||
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum::U32},
|
||||
};
|
||||
|
||||
pub struct AirbenderPlatform<D>(PhantomData<D>);
|
||||
pub struct AirbenderPlatform<H>(PhantomData<H>);
|
||||
|
||||
impl<D: OutputHasher<OutputSize = U32>> Platform for AirbenderPlatform<D> {
|
||||
impl<H: FixedOutputHasher<OutputSize = U32>> Platform for AirbenderPlatform<H> {
|
||||
fn read_whole_input() -> Vec<u8> {
|
||||
let len = riscv_common::csr_read_word() as usize;
|
||||
repeat_with(riscv_common::csr_read_word)
|
||||
@@ -25,7 +25,7 @@ impl<D: OutputHasher<OutputSize = U32>> Platform for AirbenderPlatform<D> {
|
||||
}
|
||||
|
||||
fn write_whole_output(output: &[u8]) {
|
||||
let hash = D::output_hash(output);
|
||||
let hash = H::output_hash(output);
|
||||
let words = array::from_fn(|i| u32::from_le_bytes(array::from_fn(|j| hash[4 * i + j])));
|
||||
riscv_common::zksync_os_finish_success(&words);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,12 @@ extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::{marker::PhantomData, slice};
|
||||
use ere_platform_trait::output_hasher::OutputHasher;
|
||||
|
||||
pub use ere_platform_trait::Platform;
|
||||
pub use ere_platform_trait::{
|
||||
Platform,
|
||||
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum},
|
||||
};
|
||||
pub use jolt_sdk as jolt;
|
||||
|
||||
// FIXME: Because the crate `jolt-common` is not `no_std` compatible, so we have
|
||||
@@ -65,9 +69,9 @@ impl JoltMemoryConfig for DefaulJoltMemoryConfig {
|
||||
const MEMORY_SIZE: u64 = DEFAULT_MEMORY_SIZE;
|
||||
}
|
||||
|
||||
pub struct JoltPlatform<C = DefaulJoltMemoryConfig>(PhantomData<C>);
|
||||
pub struct JoltPlatform<C = DefaulJoltMemoryConfig, H = IdentityOutput>(PhantomData<(C, H)>);
|
||||
|
||||
impl<C: JoltMemoryConfig> Platform for JoltPlatform<C> {
|
||||
impl<C: JoltMemoryConfig, H: OutputHasher> Platform for JoltPlatform<C, H> {
|
||||
fn read_whole_input() -> Vec<u8> {
|
||||
let memory_layout = C::memory_layout();
|
||||
let input_ptr = memory_layout.input_start as *const u8;
|
||||
@@ -78,10 +82,11 @@ impl<C: JoltMemoryConfig> Platform for JoltPlatform<C> {
|
||||
}
|
||||
|
||||
fn write_whole_output(output: &[u8]) {
|
||||
let hash = H::output_hash(output);
|
||||
let memory_layout = C::memory_layout();
|
||||
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(output, output_slice).unwrap();
|
||||
jolt::postcard::to_slice(&*hash, output_slice).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,18 +3,24 @@
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
use ere_platform_trait::output_hasher::OutputHasher;
|
||||
|
||||
pub use ere_platform_trait::Platform;
|
||||
pub use ere_platform_trait::{
|
||||
Platform,
|
||||
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum},
|
||||
};
|
||||
pub use nexus_rt;
|
||||
|
||||
pub struct NexusPlatform;
|
||||
pub struct NexusPlatform<H = IdentityOutput>(PhantomData<H>);
|
||||
|
||||
impl Platform for NexusPlatform {
|
||||
impl<H: OutputHasher> Platform for NexusPlatform<H> {
|
||||
fn read_whole_input() -> Vec<u8> {
|
||||
nexus_rt::read_private_input().unwrap()
|
||||
}
|
||||
|
||||
fn write_whole_output(output: &[u8]) {
|
||||
nexus_rt::write_public_output(&output).unwrap()
|
||||
let hash = H::output_hash(output);
|
||||
nexus_rt::write_public_output(&*hash).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ license.workspace = true
|
||||
openvm.workspace = true
|
||||
|
||||
# Local dependencies
|
||||
ere-platform-trait = { workspace = true, features = ["output-hasher"] }
|
||||
ere-platform-trait.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["getrandom-unsupported"]
|
||||
|
||||
@@ -3,24 +3,24 @@
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
use ere_platform_trait::output_hasher::{OutputHasher, digest::typenum::U32};
|
||||
use core::{marker::PhantomData, ops::Deref};
|
||||
use ere_platform_trait::output_hasher::FixedOutputHasher;
|
||||
|
||||
pub use ere_platform_trait::{
|
||||
Platform,
|
||||
output_hasher::{IdentityOutput, PaddedOutput},
|
||||
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum::U32},
|
||||
};
|
||||
pub use openvm;
|
||||
|
||||
pub struct OpenVMPlatform<D>(PhantomData<D>);
|
||||
pub struct OpenVMPlatform<H>(PhantomData<H>);
|
||||
|
||||
impl<D: OutputHasher<OutputSize = U32>> Platform for OpenVMPlatform<D> {
|
||||
impl<H: FixedOutputHasher<OutputSize = U32>> Platform for OpenVMPlatform<H> {
|
||||
fn read_whole_input() -> Vec<u8> {
|
||||
openvm::io::read_vec()
|
||||
}
|
||||
|
||||
fn write_whole_output(output: &[u8]) {
|
||||
let hash = D::output_hash(output);
|
||||
openvm::io::reveal_bytes32(hash.into());
|
||||
let hash = H::output_hash(output).deref().try_into().unwrap();
|
||||
openvm::io::reveal_bytes32(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,18 +3,24 @@
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
use ere_platform_trait::output_hasher::OutputHasher;
|
||||
|
||||
pub use ere_platform_trait::Platform;
|
||||
pub use ere_platform_trait::{
|
||||
Platform,
|
||||
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum},
|
||||
};
|
||||
pub use pico_sdk;
|
||||
|
||||
pub struct PicoPlatform;
|
||||
pub struct PicoPlatform<H = IdentityOutput>(PhantomData<H>);
|
||||
|
||||
impl Platform for PicoPlatform {
|
||||
impl<H: OutputHasher> Platform for PicoPlatform<H> {
|
||||
fn read_whole_input() -> Vec<u8> {
|
||||
pico_sdk::io::read_vec()
|
||||
}
|
||||
|
||||
fn write_whole_output(output: &[u8]) {
|
||||
pico_sdk::io::commit_bytes(output);
|
||||
let hash = H::output_hash(output);
|
||||
pico_sdk::io::commit_bytes(&*hash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,18 @@
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::{vec, vec::Vec};
|
||||
use core::marker::PhantomData;
|
||||
use ere_platform_trait::output_hasher::OutputHasher;
|
||||
|
||||
pub use ere_platform_trait::Platform;
|
||||
pub use ere_platform_trait::{
|
||||
Platform,
|
||||
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum},
|
||||
};
|
||||
pub use risc0_zkvm;
|
||||
|
||||
pub struct Risc0Platform;
|
||||
pub struct Risc0Platform<H = IdentityOutput>(PhantomData<H>);
|
||||
|
||||
impl Platform for Risc0Platform {
|
||||
impl<H: OutputHasher> Platform for Risc0Platform<H> {
|
||||
fn read_whole_input() -> Vec<u8> {
|
||||
let len = {
|
||||
let mut bytes = [0; 4];
|
||||
@@ -22,6 +27,7 @@ impl Platform for Risc0Platform {
|
||||
}
|
||||
|
||||
fn write_whole_output(output: &[u8]) {
|
||||
risc0_zkvm::guest::env::commit_slice(output);
|
||||
let hash = H::output_hash(output);
|
||||
risc0_zkvm::guest::env::commit_slice(&*hash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,18 +3,24 @@
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
use ere_platform_trait::output_hasher::OutputHasher;
|
||||
|
||||
pub use ere_platform_trait::Platform;
|
||||
pub use ere_platform_trait::{
|
||||
Platform,
|
||||
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum},
|
||||
};
|
||||
pub use sp1_zkvm;
|
||||
|
||||
pub struct SP1Platform;
|
||||
pub struct SP1Platform<H = IdentityOutput>(PhantomData<H>);
|
||||
|
||||
impl Platform for SP1Platform {
|
||||
impl<H: OutputHasher> Platform for SP1Platform<H> {
|
||||
fn read_whole_input() -> Vec<u8> {
|
||||
sp1_zkvm::io::read_vec()
|
||||
}
|
||||
|
||||
fn write_whole_output(output: &[u8]) {
|
||||
sp1_zkvm::io::commit_slice(output);
|
||||
let hash = H::output_hash(output);
|
||||
sp1_zkvm::io::commit_slice(&*hash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,18 +3,24 @@
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
use ere_platform_trait::output_hasher::OutputHasher;
|
||||
|
||||
pub use ere_platform_trait::Platform;
|
||||
pub use ere_platform_trait::{
|
||||
Platform,
|
||||
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum},
|
||||
};
|
||||
pub use zkm_zkvm;
|
||||
|
||||
pub struct ZirenPlatform;
|
||||
pub struct ZirenPlatform<H = IdentityOutput>(PhantomData<H>);
|
||||
|
||||
impl Platform for ZirenPlatform {
|
||||
impl<H: OutputHasher> Platform for ZirenPlatform<H> {
|
||||
fn read_whole_input() -> Vec<u8> {
|
||||
zkm_zkvm::io::read_vec()
|
||||
}
|
||||
|
||||
fn write_whole_output(output: &[u8]) {
|
||||
zkm_zkvm::io::commit_slice(output);
|
||||
let hash = H::output_hash(output);
|
||||
zkm_zkvm::io::commit_slice(&*hash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ license.workspace = true
|
||||
ziskos.workspace = true
|
||||
|
||||
# Local dependencies
|
||||
ere-platform-trait = { workspace = true, features = ["output-hasher"] }
|
||||
ere-platform-trait.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@@ -4,23 +4,23 @@ extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
use ere_platform_trait::output_hasher::{OutputHasher, digest::typenum::U32};
|
||||
use ere_platform_trait::output_hasher::FixedOutputHasher;
|
||||
|
||||
pub use ere_platform_trait::{
|
||||
Platform,
|
||||
output_hasher::{IdentityOutput, PaddedOutput},
|
||||
output_hasher::{IdentityOutput, PaddedOutput, digest::typenum::U32},
|
||||
};
|
||||
pub use ziskos;
|
||||
|
||||
pub struct ZiskPlatform<D>(PhantomData<D>);
|
||||
pub struct ZiskPlatform<H>(PhantomData<H>);
|
||||
|
||||
impl<D: OutputHasher<OutputSize = U32>> Platform for ZiskPlatform<D> {
|
||||
impl<H: FixedOutputHasher<OutputSize = U32>> Platform for ZiskPlatform<H> {
|
||||
fn read_whole_input() -> Vec<u8> {
|
||||
ziskos::read_input()
|
||||
}
|
||||
|
||||
fn write_whole_output(output: &[u8]) {
|
||||
let hash = D::output_hash(output);
|
||||
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()))
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use ere_platform_risc0::{Platform, Risc0Platform};
|
||||
|
||||
type P = Risc0Platform;
|
||||
|
||||
fn main() {
|
||||
let alignment =
|
||||
u32::from_le_bytes(Risc0Platform::read_whole_input().try_into().unwrap()) as usize;
|
||||
let alignment = u32::from_le_bytes(P::read_whole_input().try_into().unwrap()) as usize;
|
||||
|
||||
let layout = std::alloc::Layout::from_size_align(1, alignment).unwrap();
|
||||
let ptr = unsafe { std::alloc::alloc(layout) };
|
||||
|
||||
Reference in New Issue
Block a user