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