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!: Update to ACVM 0.18.1 and implement missing brillig blackboxes #1914

Merged
merged 7 commits into from
Jul 12, 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
69 changes: 45 additions & 24 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ edition = "2021"
rust-version = "1.66"

[workspace.dependencies]
acvm = "0.17.0"
acvm = "0.18.1"
arena = { path = "crates/arena" }
fm = { path = "crates/fm" }
iter-extended = { path = "crates/iter-extended" }
Expand Down
5 changes: 3 additions & 2 deletions crates/nargo/src/ops/codegen_verifier.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use acvm::SmartContract;
use acvm::{acir::circuit::Circuit, SmartContract};

pub fn codegen_verifier<B: SmartContract>(
backend: &B,
common_reference_string: &[u8],
circuit: &Circuit,
verification_key: &[u8],
) -> Result<String, B::Error> {
backend.eth_contract_from_vk(common_reference_string, verification_key)
backend.eth_contract_from_vk(common_reference_string, circuit, verification_key)
}
2 changes: 1 addition & 1 deletion crates/nargo/src/ops/execute.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use acvm::acir::brillig_vm::{ForeignCallResult, Value};
use acvm::acir::brillig::{ForeignCallResult, Value};
use acvm::pwg::{ACVMStatus, ForeignCallWaitInfo, ACVM};
use acvm::BlackBoxFunctionSolver;
use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap};
Expand Down
2 changes: 1 addition & 1 deletion crates/nargo_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ color-eyre = "0.6.2"
tokio = { version = "1.0", features = ["io-std"] }

# Backends
acvm-backend-barretenberg = { version = "0.7.0", default-features = false }
acvm-backend-barretenberg = { version = "0.8.0", default-features = false }

[dev-dependencies]
tempdir = "0.3.7"
Expand Down
10 changes: 7 additions & 3 deletions crates/nargo_cli/src/cli/codegen_verifier_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,13 @@ pub(crate) fn run<B: Backend>(
let verification_key = preprocessed_program
.verification_key
.expect("Verification key should exist as `true` is passed to `preprocess_program`");
let smart_contract_string =
codegen_verifier(backend, &common_reference_string, &verification_key)
.map_err(CliError::SmartContractError)?;
let smart_contract_string = codegen_verifier(
backend,
&common_reference_string,
&preprocessed_program.bytecode,
&verification_key,
)
.map_err(CliError::SmartContractError)?;

write_cached_common_reference_string(&common_reference_string);

Expand Down
17 changes: 6 additions & 11 deletions crates/nargo_cli/src/cli/compile_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use acvm::{acir::circuit::Circuit, compiler::CircuitSimplifier, Backend};
use acvm::{acir::circuit::Circuit, Backend};
use iter_extended::try_vecmap;
use nargo::{artifacts::contract::PreprocessedContract, NargoError};
use noirc_driver::{
Expand Down Expand Up @@ -135,16 +135,11 @@ pub(super) fn optimize_circuit<B: Backend>(
backend: &B,
circuit: Circuit,
) -> Result<Circuit, CliError<B>> {
// Note that this makes the `CircuitSimplifier` a noop.
// The `CircuitSimplifier` should be reworked to not rely on values being inserted during ACIR gen.
let simplifier = CircuitSimplifier::new(0);
let optimized_circuit = acvm::compiler::compile(
circuit,
backend.np_language(),
|opcode| backend.supports_opcode(opcode),
&simplifier,
)
.map_err(|_| NargoError::CompilationError)?;
let (optimized_circuit, _): (Circuit, Vec<acvm::acir::circuit::OpcodeLabel>) =
acvm::compiler::compile(circuit, backend.np_language(), |opcode| {
backend.supports_opcode(opcode)
})
.map_err(|_| NargoError::CompilationError)?;

Ok(optimized_circuit)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
x = "0"
y = "1"
salt = "42"

out_x = "0x0c5e1ddecd49de44ed5e5798d3f6fb7c71fe3d37f5bee8664cf88a445b5ba0af"
out_y = "0x230294a041e26fe80b827c2ef5cb8784642bbaa83842da2714d62b1f3c4f9752"
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use dep::std;

unconstrained fn main(x: Field, y: Field, salt: Field, out_x: Field, out_y: Field ) {
let res = std::hash::pedersen_with_separator([x, y], 0);
assert(res[0] == out_x);
assert(res[1] == out_y);

let raw_data = [x,y];
let mut state = 0;
for i in 0..(2 as u32) {
state = state * 8 + raw_data[i];
}
state += salt;
let hash = std::hash::pedersen_with_separator([state], 0);
assert(std::hash::pedersen_with_separator([43], 0)[0] == hash[0]);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
a = "1"
a_pub_x = "0x0000000000000000000000000000000000000000000000000000000000000001"
a_pub_y = "0x0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c"

b = "2"
b_pub_x = "0x06ce1b0827aafa85ddeb49cdaa36306d19a74caa311e13d46d8bc688cdbffffe"
b_pub_y = "0x1c122f81a3a14964909ede0ba2a6855fc93faf6fa1a788bf467be7e7a43f80ac"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use dep::std;

unconstrained fn main(
a: Field,
a_pub_x: pub Field,
a_pub_y: pub Field,
b: Field,
b_pub_x: pub Field,
b_pub_y: pub Field
) {
let mut priv_key = a;
let mut pub_x: Field = a_pub_x;
let mut pub_y: Field = a_pub_y;
if a != 1 { // Change `a` in Prover.toml to test input `b`
priv_key = b;
pub_x = b_pub_x;
pub_y = b_pub_y;
}
let res = std::scalar_mul::fixed_base(priv_key);
assert(res[0] == pub_x);
assert(res[1] == pub_y);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
message = [0,1,2,3,4,5,6,7,8,9]
pub_key_x = "0x17cbd3ed3151ccfd170efe1d54280a6a4822640bf5c369908ad74ea21518a9c5"
pub_key_y = "0x0e0456e3795c1a31f20035b741cd6158929eeccd320d299cfcac962865a6bc74"
signature = [
5, 202, 31, 146, 81, 242, 246, 69, 43, 107, 249, 153, 198, 44, 14, 111, 191, 121, 137, 166,
160, 103, 18, 181, 243, 233, 226, 95, 67, 16, 37, 128, 85, 76, 19, 253, 30, 77, 192, 53, 138,
205, 69, 33, 236, 163, 83, 194, 84, 137, 184, 221, 176, 121, 179, 27, 63, 70, 54, 16, 176,
250, 39, 239,
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use dep::std;

// Note: If main has any unsized types, then the verifier will never be able
// to figure out the circuit instance
unconstrained fn main(message: [u8; 10], pub_key_x: Field, pub_key_y: Field, signature: [u8; 64]) {
// Is there ever a situation where someone would want
// to ensure that a signature was invalid?
let valid_signature = std::schnorr::verify_signature(pub_key_x,pub_key_y,signature, message);
assert(valid_signature);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use acvm::acir::{
brillig_vm::{BlackBoxOp, HeapVector, RegisterOrMemory},
brillig::{BlackBoxOp, HeapVector, RegisterOrMemory},
BlackBoxFunc,
};

Expand Down Expand Up @@ -96,6 +96,57 @@ pub(crate) fn convert_black_box_call(
)
}
}
BlackBoxFunc::Pedersen => {
if let (
[RegisterOrMemory::HeapArray(message_array), RegisterOrMemory::RegisterIndex(domain_separator)],
[RegisterOrMemory::HeapArray(result_array)],
) = (function_arguments, function_results)
{
let message_vector = brillig_context.array_to_vector(message_array);
brillig_context.black_box_op_instruction(BlackBoxOp::Pedersen {
inputs: message_vector,
domain_separator: *domain_separator,
output: *result_array,
});
} else {
unreachable!("ICE: Pedersen expects one array argument, a register for the domain separator, and one array result")
}
}
BlackBoxFunc::SchnorrVerify => {
if let (
[RegisterOrMemory::RegisterIndex(public_key_x), RegisterOrMemory::RegisterIndex(public_key_y), RegisterOrMemory::HeapArray(signature), RegisterOrMemory::HeapArray(message_hash)],
[RegisterOrMemory::RegisterIndex(result_register)],
) = (function_arguments, function_results)
{
let message_hash = brillig_context.array_to_vector(message_hash);
let signature = brillig_context.array_to_vector(signature);
brillig_context.black_box_op_instruction(BlackBoxOp::SchnorrVerify {
public_key_x: *public_key_x,
public_key_y: *public_key_y,
message: message_hash,
signature,
result: *result_register,
});
} else {
unreachable!("ICE: Schnorr verify expects two registers for the public key, an array for signature, an array for the message hash and one result register")
}
}
BlackBoxFunc::FixedBaseScalarMul => {
if let (
[RegisterOrMemory::RegisterIndex(scalar)],
[RegisterOrMemory::HeapArray(result_array)],
) = (function_arguments, function_results)
{
brillig_context.black_box_op_instruction(BlackBoxOp::FixedBaseScalarMul {
input: *scalar,
result: *result_array,
});
} else {
unreachable!(
"ICE: FixedBaseScalarMul expects one register argument and one array result"
)
}
}
_ => unimplemented!("ICE: Black box function {:?} is not implemented", bb_func),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ use crate::ssa_refactor::ir::{
types::{NumericType, Type},
value::{Value, ValueId},
};
use acvm::acir::brillig_vm::{
BinaryFieldOp, BinaryIntOp, HeapArray, HeapVector, RegisterIndex, RegisterOrMemory,
};
use acvm::acir::brillig::{BinaryFieldOp, BinaryIntOp, HeapArray, RegisterIndex, RegisterOrMemory};
use acvm::brillig_vm::brillig::HeapVector;
use acvm::FieldElement;
use iter_extended::vecmap;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use acvm::acir::brillig_vm::{BinaryFieldOp, Opcode as BrilligOpcode, RegisterIndex, Value};
use acvm::acir::brillig::{BinaryFieldOp, Opcode as BrilligOpcode, RegisterIndex, Value};

/// Generates brillig bytecode which computes the inverse of its input if not null, and zero else.
pub(crate) fn directive_invert() -> Vec<BrilligOpcode> {
Expand Down
Loading