Coverage Report

Created: 2023-12-08 07:00

/src/cryptofuzz/modules/mcl/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
6
#if !defined(CRYPTOFUZZ_MCL_USE_BN128)
7
 #include <mcl/bls12_381.hpp>
8
#else
9
 #include <mcl/bn256.hpp>
10
#endif
11
12
#define MCL_DONT_USE_OPENSSL
13
#include <cybozu/sha2.hpp>
14
15
#if !defined(CRYPTOFUZZ_MCL_USE_BN128)
16
58.9k
 #define Namespace ::mcl::bls12
17
#else
18
 #define Namespace ::mcl::bn
19
#endif
20
21
#include <iostream>
22
#include <vector>
23
#include <string>
24
#include <sstream>
25
26
namespace cryptofuzz {
27
namespace module {
28
29
mcl::mcl(void) :
30
4
    Module("mcl") {
31
4
#if !defined(CRYPTOFUZZ_MCL_USE_BN128)
32
4
        ::mcl::bn::initPairing(::mcl::BLS12_381);
33
4
        ::mcl::bn::setMapToMode(MCL_MAP_TO_MODE_HASH_TO_CURVE_07);
34
#else
35
        ::mcl::bn::initPairing(::mcl::BN_SNARK1);
36
#endif
37
4
        CF_NORET(::mcl::bn::verifyOrderG1(1));
38
4
        CF_NORET(::mcl::bn::verifyOrderG2(1));
39
4
}
40
41
namespace mcl_detail {
42
43
5.61k
std::vector<std::string> split(const std::string& s, std::optional<size_t> expectedNumParts = std::nullopt) {
44
5.61k
    std::vector<std::string> parts;
45
5.61k
    std::stringstream ss(s);
46
5.61k
    std::string tok;
47
48
28.5k
    while (getline(ss, tok, ' ') ) {
49
22.9k
        parts.push_back(tok);
50
22.9k
    }
51
52
5.61k
    if ( expectedNumParts != std::nullopt && parts.size() != *expectedNumParts ) {
53
32
        parts = std::vector<std::string>(*expectedNumParts, std::string("0"));
54
32
    }
55
56
5.61k
    return parts;
57
5.61k
}
58
59
/* "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_" */
60
    static const std::vector<uint8_t> DST{
61
        0x42, 0x4c, 0x53, 0x5f, 0x53, 0x49, 0x47, 0x5f, 0x42, 0x4c, 0x53, 0x31,
62
        0x32, 0x33, 0x38, 0x31, 0x47, 0x31, 0x5f, 0x58, 0x4d, 0x44, 0x3a, 0x53,
63
        0x48, 0x41, 0x2d, 0x32, 0x35, 0x36, 0x5f, 0x53, 0x53, 0x57, 0x55, 0x5f,
64
        0x52, 0x4f, 0x5f, 0x50, 0x4f, 0x50, 0x5f};
65
66
    template <class T>
67
748
    Buffer MsgAug(const T& op) {
68
748
        std::vector<uint8_t> msg;
69
748
        const auto aug = op.aug.Get();
70
748
        const auto ct = op.cleartext.Get();
71
748
        msg.insert(msg.end(), aug.begin(), aug.end());
72
748
        msg.insert(msg.end(), ct.begin(), ct.end());
73
748
        return Buffer(msg);
74
748
    }
cryptofuzz::Buffer cryptofuzz::module::mcl_detail::MsgAug<cryptofuzz::operation::BLS_Sign>(cryptofuzz::operation::BLS_Sign const&)
Line
Count
Source
67
429
    Buffer MsgAug(const T& op) {
68
429
        std::vector<uint8_t> msg;
69
429
        const auto aug = op.aug.Get();
70
429
        const auto ct = op.cleartext.Get();
71
429
        msg.insert(msg.end(), aug.begin(), aug.end());
72
429
        msg.insert(msg.end(), ct.begin(), ct.end());
73
429
        return Buffer(msg);
74
429
    }
cryptofuzz::Buffer cryptofuzz::module::mcl_detail::MsgAug<cryptofuzz::operation::BLS_HashToG1>(cryptofuzz::operation::BLS_HashToG1 const&)
Line
Count
Source
67
132
    Buffer MsgAug(const T& op) {
68
132
        std::vector<uint8_t> msg;
69
132
        const auto aug = op.aug.Get();
70
132
        const auto ct = op.cleartext.Get();
71
132
        msg.insert(msg.end(), aug.begin(), aug.end());
72
132
        msg.insert(msg.end(), ct.begin(), ct.end());
73
132
        return Buffer(msg);
74
132
    }
cryptofuzz::Buffer cryptofuzz::module::mcl_detail::MsgAug<cryptofuzz::operation::BLS_HashToG2>(cryptofuzz::operation::BLS_HashToG2 const&)
Line
Count
Source
67
187
    Buffer MsgAug(const T& op) {
68
187
        std::vector<uint8_t> msg;
69
187
        const auto aug = op.aug.Get();
70
187
        const auto ct = op.cleartext.Get();
71
187
        msg.insert(msg.end(), aug.begin(), aug.end());
72
187
        msg.insert(msg.end(), ct.begin(), ct.end());
73
187
        return Buffer(msg);
74
187
    }
75
76
841
    Namespace::G1 Convert(const component::G1& g1) {
77
841
        using namespace Namespace;
78
841
        return G1(
79
841
                Fp(g1.first.ToTrimmedString(), 10),
80
841
                Fp(g1.second.ToTrimmedString(), 10));
81
841
    }
82
144
    Namespace::G2 Convert(const component::G2& g2) {
83
144
        using namespace Namespace;
84
144
        return G2(
85
144
                {Fp(g2.first.first.ToTrimmedString(), 10), Fp(g2.second.first.ToTrimmedString(), 10)},
86
144
                {Fp(g2.first.second.ToTrimmedString(), 10), Fp(g2.second.second.ToTrimmedString(), 10)});
87
144
    }
88
3.59k
    component::G1 ToComponentG1(Namespace::G1 g1) {
89
        /* Necessary? */
90
3.59k
        g1.normalize();
91
3.59k
        const auto parts = mcl_detail::split(g1.getStr(10), 3);
92
3.59k
        return { parts[1], parts[2] };
93
3.59k
    }
94
95
1.17k
    component::G2 ToComponentG2(Namespace::G2 g2) {
96
        /* Necessary? */
97
1.17k
        g2.normalize();
98
1.17k
        const auto parts = mcl_detail::split(g2.getStr(10), 5);
99
1.17k
        return { parts[1], parts[3], parts[2], parts[4] };
100
1.17k
    }
101
102
377
    component::Fp2 ToComponentFp2(Namespace::Fp2 fp2) {
103
377
        const auto parts = mcl_detail::split(fp2.getStr(10), 2);
104
377
        return { parts[0], parts[1] };
105
377
    }
106
107
472
    component::Fp12 ToComponentFp12(Namespace::Fp12 fp12) {
108
472
        const auto parts = mcl_detail::split(fp12.getStr(10), 12);
109
472
        return {
110
472
            parts[0],
111
472
            parts[1],
112
472
            parts[2],
113
472
            parts[3],
114
472
            parts[4],
115
472
            parts[5],
116
472
            parts[6],
117
472
            parts[7],
118
472
            parts[8],
119
472
            parts[9],
120
472
            parts[10],
121
472
            parts[11],
122
472
        };
123
472
    }
124
125
3.16k
    Namespace::G1 Generator(void) {
126
3.16k
#if !defined(CRYPTOFUZZ_MCL_USE_BN128)
127
3.16k
        return Namespace::G1(
128
3.16k
                Namespace::Fp("3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507", 10),
129
3.16k
                Namespace::Fp("1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569", 10) );
130
#else
131
        return Namespace::G1(
132
                Namespace::Fp("1", 10),
133
                Namespace::Fp("2", 10) );
134
#endif
135
3.16k
    }
136
137
424
    Namespace::G2 Generator_G2(void) {
138
424
#if !defined(CRYPTOFUZZ_MCL_USE_BN128)
139
424
        return Namespace::G2(
140
424
                {Namespace::Fp("352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160", 10),
141
424
                Namespace::Fp("3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758", 10)},
142
424
                {Namespace::Fp("1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905", 10),
143
424
                Namespace::Fp("927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582", 10)} );
144
#else
145
        return Namespace::G2(
146
                {Namespace::Fp("10857046999023057135944570762232829481370756359578518086990519993285655852781", 10),
147
                Namespace::Fp("11559732032986387107991004021392285783925812861821192530917403151452391805634", 10)},
148
                {Namespace::Fp("8495653923123431417604973247489272438418190587263600148770280649306958101930", 10),
149
                Namespace::Fp("4082367875863433681332203403145435568316851327593401208105741076214120093531", 10)} );
150
#endif
151
424
    }
152
153
    void Hash(Namespace::G1& P, const std::string& m)
154
0
    {
155
0
        Namespace::Fp t;
156
0
        t.setHashOf(m);
157
0
        Namespace::mapToG1(P, t);
158
0
    }
159
160
    void Hash(Namespace::G2& P, const std::string& m)
161
0
    {
162
0
        Namespace::Fp t;
163
0
        t.setHashOf(m);
164
0
        Namespace::mapToG2(P, Namespace::Fp2(t, 0));
165
0
    }
166
167
    void Sign(Namespace::G2& sign, const Namespace::Fr& s, const std::string& m)
168
0
    {
169
0
        Namespace::G2 Hm;
170
0
        Hash(Hm, m);
171
0
        Namespace::G2::mul(sign, Hm, s); // sign = s H(m)
172
0
    }
173
174
}
175
176
0
std::optional<component::Digest> mcl::OpDigest(operation::Digest& op) {
177
0
    std::optional<component::Digest> ret = std::nullopt;
178
0
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
179
180
0
    util::Multipart parts = util::ToParts(ds, op.cleartext);
181
182
0
    switch ( op.digestType.Get() ) {
183
0
        case    CF_DIGEST("SHA256"):
184
0
            {
185
0
                cybozu::Sha256 hasher;
186
0
                for (const auto& part : parts) {
187
0
                    CF_NORET(hasher.update(part.first, part.second));
188
0
                }
189
0
                uint8_t out[256 / 8];
190
0
                CF_ASSERT(hasher.digest(out, sizeof(out), nullptr, 0) == sizeof(out), "Unexpected digest() output");
191
0
                ret = {out, sizeof(out)};
192
0
            }
193
0
            break;
194
0
        case    CF_DIGEST("SHA512"):
195
0
            {
196
0
                cybozu::Sha512 hasher;
197
0
                for (const auto& part : parts) {
198
0
                    CF_NORET(hasher.update(part.first, part.second));
199
0
                }
200
0
                uint8_t out[512 / 8];
201
0
                CF_ASSERT(hasher.digest(out, sizeof(out), nullptr, 0) == sizeof(out), "Unexpected digest() output");
202
0
                ret = {out, sizeof(out)};
203
0
            }
204
0
            break;
205
0
    }
206
207
0
    return ret;
208
0
}
209
210
2.87k
std::optional<component::BLS_PublicKey> mcl::OpBLS_PrivateToPublic(operation::BLS_PrivateToPublic& op) {
211
2.87k
    std::optional<component::BLS_PublicKey> ret = std::nullopt;
212
213
2.87k
    if ( op.priv.ToTrimmedString() == "0" ) {
214
28
        return std::nullopt;
215
28
    }
216
217
2.84k
    try {
218
2.84k
        using namespace Namespace;
219
220
2.84k
        Fr sec;
221
2.84k
        sec.setStr(op.priv.ToTrimmedString(), 10);
222
223
2.84k
        G1 pub;
224
2.84k
        G1::mul(pub, mcl_detail::Generator(), sec);
225
226
2.84k
        ret = mcl_detail::ToComponentG1(pub);
227
2.84k
    } catch ( cybozu::Exception ) {
228
117
        if ( !op.priv.IsGreaterThan("52435875175126190479447740508185965837690552500527637822603658699938581184512") ) {
229
0
            CF_ASSERT(0, "Failed to sign");
230
0
        }
231
117
    }
232
233
2.84k
    return ret;
234
2.84k
}
235
236
492
std::optional<component::G2> mcl::OpBLS_PrivateToPublic_G2(operation::BLS_PrivateToPublic_G2& op) {
237
492
    std::optional<component::G2> ret = std::nullopt;
238
239
492
    if ( op.priv.ToTrimmedString() == "0" ) {
240
30
        return std::nullopt;
241
30
    }
242
243
462
    try {
244
462
        using namespace Namespace;
245
246
462
        Fr sec;
247
462
        sec.setStr(op.priv.ToTrimmedString(), 10);
248
249
462
        G2 pub;
250
462
        G2::mul(pub, mcl_detail::Generator_G2(), sec);
251
252
462
        ret = mcl_detail::ToComponentG2(pub);
253
462
    } catch ( cybozu::Exception ) {
254
38
        if ( !op.priv.IsGreaterThan("52435875175126190479447740508185965837690552500527637822603658699938581184512") ) {
255
0
            CF_ASSERT(0, "Failed to sign");
256
0
        }
257
38
    }
258
259
462
    return ret;
260
462
}
261
262
588
std::optional<component::BLS_Signature> mcl::OpBLS_Sign(operation::BLS_Sign& op) {
263
588
    std::optional<component::BLS_Signature> ret = std::nullopt;
264
588
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
265
266
588
    if ( op.priv.ToTrimmedString() == "0" ) {
267
12
        return std::nullopt;
268
12
    }
269
270
576
    try {
271
576
        using namespace Namespace;
272
576
        Fr sec;
273
576
        sec.setStr(op.priv.ToTrimmedString(), 10);
274
275
576
        G2 sign;
276
576
        if ( op.hashOrPoint == true ) {
277
429
            G2 hash;
278
429
            const auto msg = mcl_detail::MsgAug(op);
279
429
            BN::param.mapTo.mapTo_WB19_.msgToG2(hash, msg.GetPtr(&ds), msg.GetSize(), (const char*)op.dest.GetPtr(&ds), op.dest.GetSize());
280
429
            Namespace::G2::mul(sign, hash, sec);
281
429
        } else {
282
147
            const auto g2 = mcl_detail::Convert(op.point);
283
147
            Namespace::G2::mul(sign, g2, sec);
284
147
        }
285
286
576
        G1 pub;
287
576
        G1::mul(pub, mcl_detail::Generator(), sec);
288
289
576
        ret = { mcl_detail::ToComponentG2(sign), mcl_detail::ToComponentG1(pub) };
290
576
    } catch ( cybozu::Exception ) {
291
        /* Failing is acceptable if:
292
         *
293
         * - An (invalid) point was tried to sign
294
         * - Tried to sign with an invalid private key
295
         *
296
         * Abort otherwise
297
         */
298
143
        if ( op.hashOrPoint ) {
299
6
            if ( !op.priv.IsGreaterThan("52435875175126190479447740508185965837690552500527637822603658699938581184512") ) {
300
0
                CF_ASSERT(0, "Failed to sign");
301
0
            }
302
6
        }
303
143
    }
304
305
576
    return ret;
306
576
}
307
308
128
std::optional<bool> mcl::OpBLS_Verify(operation::BLS_Verify& op) {
309
128
    std::optional<bool> ret = std::nullopt;
310
128
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
311
312
128
    if ( op.dest.Get() != mcl_detail::DST ) {
313
122
        return std::nullopt;
314
122
    }
315
316
6
    try {
317
6
        using namespace Namespace;
318
6
        const auto pub = mcl_detail::Convert(op.pub);
319
6
        const auto signature = mcl_detail::Convert(op.signature);
320
321
6
        G2 Q;
322
6
        mapToG2(Q, 1);
323
324
        //ret = mcl_detail::Verify(signature, Q, pub, std::string(op.cleartext.GetPtr(), op.cleartext.GetPtr() + op.cleartext.GetSize()));
325
6
    } catch ( cybozu::Exception ) { }
326
327
6
    return ret;
328
6
}
329
330
754
std::optional<bool> mcl::OpBLS_BatchVerify(operation::BLS_BatchVerify& op) {
331
754
    std::optional<bool> ret = std::nullopt;
332
754
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
333
334
754
    Namespace::Fp12 f;
335
754
    f.setOne();
336
337
754
    try {
338
754
        for (const auto& cur : op.bf.c) {
339
719
            const auto g1 = mcl_detail::Convert(cur.g1);
340
719
            CF_CHECK_TRUE(g1.isValid());
341
342
719
            const auto g2 = mcl_detail::Convert(cur.g2);
343
719
            CF_CHECK_TRUE(g2.isValid());
344
345
719
            Namespace::Fp12 tmp;
346
719
            Namespace::millerLoop(tmp, g1, g2);
347
719
            f *= tmp;
348
719
        }
349
754
    } catch ( ... ) {
350
719
        goto end;
351
719
    }
352
353
35
    Namespace::finalExp(f, f);
354
355
35
    ret = f.isOne();
356
754
end:
357
754
    return ret;
358
35
}
359
360
116
std::optional<component::Fp12> mcl::OpBLS_Pairing(operation::BLS_Pairing& op) {
361
116
    std::optional<component::Fp12> ret = std::nullopt;
362
116
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
363
364
116
    try {
365
116
        using namespace Namespace;
366
367
116
        const auto g1 = mcl_detail::Convert(op.g1);
368
        //CF_CHECK_TRUE(g1.isValid());
369
370
116
        const auto g2 = mcl_detail::Convert(op.g2);
371
        //CF_CHECK_TRUE(g2.isValid());
372
373
116
        Fp12 f;
374
375
116
        bool precompute = false;
376
116
        try {
377
116
            precompute = ds.Get<bool>();
378
116
        } catch ( fuzzing::datasource::Base::OutOfData ) {
379
0
        }
380
381
116
        if ( precompute == true ) {
382
2
            std::vector<Fp6> Qcoeff;
383
2
            precomputeG2(Qcoeff, g2);
384
2
            precomputedMillerLoop(f, g1, Qcoeff);
385
2
        } else {
386
1
            millerLoop(f, g1, g2);
387
1
        }
388
389
3
        finalExp(f, f);
390
391
3
        ret = mcl_detail::ToComponentFp12(f);
392
393
113
    } catch ( cybozu::Exception ) {
394
113
    }
395
396
116
end:
397
116
    return ret;
398
116
}
399
400
183
std::optional<component::Fp12> mcl::OpBLS_FinalExp(operation::BLS_FinalExp& op) {
401
183
    std::optional<component::Fp12> ret = std::nullopt;
402
183
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
403
404
183
    try {
405
183
        using namespace Namespace;
406
407
183
        auto f = ::mcl::bn::Fp12(
408
183
                ::mcl::bn::Fp6(
409
183
                    ::mcl::bn::Fp2(
410
183
                        op.fp12.bn1.ToTrimmedString(),
411
183
                        op.fp12.bn2.ToTrimmedString()
412
183
                        ),
413
183
                    ::mcl::bn::Fp2(
414
183
                        op.fp12.bn3.ToTrimmedString(),
415
183
                        op.fp12.bn4.ToTrimmedString()
416
183
                        ),
417
183
                    ::mcl::bn::Fp2(
418
183
                        op.fp12.bn5.ToTrimmedString(),
419
183
                        op.fp12.bn6.ToTrimmedString()
420
183
                        )
421
183
                    ),
422
183
                ::mcl::bn::Fp6(
423
183
                    ::mcl::bn::Fp2(
424
183
                        op.fp12.bn7.ToTrimmedString(),
425
183
                        op.fp12.bn8.ToTrimmedString()
426
183
                        ),
427
183
                    ::mcl::bn::Fp2(
428
183
                        op.fp12.bn9.ToTrimmedString(),
429
183
                        op.fp12.bn10.ToTrimmedString()
430
183
                        ),
431
183
                    ::mcl::bn::Fp2(
432
183
                        op.fp12.bn11.ToTrimmedString(),
433
183
                        op.fp12.bn12.ToTrimmedString()
434
183
                        )
435
183
                    )
436
183
        );
437
438
        //::mcl::bn::Fp12::unitaryInv(f, f);
439
183
        finalExp(f, f);
440
441
183
        ret = mcl_detail::ToComponentFp12(f);
442
183
    } catch ( cybozu::Exception ) {
443
27
    }
444
445
183
end:
446
183
    return ret;
447
183
}
448
449
1.23k
std::optional<bool> mcl::OpBLS_IsG1OnCurve(operation::BLS_IsG1OnCurve& op) {
450
1.23k
    using namespace Namespace;
451
452
1.23k
    Namespace::Fp x, y;
453
454
1.23k
    try {
455
1.23k
        x = Fp(op.g1.first.ToTrimmedString(), 10);
456
1.23k
        y = Fp(op.g1.second.ToTrimmedString(), 10);
457
1.23k
    } catch ( cybozu::Exception ) {
458
        /* May throw exception if string represents value larger than curve order */
459
242
        return std::nullopt;
460
242
    }
461
462
993
    try {
463
993
        return Namespace::G1(x, y).isValid();
464
993
    } catch ( cybozu::Exception ) {
465
967
        return false;
466
967
    }
467
993
}
468
469
1.88k
std::optional<bool> mcl::OpBLS_IsG2OnCurve(operation::BLS_IsG2OnCurve& op) {
470
1.88k
    using namespace Namespace;
471
472
1.88k
    Namespace::Fp x1, y1, x2, y2;
473
474
1.88k
    try {
475
1.88k
        x1 = Fp(op.g2.first.first.ToTrimmedString(), 10);
476
1.88k
        y1 = Fp(op.g2.second.first.ToTrimmedString(), 10);
477
1.88k
        x2 = Fp(op.g2.first.second.ToTrimmedString(), 10);
478
1.88k
        y2 = Fp(op.g2.second.second.ToTrimmedString(), 10);
479
1.88k
    } catch ( cybozu::Exception ) {
480
        /* May throw exception if string represents value larger than curve order */
481
342
        return std::nullopt;
482
342
    }
483
484
1.54k
    try {
485
1.54k
        return Namespace::G2({x1, y1}, {x2, y2}).isValid();
486
1.54k
    } catch ( cybozu::Exception ) {
487
1.52k
        return false;
488
1.52k
    }
489
1.54k
}
490
491
132
std::optional<component::G1> mcl::OpBLS_HashToG1(operation::BLS_HashToG1& op) {
492
132
    std::optional<component::G1> ret = std::nullopt;
493
132
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
494
495
132
    using namespace Namespace;
496
132
    G1 P;
497
132
    const auto msg = mcl_detail::MsgAug(op);
498
132
    BN::param.mapTo.mapTo_WB19_.msgToG1(P, msg.GetPtr(&ds), msg.GetSize(), (const char*)op.dest.GetPtr(&ds), op.dest.GetSize());
499
500
    /* Alternative: requires that op.dest == mcl_detail::DST */
501
    ///* noret */ hashAndMapToG1(P, msg.data(), msg.size());
502
132
    ret = mcl_detail::ToComponentG1(P);
503
504
132
    return ret;
505
132
}
506
507
187
std::optional<component::G2> mcl::OpBLS_HashToG2(operation::BLS_HashToG2& op) {
508
187
    std::optional<component::G2> ret = std::nullopt;
509
187
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
510
511
187
    using namespace Namespace;
512
187
    G2 P;
513
187
    const auto msg = mcl_detail::MsgAug(op);
514
187
    BN::param.mapTo.mapTo_WB19_.msgToG2(P, msg.GetPtr(&ds), msg.GetSize(), (const char*)op.dest.GetPtr(&ds), op.dest.GetSize());
515
516
    /* Alternative: requires that op.dest == mcl_detail::DST */
517
    ///* noret */ hashAndMapToG2(P, msg.data(), msg.size());
518
187
    ret = mcl_detail::ToComponentG2(P);
519
520
187
    return ret;
521
187
}
522
523
193
std::optional<component::G1> mcl::OpBLS_MapToG1(operation::BLS_MapToG1& op) {
524
193
    std::optional<component::G1> ret = std::nullopt;
525
193
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
526
527
193
    using namespace Namespace;
528
193
    G1 P;
529
193
    ::mcl::bn::Fp u, v;
530
193
    try {
531
193
        u.setStr(op.u.ToTrimmedString(), 10);
532
193
        v.setStr(op.v.ToTrimmedString(), 10);
533
193
    } catch ( cybozu::Exception ) {
534
23
        goto end;
535
23
    }
536
170
    CF_NORET(BN::param.mapTo.mapTo_WB19_.FpToG1(P, u, &v));
537
538
170
    if ( !P.isValid() ) {
539
5
        ret = component::G1{"0", "0"};
540
165
    } else {
541
165
        ret = mcl_detail::ToComponentG1(P);
542
165
    }
543
544
193
end:
545
193
    return ret;
546
170
}
547
548
122
std::optional<component::G2> mcl::OpBLS_MapToG2(operation::BLS_MapToG2& op) {
549
122
    std::optional<component::G2> ret = std::nullopt;
550
122
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
551
552
122
    using namespace Namespace;
553
122
    G2 P;
554
122
    ::mcl::bn::Fp2 u, v;
555
122
    try {
556
122
        u = ::mcl::bn::Fp2(
557
122
                op.u.first.ToTrimmedString(),
558
122
                op.u.second.ToTrimmedString());
559
122
        v = ::mcl::bn::Fp2(
560
122
                op.v.first.ToTrimmedString(),
561
122
                op.v.second.ToTrimmedString());
562
122
    } catch ( cybozu::Exception ) {
563
37
        goto end;
564
37
    }
565
85
    CF_NORET(BN::param.mapTo.mapTo_WB19_.Fp2ToG2(P, u, &v));
566
567
85
    if ( !P.isValid() ) {
568
0
        ret = { "0", "0", "0", "0" };
569
85
    } else {
570
85
        ret = mcl_detail::ToComponentG2(P);
571
85
    }
572
573
122
end:
574
122
    return ret;
575
85
}
576
577
2.33k
std::optional<component::G1> mcl::OpBLS_G1_Add(operation::BLS_G1_Add& op) {
578
2.33k
    std::optional<component::G1> ret = std::nullopt;
579
2.33k
    using namespace Namespace;
580
581
2.33k
    Namespace::Fp a_x, a_y, b_x, b_y;
582
583
2.33k
    try {
584
2.33k
        a_x = Fp(op.a.first.ToTrimmedString(), 10);
585
2.33k
        a_y = Fp(op.a.second.ToTrimmedString(), 10);
586
2.33k
        b_x = Fp(op.b.first.ToTrimmedString(), 10);
587
2.33k
        b_y = Fp(op.b.second.ToTrimmedString(), 10);
588
2.33k
    } catch ( cybozu::Exception ) {
589
        /* May throw exception if string represents value larger than curve order */
590
371
        return std::nullopt;
591
371
    }
592
593
1.96k
    try {
594
1.96k
        const auto a = Namespace::G1(a_x, a_y);
595
1.96k
        const auto b = Namespace::G1(b_x, b_y);
596
597
1.96k
        const auto result = a + b;
598
599
1.96k
        ret = mcl_detail::ToComponentG1(result);
600
1.96k
    } catch ( cybozu::Exception ) {
601
1.95k
        return std::nullopt;
602
1.95k
    }
603
604
15
    return ret;
605
1.96k
}
606
607
1.56k
std::optional<component::G1> mcl::OpBLS_G1_Mul(operation::BLS_G1_Mul& op) {
608
1.56k
    std::optional<component::G1> ret = std::nullopt;
609
1.56k
    using namespace Namespace;
610
611
1.56k
    Namespace::Fp a_x, a_y;
612
1.56k
    Namespace::Fp b;
613
614
1.56k
    try {
615
1.56k
        a_x = Fp(op.a.first.ToTrimmedString(), 10);
616
1.56k
        a_y = Fp(op.a.second.ToTrimmedString(), 10);
617
618
1.56k
        b = Fp(op.b.ToTrimmedString(), 10);
619
1.56k
    } catch ( cybozu::Exception ) {
620
        /* May throw exception if string represents value larger than curve order */
621
151
        return std::nullopt;
622
151
    }
623
624
1.41k
    try {
625
1.41k
        const auto a = Namespace::G1(a_x, a_y);
626
627
1.41k
        const auto result = a * b;
628
629
1.41k
        ret = mcl_detail::ToComponentG1(result);
630
1.41k
    } catch ( cybozu::Exception ) {
631
1.32k
        return std::nullopt;
632
1.32k
    }
633
634
97
    return ret;
635
1.41k
}
636
637
131
std::optional<bool> mcl::OpBLS_G1_IsEq(operation::BLS_G1_IsEq& op) {
638
131
    std::optional<bool> ret = std::nullopt;
639
131
    using namespace Namespace;
640
641
131
    Namespace::Fp a_x, a_y, b_x, b_y;
642
643
131
    try {
644
131
        a_x = Fp(op.a.first.ToTrimmedString(), 10);
645
131
        a_y = Fp(op.a.second.ToTrimmedString(), 10);
646
131
        b_x = Fp(op.b.first.ToTrimmedString(), 10);
647
131
        b_y = Fp(op.b.second.ToTrimmedString(), 10);
648
131
    } catch ( cybozu::Exception ) {
649
        /* May throw exception if string represents value larger than curve order */
650
59
        return std::nullopt;
651
59
    }
652
653
72
    try {
654
72
        const auto a = Namespace::G1(a_x, a_y);
655
72
        const auto b = Namespace::G1(b_x, b_y);
656
657
72
        ret = a == b;
658
72
    } catch ( cybozu::Exception ) {
659
68
        return std::nullopt;
660
68
    }
661
662
4
    return ret;
663
72
}
664
665
2.24k
std::optional<component::G1> mcl::OpBLS_G1_Neg(operation::BLS_G1_Neg& op) {
666
2.24k
    std::optional<component::G1> ret = std::nullopt;
667
2.24k
    using namespace Namespace;
668
669
2.24k
    Namespace::Fp a_x, a_y;
670
671
2.24k
    try {
672
2.24k
        a_x = Fp(op.a.first.ToTrimmedString(), 10);
673
2.24k
        a_y = Fp(op.a.second.ToTrimmedString(), 10);
674
2.24k
    } catch ( cybozu::Exception ) {
675
        /* May throw exception if string represents value larger than curve order */
676
385
        return std::nullopt;
677
385
    }
678
679
1.86k
    try {
680
1.86k
        const auto a = Namespace::G1(a_x, a_y);
681
682
1.86k
        const auto result = -a;
683
684
1.86k
        ret = mcl_detail::ToComponentG1(result);
685
1.86k
    } catch ( cybozu::Exception ) {
686
1.84k
        return std::nullopt;
687
1.84k
    }
688
689
19
    return ret;
690
1.86k
}
691
692
2.32k
std::optional<component::G2> mcl::OpBLS_G2_Add(operation::BLS_G2_Add& op) {
693
2.32k
    std::optional<component::G2> ret = std::nullopt;
694
2.32k
    using namespace Namespace;
695
696
2.32k
    Namespace::Fp a_v, a_w, a_x, a_y;
697
2.32k
    Namespace::Fp b_v, b_w, b_x, b_y;
698
699
2.32k
    try {
700
2.32k
        a_v = Fp(op.a.first.first.ToTrimmedString(), 10);
701
2.32k
        a_w = Fp(op.a.first.second.ToTrimmedString(), 10);
702
2.32k
        a_x = Fp(op.a.second.first.ToTrimmedString(), 10);
703
2.32k
        a_y = Fp(op.a.second.second.ToTrimmedString(), 10);
704
705
2.32k
        b_v = Fp(op.b.first.first.ToTrimmedString(), 10);
706
2.32k
        b_w = Fp(op.b.first.second.ToTrimmedString(), 10);
707
2.32k
        b_x = Fp(op.b.second.first.ToTrimmedString(), 10);
708
2.32k
        b_y = Fp(op.b.second.second.ToTrimmedString(), 10);
709
2.32k
    } catch ( cybozu::Exception ) {
710
        /* May throw exception if string represents value larger than curve order */
711
489
        return std::nullopt;
712
489
    }
713
714
1.83k
    try {
715
1.83k
        const auto a = Namespace::G2({a_v, a_x}, {a_w, a_y});
716
1.83k
        const auto b = Namespace::G2({b_v, b_x}, {b_w, b_y});
717
718
1.83k
        const auto result = a + b;
719
720
1.83k
        ret = mcl_detail::ToComponentG2(result);
721
1.83k
    } catch ( cybozu::Exception ) {
722
1.82k
        return std::nullopt;
723
1.82k
    }
724
725
9
    return ret;
726
1.83k
}
727
728
3.85k
std::optional<component::G2> mcl::OpBLS_G2_Mul(operation::BLS_G2_Mul& op) {
729
3.85k
    std::optional<component::G2> ret = std::nullopt;
730
3.85k
    using namespace Namespace;
731
732
3.85k
    Namespace::Fp a_v, a_w, a_x, a_y;
733
3.85k
    Namespace::Fp b;
734
735
3.85k
    try {
736
3.85k
        a_v = Fp(op.a.first.first.ToTrimmedString(), 10);
737
3.85k
        a_w = Fp(op.a.first.second.ToTrimmedString(), 10);
738
3.85k
        a_x = Fp(op.a.second.first.ToTrimmedString(), 10);
739
3.85k
        a_y = Fp(op.a.second.second.ToTrimmedString(), 10);
740
741
3.85k
        b = Fp(op.b.ToTrimmedString(), 10);
742
3.85k
    } catch ( cybozu::Exception ) {
743
        /* May throw exception if string represents value larger than curve order */
744
247
        return std::nullopt;
745
247
    }
746
747
3.60k
    try {
748
3.60k
        const auto a = Namespace::G2({a_v, a_x}, {a_w, a_y});
749
750
3.60k
        const auto result = a * b;
751
752
3.60k
        ret = mcl_detail::ToComponentG2(result);
753
3.60k
    } catch ( cybozu::Exception ) {
754
3.58k
        return std::nullopt;
755
3.58k
    }
756
757
23
    return ret;
758
3.60k
}
759
760
141
std::optional<bool> mcl::OpBLS_G2_IsEq(operation::BLS_G2_IsEq& op) {
761
141
    std::optional<bool> ret = std::nullopt;
762
141
    using namespace Namespace;
763
764
141
    Namespace::Fp a_v, a_w, a_x, a_y;
765
141
    Namespace::Fp b_v, b_w, b_x, b_y;
766
767
141
    try {
768
141
        a_v = Fp(op.a.first.first.ToTrimmedString(), 10);
769
141
        a_w = Fp(op.a.first.second.ToTrimmedString(), 10);
770
141
        a_x = Fp(op.a.second.first.ToTrimmedString(), 10);
771
141
        a_y = Fp(op.a.second.second.ToTrimmedString(), 10);
772
773
141
        b_v = Fp(op.b.first.first.ToTrimmedString(), 10);
774
141
        b_w = Fp(op.b.first.second.ToTrimmedString(), 10);
775
141
        b_x = Fp(op.b.second.first.ToTrimmedString(), 10);
776
141
        b_y = Fp(op.b.second.second.ToTrimmedString(), 10);
777
141
    } catch ( cybozu::Exception ) {
778
        /* May throw exception if string represents value larger than curve order */
779
88
        return std::nullopt;
780
88
    }
781
782
53
    try {
783
53
        const auto a = Namespace::G2({a_v, a_x}, {a_w, a_y});
784
53
        const auto b = Namespace::G2({b_v, b_x}, {b_w, b_y});
785
786
53
        ret = a == b;
787
53
    } catch ( cybozu::Exception ) {
788
48
        return std::nullopt;
789
48
    }
790
791
5
    return ret;
792
53
}
793
794
2.02k
std::optional<component::G2> mcl::OpBLS_G2_Neg(operation::BLS_G2_Neg& op) {
795
2.02k
    std::optional<component::G2> ret = std::nullopt;
796
2.02k
    using namespace Namespace;
797
798
2.02k
    Namespace::Fp a_v, a_w, a_x, a_y;
799
800
2.02k
    try {
801
2.02k
        a_v = Fp(op.a.first.first.ToTrimmedString(), 10);
802
2.02k
        a_w = Fp(op.a.first.second.ToTrimmedString(), 10);
803
2.02k
        a_x = Fp(op.a.second.first.ToTrimmedString(), 10);
804
2.02k
        a_y = Fp(op.a.second.second.ToTrimmedString(), 10);
805
2.02k
    } catch ( cybozu::Exception ) {
806
        /* May throw exception if string represents value larger than curve order */
807
368
        return std::nullopt;
808
368
    }
809
810
1.65k
    try {
811
1.65k
        const auto a = Namespace::G2({a_v, a_x}, {a_w, a_y});
812
813
1.65k
        const auto result = -a;
814
815
1.65k
        ret = mcl_detail::ToComponentG2(result);
816
1.65k
    } catch ( cybozu::Exception ) {
817
1.64k
        return std::nullopt;
818
1.64k
    }
819
820
10
    return ret;
821
1.65k
}
822
823
namespace mcl_detail {
824
    template <class T>
825
3.24k
    bool UseParamTwice(fuzzing::datasource::Datasource& ds, const T& A, const T& B) {
826
3.24k
        if ( A != B ) {
827
2.79k
            return false;
828
2.79k
        }
829
830
455
        try {
831
455
            return ds.Get<bool>();
832
455
        } catch ( fuzzing::datasource::Base::OutOfData ) {
833
215
        }
834
835
215
        return false;
836
455
    }
bool cryptofuzz::module::mcl_detail::UseParamTwice<mcl::FpT<mcl::bn::local::FrTag, 256ul> >(fuzzing::datasource::Datasource&, mcl::FpT<mcl::bn::local::FrTag, 256ul> const&, mcl::FpT<mcl::bn::local::FrTag, 256ul> const&)
Line
Count
Source
825
1.85k
    bool UseParamTwice(fuzzing::datasource::Datasource& ds, const T& A, const T& B) {
826
1.85k
        if ( A != B ) {
827
1.63k
            return false;
828
1.63k
        }
829
830
224
        try {
831
224
            return ds.Get<bool>();
832
224
        } catch ( fuzzing::datasource::Base::OutOfData ) {
833
128
        }
834
835
128
        return false;
836
224
    }
bool cryptofuzz::module::mcl_detail::UseParamTwice<mcl::FpT<mcl::bn::local::FpTag, 384ul> >(fuzzing::datasource::Datasource&, mcl::FpT<mcl::bn::local::FpTag, 384ul> const&, mcl::FpT<mcl::bn::local::FpTag, 384ul> const&)
Line
Count
Source
825
1.39k
    bool UseParamTwice(fuzzing::datasource::Datasource& ds, const T& A, const T& B) {
826
1.39k
        if ( A != B ) {
827
1.16k
            return false;
828
1.16k
        }
829
830
231
        try {
831
231
            return ds.Get<bool>();
832
231
        } catch ( fuzzing::datasource::Base::OutOfData ) {
833
87
        }
834
835
87
        return false;
836
231
    }
837
838
3.24k
    uint8_t GetMod3(fuzzing::datasource::Datasource& ds) {
839
3.24k
        try {
840
3.24k
            return ds.Get<uint8_t>() % 3;
841
3.24k
        } catch ( fuzzing::datasource::Base::OutOfData ) {
842
2.15k
        }
843
844
2.15k
        return 0;
845
3.24k
    }
846
}
847
848
20.6k
std::optional<component::Bignum> mcl::OpBignumCalc(operation::BignumCalc& op) {
849
20.6k
    if ( op.modulo == std::nullopt ) {
850
10.5k
        return std::nullopt;
851
10.5k
    }
852
10.0k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
853
854
10.0k
#define PREPARE_BN() { \
855
3.67k
    ap = &a; bp = mcl_detail::UseParamTwice(ds, a, b) ? &a : &b; \
856
3.67k
    switch ( mcl_detail::GetMod3(ds) ) { \
857
2.44k
        case    0: \
858
2.44k
            resultp = &a; \
859
2.44k
            break; \
860
361
        case    1: \
861
361
            resultp = &b; \
862
361
            break; \
863
441
        case    2: \
864
441
            resultp = &result; \
865
441
            break; \
866
3.67k
    } \
867
3.67k
}
868
869
    /* TODO optimize this */
870
10.0k
    if ( op.modulo->ToTrimmedString() == "52435875175126190479447740508185965837690552500527637822603658699938581184513" ) {
871
5.13k
        ::mcl::bn::Fr a, b, result;
872
5.13k
        ::mcl::bn::Fr* ap, *bp, *resultp;
873
874
5.13k
        try {
875
5.13k
            switch ( op.calcOp.Get() ) {
876
66
                case    CF_CALCOP("Add(A,B)"):
877
66
                    a.setStr(op.bn0.ToTrimmedString(), 10);
878
66
                    b.setStr(op.bn1.ToTrimmedString(), 10);
879
66
                    PREPARE_BN();
880
49
                    return (*ap+*bp).getStr();
881
101
                case    CF_CALCOP("Sub(A,B)"):
882
101
                    a.setStr(op.bn0.ToTrimmedString(), 10);
883
101
                    b.setStr(op.bn1.ToTrimmedString(), 10);
884
101
                    PREPARE_BN();
885
77
                    return (*ap-*bp).getStr();
886
275
                case    CF_CALCOP("Mul(A,B)"):
887
275
                    a.setStr(op.bn0.ToTrimmedString(), 10);
888
275
                    b.setStr(op.bn1.ToTrimmedString(), 10);
889
275
                    PREPARE_BN();
890
242
                    return ((*ap)*(*bp)).getStr();
891
326
                case    CF_CALCOP("InvMod(A,B)"):
892
326
                    {
893
326
                        a.setStr(op.bn0.ToTrimmedString(), 10);
894
326
                        b.setStr("0", 10);
895
326
                        CF_CHECK_NE(a, b);
896
306
                        PREPARE_BN();
897
295
                        ::mcl::bn::Fr::inv(*resultp, *ap);
898
295
                        return resultp->getStr();
899
306
                    }
900
51
                case    CF_CALCOP("Sqr(A)"):
901
51
                    {
902
51
                        a.setStr(op.bn0.ToTrimmedString(), 10);
903
51
                        b.setStr("0", 10);
904
51
                        PREPARE_BN();
905
34
                        ::mcl::bn::Fr::sqr(*resultp, *ap);
906
34
                        return resultp->getStr();
907
51
                    }
908
41
                case    CF_CALCOP("Not(A)"):
909
41
                    {
910
41
                        a.setStr(op.bn0.ToTrimmedString(), 10);
911
41
                        b.setStr("0", 10);
912
41
                        PREPARE_BN();
913
32
                        ::mcl::bn::Fr::neg(*resultp, *ap);
914
32
                        return resultp->getStr();
915
41
                    }
916
170
                case    CF_CALCOP("LShift1(A)"):
917
170
                    {
918
170
                        a.setStr(op.bn0.ToTrimmedString(), 10);
919
170
                        b.setStr("0", 10);
920
170
                        PREPARE_BN();
921
158
                        ::mcl::bn::Fr::mul2(*resultp, *ap);
922
158
                        return resultp->getStr();
923
170
                    }
924
53
                case    CF_CALCOP("IsEq(A,B)"):
925
53
                    {
926
53
                        a.setStr(op.bn0.ToTrimmedString(), 10);
927
53
                        b.setStr(op.bn1.ToTrimmedString(), 10);
928
53
                        PREPARE_BN();
929
32
                        return *ap == *bp ? std::string("1") : std::string("0");
930
53
                    }
931
17
                case    CF_CALCOP("IsGt(A,B)"):
932
17
                    {
933
17
                        a.setStr(op.bn0.ToTrimmedString(), 10);
934
17
                        b.setStr(op.bn1.ToTrimmedString(), 10);
935
17
                        PREPARE_BN();
936
12
                        return *ap > *bp ? std::string("1") : std::string("0");
937
17
                    }
938
29
                case    CF_CALCOP("IsGte(A,B)"):
939
29
                    {
940
29
                        a.setStr(op.bn0.ToTrimmedString(), 10);
941
29
                        b.setStr(op.bn1.ToTrimmedString(), 10);
942
29
                        PREPARE_BN();
943
24
                        return *ap >= *bp ? std::string("1") : std::string("0");
944
29
                    }
945
42
                case    CF_CALCOP("IsLt(A,B)"):
946
42
                    {
947
42
                        a.setStr(op.bn0.ToTrimmedString(), 10);
948
42
                        b.setStr(op.bn1.ToTrimmedString(), 10);
949
42
                        PREPARE_BN();
950
38
                        return *ap < *bp ? std::string("1") : std::string("0");
951
42
                    }
952
32
                case    CF_CALCOP("IsLte(A,B)"):
953
32
                    {
954
32
                        a.setStr(op.bn0.ToTrimmedString(), 10);
955
32
                        b.setStr(op.bn1.ToTrimmedString(), 10);
956
32
                        PREPARE_BN();
957
28
                        return *ap <= *bp ? std::string("1") : std::string("0");
958
32
                    }
959
32
                case    CF_CALCOP("IsZero(A)"):
960
32
                    {
961
32
                        a.setStr(op.bn0.ToTrimmedString(), 10);
962
32
                        b.setStr("0", 10);
963
32
                        PREPARE_BN();
964
24
                        return *ap == 0 ? std::string("1") : std::string("0");
965
32
                    }
966
51
                case    CF_CALCOP("IsOne(A)"):
967
51
                    {
968
51
                        a.setStr(op.bn0.ToTrimmedString(), 10);
969
51
                        b.setStr("0", 10);
970
51
                        PREPARE_BN();
971
49
                        return *ap == 1 ? std::string("1") : std::string("0");
972
51
                    }
973
6
                case    CF_CALCOP("IsOdd(A)"):
974
6
                    {
975
6
                        a.setStr(op.bn0.ToTrimmedString(), 10);
976
6
                        b.setStr("0", 10);
977
6
                        PREPARE_BN();
978
4
                        return ap->isOdd() ? std::string("1") : std::string("0");
979
6
                    }
980
7
                case    CF_CALCOP("IsEven(A)"):
981
7
                    {
982
7
                        a.setStr(op.bn0.ToTrimmedString(), 10);
983
7
                        b.setStr("0", 10);
984
7
                        PREPARE_BN();
985
5
                        return ap->isOdd() ? std::string("0") : std::string("1");
986
7
                    }
987
696
                case    CF_CALCOP("Sqrt(A)"):
988
696
                    {
989
696
                        a.setStr(op.bn0.ToTrimmedString(), 10);
990
696
                        b.setStr("0", 10);
991
696
                        PREPARE_BN();
992
690
                        if ( ::mcl::bn::Fr::squareRoot(*resultp, *ap) == false ) {
993
217
                            return std::string("0");
994
217
                        }
995
473
                        ::mcl::bn::Fr::sqr(*resultp, *resultp);
996
473
                        return resultp->getStr();
997
690
                    }
998
19
                case    CF_CALCOP("Exp(A,B)"):
999
19
                    {
1000
19
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1001
19
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1002
19
                        PREPARE_BN();
1003
19
                        ::mcl::bn::Fr::pow(*resultp, *ap, *bp);
1004
19
                        return resultp->getStr();
1005
19
                    }
1006
52
                case    CF_CALCOP("Cmp(A,B)"):
1007
52
                    {
1008
52
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1009
52
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1010
52
                        PREPARE_BN();
1011
46
                        if ( *ap == *bp ) {
1012
4
                            return std::string("0");
1013
42
                        } else if ( *ap < *bp ) {
1014
3
                            return std::string("-1");
1015
39
                        } else if ( *ap > *bp ) {
1016
39
                            return std::string("1");
1017
39
                        } else {
1018
0
                            CF_UNREACHABLE();
1019
0
                        }
1020
46
                    }
1021
18
                case    CF_CALCOP("Set(A)"):
1022
18
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1023
18
                        return a.getStr();
1024
5.13k
            }
1025
5.13k
        } catch ( cybozu::Exception ) {
1026
196
            if (
1027
196
                    !op.bn0.IsGreaterThan("52435875175126190479447740508185965837690552500527637822603658699938581184511") &&
1028
196
                    !op.bn1.IsGreaterThan("52435875175126190479447740508185965837690552500527637822603658699938581184511") ) {
1029
0
                CF_ASSERT(0, "BignumCalc_Mod_BLS12_381_R unexpectedly failed");
1030
0
            }
1031
196
        }
1032
1033
3.24k
        return std::nullopt;
1034
5.13k
    } else if ( op.modulo->ToTrimmedString() == "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787" ) {
1035
4.88k
        ::mcl::bn::Fp a, b, result;
1036
4.88k
        ::mcl::bn::Fp* ap, *bp, *resultp;
1037
1038
4.88k
        try {
1039
4.88k
            switch ( op.calcOp.Get() ) {
1040
156
                case    CF_CALCOP("Add(A,B)"):
1041
156
                    a.setStr(op.bn0.ToTrimmedString(), 10);
1042
156
                    b.setStr(op.bn1.ToTrimmedString(), 10);
1043
156
                    PREPARE_BN();
1044
126
                    return (*ap+*bp).getStr();
1045
102
                case    CF_CALCOP("Sub(A,B)"):
1046
102
                    a.setStr(op.bn0.ToTrimmedString(), 10);
1047
102
                    b.setStr(op.bn1.ToTrimmedString(), 10);
1048
102
                    PREPARE_BN();
1049
83
                    return (*ap-*bp).getStr();
1050
238
                case    CF_CALCOP("Mul(A,B)"):
1051
238
                    a.setStr(op.bn0.ToTrimmedString(), 10);
1052
238
                    b.setStr(op.bn1.ToTrimmedString(), 10);
1053
238
                    PREPARE_BN();
1054
200
                    return ((*ap)*(*bp)).getStr();
1055
129
                case    CF_CALCOP("InvMod(A,B)"):
1056
129
                    {
1057
129
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1058
129
                        b.setStr("0", 10);
1059
129
                        CF_CHECK_NE(a, b);
1060
123
                        PREPARE_BN();
1061
106
                        ::mcl::bn::Fp::inv(*resultp, *ap);
1062
106
                        return resultp->getStr();
1063
123
                    }
1064
155
                case    CF_CALCOP("Sqr(A)"):
1065
155
                    {
1066
155
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1067
155
                        b.setStr("0", 10);
1068
155
                        PREPARE_BN();
1069
127
                        ::mcl::bn::Fp::sqr(*resultp, *ap);
1070
127
                        return resultp->getStr();
1071
155
                    }
1072
34
                case    CF_CALCOP("Not(A)"):
1073
34
                    {
1074
34
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1075
34
                        b.setStr("0", 10);
1076
34
                        PREPARE_BN();
1077
27
                        ::mcl::bn::Fp::neg(*resultp, *ap);
1078
27
                        return resultp->getStr();
1079
34
                    }
1080
109
                case    CF_CALCOP("LShift1(A)"):
1081
109
                    {
1082
109
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1083
109
                        b.setStr("0", 10);
1084
109
                        PREPARE_BN();
1085
93
                        ::mcl::bn::Fp::mul2(*resultp, *ap);
1086
93
                        return resultp->getStr();
1087
109
                    }
1088
57
                case    CF_CALCOP("IsEq(A,B)"):
1089
57
                    {
1090
57
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1091
57
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1092
57
                        PREPARE_BN();
1093
31
                        return *ap == *bp ? std::string("1") : std::string("0");
1094
57
                    }
1095
27
                case    CF_CALCOP("IsGt(A,B)"):
1096
27
                    {
1097
27
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1098
27
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1099
27
                        PREPARE_BN();
1100
23
                        return *ap > *bp ? std::string("1") : std::string("0");
1101
27
                    }
1102
55
                case    CF_CALCOP("IsGte(A,B)"):
1103
55
                    {
1104
55
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1105
55
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1106
55
                        PREPARE_BN();
1107
51
                        return *ap >= *bp ? std::string("1") : std::string("0");
1108
55
                    }
1109
18
                case    CF_CALCOP("IsLt(A,B)"):
1110
18
                    {
1111
18
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1112
18
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1113
18
                        PREPARE_BN();
1114
14
                        return *ap < *bp ? std::string("1") : std::string("0");
1115
18
                    }
1116
20
                case    CF_CALCOP("IsLte(A,B)"):
1117
20
                    {
1118
20
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1119
20
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1120
20
                        PREPARE_BN();
1121
15
                        return *ap <= *bp ? std::string("1") : std::string("0");
1122
20
                    }
1123
27
                case    CF_CALCOP("IsZero(A)"):
1124
27
                    {
1125
27
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1126
27
                        b.setStr("0", 10);
1127
27
                        PREPARE_BN();
1128
19
                        return *ap == 0 ? std::string("1") : std::string("0");
1129
27
                    }
1130
8
                case    CF_CALCOP("IsOne(A)"):
1131
8
                    {
1132
8
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1133
8
                        b.setStr("0", 10);
1134
8
                        PREPARE_BN();
1135
5
                        return *ap == 1 ? std::string("1") : std::string("0");
1136
8
                    }
1137
6
                case    CF_CALCOP("IsOdd(A)"):
1138
6
                    {
1139
6
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1140
6
                        b.setStr("0", 10);
1141
6
                        PREPARE_BN();
1142
4
                        return ap->isOdd() ? std::string("1") : std::string("0");
1143
6
                    }
1144
6
                case    CF_CALCOP("IsEven(A)"):
1145
6
                    {
1146
6
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1147
6
                        b.setStr("0", 10);
1148
6
                        PREPARE_BN();
1149
4
                        return ap->isOdd() ? std::string("0") : std::string("1");
1150
6
                    }
1151
60
                case    CF_CALCOP("RShift(A,B)"):
1152
60
                    {
1153
60
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1154
60
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1155
60
                        PREPARE_BN();
1156
49
                        if ( *bp != 1 ) {
1157
45
                            return std::nullopt;
1158
45
                        }
1159
4
                        ::mcl::bn::Fp::divBy2(*resultp, *ap);
1160
4
                        return resultp->getStr();
1161
49
                    }
1162
358
                case    CF_CALCOP("Sqrt(A)"):
1163
358
                    {
1164
358
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1165
358
                        b.setStr("0", 10);
1166
358
                        PREPARE_BN();
1167
344
                        if ( ::mcl::bn::Fp::squareRoot(*resultp, *ap) == false ) {
1168
159
                            return std::string("0");
1169
159
                        }
1170
185
                        ::mcl::bn::Fp::sqr(*resultp, *resultp);
1171
185
                        return resultp->getStr();
1172
344
                    }
1173
21
                case    CF_CALCOP("Exp(A,B)"):
1174
21
                    {
1175
21
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1176
21
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1177
21
                        PREPARE_BN();
1178
21
                        ::mcl::bn::Fp::pow(*resultp, *ap, *bp);
1179
21
                        return resultp->getStr();
1180
21
                    }
1181
53
                case    CF_CALCOP("Cmp(A,B)"):
1182
53
                    {
1183
53
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1184
53
                        b.setStr(op.bn1.ToTrimmedString(), 10);
1185
53
                        PREPARE_BN();
1186
49
                        if ( *ap == *bp ) {
1187
3
                            return std::string("0");
1188
46
                        } else if ( *ap < *bp ) {
1189
9
                            return std::string("-1");
1190
37
                        } else if ( *ap > *bp ) {
1191
37
                            return std::string("1");
1192
37
                        } else {
1193
0
                            CF_UNREACHABLE();
1194
0
                        }
1195
49
                    }
1196
19
                case    CF_CALCOP("Set(A)"):
1197
19
                        a.setStr(op.bn0.ToTrimmedString(), 10);
1198
19
                        return a.getStr();
1199
4.88k
            }
1200
4.88k
        } catch ( cybozu::Exception ) {
1201
250
            if (
1202
250
                    !op.bn0.IsGreaterThan("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786") &&
1203
250
                    !op.bn1.IsGreaterThan("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786") ) {
1204
0
                CF_ASSERT(0, "BignumCalc_Mod_BLS12_381_P unexpectedly failed");
1205
0
            }
1206
250
        }
1207
1208
3.47k
        return std::nullopt;
1209
4.88k
    }
1210
1211
26
end:
1212
26
        return std::nullopt;
1213
10.0k
}
1214
1215
1.94k
std::optional<component::Fp2> mcl::OpBignumCalc_Fp2(operation::BignumCalc_Fp2& op) {
1216
1.94k
    ::mcl::bn::Fp2 a, b, result;
1217
1.94k
    ::mcl::bn::Fp* ap, *bp, *resultp;
1218
1219
1.94k
    try {
1220
1.94k
        switch ( op.calcOp.Get() ) {
1221
84
            case    CF_CALCOP("Add(A,B)"):
1222
84
                a = ::mcl::bn::Fp2(
1223
84
                        op.bn0.first.ToTrimmedString(),
1224
84
                        op.bn0.second.ToTrimmedString());
1225
84
                b = ::mcl::bn::Fp2(
1226
84
                        op.bn1.first.ToTrimmedString(),
1227
84
                        op.bn1.second.ToTrimmedString());
1228
1229
84
                return mcl_detail::ToComponentFp2(a+b);
1230
79
            case    CF_CALCOP("Sub(A,B)"):
1231
79
                a = ::mcl::bn::Fp2(
1232
79
                        op.bn0.first.ToTrimmedString(),
1233
79
                        op.bn0.second.ToTrimmedString());
1234
79
                b = ::mcl::bn::Fp2(
1235
79
                        op.bn1.first.ToTrimmedString(),
1236
79
                        op.bn1.second.ToTrimmedString());
1237
1238
79
                return mcl_detail::ToComponentFp2(a-b);
1239
71
            case    CF_CALCOP("Mul(A,B)"):
1240
71
                a = ::mcl::bn::Fp2(
1241
71
                        op.bn0.first.ToTrimmedString(),
1242
71
                        op.bn0.second.ToTrimmedString());
1243
71
                b = ::mcl::bn::Fp2(
1244
71
                        op.bn1.first.ToTrimmedString(),
1245
71
                        op.bn1.second.ToTrimmedString());
1246
1247
71
                return mcl_detail::ToComponentFp2(a*b);
1248
80
            case    CF_CALCOP("InvMod(A,B)"):
1249
80
                a = ::mcl::bn::Fp2(
1250
80
                        op.bn0.first.ToTrimmedString(),
1251
80
                        op.bn0.second.ToTrimmedString());
1252
1253
80
                if ( !a.isZero() ) {
1254
39
                    ::mcl::bn::Fp2::inv(result, a);
1255
39
                    return mcl_detail::ToComponentFp2(result);
1256
39
                }
1257
41
                break;
1258
195
            case    CF_CALCOP("Sqrt(A)"):
1259
195
                a = ::mcl::bn::Fp2(
1260
195
                        op.bn0.first.ToTrimmedString(),
1261
195
                        op.bn0.second.ToTrimmedString());
1262
195
                if ( ::mcl::bn::Fp2::squareRoot(result, a) == false ) {
1263
40
                    return component::Fp2{"0", "0"};
1264
155
                } else {
1265
155
                    ::mcl::bn::Fp2::sqr(result, result);
1266
155
                    return mcl_detail::ToComponentFp2(result);
1267
155
                }
1268
11
            case    CF_CALCOP("Neg(A)"):
1269
11
                a = ::mcl::bn::Fp2(
1270
11
                        op.bn0.first.ToTrimmedString(),
1271
11
                        op.bn0.second.ToTrimmedString());
1272
11
                ::mcl::bn::Fp2::neg(result, a);
1273
11
                return mcl_detail::ToComponentFp2(result);
1274
45
            case    CF_CALCOP("Sqr(A)"):
1275
45
                a = ::mcl::bn::Fp2(
1276
45
                        op.bn0.first.ToTrimmedString(),
1277
45
                        op.bn0.second.ToTrimmedString());
1278
45
                ::mcl::bn::Fp2::sqr(result, a);
1279
45
                return mcl_detail::ToComponentFp2(result);
1280
46
            case    CF_CALCOP("LShift1(A)"):
1281
46
                a = ::mcl::bn::Fp2(
1282
46
                        op.bn0.first.ToTrimmedString(),
1283
46
                        op.bn0.second.ToTrimmedString());
1284
46
                ::mcl::bn::Fp2::mul2(result, a);
1285
46
                return mcl_detail::ToComponentFp2(result);
1286
1.94k
        }
1287
1.94k
    } catch ( ... ) {
1288
169
    }
1289
1290
1.52k
    return std::nullopt;
1291
1.94k
}
1292
1293
999
std::optional<component::Fp12> mcl::OpBignumCalc_Fp12(operation::BignumCalc_Fp12& op) {
1294
999
    ::mcl::bn::Fp12 a, b, result;
1295
999
    ::mcl::bn::Fp* ap, *bp, *resultp;
1296
1297
999
    try {
1298
999
        switch ( op.calcOp.Get() ) {
1299
58
            case    CF_CALCOP("Add(A,B)"):
1300
58
                a = ::mcl::bn::Fp12(
1301
58
                        ::mcl::bn::Fp6(
1302
58
                            ::mcl::bn::Fp2(
1303
58
                                op.bn0.bn1.ToTrimmedString(),
1304
58
                                op.bn0.bn2.ToTrimmedString()
1305
58
                            ),
1306
58
                            ::mcl::bn::Fp2(
1307
58
                                op.bn0.bn3.ToTrimmedString(),
1308
58
                                op.bn0.bn4.ToTrimmedString()
1309
58
                            ),
1310
58
                            ::mcl::bn::Fp2(
1311
58
                                op.bn0.bn5.ToTrimmedString(),
1312
58
                                op.bn0.bn6.ToTrimmedString()
1313
58
                            )
1314
58
                        ),
1315
58
                        ::mcl::bn::Fp6(
1316
58
                            ::mcl::bn::Fp2(
1317
58
                                op.bn0.bn7.ToTrimmedString(),
1318
58
                                op.bn0.bn8.ToTrimmedString()
1319
58
                            ),
1320
58
                            ::mcl::bn::Fp2(
1321
58
                                op.bn0.bn9.ToTrimmedString(),
1322
58
                                op.bn0.bn10.ToTrimmedString()
1323
58
                            ),
1324
58
                            ::mcl::bn::Fp2(
1325
58
                                op.bn0.bn11.ToTrimmedString(),
1326
58
                                op.bn0.bn12.ToTrimmedString()
1327
58
                            )
1328
58
                        )
1329
58
                    );
1330
58
                b = ::mcl::bn::Fp12(
1331
58
                        ::mcl::bn::Fp6(
1332
58
                            ::mcl::bn::Fp2(
1333
58
                                op.bn1.bn1.ToTrimmedString(),
1334
58
                                op.bn1.bn2.ToTrimmedString()
1335
58
                            ),
1336
58
                            ::mcl::bn::Fp2(
1337
58
                                op.bn1.bn3.ToTrimmedString(),
1338
58
                                op.bn1.bn4.ToTrimmedString()
1339
58
                            ),
1340
58
                            ::mcl::bn::Fp2(
1341
58
                                op.bn1.bn5.ToTrimmedString(),
1342
58
                                op.bn1.bn6.ToTrimmedString()
1343
58
                            )
1344
58
                        ),
1345
58
                        ::mcl::bn::Fp6(
1346
58
                            ::mcl::bn::Fp2(
1347
58
                                op.bn1.bn7.ToTrimmedString(),
1348
58
                                op.bn1.bn8.ToTrimmedString()
1349
58
                            ),
1350
58
                            ::mcl::bn::Fp2(
1351
58
                                op.bn1.bn9.ToTrimmedString(),
1352
58
                                op.bn1.bn10.ToTrimmedString()
1353
58
                            ),
1354
58
                            ::mcl::bn::Fp2(
1355
58
                                op.bn1.bn11.ToTrimmedString(),
1356
58
                                op.bn1.bn12.ToTrimmedString()
1357
58
                            )
1358
58
                        )
1359
58
                    );
1360
58
                return mcl_detail::ToComponentFp12(a+b);
1361
64
            case    CF_CALCOP("Sub(A,B)"):
1362
64
                a = ::mcl::bn::Fp12(
1363
64
                        ::mcl::bn::Fp6(
1364
64
                            ::mcl::bn::Fp2(
1365
64
                                op.bn0.bn1.ToTrimmedString(),
1366
64
                                op.bn0.bn2.ToTrimmedString()
1367
64
                            ),
1368
64
                            ::mcl::bn::Fp2(
1369
64
                                op.bn0.bn3.ToTrimmedString(),
1370
64
                                op.bn0.bn4.ToTrimmedString()
1371
64
                            ),
1372
64
                            ::mcl::bn::Fp2(
1373
64
                                op.bn0.bn5.ToTrimmedString(),
1374
64
                                op.bn0.bn6.ToTrimmedString()
1375
64
                            )
1376
64
                        ),
1377
64
                        ::mcl::bn::Fp6(
1378
64
                            ::mcl::bn::Fp2(
1379
64
                                op.bn0.bn7.ToTrimmedString(),
1380
64
                                op.bn0.bn8.ToTrimmedString()
1381
64
                            ),
1382
64
                            ::mcl::bn::Fp2(
1383
64
                                op.bn0.bn9.ToTrimmedString(),
1384
64
                                op.bn0.bn10.ToTrimmedString()
1385
64
                            ),
1386
64
                            ::mcl::bn::Fp2(
1387
64
                                op.bn0.bn11.ToTrimmedString(),
1388
64
                                op.bn0.bn12.ToTrimmedString()
1389
64
                            )
1390
64
                        )
1391
64
                    );
1392
64
                b = ::mcl::bn::Fp12(
1393
64
                        ::mcl::bn::Fp6(
1394
64
                            ::mcl::bn::Fp2(
1395
64
                                op.bn1.bn1.ToTrimmedString(),
1396
64
                                op.bn1.bn2.ToTrimmedString()
1397
64
                            ),
1398
64
                            ::mcl::bn::Fp2(
1399
64
                                op.bn1.bn3.ToTrimmedString(),
1400
64
                                op.bn1.bn4.ToTrimmedString()
1401
64
                            ),
1402
64
                            ::mcl::bn::Fp2(
1403
64
                                op.bn1.bn5.ToTrimmedString(),
1404
64
                                op.bn1.bn6.ToTrimmedString()
1405
64
                            )
1406
64
                        ),
1407
64
                        ::mcl::bn::Fp6(
1408
64
                            ::mcl::bn::Fp2(
1409
64
                                op.bn1.bn7.ToTrimmedString(),
1410
64
                                op.bn1.bn8.ToTrimmedString()
1411
64
                            ),
1412
64
                            ::mcl::bn::Fp2(
1413
64
                                op.bn1.bn9.ToTrimmedString(),
1414
64
                                op.bn1.bn10.ToTrimmedString()
1415
64
                            ),
1416
64
                            ::mcl::bn::Fp2(
1417
64
                                op.bn1.bn11.ToTrimmedString(),
1418
64
                                op.bn1.bn12.ToTrimmedString()
1419
64
                            )
1420
64
                        )
1421
64
                    );
1422
64
                return mcl_detail::ToComponentFp12(a-b);
1423
147
            case    CF_CALCOP("Mul(A,B)"):
1424
147
                a = ::mcl::bn::Fp12(
1425
147
                        ::mcl::bn::Fp6(
1426
147
                            ::mcl::bn::Fp2(
1427
147
                                op.bn0.bn1.ToTrimmedString(),
1428
147
                                op.bn0.bn2.ToTrimmedString()
1429
147
                            ),
1430
147
                            ::mcl::bn::Fp2(
1431
147
                                op.bn0.bn3.ToTrimmedString(),
1432
147
                                op.bn0.bn4.ToTrimmedString()
1433
147
                            ),
1434
147
                            ::mcl::bn::Fp2(
1435
147
                                op.bn0.bn5.ToTrimmedString(),
1436
147
                                op.bn0.bn6.ToTrimmedString()
1437
147
                            )
1438
147
                        ),
1439
147
                        ::mcl::bn::Fp6(
1440
147
                            ::mcl::bn::Fp2(
1441
147
                                op.bn0.bn7.ToTrimmedString(),
1442
147
                                op.bn0.bn8.ToTrimmedString()
1443
147
                            ),
1444
147
                            ::mcl::bn::Fp2(
1445
147
                                op.bn0.bn9.ToTrimmedString(),
1446
147
                                op.bn0.bn10.ToTrimmedString()
1447
147
                            ),
1448
147
                            ::mcl::bn::Fp2(
1449
147
                                op.bn0.bn11.ToTrimmedString(),
1450
147
                                op.bn0.bn12.ToTrimmedString()
1451
147
                            )
1452
147
                        )
1453
147
                    );
1454
147
                b = ::mcl::bn::Fp12(
1455
147
                        ::mcl::bn::Fp6(
1456
147
                            ::mcl::bn::Fp2(
1457
147
                                op.bn1.bn1.ToTrimmedString(),
1458
147
                                op.bn1.bn2.ToTrimmedString()
1459
147
                            ),
1460
147
                            ::mcl::bn::Fp2(
1461
147
                                op.bn1.bn3.ToTrimmedString(),
1462
147
                                op.bn1.bn4.ToTrimmedString()
1463
147
                            ),
1464
147
                            ::mcl::bn::Fp2(
1465
147
                                op.bn1.bn5.ToTrimmedString(),
1466
147
                                op.bn1.bn6.ToTrimmedString()
1467
147
                            )
1468
147
                        ),
1469
147
                        ::mcl::bn::Fp6(
1470
147
                            ::mcl::bn::Fp2(
1471
147
                                op.bn1.bn7.ToTrimmedString(),
1472
147
                                op.bn1.bn8.ToTrimmedString()
1473
147
                            ),
1474
147
                            ::mcl::bn::Fp2(
1475
147
                                op.bn1.bn9.ToTrimmedString(),
1476
147
                                op.bn1.bn10.ToTrimmedString()
1477
147
                            ),
1478
147
                            ::mcl::bn::Fp2(
1479
147
                                op.bn1.bn11.ToTrimmedString(),
1480
147
                                op.bn1.bn12.ToTrimmedString()
1481
147
                            )
1482
147
                        )
1483
147
                    );
1484
147
                return mcl_detail::ToComponentFp12(a*b);
1485
89
            case    CF_CALCOP("InvMod(A,B)"):
1486
89
                a = ::mcl::bn::Fp12(
1487
89
                        ::mcl::bn::Fp6(
1488
89
                            ::mcl::bn::Fp2(
1489
89
                                op.bn0.bn1.ToTrimmedString(),
1490
89
                                op.bn0.bn2.ToTrimmedString()
1491
89
                            ),
1492
89
                            ::mcl::bn::Fp2(
1493
89
                                op.bn0.bn3.ToTrimmedString(),
1494
89
                                op.bn0.bn4.ToTrimmedString()
1495
89
                            ),
1496
89
                            ::mcl::bn::Fp2(
1497
89
                                op.bn0.bn5.ToTrimmedString(),
1498
89
                                op.bn0.bn6.ToTrimmedString()
1499
89
                            )
1500
89
                        ),
1501
89
                        ::mcl::bn::Fp6(
1502
89
                            ::mcl::bn::Fp2(
1503
89
                                op.bn0.bn7.ToTrimmedString(),
1504
89
                                op.bn0.bn8.ToTrimmedString()
1505
89
                            ),
1506
89
                            ::mcl::bn::Fp2(
1507
89
                                op.bn0.bn9.ToTrimmedString(),
1508
89
                                op.bn0.bn10.ToTrimmedString()
1509
89
                            ),
1510
89
                            ::mcl::bn::Fp2(
1511
89
                                op.bn0.bn11.ToTrimmedString(),
1512
89
                                op.bn0.bn12.ToTrimmedString()
1513
89
                            )
1514
89
                        )
1515
89
                    );
1516
1517
89
                if ( !a.isZero() ) {
1518
52
                    ::mcl::bn::Fp12::inv(result, a);
1519
52
                    return mcl_detail::ToComponentFp12(result);
1520
52
                }
1521
37
                break;
1522
37
            case    CF_CALCOP("Neg(A)"):
1523
33
                a = ::mcl::bn::Fp12(
1524
33
                        ::mcl::bn::Fp6(
1525
33
                            ::mcl::bn::Fp2(
1526
33
                                op.bn0.bn1.ToTrimmedString(),
1527
33
                                op.bn0.bn2.ToTrimmedString()
1528
33
                            ),
1529
33
                            ::mcl::bn::Fp2(
1530
33
                                op.bn0.bn3.ToTrimmedString(),
1531
33
                                op.bn0.bn4.ToTrimmedString()
1532
33
                            ),
1533
33
                            ::mcl::bn::Fp2(
1534
33
                                op.bn0.bn5.ToTrimmedString(),
1535
33
                                op.bn0.bn6.ToTrimmedString()
1536
33
                            )
1537
33
                        ),
1538
33
                        ::mcl::bn::Fp6(
1539
33
                            ::mcl::bn::Fp2(
1540
33
                                op.bn0.bn7.ToTrimmedString(),
1541
33
                                op.bn0.bn8.ToTrimmedString()
1542
33
                            ),
1543
33
                            ::mcl::bn::Fp2(
1544
33
                                op.bn0.bn9.ToTrimmedString(),
1545
33
                                op.bn0.bn10.ToTrimmedString()
1546
33
                            ),
1547
33
                            ::mcl::bn::Fp2(
1548
33
                                op.bn0.bn11.ToTrimmedString(),
1549
33
                                op.bn0.bn12.ToTrimmedString()
1550
33
                            )
1551
33
                        )
1552
33
                    );
1553
33
                ::mcl::bn::Fp12::neg(result, a);
1554
33
                return mcl_detail::ToComponentFp12(result);
1555
44
            case    CF_CALCOP("Conjugate(A)"):
1556
44
                a = ::mcl::bn::Fp12(
1557
44
                        ::mcl::bn::Fp6(
1558
44
                            ::mcl::bn::Fp2(
1559
44
                                op.bn0.bn1.ToTrimmedString(),
1560
44
                                op.bn0.bn2.ToTrimmedString()
1561
44
                            ),
1562
44
                            ::mcl::bn::Fp2(
1563
44
                                op.bn0.bn3.ToTrimmedString(),
1564
44
                                op.bn0.bn4.ToTrimmedString()
1565
44
                            ),
1566
44
                            ::mcl::bn::Fp2(
1567
44
                                op.bn0.bn5.ToTrimmedString(),
1568
44
                                op.bn0.bn6.ToTrimmedString()
1569
44
                            )
1570
44
                        ),
1571
44
                        ::mcl::bn::Fp6(
1572
44
                            ::mcl::bn::Fp2(
1573
44
                                op.bn0.bn7.ToTrimmedString(),
1574
44
                                op.bn0.bn8.ToTrimmedString()
1575
44
                            ),
1576
44
                            ::mcl::bn::Fp2(
1577
44
                                op.bn0.bn9.ToTrimmedString(),
1578
44
                                op.bn0.bn10.ToTrimmedString()
1579
44
                            ),
1580
44
                            ::mcl::bn::Fp2(
1581
44
                                op.bn0.bn11.ToTrimmedString(),
1582
44
                                op.bn0.bn12.ToTrimmedString()
1583
44
                            )
1584
44
                        )
1585
44
                    );
1586
44
                ::mcl::bn::Fp12::unitaryInv(result, a);
1587
44
                return mcl_detail::ToComponentFp12(result);
1588
76
            case    CF_CALCOP("Sqr(A)"):
1589
76
                a = ::mcl::bn::Fp12(
1590
76
                        ::mcl::bn::Fp6(
1591
76
                            ::mcl::bn::Fp2(
1592
76
                                op.bn0.bn1.ToTrimmedString(),
1593
76
                                op.bn0.bn2.ToTrimmedString()
1594
76
                            ),
1595
76
                            ::mcl::bn::Fp2(
1596
76
                                op.bn0.bn3.ToTrimmedString(),
1597
76
                                op.bn0.bn4.ToTrimmedString()
1598
76
                            ),
1599
76
                            ::mcl::bn::Fp2(
1600
76
                                op.bn0.bn5.ToTrimmedString(),
1601
76
                                op.bn0.bn6.ToTrimmedString()
1602
76
                            )
1603
76
                        ),
1604
76
                        ::mcl::bn::Fp6(
1605
76
                            ::mcl::bn::Fp2(
1606
76
                                op.bn0.bn7.ToTrimmedString(),
1607
76
                                op.bn0.bn8.ToTrimmedString()
1608
76
                            ),
1609
76
                            ::mcl::bn::Fp2(
1610
76
                                op.bn0.bn9.ToTrimmedString(),
1611
76
                                op.bn0.bn10.ToTrimmedString()
1612
76
                            ),
1613
76
                            ::mcl::bn::Fp2(
1614
76
                                op.bn0.bn11.ToTrimmedString(),
1615
76
                                op.bn0.bn12.ToTrimmedString()
1616
76
                            )
1617
76
                        )
1618
76
                    );
1619
76
                ::mcl::bn::Fp12::sqr(result, a);
1620
76
                return mcl_detail::ToComponentFp12(result);
1621
#if 0
1622
            case    CF_CALCOP("CyclotomicSqr(A)"):
1623
                a = ::mcl::bn::Fp12(
1624
                        ::mcl::bn::Fp6(
1625
                            ::mcl::bn::Fp2(
1626
                                op.bn0.bn1.ToTrimmedString(),
1627
                                op.bn0.bn2.ToTrimmedString()
1628
                            ),
1629
                            ::mcl::bn::Fp2(
1630
                                op.bn0.bn3.ToTrimmedString(),
1631
                                op.bn0.bn4.ToTrimmedString()
1632
                            ),
1633
                            ::mcl::bn::Fp2(
1634
                                op.bn0.bn5.ToTrimmedString(),
1635
                                op.bn0.bn6.ToTrimmedString()
1636
                            )
1637
                        ),
1638
                        ::mcl::bn::Fp6(
1639
                            ::mcl::bn::Fp2(
1640
                                op.bn0.bn7.ToTrimmedString(),
1641
                                op.bn0.bn8.ToTrimmedString()
1642
                            ),
1643
                            ::mcl::bn::Fp2(
1644
                                op.bn0.bn9.ToTrimmedString(),
1645
                                op.bn0.bn10.ToTrimmedString()
1646
                            ),
1647
                            ::mcl::bn::Fp2(
1648
                                op.bn0.bn11.ToTrimmedString(),
1649
                                op.bn0.bn12.ToTrimmedString()
1650
                            )
1651
                        )
1652
                    );
1653
                if ( !a.isZero() ) {
1654
                    ::mcl::bn::local::mapToCyclotomic(result, a);
1655
                    return mcl_detail::ToComponentFp12(result);
1656
                }
1657
                break;
1658
#endif
1659
999
        }
1660
999
    } catch ( ... ) {
1661
186
    }
1662
1663
686
    return std::nullopt;
1664
999
}
1665
1666
10.0k
bool mcl::SupportsModularBignumCalc(void) const {
1667
10.0k
    return true;
1668
10.0k
}
1669
1670
} /* namespace module */
1671
} /* namespace cryptofuzz */