use crate::imp::core::{Bytes32, Bytes48, ExecutionProof, ProofResponse};
use crate::imp::prover::chain::ChainSource;
use crate::imp::prover::error::{ProverError, Result};
use crate::imp::prover::serving_inputs::ServingInputs;
pub trait Prover {
fn prove(
&self,
program_hash: Bytes32,
public_input: &[u8],
serving_inputs: &ServingInputs,
) -> Result<ExecutionProof>;
}
pub trait Verifier {
fn verify(
&self,
proof: &ExecutionProof,
expected_program_hash: Bytes32,
trusted_roots: &[Bytes32],
chain: &dyn ChainSource,
) -> Result<()>;
fn verify_response(
&self,
response: &ProofResponse,
expected_program_hash: Bytes32,
trusted_roots: &[Bytes32],
expected_output_bytes: &[u8],
chain: &dyn ChainSource,
) -> Result<()> {
if !trusted_roots.contains(&response.roothash) {
return Err(ProverError::UntrustedRoot(response.roothash.to_hex()));
}
let bound = bound_public_output(&response.roothash, expected_output_bytes);
if bound != response.proof.public_output {
return Err(ProverError::RootBindingMismatch {
bound: bound.to_hex(),
asserted: response.roothash.to_hex(),
});
}
self.verify(&response.proof, expected_program_hash, trusted_roots, chain)
}
fn verify_node_attested(
&self,
proof: &ExecutionProof,
expected_program_hash: Bytes32,
trusted_roots: &[Bytes32],
trusted_node_keys: &[Bytes48],
chain: &dyn ChainSource,
) -> Result<()> {
if !trusted_node_keys.contains(&proof.node_pubkey) {
return Err(ProverError::NodeKeyNotAttested(proof.node_pubkey.to_hex()));
}
self.verify(proof, expected_program_hash, trusted_roots, chain)
}
fn verify_with_nonce(
&self,
proof: &ExecutionProof,
expected_nonce: &[u8; 32],
expected_program_hash: Bytes32,
trusted_roots: &[Bytes32],
chain: &dyn ChainSource,
) -> Result<()> {
let (nonce, _block) =
crate::imp::prover::commitment::parse_public_input(&proof.public_input)?;
if &nonce != expected_nonce {
return Err(ProverError::NonceMismatch);
}
self.verify(proof, expected_program_hash, trusted_roots, chain)
}
}
pub fn bound_public_output(roothash: &Bytes32, output_bytes: &[u8]) -> Bytes32 {
let mut preimage = Vec::with_capacity(32 + output_bytes.len());
preimage.extend_from_slice(&roothash.0);
preimage.extend_from_slice(output_bytes);
crate::imp::crypto::sha256(&preimage)
}