Coverage Report

Created: 2024-06-28 06:19

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