10#define BOTAN_BIGINT_H_
12#include <botan/exceptn.h>
13#include <botan/mem_ops.h>
14#include <botan/secmem.h>
15#include <botan/types.h>
21class RandomNumberGenerator;
34 Binary
BOTAN_DEPRECATED(
"All functions using this enum are deprecated") = 256
40 enum Sign { Negative = 0, Positive = 1 };
61 static BigInt from_u64(uint64_t n);
68 static BigInt from_word(word n);
74 BOTAN_DEPRECATED(
"Use BigInt::from_u64 plus negation if required instead") static
BigInt from_s32(int32_t n);
98 explicit
BigInt(std::string_view str);
111 static
BigInt from_string(std::string_view str);
118 BigInt(const uint8_t buf[],
size_t length) { assign_from_bytes(std::span{buf, length}); }
124 explicit BigInt(std::span<const uint8_t> bytes) { assign_from_bytes(bytes); }
132 BOTAN_DEPRECATED(
"For hex/decimal use from_string")
BigInt(const uint8_t buf[],
size_t length, Base base);
146 static
BigInt from_bytes_with_max_bits(const uint8_t buf[],
size_t length,
size_t max_bits);
193 m_data.swap(other.m_data);
194 std::swap(m_signedness, other.m_signedness);
256 word operator%=(word y);
311 static BigInt add2(
const BigInt& x,
const word y[],
size_t y_words, Sign y_sign);
314 BigInt& add(
const word y[],
size_t y_words, Sign sign);
318 return add(y, y_words, sign == Positive ? Negative : Positive);
401 m_data.set_to_zero();
402 m_signedness = Positive;
412 int32_t cmp(
const BigInt& n,
bool check_signs =
true)
const;
419 bool is_equal(
const BigInt& n)
const;
426 bool is_less_than(
const BigInt& n)
const;
434 int32_t cmp_word(word n)
const;
440 bool is_even()
const {
return (get_bit(0) == 0); }
446 bool is_odd()
const {
return (get_bit(0) == 1); }
458 bool is_zero()
const {
return (sig_words() == 0); }
464 void set_bit(
size_t n) { conditionally_set_bit(n,
true); }
477 m_data.set_word_at(which, word_at(which) | mask);
484 void clear_bit(
size_t n);
506 BOTAN_DEPRECATED(
"Deprecated no replacement") uint32_t get_substring(
size_t offset,
size_t length) const;
513 uint32_t to_u32bit() const;
522 std::
string to_dec_string() const;
535 std::
string to_hex_string() const;
541 uint8_t byte_at(
size_t n) const;
548 word word_at(
size_t n)
const {
return m_data.get_word_at(n); }
550 BOTAN_DEPRECATED(
"Deprecated no replacement") void set_word_at(
size_t i, word w) { m_data.set_word_at(i, w); }
553 m_data.set_words(w, len);
578 if(sign() == Positive) {
594 if(sign == Negative && is_zero()) {
610 size_t size()
const {
return m_data.size(); }
622 size_t bytes()
const;
641 BOTAN_DEPRECATED("Deprecated no replacement") word* mutable_data() {
return m_data.mutable_data(); }
647 BOTAN_DEPRECATED(
"Deprecated no replacement") const word* data()
const {
return m_data.const_data(); }
653 return m_data.mutable_vector();
660 return m_data.const_vector();
667 BOTAN_DEPRECATED(
"Deprecated no replacement") void grow_to(
size_t n)
const { m_data.grow_to(n); }
702 void serialize_to(std::span<uint8_t> out)
const;
711 template <
typename T = std::vector<u
int8_t>>
717 this->serialize_to(out);
724 template <
typename T = std::vector<u
int8_t>>
726 return serialize<T>(this->bytes());
734 this->serialize_to(std::span{buf, this->bytes()});
751 BOTAN_DEPRECATED(
"Use BigInt::serialize_to") void binary_encode(uint8_t buf[],
size_t len) const;
759 this->assign_from_bytes(std::span{buf, length});
766 BOTAN_DEPRECATED(
"Use BigInt::from_bytes") void binary_decode(std::span<const uint8_t> buf) {
767 this->assign_from_bytes(buf);
774 BOTAN_DEPRECATED(
"Deprecated no replacement") void encode_words(word out[],
size_t size) const;
780 void ct_cond_assign(
bool predicate, const
BigInt& other);
786 void ct_cond_swap(
bool predicate,
BigInt& other);
791 void ct_cond_add(
bool predicate, const
BigInt& value);
797 void ct_shift_left(
size_t shift);
802 void cond_flip_sign(
bool predicate);
804 BOTAN_DEPRECATED("replaced by internal API")
void const_time_poison()
const { _const_time_poison(); }
806 BOTAN_DEPRECATED(
"replaced by internal API") void const_time_unpoison()
const { _const_time_unpoison(); }
808#if defined(BOTAN_CT_POISON_ENABLED)
809 void _const_time_poison()
const;
810 void _const_time_unpoison()
const;
842 return n.serialize<std::vector<uint8_t>>(n.bytes());
859 static BigInt from_bytes(std::span<const uint8_t> bytes);
868 return BigInt::from_bytes(std::span{buf, length});
877 return BigInt::from_bytes(buf);
888 static
BigInt decode(const uint8_t buf[],
size_t length, Base base);
896 BOTAN_DEPRECATED("For decimal/hex use from_string") static
BigInt decode(std::span<const uint8_t> buf, Base base);
914 static
void encode_1363(uint8_t out[],
size_t bytes, const
BigInt& n) {
915 n.serialize_to(std::span{out, bytes});
936 const word* _data()
const {
return m_data.const_data(); }
954 void assign_from_bytes(std::span<const uint8_t> bytes);
958 word* mutable_data() {
959 invalidate_sig_words();
963 const word* const_data()
const {
return m_reg.data(); }
965 secure_vector<word>& mutable_vector() {
966 invalidate_sig_words();
970 const secure_vector<word>& const_vector()
const {
return m_reg; }
972 word get_word_at(
size_t n)
const {
973 if(n < m_reg.size()) {
979 void set_word_at(
size_t i, word w) {
980 invalidate_sig_words();
981 if(i >= m_reg.size()) {
990 void set_words(
const word w[],
size_t len) {
991 invalidate_sig_words();
992 m_reg.assign(w, w + len);
996 m_reg.resize(m_reg.capacity());
1001 void set_size(
size_t s) {
1002 invalidate_sig_words();
1004 m_reg.resize(s + (8 - (s % 8)));
1007 void mask_bits(
size_t n) {
1009 return set_to_zero();
1015 if(top_word < size()) {
1017 const size_t len = size() - (top_word + 1);
1021 m_reg[top_word] &= mask;
1022 invalidate_sig_words();
1026 void grow_to(
size_t n)
const {
1028 if(n <= m_reg.capacity()) {
1031 m_reg.resize(n + (8 - (n % 8)));
1036 size_t size()
const {
return m_reg.size(); }
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);
1043 void resize(
size_t s) { m_reg.resize(s); }
1045 void swap(Data& other) {
1046 m_reg.swap(other.m_reg);
1047 std::swap(m_sig_words, other.m_sig_words);
1050 void swap(secure_vector<word>& reg) {
1052 invalidate_sig_words();
1055 void invalidate_sig_words()
const { m_sig_words = sig_words_npos; }
1057 size_t sig_words()
const {
1058 if(m_sig_words == sig_words_npos) {
1059 m_sig_words = calc_sig_words();
1067 static const size_t sig_words_npos =
static_cast<size_t>(-1);
1069 size_t calc_sig_words()
const;
1071 mutable secure_vector<word> m_reg;
1072 mutable size_t m_sig_words = sig_words_npos;
1076 Sign m_signedness = Positive;
1128 return (a.
cmp(
b) <= 0);
1132 return (a.
cmp(
b) >= 0);
1140 return b.is_less_than(a);
1171BOTAN_PUBLIC_API(2, 0) std::ostream& operator<<(std::ostream&, const BigInt&);
#define BOTAN_DEBUG_ASSERT(expr)
constexpr void _const_time_poison() const
void conditionally_set_bit(size_t n, bool set_it)
bool is_equal(const BigInt &n) const
BigInt & sub(const word y[], size_t y_words, Sign sign)
Sign reverse_sign() const
static BigInt add2(const BigInt &x, const word y[], size_t y_words, Sign y_sign)
bool is_less_than(const BigInt &n) const
int32_t cmp(const BigInt &n, bool check_signs=true) const
constexpr void _const_time_unpoison() const
BigInt & operator+=(word y)
BigInt & operator=(BigInt &&other)
BigInt & operator-=(const BigInt &y)
friend void swap(BigInt &x, BigInt &y)
int32_t cmp_word(word n) const
static BigInt power_of_2(size_t n)
BigInt & operator-=(word y)
BigInt & operator+=(const BigInt &y)
const word * _data() const
BigInt & operator=(const BigInt &)=default
void _assign_from_bytes(std::span< const uint8_t > bytes)
BigInt(std::span< const uint8_t > bytes)
bool get_bit(size_t n) const
T serialize(size_t len) const
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
#define BOTAN_DEPRECATED(msg)
#define BOTAN_MP_WORD_BITS
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)
OctetString operator+(const OctetString &k1, const OctetString &k2)
bool operator>(const ASN1_Time &, const ASN1_Time &)
BigInt abs(const BigInt &n)
BigInt operator-(const BigInt &x, const BigInt &y)
constexpr auto operator/=(Strong< T1, Tags... > &a, T2 b)
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
constexpr auto operator<<=(Strong< T1, Tags... > &a, T2 b)
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
std::vector< T, secure_allocator< T > > secure_vector
constexpr void clear_mem(T *ptr, size_t n)
constexpr auto operator*=(Strong< T1, Tags... > &a, T2 b)