Skip to content

Commit

Permalink
feat!: Update to ACVM 0.18.1 and implement missing brillig blackboxes (
Browse files Browse the repository at this point in the history
…#1914)

* feat: update to ACVM 0.18.1

* chore: point manually to the backend

* Update crates/nargo_cli/tests/test_data_ssa_refactor/brillig_pedersen/Nargo.toml

* chore: fix wasm

* chore: update backend version

* Update crates/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs

Co-authored-by: Maxim Vezenov <[email protected]>

---------

Co-authored-by: Maxim Vezenov <[email protected]>
  • Loading branch information
sirasistant and vezenovm authored Jul 12, 2023
1 parent 3ba1e72 commit 2bc7d25
Show file tree
Hide file tree
Showing 29 changed files with 271 additions and 67 deletions.
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

0 comments on commit 2bc7d25

Please sign in to comment.