mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
LibCrypto: Introduce a falible API for SignedBigInteger::shift_left
This commit is contained in:
parent
c48641c13a
commit
8fda05d8b7
Notes:
github-actions[bot]
2025-02-19 14:02:02 +00:00
Author: https://github.com/ttrssreal
Commit: 8fda05d8b7
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3615
6 changed files with 48 additions and 8 deletions
|
@ -160,13 +160,23 @@ FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_fill_to_one_based_index_w
|
||||||
output.m_words[last_word_index] = (NumericLimits<UnsignedBigInteger::Word>::max() >> (UnsignedBigInteger::BITS_IN_WORD - index)) & ~last_word;
|
output.m_words[last_word_index] = (NumericLimits<UnsignedBigInteger::Word>::max() >> (UnsignedBigInteger::BITS_IN_WORD - index)) & ~last_word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLATTEN void UnsignedBigIntegerAlgorithms::shift_left_without_allocation(
|
||||||
|
UnsignedBigInteger const& number,
|
||||||
|
size_t num_bits,
|
||||||
|
UnsignedBigInteger& temp_result,
|
||||||
|
UnsignedBigInteger& temp_plus,
|
||||||
|
UnsignedBigInteger& output)
|
||||||
|
{
|
||||||
|
MUST(try_shift_left_without_allocation(number, num_bits, temp_result, temp_plus, output));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Complexity : O(N + num_bits % 8) where N is the number of words in the number
|
* Complexity : O(N + num_bits % 8) where N is the number of words in the number
|
||||||
* Shift method :
|
* Shift method :
|
||||||
* Start by shifting by whole words in num_bits (by putting missing words at the start),
|
* Start by shifting by whole words in num_bits (by putting missing words at the start),
|
||||||
* then shift the number's words two by two by the remaining amount of bits.
|
* then shift the number's words two by two by the remaining amount of bits.
|
||||||
*/
|
*/
|
||||||
FLATTEN void UnsignedBigIntegerAlgorithms::shift_left_without_allocation(
|
FLATTEN ErrorOr<void> UnsignedBigIntegerAlgorithms::try_shift_left_without_allocation(
|
||||||
UnsignedBigInteger const& number,
|
UnsignedBigInteger const& number,
|
||||||
size_t num_bits,
|
size_t num_bits,
|
||||||
UnsignedBigInteger& temp_result,
|
UnsignedBigInteger& temp_result,
|
||||||
|
@ -177,7 +187,7 @@ FLATTEN void UnsignedBigIntegerAlgorithms::shift_left_without_allocation(
|
||||||
// where the shift amount is <= size of word (32).
|
// where the shift amount is <= size of word (32).
|
||||||
// But we do know how to shift by a multiple of word size (e.g 64=32*2)
|
// But we do know how to shift by a multiple of word size (e.g 64=32*2)
|
||||||
// So we first shift the result by how many whole words fit in 'num_bits'
|
// So we first shift the result by how many whole words fit in 'num_bits'
|
||||||
shift_left_by_n_words(number, num_bits / UnsignedBigInteger::BITS_IN_WORD, temp_result);
|
TRY(try_shift_left_by_n_words(number, num_bits / UnsignedBigInteger::BITS_IN_WORD, temp_result));
|
||||||
|
|
||||||
output.set_to(temp_result);
|
output.set_to(temp_result);
|
||||||
|
|
||||||
|
@ -185,7 +195,7 @@ FLATTEN void UnsignedBigIntegerAlgorithms::shift_left_without_allocation(
|
||||||
num_bits %= UnsignedBigInteger::BITS_IN_WORD;
|
num_bits %= UnsignedBigInteger::BITS_IN_WORD;
|
||||||
|
|
||||||
if (num_bits == 0) {
|
if (num_bits == 0) {
|
||||||
return;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < temp_result.length(); ++i) {
|
for (size_t i = 0; i < temp_result.length(); ++i) {
|
||||||
|
@ -202,9 +212,11 @@ FLATTEN void UnsignedBigIntegerAlgorithms::shift_left_without_allocation(
|
||||||
// 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.set_to_0();
|
||||||
temp_plus.m_words.append(carry_word);
|
temp_plus.m_words.append(carry_word);
|
||||||
shift_left_by_n_words(temp_plus, temp_result.length(), temp_result);
|
TRY(try_shift_left_by_n_words(temp_plus, temp_result.length(), temp_result));
|
||||||
add_into_accumulator_without_allocation(output, temp_result);
|
add_into_accumulator_without_allocation(output, temp_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
FLATTEN void UnsignedBigIntegerAlgorithms::shift_right_without_allocation(
|
FLATTEN void UnsignedBigIntegerAlgorithms::shift_right_without_allocation(
|
||||||
|
@ -220,13 +232,23 @@ void UnsignedBigIntegerAlgorithms::shift_left_by_n_words(
|
||||||
UnsignedBigInteger const& number,
|
UnsignedBigInteger const& number,
|
||||||
size_t number_of_words,
|
size_t number_of_words,
|
||||||
UnsignedBigInteger& output)
|
UnsignedBigInteger& output)
|
||||||
|
{
|
||||||
|
MUST(try_shift_left_by_n_words(number, number_of_words, output));
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<void> UnsignedBigIntegerAlgorithms::try_shift_left_by_n_words(
|
||||||
|
UnsignedBigInteger const& number,
|
||||||
|
size_t number_of_words,
|
||||||
|
UnsignedBigInteger& output)
|
||||||
{
|
{
|
||||||
// shifting left by N words means just inserting N zeroes to the beginning of the words vector
|
// shifting left by N words means just inserting N zeroes to the beginning of the words vector
|
||||||
output.set_to_0();
|
output.set_to_0();
|
||||||
output.m_words.resize_and_keep_capacity(number_of_words + number.length());
|
TRY(output.m_words.try_resize_and_keep_capacity(number_of_words + number.length()));
|
||||||
|
|
||||||
__builtin_memset(output.m_words.data(), 0, number_of_words * sizeof(unsigned));
|
__builtin_memset(output.m_words.data(), 0, number_of_words * sizeof(unsigned));
|
||||||
__builtin_memcpy(&output.m_words.data()[number_of_words], number.m_words.data(), number.m_words.size() * sizeof(unsigned));
|
__builtin_memcpy(&output.m_words.data()[number_of_words], number.m_words.data(), number.m_words.size() * sizeof(unsigned));
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnsignedBigIntegerAlgorithms::shift_right_by_n_words(
|
void UnsignedBigIntegerAlgorithms::shift_right_by_n_words(
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
static void divide_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger const& denominator, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder);
|
static void divide_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger const& denominator, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder);
|
||||||
static void divide_u16_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger::Word denominator, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder);
|
static void divide_u16_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger::Word denominator, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder);
|
||||||
|
|
||||||
|
static ErrorOr<void> try_shift_left_without_allocation(UnsignedBigInteger const& number, size_t bits_to_shift_by, UnsignedBigInteger& temp_result, UnsignedBigInteger& temp_plus, UnsignedBigInteger& output);
|
||||||
|
|
||||||
static void extended_GCD_without_allocation(UnsignedBigInteger const& a, UnsignedBigInteger const& b, UnsignedBigInteger& x, UnsignedBigInteger& y, UnsignedBigInteger& gcd, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& temp_r, UnsignedBigInteger& temp_s, UnsignedBigInteger& temp_t);
|
static void extended_GCD_without_allocation(UnsignedBigInteger const& a, UnsignedBigInteger const& b, UnsignedBigInteger& x, UnsignedBigInteger& y, UnsignedBigInteger& gcd, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& temp_r, UnsignedBigInteger& temp_s, UnsignedBigInteger& temp_t);
|
||||||
static void destructive_GCD_without_allocation(UnsignedBigInteger& temp_a, UnsignedBigInteger& temp_b, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_remainder, UnsignedBigInteger& output);
|
static void destructive_GCD_without_allocation(UnsignedBigInteger& temp_a, UnsignedBigInteger& temp_b, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_remainder, UnsignedBigInteger& output);
|
||||||
static void modular_inverse_without_allocation(UnsignedBigInteger const& a, UnsignedBigInteger const& b, UnsignedBigInteger& result, UnsignedBigInteger& temp_y, UnsignedBigInteger& temp_gcd, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& temp_r, UnsignedBigInteger& temp_s, UnsignedBigInteger& temp_t);
|
static void modular_inverse_without_allocation(UnsignedBigInteger const& a, UnsignedBigInteger const& b, UnsignedBigInteger& result, UnsignedBigInteger& temp_y, UnsignedBigInteger& temp_gcd, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& temp_r, UnsignedBigInteger& temp_s, UnsignedBigInteger& temp_t);
|
||||||
|
@ -39,6 +41,8 @@ private:
|
||||||
static void shift_left_by_n_words(UnsignedBigInteger const& number, size_t number_of_words, UnsignedBigInteger& output);
|
static void shift_left_by_n_words(UnsignedBigInteger const& number, size_t number_of_words, UnsignedBigInteger& output);
|
||||||
static void shift_right_by_n_words(UnsignedBigInteger const& number, size_t number_of_words, UnsignedBigInteger& output);
|
static void shift_right_by_n_words(UnsignedBigInteger const& number, size_t number_of_words, UnsignedBigInteger& output);
|
||||||
ALWAYS_INLINE static UnsignedBigInteger::Word shift_left_get_one_word(UnsignedBigInteger const& number, size_t num_bits, size_t result_word_index);
|
ALWAYS_INLINE static UnsignedBigInteger::Word shift_left_get_one_word(UnsignedBigInteger const& number, size_t num_bits, size_t result_word_index);
|
||||||
|
|
||||||
|
static ErrorOr<void> try_shift_left_by_n_words(UnsignedBigInteger const& number, size_t number_of_words, UnsignedBigInteger& output);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,9 +276,14 @@ bool SignedBigInteger::operator>(UnsignedBigInteger const& other) const
|
||||||
return *this != other && !(*this < other);
|
return *this != other && !(*this < other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLATTEN ErrorOr<SignedBigInteger> SignedBigInteger::try_shift_left(size_t num_bits) const
|
||||||
|
{
|
||||||
|
return SignedBigInteger { TRY(m_unsigned_data.try_shift_left(num_bits)), m_sign };
|
||||||
|
}
|
||||||
|
|
||||||
FLATTEN SignedBigInteger SignedBigInteger::shift_left(size_t num_bits) const
|
FLATTEN SignedBigInteger SignedBigInteger::shift_left(size_t num_bits) const
|
||||||
{
|
{
|
||||||
return SignedBigInteger { m_unsigned_data.shift_left(num_bits), m_sign };
|
return MUST(try_shift_left(num_bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
FLATTEN SignedBigInteger SignedBigInteger::shift_right(size_t num_bits) const
|
FLATTEN SignedBigInteger SignedBigInteger::shift_right(size_t num_bits) const
|
||||||
|
|
|
@ -120,6 +120,8 @@ public:
|
||||||
[[nodiscard]] SignedBigInteger multiplied_by(SignedBigInteger const& other) const;
|
[[nodiscard]] SignedBigInteger multiplied_by(SignedBigInteger const& other) const;
|
||||||
[[nodiscard]] SignedDivisionResult divided_by(SignedBigInteger const& divisor) const;
|
[[nodiscard]] SignedDivisionResult divided_by(SignedBigInteger const& divisor) const;
|
||||||
|
|
||||||
|
[[nodiscard]] ErrorOr<SignedBigInteger> try_shift_left(size_t num_bits) const;
|
||||||
|
|
||||||
[[nodiscard]] SignedBigInteger plus(UnsignedBigInteger const& other) const;
|
[[nodiscard]] SignedBigInteger plus(UnsignedBigInteger const& other) const;
|
||||||
[[nodiscard]] SignedBigInteger minus(UnsignedBigInteger const& other) const;
|
[[nodiscard]] SignedBigInteger minus(UnsignedBigInteger const& other) const;
|
||||||
[[nodiscard]] SignedBigInteger multiplied_by(UnsignedBigInteger const& other) const;
|
[[nodiscard]] SignedBigInteger multiplied_by(UnsignedBigInteger const& other) const;
|
||||||
|
|
|
@ -481,17 +481,22 @@ FLATTEN UnsignedBigInteger UnsignedBigInteger::bitwise_not_fill_to_one_based_ind
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FLATTEN UnsignedBigInteger UnsignedBigInteger::shift_left(size_t num_bits) const
|
FLATTEN ErrorOr<UnsignedBigInteger> UnsignedBigInteger::try_shift_left(size_t num_bits) const
|
||||||
{
|
{
|
||||||
UnsignedBigInteger output;
|
UnsignedBigInteger output;
|
||||||
UnsignedBigInteger temp_result;
|
UnsignedBigInteger temp_result;
|
||||||
UnsignedBigInteger temp_plus;
|
UnsignedBigInteger temp_plus;
|
||||||
|
|
||||||
UnsignedBigIntegerAlgorithms::shift_left_without_allocation(*this, num_bits, temp_result, temp_plus, output);
|
TRY(UnsignedBigIntegerAlgorithms::try_shift_left_without_allocation(*this, num_bits, temp_result, temp_plus, output));
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLATTEN UnsignedBigInteger UnsignedBigInteger::shift_left(size_t num_bits) const
|
||||||
|
{
|
||||||
|
return MUST(try_shift_left(num_bits));
|
||||||
|
}
|
||||||
|
|
||||||
FLATTEN UnsignedBigInteger UnsignedBigInteger::shift_right(size_t num_bits) const
|
FLATTEN UnsignedBigInteger UnsignedBigInteger::shift_right(size_t num_bits) const
|
||||||
{
|
{
|
||||||
UnsignedBigInteger output;
|
UnsignedBigInteger output;
|
||||||
|
|
|
@ -120,6 +120,8 @@ public:
|
||||||
[[nodiscard]] UnsignedBigInteger multiplied_by(UnsignedBigInteger const& other) const;
|
[[nodiscard]] UnsignedBigInteger multiplied_by(UnsignedBigInteger const& other) const;
|
||||||
[[nodiscard]] UnsignedDivisionResult divided_by(UnsignedBigInteger const& divisor) const;
|
[[nodiscard]] UnsignedDivisionResult divided_by(UnsignedBigInteger const& divisor) const;
|
||||||
|
|
||||||
|
[[nodiscard]] ErrorOr<UnsignedBigInteger> try_shift_left(size_t num_bits) const;
|
||||||
|
|
||||||
[[nodiscard]] u32 hash() const;
|
[[nodiscard]] u32 hash() const;
|
||||||
|
|
||||||
void set_bit_inplace(size_t bit_index);
|
void set_bit_inplace(size_t bit_index);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue