Coverage Report

Created: 2024-11-29 06:10

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