mirror of
https://github.com/eth-act/ere.git
synced 2026-04-25 03:00:10 -04:00
Risc0 check receipt variant (#100)
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
|
||||
|
||||
use crate::{compile::compile_risc0_program, error::Risc0Error};
|
||||
use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, Receipt, default_executor};
|
||||
use borsh::{BorshDeserialize, BorshSerialize};
|
||||
use risc0_zkvm::{
|
||||
ExecutorEnv, ExecutorEnvBuilder, InnerReceipt, Journal, Receipt, ReceiptClaim, SuccinctReceipt,
|
||||
default_executor,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{path::Path, time::Instant};
|
||||
use zkvm_interface::{
|
||||
Compiler, Input, InputItem, ProgramExecutionReport, ProgramProvingReport, ProverResourceType,
|
||||
@@ -29,6 +34,33 @@ impl Compiler for RV32_IM_RISC0_ZKVM_ELF {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
|
||||
pub struct Risc0ProofWithPublicValues {
|
||||
/// The aggregated proof generated by the Risc0 zkVM.
|
||||
pub receipt: SuccinctReceipt<ReceiptClaim>,
|
||||
/// The public values generated by the Risc0 zkVM.
|
||||
pub journal: Journal,
|
||||
}
|
||||
|
||||
impl From<Receipt> for Risc0ProofWithPublicValues {
|
||||
fn from(receipt: Receipt) -> Self {
|
||||
match receipt.inner {
|
||||
// We always use `ProverOpts::succinct()`.
|
||||
InnerReceipt::Succinct(inner) => Self {
|
||||
receipt: inner,
|
||||
journal: receipt.journal,
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Risc0ProofWithPublicValues> for Receipt {
|
||||
fn from(Risc0ProofWithPublicValues { receipt, journal }: Risc0ProofWithPublicValues) -> Self {
|
||||
Receipt::new(InnerReceipt::Succinct(receipt), journal.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EreRisc0 {
|
||||
program: <RV32_IM_RISC0_ZKVM_ELF as Compiler>::Program,
|
||||
resource: ProverResourceType,
|
||||
@@ -45,10 +77,8 @@ impl EreRisc0 {
|
||||
// If not using Metal, we use the bento stack which requires
|
||||
// Docker to spin up the proving services that use Cuda.
|
||||
if !cfg!(feature = "metal") {
|
||||
prove::bento::build_bento_images()
|
||||
.map_err(|err| zkVMError::Other(Box::new(err)))?;
|
||||
prove::bento::docker_compose_bento_up()
|
||||
.map_err(|err| zkVMError::Other(Box::new(err)))?;
|
||||
prove::bento::build_bento_images().map_err(zkVMError::other)?;
|
||||
prove::bento::docker_compose_bento_up().map_err(zkVMError::other)?;
|
||||
}
|
||||
}
|
||||
ProverResourceType::Network(_) => {
|
||||
@@ -66,13 +96,13 @@ impl zkVM for EreRisc0 {
|
||||
fn execute(&self, inputs: &Input) -> Result<ProgramExecutionReport, zkVMError> {
|
||||
let executor = default_executor();
|
||||
let mut env = ExecutorEnv::builder();
|
||||
serialize_inputs(&mut env, inputs).map_err(|err| zkVMError::Other(err.into()))?;
|
||||
let env = env.build().map_err(|err| zkVMError::Other(err.into()))?;
|
||||
serialize_inputs(&mut env, inputs).map_err(zkVMError::other)?;
|
||||
let env = env.build().map_err(zkVMError::other)?;
|
||||
|
||||
let start = Instant::now();
|
||||
let session_info = executor
|
||||
.execute(env, &self.program.elf)
|
||||
.map_err(|err| zkVMError::Other(err.into()))?;
|
||||
.map_err(zkVMError::other)?;
|
||||
Ok(ProgramExecutionReport {
|
||||
total_num_cycles: session_info.cycles() as u64,
|
||||
execution_duration: start.elapsed(),
|
||||
@@ -101,17 +131,20 @@ impl zkVM for EreRisc0 {
|
||||
}
|
||||
};
|
||||
|
||||
let encoded = borsh::to_vec(&receipt).map_err(|err| zkVMError::Other(Box::new(err)))?;
|
||||
Ok((encoded, ProgramProvingReport::new(proving_time)))
|
||||
let proof =
|
||||
borsh::to_vec(&Risc0ProofWithPublicValues::from(receipt)).map_err(zkVMError::other)?;
|
||||
|
||||
Ok((proof, ProgramProvingReport::new(proving_time)))
|
||||
}
|
||||
|
||||
fn verify(&self, proof: &[u8]) -> Result<(), zkVMError> {
|
||||
let decoded: Receipt =
|
||||
borsh::from_slice(proof).map_err(|err| zkVMError::Other(Box::new(err)))?;
|
||||
let receipt: Receipt = borsh::from_slice::<Risc0ProofWithPublicValues>(proof)
|
||||
.map_err(zkVMError::other)?
|
||||
.into();
|
||||
|
||||
decoded
|
||||
receipt
|
||||
.verify(self.program.image_id)
|
||||
.map_err(|err| zkVMError::Other(Box::new(err)))
|
||||
.map_err(zkVMError::other)
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
|
||||
@@ -84,6 +84,12 @@ pub enum zkVMError {
|
||||
Other(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
}
|
||||
|
||||
impl zkVMError {
|
||||
pub fn other(error: impl Into<Box<dyn std::error::Error + Send + Sync + 'static>>) -> Self {
|
||||
Self::Other(error.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[auto_impl::auto_impl(&, Arc, Box)]
|
||||
/// zkVM trait to abstract away the differences between each zkVM.
|
||||
|
||||
Reference in New Issue
Block a user