diff --git a/src/lib/pubkey/curve448/curve448_utils/curve448_scalar.cpp b/src/lib/pubkey/curve448/curve448_utils/curve448_scalar.cpp index f85e27e1cf9..49304952320 100644 --- a/src/lib/pubkey/curve448/curve448_utils/curve448_scalar.cpp +++ b/src/lib/pubkey/curve448/curve448_utils/curve448_scalar.cpp @@ -35,18 +35,35 @@ std::pair, std::array> div_ return {q, r}; } +template +consteval std::array load_words(const std::array& bytes) + requires(S % sizeof(word) == 0) +{ + // Currently load_le does not work with constexpr. Therefore, we have to use this workaround. + std::array res = {0}; + for(size_t i = 0; i < bytes.size(); ++i) { + res[i / sizeof(word)] |= word(bytes[i]) << ((i % sizeof(word)) * 8); + } + + return res; +} + /// @return a word array for c = 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d consteval std::array c_words() { // Currently load_le does not work with constexpr. Therefore, we have to use this workaround. const std::array c_bytes{0x0d, 0xbb, 0xa7, 0x54, 0x6d, 0x3d, 0x87, 0xdc, 0xaa, 0x70, 0x3a, 0x72, 0x8d, 0x3d, 0x93, 0xde, 0x6f, 0xc9, 0x29, 0x51, 0xb6, 0x24, 0xb1, 0x3b, 0x16, 0xdc, 0x35, 0x83}; - std::array res = {0}; - for(size_t i = 0; i < c_bytes.size(); ++i) { - res[i / sizeof(word)] |= word(c_bytes[i]) << ((i % sizeof(word)) * 8); - } + return load_words(c_bytes); +} - return res; +/// @return a word array for L = 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d +consteval std::array big_l_words() { + const std::array big_l_bytes{ + 0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78, 0x23, 0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2, 0x6c, 0x21, 0x90, 0x36, 0xd6, + 0xae, 0x49, 0xdb, 0x4e, 0xc4, 0xe9, 0x23, 0xca, 0x7c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f}; + return load_words(big_l_bytes); } /// @return c*x, with c = 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d @@ -79,15 +96,9 @@ std::array add(std::span x, std::span x) { std::array tmp; copy_mem(tmp, x); - constexpr std::array L = {0x2378c292ab5844f3, - 0x216cc2728dc58f55, - 0xc44edb49aed63690, - 0xffffffff7cca23e9, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0x3fffffffffffffff}; - - const word borrow = bigint_sub2(tmp.data(), tmp.size(), L.data(), L.size()); + constexpr auto big_l = big_l_words(); + + const word borrow = bigint_sub2(tmp.data(), tmp.size(), big_l.data(), big_l.size()); const auto smaller_than_L = CT::Mask::expand(borrow); smaller_than_L.select_n(x.data(), x.data(), tmp.data(), WORDS_446);