/ circuit / types / boolean / src / helpers / adder.rs
adder.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // This file is part of the AlphaVM 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  
 16  use super::*;
 17  
 18  impl<E: Environment> Adder for Boolean<E> {
 19      type Carry = Boolean<E>;
 20      type Sum = Boolean<E>;
 21  
 22      /// Returns the sum of `self` and `other` as a sum bit and carry bit.
 23      fn adder(&self, other: &Self, carry: &Self) -> (Self::Sum, Self::Carry) {
 24          // Compute the sum bit.
 25          let c0 = self ^ other;
 26          let sum = &c0 ^ carry;
 27  
 28          // Compute the carry bit.
 29          let c1 = self & other;
 30          let c2 = carry & c0;
 31          let carry = c1 | c2;
 32  
 33          (sum, carry)
 34      }
 35  }
 36  
 37  #[cfg(test)]
 38  mod tests {
 39      use super::*;
 40      use alphavm_circuit_environment::Circuit;
 41  
 42      fn check_adder(
 43          name: &str,
 44          expected_sum: bool,
 45          expected_carry: bool,
 46          a: Boolean<Circuit>,
 47          b: Boolean<Circuit>,
 48          c: Boolean<Circuit>,
 49          num_constants: u64,
 50          num_public: u64,
 51          num_private: u64,
 52          num_constraints: u64,
 53      ) {
 54          Circuit::scope(name, || {
 55              let case = format!("({} ADD {} WITH {})", a.eject_value(), b.eject_value(), c.eject_value());
 56              let (candidate_sum, candidate_carry) = a.adder(&b, &c);
 57              assert_eq!(expected_sum, candidate_sum.eject_value(), "SUM {case}");
 58              assert_eq!(expected_carry, candidate_carry.eject_value(), "CARRY {case}");
 59              assert_scope!(case, num_constants, num_public, num_private, num_constraints);
 60          });
 61      }
 62  
 63      #[rustfmt::skip]
 64      fn check_false_add_false_with_false(
 65          mode_a: Mode,
 66          mode_b: Mode,
 67          mode_c: Mode,
 68          num_constants: u64,
 69          num_public: u64,
 70          num_private: u64,
 71          num_constraints: u64
 72      ) {
 73          // false ADD false WITH false => (false, false)
 74          let expected_sum = false;
 75          let expected_carry = false;
 76          let a = Boolean::<Circuit>::new(mode_a, false);
 77          let b = Boolean::<Circuit>::new(mode_b, false);
 78          let c = Boolean::<Circuit>::new(mode_c, false);
 79          check_adder("false ADD false WITH false", expected_sum, expected_carry, a, b, c, num_constants, num_public, num_private, num_constraints);
 80      }
 81  
 82      #[rustfmt::skip]
 83      fn check_false_add_false_with_true(
 84          mode_a: Mode,
 85          mode_b: Mode,
 86          mode_c: Mode,
 87          num_constants: u64,
 88          num_public: u64,
 89          num_private: u64,
 90          num_constraints: u64
 91      ) {
 92          // false ADD false WITH true => (true, false)
 93          let expected_sum = true;
 94          let expected_carry = false;
 95          let a = Boolean::<Circuit>::new(mode_a, false);
 96          let b = Boolean::<Circuit>::new(mode_b, false);
 97          let c = Boolean::<Circuit>::new(mode_c, true);
 98          check_adder("false ADD false WITH true", expected_sum, expected_carry, a, b, c, num_constants, num_public, num_private, num_constraints);
 99      }
100  
101      #[rustfmt::skip]
102      fn check_false_add_true_with_false(
103          mode_a: Mode,
104          mode_b: Mode,
105          mode_c: Mode,
106          num_constants: u64,
107          num_public: u64,
108          num_private: u64,
109          num_constraints: u64
110      ) {
111          // false ADD true WITH false => (true, false)
112          let expected_sum = true;
113          let expected_carry = false;
114          let a = Boolean::<Circuit>::new(mode_a, false);
115          let b = Boolean::<Circuit>::new(mode_b, true);
116          let c = Boolean::<Circuit>::new(mode_c, false);
117          check_adder("false ADD true WITH false", expected_sum, expected_carry, a, b, c, num_constants, num_public, num_private, num_constraints);
118      }
119  
120      #[rustfmt::skip]
121      fn check_false_add_true_with_true(
122          mode_a: Mode,
123          mode_b: Mode,
124          mode_c: Mode,
125          num_constants: u64,
126          num_public: u64,
127          num_private: u64,
128          num_constraints: u64
129      ) {
130          // false ADD true WITH true => (false, true)
131          let expected_sum = false;
132          let expected_carry = true;
133          let a = Boolean::<Circuit>::new(mode_a, false);
134          let b = Boolean::<Circuit>::new(mode_b, true);
135          let c = Boolean::<Circuit>::new(mode_c, true);
136          check_adder("false ADD true WITH true", expected_sum, expected_carry, a, b, c, num_constants, num_public, num_private, num_constraints);
137      }
138  
139      #[rustfmt::skip]
140      fn check_true_add_false_with_false(
141          mode_a: Mode,
142          mode_b: Mode,
143          mode_c: Mode,
144          num_constants: u64,
145          num_public: u64,
146          num_private: u64,
147          num_constraints: u64
148      ) {
149          // true ADD false WITH false => (true, false)
150          let expected_sum = true;
151          let expected_carry = false;
152          let a = Boolean::<Circuit>::new(mode_a, true);
153          let b = Boolean::<Circuit>::new(mode_b, false);
154          let c = Boolean::<Circuit>::new(mode_c, false);
155          check_adder("true ADD false WITH false", expected_sum, expected_carry, a, b, c, num_constants, num_public, num_private, num_constraints);
156      }
157  
158      #[rustfmt::skip]
159      fn check_true_add_false_with_true(
160          mode_a: Mode,
161          mode_b: Mode,
162          mode_c: Mode,
163          num_constants: u64,
164          num_public: u64,
165          num_private: u64,
166          num_constraints: u64
167      ) {
168          // true ADD false WITH true => (false, true)
169          let expected_sum = false;
170          let expected_carry = true;
171          let a = Boolean::<Circuit>::new(mode_a, true);
172          let b = Boolean::<Circuit>::new(mode_b, false);
173          let c = Boolean::<Circuit>::new(mode_c, true);
174          check_adder("true ADD false WITH true", expected_sum, expected_carry, a, b, c, num_constants, num_public, num_private, num_constraints);
175      }
176  
177      #[rustfmt::skip]
178      fn check_true_add_true_with_false(
179          mode_a: Mode,
180          mode_b: Mode,
181          mode_c: Mode,
182          num_constants: u64,
183          num_public: u64,
184          num_private: u64,
185          num_constraints: u64
186      ) {
187          // true ADD true WITH false => (false, true)
188          let expected_sum = false;
189          let expected_carry = true;
190          let a = Boolean::<Circuit>::new(mode_a, true);
191          let b = Boolean::<Circuit>::new(mode_b, true);
192          let c = Boolean::<Circuit>::new(mode_c, false);
193          check_adder("true ADD true WITH false", expected_sum, expected_carry, a, b, c, num_constants, num_public, num_private, num_constraints);
194      }
195  
196      #[rustfmt::skip]
197      fn check_true_add_true_with_true(
198          mode_a: Mode,
199          mode_b: Mode,
200          mode_c: Mode,
201          num_constants: u64,
202          num_public: u64,
203          num_private: u64,
204          num_constraints: u64
205      ) {
206          // true ADD true WITH true => (true, true)
207          let expected_sum = true;
208          let expected_carry = true;
209          let a = Boolean::<Circuit>::new(mode_a, true);
210          let b = Boolean::<Circuit>::new(mode_b, true);
211          let c = Boolean::<Circuit>::new(mode_c, true);
212          check_adder("true ADD true WITH true", expected_sum, expected_carry, a, b, c, num_constants, num_public, num_private, num_constraints);
213      }
214  
215      #[test]
216      fn test_constant_add_constant_with_constant() {
217          check_false_add_false_with_false(Mode::Constant, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
218          check_false_add_false_with_true(Mode::Constant, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
219          check_false_add_true_with_false(Mode::Constant, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
220          check_false_add_true_with_true(Mode::Constant, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
221          check_true_add_false_with_false(Mode::Constant, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
222          check_true_add_false_with_true(Mode::Constant, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
223          check_true_add_true_with_false(Mode::Constant, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
224          check_true_add_true_with_true(Mode::Constant, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
225      }
226  
227      #[test]
228      fn test_constant_add_constant_with_public() {
229          check_false_add_false_with_false(Mode::Constant, Mode::Constant, Mode::Public, 0, 0, 0, 0);
230          check_false_add_false_with_true(Mode::Constant, Mode::Constant, Mode::Public, 0, 0, 0, 0);
231          check_false_add_true_with_false(Mode::Constant, Mode::Constant, Mode::Public, 0, 0, 0, 0);
232          check_false_add_true_with_true(Mode::Constant, Mode::Constant, Mode::Public, 0, 0, 0, 0);
233          check_true_add_false_with_false(Mode::Constant, Mode::Constant, Mode::Public, 0, 0, 0, 0);
234          check_true_add_false_with_true(Mode::Constant, Mode::Constant, Mode::Public, 0, 0, 0, 0);
235          check_true_add_true_with_false(Mode::Constant, Mode::Constant, Mode::Public, 0, 0, 0, 0);
236          check_true_add_true_with_true(Mode::Constant, Mode::Constant, Mode::Public, 0, 0, 0, 0);
237      }
238  
239      #[test]
240      fn test_constant_add_constant_with_private() {
241          check_false_add_false_with_false(Mode::Constant, Mode::Constant, Mode::Private, 0, 0, 0, 0);
242          check_false_add_false_with_true(Mode::Constant, Mode::Constant, Mode::Private, 0, 0, 0, 0);
243          check_false_add_true_with_false(Mode::Constant, Mode::Constant, Mode::Private, 0, 0, 0, 0);
244          check_false_add_true_with_true(Mode::Constant, Mode::Constant, Mode::Private, 0, 0, 0, 0);
245          check_true_add_false_with_false(Mode::Constant, Mode::Constant, Mode::Private, 0, 0, 0, 0);
246          check_true_add_false_with_true(Mode::Constant, Mode::Constant, Mode::Private, 0, 0, 0, 0);
247          check_true_add_true_with_false(Mode::Constant, Mode::Constant, Mode::Private, 0, 0, 0, 0);
248          check_true_add_true_with_true(Mode::Constant, Mode::Constant, Mode::Private, 0, 0, 0, 0);
249      }
250  
251      #[test]
252      fn test_constant_add_public_with_constant() {
253          check_false_add_false_with_false(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 0, 0);
254          check_false_add_false_with_true(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 0, 0);
255          check_false_add_true_with_false(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 0, 0);
256          check_false_add_true_with_true(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 0, 0);
257          check_true_add_false_with_false(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 0, 0);
258          check_true_add_false_with_true(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 1, 1); // <- Differs
259          check_true_add_true_with_false(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 0, 0);
260          check_true_add_true_with_true(Mode::Constant, Mode::Public, Mode::Constant, 0, 0, 1, 1);
261          // <- Differs
262      }
263  
264      #[test]
265      fn test_constant_add_public_with_public() {
266          check_false_add_false_with_false(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 2, 2);
267          check_false_add_false_with_true(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 2, 2);
268          check_false_add_true_with_false(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 2, 2);
269          check_false_add_true_with_true(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 2, 2);
270          check_true_add_false_with_false(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 3, 3); // <- Differs
271          check_true_add_false_with_true(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 3, 3); // <- Differs
272          check_true_add_true_with_false(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 3, 3); // <- Differs
273          check_true_add_true_with_true(Mode::Constant, Mode::Public, Mode::Public, 0, 0, 3, 3);
274          // <- Differs
275      }
276  
277      #[test]
278      fn test_constant_add_public_with_private() {
279          check_false_add_false_with_false(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 2, 2);
280          check_false_add_false_with_true(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 2, 2);
281          check_false_add_true_with_false(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 2, 2);
282          check_false_add_true_with_true(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 2, 2);
283          check_true_add_false_with_false(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 3, 3); // <- Differs
284          check_true_add_false_with_true(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 3, 3); // <- Differs
285          check_true_add_true_with_false(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 3, 3); // <- Differs
286          check_true_add_true_with_true(Mode::Constant, Mode::Public, Mode::Private, 0, 0, 3, 3);
287          // <- Differs
288      }
289  
290      #[test]
291      fn test_constant_add_private_with_constant() {
292          check_false_add_false_with_false(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 0, 0);
293          check_false_add_false_with_true(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 0, 0);
294          check_false_add_true_with_false(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 0, 0);
295          check_false_add_true_with_true(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 0, 0);
296          check_true_add_false_with_false(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 0, 0);
297          check_true_add_false_with_true(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 1, 1); // <- Differs
298          check_true_add_true_with_false(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 0, 0);
299          check_true_add_true_with_true(Mode::Constant, Mode::Private, Mode::Constant, 0, 0, 1, 1);
300          // <- Differs
301      }
302  
303      #[test]
304      fn test_constant_add_private_with_public() {
305          check_false_add_false_with_false(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 2, 2);
306          check_false_add_false_with_true(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 2, 2);
307          check_false_add_true_with_false(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 2, 2);
308          check_false_add_true_with_true(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 2, 2);
309          check_true_add_false_with_false(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 3, 3); // <- Differs
310          check_true_add_false_with_true(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 3, 3); // <- Differs
311          check_true_add_true_with_false(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 3, 3); // <- Differs
312          check_true_add_true_with_true(Mode::Constant, Mode::Private, Mode::Public, 0, 0, 3, 3);
313          // <- Differs
314      }
315  
316      #[test]
317      fn test_constant_add_private_with_private() {
318          check_false_add_false_with_false(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 2, 2);
319          check_false_add_false_with_true(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 2, 2);
320          check_false_add_true_with_false(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 2, 2);
321          check_false_add_true_with_true(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 2, 2);
322          check_true_add_false_with_false(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 3, 3); // <- Differs
323          check_true_add_false_with_true(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 3, 3); // <- Differs
324          check_true_add_true_with_false(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 3, 3); // <- Differs
325          check_true_add_true_with_true(Mode::Constant, Mode::Private, Mode::Private, 0, 0, 3, 3);
326          // <- Differs
327      }
328  
329      #[test]
330      fn test_public_add_constant_with_constant() {
331          check_false_add_false_with_false(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
332          check_false_add_false_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
333          check_false_add_true_with_false(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
334          check_false_add_true_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 1, 1); // <- Differs
335          check_true_add_false_with_false(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
336          check_true_add_false_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
337          check_true_add_true_with_false(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 0, 0);
338          check_true_add_true_with_true(Mode::Public, Mode::Constant, Mode::Constant, 0, 0, 1, 1);
339          // <- Differs
340      }
341  
342      #[test]
343      fn test_public_add_constant_with_public() {
344          check_false_add_false_with_false(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 2, 2);
345          check_false_add_false_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 2, 2);
346          check_false_add_true_with_false(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3); // <- Differs
347          check_false_add_true_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3); // <- Differs
348          check_true_add_false_with_false(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 2, 2);
349          check_true_add_false_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 2, 2);
350          check_true_add_true_with_false(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3); // <- Differs
351          check_true_add_true_with_true(Mode::Public, Mode::Constant, Mode::Public, 0, 0, 3, 3);
352          // <- Differs
353      }
354  
355      #[test]
356      fn test_public_add_constant_with_private() {
357          check_false_add_false_with_false(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 2, 2);
358          check_false_add_false_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 2, 2);
359          check_false_add_true_with_false(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3); // <- Differs
360          check_false_add_true_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3); // <- Differs
361          check_true_add_false_with_false(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 2, 2);
362          check_true_add_false_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 2, 2);
363          check_true_add_true_with_false(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3); // <- Differs
364          check_true_add_true_with_true(Mode::Public, Mode::Constant, Mode::Private, 0, 0, 3, 3);
365          // <- Differs
366      }
367  
368      #[test]
369      fn test_public_add_public_with_constant() {
370          check_false_add_false_with_false(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 2, 2);
371          check_false_add_false_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3); // <- Differs
372          check_false_add_true_with_false(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 2, 2);
373          check_false_add_true_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3); // <- Differs
374          check_true_add_false_with_false(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 2, 2);
375          check_true_add_false_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3); // <- Differs
376          check_true_add_true_with_false(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 2, 2);
377          check_true_add_true_with_true(Mode::Public, Mode::Public, Mode::Constant, 0, 0, 3, 3);
378          // <- Differs
379      }
380  
381      #[test]
382      fn test_public_add_public_with_public() {
383          check_false_add_false_with_false(Mode::Public, Mode::Public, Mode::Public, 0, 0, 5, 5);
384          check_false_add_false_with_true(Mode::Public, Mode::Public, Mode::Public, 0, 0, 5, 5);
385          check_false_add_true_with_false(Mode::Public, Mode::Public, Mode::Public, 0, 0, 5, 5);
386          check_false_add_true_with_true(Mode::Public, Mode::Public, Mode::Public, 0, 0, 5, 5);
387          check_true_add_false_with_false(Mode::Public, Mode::Public, Mode::Public, 0, 0, 5, 5);
388          check_true_add_false_with_true(Mode::Public, Mode::Public, Mode::Public, 0, 0, 5, 5);
389          check_true_add_true_with_false(Mode::Public, Mode::Public, Mode::Public, 0, 0, 5, 5);
390          check_true_add_true_with_true(Mode::Public, Mode::Public, Mode::Public, 0, 0, 5, 5);
391      }
392  
393      #[test]
394      fn test_public_add_public_with_private() {
395          check_false_add_false_with_false(Mode::Public, Mode::Public, Mode::Private, 0, 0, 5, 5);
396          check_false_add_false_with_true(Mode::Public, Mode::Public, Mode::Private, 0, 0, 5, 5);
397          check_false_add_true_with_false(Mode::Public, Mode::Public, Mode::Private, 0, 0, 5, 5);
398          check_false_add_true_with_true(Mode::Public, Mode::Public, Mode::Private, 0, 0, 5, 5);
399          check_true_add_false_with_false(Mode::Public, Mode::Public, Mode::Private, 0, 0, 5, 5);
400          check_true_add_false_with_true(Mode::Public, Mode::Public, Mode::Private, 0, 0, 5, 5);
401          check_true_add_true_with_false(Mode::Public, Mode::Public, Mode::Private, 0, 0, 5, 5);
402          check_true_add_true_with_true(Mode::Public, Mode::Public, Mode::Private, 0, 0, 5, 5);
403      }
404  
405      #[test]
406      fn test_public_add_private_with_constant() {
407          check_false_add_false_with_false(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 2, 2);
408          check_false_add_false_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3); // <- Differs
409          check_false_add_true_with_false(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 2, 2);
410          check_false_add_true_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3); // <- Differs
411          check_true_add_false_with_false(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 2, 2);
412          check_true_add_false_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3); // <- Differs
413          check_true_add_true_with_false(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 2, 2);
414          check_true_add_true_with_true(Mode::Public, Mode::Private, Mode::Constant, 0, 0, 3, 3);
415          // <- Differs
416      }
417  
418      #[test]
419      fn test_public_add_private_with_public() {
420          check_false_add_false_with_false(Mode::Public, Mode::Private, Mode::Public, 0, 0, 5, 5);
421          check_false_add_false_with_true(Mode::Public, Mode::Private, Mode::Public, 0, 0, 5, 5);
422          check_false_add_true_with_false(Mode::Public, Mode::Private, Mode::Public, 0, 0, 5, 5);
423          check_false_add_true_with_true(Mode::Public, Mode::Private, Mode::Public, 0, 0, 5, 5);
424          check_true_add_false_with_false(Mode::Public, Mode::Private, Mode::Public, 0, 0, 5, 5);
425          check_true_add_false_with_true(Mode::Public, Mode::Private, Mode::Public, 0, 0, 5, 5);
426          check_true_add_true_with_false(Mode::Public, Mode::Private, Mode::Public, 0, 0, 5, 5);
427          check_true_add_true_with_true(Mode::Public, Mode::Private, Mode::Public, 0, 0, 5, 5);
428      }
429  
430      #[test]
431      fn test_public_add_private_with_private() {
432          check_false_add_false_with_false(Mode::Public, Mode::Private, Mode::Private, 0, 0, 5, 5);
433          check_false_add_false_with_true(Mode::Public, Mode::Private, Mode::Private, 0, 0, 5, 5);
434          check_false_add_true_with_false(Mode::Public, Mode::Private, Mode::Private, 0, 0, 5, 5);
435          check_false_add_true_with_true(Mode::Public, Mode::Private, Mode::Private, 0, 0, 5, 5);
436          check_true_add_false_with_false(Mode::Public, Mode::Private, Mode::Private, 0, 0, 5, 5);
437          check_true_add_false_with_true(Mode::Public, Mode::Private, Mode::Private, 0, 0, 5, 5);
438          check_true_add_true_with_false(Mode::Public, Mode::Private, Mode::Private, 0, 0, 5, 5);
439          check_true_add_true_with_true(Mode::Public, Mode::Private, Mode::Private, 0, 0, 5, 5);
440      }
441  }