mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 13:36:13 +03:00
AK: Delete unused and untested sqrt, pow and pow_mod from UFixedBigInt
This commit is contained in:
parent
8f8e31e780
commit
2470fab05e
Notes:
sideshowbarker
2024-07-16 23:27:19 +09:00
Author: https://github.com/DanShaders Commit: https://github.com/SerenityOS/serenity/commit/2470fab05e Pull-request: https://github.com/SerenityOS/serenity/pull/17330 Reviewed-by: https://github.com/ADKaster Reviewed-by: https://github.com/Hendiadyoin1
@ -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<Unsigned U>
|
||||
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<Unsigned U>
|
||||
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<Unsigned ExpT, Unsigned U>
|
||||
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<Unsigned U>
|
||||
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
|
||||
|
@ -39,15 +39,6 @@ TEST_CASE(identities)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(sqrt)
|
||||
{
|
||||
srand(0);
|
||||
for (int i = 0; i < test_iterations; ++i) {
|
||||
u256 x = get_random<u128>();
|
||||
EXPECT_EQ((x * x).sqrt(), x);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(add_overflow_propagation)
|
||||
{
|
||||
u256 a = NumericLimits<u128>::max();
|
||||
|
Loading…
Reference in New Issue
Block a user