Skip to content

Commit

Permalink
Merge branch 'master' into nargo-execute
Browse files Browse the repository at this point in the history
* master:
  feat(noir)!:  Returned values are no longer required by the prover (#731)
  • Loading branch information
TomAFrench committed Feb 3, 2023
2 parents 673249f + 90b6036 commit 3b624d6
Show file tree
Hide file tree
Showing 19 changed files with 458 additions and 95 deletions.
4 changes: 2 additions & 2 deletions crates/nargo/src/cli/compile_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn generate_circuit_and_witness_to_disk<P: AsRef<Path>>(
generate_witness: bool,
allow_warnings: bool,
) -> Result<PathBuf, CliError> {
let compiled_program = compile_circuit(program_dir.as_ref(), false, allow_warnings)?;
let mut compiled_program = compile_circuit(program_dir.as_ref(), false, allow_warnings)?;
let serialized = compiled_program.circuit.to_bytes();

let mut circuit_path = create_named_dir(circuit_dir.as_ref(), "build");
Expand All @@ -58,7 +58,7 @@ pub fn generate_circuit_and_witness_to_disk<P: AsRef<Path>>(

if generate_witness {
let (_, solved_witness) =
super::execute_cmd::execute_program(program_dir, &compiled_program)?;
super::execute_cmd::execute_program(program_dir, &mut compiled_program)?;

circuit_path.pop();
save_witness_to_dir(solved_witness, circuit_name, &circuit_path)?;
Expand Down
8 changes: 4 additions & 4 deletions crates/nargo/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ fn execute(
) -> Result<(Option<InputValue>, BTreeMap<Witness, FieldElement>), CliError> {
let curr_dir = std::env::current_dir().unwrap();

let compiled_program =
let mut compiled_program =
super::compile_cmd::compile_circuit(&curr_dir, show_ssa, allow_warnings)?;

execute_program(curr_dir, &compiled_program)
execute_program(curr_dir, &mut compiled_program)
}

pub(crate) fn execute_program<P: AsRef<Path>>(
inputs_dir: P,
compiled_program: &CompiledProgram,
compiled_program: &mut CompiledProgram,
) -> Result<(Option<InputValue>, BTreeMap<Witness, FieldElement>), CliError> {
// Parse the initial witness values from Prover.toml
let witness_map = read_inputs_from_file(
Expand Down Expand Up @@ -94,7 +94,7 @@ pub(crate) fn extract_public_inputs(
}

pub(crate) fn solve_witness(
compiled_program: &noirc_driver::CompiledProgram,
compiled_program: &mut noirc_driver::CompiledProgram,
witness_map: &BTreeMap<String, InputValue>,
) -> Result<BTreeMap<Witness, FieldElement>, CliError> {
// Note that this currently accepts an input for the return value witness.
Expand Down
41 changes: 40 additions & 1 deletion crates/nargo/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use acvm::{acir::circuit::PublicInputs, FieldElement};
pub use check_cmd::check_from_path;
use clap::{App, AppSettings, Arg};
use const_format::formatcp;
Expand All @@ -9,7 +10,7 @@ use noirc_abi::{
use noirc_driver::Driver;
use noirc_frontend::graph::{CrateName, CrateType};
use std::{
collections::BTreeMap,
collections::{BTreeMap, HashMap, HashSet},
fs::File,
io::Write,
path::{Path, PathBuf},
Expand Down Expand Up @@ -220,6 +221,44 @@ fn path_to_stdlib() -> PathBuf {
dirs::config_dir().unwrap().join("noir-lang").join("std/src")
}

// Removes duplicates from the list of public input witnesses
fn dedup_public_input_indices(indices: PublicInputs) -> PublicInputs {
let duplicates_removed: HashSet<_> = indices.0.into_iter().collect();
PublicInputs(duplicates_removed.into_iter().collect())
}

// Removes duplicates from the list of public input witnesses and the
// associated list of duplicate values.
pub(crate) fn dedup_public_input_indices_values(
indices: PublicInputs,
values: Vec<FieldElement>,
) -> (PublicInputs, Vec<FieldElement>) {
// Assume that the public input index lists and the values contain duplicates
assert_eq!(indices.0.len(), values.len());

let mut public_inputs_without_duplicates = Vec::new();
let mut already_seen_public_indices = HashMap::new();

for (index, value) in indices.0.iter().zip(values) {
match already_seen_public_indices.get(index) {
Some(expected_value) => {
// The index has already been added
// so lets check that the values already inserted is equal to the value, we wish to insert
assert_eq!(*expected_value, value, "witness index {index:?} does not have a canonical map. The expected value is {expected_value}, the received value is {value}.")
}
None => {
already_seen_public_indices.insert(*index, value);
public_inputs_without_duplicates.push(value)
}
}
}

(
PublicInputs(already_seen_public_indices.keys().copied().collect()),
public_inputs_without_duplicates,
)
}

// FIXME: I not sure that this is the right place for this tests.
#[cfg(test)]
mod tests {
Expand Down
12 changes: 10 additions & 2 deletions crates/nargo/src/cli/prove_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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};
use crate::cli::dedup_public_input_indices;
use crate::{
constants::{PROOFS_DIR, PROOF_EXT, VERIFIER_INPUT_FILE},
errors::CliError,
Expand Down Expand Up @@ -39,9 +40,9 @@ pub fn prove_with_path<P: AsRef<Path>>(
show_ssa: bool,
allow_warnings: bool,
) -> Result<Option<PathBuf>, CliError> {
let compiled_program =
let mut compiled_program =
super::compile_cmd::compile_circuit(program_dir.as_ref(), show_ssa, allow_warnings)?;
let (_, solved_witness) = execute_program(&program_dir, &compiled_program)?;
let (_, solved_witness) = execute_program(&program_dir, &mut compiled_program)?;

// We allow the user to optionally not provide a value for the circuit's return value, so this may be missing from
// `witness_map`. We must then decode these from the circuit's witness values.
Expand All @@ -50,6 +51,13 @@ pub fn prove_with_path<P: AsRef<Path>>(
// Write public inputs into Verifier.toml
write_inputs_to_file(&public_inputs, &program_dir, VERIFIER_INPUT_FILE, Format::Toml)?;

// Since the public outputs are added into the public inputs list
// There can be duplicates. We keep the duplicates for when one is
// encoding the return values into the Verifier.toml
// However, for creating a proof, we remove these duplicates.
compiled_program.circuit.public_inputs =
dedup_public_input_indices(compiled_program.circuit.public_inputs.clone());

let backend = crate::backends::ConcreteBackend;
let proof = backend.prove_with_meta(compiled_program.circuit, solved_witness);

Expand Down
14 changes: 11 additions & 3 deletions crates/nargo/src/cli/verify_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use super::{compile_cmd::compile_circuit, read_inputs_from_file};
use super::{
compile_cmd::compile_circuit, dedup_public_input_indices_values, read_inputs_from_file,
};
use crate::{
constants::{PROOFS_DIR, PROOF_EXT, VERIFIER_INPUT_FILE},
errors::CliError,
Expand Down Expand Up @@ -59,7 +61,7 @@ pub fn verify_with_path<P: AsRef<Path>>(
}

fn verify_proof(
compiled_program: CompiledProgram,
mut compiled_program: CompiledProgram,
public_inputs: BTreeMap<String, InputValue>,
proof: Vec<u8>,
) -> Result<bool, CliError> {
Expand All @@ -71,8 +73,14 @@ fn verify_proof(
_ => 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.
let (dedup_public_indices, dedup_public_values) =
dedup_public_input_indices_values(compiled_program.circuit.public_inputs, public_inputs);
compiled_program.circuit.public_inputs = dedup_public_indices;

let backend = crate::backends::ConcreteBackend;
let valid_proof = backend.verify_from_cs(&proof, public_inputs, compiled_program.circuit);
let valid_proof = backend.verify_from_cs(&proof, dedup_public_values, compiled_program.circuit);

Ok(valid_proof)
}
Expand Down
1 change: 0 additions & 1 deletion crates/nargo/tests/test_data/hash_to_field/Prover.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
input = "1"
return = "0x25cebc29ded2fa515a937e2b5f674e3026c012e5b57f8a48d7dce6b7d274f9d9"
Original file line number Diff line number Diff line change
@@ -1 +1 @@
return = "5"

1 change: 0 additions & 1 deletion crates/nargo/tests/test_data/main_return/Prover.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
return = ""
x = "8"
2 changes: 1 addition & 1 deletion crates/nargo/tests/test_data/main_return/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fn main(x: Field) -> pub Field {
fn main(x: pub Field) -> pub Field {
x
}
Loading

0 comments on commit 3b624d6

Please sign in to comment.