use alloc::boxed::Box;
use sp1_hypercube::{MachineVerifierConfigError, SP1InnerPcs, VcsError};
use sp1_primitives::{SP1Field, SP1GlobalContext};
use strum::IntoDiscriminant;
use thiserror::Error;
mod config;
mod internal;
use crate::{SP1Proof, SP1ProofMode};
pub use self::internal::SP1CompressedVerifier;
pub use config::{RECURSION_LOG_STACKING_HEIGHT, RECURSION_MAX_LOG_ROW_COUNT};
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum CompressedError {
#[error("invalid proof type")]
InvalidProofType(SP1ProofMode),
#[error("failed to deserialize proof: {0}")]
DeserializeProof(Box<bincode::ErrorKind>),
#[error("failed to deserialize vkey hash: {0}")]
DeserializeVkeyHash(Box<bincode::ErrorKind>),
#[error("failed to verify proof: {0}")]
ProofRejected(#[from] MachineVerifierConfigError<SP1GlobalContext, SP1InnerPcs>),
#[error("given public values do not match the commitment in the proof")]
PublicValuesMismatch,
#[error("incorrect vkey")]
InvalidVkey(VcsError),
}
#[derive(Debug)]
pub struct SP1CompressedVerifierRaw;
impl SP1CompressedVerifierRaw {
pub fn verify_with_public_values(
proof: &[u8],
sp1_public_inputs: &[u8],
sp1_vkey_hash: &[u8],
) -> Result<(), CompressedError> {
let recursion_proof: SP1Proof =
bincode::deserialize(proof).map_err(CompressedError::DeserializeProof)?;
let vkey_hash: [SP1Field; 8] =
bincode::deserialize(sp1_vkey_hash).map_err(CompressedError::DeserializeVkeyHash)?;
let verifier = SP1CompressedVerifier::new();
if let SP1Proof::Compressed(proof) = recursion_proof {
verifier.verify_compressed_with_public_values(&proof, sp1_public_inputs, &vkey_hash)?;
} else {
return Err(CompressedError::InvalidProofType(recursion_proof.discriminant()));
}
Ok(())
}
pub fn verify(proof: &[u8], sp1_vkey_hash: &[u8]) -> Result<(), CompressedError> {
let recursion_proof: SP1Proof =
bincode::deserialize(proof).map_err(CompressedError::DeserializeProof)?;
let vkey_hash: [SP1Field; 8] =
bincode::deserialize(sp1_vkey_hash).map_err(CompressedError::DeserializeVkeyHash)?;
let verifier = SP1CompressedVerifier::new();
if let SP1Proof::Compressed(proof) = recursion_proof {
verifier.verify_compressed(&proof, &vkey_hash)?;
} else {
return Err(CompressedError::InvalidProofType(recursion_proof.discriminant()));
}
Ok(())
}
}