arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/r1cs-std/src/instantiated/mnt4_753/curves.rs
r1cs-std/src/instantiated/mnt4_753/curves.rsRaw
  1use crate::groups::mnt4;
  2use algebra::mnt4_753::Parameters;
  3
  4pub type G1Gadget = mnt4::G1Gadget<Parameters>;
  5pub type G2Gadget = mnt4::G2Gadget<Parameters>;
  6
  7pub type G1PreparedGadget = mnt4::G1PreparedGadget<Parameters>;
  8pub type G2PreparedGadget = mnt4::G2PreparedGadget<Parameters>;
  9
 10#[cfg(test)]
 11mod test {
 12    use rand::Rng;
 13
 14    use super::{G1Gadget, G2Gadget};
 15    use crate::{prelude::*, test_constraint_system::TestConstraintSystem, Vec};
 16    use algebra::{mnt4_753::*, test_rng, AffineCurve, BitIterator, PrimeField, ProjectiveCurve};
 17    use r1cs_core::ConstraintSystem;
 18
 19    #[test]
 20    fn mnt4_753_g1_constraint_costs() {
 21        use crate::boolean::AllocatedBit;
 22
 23        let mut cs = TestConstraintSystem::<Fq>::new();
 24
 25        let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true))
 26            .unwrap()
 27            .into();
 28
 29        let mut rng = test_rng();
 30        let a: G1Projective = rng.gen();
 31        let b: G1Projective = rng.gen();
 32        let gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
 33        let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
 34        let alloc_cost = cs.num_constraints();
 35        let _ = G1Gadget::conditionally_select(
 36            &mut cs.ns(|| "cond_select"),
 37            &bit,
 38            &gadget_a,
 39            &gadget_b,
 40        )
 41        .unwrap();
 42        let cond_select_cost = cs.num_constraints() - alloc_cost;
 43
 44        let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
 45        let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost;
 46
 47        assert!(cs.is_satisfied());
 48        assert_eq!(cond_select_cost, <G1Gadget as CondSelectGadget<Fq>>::cost());
 49        assert_eq!(add_cost, G1Gadget::cost_of_add());
 50    }
 51
 52    #[test]
 53    fn mnt4_753_g2_constraint_costs() {
 54        use crate::boolean::AllocatedBit;
 55
 56        let mut cs = TestConstraintSystem::<Fq>::new();
 57
 58        let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true))
 59            .unwrap()
 60            .into();
 61
 62        let mut rng = test_rng();
 63        let a: G2Projective = rng.gen();
 64        let b: G2Projective = rng.gen();
 65        let gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
 66        let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
 67        let alloc_cost = cs.num_constraints();
 68        let _ = G2Gadget::conditionally_select(
 69            &mut cs.ns(|| "cond_select"),
 70            &bit,
 71            &gadget_a,
 72            &gadget_b,
 73        )
 74        .unwrap();
 75        let cond_select_cost = cs.num_constraints() - alloc_cost;
 76
 77        let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
 78        let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost;
 79
 80        assert!(cs.is_satisfied());
 81        assert_eq!(cond_select_cost, <G2Gadget as CondSelectGadget<Fq>>::cost());
 82        assert_eq!(add_cost, G2Gadget::cost_of_add());
 83    }
 84
 85    #[test]
 86    fn mnt4_753_g1_gadget_test() {
 87        use algebra::UniformRand;
 88        use rand::SeedableRng;
 89        use rand_xorshift::XorShiftRng;
 90        let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
 91
 92        let mut cs = TestConstraintSystem::<Fq>::new();
 93
 94        let a = G1Projective::rand(&mut rng);
 95        let b = G1Projective::rand(&mut rng);
 96        let a_affine = a.into_affine();
 97        let b_affine = b.into_affine();
 98        let mut gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
 99        let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
100        assert_eq!(gadget_a.x.value.unwrap(), a_affine.x);
101        assert_eq!(gadget_a.y.value.unwrap(), a_affine.y);
102        assert_eq!(gadget_b.x.value.unwrap(), b_affine.x);
103        assert_eq!(gadget_b.y.value.unwrap(), b_affine.y);
104
105        // Check addition
106        let ab = a + &b;
107        let ab_affine = ab.into_affine();
108        let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
109        let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap();
110        gadget_ba
111            .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab)
112            .unwrap();
113
114        let ab_val = gadget_ab
115            .get_value()
116            .expect("Doubling should be successful")
117            .into_affine();
118        assert_eq!(ab_val, ab_affine, "Result of addition is unequal");
119
120        // Check doubling
121        let aa = a.double();
122        let aa_affine = aa.into_affine();
123        gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap();
124        let aa_val = gadget_a
125            .get_value()
126            .expect("Doubling should be successful")
127            .into_affine();
128        assert_eq!(
129            aa_val, aa_affine,
130            "Gadget and native values are unequal after double."
131        );
132
133        // Check mul_bits
134        let scalar = Fr::rand(&mut rng);
135        let native_result = aa.into_affine().mul(scalar) + &b;
136        let native_result = native_result.into_affine();
137
138        let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect();
139        // Get the scalar bits into little-endian form.
140        scalar.reverse();
141        let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap();
142        let result = gadget_a
143            .mul_bits(cs.ns(|| "mul_bits"), &gadget_b, input.iter())
144            .unwrap();
145        let result_val = result.get_value().unwrap().into_affine();
146        assert_eq!(
147            result_val, native_result,
148            "gadget & native values are diff. after scalar mul"
149        );
150
151        if !cs.is_satisfied() {
152            println!("{:?}", cs.which_is_unsatisfied().unwrap());
153        }
154
155        assert!(cs.is_satisfied());
156    }
157
158    #[test]
159    fn mnt4_753_g2_gadget_test() {
160        let mut cs = TestConstraintSystem::<Fq>::new();
161
162        let mut rng = test_rng();
163        let a: G2Projective = rng.gen();
164        let b: G2Projective = rng.gen();
165        let a_affine = a.into_affine();
166        let b_affine = b.into_affine();
167
168        let mut gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
169        let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
170        assert_eq!(gadget_a.x.get_value().unwrap(), a_affine.x);
171        assert_eq!(gadget_a.y.get_value().unwrap(), a_affine.y);
172        assert_eq!(gadget_b.x.get_value().unwrap(), b_affine.x);
173        assert_eq!(gadget_b.y.get_value().unwrap(), b_affine.y);
174
175        let ab = a + &b;
176        let ab_affine = ab.into_affine();
177        let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
178        let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap();
179        gadget_ba
180            .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab)
181            .unwrap();
182        assert_eq!(gadget_ab.x.get_value().unwrap(), ab_affine.x);
183        assert_eq!(gadget_ab.y.get_value().unwrap(), ab_affine.y);
184
185        let aa = a.double();
186        let aa_affine = aa.into_affine();
187        gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap();
188
189        assert_eq!(gadget_a.x.get_value().unwrap(), aa_affine.x);
190        assert_eq!(gadget_a.y.get_value().unwrap(), aa_affine.y);
191
192        if !cs.is_satisfied() {
193            println!("{:?}", cs.which_is_unsatisfied().unwrap());
194        }
195
196        assert!(cs.is_satisfied());
197    }
198}