Rust end-to-end
Use the Rust path when a service, test harness, or release pipeline can link the ProveKit crates and own artifact loading directly, instead of shelling out to provekit-cli.
Flow at a glance
Section titled “Flow at a glance”The Rust path mirrors the CLI:
- Generate
.pkpand.pkvvia the CLI (or the compiler APIs). - Load
.pkpintoprovekit_common::Prover. - Generate a
NoirProofwithprovekit_prover::Prove::prove_with_toml. - Persist the proof with
provekit_common::file::writewhen needed. - Load
.pkvintoprovekit_common::Verifier. - Verify with
provekit_verifier::Verify::verify.
Prepare artifacts
Section titled “Prepare artifacts”Start from the checked-in basic Noir package:
cd noir-examples/basicmkdir -p artifacts
cargo run --release --bin provekit-cli -- prepare . \ --pkp artifacts/basic.pkp \ --pkv artifacts/basic.pkvThe Rust program below reads these .pkp and .pkv files.
Cargo dependencies
Section titled “Cargo dependencies”The crates are published on crates.io. Pin exact versions; the current release is 1.0.0 (see GitHub Releases for newer tags).
[dependencies]provekit-common = "1.0.0"provekit-prover = "1.0.0"provekit-verifier = "1.0.0"Use path or Git dependencies only when you are deliberately testing an unpublished checkout.
Minimal program
Section titled “Minimal program”Run the program from the repository root so the example paths resolve to noir-examples/basic/....
use std::{error::Error, path::Path};
use provekit_common::{ file::{read, write}, NoirProof, Prover, Verifier,};use provekit_prover::Prove;use provekit_verifier::Verify;
fn main() -> Result<(), Box<dyn Error>> { let prover_path = Path::new("noir-examples/basic/artifacts/basic.pkp"); let verifier_path = Path::new("noir-examples/basic/artifacts/basic.pkv"); let input_path = Path::new("noir-examples/basic/Prover.toml"); let proof_path = Path::new("noir-examples/basic/artifacts/proof.np");
let prover: Prover = read(prover_path)?; let proof = prover.prove_with_toml(input_path)?; write(&proof, proof_path)?;
let mut verifier: Verifier = read(verifier_path)?; verifier.verify(&proof)?;
// Optional: confirm the serialized proof round-trips through the same // file format used by the CLI. let persisted_proof: NoirProof = read(proof_path)?; let mut fresh_verifier: Verifier = read(verifier_path)?; fresh_verifier.verify(&persisted_proof)?;
Ok(())}Verifier lifecycle
Section titled “Verifier lifecycle”The sample above intentionally loads fresh_verifier for the round-trip check. A long-lived service should make that lifecycle explicit.
Production notes
Section titled “Production notes”- Use absolute, explicit artifact paths. Don’t depend on the process current directory in services.
- Treat
.pkp,.pkv, andproof.npas versioned deployment artifacts. - Validate public inputs with
show-inputsduring integration testing. - Add negative tests for mismatched
.pkv/ proof pairs. - Regenerate keys and proofs after any change to circuit, branch, lockfile, toolchain, or
prepare --hash. - Walk through the Production checklist before shipping a Rust prover or verifier service.