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