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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use core::borrow::Borrow;
use crate::expression::{BooleanExpression, Expression};
use crate::gadget_builder::GadgetBuilder;
impl GadgetBuilder {
pub fn not<BE: Borrow<BooleanExpression>>(&mut self, x: BE) -> BooleanExpression {
BooleanExpression::new_unsafe(Expression::one() - x.borrow().expression())
}
pub fn and<BE1, BE2>(&mut self, x: BE1, y: BE2) -> BooleanExpression
where BE1: Borrow<BooleanExpression>, BE2: Borrow<BooleanExpression> {
BooleanExpression::new_unsafe(self.product(x.borrow().expression(), y.borrow().expression()))
}
pub fn or<BE1, BE2>(&mut self, x: BE1, y: BE2) -> BooleanExpression
where BE1: Borrow<BooleanExpression>, BE2: Borrow<BooleanExpression> {
let x_exp = x.borrow().expression();
let y_exp = y.borrow().expression();
BooleanExpression::new_unsafe(
x_exp + y_exp - self.product(x_exp, y_exp))
}
pub fn xor<BE1, BE2>(&mut self, x: BE1, y: BE2) -> BooleanExpression
where BE1: Borrow<BooleanExpression>, BE2: Borrow<BooleanExpression> {
let x_exp = x.borrow().expression();
let y_exp = y.borrow().expression();
BooleanExpression::new_unsafe(x_exp + y_exp - self.product(x_exp, y_exp) * 2u128)
}
}
#[cfg(test)]
mod tests {
use crate::expression::BooleanExpression;
use crate::gadget_builder::GadgetBuilder;
#[test]
fn and() {
let mut builder = GadgetBuilder::new();
let (x, y) = (builder.boolean_wire(), builder.boolean_wire());
let and = builder.and(BooleanExpression::from(x), BooleanExpression::from(y));
let gadget = builder.build();
let mut values00 = boolean_values!(x => false, y => false);
assert!(gadget.execute(&mut values00));
assert_eq!(false, and.evaluate(&values00));
let mut values01 = boolean_values!(x => false, y => true);
assert!(gadget.execute(&mut values01));
assert_eq!(false, and.evaluate(&values01));
let mut values10 = boolean_values!(x => true, y => false);
assert!(gadget.execute(&mut values10));
assert_eq!(false, and.evaluate(&values10));
let mut values11 = boolean_values!(x => true, y => true);
assert!(gadget.execute(&mut values11));
assert_eq!(true, and.evaluate(&values11));
}
#[test]
fn or() {
let mut builder = GadgetBuilder::new();
let (x, y) = (builder.boolean_wire(), builder.boolean_wire());
let or = builder.or(BooleanExpression::from(x), BooleanExpression::from(y));
let gadget = builder.build();
let mut values00 = boolean_values!(x => false, y => false);
assert!(gadget.execute(&mut values00));
assert_eq!(false, or.evaluate(&values00));
let mut values01 = boolean_values!(x => false, y => true);
assert!(gadget.execute(&mut values01));
assert_eq!(true, or.evaluate(&values01));
let mut values10 = boolean_values!(x => true, y => false);
assert!(gadget.execute(&mut values10));
assert_eq!(true, or.evaluate(&values10));
let mut values11 = boolean_values!(x => true, y => true);
assert!(gadget.execute(&mut values11));
assert_eq!(true, or.evaluate(&values11));
}
#[test]
fn xor() {
let mut builder = GadgetBuilder::new();
let (x, y) = (builder.boolean_wire(), builder.boolean_wire());
let xor = builder.xor(BooleanExpression::from(x), BooleanExpression::from(y));
let gadget = builder.build();
let mut values00 = boolean_values!(x => false, y => false);
assert!(gadget.execute(&mut values00));
assert_eq!(false, xor.evaluate(&values00));
let mut values01 = boolean_values!(x => false, y => true);
assert!(gadget.execute(&mut values01));
assert_eq!(true, xor.evaluate(&values01));
let mut values10 = boolean_values!(x => true, y => false);
assert!(gadget.execute(&mut values10));
assert_eq!(true, xor.evaluate(&values10));
let mut values11 = boolean_values!(x => true, y => true);
assert!(gadget.execute(&mut values11));
assert_eq!(false, xor.evaluate(&values11));
}
}