mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:47:34 +00:00
LibCrypto: Add ::import_data() and ::export_data() to UnsignedBigInteger
These functions allow conversion to-and-from big-endian buffers This commit also adds a ""_bigint operator for easy bigint use
This commit is contained in:
parent
c52d3e65b9
commit
6b742c69bd
3 changed files with 66 additions and 0 deletions
|
@ -312,4 +312,32 @@ UnsignedBigInteger UnsignedBigInteger::create_invalid()
|
||||||
invalid.invalidate();
|
invalid.invalidate();
|
||||||
return 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.add(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
return integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t UnsignedBigInteger::export_data(AK::ByteBuffer& data)
|
||||||
|
{
|
||||||
|
UnsignedBigInteger copy { *this };
|
||||||
|
|
||||||
|
size_t size = trimmed_length() * sizeof(u32);
|
||||||
|
size_t i = 0;
|
||||||
|
for (; i < size; ++i) {
|
||||||
|
if (copy.length() == 0)
|
||||||
|
break;
|
||||||
|
data[size - i - 1] = copy.m_words[0] & 0xff;
|
||||||
|
copy = copy.divide(256).quotient;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <AK/ByteBuffer.h>
|
||||||
#include <AK/LogStream.h>
|
#include <AK/LogStream.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
@ -48,6 +49,16 @@ public:
|
||||||
static UnsignedBigInteger from_base10(const String& str);
|
static UnsignedBigInteger from_base10(const String& str);
|
||||||
static UnsignedBigInteger create_invalid();
|
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);
|
||||||
|
|
||||||
|
size_t export_data(AK::ByteBuffer& data);
|
||||||
|
size_t export_data(const u8* ptr, size_t length)
|
||||||
|
{
|
||||||
|
auto buffer = ByteBuffer::wrap(ptr, length);
|
||||||
|
return export_data(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
const AK::Vector<u32>& words() const { return m_words; }
|
const AK::Vector<u32>& words() const { return m_words; }
|
||||||
|
|
||||||
UnsignedBigInteger add(const UnsignedBigInteger& other) const;
|
UnsignedBigInteger add(const UnsignedBigInteger& other) const;
|
||||||
|
@ -103,3 +114,9 @@ operator<<(const LogStream& stream, const Crypto::UnsignedBigInteger value)
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Crypto::UnsignedBigInteger
|
||||||
|
operator""_bigint(const char* string, size_t length)
|
||||||
|
{
|
||||||
|
return Crypto::UnsignedBigInteger::from_base10({ string, length });
|
||||||
|
}
|
||||||
|
|
|
@ -183,6 +183,9 @@ auto main(int argc, char** argv) -> int
|
||||||
puts("\tencrypt -- Access encryption functions");
|
puts("\tencrypt -- Access encryption functions");
|
||||||
puts("\tdecrypt -- Access decryption functions");
|
puts("\tdecrypt -- Access decryption functions");
|
||||||
puts("\tlist -- List all known modes");
|
puts("\tlist -- List all known modes");
|
||||||
|
puts("these modes only contain tests");
|
||||||
|
puts("\tbigint -- Run big integer test suite");
|
||||||
|
puts("\tpk -- Run Public-key system tests");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,6 +311,7 @@ void bigint_subtraction();
|
||||||
void bigint_multiplication();
|
void bigint_multiplication();
|
||||||
void bigint_division();
|
void bigint_division();
|
||||||
void bigint_base10();
|
void bigint_base10();
|
||||||
|
void bigint_import_export();
|
||||||
|
|
||||||
int aes_cbc_tests()
|
int aes_cbc_tests()
|
||||||
{
|
{
|
||||||
|
@ -805,6 +809,7 @@ int bigint_tests()
|
||||||
bigint_multiplication();
|
bigint_multiplication();
|
||||||
bigint_division();
|
bigint_division();
|
||||||
bigint_base10();
|
bigint_base10();
|
||||||
|
bigint_import_export();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1027,3 +1032,19 @@ void bigint_base10()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bigint_import_export()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
I_TEST((BigInteger | BigEndian Decode / Encode roundtrip));
|
||||||
|
u8 random_bytes[128];
|
||||||
|
u8 target_buffer[128];
|
||||||
|
arc4random_buf(random_bytes, 128);
|
||||||
|
auto encoded = Crypto::UnsignedBigInteger::import_data(random_bytes, 128);
|
||||||
|
encoded.export_data(target_buffer, 128);
|
||||||
|
if (memcmp(target_buffer, random_bytes, 128) != 0)
|
||||||
|
FAIL(Could not roundtrip);
|
||||||
|
else
|
||||||
|
PASS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue