Hello World using powdr as a library
Besides the CLI, powdr can also be used as a Rust library. The powdr crate exposes internal crates and data structures needed to compile code, generate witnesses, and compute proofs.
Add powdr
to your crate's dependencies:
[dependencies]
powdr = { git = "https://github.com/powdr-labs/powdr", branch = "main" }
The following Rust code has the same workflow as our previous "Hello World" example. The full project can be found here, and as an example in the powdr crate. To run the example in the powdr repository, run:
cargo run --example powdr_crate_usage
You can also enable logs to know what is happening internally:
RUST_LOG=info cargo run --example powdr_crate_usage
use powdr_test::halo2_pipeline;
fn main() {
env_logger::init();
halo2_pipeline(
"test_data/asm/book/hello_world.asm",
vec![0.into()],
vec![],
8,
);
}
use powdr::backend::BackendType;
use powdr::number::buffered_write_file;
use powdr::Bn254Field;
use powdr::Pipeline;
use std::path::Path;
pub fn halo2_pipeline(
pil: &str,
prover_inputs: Vec<Bn254Field>,
publics: Vec<Bn254Field>,
setup_size: u64,
) {
// Straightforward case
let _proof = Pipeline::<Bn254Field>::default()
.from_file(pil.into())
.with_prover_inputs(prover_inputs.clone())
.with_backend(BackendType::Halo2, None)
.compute_proof()
.unwrap();
// Step-by-step case
// First we create the universal setup of size 8
buffered_write_file(Path::new("params.bin"), |writer| {
BackendType::Halo2
.factory::<Bn254Field>()
.generate_setup(setup_size, writer)
.unwrap()
})
.unwrap();
// Configure a pipeline
let mut pipeline = Pipeline::<Bn254Field>::default()
.from_file(pil.into())
.with_prover_inputs(prover_inputs)
.with_backend(BackendType::Halo2, None)
.with_setup_file(Some("params.bin".into()));
// Create the verification key
buffered_write_file(Path::new("vkey.bin"), |w| {
pipeline.export_verification_key(w).unwrap()
})
.unwrap();
// Add the verification key to a fresh pipeline and create a proof
let mut pipeline_fresh = pipeline.clone().with_vkey_file(Some("vkey.bin".into()));
let proof = pipeline_fresh.compute_proof().unwrap();
// Create yet another fresh pipeline only for proof verification
let mut pipeline = pipeline
.with_backend(BackendType::Halo2, None)
.with_setup_file(Some("params.bin".into()))
.with_vkey_file(Some("vkey.bin".into()));
// Verify a proof created by a different Pipeline
pipeline.verify(proof, &[publics]).unwrap();
}