1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use core::borrow::Borrow;
use crate::bits::BinaryExpression;
use crate::field_element::FieldElement;
use crate::gadget_builder::GadgetBuilder;
use crate::wire_values::WireValues;
impl GadgetBuilder {
pub fn binary_sum<BE1, BE2>(&mut self, x: BE1, y: BE2) -> BinaryExpression
where BE1: Borrow<BinaryExpression>, BE2: Borrow<BinaryExpression> {
let x = x.borrow();
let y = y.borrow();
let in_bits = x.len().max(y.len());
let sum_bits = in_bits + 1;
assert!(sum_bits < FieldElement::max_bits(),
"Binary operands are too large to fit an a field element.");
let sum_wire = self.binary_wire(sum_bits);
let sum = BinaryExpression::from(sum_wire.clone());
let x_joined = x.join();
let y_joined = y.join();
let sum_joined = sum.join();
self.assert_equal(x_joined.clone() + y_joined.clone(), sum_joined);
self.generator(
[x.dependencies(), y.dependencies()].concat(),
move |values: &mut WireValues| {
let sum_value = (x_joined.clone() + y_joined.clone())
.evaluate(values).value().clone();
values.set_binary_unsigned(sum_wire.clone(), sum_value);
},
);
sum
}
pub fn binary_sum_ignoring_overflow<BE1, BE2>(&mut self, x: BE1, y: BE2) -> BinaryExpression
where BE1: Borrow<BinaryExpression>, BE2: Borrow<BinaryExpression> {
let sum = self.binary_sum(x, y);
sum.truncated(sum.len() - 1)
}
pub fn binary_sum_asserting_no_overflow<BE1, BE2>(&mut self, x: BE1, y: BE2) -> BinaryExpression
where BE1: Borrow<BinaryExpression>, BE2: Borrow<BinaryExpression> {
let sum = self.binary_sum(x, y);
let overflow_bit = sum.bits[sum.len() - 1].clone();
self.assert_false(overflow_bit);
sum.truncated(sum.len() - 1)
}
}