11use super :: { insert_value, witness_to_value} ;
22use crate :: { pwg:: OpcodeResolution , OpcodeResolutionError } ;
3- use acir:: { circuit:: opcodes:: BlackBoxFuncCall , native_types:: Witness , BlackBoxFunc , FieldElement } ;
3+ use acir:: { circuit:: opcodes:: BlackBoxFuncCall , native_types:: Witness , FieldElement } ;
44use std:: collections:: BTreeMap ;
55
6- pub fn solve_logic_opcode (
6+ /// Solves a [`BlackBoxFunc::And`][acir::circuit::black_box_functions::BlackBoxFunc::AND] opcode and inserts
7+ /// the result into the supplied witness map
8+ pub fn and (
79 initial_witness : & mut BTreeMap < Witness , FieldElement > ,
8- func_call : & BlackBoxFuncCall ,
10+ gate : & BlackBoxFuncCall ,
911) -> Result < OpcodeResolution , OpcodeResolutionError > {
10- match func_call. name {
11- BlackBoxFunc :: AND => LogicSolver :: solve_and_gate ( initial_witness, func_call) ,
12- BlackBoxFunc :: XOR => LogicSolver :: solve_xor_gate ( initial_witness, func_call) ,
13- _ => Err ( OpcodeResolutionError :: UnexpectedOpcode ( "logic opcode" , func_call. name ) ) ,
14- }
12+ let ( a, b, result, num_bits) = extract_input_output ( gate) ;
13+ solve_logic_gate ( initial_witness, & a, & b, result, |left, right| left. and ( right, num_bits) )
1514}
1615
17- pub struct LogicSolver ;
18-
19- impl LogicSolver {
20- /// Derives the rest of the witness based on the initial low level variables
21- fn solve_logic_gate (
22- initial_witness : & mut BTreeMap < Witness , FieldElement > ,
23- a : & Witness ,
24- b : & Witness ,
25- result : Witness ,
26- num_bits : u32 ,
27- is_xor_gate : bool ,
28- ) -> Result < OpcodeResolution , OpcodeResolutionError > {
29- let w_l_value = witness_to_value ( initial_witness, * a) ?;
30- let w_r_value = witness_to_value ( initial_witness, * b) ?;
31-
32- let assignment = if is_xor_gate {
33- w_l_value. xor ( w_r_value, num_bits)
34- } else {
35- w_l_value. and ( w_r_value, num_bits)
36- } ;
37- insert_value ( & result, assignment, initial_witness) ?;
38- Ok ( OpcodeResolution :: Solved )
39- }
40-
41- pub fn solve_and_gate (
42- initial_witness : & mut BTreeMap < Witness , FieldElement > ,
43- gate : & BlackBoxFuncCall ,
44- ) -> Result < OpcodeResolution , OpcodeResolutionError > {
45- let ( a, b, result, num_bits) = extract_input_output ( gate) ;
46- LogicSolver :: solve_logic_gate ( initial_witness, & a, & b, result, num_bits, false )
47- }
48- pub fn solve_xor_gate (
49- initial_witness : & mut BTreeMap < Witness , FieldElement > ,
50- gate : & BlackBoxFuncCall ,
51- ) -> Result < OpcodeResolution , OpcodeResolutionError > {
52- let ( a, b, result, num_bits) = extract_input_output ( gate) ;
53- LogicSolver :: solve_logic_gate ( initial_witness, & a, & b, result, num_bits, true )
54- }
16+ /// Solves a [`BlackBoxFunc::XOR`][acir::circuit::black_box_functions::BlackBoxFunc::XOR] opcode and inserts
17+ /// the result into the supplied witness map
18+ pub fn xor (
19+ initial_witness : & mut BTreeMap < Witness , FieldElement > ,
20+ gate : & BlackBoxFuncCall ,
21+ ) -> Result < OpcodeResolution , OpcodeResolutionError > {
22+ let ( a, b, result, num_bits) = extract_input_output ( gate) ;
23+ solve_logic_gate ( initial_witness, & a, & b, result, |left, right| left. xor ( right, num_bits) )
5524}
25+
5626// TODO: Is there somewhere else that we can put this?
5727// TODO: extraction methods are needed for some opcodes like logic and range
5828pub ( crate ) fn extract_input_output (
@@ -69,3 +39,19 @@ pub(crate) fn extract_input_output(
6939
7040 ( a. witness , b. witness , * result, num_bits)
7141}
42+
43+ /// Derives the rest of the witness based on the initial low level variables
44+ fn solve_logic_gate (
45+ initial_witness : & mut BTreeMap < Witness , FieldElement > ,
46+ a : & Witness ,
47+ b : & Witness ,
48+ result : Witness ,
49+ logic_op : impl Fn ( & FieldElement , & FieldElement ) -> FieldElement ,
50+ ) -> Result < OpcodeResolution , OpcodeResolutionError > {
51+ let w_l_value = witness_to_value ( initial_witness, * a) ?;
52+ let w_r_value = witness_to_value ( initial_witness, * b) ?;
53+ let assignment = logic_op ( w_l_value, w_r_value) ;
54+
55+ insert_value ( & result, assignment, initial_witness) ?;
56+ Ok ( OpcodeResolution :: Solved )
57+ }
0 commit comments