ark-curves-cherry-picked/curve-constraint-tests/src/lib.rs
curve-constraint-tests/src/lib.rsRaw
1#![macro_use]
2extern crate ark_relations;
3
4pub mod fields {
5 use ark_ff::{BigInteger, BitIteratorLE, Field, PrimeField, UniformRand};
6 use ark_r1cs_std::prelude::*;
7 use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
8 use ark_std::{test_rng, vec::Vec};
9
10 pub fn field_test<F, ConstraintF, AF>() -> Result<(), SynthesisError>
11 where
12 F: PrimeField,
13 ConstraintF: Field,
14 AF: FieldVar<F, ConstraintF>,
15 AF: TwoBitLookupGadget<ConstraintF, TableConstant = F>,
16 for<'a> &'a AF: FieldOpsBounds<'a, F, AF>,
17 {
18 let modes = [
19 AllocationMode::Input,
20 AllocationMode::Witness,
21 AllocationMode::Constant,
22 ];
23 for &mode in &modes {
24 let cs = ConstraintSystem::<ConstraintF>::new_ref();
25
26 let mut rng = test_rng();
27 let a_native = F::rand(&mut rng);
28 let b_native = F::rand(&mut rng);
29 let a = AF::new_variable(ark_relations::ns!(cs, "generate_a"), || Ok(a_native), mode)?;
30 let b = AF::new_variable(ark_relations::ns!(cs, "generate_b"), || Ok(b_native), mode)?;
31 let b_const = AF::new_constant(ark_relations::ns!(cs, "b_as_constant"), b_native)?;
32
33 let zero = AF::zero();
34 let zero_native = zero.value()?;
35 zero.enforce_equal(&zero)?;
36
37 let one = AF::one();
38 let one_native = one.value()?;
39 one.enforce_equal(&one)?;
40
41 one.enforce_not_equal(&zero)?;
42
43 let one_dup = &zero + &one;
44 one_dup.enforce_equal(&one)?;
45
46 let two = &one + &one;
47 two.enforce_equal(&two)?;
48 two.enforce_equal(&one.double()?)?;
49 two.enforce_not_equal(&one)?;
50 two.enforce_not_equal(&zero)?;
51
52 // a + 0 = a
53 let a_plus_zero = &a + &zero;
54 assert_eq!(a_plus_zero.value()?, a_native);
55 a_plus_zero.enforce_equal(&a)?;
56 a_plus_zero.enforce_not_equal(&a.double()?)?;
57
58 // a - 0 = a
59 let a_minus_zero = &a - &zero;
60 assert_eq!(a_minus_zero.value()?, a_native);
61 a_minus_zero.enforce_equal(&a)?;
62
63 // a - a = 0
64 let a_minus_a = &a - &a;
65 assert_eq!(a_minus_a.value()?, zero_native);
66 a_minus_a.enforce_equal(&zero)?;
67
68 // a + b = b + a
69 let a_b = &a + &b;
70 let b_a = &b + &a;
71 assert_eq!(a_b.value()?, a_native + &b_native);
72 a_b.enforce_equal(&b_a)?;
73
74 // (a + b) + a = a + (b + a)
75 let ab_a = &a_b + &a;
76 let a_ba = &a + &b_a;
77 assert_eq!(ab_a.value()?, a_native + &b_native + &a_native);
78 ab_a.enforce_equal(&a_ba)?;
79
80 let b_times_a_plus_b = &a_b * &b;
81 let b_times_b_plus_a = &b_a * &b;
82 assert_eq!(
83 b_times_a_plus_b.value()?,
84 b_native * &(b_native + &a_native)
85 );
86 assert_eq!(
87 b_times_a_plus_b.value()?,
88 (b_native + &a_native) * &b_native
89 );
90 assert_eq!(
91 b_times_a_plus_b.value()?,
92 (a_native + &b_native) * &b_native
93 );
94 b_times_b_plus_a.enforce_equal(&b_times_a_plus_b)?;
95
96 // a * 1 = a
97 assert_eq!((&a * &one).value()?, a_native * &one_native);
98
99 // a * b = b * a
100 let ab = &a * &b;
101 let ba = &b * &a;
102 assert_eq!(ab.value()?, ba.value()?);
103 assert_eq!(ab.value()?, a_native * &b_native);
104
105 let ab_const = &a * &b_const;
106 let b_const_a = &b_const * &a;
107 assert_eq!(ab_const.value()?, b_const_a.value()?);
108 assert_eq!(ab_const.value()?, ab.value()?);
109 assert_eq!(ab_const.value()?, a_native * &b_native);
110
111 // (a * b) * a = a * (b * a)
112 let ab_a = &ab * &a;
113 let a_ba = &a * &ba;
114 assert_eq!(ab_a.value()?, a_ba.value()?);
115 assert_eq!(ab_a.value()?, a_native * &b_native * &a_native);
116
117 let aa = &a * &a;
118 let a_squared = a.square()?;
119 a_squared.enforce_equal(&aa)?;
120 assert_eq!(aa.value()?, a_squared.value()?);
121 assert_eq!(aa.value()?, a_native.square());
122
123 let aa = &a * a_native;
124 a_squared.enforce_equal(&aa)?;
125 assert_eq!(aa.value()?, a_squared.value()?);
126 assert_eq!(aa.value()?, a_native.square());
127
128 let a_b2 = &a + b_native;
129 a_b.enforce_equal(&a_b2)?;
130 assert_eq!(a_b.value()?, a_b2.value()?);
131
132 let a_inv = a.inverse()?;
133 a_inv.mul_equals(&a, &one)?;
134 assert_eq!(a_inv.value()?, a.value()?.inverse().unwrap());
135 assert_eq!(a_inv.value()?, a_native.inverse().unwrap());
136
137 let a_b_inv = a.mul_by_inverse(&b)?;
138 a_b_inv.mul_equals(&b, &a)?;
139 assert_eq!(a_b_inv.value()?, a_native * b_native.inverse().unwrap());
140
141 // a * a * a = a^3
142 let bits = BitIteratorLE::without_trailing_zeros([3u64])
143 .map(Boolean::constant)
144 .collect::<Vec<_>>();
145 assert_eq!(a_native.pow([0x3]), a.pow_le(&bits)?.value()?);
146
147 // a * a * a = a^3
148 assert_eq!(a_native.pow([0x3]), a.pow_by_constant(&[0x3])?.value()?);
149 assert!(cs.is_satisfied().unwrap());
150
151 let mut constants = [F::zero(); 4];
152 for c in &mut constants {
153 *c = UniformRand::rand(&mut test_rng());
154 }
155 let bits = [
156 Boolean::<ConstraintF>::constant(false),
157 Boolean::constant(true),
158 ];
159 let lookup_result = AF::two_bit_lookup(&bits, constants.as_ref())?;
160 assert_eq!(lookup_result.value()?, constants[2]);
161 assert!(cs.is_satisfied().unwrap());
162
163 let f = F::from(1u128 << 64);
164 let f_bits = ark_ff::BitIteratorLE::new(&[0u64, 1u64]).collect::<Vec<_>>();
165 let fv = AF::new_variable(ark_relations::ns!(cs, "alloc u128"), || Ok(f), mode)?;
166 assert_eq!(fv.to_bits_le()?.value().unwrap()[..128], f_bits[..128]);
167 assert!(cs.is_satisfied().unwrap());
168
169 let r_native: F = UniformRand::rand(&mut test_rng());
170
171 let r = AF::new_variable(ark_relations::ns!(cs, "r_native"), || Ok(r_native), mode)
172 .unwrap();
173 let _ = r.to_non_unique_bits_le()?;
174 assert!(cs.is_satisfied().unwrap());
175 let _ = r.to_bits_le()?;
176 assert!(cs.is_satisfied().unwrap());
177
178 let bytes = r.to_non_unique_bytes()?;
179 assert_eq!(r_native.into_bigint().to_bytes_le(), bytes.value().unwrap());
180 assert!(cs.is_satisfied().unwrap());
181 let bytes = r.to_bytes()?;
182 assert_eq!(r_native.into_bigint().to_bytes_le(), bytes.value().unwrap());
183 assert!(cs.is_satisfied().unwrap());
184
185 let ab_false = &a + (AF::from(Boolean::Constant(false)) * b_native);
186 let ab_true = &a + (AF::from(Boolean::Constant(true)) * b_native);
187 assert_eq!(ab_false.value()?, a_native);
188 assert_eq!(ab_true.value()?, a_native + &b_native);
189
190 if !cs.is_satisfied().unwrap() {
191 panic!(
192 "Unsatisfied in mode {:?}.\n{:?}",
193 mode,
194 cs.which_is_unsatisfied().unwrap()
195 );
196 }
197 assert!(cs.is_satisfied().unwrap());
198 }
199 Ok(())
200 }
201
202 pub fn frobenius_tests<F: Field, ConstraintF, AF>(maxpower: usize) -> Result<(), SynthesisError>
203 where
204 F: Field,
205 ConstraintF: Field,
206 AF: FieldVar<F, ConstraintF>,
207 for<'a> &'a AF: FieldOpsBounds<'a, F, AF>,
208 {
209 let modes = [
210 AllocationMode::Input,
211 AllocationMode::Witness,
212 AllocationMode::Constant,
213 ];
214 for &mode in &modes {
215 let cs = ConstraintSystem::<ConstraintF>::new_ref();
216 let mut rng = test_rng();
217 for i in 0..=maxpower {
218 let mut a = F::rand(&mut rng);
219 let mut a_gadget = AF::new_variable(ark_relations::ns!(cs, "a"), || Ok(a), mode)?;
220 a_gadget.frobenius_map_in_place(i)?;
221 a.frobenius_map(i);
222
223 assert_eq!(a_gadget.value()?, a);
224 }
225
226 assert!(cs.is_satisfied().unwrap());
227 }
228 Ok(())
229 }
230}
231
232pub mod curves {
233 use ark_ec::{
234 short_weierstrass::Projective as SWProjective, twisted_edwards::Projective as TEProjective,
235 ProjectiveCurve,
236 };
237 use ark_ff::{BitIteratorLE, Field, One, PrimeField};
238 use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
239 use ark_std::{test_rng, vec::Vec, UniformRand};
240
241 use ark_r1cs_std::prelude::*;
242
243 pub fn group_test<C, ConstraintF, GG>() -> Result<(), SynthesisError>
244 where
245 C: ProjectiveCurve,
246 ConstraintF: Field,
247 GG: CurveVar<C, ConstraintF>,
248 for<'a> &'a GG: GroupOpsBounds<'a, C, GG>,
249 {
250 let modes = [
251 AllocationMode::Input,
252 AllocationMode::Witness,
253 AllocationMode::Constant,
254 ];
255 for &mode in &modes {
256 let cs = ConstraintSystem::<ConstraintF>::new_ref();
257
258 let mut rng = test_rng();
259 let a_native = C::rand(&mut rng);
260 let b_native = C::rand(&mut rng);
261 let a = GG::new_variable(ark_relations::ns!(cs, "generate_a"), || Ok(a_native), mode)
262 .unwrap();
263 let b = GG::new_variable(ark_relations::ns!(cs, "generate_b"), || Ok(b_native), mode)
264 .unwrap();
265
266 let zero = GG::zero();
267 assert_eq!(zero.value()?, zero.value()?);
268
269 // a == a
270 assert_eq!(a.value()?, a.value()?);
271 // a + 0 = a
272 assert_eq!((&a + &zero).value()?, a.value()?);
273 // a - 0 = a
274 assert_eq!((&a - &zero).value()?, a.value()?);
275 // a - a = 0
276 assert_eq!((&a - &a).value()?, zero.value()?);
277 // a + b = b + a
278 let a_b = &a + &b;
279 let b_a = &b + &a;
280 assert_eq!(a_b.value()?, b_a.value()?);
281 a_b.enforce_equal(&b_a)?;
282 assert!(cs.is_satisfied().unwrap());
283
284 // (a + b) + a = a + (b + a)
285 let ab_a = &a_b + &a;
286 let a_ba = &a + &b_a;
287 assert_eq!(ab_a.value()?, a_ba.value()?);
288 ab_a.enforce_equal(&a_ba)?;
289 assert!(cs.is_satisfied().unwrap());
290
291 // a.double() = a + a
292 let a_a = &a + &a;
293 let mut a2 = a.clone();
294 a2.double_in_place()?;
295 a2.enforce_equal(&a_a)?;
296 assert_eq!(a2.value()?, a_native.double());
297 assert_eq!(a_a.value()?, a_native.double());
298 assert_eq!(a2.value()?, a_a.value()?);
299 assert!(cs.is_satisfied().unwrap());
300
301 // b.double() = b + b
302 let mut b2 = b.clone();
303 b2.double_in_place()?;
304 let b_b = &b + &b;
305 b2.enforce_equal(&b_b)?;
306 assert!(cs.is_satisfied().unwrap());
307 assert_eq!(b2.value()?, b_b.value()?);
308
309 let _ = a.to_bytes()?;
310 assert!(cs.is_satisfied().unwrap());
311 let _ = a.to_non_unique_bytes()?;
312 assert!(cs.is_satisfied().unwrap());
313
314 let _ = b.to_bytes()?;
315 let _ = b.to_non_unique_bytes()?;
316 if !cs.is_satisfied().unwrap() {
317 panic!(
318 "Unsatisfied in mode {:?}.\n{:?}",
319 mode,
320 cs.which_is_unsatisfied().unwrap()
321 );
322 }
323 assert!(cs.is_satisfied().unwrap());
324
325 let modulus = <C::ScalarField as PrimeField>::MODULUS.as_ref().to_vec();
326 let mut max = modulus.clone();
327 for limb in &mut max {
328 *limb = u64::MAX;
329 }
330
331 let modulus_last_limb_bits = <C::ScalarField as PrimeField>::MODULUS_BIT_SIZE % 64;
332 *max.last_mut().unwrap() >>= 64 - modulus_last_limb_bits;
333 let scalars = [
334 C::ScalarField::rand(&mut rng)
335 .into_bigint()
336 .as_ref()
337 .to_vec(),
338 vec![u64::rand(&mut rng)],
339 (-C::ScalarField::one()).into_bigint().as_ref().to_vec(),
340 <C::ScalarField as PrimeField>::MODULUS.as_ref().to_vec(),
341 max,
342 vec![0; 50],
343 vec![1000012341233u64; 36],
344 ];
345
346 let mut input = vec![];
347
348 // Check scalar mul with edge cases
349 for scalar in scalars.iter() {
350 let native_result = a_native.mul(scalar);
351 let native_result = native_result.into_affine();
352
353 let scalar_bits: Vec<bool> = BitIteratorLE::new(&scalar).collect();
354 input =
355 Vec::new_witness(ark_relations::ns!(cs, "bits"), || Ok(scalar_bits)).unwrap();
356 let result = a
357 .scalar_mul_le(input.iter())
358 .expect(&format!("Mode: {:?}", mode));
359 let result_val = result.value()?.into_affine();
360 assert_eq!(
361 result_val, native_result,
362 "gadget & native values are diff. after scalar mul {:?}",
363 scalar,
364 );
365 assert!(cs.is_satisfied().unwrap());
366 }
367
368 let result = zero.scalar_mul_le(input.iter())?;
369 let result_val = result.value()?.into_affine();
370 result.enforce_equal(&zero)?;
371 assert_eq!(
372 result_val,
373 C::zero().into_affine(),
374 "gadget & native values are diff. after scalar mul of zero"
375 );
376 assert!(cs.is_satisfied().unwrap());
377 }
378 Ok(())
379 }
380
381 pub fn sw_test<P, GG>() -> Result<(), SynthesisError>
382 where
383 P: ark_ec::models::short_weierstrass::SWCurveConfig,
384 GG: CurveVar<SWProjective<P>, <P::BaseField as Field>::BasePrimeField>,
385 for<'a> &'a GG: GroupOpsBounds<'a, SWProjective<P>, GG>,
386 {
387 group_test::<SWProjective<P>, _, GG>()?;
388 let modes = [
389 AllocationMode::Input,
390 AllocationMode::Witness,
391 AllocationMode::Constant,
392 ];
393 for &mode in &modes {
394 let mut rng = test_rng();
395
396 let cs = ConstraintSystem::<<P::BaseField as Field>::BasePrimeField>::new_ref();
397
398 let a = SWProjective::<P>::rand(&mut rng);
399 let b = SWProjective::<P>::rand(&mut rng);
400 let a_affine = a.into_affine();
401 let b_affine = b.into_affine();
402
403 let ns = ark_relations::ns!(cs, "allocating variables");
404 let mut gadget_a = GG::new_variable(cs.clone(), || Ok(a), mode)?;
405 let gadget_b = GG::new_variable(cs.clone(), || Ok(b), mode)?;
406 let zero = GG::zero();
407 drop(ns);
408 assert_eq!(gadget_a.value()?.into_affine().x, a_affine.x);
409 assert_eq!(gadget_a.value()?.into_affine().y, a_affine.y);
410 assert_eq!(gadget_b.value()?.into_affine().x, b_affine.x);
411 assert_eq!(gadget_b.value()?.into_affine().y, b_affine.y);
412 assert_eq!(cs.which_is_unsatisfied().unwrap(), None);
413
414 // Check addition
415 let ab = a + &b;
416 let ab_affine = ab.into_affine();
417 let gadget_ab = &gadget_a + &gadget_b;
418 let gadget_ba = &gadget_b + &gadget_a;
419 gadget_ba.enforce_equal(&gadget_ab)?;
420
421 let ab_val = gadget_ab.value()?.into_affine();
422 assert_eq!(ab_val, ab_affine, "Result of addition is unequal");
423 assert!(cs.is_satisfied().unwrap());
424
425 let gadget_a_zero = &gadget_a + &zero;
426 gadget_a_zero.enforce_equal(&gadget_a)?;
427
428 // Check doubling
429 let aa = &a.double();
430 let aa_affine = aa.into_affine();
431 gadget_a.double_in_place()?;
432 let aa_val = gadget_a.value()?.into_affine();
433 assert_eq!(
434 aa_val, aa_affine,
435 "Gadget and native values are unequal after double."
436 );
437 assert!(cs.is_satisfied().unwrap());
438
439 if !cs.is_satisfied().unwrap() {
440 panic!(
441 "Unsatisfied in mode {:?}.\n{:?}",
442 mode,
443 cs.which_is_unsatisfied().unwrap()
444 );
445 }
446
447 assert!(cs.is_satisfied().unwrap());
448 }
449 Ok(())
450 }
451
452 pub fn te_test<P, GG>() -> Result<(), SynthesisError>
453 where
454 P: ark_ec::twisted_edwards::TECurveConfig,
455 GG: CurveVar<TEProjective<P>, <P::BaseField as Field>::BasePrimeField>,
456 for<'a> &'a GG: GroupOpsBounds<'a, TEProjective<P>, GG>,
457 {
458 group_test::<TEProjective<P>, _, GG>()?;
459 let modes = [
460 AllocationMode::Input,
461 AllocationMode::Witness,
462 AllocationMode::Constant,
463 ];
464 for &mode in &modes {
465 let mut rng = test_rng();
466
467 let cs = ConstraintSystem::<<P::BaseField as Field>::BasePrimeField>::new_ref();
468
469 let a = TEProjective::<P>::rand(&mut rng);
470 let b = TEProjective::<P>::rand(&mut rng);
471 let a_affine = a.into_affine();
472 let b_affine = b.into_affine();
473
474 let ns = ark_relations::ns!(cs, "allocating variables");
475 let mut gadget_a = GG::new_variable(cs.clone(), || Ok(a), mode)?;
476 let gadget_b = GG::new_variable(cs.clone(), || Ok(b), mode)?;
477 drop(ns);
478
479 assert_eq!(gadget_a.value()?.into_affine().x, a_affine.x);
480 assert_eq!(gadget_a.value()?.into_affine().y, a_affine.y);
481 assert_eq!(gadget_b.value()?.into_affine().x, b_affine.x);
482 assert_eq!(gadget_b.value()?.into_affine().y, b_affine.y);
483 assert_eq!(cs.which_is_unsatisfied()?, None);
484
485 // Check addition
486 let ab = a + &b;
487 let ab_affine = ab.into_affine();
488 let gadget_ab = &gadget_a + &gadget_b;
489 let gadget_ba = &gadget_b + &gadget_a;
490 gadget_ba.enforce_equal(&gadget_ab)?;
491
492 let ab_val = gadget_ab.value()?.into_affine();
493 assert_eq!(ab_val, ab_affine, "Result of addition is unequal");
494 assert!(cs.is_satisfied().unwrap());
495
496 // Check doubling
497 let aa = &a.double();
498 let aa_affine = aa.into_affine();
499 gadget_a.double_in_place()?;
500 let aa_val = gadget_a.value()?.into_affine();
501 assert_eq!(
502 aa_val, aa_affine,
503 "Gadget and native values are unequal after double."
504 );
505 assert!(cs.is_satisfied().unwrap());
506
507 if !cs.is_satisfied().unwrap() {
508 panic!(
509 "Unsatisfied in mode {:?}.\n{:?}",
510 mode,
511 cs.which_is_unsatisfied().unwrap()
512 );
513 }
514
515 assert!(cs.is_satisfied().unwrap());
516 }
517 Ok(())
518 }
519}
520
521pub mod pairing {
522 use ark_ec::{PairingEngine, ProjectiveCurve};
523 use ark_ff::{BitIteratorLE, Field, PrimeField};
524 use ark_r1cs_std::prelude::*;
525 use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
526 use ark_std::{test_rng, vec::Vec, UniformRand};
527
528 #[allow(dead_code)]
529 pub fn bilinearity_test<E: PairingEngine, P: PairingVar<E>>() -> Result<(), SynthesisError>
530 where
531 for<'a> &'a P::G1Var: GroupOpsBounds<'a, E::G1Projective, P::G1Var>,
532 for<'a> &'a P::G2Var: GroupOpsBounds<'a, E::G2Projective, P::G2Var>,
533 for<'a> &'a P::GTVar: FieldOpsBounds<'a, E::Fqk, P::GTVar>,
534 {
535 let modes = [
536 AllocationMode::Input,
537 AllocationMode::Witness,
538 AllocationMode::Constant,
539 ];
540 for &mode in &modes {
541 let cs = ConstraintSystem::<E::Fq>::new_ref();
542
543 let mut rng = test_rng();
544 let a = E::G1Projective::rand(&mut rng);
545 let b = E::G2Projective::rand(&mut rng);
546 let s = E::Fr::rand(&mut rng);
547
548 let mut sa = a;
549 sa *= s;
550 let mut sb = b;
551 sb *= s;
552
553 let a_g = P::G1Var::new_variable(cs.clone(), || Ok(a.into_affine()), mode)?;
554 let b_g = P::G2Var::new_variable(cs.clone(), || Ok(b.into_affine()), mode)?;
555 let sa_g = P::G1Var::new_variable(cs.clone(), || Ok(sa.into_affine()), mode)?;
556 let sb_g = P::G2Var::new_variable(cs.clone(), || Ok(sb.into_affine()), mode)?;
557
558 let mut _preparation_num_constraints = cs.num_constraints();
559 let a_prep_g = P::prepare_g1(&a_g)?;
560 let b_prep_g = P::prepare_g2(&b_g)?;
561 _preparation_num_constraints = cs.num_constraints() - _preparation_num_constraints;
562
563 let sa_prep_g = P::prepare_g1(&sa_g)?;
564 let sb_prep_g = P::prepare_g2(&sb_g)?;
565
566 let (ans1_g, ans1_n) = {
567 let _ml_constraints = cs.num_constraints();
568 let ml_g = P::miller_loop(&[sa_prep_g], &[b_prep_g.clone()])?;
569 let _fe_constraints = cs.num_constraints();
570 let ans_g = P::final_exponentiation(&ml_g)?;
571 let ans_n = E::pairing(sa, b);
572 (ans_g, ans_n)
573 };
574
575 let (ans2_g, ans2_n) = {
576 let ans_g = P::pairing(a_prep_g.clone(), sb_prep_g)?;
577 let ans_n = E::pairing(a, sb);
578 (ans_g, ans_n)
579 };
580
581 let (ans3_g, ans3_n) = {
582 let s_iter = BitIteratorLE::without_trailing_zeros(s.into_bigint())
583 .map(Boolean::constant)
584 .collect::<Vec<_>>();
585
586 let mut ans_g = P::pairing(a_prep_g, b_prep_g)?;
587 let mut ans_n = E::pairing(a, b);
588 ans_n = ans_n.pow(s.into_bigint());
589 ans_g = ans_g.pow_le(&s_iter)?;
590
591 (ans_g, ans_n)
592 };
593
594 ans1_g.enforce_equal(&ans2_g)?;
595 ans2_g.enforce_equal(&ans3_g)?;
596
597 assert_eq!(ans1_g.value()?, ans1_n, "Failed native test 1");
598 assert_eq!(ans2_g.value()?, ans2_n, "Failed native test 2");
599 assert_eq!(ans3_g.value()?, ans3_n, "Failed native test 3");
600
601 assert_eq!(ans1_n, ans2_n, "Failed ans1_native == ans2_native");
602 assert_eq!(ans2_n, ans3_n, "Failed ans2_native == ans3_native");
603 assert_eq!(ans1_g.value()?, ans3_g.value()?, "Failed ans1 == ans3");
604 assert_eq!(ans1_g.value()?, ans2_g.value()?, "Failed ans1 == ans2");
605 assert_eq!(ans2_g.value()?, ans3_g.value()?, "Failed ans2 == ans3");
606
607 if !cs.is_satisfied().unwrap() {
608 panic!(
609 "Unsatisfied in mode {:?}.\n{:?}",
610 mode,
611 cs.which_is_unsatisfied().unwrap()
612 );
613 }
614
615 assert!(cs.is_satisfied().unwrap(), "cs is not satisfied");
616 }
617 Ok(())
618 }
619}