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

chore: pull acvm-backend-barretenberg into main Noir repo #2495

Merged
merged 3 commits into from
Aug 31, 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
79 changes: 44 additions & 35 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]

members = [
"crates/acvm_backend_barretenberg",
"crates/noirc_evaluator",
"crates/noirc_frontend",
"crates/noirc_errors",
Expand Down
1 change: 1 addition & 0 deletions crates/acvm_backend_barretenberg/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!src/witness.tr
233 changes: 233 additions & 0 deletions crates/acvm_backend_barretenberg/CHANGELOG.md

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions crates/acvm_backend_barretenberg/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[package]
name = "acvm-backend-barretenberg"
description = "An ACVM backend which allows proving/verifying ACIR circuits against Aztec Lab's Barretenberg library."
version = "0.11.0"
authors.workspace = true
edition.workspace = true
rust-version = "1.66"
license = "MIT OR Apache-2.0"

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

[dependencies]
acvm.workspace = true
dirs.workspace = true
thiserror.workspace = true
base64.workspace = true

tempfile = "3.6.0"

## bb binary downloading
const_format = "0.2.30"
tar = "~0.4.15"
flate2 = "~1.0.1"
reqwest = { version = "0.11.16", default-features = false, features = [
"rustls-tls",
"blocking",
] }

[dev-dependencies]
serial_test = "2.0.0"

[build-dependencies]
build-target = "0.4.0"
32 changes: 32 additions & 0 deletions crates/acvm_backend_barretenberg/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use build_target::{Arch, Os};

// Useful for printing debugging messages during the build
// macro_rules! p {
// ($($tokens: tt)*) => {
// println!("cargo:warning={}", format!($($tokens)*))
// }
// }

fn main() -> Result<(), String> {
// We need to inject which OS we're building for so that we can download the correct barretenberg binary.
let os = match build_target::target_os().unwrap() {
os @ (Os::Linux | Os::MacOs) => os,
Os::Windows => todo!("Windows is not currently supported"),
os_name => panic!("Unsupported OS {}", os_name),
};

let arch = match build_target::target_arch().unwrap() {
arch @ (Arch::X86_64 | Arch::AARCH64) => arch,
arch_name => panic!("Unsupported Architecture {}", arch_name),
};

// Arm builds of linux are not supported
if let (Os::Linux, Arch::AARCH64) = (&os, &arch) {
panic!("ARM64 builds of linux are not supported")
};

println!("cargo:rustc-env=TARGET_OS={os}");
println!("cargo:rustc-env=TARGET_ARCH={arch}");

Ok(())
}
1 change: 1 addition & 0 deletions crates/acvm_backend_barretenberg/src/1_mul.bytecode
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
H4sIAAAAAAAA/+2Z326CMBTGP2SIyCTLsmw3u+ARWv5ouZuPMjN8/0fYyFo5MHbFV6KJJyG1jf16/vT8NPoG4B2/Fvw8KzvmYr4azUM7D+0Dsb+zDzuqeabdeeDqKkzYTG3tUftyhszFgx0jsZbY0dWss7WoTSj2HsW+QIyB0DiKPVPvCf7RScSa258JX8DLiVqDfu9UJjTZDl8udVeEHH1TRXYO+GuksW6p9lXVHopWl/pTFc3J1KqqT3ujja5N/VWYsmxNZQ7NqTmoRldlq891U56t8BP8NGXI8bOwfuoHYswRsS7M/PmGcYQhbFh+Y8Jmai8OYwe2WKzdYczRXATGneM5ehjH8Adj10hsGD/jNmC8JsYcE+vCzJ9vGMcYwoblNyZspvbiMN7YUYLvDmOO5iIw7gqYo4dxAn8wdo3EhvELbgPGG2LMCbEuzPz5hnGCYWOz/MaEzdReHMZbO6Zi7Q5jjuYiMO4KmKOHcQp/MHaNxIbxK24DxltizCmxLleev0vMITHmlOjXI7gfZn+aHvxeZPos/d2J1+437NXEnfAATI3ROeM8egWqryLtPOhm4F1+X3Fn/BoN4HTNOZXfdtwfcmP7BvHx78jZGwAA
76 changes: 76 additions & 0 deletions crates/acvm_backend_barretenberg/src/bb/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use super::{assert_binary_exists, get_binary_path, CliShimError};

/// VerifyCommand will call the barretenberg binary
/// to return a solidity library with the verification key
/// that can be used to verify proofs on-chain.
///
/// This does not return a Solidity file that is able
/// to verify a proof. See acvm_interop/contract.sol for the
/// remaining logic that is missing.
pub(crate) struct ContractCommand {
pub(crate) verbose: bool,
pub(crate) path_to_crs: String,
pub(crate) path_to_vk: String,
pub(crate) path_to_contract: String,
}

impl ContractCommand {
pub(crate) fn run(self) -> Result<(), CliShimError> {
assert_binary_exists();
let mut command = std::process::Command::new(get_binary_path());

command
.arg("contract")
.arg("-c")
.arg(self.path_to_crs)
.arg("-k")
.arg(self.path_to_vk)
.arg("-o")
.arg(self.path_to_contract);

if self.verbose {
command.arg("-v");
}

let output = command.output().expect("Failed to execute command");
if output.status.success() {
Ok(())
} else {
Err(CliShimError(String::from_utf8(output.stderr).unwrap()))
}
}
}

#[test]
#[serial_test::serial]
fn contract_command() {
use tempfile::tempdir;

let path_to_1_mul = "./src/1_mul.bytecode";

let temp_directory = tempdir().expect("could not create a temporary directory");
let temp_directory_path = temp_directory.path();
let path_to_crs = temp_directory_path.join("crs");
let path_to_vk = temp_directory_path.join("vk");
let path_to_contract = temp_directory_path.join("contract");

let write_vk_command = super::WriteVkCommand {
verbose: true,
path_to_bytecode: path_to_1_mul.to_string(),
path_to_vk_output: path_to_vk.to_str().unwrap().to_string(),
is_recursive: false,
path_to_crs: path_to_crs.to_str().unwrap().to_string(),
};

assert!(write_vk_command.run().is_ok());

let contract_command = ContractCommand {
verbose: true,
path_to_vk: path_to_vk.to_str().unwrap().to_string(),
path_to_crs: path_to_crs.to_str().unwrap().to_string(),
path_to_contract: path_to_contract.to_str().unwrap().to_string(),
};

assert!(contract_command.run().is_ok());
drop(temp_directory);
}
72 changes: 72 additions & 0 deletions crates/acvm_backend_barretenberg/src/bb/gates.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use super::{assert_binary_exists, get_binary_path};

/// GatesCommand will call the barretenberg binary
/// to return the number of gates needed to create a proof
/// for the given bytecode.
pub(crate) struct GatesCommand {
pub(crate) path_to_crs: String,
pub(crate) path_to_bytecode: String,
}

impl GatesCommand {
pub(crate) fn run(self) -> u32 {
assert_binary_exists();
let output = std::process::Command::new(get_binary_path())
.arg("gates")
.arg("-c")
.arg(self.path_to_crs)
.arg("-b")
.arg(self.path_to_bytecode)
.output()
.expect("Failed to execute command");

if !output.status.success() {
panic!(
"gates command encountered an error: {}",
String::from_utf8_lossy(&output.stderr)
);
}
// Note: barretenberg includes the newline, so that subsequent prints to stdout
// are not on the same line as the gates output.

// Ensure we got the expected number of bytes
if output.stdout.len() != 8 {
panic!("Unexpected 8 bytes, received {}", output.stdout.len());
}

// Convert bytes to u64 in little-endian format
let value = u64::from_le_bytes([
output.stdout[0],
output.stdout[1],
output.stdout[2],
output.stdout[3],
output.stdout[4],
output.stdout[5],
output.stdout[6],
output.stdout[7],
]);

value as u32
}
}

#[test]
#[serial_test::serial]
fn gate_command() {
use tempfile::tempdir;

let path_to_1_mul = "./src/1_mul.bytecode";

let temp_directory = tempdir().expect("could not create a temporary directory");
let temp_directory_path = temp_directory.path();
let path_to_crs = temp_directory_path.join("crs");

let gate_command = GatesCommand {
path_to_crs: path_to_crs.to_str().unwrap().to_string(),
path_to_bytecode: path_to_1_mul.to_string(),
};

let output = gate_command.run();
assert_eq!(output, 2775);
drop(temp_directory);
}
Loading