diff --git a/GCryptLib/include/GCrypt/Key.h b/GCryptLib/include/GCrypt/Key.h index d63dd65..c7d505b 100644 --- a/GCryptLib/include/GCrypt/Key.h +++ b/GCryptLib/include/GCrypt/Key.h @@ -11,7 +11,12 @@ namespace Leonetienne::GCrypt { */ class Key : public Block { public: + //! Will generate a key from a password static Key FromPassword(const std::string& password); + + //! Will generate a random key from actual randomness (std::random_device) + static Key Random(); + Key(); Key(const Key& k); Key(const Block& b); diff --git a/GCryptLib/src/Key.cpp b/GCryptLib/src/Key.cpp index 2bffc67..f77623b 100644 --- a/GCryptLib/src/Key.cpp +++ b/GCryptLib/src/Key.cpp @@ -1,6 +1,8 @@ #include "GCrypt/Key.h" #include "GCrypt/GHash.h" #include "GCrypt/Util.h" +#include +#include namespace Leonetienne::GCrypt { @@ -10,6 +12,24 @@ namespace Leonetienne::GCrypt { ); } + Key Key::Random() { + // Create our truly-random rng + std::random_device rng; + constexpr std::size_t bitsPerCall = sizeof(std::random_device::result_type) * 8; + + // Fetch BLOCK_SIZE bits + std::stringstream ss; + for (std::size_t i = 0; i < BLOCK_SIZE / bitsPerCall; i++) { + ss << std::bitset(rng()); + } + + // Verify that we actually have the correct size + assert(ss.str().length() == BLOCK_SIZE); + + // Return them as a key + return Key(Block(ss.str())); + } + Key::Key() : Block() { }