mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibCrypto: Optimize UnsignedBigInteger import_data/export_data
No need to do complicated math to import or export numbers, just convert the byte stream to words and vice versa.
This commit is contained in:
parent
08221139a5
commit
3fdacef07f
Notes:
sideshowbarker
2024-07-19 04:38:05 +09:00
Author: https://github.com/tomuta Commit: https://github.com/SerenityOS/serenity/commit/3fdacef07f5 Pull-request: https://github.com/SerenityOS/serenity/pull/2857
2 changed files with 47 additions and 28 deletions
|
@ -29,6 +29,25 @@
|
|||
|
||||
namespace Crypto {
|
||||
|
||||
UnsignedBigInteger::UnsignedBigInteger(const u8* ptr, size_t length)
|
||||
{
|
||||
m_words.resize_and_keep_capacity((length + sizeof(u32) - 1) / sizeof(u32));
|
||||
size_t in = length, out = 0;
|
||||
while (in >= sizeof(u32)) {
|
||||
in -= sizeof(u32);
|
||||
u32 word = ((u32)ptr[in] << 24) | ((u32)ptr[in + 1] << 16) | ((u32)ptr[in + 2] << 8) | (u32)ptr[in + 3];
|
||||
m_words[out++] = word;
|
||||
}
|
||||
if (in > 0) {
|
||||
u32 word = 0;
|
||||
for (size_t i = 0; i < in; i++) {
|
||||
word <<= 8;
|
||||
word |= (u32)ptr[i];
|
||||
}
|
||||
m_words[out++] = word;
|
||||
}
|
||||
}
|
||||
|
||||
UnsignedBigInteger UnsignedBigInteger::create_invalid()
|
||||
{
|
||||
UnsignedBigInteger invalid(0);
|
||||
|
@ -36,35 +55,30 @@ UnsignedBigInteger UnsignedBigInteger::create_invalid()
|
|||
return invalid;
|
||||
}
|
||||
|
||||
// FIXME: in great need of optimisation
|
||||
UnsignedBigInteger UnsignedBigInteger::import_data(const u8* ptr, size_t length)
|
||||
{
|
||||
UnsignedBigInteger integer { 0 };
|
||||
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
auto part = UnsignedBigInteger { ptr[length - i - 1] }.shift_left(8 * i);
|
||||
integer = integer.plus(part);
|
||||
}
|
||||
|
||||
return integer;
|
||||
}
|
||||
|
||||
size_t UnsignedBigInteger::export_data(AK::ByteBuffer& data) const
|
||||
{
|
||||
UnsignedBigInteger copy { *this };
|
||||
UnsignedBigInteger quotient;
|
||||
UnsignedBigInteger remainder;
|
||||
|
||||
size_t size = trimmed_length() * sizeof(u32);
|
||||
size_t i = 0;
|
||||
for (; i < size; ++i) {
|
||||
if (copy.trimmed_length() == 0)
|
||||
break;
|
||||
data[size - i - 1] = copy.m_words[0] & 0xff;
|
||||
divide_u16_without_allocation(copy, 256, quotient, remainder);
|
||||
copy.set_to(quotient);
|
||||
size_t word_count = trimmed_length();
|
||||
size_t out = 0;
|
||||
if (word_count > 0) {
|
||||
ssize_t leading_zeros = -1;
|
||||
u32 word = m_words[word_count - 1];
|
||||
for (size_t i = 0; i < sizeof(u32); i++) {
|
||||
u8 byte = (u8)(word >> ((sizeof(u32) - i - 1) * 8));
|
||||
data[out++] = byte;
|
||||
if (leading_zeros < 0 && byte != 0)
|
||||
leading_zeros = (int)i;
|
||||
}
|
||||
for (size_t i = word_count - 1; i > 0; i--) {
|
||||
word = m_words[i - 1];
|
||||
data[out++] = (u8)(word >> 24);
|
||||
data[out++] = (u8)(word >> 16);
|
||||
data[out++] = (u8)(word >> 8);
|
||||
data[out++] = (u8)word;
|
||||
}
|
||||
if (leading_zeros > 0)
|
||||
out -= leading_zeros;
|
||||
}
|
||||
return i;
|
||||
return out;
|
||||
}
|
||||
|
||||
UnsignedBigInteger UnsignedBigInteger::from_base10(const String& str)
|
||||
|
|
|
@ -46,12 +46,17 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
explicit UnsignedBigInteger(const u8* ptr, size_t length);
|
||||
|
||||
UnsignedBigInteger() { }
|
||||
|
||||
static UnsignedBigInteger create_invalid();
|
||||
|
||||
static UnsignedBigInteger import_data(const AK::StringView& data) { return import_data((const u8*)data.characters_without_null_termination(), data.length()); }
|
||||
static UnsignedBigInteger import_data(const u8* ptr, size_t length);
|
||||
static UnsignedBigInteger import_data(const u8* ptr, size_t length)
|
||||
{
|
||||
return UnsignedBigInteger(ptr, length);
|
||||
}
|
||||
|
||||
size_t export_data(AK::ByteBuffer& data) const;
|
||||
size_t export_data(const u8* ptr, size_t length) const
|
||||
|
@ -129,7 +134,7 @@ struct UnsignedDivisionResult {
|
|||
}
|
||||
|
||||
inline const LogStream&
|
||||
operator<<(const LogStream& stream, const Crypto::UnsignedBigInteger value)
|
||||
operator<<(const LogStream& stream, const Crypto::UnsignedBigInteger& value)
|
||||
{
|
||||
if (value.is_invalid()) {
|
||||
stream << "Invalid BigInt";
|
||||
|
|
Loading…
Reference in a new issue