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