diff --git a/src/lib/math/bigint/big_ops2.cpp b/src/lib/math/bigint/big_ops2.cpp index 9441a533126..e3da4c5d3b1 100644 --- a/src/lib/math/bigint/big_ops2.cpp +++ b/src/lib/math/bigint/big_ops2.cpp @@ -258,17 +258,12 @@ word BigInt::operator%=(word mod) { * Left Shift Operator */ BigInt& BigInt::operator<<=(size_t shift) { - const size_t shift_words = shift / BOTAN_MP_WORD_BITS; - const size_t shift_bits = shift % BOTAN_MP_WORD_BITS; - const size_t size = sig_words(); - - const size_t bits_free = top_bits_free(); - - const size_t new_size = size + shift_words + (bits_free < shift_bits); + const size_t sw = sig_words(); + const size_t new_size = sw + (shift + BOTAN_MP_WORD_BITS - 1) / BOTAN_MP_WORD_BITS; m_data.grow_to(new_size); - bigint_shl1(m_data.mutable_data(), new_size, size, shift_words, shift_bits); + bigint_shl1(m_data.mutable_data(), new_size, sw, shift); return (*this); } @@ -277,10 +272,7 @@ BigInt& BigInt::operator<<=(size_t shift) { * Right Shift Operator */ BigInt& BigInt::operator>>=(size_t shift) { - const size_t shift_words = shift / BOTAN_MP_WORD_BITS; - const size_t shift_bits = shift % BOTAN_MP_WORD_BITS; - - bigint_shr1(m_data.mutable_data(), m_data.size(), shift_words, shift_bits); + bigint_shr1(m_data.mutable_data(), m_data.size(), shift); if(is_negative() && is_zero()) { set_sign(Positive); diff --git a/src/lib/math/bigint/big_ops3.cpp b/src/lib/math/bigint/big_ops3.cpp index 1fd5dcbae1a..d36192a46da 100644 --- a/src/lib/math/bigint/big_ops3.cpp +++ b/src/lib/math/bigint/big_ops3.cpp @@ -172,12 +172,11 @@ word operator%(const BigInt& n, word mod) { * Left Shift Operator */ BigInt operator<<(const BigInt& x, size_t shift) { - const size_t shift_words = shift / BOTAN_MP_WORD_BITS, shift_bits = shift % BOTAN_MP_WORD_BITS; - const size_t x_sw = x.sig_words(); - 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); + const size_t new_size = x_sw + (shift + BOTAN_MP_WORD_BITS - 1) / BOTAN_MP_WORD_BITS; + BigInt y = BigInt::with_capacity(new_size); + bigint_shl2(y.mutable_data(), x.data(), x_sw, shift); y.set_sign(x.sign()); return y; } @@ -187,7 +186,6 @@ BigInt operator<<(const BigInt& x, size_t shift) { */ BigInt operator>>(const BigInt& x, size_t shift) { const size_t shift_words = shift / BOTAN_MP_WORD_BITS; - const size_t shift_bits = shift % BOTAN_MP_WORD_BITS; const size_t x_sw = x.sig_words(); if(shift_words >= x_sw) { @@ -195,7 +193,7 @@ BigInt operator>>(const BigInt& x, size_t shift) { } BigInt y = BigInt::with_capacity(x_sw - shift_words); - bigint_shr2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits); + bigint_shr2(y.mutable_data(), x.data(), x_sw, shift); if(x.is_negative() && y.is_zero()) { y.set_sign(BigInt::Positive); diff --git a/src/lib/math/bigint/bigint.cpp b/src/lib/math/bigint/bigint.cpp index 41f0817344c..a6e59b275ad 100644 --- a/src/lib/math/bigint/bigint.cpp +++ b/src/lib/math/bigint/bigint.cpp @@ -433,14 +433,14 @@ void BigInt::ct_cond_add(bool predicate, const BigInt& value) { void BigInt::ct_shift_left(size_t shift) { auto shl_bit = [](const BigInt& a, BigInt& result) { BOTAN_DEBUG_ASSERT(a.size() + 1 == result.size()); - bigint_shl2(result.mutable_data(), a.data(), a.size(), 0, 1); + bigint_shl2(result.mutable_data(), a.data(), a.size(), 1); // shl2 may have shifted a bit into the next word, which must be dropped clear_mem(result.mutable_data() + result.size() - 1, 1); }; auto shl_word = [](const BigInt& a, BigInt& result) { // the most significant word is not copied, aka. shifted out - bigint_shl2(result.mutable_data(), a.data(), a.size() - 1 /* ignore msw */, 1, 0); + bigint_shl2(result.mutable_data(), a.data(), a.size() - 1 /* ignore msw */, BOTAN_MP_WORD_BITS); // we left-shifted by a full word, the least significant word must be zero'ed clear_mem(result.mutable_data(), 1); }; diff --git a/src/lib/math/bigint/divide.cpp b/src/lib/math/bigint/divide.cpp index 341ebd8f0b9..5d91510473b 100644 --- a/src/lib/math/bigint/divide.cpp +++ b/src/lib/math/bigint/divide.cpp @@ -202,7 +202,7 @@ void vartime_divide(const BigInt& x, const BigInt& y_arg, BigInt& q_out, BigInt& word qjt = bigint_divop_vartime(x_j0, x_j1, y_t0); - qjt = CT::Mask::is_equal(x_j0, y_t0).select(MP_WORD_MAX, qjt); + qjt = CT::Mask::is_equal(x_j0, y_t0).select(WordInfo::max, qjt); // Per HAC 14.23, this operation is required at most twice qjt -= division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2); diff --git a/src/lib/math/mp/mp_asmi.h b/src/lib/math/mp/mp_asmi.h index 307645c40f8..2c0245c4a70 100644 --- a/src/lib/math/mp/mp_asmi.h +++ b/src/lib/math/mp/mp_asmi.h @@ -34,24 +34,30 @@ template concept WordType = (std::same_as || std::same_as); template -struct DwordType {}; +struct WordInfo {}; template <> -struct DwordType { +struct WordInfo { public: - typedef uint64_t type; - static const bool is_native = true; + static const constexpr size_t bits = 32; + static const constexpr uint32_t max = 0xFFFFFFFF; + + typedef uint64_t dword; + static const constexpr bool dword_is_native = true; }; template <> -struct DwordType { +struct WordInfo { public: + static const constexpr size_t bits = 64; + static const constexpr uint64_t max = 0xFFFFFFFFFFFFFFFF; + #if defined(BOTAN_TARGET_HAS_NATIVE_UINT128) - typedef uint128_t type; - static const bool is_native = true; + typedef uint128_t dword; + static const constexpr bool dword_is_native = true; #else - typedef donna128 type; - static const bool is_native = false; + typedef donna128 dword; + static const constexpr bool dword_is_native = false; #endif }; @@ -90,7 +96,7 @@ inline constexpr auto word_madd2(W a, W b, W* c) -> W { } #endif - typedef typename DwordType::type dword; + typedef typename WordInfo::dword dword; const dword s = dword(a) * b + *c; *c = static_cast(s >> (sizeof(W) * 8)); return static_cast(s); @@ -139,7 +145,7 @@ inline constexpr auto word_madd3(W a, W b, W c, W* d) -> W { } #endif - typedef typename DwordType::type dword; + typedef typename WordInfo::dword dword; const dword s = dword(a) * b + c + *d; *d = static_cast(s >> (sizeof(W) * 8)); return static_cast(s); diff --git a/src/lib/math/mp/mp_core.h b/src/lib/math/mp/mp_core.h index 79044b9f15e..4ecd319e190 100644 --- a/src/lib/math/mp/mp_core.h +++ b/src/lib/math/mp/mp_core.h @@ -19,8 +19,6 @@ namespace Botan { -const word MP_WORD_MAX = ~static_cast(0); - /* * If cond == 0, does nothing. * If cond > 0, swaps x[0:size] with y[0:size] @@ -396,12 +394,15 @@ inline constexpr auto bigint_sub_abs(W z[], const W x[], const W y[], size_t N, * Shift Operations */ template -inline constexpr void bigint_shl1(W x[], size_t x_size, size_t x_words, size_t word_shift, size_t bit_shift) { +inline constexpr void bigint_shl1(W x[], size_t x_size, size_t x_words, size_t shift) { + const size_t word_shift = shift / WordInfo::bits; + const size_t bit_shift = shift % WordInfo::bits; + copy_mem(x + word_shift, x, x_words); clear_mem(x, word_shift); const auto carry_mask = CT::Mask::expand(bit_shift); - const W carry_shift = carry_mask.if_set_return(sizeof(W) * 8 - bit_shift); + const W carry_shift = carry_mask.if_set_return(WordInfo::bits - bit_shift); W carry = 0; for(size_t i = word_shift; i != x_size; ++i) { @@ -412,7 +413,10 @@ inline constexpr void bigint_shl1(W x[], size_t x_size, size_t x_words, size_t w } template -inline constexpr void bigint_shr1(W x[], size_t x_size, size_t word_shift, size_t bit_shift) { +inline constexpr void bigint_shr1(W x[], size_t x_size, size_t shift) { + const size_t word_shift = shift / WordInfo::bits; + const size_t bit_shift = shift % WordInfo::bits; + const size_t top = x_size >= word_shift ? (x_size - word_shift) : 0; if(top > 0) { @@ -421,7 +425,7 @@ inline constexpr void bigint_shr1(W x[], size_t x_size, size_t word_shift, size_ clear_mem(x + top, std::min(word_shift, x_size)); const auto carry_mask = CT::Mask::expand(bit_shift); - const W carry_shift = carry_mask.if_set_return(sizeof(W) * 8 - bit_shift); + const W carry_shift = carry_mask.if_set_return(WordInfo::bits - bit_shift); W carry = 0; @@ -433,11 +437,14 @@ inline constexpr void bigint_shr1(W x[], size_t x_size, size_t word_shift, size_ } template -inline constexpr void bigint_shl2(W y[], const W x[], size_t x_size, size_t word_shift, size_t bit_shift) { +inline constexpr void bigint_shl2(W y[], const W x[], size_t x_size, size_t shift) { + const size_t word_shift = shift / WordInfo::bits; + const size_t bit_shift = shift % WordInfo::bits; + copy_mem(y + word_shift, x, x_size); const auto carry_mask = CT::Mask::expand(bit_shift); - const W carry_shift = carry_mask.if_set_return(sizeof(W) * 8 - bit_shift); + const W carry_shift = carry_mask.if_set_return(WordInfo::bits - bit_shift); W carry = 0; for(size_t i = word_shift; i != x_size + word_shift + 1; ++i) { @@ -448,7 +455,9 @@ inline constexpr void bigint_shl2(W y[], const W x[], size_t x_size, size_t word } template -inline constexpr void bigint_shr2(W y[], const W x[], size_t x_size, size_t word_shift, size_t bit_shift) { +inline constexpr void bigint_shr2(W y[], const W x[], size_t x_size, size_t shift) { + const size_t word_shift = shift / WordInfo::bits; + const size_t bit_shift = shift % WordInfo::bits; const size_t new_size = x_size < word_shift ? 0 : (x_size - word_shift); if(new_size > 0) { @@ -456,7 +465,7 @@ inline constexpr void bigint_shr2(W y[], const W x[], size_t x_size, size_t word } const auto carry_mask = CT::Mask::expand(bit_shift); - const W carry_shift = carry_mask.if_set_return(sizeof(W) * 8 - bit_shift); + const W carry_shift = carry_mask.if_set_return(WordInfo::bits - bit_shift); W carry = 0; for(size_t i = new_size; i > 0; --i) { @@ -701,22 +710,20 @@ inline constexpr auto bigint_divop_vartime(W n1, W n0, W d) -> W { throw Invalid_Argument("bigint_divop_vartime divide by zero"); } - constexpr const size_t W_bits = sizeof(W) * 8; - - if constexpr(DwordType::is_native) { - typename DwordType::type n = n1; - n <<= W_bits; + if constexpr(WordInfo::dword_is_native) { + typename WordInfo::dword n = n1; + n <<= WordInfo::bits; n |= n0; return static_cast(n / d); } else { W high = n1 % d; W quotient = 0; - for(size_t i = 0; i != W_bits; ++i) { - const W high_top_bit = high >> (W_bits - 1); + for(size_t i = 0; i != WordInfo::bits; ++i) { + const W high_top_bit = high >> (WordInfo::bits - 1); high <<= 1; - high |= (n0 >> (W_bits - 1 - i)) & 1; + high |= (n0 >> (WordInfo::bits - 1 - i)) & 1; quotient <<= 1; if(high_top_bit || high >= d) { diff --git a/src/lib/math/numbertheory/mod_inv.cpp b/src/lib/math/numbertheory/mod_inv.cpp index 29d7f169a76..97e8bbd02d1 100644 --- a/src/lib/math/numbertheory/mod_inv.cpp +++ b/src/lib/math/numbertheory/mod_inv.cpp @@ -62,7 +62,7 @@ BigInt inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod) { // compute (mod + 1) / 2 which [because mod is odd] is equal to // (mod / 2) + 1 copy_mem(mp1o2, mod.data(), std::min(mod.size(), mod_words)); - bigint_shr1(mp1o2, mod_words, 0, 1); + bigint_shr1(mp1o2, mod_words, 1); word carry = bigint_add2_nc(mp1o2, mod_words, u_w, 1); BOTAN_ASSERT_NOMSG(carry == 0); @@ -81,7 +81,7 @@ BigInt inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod) { bigint_cnd_swap(underflow, u_w, v_w, mod_words); // a >>= 1 - bigint_shr1(a_w, mod_words, 0, 1); + bigint_shr1(a_w, mod_words, 1); //if(odd_a) u -= v; word borrow = bigint_cnd_sub(odd_a, u_w, v_w, mod_words); @@ -92,7 +92,7 @@ BigInt inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod) { const word odd_u = u_w[0] & 1; // u >>= 1 - bigint_shr1(u_w, mod_words, 0, 1); + bigint_shr1(u_w, mod_words, 1); //if(odd_u) u += mp1o2; bigint_cnd_add(odd_u, u_w, mp1o2, mod_words); diff --git a/src/lib/math/numbertheory/monty.cpp b/src/lib/math/numbertheory/monty.cpp index 0c9809b9de7..ceec2090f1f 100644 --- a/src/lib/math/numbertheory/monty.cpp +++ b/src/lib/math/numbertheory/monty.cpp @@ -26,17 +26,17 @@ word monty_inverse(word a) { word b = 1; word r = 0; - for(size_t i = 0; i != BOTAN_MP_WORD_BITS; ++i) { + for(size_t i = 0; i != WordInfo::bits; ++i) { const word bi = b % 2; r >>= 1; - r += bi << (BOTAN_MP_WORD_BITS - 1); + r += bi << (WordInfo::bits - 1); b -= a * bi; b >>= 1; } // Now invert in addition space - r = (MP_WORD_MAX - r) + 1; + r = (WordInfo::max - r) + 1; return r; } diff --git a/src/lib/math/numbertheory/nistp_redc.cpp b/src/lib/math/numbertheory/nistp_redc.cpp index 923507cd34c..03ed2742b6f 100644 --- a/src/lib/math/numbertheory/nistp_redc.cpp +++ b/src/lib/math/numbertheory/nistp_redc.cpp @@ -62,7 +62,7 @@ void redc_p521(BigInt& x, secure_vector& ws) { } clear_mem(ws.data(), ws.size()); - bigint_shr2(ws.data(), x.data(), std::min(x.size(), 2 * p_words), p_full_words, p_top_bits); + bigint_shr2(ws.data(), x.data(), std::min(x.size(), 2 * p_words), 521); x.mask_bits(521); x.grow_to(p_words); @@ -81,11 +81,12 @@ void redc_p521(BigInt& x, secure_vector& ws) { */ const auto bit_522_set = CT::Mask::expand(top_word >> p_top_bits); - word and_512 = MP_WORD_MAX; + const word max = WordInfo::max; + word and_512 = max; for(size_t i = 0; i != p_full_words; ++i) { and_512 &= x.word_at(i); } - const auto all_512_low_bits_set = CT::Mask::is_equal(and_512, MP_WORD_MAX); + const auto all_512_low_bits_set = CT::Mask::is_equal(and_512, max); const auto has_p521_top_word = CT::Mask::is_equal(top_word, 0x1FF); const auto is_p521 = all_512_low_bits_set & has_p521_top_word; diff --git a/src/lib/math/numbertheory/numthry.cpp b/src/lib/math/numbertheory/numthry.cpp index c1b592c7b23..7ab4e52cc04 100644 --- a/src/lib/math/numbertheory/numthry.cpp +++ b/src/lib/math/numbertheory/numthry.cpp @@ -240,11 +240,11 @@ BigInt gcd(const BigInt& a, const BigInt& b) { factors_of_two += (u_is_even & v_is_even).if_set_return(1); // remove one factor of 2, if u is even - bigint_shr2(tmp.mutable_data(), u.data(), sz, 0, 1); + bigint_shr2(tmp.mutable_data(), u.data(), sz, 1); u.ct_cond_assign(u_is_even.as_bool(), tmp); // remove one factor of 2, if v is even - bigint_shr2(tmp.mutable_data(), v.data(), sz, 0, 1); + bigint_shr2(tmp.mutable_data(), v.data(), sz, 1); v.ct_cond_assign(v_is_even.as_bool(), tmp); } diff --git a/src/lib/pubkey/curve448/curve448_scalar.cpp b/src/lib/pubkey/curve448/curve448_scalar.cpp index f2357a05e91..a45b748ed90 100644 --- a/src/lib/pubkey/curve448/curve448_scalar.cpp +++ b/src/lib/pubkey/curve448/curve448_scalar.cpp @@ -28,11 +28,8 @@ auto div_mod_2_446(std::span x) { // Clear the two most significant bits r[Scalar448::WORDS - 1] &= ~(word(0b11) << (sizeof(word) * 8 - 2)); - constexpr size_t word_shift = 446 / (sizeof(word) * 8); - constexpr size_t bit_shift = 446 % (sizeof(word) * 8); - std::array q; - bigint_shr2(q.data(), x.data(), x.size(), word_shift, bit_shift); + bigint_shr2(q.data(), x.data(), x.size(), 446); return std::make_pair(q, r); } diff --git a/src/lib/utils/mem_pool/mem_pool.cpp b/src/lib/utils/mem_pool/mem_pool.cpp index ebd92259fa4..93c40d6ee8d 100644 --- a/src/lib/utils/mem_pool/mem_pool.cpp +++ b/src/lib/utils/mem_pool/mem_pool.cpp @@ -185,14 +185,12 @@ class BitMap final { private: #if defined(BOTAN_ENABLE_DEBUG_ASSERTS) using bitmask_type = uint8_t; - - enum { BITMASK_BITS = 8 }; #else using bitmask_type = word; - - enum { BITMASK_BITS = BOTAN_MP_WORD_BITS }; #endif + static const size_t BITMASK_BITS = sizeof(bitmask_type) * 8; + size_t m_len; bitmask_type m_main_mask; bitmask_type m_last_mask; diff --git a/src/tests/test_mp.cpp b/src/tests/test_mp.cpp index ff07e0bb763..dd976c22c54 100644 --- a/src/tests/test_mp.cpp +++ b/src/tests/test_mp.cpp @@ -33,7 +33,7 @@ class MP_Unit_Tests final : public Test { static Result test_cnd_add() { Result result("bigint_cnd_add"); - const Botan::word max = Botan::MP_WORD_MAX; + const Botan::word max = ~static_cast(0); Botan::word a = 2; Botan::word c = Botan::bigint_cnd_add(0, &a, &max, 1); @@ -63,7 +63,7 @@ class MP_Unit_Tests final : public Test { c = Botan::bigint_cnd_sub(1, &a, &b, 1); - result.test_int_eq(a, Botan::MP_WORD_MAX, "Sub"); + result.test_int_eq(a, ~static_cast(0), "Sub"); result.test_int_eq(c, 1, "Borrow"); return result; @@ -72,7 +72,9 @@ class MP_Unit_Tests final : public Test { static Result test_cnd_abs() { Result result("bigint_cnd_abs"); - Botan::word x1 = Botan::MP_WORD_MAX; + const Botan::word max = Botan::WordInfo::max; + + Botan::word x1 = max; Botan::bigint_cnd_abs(1, &x1, 1); result.test_int_eq(x1, 1, "Abs"); @@ -82,13 +84,13 @@ class MP_Unit_Tests final : public Test { x1 = 1; Botan::bigint_cnd_abs(1, &x1, 1); - result.test_int_eq(x1, Botan::MP_WORD_MAX, "Abs"); + result.test_int_eq(x1, max, "Abs"); x1 = 1; Botan::bigint_cnd_abs(0, &x1, 1); result.test_int_eq(x1, 1, "No change"); - Botan::word x2[2] = {Botan::MP_WORD_MAX, Botan::MP_WORD_MAX}; + Botan::word x2[2] = {max, max}; Botan::bigint_cnd_abs(1, x2, 2); result.test_int_eq(x2[0], 1, "Abs");