From aab2ad18448cf2ebed757d617dba7de85b95d776 Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Mon, 20 Feb 2023 23:35:15 +0000 Subject: [PATCH 1/3] chore: move IO logic into separate module --- crates/nargo/src/cli/check_cmd.rs | 3 +- crates/nargo/src/cli/compile_cmd.rs | 49 +------- crates/nargo/src/cli/contract_cmd.rs | 3 +- crates/nargo/src/cli/execute_cmd.rs | 23 +--- crates/nargo/src/cli/fs/acir.rs | 29 +++++ crates/nargo/src/cli/fs/inputs.rs | 75 ++++++++++++ crates/nargo/src/cli/fs/keys.rs | 75 ++++++++++++ crates/nargo/src/cli/fs/mod.rs | 47 ++++++++ crates/nargo/src/cli/fs/proof.rs | 19 +++ crates/nargo/src/cli/fs/witness.rs | 23 ++++ crates/nargo/src/cli/mod.rs | 167 +-------------------------- crates/nargo/src/cli/new_cmd.rs | 3 +- crates/nargo/src/cli/prove_cmd.rs | 24 +--- crates/nargo/src/cli/verify_cmd.rs | 6 +- 14 files changed, 292 insertions(+), 254 deletions(-) create mode 100644 crates/nargo/src/cli/fs/acir.rs create mode 100644 crates/nargo/src/cli/fs/inputs.rs create mode 100644 crates/nargo/src/cli/fs/keys.rs create mode 100644 crates/nargo/src/cli/fs/mod.rs create mode 100644 crates/nargo/src/cli/fs/proof.rs create mode 100644 crates/nargo/src/cli/fs/witness.rs diff --git a/crates/nargo/src/cli/check_cmd.rs b/crates/nargo/src/cli/check_cmd.rs index 75c4b344c82..fd37a841952 100644 --- a/crates/nargo/src/cli/check_cmd.rs +++ b/crates/nargo/src/cli/check_cmd.rs @@ -8,7 +8,8 @@ use std::{ path::{Path, PathBuf}, }; -use super::{add_std_lib, write_to_file, NargoConfig}; +use super::fs::write_to_file; +use super::{add_std_lib, NargoConfig}; use crate::constants::{PROVER_INPUT_FILE, VERIFIER_INPUT_FILE}; /// Checks the constraint system for errors diff --git a/crates/nargo/src/cli/compile_cmd.rs b/crates/nargo/src/cli/compile_cmd.rs index 81e52b3a2fb..70b9d22f73b 100644 --- a/crates/nargo/src/cli/compile_cmd.rs +++ b/crates/nargo/src/cli/compile_cmd.rs @@ -1,16 +1,13 @@ +use acvm::acir::circuit::Circuit; use acvm::ProofSystemCompiler; -use acvm::{acir::circuit::Circuit, hash_constraint_system}; use std::path::{Path, PathBuf}; use clap::Args; -use crate::{ - constants::{ACIR_EXT, PK_EXT, TARGET_DIR, VK_EXT}, - errors::CliError, - resolver::Resolver, -}; +use crate::{constants::TARGET_DIR, errors::CliError, resolver::Resolver}; -use super::{add_std_lib, create_named_dir, write_to_file, NargoConfig}; +use super::fs::{acir::save_acir_to_dir, keys::save_key_to_dir}; +use super::{add_std_lib, NargoConfig}; /// Compile the program and its secret execution trace into ACIR format #[derive(Debug, Clone, Args)] @@ -81,41 +78,3 @@ fn preprocess_with_path>( Ok((pk_path, vk_path)) } - -fn save_acir_to_dir>( - circuit: &Circuit, - circuit_name: &str, - circuit_dir: P, -) -> PathBuf { - let mut circuit_path = create_named_dir(circuit_dir.as_ref(), "target"); - circuit_path.push(circuit_name); - - let mut serialized = Vec::new(); - circuit.write(&mut serialized).expect("could not serialize circuit"); - - circuit_path.set_extension(ACIR_EXT); - write_to_file(serialized.as_slice(), &circuit_path); - - // Save a checksum of the circuit to compare against during proving and verification - let acir_hash = hash_constraint_system(circuit); - circuit_path.set_extension(ACIR_EXT.to_owned() + ".sha256"); - write_to_file(hex::encode(acir_hash).as_bytes(), &circuit_path); - - circuit_path -} - -fn save_key_to_dir>( - key: Vec, - key_name: &str, - key_dir: P, - is_proving_key: bool, -) -> Result { - let mut key_path = create_named_dir(key_dir.as_ref(), key_name); - key_path.push(key_name); - let extension = if is_proving_key { PK_EXT } else { VK_EXT }; - key_path.set_extension(extension); - - write_to_file(hex::encode(key).as_bytes(), &key_path); - - Ok(key_path) -} diff --git a/crates/nargo/src/cli/contract_cmd.rs b/crates/nargo/src/cli/contract_cmd.rs index 3db62404b4f..1aa2711d679 100644 --- a/crates/nargo/src/cli/contract_cmd.rs +++ b/crates/nargo/src/cli/contract_cmd.rs @@ -1,4 +1,5 @@ -use super::{create_named_dir, write_to_file, NargoConfig}; +use super::fs::{create_named_dir, write_to_file}; +use super::NargoConfig; use crate::{cli::compile_cmd::compile_circuit, constants::CONTRACT_DIR, errors::CliError}; use acvm::SmartContract; use clap::Args; diff --git a/crates/nargo/src/cli/execute_cmd.rs b/crates/nargo/src/cli/execute_cmd.rs index 11e905990a3..761f376d8f8 100644 --- a/crates/nargo/src/cli/execute_cmd.rs +++ b/crates/nargo/src/cli/execute_cmd.rs @@ -1,17 +1,16 @@ -use std::path::{Path, PathBuf}; +use std::path::Path; -use acvm::acir::native_types::Witness; use acvm::PartialWitnessGenerator; use clap::Args; use noirc_abi::input_parser::{Format, InputValue}; use noirc_abi::{InputMap, WitnessMap}; use noirc_driver::CompiledProgram; +use super::fs::{inputs::read_inputs_from_file, witness::save_witness_to_dir}; use super::NargoConfig; -use super::{create_named_dir, read_inputs_from_file, write_to_file}; use crate::{ cli::compile_cmd::compile_circuit, - constants::{PROVER_INPUT_FILE, TARGET_DIR, WITNESS_EXT}, + constants::{PROVER_INPUT_FILE, TARGET_DIR}, errors::CliError, }; @@ -83,19 +82,3 @@ pub(crate) fn execute_program( Ok(solved_witness) } - -pub(crate) fn save_witness_to_dir>( - witness: WitnessMap, - witness_name: &str, - witness_dir: P, -) -> Result { - let mut witness_path = create_named_dir(witness_dir.as_ref(), "witness"); - witness_path.push(witness_name); - witness_path.set_extension(WITNESS_EXT); - - let buf = Witness::to_bytes(&witness); - - write_to_file(buf.as_slice(), &witness_path); - - Ok(witness_path) -} diff --git a/crates/nargo/src/cli/fs/acir.rs b/crates/nargo/src/cli/fs/acir.rs new file mode 100644 index 00000000000..988b97f05ae --- /dev/null +++ b/crates/nargo/src/cli/fs/acir.rs @@ -0,0 +1,29 @@ +use std::path::{Path, PathBuf}; + +use acvm::{acir::circuit::Circuit, hash_constraint_system}; + +use crate::constants::ACIR_EXT; + +use super::{create_named_dir, write_to_file}; + +pub(crate) fn save_acir_to_dir>( + circuit: &Circuit, + circuit_name: &str, + circuit_dir: P, +) -> PathBuf { + let mut circuit_path = create_named_dir(circuit_dir.as_ref(), "target"); + circuit_path.push(circuit_name); + + let mut serialized = Vec::new(); + circuit.write(&mut serialized).expect("could not serialize circuit"); + + circuit_path.set_extension(ACIR_EXT); + write_to_file(serialized.as_slice(), &circuit_path); + + // Save a checksum of the circuit to compare against during proving and verification + let acir_hash = hash_constraint_system(circuit); + circuit_path.set_extension(ACIR_EXT.to_owned() + ".sha256"); + write_to_file(hex::encode(acir_hash).as_bytes(), &circuit_path); + + circuit_path +} diff --git a/crates/nargo/src/cli/fs/inputs.rs b/crates/nargo/src/cli/fs/inputs.rs new file mode 100644 index 00000000000..5df9d9bc7eb --- /dev/null +++ b/crates/nargo/src/cli/fs/inputs.rs @@ -0,0 +1,75 @@ +use noirc_abi::{ + input_parser::{Format, InputValue}, + Abi, InputMap, MAIN_RETURN_NAME, +}; +use std::{collections::BTreeMap, path::Path}; + +use crate::errors::CliError; + +use super::write_to_file; + +/// Returns the circuit's parameters and its return value, if one exists. +/// # Examples +/// +/// ```ignore +/// let (input_map, return_value): (InputMap, Option) = +/// read_inputs_from_file(path, "Verifier", Format::Toml, &abi)?; +/// ``` +pub fn read_inputs_from_file>( + path: P, + file_name: &str, + format: Format, + abi: &Abi, +) -> Result<(InputMap, Option), CliError> { + if abi.is_empty() { + return Ok((BTreeMap::new(), None)); + } + + let file_path = { + let mut dir_path = path.as_ref().to_path_buf(); + dir_path.push(file_name); + dir_path.set_extension(format.ext()); + dir_path + }; + if !file_path.exists() { + return Err(CliError::MissingTomlFile(file_name.to_owned(), file_path)); + } + + let input_string = std::fs::read_to_string(file_path).unwrap(); + let mut input_map = format.parse(&input_string, abi)?; + let return_value = input_map.remove(MAIN_RETURN_NAME); + + Ok((input_map, return_value)) +} + +pub fn write_inputs_to_file>( + input_map: &InputMap, + return_value: &Option, + path: P, + file_name: &str, + format: Format, +) -> Result<(), CliError> { + let file_path = { + let mut dir_path = path.as_ref().to_path_buf(); + dir_path.push(file_name); + dir_path.set_extension(format.ext()); + dir_path + }; + + // We must insert the return value into the `InputMap` in order for it to be written to file. + let serialized_output = match return_value { + // Parameters and return values are kept separate except for when they're being written to file. + // As a result, we don't want to modify the original map and must clone it before insertion. + Some(return_value) => { + let mut input_map = input_map.clone(); + input_map.insert(MAIN_RETURN_NAME.to_owned(), return_value.clone()); + format.serialize(&input_map)? + } + // If no return value exists, then we can serialize the original map directly. + None => format.serialize(input_map)?, + }; + + write_to_file(serialized_output.as_bytes(), &file_path); + + Ok(()) +} diff --git a/crates/nargo/src/cli/fs/keys.rs b/crates/nargo/src/cli/fs/keys.rs new file mode 100644 index 00000000000..21bf4f43cae --- /dev/null +++ b/crates/nargo/src/cli/fs/keys.rs @@ -0,0 +1,75 @@ +use std::path::{Path, PathBuf}; + +use acvm::{acir::circuit::Circuit, hash_constraint_system, ProofSystemCompiler}; + +use crate::{ + constants::{ACIR_EXT, PK_EXT, VK_EXT}, + errors::CliError, +}; + +use super::{create_named_dir, load_hex_data, write_to_file}; + +pub(crate) fn save_key_to_dir>( + key: Vec, + key_name: &str, + key_dir: P, + is_proving_key: bool, +) -> Result { + let mut key_path = create_named_dir(key_dir.as_ref(), key_name); + key_path.push(key_name); + let extension = if is_proving_key { PK_EXT } else { VK_EXT }; + key_path.set_extension(extension); + + write_to_file(hex::encode(key).as_bytes(), &key_path); + + Ok(key_path) +} + +pub(crate) fn fetch_pk_and_vk>( + circuit: &Circuit, + circuit_build_path: Option

, + prove_circuit: bool, + check_proof: bool, +) -> Result<(Vec, Vec), CliError> { + let backend = crate::backends::ConcreteBackend; + if let Some(circuit_build_path) = circuit_build_path { + let mut acir_hash_path = PathBuf::new(); + acir_hash_path.push(circuit_build_path.as_ref()); + acir_hash_path.set_extension(ACIR_EXT.to_owned() + ".sha256"); + let expected_acir_hash = load_hex_data(acir_hash_path.clone())?; + + let new_acir_hash = hash_constraint_system(circuit); + + if new_acir_hash[..] != expected_acir_hash { + return Err(CliError::MismatchedAcir(acir_hash_path)); + } + + // This flag exists to avoid an unnecessary read of the proving key during verification + // as this method is used by both `nargo prove` and `nargo verify` + let proving_key = if prove_circuit { + let mut proving_key_path = PathBuf::new(); + proving_key_path.push(circuit_build_path.as_ref()); + proving_key_path.set_extension(PK_EXT); + load_hex_data(proving_key_path)? + } else { + // We can return an empty Vec here as `prove_circuit` should only be false when running `nargo verify` + vec![] + }; + + let verification_key = if check_proof { + let mut verification_key_path = PathBuf::new(); + verification_key_path.push(circuit_build_path); + verification_key_path.set_extension(VK_EXT); + load_hex_data(verification_key_path)? + } else { + // We can return an empty Vec here as the verification key is used only is `check_proof` is true + vec![] + }; + + Ok((proving_key, verification_key)) + } else { + // If a path to the circuit's build dir has not been provided, run preprocess and generate the proving and verification keys + let (proving_key, verification_key) = backend.preprocess(circuit.clone()); + Ok((proving_key, verification_key)) + } +} diff --git a/crates/nargo/src/cli/fs/mod.rs b/crates/nargo/src/cli/fs/mod.rs new file mode 100644 index 00000000000..91bd7e88b77 --- /dev/null +++ b/crates/nargo/src/cli/fs/mod.rs @@ -0,0 +1,47 @@ +use std::{ + fs::File, + io::Write, + path::{Path, PathBuf}, +}; + +use crate::errors::CliError; + +pub mod acir; +pub mod inputs; +pub mod keys; +pub mod proof; +pub mod witness; + +fn create_dir>(dir_path: P) -> Result { + let mut dir = std::path::PathBuf::new(); + dir.push(dir_path); + std::fs::create_dir_all(&dir)?; + Ok(dir) +} + +pub(crate) fn create_named_dir(named_dir: &Path, name: &str) -> PathBuf { + create_dir(named_dir).unwrap_or_else(|_| panic!("could not create the `{name}` directory")) +} + +pub(crate) fn write_to_file(bytes: &[u8], path: &Path) -> String { + let display = path.display(); + + let mut file = match File::create(path) { + Err(why) => panic!("couldn't create {display}: {why}"), + Ok(file) => file, + }; + + match file.write_all(bytes) { + Err(why) => panic!("couldn't write to {display}: {why}"), + Ok(_) => display.to_string(), + } +} + +pub fn load_hex_data>(path: P) -> Result, CliError> { + let hex_data: Vec<_> = + std::fs::read(&path).map_err(|_| CliError::PathNotValid(path.as_ref().to_path_buf()))?; + + let raw_bytes = hex::decode(hex_data).map_err(CliError::HexArtifactNotValid)?; + + Ok(raw_bytes) +} diff --git a/crates/nargo/src/cli/fs/proof.rs b/crates/nargo/src/cli/fs/proof.rs new file mode 100644 index 00000000000..9b76942fb05 --- /dev/null +++ b/crates/nargo/src/cli/fs/proof.rs @@ -0,0 +1,19 @@ +use std::path::{Path, PathBuf}; + +use crate::{constants::PROOF_EXT, errors::CliError}; + +use super::{create_named_dir, write_to_file}; + +pub(crate) fn save_proof_to_dir>( + proof: &[u8], + proof_name: &str, + proof_dir: P, +) -> Result { + let mut proof_path = create_named_dir(proof_dir.as_ref(), "proof"); + proof_path.push(proof_name); + proof_path.set_extension(PROOF_EXT); + + write_to_file(hex::encode(proof).as_bytes(), &proof_path); + + Ok(proof_path) +} diff --git a/crates/nargo/src/cli/fs/witness.rs b/crates/nargo/src/cli/fs/witness.rs new file mode 100644 index 00000000000..c457728104f --- /dev/null +++ b/crates/nargo/src/cli/fs/witness.rs @@ -0,0 +1,23 @@ +use std::path::{Path, PathBuf}; + +use acvm::acir::native_types::Witness; +use noirc_abi::WitnessMap; + +use super::{create_named_dir, write_to_file}; +use crate::{constants::WITNESS_EXT, errors::CliError}; + +pub(crate) fn save_witness_to_dir>( + witness: WitnessMap, + witness_name: &str, + witness_dir: P, +) -> Result { + let mut witness_path = create_named_dir(witness_dir.as_ref(), "witness"); + witness_path.push(witness_name); + witness_path.set_extension(WITNESS_EXT); + + let buf = Witness::to_bytes(&witness); + + write_to_file(buf.as_slice(), &witness_path); + + Ok(witness_path) +} diff --git a/crates/nargo/src/cli/mod.rs b/crates/nargo/src/cli/mod.rs index 2a4183d80fb..b0b778ad226 100644 --- a/crates/nargo/src/cli/mod.rs +++ b/crates/nargo/src/cli/mod.rs @@ -1,26 +1,14 @@ -use acvm::{acir::circuit::Circuit, hash_constraint_system, ProofSystemCompiler}; pub use check_cmd::check_from_path; use clap::{Args, Parser, Subcommand}; use const_format::formatcp; -use noirc_abi::{ - input_parser::{Format, InputValue}, - Abi, InputMap, MAIN_RETURN_NAME, -}; +use noirc_abi::InputMap; use noirc_driver::Driver; use noirc_frontend::graph::{CrateName, CrateType}; -use std::{ - collections::BTreeMap, - fs::File, - io::Write, - path::{Path, PathBuf}, -}; +use std::path::{Path, PathBuf}; extern crate tempdir; use tempdir::TempDir; -use crate::{ - constants::{ACIR_EXT, PK_EXT, VK_EXT}, - errors::CliError, -}; +mod fs; mod check_cmd; mod compile_cmd; @@ -89,97 +77,6 @@ pub fn start_cli() { } } -fn create_dir>(dir_path: P) -> Result { - let mut dir = std::path::PathBuf::new(); - dir.push(dir_path); - std::fs::create_dir_all(&dir)?; - Ok(dir) -} - -pub fn create_named_dir(named_dir: &Path, name: &str) -> PathBuf { - create_dir(named_dir).unwrap_or_else(|_| panic!("could not create the `{name}` directory")) -} - -fn write_to_file(bytes: &[u8], path: &Path) -> String { - let display = path.display(); - - let mut file = match File::create(path) { - Err(why) => panic!("couldn't create {display}: {why}"), - Ok(file) => file, - }; - - match file.write_all(bytes) { - Err(why) => panic!("couldn't write to {display}: {why}"), - Ok(_) => display.to_string(), - } -} - -/// Returns the circuit's parameters and its return value, if one exists. -/// # Examples -/// -/// ```ignore -/// let (input_map, return_value): (InputMap, Option) = -/// read_inputs_from_file(path, "Verifier", Format::Toml, &abi)?; -/// ``` -pub fn read_inputs_from_file>( - path: P, - file_name: &str, - format: Format, - abi: &Abi, -) -> Result<(InputMap, Option), CliError> { - if abi.is_empty() { - return Ok((BTreeMap::new(), None)); - } - - let file_path = { - let mut dir_path = path.as_ref().to_path_buf(); - dir_path.push(file_name); - dir_path.set_extension(format.ext()); - dir_path - }; - if !file_path.exists() { - return Err(CliError::MissingTomlFile(file_name.to_owned(), file_path)); - } - - let input_string = std::fs::read_to_string(file_path).unwrap(); - let mut input_map = format.parse(&input_string, abi)?; - let return_value = input_map.remove(MAIN_RETURN_NAME); - - Ok((input_map, return_value)) -} - -pub fn write_inputs_to_file>( - input_map: &InputMap, - return_value: &Option, - path: P, - file_name: &str, - format: Format, -) -> Result<(), CliError> { - let file_path = { - let mut dir_path = path.as_ref().to_path_buf(); - dir_path.push(file_name); - dir_path.set_extension(format.ext()); - dir_path - }; - - // We must insert the return value into the `InputMap` in order for it to be written to file. - let serialized_output = match return_value { - // Parameters and return values are kept separate except for when they're being written to file. - // As a result, we don't want to modify the original map and must clone it before insertion. - Some(return_value) => { - let mut input_map = input_map.clone(); - input_map.insert(MAIN_RETURN_NAME.to_owned(), return_value.clone()); - format.serialize(&input_map)? - } - // If no return value exists, then we can serialize the original map directly. - None => format.serialize(input_map)?, - }; - - write_to_file(serialized_output.as_bytes(), &file_path); - - Ok(()) -} - // helper function which tests noir programs by trying to generate a proof and verify it pub fn prove_and_verify(proof_name: &str, prg_dir: &Path, show_ssa: bool) -> bool { let tmp_dir = TempDir::new("p_and_v_tests").unwrap(); @@ -211,64 +108,6 @@ fn path_to_stdlib() -> PathBuf { dirs::config_dir().unwrap().join("noir-lang").join("std/src") } -pub fn load_hex_data>(path: P) -> Result, CliError> { - let hex_data: Vec<_> = - std::fs::read(&path).map_err(|_| CliError::PathNotValid(path.as_ref().to_path_buf()))?; - - let raw_bytes = hex::decode(hex_data).map_err(CliError::HexArtifactNotValid)?; - - Ok(raw_bytes) -} - -fn fetch_pk_and_vk>( - circuit: &Circuit, - circuit_build_path: Option

, - prove_circuit: bool, - check_proof: bool, -) -> Result<(Vec, Vec), CliError> { - let backend = crate::backends::ConcreteBackend; - if let Some(circuit_build_path) = circuit_build_path { - let mut acir_hash_path = PathBuf::new(); - acir_hash_path.push(circuit_build_path.as_ref()); - acir_hash_path.set_extension(ACIR_EXT.to_owned() + ".sha256"); - let expected_acir_hash = load_hex_data(acir_hash_path.clone())?; - - let new_acir_hash = hash_constraint_system(circuit); - - if new_acir_hash[..] != expected_acir_hash { - return Err(CliError::MismatchedAcir(acir_hash_path)); - } - - // This flag exists to avoid an unnecessary read of the proving key during verification - // as this method is used by both `nargo prove` and `nargo verify` - let proving_key = if prove_circuit { - let mut proving_key_path = PathBuf::new(); - proving_key_path.push(circuit_build_path.as_ref()); - proving_key_path.set_extension(PK_EXT); - load_hex_data(proving_key_path)? - } else { - // We can return an empty Vec here as `prove_circuit` should only be false when running `nargo verify` - vec![] - }; - - let verification_key = if check_proof { - let mut verification_key_path = PathBuf::new(); - verification_key_path.push(circuit_build_path); - verification_key_path.set_extension(VK_EXT); - load_hex_data(verification_key_path)? - } else { - // We can return an empty Vec here as the verification key is used only is `check_proof` is true - vec![] - }; - - Ok((proving_key, verification_key)) - } else { - // If a path to the circuit's build dir has not been provided, run preprocess and generate the proving and verification keys - let (proving_key, verification_key) = backend.preprocess(circuit.clone()); - Ok((proving_key, verification_key)) - } -} - // FIXME: I not sure that this is the right place for this tests. #[cfg(test)] mod tests { diff --git a/crates/nargo/src/cli/new_cmd.rs b/crates/nargo/src/cli/new_cmd.rs index 756b07599d1..452f2affcd2 100644 --- a/crates/nargo/src/cli/new_cmd.rs +++ b/crates/nargo/src/cli/new_cmd.rs @@ -3,7 +3,8 @@ use crate::{ errors::CliError, }; -use super::{create_named_dir, write_to_file, NargoConfig}; +use super::fs::{create_named_dir, write_to_file}; +use super::NargoConfig; use clap::Args; use std::path::{Path, PathBuf}; diff --git a/crates/nargo/src/cli/prove_cmd.rs b/crates/nargo/src/cli/prove_cmd.rs index 4f107b2ae0d..6c69d2e4022 100644 --- a/crates/nargo/src/cli/prove_cmd.rs +++ b/crates/nargo/src/cli/prove_cmd.rs @@ -4,13 +4,15 @@ use acvm::ProofSystemCompiler; use clap::Args; use noirc_abi::input_parser::Format; -use super::{ - create_named_dir, fetch_pk_and_vk, read_inputs_from_file, write_inputs_to_file, write_to_file, - NargoConfig, +use super::fs::{ + inputs::{read_inputs_from_file, write_inputs_to_file}, + keys::fetch_pk_and_vk, + proof::save_proof_to_dir, }; +use super::NargoConfig; use crate::{ cli::{execute_cmd::execute_program, verify_cmd::verify_proof}, - constants::{PROOFS_DIR, PROOF_EXT, PROVER_INPUT_FILE, TARGET_DIR, VERIFIER_INPUT_FILE}, + constants::{PROOFS_DIR, PROVER_INPUT_FILE, TARGET_DIR, VERIFIER_INPUT_FILE}, errors::CliError, }; @@ -124,17 +126,3 @@ pub fn prove_with_path>( Ok(proof_path) } - -fn save_proof_to_dir>( - proof: &[u8], - proof_name: &str, - proof_dir: P, -) -> Result { - let mut proof_path = create_named_dir(proof_dir.as_ref(), "proof"); - proof_path.push(proof_name); - proof_path.set_extension(PROOF_EXT); - - write_to_file(hex::encode(proof).as_bytes(), &proof_path); - - Ok(proof_path) -} diff --git a/crates/nargo/src/cli/verify_cmd.rs b/crates/nargo/src/cli/verify_cmd.rs index b0558ed44ca..05c7570ce80 100644 --- a/crates/nargo/src/cli/verify_cmd.rs +++ b/crates/nargo/src/cli/verify_cmd.rs @@ -1,7 +1,5 @@ -use super::{ - compile_cmd::compile_circuit, fetch_pk_and_vk, load_hex_data, read_inputs_from_file, InputMap, - NargoConfig, -}; +use super::fs::{inputs::read_inputs_from_file, keys::fetch_pk_and_vk, load_hex_data}; +use super::{compile_cmd::compile_circuit, InputMap, NargoConfig}; use crate::{ constants::{PROOFS_DIR, PROOF_EXT, TARGET_DIR, VERIFIER_INPUT_FILE}, errors::CliError, From 14a08864e5b65de35daa30cad2b378f8a24ebcfe Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Tue, 21 Feb 2023 16:22:54 +0000 Subject: [PATCH 2/3] chore: remove preprocessing from io module --- crates/nargo/src/cli/fs/keys.rs | 69 ++++++++++++++---------------- crates/nargo/src/cli/prove_cmd.rs | 8 +++- crates/nargo/src/cli/verify_cmd.rs | 8 +++- 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/crates/nargo/src/cli/fs/keys.rs b/crates/nargo/src/cli/fs/keys.rs index 21bf4f43cae..e47b28ea68f 100644 --- a/crates/nargo/src/cli/fs/keys.rs +++ b/crates/nargo/src/cli/fs/keys.rs @@ -1,6 +1,6 @@ use std::path::{Path, PathBuf}; -use acvm::{acir::circuit::Circuit, hash_constraint_system, ProofSystemCompiler}; +use acvm::{acir::circuit::Circuit, hash_constraint_system}; use crate::{ constants::{ACIR_EXT, PK_EXT, VK_EXT}, @@ -27,49 +27,42 @@ pub(crate) fn save_key_to_dir>( pub(crate) fn fetch_pk_and_vk>( circuit: &Circuit, - circuit_build_path: Option

, + circuit_build_path: P, prove_circuit: bool, check_proof: bool, ) -> Result<(Vec, Vec), CliError> { - let backend = crate::backends::ConcreteBackend; - if let Some(circuit_build_path) = circuit_build_path { - let mut acir_hash_path = PathBuf::new(); - acir_hash_path.push(circuit_build_path.as_ref()); - acir_hash_path.set_extension(ACIR_EXT.to_owned() + ".sha256"); - let expected_acir_hash = load_hex_data(acir_hash_path.clone())?; + let mut acir_hash_path = PathBuf::new(); + acir_hash_path.push(circuit_build_path.as_ref()); + acir_hash_path.set_extension(ACIR_EXT.to_owned() + ".sha256"); + let expected_acir_hash = load_hex_data(acir_hash_path.clone())?; - let new_acir_hash = hash_constraint_system(circuit); + let new_acir_hash = hash_constraint_system(circuit); - if new_acir_hash[..] != expected_acir_hash { - return Err(CliError::MismatchedAcir(acir_hash_path)); - } - - // This flag exists to avoid an unnecessary read of the proving key during verification - // as this method is used by both `nargo prove` and `nargo verify` - let proving_key = if prove_circuit { - let mut proving_key_path = PathBuf::new(); - proving_key_path.push(circuit_build_path.as_ref()); - proving_key_path.set_extension(PK_EXT); - load_hex_data(proving_key_path)? - } else { - // We can return an empty Vec here as `prove_circuit` should only be false when running `nargo verify` - vec![] - }; + if new_acir_hash[..] != expected_acir_hash { + return Err(CliError::MismatchedAcir(acir_hash_path)); + } - let verification_key = if check_proof { - let mut verification_key_path = PathBuf::new(); - verification_key_path.push(circuit_build_path); - verification_key_path.set_extension(VK_EXT); - load_hex_data(verification_key_path)? - } else { - // We can return an empty Vec here as the verification key is used only is `check_proof` is true - vec![] - }; + // This flag exists to avoid an unnecessary read of the proving key during verification + // as this method is used by both `nargo prove` and `nargo verify` + let proving_key = if prove_circuit { + let mut proving_key_path = PathBuf::new(); + proving_key_path.push(circuit_build_path.as_ref()); + proving_key_path.set_extension(PK_EXT); + load_hex_data(proving_key_path)? + } else { + // We can return an empty Vec here as `prove_circuit` should only be false when running `nargo verify` + vec![] + }; - Ok((proving_key, verification_key)) + let verification_key = if check_proof { + let mut verification_key_path = PathBuf::new(); + verification_key_path.push(circuit_build_path); + verification_key_path.set_extension(VK_EXT); + load_hex_data(verification_key_path)? } else { - // If a path to the circuit's build dir has not been provided, run preprocess and generate the proving and verification keys - let (proving_key, verification_key) = backend.preprocess(circuit.clone()); - Ok((proving_key, verification_key)) - } + // We can return an empty Vec here as the verification key is used only is `check_proof` is true + vec![] + }; + + Ok((proving_key, verification_key)) } diff --git a/crates/nargo/src/cli/prove_cmd.rs b/crates/nargo/src/cli/prove_cmd.rs index 6c69d2e4022..0504b44c85e 100644 --- a/crates/nargo/src/cli/prove_cmd.rs +++ b/crates/nargo/src/cli/prove_cmd.rs @@ -75,8 +75,12 @@ pub fn prove_with_path>( ) -> Result, CliError> { let compiled_program = super::compile_cmd::compile_circuit(program_dir.as_ref(), show_ssa, allow_warnings)?; - let (proving_key, verification_key) = - fetch_pk_and_vk(&compiled_program.circuit, circuit_build_path.as_ref(), true, check_proof)?; + let (proving_key, verification_key) = if let Some(circuit_build_path) = circuit_build_path { + fetch_pk_and_vk(&compiled_program.circuit, circuit_build_path, true, true)? + } else { + let backend = crate::backends::ConcreteBackend; + backend.preprocess(compiled_program.circuit.clone()) + }; // Parse the initial witness values from Prover.toml let (inputs_map, _) = read_inputs_from_file( diff --git a/crates/nargo/src/cli/verify_cmd.rs b/crates/nargo/src/cli/verify_cmd.rs index 05c7570ce80..d72c022ea64 100644 --- a/crates/nargo/src/cli/verify_cmd.rs +++ b/crates/nargo/src/cli/verify_cmd.rs @@ -59,8 +59,12 @@ pub fn verify_with_path>( allow_warnings: bool, ) -> Result { let compiled_program = compile_circuit(program_dir.as_ref(), show_ssa, allow_warnings)?; - let (_, verification_key) = - fetch_pk_and_vk(&compiled_program.circuit, circuit_build_path, false, true)?; + let (_, verification_key) = if let Some(circuit_build_path) = circuit_build_path { + fetch_pk_and_vk(&compiled_program.circuit, circuit_build_path, false, true)? + } else { + let backend = crate::backends::ConcreteBackend; + backend.preprocess(compiled_program.circuit.clone()) + }; // Load public inputs (if any) from `VERIFIER_INPUT_FILE`. let public_abi = compiled_program.abi.clone().public_abi(); From 0010e3ac7d430f3c8a69646e90f2126a61b2296d Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Tue, 21 Feb 2023 23:22:52 +0000 Subject: [PATCH 3/3] chore: replace if-lets with match --- crates/nargo/src/cli/prove_cmd.rs | 13 ++++++++----- crates/nargo/src/cli/verify_cmd.rs | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/crates/nargo/src/cli/prove_cmd.rs b/crates/nargo/src/cli/prove_cmd.rs index 0504b44c85e..d8a37ff10b3 100644 --- a/crates/nargo/src/cli/prove_cmd.rs +++ b/crates/nargo/src/cli/prove_cmd.rs @@ -75,11 +75,14 @@ pub fn prove_with_path>( ) -> Result, CliError> { let compiled_program = super::compile_cmd::compile_circuit(program_dir.as_ref(), show_ssa, allow_warnings)?; - let (proving_key, verification_key) = if let Some(circuit_build_path) = circuit_build_path { - fetch_pk_and_vk(&compiled_program.circuit, circuit_build_path, true, true)? - } else { - let backend = crate::backends::ConcreteBackend; - backend.preprocess(compiled_program.circuit.clone()) + let (proving_key, verification_key) = match circuit_build_path { + Some(circuit_build_path) => { + fetch_pk_and_vk(&compiled_program.circuit, circuit_build_path, true, true)? + } + None => { + let backend = crate::backends::ConcreteBackend; + backend.preprocess(compiled_program.circuit.clone()) + } }; // Parse the initial witness values from Prover.toml diff --git a/crates/nargo/src/cli/verify_cmd.rs b/crates/nargo/src/cli/verify_cmd.rs index d72c022ea64..6a2f5a794bd 100644 --- a/crates/nargo/src/cli/verify_cmd.rs +++ b/crates/nargo/src/cli/verify_cmd.rs @@ -59,11 +59,14 @@ pub fn verify_with_path>( allow_warnings: bool, ) -> Result { let compiled_program = compile_circuit(program_dir.as_ref(), show_ssa, allow_warnings)?; - let (_, verification_key) = if let Some(circuit_build_path) = circuit_build_path { - fetch_pk_and_vk(&compiled_program.circuit, circuit_build_path, false, true)? - } else { - let backend = crate::backends::ConcreteBackend; - backend.preprocess(compiled_program.circuit.clone()) + let (_, verification_key) = match circuit_build_path { + Some(circuit_build_path) => { + fetch_pk_and_vk(&compiled_program.circuit, circuit_build_path, false, true)? + } + None => { + let backend = crate::backends::ConcreteBackend; + backend.preprocess(compiled_program.circuit.clone()) + } }; // Load public inputs (if any) from `VERIFIER_INPUT_FILE`.