Skip to content

Commit

Permalink
Merge branch 'master' into nargo-execute
Browse files Browse the repository at this point in the history
* master:
  chore(nargo): add InputMap and WitnessMap terminology (#713)
  chore(ci): Avoid reporting errors if labeler action fails (#746)
  • Loading branch information
TomAFrench committed Feb 3, 2023
2 parents 58cf912 + 0b0d74c commit 9756672
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 42 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: github/issue-labeler@v2.6
# We continue-on-error because the action is buggy and tries to remove labels when they don't exist
continue-on-error: true
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
configuration-path: .github/labeler.yml
Expand Down
61 changes: 35 additions & 26 deletions crates/nargo/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};

use acvm::acir::native_types::Witness;
Expand All @@ -7,16 +6,16 @@ use acvm::PartialWitnessGenerator;
use clap::ArgMatches;
use noirc_abi::errors::AbiError;
use noirc_abi::input_parser::{Format, InputValue};
use noirc_abi::MAIN_RETURN_NAME;
use noirc_abi::{Abi, MAIN_RETURN_NAME};
use noirc_driver::CompiledProgram;

use super::{create_named_dir, read_inputs_from_file, write_to_file};
use super::{InputMap, WitnessMap};
use crate::{
constants::{PROVER_INPUT_FILE, TARGET_DIR, WITNESS_EXT},
errors::CliError,
};

use super::{create_named_dir, read_inputs_from_file, write_to_file};

pub(crate) fn run(args: ArgMatches) -> Result<(), CliError> {
let args = args.subcommand_matches("execute").unwrap();
let witness_name = args.value_of("witness_name");
Expand Down Expand Up @@ -46,7 +45,7 @@ const WITNESS_OFFSET: u32 = 1;
fn execute(
show_ssa: bool,
allow_warnings: bool,
) -> Result<(Option<InputValue>, BTreeMap<Witness, FieldElement>), CliError> {
) -> Result<(Option<InputValue>, WitnessMap), CliError> {
let current_dir = std::env::current_dir().unwrap();

let compiled_program =
Expand All @@ -58,7 +57,7 @@ fn execute(
pub(crate) fn execute_program<P: AsRef<Path>>(
inputs_dir: P,
compiled_program: &CompiledProgram,
) -> Result<(Option<InputValue>, BTreeMap<Witness, FieldElement>), CliError> {
) -> Result<(Option<InputValue>, WitnessMap), CliError> {
// Parse the initial witness values from Prover.toml
let witness_map = read_inputs_from_file(
inputs_dir,
Expand All @@ -78,8 +77,8 @@ pub(crate) fn execute_program<P: AsRef<Path>>(

pub(crate) fn extract_public_inputs(
compiled_program: &noirc_driver::CompiledProgram,
solved_witness: &BTreeMap<Witness, FieldElement>,
) -> Result<BTreeMap<String, InputValue>, AbiError> {
solved_witness: &WitnessMap,
) -> Result<InputMap, AbiError> {
let encoded_public_inputs: Vec<FieldElement> = compiled_program
.circuit
.public_inputs
Expand All @@ -95,33 +94,43 @@ pub(crate) fn extract_public_inputs(

pub(crate) fn solve_witness(
compiled_program: &noirc_driver::CompiledProgram,
witness_map: &BTreeMap<String, InputValue>,
) -> Result<BTreeMap<Witness, FieldElement>, CliError> {
let abi = compiled_program.abi.as_ref().unwrap();
let encoded_inputs = abi.clone().encode(witness_map, true).map_err(|error| match error {
AbiError::UndefinedInput(_) => {
CliError::Generic(format!("{error} in the {PROVER_INPUT_FILE}.toml file."))
}
_ => CliError::from(error),
})?;

let mut solved_witness: BTreeMap<Witness, FieldElement> = encoded_inputs
input_map: &InputMap,
) -> Result<WitnessMap, CliError> {
let abi = compiled_program.abi.as_ref().unwrap().clone();
let mut solved_witness =
input_map_to_witness_map(abi, input_map).map_err(|error| match error {
AbiError::UndefinedInput(_) => {
CliError::Generic(format!("{error} in the {PROVER_INPUT_FILE}.toml file."))
}
_ => CliError::from(error),
})?;

let backend = crate::backends::ConcreteBackend;
backend.solve(&mut solved_witness, compiled_program.circuit.opcodes.clone())?;

Ok(solved_witness)
}

/// Given an InputMap and an Abi, produce a WitnessMap
///
/// In particular, this method shows one how to associate values in a Toml/JSON
/// file with witness indices
fn input_map_to_witness_map(abi: Abi, input_map: &InputMap) -> Result<WitnessMap, AbiError> {
// The ABI map is first encoded as a vector of field elements
let encoded_inputs = abi.encode(input_map, true)?;

Ok(encoded_inputs
.into_iter()
.enumerate()
.map(|(index, witness_value)| {
let witness = Witness::new(WITNESS_OFFSET + (index as u32));
(witness, witness_value)
})
.collect();

let backend = crate::backends::ConcreteBackend;
backend.solve(&mut solved_witness, compiled_program.circuit.opcodes.clone())?;

Ok(solved_witness)
.collect())
}

pub(crate) fn save_witness_to_dir<P: AsRef<Path>>(
witness: BTreeMap<Witness, FieldElement>,
witness: WitnessMap,
witness_name: &str,
witness_dir: P,
) -> Result<PathBuf, CliError> {
Expand Down
15 changes: 12 additions & 3 deletions crates/nargo/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use acvm::{acir::circuit::PublicInputs, FieldElement};
use acvm::{
acir::{circuit::PublicInputs, native_types::Witness},
FieldElement,
};
pub use check_cmd::check_from_path;
use clap::{App, AppSettings, Arg};
use const_format::formatcp;
Expand Down Expand Up @@ -33,6 +36,12 @@ mod verify_cmd;
const SHORT_GIT_HASH: &str = git_version!(prefix = "git:");
const VERSION_STRING: &str = formatcp!("{} ({})", env!("CARGO_PKG_VERSION"), SHORT_GIT_HASH);

/// A map from the fields in an TOML/JSON file which correspond to some ABI to their values
pub type InputMap = BTreeMap<String, InputValue>;

/// A map from the witnesses in a constraint system to the field element values
pub type WitnessMap = BTreeMap<Witness, FieldElement>;

pub fn start_cli() {
let allow_warnings = Arg::with_name("allow-warnings")
.long("allow-warnings")
Expand Down Expand Up @@ -166,7 +175,7 @@ pub fn read_inputs_from_file<P: AsRef<Path>>(
file_name: &str,
format: Format,
abi: Abi,
) -> Result<BTreeMap<String, InputValue>, CliError> {
) -> Result<InputMap, CliError> {
let file_path = {
let mut dir_path = path.as_ref().to_path_buf();
dir_path.push(file_name);
Expand All @@ -182,7 +191,7 @@ pub fn read_inputs_from_file<P: AsRef<Path>>(
}

fn write_inputs_to_file<P: AsRef<Path>>(
w_map: &BTreeMap<String, InputValue>,
w_map: &InputMap,
path: P,
file_name: &str,
format: Format,
Expand Down
3 changes: 1 addition & 2 deletions crates/nargo/src/cli/prove_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use std::path::PathBuf;
use std::path::{Path, PathBuf};

use acvm::ProofSystemCompiler;
use clap::ArgMatches;
use noirc_abi::input_parser::Format;
use std::path::Path;

use super::execute_cmd::{execute_program, extract_public_inputs};
use super::{create_named_dir, write_inputs_to_file, write_to_file};
Expand Down
24 changes: 13 additions & 11 deletions crates/nargo/src/cli/verify_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{
compile_cmd::compile_circuit, dedup_public_input_indices_values, read_inputs_from_file,
InputMap,
};
use crate::{
constants::{PROOFS_DIR, PROOF_EXT, VERIFIER_INPUT_FILE},
Expand All @@ -8,7 +9,7 @@ use crate::{
use acvm::ProofSystemCompiler;
use clap::ArgMatches;
use noirc_abi::errors::AbiError;
use noirc_abi::input_parser::{Format, InputValue};
use noirc_abi::input_parser::Format;
use noirc_driver::CompiledProgram;
use std::{collections::BTreeMap, path::Path, path::PathBuf};

Expand Down Expand Up @@ -44,34 +45,35 @@ pub fn verify_with_path<P: AsRef<Path>>(
allow_warnings: bool,
) -> Result<bool, CliError> {
let compiled_program = compile_circuit(program_dir.as_ref(), show_ssa, allow_warnings)?;
let mut public_inputs = BTreeMap::new();
let mut public_inputs_map: InputMap = BTreeMap::new();

// Load public inputs (if any) from `VERIFIER_INPUT_FILE`.
let public_abi = compiled_program.abi.clone().unwrap().public_abi();
let num_pub_params = public_abi.num_parameters();
if num_pub_params != 0 {
let current_dir = program_dir;
public_inputs =
public_inputs_map =
read_inputs_from_file(current_dir, VERIFIER_INPUT_FILE, Format::Toml, public_abi)?;
}

let valid_proof = verify_proof(compiled_program, public_inputs, load_proof(proof_path)?)?;
let valid_proof = verify_proof(compiled_program, public_inputs_map, load_proof(proof_path)?)?;

Ok(valid_proof)
}

fn verify_proof(
mut compiled_program: CompiledProgram,
public_inputs: BTreeMap<String, InputValue>,
public_inputs_map: InputMap,
proof: Vec<u8>,
) -> Result<bool, CliError> {
let public_abi = compiled_program.abi.unwrap().public_abi();
let public_inputs = public_abi.encode(&public_inputs, false).map_err(|error| match error {
AbiError::UndefinedInput(_) => {
CliError::Generic(format!("{error} in the {VERIFIER_INPUT_FILE}.toml file."))
}
_ => CliError::from(error),
})?;
let public_inputs =
public_abi.encode(&public_inputs_map, false).map_err(|error| match error {
AbiError::UndefinedInput(_) => {
CliError::Generic(format!("{error} in the {VERIFIER_INPUT_FILE}.toml file."))
}
_ => CliError::from(error),
})?;

// Similarly to when proving -- we must remove the duplicate public witnesses which
// can be present because a public input can also be added as a public output.
Expand Down

0 comments on commit 9756672

Please sign in to comment.