From 3f4557c065d9e6aba42544d6526824f82983b4cb Mon Sep 17 00:00:00 2001 From: vezenovm Date: Tue, 5 Sep 2023 15:40:46 +0000 Subject: [PATCH 1/4] check how CI handles switch back to as_slice --- .../double_verify_proof/src/main.nr | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr b/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr index 82418618f26..57a46535416 100644 --- a/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr @@ -9,28 +9,44 @@ fn main( 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 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, + // let output_aggregation_object_a = std::verify_proof( + // verification_key, + // proof, + // public_inputs, + // key_hash, + // input_aggregation_object + // ); + + // let output_aggregation_object = std::verify_proof( + // verification_key, + // proof_b, + // public_inputs, + // key_hash, + // output_aggregation_object_a + // ); + + let output_aggregation_object_a = std::verify_proof( + 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]; From 744e1546076cb14a830721e6690166789b05ab12 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Tue, 5 Sep 2023 16:41:34 +0000 Subject: [PATCH 2/4] update RecursiveAggregation black box for slices --- .../ssa/acir_gen/acir_ir/generated_acir.rs | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 8304ce1fbee..d986c2fc0b5 100644 --- a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -253,6 +253,26 @@ impl GeneratedAcir { let inputs = if inputs.len() > 2 { inputs[1].clone() } else { inputs[0].clone() }; BlackBoxFuncCall::Keccak256VariableLength { inputs, var_message_size, outputs } } + // BlackBoxFunc::RecursiveAggregation => { + // let has_previous_aggregation = self.opcodes.iter().any(|op| { + // matches!( + // op, + // AcirOpcode::BlackBoxFuncCall(BlackBoxFuncCall::RecursiveAggregation { .. }) + // ) + // }); + + // let input_aggregation_object = + // if !has_previous_aggregation { None } else { Some(inputs[4].clone()) }; + + // BlackBoxFuncCall::RecursiveAggregation { + // verification_key: inputs[0].clone(), + // proof: inputs[1].clone(), + // public_inputs: inputs[2].clone(), + // key_hash: inputs[3][0], + // input_aggregation_object, + // output_aggregation_object: outputs, + // } + // } BlackBoxFunc::RecursiveAggregation => { let has_previous_aggregation = self.opcodes.iter().any(|op| { matches!( @@ -261,14 +281,18 @@ impl GeneratedAcir { ) }); + // Slices are represented as a tuple of (length, slice contents). + // All inputs to the `RecursiveAggregation` black box func are slices, + // thus we must make sure to only fetch the slice contents rather than + // the slice length when setting up the inputs. let input_aggregation_object = - if !has_previous_aggregation { None } else { Some(inputs[4].clone()) }; + if !has_previous_aggregation { None } else { Some(inputs[7].clone()) }; BlackBoxFuncCall::RecursiveAggregation { - verification_key: inputs[0].clone(), - proof: inputs[1].clone(), - public_inputs: inputs[2].clone(), - key_hash: inputs[3][0], + verification_key: inputs[1].clone(), + proof: inputs[3].clone(), + public_inputs: inputs[5].clone(), + key_hash: inputs[6][0], input_aggregation_object, output_aggregation_object: outputs, } From 5e93d8dc4e0d4aed2184c3a17735286ef921b163 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Tue, 5 Sep 2023 19:02:49 +0000 Subject: [PATCH 3/4] generalized slice/array inputs for black box funcs --- .../acir_artifacts/schnorr/target/acir.gz | Bin 2212 -> 2204 bytes .../acir_artifacts/schnorr/target/witness.gz | Bin 822 -> 819 bytes .../double_verify_proof/src/main.nr | 3 +- .../brillig/brillig_gen/brillig_black_box.rs | 157 ++++-------------- .../src/brillig/brillig_gen/brillig_block.rs | 23 ++- .../ssa/acir_gen/acir_ir/generated_acir.rs | 107 +++--------- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 23 ++- 7 files changed, 102 insertions(+), 211 deletions(-) diff --git a/crates/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz b/crates/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz index 67a7af6022f58460b08dcee751c90f91dc24cab7..f2901f3cc9149d4553c46bd76c8a41f190997585 100644 GIT binary patch delta 1772 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 literal 822 zcmV-61Ihd!iwFP!00002|E-$Uj@(KRKy#UynVFj5Qka<;+6`f5W@d%+wQ;nGviq7j zmPVR~nWOS?b#=Myd!vSqXZp{WN8iPO$Fm$uKF6`t^BhaRz_HAW9Lv7MvE0iX%fG_0 z!mAuBzV`GiDU{H{2rHcMB8d38b^f^)AWw}y)1;;NeSRSdUp z3yZO|bzH6{&z)llV2>HOwJrbV>T3Rn+iUf|T%FMWao17(&&6d%gFVw2t_KKXF;*$# zxVXf4uwR|P#ib{5HM*O`)xtKJt2u587nhp~_BqqQ{F=_~+i3<@qy0>-Mz>kuyl^%+ z$D9MsSLcFr-+AD?a6ULEUjWYU7lO|f7J<(@7K6`WmJDNQ;f$$X)xK3vLd7oFzN_k7 zkfEO-+oFQjHJIRI7rlu6omrL5M%^C8wRCt~T`1AGRAcZ`Dl4q_)|&orA*+(3Ej8N| zVy-@yl8tmpdutw!tD=;hSq7fta*(xxW2Kd#`&FR()u696AS(^PY9kNVf$lTtzJR_e z$ZDK>zZP`A4s^dB^tAzGZRFgCO`!YDp!+SLudN_!8|OZ52i@-g-R}f_?E+c5IrnJ~ z=zcHgejn&-Kgc@3x$h2w?hk?P4}-prfUKjO`+N*^e;jmw0`zqfWS!#Nm(!s8Gobsk zps#Zv>pbVaUI5)+1l?Z(eO(4wS2*|WDtM244V;@?2U#~pVebTrn@^vs@^P-#zPE2d z$Xf%mLak{i&f5dAN^SDV8oD#cdXyvA<6Y4GJ;GNUa({oIa~$dG0ZVX9TXZb|0FM*5 AWB>pF diff --git a/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr b/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr index 57a46535416..5a0e93f2c30 100644 --- a/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr @@ -14,7 +14,6 @@ fn main( // let proof_b : [Field] = proof_b; // let public_inputs : [Field] = public_inputs; - // let output_aggregation_object_a = std::verify_proof( // verification_key, // proof, @@ -31,7 +30,7 @@ fn main( // output_aggregation_object_a // ); - let output_aggregation_object_a = std::verify_proof( + let output_aggregation_object_a = std::verify_proof( verification_key.as_slice(), proof.as_slice(), public_inputs.as_slice(), diff --git a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index 7180467aff7..16df0687a1a 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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 + ), + } +} diff --git a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index 15195fc4dcb..a62c8e72498 100644 --- a/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -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) diff --git a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index d986c2fc0b5..a914d32a8f7 100644 --- a/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/crates/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -149,58 +149,30 @@ impl GeneratedAcir { BlackBoxFuncCall::XOR { lhs: inputs[0][0], rhs: inputs[1][0], output: outputs[0] } } BlackBoxFunc::RANGE => BlackBoxFuncCall::RANGE { input: inputs[0][0] }, - BlackBoxFunc::SHA256 => { - // 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 inputs = if inputs.len() > 1 { inputs[1].clone() } else { inputs[0].clone() }; - BlackBoxFuncCall::SHA256 { inputs, outputs } - } + BlackBoxFunc::SHA256 => BlackBoxFuncCall::SHA256 { inputs: inputs[0].clone(), outputs }, BlackBoxFunc::Blake2s => { - // 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 inputs = if inputs.len() > 1 { inputs[1].clone() } else { inputs[0].clone() }; - BlackBoxFuncCall::Blake2s { inputs, outputs } - } - BlackBoxFunc::HashToField128Security => { - // 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 inputs = if inputs.len() > 1 { inputs[1].clone() } else { inputs[0].clone() }; - BlackBoxFuncCall::HashToField128Security { inputs, output: outputs[0] } + BlackBoxFuncCall::Blake2s { inputs: inputs[0].clone(), outputs } } + BlackBoxFunc::HashToField128Security => BlackBoxFuncCall::HashToField128Security { + inputs: inputs[0].clone(), + output: outputs[0], + }, BlackBoxFunc::SchnorrVerify => { - // 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 inputs.len() > 4 { inputs[4].clone() } else { inputs[3].clone() }; BlackBoxFuncCall::SchnorrVerify { public_key_x: inputs[0][0], public_key_y: inputs[1][0], // Schnorr signature is an r & s, 32 bytes each signature: inputs[2].clone(), - message, + message: inputs[3].clone(), output: outputs[0], } } - BlackBoxFunc::Pedersen => { - // 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 inputs = if inputs.len() > 1 { inputs[1].clone() } else { inputs[0].clone() }; - BlackBoxFuncCall::Pedersen { - inputs, - outputs: (outputs[0], outputs[1]), - domain_separator: constants[0].to_u128() as u32, - } - } + BlackBoxFunc::Pedersen => BlackBoxFuncCall::Pedersen { + inputs: inputs[0].clone(), + outputs: (outputs[0], outputs[1]), + domain_separator: constants[0].to_u128() as u32, + }, BlackBoxFunc::EcdsaSecp256k1 => { - // 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 hashed_message = - if inputs.len() > 4 { inputs[4].clone() } else { inputs[3].clone() }; BlackBoxFuncCall::EcdsaSecp256k1 { // 32 bytes for each public key co-ordinate public_key_x: inputs[0].clone(), @@ -208,16 +180,11 @@ impl GeneratedAcir { // (r,s) are both 32 bytes each, so signature // takes up 64 bytes signature: inputs[2].clone(), - hashed_message, + hashed_message: inputs[3].clone(), output: outputs[0], } } BlackBoxFunc::EcdsaSecp256r1 => { - // 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 hashed_message = - if inputs.len() > 4 { inputs[4].clone() } else { inputs[3].clone() }; BlackBoxFuncCall::EcdsaSecp256r1 { // 32 bytes for each public key co-ordinate public_key_x: inputs[0].clone(), @@ -225,7 +192,7 @@ impl GeneratedAcir { // (r,s) are both 32 bytes each, so signature // takes up 64 bytes signature: inputs[2].clone(), - hashed_message, + hashed_message: inputs[3].clone(), output: outputs[0], } } @@ -245,34 +212,12 @@ impl GeneratedAcir { } }; - // 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. - // `inputs` is cloned into a vector before being popped to find the `var_message_size` - // so we still check `inputs` against its original size passed into `call_black_box` - let inputs = if inputs.len() > 2 { inputs[1].clone() } else { inputs[0].clone() }; - BlackBoxFuncCall::Keccak256VariableLength { inputs, var_message_size, outputs } + BlackBoxFuncCall::Keccak256VariableLength { + inputs: inputs[0].clone(), + var_message_size, + outputs, + } } - // BlackBoxFunc::RecursiveAggregation => { - // let has_previous_aggregation = self.opcodes.iter().any(|op| { - // matches!( - // op, - // AcirOpcode::BlackBoxFuncCall(BlackBoxFuncCall::RecursiveAggregation { .. }) - // ) - // }); - - // let input_aggregation_object = - // if !has_previous_aggregation { None } else { Some(inputs[4].clone()) }; - - // BlackBoxFuncCall::RecursiveAggregation { - // verification_key: inputs[0].clone(), - // proof: inputs[1].clone(), - // public_inputs: inputs[2].clone(), - // key_hash: inputs[3][0], - // input_aggregation_object, - // output_aggregation_object: outputs, - // } - // } BlackBoxFunc::RecursiveAggregation => { let has_previous_aggregation = self.opcodes.iter().any(|op| { matches!( @@ -281,18 +226,14 @@ impl GeneratedAcir { ) }); - // Slices are represented as a tuple of (length, slice contents). - // All inputs to the `RecursiveAggregation` black box func are slices, - // thus we must make sure to only fetch the slice contents rather than - // the slice length when setting up the inputs. let input_aggregation_object = - if !has_previous_aggregation { None } else { Some(inputs[7].clone()) }; + if !has_previous_aggregation { None } else { Some(inputs[4].clone()) }; BlackBoxFuncCall::RecursiveAggregation { - verification_key: inputs[1].clone(), - proof: inputs[3].clone(), - public_inputs: inputs[5].clone(), - key_hash: inputs[6][0], + verification_key: inputs[0].clone(), + proof: inputs[1].clone(), + public_inputs: inputs[2].clone(), + key_hash: inputs[3][0], input_aggregation_object, output_aggregation_object: outputs, } diff --git a/crates/noirc_evaluator/src/ssa/acir_gen/mod.rs b/crates/noirc_evaluator/src/ssa/acir_gen/mod.rs index 92619c06f39..a65f5beaa78 100644 --- a/crates/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/crates/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1033,7 +1033,28 @@ impl Context { ) -> Result, RuntimeError> { match intrinsic { Intrinsic::BlackBox(black_box) => { - let inputs = vecmap(arguments, |arg| self.convert_value(*arg, dfg)); + // 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 inputs = vecmap(&arguments_no_slice_len, |arg| self.convert_value(*arg, dfg)); let output_count = result_ids.iter().fold(0usize, |sum, result_id| { sum + dfg.try_get_array_length(*result_id).unwrap_or(1) From 40ef085918fe77ce8af6345331ca52ae95e3ce7d Mon Sep 17 00:00:00 2001 From: vezenovm Date: Tue, 5 Sep 2023 19:08:38 +0000 Subject: [PATCH 4/4] remove comments from double_verify_proof --- .../double_verify_proof/src/main.nr | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr b/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr index 5a0e93f2c30..39b8c142ace 100644 --- a/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr @@ -8,28 +8,6 @@ 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, - // input_aggregation_object - // ); - - // let output_aggregation_object = std::verify_proof( - // verification_key, - // proof_b, - // public_inputs, - // key_hash, - // output_aggregation_object_a - // ); - let output_aggregation_object_a = std::verify_proof( verification_key.as_slice(), proof.as_slice(),