Botan 3.6.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 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 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 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 BigInt(BigInt&& other) { this->swap(other); }
169
170 ~BigInt() { _const_time_unpoison(); }
171
172 /**
173 * Move assignment
174 */
176 if(this != &other) {
177 this->swap(other);
178 }
179
180 return (*this);
181 }
182
183 /**
184 * Copy assignment
185 */
186 BigInt& operator=(const BigInt&) = default;
187
188 /**
189 * Swap this value with another
190 * @param other BigInt to swap values with
191 */
192 void swap(BigInt& other) {
193 m_data.swap(other.m_data);
194 std::swap(m_signedness, other.m_signedness);
195 }
196
197 friend void swap(BigInt& x, BigInt& y) { x.swap(y); }
198
199 BOTAN_DEPRECATED("Deprecated no replacement") void swap_reg(secure_vector<word>& reg) {
200 m_data.swap(reg);
201 // sign left unchanged
202 }
203
204 /**
205 * += operator
206 * @param y the BigInt to add to this
207 */
208 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 BigInt& operator+=(word y) { return add(&y, 1, Positive); }
215
216 /**
217 * -= operator
218 * @param y the BigInt to subtract from this
219 */
220 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 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 BigInt& operator++() { return (*this += 1); }
274
275 /**
276 * Decrement operator
277 */
278 BigInt& operator--() { return (*this -= 1); }
279
280 /**
281 * Postfix increment operator
282 */
284 BigInt x = (*this);
285 ++(*this);
286 return x;
287 }
288
289 /**
290 * Postfix decrement operator
291 */
293 BigInt x = (*this);
294 --(*this);
295 return x;
296 }
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 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 BigInt& sub(const word y[], size_t y_words, Sign sign) {
318 return add(y, y_words, sign == Positive ? Negative : Positive);
319 }
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 void clear() {
401 m_data.set_to_zero();
402 m_signedness = Positive;
403 }
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 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 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 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 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 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 void conditionally_set_bit(size_t n, bool set_it) {
475 const size_t which = n / BOTAN_MP_WORD_BITS;
476 const word mask = static_cast<word>(set_it) << (n % BOTAN_MP_WORD_BITS);
477 m_data.set_word_at(which, word_at(which) | mask);
478 }
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 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 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 word word_at(size_t n) const { return m_data.get_word_at(n); }
549
550 BOTAN_DEPRECATED("Deprecated no replacement") void set_word_at(size_t i, word w) { m_data.set_word_at(i, w); }
551
552 BOTAN_DEPRECATED("Deprecated no replacement") void set_words(const word w[], size_t len) {
553 m_data.set_words(w, len);
554 }
555
556 /**
557 * Tests if the sign of the integer is negative
558 * @result true, iff the integer has a negative sign
559 */
560 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 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 Sign sign() const { return (m_signedness); }
573
574 /**
575 * @result the opposite sign of the represented integer value
576 */
578 if(sign() == Positive) {
579 return Negative;
580 }
581 return Positive;
582 }
583
584 /**
585 * Flip the sign of this BigInt
586 */
587 void flip_sign() { set_sign(reverse_sign()); }
588
589 /**
590 * Set sign of the integer
591 * @param sign new Sign to set
592 */
593 void set_sign(Sign sign) {
594 if(sign == Negative && is_zero()) {
595 sign = Positive;
596 }
597
598 m_signedness = sign;
599 }
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 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 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 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 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 BOTAN_DEPRECATED("Deprecated no replacement") secure_vector<word>& get_word_vector() {
653 return m_data.mutable_vector();
654 }
655
656 /**
657 * Don't use this function in application code
658 */
659 BOTAN_DEPRECATED("Deprecated no replacement") const secure_vector<word>& get_word_vector() const {
660 return m_data.const_vector();
661 }
662
663 /**
664 * Increase internal register buffer to at least n words
665 * @param n new size of register
666 */
667 BOTAN_DEPRECATED("Deprecated no replacement") void grow_to(size_t n) const { m_data.grow_to(n); }
668
669 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 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 T out(len);
717 this->serialize_to(out);
718 return out;
719 }
720
721 /**
722 * Serialize the value of this BigInt as a big endian encoding.
723 */
724 template <typename T = std::vector<uint8_t>>
725 T serialize() const {
726 return serialize<T>(this->bytes());
727 }
728
729 /**
730 * Store BigInt-value in a given byte array
731 * @param buf destination byte array for the integer value
732 */
733 BOTAN_DEPRECATED("Use BigInt::serialize_to") void binary_encode(uint8_t buf[]) const {
734 this->serialize_to(std::span{buf, this->bytes()});
735 }
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 BOTAN_DEPRECATED("Use BigInt::from_bytes") void binary_decode(const uint8_t buf[], size_t length) {
759 this->assign_from_bytes(std::span{buf, length});
760 }
761
762 /**
763 * Read integer value from a byte vector
764 * @param buf the vector to load from
765 */
766 BOTAN_DEPRECATED("Use BigInt::from_bytes") void binary_decode(std::span<const uint8_t> buf) {
767 this->assign_from_bytes(buf);
768 }
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 BOTAN_DEPRECATED("replaced by internal API") void const_time_poison() const { _const_time_poison(); }
805
806 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 constexpr void _const_time_poison() const {}
813
814 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 static BigInt power_of_2(size_t n) {
831 BigInt b;
832 b.set_bit(n);
833 return b;
834 }
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 BOTAN_DEPRECATED("Use BigInt::serialize") static std::vector<uint8_t> encode(const BigInt& n) {
842 return n.serialize<std::vector<uint8_t>>(n.bytes());
843 }
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 BOTAN_DEPRECATED("Use BigInt::serialize") static secure_vector<uint8_t> encode_locked(const BigInt& n) {
851 return n.serialize<secure_vector<uint8_t>>(n.bytes());
852 }
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 BOTAN_DEPRECATED("Use BigInt::from_bytes") static BigInt decode(const uint8_t buf[], size_t length) {
868 return BigInt::from_bytes(std::span{buf, length});
869 }
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 BOTAN_DEPRECATED("Use BigInt::from_bytes") static BigInt decode(std::span<const uint8_t> buf) {
877 return BigInt::from_bytes(buf);
878 }
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 static secure_vector<uint8_t> encode_1363(const BigInt& n, size_t bytes) {
906 return n.serialize<secure_vector<uint8_t>>(bytes);
907 }
908
909 BOTAN_DEPRECATED("Use BigInt::serialize_to") static void encode_1363(std::span<uint8_t> out, const BigInt& n) {
910 n.serialize_to(out);
911 }
912
913 BOTAN_DEPRECATED("Use BigInt::serialize_to")
914 static void encode_1363(uint8_t out[], size_t bytes, const BigInt& n) {
915 n.serialize_to(std::span{out, bytes});
916 }
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 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 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 word* mutable_data() {
959 invalidate_sig_words();
960 return m_reg.data();
961 }
962
963 const word* const_data() const { return m_reg.data(); }
964
965 secure_vector<word>& mutable_vector() {
966 invalidate_sig_words();
967 return m_reg;
968 }
969
970 const secure_vector<word>& const_vector() const { return m_reg; }
971
972 word get_word_at(size_t n) const {
973 if(n < m_reg.size()) {
974 return m_reg[n];
975 }
976 return 0;
977 }
978
979 void set_word_at(size_t i, word w) {
980 invalidate_sig_words();
981 if(i >= m_reg.size()) {
982 if(w == 0) {
983 return;
984 }
985 grow_to(i + 1);
986 }
987 m_reg[i] = w;
988 }
989
990 void set_words(const word w[], size_t len) {
991 invalidate_sig_words();
992 m_reg.assign(w, w + len);
993 }
994
995 void set_to_zero() {
996 m_reg.resize(m_reg.capacity());
997 clear_mem(m_reg.data(), m_reg.size());
998 m_sig_words = 0;
999 }
1000
1001 void set_size(size_t s) {
1002 invalidate_sig_words();
1003 clear_mem(m_reg.data(), m_reg.size());
1004 m_reg.resize(s + (8 - (s % 8)));
1005 }
1006
1007 void mask_bits(size_t n) {
1008 if(n == 0) {
1009 return set_to_zero();
1010 }
1011
1012 const size_t top_word = n / BOTAN_MP_WORD_BITS;
1013
1014 // if(top_word < sig_words()) ?
1015 if(top_word < size()) {
1016 const word mask = (static_cast<word>(1) << (n % BOTAN_MP_WORD_BITS)) - 1;
1017 const size_t len = size() - (top_word + 1);
1018 if(len > 0) {
1019 clear_mem(&m_reg[top_word + 1], len);
1020 }
1021 m_reg[top_word] &= mask;
1022 invalidate_sig_words();
1023 }
1024 }
1025
1026 void grow_to(size_t n) const {
1027 if(n > size()) {
1028 if(n <= m_reg.capacity()) {
1029 m_reg.resize(n);
1030 } else {
1031 m_reg.resize(n + (8 - (n % 8)));
1032 }
1033 }
1034 }
1035
1036 size_t size() const { return m_reg.size(); }
1037
1038 void shrink_to_fit(size_t min_size = 0) {
1039 const size_t words = std::max(min_size, sig_words());
1040 m_reg.resize(words);
1041 }
1042
1043 void resize(size_t s) { m_reg.resize(s); }
1044
1045 void swap(Data& other) {
1046 m_reg.swap(other.m_reg);
1047 std::swap(m_sig_words, other.m_sig_words);
1048 }
1049
1050 void swap(secure_vector<word>& reg) {
1051 m_reg.swap(reg);
1052 invalidate_sig_words();
1053 }
1054
1055 void invalidate_sig_words() const { m_sig_words = sig_words_npos; }
1056
1057 size_t sig_words() const {
1058 if(m_sig_words == sig_words_npos) {
1059 m_sig_words = calc_sig_words();
1060 } else {
1061 BOTAN_DEBUG_ASSERT(m_sig_words == calc_sig_words());
1062 }
1063 return m_sig_words;
1064 }
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*/
1082inline BigInt operator+(const BigInt& x, const BigInt& y) {
1083 return BigInt::add2(x, y._data(), y.sig_words(), y.sign());
1084}
1085
1086inline BigInt operator+(const BigInt& x, word y) {
1087 return BigInt::add2(x, &y, 1, BigInt::Positive);
1088}
1089
1090inline BigInt operator+(word x, const BigInt& y) {
1091 return y + x;
1092}
1093
1094inline BigInt operator-(const BigInt& x, const BigInt& y) {
1095 return BigInt::add2(x, y._data(), y.sig_words(), y.reverse_sign());
1096}
1097
1098inline BigInt operator-(const BigInt& x, word y) {
1099 return BigInt::add2(x, &y, 1, BigInt::Negative);
1100}
1101
1102BOTAN_PUBLIC_API(2, 0) BigInt operator*(const BigInt& x, const BigInt& y);
1103BOTAN_PUBLIC_API(2, 8) BigInt operator*(const BigInt& x, word y);
1104
1105inline BigInt operator*(word x, const BigInt& y) {
1106 return y * x;
1107}
1108
1109BOTAN_PUBLIC_API(2, 0) BigInt operator/(const BigInt& x, const BigInt& d);
1110BOTAN_PUBLIC_API(2, 0) BigInt operator/(const BigInt& x, word m);
1111BOTAN_PUBLIC_API(2, 0) BigInt operator%(const BigInt& x, const BigInt& m);
1112BOTAN_PUBLIC_API(2, 0) word operator%(const BigInt& x, word m);
1113BOTAN_PUBLIC_API(2, 0) BigInt operator<<(const BigInt& x, size_t n);
1114BOTAN_PUBLIC_API(2, 0) BigInt operator>>(const BigInt& x, size_t n);
1115
1116/*
1117 * Comparison Operators
1118 */
1119inline bool operator==(const BigInt& a, const BigInt& b) {
1120 return a.is_equal(b);
1121}
1122
1123inline bool operator!=(const BigInt& a, const BigInt& b) {
1124 return !a.is_equal(b);
1125}
1126
1127inline bool operator<=(const BigInt& a, const BigInt& b) {
1128 return (a.cmp(b) <= 0);
1129}
1130
1131inline bool operator>=(const BigInt& a, const BigInt& b) {
1132 return (a.cmp(b) >= 0);
1133}
1134
1135inline bool operator<(const BigInt& a, const BigInt& b) {
1136 return a.is_less_than(b);
1137}
1138
1139inline bool operator>(const BigInt& a, const BigInt& b) {
1140 return b.is_less_than(a);
1141}
1142
1143inline bool operator==(const BigInt& a, word b) {
1144 return (a.cmp_word(b) == 0);
1145}
1146
1147inline bool operator!=(const BigInt& a, word b) {
1148 return (a.cmp_word(b) != 0);
1149}
1150
1151inline bool operator<=(const BigInt& a, word b) {
1152 return (a.cmp_word(b) <= 0);
1153}
1154
1155inline bool operator>=(const BigInt& a, word b) {
1156 return (a.cmp_word(b) >= 0);
1157}
1158
1159inline bool operator<(const BigInt& a, word b) {
1160 return (a.cmp_word(b) < 0);
1161}
1162
1163inline bool operator>(const BigInt& a, word b) {
1164 return (a.cmp_word(b) > 0);
1165}
1166
1167/*
1168 * I/O Operators
1169 */
1170BOTAN_DEPRECATED("Use BigInt::to_{hex,dec}_string")
1171BOTAN_PUBLIC_API(2, 0) std::ostream& operator<<(std::ostream&, const BigInt&);
1172
1173BOTAN_DEPRECATED("Use BigInt::from_string") BOTAN_PUBLIC_API(2, 0) std::istream& operator>>(std::istream&, BigInt&);
1174
1175} // namespace Botan
1176
1177#endif
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:98
BigInt & operator++()
Definition bigint.h:273
constexpr void _const_time_poison() const
Definition bigint.h:812
void swap(BigInt &other)
Definition bigint.h:192
static BigInt zero()
Definition bigint.h:50
size_t sig_words() const
Definition bigint.h:616
void conditionally_set_bit(size_t n, bool set_it)
Definition bigint.h:474
bool is_odd() const
Definition bigint.h:446
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:317
size_t size() const
Definition bigint.h:610
T serialize() const
Definition bigint.h:725
Sign reverse_sign() const
Definition bigint.h:577
void flip_sign()
Definition bigint.h:587
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
constexpr void _const_time_unpoison() const
Definition bigint.h:814
BigInt & operator+=(word y)
Definition bigint.h:214
BigInt & operator=(BigInt &&other)
Definition bigint.h:175
static BigInt one()
Definition bigint.h:55
BigInt & operator-=(const BigInt &y)
Definition bigint.h:220
void set_bit(size_t n)
Definition bigint.h:464
friend void swap(BigInt &x, BigInt &y)
Definition bigint.h:197
int32_t cmp_word(word n) const
Definition bigint.cpp:134
void mask_bits(size_t n)
Definition bigint.h:490
BigInt operator--(int)
Definition bigint.h:292
bool is_even() const
Definition bigint.h:440
static BigInt power_of_2(size_t n)
Definition bigint.h:830
bool operator!() const
Definition bigint.h:308
BigInt & operator-=(word y)
Definition bigint.h:226
BigInt & operator+=(const BigInt &y)
Definition bigint.h:208
const word * _data() const
Definition bigint.h:936
Sign sign() const
Definition bigint.h:572
BigInt & operator=(const BigInt &)=default
void _assign_from_bytes(std::span< const uint8_t > bytes)
Definition bigint.h:947
BigInt(std::span< const uint8_t > bytes)
Definition bigint.h:124
BigInt & operator--()
Definition bigint.h:278
bool is_zero() const
Definition bigint.h:458
BigInt operator++(int)
Definition bigint.h:283
bool is_negative() const
Definition bigint.h:560
bool is_nonzero() const
Definition bigint.h:452
bool is_positive() const
Definition bigint.h:566
bool get_bit(size_t n) const
Definition bigint.h:497
T serialize(size_t len) const
Definition bigint.h:712
void set_sign(Sign sign)
Definition bigint.h:593
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:71
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:1094
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
const SIMD_8x32 & b
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)