From 2470fab05e29f94fab86b4dfd089d01d99410ff1 Mon Sep 17 00:00:00 2001 From: Dan Klishch Date: Tue, 22 Nov 2022 01:25:47 +0300 Subject: [PATCH] AK: Delete unused and untested sqrt, pow and pow_mod from UFixedBigInt --- AK/UFixedBigInt.h | 126 +--------------------------------- Tests/AK/TestUFixedBigInt.cpp | 9 --- 2 files changed, 2 insertions(+), 133 deletions(-) diff --git a/AK/UFixedBigInt.h b/AK/UFixedBigInt.h index a57ed8cfdd..76012ed641 100644 --- a/AK/UFixedBigInt.h +++ b/AK/UFixedBigInt.h @@ -475,130 +475,8 @@ public: return *this; } - constexpr R sqrt() const - { - // Bitwise method: https://en.wikipedia.org/wiki/Integer_square_root#Using_bitwise_operations - // the bitwise method seems to be way faster then Newtons: - // https://quick-bench.com/q/eXZwW1DVhZxLE0llumeCXkfOK3Q - if (*this == 1u) - return 1u; - - ssize_t shift = (sizeof(R) * 8 - clz()) & ~1ULL; - // should be equivalent to: - // long shift = 2; - // while ((val >> shift) != 0) - // shift += 2; - - R res = 0u; - while (shift >= 0) { - res = res << 1u; - R large_cand = (res | 1u); - if (*this >> (size_t)shift >= large_cand * large_cand) - res = large_cand; - shift -= 2; - } - return res; - } - - constexpr R pow(u64 exp) - { - // Montgomery's Ladder Technique - // https://en.wikipedia.org/wiki/Exponentiation_by_squaring#Montgomery's_ladder_technique - R x1 = *this; - R x2 = *this * *this; - u64 exp_copy = exp; - for (ssize_t i = sizeof(u64) * 8 - count_leading_zeroes(exp) - 2; i >= 0; --i) { - if (exp_copy & 1u) { - x2 *= x1; - x1 *= x1; - } else { - x1 *= x2; - x2 *= x2; - } - exp_copy >>= 1u; - } - return x1; - } - template - requires(sizeof(U) > sizeof(u64)) constexpr R pow(U exp) - { - // Montgomery's Ladder Technique - // https://en.wikipedia.org/wiki/Exponentiation_by_squaring#Montgomery's_ladder_technique - R x1 = *this; - R x2 = *this * *this; - U exp_copy = exp; - for (ssize_t i = sizeof(U) * 8 - exp().clz() - 2; i >= 0; --i) { - if (exp_copy & 1u) { - x2 *= x1; - x1 *= x1; - } else { - x1 *= x2; - x2 *= x2; - } - exp_copy >>= 1u; - } - return x1; - } - - template - constexpr U pow_mod(u64 exp, U mod) - { - // Left to right binary method: - // https://en.wikipedia.org/wiki/Modular_exponentiation#Left-to-right_binary_method - // FIXME: this is not sidechanel proof - if (!mod) - return 0u; - - U res = 1; - u64 exp_copy = exp; - for (size_t i = sizeof(u64) - count_leading_zeroes(exp) - 1u; i < exp; ++i) { - res *= res; - res %= mod; - if (exp_copy & 1u) { - res = (*this * res) % mod; - } - exp_copy >>= 1u; - } - return res; - } - template - requires(sizeof(ExpT) > sizeof(u64)) constexpr U pow_mod(ExpT exp, U mod) - { - // Left to right binary method: - // https://en.wikipedia.org/wiki/Modular_exponentiation#Left-to-right_binary_method - // FIXME: this is not side channel proof - if (!mod) - return 0u; - - U res = 1; - ExpT exp_copy = exp; - for (size_t i = sizeof(ExpT) - exp.clz() - 1u; i < exp; ++i) { - res *= res; - res %= mod; - if (exp_copy & 1u) { - res = (*this * res) % mod; - } - exp_copy >>= 1u; - } - return res; - } - - constexpr size_t log2() - { - // FIXME: proper rounding - return sizeof(R) - clz(); - } - constexpr size_t logn(u64 base) - { - // FIXME: proper rounding - return log2() / (sizeof(u64) - count_leading_zeroes(base)); - } - template - requires(sizeof(U) > sizeof(u64)) constexpr size_t logn(U base) - { - // FIXME: proper rounding - return log2() / base.log2(); - } + // Note: If there ever be need for non side-channel proof sqrt/pow/pow_mod of UFixedBigInt, you + // can restore them from Git history. #undef DEFINE_STANDARD_BINARY_OPERATOR #undef DEFINE_STANDARD_COMPOUND_ASSIGNMENT diff --git a/Tests/AK/TestUFixedBigInt.cpp b/Tests/AK/TestUFixedBigInt.cpp index ae41da867c..73972b560b 100644 --- a/Tests/AK/TestUFixedBigInt.cpp +++ b/Tests/AK/TestUFixedBigInt.cpp @@ -39,15 +39,6 @@ TEST_CASE(identities) } } -TEST_CASE(sqrt) -{ - srand(0); - for (int i = 0; i < test_iterations; ++i) { - u256 x = get_random(); - EXPECT_EQ((x * x).sqrt(), x); - } -} - TEST_CASE(add_overflow_propagation) { u256 a = NumericLimits::max();