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