diff --git a/src/lib/math/mp/mp_core.h b/src/lib/math/mp/mp_core.h index 152ed78f051..c980c033b6f 100644 --- a/src/lib/math/mp/mp_core.h +++ b/src/lib/math/mp/mp_core.h @@ -16,6 +16,7 @@ #include #include #include +#include namespace Botan { @@ -751,6 +752,52 @@ inline constexpr auto bigint_modop_vartime(W n1, W n0, W d) -> W { return (n0 - z); } +template +inline consteval W shift_left(std::array& x) { + static_assert(S < WordInfo::bits, "Shift too large"); + + W carry = 0; + for(size_t j = 0; j != N; ++j) { + const W w = x[j]; + x[j] = (w << S) | carry; + carry = w >> (WordInfo::bits - S); + } + + return carry; +} + +template +consteval auto hex_to_words(const char (&s)[N]) { + // Char count includes null terminator which we ignore + const constexpr size_t C = N - 1; + + const size_t S = (C + sizeof(W) * 2 - 1) / (sizeof(W) * 2); + + auto hex2int = [](char c) -> int8_t { + if(c >= '0' && c <= '9') { + return static_cast(c - '0'); + } else if(c >= 'a' && c <= 'f') { + return static_cast(c - 'a' + 10); + } else if(c >= 'A' && c <= 'F') { + return static_cast(c - 'A' + 10); + } else { + return -1; + } + }; + + std::array r = {0}; + + for(size_t i = 0; i != C; ++i) { + const int8_t c = hex2int(s[i]); + if(c >= 0) { + shift_left<4>(r); + r[0] += c; + } + } + + return r; +} + /* * Comba Fixed Length Multiplication */ diff --git a/src/lib/math/numbertheory/nistp_redc.cpp b/src/lib/math/numbertheory/nistp_redc.cpp index 03ed2742b6f..499fff0e91e 100644 --- a/src/lib/math/numbertheory/nistp_redc.cpp +++ b/src/lib/math/numbertheory/nistp_redc.cpp @@ -27,35 +27,9 @@ void redc_p521(BigInt& x, secure_vector& ws) { const size_t p_top_bits = 521 % BOTAN_MP_WORD_BITS; const size_t p_words = p_full_words + 1; -#if(BOTAN_MP_WORD_BITS == 64) - static const word p521_words[p_words] = {0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0x1FF}; -#else - static const word p521_words[p_words] = {0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0x1FF}; -#endif + static const constinit auto p521_words = hex_to_words( + "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); if(ws.size() < p_words + 1) { ws.resize(p_words + 1); @@ -92,7 +66,7 @@ void redc_p521(BigInt& x, secure_vector& ws) { const auto needs_reduction = is_p521 | bit_522_set; - bigint_cnd_sub(needs_reduction.value(), x.mutable_data(), p521_words, p_words); + bigint_cnd_sub(needs_reduction.value(), x.mutable_data(), p521_words.data(), p_words); } namespace { @@ -193,16 +167,10 @@ void redc_p192(BigInt& x, secure_vector& ws) { /* This is a table of (i*P-192) % 2**192 for i in 1...3 */ - static const word p192_mults[3][p192_limbs] = { -#if(BOTAN_MP_WORD_BITS == 64) - {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF}, - {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF}, - {0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF}, -#else - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, -#endif + static const constinit std::array p192_mults[3] = { + hex_to_words("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"), + hex_to_words("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFFE"), + hex_to_words("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFFFFFFFFFFFFFFFD"), }; CT::unpoison(S); @@ -210,9 +178,9 @@ void redc_p192(BigInt& x, secure_vector& ws) { BOTAN_ASSERT_NOMSG(x.size() >= p192_limbs + 1); x.mask_bits(192); - word borrow = bigint_sub2(x.mutable_data(), p192_limbs + 1, p192_mults[S], p192_limbs); + word borrow = bigint_sub2(x.mutable_data(), p192_limbs + 1, p192_mults[S].data(), p192_limbs); BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); - bigint_cnd_add(borrow, x.mutable_data(), p192_limbs + 1, p192_mults[0], p192_limbs); + bigint_cnd_add(borrow, x.mutable_data(), p192_limbs + 1, p192_mults[0].data(), p192_limbs); } const BigInt& prime_p224() { @@ -294,17 +262,10 @@ void redc_p224(BigInt& x, secure_vector& ws) { set_words(xw, 6, R0, 0); - static const word p224_mults[3][p224_limbs] = { -#if(BOTAN_MP_WORD_BITS == 64) - {0x0000000000000001, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, - {0x0000000000000002, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, - {0x0000000000000003, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, -#else - {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0x00000003, 0x00000000, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} -#endif - + static const constinit std::array p224_mults[3] = { + hex_to_words("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"), + hex_to_words("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000000000000000000000002"), + hex_to_words("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD000000000000000000000003"), }; CT::unpoison(S); @@ -312,9 +273,9 @@ void redc_p224(BigInt& x, secure_vector& ws) { BOTAN_ASSERT_NOMSG(x.size() >= p224_limbs + 1); x.mask_bits(224); - word borrow = bigint_sub2(x.mutable_data(), p224_limbs + 1, p224_mults[S], p224_limbs); + word borrow = bigint_sub2(x.mutable_data(), p224_limbs + 1, p224_mults[S].data(), p224_limbs); BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); - bigint_cnd_add(borrow, x.mutable_data(), p224_limbs + 1, p224_mults[0], p224_limbs); + bigint_cnd_add(borrow, x.mutable_data(), p224_limbs + 1, p224_mults[0].data(), p224_limbs); } const BigInt& prime_p256() { @@ -407,32 +368,18 @@ void redc_p256(BigInt& x, secure_vector& ws) { /* This is a table of (i*P-256) % 2**256 for i in 1...10 */ - static const word p256_mults[11][p256_limbs] = { -#if(BOTAN_MP_WORD_BITS == 64) - {0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000001}, - {0xFFFFFFFFFFFFFFFE, 0x00000001FFFFFFFF, 0x0000000000000000, 0xFFFFFFFE00000002}, - {0xFFFFFFFFFFFFFFFD, 0x00000002FFFFFFFF, 0x0000000000000000, 0xFFFFFFFD00000003}, - {0xFFFFFFFFFFFFFFFC, 0x00000003FFFFFFFF, 0x0000000000000000, 0xFFFFFFFC00000004}, - {0xFFFFFFFFFFFFFFFB, 0x00000004FFFFFFFF, 0x0000000000000000, 0xFFFFFFFB00000005}, - {0xFFFFFFFFFFFFFFFA, 0x00000005FFFFFFFF, 0x0000000000000000, 0xFFFFFFFA00000006}, - {0xFFFFFFFFFFFFFFF9, 0x00000006FFFFFFFF, 0x0000000000000000, 0xFFFFFFF900000007}, - {0xFFFFFFFFFFFFFFF8, 0x00000007FFFFFFFF, 0x0000000000000000, 0xFFFFFFF800000008}, - {0xFFFFFFFFFFFFFFF7, 0x00000008FFFFFFFF, 0x0000000000000000, 0xFFFFFFF700000009}, - {0xFFFFFFFFFFFFFFF6, 0x00000009FFFFFFFF, 0x0000000000000000, 0xFFFFFFF60000000A}, - {0xFFFFFFFFFFFFFFF5, 0x0000000AFFFFFFFF, 0x0000000000000000, 0xFFFFFFF50000000B}, -#else - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF}, - {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE}, - {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD}, - {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003, 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC}, - {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB}, - {0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000005, 0x00000000, 0x00000000, 0x00000006, 0xFFFFFFFA}, - {0xFFFFFFF9, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0xFFFFFFF9}, - {0xFFFFFFF8, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000, 0x00000000, 0x00000008, 0xFFFFFFF8}, - {0xFFFFFFF7, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000008, 0x00000000, 0x00000000, 0x00000009, 0xFFFFFFF7}, - {0xFFFFFFF6, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000009, 0x00000000, 0x00000000, 0x0000000A, 0xFFFFFFF6}, - {0xFFFFFFF5, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000A, 0x00000000, 0x00000000, 0x0000000B, 0xFFFFFFF5}, -#endif + static const constinit std::array p256_mults[11] = { + hex_to_words("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"), + hex_to_words("FFFFFFFE00000002000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFE"), + hex_to_words("FFFFFFFD00000003000000000000000000000002FFFFFFFFFFFFFFFFFFFFFFFD"), + hex_to_words("FFFFFFFC00000004000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFC"), + hex_to_words("FFFFFFFB00000005000000000000000000000004FFFFFFFFFFFFFFFFFFFFFFFB"), + hex_to_words("FFFFFFFA00000006000000000000000000000005FFFFFFFFFFFFFFFFFFFFFFFA"), + hex_to_words("FFFFFFF900000007000000000000000000000006FFFFFFFFFFFFFFFFFFFFFFF9"), + hex_to_words("FFFFFFF800000008000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFF8"), + hex_to_words("FFFFFFF700000009000000000000000000000008FFFFFFFFFFFFFFFFFFFFFFF7"), + hex_to_words("FFFFFFF60000000A000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFF6"), + hex_to_words("FFFFFFF50000000B00000000000000000000000AFFFFFFFFFFFFFFFFFFFFFFF5"), }; CT::unpoison(S); @@ -440,9 +387,9 @@ void redc_p256(BigInt& x, secure_vector& ws) { BOTAN_ASSERT_NOMSG(x.size() >= p256_limbs + 1); x.mask_bits(256); - word borrow = bigint_sub2(x.mutable_data(), p256_limbs + 1, p256_mults[S], p256_limbs); + word borrow = bigint_sub2(x.mutable_data(), p256_limbs + 1, p256_mults[S].data(), p256_limbs); BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); - bigint_cnd_add(borrow, x.mutable_data(), p256_limbs + 1, p256_mults[0], p256_limbs); + bigint_cnd_add(borrow, x.mutable_data(), p256_limbs + 1, p256_mults[0].data(), p256_limbs); } const BigInt& prime_p384() { @@ -567,101 +514,17 @@ void redc_p384(BigInt& x, secure_vector& ws) { /* This is a table of (i*P-384) % 2**384 for i in 1...4 */ - static const word p384_mults[5][p384_limbs] = { -#if(BOTAN_MP_WORD_BITS == 64) - {0x00000000FFFFFFFF, - 0xFFFFFFFF00000000, - 0xFFFFFFFFFFFFFFFE, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF}, - {0x00000001FFFFFFFE, - 0xFFFFFFFE00000000, - 0xFFFFFFFFFFFFFFFD, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF}, - {0x00000002FFFFFFFD, - 0xFFFFFFFD00000000, - 0xFFFFFFFFFFFFFFFC, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF}, - {0x00000003FFFFFFFC, - 0xFFFFFFFC00000000, - 0xFFFFFFFFFFFFFFFB, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF}, - {0x00000004FFFFFFFB, - 0xFFFFFFFB00000000, - 0xFFFFFFFFFFFFFFFA, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF}, - -#else - {0xFFFFFFFF, - 0x00000000, - 0x00000000, - 0xFFFFFFFF, - 0xFFFFFFFE, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF}, - {0xFFFFFFFE, - 0x00000001, - 0x00000000, - 0xFFFFFFFE, - 0xFFFFFFFD, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF}, - {0xFFFFFFFD, - 0x00000002, - 0x00000000, - 0xFFFFFFFD, - 0xFFFFFFFC, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF}, - {0xFFFFFFFC, - 0x00000003, - 0x00000000, - 0xFFFFFFFC, - 0xFFFFFFFB, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF}, - {0xFFFFFFFB, - 0x00000004, - 0x00000000, - 0xFFFFFFFB, - 0xFFFFFFFA, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF}, -#endif + static const constinit std::array p384_mults[5] = { + hex_to_words( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"), + hex_to_words( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFE0000000000000001FFFFFFFE"), + hex_to_words( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFFFFFFFD0000000000000002FFFFFFFD"), + hex_to_words( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFC0000000000000003FFFFFFFC"), + hex_to_words( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFFFFFFFB0000000000000004FFFFFFFB"), }; CT::unpoison(S); @@ -669,9 +532,9 @@ void redc_p384(BigInt& x, secure_vector& ws) { BOTAN_ASSERT_NOMSG(x.size() >= p384_limbs + 1); x.mask_bits(384); - word borrow = bigint_sub2(x.mutable_data(), p384_limbs + 1, p384_mults[S], p384_limbs); + word borrow = bigint_sub2(x.mutable_data(), p384_limbs + 1, p384_mults[S].data(), p384_limbs); BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); - bigint_cnd_add(borrow, x.mutable_data(), p384_limbs + 1, p384_mults[0], p384_limbs); + bigint_cnd_add(borrow, x.mutable_data(), p384_limbs + 1, p384_mults[0].data(), p384_limbs); } } // namespace Botan diff --git a/src/lib/utils/mem_ops.h b/src/lib/utils/mem_ops.h index ff1e0775737..9a4e8e7c5fd 100644 --- a/src/lib/utils/mem_ops.h +++ b/src/lib/utils/mem_ops.h @@ -161,7 +161,9 @@ template std::is_trivially_copyable_v> inline constexpr void copy_mem(OutR&& out, InR&& in) { ranges::assert_equal_byte_lengths(out, in); - if(ranges::size_bytes(out) > 0) { + if(std::is_constant_evaluated()) { + std::copy(std::ranges::begin(in), std::ranges::end(in), std::ranges::begin(out)); + } else if(ranges::size_bytes(out) > 0) { std::memmove(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out)); } }