Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(nargo): Remove usage of CompiledProgram in CLI code and use separate ABI/bytecode #1269

Merged
merged 3 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions crates/nargo_cli/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::path::Path;

use acvm::acir::circuit::Circuit;
use acvm::PartialWitnessGenerator;
use clap::Args;
use noirc_abi::input_parser::{Format, InputValue};
use noirc_abi::{InputMap, WitnessMap};
use noirc_abi::{Abi, InputMap, WitnessMap};
use noirc_driver::{CompileOptions, CompiledProgram};

use super::fs::{inputs::read_inputs_from_file, witness::save_witness_to_dir};
Expand Down Expand Up @@ -48,29 +49,29 @@ fn execute_with_path(
) -> Result<(Option<InputValue>, WitnessMap), CliError> {
let backend = crate::backends::ConcreteBackend::default();

let compiled_program = compile_circuit(&backend, program_dir, compile_options)?;
let CompiledProgram { abi, circuit } = compile_circuit(&backend, program_dir, compile_options)?;

// Parse the initial witness values from Prover.toml
let (inputs_map, _) =
read_inputs_from_file(program_dir, PROVER_INPUT_FILE, Format::Toml, &compiled_program.abi)?;
read_inputs_from_file(program_dir, PROVER_INPUT_FILE, Format::Toml, &abi)?;

let solved_witness = execute_program(&backend, &compiled_program, &inputs_map)?;
let solved_witness = execute_program(&backend, circuit, &abi, &inputs_map)?;

let public_abi = compiled_program.abi.public_abi();
let public_abi = abi.public_abi();
let (_, return_value) = public_abi.decode(&solved_witness)?;

Ok((return_value, solved_witness))
}

pub(crate) fn execute_program(
backend: &impl PartialWitnessGenerator,
compiled_program: &CompiledProgram,
circuit: Circuit,
abi: &Abi,
inputs_map: &InputMap,
) -> Result<WitnessMap, CliError> {
let initial_witness = compiled_program.abi.encode(inputs_map, None)?;
let initial_witness = abi.encode(inputs_map, None)?;

let solved_witness =
nargo::ops::execute_circuit(backend, compiled_program.circuit.clone(), initial_witness)?;
let solved_witness = nargo::ops::execute_circuit(backend, circuit, initial_witness)?;

Ok(solved_witness)
}
1 change: 0 additions & 1 deletion crates/nargo_cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use clap::{Args, Parser, Subcommand};
use const_format::formatcp;
use noirc_abi::InputMap;
use noirc_driver::CompileOptions;
use std::path::{Path, PathBuf};

Expand Down
38 changes: 15 additions & 23 deletions crates/nargo_cli/src/cli/prove_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use std::path::{Path, PathBuf};

use clap::Args;
use nargo::artifacts::program::PreprocessedProgram;
use nargo::ops::{preprocess_program, prove_execution};
use nargo::ops::{preprocess_program, prove_execution, verify_proof};
use noirc_abi::input_parser::Format;
use noirc_driver::{CompileOptions, CompiledProgram};
use noirc_driver::CompileOptions;

use super::NargoConfig;
use super::{
Expand All @@ -16,7 +16,7 @@ use super::{
},
};
use crate::{
cli::{execute_cmd::execute_program, verify_cmd::verify_proof},
cli::execute_cmd::execute_program,
constants::{PROOFS_DIR, PROVER_INPUT_FILE, TARGET_DIR, VERIFIER_INPUT_FILE},
errors::CliError,
};
Expand Down Expand Up @@ -78,20 +78,15 @@ pub(crate) fn prove_with_path<P: AsRef<Path>>(

let PreprocessedProgram { abi, bytecode, proving_key, verification_key, .. } =
preprocessed_program;
let compiled_program = CompiledProgram { abi, circuit: bytecode };

// Parse the initial witness values from Prover.toml
let (inputs_map, _) = read_inputs_from_file(
&program_dir,
PROVER_INPUT_FILE,
Format::Toml,
&compiled_program.abi,
)?;
let (inputs_map, _) =
read_inputs_from_file(&program_dir, PROVER_INPUT_FILE, Format::Toml, &abi)?;

let solved_witness = execute_program(&backend, &compiled_program, &inputs_map)?;
let solved_witness = execute_program(&backend, bytecode.clone(), &abi, &inputs_map)?;
kevaundray marked this conversation as resolved.
Show resolved Hide resolved

// Write public inputs into Verifier.toml
let public_abi = compiled_program.abi.clone().public_abi();
let public_abi = abi.public_abi();
let (public_inputs, return_value) = public_abi.decode(&solved_witness)?;

write_inputs_to_file(
Expand All @@ -102,19 +97,16 @@ pub(crate) fn prove_with_path<P: AsRef<Path>>(
Format::Toml,
)?;

let proof = prove_execution(&backend, &compiled_program.circuit, solved_witness, &proving_key)?;
let proof = prove_execution(&backend, &bytecode, solved_witness, &proving_key)?;

if check_proof {
let no_proof_name = "".into();
verify_proof(
&backend,
&compiled_program,
public_inputs,
return_value,
&proof,
&verification_key,
no_proof_name,
)?;
let public_inputs = public_abi.encode(&public_inputs, return_value)?;
let valid_proof =
verify_proof(&backend, &bytecode, &proof, public_inputs, &verification_key)?;

if !valid_proof {
return Err(CliError::InvalidProof("".into()));
}
}

let proof_path = if let Some(proof_name) = proof_name {
Expand Down
51 changes: 15 additions & 36 deletions crates/nargo_cli/src/cli/verify_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use super::compile_cmd::compile_circuit;
use super::fs::{inputs::read_inputs_from_file, load_hex_data, program::read_program_from_file};
use super::{InputMap, NargoConfig};
use super::NargoConfig;
use crate::{
constants::{PROOFS_DIR, PROOF_EXT, TARGET_DIR, VERIFIER_INPUT_FILE},
errors::CliError,
};
use acvm::ProofSystemCompiler;

use clap::Args;
use nargo::artifacts::program::PreprocessedProgram;
use nargo::ops::preprocess_program;
use noirc_abi::input_parser::{Format, InputValue};
use noirc_driver::{CompileOptions, CompiledProgram};
use noirc_abi::input_parser::Format;
use noirc_driver::CompileOptions;
use std::path::{Path, PathBuf};

/// Given a proof and a program, verify whether the proof is valid
Expand All @@ -34,7 +34,12 @@ pub(crate) fn run(args: VerifyCommand, config: NargoConfig) -> Result<(), CliErr
.circuit_name
.map(|circuit_name| config.program_dir.join(TARGET_DIR).join(circuit_name));

verify_with_path(config.program_dir, proof_path, circuit_build_path, args.compile_options)
verify_with_path(
&config.program_dir,
proof_path,
circuit_build_path.as_ref(),
args.compile_options,
)
}

fn verify_with_path<P: AsRef<Path>>(
Expand All @@ -55,47 +60,21 @@ fn verify_with_path<P: AsRef<Path>>(
};

let PreprocessedProgram { abi, bytecode, verification_key, .. } = preprocessed_program;
let compiled_program = CompiledProgram { abi, circuit: bytecode };

// Load public inputs (if any) from `VERIFIER_INPUT_FILE`.
let public_abi = compiled_program.abi.clone().public_abi();
let public_abi = abi.public_abi();
let (public_inputs_map, return_value) =
read_inputs_from_file(program_dir, VERIFIER_INPUT_FILE, Format::Toml, &public_abi)?;

verify_proof(
&backend,
&compiled_program,
public_inputs_map,
return_value,
&load_hex_data(&proof_path)?,
&verification_key,
proof_path,
)
}

pub(crate) fn verify_proof(
backend: &impl ProofSystemCompiler,
compiled_program: &CompiledProgram,
public_inputs_map: InputMap,
return_value: Option<InputValue>,
proof: &[u8],
verification_key: &[u8],
proof_name: PathBuf,
) -> Result<(), CliError> {
let public_abi = compiled_program.abi.clone().public_abi();
let public_inputs = public_abi.encode(&public_inputs_map, return_value)?;
let proof = load_hex_data(&proof_path)?;

let valid_proof = nargo::ops::verify_proof(
backend,
&compiled_program.circuit,
proof,
public_inputs,
verification_key,
)?;
let valid_proof =
nargo::ops::verify_proof(&backend, &bytecode, &proof, public_inputs, &verification_key)?;

if valid_proof {
Ok(())
} else {
Err(CliError::InvalidProof(proof_name))
Err(CliError::InvalidProof(proof_path))
}
}