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