diff --git a/acvm/src/compiler/transformers/fallback.rs b/acvm/src/compiler/transformers/fallback.rs index 4b01b4dd6..b9bc8834e 100644 --- a/acvm/src/compiler/transformers/fallback.rs +++ b/acvm/src/compiler/transformers/fallback.rs @@ -76,7 +76,8 @@ impl FallbackTransformer { ) -> Result<(u32, Vec), CompileError> { let (updated_witness_index, opcodes_fallback) = match gc.name { BlackBoxFunc::AND => { - let (lhs, rhs, result, num_bits) = crate::pwg::logic::extract_input_output(gc); + let (lhs, rhs, result, num_bits) = + crate::pwg::logic::extract_input_output(&gc.inputs, &gc.outputs); stdlib::fallback::and( Expression::from(lhs), Expression::from(rhs), @@ -86,7 +87,8 @@ impl FallbackTransformer { ) } BlackBoxFunc::XOR => { - let (lhs, rhs, result, num_bits) = crate::pwg::logic::extract_input_output(gc); + let (lhs, rhs, result, num_bits) = + crate::pwg::logic::extract_input_output(&gc.inputs, &gc.outputs); stdlib::fallback::xor( Expression::from(lhs), Expression::from(rhs), diff --git a/acvm/src/lib.rs b/acvm/src/lib.rs index a720daf71..60609b1fd 100644 --- a/acvm/src/lib.rs +++ b/acvm/src/lib.rs @@ -82,7 +82,6 @@ pub trait PartialWitnessGenerator { &self, initial_witness: &mut BTreeMap, inputs: &[FunctionInput], - outputs: &[Witness], ) -> Result; fn sha256( &self, @@ -283,9 +282,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn and( &self, @@ -293,9 +290,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn xor( &self, @@ -303,19 +298,14 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn range( &self, _initial_witness: &mut BTreeMap, _inputs: &[FunctionInput], - _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn sha256( &self, @@ -323,9 +313,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn blake2s( &self, @@ -333,9 +321,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn compute_merkle_root( &self, @@ -343,9 +329,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn schnorr_verify( &self, @@ -353,9 +337,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn pedersen( &self, @@ -363,9 +345,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn hash_to_field128_security( &self, @@ -373,9 +353,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn ecdsa_secp256k1( &self, @@ -383,9 +361,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn fixed_base_scalar_mul( &self, @@ -393,9 +369,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } fn keccak256( &self, @@ -403,9 +377,7 @@ mod test { _inputs: &[FunctionInput], _outputs: &[Witness], ) -> Result { - { - panic!("Path not trodden by this test") - } + panic!("Path not trodden by this test") } } diff --git a/acvm/src/pwg/blackbox.rs b/acvm/src/pwg/blackbox.rs index 3c507592f..76c4870a1 100644 --- a/acvm/src/pwg/blackbox.rs +++ b/acvm/src/pwg/blackbox.rs @@ -61,7 +61,8 @@ pub(crate) fn solve( backend.xor(initial_witness, inputs, outputs) } BlackBoxFuncCall { name: BlackBoxFunc::RANGE, inputs, outputs } => { - backend.range(initial_witness, inputs, outputs) + assert!(outputs.is_empty()); + backend.range(initial_witness, inputs) } BlackBoxFuncCall { name: BlackBoxFunc::SHA256, inputs, outputs } => { backend.sha256(initial_witness, inputs, outputs) diff --git a/acvm/src/pwg/hash.rs b/acvm/src/pwg/hash.rs index 2333ec21b..127b8a825 100644 --- a/acvm/src/pwg/hash.rs +++ b/acvm/src/pwg/hash.rs @@ -1,4 +1,4 @@ -use acir::{circuit::opcodes::BlackBoxFuncCall, native_types::Witness, FieldElement}; +use acir::{circuit::opcodes::FunctionInput, native_types::Witness, FieldElement}; use blake2::{Blake2s256, Digest}; use sha2::Sha256; use sha3::Keccak256; @@ -10,11 +10,12 @@ use super::{insert_value, witness_to_value}; pub fn blake2s256( initial_witness: &mut BTreeMap, - func_call: &BlackBoxFuncCall, + inputs: &[FunctionInput], + outputs: &[Witness], ) -> Result { - let hash = generic_hash_256::(initial_witness, func_call)?; + let hash = generic_hash_256::(initial_witness, inputs)?; - for (output_witness, value) in func_call.outputs.iter().zip(hash.iter()) { + for (output_witness, value) in outputs.iter().zip(hash.iter()) { insert_value( output_witness, FieldElement::from_be_bytes_reduce(&[*value]), @@ -27,11 +28,12 @@ pub fn blake2s256( pub fn sha256( initial_witness: &mut BTreeMap, - func_call: &BlackBoxFuncCall, + inputs: &[FunctionInput], + outputs: &[Witness], ) -> Result { - let hash = generic_hash_256::(initial_witness, func_call)?; + let hash = generic_hash_256::(initial_witness, inputs)?; - for (output_witness, value) in func_call.outputs.iter().zip(hash.iter()) { + for (output_witness, value) in outputs.iter().zip(hash.iter()) { insert_value( output_witness, FieldElement::from_be_bytes_reduce(&[*value]), @@ -44,11 +46,12 @@ pub fn sha256( pub fn keccak256( initial_witness: &mut BTreeMap, - func_call: &BlackBoxFuncCall, + inputs: &[FunctionInput], + outputs: &[Witness], ) -> Result { - let hash = generic_hash_256::(initial_witness, func_call)?; + let hash = generic_hash_256::(initial_witness, inputs)?; - for (output_witness, value) in func_call.outputs.iter().zip(hash.iter()) { + for (output_witness, value) in outputs.iter().zip(hash.iter()) { insert_value( output_witness, FieldElement::from_be_bytes_reduce(&[*value]), @@ -61,24 +64,25 @@ pub fn keccak256( pub fn hash_to_field_128_security( initial_witness: &mut BTreeMap, - func_call: &BlackBoxFuncCall, + inputs: &[FunctionInput], + outputs: &[Witness], ) -> Result { - let hash = generic_hash_256::(initial_witness, func_call)?; + let hash = generic_hash_256::(initial_witness, inputs)?; let reduced_res = FieldElement::from_be_bytes_reduce(&hash); - insert_value(&func_call.outputs[0], reduced_res, initial_witness)?; + insert_value(&outputs[0], reduced_res, initial_witness)?; Ok(OpcodeResolution::Solved) } fn generic_hash_256( initial_witness: &mut BTreeMap, - func_call: &BlackBoxFuncCall, + inputs: &[FunctionInput], ) -> Result<[u8; 32], OpcodeResolutionError> { let mut hasher = D::new(); // Read witness assignments into hasher. - for input in func_call.inputs.iter() { + for input in inputs.iter() { let witness = input.witness; let num_bits = input.num_bits as usize; diff --git a/acvm/src/pwg/logic.rs b/acvm/src/pwg/logic.rs index 3f4a98e5e..2ed2cd4b0 100644 --- a/acvm/src/pwg/logic.rs +++ b/acvm/src/pwg/logic.rs @@ -1,15 +1,16 @@ use super::{insert_value, witness_to_value}; use crate::{pwg::OpcodeResolution, OpcodeResolutionError}; -use acir::{circuit::opcodes::BlackBoxFuncCall, native_types::Witness, FieldElement}; +use acir::{circuit::opcodes::FunctionInput, native_types::Witness, FieldElement}; use std::collections::BTreeMap; /// Solves a [`BlackBoxFunc::And`][acir::circuit::black_box_functions::BlackBoxFunc::AND] opcode and inserts /// the result into the supplied witness map pub fn and( initial_witness: &mut BTreeMap, - gate: &BlackBoxFuncCall, + inputs: &[FunctionInput], + outputs: &[Witness], ) -> Result { - let (a, b, result, num_bits) = extract_input_output(gate); + let (a, b, result, num_bits) = extract_input_output(inputs, outputs); solve_logic_gate(initial_witness, &a, &b, result, |left, right| left.and(right, num_bits)) } @@ -17,27 +18,29 @@ pub fn and( /// the result into the supplied witness map pub fn xor( initial_witness: &mut BTreeMap, - gate: &BlackBoxFuncCall, + inputs: &[FunctionInput], + outputs: &[Witness], ) -> Result { - let (a, b, result, num_bits) = extract_input_output(gate); + let (a, b, result, num_bits) = extract_input_output(inputs, outputs); solve_logic_gate(initial_witness, &a, &b, result, |left, right| left.xor(right, num_bits)) } // TODO: Is there somewhere else that we can put this? // TODO: extraction methods are needed for some opcodes like logic and range pub(crate) fn extract_input_output( - bb_func_call: &BlackBoxFuncCall, + inputs: &[FunctionInput], + outputs: &[Witness], ) -> (Witness, Witness, Witness, u32) { - let a = &bb_func_call.inputs[0]; - let b = &bb_func_call.inputs[1]; - let result = &bb_func_call.outputs[0]; + let a = &inputs[0]; + let b = &inputs[1]; + let result = outputs[0]; // The num_bits variable should be the same for all witnesses assert_eq!(a.num_bits, b.num_bits, "number of bits specified for each input must be the same"); let num_bits = a.num_bits; - (a.witness, b.witness, *result, num_bits) + (a.witness, b.witness, result, num_bits) } /// Derives the rest of the witness based on the initial low level variables diff --git a/acvm/src/pwg/range.rs b/acvm/src/pwg/range.rs index b0a0a5855..8754dce06 100644 --- a/acvm/src/pwg/range.rs +++ b/acvm/src/pwg/range.rs @@ -1,10 +1,10 @@ use crate::{pwg::witness_to_value, pwg::OpcodeResolution, OpcodeResolutionError}; -use acir::{circuit::opcodes::BlackBoxFuncCall, native_types::Witness, BlackBoxFunc, FieldElement}; +use acir::{circuit::opcodes::FunctionInput, native_types::Witness, BlackBoxFunc, FieldElement}; use std::collections::BTreeMap; pub fn solve_range_opcode( initial_witness: &mut BTreeMap, - func_call: &BlackBoxFuncCall, + inputs: &[FunctionInput], ) -> Result { // TODO: this consistency check can be moved to a general function let defined_input_size = BlackBoxFunc::RANGE @@ -13,7 +13,7 @@ pub fn solve_range_opcode( .fixed_size() .expect("infallible: input for range gate is fixed"); - let num_arguments = func_call.inputs.len(); + let num_arguments = inputs.len(); if num_arguments != defined_input_size as usize { return Err(OpcodeResolutionError::IncorrectNumFunctionArguments( defined_input_size as usize, @@ -25,7 +25,7 @@ pub fn solve_range_opcode( // For the range constraint, we know that the input size should be one assert_eq!(defined_input_size, 1); - let input = func_call.inputs.first().expect("infallible: checked that input size is 1"); + let input = inputs.first().expect("infallible: checked that input size is 1"); let w_value = witness_to_value(initial_witness, input.witness)?; if w_value.num_bits() > input.num_bits { diff --git a/acvm/src/pwg/signature/ecdsa.rs b/acvm/src/pwg/signature/ecdsa.rs index 1687e72ac..b22a81cf0 100644 --- a/acvm/src/pwg/signature/ecdsa.rs +++ b/acvm/src/pwg/signature/ecdsa.rs @@ -1,13 +1,14 @@ -use acir::{circuit::opcodes::BlackBoxFuncCall, native_types::Witness, FieldElement}; +use acir::{circuit::opcodes::FunctionInput, native_types::Witness, FieldElement}; use std::collections::BTreeMap; use crate::{pwg::witness_to_value, pwg::OpcodeResolution, OpcodeResolutionError}; pub fn secp256k1_prehashed( initial_witness: &mut BTreeMap, - gadget_call: &BlackBoxFuncCall, + inputs: &[FunctionInput], + outputs: &[Witness], ) -> Result { - let mut inputs_iter = gadget_call.inputs.iter(); + let mut inputs_iter = inputs.iter(); let mut pub_key_x = [0u8; 32]; for (i, pkx) in pub_key_x.iter_mut().enumerate() { @@ -50,7 +51,7 @@ pub fn secp256k1_prehashed( ecdsa_secp256k1::verify_prehashed(&hashed_message, &pub_key_x, &pub_key_y, &signature) .is_ok(); - initial_witness.insert(gadget_call.outputs[0], FieldElement::from(result)); + initial_witness.insert(outputs[0], FieldElement::from(result)); Ok(OpcodeResolution::Solved) }