Skip to content

Commit

Permalink
chore: pfsys error bubbling (partial)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-camuto committed Jan 11, 2023
1 parent 0af1afb commit 4539496
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 85 deletions.
2 changes: 1 addition & 1 deletion src/bin/ezkl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub fn main() -> Result<(), Box<dyn Error>> {
let args = Cli::create();
colog::init();
banner();
info!("{}", &args.as_json());
info!("{}", &args.as_json()?);
run(args)
}

Expand Down
10 changes: 5 additions & 5 deletions src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//use crate::onnx::OnnxModel;
use crate::abort;
use clap::{Parser, Subcommand, ValueEnum};
use log::{error, info};
use log::info;
use serde::{Deserialize, Serialize};
use std::env;
use std::error::Error;
use std::io::{stdin, stdout, Write};
use std::path::PathBuf;

Expand Down Expand Up @@ -44,14 +44,14 @@ pub struct Cli {

impl Cli {
/// Export the ezkl configuration as json
pub fn as_json(&self) -> String {
pub fn as_json(&self) -> Result<String, Box<dyn Error>> {
let serialized = match serde_json::to_string(&self) {
Ok(s) => s,
Err(e) => {
abort!("failed to convert Cli to string {:?}", e);
return Err(Box::new(e));
}
};
serialized
Ok(serialized)
}
/// Parse an ezkl configuration from a json
pub fn from_json(arg_json: &str) -> Result<Self, serde_json::Error> {
Expand Down
25 changes: 12 additions & 13 deletions src/execute.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::abort;
use crate::commands::{Cli, Commands, ProofSystem};
use crate::fieldutils::i32_to_felt;
use crate::graph::Model;
Expand Down Expand Up @@ -34,7 +33,7 @@ use halo2curves::bn256::G1Affine;
use halo2curves::bn256::{Bn256, Fr};
use halo2curves::pasta::vesta;
use halo2curves::pasta::Fp;
use log::{error, info, trace};
use log::{info, trace};
#[cfg(feature = "evm")]
use plonk_verifier::system::halo2::transcript::evm::EvmTranscript;
use std::error::Error;
Expand All @@ -50,7 +49,7 @@ pub fn run(args: Cli) -> Result<(), Box<dyn Error>> {
println!("{}", Table::new(om.nodes.flatten()));
}
Commands::Mock { ref data, model: _ } => {
let data = prepare_data(data.to_string());
let data = prepare_data(data.to_string())?;
let (circuit, public_inputs) = prepare_circuit_and_public_input(&data, &args)?;
info!("Mock proof");
let pi: Vec<Vec<Fp>> = public_inputs
Expand All @@ -61,7 +60,7 @@ pub fn run(args: Cli) -> Result<(), Box<dyn Error>> {
let prover = match MockProver::run(args.logrows, &circuit, pi) {
Ok(p) => p,
Err(e) => {
abort!("mock prover failed to run {:?}", e);
return Err(Box::new(e));
}
};
match prover.verify() {
Expand All @@ -84,7 +83,7 @@ pub fn run(args: Cli) -> Result<(), Box<dyn Error>> {
} => {
// A direct proof

let data = prepare_data(data.to_string());
let data = prepare_data(data.to_string())?;

match pfsys {
ProofSystem::IPA => {
Expand Down Expand Up @@ -179,7 +178,7 @@ pub fn run(args: Cli) -> Result<(), Box<dyn Error>> {
ref params_path,
pfsys,
} => {
let data = prepare_data(data.to_string());
let data = prepare_data(data.to_string())?;

match pfsys {
ProofSystem::IPA => {
Expand All @@ -197,7 +196,7 @@ pub fn run(args: Cli) -> Result<(), Box<dyn Error>> {
&pk,
);

proof.save(proof_path);
proof.save(proof_path)?;
save_params::<IPACommitmentScheme<_>>(params_path, &params);
save_vk::<IPACommitmentScheme<_>>(vk_path, pk.get_vk());
}
Expand All @@ -216,7 +215,7 @@ pub fn run(args: Cli) -> Result<(), Box<dyn Error>> {
&circuit, &public_inputs, &params, &pk
);

proof.save(proof_path);
proof.save(proof_path)?;
save_params::<KZGCommitmentScheme<Bn256>>(params_path, &params);
save_vk::<KZGCommitmentScheme<Bn256>>(vk_path, pk.get_vk());
}
Expand All @@ -229,22 +228,22 @@ pub fn run(args: Cli) -> Result<(), Box<dyn Error>> {
params_path,
pfsys,
} => {
let proof = Proof::load(&proof_path);
let proof = Proof::load(&proof_path)?;
match pfsys {
ProofSystem::IPA => {
let params: ParamsIPA<vesta::Affine> =
load_params::<IPACommitmentScheme<_>>(params_path);
load_params::<IPACommitmentScheme<_>>(params_path)?;
let strategy = IPASingleStrategy::new(&params);
let vk = load_vk::<IPACommitmentScheme<_>, Fp>(vk_path, &params);
let vk = load_vk::<IPACommitmentScheme<_>, Fp>(vk_path, &params)?;
let result = verify_proof_model(proof, &params, &vk, strategy);
info!("verified: {}", result);
assert!(result);
}
ProofSystem::KZG => {
let params: ParamsKZG<Bn256> =
load_params::<KZGCommitmentScheme<Bn256>>(params_path);
load_params::<KZGCommitmentScheme<Bn256>>(params_path)?;
let strategy = KZGSingleStrategy::new(&params);
let vk = load_vk::<KZGCommitmentScheme<Bn256>, Fr>(vk_path, &params);
let vk = load_vk::<KZGCommitmentScheme<Bn256>, Fr>(vk_path, &params)?;
let result = verify_proof_model::<_, VerifierGWC<'_, Bn256>, _, _>(
proof, &params, &vk, strategy,
);
Expand Down
123 changes: 57 additions & 66 deletions src/pfsys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#[cfg(feature = "evm")]
pub mod aggregation;

use crate::abort;
use crate::commands::{data_path, Cli};
use crate::fieldutils::i32_to_felt;
use crate::graph::{utilities::vector_to_quantized, Model, ModelCircuit};
Expand Down Expand Up @@ -50,34 +49,32 @@ pub struct Proof {

impl Proof {
/// Saves the Proof to a specified `proof_path`.
pub fn save(&self, proof_path: &PathBuf) {
pub fn save(&self, proof_path: &PathBuf) -> Result<(), Box<dyn Error>> {
let serialized = match serde_json::to_string(&self) {
Ok(s) => s,
Err(e) => {
abort!("failed to convert proof json to string {:?}", e);
}
Err(e) => return Err(Box::new(e)),
};

let mut file = std::fs::File::create(proof_path).expect("create failed");
file.write_all(serialized.as_bytes()).expect("write failed");
Ok(())
}

/// Load a json serialized proof from the provided path.
pub fn load(proof_path: &PathBuf) -> Self {
pub fn load(proof_path: &PathBuf) -> Result<Self, Box<dyn Error>> {
let mut file = match File::open(proof_path) {
Ok(f) => f,
Err(e) => {
abort!("failed to open proof file {:?}", e);
}
Err(e) => return Err(Box::new(e)),
};
let mut data = String::new();
match file.read_to_string(&mut data) {
Ok(_) => {}
Err(e) => {
abort!("failed to read file {:?}", e);
}
Err(e) => return Err(Box::new(e)),
};
serde_json::from_str(&data).expect("JSON was not well-formatted")
match serde_json::from_str(&data) {
Ok(a) => Ok(a),
Err(e) => Err(Box::new(e)),
}
}
}

Expand Down Expand Up @@ -130,43 +127,28 @@ pub fn prepare_circuit_and_public_input<F: FieldExt>(
) -> Result<(ModelCircuit<F>, Vec<Tensor<i32>>), Box<dyn Error>> {
let model = Model::from_ezkl_conf(args.clone())?;
let out_scales = model.get_output_scales();
let circuit = prepare_circuit(data, args);
let circuit = prepare_circuit(data, args)?;

// quantize the supplied data using the provided scale.
// the ordering here is important, we want the inputs to come before the outputs
// as they are configured in that order as Column<Instances>
let mut public_inputs = vec![];
if model.visibility.input.is_public() {
let mut res = data
.input_data
.iter()
.enumerate()
.map(|(idx, v)| {
match vector_to_quantized(v, &Vec::from([v.len()]), 0.0, out_scales[idx]) {
Ok(q) => q,
Err(e) => {
abort!("failed to quantize vector {:?}", e);
}
}
})
.collect();
let mut res: Vec<Tensor<i32>> = vec![];
for (idx, v) in data.input_data.iter().enumerate() {
let t = vector_to_quantized(v, &Vec::from([v.len()]), 0.0, out_scales[idx])?;
res.push(t);
}
public_inputs.append(&mut res);
}
if model.visibility.output.is_public() {
let mut res = data
.output_data
.iter()
.enumerate()
.map(|(idx, v)| {
match vector_to_quantized(v, &Vec::from([v.len()]), 0.0, out_scales[idx]) {
Ok(q) => q,
Err(e) => {
abort!("failed to quantize vector {:?}", e);
}
}
})
.collect();
public_inputs.append(&mut res);
let mut public_outputs = vec![];
if model.visibility.input.is_public() {
let mut res: Vec<Tensor<i32>> = vec![];
for (idx, v) in data.output_data.iter().enumerate() {
let t = vector_to_quantized(v, &Vec::from([v.len()]), 0.0, out_scales[idx])?;
res.push(t);
}
public_outputs.append(&mut res);
}
info!(
"public inputs lengths: {:?}",
Expand All @@ -180,44 +162,41 @@ pub fn prepare_circuit_and_public_input<F: FieldExt>(
}

/// Initialize the model circuit
pub fn prepare_circuit<F: FieldExt>(data: &ModelInput, args: &Cli) -> ModelCircuit<F> {
pub fn prepare_circuit<F: FieldExt>(
data: &ModelInput,
args: &Cli,
) -> Result<ModelCircuit<F>, Box<dyn Error>> {
// quantize the supplied data using the provided scale.
let inputs = data
.input_data
.iter()
.zip(data.input_shapes.clone())
.map(|(i, s)| match vector_to_quantized(i, &s, 0.0, args.scale) {
Ok(q) => q,
Err(e) => {
abort!("failed to quantize vector {:?}", e);
}
})
.collect();
let mut inputs: Vec<Tensor<i32>> = vec![];
for (idx, s) in data.input_data.iter().zip(data.input_shapes.clone()) {
let t = vector_to_quantized(idx, &s, 0.0, args.scale)?;
inputs.push(t);
}

ModelCircuit::<F> {
Ok(ModelCircuit::<F> {
inputs,
_marker: PhantomData,
}
})
}

/// Deserializes the required inputs to a model at path `datapath` to a [ModelInput] struct.
pub fn prepare_data(datapath: String) -> ModelInput {
pub fn prepare_data(datapath: String) -> Result<ModelInput, Box<dyn Error>> {
let mut file = match File::open(data_path(datapath)) {
Ok(t) => t,
Err(e) => {
abort!("failed to open data file {:?}", e);
return Err(Box::new(e));
}
};
let mut data = String::new();
match file.read_to_string(&mut data) {
Ok(_) => {}
Err(e) => {
abort!("failed to read file {:?}", e);
return Err(Box::new(e));
}
};
let data: ModelInput = serde_json::from_str(&data).expect("JSON was not well-formatted");

data
Ok(data)
}

/// Creates a [VerifyingKey] and [ProvingKey] for a [ModelCircuit] (`circuit`) with specific [CommitmentScheme] parameters (`params`).
Expand Down Expand Up @@ -346,32 +325,44 @@ where
pub fn load_vk<Scheme: CommitmentScheme, F: FieldExt + TensorType>(
path: PathBuf,
params: &'_ Scheme::ParamsVerifier,
) -> VerifyingKey<Scheme::Curve>
) -> Result<VerifyingKey<Scheme::Curve>, Box<dyn Error>>
where
ModelCircuit<F>: Circuit<Scheme::Scalar>,
{
info!("loading verification key from {:?}", path);
let f = match File::open(path) {
Ok(f) => f,
Err(e) => {
abort!("failed to load vk {}", e);
return Err(Box::new(e));
}
};
let mut reader = BufReader::new(f);
VerifyingKey::<Scheme::Curve>::read::<_, ModelCircuit<F>>(&mut reader, params).unwrap()
match VerifyingKey::<Scheme::Curve>::read::<_, ModelCircuit<F>>(&mut reader, params) {
Ok(f) => Ok(f),
Err(e) => {
return Err(Box::new(e));
}
}
}

/// Loads the [CommitmentScheme::ParamsVerifier] at `path`.
pub fn load_params<Scheme: CommitmentScheme>(path: PathBuf) -> Scheme::ParamsVerifier {
pub fn load_params<Scheme: CommitmentScheme>(
path: PathBuf,
) -> Result<Scheme::ParamsVerifier, Box<dyn Error>> {
info!("loading params from {:?}", path);
let f = match File::open(path) {
Ok(f) => f,
Err(e) => {
abort!("failed to load params {}", e);
return Err(Box::new(e));
}
};
let mut reader = BufReader::new(f);
Params::<'_, Scheme::Curve>::read(&mut reader).unwrap()
match Params::<'_, Scheme::Curve>::read(&mut reader) {
Ok(f) => Ok(f),
Err(e) => {
return Err(Box::new(e));
}
}
}

/// Saves a [VerifyingKey] to `path`.
Expand Down

0 comments on commit 4539496

Please sign in to comment.