pub mod attestation;
pub mod risc0;
pub mod sp1;
use alloy::primitives::FixedBytes;
use risc0_zkvm::{Digest, Receipt};
use serde::{Deserialize, Serialize};
use sp1_sdk::{HashableKey, Prover, ProverClient, SP1ProofWithPublicValues, SP1VerifyingKey};
use std::path::PathBuf;
use crate::{
generated::rego_verifier::IRegoVerifier::RegoContext,
newton_prover_task_manager::INewtonProverTaskManager::{Task, TaskResponse},
};
pub const SP1_REGO_ELF: &[u8] = include_bytes!("./elf/sp1-rego");
pub const SP1_ATTESTATION_ELF: &[u8] = include_bytes!("./elf/sp1-attestation");
#[derive(strum_macros::Display, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[strum(serialize_all = "lowercase")]
pub enum Zkvm {
Sp1,
Risc0,
}
#[derive(strum_macros::Display, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[strum(serialize_all = "lowercase")]
pub enum ProofSystem {
Groth16,
Plonk,
}
#[derive(Clone, Serialize, Deserialize)]
pub enum Proof {
Sp1 {
journal: Vec<u8>,
vk: SP1VerifyingKey,
proof: SP1ProofWithPublicValues,
request_id: FixedBytes<32>,
},
Risc0 {
receipt: Receipt,
image_id: Digest,
seal: Vec<u8>,
},
}
impl std::fmt::Debug for Proof {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Proof::Sp1 {
journal,
vk,
proof,
request_id,
} => write!(
f,
"Proof::Sp1 {{ journal: {:?}, vk: {:?}, proof bytes: {:?}, request_id: {:?} }}",
crate::hex!(journal.as_slice()),
vk.bytes32().to_string().as_str(),
crate::hex!(proof.bytes()),
crate::hex!(request_id)
),
Proof::Risc0 {
receipt,
image_id,
seal,
} => write!(
f,
"Proof::Risc0 {{ journal: {:?}, image_id: {:?}, seal: {:?} }}",
crate::hex!(receipt.journal.bytes.as_slice()),
crate::hex!(image_id),
crate::hex!(seal.as_slice())
),
}
}
}
pub async fn prove(
circuit: Vec<u8>,
zkvm: Zkvm,
task: Task,
task_response: TaskResponse,
entrypoint: String,
) -> eyre::Result<Proof> {
match zkvm {
Zkvm::Sp1 => sp1::prove(circuit, task, task_response, entrypoint).await,
Zkvm::Risc0 => risc0::prove(circuit, task, task_response, entrypoint).await,
}
}
pub async fn verify_raw_proof(proof_bytes: Vec<u8>, vkey_bytes: Vec<u8>, proof_type: Zkvm) -> eyre::Result<bool> {
let result = match proof_type {
Zkvm::Sp1 => {
let vk = serde_json::from_slice::<SP1VerifyingKey>(&vkey_bytes)?;
let proof = serde_json::from_slice::<SP1ProofWithPublicValues>(&proof_bytes)?;
ProverClient::from_env()
.await
.verify(&proof, &vk, None)
.map_err(|e| eyre::eyre!("SP1 verification failed: {}", e))
}
Zkvm::Risc0 => {
let receipt = serde_json::from_slice::<Receipt>(&proof_bytes)?;
let image_id = serde_json::from_slice::<Digest>(&vkey_bytes)?;
receipt
.verify(image_id)
.map_err(|e| eyre::eyre!("Risc0 verification failed: {}", e))
}
};
Ok(result.is_ok())
}