Skip to content

Commit

Permalink
Merge branch 'master' into fix-aztec
Browse files Browse the repository at this point in the history
* master:
  feat(ssa): Replace values which have previously been constrained with simplified value (#2483)
  fix: Black box func slice handling (#2562)
  • Loading branch information
TomAFrench committed Sep 5, 2023
2 parents 36bd077 + 9be750a commit 8b315a3
Show file tree
Hide file tree
Showing 28 changed files with 234 additions and 204 deletions.
Binary file modified crates/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz
Binary file not shown.
Binary file modified crates/nargo_cli/tests/acir_artifacts/6_array/target/witness.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified crates/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz
Binary file not shown.
Binary file modified crates/nargo_cli/tests/acir_artifacts/schnorr/target/witness.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified crates/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz
Binary file not shown.
Binary file modified crates/nargo_cli/tests/acir_artifacts/tuples/target/witness.gz
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,22 @@ fn main(
input_aggregation_object : [Field; 16],
proof_b : [Field; 94],
) -> pub [Field; 16] {

let verification_key : [Field] = verification_key;
let proof : [Field] = proof;
let proof_b : [Field] = proof_b;
let public_inputs : [Field] = public_inputs;


let output_aggregation_object_a = std::verify_proof(
verification_key,
proof,
public_inputs,
key_hash,
verification_key.as_slice(),
proof.as_slice(),
public_inputs.as_slice(),
key_hash,
input_aggregation_object
);

let output_aggregation_object = std::verify_proof(
verification_key,
proof_b,
public_inputs,
verification_key.as_slice(),
proof_b.as_slice(),
public_inputs.as_slice(),
key_hash,
output_aggregation_object_a
);

let mut output = [0; 16];
for i in 0..16 {
output[i] = output_aggregation_object[i];
Expand Down
157 changes: 33 additions & 124 deletions crates/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,10 @@ pub(crate) fn convert_black_box_call(
) {
match bb_func {
BlackBoxFunc::SHA256 => {
if let ([..], [RegisterOrMemory::HeapArray(result_array)]) =
if let ([message], [RegisterOrMemory::HeapArray(result_array)]) =
(function_arguments, function_results)
{
// Slices are represented as a tuple of (length, slice contents).
// We must check the number of inputs to differentiate between arrays and slices
// and make sure that we pass the correct inputs to the function call.
let message = if function_arguments.len() > 1 {
&function_arguments[1]
} else {
&function_arguments[0]
};
let message_vector = match message {
RegisterOrMemory::HeapArray(message_array) => {
brillig_context.array_to_vector(message_array)
}
RegisterOrMemory::HeapVector(message_vector) => *message_vector,
_ => unreachable!("ICE: SHA256 expects the message to be an array or a vector"),
};
let message_vector = convert_array_or_vector(brillig_context, message, bb_func);
brillig_context.black_box_op_instruction(BlackBoxOp::Sha256 {
message: message_vector,
output: *result_array,
Expand All @@ -43,26 +29,10 @@ pub(crate) fn convert_black_box_call(
}
}
BlackBoxFunc::Blake2s => {
if let ([..], [RegisterOrMemory::HeapArray(result_array)]) =
if let ([message], [RegisterOrMemory::HeapArray(result_array)]) =
(function_arguments, function_results)
{
// Slices are represented as a tuple of (length, slice contents).
// We must check the number of inputs to differentiate between arrays and slices
// and make sure that we pass the correct inputs to the function call.
let message = if function_arguments.len() > 1 {
&function_arguments[1]
} else {
&function_arguments[0]
};
let message_vector = match message {
RegisterOrMemory::HeapArray(message_array) => {
brillig_context.array_to_vector(message_array)
}
RegisterOrMemory::HeapVector(message_vector) => *message_vector,
_ => {
unreachable!("ICE: Blake2s expects the message to be an array or a vector")
}
};
let message_vector = convert_array_or_vector(brillig_context, message, bb_func);
brillig_context.black_box_op_instruction(BlackBoxOp::Blake2s {
message: message_vector,
output: *result_array,
Expand All @@ -73,27 +43,13 @@ pub(crate) fn convert_black_box_call(
}
BlackBoxFunc::Keccak256 => {
if let (
[.., RegisterOrMemory::RegisterIndex(array_size)],
[message, RegisterOrMemory::RegisterIndex(array_size)],
[RegisterOrMemory::HeapArray(result_array)],
) = (function_arguments, function_results)
{
// Slices are represented as a tuple of (length, slice contents).
// We must check the number of inputs to differentiate between arrays and slices
// and make sure that we pass the correct inputs to the function call.
let message = if function_arguments.len() > 2 {
&function_arguments[1]
} else {
&function_arguments[0]
};
let message_vector = match message {
RegisterOrMemory::HeapArray(message_array) => {
HeapVector { size: *array_size, pointer: message_array.pointer }
}
RegisterOrMemory::HeapVector(message_vector) => *message_vector,
_ => unreachable!(
"ICE: Keccak256 expects the message to be an array or a vector"
),
};
let mut message_vector = convert_array_or_vector(brillig_context, message, bb_func);
message_vector.size = *array_size;

brillig_context.black_box_op_instruction(BlackBoxOp::Keccak256 {
message: message_vector,
output: *result_array,
Expand All @@ -103,26 +59,10 @@ pub(crate) fn convert_black_box_call(
}
}
BlackBoxFunc::HashToField128Security => {
if let ([..], [RegisterOrMemory::RegisterIndex(result_register)]) =
if let ([message], [RegisterOrMemory::RegisterIndex(result_register)]) =
(function_arguments, function_results)
{
// Slices are represented as a tuple of (length, slice contents).
// We must check the number of inputs to differentiate between arrays and slices
// and make sure that we pass the correct inputs to the function call.
let message = if function_arguments.len() > 1 {
&function_arguments[1]
} else {
&function_arguments[0]
};
let message_vector = match message {
RegisterOrMemory::HeapArray(message_array) => {
brillig_context.array_to_vector(message_array)
}
RegisterOrMemory::HeapVector(message_vector) => {
*message_vector
}
_ => unreachable!("ICE: HashToField128Security expects the message to be an array or a vector"),
};
let message_vector = convert_array_or_vector(brillig_context, message, bb_func);
brillig_context.black_box_op_instruction(BlackBoxOp::HashToField128Security {
message: message_vector,
output: *result_register,
Expand All @@ -133,27 +73,12 @@ pub(crate) fn convert_black_box_call(
}
BlackBoxFunc::EcdsaSecp256k1 => {
if let (
[RegisterOrMemory::HeapArray(public_key_x), RegisterOrMemory::HeapArray(public_key_y), RegisterOrMemory::HeapArray(signature), ..],
[RegisterOrMemory::HeapArray(public_key_x), RegisterOrMemory::HeapArray(public_key_y), RegisterOrMemory::HeapArray(signature), message],
[RegisterOrMemory::RegisterIndex(result_register)],
) = (function_arguments, function_results)
{
// Slices are represented as a tuple of (length, slice contents).
// We must check the number of inputs to differentiate between arrays and slices
// and make sure that we pass the correct inputs to the function call.
let message = if function_arguments.len() > 4 {
&function_arguments[4]
} else {
&function_arguments[3]
};
let message_hash_vector = match message {
RegisterOrMemory::HeapArray(message_hash) => {
brillig_context.array_to_vector(message_hash)
}
RegisterOrMemory::HeapVector(message_hash_vector) => *message_hash_vector,
_ => unreachable!(
"ICE: EcdsaSecp256k1 expects the message to be an array or a vector"
),
};
let message_hash_vector =
convert_array_or_vector(brillig_context, message, bb_func);
brillig_context.black_box_op_instruction(BlackBoxOp::EcdsaSecp256k1 {
hashed_msg: message_hash_vector,
public_key_x: *public_key_x,
Expand All @@ -169,27 +94,11 @@ pub(crate) fn convert_black_box_call(
}
BlackBoxFunc::Pedersen => {
if let (
[.., RegisterOrMemory::RegisterIndex(domain_separator)],
[message, RegisterOrMemory::RegisterIndex(domain_separator)],
[RegisterOrMemory::HeapArray(result_array)],
) = (function_arguments, function_results)
{
// Slices are represented as a tuple of (length, slice contents).
// We must check the number of inputs to differentiate between arrays and slices
// and make sure that we pass the correct inputs to the function call.
let message = if function_arguments.len() > 2 {
&function_arguments[1]
} else {
&function_arguments[0]
};
let message_vector = match message {
RegisterOrMemory::HeapArray(message_array) => {
brillig_context.array_to_vector(message_array)
}
RegisterOrMemory::HeapVector(message_vector) => *message_vector,
_ => {
unreachable!("ICE: Pedersen expects the message to be an array or a vector")
}
};
let message_vector = convert_array_or_vector(brillig_context, message, bb_func);
brillig_context.black_box_op_instruction(BlackBoxOp::Pedersen {
inputs: message_vector,
domain_separator: *domain_separator,
Expand All @@ -201,27 +110,11 @@ pub(crate) fn convert_black_box_call(
}
BlackBoxFunc::SchnorrVerify => {
if let (
[RegisterOrMemory::RegisterIndex(public_key_x), RegisterOrMemory::RegisterIndex(public_key_y), RegisterOrMemory::HeapArray(signature), ..],
[RegisterOrMemory::RegisterIndex(public_key_x), RegisterOrMemory::RegisterIndex(public_key_y), RegisterOrMemory::HeapArray(signature), message],
[RegisterOrMemory::RegisterIndex(result_register)],
) = (function_arguments, function_results)
{
// Slices are represented as a tuple of (length, slice contents).
// We must check the number of inputs to differentiate between arrays and slices
// and make sure that we pass the correct inputs to the function call.
let message = if function_arguments.len() > 4 {
&function_arguments[4]
} else {
&function_arguments[3]
};
let message_hash = match message {
RegisterOrMemory::HeapArray(message_hash) => {
brillig_context.array_to_vector(message_hash)
}
RegisterOrMemory::HeapVector(message_hash) => *message_hash,
_ => unreachable!(
"ICE: Schnorr verify expects the message to be an array or a vector"
),
};
let message_hash = convert_array_or_vector(brillig_context, message, bb_func);
let signature = brillig_context.array_to_vector(signature);
brillig_context.black_box_op_instruction(BlackBoxOp::SchnorrVerify {
public_key_x: *public_key_x,
Expand Down Expand Up @@ -253,3 +146,19 @@ pub(crate) fn convert_black_box_call(
_ => unimplemented!("ICE: Black box function {:?} is not implemented", bb_func),
}
}

fn convert_array_or_vector(
brillig_context: &mut BrilligContext,
array_or_vector: &RegisterOrMemory,
bb_func: &BlackBoxFunc,
) -> HeapVector {
match array_or_vector {
RegisterOrMemory::HeapArray(array) => brillig_context.array_to_vector(array),
RegisterOrMemory::HeapVector(vector) => *vector,
_ => unreachable!(
"ICE: {} expected an array or a vector, but got {:?}",
bb_func.name(),
array_or_vector
),
}
}
23 changes: 22 additions & 1 deletion crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,29 @@ impl<'block> BrilligBlock<'block> {
self.convert_ssa_function_call(*func_id, arguments, dfg, instruction_id);
}
Value::Intrinsic(Intrinsic::BlackBox(bb_func)) => {
// Slices are represented as a tuple of (length, slice contents).
// We must check the inputs to determine if there are slices
// and make sure that we pass the correct inputs to the black box function call.
// The loop below only keeps the slice contents, so that
// setting up a black box function with slice inputs matches the expected
// number of arguments specified in the function signature.
let mut arguments_no_slice_len = Vec::new();
for (i, arg) in arguments.iter().enumerate() {
if matches!(dfg.type_of_value(*arg), Type::Numeric(_)) {
if i < arguments.len() - 1 {
if !matches!(dfg.type_of_value(arguments[i + 1]), Type::Slice(_)) {
arguments_no_slice_len.push(*arg);
}
} else {
arguments_no_slice_len.push(*arg);
}
} else {
arguments_no_slice_len.push(*arg);
}
}

let function_arguments =
vecmap(arguments, |arg| self.convert_ssa_value(*arg, dfg));
vecmap(&arguments_no_slice_len, |arg| self.convert_ssa_value(*arg, dfg));
let function_results = dfg.instruction_results(instruction_id);
let function_results = vecmap(function_results, |result| {
self.allocate_external_call_result(*result, dfg)
Expand Down
Loading

0 comments on commit 8b315a3

Please sign in to comment.