summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp28
-rw-r--r--Libraries/LibCrypto/BigInt/UnsignedBigInteger.h17
-rw-r--r--Userland/test-crypto.cpp21
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;
+ }
+}