Skip to content

Commit

Permalink
chore: encapsulate abstraction leaks from bb into new crate (#2747)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench authored Sep 19, 2023
1 parent ddb05ab commit fb9ee4f
Show file tree
Hide file tree
Showing 39 changed files with 122 additions and 90 deletions.
49 changes: 30 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ members = [
"compiler/utils/arena",
"compiler/utils/iter-extended",
# Crates related to tooling built ontop of the Noir compiler
"tooling/acvm_backend_barretenberg",
"tooling/backend_interface",
"tooling/bb_abstraction_leaks",
"tooling/nargo",
"tooling/nargo_cli",
"tooling/nargo_toml",
Expand Down Expand Up @@ -41,6 +42,7 @@ nargo_cli = { path = "tooling/nargo_cli" }
nargo_toml = { path = "tooling/nargo_toml" }
noir_lsp = { path = "tooling/lsp" }
noirc_abi = { path = "tooling/noirc_abi" }
bb_abstraction_leaks = { path = "tooling/bb_abstraction_leaks" }
noirc_driver = { path = "compiler/noirc_driver" }
noirc_errors = { path = "compiler/noirc_errors" }
noirc_evaluator = { path = "compiler/noirc_evaluator" }
Expand Down
1 change: 0 additions & 1 deletion tooling/acvm_backend_barretenberg/.gitignore

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "acvm-backend-barretenberg"
description = "An ACVM backend which allows proving/verifying ACIR circuits against Aztec Lab's Barretenberg library."
name = "backend-interface"
description = "The definition of the backend CLI interface which Nargo uses for proving/verifying ACIR circuits."
version = "0.11.0"
authors.workspace = true
edition.workspace = true
Expand All @@ -15,6 +15,7 @@ dirs.workspace = true
thiserror.workspace = true
serde.workspace = true
serde_json.workspace = true
bb_abstraction_leaks.workspace = true

tempfile = "3.6.0"

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ mod proof_system;
mod smart_contract;

use acvm::acir::circuit::Opcode;
use bb_abstraction_leaks::ACVM_BACKEND_BARRETENBERG;
pub use download::download_backend;

const BACKENDS_DIR: &str = ".nargo/backends";
pub const ACVM_BACKEND_BARRETENBERG: &str = "acvm-backend-barretenberg";

pub fn backends_directory() -> PathBuf {
let home_directory = dirs::home_dir().unwrap();
Expand Down Expand Up @@ -65,6 +65,10 @@ impl Backend {
Backend { name, binary_path }
}

pub fn name(&self) -> &str {
&self.name
}

fn binary_path(&self) -> &PathBuf {
&self.binary_path
}
Expand All @@ -77,7 +81,7 @@ impl Backend {
if self.name == ACVM_BACKEND_BARRETENBERG {
// If we're trying to use barretenberg, automatically go and install it.
let bb_url = std::env::var("BB_BINARY_URL")
.unwrap_or_else(|_| env!("BB_BINARY_URL").to_string());
.unwrap_or_else(|_| bb_abstraction_leaks::BB_DOWNLOAD_URL.to_owned());
download_backend(&bb_url, binary_path)?;
return Ok(binary_path);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,10 @@ impl Backend {
}
.run(binary_path)?;

// Barretenberg return the proof prepended with the public inputs.
//
// This is not how the API expects the proof to be formatted,
// so we remove the public inputs from the proof.
//
// TODO: As noted in the verification procedure, this is an abstraction leak
// TODO: and will need modifications to barretenberg
let proof =
remove_public_inputs(circuit.public_inputs().0.len(), &proof_with_public_inputs);
let proof = bb_abstraction_leaks::remove_public_inputs(
circuit.public_inputs().0.len(),
&proof_with_public_inputs,
);
Ok(proof)
}

Expand All @@ -92,12 +87,10 @@ impl Backend {
let flattened_public_inputs: Vec<FieldElement> =
public_inputs.into_iter().map(|(_, el)| el).collect();

// Barretenberg expects the proof to be prepended with the public inputs.
//
// TODO: This is an abstraction leak and barretenberg's API should accept the public inputs
// TODO: separately and then prepend them internally
let proof_with_public_inputs =
prepend_public_inputs(proof.to_vec(), flattened_public_inputs.to_vec());
let proof_with_public_inputs = bb_abstraction_leaks::prepend_public_inputs(
proof.to_vec(),
flattened_public_inputs.to_vec(),
);

// Create a temporary file for the proof
let proof_path = temp_directory.join("proof").with_extension("proof");
Expand Down Expand Up @@ -139,26 +132,6 @@ pub(super) fn write_to_file(bytes: &[u8], path: &Path) -> String {
}
}

/// Removes the public inputs which are prepended to a proof by Barretenberg.
fn remove_public_inputs(num_pub_inputs: usize, proof: &[u8]) -> Vec<u8> {
// Barretenberg prepends the public inputs onto the proof so we need to remove
// the first `num_pub_inputs` field elements.
let num_bytes_to_remove = num_pub_inputs * (FieldElement::max_num_bytes() as usize);
proof[num_bytes_to_remove..].to_vec()
}

/// Prepends a set of public inputs to a proof.
fn prepend_public_inputs(proof: Vec<u8>, public_inputs: Vec<FieldElement>) -> Vec<u8> {
if public_inputs.is_empty() {
return proof;
}

let public_inputs_bytes =
public_inputs.into_iter().flat_map(|assignment| assignment.to_be_bytes());

public_inputs_bytes.chain(proof).collect()
}

// TODO: See nargo/src/artifacts/mod.rs
// TODO: This method should live in ACVM and be the default method for serializing/deserializing circuits
pub(super) fn serialize_circuit(circuit: &Circuit) -> Vec<u8> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ use crate::{
use acvm::acir::circuit::Circuit;
use tempfile::tempdir;

/// Embed the Solidity verifier file
const ULTRA_VERIFIER_CONTRACT: &str = include_str!("contract.sol");

impl Backend {
pub fn eth_contract(&self, circuit: &Circuit) -> Result<String, BackendError> {
let binary_path = self.assert_binary_exists()?;
Expand All @@ -32,11 +29,7 @@ impl Backend {
}
.run(binary_path)?;

let verification_key_library =
ContractCommand { crs_path: self.crs_directory(), vk_path }.run(binary_path)?;

drop(temp_directory);
Ok(format!("{verification_key_library}{ULTRA_VERIFIER_CONTRACT}"))
ContractCommand { crs_path: self.crs_directory(), vk_path }.run(binary_path)
}
}

Expand Down Expand Up @@ -67,9 +60,7 @@ mod tests {

let contract = get_mock_backend()?.eth_contract(&circuit)?;

assert!(contract.contains("contract BaseUltraVerifier"));
assert!(contract.contains("contract UltraVerifier"));
assert!(contract.contains("library UltraVerificationKey"));
assert!(contract.contains("contract VerifierContract"));

Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,5 @@ pub(crate) struct ContractCommand {
pub(crate) fn run(args: ContractCommand) {
assert!(args.vk_path.is_file(), "Could not find vk file at provided path");

std::io::stdout()
.write_all(
b"contract BaseUltraVerifier contract UltraVerifier library UltraVerificationKey",
)
.unwrap();
std::io::stdout().write_all(b"contract VerifierContract {}").unwrap();
}
17 changes: 17 additions & 0 deletions tooling/bb_abstraction_leaks/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "bb_abstraction_leaks"
description = "A crate which encapsulates knowledge about Barretenberg which is currently leaking into Nargo"
version = "0.11.0"
authors.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
acvm.workspace = true

[build-dependencies]
build-target = "0.4.0"
const_format = "0.2.30"
File renamed without changes.
34 changes: 34 additions & 0 deletions tooling/bb_abstraction_leaks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#![warn(unused_crate_dependencies, unused_extern_crates)]
#![warn(unreachable_pub)]

use acvm::FieldElement;

pub const ACVM_BACKEND_BARRETENBERG: &str = "acvm-backend-barretenberg";
pub const BB_DOWNLOAD_URL: &str = env!("BB_BINARY_URL");

/// Embed the Solidity verifier file
const ULTRA_VERIFIER_CONTRACT: &str = include_str!("contract.sol");

pub fn complete_barretenberg_verifier_contract(contract: String) -> String {
format!("{contract}{ULTRA_VERIFIER_CONTRACT}")
}

/// Removes the public inputs which are prepended to a proof by Barretenberg.
pub fn remove_public_inputs(num_pub_inputs: usize, proof: &[u8]) -> Vec<u8> {
// Barretenberg prepends the public inputs onto the proof so we need to remove
// the first `num_pub_inputs` field elements.
let num_bytes_to_remove = num_pub_inputs * (FieldElement::max_num_bytes() as usize);
proof[num_bytes_to_remove..].to_vec()
}

/// Prepends a set of public inputs to a proof.
pub fn prepend_public_inputs(proof: Vec<u8>, public_inputs: Vec<FieldElement>) -> Vec<u8> {
if public_inputs.is_empty() {
return proof;
}

let public_inputs_bytes =
public_inputs.into_iter().flat_map(|assignment| assignment.to_be_bytes());

public_inputs_bytes.chain(proof).collect()
}
3 changes: 2 additions & 1 deletion tooling/nargo_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ color-eyre = "0.6.2"
tokio = { version = "1.0", features = ["io-std"] }

# Backends
acvm-backend-barretenberg = { path = "../acvm_backend_barretenberg" }
backend-interface = { path = "../backend_interface" }
bb_abstraction_leaks.workspace = true

[target.'cfg(not(unix))'.dependencies]
tokio-util = { version = "0.7.8", features = ["compat"] }
Expand Down
4 changes: 2 additions & 2 deletions tooling/nargo_cli/src/backends.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::PathBuf;

use acvm_backend_barretenberg::backends_directory;
pub(crate) use acvm_backend_barretenberg::Backend;
use backend_interface::backends_directory;
pub(crate) use backend_interface::Backend;

fn active_backend_file_path() -> PathBuf {
backends_directory().join(".selected_backend")
Expand Down
2 changes: 1 addition & 1 deletion tooling/nargo_cli/src/cli/backend_cmd/install_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::Args;

use acvm_backend_barretenberg::{backends_directory, download_backend};
use backend_interface::{backends_directory, download_backend};

use crate::errors::{BackendError, CliError};

Expand Down
2 changes: 1 addition & 1 deletion tooling/nargo_cli/src/cli/backend_cmd/ls_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use acvm_backend_barretenberg::backends_directory;
use backend_interface::backends_directory;
use clap::Args;

use crate::errors::CliError;
Expand Down
2 changes: 1 addition & 1 deletion tooling/nargo_cli/src/cli/backend_cmd/uninstall_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::Args;

use acvm_backend_barretenberg::backends_directory;
use backend_interface::backends_directory;

use crate::{
backends::{
Expand Down
8 changes: 7 additions & 1 deletion tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::errors::CliError;

use acvm::acir::circuit::Opcode;
use acvm::Language;
use bb_abstraction_leaks::ACVM_BACKEND_BARRETENBERG;
use clap::Args;
use nargo::artifacts::program::PreprocessedProgram;
use nargo::package::Package;
Expand Down Expand Up @@ -91,7 +92,12 @@ fn smart_contract_for_package(
}
};

let smart_contract_string = backend.eth_contract(&preprocessed_program.bytecode)?;
let mut smart_contract_string = backend.eth_contract(&preprocessed_program.bytecode)?;

if backend.name() == ACVM_BACKEND_BARRETENBERG {
smart_contract_string =
bb_abstraction_leaks::complete_barretenberg_verifier_contract(smart_contract_string);
}

Ok(smart_contract_string)
}
2 changes: 1 addition & 1 deletion tooling/nargo_cli/src/cli/compile_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::path::Path;

use acvm::acir::circuit::Opcode;
use acvm::Language;
use acvm_backend_barretenberg::BackendOpcodeSupport;
use backend_interface::BackendOpcodeSupport;
use fm::FileManager;
use iter_extended::vecmap;
use nargo::artifacts::contract::PreprocessedContract;
Expand Down
2 changes: 1 addition & 1 deletion tooling/nargo_cli/src/cli/info_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use acvm::Language;
use acvm_backend_barretenberg::BackendError;
use backend_interface::BackendError;
use clap::Args;
use iter_extended::vecmap;
use nargo::package::Package;
Expand Down
2 changes: 1 addition & 1 deletion tooling/nargo_cli/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub(crate) enum CliError {

/// Error related to communication with backend.
#[error(transparent)]
BackendCommunicationError(#[from] acvm_backend_barretenberg::BackendError),
BackendCommunicationError(#[from] backend_interface::BackendError),
}

#[derive(Debug, thiserror::Error)]
Expand Down
Loading

0 comments on commit fb9ee4f

Please sign in to comment.