Implemented a key class

This commit is contained in:
Leonetienne
2022-05-22 13:43:23 +02:00
parent bb76cbb2d7
commit 9fdc642bd6
13 changed files with 100 additions and 95 deletions

View File

@@ -5,7 +5,7 @@
namespace Leonetienne::GCrypt {
Feistel::Feistel(const Block& key) {
Feistel::Feistel(const Key& key) {
SetKey(key);
return;
}
@@ -16,7 +16,7 @@ namespace Leonetienne::GCrypt {
return;
}
void Feistel::SetKey(const Block& key) {
void Feistel::SetKey(const Key& key) {
GenerateRoundKeys(key);
return;
}
@@ -59,7 +59,7 @@ namespace Leonetienne::GCrypt {
return FeistelCombine(r, l);
}
Halfblock Feistel::F(Halfblock m, const Block& key) {
Halfblock Feistel::F(Halfblock m, const Key& key) {
// Made-up F function
// Expand to full bitwidth
@@ -174,7 +174,7 @@ namespace Leonetienne::GCrypt {
return subMap[in];
}
void Feistel::GenerateRoundKeys(const Block& seedKey) {
void Feistel::GenerateRoundKeys(const Key& seedKey) {
// Clear initial key memory
ZeroKeyMemory();
roundKeys = Keyset();
@@ -234,7 +234,7 @@ namespace Leonetienne::GCrypt {
Halfblock halfkey1 = F(halfkeys.first, roundKeys[i - 2]);
Halfblock halfkey2 = halfkeys.second ^ halfkey1; // I know this is reversible, but it helps to diffuse future round keys.
roundKeys[i] = FeistelCombine(halfkey1, halfkey2);
roundKeys[i] = Key(FeistelCombine(halfkey1, halfkey2));
}
return;
@@ -248,7 +248,7 @@ namespace Leonetienne::GCrypt {
#pragma GCC optimize ("O0")
#endif
void Feistel::ZeroKeyMemory() {
for (Block& key : roundKeys) {
for (Key& key : roundKeys) {
key.reset();
}

View File

@@ -7,9 +7,8 @@
namespace Leonetienne::GCrypt {
GCipher::GCipher(const Block& key, const DIRECTION direction)
GCipher::GCipher(const Key& key, const DIRECTION direction)
:
key { key },
direction { direction },
lastBlock(InitializationVector(key)), // Initialize our lastBlock with some deterministic initial value, based on the key
feistel(key) {
@@ -17,22 +16,6 @@ namespace Leonetienne::GCrypt {
return;
}
GCipher::GCipher(const std::string& password, const DIRECTION direction)
:
key { PasswordToKey(password) },
direction { direction },
lastBlock(InitializationVector(key)), // Initialize our lastBlock with some deterministic initial value, based on the key feistel(key) {
feistel(key) {
return;
}
GCipher::~GCipher() {
// Clear key memory
ZeroKeyMemory();
return;
}
Block GCipher::Digest(const Block& input) {
switch (direction) {
@@ -67,23 +50,5 @@ namespace Leonetienne::GCrypt {
throw std::runtime_error("Unreachable branch reached.");
}
// These pragmas only work for MSVC and g++, as far as i know. Beware!!!
#if defined _WIN32 || defined _WIN64
#pragma optimize("", off )
#elif defined __GNUG__
#pragma GCC push_options
#pragma GCC optimize ("O0")
#endif
void GCipher::ZeroKeyMemory() {
key.reset();
return;
}
#if defined _WIN32 || defined _WIN64
#pragma optimize("", on )
#elif defined __GNUG__
#pragma GCC pop_options
#endif
}

View File

@@ -7,7 +7,9 @@ namespace Leonetienne::GCrypt {
GHash::GHash() :
// Initialize our cipher with a static, but randomly distributed key.
cipher(
StringToBitblock("CfRtNdMTP4Y5CWRd"),
// Can't use Key::FromPassword here, because it depends on GHash.
// Instead use a hardcoded key.
Key(StringToBitblock("CfRtNdMTP4Y5CWRd")),
GCipher::DIRECTION::ENCIPHER
) {
block = InitializationVector(StringToBitblock("3J7IipfQTDJbO8jtasz9PgWui6faPaEMOuVuAqyhB1S2CRcLw5caawewgDUEG1WN"));

View File

@@ -4,10 +4,10 @@
namespace Leonetienne::GCrypt {
std::string GWrapper::EncryptString(const std::string& cleartext, const std::string& password) {
// Transform the password to a key
const Block key = PasswordToKey(password);
std::string GWrapper::EncryptString(
const std::string& cleartext,
const Key& key)
{
// Recode the ascii-string to bits
const Flexblock cleartext_bits = StringToBits(cleartext);
@@ -21,10 +21,10 @@ namespace Leonetienne::GCrypt {
return ciphertext;
}
std::string GWrapper::DecryptString(const std::string& ciphertext, const std::string& password) {
// Transform the password to a key
const Block key = PasswordToKey(password);
std::string GWrapper::DecryptString(
const std::string& ciphertext,
const Key& key)
{
// Recode the hex-string to bits
const Flexblock ciphertext_bits = HexstringToBits(ciphertext);
@@ -38,14 +38,16 @@ namespace Leonetienne::GCrypt {
return cleartext;
}
bool GWrapper::EncryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport) {
bool GWrapper::EncryptFile(
const std::string& filename_in,
const std::string& filename_out,
const Key& key,
bool printProgressReport)
{
try {
// Read the file to bits
const Flexblock cleartext_bits = ReadFileToBits(filename_in);
// Transform the password to a key
const Block key = PasswordToKey(password);
// Encrypt our cleartext bits
const Flexblock ciphertext_bits = CipherFlexblock(cleartext_bits, key, GCipher::DIRECTION::ENCIPHER);
@@ -59,14 +61,16 @@ namespace Leonetienne::GCrypt {
}
}
bool GWrapper::DecryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport) {
bool GWrapper::DecryptFile(
const std::string& filename_in,
const std::string& filename_out,
const Key& key,
bool printProgressReport)
{
try {
// Read the file to bits
const Flexblock ciphertext_bits = ReadFileToBits(filename_in);
// Transform the password to a key
const Block key = PasswordToKey(password);
// Decrypt the ciphertext bits
const Flexblock cleartext_bits = CipherFlexblock(ciphertext_bits, key, GCipher::DIRECTION::DECIPHER);
@@ -82,7 +86,7 @@ namespace Leonetienne::GCrypt {
Flexblock GWrapper::CipherFlexblock(
const Flexblock& data,
const Block& key,
const Key& key,
const GCipher::DIRECTION direction)
{
// Split input into blocks

22
GCryptLib/src/Key.cpp Normal file
View File

@@ -0,0 +1,22 @@
#include "GCrypt/Key.h"
#include "GCrypt/GHash.h"
#include "GCrypt/Util.h"
namespace Leonetienne::GCrypt {
Key Key::FromPassword(const std::string& password) {
return GHash::CalculateHashsum(
StringToBits(password)
);
}
Key::Key() : Block() {
}
Key::Key(const Block& b) : Block(b) {
}
Key::Key(const Key& k) : Block(k) {
}
}

View File

@@ -2,12 +2,5 @@
#include "GCrypt/GHash.h"
namespace Leonetienne::GCrypt {
Block PasswordToKey(const std::string& in) {
// We already have a hashing algorithm, so why not use it
// Yeah, this won't work, because it would create an include loop. This method needs to be outsourced to a cpp file..
const Block hashedPassword = GHash::CalculateHashsum(StringToBits(in));
return hashedPassword;
}
}