9 #ifndef BOTAN_BIGINT_H_
10 #define BOTAN_BIGINT_H_
12 #include <botan/types.h>
13 #include <botan/secmem.h>
14 #include <botan/exceptn.h>
19 class RandomNumberGenerator;
30 enum Base { Decimal = 10, Hexadecimal = 16, Binary = 256 };
35 enum Sign { Negative = 0, Positive = 1 };
73 explicit BigInt(
const std::string& str);
80 BigInt(
const uint8_t buf[],
size_t length);
86 template<
typename Alloc>
87 explicit BigInt(
const std::vector<uint8_t, Alloc>& vec) :
BigInt(vec.data(), vec.size()) {}
95 BigInt(
const uint8_t buf[],
size_t length, Base base);
104 BigInt(
const uint8_t buf[],
size_t length,
size_t max_bits);
111 BigInt(
const word words[],
size_t length);
129 BigInt(Sign sign,
size_t n);
161 m_data.swap(other.m_data);
162 std::swap(m_signedness, other.m_signedness);
186 return add(&y, 1, Positive);
204 return sub(&y, 1, Positive);
217 BigInt& operator*=(word y);
235 word operator%=(word y);
241 BigInt& operator<<=(
size_t shift);
247 BigInt& operator>>=(
size_t shift);
279 bool operator !()
const {
return (!is_nonzero()); }
281 static BigInt add2(
const BigInt& x,
const word y[],
size_t y_words, Sign y_sign);
283 BigInt& add(
const word y[],
size_t y_words, Sign sign);
287 return add(y, y_words, sign == Positive ? Negative : Positive);
364 void clear() { m_data.set_to_zero(); m_signedness = Positive; }
373 int32_t cmp(
const BigInt& n,
bool check_signs =
true)
const;
380 bool is_equal(
const BigInt& n)
const;
387 bool is_less_than(
const BigInt& n)
const;
395 int32_t cmp_word(word n)
const;
401 bool is_even()
const {
return (get_bit(0) == 0); }
407 bool is_odd()
const {
return (get_bit(0) == 1); }
421 return (sig_words() == 0);
430 conditionally_set_bit(n,
true);
441 void conditionally_set_bit(
size_t n,
bool set_it);
447 void clear_bit(
size_t n);
465 return ((word_at(n / BOTAN_MP_WORD_BITS) >> (n % BOTAN_MP_WORD_BITS)) & 1);
475 uint32_t get_substring(
size_t offset,
size_t length)
const;
488 std::string to_dec_string()
const;
493 std::string to_hex_string()
const;
499 uint8_t byte_at(
size_t n)
const;
508 return m_data.get_word_at(n);
513 m_data.set_word_at(i, w);
518 m_data.set_words(w, len);
544 if(sign() == Positive)
554 set_sign(reverse_sign());
563 if(sign == Negative && is_zero())
578 size_t size()
const {
return m_data.size(); }
586 return m_data.sig_words();
593 size_t bytes()
const;
606 size_t top_bits_free()
const;
618 const word*
data()
const {
return m_data.const_data(); }
634 void grow_to(
size_t n)
const { m_data.grow_to(n); }
642 m_data.shrink_to_fit(min_size);
645 void resize(
size_t s) { m_data.resize(s); }
664 void binary_encode(uint8_t buf[])
const;
676 void binary_encode(uint8_t buf[],
size_t len)
const;
683 void binary_decode(
const uint8_t buf[],
size_t length);
689 template<
typename Alloc>
692 binary_decode(buf.data(), buf.size());
702 BOTAN_DEPRECATED(
"See comments on declaration")
703 size_t encoded_size(Base base = Binary) const;
709 void encode_words(word out[],
size_t size) const;
715 void ct_cond_assign(
bool predicate, const
BigInt& other);
721 void ct_cond_swap(
bool predicate,
BigInt& other);
726 void cond_flip_sign(
bool predicate);
728 #if defined(BOTAN_HAS_VALGRIND)
729 void const_time_poison()
const;
730 void const_time_unpoison()
const;
765 std::vector<uint8_t> output(n.
bytes());
787 static BOTAN_DEPRECATED(
"Use n.binary_encode") void
encode(uint8_t buf[], const
BigInt& n)
789 n.binary_encode(buf);
800 return BigInt(buf, length);
808 template<
typename Alloc>
824 BOTAN_DEPRECATED(
"See comments on declaration")
837 BOTAN_DEPRECATED("See comments on declaration")
851 BOTAN_DEPRECATED("See comments on declaration")
852 static
void encode(uint8_t buf[], const
BigInt& n, Base base);
861 static
BigInt decode(const uint8_t buf[],
size_t length,
870 template<typename Alloc>
886 static void encode_1363(uint8_t out[],
size_t bytes,
const BigInt& n);
903 static void BOTAN_DEPRECATED(
"No longer in use") const_time_lookup(
915 invalidate_sig_words();
919 const word* const_data()
const
924 secure_vector<word>& mutable_vector()
926 invalidate_sig_words();
930 const secure_vector<word>& const_vector()
const
935 word get_word_at(
size_t n)
const
942 void set_word_at(
size_t i, word w)
944 invalidate_sig_words();
945 if(i >= m_reg.size())
954 void set_words(
const word w[],
size_t len)
956 invalidate_sig_words();
957 m_reg.assign(w, w + len);
962 m_reg.resize(m_reg.capacity());
967 void set_size(
size_t s)
969 invalidate_sig_words();
971 m_reg.resize(s + (8 - (s % 8)));
974 void mask_bits(
size_t n)
976 if(n == 0) {
return set_to_zero(); }
978 const size_t top_word = n / BOTAN_MP_WORD_BITS;
981 if(top_word < size())
983 const word mask = (
static_cast<word
>(1) << (n % BOTAN_MP_WORD_BITS)) - 1;
984 const size_t len = size() - (top_word + 1);
989 m_reg[top_word] &= mask;
990 invalidate_sig_words();
994 void grow_to(
size_t n)
const
998 if(n <= m_reg.capacity())
1001 m_reg.resize(n + (8 - (n % 8)));
1005 size_t size()
const {
return m_reg.size(); }
1007 void shrink_to_fit(
size_t min_size = 0)
1009 const size_t words = std::max(min_size, sig_words());
1010 m_reg.resize(words);
1013 void resize(
size_t s)
1018 void swap(Data& other)
1020 m_reg.swap(other.m_reg);
1021 std::swap(m_sig_words, other.m_sig_words);
1024 void swap(secure_vector<word>& reg)
1027 invalidate_sig_words();
1030 void invalidate_sig_words()
const
1032 m_sig_words = sig_words_npos;
1035 size_t sig_words()
const
1037 if(m_sig_words == sig_words_npos)
1039 m_sig_words = calc_sig_words();
1048 static const size_t sig_words_npos =
static_cast<size_t>(-1);
1050 size_t calc_sig_words()
const;
1052 mutable secure_vector<word> m_reg;
1053 mutable size_t m_sig_words = sig_words_npos;
1057 Sign m_signedness = Positive;
1094 word BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, word m);
1095 BigInt BOTAN_PUBLIC_API(2,0) operator<<(const BigInt& x,
size_t n);
1096 BigInt BOTAN_PUBLIC_API(2,0) operator>>(const BigInt& x,
size_t n);
1102 {
return a.is_equal(b); }
1106 {
return (a.
cmp(b) <= 0); }
1108 {
return (a.
cmp(b) >= 0); }
word word_at(size_t n) const
void binary_encode(uint8_t buf[]) const
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
bool operator>=(const X509_Time &t1, const X509_Time &t2)
OID operator+(const OID &oid, uint32_t new_component)
bool is_equal(const BigInt &n) const
BigInt & operator+=(const BigInt &y)
void binary_decode(const std::vector< uint8_t, Alloc > &buf)
void clear_mem(T *ptr, size_t n)
static std::vector< uint8_t > encode(const BigInt &n)
void const_time_unpoison() const
int(* final)(unsigned char *, CTX *)
secure_vector< word > & get_word_vector()
#define BOTAN_PUBLIC_API(maj, min)
Sign reverse_sign() const
void swap_reg(secure_vector< word > ®)
BigInt operator-(const BigInt &x, const BigInt &y)
uint32_t to_u32bit(const std::string &str)
static secure_vector< uint8_t > encode_locked(const BigInt &n)
int32_t cmp(const BigInt &n, bool check_signs=true) const
bool operator<(const OID &a, const OID &b)
BigInt abs(const BigInt &n)
std::vector< T, secure_allocator< T >> secure_vector
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
#define BOTAN_DEBUG_ASSERT(expr)
const secure_vector< word > & get_word_vector() const
BigInt square(const BigInt &x)
const word * data() const
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
void set_words(const word w[], size_t len)
static BigInt power_of_2(size_t n)
static BigInt decode(const std::vector< uint8_t, Alloc > &buf)
static BigInt decode(const uint8_t buf[], size_t length)
BigInt(const std::vector< uint8_t, Alloc > &vec)
void grow_to(size_t n) const
BigInt & sub(const word y[], size_t y_words, Sign sign)
void set_word_at(size_t i, word w)
bool is_less_than(const BigInt &n) const
BigInt & operator=(BigInt &&other)
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
bool get_bit(size_t n) const
int32_t cmp_word(word n) const
static BigInt add2(const BigInt &x, const word y[], size_t y_words, Sign y_sign)
BigInt & operator-=(word y)
void shrink_to_fit(size_t min_size=0)
bool operator>(const X509_Time &t1, const X509_Time &t2)
BigInt & operator+=(word y)
bool operator<=(const X509_Time &t1, const X509_Time &t2)
BigInt & operator-=(const BigInt &y)
void const_time_poison() const