diff options
37 files changed, 218 insertions, 145 deletions
diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp index cc9cfb09a..a68a94005 100644 --- a/src/cli/speed.cpp +++ b/src/cli/speed.cpp @@ -1124,7 +1124,10 @@ class Speed final : public Command auto dbl_timer = make_timer(group_name + " dbl"); const Botan::PointGFp& base_point = ec_group.get_base_point(); - Botan::PointGFp non_affine_pt = ec_group.get_base_point() * 1776; // create a non-affine point + + // create a non-affine point + const auto random_k = Botan::BigInt::from_u64(0x4E6F537465707E); + Botan::PointGFp non_affine_pt = ec_group.get_base_point() * random_k; Botan::PointGFp pt = ec_group.get_base_point(); std::vector<Botan::BigInt> ws(Botan::PointGFp::WORKSPACE_SIZE); @@ -1227,7 +1230,7 @@ class Speed final : public Command void bench_fpe_fe1(const std::chrono::milliseconds runtime) { - const Botan::BigInt n = 1000000000000000; + const auto n = Botan::BigInt::from_u64(1000000000000000); auto enc_timer = make_timer("FPE_FE1 encrypt"); auto dec_timer = make_timer("FPE_FE1 decrypt"); @@ -1235,7 +1238,7 @@ class Speed final : public Command const Botan::SymmetricKey key(rng(), 32); const std::vector<uint8_t> tweak(8); // 8 zeros - Botan::BigInt x = 1; + auto x = Botan::BigInt::one(); Botan::FPE_FE1 fpe_fe1(n); fpe_fe1.set_key(key); @@ -1377,7 +1380,7 @@ class Speed final : public Command Botan::BigInt x; Botan::secure_vector<Botan::word> ws; - const Botan::BigInt ten(10); + const auto ten = Botan::BigInt::from_word(10); Botan::BigInt q1, r1, q2; uint8_t r2; @@ -1585,7 +1588,7 @@ class Speed final : public Command void bench_random_prime(const std::chrono::milliseconds runtime) { - const size_t coprime = 65537; // simulates RSA key gen + const auto coprime = Botan::BigInt::from_word(0x10001); for(size_t bits : { 256, 384, 512, 768, 1024, 1536 }) { diff --git a/src/lib/asn1/ber_dec.cpp b/src/lib/asn1/ber_dec.cpp index 11f9b5412..c35cd1024 100644 --- a/src/lib/asn1/ber_dec.cpp +++ b/src/lib/asn1/ber_dec.cpp @@ -467,7 +467,7 @@ BER_Decoder& BER_Decoder::decode(BigInt& out, if(obj.length() == 0) { - out = 0; + out.clear(); } else { diff --git a/src/lib/asn1/der_enc.cpp b/src/lib/asn1/der_enc.cpp index bdae43075..e40b492d8 100644 --- a/src/lib/asn1/der_enc.cpp +++ b/src/lib/asn1/der_enc.cpp @@ -295,7 +295,7 @@ DER_Encoder& DER_Encoder::encode(bool is_true) */ DER_Encoder& DER_Encoder::encode(size_t n) { - return encode(BigInt(n), ASN1_Type::Integer, ASN1_Class::Universal); + return encode(BigInt::from_u64(n), ASN1_Type::Integer, ASN1_Class::Universal); } /* @@ -331,7 +331,7 @@ DER_Encoder& DER_Encoder::encode(bool is_true, DER_Encoder& DER_Encoder::encode(size_t n, ASN1_Type type_tag, ASN1_Class class_tag) { - return encode(BigInt(n), type_tag, class_tag); + return encode(BigInt::from_u64(n), type_tag, class_tag); } /* diff --git a/src/lib/ffi/ffi_mp.cpp b/src/lib/ffi/ffi_mp.cpp index 96ef9998f..1f7dece47 100644 --- a/src/lib/ffi/ffi_mp.cpp +++ b/src/lib/ffi/ffi_mp.cpp @@ -37,15 +37,7 @@ int botan_mp_clear(botan_mp_t mp) int botan_mp_set_from_int(botan_mp_t mp, int initial_value) { return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { - if(initial_value >= 0) - { - bn = Botan::BigInt(static_cast<uint64_t>(initial_value)); - } - else - { - bn = Botan::BigInt(static_cast<uint64_t>(-initial_value)); - bn.flip_sign(); - } + bn = Botan::BigInt::from_s32(initial_value); }); } diff --git a/src/lib/math/bigint/big_ops3.cpp b/src/lib/math/bigint/big_ops3.cpp index e686e951c..43a722ee8 100644 --- a/src/lib/math/bigint/big_ops3.cpp +++ b/src/lib/math/bigint/big_ops3.cpp @@ -19,11 +19,12 @@ BigInt BigInt::add2(const BigInt& x, const word y[], size_t y_words, BigInt::Sig { const size_t x_sw = x.sig_words(); - BigInt z(x.sign(), std::max(x_sw, y_words) + 1); + BigInt z = BigInt::with_capacity(std::max(x_sw, y_words) + 1); if(x.sign() == y_sign) { bigint_add3(z.mutable_data(), x.data(), x_sw, y, y_words); + z.set_sign(x.sign()); } else { @@ -34,6 +35,8 @@ BigInt BigInt::add2(const BigInt& x, const word y[], size_t y_words, BigInt::Sig z.set_sign(y_sign); else if(relative_size == 0) z.set_sign(BigInt::Positive); + else + z.set_sign(x.sign()); } return z; @@ -47,7 +50,7 @@ BigInt operator*(const BigInt& x, const BigInt& y) const size_t x_sw = x.sig_words(); const size_t y_sw = y.sig_words(); - BigInt z(BigInt::Positive, x.size() + y.size()); + BigInt z = BigInt::with_capacity(x.size() + y.size()); if(x_sw == 1 && y_sw) bigint_linmul3(z.mutable_data(), y.data(), y_sw, x.word_at(0)); @@ -75,7 +78,7 @@ BigInt operator*(const BigInt& x, word y) { const size_t x_sw = x.sig_words(); - BigInt z(BigInt::Positive, x_sw + 1); + BigInt z = BigInt::with_capacity(x_sw + 1); if(x_sw && y) { @@ -121,7 +124,7 @@ BigInt operator/(const BigInt& x, word y) } BigInt q, r; - vartime_divide(x, y, q, r); + vartime_divide_word(x, y, q, r); return q; } @@ -139,7 +142,7 @@ BigInt operator%(const BigInt& n, const BigInt& mod) if(mod.sig_words() == 1) { - return n % mod.word_at(0); + return BigInt::from_word(n % mod.word_at(0)); } BigInt q, r; @@ -188,8 +191,9 @@ BigInt operator<<(const BigInt& x, size_t shift) const size_t x_sw = x.sig_words(); - BigInt y(x.sign(), x_sw + shift_words + (shift_bits ? 1 : 0)); + BigInt y = BigInt::with_capacity(x_sw + shift_words + (shift_bits ? 1 : 0)); bigint_shl2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits); + y.set_sign(x.sign()); return y; } @@ -203,13 +207,15 @@ BigInt operator>>(const BigInt& x, size_t shift) const size_t x_sw = x.sig_words(); if(shift_words >= x_sw) - return 0; + return BigInt::zero(); - BigInt y(x.sign(), x_sw - shift_words); + BigInt y = BigInt::with_capacity(x_sw - shift_words); bigint_shr2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits); if(x.is_negative() && y.is_zero()) y.set_sign(BigInt::Positive); + else + y.set_sign(x.sign()); return y; } diff --git a/src/lib/math/bigint/bigint.cpp b/src/lib/math/bigint/bigint.cpp index 33681f9e5..3856ac1fe 100644 --- a/src/lib/math/bigint/bigint.cpp +++ b/src/lib/math/bigint/bigint.cpp @@ -14,35 +14,54 @@ namespace Botan { -BigInt::BigInt(const word words[], size_t length) +BigInt::BigInt(uint64_t n) { - m_data.set_words(words, length); +#if BOTAN_MP_WORD_BITS == 64 + m_data.set_word_at(0, n); +#else + m_data.set_word_at(1, static_cast<word>(n >> 32)); + m_data.set_word_at(0, static_cast<word>(n)); +#endif } -/* -* Construct a BigInt from a regular number -*/ -BigInt::BigInt(uint64_t n) +//static +BigInt BigInt::from_u64(uint64_t n) { - if(n > 0) - { -#if BOTAN_MP_WORD_BITS == 32 - m_data.set_word_at(0, static_cast<word>(n)); - m_data.set_word_at(1, static_cast<word>(n >> 32)); + BigInt bn; + +#if BOTAN_MP_WORD_BITS == 64 + bn.set_word_at(0, n); #else - m_data.set_word_at(0, n); + bn.set_word_at(1, static_cast<word>(n >> 32)); + bn.set_word_at(0, static_cast<word>(n)); #endif - } + return bn; } -/* -* Construct a BigInt of the specified size -*/ -BigInt::BigInt(Sign s, size_t size) +//static +BigInt BigInt::from_word(word n) { - m_data.set_size(size); - m_signedness = s; + BigInt bn; + bn.set_word_at(0, n); + return bn; + } + +//static +BigInt BigInt::from_s32(int32_t n) + { + if(n >= 0) + return BigInt::from_u64(static_cast<uint64_t>(n)); + else + return -BigInt::from_u64(static_cast<uint64_t>(-n)); + } + +//static +BigInt BigInt::with_capacity(size_t size) + { + BigInt bn; + bn.grow_to(size); + return bn; } /* @@ -87,15 +106,19 @@ BigInt::BigInt(const uint8_t input[], size_t length, Base base) *this = decode(input, length, base); } -BigInt::BigInt(const uint8_t buf[], size_t length, size_t max_bits) +//static +BigInt BigInt::from_bytes_with_max_bits(const uint8_t buf[], size_t length, size_t max_bits) { if(8 * length > max_bits) length = (max_bits + 7) / 8; - binary_decode(buf, length); + BigInt bn; + bn.binary_decode(buf, length); if(8 * length > max_bits) - *this >>= (8 - (max_bits % 8)); + bn >>= (8 - (max_bits % 8)); + + return bn; } /* diff --git a/src/lib/math/bigint/bigint.h b/src/lib/math/bigint/bigint.h index 1712724b1..352a4a0d0 100644 --- a/src/lib/math/bigint/bigint.h +++ b/src/lib/math/bigint/bigint.h @@ -35,12 +35,40 @@ class BOTAN_PUBLIC_API(2,0) BigInt final enum Sign { Negative = 0, Positive = 1 }; /** - * Create empty BigInt + * Create empty (zero) BigInt */ BigInt() = default; /** - * Create BigInt from 64 bit integer + * Create a 0-value BigInt + */ + static BigInt zero() { return BigInt(); } + + /** + * Create a 1-value BigInt + */ + static BigInt one() { return BigInt::from_word(1); } + + /** + * Create BigInt from an unsigned 64 bit integer + * @param n initial value of this BigInt + */ + static BigInt from_u64(uint64_t n); + + /** + * Create BigInt from a word (limb) + * @param n initial value of this BigInt + */ + static BigInt from_word(word n); + + /** + * Create BigInt from a signed 32 bit integer + * @param n initial value of this BigInt + */ + static BigInt from_s32(int32_t n); + + /** + * Create BigInt from an unsigned 64 bit integer * @param n initial value of this BigInt */ BigInt(uint64_t n); @@ -89,14 +117,8 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @param max_bits if the resulting integer is more than max_bits, * it will be shifted so it is at most max_bits in length. */ - BigInt(const uint8_t buf[], size_t length, size_t max_bits); - - /** - * Create a BigInt from an array of words - * @param words the words - * @param length number of words - */ - BigInt(const word words[], size_t length); + static BigInt from_bytes_with_max_bits(const uint8_t buf[], size_t length, + size_t max_bits); /** * \brief Create a random BigInt of the specified size @@ -111,10 +133,9 @@ class BOTAN_PUBLIC_API(2,0) BigInt final /** * Create BigInt of specified size, all zeros - * @param sign the sign * @param n size of the internal register in words */ - BigInt(Sign sign, size_t n); + static BigInt with_capacity(size_t n); /** * Move constructor diff --git a/src/lib/math/bigint/divide.cpp b/src/lib/math/bigint/divide.cpp index b1d106872..9b92c9e39 100644 --- a/src/lib/math/bigint/divide.cpp +++ b/src/lib/math/bigint/divide.cpp @@ -56,9 +56,9 @@ void ct_divide(const BigInt& x, const BigInt& y, BigInt& q_out, BigInt& r_out) const size_t x_bits = x.bits(); - BigInt q(BigInt::Positive, x_words); - BigInt r(BigInt::Positive, y_words); - BigInt t(BigInt::Positive, y_words); // a temporary + BigInt q = BigInt::with_capacity(x_words); + BigInt r = BigInt::with_capacity(y_words); + BigInt t = BigInt::with_capacity(y_words); // a temporary for(size_t i = 0; i != x_bits; ++i) { @@ -84,7 +84,7 @@ void ct_divide_u8(const BigInt& x, uint8_t y, BigInt& q_out, uint8_t& r_out) const size_t x_words = x.sig_words(); const size_t x_bits = x.bits(); - BigInt q(BigInt::Positive, x_words); + BigInt q = BigInt::with_capacity(x_words); uint32_t r = 0; for(size_t i = 0; i != x_bits; ++i) @@ -124,8 +124,8 @@ BigInt ct_modulo(const BigInt& x, const BigInt& y) const size_t x_bits = x.bits(); - BigInt r(BigInt::Positive, y_words); - BigInt t(BigInt::Positive, y_words); + BigInt r = BigInt::with_capacity(y_words); + BigInt t = BigInt::with_capacity(y_words); for(size_t i = 0; i != x_bits; ++i) { @@ -151,6 +151,17 @@ BigInt ct_modulo(const BigInt& x, const BigInt& y) return r; } +void vartime_divide_word(const BigInt& x, const word y, BigInt& q_out, BigInt& r_out) + { + if(y == 0) + throw Invalid_Argument("vartime_divide_word: cannot divide by zero"); + + // It might be worthwhile to specialize vartime_divide for y with 1 word + + // until then: + vartime_divide(x, BigInt::from_word(y), q_out, r_out); + } + /* * Solve x = q * y + r * @@ -168,7 +179,7 @@ void vartime_divide(const BigInt& x, const BigInt& y_arg, BigInt& q_out, BigInt& BigInt y = y_arg; BigInt r = x; - BigInt q = 0; + BigInt q = BigInt::zero(); secure_vector<word> ws; r.set_sign(BigInt::Positive); diff --git a/src/lib/math/bigint/divide.h b/src/lib/math/bigint/divide.h index cd98ca3eb..26468bda1 100644 --- a/src/lib/math/bigint/divide.h +++ b/src/lib/math/bigint/divide.h @@ -26,6 +26,19 @@ void vartime_divide(const BigInt& x, BigInt& r); /** +* BigInt/word Division +* @param x an integer +* @param y a non-zero integer +* @param q will be set to x / y +* @param r will be set to x % y +*/ +BOTAN_TEST_API +void vartime_divide_word(const BigInt& x, + word y, + BigInt& q, + BigInt& r); + +/** * BigInt division, const time variant * * This runs with control flow independent of the values of x/y. diff --git a/src/lib/math/bigint/info.txt b/src/lib/math/bigint/info.txt index c358299eb..d4dadfac4 100644 --- a/src/lib/math/bigint/info.txt +++ b/src/lib/math/bigint/info.txt @@ -1,5 +1,5 @@ <defines> -BIGINT -> 20131128 +BIGINT -> 20210423 </defines> <header:public> diff --git a/src/lib/math/numbertheory/make_prm.cpp b/src/lib/math/numbertheory/make_prm.cpp index 760e916e2..c5536b790 100644 --- a/src/lib/math/numbertheory/make_prm.cpp +++ b/src/lib/math/numbertheory/make_prm.cpp @@ -136,15 +136,15 @@ BigInt random_prime(RandomNumberGenerator& rng, if(bits == 2) { - return ((rng.next_byte() % 2) ? 2 : 3); + return BigInt::from_word(((rng.next_byte() % 2) ? 2 : 3)); } else if(bits == 3) { - return ((rng.next_byte() % 2) ? 5 : 7); + return BigInt::from_word(((rng.next_byte() % 2) ? 5 : 7)); } else if(bits == 4) { - return ((rng.next_byte() % 2) ? 11 : 13); + return BigInt::from_word(((rng.next_byte() % 2) ? 11 : 13)); } else { @@ -157,7 +157,7 @@ BigInt random_prime(RandomNumberGenerator& rng, const uint16_t small_prime = PRIMES[idx]; if(high_bit(small_prime) == bits) - return small_prime; + return BigInt::from_word(small_prime); } } } @@ -320,7 +320,7 @@ BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits) Generate q == 2 (mod 3), since otherwise [in the case of q == 1 (mod 3)], 2*q+1 == 3 (mod 3) and so certainly not prime. */ - q = random_prime(rng, bits - 1, 0, 2, 3, error_bound); + q = random_prime(rng, bits - 1, BigInt::zero(), 2, 3, error_bound); p = (q << 1) + 1; if(is_prime(p, rng, error_bound, true)) diff --git a/src/lib/math/numbertheory/mod_inv.cpp b/src/lib/math/numbertheory/mod_inv.cpp index 1c07c125f..a50861d8e 100644 --- a/src/lib/math/numbertheory/mod_inv.cpp +++ b/src/lib/math/numbertheory/mod_inv.cpp @@ -135,15 +135,15 @@ BigInt inverse_mod_pow2(const BigInt& a1, size_t k) */ if(a1.is_even() || k == 0) - return 0; + return BigInt::zero(); if(k == 1) - return 1; + return BigInt::one(); BigInt a = a1; a.mask_bits(k); - BigInt b = 1; - BigInt X = 0; + BigInt b = BigInt::one(); + BigInt X = BigInt::zero(); BigInt newb; const size_t a_words = a.sig_words(); @@ -181,7 +181,7 @@ BigInt inverse_mod(const BigInt& n, const BigInt& mod) if(mod.is_negative() || n.is_negative()) throw Invalid_Argument("inverse_mod: arguments must be non-negative"); if(n.is_zero() || (n.is_even() && mod.is_even())) - return 0; + return BigInt::zero(); if(mod.is_odd()) { @@ -232,7 +232,7 @@ BigInt inverse_mod(const BigInt& n, const BigInt& mod) // No modular inverse in this case: if(inv_o == 0) - return 0; + return BigInt::zero(); BigInt h = inv_o; h.ct_cond_add(!inv_o.get_bit(0), o); @@ -253,7 +253,7 @@ BigInt inverse_mod(const BigInt& n, const BigInt& mod) // No modular inverse in this case: if(inv_o == 0 || inv_2k == 0) - return 0; + return BigInt::zero(); const BigInt m2k = BigInt::power_of_2(mod_lz); // Compute the CRT parameter diff --git a/src/lib/math/numbertheory/monty.cpp b/src/lib/math/numbertheory/monty.cpp index a6e22c9b7..9021db1f0 100644 --- a/src/lib/math/numbertheory/monty.cpp +++ b/src/lib/math/numbertheory/monty.cpp @@ -109,7 +109,7 @@ BigInt Montgomery_Params::mul(const BigInt& x, const BigInt& y, BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); - BigInt z(BigInt::Positive, output_size); + BigInt z = BigInt::with_capacity(output_size); bigint_mul(z.mutable_data(), z.size(), x.data(), x.size(), std::min(m_p_words, x.size()), y.data(), y.size(), std::min(m_p_words, y.size()), @@ -129,7 +129,7 @@ BigInt Montgomery_Params::mul(const BigInt& x, const size_t output_size = 2*m_p_words + 2; if(ws.size() < output_size) ws.resize(output_size); - BigInt z(BigInt::Positive, output_size); + BigInt z = BigInt::with_capacity(output_size); BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); @@ -208,7 +208,7 @@ BigInt Montgomery_Params::sqr(const BigInt& x, secure_vector<word>& ws) const if(ws.size() < output_size) ws.resize(output_size); - BigInt z(BigInt::Positive, output_size); + BigInt z = BigInt::with_capacity(output_size); BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); @@ -283,9 +283,10 @@ Montgomery_Int::Montgomery_Int(std::shared_ptr<const Montgomery_Params> params, Montgomery_Int::Montgomery_Int(std::shared_ptr<const Montgomery_Params> params, const word words[], size_t len, bool redc_needed) : - m_params(params), - m_v(words, len) + m_params(params) { + m_v.set_words(words, len); + if(redc_needed) { BOTAN_ASSERT_NOMSG(m_v < m_params->p()); diff --git a/src/lib/math/numbertheory/monty_exp.cpp b/src/lib/math/numbertheory/monty_exp.cpp index 112041be2..0c17bc2bd 100644 --- a/src/lib/math/numbertheory/monty_exp.cpp +++ b/src/lib/math/numbertheory/monty_exp.cpp @@ -106,7 +106,7 @@ BigInt Montgomery_Exponentation_State::exponentiation(const BigInt& scalar, size const size_t exp_nibbles = (max_k_bits + m_window_bits - 1) / m_window_bits; if(exp_nibbles == 0) - return 1; + return BigInt::one(); secure_vector<word> e_bits(m_params->p_words()); secure_vector<word> ws; @@ -132,7 +132,7 @@ BigInt Montgomery_Exponentation_State::exponentiation_vartime(const BigInt& scal secure_vector<word> ws; if(exp_nibbles == 0) - return 1; + return BigInt::one(); Montgomery_Int x = m_g[scalar.get_substring(m_window_bits*(exp_nibbles-1), m_window_bits)]; diff --git a/src/lib/math/numbertheory/numthry.cpp b/src/lib/math/numbertheory/numthry.cpp index 96fe37756..528b5e851 100644 --- a/src/lib/math/numbertheory/numthry.cpp +++ b/src/lib/math/numbertheory/numthry.cpp @@ -43,7 +43,7 @@ BigInt ressol(const BigInt& a, const BigInt& p) throw Invalid_Argument("ressol: invalid prime"); if(a == 0) - return 0; + return BigInt::zero(); else if(a < 0) throw Invalid_Argument("ressol: value to solve for must be positive"); else if(a >= p) @@ -53,7 +53,7 @@ BigInt ressol(const BigInt& a, const BigInt& p) return a; if(jacobi(a, p) != 1) // not a quadratic residue - return -BigInt(1); + return BigInt::from_s32(-1); Modular_Reducer mod_p(p); auto monty_p = std::make_shared<Montgomery_Params>(p, mod_p); @@ -80,7 +80,7 @@ BigInt ressol(const BigInt& a, const BigInt& p) word z = 2; for(;;) { - if(jacobi(z, p) == -1) // found one + if(jacobi(BigInt::from_word(z), p) == -1) // found one break; z += 1; // try next z @@ -91,10 +91,10 @@ BigInt ressol(const BigInt& a, const BigInt& p) * certainly we have been given a non-prime p. */ if(z >= 256) - return -BigInt(1); + return BigInt::from_s32(-1); } - BigInt c = monty_exp_vartime(monty_p, z, (q << 1) + 1); + BigInt c = monty_exp_vartime(monty_p, BigInt::from_word(z), (q << 1) + 1); while(n > 1) { @@ -108,7 +108,7 @@ BigInt ressol(const BigInt& a, const BigInt& p) if(i >= s) { - return -BigInt(1); + return BigInt::from_s32(-1); } } @@ -201,7 +201,7 @@ size_t low_zero_bits(const BigInt& n) } // if we saw no words with x > 0 then n == 0 and the value we have - // computed is meaningless. Instead return 0 in that case. + // computed is meaningless. Instead return BigInt::zero() in that case. return seen_nonempty_word.if_set_return(low_zero); } @@ -230,7 +230,7 @@ BigInt gcd(const BigInt& a, const BigInt& b) if(b.is_zero()) return abs(a); if(a == 1 || b == 1) - return 1; + return BigInt::one(); // See https://gcd.cr.yp.to/safegcd-20190413.pdf fig 1.2 @@ -297,14 +297,14 @@ BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) { if(mod.is_negative() || mod == 1) { - return 0; + return BigInt::zero(); } if(base.is_zero() || mod.is_zero()) { if(exp.is_zero()) - return 1; - return 0; + return BigInt::one(); + return BigInt::zero(); } Modular_Reducer reduce_mod(mod); @@ -321,7 +321,7 @@ BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) Support for even modulus is just a convenience and not considered cryptographically important, so this implementation is slow ... */ - BigInt accum = 1; + BigInt accum = BigInt::one(); BigInt g = reduce_mod.reduce(base); BigInt t; @@ -340,7 +340,7 @@ BigInt is_perfect_square(const BigInt& C) if(C < 1) throw Invalid_Argument("is_perfect_square requires C >= 1"); if(C == 1) - return 1; + return BigInt::one(); const size_t n = C.bits(); const size_t m = (n + 1) / 2; @@ -361,7 +361,7 @@ BigInt is_perfect_square(const BigInt& C) if(X2 == C) return X; else - return 0; + return BigInt::zero(); } /* diff --git a/src/lib/math/numbertheory/numthry.h b/src/lib/math/numbertheory/numthry.h index 684022a1c..92a99418b 100644 --- a/src/lib/math/numbertheory/numthry.h +++ b/src/lib/math/numbertheory/numthry.h @@ -136,7 +136,7 @@ BigInt BOTAN_PUBLIC_API(2,8) is_perfect_square(const BigInt& x); */ BigInt BOTAN_PUBLIC_API(2,0) random_prime(RandomNumberGenerator& rng, size_t bits, - const BigInt& coprime = 0, + const BigInt& coprime = BigInt::from_u64(0), size_t equiv = 1, size_t equiv_mod = 2, size_t prob = 128); diff --git a/src/lib/math/numbertheory/primality.cpp b/src/lib/math/numbertheory/primality.cpp index 779677ef8..d980a8a57 100644 --- a/src/lib/math/numbertheory/primality.cpp +++ b/src/lib/math/numbertheory/primality.cpp @@ -25,7 +25,7 @@ bool is_lucas_probable_prime(const BigInt& C, const Modular_Reducer& mod_C) else if(C == 3 || C == 5 || C == 7 || C == 11 || C == 13) return true; - BigInt D = 5; + BigInt D = BigInt::from_word(5); for(;;) { @@ -55,8 +55,8 @@ bool is_lucas_probable_prime(const BigInt& C, const Modular_Reducer& mod_C) const BigInt K = C + 1; const size_t K_bits = K.bits() - 1; - BigInt U = 1; - BigInt V = 1; + BigInt U = BigInt::one(); + BigInt V = BigInt::one(); BigInt Ut, Vt, U2, V2; @@ -95,7 +95,8 @@ bool is_bailie_psw_probable_prime(const BigInt& n, const Modular_Reducer& mod_n) return false; auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n); - return passes_miller_rabin_test(n, mod_n, monty_n, 2) && is_lucas_probable_prime(n, mod_n); + const auto base = BigInt::from_word(2); + return passes_miller_rabin_test(n, mod_n, monty_n, base) && is_lucas_probable_prime(n, mod_n); } bool is_bailie_psw_probable_prime(const BigInt& n) @@ -158,7 +159,7 @@ bool is_miller_rabin_probable_prime(const BigInt& n, for(size_t i = 0; i != test_iterations; ++i) { - const BigInt a = BigInt::random_integer(rng, 2, n); + const BigInt a = BigInt::random_integer(rng, BigInt::from_word(2), n); if(!passes_miller_rabin_test(n, mod_n, monty_n, a)) return false; diff --git a/src/lib/misc/fpe_fe1/fpe_fe1.cpp b/src/lib/misc/fpe_fe1/fpe_fe1.cpp index ab6d073c1..895ca11a0 100644 --- a/src/lib/misc/fpe_fe1/fpe_fe1.cpp +++ b/src/lib/misc/fpe_fe1/fpe_fe1.cpp @@ -26,8 +26,8 @@ const size_t MAX_N_BYTES = 128/8; */ void factor(BigInt n, BigInt& a, BigInt& b) { - a = 1; - b = 1; + a = BigInt::one(); + b = BigInt::one(); size_t n_low_zero = low_zero_bits(n); @@ -42,7 +42,7 @@ void factor(BigInt n, BigInt& a, BigInt& b) a *= PRIMES[i]; if(a > b) std::swap(a, b); - n /= PRIMES[i]; + n /= BigInt::from_word(PRIMES[i]); } } diff --git a/src/lib/prov/pkcs11/p11_rsa.h b/src/lib/prov/pkcs11/p11_rsa.h index e3b557f94..50bb688e6 100644 --- a/src/lib/prov/pkcs11/p11_rsa.h +++ b/src/lib/prov/pkcs11/p11_rsa.h @@ -29,7 +29,7 @@ class BOTAN_PUBLIC_API(2,0) RSA_PublicKeyGenerationProperties final : public Pub explicit RSA_PublicKeyGenerationProperties(Ulong bits); /// @param pub_exponent public exponent e - inline void set_pub_exponent(const BigInt& pub_exponent = BigInt(0x10001)) + inline void set_pub_exponent(const BigInt& pub_exponent = BigInt::from_word(0x10001)) { add_binary(AttributeType::PublicExponent, BigInt::encode(pub_exponent)); } diff --git a/src/lib/pubkey/dh/dh.h b/src/lib/pubkey/dh/dh.h index 3b81bbf5d..e4c9c937d 100644 --- a/src/lib/pubkey/dh/dh.h +++ b/src/lib/pubkey/dh/dh.h @@ -68,7 +68,7 @@ class BOTAN_PUBLIC_API(2,0) DH_PrivateKey final : public DH_PublicKey, * @param x the key's secret value (or if zero, generate a new key) */ DH_PrivateKey(RandomNumberGenerator& rng, const DL_Group& grp, - const BigInt& x = 0); + const BigInt& x = BigInt::zero()); std::unique_ptr<Public_Key> public_key() const override; diff --git a/src/lib/pubkey/dl_group/dl_group.cpp b/src/lib/pubkey/dl_group/dl_group.cpp index 26ea39f17..288000b53 100644 --- a/src/lib/pubkey/dl_group/dl_group.cpp +++ b/src/lib/pubkey/dl_group/dl_group.cpp @@ -240,7 +240,7 @@ BigInt make_dsa_generator(const BigInt& p, const BigInt& q) for(size_t i = 0; i != PRIME_TABLE_SIZE; ++i) { // TODO precompute! - BigInt g = power_mod(PRIMES[i], e, p); + BigInt g = power_mod(BigInt::from_word(PRIMES[i]), e, p); if(g > 1) return g; } @@ -271,13 +271,13 @@ DL_Group::DL_Group(RandomNumberGenerator& rng, Always choose a generator that is quadratic reside mod p, this forces g to be a generator of the subgroup of size q. */ - BigInt g = 2; + BigInt g = BigInt::from_word(2); if(jacobi(g, p) != 1) { // prime table does not contain 2 for(size_t i = 0; i < PRIME_TABLE_SIZE; ++i) { - g = PRIMES[i]; + g = BigInt::from_word(PRIMES[i]); if(jacobi(g, p) == 1) break; } @@ -341,7 +341,7 @@ DL_Group::DL_Group(RandomNumberGenerator& rng, */ DL_Group::DL_Group(const BigInt& p, const BigInt& g) { - m_data = std::make_shared<DL_Group_Data>(p, 0, g, DL_Group_Source::ExternalSource); + m_data = std::make_shared<DL_Group_Data>(p, BigInt::zero(), g, DL_Group_Source::ExternalSource); } /* @@ -442,7 +442,7 @@ bool DL_Group::verify_group(RandomNumberGenerator& rng, for(size_t i = 2; i != upper_bound; ++i) { - if(data().power_g_p_vartime(i) == 1) + if(data().power_g_p_vartime(BigInt::from_word(i)) == 1) { return false; } diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp index a9cfb34f2..616b1e287 100644 --- a/src/lib/pubkey/dsa/dsa.cpp +++ b/src/lib/pubkey/dsa/dsa.cpp @@ -108,7 +108,7 @@ DSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, { const BigInt& q = m_group.get_q(); - BigInt m(msg, msg_len, m_group.q_bits()); + BigInt m = BigInt::from_bytes_with_max_bits(msg, msg_len, m_group.q_bits()); while(m >= q) m -= q; @@ -187,7 +187,7 @@ bool DSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len, BigInt r(sig, q_bytes); BigInt s(sig + q_bytes, q_bytes); - BigInt i(msg, msg_len, q.bits()); + BigInt i = BigInt::from_bytes_with_max_bits(msg, msg_len, m_group.q_bits()); if(r <= 0 || r >= q || s <= 0 || s >= q) return false; diff --git a/src/lib/pubkey/dsa/dsa.h b/src/lib/pubkey/dsa/dsa.h index 75513a78d..e2722383a 100644 --- a/src/lib/pubkey/dsa/dsa.h +++ b/src/lib/pubkey/dsa/dsa.h @@ -72,7 +72,7 @@ class BOTAN_PUBLIC_API(2,0) DSA_PrivateKey final : public DSA_PublicKey, */ DSA_PrivateKey(RandomNumberGenerator& rng, const DL_Group& group, - const BigInt& private_key = 0); + const BigInt& private_key = BigInt::zero()); std::unique_ptr<Public_Key> public_key() const override; diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp index b253f56ab..0236e6272 100644 --- a/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/lib/pubkey/ec_group/ec_group.cpp @@ -637,13 +637,13 @@ BigInt EC_Group::blinded_base_point_multiply_x(const BigInt& k, const PointGFp pt = data().blinded_base_point_multiply(k, rng, ws); if(pt.is_zero()) - return 0; + return BigInt::zero(); return pt.get_affine_x(); } BigInt EC_Group::random_scalar(RandomNumberGenerator& rng) const { - return BigInt::random_integer(rng, 1, get_order()); + return BigInt::random_integer(rng, BigInt::one(), get_order()); } PointGFp EC_Group::blinded_var_point_multiply(const PointGFp& point, diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h index 4be7e656c..4a6061e1a 100644 --- a/src/lib/pubkey/ecdh/ecdh.h +++ b/src/lib/pubkey/ecdh/ecdh.h @@ -86,7 +86,7 @@ class BOTAN_PUBLIC_API(2,0) ECDH_PrivateKey final : public ECDH_PublicKey, */ ECDH_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, - const BigInt& x = 0) : + const BigInt& x = BigInt::zero()) : EC_PrivateKey(rng, domain, x) {} std::unique_ptr<Public_Key> public_key() const override; diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index 490364f8b..2324edf85 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -52,7 +52,7 @@ PointGFp recover_ecdsa_public_key(const EC_Group& group, try { - const BigInt e(msg.data(), msg.size(), group.get_order_bits()); + const BigInt e = BigInt::from_bytes_with_max_bits(msg.data(), msg.size(), group.get_order_bits()); const BigInt r_inv = group.inverse_mod_order(r); BigInt x = r + add_order*group_order; @@ -179,7 +179,7 @@ secure_vector<uint8_t> ECDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) { - BigInt m(msg, msg_len, m_group.get_order_bits()); + BigInt m = BigInt::from_bytes_with_max_bits(msg, msg_len, m_group.get_order_bits()); #if defined(BOTAN_HAS_RFC6979_GENERATOR) const BigInt k = m_rfc6979->nonce_for(m); @@ -241,7 +241,7 @@ bool ECDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len, if(sig_len != m_group.get_order_bytes() * 2) return false; - const BigInt e(msg, msg_len, m_group.get_order_bits()); + const BigInt e = BigInt::from_bytes_with_max_bits(msg, msg_len, m_group.get_order_bits()); const BigInt r(sig, sig_len / 2); const BigInt s(sig + sig_len / 2, sig_len / 2); diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h index 2bdb9e79b..581d024e9 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.h +++ b/src/lib/pubkey/ecdsa/ecdsa.h @@ -101,7 +101,7 @@ class BOTAN_PUBLIC_API(2,0) ECDSA_PrivateKey final : public ECDSA_PublicKey, */ ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, - const BigInt& x = 0) : + const BigInt& x = BigInt::zero()) : EC_PrivateKey(rng, domain, x) {} bool check_key(RandomNumberGenerator& rng, bool) const override; diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.cpp b/src/lib/pubkey/ecgdsa/ecgdsa.cpp index 0fe87d14a..073f4e91a 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.cpp +++ b/src/lib/pubkey/ecgdsa/ecgdsa.cpp @@ -65,7 +65,7 @@ secure_vector<uint8_t> ECGDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) { - const BigInt m(msg, msg_len, m_group.get_order_bits()); + const BigInt m = BigInt::from_bytes_with_max_bits(msg, msg_len, m_group.get_order_bits()); const BigInt k = m_group.random_scalar(rng); @@ -115,7 +115,7 @@ bool ECGDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len, if(sig_len != m_group.get_order_bytes() * 2) return false; - const BigInt e(msg, msg_len, m_group.get_order_bits()); + const BigInt e = BigInt::from_bytes_with_max_bits(msg, msg_len, m_group.get_order_bits()); const BigInt r(sig, sig_len / 2); const BigInt s(sig + sig_len / 2, sig_len / 2); diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.h b/src/lib/pubkey/ecgdsa/ecgdsa.h index cf9f09de2..ea8e912a3 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.h +++ b/src/lib/pubkey/ecgdsa/ecgdsa.h @@ -79,8 +79,8 @@ class BOTAN_PUBLIC_API(2,0) ECGDSA_PrivateKey final : public ECGDSA_PublicKey, * @param x the private key (if zero, generate a new random key) */ ECGDSA_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& x = 0) : + const EC_Group& domain, + const BigInt& x = BigInt::zero()) : EC_PrivateKey(rng, domain, x, true) {} std::unique_ptr<Public_Key> public_key() const override; diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.h b/src/lib/pubkey/eckcdsa/eckcdsa.h index 924f56c4c..ebf5ada30 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.h +++ b/src/lib/pubkey/eckcdsa/eckcdsa.h @@ -79,8 +79,8 @@ class BOTAN_PUBLIC_API(2,0) ECKCDSA_PrivateKey final : public ECKCDSA_PublicKey, * @param x the private key (if zero, generate a new random key) */ ECKCDSA_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& x = 0) : + const EC_Group& domain, + const BigInt& x = BigInt::zero()) : EC_PrivateKey(rng, domain, x, true) {} bool check_key(RandomNumberGenerator& rng, bool) const override; diff --git a/src/lib/pubkey/elgamal/elgamal.h b/src/lib/pubkey/elgamal/elgamal.h index 0c440df00..a316d9c50 100644 --- a/src/lib/pubkey/elgamal/elgamal.h +++ b/src/lib/pubkey/elgamal/elgamal.h @@ -72,7 +72,7 @@ class BOTAN_PUBLIC_API(2,0) ElGamal_PrivateKey final : public ElGamal_PublicKey, */ ElGamal_PrivateKey(RandomNumberGenerator& rng, const DL_Group& group, - const BigInt& priv_key = 0); + const BigInt& priv_key = BigInt::zero()); std::unique_ptr<Public_Key> public_key() const override; diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index 6ec46f3b6..cfa03fe46 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -161,8 +161,8 @@ GOST_3410_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, BigInt e = decode_le(msg, msg_len); e = m_group.mod_order(e); - if(e == 0) - e = 1; + if(e.is_zero()) + e = BigInt::one(); const BigInt r = m_group.mod_order( m_group.blinded_base_point_multiply_x(k, rng, m_ws)); @@ -218,8 +218,8 @@ bool GOST_3410_Verification_Operation::verify(const uint8_t msg[], size_t msg_le BigInt e = decode_le(msg, msg_len); e = m_group.mod_order(e); - if(e == 0) - e = 1; + if(e.is_zero()) + e = BigInt::one(); const BigInt v = m_group.inverse_mod_order(e); diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h index ffce3ef97..ed16aeebf 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.h +++ b/src/lib/pubkey/gost_3410/gost_3410.h @@ -88,7 +88,7 @@ class BOTAN_PUBLIC_API(2,0) GOST_3410_PrivateKey final : */ GOST_3410_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, - const BigInt& x = 0); + const BigInt& x = BigInt::zero()); std::unique_ptr<Public_Key> public_key() const override; diff --git a/src/lib/pubkey/rsa/rsa.h b/src/lib/pubkey/rsa/rsa.h index ccea7c310..99a83f820 100644 --- a/src/lib/pubkey/rsa/rsa.h +++ b/src/lib/pubkey/rsa/rsa.h @@ -111,9 +111,9 @@ class BOTAN_PUBLIC_API(2,0) RSA_PrivateKey final : public Private_Key, public RS * @param n if specified, this must be n = p * q. Leave it as 0 * if you wish to the constructor to calculate it. */ - RSA_PrivateKey(const BigInt& p, const BigInt& q, - const BigInt& e, const BigInt& d = 0, - const BigInt& n = 0); + RSA_PrivateKey(const BigInt& p, const BigInt& q, const BigInt& e, + const BigInt& d = BigInt::zero(), + const BigInt& n = BigInt::zero()); /** * Create a new private key with the specified bit length diff --git a/src/lib/pubkey/sm2/sm2.h b/src/lib/pubkey/sm2/sm2.h index 2341ed861..d2edf3d6f 100644 --- a/src/lib/pubkey/sm2/sm2.h +++ b/src/lib/pubkey/sm2/sm2.h @@ -85,7 +85,7 @@ class BOTAN_PUBLIC_API(2,2) SM2_PrivateKey final : */ SM2_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, - const BigInt& x = 0); + const BigInt& x = BigInt::zero()); bool check_key(RandomNumberGenerator& rng, bool) const override; diff --git a/src/tests/test_tests.cpp b/src/tests/test_tests.cpp index c3cf83645..dce916008 100644 --- a/src/tests/test_tests.cpp +++ b/src/tests/test_tests.cpp @@ -164,14 +164,16 @@ class Test_Tests final : public Test #if defined(BOTAN_HAS_BIGINT) { Test::Result test_result(testcase_name); - Botan::BigInt x = 5, y = 6; + const auto x = Botan::BigInt::from_word(5); + const auto y = Botan::BigInt::from_word(6); test_result.test_eq("test ints equal", x, y); verify_failure("test ints equal", result, test_result); } { Test::Result test_result(testcase_name); - Botan::BigInt x = 5, y = 5; + const auto x = Botan::BigInt::from_word(5); + const auto y = Botan::BigInt::from_word(5); test_result.test_ne("test ints not equal", x, y); verify_failure("test ints not equal", result, test_result); } diff --git a/src/tests/unit_ecdsa.cpp b/src/tests/unit_ecdsa.cpp index ad53f00db..83e6e3a3e 100644 --- a/src/tests/unit_ecdsa.cpp +++ b/src/tests/unit_ecdsa.cpp @@ -237,7 +237,7 @@ Test::Result test_unusual_curve() const Botan::BigInt a("0x0a377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe"); const Botan::BigInt b("0x0a9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7"); const Botan::BigInt order_g("0x0e1a16196e6000000000bc7f1618d867b15bb86474418f"); - const Botan::BigInt cofactor = 1; + const Botan::BigInt cofactor = Botan::BigInt::one(); const BigInt Gx("1503931002566715881584977704503341991763310127581173321974500299341775226206001860606586625324214456299149080935147329869147994265934715820"); const BigInt Gy("1774988776970033741491814582357926984496972046739476148938345272681378523636129776486407268230155403536112014267092770854858769258781598199"); |