Coverage Report

Created: 2026-10-13 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cryptofuzz/modules/relic/bn_ops.cpp
Line
Count
Source
1
#include "bn_ops.h"
2
#include <cryptofuzz/util.h>
3
#include <limits>
4
5
3.13k
#define GET_WHICH(max) uint8_t which = 0; try { which = ds.Get<uint8_t>(); which %= ((max)+1); } catch ( ... ) { }
6
7
namespace cryptofuzz {
8
namespace module {
9
namespace relic_bignum {
10
11
39
bool Add::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
12
39
    (void)ds;
13
14
39
    RLC_TRY {
15
39
        /* noret */ bn_add(res.Get(), bn[0].Get(), bn[1].Get());
16
78
    } RLC_CATCH_ANY {
17
0
        return false;
18
0
    }
19
20
39
    return true;
21
39
}
22
23
109
bool Sub::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
24
109
    (void)ds;
25
26
109
    RLC_TRY {
27
109
        /* noret */ bn_sub(res.Get(), bn[0].Get(), bn[1].Get());
28
218
    } RLC_CATCH_ANY {
29
0
        return false;
30
0
    }
31
32
109
    return true;
33
109
}
34
35
179
bool Mul::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
36
179
    GET_WHICH(3);
37
179
    switch ( which ) {
38
59
        case    0:
39
59
            RLC_TRY {
40
59
                /* noret */ bn_mul(res.Get(), bn[0].Get(), bn[1].Get());
41
118
            } RLC_CATCH_ANY {
42
0
                return false;
43
0
            }
44
59
            return true;
45
65
        case    1:
46
65
            RLC_TRY {
47
65
                /* noret */ bn_mul_basic(res.Get(), bn[0].Get(), bn[1].Get());
48
130
            } RLC_CATCH_ANY {
49
0
                return false;
50
0
            }
51
65
            return true;
52
25
        case    2:
53
25
            RLC_TRY {
54
25
                /* noret */ bn_mul_comba(res.Get(), bn[0].Get(), bn[1].Get());
55
50
            } RLC_CATCH_ANY {
56
0
                return false;
57
0
            }
58
25
            return true;
59
30
        case    3:
60
30
            RLC_TRY {
61
30
                /* noret */ bn_mul_karat(res.Get(), bn[0].Get(), bn[1].Get());
62
60
            } RLC_CATCH_ANY {
63
0
                return false;
64
0
            }
65
30
            return true;
66
179
    }
67
68
0
    return false;
69
179
}
70
71
284
bool Sqr::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
72
284
    GET_WHICH(3);
73
284
    switch ( which ) {
74
169
        case    0:
75
169
            RLC_TRY {
76
169
                /* noret */ bn_sqr(res.Get(), bn[0].Get());
77
338
            } RLC_CATCH_ANY {
78
0
                return false;
79
0
            }
80
169
            return true;
81
69
        case    1:
82
69
            RLC_TRY {
83
69
                /* noret */ bn_sqr_basic(res.Get(), bn[0].Get());
84
138
            } RLC_CATCH_ANY {
85
0
                return false;
86
0
            }
87
69
            return true;
88
21
        case    2:
89
21
            RLC_TRY {
90
21
                /* noret */ bn_sqr_comba(res.Get(), bn[0].Get());
91
42
            } RLC_CATCH_ANY {
92
0
                return false;
93
0
            }
94
21
            return true;
95
25
        case    3:
96
25
            RLC_TRY {
97
25
                /* noret */ bn_sqr_karat(res.Get(), bn[0].Get());
98
50
            } RLC_CATCH_ANY {
99
0
                return false;
100
0
            }
101
25
            return true;
102
284
    }
103
104
0
    return false;
105
284
}
106
107
89
bool Div::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
108
89
    (void)ds;
109
110
89
    RLC_TRY {
111
89
        /* noret */ bn_div(res.Get(), bn[0].Get(), bn[1].Get());
112
178
    } RLC_CATCH_ANY {
113
11
        return false;
114
11
    }
115
116
78
    return true;
117
89
}
118
119
enum GCDType : uint8_t {
120
    GCD = 0,
121
    ExtGCD_X = 1,
122
    ExtGCD_Y = 2,
123
};
124
125
398
static void GCD_ExtGCD_SetResult(bn_t& res, const bn_t& X, const bn_t& Y, const GCDType type) {
126
398
    if ( type == GCDType::GCD ) {
127
        /* do nothing */
128
398
    } else if ( type == GCDType::ExtGCD_X ) {
129
0
        bn_copy(res, X);
130
0
    } else if ( type == GCDType::ExtGCD_Y ) {
131
0
        bn_copy(res, Y);
132
0
    } else {
133
0
        CF_UNREACHABLE();
134
0
    }
135
398
}
136
137
971
static bool GCD_ExtGCD(Datasource& ds, Bignum& res, std::vector<Bignum>& bn, const GCDType type) {
138
971
    GET_WHICH(8);
139
140
971
    if ( type == GCDType::ExtGCD_X || type == GCDType::ExtGCD_Y ) {
141
0
        if ( which >= 0 && which <= 3 ) {
142
0
            which += 4;
143
0
        }
144
0
    }
145
146
971
    switch ( which ) {
147
73
        case    0:
148
73
            RLC_TRY {
149
73
                /* noret */ bn_gcd(res.Get(), bn[0].Get(), bn[1].Get());
150
146
            } RLC_CATCH_ANY {
151
0
                return false;
152
0
            }
153
73
            return true;
154
17
        case    1:
155
17
            RLC_TRY {
156
17
                /* noret */ bn_gcd_basic(res.Get(), bn[0].Get(), bn[1].Get());
157
34
            } RLC_CATCH_ANY {
158
0
                return false;
159
0
            }
160
17
            return true;
161
292
        case    2:
162
292
            RLC_TRY {
163
292
                /* noret */ bn_gcd_lehme(res.Get(), bn[0].Get(), bn[1].Get());
164
584
            } RLC_CATCH_ANY {
165
0
                return false;
166
0
            }
167
292
            return true;
168
84
        case    3:
169
84
            RLC_TRY {
170
84
                /* noret */ bn_gcd_binar(res.Get(), bn[0].Get(), bn[1].Get());
171
168
            } RLC_CATCH_ANY {
172
0
                return false;
173
0
            }
174
84
            return true;
175
41
        case    4:
176
41
            {
177
41
                CF_CHECK_NE(bn_bits(bn[0].Get()), 0);
178
31
                CF_CHECK_NE(bn_bits(bn[1].Get()), 0);
179
180
20
                Bignum t1(ds), t2(ds);
181
182
20
                RLC_TRY {
183
20
                    /* noret */ bn_gcd_ext(res.Get(), t1.Get(), t2.Get(), bn[0].Get(), bn[1].Get());
184
40
                } RLC_CATCH_ANY {
185
0
                    return false;
186
0
                }
187
188
20
                CF_NORET(GCD_ExtGCD_SetResult(res.Get(), t1.Get(), t2.Get(), type));
189
190
20
                return true;
191
20
            }
192
54
        case    5:
193
54
            {
194
54
                CF_CHECK_NE(bn_bits(bn[0].Get()), 0);
195
43
                CF_CHECK_NE(bn_bits(bn[1].Get()), 0);
196
197
31
                Bignum t1(ds), t2(ds);
198
199
31
                RLC_TRY {
200
31
                    /* noret */ bn_gcd_ext_basic(res.Get(), t1.Get(), t2.Get(), bn[0].Get(), bn[1].Get());
201
62
                } RLC_CATCH_ANY {
202
0
                    return false;
203
0
                }
204
205
31
                CF_NORET(GCD_ExtGCD_SetResult(res.Get(), t1.Get(), t2.Get(), type));
206
207
31
                return true;
208
31
            }
209
256
        case    6:
210
256
            {
211
256
                CF_CHECK_NE(bn_bits(bn[0].Get()), 0);
212
243
                CF_CHECK_NE(bn_bits(bn[1].Get()), 0);
213
214
228
                Bignum t1(ds), t2(ds);
215
216
228
                RLC_TRY {
217
228
                    /* noret */ bn_gcd_ext_lehme(res.Get(), t1.Get(), t2.Get(), bn[0].Get(), bn[1].Get());
218
456
                } RLC_CATCH_ANY {
219
0
                    return false;
220
0
                }
221
222
228
                CF_NORET(GCD_ExtGCD_SetResult(res.Get(), t1.Get(), t2.Get(), type));
223
224
228
                return true;
225
228
            }
226
142
        case    7:
227
142
            {
228
142
                CF_CHECK_NE(bn_bits(bn[0].Get()), 0);
229
138
                CF_CHECK_NE(bn_bits(bn[1].Get()), 0);
230
231
127
                Bignum t1(ds), t2(ds);
232
233
127
                RLC_TRY {
234
127
                    /* noret */ bn_gcd_ext_binar(res.Get(), t1.Get(), t2.Get(), bn[0].Get(), bn[1].Get());
235
254
                } RLC_CATCH_ANY {
236
8
                    return false;
237
8
                }
238
239
119
                CF_NORET(GCD_ExtGCD_SetResult(res.Get(), t1.Get(), t2.Get(), type));
240
241
119
                return true;
242
127
            }
243
12
        case    8:
244
12
            {
245
                /* XXX */
246
12
                goto end;
247
0
                CF_CHECK_NE(bn_bits(bn[0].Get()), 0);
248
0
                CF_CHECK_NE(bn_bits(bn[1].Get()), 0);
249
250
0
                Bignum t1(ds), t2(ds), t3(ds);
251
252
0
                RLC_TRY {
253
0
                    /* noret */ bn_gcd_ext_mid(res.Get(), t1.Get(), t2.Get(), t3.Get(), bn[0].Get(), bn[1].Get());
254
0
                } RLC_CATCH_ANY {
255
0
                    return false;
256
0
                }
257
258
0
                CF_NORET(GCD_ExtGCD_SetResult(res.Get(), t1.Get(), t2.Get(), type));
259
260
0
                return true;
261
0
            }
262
971
    }
263
264
99
end:
265
99
    return false;
266
971
}
267
268
971
bool GCD::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
269
971
    return GCD_ExtGCD(ds, res, bn, GCDType::GCD);
270
971
}
271
272
0
bool ExtGCD_X::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
273
0
    return GCD_ExtGCD(ds, res, bn, GCDType::ExtGCD_X);
274
0
}
275
276
0
bool ExtGCD_Y::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
277
0
    return GCD_ExtGCD(ds, res, bn, GCDType::ExtGCD_Y);
278
0
}
279
280
298
bool LCM::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
281
298
    (void)ds;
282
283
298
    RLC_TRY {
284
298
        /* noret */ bn_lcm(res.Get(), bn[0].Get(), bn[1].Get());
285
596
    } RLC_CATCH_ANY {
286
10
        return false;
287
10
    }
288
289
288
    return true;
290
298
}
291
292
278
bool InvMod::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
293
278
    return false;
294
0
    (void)ds;
295
296
0
    RLC_TRY {
297
0
        /* noret */ bn_mod_inv(res.Get(), bn[0].Get(), bn[1].Get());
298
0
    } RLC_CATCH_ANY {
299
        /* Modular inverse does not exist */
300
0
        if ( res.Set("0") == false ) {
301
0
            return false;
302
0
        }
303
0
    }
304
305
0
    return true;
306
0
}
307
308
63
bool LShift1::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
309
63
    GET_WHICH(1);
310
63
    switch ( which ) {
311
41
        case    0:
312
41
            RLC_TRY {
313
41
                bn_lsh(res.Get(), bn[0].Get(), 1);
314
82
            } RLC_CATCH_ANY {
315
0
                return false;
316
0
            }
317
41
            return true;
318
22
        case    1:
319
22
            RLC_TRY {
320
22
                bn_dbl(res.Get(), bn[0].Get());
321
44
            } RLC_CATCH_ANY {
322
0
                return false;
323
0
            }
324
22
            return true;
325
63
    }
326
327
0
    return false;
328
63
}
329
330
486
bool Jacobi::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
331
486
    (void)ds;
332
333
486
    RLC_TRY {
334
486
        res.Set(std::to_string(bn_smb_jac(bn[0].Get(), bn[1].Get())));
335
972
    } RLC_CATCH_ANY {
336
19
        return false;
337
19
    }
338
339
467
    return true;
340
486
}
341
342
32
bool Cmp::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
343
32
    bool ret = false;
344
32
    (void)ds;
345
346
32
    RLC_TRY {
347
32
        const auto r = bn_cmp(bn[0].Get(), bn[1].Get());
348
349
32
        if ( r == RLC_EQ ) {
350
11
            CF_CHECK_TRUE(res.Set("0"));
351
21
        } else if ( r == RLC_LT ) {
352
10
            CF_CHECK_TRUE(res.Set("-1"));
353
11
        } else if ( r == RLC_GT ) {
354
11
            CF_CHECK_TRUE(res.Set("1"));
355
11
        } else {
356
0
            CF_UNREACHABLE();
357
0
        }
358
359
32
        ret = true;
360
64
    } RLC_CATCH_ANY {
361
        /* Fall through */
362
0
    }
363
364
32
end:
365
32
    return ret;
366
32
}
367
368
306
bool Mod::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
369
306
    GET_WHICH(5);
370
306
    switch ( which ) {
371
48
        case    0:
372
48
            RLC_TRY {
373
48
                /* noret */ bn_mod(res.Get(), bn[0].Get(), bn[1].Get());
374
96
            } RLC_CATCH_ANY {
375
12
                return false;
376
12
            }
377
36
            return true;
378
23
        case    1:
379
23
            RLC_TRY {
380
23
                /* noret */ bn_mod_basic(res.Get(), bn[0].Get(), bn[1].Get());
381
46
            } RLC_CATCH_ANY {
382
10
                return false;
383
10
            }
384
13
            return true;
385
76
        case    2:
386
76
            {
387
76
                Bignum t1(ds);
388
389
76
                RLC_TRY {
390
76
                    bn_mod_pre_barrt(t1.Get(), bn[1].Get());
391
76
                    bn_mod_barrt(res.Get(), bn[0].Get(), bn[1].Get(), t1.Get());
392
152
                } RLC_CATCH_ANY {
393
17
                    return false;
394
17
                }
395
396
59
                return true;
397
76
            }
398
68
        case    3:
399
68
            {
400
68
                Bignum t1(ds), t2(ds);
401
402
68
                RLC_TRY {
403
68
                    bn_mod_monty_conv(t1.Get(), bn[0].Get(), bn[1].Get());
404
68
                    bn_mod_pre_monty(t2.Get(), bn[1].Get());
405
68
                    bn_mod_monty_basic(res.Get(), t1.Get(), bn[1].Get(), t2.Get());
406
136
                } RLC_CATCH_ANY {
407
15
                    return false;
408
15
                }
409
410
53
                return true;
411
68
            }
412
23
        case    4:
413
23
            {
414
23
                Bignum t1(ds), t2(ds);
415
416
23
                RLC_TRY {
417
23
                    bn_mod_monty_conv(t1.Get(), bn[0].Get(), bn[1].Get());
418
23
                    bn_mod_pre_monty(t2.Get(), bn[1].Get());
419
23
                    bn_mod_monty_comba(res.Get(), t1.Get(), bn[1].Get(), t2.Get());
420
46
                } RLC_CATCH_ANY {
421
12
                    return false;
422
12
                }
423
424
11
                return true;
425
23
            }
426
68
        case    5:
427
68
            {
428
68
                Bignum t1(ds);
429
430
68
                RLC_TRY {
431
68
                    bn_mod_pre_pmers(t1.Get(), bn[1].Get());
432
68
                    bn_mod_pmers(res.Get(), bn[0].Get(), bn[1].Get(), t1.Get());
433
136
                } RLC_CATCH_ANY {
434
11
                    return false;
435
11
                }
436
437
57
                return true;
438
68
            }
439
306
    }
440
441
0
    return false;
442
443
306
}
444
445
30
bool IsEven::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
446
30
    bool ret = false;
447
30
    (void)ds;
448
449
30
    RLC_TRY {
450
30
        const auto r = bn_is_even(bn[0].Get());
451
30
        if ( r == 1 ) {
452
17
            CF_CHECK_TRUE(res.Set("1"));
453
17
        } else if ( r == 0 ) {
454
13
            CF_CHECK_TRUE(res.Set("0"));
455
13
        } else {
456
0
            CF_UNREACHABLE();
457
0
        }
458
459
30
        ret = true;
460
60
    } RLC_CATCH_ANY {
461
        /* Fall through */
462
0
    }
463
464
30
end:
465
30
    return ret;
466
30
}
467
468
21
bool IsOdd::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
469
21
    bool ret = false;
470
21
    (void)ds;
471
472
21
    RLC_TRY {
473
21
        const auto r = bn_is_even(bn[0].Get());
474
21
        if ( r == 1 ) {
475
10
            CF_CHECK_TRUE(res.Set("0"));
476
11
        } else if ( r == 0 ) {
477
11
            CF_CHECK_TRUE(res.Set("1"));
478
11
        } else {
479
0
            CF_UNREACHABLE();
480
0
        }
481
482
21
        ret = true;
483
42
    } RLC_CATCH_ANY {
484
        /* Fall through */
485
0
    }
486
487
21
end:
488
21
    return ret;
489
21
}
490
491
22
bool IsZero::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
492
22
    bool ret = false;
493
22
    (void)ds;
494
495
22
    RLC_TRY {
496
22
        const auto r = bn_is_zero(bn[0].Get());
497
22
        if ( r == 1 ) {
498
14
            CF_CHECK_TRUE(res.Set("1"));
499
14
        } else if ( r == 0 ) {
500
8
            CF_CHECK_TRUE(res.Set("0"));
501
8
        } else {
502
0
            CF_UNREACHABLE();
503
0
        }
504
505
22
        ret = true;
506
44
    } RLC_CATCH_ANY {
507
        /* Fall through */
508
0
    }
509
510
22
end:
511
22
    return ret;
512
22
}
513
514
108
bool Neg::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
515
108
    (void)ds;
516
517
108
    RLC_TRY {
518
108
        /* noret */ bn_neg(res.Get(), bn[0].Get());
519
216
    } RLC_CATCH_ANY {
520
0
        return false;
521
0
    }
522
523
108
    return true;
524
108
}
525
526
401
bool Sqrt::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
527
401
    (void)ds;
528
529
401
    RLC_TRY {
530
401
        /* noret */ bn_srt(res.Get(), bn[0].Get());
531
802
    } RLC_CATCH_ANY {
532
5
        return false;
533
5
    }
534
535
396
    return true;
536
401
}
537
538
14
bool Abs::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
539
14
    (void)ds;
540
541
14
    RLC_TRY {
542
14
        /* noret */ bn_abs(res.Get(), bn[0].Get());
543
28
    } RLC_CATCH_ANY {
544
0
        return false;
545
0
    }
546
547
14
    return true;
548
14
}
549
550
1.33k
bool ExpMod::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
551
1.33k
    GET_WHICH(3);
552
1.33k
    switch ( which ) {
553
1.15k
        case    0:
554
1.15k
            RLC_TRY {
555
1.15k
                /* noret */ bn_mxp(res.Get(), bn[0].Get(), bn[1].Get(), bn[2].Get());
556
2.31k
            } RLC_CATCH_ANY {
557
12
                return false;
558
12
            }
559
1.14k
            return true;
560
42
        case    1:
561
42
            RLC_TRY {
562
42
                /* noret */ bn_mxp_basic(res.Get(), bn[0].Get(), bn[1].Get(), bn[2].Get());
563
84
            } RLC_CATCH_ANY {
564
4
                return false;
565
4
            }
566
38
            return true;
567
45
        case    2:
568
45
            RLC_TRY {
569
45
                /* noret */ bn_mxp_slide(res.Get(), bn[0].Get(), bn[1].Get(), bn[2].Get());
570
90
            } RLC_CATCH_ANY {
571
10
                return false;
572
10
            }
573
35
            return true;
574
91
        case    3:
575
91
            RLC_TRY {
576
91
                /* noret */ bn_mxp_monty(res.Get(), bn[0].Get(), bn[1].Get(), bn[2].Get());
577
182
            } RLC_CATCH_ANY {
578
14
                return false;
579
14
            }
580
77
            return true;
581
1.33k
    }
582
583
0
    return false;
584
1.33k
}
585
586
12
bool NumBits::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
587
12
    (void)ds;
588
12
    bool ret = false;
589
590
12
    RLC_TRY {
591
12
        CF_CHECK_TRUE(res.Set( std::to_string( bn_bits(bn[0].Get()) ) ));
592
12
        ret = true;
593
24
    } RLC_CATCH_ANY {
594
0
        return false;
595
0
    }
596
597
12
end:
598
12
    return ret;
599
12
}
600
601
37
bool CmpAbs::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
602
37
    bool ret = false;
603
37
    (void)ds;
604
605
37
    RLC_TRY {
606
37
        const auto r = bn_cmp_abs(bn[0].Get(), bn[1].Get());
607
608
37
        if ( r == RLC_EQ ) {
609
6
            CF_CHECK_TRUE(res.Set("0"));
610
31
        } else if ( r == RLC_LT ) {
611
15
            CF_CHECK_TRUE(res.Set("-1"));
612
16
        } else if ( r == RLC_GT ) {
613
16
            CF_CHECK_TRUE(res.Set("1"));
614
16
        } else {
615
0
            CF_UNREACHABLE();
616
0
        }
617
618
37
        ret = true;
619
74
    } RLC_CATCH_ANY {
620
        /* Fall through */
621
0
    }
622
623
37
end:
624
37
    return ret;
625
37
}
626
627
162
bool RShift::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
628
162
    (void)ds;
629
630
162
    auto bits = bn[1].ToSizeT();
631
162
    if ( bits == std::nullopt ) {
632
10
        return false;
633
10
    }
634
635
    /* Not expected to throw */
636
152
    /* noret */ bn_rsh(res.Get(), bn[0].Get(), *bits);
637
638
152
    return true;
639
162
}
640
641
147
bool Bit::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
642
147
    (void)ds;
643
147
    bool ret = false;
644
645
147
    auto bit = bn[1].ToSizeT();
646
147
    if ( bit == std::nullopt ) {
647
10
        return false;
648
10
    }
649
650
137
    if ( (*bit+1) == 0 || (*bit+1) > bn_bits(bn[0].Get()) ) {
651
112
        return false;
652
112
    }
653
654
    /* Not expected to throw */
655
25
    const auto r = bn_get_bit(bn[0].Get(), *bit);
656
657
25
    if ( r == 1 ) {
658
15
        CF_CHECK_TRUE(res.Set("1"));
659
15
    } else if ( r == 0 ) {
660
10
        CF_CHECK_TRUE(res.Set("0"));
661
10
    } else {
662
0
        CF_UNREACHABLE();
663
0
    }
664
665
25
    ret = true;
666
667
25
end:
668
25
    return ret;
669
25
}
670
671
110
bool SetBit::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
672
110
    (void)ds;
673
674
110
    auto bit = bn[1].ToSizeT();
675
110
    if ( bit == std::nullopt ) {
676
0
        return false;
677
0
    }
678
679
110
    if ( (*bit+1) == 0 || (*bit+1) > bn_bits(bn[0].Get()) ) {
680
95
        return false;
681
95
    }
682
683
15
    bn_copy(res.Get(), bn[0].Get());
684
685
    /* Not expected to throw */
686
    /* noret */ bn_set_bit(res.Get(), *bit, 1);
687
688
15
    return true;
689
110
}
690
691
143
bool ClearBit::Run(Datasource& ds, Bignum& res, std::vector<Bignum>& bn) const {
692
143
    (void)ds;
693
694
143
    auto bit = bn[1].ToSizeT();
695
143
    if ( bit == std::nullopt ) {
696
17
        return false;
697
17
    }
698
699
126
    if ( (*bit+1) == 0 || (*bit+1) > bn_bits(bn[0].Get()) ) {
700
115
        return false;
701
115
    }
702
703
11
    bn_copy(res.Get(), bn[0].Get());
704
705
    /* Not expected to throw */
706
    /* noret */ bn_set_bit(res.Get(), *bit, 0);
707
708
11
    return true;
709
126
}
710
711
} /* namespace relic_bignum */
712
} /* namespace module */
713
} /* namespace cryptofuzz */