snarkvm_circuit_types_boolean/
equal.rs

1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use super::*;
17
18impl<E: Environment> Equal<Self> for Boolean<E> {
19    type Output = Boolean<E>;
20
21    /// Returns `true` if `self` and `other` are equal.
22    fn is_equal(&self, other: &Self) -> Self::Output {
23        !self.is_not_equal(other)
24    }
25
26    /// Returns `true` if `self` and `other` are *not* equal.
27    fn is_not_equal(&self, other: &Self) -> Self::Output {
28        self ^ other
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35    use snarkvm_circuit_environment::Circuit;
36
37    fn check_is_equal(
38        name: &str,
39        expected: bool,
40        a: Boolean<Circuit>,
41        b: Boolean<Circuit>,
42        num_constants: u64,
43        num_public: u64,
44        num_private: u64,
45        num_constraints: u64,
46    ) {
47        Circuit::scope(name, || {
48            let candidate = a.is_equal(&b);
49            assert_eq!(expected, candidate.eject_value(), "({} == {})", a.eject_value(), b.eject_value());
50            assert_scope!(num_constants, num_public, num_private, num_constraints);
51        });
52    }
53
54    #[test]
55    fn test_constant_equals_constant() {
56        // false == false
57        let expected = true;
58        let a = Boolean::<Circuit>::new(Mode::Constant, false);
59        let b = Boolean::<Circuit>::new(Mode::Constant, false);
60        check_is_equal("false == false", expected, a, b, 0, 0, 0, 0);
61
62        // false == true
63        let expected = false;
64        let a = Boolean::<Circuit>::new(Mode::Constant, false);
65        let b = Boolean::<Circuit>::new(Mode::Constant, true);
66        check_is_equal("false == true", expected, a, b, 0, 0, 0, 0);
67
68        // true == false
69        let expected = false;
70        let a = Boolean::<Circuit>::new(Mode::Constant, true);
71        let b = Boolean::<Circuit>::new(Mode::Constant, false);
72        check_is_equal("true == false", expected, a, b, 0, 0, 0, 0);
73
74        // true == true
75        let expected = true;
76        let a = Boolean::<Circuit>::new(Mode::Constant, true);
77        let b = Boolean::<Circuit>::new(Mode::Constant, true);
78        check_is_equal("true == true", expected, a, b, 0, 0, 0, 0);
79    }
80
81    #[test]
82    fn test_constant_equals_public() {
83        // false == false
84        let expected = true;
85        let a = Boolean::<Circuit>::new(Mode::Constant, false);
86        let b = Boolean::<Circuit>::new(Mode::Public, false);
87        check_is_equal("false == false", expected, a, b, 0, 0, 0, 0);
88
89        // false == true
90        let expected = false;
91        let a = Boolean::<Circuit>::new(Mode::Constant, false);
92        let b = Boolean::<Circuit>::new(Mode::Public, true);
93        check_is_equal("false == true", expected, a, b, 0, 0, 0, 0);
94
95        // true == false
96        let expected = false;
97        let a = Boolean::<Circuit>::new(Mode::Constant, true);
98        let b = Boolean::<Circuit>::new(Mode::Public, false);
99        check_is_equal("true == false", expected, a, b, 0, 0, 0, 0);
100
101        // true == true
102        let expected = true;
103        let a = Boolean::<Circuit>::new(Mode::Constant, true);
104        let b = Boolean::<Circuit>::new(Mode::Public, true);
105        check_is_equal("true == true", expected, a, b, 0, 0, 0, 0);
106    }
107
108    #[test]
109    fn test_constant_equal_private() {
110        // false == false
111        let expected = true;
112        let a = Boolean::<Circuit>::new(Mode::Constant, false);
113        let b = Boolean::<Circuit>::new(Mode::Private, false);
114        check_is_equal("false == false", expected, a, b, 0, 0, 0, 0);
115
116        // false == true
117        let expected = false;
118        let a = Boolean::<Circuit>::new(Mode::Constant, false);
119        let b = Boolean::<Circuit>::new(Mode::Private, true);
120        check_is_equal("false == true", expected, a, b, 0, 0, 0, 0);
121
122        // true == false
123        let expected = false;
124        let a = Boolean::<Circuit>::new(Mode::Constant, true);
125        let b = Boolean::<Circuit>::new(Mode::Private, false);
126        check_is_equal("true == false", expected, a, b, 0, 0, 0, 0);
127
128        // true == true
129        let expected = true;
130        let a = Boolean::<Circuit>::new(Mode::Constant, true);
131        let b = Boolean::<Circuit>::new(Mode::Private, true);
132        check_is_equal("true == true", expected, a, b, 0, 0, 0, 0);
133    }
134
135    #[test]
136    fn test_public_equals_constant() {
137        // false == false
138        let expected = true;
139        let a = Boolean::<Circuit>::new(Mode::Public, false);
140        let b = Boolean::<Circuit>::new(Mode::Constant, false);
141        check_is_equal("false == false", expected, a, b, 0, 0, 0, 0);
142
143        // false == true
144        let expected = false;
145        let a = Boolean::<Circuit>::new(Mode::Public, false);
146        let b = Boolean::<Circuit>::new(Mode::Constant, true);
147        check_is_equal("false == true", expected, a, b, 0, 0, 0, 0);
148
149        // true == false
150        let expected = false;
151        let a = Boolean::<Circuit>::new(Mode::Public, true);
152        let b = Boolean::<Circuit>::new(Mode::Constant, false);
153        check_is_equal("true == false", expected, a, b, 0, 0, 0, 0);
154
155        // true == true
156        let expected = true;
157        let a = Boolean::<Circuit>::new(Mode::Public, true);
158        let b = Boolean::<Circuit>::new(Mode::Constant, true);
159        check_is_equal("true == true", expected, a, b, 0, 0, 0, 0);
160    }
161
162    #[test]
163    fn test_public_equals_public() {
164        // false == false
165        let expected = true;
166        let a = Boolean::<Circuit>::new(Mode::Public, false);
167        let b = Boolean::<Circuit>::new(Mode::Public, false);
168        check_is_equal("false == false", expected, a, b, 0, 0, 1, 1);
169
170        // false == true
171        let expected = false;
172        let a = Boolean::<Circuit>::new(Mode::Public, false);
173        let b = Boolean::<Circuit>::new(Mode::Public, true);
174        check_is_equal("false == true", expected, a, b, 0, 0, 1, 1);
175
176        // true == false
177        let expected = false;
178        let a = Boolean::<Circuit>::new(Mode::Public, true);
179        let b = Boolean::<Circuit>::new(Mode::Public, false);
180        check_is_equal("true == false", expected, a, b, 0, 0, 1, 1);
181
182        // true == true
183        let expected = true;
184        let a = Boolean::<Circuit>::new(Mode::Public, true);
185        let b = Boolean::<Circuit>::new(Mode::Public, true);
186        check_is_equal("true == true", expected, a, b, 0, 0, 1, 1);
187    }
188
189    #[test]
190    fn test_public_equals_private() {
191        // false == false
192        let expected = true;
193        let a = Boolean::<Circuit>::new(Mode::Public, false);
194        let b = Boolean::<Circuit>::new(Mode::Private, false);
195        check_is_equal("false == false", expected, a, b, 0, 0, 1, 1);
196
197        // false == true
198        let expected = false;
199        let a = Boolean::<Circuit>::new(Mode::Public, false);
200        let b = Boolean::<Circuit>::new(Mode::Private, true);
201        check_is_equal("false == true", expected, a, b, 0, 0, 1, 1);
202
203        // true == false
204        let expected = false;
205        let a = Boolean::<Circuit>::new(Mode::Public, true);
206        let b = Boolean::<Circuit>::new(Mode::Private, false);
207        check_is_equal("true == false", expected, a, b, 0, 0, 1, 1);
208
209        // true == true
210        let expected = true;
211        let a = Boolean::<Circuit>::new(Mode::Public, true);
212        let b = Boolean::<Circuit>::new(Mode::Private, true);
213        check_is_equal("true == true", expected, a, b, 0, 0, 1, 1);
214    }
215
216    #[test]
217    fn test_private_equals_constant() {
218        // false == false
219        let expected = true;
220        let a = Boolean::<Circuit>::new(Mode::Private, false);
221        let b = Boolean::<Circuit>::new(Mode::Constant, false);
222        check_is_equal("false == false", expected, a, b, 0, 0, 0, 0);
223
224        // false == true
225        let expected = false;
226        let a = Boolean::<Circuit>::new(Mode::Private, false);
227        let b = Boolean::<Circuit>::new(Mode::Constant, true);
228        check_is_equal("false == true", expected, a, b, 0, 0, 0, 0);
229
230        // true == false
231        let expected = false;
232        let a = Boolean::<Circuit>::new(Mode::Private, true);
233        let b = Boolean::<Circuit>::new(Mode::Constant, false);
234        check_is_equal("true == false", expected, a, b, 0, 0, 0, 0);
235
236        // true == true
237        let expected = true;
238        let a = Boolean::<Circuit>::new(Mode::Private, true);
239        let b = Boolean::<Circuit>::new(Mode::Constant, true);
240        check_is_equal("true == true", expected, a, b, 0, 0, 0, 0);
241    }
242
243    #[test]
244    fn test_private_equal_public() {
245        // false == false
246        let expected = true;
247        let a = Boolean::<Circuit>::new(Mode::Private, false);
248        let b = Boolean::<Circuit>::new(Mode::Public, false);
249        check_is_equal("false == false", expected, a, b, 0, 0, 1, 1);
250
251        // false == true
252        let expected = false;
253        let a = Boolean::<Circuit>::new(Mode::Private, false);
254        let b = Boolean::<Circuit>::new(Mode::Public, true);
255        check_is_equal("false == true", expected, a, b, 0, 0, 1, 1);
256
257        // true == false
258        let expected = false;
259        let a = Boolean::<Circuit>::new(Mode::Private, true);
260        let b = Boolean::<Circuit>::new(Mode::Public, false);
261        check_is_equal("true == false", expected, a, b, 0, 0, 1, 1);
262
263        // true == true
264        let expected = true;
265        let a = Boolean::<Circuit>::new(Mode::Private, true);
266        let b = Boolean::<Circuit>::new(Mode::Public, true);
267        check_is_equal("true == true", expected, a, b, 0, 0, 1, 1);
268    }
269
270    #[test]
271    fn test_private_equals_private() {
272        // false == false
273        let expected = true;
274        let a = Boolean::<Circuit>::new(Mode::Private, false);
275        let b = Boolean::<Circuit>::new(Mode::Private, false);
276        check_is_equal("false == false", expected, a, b, 0, 0, 1, 1);
277
278        // false == true
279        let expected = false;
280        let a = Boolean::<Circuit>::new(Mode::Private, false);
281        let b = Boolean::<Circuit>::new(Mode::Private, true);
282        check_is_equal("false == true", expected, a, b, 0, 0, 1, 1);
283
284        // true == false
285        let expected = false;
286        let a = Boolean::<Circuit>::new(Mode::Private, true);
287        let b = Boolean::<Circuit>::new(Mode::Private, false);
288        check_is_equal("true == false", expected, a, b, 0, 0, 1, 1);
289
290        // true == true
291        let expected = true;
292        let a = Boolean::<Circuit>::new(Mode::Private, true);
293        let b = Boolean::<Circuit>::new(Mode::Private, true);
294        check_is_equal("true == true", expected, a, b, 0, 0, 1, 1);
295    }
296}