Implemented a key class
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
@@ -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"));
|
||||
|
@@ -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
22
GCryptLib/src/Key.cpp
Normal 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) {
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user