-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
268 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule aztec-packages
updated
2 files
+12 −2 | barretenberg/bb_rs/src/barretenberg_api/acir.rs | |
+1 −1 | barretenberg/bb_rs/src/barretenberg_api/tests/mod.rs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "nargo" | ||
version.workspace = true | ||
edition.workspace = true | ||
authors.workspace = true | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
acir.workspace = true | ||
acvm.workspace = true | ||
acvm_blackbox_solver.workspace = true | ||
bn254_blackbox_solver.workspace = true | ||
base64.workspace = true | ||
bb_rs.workspace = true | ||
bincode.workspace = true | ||
flate2.workspace = true | ||
hex.workspace = true | ||
reqwest.workspace = true | ||
serde.workspace = true | ||
thiserror.workspace = true | ||
tracing-subscriber.workspace = true | ||
tracing.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use acvm::{acir::circuit::OpcodeLocation, pwg::OpcodeResolutionError}; | ||
|
||
use thiserror::Error; | ||
|
||
#[derive(Debug, Error)] | ||
pub enum NargoError { | ||
/// Error while compiling Noir into ACIR. | ||
#[error("Failed to compile circuit")] | ||
CompilationError, | ||
|
||
/// ACIR circuit execution error | ||
#[error(transparent)] | ||
ExecutionError(#[from] ExecutionError), | ||
} | ||
|
||
impl NargoError { | ||
/// Extracts the user defined failure message from the ExecutionError | ||
/// If one exists. | ||
/// | ||
/// We want to extract the user defined error so that we can compare it | ||
/// in tests to expected failure messages | ||
pub fn user_defined_failure_message(&self) -> Option<&str> { | ||
let execution_error = match self { | ||
NargoError::ExecutionError(error) => error, | ||
_ => return None, | ||
}; | ||
|
||
match execution_error { | ||
ExecutionError::AssertionFailed(message, _) => Some(message), | ||
ExecutionError::SolvingError(error) => match error { | ||
OpcodeResolutionError::IndexOutOfBounds { .. } | ||
| OpcodeResolutionError::OpcodeNotSolvable(_) | ||
| OpcodeResolutionError::UnsatisfiedConstrain { .. } => None, | ||
OpcodeResolutionError::BrilligFunctionFailed { message, .. } => Some(message), | ||
OpcodeResolutionError::BlackBoxFunctionFailed(_, reason) => Some(reason), | ||
}, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Error)] | ||
pub enum ExecutionError { | ||
#[error("Failed assertion: '{}'", .0)] | ||
AssertionFailed(String, Vec<OpcodeLocation>), | ||
|
||
#[error(transparent)] | ||
SolvingError(#[from] OpcodeResolutionError), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod errors; | ||
pub mod ops; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
use acir::{circuit::Circuit, native_types::WitnessMap}; | ||
use acvm::{ | ||
pwg::{ACVMStatus, ErrorLocation, OpcodeResolutionError, ACVM}, | ||
BlackBoxFunctionSolver, | ||
}; | ||
|
||
use crate::errors::{ExecutionError, NargoError}; | ||
|
||
pub fn execute_circuit<B: BlackBoxFunctionSolver>( | ||
circuit: &Circuit, | ||
initial_witness: WitnessMap, | ||
blackbox_solver: &B, | ||
) -> Result<WitnessMap, NargoError> { | ||
let mut acvm = ACVM::new(blackbox_solver, &circuit.opcodes, initial_witness); | ||
|
||
// This message should be resolved by a nargo foreign call only when we have an unsatisfied assertion. | ||
let assert_message: Option<String> = None; | ||
loop { | ||
let solver_status = acvm.solve(); | ||
|
||
match solver_status { | ||
ACVMStatus::Solved => break, | ||
ACVMStatus::InProgress => { | ||
unreachable!("Execution should not stop while in `InProgress` state.") | ||
} | ||
ACVMStatus::Failure(error) => { | ||
let call_stack = match &error { | ||
OpcodeResolutionError::UnsatisfiedConstrain { | ||
opcode_location: ErrorLocation::Resolved(opcode_location), | ||
} => Some(vec![*opcode_location]), | ||
OpcodeResolutionError::BrilligFunctionFailed { call_stack, .. } => { | ||
Some(call_stack.clone()) | ||
} | ||
_ => None, | ||
}; | ||
|
||
return Err(NargoError::ExecutionError(match call_stack { | ||
Some(call_stack) => { | ||
// First check whether we have a runtime assertion message that should be resolved on an ACVM failure | ||
// If we do not have a runtime assertion message, we should check whether the circuit has any hardcoded | ||
// messages associated with a specific `OpcodeLocation`. | ||
// Otherwise return the provided opcode resolution error. | ||
if let Some(assert_message) = assert_message { | ||
ExecutionError::AssertionFailed(assert_message.to_owned(), call_stack) | ||
} else if let Some(assert_message) = circuit.get_assert_message( | ||
*call_stack.last().expect("Call stacks should not be empty"), | ||
) { | ||
ExecutionError::AssertionFailed(assert_message.to_owned(), call_stack) | ||
} else { | ||
ExecutionError::SolvingError(error) | ||
} | ||
} | ||
None => ExecutionError::SolvingError(error), | ||
})); | ||
} | ||
ACVMStatus::RequiresForeignCall(_foreign_call) => {} | ||
} | ||
} | ||
|
||
Ok(acvm.finalize()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod execute; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use std::io::Read; | ||
|
||
use acir::{circuit::Circuit, native_types::WitnessMap}; | ||
use base64::{engine::general_purpose, Engine}; | ||
use bb_rs::barretenberg_api::{ | ||
acir::{acir_create_proof, acir_get_verification_key, get_circuit_sizes, new_acir_composer}, | ||
srs::init_srs, | ||
}; | ||
use bn254_blackbox_solver::Bn254BlackBoxSolver; | ||
use flate2::bufread::GzDecoder; | ||
use nargo::ops::execute::execute_circuit; | ||
|
||
use crate::netsrs::NetSrs; | ||
|
||
pub fn prove( | ||
circuit_bytecode: String, | ||
initial_witness: WitnessMap, | ||
) -> Result<(Vec<u8>, Vec<u8>), String> { | ||
let acir_buffer = general_purpose::STANDARD | ||
.decode(circuit_bytecode) | ||
.map_err(|e| e.to_string())?; | ||
|
||
let circuit = Circuit::deserialize_circuit(&acir_buffer).map_err(|e| e.to_string())?; | ||
|
||
let mut decoder = GzDecoder::new(acir_buffer.as_slice()); | ||
let mut acir_buffer_uncompressed = Vec::<u8>::new(); | ||
decoder | ||
.read_to_end(&mut acir_buffer_uncompressed) | ||
.map_err(|e| e.to_string())?; | ||
|
||
let blackbox_solver = Bn254BlackBoxSolver::new(); | ||
|
||
let solved_witness = | ||
execute_circuit(&circuit, initial_witness, &blackbox_solver).map_err(|e| e.to_string())?; | ||
let serialized_solved_witness = | ||
bincode::serialize(&solved_witness).map_err(|e| e.to_string())?; | ||
|
||
let circuit_size = unsafe { get_circuit_sizes(&acir_buffer_uncompressed) }; | ||
let log_value = (circuit_size.total as f64).log2().ceil() as u32; | ||
let subgroup_size = 2u32.pow(log_value); | ||
|
||
let srs = NetSrs::new(subgroup_size + 1); | ||
unsafe { init_srs(&srs.data, srs.num_points, &srs.g2_data) }; | ||
|
||
let mut acir_ptr = unsafe { new_acir_composer(subgroup_size) }; | ||
|
||
Ok(( | ||
unsafe { | ||
acir_create_proof( | ||
&mut acir_ptr, | ||
&acir_buffer_uncompressed, | ||
&serialized_solved_witness, | ||
) | ||
}, | ||
unsafe { acir_get_verification_key(&mut acir_ptr) }, | ||
)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use std::io::Read; | ||
|
||
use base64::{engine::general_purpose, Engine}; | ||
use bb_rs::barretenberg_api::{ | ||
acir::{acir_load_verification_key, acir_verify_proof, get_circuit_sizes, new_acir_composer}, | ||
srs::init_srs, | ||
}; | ||
use flate2::bufread::GzDecoder; | ||
|
||
use crate::netsrs::NetSrs; | ||
|
||
pub fn verify( | ||
circuit_bytecode: String, | ||
proof: Vec<u8>, | ||
verification_key: Vec<u8>, | ||
) -> Result<bool, String> { | ||
let acir_buffer = general_purpose::STANDARD | ||
.decode(circuit_bytecode) | ||
.map_err(|e| e.to_string())?; | ||
|
||
let mut decoder = GzDecoder::new(acir_buffer.as_slice()); | ||
let mut acir_buffer_uncompressed = Vec::<u8>::new(); | ||
decoder | ||
.read_to_end(&mut acir_buffer_uncompressed) | ||
.map_err(|e| e.to_string())?; | ||
|
||
let circuit_size = unsafe { get_circuit_sizes(&acir_buffer_uncompressed) }; | ||
let log_value = (circuit_size.total as f64).log2().ceil() as u32; | ||
let subgroup_size = 2u32.pow(log_value); | ||
|
||
let srs = NetSrs::new(subgroup_size + 1); | ||
unsafe { init_srs(&srs.data, srs.num_points, &srs.g2_data) }; | ||
|
||
let mut acir_ptr = unsafe { new_acir_composer(subgroup_size) }; | ||
unsafe { acir_load_verification_key(&mut acir_ptr, &verification_key) }; | ||
Ok(unsafe { acir_verify_proof(&mut acir_ptr, &proof) }) | ||
} |