Botan 3.5.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/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
19namespace Botan {
20
21class RandomNumberGenerator;
22
23/**
24 * Arbitrary precision integer
25 */
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 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);
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);
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 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 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 BigInt(BigInt&& other) { this->swap(other); }
168
169 ~BigInt() { const_time_unpoison(); }
170
171 /**
172 * Move assignment
173 */
175 if(this != &other) {
176 this->swap(other);
177 }
178
179 return (*this);
180 }
181
182 /**
183 * Copy assignment
184 */
185 BigInt& operator=(const BigInt&) = default;
186
187 /**
188 * Swap this value with another
189 * @param other BigInt to swap values with
190 */
191 void swap(BigInt& other) {
192 m_data.swap(other.m_data);
193 std::swap(m_signedness, other.m_signedness);
194 }
195
196 friend void swap(BigInt& x, BigInt& y) { x.swap(y); }
197
198 BOTAN_DEPRECATED("Deprecated no replacement") void swap_reg(secure_vector<word>& reg) {
199 m_data.swap(reg);
200 // sign left unchanged
201 }
202
203 /**
204 * += operator
205 * @param y the BigInt to add to this
206 */
207 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 BigInt& operator+=(word y) { return add(&y, 1, Positive); }
214
215 /**
216 * -= operator
217 * @param y the BigInt to subtract from this
218 */
219 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 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 BigInt& operator++() { return (*this += 1); }
273
274 /**
275 * Decrement operator
276 */
277 BigInt& operator--() { return (*this -= 1); }
278
279 /**
280 * Postfix increment operator
281 */
283 BigInt x = (*this);
284 ++(*this);
285 return x;
286 }
287
288 /**
289 * Postfix decrement operator
290 */
292 BigInt x = (*this);
293 --(*this);
294 return x;
295 }
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 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 BigInt& sub(const word y[], size_t y_words, Sign sign) {
317 return add(y, y_words, sign == Positive ? Negative : Positive);
318 }
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 void clear() {
400 m_data.set_to_zero();
401 m_signedness = Positive;
402 }
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 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 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 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 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 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 void conditionally_set_bit(size_t n, bool set_it) {
474 const size_t which = n / BOTAN_MP_WORD_BITS;
475 const word mask = static_cast<word>(set_it) << (n % BOTAN_MP_WORD_BITS);
476 m_data.set_word_at(which, word_at(which) | mask);
477 }
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 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 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 word word_at(size_t n) const { return m_data.get_word_at(n); }
548
549 BOTAN_DEPRECATED("Deprecated no replacement") void set_word_at(size_t i, word w) { m_data.set_word_at(i, w); }
550
551 BOTAN_DEPRECATED("Deprecated no replacement") void set_words(const word w[], size_t len) {
552 m_data.set_words(w, len);
553 }
554
555 /**
556 * Tests if the sign of the integer is negative
557 * @result true, iff the integer has a negative sign
558 */
559 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 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 Sign sign() const { return (m_signedness); }
572
573 /**
574 * @result the opposite sign of the represented integer value
575 */
577 if(sign() == Positive) {
578 return Negative;
579 }
580 return Positive;
581 }
582
583 /**
584 * Flip the sign of this BigInt
585 */
586 void flip_sign() { set_sign(reverse_sign()); }
587
588 /**
589 * Set sign of the integer
590 * @param sign new Sign to set
591 */
592 void set_sign(Sign sign) {
593 if(sign == Negative && is_zero()) {
594 sign = Positive;
595 }
596
597 m_signedness = sign;
598 }
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 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 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 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 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 BOTAN_DEPRECATED("Deprecated no replacement") secure_vector<word>& get_word_vector() {
652 return m_data.mutable_vector();
653 }
654
655 /**
656 * Don't use this function in application code
657 */
658 BOTAN_DEPRECATED("Deprecated no replacement") const secure_vector<word>& get_word_vector() const {
659 return m_data.const_vector();
660 }
661
662 /**
663 * Increase internal register buffer to at least n words
664 * @param n new size of register
665 */
666 BOTAN_DEPRECATED("Deprecated no replacement") void grow_to(size_t n) const { m_data.grow_to(n); }
667
668 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 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 T out(len);
716 this->serialize_to(out);
717 return out;
718 }
719
720 /**
721 * Serialize the value of this BigInt as a big endian encoding.
722 */
723 template <typename T = std::vector<uint8_t>>
724 T serialize() const {
725 return serialize<T>(this->bytes());
726 }
727
728 /**
729 * Store BigInt-value in a given byte array
730 * @param buf destination byte array for the integer value
731 */
732 BOTAN_DEPRECATED("Use BigInt::serialize_to") void binary_encode(uint8_t buf[]) const {
733 this->serialize_to(std::span{buf, this->bytes()});
734 }
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 BOTAN_DEPRECATED("Use BigInt::from_bytes") void binary_decode(const uint8_t buf[], size_t length) {
758 this->assign_from_bytes(std::span{buf, length});
759 }
760
761 /**
762 * Read integer value from a byte vector
763 * @param buf the vector to load from
764 */
765 BOTAN_DEPRECATED("Use BigInt::from_bytes") void binary_decode(std::span<const uint8_t> buf) {
766 this->assign_from_bytes(buf);
767 }
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 void const_time_poison() const {}
808
809 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 static BigInt power_of_2(size_t n) {
826 BigInt b;
827 b.set_bit(n);
828 return b;
829 }
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 BOTAN_DEPRECATED("Use BigInt::serialize") static std::vector<uint8_t> encode(const BigInt& n) {
837 return n.serialize<std::vector<uint8_t>>(n.bytes());
838 }
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 BOTAN_DEPRECATED("Use BigInt::serialize") static secure_vector<uint8_t> encode_locked(const BigInt& n) {
846 return n.serialize<secure_vector<uint8_t>>(n.bytes());
847 }
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 BOTAN_DEPRECATED("Use BigInt::from_bytes") static BigInt decode(const uint8_t buf[], size_t length) {
863 return BigInt::from_bytes(std::span{buf, length});
864 }
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 BOTAN_DEPRECATED("Use BigInt::from_bytes") static BigInt decode(std::span<const uint8_t> buf) {
872 return BigInt::from_bytes(buf);
873 }
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 static secure_vector<uint8_t> encode_1363(const BigInt& n, size_t bytes) {
901 return n.serialize<secure_vector<uint8_t>>(bytes);
902 }
903
904 BOTAN_DEPRECATED("Use BigInt::serialize_to") static void encode_1363(std::span<uint8_t> out, const BigInt& n) {
905 n.serialize_to(out);
906 }
907
908 BOTAN_DEPRECATED("Use BigInt::serialize_to")
909 static void encode_1363(uint8_t out[], size_t bytes, const BigInt& n) {
910 n.serialize_to(std::span{out, bytes});
911 }
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 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 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 word* mutable_data() {
954 invalidate_sig_words();
955 return m_reg.data();
956 }
957
958 const word* const_data() const { return m_reg.data(); }
959
960 secure_vector<word>& mutable_vector() {
961 invalidate_sig_words();
962 return m_reg;
963 }
964
965 const secure_vector<word>& const_vector() const { return m_reg; }
966
967 word get_word_at(size_t n) const {
968 if(n < m_reg.size()) {
969 return m_reg[n];
970 }
971 return 0;
972 }
973
974 void set_word_at(size_t i, word w) {
975 invalidate_sig_words();
976 if(i >= m_reg.size()) {
977 if(w == 0) {
978 return;
979 }
980 grow_to(i + 1);
981 }
982 m_reg[i] = w;
983 }
984
985 void set_words(const word w[], size_t len) {
986 invalidate_sig_words();
987 m_reg.assign(w, w + len);
988 }
989
990 void set_to_zero() {
991 m_reg.resize(m_reg.capacity());
992 clear_mem(m_reg.data(), m_reg.size());
993 m_sig_words = 0;
994 }
995
996 void set_size(size_t s) {
997 invalidate_sig_words();
998 clear_mem(m_reg.data(), m_reg.size());
999 m_reg.resize(s + (8 - (s % 8)));
1000 }
1001
1002 void mask_bits(size_t n) {
1003 if(n == 0) {
1004 return set_to_zero();
1005 }
1006
1007 const size_t top_word = n / BOTAN_MP_WORD_BITS;
1008
1009 // if(top_word < sig_words()) ?
1010 if(top_word < size()) {
1011 const word mask = (static_cast<word>(1) << (n % BOTAN_MP_WORD_BITS)) - 1;
1012 const size_t len = size() - (top_word + 1);
1013 if(len > 0) {
1014 clear_mem(&m_reg[top_word + 1], len);
1015 }
1016 m_reg[top_word] &= mask;
1017 invalidate_sig_words();
1018 }
1019 }
1020
1021 void grow_to(size_t n) const {
1022 if(n > size()) {
1023 if(n <= m_reg.capacity()) {
1024 m_reg.resize(n);
1025 } else {
1026 m_reg.resize(n + (8 - (n % 8)));
1027 }
1028 }
1029 }
1030
1031 size_t size() const { return m_reg.size(); }
1032
1033 void shrink_to_fit(size_t min_size = 0) {
1034 const size_t words = std::max(min_size, sig_words());
1035 m_reg.resize(words);
1036 }
1037
1038 void resize(size_t s) { m_reg.resize(s); }
1039
1040 void swap(Data& other) {
1041 m_reg.swap(other.m_reg);
1042 std::swap(m_sig_words, other.m_sig_words);
1043 }
1044
1045 void swap(secure_vector<word>& reg) {
1046 m_reg.swap(reg);
1047 invalidate_sig_words();
1048 }
1049
1050 void invalidate_sig_words() const { m_sig_words = sig_words_npos; }
1051
1052 size_t sig_words() const {
1053 if(m_sig_words == sig_words_npos) {
1054 m_sig_words = calc_sig_words();
1055 } else {
1056 BOTAN_DEBUG_ASSERT(m_sig_words == calc_sig_words());
1057 }
1058 return m_sig_words;
1059 }
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*/
1077inline BigInt operator+(const BigInt& x, const BigInt& y) {
1078 return BigInt::add2(x, y._data(), y.sig_words(), y.sign());
1079}
1080
1081inline BigInt operator+(const BigInt& x, word y) {
1082 return BigInt::add2(x, &y, 1, BigInt::Positive);
1083}
1084
1085inline BigInt operator+(word x, const BigInt& y) {
1086 return y + x;
1087}
1088
1089inline BigInt operator-(const BigInt& x, const BigInt& y) {
1090 return BigInt::add2(x, y._data(), y.sig_words(), y.reverse_sign());
1091}
1092
1093inline BigInt operator-(const BigInt& x, word y) {
1094 return BigInt::add2(x, &y, 1, BigInt::Negative);
1095}
1096
1097BOTAN_PUBLIC_API(2, 0) BigInt operator*(const BigInt& x, const BigInt& y);
1098BOTAN_PUBLIC_API(2, 8) BigInt operator*(const BigInt& x, word y);
1099
1100inline BigInt operator*(word x, const BigInt& y) {
1101 return y * x;
1102}
1103
1104BOTAN_PUBLIC_API(2, 0) BigInt operator/(const BigInt& x, const BigInt& d);
1105BOTAN_PUBLIC_API(2, 0) BigInt operator/(const BigInt& x, word m);
1106BOTAN_PUBLIC_API(2, 0) BigInt operator%(const BigInt& x, const BigInt& m);
1107BOTAN_PUBLIC_API(2, 0) word operator%(const BigInt& x, word m);
1108BOTAN_PUBLIC_API(2, 0) BigInt operator<<(const BigInt& x, size_t n);
1109BOTAN_PUBLIC_API(2, 0) BigInt operator>>(const BigInt& x, size_t n);
1110
1111/*
1112 * Comparison Operators
1113 */
1114inline bool operator==(const BigInt& a, const BigInt& b) {
1115 return a.is_equal(b);
1116}
1117
1118inline bool operator!=(const BigInt& a, const BigInt& b) {
1119 return !a.is_equal(b);
1120}
1121
1122inline bool operator<=(const BigInt& a, const BigInt& b) {
1123 return (a.cmp(b) <= 0);
1124}
1125
1126inline bool operator>=(const BigInt& a, const BigInt& b) {
1127 return (a.cmp(b) >= 0);
1128}
1129
1130inline bool operator<(const BigInt& a, const BigInt& b) {
1131 return a.is_less_than(b);
1132}
1133
1134inline bool operator>(const BigInt& a, const BigInt& b) {
1135 return b.is_less_than(a);
1136}
1137
1138inline bool operator==(const BigInt& a, word b) {
1139 return (a.cmp_word(b) == 0);
1140}
1141
1142inline bool operator!=(const BigInt& a, word b) {
1143 return (a.cmp_word(b) != 0);
1144}
1145
1146inline bool operator<=(const BigInt& a, word b) {
1147 return (a.cmp_word(b) <= 0);
1148}
1149
1150inline bool operator>=(const BigInt& a, word b) {
1151 return (a.cmp_word(b) >= 0);
1152}
1153
1154inline bool operator<(const BigInt& a, word b) {
1155 return (a.cmp_word(b) < 0);
1156}
1157
1158inline bool operator>(const BigInt& a, word b) {
1159 return (a.cmp_word(b) > 0);
1160}
1161
1162/*
1163 * I/O Operators
1164 */
1165BOTAN_DEPRECATED("Use BigInt::to_{hex,dec}_string")
1166BOTAN_PUBLIC_API(2, 0) std::ostream& operator<<(std::ostream&, const BigInt&);
1167
1168BOTAN_DEPRECATED("Use BigInt::from_string") BOTAN_PUBLIC_API(2, 0) std::istream& operator>>(std::istream&, BigInt&);
1169
1170} // namespace Botan
1171
1172#endif
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:98
BigInt & operator++()
Definition bigint.h:272
void swap(BigInt &other)
Definition bigint.h:191
static BigInt zero()
Definition bigint.h:50
size_t sig_words() const
Definition bigint.h:615
void conditionally_set_bit(size_t n, bool set_it)
Definition bigint.h:473
bool is_odd() const
Definition bigint.h:445
BigInt()=default
bool is_equal(const BigInt &n) const
Definition bigint.cpp:168
BigInt & sub(const word y[], size_t y_words, Sign sign)
Definition bigint.h:316
size_t size() const
Definition bigint.h:609
T serialize() const
Definition bigint.h:724
Sign reverse_sign() const
Definition bigint.h:576
void flip_sign()
Definition bigint.h:586
static BigInt add2(const BigInt &x, const word y[], size_t y_words, Sign y_sign)
Definition big_ops3.cpp:19
bool is_less_than(const BigInt &n) const
Definition bigint.cpp:176
int32_t cmp(const BigInt &n, bool check_signs=true) const
Definition bigint.cpp:150
BigInt & operator+=(word y)
Definition bigint.h:213
BigInt & operator=(BigInt &&other)
Definition bigint.h:174
static BigInt one()
Definition bigint.h:55
BigInt & operator-=(const BigInt &y)
Definition bigint.h:219
void set_bit(size_t n)
Definition bigint.h:463
friend void swap(BigInt &x, BigInt &y)
Definition bigint.h:196
int32_t cmp_word(word n) const
Definition bigint.cpp:134
void mask_bits(size_t n)
Definition bigint.h:489
BigInt operator--(int)
Definition bigint.h:291
bool is_even() const
Definition bigint.h:439
static BigInt power_of_2(size_t n)
Definition bigint.h:825
bool operator!() const
Definition bigint.h:307
BigInt & operator-=(word y)
Definition bigint.h:225
BigInt & operator+=(const BigInt &y)
Definition bigint.h:207
const word * _data() const
Definition bigint.h:931
Sign sign() const
Definition bigint.h:571
void const_time_poison() const
Definition bigint.h:807
BigInt & operator=(const BigInt &)=default
void _assign_from_bytes(std::span< const uint8_t > bytes)
Definition bigint.h:942
BigInt(std::span< const uint8_t > bytes)
Definition bigint.h:124
BigInt & operator--()
Definition bigint.h:277
bool is_zero() const
Definition bigint.h:457
BigInt operator++(int)
Definition bigint.h:282
bool is_negative() const
Definition bigint.h:559
bool is_nonzero() const
Definition bigint.h:451
void const_time_unpoison() const
Definition bigint.h:809
bool is_positive() const
Definition bigint.h:565
bool get_bit(size_t n) const
Definition bigint.h:496
T serialize(size_t len) const
Definition bigint.h:711
void set_sign(Sign sign)
Definition bigint.h:592
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition compiler.h:31
#define BOTAN_DEPRECATED(msg)
Definition compiler.h:125
FE_25519 T
Definition ge.cpp:34
#define BOTAN_MP_WORD_BITS
Definition build.h:50
bool operator>=(const ASN1_Time &, const ASN1_Time &)
bool operator<=(const ASN1_Time &, const ASN1_Time &)
constexpr auto operator>>=(Strong< T1, Tags... > &a, T2 b)
bool operator<(const OID &a, const OID &b)
Definition asn1_oid.cpp:158
OctetString operator+(const OctetString &k1, const OctetString &k2)
Definition symkey.cpp:99
bool operator>(const ASN1_Time &, const ASN1_Time &)
BigInt abs(const BigInt &n)
Definition numthry.h:22
BigInt operator-(const BigInt &x, const BigInt &y)
Definition bigint.h:1089
constexpr auto operator/=(Strong< T1, Tags... > &a, T2 b)
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition alg_id.cpp:69
constexpr auto operator<<=(Strong< T1, Tags... > &a, T2 b)
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition alg_id.cpp:54
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
constexpr void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:120
constexpr auto operator*=(Strong< T1, Tags... > &a, T2 b)