diff --git a/Userland/Libraries/LibCrypto/BigInt/Algorithms/BitwiseOperations.cpp b/Userland/Libraries/LibCrypto/BigInt/Algorithms/BitwiseOperations.cpp index 2003e4896c4..fd4376a8d32 100644 --- a/Userland/Libraries/LibCrypto/BigInt/Algorithms/BitwiseOperations.cpp +++ b/Userland/Libraries/LibCrypto/BigInt/Algorithms/BitwiseOperations.cpp @@ -6,6 +6,7 @@ */ #include "UnsignedBigIntegerAlgorithms.h" +#include #include #include @@ -207,6 +208,15 @@ FLATTEN void UnsignedBigIntegerAlgorithms::shift_left_without_allocation( } } +FLATTEN void UnsignedBigIntegerAlgorithms::shift_right_without_allocation( + UnsignedBigInteger const& number, + size_t num_bits, + UnsignedBigInteger& output) +{ + output.m_words.resize_and_keep_capacity(number.length() - (num_bits / UnsignedBigInteger::BITS_IN_WORD)); + Ops::shift_right(number.words_span(), num_bits, output.words_span()); +} + void UnsignedBigIntegerAlgorithms::shift_left_by_n_words( UnsignedBigInteger const& number, size_t number_of_words, diff --git a/Userland/Libraries/LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h b/Userland/Libraries/LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h index 18c8247e574..d8f02654e8f 100644 --- a/Userland/Libraries/LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h +++ b/Userland/Libraries/LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h @@ -11,6 +11,8 @@ namespace Crypto { class UnsignedBigIntegerAlgorithms { + using Ops = AK::StorageOperations; + public: static void add_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output); static void add_into_accumulator_without_allocation(UnsignedBigInteger& accumulator, UnsignedBigInteger const& value); @@ -20,6 +22,7 @@ public: static void bitwise_xor_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output); static void bitwise_not_fill_to_one_based_index_without_allocation(UnsignedBigInteger const& left, size_t, UnsignedBigInteger& output); static void shift_left_without_allocation(UnsignedBigInteger const& number, size_t bits_to_shift_by, UnsignedBigInteger& temp_result, UnsignedBigInteger& temp_plus, UnsignedBigInteger& output); + static void shift_right_without_allocation(UnsignedBigInteger const& number, size_t num_bits, UnsignedBigInteger& output); static void multiply_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& output); static void divide_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger const& denominator, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& temp_minus, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder); static void divide_u16_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger::Word denominator, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder); diff --git a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp index 14b70a8c396..a158d9db73a 100644 --- a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp +++ b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp @@ -281,6 +281,11 @@ FLATTEN SignedBigInteger SignedBigInteger::shift_left(size_t num_bits) const return SignedBigInteger { m_unsigned_data.shift_left(num_bits), m_sign }; } +FLATTEN SignedBigInteger SignedBigInteger::shift_right(size_t num_bits) const +{ + return SignedBigInteger { m_unsigned_data.shift_right(num_bits), m_sign }; +} + FLATTEN SignedBigInteger SignedBigInteger::multiplied_by(SignedBigInteger const& other) const { bool result_sign = m_sign ^ other.m_sign; diff --git a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h index 532bc7ed469..725e4f8bdf2 100644 --- a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h +++ b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h @@ -117,6 +117,7 @@ public: [[nodiscard]] SignedBigInteger bitwise_xor(SignedBigInteger const& other) const; [[nodiscard]] SignedBigInteger bitwise_not() const; [[nodiscard]] SignedBigInteger shift_left(size_t num_bits) const; + [[nodiscard]] SignedBigInteger shift_right(size_t num_bits) const; [[nodiscard]] SignedBigInteger multiplied_by(SignedBigInteger const& other) const; [[nodiscard]] SignedDivisionResult divided_by(SignedBigInteger const& divisor) const; diff --git a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp index cb6bb42d324..27194877e56 100644 --- a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp +++ b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp @@ -492,6 +492,15 @@ FLATTEN UnsignedBigInteger UnsignedBigInteger::shift_left(size_t num_bits) const return output; } +FLATTEN UnsignedBigInteger UnsignedBigInteger::shift_right(size_t num_bits) const +{ + UnsignedBigInteger output; + + UnsignedBigIntegerAlgorithms::shift_right_without_allocation(*this, num_bits, output); + + return output; +} + FLATTEN UnsignedBigInteger UnsignedBigInteger::multiplied_by(UnsignedBigInteger const& other) const { UnsignedBigInteger result; diff --git a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h index 1ec8e748821..50c56ac0b29 100644 --- a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h +++ b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -24,6 +25,8 @@ constexpr size_t STARTING_WORD_SIZE = 32; class UnsignedBigInteger { public: using Word = u32; + using StorageSpan = AK::Detail::StorageSpan; + using ConstStorageSpan = AK::Detail::StorageSpan; static constexpr size_t BITS_IN_WORD = 32; // This constructor accepts any unsigned with size up to Word. @@ -114,6 +117,7 @@ public: [[nodiscard]] UnsignedBigInteger bitwise_xor(UnsignedBigInteger const& other) const; [[nodiscard]] UnsignedBigInteger bitwise_not_fill_to_one_based_index(size_t) const; [[nodiscard]] UnsignedBigInteger shift_left(size_t num_bits) const; + [[nodiscard]] UnsignedBigInteger shift_right(size_t num_bits) const; [[nodiscard]] UnsignedBigInteger multiplied_by(UnsignedBigInteger const& other) const; [[nodiscard]] UnsignedDivisionResult divided_by(UnsignedBigInteger const& divisor) const; @@ -140,6 +144,8 @@ private: // Little endian // m_word[0] + m_word[1] * Word::MAX + m_word[2] * Word::MAX * Word::MAX + ... Vector m_words; + StorageSpan words_span() { return { m_words.data(), m_words.size() }; } + ConstStorageSpan words_span() const { return { m_words.data(), m_words.size() }; } mutable u32 m_cached_hash { 0 };