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::{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: Field,
13 ConstraintF: PrimeField,
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 ab_false = &a + (AF::from(Boolean::Constant(false)) * b_native);
179 let ab_true = &a + (AF::from(Boolean::Constant(true)) * b_native);
180 assert_eq!(ab_false.value()?, a_native);
181 assert_eq!(ab_true.value()?, a_native + &b_native);
182
183 if !cs.is_satisfied().unwrap() {
184 panic!(
185 "Unsatisfied in mode {:?}.\n{:?}",
186 mode,
187 cs.which_is_unsatisfied().unwrap()
188 );
189 }
190 assert!(cs.is_satisfied().unwrap());
191 }
192 Ok(())
193 }
194
195 pub fn frobenius_tests<F: Field, ConstraintF, AF>(maxpower: usize) -> Result<(), SynthesisError>
196 where
197 F: Field,
198 ConstraintF: Field,
199 AF: FieldVar<F, ConstraintF>,
200 for<'a> &'a AF: FieldOpsBounds<'a, F, AF>,
201 {
202 let modes = [
203 AllocationMode::Input,
204 AllocationMode::Witness,
205 AllocationMode::Constant,
206 ];
207 for &mode in &modes {
208 let cs = ConstraintSystem::<ConstraintF>::new_ref();
209 let mut rng = test_rng();
210 for i in 0..=maxpower {
211 let mut a = F::rand(&mut rng);
212 let mut a_gadget = AF::new_variable(ark_relations::ns!(cs, "a"), || Ok(a), mode)?;
213 a_gadget.frobenius_map_in_place(i)?;
214 a.frobenius_map_in_place(i);
215
216 assert_eq!(a_gadget.value()?, a);
217 }
218
219 assert!(cs.is_satisfied().unwrap());
220 }
221 Ok(())
222 }
223}
224
225pub mod curves {
226 use ark_ec::{
227 short_weierstrass::Projective as SWProjective, twisted_edwards::Projective as TEProjective,
228 AdditiveGroup, CurveGroup,
229 };
230 use ark_ff::{BitIteratorLE, Field, One, PrimeField};
231 use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
232 use ark_std::{test_rng, vec::Vec, UniformRand};
233
234 use ark_r1cs_std::prelude::*;
235
236 pub fn group_test<C, ConstraintF, GG>() -> Result<(), SynthesisError>
237 where
238 C: CurveGroup,
239 ConstraintF: Field,
240 GG: CurveVar<C, ConstraintF>,
241 for<'a> &'a GG: GroupOpsBounds<'a, C, GG>,
242 {
243 let modes = [
244 AllocationMode::Input,
245 AllocationMode::Witness,
246 AllocationMode::Constant,
247 ];
248 for &mode in &modes {
249 let cs = ConstraintSystem::<ConstraintF>::new_ref();
250
251 let mut rng = test_rng();
252 let a_native = C::rand(&mut rng);
253 let b_native = C::rand(&mut rng);
254 let a = GG::new_variable(ark_relations::ns!(cs, "generate_a"), || Ok(a_native), mode)
255 .unwrap();
256 let b = GG::new_variable(ark_relations::ns!(cs, "generate_b"), || Ok(b_native), mode)
257 .unwrap();
258
259 let zero = GG::zero();
260 assert_eq!(zero.value()?, zero.value()?);
261
262 // a == a
263 assert_eq!(a.value()?, a.value()?);
264 // a + 0 = a
265 assert_eq!((&a + &zero).value()?, a.value()?);
266 // a - 0 = a
267 assert_eq!((&a - &zero).value()?, a.value()?);
268 // a - a = 0
269 assert_eq!((&a - &a).value()?, zero.value()?);
270 // a + b = b + a
271 let a_b = &a + &b;
272 let b_a = &b + &a;
273 assert_eq!(a_b.value()?, b_a.value()?);
274 a_b.enforce_equal(&b_a)?;
275 assert!(cs.is_satisfied().unwrap());
276
277 // (a + b) + a = a + (b + a)
278 let ab_a = &a_b + &a;
279 let a_ba = &a + &b_a;
280 assert_eq!(ab_a.value()?, a_ba.value()?);
281 ab_a.enforce_equal(&a_ba)?;
282 assert!(cs.is_satisfied().unwrap());
283
284 // a.double() = a + a
285 let a_a = &a + &a;
286 let mut a2 = a.clone();
287 a2.double_in_place()?;
288 a2.enforce_equal(&a_a)?;
289 assert_eq!(a2.value()?, a_native.double());
290 assert_eq!(a_a.value()?, a_native.double());
291 assert_eq!(a2.value()?, a_a.value()?);
292 assert!(cs.is_satisfied().unwrap());
293
294 // b.double() = b + b
295 let mut b2 = b.clone();
296 b2.double_in_place()?;
297 let b_b = &b + &b;
298 b2.enforce_equal(&b_b)?;
299 assert!(cs.is_satisfied().unwrap());
300 assert_eq!(b2.value()?, b_b.value()?);
301
302 let _ = a.to_bytes()?;
303 assert!(cs.is_satisfied().unwrap());
304 let _ = a.to_non_unique_bytes()?;
305 assert!(cs.is_satisfied().unwrap());
306
307 let _ = b.to_bytes()?;
308 let _ = b.to_non_unique_bytes()?;
309 if !cs.is_satisfied().unwrap() {
310 panic!(
311 "Unsatisfied in mode {:?}.\n{:?}",
312 mode,
313 cs.which_is_unsatisfied().unwrap()
314 );
315 }
316 assert!(cs.is_satisfied().unwrap());
317
318 let modulus = C::ScalarField::MODULUS.as_ref().to_vec();
319 let mut max = modulus.clone();
320 for limb in &mut max {
321 *limb = u64::MAX;
322 }
323
324 let num_limbs = max.len();
325
326 let modulus_num_bits_mod_64 = <C::ScalarField as PrimeField>::MODULUS_BIT_SIZE % 64;
327 if modulus_num_bits_mod_64 != 0 {
328 *max.last_mut().unwrap() >>= 64 - modulus_num_bits_mod_64;
329 }
330 let scalars = [
331 C::ScalarField::rand(&mut rng)
332 .into_bigint()
333 .as_ref()
334 .to_vec(),
335 vec![u64::rand(&mut rng)],
336 (-C::ScalarField::one()).into_bigint().as_ref().to_vec(),
337 modulus,
338 max,
339 vec![0u64; num_limbs],
340 vec![1000012341233u64; num_limbs],
341 ];
342
343 let mut input = vec![];
344
345 // Check scalar mul with edge cases
346 for scalar in scalars.iter() {
347 let native_result = a_native.mul_bigint(scalar);
348 let native_result = native_result.into_affine();
349
350 let scalar_bits: Vec<bool> = BitIteratorLE::new(&scalar).collect();
351 input =
352 Vec::new_witness(ark_relations::ns!(cs, "bits"), || Ok(scalar_bits)).unwrap();
353 let result = a
354 .scalar_mul_le(input.iter())
355 .expect(&format!("Mode: {:?}", mode));
356 let result_val = result.value()?.into_affine();
357 assert_eq!(
358 result_val, native_result,
359 "gadget & native values are diff. after scalar mul {:?}",
360 scalar,
361 );
362 assert!(cs.is_satisfied().unwrap());
363 }
364
365 let result = zero.scalar_mul_le(input.iter())?;
366 let result_val = result.value()?.into_affine();
367 result.enforce_equal(&zero)?;
368 assert_eq!(
369 result_val,
370 C::zero().into_affine(),
371 "gadget & native values are diff. after scalar mul of zero"
372 );
373 assert!(cs.is_satisfied().unwrap());
374 }
375 Ok(())
376 }
377
378 pub fn sw_test<P, GG>() -> Result<(), SynthesisError>
379 where
380 P: ark_ec::models::short_weierstrass::SWCurveConfig,
381 GG: CurveVar<SWProjective<P>, <P::BaseField as Field>::BasePrimeField>,
382 for<'a> &'a GG: GroupOpsBounds<'a, SWProjective<P>, GG>,
383 {
384 group_test::<SWProjective<P>, _, GG>()?;
385 let modes = [
386 AllocationMode::Input,
387 AllocationMode::Witness,
388 AllocationMode::Constant,
389 ];
390 for &mode in &modes {
391 let mut rng = test_rng();
392
393 let cs = ConstraintSystem::<<P::BaseField as Field>::BasePrimeField>::new_ref();
394
395 let a = SWProjective::<P>::rand(&mut rng);
396 let b = SWProjective::<P>::rand(&mut rng);
397 let a_affine = a.into_affine();
398 let b_affine = b.into_affine();
399
400 let ns = ark_relations::ns!(cs, "allocating variables");
401 let mut gadget_a = GG::new_variable(cs.clone(), || Ok(a), mode)?;
402 let gadget_b = GG::new_variable(cs.clone(), || Ok(b), mode)?;
403 let zero = GG::zero();
404 drop(ns);
405 assert_eq!(gadget_a.value()?.into_affine().x, a_affine.x);
406 assert_eq!(gadget_a.value()?.into_affine().y, a_affine.y);
407 assert_eq!(gadget_b.value()?.into_affine().x, b_affine.x);
408 assert_eq!(gadget_b.value()?.into_affine().y, b_affine.y);
409 assert_eq!(cs.which_is_unsatisfied().unwrap(), None);
410
411 // Check addition
412 let ab = a + &b;
413 let ab_affine = ab.into_affine();
414 let gadget_ab = &gadget_a + &gadget_b;
415 let gadget_ba = &gadget_b + &gadget_a;
416 gadget_ba.enforce_equal(&gadget_ab)?;
417
418 let ab_val = gadget_ab.value()?.into_affine();
419 assert_eq!(ab_val, ab_affine, "Result of addition is unequal");
420 assert!(cs.is_satisfied().unwrap());
421
422 let gadget_a_zero = &gadget_a + &zero;
423 gadget_a_zero.enforce_equal(&gadget_a)?;
424
425 // Check doubling
426 let aa = &a.double();
427 let aa_affine = aa.into_affine();
428 gadget_a.double_in_place()?;
429 let aa_val = gadget_a.value()?.into_affine();
430 assert_eq!(
431 aa_val, aa_affine,
432 "Gadget and native values are unequal after double."
433 );
434 assert!(cs.is_satisfied().unwrap());
435
436 if !cs.is_satisfied().unwrap() {
437 panic!(
438 "Unsatisfied in mode {:?}.\n{:?}",
439 mode,
440 cs.which_is_unsatisfied().unwrap()
441 );
442 }
443
444 assert!(cs.is_satisfied().unwrap());
445 }
446 Ok(())
447 }
448
449 pub fn te_test<P, GG>() -> Result<(), SynthesisError>
450 where
451 P: ark_ec::twisted_edwards::TECurveConfig,
452 GG: CurveVar<TEProjective<P>, <P::BaseField as Field>::BasePrimeField>,
453 for<'a> &'a GG: GroupOpsBounds<'a, TEProjective<P>, GG>,
454 {
455 group_test::<TEProjective<P>, _, GG>()?;
456 let modes = [
457 AllocationMode::Input,
458 AllocationMode::Witness,
459 AllocationMode::Constant,
460 ];
461 for &mode in &modes {
462 let mut rng = test_rng();
463
464 let cs = ConstraintSystem::<<P::BaseField as Field>::BasePrimeField>::new_ref();
465
466 let a = TEProjective::<P>::rand(&mut rng);
467 let b = TEProjective::<P>::rand(&mut rng);
468 let a_affine = a.into_affine();
469 let b_affine = b.into_affine();
470
471 let ns = ark_relations::ns!(cs, "allocating variables");
472 let mut gadget_a = GG::new_variable(cs.clone(), || Ok(a), mode)?;
473 let gadget_b = GG::new_variable(cs.clone(), || Ok(b), mode)?;
474 drop(ns);
475
476 assert_eq!(gadget_a.value()?.into_affine().x, a_affine.x);
477 assert_eq!(gadget_a.value()?.into_affine().y, a_affine.y);
478 assert_eq!(gadget_b.value()?.into_affine().x, b_affine.x);
479 assert_eq!(gadget_b.value()?.into_affine().y, b_affine.y);
480 assert_eq!(cs.which_is_unsatisfied()?, None);
481
482 // Check addition
483 let ab = a + &b;
484 let ab_affine = ab.into_affine();
485 let gadget_ab = &gadget_a + &gadget_b;
486 let gadget_ba = &gadget_b + &gadget_a;
487 gadget_ba.enforce_equal(&gadget_ab)?;
488
489 let ab_val = gadget_ab.value()?.into_affine();
490 assert_eq!(ab_val, ab_affine, "Result of addition is unequal");
491 assert!(cs.is_satisfied().unwrap());
492
493 // Check doubling
494 let aa = &a.double();
495 let aa_affine = aa.into_affine();
496 gadget_a.double_in_place()?;
497 let aa_val = gadget_a.value()?.into_affine();
498 assert_eq!(
499 aa_val, aa_affine,
500 "Gadget and native values are unequal after double."
501 );
502 assert!(cs.is_satisfied().unwrap());
503
504 if !cs.is_satisfied().unwrap() {
505 panic!(
506 "Unsatisfied in mode {:?}.\n{:?}",
507 mode,
508 cs.which_is_unsatisfied().unwrap()
509 );
510 }
511
512 assert!(cs.is_satisfied().unwrap());
513 }
514 Ok(())
515 }
516}
517
518pub mod pairing {
519 use ark_ec::{
520 pairing::{Pairing, PairingOutput},
521 AffineRepr, CurveGroup,
522 };
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: Pairing, P: PairingVar<E>>() -> Result<(), SynthesisError>
530 where
531 for<'a> &'a P::G1Var: GroupOpsBounds<'a, E::G1, P::G1Var>,
532 for<'a> &'a P::G2Var: GroupOpsBounds<'a, E::G2, P::G2Var>,
533 for<'a> &'a P::GTVar: FieldOpsBounds<'a, E::TargetField, 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::G1 as CurveGroup>::BaseField>::new_ref();
542
543 let mut rng = test_rng();
544 let a = E::G1::rand(&mut rng);
545 let b = E::G2::rand(&mut rng);
546 let s = E::ScalarField::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 = PairingOutput(ans_n.0.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.0, "Failed native test 1");
598 assert_eq!(ans2_g.value()?, ans2_n.0, "Failed native test 2");
599 assert_eq!(ans3_g.value()?, ans3_n.0, "Failed native test 3");
600
601 assert_eq!(ans1_n.0, ans2_n.0, "Failed ans1_native == ans2_native");
602 assert_eq!(ans2_n.0, ans3_n.0, "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
620 #[allow(dead_code)]
621 pub fn g2_prepare_consistency_test<E: Pairing, P: PairingVar<E>>() -> Result<(), SynthesisError>
622 {
623 let test_g2_elem = E::G2Affine::generator();
624 let test_g2_prepared = E::G2Prepared::from(test_g2_elem.clone());
625
626 let modes = [
627 AllocationMode::Input,
628 AllocationMode::Witness,
629 AllocationMode::Constant,
630 ];
631 for &mode in &modes {
632 let cs = ConstraintSystem::new_ref();
633
634 let test_g2_gadget =
635 P::G2Var::new_witness(cs.clone(), || Ok(test_g2_elem.clone())).unwrap();
636
637 let prepared_test_g2_gadget = P::prepare_g2(&test_g2_gadget).unwrap();
638 let allocated_test_g2_gadget =
639 P::G2PreparedVar::new_variable(cs.clone(), || Ok(test_g2_prepared.clone()), mode)
640 .unwrap();
641
642 let prepared_test_g2_gadget_bytes = prepared_test_g2_gadget.to_bytes().unwrap();
643 let allocated_test_g2_gadget_bytes = allocated_test_g2_gadget.to_bytes().unwrap();
644
645 prepared_test_g2_gadget_bytes
646 .enforce_equal(&allocated_test_g2_gadget_bytes)
647 .unwrap();
648
649 assert!(cs.is_satisfied().unwrap(), "cs is not satisfied");
650 }
651 Ok(())
652 }
653}