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}