Coverage Report

Created: 2025-04-24 07:09

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