mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 15:10:19 +00:00
LibCrypto: Implement arbitrarily sized right shifts
Previously we could only shift by words at a time
This commit is contained in:
parent
9045840e33
commit
1af9fa1968
Notes:
sideshowbarker
2024-07-17 06:40:35 +09:00
Author: https://github.com/Hendiadyoin1 Commit: https://github.com/SerenityOS/serenity/commit/1af9fa1968 Pull-request: https://github.com/SerenityOS/serenity/pull/23619 Issue: https://github.com/SerenityOS/serenity/issues/23575 Reviewed-by: https://github.com/ADKaster ✅ Reviewed-by: https://github.com/DanShaders ✅
6 changed files with 34 additions and 0 deletions
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include "UnsignedBigIntegerAlgorithms.h"
|
||||
#include <AK/BigIntBase.h>
|
||||
#include <AK/BuiltinWrappers.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
|
||||
|
@ -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,
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
namespace Crypto {
|
||||
|
||||
class UnsignedBigIntegerAlgorithms {
|
||||
using Ops = AK::StorageOperations<UnsignedBigInteger::Word>;
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/BigIntBase.h>
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/ByteString.h>
|
||||
#include <AK/Concepts.h>
|
||||
|
@ -24,6 +25,8 @@ constexpr size_t STARTING_WORD_SIZE = 32;
|
|||
class UnsignedBigInteger {
|
||||
public:
|
||||
using Word = u32;
|
||||
using StorageSpan = AK::Detail::StorageSpan<Word, false>;
|
||||
using ConstStorageSpan = AK::Detail::StorageSpan<Word const, false>;
|
||||
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<Word, STARTING_WORD_SIZE> 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 };
|
||||
|
||||
|
|
Loading…
Reference in a new issue