diff --git a/acvm-repo/acir/src/native_types/witness_map.rs b/acvm-repo/acir/src/native_types/witness_map.rs index 00245d5842c..e37fe2adafc 100644 --- a/acvm-repo/acir/src/native_types/witness_map.rs +++ b/acvm-repo/acir/src/native_types/witness_map.rs @@ -43,6 +43,19 @@ impl WitnessMap { pub fn insert(&mut self, key: Witness, value: FieldElement) -> Option { self.0.insert(key, value) } + pub fn extract_if(&self, mut f: F) -> WitnessMap + where + F: FnMut(&Witness, &FieldElement) -> bool, + { + let mut result = BTreeMap::new(); + for (k, v) in &self.0 { + if f(k, v) { + result.insert(*k, *v); + } + } + + WitnessMap(result) + } } impl Index<&Witness> for WitnessMap { diff --git a/tooling/backend_interface/src/proof_system.rs b/tooling/backend_interface/src/proof_system.rs index fa1f82a5722..9bac1947509 100644 --- a/tooling/backend_interface/src/proof_system.rs +++ b/tooling/backend_interface/src/proof_system.rs @@ -83,7 +83,8 @@ impl Backend { let proof = bb_abstraction_leaks::remove_public_inputs( // TODO(https://github.com/noir-lang/noir/issues/4428) - program.functions[0].public_inputs().0.len(), + program.functions[0].public_parameters.0.len() + + program.functions[0].return_values.0.len(), &proof_with_public_inputs, ); Ok(proof) @@ -93,8 +94,9 @@ impl Backend { pub fn verify( &self, proof: &[u8], - public_inputs: WitnessMap, program: &Program, + public_inputs: WitnessMap, + public_outputs: WitnessMap, ) -> Result { let binary_path = self.assert_binary_exists()?; self.assert_correct_version()?; @@ -104,7 +106,11 @@ impl Backend { // Create a temporary file for the proof let proof_with_public_inputs = - bb_abstraction_leaks::prepend_public_inputs(proof.to_vec(), public_inputs); + bb_abstraction_leaks::prepend_public_inputs(proof.to_vec(), public_outputs); + let proof_with_public_inputs = bb_abstraction_leaks::prepend_public_inputs( + proof_with_public_inputs.to_vec(), + public_inputs, + ); let proof_path = temp_directory.join("proof").with_extension("proof"); write_to_file(&proof_with_public_inputs, &proof_path); diff --git a/tooling/nargo_cli/src/cli/prove_cmd.rs b/tooling/nargo_cli/src/cli/prove_cmd.rs index b9e4bca9e69..983924feaa0 100644 --- a/tooling/nargo_cli/src/cli/prove_cmd.rs +++ b/tooling/nargo_cli/src/cli/prove_cmd.rs @@ -15,6 +15,7 @@ use super::fs::{ inputs::{read_inputs_from_file, write_inputs_to_file}, proof::save_proof_to_dir, }; +use super::verify_cmd::extract_public_inputs_and_outputs; use super::NargoConfig; use crate::{backends::Backend, cli::execute_cmd::execute_program, errors::CliError}; @@ -144,7 +145,8 @@ pub(crate) fn prove_package( if check_proof { let public_inputs = public_abi.encode(&public_inputs, return_value)?; - let valid_proof = backend.verify(&proof, public_inputs, &compiled_program.program)?; + let (inputs, outputs) = extract_public_inputs_and_outputs(&public_inputs, public_abi); + let valid_proof = backend.verify(&proof, &compiled_program.program, inputs, outputs)?; if !valid_proof { return Err(CliError::InvalidProof("".into())); diff --git a/tooling/nargo_cli/src/cli/verify_cmd.rs b/tooling/nargo_cli/src/cli/verify_cmd.rs index 7202a179aae..2cf9fb308d5 100644 --- a/tooling/nargo_cli/src/cli/verify_cmd.rs +++ b/tooling/nargo_cli/src/cli/verify_cmd.rs @@ -2,6 +2,7 @@ use super::fs::{inputs::read_inputs_from_file, load_hex_data}; use super::NargoConfig; use crate::{backends::Backend, errors::CliError}; +use acvm::acir::native_types::WitnessMap; use clap::Args; use nargo::constants::{PROOF_EXT, VERIFIER_INPUT_FILE}; use nargo::ops::{compile_program, report_errors}; @@ -10,6 +11,7 @@ use nargo::workspace::Workspace; use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; use noirc_abi::input_parser::Format; +use noirc_abi::Abi; use noirc_driver::{ file_manager_with_stdlib, CompileOptions, CompiledProgram, NOIR_ARTIFACT_VERSION_STRING, }; @@ -94,15 +96,14 @@ fn verify_package( let public_abi = compiled_program.abi.public_abi(); let (public_inputs_map, return_value) = read_inputs_from_file(&package.root_dir, verifier_name, Format::Toml, &public_abi)?; - let public_inputs = public_abi.encode(&public_inputs_map, return_value)?; - + let (inputs, outputs) = extract_public_inputs_and_outputs(&public_inputs, public_abi); let proof_path = workspace.proofs_directory_path().join(package.name.to_string()).with_extension(PROOF_EXT); let proof = load_hex_data(&proof_path)?; - let valid_proof = backend.verify(&proof, public_inputs, &compiled_program.program)?; + let valid_proof = backend.verify(&proof, &compiled_program.program, inputs, outputs)?; if valid_proof { Ok(()) @@ -110,3 +111,21 @@ fn verify_package( Err(CliError::InvalidProof(proof_path)) } } + +pub(crate) fn extract_public_inputs_and_outputs( + public_inputs: &WitnessMap, + public_abi: Abi, +) -> (WitnessMap, WitnessMap) { + let inputs = public_inputs.extract_if(|k, _| { + for ranges in public_abi.param_witnesses.values() { + for range in ranges { + if range.contains(k) { + return true; + } + } + } + false + }); + let outputs = public_inputs.extract_if(|k, _| public_abi.return_witnesses.contains(k)); + (inputs, outputs) +}