diff --git a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp index 0e08a76d9d..9ee6622009 100644 --- a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp +++ b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp @@ -156,6 +156,13 @@ size_t UnsignedBigInteger::trimmed_length() const return m_cached_trimmed_length.value(); } +void UnsignedBigInteger::clamp_to_trimmed_length() +{ + auto length = trimmed_length(); + if (m_words.size() > length) + m_words.resize(length); +} + FLATTEN UnsignedBigInteger UnsignedBigInteger::plus(const UnsignedBigInteger& other) const { UnsignedBigInteger result; @@ -578,7 +585,7 @@ FLATTEN void UnsignedBigInteger::shift_left_without_allocation( // output += (carry_word << temp_result.length()) // FIXME : Using temp_plus this way to transform carry_word into a bigint is not - // efficient nor pretty. Maybe we should have an "add_with_shift" method ? + // efficient nor pretty. Maybe we should have an "add_with_shift" method ? temp_plus.set_to_0(); temp_plus.m_words.append(carry_word); shift_left_by_n_words(temp_plus, temp_result.length(), temp_result); diff --git a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h index 51c1d9f776..b2805e685c 100644 --- a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h +++ b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h @@ -81,6 +81,8 @@ public: // The "trimmed length" is the number of words after trimming leading zeroed words size_t trimmed_length() const; + void clamp_to_trimmed_length(); + UnsignedBigInteger plus(const UnsignedBigInteger& other) const; UnsignedBigInteger minus(const UnsignedBigInteger& other) const; UnsignedBigInteger bitwise_or(const UnsignedBigInteger& other) const; diff --git a/Userland/Libraries/LibCrypto/NumberTheory/ModularFunctions.cpp b/Userland/Libraries/LibCrypto/NumberTheory/ModularFunctions.cpp index 4125916a84..990f2c4323 100644 --- a/Userland/Libraries/LibCrypto/NumberTheory/ModularFunctions.cpp +++ b/Userland/Libraries/LibCrypto/NumberTheory/ModularFunctions.cpp @@ -150,6 +150,13 @@ UnsignedBigInteger ModularPower(const UnsignedBigInteger& b, const UnsignedBigIn UnsignedBigInteger::multiply_without_allocation(base, base, temp_1, temp_2, temp_3, temp_4, temp_multiply); UnsignedBigInteger::divide_without_allocation(temp_multiply, m, temp_1, temp_2, temp_3, temp_4, temp_quotient, temp_remainder); base.set_to(temp_remainder); + + // Note that not clamping here would cause future calculations (multiply, specifically) to allocate even more unused space + // which would then persist through the temp bigints, and significantly slow down later loops. + // To avoid that, we can clamp to a specific max size, or just clamp to the min needed amount of space. + ep.clamp_to_trimmed_length(); + exp.clamp_to_trimmed_length(); + base.clamp_to_trimmed_length(); } return exp; }