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