provekit-cli 1.0.0

ProveKit CLI for generating and verifying zero-knowledge proofs
use {
    super::{util::resolve_key_path, Command},
    anyhow::{Context, Result},
    argh::FromArgs,
    provekit_common::{
        file::{read, write},
        Prover,
    },
    provekit_prover::Prove,
    std::path::PathBuf,
    tracing::{info, instrument},
};
#[cfg(test)]
use {provekit_common::Verifier, provekit_verifier::Verify};

/// Prove a prepared Noir program.
#[derive(FromArgs, PartialEq, Eq, Debug)]
#[argh(subcommand, name = "prove")]
pub struct Args {
    /// path to the prover key (default: `<circuit>.pkp`)
    #[argh(option, long = "prover", short = 'p')]
    prover_path: Option<PathBuf>,

    /// path to the input values (default: ./Prover.toml)
    #[argh(option, long = "input", short = 'i')]
    input_path: Option<PathBuf>,

    /// path to store the proof file
    #[argh(
        option,
        long = "out",
        short = 'o',
        default = "PathBuf::from(\"./proof.np\")"
    )]
    proof_path: PathBuf,

    #[cfg(test)]
    /// path to the verifier key (default: `<circuit>.pkv`)
    #[argh(option, long = "verifier")]
    verifier_path: Option<PathBuf>,
}

impl Command for Args {
    #[instrument(skip_all)]
    fn run(&self) -> Result<()> {
        let prover_path = resolve_key_path(self.prover_path.as_deref(), "pkp")?;
        let input_path = self
            .input_path
            .clone()
            .unwrap_or_else(|| PathBuf::from("./Prover.toml"));

        let prover: Prover = read(&prover_path).context("while reading Provekit Prover")?;
        let (constraints, witnesses) = prover.size();
        info!(constraints, witnesses, "Read Noir proof scheme");

        let proof = prover
            .prove_with_toml(&input_path)
            .context("While proving Noir program statement")?;

        write(&proof, &self.proof_path).context("while writing proof")?;

        // Test-only round-trip: verify the proof we just wrote.
        #[cfg(test)]
        {
            let verifier_path = resolve_key_path(self.verifier_path.as_deref(), "pkv")?;
            let mut verifier: Verifier =
                read(&verifier_path).context("while reading Provekit Verifier")?;
            verifier
                .verify(&proof)
                .context("While verifying Noir proof")?;
        }

        Ok(())
    }
}