arnaucube
arnaucube/ark-curves-cherry-pickedPublic Self-hosted repository
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}