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 rand::{Rand, SeedableRng, XorShiftRng};
100 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
101
102 let mut cs = TestConstraintSystem::<Fq>::new();
103
104 let a = G1::rand(&mut rng);
105 let b = G1::rand(&mut rng);
106 let a_affine = a.into_affine();
107 let b_affine = b.into_affine();
108 let mut gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
109 let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
110 assert_eq!(gadget_a.x.value.unwrap(), a_affine.x);
111 assert_eq!(gadget_a.y.value.unwrap(), a_affine.y);
112 assert_eq!(gadget_b.x.value.unwrap(), b_affine.x);
113 assert_eq!(gadget_b.y.value.unwrap(), b_affine.y);
114
115 // Check addition
116 let ab = a + &b;
117 let ab_affine = ab.into_affine();
118 let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
119 let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap();
120 gadget_ba
121 .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab)
122 .unwrap();
123
124 let ab_val = gadget_ab
125 .get_value()
126 .expect("Doubling should be successful")
127 .into_affine();
128 assert_eq!(ab_val, ab_affine, "Result of addition is unequal");
129
130 // Check doubling
131 let aa = a.double();
132 let aa_affine = aa.into_affine();
133 gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap();
134 let aa_val = gadget_a
135 .get_value()
136 .expect("Doubling should be successful")
137 .into_affine();
138 assert_eq!(
139 aa_val, aa_affine,
140 "Gadget and native values are unequal after double."
141 );
142
143 // Check mul_bits
144 let scalar = Fr::rand(&mut rng);
145 let native_result = aa.into_affine().mul(scalar) + &b;
146 let native_result = native_result.into_affine();
147
148 let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect();
149 // Get the scalar bits into little-endian form.
150 scalar.reverse();
151 let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap();
152 let result = gadget_a
153 .mul_bits(cs.ns(|| "mul_bits"), &gadget_b, input.iter())
154 .unwrap();
155 let result_val = result.get_value().unwrap().into_affine();
156 assert_eq!(
157 result_val, native_result,
158 "gadget & native values are diff. after scalar mul"
159 );
160
161 if !cs.is_satisfied() {
162 println!("{:?}", cs.which_is_unsatisfied().unwrap());
163 }
164
165 assert!(cs.is_satisfied());
166 }
167
168 #[test]
169 fn bls12_g2_gadget_test() {
170 let mut cs = TestConstraintSystem::<Fq>::new();
171
172 let a: G2 = rand::random();
173 let b: G2 = rand::random();
174 let a_affine = a.into_affine();
175 let b_affine = b.into_affine();
176
177 let mut gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
178 let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
179 assert_eq!(gadget_a.x.get_value().unwrap(), a_affine.x);
180 assert_eq!(gadget_a.y.get_value().unwrap(), a_affine.y);
181 assert_eq!(gadget_b.x.get_value().unwrap(), b_affine.x);
182 assert_eq!(gadget_b.y.get_value().unwrap(), b_affine.y);
183
184 let ab = a + &b;
185 let ab_affine = ab.into_affine();
186 let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
187 let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap();
188 gadget_ba
189 .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab)
190 .unwrap();
191 assert_eq!(gadget_ab.x.get_value().unwrap(), ab_affine.x);
192 assert_eq!(gadget_ab.y.get_value().unwrap(), ab_affine.y);
193
194 let aa = a.double();
195 let aa_affine = aa.into_affine();
196 gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap();
197
198 assert_eq!(gadget_a.x.get_value().unwrap(), aa_affine.x);
199 assert_eq!(gadget_a.y.get_value().unwrap(), aa_affine.y);
200
201 if !cs.is_satisfied() {
202 println!("{:?}", cs.which_is_unsatisfied().unwrap());
203 }
204
205 assert!(cs.is_satisfied());
206 }
207}