/src/cryptofuzz/modules/blst/module.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "module.h" |
2 | | #include <cryptofuzz/util.h> |
3 | | #include <cryptofuzz/repository.h> |
4 | | #include <fuzzing/datasource/id.hpp> |
5 | | #include <boost/multiprecision/cpp_int.hpp> |
6 | | |
7 | | extern "C" { |
8 | | #include <blst.h> |
9 | | } |
10 | | |
11 | | namespace cryptofuzz { |
12 | | namespace module { |
13 | | |
14 | | blst::blst(void) : |
15 | 4 | Module("blst") { |
16 | 4 | } |
17 | | |
18 | | namespace blst_detail { |
19 | | template <size_t Size> |
20 | 290k | void Reverse(std::array<uint8_t, Size>& v) { |
21 | 290k | std::reverse(v.begin(), v.end()); |
22 | 290k | } void cryptofuzz::module::blst_detail::Reverse<32ul>(std::__1::array<unsigned char, 32ul>&) Line | Count | Source | 20 | 9.49k | void Reverse(std::array<uint8_t, Size>& v) { | 21 | 9.49k | std::reverse(v.begin(), v.end()); | 22 | 9.49k | } |
void cryptofuzz::module::blst_detail::Reverse<48ul>(std::__1::array<unsigned char, 48ul>&) Line | Count | Source | 20 | 280k | void Reverse(std::array<uint8_t, Size>& v) { | 21 | 280k | std::reverse(v.begin(), v.end()); | 22 | 280k | } |
|
23 | | |
24 | | template <size_t Size> |
25 | 231k | std::optional<std::array<uint8_t, Size>> ToArray(const component::Bignum& bn, const bool reverse = true) { |
26 | 231k | const auto _ret = util::DecToBin(bn.ToTrimmedString(), Size); |
27 | 231k | if ( _ret == std::nullopt ) { |
28 | 3.71k | return std::nullopt; |
29 | 3.71k | } |
30 | | |
31 | 228k | std::array<uint8_t, Size> ret; |
32 | 228k | memcpy(ret.data(), _ret->data(), Size); |
33 | 228k | if ( reverse == true ) { |
34 | 227k | Reverse<>(ret); |
35 | 227k | } |
36 | | |
37 | 228k | return ret; |
38 | 231k | } std::__1::optional<std::__1::array<unsigned char, 32ul> > cryptofuzz::module::blst_detail::ToArray<32ul>(cryptofuzz::Bignum const&, bool) Line | Count | Source | 25 | 8.21k | std::optional<std::array<uint8_t, Size>> ToArray(const component::Bignum& bn, const bool reverse = true) { | 26 | 8.21k | const auto _ret = util::DecToBin(bn.ToTrimmedString(), Size); | 27 | 8.21k | if ( _ret == std::nullopt ) { | 28 | 463 | return std::nullopt; | 29 | 463 | } | 30 | | | 31 | 7.75k | std::array<uint8_t, Size> ret; | 32 | 7.75k | memcpy(ret.data(), _ret->data(), Size); | 33 | 7.75k | if ( reverse == true ) { | 34 | 7.75k | Reverse<>(ret); | 35 | 7.75k | } | 36 | | | 37 | 7.75k | return ret; | 38 | 8.21k | } |
std::__1::optional<std::__1::array<unsigned char, 48ul> > cryptofuzz::module::blst_detail::ToArray<48ul>(cryptofuzz::Bignum const&, bool) Line | Count | Source | 25 | 223k | std::optional<std::array<uint8_t, Size>> ToArray(const component::Bignum& bn, const bool reverse = true) { | 26 | 223k | const auto _ret = util::DecToBin(bn.ToTrimmedString(), Size); | 27 | 223k | if ( _ret == std::nullopt ) { | 28 | 3.25k | return std::nullopt; | 29 | 3.25k | } | 30 | | | 31 | 220k | std::array<uint8_t, Size> ret; | 32 | 220k | memcpy(ret.data(), _ret->data(), Size); | 33 | 220k | if ( reverse == true ) { | 34 | 219k | Reverse<>(ret); | 35 | 219k | } | 36 | | | 37 | 220k | return ret; | 38 | 223k | } |
|
39 | 3.24k | bool To_blst_fr(const component::Bignum& bn, blst_fr& out) { |
40 | 3.24k | const auto ret = ToArray<32>(bn); |
41 | | |
42 | 3.24k | if ( ret == std::nullopt ) { |
43 | 344 | return false; |
44 | 344 | } |
45 | | |
46 | 2.89k | CF_NORET(blst_fr_from_uint64(&out, (const uint64_t*)ret->data())); |
47 | 2.89k | return true; |
48 | 3.24k | } |
49 | 222k | bool To_blst_fp(const component::Bignum& bn, blst_fp& out) { |
50 | 222k | const auto ret = ToArray<48>(bn); |
51 | | |
52 | 222k | if ( ret == std::nullopt ) { |
53 | 3.18k | return false; |
54 | 3.18k | } |
55 | | |
56 | 219k | CF_NORET(blst_fp_from_uint64(&out, (const uint64_t*)ret->data())); |
57 | 219k | return true; |
58 | 222k | } |
59 | 2.35k | bool To_blst_fp2(const component::Fp2& bn, blst_fp2& out) { |
60 | 2.35k | return To_blst_fp(bn.first, out.fp[0]) && |
61 | 2.35k | To_blst_fp(bn.second, out.fp[1]); |
62 | 2.35k | } |
63 | 1.50k | bool To_blst_fp12(const component::Fp12& bn, blst_fp12& out) { |
64 | 1.50k | return To_blst_fp(bn.bn1, out.fp6[0].fp2[0].fp[0]) && |
65 | 1.50k | To_blst_fp(bn.bn2, out.fp6[0].fp2[0].fp[1]) && |
66 | 1.50k | To_blst_fp(bn.bn3, out.fp6[0].fp2[1].fp[0]) && |
67 | 1.50k | To_blst_fp(bn.bn4, out.fp6[0].fp2[1].fp[1]) && |
68 | 1.50k | To_blst_fp(bn.bn5, out.fp6[0].fp2[2].fp[0]) && |
69 | 1.50k | To_blst_fp(bn.bn6, out.fp6[0].fp2[2].fp[1]) && |
70 | | |
71 | 1.50k | To_blst_fp(bn.bn7, out.fp6[1].fp2[0].fp[0]) && |
72 | 1.50k | To_blst_fp(bn.bn8, out.fp6[1].fp2[0].fp[1]) && |
73 | 1.50k | To_blst_fp(bn.bn9, out.fp6[1].fp2[1].fp[0]) && |
74 | 1.50k | To_blst_fp(bn.bn10, out.fp6[1].fp2[1].fp[1]) && |
75 | 1.50k | To_blst_fp(bn.bn11, out.fp6[1].fp2[2].fp[0]) && |
76 | 1.50k | To_blst_fp(bn.bn12, out.fp6[1].fp2[2].fp[1]); |
77 | 1.50k | } |
78 | 1.64k | component::Bignum To_component_bignum(const blst_fr& in) { |
79 | 1.64k | std::array<uint8_t, 32> v; |
80 | | |
81 | 1.64k | blst_uint64_from_fr((uint64_t*)v.data(), &in); |
82 | | |
83 | 1.64k | Reverse<>(v); |
84 | 1.64k | return util::BinToDec(v.data(), 32); |
85 | 1.64k | } |
86 | 1.60k | component::Bignum To_component_bignum(const blst_fp& in) { |
87 | 1.60k | std::array<uint8_t, 48> v; |
88 | | |
89 | 1.60k | blst_uint64_from_fp((uint64_t*)v.data(), &in); |
90 | | |
91 | 1.60k | Reverse<>(v); |
92 | 1.60k | return util::BinToDec(v.data(), 48); |
93 | 1.60k | } |
94 | 875 | component::Fp2 To_component_Fp2(const blst_fp2& in) { |
95 | 875 | std::array<uint8_t, 48> v1, v2; |
96 | | |
97 | 875 | blst_uint64_from_fp((uint64_t*)v1.data(), &in.fp[0]); |
98 | 875 | Reverse<>(v1); |
99 | | |
100 | 875 | blst_uint64_from_fp((uint64_t*)v2.data(), &in.fp[1]); |
101 | 875 | Reverse<>(v2); |
102 | | |
103 | 875 | return { |
104 | 875 | util::BinToDec(v1.data(), 48), |
105 | 875 | util::BinToDec(v2.data(), 48), |
106 | 875 | }; |
107 | 875 | } |
108 | 839 | boost::multiprecision::cpp_int To_cpp_int(const component::Bignum& in) { |
109 | 839 | return boost::multiprecision::cpp_int(in.ToTrimmedString()); |
110 | 839 | } |
111 | | |
112 | | class G1 { |
113 | | private: |
114 | | fuzzing::datasource::Datasource& ds; |
115 | | blst_p1_affine g1; |
116 | | public: |
117 | | G1(const blst_p1_affine& g1, fuzzing::datasource::Datasource& ds) : |
118 | 7.50k | ds(ds) { |
119 | 7.50k | memcpy(&this->g1, &g1, sizeof(g1)); |
120 | 7.50k | } |
121 | 7.50k | const blst_p1_affine* Get(void) { |
122 | 7.50k | return &g1; |
123 | 7.50k | } |
124 | 7.50k | component::G1 To_Component_G1(void) { |
125 | 7.50k | std::array<uint8_t, 48> x, y; |
126 | | |
127 | 7.50k | const blst_p1_affine* ptr = Get(); |
128 | | |
129 | 7.50k | blst_uint64_from_fp((uint64_t*)x.data(), &ptr->x); |
130 | 7.50k | blst_uint64_from_fp((uint64_t*)y.data(), &ptr->y); |
131 | | |
132 | 7.50k | Reverse<>(x); |
133 | 7.50k | Reverse<>(y); |
134 | | |
135 | 7.50k | return {util::BinToDec(x.data(), 48), util::BinToDec(y.data(), 48)}; |
136 | 7.50k | } |
137 | | }; |
138 | 7.72k | component::G2 To_G2(const blst_p2_affine& g2) { |
139 | 7.72k | std::array<uint8_t, 48> x1, y1, x2, y2; |
140 | | |
141 | 7.72k | blst_uint64_from_fp((uint64_t*)x1.data(), &g2.x.fp[0]); |
142 | 7.72k | blst_uint64_from_fp((uint64_t*)y1.data(), &g2.y.fp[0]); |
143 | 7.72k | blst_uint64_from_fp((uint64_t*)x2.data(), &g2.x.fp[1]); |
144 | 7.72k | blst_uint64_from_fp((uint64_t*)y2.data(), &g2.y.fp[1]); |
145 | | |
146 | 7.72k | Reverse<>(x1); |
147 | 7.72k | Reverse<>(y1); |
148 | 7.72k | Reverse<>(x2); |
149 | 7.72k | Reverse<>(y2); |
150 | | |
151 | 7.72k | return { |
152 | 7.72k | util::BinToDec(x1.data(), 48), |
153 | 7.72k | util::BinToDec(y1.data(), 48), |
154 | 7.72k | util::BinToDec(x2.data(), 48), |
155 | 7.72k | util::BinToDec(y2.data(), 48) |
156 | 7.72k | }; |
157 | 7.72k | } |
158 | | |
159 | 971 | component::Fp12 To_component_Fp12(const blst_fp12& fp12) { |
160 | 971 | std::array<uint8_t, 48> bn1, bn2, bn3, bn4, bn5, bn6, bn7, bn8, bn9, bn10, bn11, bn12; |
161 | | |
162 | 971 | blst_uint64_from_fp((uint64_t*)bn1.data(), &fp12.fp6[0].fp2[0].fp[0]); |
163 | 971 | Reverse<>(bn1); |
164 | | |
165 | 971 | blst_uint64_from_fp((uint64_t*)bn2.data(), &fp12.fp6[0].fp2[0].fp[1]); |
166 | 971 | Reverse<>(bn2); |
167 | | |
168 | 971 | blst_uint64_from_fp((uint64_t*)bn3.data(), &fp12.fp6[0].fp2[1].fp[0]); |
169 | 971 | Reverse<>(bn3); |
170 | | |
171 | 971 | blst_uint64_from_fp((uint64_t*)bn4.data(), &fp12.fp6[0].fp2[1].fp[1]); |
172 | 971 | Reverse<>(bn4); |
173 | | |
174 | 971 | blst_uint64_from_fp((uint64_t*)bn5.data(), &fp12.fp6[0].fp2[2].fp[0]); |
175 | 971 | Reverse<>(bn5); |
176 | | |
177 | 971 | blst_uint64_from_fp((uint64_t*)bn6.data(), &fp12.fp6[0].fp2[2].fp[1]); |
178 | 971 | Reverse<>(bn6); |
179 | | |
180 | 971 | blst_uint64_from_fp((uint64_t*)bn7.data(), &fp12.fp6[1].fp2[0].fp[0]); |
181 | 971 | Reverse<>(bn7); |
182 | | |
183 | 971 | blst_uint64_from_fp((uint64_t*)bn8.data(), &fp12.fp6[1].fp2[0].fp[1]); |
184 | 971 | Reverse<>(bn8); |
185 | | |
186 | 971 | blst_uint64_from_fp((uint64_t*)bn9.data(), &fp12.fp6[1].fp2[1].fp[0]); |
187 | 971 | Reverse<>(bn9); |
188 | | |
189 | 971 | blst_uint64_from_fp((uint64_t*)bn10.data(), &fp12.fp6[1].fp2[1].fp[1]); |
190 | 971 | Reverse<>(bn10); |
191 | | |
192 | 971 | blst_uint64_from_fp((uint64_t*)bn11.data(), &fp12.fp6[1].fp2[2].fp[0]); |
193 | 971 | Reverse<>(bn11); |
194 | | |
195 | 971 | blst_uint64_from_fp((uint64_t*)bn12.data(), &fp12.fp6[1].fp2[2].fp[1]); |
196 | 971 | Reverse<>(bn12); |
197 | | |
198 | 971 | return { |
199 | 971 | util::BinToDec(bn1.data(), 48), |
200 | 971 | util::BinToDec(bn2.data(), 48), |
201 | 971 | util::BinToDec(bn3.data(), 48), |
202 | 971 | util::BinToDec(bn4.data(), 48), |
203 | 971 | util::BinToDec(bn5.data(), 48), |
204 | 971 | util::BinToDec(bn6.data(), 48), |
205 | 971 | util::BinToDec(bn7.data(), 48), |
206 | 971 | util::BinToDec(bn8.data(), 48), |
207 | 971 | util::BinToDec(bn9.data(), 48), |
208 | 971 | util::BinToDec(bn10.data(), 48), |
209 | 971 | util::BinToDec(bn11.data(), 48), |
210 | 971 | util::BinToDec(bn12.data(), 48), |
211 | 971 | }; |
212 | 971 | } |
213 | | |
214 | 4.97k | bool To_blst_scalar(const component::Bignum& bn, blst_scalar& out) { |
215 | 4.97k | const auto ret = ToArray<32>(bn); |
216 | | |
217 | 4.97k | if ( ret == std::nullopt ) { |
218 | 119 | return false; |
219 | 119 | } |
220 | | |
221 | 4.85k | CF_NORET(blst_scalar_from_uint64(&out, (const uint64_t*)ret->data())); |
222 | | |
223 | 4.85k | return true; |
224 | 4.97k | } |
225 | 0 | bool IsLessThan(const blst_fp& A, const blst_fp& B) { |
226 | 0 | std::array<uint8_t, 48> A_words, B_words; |
227 | |
|
228 | 0 | uint64_t* A_ptr = (uint64_t*)A_words.data(); |
229 | 0 | uint64_t* B_ptr = (uint64_t*)B_words.data(); |
230 | |
|
231 | 0 | blst_uint64_from_fp(A_ptr, &A); |
232 | 0 | blst_uint64_from_fp(B_ptr, &B); |
233 | |
|
234 | 0 | for (int i = 5; i >= 0; i--) { |
235 | 0 | if ( A_ptr[i] == B_ptr[i] ) { |
236 | 0 | continue; |
237 | 0 | } |
238 | 0 | return A_ptr[i] < B_ptr[i]; |
239 | 0 | } |
240 | | |
241 | 0 | return false; |
242 | 0 | } |
243 | 465 | static size_t isMultipleOf2(const std::string s) { |
244 | 465 | auto i = boost::multiprecision::cpp_int(s); |
245 | 465 | if ( i == 0 || i == 1 ) { |
246 | 34 | return 0; |
247 | 34 | } |
248 | 431 | size_t num = 0; |
249 | 13.1k | while ( i ) { |
250 | 13.0k | if ( i != 1 && i & 1 ) { |
251 | 265 | return 0; |
252 | 265 | } |
253 | 12.7k | i >>= 1; |
254 | 12.7k | num++; |
255 | 12.7k | } |
256 | | |
257 | 166 | return num - 1; |
258 | 431 | } |
259 | 2.19k | static bool IsZero(const blst_p2_affine* g2) { |
260 | 2.19k | blst_p2_affine zero; |
261 | 2.19k | memset(&zero, 0, sizeof(zero)); |
262 | 2.19k | return memcmp(g2, &zero, sizeof(zero)) == 0; |
263 | 2.19k | } |
264 | | |
265 | 7.40k | static std::optional<blst_p1_affine> Load_G1_Affine(const component::G1& g1) { |
266 | 7.40k | std::optional<blst_p1_affine> ret = std::nullopt; |
267 | | |
268 | 7.40k | blst_p1_affine aff_a; |
269 | | |
270 | 7.40k | CF_CHECK_TRUE(blst_detail::To_blst_fp(g1.first, aff_a.x)); |
271 | 7.26k | CF_CHECK_TRUE(blst_detail::To_blst_fp(g1.second, aff_a.y)); |
272 | | |
273 | 7.14k | ret = aff_a; |
274 | 7.40k | end: |
275 | 7.40k | return ret; |
276 | 7.14k | } |
277 | | |
278 | | static std::optional<blst_p1> Load_G1_Projective( |
279 | | fuzzing::datasource::Datasource& ds, |
280 | 11.1k | const component::G1& g1) { |
281 | 11.1k | std::optional<blst_p1> ret = std::nullopt; |
282 | | |
283 | 11.1k | blst_p1 a; |
284 | | |
285 | 11.1k | const auto proj = util::ToRandomProjective( |
286 | 11.1k | ds, |
287 | 11.1k | g1.first.ToTrimmedString(), |
288 | 11.1k | g1.second.ToTrimmedString(), |
289 | 11.1k | CF_ECC_CURVE("BLS12_381")); |
290 | | |
291 | 11.1k | CF_CHECK_TRUE(blst_detail::To_blst_fp(proj[0], a.x)); |
292 | 11.1k | CF_CHECK_TRUE(blst_detail::To_blst_fp(proj[1], a.y)); |
293 | 11.0k | CF_CHECK_TRUE(blst_detail::To_blst_fp(proj[2], a.z)); |
294 | | |
295 | 11.0k | ret = a; |
296 | 11.1k | end: |
297 | 11.1k | return ret; |
298 | 11.0k | } |
299 | | } |
300 | | |
301 | 3.02k | std::optional<component::BLS_PublicKey> blst::OpBLS_PrivateToPublic(operation::BLS_PrivateToPublic& op) { |
302 | 3.02k | if ( op.curveType.Get() != CF_ECC_CURVE("BLS12_381") ) { |
303 | | //return std::nullopt; |
304 | 0 | } |
305 | | |
306 | 3.02k | std::optional<component::BLS_PublicKey> ret = std::nullopt; |
307 | 3.02k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
308 | | |
309 | 3.02k | blst_scalar priv; |
310 | 3.02k | blst_p1 pub; |
311 | 3.02k | blst_p1_affine pub_affine; |
312 | | |
313 | 3.02k | CF_CHECK_TRUE(blst_detail::To_blst_scalar(op.priv, priv)); |
314 | | |
315 | | /* blst_sk_to_pk_in_g1 does not reduce the private key, |
316 | | * so check if it's valid first |
317 | | */ |
318 | 2.97k | CF_CHECK_TRUE(blst_sk_check(&priv)); |
319 | | |
320 | 2.83k | CF_NORET(blst_sk_to_pk_in_g1(&pub, &priv)); |
321 | 2.83k | CF_ASSERT(blst_p1_on_curve(&pub) == true, "Generated pubkey not on curve"); |
322 | 2.83k | CF_ASSERT(blst_p1_in_g1(&pub) == true, "Generated pubkey not in group"); |
323 | | |
324 | 2.83k | CF_NORET(blst_p1_to_affine(&pub_affine, &pub)); |
325 | | |
326 | 2.83k | { |
327 | 2.83k | blst_detail::G1 g1(pub_affine, ds); |
328 | 2.83k | ret = g1.To_Component_G1(); |
329 | 2.83k | } |
330 | | |
331 | 3.02k | end: |
332 | 3.02k | return ret; |
333 | 2.83k | } |
334 | | |
335 | 607 | std::optional<component::G2> blst::OpBLS_PrivateToPublic_G2(operation::BLS_PrivateToPublic_G2& op) { |
336 | 607 | if ( op.curveType.Get() != CF_ECC_CURVE("BLS12_381") ) { |
337 | | //return std::nullopt; |
338 | 256 | } |
339 | | |
340 | 607 | std::optional<component::G2> ret = std::nullopt; |
341 | 607 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
342 | | |
343 | 607 | blst_scalar priv; |
344 | 607 | blst_p2 pub; |
345 | 607 | blst_p2_affine pub_affine; |
346 | | |
347 | 607 | CF_CHECK_TRUE(blst_detail::To_blst_scalar(op.priv, priv)); |
348 | | |
349 | | /* blst_sk_to_pk_in_g2 does not reduce the private key, |
350 | | * so check if it's valid first |
351 | | */ |
352 | 552 | CF_CHECK_TRUE(blst_sk_check(&priv)); |
353 | | |
354 | 481 | CF_NORET(blst_sk_to_pk_in_g2(&pub, &priv)); |
355 | 481 | CF_ASSERT(blst_p2_on_curve(&pub) == true, "Generated pubkey not on curve"); |
356 | 481 | CF_ASSERT(blst_p2_in_g2(&pub) == true, "Generated pubkey not in group"); |
357 | | |
358 | 481 | CF_NORET(blst_p2_to_affine(&pub_affine, &pub)); |
359 | | |
360 | 481 | ret = blst_detail::To_G2(pub_affine); |
361 | | |
362 | 607 | end: |
363 | 607 | return ret; |
364 | 481 | } |
365 | | |
366 | 188 | std::optional<component::G1> blst::OpBLS_HashToG1(operation::BLS_HashToG1& op) { |
367 | 188 | if ( op.curveType.Get() != CF_ECC_CURVE("BLS12_381") ) { |
368 | | //return std::nullopt; |
369 | 0 | } |
370 | | |
371 | 188 | std::optional<component::G1> ret = std::nullopt; |
372 | 188 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
373 | | |
374 | 188 | blst_p1 g1; |
375 | 188 | blst_p1_affine g1_affine; |
376 | | |
377 | 188 | CF_NORET(blst_hash_to_g1( |
378 | 188 | &g1, |
379 | 188 | op.cleartext.GetPtr(&ds), op.cleartext.GetSize(), |
380 | 188 | op.dest.GetPtr(&ds), op.dest.GetSize(), |
381 | 188 | op.aug.GetPtr(&ds), op.aug.GetSize())); |
382 | | |
383 | 188 | CF_ASSERT(blst_p1_on_curve(&g1) == true, "Generated g1 not on curve"); |
384 | 188 | CF_ASSERT(blst_p1_in_g1(&g1) == true, "Generated g1 not in group"); |
385 | | |
386 | 188 | CF_NORET(blst_p1_to_affine(&g1_affine, &g1)); |
387 | | |
388 | 188 | { |
389 | 188 | blst_detail::G1 _g1(g1_affine, ds); |
390 | 188 | ret = _g1.To_Component_G1(); |
391 | 188 | } |
392 | | |
393 | 188 | return ret; |
394 | 188 | } |
395 | | |
396 | 249 | std::optional<component::G2> blst::OpBLS_HashToG2(operation::BLS_HashToG2& op) { |
397 | 249 | if ( op.curveType.Get() != CF_ECC_CURVE("BLS12_381") ) { |
398 | | //return std::nullopt; |
399 | 0 | } |
400 | | |
401 | 249 | std::optional<component::G2> ret = std::nullopt; |
402 | 249 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
403 | | |
404 | 249 | blst_p2 g2; |
405 | 249 | blst_p2_affine g2_affine; |
406 | | |
407 | 249 | CF_NORET(blst_hash_to_g2( |
408 | 249 | &g2, |
409 | 249 | op.cleartext.GetPtr(&ds), op.cleartext.GetSize(), |
410 | 249 | op.dest.GetPtr(&ds), op.dest.GetSize(), |
411 | 249 | op.aug.GetPtr(&ds), op.aug.GetSize())); |
412 | | |
413 | 249 | CF_ASSERT(blst_p2_on_curve(&g2) == true, "Generated g2 not on curve"); |
414 | 249 | CF_ASSERT(blst_p2_in_g2(&g2) == true, "Generated g2 not in group"); |
415 | | |
416 | 249 | CF_NORET(blst_p2_to_affine(&g2_affine, &g2)); |
417 | | |
418 | 249 | ret = blst_detail::To_G2(g2_affine); |
419 | | |
420 | 249 | return ret; |
421 | 249 | } |
422 | | |
423 | 298 | std::optional<component::G1> blst::OpBLS_MapToG1(operation::BLS_MapToG1& op) { |
424 | 298 | if ( op.curveType.Get() != CF_ECC_CURVE("BLS12_381") ) { |
425 | | //return std::nullopt; |
426 | 125 | } |
427 | | |
428 | 298 | std::optional<component::G1> ret = std::nullopt; |
429 | 298 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
430 | | |
431 | 298 | blst_p1 g1; |
432 | 298 | blst_p1_affine g1_affine; |
433 | 298 | blst_fp u, v; |
434 | | |
435 | 298 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.u, u)); |
436 | 277 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.v, v)); |
437 | | |
438 | 248 | CF_NORET(blst_map_to_g1(&g1, &u, &v)); |
439 | | |
440 | 248 | CF_ASSERT(blst_p1_on_curve(&g1) == true, "Generated g1 not on curve"); |
441 | 248 | CF_ASSERT(blst_p1_in_g1(&g1) == true, "Generated g1 not in group"); |
442 | | |
443 | 248 | CF_NORET(blst_p1_to_affine(&g1_affine, &g1)); |
444 | | |
445 | 248 | { |
446 | 248 | blst_detail::G1 _g1(g1_affine, ds); |
447 | 248 | ret = _g1.To_Component_G1(); |
448 | 248 | } |
449 | | |
450 | 298 | end: |
451 | 298 | return ret; |
452 | 248 | } |
453 | | |
454 | 234 | std::optional<component::G2> blst::OpBLS_MapToG2(operation::BLS_MapToG2& op) { |
455 | 234 | if ( op.curveType.Get() != CF_ECC_CURVE("BLS12_381") ) { |
456 | | //return std::nullopt; |
457 | 130 | } |
458 | | |
459 | 234 | std::optional<component::G2> ret = std::nullopt; |
460 | 234 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
461 | | |
462 | 234 | blst_p2 g2; |
463 | 234 | blst_p2_affine g2_affine; |
464 | 234 | blst_fp2 u, v; |
465 | | |
466 | 234 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.u, u)); |
467 | 194 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.v, v)); |
468 | | |
469 | 152 | CF_NORET(blst_map_to_g2(&g2, &u, &v)); |
470 | | |
471 | 152 | CF_ASSERT(blst_p2_on_curve(&g2) == true, "Generated g2 not on curve"); |
472 | 152 | CF_ASSERT(blst_p2_in_g2(&g2) == true, "Generated g2 not in group"); |
473 | | |
474 | 152 | CF_NORET(blst_p2_to_affine(&g2_affine, &g2)); |
475 | | |
476 | 152 | ret = blst_detail::To_G2(g2_affine); |
477 | | |
478 | 234 | end: |
479 | 234 | return ret; |
480 | 152 | } |
481 | | |
482 | 1.34k | std::optional<component::BLS_Signature> blst::OpBLS_Sign(operation::BLS_Sign& op) { |
483 | 1.34k | if ( op.curveType.Get() != CF_ECC_CURVE("BLS12_381") ) { |
484 | | //return std::nullopt; |
485 | 1.02k | } |
486 | | |
487 | 1.34k | std::optional<component::BLS_Signature> ret; |
488 | 1.34k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
489 | | |
490 | 1.34k | blst_scalar priv; |
491 | 1.34k | blst_p1 pub; |
492 | 1.34k | blst_p1_affine pub_affine; |
493 | 1.34k | blst_p2_affine hash_affine; |
494 | 1.34k | blst_p2 hash; |
495 | 1.34k | blst_p2 signature; |
496 | 1.34k | blst_p2_affine signature_affine; |
497 | | |
498 | 1.34k | CF_CHECK_TRUE(blst_detail::To_blst_scalar(op.priv, priv)); |
499 | 1.32k | CF_CHECK_TRUE(blst_sk_check(&priv)); |
500 | | |
501 | 1.28k | CF_NORET(blst_sk_to_pk_in_g1(&pub, &priv)); |
502 | 1.28k | CF_ASSERT(blst_p1_on_curve(&pub) == true, "Generated pubkey not on curve"); |
503 | 1.28k | CF_ASSERT(blst_p1_in_g1(&pub) == true, "Generated pubkey not in group"); |
504 | 1.28k | CF_NORET(blst_p1_to_affine(&pub_affine, &pub)); |
505 | | |
506 | 1.28k | if ( op.hashOrPoint == true ) { |
507 | 944 | CF_NORET(blst_hash_to_g2( |
508 | 944 | &hash, |
509 | 944 | op.cleartext.GetPtr(&ds), op.cleartext.GetSize(), |
510 | 944 | op.dest.GetPtr(&ds), op.dest.GetSize(), |
511 | 944 | op.aug.GetPtr(&ds), op.aug.GetSize())); |
512 | 944 | } else { |
513 | 342 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.point.first.first, hash_affine.x.fp[0])); |
514 | 322 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.point.first.second, hash_affine.y.fp[0])); |
515 | 302 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.point.second.first, hash_affine.x.fp[1])); |
516 | 281 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.point.second.second, hash_affine.y.fp[1])); |
517 | 261 | CF_NORET(blst_p2_from_affine(&hash, &hash_affine)); |
518 | 261 | } |
519 | 1.20k | CF_NORET(blst_sign_pk_in_g1(&signature, &hash, &priv)); |
520 | | |
521 | 1.20k | if ( op.hashOrPoint == true ) { |
522 | 944 | CF_ASSERT(blst_p2_on_curve(&signature) == true, "Generated signature not on curve"); |
523 | 944 | CF_ASSERT(blst_p2_in_g2(&signature) == true, "Generated signature not in group"); |
524 | 944 | } else { |
525 | 261 | if ( blst_p2_affine_on_curve(&hash_affine) ) { |
526 | 232 | CF_ASSERT(blst_p2_on_curve(&signature) == true, "Generated signature not on curve"); |
527 | 232 | } |
528 | | |
529 | 261 | if ( blst_p2_affine_in_g2(&hash_affine) ) { |
530 | 232 | CF_ASSERT(blst_p2_in_g2(&signature) == true, "Generated signature not in group"); |
531 | 232 | } |
532 | 261 | } |
533 | | |
534 | 1.20k | CF_NORET(blst_p2_to_affine(&signature_affine, &signature)); |
535 | | |
536 | 1.20k | { |
537 | 1.20k | blst_detail::G1 g1(pub_affine, ds); |
538 | 1.20k | ret = {blst_detail::To_G2(signature_affine), g1.To_Component_G1()}; |
539 | 1.20k | } |
540 | | |
541 | 1.20k | if ( op.hashOrPoint == true ) { |
542 | 944 | if ( blst_core_verify_pk_in_g1( |
543 | 944 | &pub_affine, &signature_affine, |
544 | 944 | true, |
545 | 944 | op.cleartext.GetPtr(&ds), op.cleartext.GetSize(), |
546 | 944 | op.dest.GetPtr(&ds), op.dest.GetSize(), |
547 | 944 | op.aug.GetPtr(&ds), op.aug.GetSize()) != BLST_SUCCESS ) { |
548 | 0 | abort(); |
549 | 0 | } |
550 | 944 | } |
551 | | |
552 | 1.34k | end: |
553 | 1.34k | return ret; |
554 | 1.20k | } |
555 | | |
556 | | namespace blst_detail { |
557 | | std::optional<bool> Verify( |
558 | | Datasource& ds, |
559 | | const component::Cleartext& msg, |
560 | | const component::Cleartext& dst, |
561 | | const component::Cleartext& aug, |
562 | | const component::G1& pub, |
563 | | const component::G2& sig, |
564 | 0 | const bool hashOrEncode) { |
565 | 0 | std::optional<bool> ret = std::nullopt; |
566 | |
|
567 | 0 | blst_p1_affine pub_affine; |
568 | 0 | blst_p2_affine sig_affine; |
569 | |
|
570 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(pub.first, pub_affine.x)); |
571 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(pub.second, pub_affine.y)); |
572 | |
|
573 | 0 | if ( !(blst_p1_affine_on_curve(&pub_affine) && blst_p1_affine_in_g1(&pub_affine)) ) { |
574 | 0 | return false; |
575 | 0 | } |
576 | | |
577 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.first.first, sig_affine.x.fp[0])); |
578 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.first.second, sig_affine.y.fp[0])); |
579 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.second.first, sig_affine.x.fp[1])); |
580 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.second.second, sig_affine.y.fp[1])); |
581 | |
|
582 | 0 | if ( !(blst_p2_affine_on_curve(&sig_affine) && blst_p2_affine_in_g2(&sig_affine)) ) { |
583 | 0 | return false; |
584 | 0 | } |
585 | | |
586 | 0 | ret = blst_core_verify_pk_in_g1( |
587 | 0 | &pub_affine, &sig_affine, |
588 | 0 | hashOrEncode, |
589 | 0 | msg.GetPtr(&ds), msg.GetSize(), |
590 | 0 | dst.GetPtr(&ds), dst.GetSize(), |
591 | 0 | aug.GetPtr(&ds), aug.GetSize()) == BLST_SUCCESS; |
592 | |
|
593 | 0 | end: |
594 | 0 | return ret; |
595 | 0 | } |
596 | | } |
597 | | |
598 | 304 | std::optional<bool> blst::OpBLS_Verify(operation::BLS_Verify& op) { |
599 | 304 | if ( op.curveType.Get() != CF_ECC_CURVE("BLS12_381") ) { |
600 | | //return std::nullopt; |
601 | 277 | } |
602 | 304 | if ( op.hashOrPoint == false ) { |
603 | 68 | return std::nullopt; |
604 | 68 | } |
605 | | |
606 | 236 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
607 | | |
608 | 236 | std::optional<bool> ret = std::nullopt; |
609 | | |
610 | 236 | blst_p1_affine pub; |
611 | 236 | blst_p2_affine sig; |
612 | | |
613 | 236 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.pub.first, pub.x)); |
614 | 214 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.pub.second, pub.y)); |
615 | | |
616 | 193 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.signature.first.first, sig.x.fp[0])); |
617 | 173 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.signature.first.second, sig.y.fp[0])); |
618 | 153 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.signature.second.first, sig.x.fp[1])); |
619 | 133 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.signature.second.second, sig.y.fp[1])); |
620 | | |
621 | 108 | ret = blst_core_verify_pk_in_g1( |
622 | 108 | &pub, &sig, |
623 | 108 | true, |
624 | 108 | op.cleartext.GetPtr(&ds), op.cleartext.GetSize(), |
625 | 108 | op.dest.GetPtr(&ds), op.dest.GetSize(), |
626 | 108 | nullptr, 0) == BLST_SUCCESS; |
627 | | |
628 | 236 | end: |
629 | 236 | return ret; |
630 | 108 | } |
631 | | |
632 | 988 | std::optional<bool> blst::OpBLS_BatchVerify(operation::BLS_BatchVerify& op) { |
633 | 988 | std::optional<bool> ret = std::nullopt; |
634 | | |
635 | 988 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
636 | | |
637 | 988 | const blst_fp12 one = *blst_fp12_one(); |
638 | 988 | blst_fp12 f = *blst_fp12_one(); |
639 | | |
640 | 12.7k | for (const auto& cur : op.bf.c) { |
641 | 12.7k | blst_p1_affine g1_affine; |
642 | 12.7k | blst_p2_affine g2_affine; |
643 | | |
644 | | /* Load G1 */ |
645 | 12.7k | CF_CHECK_TRUE(blst_detail::To_blst_fp(cur.g1.first, g1_affine.x)); |
646 | 12.7k | CF_CHECK_TRUE(blst_detail::To_blst_fp(cur.g1.second, g1_affine.y)); |
647 | | |
648 | 12.6k | CF_CHECK_TRUE(blst_p1_affine_on_curve(&g1_affine) && blst_p1_affine_in_g1(&g1_affine)); |
649 | | |
650 | | /* Load G2 */ |
651 | 12.0k | CF_CHECK_TRUE(blst_detail::To_blst_fp(cur.g2.first.first, g2_affine.x.fp[0])); |
652 | 12.0k | CF_CHECK_TRUE(blst_detail::To_blst_fp(cur.g2.first.second, g2_affine.y.fp[0])); |
653 | 12.0k | CF_CHECK_TRUE(blst_detail::To_blst_fp(cur.g2.second.first, g2_affine.x.fp[1])); |
654 | 11.9k | CF_CHECK_TRUE(blst_detail::To_blst_fp(cur.g2.second.second, g2_affine.y.fp[1])); |
655 | | |
656 | 11.9k | CF_CHECK_TRUE(blst_p2_affine_on_curve(&g2_affine) && blst_p2_affine_in_g2(&g2_affine)); |
657 | | |
658 | 11.8k | blst_fp12 tmp; |
659 | 11.8k | CF_NORET(blst_miller_loop(&tmp, &g2_affine, &g1_affine)); |
660 | 11.8k | CF_NORET(blst_fp12_mul(&f, &f, &tmp)); |
661 | 11.8k | } |
662 | | |
663 | 149 | CF_NORET(blst_final_exp(&f, &f)); |
664 | | |
665 | 149 | ret = blst_fp12_is_equal(&f, &one) == 1; |
666 | | |
667 | 988 | end: |
668 | 988 | return ret; |
669 | 149 | } |
670 | | |
671 | 1.59k | std::optional<bool> blst::OpBLS_IsG1OnCurve(operation::BLS_IsG1OnCurve& op) { |
672 | 1.59k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
673 | | |
674 | 1.59k | bool useAffine = true; |
675 | | |
676 | 1.59k | try { |
677 | 1.59k | useAffine = ds.Get<bool>(); |
678 | 1.59k | } catch ( fuzzing::datasource::Base::OutOfData ) { } |
679 | | |
680 | 1.59k | if ( useAffine ) { |
681 | 1.06k | std::optional<blst_p1_affine> aff_g1; |
682 | 1.06k | CF_CHECK_NE(aff_g1 = blst_detail::Load_G1_Affine(op.g1), std::nullopt); |
683 | 1.01k | return |
684 | 1.01k | !blst_p1_affine_is_inf(&*aff_g1) && |
685 | 1.01k | blst_p1_affine_on_curve(&*aff_g1) && |
686 | 1.01k | blst_p1_affine_in_g1(&*aff_g1); |
687 | 1.06k | } else { |
688 | 531 | std::optional<blst_p1> g1; |
689 | 531 | CF_CHECK_NE(g1 = blst_detail::Load_G1_Projective(ds, op.g1), std::nullopt); |
690 | 502 | return |
691 | 502 | !blst_p1_is_inf(&*g1) && |
692 | 502 | blst_p1_on_curve(&*g1) && |
693 | 502 | blst_p1_in_g1(&*g1); |
694 | 531 | } |
695 | 76 | end: |
696 | 76 | return false; |
697 | 1.59k | } |
698 | | |
699 | 2.30k | std::optional<bool> blst::OpBLS_IsG2OnCurve(operation::BLS_IsG2OnCurve& op) { |
700 | 2.30k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
701 | | |
702 | 2.30k | bool useAffine = true; |
703 | | |
704 | 2.30k | try { |
705 | 2.30k | useAffine = ds.Get<bool>(); |
706 | 2.30k | } catch ( fuzzing::datasource::Base::OutOfData ) { } |
707 | | |
708 | 2.30k | blst_p2 g2; |
709 | 2.30k | blst_p2_affine g2_affine; |
710 | | |
711 | 2.30k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.first.first, g2_affine.x.fp[0])); |
712 | 2.27k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.first.second, g2_affine.y.fp[0])); |
713 | 2.25k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.second.first, g2_affine.x.fp[1])); |
714 | 2.21k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.second.second, g2_affine.y.fp[1])); |
715 | | |
716 | 2.19k | CF_CHECK_FALSE(blst_detail::IsZero(&g2_affine)); |
717 | | |
718 | 2.06k | if ( useAffine ) { |
719 | 1.48k | return blst_p2_affine_on_curve(&g2_affine) && blst_p2_affine_in_g2(&g2_affine); |
720 | 1.48k | } else { |
721 | 586 | CF_NORET(blst_p2_from_affine(&g2, &g2_affine)); |
722 | 586 | return blst_p2_on_curve(&g2) && blst_p2_in_g2(&g2); |
723 | 586 | } |
724 | | |
725 | 235 | end: |
726 | 235 | return false; |
727 | 2.06k | } |
728 | | |
729 | 198 | std::optional<component::BLS_KeyPair> blst::OpBLS_GenerateKeyPair(operation::BLS_GenerateKeyPair& op) { |
730 | 198 | std::optional<component::BLS_KeyPair> ret = std::nullopt; |
731 | 198 | if ( op.ikm.GetSize() < 32 ) { |
732 | 100 | return std::nullopt; |
733 | 100 | } |
734 | | |
735 | 98 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
736 | | |
737 | 98 | blst_scalar priv; |
738 | 98 | blst_p1 pub; |
739 | 98 | blst_p1_affine pub_affine; |
740 | | |
741 | 98 | CF_NORET(blst_keygen(&priv, op.ikm.GetPtr(&ds), op.ikm.GetSize(), op.info.GetPtr(&ds), op.info.GetSize())); |
742 | 98 | CF_ASSERT(blst_sk_check(&priv) == true, "blst_keygen generated invalid private key"); |
743 | | |
744 | 98 | CF_NORET(blst_sk_to_pk_in_g1(&pub, &priv)); |
745 | 98 | CF_NORET(blst_p1_to_affine(&pub_affine, &pub)); |
746 | | |
747 | 98 | { |
748 | 98 | std::array<uint8_t, 32> priv_bytes; |
749 | 98 | CF_NORET(blst_uint64_from_scalar((uint64_t*)priv_bytes.data(), &priv)); |
750 | | |
751 | 98 | blst_detail::Reverse<>(priv_bytes); |
752 | 98 | blst_detail::G1 g1(pub_affine, ds); |
753 | | |
754 | 98 | { |
755 | 98 | const auto priv = util::BinToDec(priv_bytes.data(), 32); |
756 | 98 | const auto pub = g1.To_Component_G1(); |
757 | | |
758 | 98 | CF_ASSERT(blst_p1_affine_on_curve(&pub_affine) == true, "Generated public key not on curve"); |
759 | 98 | CF_ASSERT(blst_p1_affine_in_g1(&pub_affine), "Generated public key not in group"); |
760 | | |
761 | 98 | ret = {priv, pub}; |
762 | 98 | } |
763 | 98 | } |
764 | | |
765 | 0 | return ret; |
766 | 98 | } |
767 | | |
768 | 244 | std::optional<component::G1> blst::OpBLS_Aggregate_G1(operation::BLS_Aggregate_G1& op) { |
769 | 244 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
770 | 244 | std::optional<component::G1> ret = std::nullopt; |
771 | | |
772 | 244 | blst_p1 res; |
773 | 244 | blst_p1_affine res_affine; |
774 | | |
775 | 244 | bool first = true; |
776 | 2.02k | for (const auto& sig : op.points.points) { |
777 | 2.02k | uint8_t serialized[96]; |
778 | 2.02k | blst_p1_affine a; |
779 | 2.02k | blst_p1 a_; |
780 | | |
781 | 2.02k | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.first, a.x)); |
782 | 2.00k | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.second, a.y)); |
783 | | |
784 | 1.97k | CF_NORET(blst_p1_from_affine(&a_, &a)); |
785 | | |
786 | 1.97k | CF_NORET(blst_p1_serialize(serialized, &a_)); |
787 | | |
788 | 1.97k | CF_CHECK_EQ( |
789 | 1.97k | blst_aggregate_in_g1( |
790 | 1.97k | &res, |
791 | 1.97k | first == true ? nullptr : &res, |
792 | 1.97k | serialized), BLST_SUCCESS); |
793 | | |
794 | 1.95k | first = false; |
795 | 1.95k | } |
796 | | |
797 | 168 | if ( first == false ) { |
798 | 70 | CF_NORET(blst_p1_to_affine(&res_affine, &res)); |
799 | 70 | CF_ASSERT(blst_p1_affine_on_curve(&res_affine) && blst_p1_affine_in_g1(&res_affine), "Aggregate created invalid point"); |
800 | 70 | blst_detail::G1 _g1(res_affine, ds); |
801 | 70 | ret = _g1.To_Component_G1(); |
802 | 70 | } |
803 | | |
804 | 244 | end: |
805 | 244 | return ret; |
806 | 168 | } |
807 | | |
808 | 283 | std::optional<component::G2> blst::OpBLS_Aggregate_G2(operation::BLS_Aggregate_G2& op) { |
809 | 283 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
810 | 283 | std::optional<component::G2> ret = std::nullopt; |
811 | | |
812 | 283 | blst_p2 res; |
813 | 283 | blst_p2_affine res_affine; |
814 | | |
815 | 283 | bool first = true; |
816 | 2.27k | for (const auto& sig : op.points.points) { |
817 | 2.27k | uint8_t serialized[192]; |
818 | 2.27k | blst_p2_affine a; |
819 | 2.27k | blst_p2 a_; |
820 | | |
821 | 2.27k | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.first.first, a.x.fp[0])); |
822 | 2.25k | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.first.second, a.y.fp[0])); |
823 | 2.22k | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.second.first, a.x.fp[1])); |
824 | 2.20k | CF_CHECK_TRUE(blst_detail::To_blst_fp(sig.second.second, a.y.fp[1])); |
825 | | |
826 | 2.17k | CF_NORET(blst_p2_from_affine(&a_, &a)); |
827 | | |
828 | 2.17k | CF_NORET(blst_p2_serialize(serialized, &a_)); |
829 | | |
830 | 2.17k | CF_CHECK_EQ( |
831 | 2.17k | blst_aggregate_in_g2( |
832 | 2.17k | &res, |
833 | 2.17k | first == true ? nullptr : &res, |
834 | 2.17k | serialized), BLST_SUCCESS); |
835 | | |
836 | 2.14k | first = false; |
837 | 2.14k | } |
838 | | |
839 | 154 | if ( first == false ) { |
840 | 75 | CF_NORET(blst_p2_to_affine(&res_affine, &res)); |
841 | 75 | CF_ASSERT(blst_p2_affine_on_curve(&res_affine) && blst_p2_affine_in_g2(&res_affine), "Aggregate created invalid point"); |
842 | 75 | ret = blst_detail::To_G2(res_affine); |
843 | 75 | } |
844 | | |
845 | 283 | end: |
846 | 283 | return ret; |
847 | 154 | } |
848 | | |
849 | 273 | std::optional<component::Fp12> blst::OpBLS_Pairing(operation::BLS_Pairing& op) { |
850 | 273 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
851 | 273 | std::optional<component::Fp12> ret = std::nullopt; |
852 | | |
853 | 273 | blst_p1_affine g1_affine; |
854 | 273 | blst_p2_affine g2_affine; |
855 | 273 | blst_fp12 out; |
856 | | |
857 | 273 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g1.first, g1_affine.x)); |
858 | 252 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g1.second, g1_affine.y)); |
859 | | |
860 | 231 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.first.first, g2_affine.x.fp[0])); |
861 | 210 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.first.second, g2_affine.y.fp[0])); |
862 | 190 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.second.first, g2_affine.x.fp[1])); |
863 | 166 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.second.second, g2_affine.y.fp[1])); |
864 | | |
865 | 140 | CF_NORET(blst_miller_loop(&out, &g2_affine, &g1_affine)); |
866 | 140 | CF_NORET(blst_final_exp(&out, &out)); |
867 | | |
868 | 140 | ret = blst_detail::To_component_Fp12(out); |
869 | | |
870 | 273 | end: |
871 | 273 | return ret; |
872 | 140 | } |
873 | | |
874 | 0 | std::optional<component::Fp12> blst::OpBLS_MillerLoop(operation::BLS_MillerLoop& op) { |
875 | 0 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
876 | 0 | std::optional<component::Fp12> ret = std::nullopt; |
877 | |
|
878 | 0 | blst_p1_affine g1_affine; |
879 | 0 | blst_p2_affine g2_affine; |
880 | 0 | blst_fp12 out; |
881 | |
|
882 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g1.first, g1_affine.x)); |
883 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g1.second, g1_affine.y)); |
884 | |
|
885 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.first.first, g2_affine.x.fp[0])); |
886 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.first.second, g2_affine.y.fp[0])); |
887 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.second.first, g2_affine.x.fp[1])); |
888 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.g2.second.second, g2_affine.y.fp[1])); |
889 | |
|
890 | 0 | CF_NORET(blst_miller_loop(&out, &g2_affine, &g1_affine)); |
891 | |
|
892 | 0 | ret = blst_detail::To_component_Fp12(out); |
893 | |
|
894 | 0 | end: |
895 | 0 | return ret; |
896 | 0 | } |
897 | | |
898 | 281 | std::optional<component::Fp12> blst::OpBLS_FinalExp(operation::BLS_FinalExp& op) { |
899 | 281 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
900 | 281 | std::optional<component::Fp12> ret = std::nullopt; |
901 | | |
902 | 281 | blst_fp12 out; |
903 | | |
904 | 281 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.fp12, out)); |
905 | | |
906 | 253 | CF_NORET(blst_final_exp(&out, &out)); |
907 | | |
908 | 253 | ret = blst_detail::To_component_Fp12(out); |
909 | | |
910 | 281 | end: |
911 | 281 | return ret; |
912 | 253 | } |
913 | | |
914 | | namespace blst_detail { |
915 | | template <class T> |
916 | 1.65k | bool UseParamTwice(fuzzing::datasource::Datasource& ds, const T* A, const T* B) { |
917 | 1.65k | if ( memcmp(A, B, sizeof(T)) != 0 ) { |
918 | 1.06k | return false; |
919 | 1.06k | } |
920 | | |
921 | 586 | try { |
922 | 586 | return ds.Get<bool>(); |
923 | 586 | } catch ( fuzzing::datasource::Base::OutOfData ) { |
924 | 311 | } |
925 | | |
926 | 311 | return false; |
927 | 586 | } bool cryptofuzz::module::blst_detail::UseParamTwice<blst_fr>(fuzzing::datasource::Datasource&, blst_fr const*, blst_fr const*) Line | Count | Source | 916 | 573 | bool UseParamTwice(fuzzing::datasource::Datasource& ds, const T* A, const T* B) { | 917 | 573 | if ( memcmp(A, B, sizeof(T)) != 0 ) { | 918 | 385 | return false; | 919 | 385 | } | 920 | | | 921 | 188 | try { | 922 | 188 | return ds.Get<bool>(); | 923 | 188 | } catch ( fuzzing::datasource::Base::OutOfData ) { | 924 | 103 | } | 925 | | | 926 | 103 | return false; | 927 | 188 | } |
bool cryptofuzz::module::blst_detail::UseParamTwice<blst_fp>(fuzzing::datasource::Datasource&, blst_fp const*, blst_fp const*) Line | Count | Source | 916 | 576 | bool UseParamTwice(fuzzing::datasource::Datasource& ds, const T* A, const T* B) { | 917 | 576 | if ( memcmp(A, B, sizeof(T)) != 0 ) { | 918 | 435 | return false; | 919 | 435 | } | 920 | | | 921 | 141 | try { | 922 | 141 | return ds.Get<bool>(); | 923 | 141 | } catch ( fuzzing::datasource::Base::OutOfData ) { | 924 | 61 | } | 925 | | | 926 | 61 | return false; | 927 | 141 | } |
bool cryptofuzz::module::blst_detail::UseParamTwice<blst_fp2>(fuzzing::datasource::Datasource&, blst_fp2 const*, blst_fp2 const*) Line | Count | Source | 916 | 336 | bool UseParamTwice(fuzzing::datasource::Datasource& ds, const T* A, const T* B) { | 917 | 336 | if ( memcmp(A, B, sizeof(T)) != 0 ) { | 918 | 162 | return false; | 919 | 162 | } | 920 | | | 921 | 174 | try { | 922 | 174 | return ds.Get<bool>(); | 923 | 174 | } catch ( fuzzing::datasource::Base::OutOfData ) { | 924 | 100 | } | 925 | | | 926 | 100 | return false; | 927 | 174 | } |
bool cryptofuzz::module::blst_detail::UseParamTwice<blst_fp12>(fuzzing::datasource::Datasource&, blst_fp12 const*, blst_fp12 const*) Line | Count | Source | 916 | 168 | bool UseParamTwice(fuzzing::datasource::Datasource& ds, const T* A, const T* B) { | 917 | 168 | if ( memcmp(A, B, sizeof(T)) != 0 ) { | 918 | 85 | return false; | 919 | 85 | } | 920 | | | 921 | 83 | try { | 922 | 83 | return ds.Get<bool>(); | 923 | 83 | } catch ( fuzzing::datasource::Base::OutOfData ) { | 924 | 47 | } | 925 | | | 926 | 47 | return false; | 927 | 83 | } |
|
928 | | |
929 | 4.24k | uint8_t GetMod3(fuzzing::datasource::Datasource& ds) { |
930 | 4.24k | try { |
931 | 4.24k | return ds.Get<uint8_t>() % 3; |
932 | 4.24k | } catch ( fuzzing::datasource::Base::OutOfData ) { |
933 | 1.89k | } |
934 | | |
935 | 1.89k | return 0; |
936 | 4.24k | } |
937 | | |
938 | 3.13k | #define PREPARE_RESULT() {resultIdx = GetMod3(ds);} |
939 | 1.76k | #define RESULT_PTR() (resultIdx == 0 ? &result : (resultIdx == 1 ? &A : &B)) |
940 | 3.00k | #define RESULT() (resultIdx == 0 ? result : (resultIdx == 1 ? A : B)) |
941 | 586 | #define PARAM_B() (UseParamTwice(ds, &A, &B) ? &A : &B) |
942 | | |
943 | 6.27k | std::optional<component::Bignum> OpBignumCalc_order(operation::BignumCalc& op) { |
944 | 6.27k | std::optional<component::Bignum> ret = std::nullopt; |
945 | 6.27k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
946 | 6.27k | blst_fr result, A, B; |
947 | 6.27k | uint8_t resultIdx; |
948 | 6.27k | static const blst_fr zero = {0}; |
949 | | |
950 | 6.27k | switch ( op.calcOp.Get() ) { |
951 | 149 | case CF_CALCOP("Add(A,B)"): |
952 | 149 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
953 | 128 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn1, B)); |
954 | 108 | PREPARE_RESULT(); |
955 | 108 | blst_fr_add(RESULT_PTR(), &A, PARAM_B()); |
956 | 108 | ret = blst_detail::To_component_bignum(RESULT()); |
957 | 108 | break; |
958 | 186 | case CF_CALCOP("Sub(A,B)"): |
959 | 186 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
960 | 166 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn1, B)); |
961 | 146 | PREPARE_RESULT(); |
962 | 146 | blst_fr_sub(RESULT_PTR(), &A, PARAM_B()); |
963 | 146 | ret = blst_detail::To_component_bignum(RESULT()); |
964 | 146 | break; |
965 | 502 | case CF_CALCOP("Mul(A,B)"): |
966 | 502 | { |
967 | 502 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
968 | | |
969 | 482 | size_t shiftCount; |
970 | 482 | uint8_t which = 0; |
971 | 482 | try { |
972 | 482 | which = ds.Get<uint8_t>() % 3; |
973 | 482 | } catch ( fuzzing::datasource::Base::OutOfData ) { |
974 | 68 | } |
975 | 482 | if ( which == 1 ) { |
976 | 142 | if ( op.bn1.ToTrimmedString() != "3" ) { |
977 | 84 | which = 0; |
978 | 84 | } |
979 | 340 | } else if ( which == 2 ) { |
980 | 251 | shiftCount = blst_detail::isMultipleOf2(op.bn1.ToTrimmedString()); |
981 | 251 | if ( shiftCount == 0 ) { |
982 | 195 | which = 0; |
983 | 195 | } |
984 | 251 | } |
985 | | |
986 | 482 | switch ( which ) { |
987 | 368 | case 0: |
988 | 368 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn1, B)); |
989 | 319 | PREPARE_RESULT(); |
990 | 319 | CF_NORET(blst_fr_mul(RESULT_PTR(), &A, PARAM_B())); |
991 | 319 | break; |
992 | 58 | case 1: |
993 | 58 | PREPARE_RESULT(); |
994 | 58 | CF_NORET(blst_fr_mul_by_3(RESULT_PTR(), &A)); |
995 | 58 | break; |
996 | 56 | case 2: |
997 | 56 | PREPARE_RESULT(); |
998 | 56 | blst_fr_lshift(RESULT_PTR(), &A, shiftCount); |
999 | 56 | ret = blst_detail::To_component_bignum(RESULT()); |
1000 | 56 | break; |
1001 | 482 | } |
1002 | | |
1003 | 433 | ret = blst_detail::To_component_bignum(RESULT()); |
1004 | 433 | } |
1005 | 0 | break; |
1006 | 106 | case CF_CALCOP("Sqr(A)"): |
1007 | 106 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
1008 | 77 | PREPARE_RESULT(); |
1009 | 77 | blst_fr_sqr(RESULT_PTR(), &A); |
1010 | 77 | ret = blst_detail::To_component_bignum(RESULT()); |
1011 | 77 | break; |
1012 | 454 | case CF_CALCOP("InvMod(A,B)"): |
1013 | 454 | { |
1014 | 454 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
1015 | | |
1016 | 433 | bool which = false; |
1017 | 433 | try { |
1018 | 433 | which = ds.Get<bool>(); |
1019 | 433 | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1020 | 202 | } |
1021 | | |
1022 | 433 | if ( which ) { |
1023 | 134 | PREPARE_RESULT(); |
1024 | 134 | CF_NORET(blst_fr_eucl_inverse(RESULT_PTR(), &A)); |
1025 | 299 | } else { |
1026 | 299 | PREPARE_RESULT(); |
1027 | 299 | CF_NORET(blst_fr_inverse(RESULT_PTR(), &A)); |
1028 | 299 | } |
1029 | | |
1030 | 433 | ret = blst_detail::To_component_bignum(RESULT()); |
1031 | 433 | } |
1032 | 0 | break; |
1033 | 221 | case CF_CALCOP("LShift1(A)"): |
1034 | 221 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
1035 | 201 | PREPARE_RESULT(); |
1036 | 201 | blst_fr_lshift(RESULT_PTR(), &A, 1); |
1037 | 201 | ret = blst_detail::To_component_bignum(RESULT()); |
1038 | 201 | break; |
1039 | 571 | case CF_CALCOP("RShift(A,B)"): |
1040 | 571 | { |
1041 | 571 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
1042 | 551 | const auto B_cpp_int = blst_detail::To_cpp_int(op.bn1); |
1043 | 551 | size_t count = static_cast<size_t>(B_cpp_int); |
1044 | 551 | CF_CHECK_EQ(count, B_cpp_int); |
1045 | 519 | CF_CHECK_GT(count, 0); |
1046 | 497 | CF_CHECK_LT(count, 1024000); |
1047 | | |
1048 | 336 | PREPARE_RESULT(); |
1049 | 336 | blst_fr_rshift(RESULT_PTR(), &A, count); |
1050 | | |
1051 | 336 | { |
1052 | 336 | CF_CHECK_EQ(count, 1); |
1053 | 288 | const auto A_cpp_int = blst_detail::To_cpp_int(op.bn0); |
1054 | 288 | CF_CHECK_LT(A_cpp_int, boost::multiprecision::cpp_int("52435875175126190479447740508185965837690552500527637822603658699938581184513")); |
1055 | 215 | CF_CHECK_EQ(A_cpp_int % 2, 1); |
1056 | 97 | ret = blst_detail::To_component_bignum(RESULT()); |
1057 | 97 | } |
1058 | 97 | } |
1059 | 0 | break; |
1060 | 97 | case CF_CALCOP("Not(A)"): |
1061 | 97 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
1062 | 76 | PREPARE_RESULT(); |
1063 | 76 | blst_fr_cneg(RESULT_PTR(), &A, true); |
1064 | 76 | ret = blst_detail::To_component_bignum(RESULT()); |
1065 | 76 | break; |
1066 | 42 | case CF_CALCOP("Set(A)"): |
1067 | 42 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
1068 | 22 | ret = blst_detail::To_component_bignum(A); |
1069 | 22 | break; |
1070 | 102 | case CF_CALCOP("IsEq(A,B)"): |
1071 | 102 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
1072 | 81 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn1, B)); |
1073 | 59 | ret = memcmp(&A, &B, sizeof(A)) == 0 ? std::string("1") : std::string("0"); |
1074 | 59 | break; |
1075 | 69 | case CF_CALCOP("IsZero(A)"): |
1076 | 69 | CF_CHECK_TRUE(blst_detail::To_blst_fr(op.bn0, A)); |
1077 | 49 | ret = memcmp(&A, &zero, sizeof(A)) == 0 ? std::string("1") : std::string("0"); |
1078 | 49 | break; |
1079 | 6.27k | } |
1080 | | |
1081 | 6.27k | end: |
1082 | 6.27k | return ret; |
1083 | 6.27k | } |
1084 | | |
1085 | 5.81k | std::optional<component::Bignum> OpBignumCalc_prime(operation::BignumCalc& op) { |
1086 | 5.81k | std::optional<component::Bignum> ret = std::nullopt; |
1087 | 5.81k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1088 | 5.81k | blst_fp result, A, B; |
1089 | 5.81k | uint8_t resultIdx; |
1090 | 5.81k | static const blst_fp zero = {0}; |
1091 | | |
1092 | 5.81k | switch ( op.calcOp.Get() ) { |
1093 | 228 | case CF_CALCOP("Add(A,B)"): |
1094 | 228 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1095 | 208 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn1, B)); |
1096 | 187 | PREPARE_RESULT(); |
1097 | 187 | blst_fp_add(RESULT_PTR(), &A, PARAM_B()); |
1098 | 187 | ret = blst_detail::To_component_bignum(RESULT()); |
1099 | 187 | break; |
1100 | 185 | case CF_CALCOP("Sub(A,B)"): |
1101 | 185 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1102 | 165 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn1, B)); |
1103 | 145 | PREPARE_RESULT(); |
1104 | 145 | blst_fp_sub(RESULT_PTR(), &A, PARAM_B()); |
1105 | 145 | ret = blst_detail::To_component_bignum(RESULT()); |
1106 | 145 | break; |
1107 | 437 | case CF_CALCOP("Mul(A,B)"): |
1108 | 437 | { |
1109 | 437 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1110 | | |
1111 | 415 | size_t shiftCount; |
1112 | 415 | uint8_t which = 0; |
1113 | 415 | try { |
1114 | 415 | which = ds.Get<uint8_t>() % 4; |
1115 | 415 | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1116 | 48 | } |
1117 | | |
1118 | 415 | if ( which == 1 ) { |
1119 | 93 | if ( op.bn1.ToTrimmedString() != "3" ) { |
1120 | 60 | which = 0; |
1121 | 60 | } |
1122 | 322 | } else if ( which == 2 ) { |
1123 | 96 | if ( op.bn1.ToTrimmedString() != "8" ) { |
1124 | 39 | which = 0; |
1125 | 39 | } |
1126 | 226 | } else if ( which == 3 ) { |
1127 | 159 | shiftCount = blst_detail::isMultipleOf2(op.bn1.ToTrimmedString()); |
1128 | 159 | if ( shiftCount == 0 ) { |
1129 | 104 | which = 0; |
1130 | 104 | } |
1131 | 159 | } |
1132 | | |
1133 | 415 | switch ( which ) { |
1134 | 270 | case 0: |
1135 | 270 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn1, B)); |
1136 | 244 | PREPARE_RESULT(); |
1137 | 244 | CF_NORET(blst_fp_mul(RESULT_PTR(), &A, PARAM_B())); |
1138 | 244 | break; |
1139 | 33 | case 1: |
1140 | 33 | PREPARE_RESULT(); |
1141 | 33 | CF_NORET(blst_fp_mul_by_3(RESULT_PTR(), &A)); |
1142 | 33 | break; |
1143 | 57 | case 2: |
1144 | 57 | PREPARE_RESULT(); |
1145 | 57 | CF_NORET(blst_fp_mul_by_8(RESULT_PTR(), &A)); |
1146 | 57 | break; |
1147 | 55 | case 3: |
1148 | 55 | size_t shiftCount; |
1149 | 55 | CF_CHECK_NE(shiftCount = blst_detail::isMultipleOf2(op.bn1.ToTrimmedString()), 0); |
1150 | | |
1151 | 55 | PREPARE_RESULT(); |
1152 | 55 | blst_fp_lshift(RESULT_PTR(), &A, shiftCount); |
1153 | 55 | ret = blst_detail::To_component_bignum(RESULT()); |
1154 | 55 | break; |
1155 | 415 | } |
1156 | | |
1157 | 389 | ret = blst_detail::To_component_bignum(RESULT()); |
1158 | 389 | } |
1159 | 0 | break; |
1160 | 162 | case CF_CALCOP("LShift1(A)"): |
1161 | 162 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1162 | 142 | PREPARE_RESULT(); |
1163 | 142 | blst_fp_lshift(RESULT_PTR(), &A, 1); |
1164 | 142 | ret = blst_detail::To_component_bignum(RESULT()); |
1165 | 142 | break; |
1166 | 209 | case CF_CALCOP("Sqr(A)"): |
1167 | 209 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1168 | 169 | PREPARE_RESULT(); |
1169 | 169 | blst_fp_sqr(RESULT_PTR(), &A); |
1170 | 169 | ret = blst_detail::To_component_bignum(RESULT()); |
1171 | 169 | break; |
1172 | 248 | case CF_CALCOP("InvMod(A,B)"): |
1173 | 248 | { |
1174 | 248 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1175 | | |
1176 | 228 | bool which = false; |
1177 | 228 | try { |
1178 | 228 | which = ds.Get<bool>(); |
1179 | 228 | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1180 | 77 | } |
1181 | | |
1182 | 228 | if ( which ) { |
1183 | 92 | PREPARE_RESULT(); |
1184 | 92 | CF_NORET(blst_fp_eucl_inverse(RESULT_PTR(), &A)); |
1185 | 136 | } else { |
1186 | 136 | PREPARE_RESULT(); |
1187 | 136 | CF_NORET(blst_fp_inverse(RESULT_PTR(), &A)); |
1188 | 136 | } |
1189 | | |
1190 | 228 | ret = blst_detail::To_component_bignum(RESULT()); |
1191 | 228 | } |
1192 | 0 | break; |
1193 | 398 | case CF_CALCOP("Sqrt(A)"): |
1194 | 398 | { |
1195 | 398 | blst_fp result2; |
1196 | 398 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1197 | | |
1198 | 378 | if ( blst_fp_sqrt(&result, &A) == true ) { |
1199 | 201 | CF_NORET(blst_fp_sqr(&result, &result)); |
1200 | 201 | ret = blst_detail::To_component_bignum(result); |
1201 | 201 | } else { |
1202 | 177 | CF_NORET(blst_fp_cneg(&A, &A, 1)); |
1203 | 177 | CF_ASSERT(blst_fp_sqrt(&A, &A) == true, "Square root must exist"); |
1204 | | |
1205 | 177 | ret = std::string("0"); |
1206 | 177 | } |
1207 | 378 | } |
1208 | 378 | break; |
1209 | 378 | case CF_CALCOP("IsSquare(A)"): |
1210 | 58 | { |
1211 | 58 | blst_fp tmp; |
1212 | | |
1213 | 58 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1214 | 41 | const bool is_square = blst_fp_is_square(&A); |
1215 | | |
1216 | 41 | if ( !is_square ) { |
1217 | 21 | CF_NORET(blst_fp_cneg(&tmp, &A, 1)); |
1218 | 21 | CF_ASSERT(blst_fp_is_square(&tmp) == true, "Must be square"); |
1219 | 21 | } else { |
1220 | 20 | CF_ASSERT(blst_fp_sqrt(&tmp, &A) == true, "Square root must exist"); |
1221 | 20 | } |
1222 | | |
1223 | 41 | CF_ASSERT( |
1224 | 41 | is_square == |
1225 | 41 | blst_fp_sqrt(&result, &A), ""); |
1226 | 41 | ret = is_square ? std::string("1") : std::string("0"); |
1227 | 41 | } |
1228 | 0 | break; |
1229 | 80 | case CF_CALCOP("Not(A)"): |
1230 | 80 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1231 | 64 | PREPARE_RESULT(); |
1232 | 64 | blst_fp_cneg(RESULT_PTR(), &A, true); |
1233 | 64 | ret = blst_detail::To_component_bignum(RESULT()); |
1234 | 64 | break; |
1235 | 43 | case CF_CALCOP("Set(A)"): |
1236 | 43 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1237 | 23 | ret = blst_detail::To_component_bignum(A); |
1238 | 23 | break; |
1239 | 110 | case CF_CALCOP("IsEq(A,B)"): |
1240 | 110 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1241 | 86 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn1, B)); |
1242 | 61 | ret = memcmp(&A, &B, sizeof(A)) == 0 ? std::string("1") : std::string("0"); |
1243 | 61 | break; |
1244 | 64 | case CF_CALCOP("IsZero(A)"): |
1245 | 64 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.bn0, A)); |
1246 | 44 | ret = memcmp(&A, &zero, sizeof(A)) == 0 ? std::string("1") : std::string("0"); |
1247 | 44 | break; |
1248 | 5.81k | } |
1249 | | |
1250 | 5.81k | end: |
1251 | 5.81k | return ret; |
1252 | 5.81k | } |
1253 | | |
1254 | | #undef PREPARE_RESULT |
1255 | | #undef RESULT_PTR |
1256 | | #undef RESULT |
1257 | | #undef PARAM_B |
1258 | | } |
1259 | | |
1260 | 22.9k | std::optional<component::Bignum> blst::OpBignumCalc(operation::BignumCalc& op) { |
1261 | 22.9k | if ( op.modulo == std::nullopt ) { |
1262 | 10.8k | return std::nullopt; |
1263 | 10.8k | } |
1264 | | |
1265 | | /* TODO optimize this */ |
1266 | 12.0k | if ( op.modulo->ToTrimmedString() == "52435875175126190479447740508185965837690552500527637822603658699938581184513" ) { |
1267 | 6.27k | return blst_detail::OpBignumCalc_order(op); |
1268 | 6.27k | } else if ( op.modulo->ToTrimmedString() == "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787" ) { |
1269 | 5.81k | return blst_detail::OpBignumCalc_prime(op); |
1270 | 5.81k | } else { |
1271 | 0 | return std::nullopt; |
1272 | 0 | } |
1273 | 12.0k | } |
1274 | | |
1275 | | namespace blst_detail { |
1276 | 701 | #define PREPARE_RESULT() {resultIdx = GetMod3(ds);} |
1277 | 453 | #define RESULT_PTR() (resultIdx == 0 ? &result : (resultIdx == 1 ? &A : &B)) |
1278 | 701 | #define RESULT() (resultIdx == 0 ? result : (resultIdx == 1 ? A : B)) |
1279 | 232 | #define PARAM_B() (UseParamTwice(ds, &A, &B) ? &A : &B) |
1280 | | |
1281 | 2.84k | std::optional<component::Fp2> OpBignumCalc_Fp2_prime(operation::BignumCalc_Fp2& op) { |
1282 | 2.84k | std::optional<component::Fp2> ret = std::nullopt; |
1283 | 2.84k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1284 | 2.84k | blst_fp2 result, A, B; |
1285 | 2.84k | uint8_t resultIdx; |
1286 | | |
1287 | 2.84k | switch ( op.calcOp.Get() ) { |
1288 | 202 | case CF_CALCOP("Add(A,B)"): |
1289 | 202 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1290 | 162 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn1, B)); |
1291 | 122 | PREPARE_RESULT(); |
1292 | 122 | blst_fp2_add(RESULT_PTR(), &A, PARAM_B()); |
1293 | 122 | ret = blst_detail::To_component_Fp2(RESULT()); |
1294 | 122 | break; |
1295 | 194 | case CF_CALCOP("Sub(A,B)"): |
1296 | 194 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1297 | 150 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn1, B)); |
1298 | 110 | PREPARE_RESULT(); |
1299 | 110 | blst_fp2_sub(RESULT_PTR(), &A, PARAM_B()); |
1300 | 110 | ret = blst_detail::To_component_Fp2(RESULT()); |
1301 | 110 | break; |
1302 | 185 | case CF_CALCOP("Mul(A,B)"): |
1303 | 185 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1304 | 144 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn1, B)); |
1305 | 104 | PREPARE_RESULT(); |
1306 | 104 | CF_NORET(blst_fp2_mul(RESULT_PTR(), &A, PARAM_B())); |
1307 | | |
1308 | 104 | ret = blst_detail::To_component_Fp2(RESULT()); |
1309 | 104 | break; |
1310 | 113 | case CF_CALCOP("LShift1(A)"): |
1311 | 113 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1312 | 77 | PREPARE_RESULT(); |
1313 | 77 | blst_fp2_lshift(RESULT_PTR(), &A, 1); |
1314 | 77 | ret = blst_detail::To_component_Fp2(RESULT()); |
1315 | 77 | break; |
1316 | 106 | case CF_CALCOP("Sqr(A)"): |
1317 | 106 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1318 | 65 | PREPARE_RESULT(); |
1319 | 65 | blst_fp2_sqr(RESULT_PTR(), &A); |
1320 | 65 | ret = blst_detail::To_component_Fp2(RESULT()); |
1321 | 65 | break; |
1322 | 181 | case CF_CALCOP("InvMod(A,B)"): |
1323 | 181 | { |
1324 | 181 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1325 | | |
1326 | 144 | bool which = false; |
1327 | 144 | try { |
1328 | 144 | which = ds.Get<bool>(); |
1329 | 144 | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1330 | 38 | } |
1331 | | |
1332 | 144 | if ( which ) { |
1333 | 55 | PREPARE_RESULT(); |
1334 | 55 | CF_NORET(blst_fp2_eucl_inverse(RESULT_PTR(), &A)); |
1335 | 89 | } else { |
1336 | 89 | PREPARE_RESULT(); |
1337 | 89 | CF_NORET(blst_fp2_inverse(RESULT_PTR(), &A)); |
1338 | 89 | } |
1339 | | |
1340 | 144 | ret = blst_detail::To_component_Fp2(RESULT()); |
1341 | 144 | } |
1342 | 0 | break; |
1343 | 248 | case CF_CALCOP("Sqrt(A)"): |
1344 | 248 | { |
1345 | 248 | blst_fp result2; |
1346 | 248 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1347 | | |
1348 | 206 | if ( blst_fp2_sqrt(&result, &A) == true ) { |
1349 | 154 | CF_NORET(blst_fp2_sqr(&result, &result)); |
1350 | 154 | ret = blst_detail::To_component_Fp2(result); |
1351 | 154 | } else { |
1352 | 52 | ret = { std::string("0"), std::string("0") }; |
1353 | 52 | } |
1354 | 206 | } |
1355 | 0 | break; |
1356 | 60 | case CF_CALCOP("IsSquare(A)"): |
1357 | 60 | { |
1358 | 60 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1359 | 20 | const bool is_square = blst_fp2_is_square(&A); |
1360 | 20 | CF_ASSERT( |
1361 | 20 | is_square == |
1362 | 20 | blst_fp2_sqrt(&result, &A), ""); |
1363 | 20 | } |
1364 | 0 | break; |
1365 | 120 | case CF_CALCOP("Not(A)"): |
1366 | 120 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1367 | 79 | PREPARE_RESULT(); |
1368 | 79 | blst_fp2_cneg(RESULT_PTR(), &A, true); |
1369 | 79 | ret = blst_detail::To_component_Fp2(RESULT()); |
1370 | 79 | break; |
1371 | 63 | case CF_CALCOP("Set(A)"): |
1372 | 63 | CF_CHECK_TRUE(blst_detail::To_blst_fp2(op.bn0, A)); |
1373 | 20 | ret = blst_detail::To_component_Fp2(A); |
1374 | 20 | break; |
1375 | 2.84k | } |
1376 | | |
1377 | 2.84k | end: |
1378 | 2.84k | return ret; |
1379 | 2.84k | } |
1380 | | |
1381 | | #undef PREPARE_RESULT |
1382 | | #undef RESULT_PTR |
1383 | | #undef RESULT |
1384 | | #undef PARAM_B |
1385 | | } |
1386 | | |
1387 | 2.84k | std::optional<component::Fp2> blst::OpBignumCalc_Fp2(operation::BignumCalc_Fp2& op) { |
1388 | 2.84k | return blst_detail::OpBignumCalc_Fp2_prime(op); |
1389 | 2.84k | } |
1390 | | |
1391 | | namespace blst_detail { |
1392 | 411 | #define PREPARE_RESULT() {resultIdx = GetMod3(ds);} |
1393 | | #define RESULT_PTR() (resultIdx == 0 ? &result : (resultIdx == 1 ? &A : &B)) |
1394 | 411 | #define RESULT() (resultIdx == 0 ? result : (resultIdx == 1 ? A : B)) |
1395 | | #define PARAM_B() (UseParamTwice(ds, &A, &B) ? &A : &B) |
1396 | | |
1397 | 1.63k | std::optional<component::Fp12> OpBignumCalc_Fp12_prime(operation::BignumCalc_Fp12& op) { |
1398 | 1.63k | std::optional<component::Fp12> ret = std::nullopt; |
1399 | 1.63k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1400 | 1.63k | blst_fp12 result, A, B; |
1401 | 1.63k | uint8_t resultIdx; |
1402 | | |
1403 | 1.63k | switch ( op.calcOp.Get() ) { |
1404 | 300 | case CF_CALCOP("Mul(A,B)"): |
1405 | 300 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn0, A)); |
1406 | 244 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn1, B)); |
1407 | 168 | PREPARE_RESULT(); |
1408 | 168 | CF_NORET(blst_fp12_mul(RESULT_PTR(), &A, PARAM_B())); |
1409 | | |
1410 | 168 | ret = blst_detail::To_component_Fp12(RESULT()); |
1411 | 168 | break; |
1412 | 74 | case CF_CALCOP("Conjugate(A)"): |
1413 | 74 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn0, A)); |
1414 | 43 | CF_NORET(blst_fp12_conjugate(&A)); |
1415 | 43 | ret = blst_detail::To_component_Fp12(A); |
1416 | 43 | break; |
1417 | 153 | case CF_CALCOP("Sqr(A)"): |
1418 | 153 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn0, A)); |
1419 | 132 | PREPARE_RESULT(); |
1420 | 132 | CF_NORET(blst_fp12_sqr(RESULT_PTR(), &A)); |
1421 | 132 | ret = blst_detail::To_component_Fp12(RESULT()); |
1422 | 132 | break; |
1423 | 68 | case CF_CALCOP("CyclotomicSqr(A)"): |
1424 | 68 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn0, A)); |
1425 | 38 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn1, B)); |
1426 | 20 | CF_NORET(blst_fp12_cyclotomic_sqr(&A, &B)); |
1427 | 20 | ret = blst_detail::To_component_Fp12(A); |
1428 | 20 | break; |
1429 | 156 | case CF_CALCOP("InvMod(A,B)"): |
1430 | 156 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn0, A)); |
1431 | | |
1432 | 111 | PREPARE_RESULT(); |
1433 | 111 | CF_NORET(blst_fp12_inverse(RESULT_PTR(), &A)); |
1434 | | |
1435 | 111 | ret = blst_detail::To_component_Fp12(RESULT()); |
1436 | 111 | break; |
1437 | 20 | case CF_CALCOP("One()"): |
1438 | 20 | ret = blst_detail::To_component_Fp12(*(blst_fp12_one())); |
1439 | 20 | break; |
1440 | 63 | case CF_CALCOP("IsOne(A)"): |
1441 | 63 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn0, A)); |
1442 | 43 | if ( blst_fp12_is_one(&A) ) { |
1443 | 16 | ret = blst_detail::To_component_Fp12(*(blst_fp12_one())); |
1444 | 27 | } else { |
1445 | 27 | memset(&result, 0, sizeof(result)); |
1446 | 27 | ret = blst_detail::To_component_Fp12(result); |
1447 | 27 | } |
1448 | 43 | break; |
1449 | 75 | case CF_CALCOP("IsEq(A,B)"): |
1450 | 75 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn0, A)); |
1451 | 54 | CF_CHECK_TRUE(blst_detail::To_blst_fp12(op.bn1, B)); |
1452 | | |
1453 | 41 | if ( blst_fp12_is_equal(&A, &B) ) { |
1454 | 21 | ret = blst_detail::To_component_Fp12(*(blst_fp12_one())); |
1455 | 21 | } else { |
1456 | 20 | memset(&result, 0, sizeof(result)); |
1457 | 20 | ret = blst_detail::To_component_Fp12(result); |
1458 | 20 | } |
1459 | 41 | break; |
1460 | 1.63k | } |
1461 | | |
1462 | 1.63k | end: |
1463 | 1.63k | return ret; |
1464 | 1.63k | } |
1465 | | |
1466 | | #undef PREPARE_RESULT |
1467 | | #undef RESULT_PTR |
1468 | | #undef RESULT |
1469 | | #undef PARAM_B |
1470 | | } |
1471 | | |
1472 | 1.63k | std::optional<component::Fp12> blst::OpBignumCalc_Fp12(operation::BignumCalc_Fp12& op) { |
1473 | 1.63k | return blst_detail::OpBignumCalc_Fp12_prime(op); |
1474 | 1.63k | } |
1475 | | |
1476 | 362 | std::optional<component::G1> blst::OpBLS_Decompress_G1(operation::BLS_Decompress_G1& op) { |
1477 | 362 | std::optional<component::G1> ret = std::nullopt; |
1478 | 362 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1479 | | |
1480 | 362 | blst_p1_affine point; |
1481 | 362 | std::optional<std::array<uint8_t, 48>> compressed = std::nullopt; |
1482 | | |
1483 | 362 | CF_CHECK_NE(compressed = blst_detail::ToArray<48>(op.compressed, false), std::nullopt); |
1484 | | |
1485 | 335 | if ( blst_p1_uncompress(&point, compressed->data()) == BLST_SUCCESS ) { |
1486 | 58 | blst_detail::G1 g1(point, ds); |
1487 | 58 | ret = g1.To_Component_G1(); |
1488 | 277 | } else { |
1489 | 277 | ret = component::G1{"0", "0"}; |
1490 | 277 | } |
1491 | | |
1492 | 362 | end: |
1493 | 362 | return ret; |
1494 | 335 | } |
1495 | | |
1496 | 197 | std::optional<component::Bignum> blst::OpBLS_Compress_G1(operation::BLS_Compress_G1& op) { |
1497 | 197 | std::optional<component::Bignum> ret = std::nullopt; |
1498 | | |
1499 | 197 | std::array<uint8_t, 48> out; |
1500 | 197 | blst_p1_affine point; |
1501 | | |
1502 | 197 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.uncompressed.first, point.x)); |
1503 | 176 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.uncompressed.second, point.y)); |
1504 | | //CF_CHECK_FALSE(blst_detail::IsZero(&point)); |
1505 | | |
1506 | 156 | CF_CHECK_TRUE(blst_p1_affine_on_curve(&point)); |
1507 | | |
1508 | 109 | CF_NORET(blst_p1_affine_compress(out.data(), &point)); |
1509 | 109 | ret = util::BinToDec(out.data(), 48); |
1510 | | |
1511 | 197 | end: |
1512 | 197 | return ret; |
1513 | 109 | } |
1514 | | |
1515 | 268 | std::optional<component::G2> blst::OpBLS_Decompress_G2(operation::BLS_Decompress_G2& op) { |
1516 | 268 | std::optional<component::G2> ret = std::nullopt; |
1517 | 268 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1518 | | |
1519 | 268 | blst_p2_affine point; |
1520 | 268 | std::optional<std::array<uint8_t, 48>> compressed_x = std::nullopt; |
1521 | 268 | std::optional<std::array<uint8_t, 48>> compressed_y = std::nullopt; |
1522 | 268 | std::array<uint8_t, 96> compressed; |
1523 | | |
1524 | 268 | CF_CHECK_NE(compressed_x = blst_detail::ToArray<48>(op.compressed.first, false), std::nullopt); |
1525 | 246 | CF_CHECK_NE(compressed_y = blst_detail::ToArray<48>(op.compressed.second, false), std::nullopt); |
1526 | | |
1527 | 225 | memcpy(compressed.data(), compressed_x->data(), 48); |
1528 | 225 | memcpy(compressed.data() + 48, compressed_y->data(), 48); |
1529 | | |
1530 | 225 | if ( blst_p2_uncompress(&point, compressed.data()) == BLST_SUCCESS ) { |
1531 | 58 | ret = blst_detail::To_G2(point); |
1532 | 167 | } else { |
1533 | 167 | ret = component::G2{"0", "0", "0", "0"}; |
1534 | 167 | } |
1535 | | |
1536 | 268 | end: |
1537 | 268 | return ret; |
1538 | 225 | } |
1539 | | |
1540 | 251 | std::optional<component::G1> blst::OpBLS_Compress_G2(operation::BLS_Compress_G2& op) { |
1541 | 251 | std::optional<component::G1> ret = std::nullopt; |
1542 | | |
1543 | 251 | std::array<uint8_t, 96> out; |
1544 | 251 | blst_p2_affine point; |
1545 | | |
1546 | 251 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.uncompressed.first.first, point.x.fp[0])); |
1547 | 231 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.uncompressed.first.second, point.y.fp[0])); |
1548 | 211 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.uncompressed.second.first, point.x.fp[1])); |
1549 | 190 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.uncompressed.second.second, point.y.fp[1])); |
1550 | | |
1551 | 170 | CF_CHECK_TRUE(blst_p2_affine_on_curve(&point)); |
1552 | | |
1553 | 142 | CF_NORET(blst_p2_affine_compress(out.data(), &point)); |
1554 | 142 | ret = { util::BinToDec(out.data(), 48), util::BinToDec(out.data() + 48, 48) }; |
1555 | | |
1556 | 251 | end: |
1557 | 251 | return ret; |
1558 | 142 | } |
1559 | | |
1560 | 2.95k | std::optional<component::G1> blst::OpBLS_G1_Add(operation::BLS_G1_Add& op) { |
1561 | 2.95k | std::optional<component::G1> ret = std::nullopt; |
1562 | 2.95k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1563 | | |
1564 | 2.95k | std::optional<blst_p1_affine> aff_tmp; |
1565 | 2.95k | blst_p1_affine aff_a, aff_b, aff_result; |
1566 | | |
1567 | 2.95k | std::optional<blst_p1> tmp; |
1568 | 2.95k | blst_p1 a, b, result; |
1569 | | |
1570 | 2.95k | bool eq; |
1571 | 2.95k | uint8_t mode = 0; |
1572 | 2.95k | bool doAffine = true; |
1573 | | |
1574 | 2.95k | CF_CHECK_NE(aff_tmp = blst_detail::Load_G1_Affine(op.a), std::nullopt); |
1575 | 2.89k | aff_a = *aff_tmp; |
1576 | | |
1577 | 2.89k | CF_CHECK_NE(aff_tmp = blst_detail::Load_G1_Affine(op.b), std::nullopt); |
1578 | 2.84k | aff_b = *aff_tmp; |
1579 | | |
1580 | 2.84k | CF_CHECK_NE(tmp = blst_detail::Load_G1_Projective(ds, op.a), std::nullopt); |
1581 | 2.84k | a = *tmp; |
1582 | | |
1583 | 2.84k | CF_CHECK_NE(tmp = blst_detail::Load_G1_Projective(ds, op.b), std::nullopt); |
1584 | 2.84k | b = *tmp; |
1585 | | |
1586 | 2.84k | eq = blst_p1_is_equal(&a, &b); |
1587 | | |
1588 | 2.84k | try { |
1589 | 2.84k | mode = ds.Get<uint8_t>() % 3; |
1590 | 2.84k | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1591 | 1.34k | } |
1592 | | |
1593 | | /* Modes: |
1594 | | * |
1595 | | * 0 = pure add |
1596 | | * 1 = pure double |
1597 | | * 2 = mixed add and double |
1598 | | */ |
1599 | | |
1600 | 2.84k | if ( mode == 0 && eq ) { |
1601 | 58 | mode = 1; |
1602 | 2.78k | } else if ( mode == 1 && !eq ) { |
1603 | 562 | mode = 0; |
1604 | 562 | } |
1605 | | |
1606 | 2.84k | try { |
1607 | 2.84k | doAffine = ds.Get<bool>(); |
1608 | 2.84k | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1609 | 1.53k | } |
1610 | | |
1611 | 2.84k | switch ( mode ) { |
1612 | 2.31k | case 0: |
1613 | 2.31k | if ( doAffine == true ) { |
1614 | 1.89k | bool doMulti = false; |
1615 | 1.89k | try { |
1616 | 1.89k | doMulti = ds.Get<bool>(); |
1617 | 1.89k | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1618 | 1.45k | } |
1619 | | |
1620 | 1.89k | if ( doMulti == false ) { |
1621 | 1.62k | CF_NORET(blst_p1_add_affine(&result, &a, &aff_b)); |
1622 | 1.62k | } else { |
1623 | 276 | const blst_p1_affine *const points[2] = {&aff_a, &aff_b}; |
1624 | 276 | CF_NORET(blst_p1s_add(&result, points, 2)); |
1625 | 276 | } |
1626 | 1.89k | } else { |
1627 | 421 | CF_NORET(blst_p1_add(&result, &a, &b)); |
1628 | 421 | } |
1629 | 2.31k | break; |
1630 | 2.31k | case 1: |
1631 | 87 | CF_NORET(blst_p1_double(&result, &a)); |
1632 | 87 | break; |
1633 | 440 | case 2: |
1634 | 440 | if ( doAffine == true ) { |
1635 | 256 | CF_NORET(blst_p1_add_or_double_affine(&result, &a, &aff_b)); |
1636 | 256 | } else { |
1637 | 184 | CF_NORET(blst_p1_add_or_double(&result, &a, &b)); |
1638 | 184 | } |
1639 | 440 | break; |
1640 | 0 | default: |
1641 | 0 | CF_UNREACHABLE(); |
1642 | 2.84k | } |
1643 | | |
1644 | 2.84k | CF_CHECK_TRUE( |
1645 | 2.84k | !blst_p1_affine_is_inf(&aff_a) && |
1646 | 2.84k | blst_p1_affine_on_curve(&aff_a) && |
1647 | 2.84k | blst_p1_affine_in_g1(&aff_a)); |
1648 | 189 | CF_CHECK_TRUE( |
1649 | 189 | !blst_p1_affine_is_inf(&aff_b) && |
1650 | 189 | blst_p1_affine_on_curve(&aff_b) && |
1651 | 189 | blst_p1_affine_in_g1(&aff_b)); |
1652 | | |
1653 | 61 | CF_NORET(blst_p1_to_affine(&aff_result, &result)); |
1654 | | |
1655 | 61 | { |
1656 | 61 | blst_detail::G1 g1(aff_result, ds); |
1657 | 61 | ret = g1.To_Component_G1(); |
1658 | 61 | } |
1659 | | |
1660 | 2.95k | end: |
1661 | 2.95k | return ret; |
1662 | 61 | } |
1663 | | |
1664 | 1.97k | std::optional<component::G1> blst::OpBLS_G1_Mul(operation::BLS_G1_Mul& op) { |
1665 | 1.97k | std::optional<component::G1> ret = std::nullopt; |
1666 | 1.97k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1667 | | |
1668 | 1.97k | blst_p1_affine aff_result; |
1669 | 1.97k | std::optional<blst_p1> tmp; |
1670 | 1.97k | blst_p1 a, result; |
1671 | 1.97k | std::optional<std::vector<uint8_t>> b; |
1672 | | |
1673 | 1.97k | CF_CHECK_NE(tmp = blst_detail::Load_G1_Projective(ds, op.a), std::nullopt); |
1674 | 1.94k | a = *tmp; |
1675 | | |
1676 | 1.94k | CF_CHECK_NE(b = util::DecToBin(op.b.ToTrimmedString()), std::nullopt); |
1677 | | |
1678 | 1.94k | { |
1679 | 1.94k | std::vector<uint8_t> b_reversed = util::AddLeadingZeroes(ds, *b); |
1680 | 1.94k | CF_NORET(std::reverse(b_reversed.begin(), b_reversed.end())); |
1681 | | |
1682 | 1.94k | Buffer B(b_reversed); |
1683 | | |
1684 | 1.94k | CF_NORET(blst_p1_mult(&result, &a, B.GetPtr(&ds), B.GetSize() * 8)); |
1685 | 1.94k | } |
1686 | | |
1687 | 1.94k | CF_NORET(blst_p1_to_affine(&aff_result, &result)); |
1688 | | |
1689 | 1.94k | CF_CHECK_TRUE( |
1690 | 1.94k | !blst_p1_is_inf(&a) && |
1691 | 1.94k | blst_p1_on_curve(&a) && |
1692 | 1.94k | blst_p1_in_g1(&a)); |
1693 | | |
1694 | 171 | { |
1695 | 171 | blst_detail::G1 g1(aff_result, ds); |
1696 | 171 | ret = g1.To_Component_G1(); |
1697 | 171 | } |
1698 | | |
1699 | 1.97k | end: |
1700 | 1.97k | return ret; |
1701 | 171 | } |
1702 | | |
1703 | 274 | std::optional<bool> blst::OpBLS_G1_IsEq(operation::BLS_G1_IsEq& op) { |
1704 | 274 | std::optional<bool> ret = std::nullopt; |
1705 | 274 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1706 | | |
1707 | 274 | std::optional<blst_p1_affine> aff_tmp; |
1708 | 274 | blst_p1_affine aff_a, aff_b; |
1709 | | |
1710 | 274 | std::optional<blst_p1> tmp; |
1711 | 274 | blst_p1 a, b; |
1712 | | |
1713 | 274 | bool doAffine = false; |
1714 | | |
1715 | 274 | CF_CHECK_NE(aff_tmp = blst_detail::Load_G1_Affine(op.a), std::nullopt); |
1716 | 214 | aff_a = *aff_tmp; |
1717 | | |
1718 | 214 | CF_CHECK_NE(aff_tmp = blst_detail::Load_G1_Affine(op.b), std::nullopt); |
1719 | 172 | aff_b = *aff_tmp; |
1720 | | |
1721 | 172 | CF_CHECK_NE(tmp = blst_detail::Load_G1_Projective(ds, op.a), std::nullopt); |
1722 | 172 | a = *tmp; |
1723 | | |
1724 | 172 | CF_CHECK_NE(tmp = blst_detail::Load_G1_Projective(ds, op.b), std::nullopt); |
1725 | 172 | b = *tmp; |
1726 | | |
1727 | 172 | try { |
1728 | 172 | doAffine = ds.Get<bool>(); |
1729 | 172 | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1730 | 91 | } |
1731 | | |
1732 | 172 | if ( doAffine == true ) { |
1733 | 60 | ret = blst_p1_affine_is_equal(&aff_a, &aff_b); |
1734 | 112 | } else { |
1735 | 112 | ret = blst_p1_is_equal(&a, &b); |
1736 | 112 | } |
1737 | | |
1738 | 274 | end: |
1739 | 274 | return ret; |
1740 | 172 | } |
1741 | | |
1742 | 2.63k | std::optional<component::G1> blst::OpBLS_G1_Neg(operation::BLS_G1_Neg& op) { |
1743 | 2.63k | std::optional<component::G1> ret = std::nullopt; |
1744 | 2.63k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1745 | | |
1746 | 2.63k | blst_p1_affine aff_result; |
1747 | 2.63k | std::optional<blst_p1> tmp; |
1748 | 2.63k | blst_p1 a; |
1749 | | |
1750 | 2.63k | CF_CHECK_NE(tmp = blst_detail::Load_G1_Projective(ds, op.a), std::nullopt); |
1751 | 2.57k | a = *tmp; |
1752 | | |
1753 | 2.57k | CF_NORET(blst_p1_cneg(&a, true)); |
1754 | | |
1755 | 2.57k | CF_NORET(blst_p1_to_affine(&aff_result, &a)); |
1756 | | |
1757 | 2.57k | { |
1758 | 2.57k | blst_detail::G1 g1(aff_result, ds); |
1759 | 2.57k | ret = g1.To_Component_G1(); |
1760 | 2.57k | } |
1761 | | |
1762 | 2.63k | end: |
1763 | 2.63k | return ret; |
1764 | 2.57k | } |
1765 | | |
1766 | 2.82k | std::optional<component::G2> blst::OpBLS_G2_Add(operation::BLS_G2_Add& op) { |
1767 | 2.82k | std::optional<component::G2> ret = std::nullopt; |
1768 | 2.82k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1769 | | |
1770 | 2.82k | blst_p2_affine a, b, result_; |
1771 | 2.82k | blst_p2 a_, b_, result; |
1772 | 2.82k | bool doDouble = false; |
1773 | | |
1774 | 2.82k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.first.first, a.x.fp[0])); |
1775 | 2.79k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.first.second, a.y.fp[0])); |
1776 | 2.76k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.second.first, a.x.fp[1])); |
1777 | 2.74k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.second.second, a.y.fp[1])); |
1778 | | |
1779 | 2.72k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.b.first.first, b.x.fp[0])); |
1780 | 2.70k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.b.first.second, b.y.fp[0])); |
1781 | 2.68k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.b.second.first, b.x.fp[1])); |
1782 | 2.66k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.b.second.second, b.y.fp[1])); |
1783 | | |
1784 | 2.64k | CF_NORET(blst_p2_from_affine(&a_, &a)); |
1785 | 2.64k | CF_NORET(blst_p2_from_affine(&b_, &b)); |
1786 | | |
1787 | 2.64k | if ( blst_p2_is_equal(&a_, &b_) ) { |
1788 | 96 | try { |
1789 | 96 | doDouble = ds.Get<bool>(); |
1790 | 96 | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1791 | 46 | } |
1792 | 96 | } |
1793 | | |
1794 | 2.64k | if ( doDouble == false ) { |
1795 | 2.60k | CF_NORET(blst_p2_add_or_double_affine(&result, &a_, &b)); |
1796 | 2.60k | } else { |
1797 | 38 | CF_NORET(blst_p2_double(&result, &a_)); |
1798 | 38 | } |
1799 | | |
1800 | | |
1801 | 2.64k | CF_NORET(blst_p2_to_affine(&result_, &result)); |
1802 | | |
1803 | 2.64k | ret = blst_detail::To_G2(result_); |
1804 | | |
1805 | 2.82k | end: |
1806 | 2.82k | return ret; |
1807 | 2.64k | } |
1808 | | |
1809 | 4.35k | std::optional<component::G2> blst::OpBLS_G2_Mul(operation::BLS_G2_Mul& op) { |
1810 | 4.35k | std::optional<component::G2> ret = std::nullopt; |
1811 | 4.35k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1812 | | |
1813 | 4.35k | blst_p2_affine a, result_; |
1814 | 4.35k | blst_p2 a_, result; |
1815 | 4.35k | std::optional<std::vector<uint8_t>> b; |
1816 | 4.35k | bool doDouble = false; |
1817 | | |
1818 | 4.35k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.first.first, a.x.fp[0])); |
1819 | 4.32k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.first.second, a.y.fp[0])); |
1820 | 4.30k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.second.first, a.x.fp[1])); |
1821 | 4.27k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.second.second, a.y.fp[1])); |
1822 | 4.24k | CF_CHECK_NE(b = util::DecToBin(op.b.ToTrimmedString()), std::nullopt); |
1823 | | |
1824 | 4.24k | if ( !(blst_p2_affine_on_curve(&a) && blst_p2_affine_in_g2(&a)) ) { |
1825 | 3.73k | return ret; |
1826 | 3.73k | } |
1827 | | |
1828 | 505 | CF_NORET(blst_p2_from_affine(&a_, &a)); |
1829 | | |
1830 | 505 | if ( op.b.ToTrimmedString() == "2" ) { |
1831 | 60 | try { |
1832 | 60 | doDouble = ds.Get<bool>(); |
1833 | 60 | } catch ( fuzzing::datasource::Base::OutOfData ) { |
1834 | 27 | } |
1835 | 60 | } |
1836 | | |
1837 | 505 | if ( doDouble == false ) { |
1838 | 480 | std::vector<uint8_t> b_reversed = util::AddLeadingZeroes(ds, *b); |
1839 | 480 | CF_NORET(std::reverse(b_reversed.begin(), b_reversed.end())); |
1840 | | |
1841 | 480 | Buffer B(b_reversed); |
1842 | | |
1843 | 480 | CF_NORET(blst_p2_mult(&result, &a_, B.GetPtr(&ds), B.GetSize() * 8)); |
1844 | 480 | } else { |
1845 | 25 | CF_NORET(blst_p2_double(&result, &a_)); |
1846 | 25 | } |
1847 | | |
1848 | 505 | CF_NORET(blst_p2_to_affine(&result_, &result)); |
1849 | | |
1850 | 505 | ret = blst_detail::To_G2(result_); |
1851 | | |
1852 | 613 | end: |
1853 | 613 | return ret; |
1854 | 505 | } |
1855 | | |
1856 | 298 | std::optional<bool> blst::OpBLS_G2_IsEq(operation::BLS_G2_IsEq& op) { |
1857 | 298 | std::optional<bool> ret = std::nullopt; |
1858 | | |
1859 | 298 | blst_p2_affine a, b; |
1860 | 298 | blst_p2 a_, b_; |
1861 | | |
1862 | 298 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.first.first, a.x.fp[0])); |
1863 | 273 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.first.second, a.y.fp[0])); |
1864 | 252 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.second.first, a.x.fp[1])); |
1865 | 227 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.second.second, a.y.fp[1])); |
1866 | | |
1867 | 200 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.b.first.first, b.x.fp[0])); |
1868 | 171 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.b.first.second, b.y.fp[0])); |
1869 | 147 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.b.second.first, b.x.fp[1])); |
1870 | 127 | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.b.second.second, b.y.fp[1])); |
1871 | | |
1872 | 107 | CF_NORET(blst_p2_from_affine(&a_, &a)); |
1873 | 107 | CF_NORET(blst_p2_from_affine(&b_, &b)); |
1874 | | |
1875 | 107 | ret = blst_p2_is_equal(&a_, &b_); |
1876 | | |
1877 | 298 | end: |
1878 | 298 | return ret; |
1879 | 107 | } |
1880 | | |
1881 | 2.45k | std::optional<component::G2> blst::OpBLS_G2_Neg(operation::BLS_G2_Neg& op) { |
1882 | 2.45k | std::optional<component::G2> ret = std::nullopt; |
1883 | 2.45k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1884 | | |
1885 | 2.45k | blst_p2_affine a; |
1886 | 2.45k | blst_p2 a_; |
1887 | | |
1888 | 2.45k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.first.first, a.x.fp[0])); |
1889 | 2.43k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.first.second, a.y.fp[0])); |
1890 | 2.40k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.second.first, a.x.fp[1])); |
1891 | 2.38k | CF_CHECK_TRUE(blst_detail::To_blst_fp(op.a.second.second, a.y.fp[1])); |
1892 | | |
1893 | 2.36k | CF_NORET(blst_p2_from_affine(&a_, &a)); |
1894 | | |
1895 | 2.36k | CF_NORET(blst_p2_cneg(&a_, true)); |
1896 | | |
1897 | 2.36k | CF_NORET(blst_p2_to_affine(&a, &a_)); |
1898 | | |
1899 | 2.36k | ret = blst_detail::To_G2(a); |
1900 | | |
1901 | 2.45k | end: |
1902 | 2.45k | return ret; |
1903 | 2.36k | } |
1904 | | |
1905 | 0 | std::optional<component::G1> blst::OpBLS_G1_MultiExp(operation::BLS_G1_MultiExp& op) { |
1906 | 0 | std::optional<component::G1> ret = std::nullopt; |
1907 | 0 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1908 | |
|
1909 | 0 | const size_t num = op.points_scalars.points_scalars.size(); |
1910 | | /* blst_p1s_mult_pippenger crashes with num == 0 |
1911 | | * blst_p1s_mult_pippenger OOB read with num == 1 |
1912 | | */ |
1913 | 0 | if ( num < 2 ) return std::nullopt; |
1914 | | |
1915 | 0 | blst_p1_affine* points = (blst_p1_affine*)util::malloc(num * sizeof(blst_p1_affine)); |
1916 | 0 | const blst_p1_affine* points_ptrs[2] = {points, nullptr}; |
1917 | 0 | blst_scalar* scalars = (blst_scalar*)util::malloc(num * sizeof(blst_scalar)); |
1918 | 0 | const uint8_t* scalars_ptrs[2] = {(uint8_t*)scalars, nullptr}; |
1919 | |
|
1920 | 0 | uint8_t* scratch = util::malloc(blst_p1s_mult_pippenger_scratch_sizeof(num)); |
1921 | |
|
1922 | 0 | bool points_are_valid = true; |
1923 | |
|
1924 | 0 | for (size_t i = 0; i < num; i++) { |
1925 | 0 | const auto& cur = op.points_scalars.points_scalars[i]; |
1926 | |
|
1927 | 0 | std::optional<blst_p1_affine> point; |
1928 | 0 | CF_CHECK_NE(point = blst_detail::Load_G1_Affine(cur.first), std::nullopt); |
1929 | 0 | points[i] = *point; |
1930 | |
|
1931 | 0 | points_are_valid &= |
1932 | 0 | !blst_p1_affine_is_inf(&*point) && |
1933 | 0 | blst_p1_affine_on_curve(&*point) && |
1934 | 0 | blst_p1_affine_in_g1(&*point); |
1935 | |
|
1936 | 0 | CF_CHECK_TRUE(blst_detail::To_blst_scalar(cur.second, scalars[i])); |
1937 | 0 | } |
1938 | | |
1939 | 0 | { |
1940 | 0 | blst_p1 res; |
1941 | 0 | CF_NORET(blst_p1s_mult_pippenger( |
1942 | 0 | &res, |
1943 | 0 | points_ptrs, num, |
1944 | 0 | scalars_ptrs, sizeof(blst_scalar) * 8, |
1945 | 0 | (limb_t*)scratch)); |
1946 | |
|
1947 | 0 | CF_CHECK_TRUE(points_are_valid); |
1948 | |
|
1949 | 0 | blst_p1_affine res_affine; |
1950 | 0 | CF_NORET(blst_p1_to_affine(&res_affine, &res)); |
1951 | 0 | blst_detail::G1 g1(res_affine, ds); |
1952 | 0 | ret = g1.To_Component_G1(); |
1953 | 0 | } |
1954 | | |
1955 | 0 | end: |
1956 | 0 | util::free(points); |
1957 | 0 | util::free(scalars); |
1958 | 0 | util::free(scratch); |
1959 | |
|
1960 | 0 | return ret; |
1961 | 0 | } |
1962 | | |
1963 | 778 | std::optional<Buffer> blst::OpMisc(operation::Misc& op) { |
1964 | 778 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1965 | | |
1966 | 778 | try { |
1967 | 778 | switch ( op.operation.Get() ) { |
1968 | 83 | case 0: |
1969 | 83 | { |
1970 | 83 | const auto data = ds.GetData(0, 48, 48); |
1971 | 83 | blst_p1_affine point; |
1972 | 83 | CF_CHECK_EQ(blst_p1_uncompress(&point, data.data()), BLST_SUCCESS); |
1973 | 60 | uint8_t out[48]; |
1974 | 60 | CF_NORET(blst_p1_affine_compress(out, &point)); |
1975 | 60 | if ( blst_p1_affine_on_curve(&point) ) { |
1976 | 21 | CF_ASSERT(memcmp(data.data(), out, data.size()) == 0, "Serialization asymmetry"); |
1977 | 21 | } |
1978 | 60 | } |
1979 | 60 | break; |
1980 | 127 | case 1: |
1981 | 127 | { |
1982 | 127 | const auto data = ds.GetData(0, 96, 96); |
1983 | 127 | blst_p1_affine point; |
1984 | 127 | CF_CHECK_EQ(blst_p1_deserialize(&point, data.data()), BLST_SUCCESS); |
1985 | 49 | uint8_t out[96]; |
1986 | 49 | CF_NORET(blst_p1_affine_serialize(out, &point)); |
1987 | 49 | if ( blst_p1_affine_on_curve(&point) ) { |
1988 | 23 | blst_p1_affine point2; |
1989 | 23 | CF_ASSERT(blst_p1_deserialize(&point2, out) == BLST_SUCCESS, "Cannot deserialize serialized point"); |
1990 | | |
1991 | 23 | uint8_t out2[96]; |
1992 | 23 | CF_NORET(blst_p1_affine_serialize(out2, &point2)); |
1993 | 23 | CF_ASSERT(memcmp(out, out2, sizeof(out)) == 0, "Serialization asymmetry"); |
1994 | | //CF_ASSERT(memcmp(data.data(), out, data.size()) == 0, "Serialization asymmetry"); |
1995 | 23 | } |
1996 | 49 | } |
1997 | 49 | break; |
1998 | 96 | case 2: |
1999 | 96 | { |
2000 | 96 | const auto data = ds.GetData(0, 96, 96); |
2001 | 96 | blst_p2_affine point; |
2002 | 96 | CF_CHECK_EQ(blst_p2_uncompress(&point, data.data()), BLST_SUCCESS); |
2003 | 52 | uint8_t out[96]; |
2004 | 52 | CF_NORET(blst_p2_affine_compress(out, &point)); |
2005 | 52 | if ( blst_p2_affine_on_curve(&point) ) { |
2006 | 20 | CF_ASSERT(memcmp(data.data(), out, data.size()) == 0, "Serialization asymmetry"); |
2007 | 20 | } |
2008 | 52 | } |
2009 | 52 | break; |
2010 | 112 | case 3: |
2011 | 112 | { |
2012 | 112 | const auto data = ds.GetData(0, 192, 192); |
2013 | 112 | blst_p2_affine point; |
2014 | 112 | CF_CHECK_EQ(blst_p2_deserialize(&point, data.data()), BLST_SUCCESS); |
2015 | 52 | uint8_t out[192]; |
2016 | 52 | CF_NORET(blst_p2_affine_serialize(out, &point)); |
2017 | 52 | if ( blst_p2_affine_on_curve(&point) ) { |
2018 | 21 | blst_p2_affine point2; |
2019 | 21 | CF_ASSERT(blst_p2_deserialize(&point2, out) == BLST_SUCCESS, "Cannot deserialize serialized point"); |
2020 | | |
2021 | 21 | uint8_t out2[192]; |
2022 | 21 | CF_NORET(blst_p2_affine_serialize(out2, &point2)); |
2023 | 21 | CF_ASSERT(memcmp(out, out2, sizeof(out)) == 0, "Serialization asymmetry"); |
2024 | | //CF_ASSERT(memcmp(data.data(), out, data.size()) == 0, "Serialization asymmetry"); |
2025 | 21 | } |
2026 | 52 | } |
2027 | 52 | break; |
2028 | 82 | case 4: |
2029 | 82 | { |
2030 | 82 | blst_p1_affine point; |
2031 | 82 | { |
2032 | 82 | const auto data = ds.GetData(0, 96, 96); |
2033 | 82 | CF_CHECK_EQ(blst_p1_deserialize(&point, data.data()), BLST_SUCCESS); |
2034 | 62 | } |
2035 | | |
2036 | 0 | blst_fp6 Qlines[68]; |
2037 | 62 | { |
2038 | 62 | const auto data = ds.GetData(0, sizeof(Qlines), sizeof(Qlines)); |
2039 | 62 | memcpy(Qlines, data.data(), sizeof(Qlines)); |
2040 | 62 | } |
2041 | | |
2042 | 62 | blst_fp12 out; |
2043 | 62 | CF_NORET(blst_miller_loop_lines(&out, Qlines, &point)); |
2044 | 62 | } |
2045 | 0 | break; |
2046 | 130 | case 5: |
2047 | 130 | { |
2048 | 130 | blst_p2_affine point; |
2049 | 130 | { |
2050 | 130 | const auto data = ds.GetData(0, 192, 192); |
2051 | 130 | CF_CHECK_EQ(blst_p2_deserialize(&point, data.data()), BLST_SUCCESS); |
2052 | 61 | } |
2053 | | |
2054 | 0 | blst_fp6 Qlines[68]; |
2055 | 61 | CF_NORET(blst_precompute_lines(Qlines, &point)); |
2056 | 61 | } |
2057 | 0 | break; |
2058 | 117 | case 6: |
2059 | 117 | { |
2060 | 117 | blst_fp12 out; |
2061 | 117 | blst_p1_affine p1; |
2062 | 117 | blst_p2_affine p2; |
2063 | | |
2064 | 117 | { |
2065 | 117 | const auto data = ds.GetData(0, 96, 96); |
2066 | 117 | CF_CHECK_EQ(blst_p1_deserialize(&p1, data.data()), BLST_SUCCESS); |
2067 | 86 | } |
2068 | | |
2069 | 0 | { |
2070 | 86 | const auto data = ds.GetData(0, 192, 192); |
2071 | 86 | CF_CHECK_EQ(blst_p2_deserialize(&p2, data.data()), BLST_SUCCESS); |
2072 | 66 | } |
2073 | | |
2074 | 66 | CF_NORET(blst_miller_loop(&out, &p2, &p1)); |
2075 | 66 | } |
2076 | 0 | break; |
2077 | 778 | } |
2078 | 778 | } catch ( fuzzing::datasource::Base::OutOfData ) { } |
2079 | | |
2080 | 778 | end: |
2081 | 778 | return std::nullopt; |
2082 | 778 | } |
2083 | | |
2084 | 12.1k | bool blst::SupportsModularBignumCalc(void) const { |
2085 | 12.1k | return true; |
2086 | 12.1k | } |
2087 | | |
2088 | | } /* namespace module */ |
2089 | | } /* namespace cryptofuzz */ |