From 6697d8c99e213b188bbf00ab817fdfae37dbb5d0 Mon Sep 17 00:00:00 2001 From: Jochen <97750753+Jochengehtab@users.noreply.github.com> Date: Thu, 9 Jul 2026 23:28:08 +0200 Subject: [PATCH 1/2] add factory methods and tests --- src/keyPair.cpp | 25 +++++++++++++++++++++++ src/keyPair.h | 7 +++++++ tests/test_rsa.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/src/keyPair.cpp b/src/keyPair.cpp index 5c67b36..33bb2c7 100644 --- a/src/keyPair.cpp +++ b/src/keyPair.cpp @@ -4,6 +4,7 @@ #include #include #include +#include // clang-format off #if defined(_WIN32) @@ -109,6 +110,10 @@ keyPair::keyPair() { private_key.d = d; } +// Constructor for already deserialized key structures +keyPair::keyPair(PublicKey publicKey, PrivateKey privateKey) + : public_key(std::move(publicKey)), private_key(std::move(privateKey)) {} + // Import Constructor: Imports keys from Base64 encoded serialized strings keyPair::keyPair(const std::string &publicKey, const std::string &privateKey) { const std::vector pubBytes = base64Decode(publicKey); @@ -190,6 +195,26 @@ bool keyPair::s_deserialize(const std::vector &data, operations::Base25 return true; } +// Static factory that creates a keyPair from populated PublicKey and PrivateKey structs +keyPair keyPair::create(const PublicKey &publicKey, const PrivateKey &privateKey) { + return keyPair(publicKey, privateKey); +} + +// Static factory that deserializes raw binary data and creates a keyPair +keyPair keyPair::create(const std::vector &pubData, const std::vector &privData) { + PublicKey pub; + PrivateKey priv; + + if (!s_deserialize(pubData, pub.n, pub.e)) { + throw std::runtime_error("Failed to deserialize public key data."); + } + if (!s_deserialize(privData, priv.n, priv.d)) { + throw std::runtime_error("Failed to deserialize private key data."); + } + + return keyPair(pub, priv); +} + std::string keyPair::base64Encode(const std::vector &data) { std::vector result; size_t index = 0; diff --git a/src/keyPair.h b/src/keyPair.h index b1570d0..17d6122 100644 --- a/src/keyPair.h +++ b/src/keyPair.h @@ -40,9 +40,16 @@ class keyPair { keyPair(const std::string &publicKey, const std::string &privateKey); + // Constructor to build a keyPair without triggering expensive prime generation + keyPair(PublicKey publicKey, PrivateKey privateKey); + PublicKey getPublicKey() { return public_key; } PrivateKey getPrivateKey() { return private_key; } + // Static factory methods to safely create a keyPair + static keyPair create(const PublicKey &publicKey, const PrivateKey &privateKey); + static keyPair create(const std::vector &pubData, const std::vector &privData); + static std::vector s_serialize(const operations::Base256 &first, const operations::Base256 &second); static bool s_deserialize(const std::vector &data, operations::Base256 &outFirst, diff --git a/tests/test_rsa.cpp b/tests/test_rsa.cpp index 8f335fb..1b49179 100644 --- a/tests/test_rsa.cpp +++ b/tests/test_rsa.cpp @@ -74,4 +74,55 @@ TEST_CASE("RSA Core: Key Serialization and Base64 Import/Export") { std::string recovered = decrypt(importedPair, ciphertext); REQUIRE(recovered == plaintext); +} + +TEST_CASE("RSA Core: Key Creation and Struct-based Initialization") { + static keyPair originalPair; + + SECTION("Creating keyPair from deserialized PublicKey and PrivateKey structs") { + PublicKey pub = originalPair.getPublicKey(); + PrivateKey priv = originalPair.getPrivateKey(); + + // 1. Verify the new struct-based constructor + keyPair constructedPair(pub, priv); + + std::string plaintext = "Struct Constructor Roundtrip Verification"; + std::vector ciphertext = encrypt(constructedPair, plaintext); + std::string recovered = decrypt(originalPair, ciphertext); + + REQUIRE(recovered == plaintext); + + // 2. Verify the static factory method 'create' with structs + keyPair factoryStructPair = keyPair::create(pub, priv); + + std::vector ciphertext2 = encrypt(originalPair, plaintext); + std::string recovered2 = decrypt(factoryStructPair, ciphertext2); + + REQUIRE(recovered2 == plaintext); + } + + SECTION("Creating keyPair from raw serialized byte vectors") { + std::vector pubBytes = originalPair.getPublicKey().serialize(); + std::vector privBytes = originalPair.getPrivateKey().serialize(); + + REQUIRE_FALSE(pubBytes.empty()); + REQUIRE_FALSE(privBytes.empty()); + + // Verify the static factory method 'create' with raw byte vectors (bypassing Base64) + keyPair factoryBytesPair = keyPair::create(pubBytes, privBytes); + + std::string plaintext = "Binary Serialization Factory Verification"; + std::vector ciphertext = encrypt(factoryBytesPair, plaintext); + std::string recovered = decrypt(originalPair, ciphertext); + + REQUIRE(recovered == plaintext); + } + + SECTION("Creating keyPair from invalid/corrupt serialized bytes throws exception") { + std::vector invalidPub = {1, 2, 3, 4}; // Invalid size and payload + std::vector invalidPriv = {5, 6, 7, 8}; + + // Expect std::runtime_error as specified in keyPair::create + REQUIRE_THROWS_AS(keyPair::create(invalidPub, invalidPriv), std::runtime_error); + } } \ No newline at end of file From 1b675ddaf3b4e1adfcc1e49781120bd1ff859407 Mon Sep 17 00:00:00 2001 From: Jochengehtab <97750753+Jochengehtab@users.noreply.github.com> Date: Fri, 10 Jul 2026 14:06:42 +0000 Subject: [PATCH 2/2] Apply Clang formatting --- src/keyPair.h | 3 ++- tests/test_rsa.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/keyPair.h b/src/keyPair.h index 17d6122..961e110 100644 --- a/src/keyPair.h +++ b/src/keyPair.h @@ -48,7 +48,8 @@ class keyPair { // Static factory methods to safely create a keyPair static keyPair create(const PublicKey &publicKey, const PrivateKey &privateKey); - static keyPair create(const std::vector &pubData, const std::vector &privData); + static keyPair create(const std::vector &pubData, + const std::vector &privData); static std::vector s_serialize(const operations::Base256 &first, const operations::Base256 &second); diff --git a/tests/test_rsa.cpp b/tests/test_rsa.cpp index 1b49179..32dd851 100644 --- a/tests/test_rsa.cpp +++ b/tests/test_rsa.cpp @@ -119,7 +119,7 @@ TEST_CASE("RSA Core: Key Creation and Struct-based Initialization") { } SECTION("Creating keyPair from invalid/corrupt serialized bytes throws exception") { - std::vector invalidPub = {1, 2, 3, 4}; // Invalid size and payload + std::vector invalidPub = {1, 2, 3, 4}; // Invalid size and payload std::vector invalidPriv = {5, 6, 7, 8}; // Expect std::runtime_error as specified in keyPair::create