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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use super::AllocatedScalar;
use crate::Error as GadgetsError;
use dusk_plonk::prelude::*;
pub fn conditionally_select_zero(
composer: &mut StandardComposer,
x: Variable,
select: Variable,
) -> Variable {
composer.mul(BlsScalar::one(), x, select, BlsScalar::zero(), None)
}
pub fn conditionally_select_one(
composer: &mut StandardComposer,
y: Variable,
selector: Variable,
) -> Variable {
let one = composer.add_witness_to_circuit_description(BlsScalar::one());
let selector_y = composer.mul(BlsScalar::one(), y, selector, BlsScalar::zero(), None);
let one_min_selector = composer.add(
(BlsScalar::one(), one),
(-BlsScalar::one(), selector),
BlsScalar::zero(),
None,
);
composer.add(
(BlsScalar::one(), selector_y),
(BlsScalar::one(), one_min_selector),
BlsScalar::zero(),
None,
)
}
pub fn is_non_zero(
composer: &mut StandardComposer,
var: Variable,
value_assigned: BlsScalar,
) -> Result<(), GadgetsError> {
let var_assigned = composer.add_input(value_assigned);
composer.assert_equal(var, var_assigned);
let inverse = value_assigned.invert();
let inv: Variable;
if inverse.is_some().unwrap_u8() == 1u8 {
inv = composer.add_input(inverse.unwrap());
} else {
return Err(GadgetsError::NonExistingInverse);
}
let one = composer.add_witness_to_circuit_description(BlsScalar::one());
composer.poly_gate(
var,
inv,
one,
BlsScalar::one(),
BlsScalar::zero(),
BlsScalar::zero(),
-BlsScalar::one(),
BlsScalar::zero(),
None,
);
Ok(())
}
pub fn maybe_equal(
composer: &mut StandardComposer,
a: AllocatedScalar,
b: AllocatedScalar,
) -> Variable {
let u = {
let q_l_a = (BlsScalar::one(), a.var);
let q_r_b = (-BlsScalar::one(), b.var);
let q_c = BlsScalar::zero();
composer.add(q_l_a, q_r_b, q_c, None)
};
let u_scalar = a.scalar - b.scalar;
let u_inv_scalar = u_scalar.invert().unwrap_or(BlsScalar::zero());
let z = composer.add_input(u_inv_scalar);
let y = composer.mul(-BlsScalar::one(), z, u, BlsScalar::one(), None);
{
let a = y;
let b = u;
let c = u;
let q_m = BlsScalar::one();
let q_o = BlsScalar::zero();
let q_c = BlsScalar::zero();
composer.mul_gate(a, b, c, q_m, q_o, q_c, None);
}
y
}