From 658d8b4862a91eb1cbed3625b1f1208485cb6f9b Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 12 Nov 2018 12:35:04 +0100 Subject: [PATCH] use instances, update cli to instanciate backend and move compile flags --- zokrates_cli/src/bin.rs | 275 ++++++++++++----------- zokrates_core/src/proof_system/mod.rs | 2 + zokrates_core/src/proof_system/pghr13.rs | 8 + 3 files changed, 157 insertions(+), 128 deletions(-) diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index bf7f075d..4bf8867e 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -35,6 +35,7 @@ fn main() { const WITNESS_DEFAULT_PATH: &str = "witness"; const VARIABLES_INFORMATION_KEY_DEFAULT_PATH: &str = "variables.inf"; const JSON_PROOF_PATH: &str = "proof.json"; + const DEFAULT_BACKEND: &str = "pghr13"; // cli specification using clap library let matches = App::new("ZoKrates") @@ -103,6 +104,15 @@ fn main() { .required(false) .default_value(VARIABLES_INFORMATION_KEY_DEFAULT_PATH) ) + .arg(Arg::with_name("backend") + .short("b") + .long("backend") + .help("Backend to use in the setup. Currently only PGHR13") + .value_name("FILE") + .takes_value(true) + .required(false) + .default_value(DEFAULT_BACKEND) + ) ) .subcommand(SubCommand::with_name("export-verifier") .about("Exports a verifier as Solidity smart contract.") @@ -384,67 +394,73 @@ fn main() { bw.flush().expect("Unable to flush buffer."); } ("setup", Some(sub_matches)) => { - println!("Performing setup..."); - - let path = Path::new(sub_matches.value_of("input").unwrap()); - let mut file = match File::open(&path) { - Ok(file) => file, - Err(why) => panic!("couldn't open {}: {}", path.display(), why), - }; - - let program_ast: FlatProg = match deserialize_from(&mut file, Infinite) { - Ok(x) => x, - Err(why) => { - println!("{:?}", why); - std::process::exit(1); - } - }; - - let main_flattened = program_ast - .functions - .iter() - .find(|x| x.id == "main") - .unwrap(); - - // print deserialized flattened program - println!("{}", main_flattened); - - // transform to R1CS - let (variables, public_variables_count, a, b, c) = r1cs_program(&program_ast); - - // write variables meta information to file - let var_inf_path = Path::new(sub_matches.value_of("meta-information").unwrap()); - let var_inf_file = match File::create(&var_inf_path) { - Ok(file) => file, - Err(why) => panic!("couldn't open {}: {}", var_inf_path.display(), why), - }; - let mut bw = BufWriter::new(var_inf_file); - - write!( - &mut bw, - "Private inputs offset:\n{}\n", - public_variables_count - ) - .expect("Unable to write data to file."); - write!(&mut bw, "R1CS variable order:\n").expect("Unable to write data to file."); - - for var in &variables { - write!(&mut bw, "{} ", var).expect("Unable to write data to file."); - } - write!(&mut bw, "\n").expect("Unable to write data to file."); - bw.flush().expect("Unable to flush buffer."); - - // get paths for proving and verification keys - let pk_path = sub_matches.value_of("proving-key-path").unwrap(); - let vk_path = sub_matches.value_of("verification-key-path").unwrap(); - - // run setup phase #[cfg(feature = "libsnark")] { + println!("Performing setup..."); + + let backend = match sub_matches.value_of("backend").unwrap().to_lowercase().as_ref() { + "pghr13" => PGHR13::new(), + s => panic!("Backend \"{}\" not supported", s), + }; + + let path = Path::new(sub_matches.value_of("input").unwrap()); + let mut file = match File::open(&path) { + Ok(file) => file, + Err(why) => panic!("couldn't open {}: {}", path.display(), why), + }; + + let program_ast: FlatProg = match deserialize_from(&mut file, Infinite) + { + Ok(x) => x, + Err(why) => { + println!("{:?}", why); + std::process::exit(1); + } + }; + + let main_flattened = program_ast + .functions + .iter() + .find(|x| x.id == "main") + .unwrap(); + + // print deserialized flattened program + println!("{}", main_flattened); + + // transform to R1CS + let (variables, public_variables_count, a, b, c) = r1cs_program(&program_ast); + + // write variables meta information to file + let var_inf_path = Path::new(sub_matches.value_of("meta-information").unwrap()); + let var_inf_file = match File::create(&var_inf_path) { + Ok(file) => file, + Err(why) => panic!("couldn't open {}: {}", var_inf_path.display(), why), + }; + let mut bw = BufWriter::new(var_inf_file); + + write!( + &mut bw, + "Private inputs offset:\n{}\n", + public_variables_count + ) + .expect("Unable to write data to file."); + write!(&mut bw, "R1CS variable order:\n").expect("Unable to write data to file."); + + for var in &variables { + write!(&mut bw, "{} ", var).expect("Unable to write data to file."); + } + write!(&mut bw, "\n").expect("Unable to write data to file."); + bw.flush().expect("Unable to flush buffer."); + + // get paths for proving and verification keys + let pk_path = sub_matches.value_of("proving-key-path").unwrap(); + let vk_path = sub_matches.value_of("verification-key-path").unwrap(); + + // run setup phase // number of inputs in the zkSNARK sense, i.e., input variables + output variables println!( "setup successful: {:?}", - PGHR13::setup( + backend.setup( variables, a, b, @@ -541,82 +557,85 @@ fn main() { println!("Finished exporting verifier."); } ("generate-proof", Some(sub_matches)) => { - println!("Generating proof..."); - - // deserialize witness - let witness_path = Path::new(sub_matches.value_of("witness").unwrap()); - let witness_file = match File::open(&witness_path) { - Ok(file) => file, - Err(why) => panic!("couldn't open {}: {}", witness_path.display(), why), - }; - - let reader = BufReader::new(witness_file); - let mut lines = reader.lines(); - let mut witness_map = HashMap::new(); - - loop { - match lines.next() { - Some(Ok(ref x)) => { - let pairs: Vec<&str> = x.split_whitespace().collect(); - witness_map.insert( - pairs[0].to_string(), - FieldPrime::from_dec_string(pairs[1].to_string()), - ); - } - None => break, - Some(Err(err)) => panic!("Error reading witness: {}", err), - } - } - - // determine variable order - let var_inf_path = Path::new(sub_matches.value_of("meta-information").unwrap()); - let var_inf_file = match File::open(&var_inf_path) { - Ok(file) => file, - Err(why) => panic!("couldn't open {}: {}", var_inf_path.display(), why), - }; - let var_reader = BufReader::new(var_inf_file); - let mut var_lines = var_reader.lines(); - - // get private inputs offset - let private_inputs_offset; - if let Some(Ok(ref o)) = var_lines.nth(1) { - // consumes first 2 lines - private_inputs_offset = o.parse().expect("Failed parsing private inputs offset"); - } else { - panic!("Error reading private inputs offset"); - } - - // get variables vector - let mut variables: Vec = Vec::new(); - if let Some(Ok(ref v)) = var_lines.nth(1) { - let iter = v.split_whitespace(); - for i in iter { - variables.push(i.to_string()); - } - } else { - panic!("Error reading variables."); - } - - println!("Using Witness: {:?}", witness_map); - - let witness: Vec<_> = variables.iter().map(|x| witness_map[x].clone()).collect(); - - // split witness into public and private inputs at offset - let mut public_inputs: Vec<_> = witness.clone(); - let private_inputs: Vec<_> = public_inputs.split_off(private_inputs_offset); - - println!("Public inputs: {:?}", public_inputs); - println!("Private inputs: {:?}", private_inputs); - - let pk_path = sub_matches.value_of("provingkey").unwrap(); - let proof_path = sub_matches.value_of("proofpath").unwrap(); - - // run libsnark #[cfg(feature = "libsnark")] { + println!("Generating proof..."); + + let backend = PGHR13::new(); + + // deserialize witness + let witness_path = Path::new(sub_matches.value_of("witness").unwrap()); + let witness_file = match File::open(&witness_path) { + Ok(file) => file, + Err(why) => panic!("couldn't open {}: {}", witness_path.display(), why), + }; + + let reader = BufReader::new(witness_file); + let mut lines = reader.lines(); + let mut witness_map = HashMap::new(); + + loop { + match lines.next() { + Some(Ok(ref x)) => { + let pairs: Vec<&str> = x.split_whitespace().collect(); + witness_map.insert( + pairs[0].to_string(), + FieldPrime::from_dec_string(pairs[1].to_string()), + ); + } + None => break, + Some(Err(err)) => panic!("Error reading witness: {}", err), + } + } + + // determine variable order + let var_inf_path = Path::new(sub_matches.value_of("meta-information").unwrap()); + let var_inf_file = match File::open(&var_inf_path) { + Ok(file) => file, + Err(why) => panic!("couldn't open {}: {}", var_inf_path.display(), why), + }; + let var_reader = BufReader::new(var_inf_file); + let mut var_lines = var_reader.lines(); + + // get private inputs offset + let private_inputs_offset; + if let Some(Ok(ref o)) = var_lines.nth(1) { + // consumes first 2 lines + private_inputs_offset = + o.parse().expect("Failed parsing private inputs offset"); + } else { + panic!("Error reading private inputs offset"); + } + + // get variables vector + let mut variables: Vec = Vec::new(); + if let Some(Ok(ref v)) = var_lines.nth(1) { + let iter = v.split_whitespace(); + for i in iter { + variables.push(i.to_string()); + } + } else { + panic!("Error reading variables."); + } + + println!("Using Witness: {:?}", witness_map); + + let witness: Vec<_> = variables.iter().map(|x| witness_map[x].clone()).collect(); + + // split witness into public and private inputs at offset + let mut public_inputs: Vec<_> = witness.clone(); + let private_inputs: Vec<_> = public_inputs.split_off(private_inputs_offset); + + println!("Public inputs: {:?}", public_inputs); + println!("Private inputs: {:?}", private_inputs); + + let pk_path = sub_matches.value_of("provingkey").unwrap(); + let proof_path = sub_matches.value_of("proofpath").unwrap(); + + // run libsnark println!( "generate-proof successful: {:?}", - PGHR13::generate_proof(pk_path, proof_path, public_inputs, private_inputs) + backend.generate_proof(pk_path, proof_path, public_inputs, private_inputs) ); } } diff --git a/zokrates_core/src/proof_system/mod.rs b/zokrates_core/src/proof_system/mod.rs index d2365872..d0ea033f 100644 --- a/zokrates_core/src/proof_system/mod.rs +++ b/zokrates_core/src/proof_system/mod.rs @@ -8,6 +8,7 @@ use flat_absy::flat_variable::FlatVariable; pub trait ProofSystem { fn setup( + &self, variables: Vec, a: Vec>, b: Vec>, @@ -18,6 +19,7 @@ pub trait ProofSystem { ) -> bool; fn generate_proof( + &self, pk_path: &str, proof_path: &str, public_inputs: Vec, diff --git a/zokrates_core/src/proof_system/pghr13.rs b/zokrates_core/src/proof_system/pghr13.rs index 3ff36147..d212ac6f 100644 --- a/zokrates_core/src/proof_system/pghr13.rs +++ b/zokrates_core/src/proof_system/pghr13.rs @@ -9,6 +9,12 @@ use field::Field; pub struct PGHR13 {} +impl PGHR13 { + pub fn new() -> Self { + PGHR13 {} + } +} + extern "C" { fn _pghr13_setup( A: *const uint8_t, @@ -36,6 +42,7 @@ extern "C" { impl ProofSystem for PGHR13 { fn setup( + &self, variables: Vec, a: Vec>, b: Vec>, @@ -76,6 +83,7 @@ impl ProofSystem for PGHR13 { } fn generate_proof( + &self, pk_path: &str, proof_path: &str, public_inputs: Vec,