Made bit-tuple substitutions use std::maps to reduce timing attack vulnerability

This commit is contained in:
Leonetienne 2021-12-15 20:13:40 +01:00
parent 3750e96a5f
commit 4731a409e3
4 changed files with 144 additions and 120 deletions

View File

@ -1,3 +1,4 @@
#include <unordered_map>
#include "Feistel.h"
#include "Util.h"
#include "Config.h"
@ -105,16 +106,17 @@ GhettoCipher::Block GhettoCipher::Feistel::ExpansionFunction(const Halfblock& bl
std::stringstream ss;
const std::string bits = block.to_string();
std::unordered_map<std::string, std::string> expansionMap;
expansionMap["00"] = "1101";
expansionMap["01"] = "1000";
expansionMap["10"] = "0010";
expansionMap["11"] = "0111";
// We have to double the bits!
for (std::size_t i = 0; i < bits.size(); i += 2)
{
const std::string sub = bits.substr(i, 2);
if (sub == "00") ss << "1101";
else if (sub == "01") ss << "1000";
else if (sub == "10") ss << "0010";
else if (sub == "11") ss << "0111";
ss << expansionMap[sub];
}
return Block(ss.str());
@ -125,27 +127,29 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block&
std::stringstream ss;
const std::string bits = block.to_string();
std::unordered_map<std::string, std::string> compressionMap;
compressionMap["0000"] = "10";
compressionMap["0001"] = "01";
compressionMap["0010"] = "10";
compressionMap["0011"] = "10";
compressionMap["0100"] = "11";
compressionMap["0101"] = "01";
compressionMap["0110"] = "00";
compressionMap["0111"] = "11";
compressionMap["1000"] = "01";
compressionMap["1001"] = "00";
compressionMap["1010"] = "11";
compressionMap["1011"] = "00";
compressionMap["1100"] = "11";
compressionMap["1101"] = "10";
compressionMap["1110"] = "00";
compressionMap["1111"] = "01";
// We have to half the bits!
for (std::size_t i = 0; i < bits.size(); i += 4)
{
const std::string sub = bits.substr(i, 4);
if (sub == "0000") ss << "10";
else if (sub == "0001") ss << "01";
else if (sub == "0010") ss << "10";
else if (sub == "0011") ss << "10";
else if (sub == "0100") ss << "11";
else if (sub == "0101") ss << "01";
else if (sub == "0110") ss << "00";
else if (sub == "0111") ss << "11";
else if (sub == "1000") ss << "01";
else if (sub == "1001") ss << "00";
else if (sub == "1010") ss << "11";
else if (sub == "1011") ss << "00";
else if (sub == "1100") ss << "11";
else if (sub == "1101") ss << "10";
else if (sub == "1110") ss << "00";
else if (sub == "1111") ss << "01";
ss << compressionMap[sub];
}
return Halfblock(ss.str());
@ -153,22 +157,30 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block&
std::string GhettoCipher::Feistel::SBox(const std::string& in)
{
if (in == "0000") return "1100";
else if (in == "0001") return "1000";
else if (in == "0010") return "0001";
else if (in == "0011") return "0111";
else if (in == "0100") return "1011";
else if (in == "0101") return "0011";
else if (in == "0110") return "1101";
else if (in == "0111") return "1111";
else if (in == "1000") return "0000";
else if (in == "1001") return "1010";
else if (in == "1010") return "0100";
else if (in == "1011") return "1001";
else if (in == "1100") return "0010";
else if (in == "1101") return "1110";
else if (in == "1110") return "0101";
else /*if (in == "1111")*/ return "0110";
static std::unordered_map<std::string, std::string> subMap;
static bool mapInitialized = false;
if (!mapInitialized)
{
subMap["0000"] = "1100";
subMap["0001"] = "1000";
subMap["0010"] = "0001";
subMap["0011"] = "0111";
subMap["0100"] = "1011";
subMap["0101"] = "0011";
subMap["0110"] = "1101";
subMap["0111"] = "1111";
subMap["1000"] = "0000";
subMap["1001"] = "1010";
subMap["1010"] = "0100";
subMap["1011"] = "1001";
subMap["1100"] = "0010";
subMap["1101"] = "1110";
subMap["1110"] = "0101";
subMap["1111"] = "0110";
mapInitialized = true;
}
return subMap[in];
}
void GhettoCipher::Feistel::GenerateRoundKeys(const Block& seedKey)

View File

@ -1,2 +1,2 @@
#pragma once
#define GHETTOCRYPT_VERSION 0.12
#define GHETTOCRYPT_VERSION 0.13

View File

@ -165,6 +165,7 @@ const GhettoCipher::Block GhettoCipher::Cipher::emptyBlock;
/*** ./../GhettoCrypt/Feistel.cpp ***/
#include <unordered_map>
GhettoCipher::Feistel::Feistel(const Block& key)
{
@ -269,16 +270,17 @@ GhettoCipher::Block GhettoCipher::Feistel::ExpansionFunction(const Halfblock& bl
std::stringstream ss;
const std::string bits = block.to_string();
std::unordered_map<std::string, std::string> expansionMap;
expansionMap["00"] = "1101";
expansionMap["01"] = "1000";
expansionMap["10"] = "0010";
expansionMap["11"] = "0111";
// We have to double the bits!
for (std::size_t i = 0; i < bits.size(); i += 2)
{
const std::string sub = bits.substr(i, 2);
if (sub == "00") ss << "1101";
else if (sub == "01") ss << "1000";
else if (sub == "10") ss << "0010";
else if (sub == "11") ss << "0111";
ss << expansionMap[sub];
}
return Block(ss.str());
@ -289,27 +291,29 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block&
std::stringstream ss;
const std::string bits = block.to_string();
std::unordered_map<std::string, std::string> compressionMap;
compressionMap["0000"] = "10";
compressionMap["0001"] = "01";
compressionMap["0010"] = "10";
compressionMap["0011"] = "10";
compressionMap["0100"] = "11";
compressionMap["0101"] = "01";
compressionMap["0110"] = "00";
compressionMap["0111"] = "11";
compressionMap["1000"] = "01";
compressionMap["1001"] = "00";
compressionMap["1010"] = "11";
compressionMap["1011"] = "00";
compressionMap["1100"] = "11";
compressionMap["1101"] = "10";
compressionMap["1110"] = "00";
compressionMap["1111"] = "01";
// We have to half the bits!
for (std::size_t i = 0; i < bits.size(); i += 4)
{
const std::string sub = bits.substr(i, 4);
if (sub == "0000") ss << "10";
else if (sub == "0001") ss << "01";
else if (sub == "0010") ss << "10";
else if (sub == "0011") ss << "10";
else if (sub == "0100") ss << "11";
else if (sub == "0101") ss << "01";
else if (sub == "0110") ss << "00";
else if (sub == "0111") ss << "11";
else if (sub == "1000") ss << "01";
else if (sub == "1001") ss << "00";
else if (sub == "1010") ss << "11";
else if (sub == "1011") ss << "00";
else if (sub == "1100") ss << "11";
else if (sub == "1101") ss << "10";
else if (sub == "1110") ss << "00";
else if (sub == "1111") ss << "01";
ss << compressionMap[sub];
}
return Halfblock(ss.str());
@ -317,22 +321,30 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block&
std::string GhettoCipher::Feistel::SBox(const std::string& in)
{
if (in == "0000") return "1100";
else if (in == "0001") return "1000";
else if (in == "0010") return "0001";
else if (in == "0011") return "0111";
else if (in == "0100") return "1011";
else if (in == "0101") return "0011";
else if (in == "0110") return "1101";
else if (in == "0111") return "1111";
else if (in == "1000") return "0000";
else if (in == "1001") return "1010";
else if (in == "1010") return "0100";
else if (in == "1011") return "1001";
else if (in == "1100") return "0010";
else if (in == "1101") return "1110";
else if (in == "1110") return "0101";
else /*if (in == "1111")*/ return "0110";
static std::unordered_map<std::string, std::string> subMap;
static bool mapInitialized = false;
if (!mapInitialized)
{
subMap["0000"] = "1100";
subMap["0001"] = "1000";
subMap["0010"] = "0001";
subMap["0011"] = "0111";
subMap["0100"] = "1011";
subMap["0101"] = "0011";
subMap["0110"] = "1101";
subMap["0111"] = "1111";
subMap["1000"] = "0000";
subMap["1001"] = "1010";
subMap["1010"] = "0100";
subMap["1011"] = "1001";
subMap["1100"] = "0010";
subMap["1101"] = "1110";
subMap["1110"] = "0101";
subMap["1111"] = "0110";
mapInitialized = true;
}
return subMap[in];
}
void GhettoCipher::Feistel::GenerateRoundKeys(const Block& seedKey)

View File

@ -28,6 +28,11 @@
#pragma once
/*** ./../GhettoCrypt/Version.h ***/
#pragma once
#define GHETTOCRYPT_VERSION 0.13
/*** ./../GhettoCrypt/Flexblock.h ***/
#pragma once
@ -39,11 +44,6 @@ namespace GhettoCipher
typedef std::string Flexblock;
}
/*** ./../GhettoCrypt/Version.h ***/
#pragma once
#define GHETTOCRYPT_VERSION 0.12
/*** ./../GhettoCrypt/Config.h ***/
#pragma once
@ -652,6 +652,42 @@ namespace GhettoCipher
}
}
/*** ./../GhettoCrypt/GhettoCryptWrapper.h ***/
#pragma once
#include <string>
namespace GhettoCipher
{
/** This class is a wrapper to make working with the GhettoCipher super easy with a python-like syntax
*/
class GhettoCryptWrapper
{
public:
//! Will encrypt a string and return it hexadecimally encoded.
static std::string EncryptString(const std::string& cleartext, const std::string& password);
//! Will decrypt a hexadecimally encoded string.
static std::string DecryptString(const std::string& ciphertext, const std::string& password);
//! Will encrypt a file.
//! Returns false if anything goes wrong (like, file-access).
//! @filename_in The file to be read.
//! @filename_out The file the encrypted version should be saved in.
static bool EncryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport = false);
//! Will decrypt a file.
//! Returns false if anything goes wrong (like, file-access).
//! @filename_in The file to be read.
//! @filename_out The file the decrypted version should be saved in.
static bool DecryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport = false);
private:
// No instanciation! >:(
GhettoCryptWrapper();
};
}
/*** ./../GhettoCrypt/Keyset.h ***/
#pragma once
@ -733,42 +769,6 @@ namespace GhettoCipher
};
}
/*** ./../GhettoCrypt/GhettoCryptWrapper.h ***/
#pragma once
#include <string>
namespace GhettoCipher
{
/** This class is a wrapper to make working with the GhettoCipher super easy with a python-like syntax
*/
class GhettoCryptWrapper
{
public:
//! Will encrypt a string and return it hexadecimally encoded.
static std::string EncryptString(const std::string& cleartext, const std::string& password);
//! Will decrypt a hexadecimally encoded string.
static std::string DecryptString(const std::string& ciphertext, const std::string& password);
//! Will encrypt a file.
//! Returns false if anything goes wrong (like, file-access).
//! @filename_in The file to be read.
//! @filename_out The file the encrypted version should be saved in.
static bool EncryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport = false);
//! Will decrypt a file.
//! Returns false if anything goes wrong (like, file-access).
//! @filename_in The file to be read.
//! @filename_out The file the decrypted version should be saved in.
static bool DecryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport = false);
private:
// No instanciation! >:(
GhettoCryptWrapper();
};
}
/*** ./../GhettoCrypt/Cipher.h ***/
#pragma once