zkpo 0.1.7

Zero knowledge program operations
Documentation
//! An interface for zk programs and arguments of execution.
//!
//! With zk you compile (arithmetize) a program to a system
//! of equations. Then you prove/argue knowledge of a solution
//! to the system of equations, which implies execution.
use anyhow::Result;

/// Exports all zkpo types, including concrete implementations
/// behind features.
pub mod prelude;

#[cfg(feature = "risc0")]
pub mod risc0;
#[cfg(feature = "sp1")]
pub mod sp1;

/// A structure that can execute `&dyn ZKProgram`'s
/// and verify arguments of execution (`&dyn ZKExe`).
///
/// Agents may verify many different programs using
/// many different proving systems.
pub trait ZKAgent {
    /// Generate an argument of execution. Inputs are expected
    /// to be serialized arbitrarily outside of this implementation.
    fn execute(&self, input: &[u8], program: &dyn ZKProgram) -> Result<Box<dyn ZKExe>>;
    /// Verify an argument of execution and return the public output data.
    ///
    /// Each implementation MUST verify the `program_id` as a part
    /// of the cryptographic argument of knowledge.
    fn verify(&self, proof: &dyn ZKExe) -> Result<Vec<u8>>;
}

/// A program that can be executed in zk by an agent.
/// The agent yields an argument of execution, which
/// can be verified.
pub trait ZKProgram {
    /// Unique (per agent) identifier for the program.
    ///
    /// Although this is available, prefer statically
    /// analyzable program identification.
    fn id(&self) -> &[u8; 32];
    /// Optional human readable name.
    fn name(&self) -> Option<&str>;
    /// Executable linkable format data of the program.
    /// Arbitrary, defined by each agent implementation.
    fn elf(&self) -> &[u8];
    /// Statically stable agent implementation
    /// compatible with this program.
    fn agent(&self) -> &dyn ZKAgent;
    /// Use an agent to execute the program in zk and
    /// generate an argument of execution.
    fn execute(&self, input: &[u8], agent: Option<&dyn ZKAgent>) -> Result<Box<dyn ZKExe>>
    where
        Self: Sized,
    {
        let agent = agent.unwrap_or(self.agent());
        agent.execute(input, self)
    }
}

/// An arithmetization agnostic argument of execution.
pub trait ZKExe {
    /// Opaque agent specific data necessary for verification.
    fn cipher_bytes(&self) -> &[u8];
    /// 32 byte program id that Self argues was executed.
    fn program_id(&self) -> &[u8; 32];
    /// Optional structure capable of creating and verifying Self.
    fn agent(&self) -> &dyn ZKAgent;
    /// Optional reference to program. For statically safe
    /// programs over the wire.
    fn program(&self) -> Option<&dyn ZKProgram>;

    /// Attempt to determine a program name, or return a placeholder.
    fn program_name(&self) -> &str {
        self.program()
            .map(|p| p.name())
            .flatten()
            .unwrap_or("unnamed program")
    }
}