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}