Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

feat!: Implement CommonReferenceString trait #139

Merged
merged 21 commits into from
May 16, 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
44 changes: 29 additions & 15 deletions Cargo.lock

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

21 changes: 8 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ license = "MIT OR Apache-2.0"
acvm = { version = "0.11.0", features = ["bn254"] }

thiserror = "1.0.21"
serde = { version = "1.0.136", features = ["derive"] }
bincode = "1.3.3"
bytes = "1.4"

dirs = { version = "3.0", optional = true }
reqwest = { version = "0.11.16", optional = true, default-features = false, features = [
"stream",
"rustls-tls",
] }
tokio = { version = "1.0", optional = true }
reqwest = { version = "0.11.16", optional = true, default-features = false, features = ["stream", "rustls-tls"] }
futures-util = { version = "0.3.14", optional = true }
indicatif = { version = "0.17.3", optional = true }

Expand All @@ -42,16 +40,15 @@ pkg-config = "0.3"
blake2 = "0.10.6"
sled = "0.34.6"
tempfile = "3.3"
tokio = "1.0"

[features]
default = ["native"]
native = [
"dep:barretenberg-sys",
"dep:reqwest",
"dep:tokio",
"dep:futures-util",
"dep:dirs",
"dep:indicatif",
"dep:indicatif"
]
wasm = [
"wasmer",
Expand All @@ -63,10 +60,8 @@ wasm = [
"wasmer/default-cranelift",
"wasmer/default-universal",
"dep:reqwest",
"dep:tokio",
"dep:futures-util",
"dep:dirs",
"dep:indicatif",
"dep:indicatif"
]
js = [
"wasmer",
Expand All @@ -76,4 +71,4 @@ js = [
]

[patch.crates-io]
acvm = { git = "https://github.com/noir-lang/acvm", rev = "bbd9ab7ca5be3fb31f3e141fee2522704852f5de" }
acvm = { package = "acvm", git = "https://github.com/noir-lang/acvm", rev = "eeddcf179880f246383f7f67a11e589269c4e3ff" }
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"envrc",
"subshell",
"thiserror",
"bincode",
// In Solidity
//
"addmod",
Expand Down
41 changes: 35 additions & 6 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@
# Note: Setting this allows for consistent behavior across build and shells, but is mostly
# hidden from the developer - i.e. when they see the command being run via `nix flake check`
RUST_TEST_THREADS = "1";

# We provide `barretenberg-transcript00` from the overlay to the build.
# This is necessary because the Nix sandbox is read-only and downloading during tests would fail
BARRETENBERG_TRANSCRIPT = pkgs.barretenberg-transcript00;
};

nativeEnvironment = sharedEnvironment // {
Expand Down Expand Up @@ -153,6 +149,27 @@
buildInputs = [ ] ++ extraBuildInputs;
};

# The `port` is parameterized to support parallel test runs without colliding static servers
networkTestArgs = port: {
# We provide `barretenberg-transcript00` from the overlay to the tests as a URL hosted via a static server
# This is necessary because the Nix sandbox has no network access and downloading during tests would fail
TRANSCRIPT_URL = "http://0.0.0.0:${toString port}/${builtins.baseNameOf pkgs.barretenberg-transcript00}";

# This copies the `barretenberg-transcript00` from the Nix store into this sandbox
# which avoids exposing the entire Nix store to the static server it starts
# The static server is moved to the background and killed after checks are completed
preCheck = ''
cp ${pkgs.barretenberg-transcript00} .
echo "Starting simple static server"
${pkgs.simple-http-server}/bin/simple-http-server --port ${toString port} --silent &
HTTP_SERVER_PID=$!
'';

postCheck = ''
kill $HTTP_SERVER_PID
'';
};
kobyhallx marked this conversation as resolved.
Show resolved Hide resolved

# Build *just* the cargo dependencies, so we can reuse all of that work between runs
native-cargo-artifacts = craneLib.buildDepsOnly nativeArgs;
wasm-cargo-artifacts = craneLib.buildDepsOnly wasmArgs;
Expand All @@ -167,25 +184,37 @@
rec {
checks = {
cargo-clippy-native = craneLib.cargoClippy (nativeArgs // {
# Crane appends "clippy"
pname = "native";

cargoArtifacts = native-cargo-artifacts;

cargoClippyExtraArgs = "--all-targets -- -D warnings";
});

cargo-test-native = craneLib.cargoTest (nativeArgs // {
cargo-test-native = craneLib.cargoTest (nativeArgs // (networkTestArgs 8000) // {
# Crane appends "test"
pname = "native";

cargoArtifacts = native-cargo-artifacts;

# It's unclear why doCheck needs to be enabled for tests to run but not clippy
doCheck = true;
});

cargo-clippy-wasm = craneLib.cargoClippy (wasmArgs // {
# Crane appends "clippy"
pname = "wasm";

cargoArtifacts = wasm-cargo-artifacts;

cargoClippyExtraArgs = "--all-targets -- -D warnings";
});

cargo-test-wasm = craneLib.cargoTest (wasmArgs // {
cargo-test-wasm = craneLib.cargoTest (wasmArgs // (networkTestArgs 8001) // {
# Crane appends "test"
pname = "wasm";

cargoArtifacts = wasm-cargo-artifacts;

# It's unclear why doCheck needs to be enabled for tests to run but not clippy
Expand Down
34 changes: 34 additions & 0 deletions src/acvm_interop/common_reference_string.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use acvm::{acir::circuit::Circuit, async_trait, CommonReferenceString};

use crate::{composer::Composer, BackendError, Barretenberg};

// TODO: Separate impl for JS feature
#[async_trait]
impl CommonReferenceString for Barretenberg {
type Error = BackendError;

async fn generate_common_reference_string(
&self,
circuit: &Circuit,
) -> Result<Vec<u8>, Self::Error> {
let constraint_system = &circuit.try_into()?;
let common_reference_string = self.get_crs(constraint_system).await?.try_into()?;
// Separated to have nicer coercion on error types
Ok(common_reference_string)
}

async fn update_common_reference_string(
&self,
common_reference_string: Vec<u8>,
circuit: &Circuit,
) -> Result<Vec<u8>, Self::Error> {
let mut crs = common_reference_string.try_into()?;
let constraint_system = &circuit.try_into()?;
let common_reference_string = self
.update_crs(&mut crs, constraint_system)
.await?
.try_into()?;
// Separated to have nicer coercion on error types
Ok(common_reference_string)
}
}
1 change: 1 addition & 0 deletions src/acvm_interop/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::Barretenberg;

mod common_reference_string;
mod proof_system;
mod pwg;
mod smart_contract;
Expand Down
20 changes: 14 additions & 6 deletions src/acvm_interop/proof_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ use acvm::acir::{circuit::Circuit, native_types::WitnessMap, BlackBoxFunc};
use acvm::FieldElement;
use acvm::{Language, ProofSystemCompiler};

use crate::barretenberg_structures::Assignments;
use crate::composer::Composer;
use crate::{BackendError, Barretenberg};
use crate::{barretenberg_structures::Assignments, composer::Composer, BackendError, Barretenberg};

impl ProofSystemCompiler for Barretenberg {
type Error = BackendError;
Expand Down Expand Up @@ -39,40 +37,50 @@ impl ProofSystemCompiler for Barretenberg {
}
}

fn preprocess(&self, circuit: &Circuit) -> Result<(Vec<u8>, Vec<u8>), Self::Error> {
fn preprocess(
&self,
common_reference_string: &[u8],
circuit: &Circuit,
) -> Result<(Vec<u8>, Vec<u8>), Self::Error> {
let crs = common_reference_string.try_into()?;
let constraint_system = &circuit.try_into()?;

let proving_key = self.compute_proving_key(constraint_system)?;
let verification_key = self.compute_verification_key(constraint_system, &proving_key)?;
let verification_key = self.compute_verification_key(&crs, &proving_key)?;

Ok((proving_key, verification_key))
}

fn prove_with_pk(
&self,
common_reference_string: &[u8],
circuit: &Circuit,
witness_values: WitnessMap,
proving_key: &[u8],
) -> Result<Vec<u8>, Self::Error> {
let crs = common_reference_string.try_into()?;
let assignments = flatten_witness_map(circuit, witness_values);

Ok(self.create_proof_with_pk(&circuit.try_into()?, assignments, proving_key)?)
Ok(self.create_proof_with_pk(&crs, &circuit.try_into()?, assignments, proving_key)?)
}

fn verify_with_vk(
&self,
common_reference_string: &[u8],
proof: &[u8],
public_inputs: WitnessMap,
circuit: &Circuit,
verification_key: &[u8],
) -> Result<bool, Self::Error> {
let crs = common_reference_string.try_into()?;
// Unlike when proving, we omit any unassigned witnesses.
// Witness values should be ordered by their index but we skip over any indices without an assignment.
let flattened_public_inputs: Vec<FieldElement> =
public_inputs.into_iter().map(|(_, el)| el).collect();

Ok(Composer::verify_with_vk(
self,
&crs,
&circuit.try_into()?,
proof,
flattened_public_inputs.into(),
Expand Down
Loading