Alternative of #182 (#183)

Co-authored-by: =?UTF-8?q?Lancelot=20de=20Ferri=C3=A8re?= <wraitii@gmail.com>
This commit is contained in:
Han
2025-10-29 23:01:48 +08:00
committed by GitHub
parent e9cdb1795d
commit 9957836858
14 changed files with 132 additions and 26 deletions

View File

@@ -1,5 +1,6 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![allow(clippy::double_parens)]
#![allow(non_camel_case_types)]
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use std::path::Path;
@@ -91,7 +92,6 @@ impl Proof {
}
}
#[allow(non_camel_case_types)]
#[auto_impl::auto_impl(&, Arc, Box)]
/// zkVM trait to abstract away the differences between each zkVM.
///
@@ -124,3 +124,11 @@ pub trait zkVM {
/// Returns the version of the zkVM SDK (e.g. 0.1.0)
fn sdk_version(&self) -> &'static str;
}
pub trait zkVMProgramDigest {
/// Digest of specific compiled guest program used when verify a proof.
type ProgramDigest: Clone + Serialize + DeserializeOwned;
/// Returns [`zkVMProgramDigest::ProgramDigest`].
fn program_digest(&self) -> anyhow::Result<Self::ProgramDigest>;
}

View File

@@ -42,6 +42,10 @@ impl AirbenderSdk {
}
}
pub fn vk_chain_hash(&self) -> &VkHashChain {
&self.vk_hash_chain
}
pub fn execute(&self, input: &[u8]) -> Result<(PublicValues, u64), AirbenderError> {
let tempdir = tempdir().map_err(CommonError::tempdir)?;

View File

@@ -1,11 +1,15 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
use crate::{client::AirbenderSdk, compiler::AirbenderProgram, error::AirbenderError};
use crate::{
client::{AirbenderSdk, VkHashChain},
compiler::AirbenderProgram,
error::AirbenderError,
};
use airbender_execution_utils::ProgramProof;
use anyhow::bail;
use ere_zkvm_interface::{
CommonError, ProgramExecutionReport, ProgramProvingReport, Proof, ProofKind,
ProverResourceType, PublicValues, zkVM,
ProverResourceType, PublicValues, zkVM, zkVMProgramDigest,
};
use std::time::Instant;
@@ -97,6 +101,14 @@ impl zkVM for EreAirbender {
}
}
impl zkVMProgramDigest for EreAirbender {
type ProgramDigest = VkHashChain;
fn program_digest(&self) -> anyhow::Result<Self::ProgramDigest> {
Ok(*self.sdk.vk_chain_hash())
}
}
#[cfg(test)]
mod tests {
use crate::{

View File

@@ -1,15 +1,30 @@
use miden_core::utils::{Deserializable, Serializable};
use miden_core::{
Program, ProgramInfo,
utils::{Deserializable, Serializable},
};
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
use std::ops::Deref;
mod miden_asm;
pub use miden_asm::MidenAsm;
/// Wrapper for [`miden_core::Program`] that implements `serde`.
#[derive(Clone)]
pub struct MidenProgram(pub miden_core::Program);
pub type MidenProgram = MidenSerdeWrapper<Program>;
pub type MidenProgramInfo = MidenSerdeWrapper<ProgramInfo>;
impl Serialize for MidenProgram {
/// Wrapper that implements `serde` for Miden structures.
#[derive(Clone)]
pub struct MidenSerdeWrapper<T>(pub T);
impl<T> Deref for MidenSerdeWrapper<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: Serializable> Serialize for MidenSerdeWrapper<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
@@ -18,13 +33,13 @@ impl Serialize for MidenProgram {
}
}
impl<'de> Deserialize<'de> for MidenProgram {
impl<'de, T: Deserializable> Deserialize<'de> for MidenSerdeWrapper<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let bytes = Vec::<u8>::deserialize(deserializer)?;
miden_core::Program::read_from_bytes(&bytes)
T::read_from_bytes(&bytes)
.map(Self)
.map_err(D::Error::custom)
}

View File

@@ -1,4 +1,7 @@
use crate::{compiler::MidenProgram, error::CompileError};
use crate::{
compiler::{MidenProgram, MidenSerdeWrapper},
error::CompileError,
};
use ere_zkvm_interface::Compiler;
use miden_assembly::Assembler;
use miden_stdlib::StdLibrary;
@@ -42,7 +45,7 @@ impl Compiler for MidenAsm {
.assemble_program(&source)
.map_err(CompileError::AssemblyCompilation)?;
Ok(MidenProgram(program))
Ok(MidenSerdeWrapper(program))
}
}

View File

@@ -1,10 +1,13 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
use crate::{compiler::MidenProgram, error::MidenError};
use crate::{
compiler::{MidenProgram, MidenProgramInfo, MidenSerdeWrapper},
error::MidenError,
};
use anyhow::bail;
use ere_zkvm_interface::{
CommonError, ProgramExecutionReport, ProgramProvingReport, Proof, ProofKind,
ProverResourceType, PublicValues, zkVM,
ProverResourceType, PublicValues, zkVM, zkVMProgramDigest,
};
use miden_core::{
Program,
@@ -155,6 +158,14 @@ impl zkVM for EreMiden {
}
}
impl zkVMProgramDigest for EreMiden {
type ProgramDigest = MidenProgramInfo;
fn program_digest(&self) -> anyhow::Result<Self::ProgramDigest> {
Ok(MidenSerdeWrapper(self.program.clone().into()))
}
}
/// Convert Miden field elements into bytes
pub fn felts_to_bytes(felts: &[Felt]) -> Vec<u8> {
felts

View File

@@ -4,7 +4,7 @@ use crate::{compiler::OpenVMProgram, error::OpenVMError};
use anyhow::bail;
use ere_zkvm_interface::{
CommonError, ProgramExecutionReport, ProgramProvingReport, Proof, ProofKind,
ProverResourceType, PublicValues, zkVM,
ProverResourceType, PublicValues, zkVM, zkVMProgramDigest,
};
use openvm_circuit::arch::instructions::exe::VmExe;
use openvm_continuations::verifier::internal::types::VmStarkProof;
@@ -197,6 +197,14 @@ impl zkVM for EreOpenVM {
}
}
impl zkVMProgramDigest for EreOpenVM {
type ProgramDigest = AppExecutionCommit;
fn program_digest(&self) -> anyhow::Result<Self::ProgramDigest> {
Ok(self.app_commit)
}
}
/// Extract public values in bytes from field elements.
///
/// The public values revealed in guest program will be flatten into `Vec<u8>`

View File

@@ -11,7 +11,7 @@ use pico_vm::{
instances::compiler::shapes::{
recursion_shape::RecursionShapeConfig, riscv_shape::RiscvShapeConfig,
},
machine::proof,
machine::{keys, proof},
proverchain::{
CombineProver, CompressProver, ConvertProver, InitialProverSetup, MachineProver,
ProverChain, RiscvProver,
@@ -20,6 +20,7 @@ use pico_vm::{
pub type SC = KoalaBearPoseidon2;
pub type MetaProof = proof::MetaProof<SC>;
pub type BaseVerifyingKey = keys::BaseVerifyingKey<SC>;
pub struct ProverClient {
riscv: RiscvProver<SC, Program>,
@@ -54,6 +55,10 @@ impl ProverClient {
}
}
pub fn vk(&self) -> &BaseVerifyingKey {
self.riscv.vk()
}
pub fn new_stdin_builder(&self) -> EmulatorStdinBuilder<Vec<u8>, SC> {
EmulatorStdinBuilder::default()
}

View File

@@ -1,14 +1,14 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
use crate::{
client::{MetaProof, ProverClient},
client::{BaseVerifyingKey, MetaProof, ProverClient},
compiler::PicoProgram,
error::PicoError,
};
use anyhow::bail;
use ere_zkvm_interface::{
CommonError, ProgramExecutionReport, ProgramProvingReport, Proof, ProofKind,
ProverResourceType, PublicValues, zkVM,
ProverResourceType, PublicValues, zkVM, zkVMProgramDigest,
};
use pico_p3_field::PrimeField32;
use pico_vm::emulator::stdin::EmulatorStdinBuilder;
@@ -142,6 +142,14 @@ impl zkVM for ErePico {
}
}
impl zkVMProgramDigest for ErePico {
type ProgramDigest = BaseVerifyingKey;
fn program_digest(&self) -> anyhow::Result<Self::ProgramDigest> {
Ok(self.client().vk().clone())
}
}
/// Extract public values sha256 digest from base proof of compressed proof.
/// The sha256 digest will be placed at the first 32 field elements of the
/// public values of the only base proof.

View File

@@ -4,11 +4,11 @@ use crate::{compiler::Risc0Program, error::Risc0Error};
use anyhow::bail;
use ere_zkvm_interface::{
CommonError, ProgramExecutionReport, ProgramProvingReport, Proof, ProofKind,
ProverResourceType, PublicValues, zkVM,
ProverResourceType, PublicValues, zkVM, zkVMProgramDigest,
};
use risc0_zkvm::{
DEFAULT_MAX_PO2, DefaultProver, ExecutorEnv, ExternalProver, InnerReceipt, ProverOpts, Receipt,
default_executor, default_prover,
DEFAULT_MAX_PO2, DefaultProver, Digest, ExecutorEnv, ExternalProver, InnerReceipt, ProverOpts,
Receipt, default_executor, default_prover,
};
use std::{env, ops::RangeInclusive, rc::Rc, time::Instant};
@@ -209,6 +209,14 @@ impl zkVM for EreRisc0 {
}
}
impl zkVMProgramDigest for EreRisc0 {
type ProgramDigest = Digest;
fn program_digest(&self) -> anyhow::Result<Self::ProgramDigest> {
Ok(self.program.image_id)
}
}
#[cfg(test)]
mod tests {
use crate::{

View File

@@ -4,7 +4,7 @@ use crate::{compiler::SP1Program, error::SP1Error};
use anyhow::bail;
use ere_zkvm_interface::{
CommonError, NetworkProverConfig, ProgramExecutionReport, ProgramProvingReport, Proof,
ProofKind, ProverResourceType, PublicValues, zkVM,
ProofKind, ProverResourceType, PublicValues, zkVM, zkVMProgramDigest,
};
use sp1_sdk::{
CpuProver, CudaProver, NetworkProver, Prover, ProverClient, SP1ProofMode,
@@ -230,6 +230,14 @@ impl zkVM for EreSP1 {
}
}
impl zkVMProgramDigest for EreSP1 {
type ProgramDigest = SP1VerifyingKey;
fn program_digest(&self) -> anyhow::Result<Self::ProgramDigest> {
Ok(self.vk.clone())
}
}
fn panic_msg(err: Box<dyn std::any::Any + Send + 'static>) -> String {
None.or_else(|| err.downcast_ref::<String>().cloned())
.or_else(|| err.downcast_ref::<&'static str>().map(ToString::to_string))

View File

@@ -4,7 +4,7 @@ use crate::{compiler::ZirenProgram, error::ZirenError};
use anyhow::bail;
use ere_zkvm_interface::{
CommonError, ProgramExecutionReport, ProgramProvingReport, Proof, ProofKind,
ProverResourceType, PublicValues, zkVM,
ProverResourceType, PublicValues, zkVM, zkVMProgramDigest,
};
use std::{panic, time::Instant};
use tracing::info;
@@ -128,6 +128,14 @@ impl zkVM for EreZiren {
}
}
impl zkVMProgramDigest for EreZiren {
type ProgramDigest = ZKMVerifyingKey;
fn program_digest(&self) -> anyhow::Result<Self::ProgramDigest> {
Ok(self.vk.clone())
}
}
fn panic_msg(err: Box<dyn std::any::Any + Send + 'static>) -> String {
None.or_else(|| err.downcast_ref::<String>().cloned())
.or_else(|| err.downcast_ref::<&'static str>().map(ToString::to_string))

View File

@@ -220,7 +220,7 @@ impl ZiskSdk {
///
/// If it is not setup yet, it makes sure the global setup is done, then
/// does ROM setup of the ELF and stores the ROM digest for later usage.
fn rom_digest(&self) -> Result<RomDigest, ZiskError> {
pub fn rom_digest(&self) -> Result<RomDigest, ZiskError> {
// FIXME: Use `get_or_try_init` when it is stabilized
let mut result = Ok(());
let rom_digest = *self.rom_digest.get_or_init(|| {

View File

@@ -1,14 +1,14 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
use crate::{
client::{ZiskOptions, ZiskSdk, ZiskServer},
client::{RomDigest, ZiskOptions, ZiskSdk, ZiskServer},
compiler::ZiskProgram,
error::ZiskError,
};
use anyhow::bail;
use ere_zkvm_interface::{
CommonError, ProgramExecutionReport, ProgramProvingReport, Proof, ProofKind,
ProverResourceType, PublicValues, zkVM,
ProverResourceType, PublicValues, zkVM, zkVMProgramDigest,
};
use std::{
sync::{Mutex, MutexGuard},
@@ -125,6 +125,14 @@ impl zkVM for EreZisk {
}
}
impl zkVMProgramDigest for EreZisk {
type ProgramDigest = RomDigest;
fn program_digest(&self) -> anyhow::Result<Self::ProgramDigest> {
Ok(self.sdk.rom_digest()?)
}
}
#[cfg(test)]
mod tests {
use crate::{EreZisk, compiler::RustRv64imaCustomized};