Skip to content
This repository was archived by the owner on Apr 9, 2024. It is now read-only.

Commit 84b5d18

Browse files
authored
chore(acvm)!: expose separate solvers for AND and XOR opcodes (#266)
* chore!: expose separate solvers for AND and XOR opcodes * chore: replace boolean flag and `num_bits` args with closure
1 parent 7bc42c6 commit 84b5d18

1 file changed

Lines changed: 32 additions & 46 deletions

File tree

acvm/src/pwg/logic.rs

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,28 @@
11
use super::{insert_value, witness_to_value};
22
use 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};
44
use 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
5828
pub(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

Comments
 (0)