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