Coverage Report

Created: 2025-07-11 06:15

/src/Botan-3.4.0/build/include/public/botan/bigint.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* BigInt
3
* (C) 1999-2008,2012,2018 Jack Lloyd
4
*     2007 FlexSecure
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8
9
#ifndef BOTAN_BIGINT_H_
10
#define BOTAN_BIGINT_H_
11
12
#include <botan/exceptn.h>
13
#include <botan/mem_ops.h>
14
#include <botan/secmem.h>
15
#include <botan/types.h>
16
#include <iosfwd>
17
#include <span>
18
19
namespace Botan {
20
21
class RandomNumberGenerator;
22
23
/**
24
 * Arbitrary precision integer
25
 */
26
class BOTAN_PUBLIC_API(2, 0) BigInt final {
27
   public:
28
      /**
29
       * Base enumerator for encoding and decoding
30
       */
31
      enum Base { Decimal = 10, Hexadecimal = 16, Binary = 256 };
32
33
      /**
34
       * Sign symbol definitions for positive and negative numbers
35
       */
36
      enum Sign { Negative = 0, Positive = 1 };
37
38
      /**
39
       * Create empty (zero) BigInt
40
       */
41
12.3M
      BigInt() = default;
42
43
      /**
44
       * Create a 0-value BigInt
45
       */
46
12.6k
      static BigInt zero() { return BigInt(); }
47
48
      /**
49
       * Create a 1-value BigInt
50
       */
51
1.78k
      static BigInt one() { return BigInt::from_word(1); }
52
53
      /**
54
       * Create BigInt from an unsigned 64 bit integer
55
       * @param n initial value of this BigInt
56
       */
57
      static BigInt from_u64(uint64_t n);
58
59
      /**
60
       * Create BigInt from a word (limb)
61
       * @param n initial value of this BigInt
62
       */
63
      static BigInt from_word(word n);
64
65
      /**
66
       * Create BigInt from a signed 32 bit integer
67
       * @param n initial value of this BigInt
68
       */
69
      static BigInt from_s32(int32_t n);
70
71
      /**
72
       * Create BigInt from an unsigned 64 bit integer
73
       * @param n initial value of this BigInt
74
       */
75
      BigInt(uint64_t n);
76
77
      /**
78
       * Copy Constructor
79
       * @param other the BigInt to copy
80
       */
81
4.94M
      BigInt(const BigInt& other) = default;
82
83
      /**
84
       * Create BigInt from a string. If the string starts with 0x the
85
       * rest of the string will be interpreted as hexadecimal digits.
86
       * Otherwise, it will be interpreted as a decimal number.
87
       *
88
       * @param str the string to parse for an integer value
89
       */
90
      explicit BigInt(std::string_view str);
91
92
      /**
93
       * Create a BigInt from an integer in a byte array
94
       * @param buf the byte array holding the value
95
       * @param length size of buf
96
       */
97
      BigInt(const uint8_t buf[], size_t length);
98
99
      /**
100
       * Create a BigInt from an integer in a byte array
101
       * @param vec the byte vector holding the value
102
       */
103
7.45k
      explicit BigInt(std::span<const uint8_t> vec) : BigInt(vec.data(), vec.size()) {}
104
105
      /**
106
       * Create a BigInt from an integer in a byte array
107
       * @param buf the byte array holding the value
108
       * @param length size of buf
109
       * @param base is the number base of the integer in buf
110
       */
111
      BigInt(const uint8_t buf[], size_t length, Base base);
112
113
      /**
114
       * Create a BigInt from an integer in a byte array
115
       *
116
       * Note this function is primarily used for implementing signature
117
       * schemes and is not useful in typical applications.
118
       *
119
       * @param buf the byte array holding the value
120
       * @param length size of buf
121
       * @param max_bits if the resulting integer is more than max_bits,
122
       *        it will be shifted so it is at most max_bits in length.
123
       */
124
      static BigInt from_bytes_with_max_bits(const uint8_t buf[], size_t length, size_t max_bits);
125
126
      /**
127
       * @brief Create a random BigInt of the specified size
128
       *
129
       * @param rng random number generator
130
       * @param bits size in bits
131
       * @param set_high_bit if true, the highest bit is always set
132
       *
133
       * @see randomize
134
       */
135
      BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit = true);
136
137
      /**
138
       * Create BigInt of specified size, all zeros
139
       * @param n size of the internal register in words
140
       */
141
      static BigInt with_capacity(size_t n);
142
143
      /**
144
       * Move constructor
145
       */
146
276k
      BigInt(BigInt&& other) { this->swap(other); }
147
148
17.9M
      ~BigInt() { const_time_unpoison(); }
149
150
      /**
151
       * Move assignment
152
       */
153
3.29M
      BigInt& operator=(BigInt&& other) {
154
3.29M
         if(this != &other) {
155
3.29M
            this->swap(other);
156
3.29M
         }
157
158
3.29M
         return (*this);
159
3.29M
      }
160
161
      /**
162
       * Copy assignment
163
       */
164
16.7M
      BigInt& operator=(const BigInt&) = default;
165
166
      /**
167
       * Swap this value with another
168
       * @param other BigInt to swap values with
169
       */
170
107M
      void swap(BigInt& other) {
171
107M
         m_data.swap(other.m_data);
172
107M
         std::swap(m_signedness, other.m_signedness);
173
107M
      }
174
175
0
      friend void swap(BigInt& x, BigInt& y) { x.swap(y); }
176
177
123M
      void swap_reg(secure_vector<word>& reg) {
178
123M
         m_data.swap(reg);
179
         // sign left unchanged
180
123M
      }
181
182
      /**
183
       * += operator
184
       * @param y the BigInt to add to this
185
       */
186
218k
      BigInt& operator+=(const BigInt& y) { return add(y.data(), y.sig_words(), y.sign()); }
187
188
      /**
189
       * += operator
190
       * @param y the word to add to this
191
       */
192
6
      BigInt& operator+=(word y) { return add(&y, 1, Positive); }
193
194
      /**
195
       * -= operator
196
       * @param y the BigInt to subtract from this
197
       */
198
221k
      BigInt& operator-=(const BigInt& y) { return sub(y.data(), y.sig_words(), y.sign()); }
199
200
      /**
201
       * -= operator
202
       * @param y the word to subtract from this
203
       */
204
0
      BigInt& operator-=(word y) { return sub(&y, 1, Positive); }
205
206
      /**
207
       * *= operator
208
       * @param y the BigInt to multiply with this
209
       */
210
      BigInt& operator*=(const BigInt& y);
211
212
      /**
213
       * *= operator
214
       * @param y the word to multiply with this
215
       */
216
      BigInt& operator*=(word y);
217
218
      /**
219
       * /= operator
220
       * @param y the BigInt to divide this by
221
       */
222
      BigInt& operator/=(const BigInt& y);
223
224
      /**
225
       * Modulo operator
226
       * @param y the modulus to reduce this by
227
       */
228
      BigInt& operator%=(const BigInt& y);
229
230
      /**
231
       * Modulo operator
232
       * @param y the modulus (word) to reduce this by
233
       */
234
      word operator%=(word y);
235
236
      /**
237
       * Left shift operator
238
       * @param shift the number of bits to shift this left by
239
       */
240
      BigInt& operator<<=(size_t shift);
241
242
      /**
243
       * Right shift operator
244
       * @param shift the number of bits to shift this right by
245
       */
246
      BigInt& operator>>=(size_t shift);
247
248
      /**
249
       * Increment operator
250
       */
251
0
      BigInt& operator++() { return (*this += 1); }
252
253
      /**
254
       * Decrement operator
255
       */
256
0
      BigInt& operator--() { return (*this -= 1); }
257
258
      /**
259
       * Postfix increment operator
260
       */
261
0
      BigInt operator++(int) {
262
0
         BigInt x = (*this);
263
0
         ++(*this);
264
0
         return x;
265
0
      }
266
267
      /**
268
       * Postfix decrement operator
269
       */
270
0
      BigInt operator--(int) {
271
0
         BigInt x = (*this);
272
0
         --(*this);
273
0
         return x;
274
0
      }
275
276
      /**
277
       * Unary negation operator
278
       * @return negative this
279
       */
280
      BigInt operator-() const;
281
282
      /**
283
       * ! operator
284
       * @return true iff this is zero, otherwise false
285
       */
286
0
      bool operator!() const { return (!is_nonzero()); }
287
288
      static BigInt add2(const BigInt& x, const word y[], size_t y_words, Sign y_sign);
289
290
      BigInt& add(const word y[], size_t y_words, Sign sign);
291
292
221k
      BigInt& sub(const word y[], size_t y_words, Sign sign) {
293
221k
         return add(y, y_words, sign == Positive ? Negative : Positive);
294
221k
      }
295
296
      /**
297
       * Multiply this with y
298
       * @param y the BigInt to multiply with this
299
       * @param ws a temp workspace
300
       */
301
      BigInt& mul(const BigInt& y, secure_vector<word>& ws);
302
303
      /**
304
       * Square value of *this
305
       * @param ws a temp workspace
306
       */
307
      BigInt& square(secure_vector<word>& ws);
308
309
      /**
310
       * Set *this to y - *this
311
       * @param y the BigInt to subtract from as a sequence of words
312
       * @param y_words length of y in words
313
       * @param ws a temp workspace
314
       */
315
      BigInt& rev_sub(const word y[], size_t y_words, secure_vector<word>& ws);
316
317
      /**
318
       * Set *this to (*this + y) % mod
319
       * This function assumes *this is >= 0 && < mod
320
       * @param y the BigInt to add - assumed y >= 0 and y < mod
321
       * @param mod the positive modulus
322
       * @param ws a temp workspace
323
       */
324
      BigInt& mod_add(const BigInt& y, const BigInt& mod, secure_vector<word>& ws);
325
326
      /**
327
       * Set *this to (*this - y) % mod
328
       * This function assumes *this is >= 0 && < mod
329
       * @param y the BigInt to subtract - assumed y >= 0 and y < mod
330
       * @param mod the positive modulus
331
       * @param ws a temp workspace
332
       */
333
      BigInt& mod_sub(const BigInt& y, const BigInt& mod, secure_vector<word>& ws);
334
335
      /**
336
       * Set *this to (*this * y) % mod
337
       * This function assumes *this is >= 0 && < mod
338
       * y should be small, less than 16
339
       * @param y the small integer to multiply by
340
       * @param mod the positive modulus
341
       * @param ws a temp workspace
342
       */
343
      BigInt& mod_mul(uint8_t y, const BigInt& mod, secure_vector<word>& ws);
344
345
      /**
346
       * Return *this % mod
347
       *
348
       * Assumes that *this is (if anything) only slightly larger than
349
       * mod and performs repeated subtractions. It should not be used if
350
       * *this is much larger than mod, instead use modulo operator.
351
       */
352
      size_t reduce_below(const BigInt& mod, secure_vector<word>& ws);
353
354
      /**
355
       * Return *this % mod
356
       *
357
       * Assumes that *this is (if anything) only slightly larger than mod and
358
       * performs repeated subtractions. It should not be used if *this is much
359
       * larger than mod, instead use modulo operator.
360
       *
361
       * Performs exactly bound subtractions, so if *this is >= bound*mod then the
362
       * result will not be fully reduced. If bound is zero, nothing happens.
363
       */
364
      void ct_reduce_below(const BigInt& mod, secure_vector<word>& ws, size_t bound);
365
366
      /**
367
       * Zeroize the BigInt. The size of the underlying register is not
368
       * modified.
369
       */
370
718k
      void clear() {
371
718k
         m_data.set_to_zero();
372
718k
         m_signedness = Positive;
373
718k
      }
374
375
      /**
376
       * Compare this to another BigInt
377
       * @param n the BigInt value to compare with
378
       * @param check_signs include sign in comparison?
379
       * @result if (this<n) return -1, if (this>n) return 1, if both
380
       * values are identical return 0 [like Perl's <=> operator]
381
       */
382
      int32_t cmp(const BigInt& n, bool check_signs = true) const;
383
384
      /**
385
       * Compare this to another BigInt
386
       * @param n the BigInt value to compare with
387
       * @result true if this == n or false otherwise
388
       */
389
      bool is_equal(const BigInt& n) const;
390
391
      /**
392
       * Compare this to another BigInt
393
       * @param n the BigInt value to compare with
394
       * @result true if this < n or false otherwise
395
       */
396
      bool is_less_than(const BigInt& n) const;
397
398
      /**
399
       * Compare this to an integer
400
       * @param n the value to compare with
401
       * @result if (this<n) return -1, if (this>n) return 1, if both
402
       * values are identical return 0 [like Perl's <=> operator]
403
       */
404
      int32_t cmp_word(word n) const;
405
406
      /**
407
       * Test if the integer has an even value
408
       * @result true if the integer is even, false otherwise
409
       */
410
326k
      bool is_even() const { return (get_bit(0) == 0); }
411
412
      /**
413
       * Test if the integer has an odd value
414
       * @result true if the integer is odd, false otherwise
415
       */
416
101k
      bool is_odd() const { return (get_bit(0) == 1); }
417
418
      /**
419
       * Test if the integer is not zero
420
       * @result true if the integer is non-zero, false otherwise
421
       */
422
434k
      bool is_nonzero() const { return (!is_zero()); }
423
424
      /**
425
       * Test if the integer is zero
426
       * @result true if the integer is zero, false otherwise
427
       */
428
68.8M
      bool is_zero() const { return (sig_words() == 0); }
429
430
      /**
431
       * Set bit at specified position
432
       * @param n bit position to set
433
       */
434
141k
      void set_bit(size_t n) { conditionally_set_bit(n, true); }
435
436
      /**
437
       * Conditionally set bit at specified position. Note if set_it is
438
       * false, nothing happens, and if the bit is already set, it
439
       * remains set.
440
       *
441
       * @param n bit position to set
442
       * @param set_it if the bit should be set
443
       */
444
252M
      void conditionally_set_bit(size_t n, bool set_it) {
445
252M
         const size_t which = n / BOTAN_MP_WORD_BITS;
446
252M
         const word mask = static_cast<word>(set_it) << (n % BOTAN_MP_WORD_BITS);
447
252M
         m_data.set_word_at(which, word_at(which) | mask);
448
252M
      }
449
450
      /**
451
       * Clear bit at specified position
452
       * @param n bit position to clear
453
       */
454
      void clear_bit(size_t n);
455
456
      /**
457
       * Clear all but the lowest n bits
458
       * @param n amount of bits to keep
459
       */
460
219M
      void mask_bits(size_t n) { m_data.mask_bits(n); }
461
462
      /**
463
       * Return bit value at specified position
464
       * @param n the bit offset to test
465
       * @result true, if the bit at position n is set, false otherwise
466
       */
467
126M
      bool get_bit(size_t n) const { return ((word_at(n / BOTAN_MP_WORD_BITS) >> (n % BOTAN_MP_WORD_BITS)) & 1); }
468
469
      /**
470
       * Return (a maximum of) 32 bits of the complete value
471
       * @param offset the offset to start extracting
472
       * @param length amount of bits to extract (starting at offset)
473
       * @result the integer extracted from the register starting at
474
       * offset with specified length
475
       */
476
      uint32_t get_substring(size_t offset, size_t length) const;
477
478
      /**
479
       * Convert this value into a uint32_t, if it is in the range
480
       * [0 ... 2**32-1], or otherwise throw an exception.
481
       * @result the value as a uint32_t if conversion is possible
482
       */
483
      uint32_t to_u32bit() const;
484
485
      /**
486
       * Convert this value to a decimal string.
487
       * Warning: decimal conversions are relatively slow
488
       *
489
       * If the integer is zero then "0" is returned.
490
       * If the integer is negative then "-" is prefixed.
491
       */
492
      std::string to_dec_string() const;
493
494
      /**
495
       * Convert this value to a hexadecimal string.
496
       *
497
       * If the integer is negative then "-" is prefixed.
498
       * Then a prefix of "0x" is added.
499
       * Follows is a sequence of hexadecimal characters in uppercase.
500
       *
501
       * The number of hexadecimal characters is always an even number,
502
       * with a zero prefix being included if necessary.
503
       * For example encoding the integer "5" results in "0x05"
504
       */
505
      std::string to_hex_string() const;
506
507
      /**
508
       * @param n the offset to get a byte from
509
       * @result byte at offset n
510
       */
511
      uint8_t byte_at(size_t n) const;
512
513
      /**
514
       * Return the word at a specified position of the internal register
515
       * @param n position in the register
516
       * @return value at position n
517
       */
518
1.04G
      word word_at(size_t n) const { return m_data.get_word_at(n); }
519
520
201M
      void set_word_at(size_t i, word w) { m_data.set_word_at(i, w); }
521
522
15.9M
      void set_words(const word w[], size_t len) { m_data.set_words(w, len); }
523
524
      /**
525
       * Tests if the sign of the integer is negative
526
       * @result true, iff the integer has a negative sign
527
       */
528
742M
      bool is_negative() const { return (sign() == Negative); }
529
530
      /**
531
       * Tests if the sign of the integer is positive
532
       * @result true, iff the integer has a positive sign
533
       */
534
629k
      bool is_positive() const { return (sign() == Positive); }
535
536
      /**
537
       * Return the sign of the integer
538
       * @result the sign of the integer
539
       */
540
752M
      Sign sign() const { return (m_signedness); }
541
542
      /**
543
       * @result the opposite sign of the represented integer value
544
       */
545
115k
      Sign reverse_sign() const {
546
115k
         if(sign() == Positive) {
547
115k
            return Negative;
548
115k
         }
549
0
         return Positive;
550
115k
      }
551
552
      /**
553
       * Flip the sign of this BigInt
554
       */
555
0
      void flip_sign() { set_sign(reverse_sign()); }
556
557
      /**
558
       * Set sign of the integer
559
       * @param sign new Sign to set
560
       */
561
3.65M
      void set_sign(Sign sign) {
562
3.65M
         if(sign == Negative && is_zero()) {
563
0
            sign = Positive;
564
0
         }
565
566
3.65M
         m_signedness = sign;
567
3.65M
      }
568
569
      /**
570
       * @result absolute (positive) value of this
571
       */
572
      BigInt abs() const;
573
574
      /**
575
       * Give size of internal register
576
       * @result size of internal register in words
577
       */
578
2.41G
      size_t size() const { return m_data.size(); }
579
580
      /**
581
       * Return how many words we need to hold this value
582
       * @result significant words of the represented integer value
583
       */
584
325M
      size_t sig_words() const { return m_data.sig_words(); }
585
586
      /**
587
       * Give byte length of the integer
588
       * @result byte length of the represented integer value
589
       */
590
      size_t bytes() const;
591
592
      /**
593
       * Get the bit length of the integer
594
       * @result bit length of the represented integer value
595
       */
596
      size_t bits() const;
597
598
      /**
599
       * Get the number of high bits unset in the top (allocated) word
600
       * of this integer. Returns BOTAN_MP_WORD_BITS only iff *this is
601
       * zero. Ignores sign.
602
       */
603
      size_t top_bits_free() const;
604
605
      /**
606
       * Return a mutable pointer to the register
607
       * @result a pointer to the start of the internal register
608
       */
609
1.69G
      word* mutable_data() { return m_data.mutable_data(); }
610
611
      /**
612
       * Return a const pointer to the register
613
       * @result a pointer to the start of the internal register
614
       */
615
1.78G
      const word* data() const { return m_data.const_data(); }
616
617
      /**
618
       * Don't use this function in application code
619
       */
620
59.0M
      secure_vector<word>& get_word_vector() { return m_data.mutable_vector(); }
621
622
      /**
623
       * Don't use this function in application code
624
       */
625
0
      const secure_vector<word>& get_word_vector() const { return m_data.const_vector(); }
626
627
      /**
628
       * Increase internal register buffer to at least n words
629
       * @param n new size of register
630
       */
631
836M
      void grow_to(size_t n) const { m_data.grow_to(n); }
632
633
0
      void resize(size_t s) { m_data.resize(s); }
634
635
      /**
636
       * Fill BigInt with a random number with size of bitsize
637
       *
638
       * If \p set_high_bit is true, the highest bit will be set, which causes
639
       * the entropy to be \a bits-1. Otherwise the highest bit is randomly chosen
640
       * by the rng, causing the entropy to be \a bits.
641
       *
642
       * @param rng the random number generator to use
643
       * @param bitsize number of bits the created random value should have
644
       * @param set_high_bit if true, the highest bit is always set
645
       */
646
      void randomize(RandomNumberGenerator& rng, size_t bitsize, bool set_high_bit = true);
647
648
      /**
649
       * Store BigInt-value in a given byte array
650
       * @param buf destination byte array for the integer value
651
       */
652
      void binary_encode(uint8_t buf[]) const;
653
654
      /**
655
       * Store BigInt-value in a given byte array. If len is less than
656
       * the size of the value, then it will be truncated. If len is
657
       * greater than the size of the value, it will be zero-padded.
658
       * If len exactly equals this->bytes(), this function behaves identically
659
       * to binary_encode.
660
       *
661
       * Zero-padding the binary encoding is useful to ensure that other
662
       * applications correctly parse the encoded value as "positive integer",
663
       * as a leading 1-bit may be interpreted as a sign bit.
664
       *
665
       * @param buf destination byte array for the integer value
666
       * @param len how many bytes to write
667
       */
668
      void binary_encode(uint8_t buf[], size_t len) const;
669
670
      /**
671
       * Read integer value from a byte array with given size
672
       * @param buf byte array buffer containing the integer
673
       * @param length size of buf
674
       */
675
      void binary_decode(const uint8_t buf[], size_t length);
676
677
      /**
678
       * Read integer value from a byte vector
679
       * @param buf the vector to load from
680
       */
681
0
      void binary_decode(std::span<const uint8_t> buf) { binary_decode(buf.data(), buf.size()); }
682
683
      /**
684
       * Place the value into out, zero-padding up to size words
685
       * Throw if *this cannot be represented in size words
686
       */
687
      void encode_words(word out[], size_t size) const;
688
689
      /**
690
       * If predicate is true assign other to *this
691
       * Uses a masked operation to avoid side channels
692
       */
693
      void ct_cond_assign(bool predicate, const BigInt& other);
694
695
      /**
696
       * If predicate is true swap *this and other
697
       * Uses a masked operation to avoid side channels
698
       */
699
      void ct_cond_swap(bool predicate, BigInt& other);
700
701
      /**
702
       * If predicate is true add value to *this
703
       */
704
      void ct_cond_add(bool predicate, const BigInt& value);
705
706
      /**
707
       * Shift @p shift bits to the left, runtime is independent of
708
       * the value of @p shift.
709
       */
710
      void ct_shift_left(size_t shift);
711
712
      /**
713
       * If predicate is true flip the sign of *this
714
       */
715
      void cond_flip_sign(bool predicate);
716
717
#if defined(BOTAN_HAS_VALGRIND)
718
      void const_time_poison() const;
719
      void const_time_unpoison() const;
720
#else
721
185k
      void const_time_poison() const {}
722
723
17.9M
      void const_time_unpoison() const {}
724
#endif
725
726
      /**
727
       * @param rng a random number generator
728
       * @param min the minimum value (must be non-negative)
729
       * @param max the maximum value (must be non-negative and > min)
730
       * @return random integer in [min,max)
731
       */
732
      static BigInt random_integer(RandomNumberGenerator& rng, const BigInt& min, const BigInt& max);
733
734
      /**
735
       * Create a power of two
736
       * @param n the power of two to create
737
       * @return bigint representing 2^n
738
       */
739
65.3k
      static BigInt power_of_2(size_t n) {
740
65.3k
         BigInt b;
741
65.3k
         b.set_bit(n);
742
65.3k
         return b;
743
65.3k
      }
744
745
      /**
746
       * Encode the integer value from a BigInt to a std::vector of bytes
747
       * @param n the BigInt to use as integer source
748
       * @result secure_vector of bytes containing the bytes of the integer
749
       */
750
45.4k
      static std::vector<uint8_t> encode(const BigInt& n) {
751
45.4k
         std::vector<uint8_t> output(n.bytes());
752
45.4k
         n.binary_encode(output.data());
753
45.4k
         return output;
754
45.4k
      }
755
756
      /**
757
       * Encode the integer value from a BigInt to a secure_vector of bytes
758
       * @param n the BigInt to use as integer source
759
       * @result secure_vector of bytes containing the bytes of the integer
760
       */
761
0
      static secure_vector<uint8_t> encode_locked(const BigInt& n) {
762
0
         secure_vector<uint8_t> output(n.bytes());
763
0
         n.binary_encode(output.data());
764
0
         return output;
765
0
      }
766
767
      /**
768
       * Create a BigInt from an integer in a byte array
769
       * @param buf the binary value to load
770
       * @param length size of buf
771
       * @result BigInt representing the integer in the byte array
772
       */
773
0
      static BigInt decode(const uint8_t buf[], size_t length) { return BigInt(buf, length); }
774
775
      /**
776
       * Create a BigInt from an integer in a byte array
777
       * @param buf the binary value to load
778
       * @result BigInt representing the integer in the byte array
779
       */
780
7.45k
      static BigInt decode(std::span<const uint8_t> buf) { return BigInt(buf); }
781
782
      /**
783
       * Create a BigInt from an integer in a byte array
784
       * @param buf the binary value to load
785
       * @param length size of buf
786
       * @param base number-base of the integer in buf
787
       * @result BigInt representing the integer in the byte array
788
       */
789
      static BigInt decode(const uint8_t buf[], size_t length, Base base);
790
791
      /**
792
       * Create a BigInt from an integer in a byte array
793
       * @param buf the binary value to load
794
       * @param base number-base of the integer in buf
795
       * @result BigInt representing the integer in the byte array
796
       */
797
0
      static BigInt decode(std::span<const uint8_t> buf, Base base) {
798
0
         if(base == Binary) {
799
0
            return BigInt(buf);
800
0
         }
801
0
         return BigInt::decode(buf.data(), buf.size(), base);
802
0
      }
803
804
      /**
805
       * Encode a BigInt to a byte array according to IEEE 1363
806
       * @param n the BigInt to encode
807
       * @param bytes the length of the resulting secure_vector<uint8_t>
808
       * @result a secure_vector<uint8_t> containing the encoded BigInt
809
       */
810
      static secure_vector<uint8_t> encode_1363(const BigInt& n, size_t bytes);
811
      static void encode_1363(std::span<uint8_t> out, const BigInt& n);
812
813
      static void encode_1363(uint8_t out[], size_t bytes, const BigInt& n);
814
815
      /**
816
       * Encode two BigInt to a byte array according to IEEE 1363
817
       * @param n1 the first BigInt to encode
818
       * @param n2 the second BigInt to encode
819
       * @param bytes the length of the encoding of each single BigInt
820
       * @result a secure_vector<uint8_t> containing the concatenation of the two encoded BigInt
821
       */
822
      static secure_vector<uint8_t> encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes);
823
824
   private:
825
      class Data {
826
         public:
827
1.69G
            word* mutable_data() {
828
1.69G
               invalidate_sig_words();
829
1.69G
               return m_reg.data();
830
1.69G
            }
831
832
1.78G
            const word* const_data() const { return m_reg.data(); }
833
834
59.0M
            secure_vector<word>& mutable_vector() {
835
59.0M
               invalidate_sig_words();
836
59.0M
               return m_reg;
837
59.0M
            }
838
839
0
            const secure_vector<word>& const_vector() const { return m_reg; }
840
841
1.04G
            word get_word_at(size_t n) const {
842
1.04G
               if(n < m_reg.size()) {
843
1.04G
                  return m_reg[n];
844
1.04G
               }
845
154k
               return 0;
846
1.04G
            }
847
848
454M
            void set_word_at(size_t i, word w) {
849
454M
               invalidate_sig_words();
850
454M
               if(i >= m_reg.size()) {
851
201M
                  if(w == 0) {
852
201M
                     return;
853
201M
                  }
854
143k
                  grow_to(i + 1);
855
143k
               }
856
253M
               m_reg[i] = w;
857
253M
            }
858
859
15.9M
            void set_words(const word w[], size_t len) {
860
15.9M
               invalidate_sig_words();
861
15.9M
               m_reg.assign(w, w + len);
862
15.9M
            }
863
864
718k
            void set_to_zero() {
865
718k
               m_reg.resize(m_reg.capacity());
866
718k
               clear_mem(m_reg.data(), m_reg.size());
867
718k
               m_sig_words = 0;
868
718k
            }
869
870
0
            void set_size(size_t s) {
871
0
               invalidate_sig_words();
872
0
               clear_mem(m_reg.data(), m_reg.size());
873
0
               m_reg.resize(s + (8 - (s % 8)));
874
0
            }
875
876
219M
            void mask_bits(size_t n) {
877
219M
               if(n == 0) {
878
0
                  return set_to_zero();
879
0
               }
880
881
219M
               const size_t top_word = n / BOTAN_MP_WORD_BITS;
882
883
               // if(top_word < sig_words()) ?
884
219M
               if(top_word < size()) {
885
219M
                  const word mask = (static_cast<word>(1) << (n % BOTAN_MP_WORD_BITS)) - 1;
886
219M
                  const size_t len = size() - (top_word + 1);
887
219M
                  if(len > 0) {
888
219M
                     clear_mem(&m_reg[top_word + 1], len);
889
219M
                  }
890
219M
                  m_reg[top_word] &= mask;
891
219M
                  invalidate_sig_words();
892
219M
               }
893
219M
            }
894
895
836M
            void grow_to(size_t n) const {
896
836M
               if(n > size()) {
897
22.6M
                  if(n <= m_reg.capacity()) {
898
14.6M
                     m_reg.resize(n);
899
14.6M
                  } else {
900
8.04M
                     m_reg.resize(n + (8 - (n % 8)));
901
8.04M
                  }
902
22.6M
               }
903
836M
            }
904
905
3.68G
            size_t size() const { return m_reg.size(); }
906
907
0
            void shrink_to_fit(size_t min_size = 0) {
908
0
               const size_t words = std::max(min_size, sig_words());
909
0
               m_reg.resize(words);
910
0
            }
911
912
0
            void resize(size_t s) { m_reg.resize(s); }
913
914
107M
            void swap(Data& other) {
915
107M
               m_reg.swap(other.m_reg);
916
107M
               std::swap(m_sig_words, other.m_sig_words);
917
107M
            }
918
919
123M
            void swap(secure_vector<word>& reg) {
920
123M
               m_reg.swap(reg);
921
123M
               invalidate_sig_words();
922
123M
            }
923
924
2.57G
            void invalidate_sig_words() const { m_sig_words = sig_words_npos; }
925
926
325M
            size_t sig_words() const {
927
325M
               if(m_sig_words == sig_words_npos) {
928
63.8M
                  m_sig_words = calc_sig_words();
929
261M
               } else {
930
261M
                  BOTAN_DEBUG_ASSERT(m_sig_words == calc_sig_words());
931
261M
               }
932
325M
               return m_sig_words;
933
325M
            }
934
935
         private:
936
            static const size_t sig_words_npos = static_cast<size_t>(-1);
937
938
            size_t calc_sig_words() const;
939
940
            mutable secure_vector<word> m_reg;
941
            mutable size_t m_sig_words = sig_words_npos;
942
      };
943
944
      Data m_data;
945
      Sign m_signedness = Positive;
946
};
947
948
/*
949
* Arithmetic Operators
950
*/
951
524k
inline BigInt operator+(const BigInt& x, const BigInt& y) {
952
524k
   return BigInt::add2(x, y.data(), y.sig_words(), y.sign());
953
524k
}
954
955
15
inline BigInt operator+(const BigInt& x, word y) {
956
15
   return BigInt::add2(x, &y, 1, BigInt::Positive);
957
15
}
958
959
0
inline BigInt operator+(word x, const BigInt& y) {
960
0
   return y + x;
961
0
}
962
963
115k
inline BigInt operator-(const BigInt& x, const BigInt& y) {
964
115k
   return BigInt::add2(x, y.data(), y.sig_words(), y.reverse_sign());
965
115k
}
966
967
24
inline BigInt operator-(const BigInt& x, word y) {
968
24
   return BigInt::add2(x, &y, 1, BigInt::Negative);
969
24
}
970
971
BigInt BOTAN_PUBLIC_API(2, 0) operator*(const BigInt& x, const BigInt& y);
972
BigInt BOTAN_PUBLIC_API(2, 8) operator*(const BigInt& x, word y);
973
974
435k
inline BigInt operator*(word x, const BigInt& y) {
975
435k
   return y * x;
976
435k
}
977
978
BigInt BOTAN_PUBLIC_API(2, 0) operator/(const BigInt& x, const BigInt& d);
979
BigInt BOTAN_PUBLIC_API(2, 0) operator/(const BigInt& x, word m);
980
BigInt BOTAN_PUBLIC_API(2, 0) operator%(const BigInt& x, const BigInt& m);
981
word BOTAN_PUBLIC_API(2, 0) operator%(const BigInt& x, word m);
982
BigInt BOTAN_PUBLIC_API(2, 0) operator<<(const BigInt& x, size_t n);
983
BigInt BOTAN_PUBLIC_API(2, 0) operator>>(const BigInt& x, size_t n);
984
985
/*
986
 * Comparison Operators
987
 */
988
228k
inline bool operator==(const BigInt& a, const BigInt& b) {
989
228k
   return a.is_equal(b);
990
228k
}
991
992
257k
inline bool operator!=(const BigInt& a, const BigInt& b) {
993
257k
   return !a.is_equal(b);
994
257k
}
995
996
0
inline bool operator<=(const BigInt& a, const BigInt& b) {
997
0
   return (a.cmp(b) <= 0);
998
0
}
999
1000
359k
inline bool operator>=(const BigInt& a, const BigInt& b) {
1001
359k
   return (a.cmp(b) >= 0);
1002
359k
}
1003
1004
247k
inline bool operator<(const BigInt& a, const BigInt& b) {
1005
247k
   return a.is_less_than(b);
1006
247k
}
1007
1008
0
inline bool operator>(const BigInt& a, const BigInt& b) {
1009
0
   return b.is_less_than(a);
1010
0
}
1011
1012
47.1k
inline bool operator==(const BigInt& a, word b) {
1013
47.1k
   return (a.cmp_word(b) == 0);
1014
47.1k
}
1015
1016
0
inline bool operator!=(const BigInt& a, word b) {
1017
0
   return (a.cmp_word(b) != 0);
1018
0
}
1019
1020
37.4k
inline bool operator<=(const BigInt& a, word b) {
1021
37.4k
   return (a.cmp_word(b) <= 0);
1022
37.4k
}
1023
1024
0
inline bool operator>=(const BigInt& a, word b) {
1025
0
   return (a.cmp_word(b) >= 0);
1026
0
}
1027
1028
287k
inline bool operator<(const BigInt& a, word b) {
1029
287k
   return (a.cmp_word(b) < 0);
1030
287k
}
1031
1032
76.3k
inline bool operator>(const BigInt& a, word b) {
1033
76.3k
   return (a.cmp_word(b) > 0);
1034
76.3k
}
1035
1036
/*
1037
 * I/O Operators
1038
 */
1039
BOTAN_PUBLIC_API(2, 0) std::ostream& operator<<(std::ostream&, const BigInt&);
1040
BOTAN_PUBLIC_API(2, 0) std::istream& operator>>(std::istream&, BigInt&);
1041
1042
}  // namespace Botan
1043
1044
#endif