diff options
-rw-r--r-- | Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp | 28 | ||||
-rw-r--r-- | Libraries/LibCrypto/BigInt/UnsignedBigInteger.h | 17 | ||||
-rw-r--r-- | Userland/test-crypto.cpp | 21 |
3 files changed, 66 insertions, 0 deletions
diff --git a/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp b/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp index b682704a2e..5cdff360a5 100644 --- a/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp +++ b/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp @@ -312,4 +312,32 @@ UnsignedBigInteger UnsignedBigInteger::create_invalid() invalid.invalidate(); 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; +} } diff --git a/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h b/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h index 660b234583..dbecbf0735 100644 --- a/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h +++ b/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h @@ -25,6 +25,7 @@ */ #pragma once +#include <AK/ByteBuffer.h> #include <AK/LogStream.h> #include <AK/String.h> #include <AK/Types.h> @@ -48,6 +49,16 @@ public: static UnsignedBigInteger from_base10(const String& str); 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; } UnsignedBigInteger add(const UnsignedBigInteger& other) const; @@ -103,3 +114,9 @@ operator<<(const LogStream& stream, const Crypto::UnsignedBigInteger value) } return stream; } + +inline Crypto::UnsignedBigInteger +operator""_bigint(const char* string, size_t length) +{ + return Crypto::UnsignedBigInteger::from_base10({ string, length }); +} diff --git a/Userland/test-crypto.cpp b/Userland/test-crypto.cpp index 7496a3df07..19acf079c6 100644 --- a/Userland/test-crypto.cpp +++ b/Userland/test-crypto.cpp @@ -183,6 +183,9 @@ auto main(int argc, char** argv) -> int puts("\tencrypt -- Access encryption functions"); puts("\tdecrypt -- Access decryption functions"); 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; } @@ -308,6 +311,7 @@ void bigint_subtraction(); void bigint_multiplication(); void bigint_division(); void bigint_base10(); +void bigint_import_export(); int aes_cbc_tests() { @@ -805,6 +809,7 @@ int bigint_tests() bigint_multiplication(); bigint_division(); bigint_base10(); + bigint_import_export(); 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; + } +} |