Made bit-tuple substitutions use std::maps to reduce timing attack vulnerability
This commit is contained in:
parent
3750e96a5f
commit
4731a409e3
@ -1,3 +1,4 @@
|
|||||||
|
#include <unordered_map>
|
||||||
#include "Feistel.h"
|
#include "Feistel.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
@ -105,16 +106,17 @@ GhettoCipher::Block GhettoCipher::Feistel::ExpansionFunction(const Halfblock& bl
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const std::string bits = block.to_string();
|
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!
|
// We have to double the bits!
|
||||||
for (std::size_t i = 0; i < bits.size(); i += 2)
|
for (std::size_t i = 0; i < bits.size(); i += 2)
|
||||||
{
|
{
|
||||||
const std::string sub = bits.substr(i, 2);
|
const std::string sub = bits.substr(i, 2);
|
||||||
|
ss << expansionMap[sub];
|
||||||
if (sub == "00") ss << "1101";
|
|
||||||
else if (sub == "01") ss << "1000";
|
|
||||||
else if (sub == "10") ss << "0010";
|
|
||||||
else if (sub == "11") ss << "0111";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Block(ss.str());
|
return Block(ss.str());
|
||||||
@ -125,27 +127,29 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block&
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const std::string bits = block.to_string();
|
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!
|
// We have to half the bits!
|
||||||
for (std::size_t i = 0; i < bits.size(); i += 4)
|
for (std::size_t i = 0; i < bits.size(); i += 4)
|
||||||
{
|
{
|
||||||
const std::string sub = bits.substr(i, 4);
|
const std::string sub = bits.substr(i, 4);
|
||||||
|
ss << compressionMap[sub];
|
||||||
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";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Halfblock(ss.str());
|
return Halfblock(ss.str());
|
||||||
@ -153,22 +157,30 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block&
|
|||||||
|
|
||||||
std::string GhettoCipher::Feistel::SBox(const std::string& in)
|
std::string GhettoCipher::Feistel::SBox(const std::string& in)
|
||||||
{
|
{
|
||||||
if (in == "0000") return "1100";
|
static std::unordered_map<std::string, std::string> subMap;
|
||||||
else if (in == "0001") return "1000";
|
static bool mapInitialized = false;
|
||||||
else if (in == "0010") return "0001";
|
if (!mapInitialized)
|
||||||
else if (in == "0011") return "0111";
|
{
|
||||||
else if (in == "0100") return "1011";
|
subMap["0000"] = "1100";
|
||||||
else if (in == "0101") return "0011";
|
subMap["0001"] = "1000";
|
||||||
else if (in == "0110") return "1101";
|
subMap["0010"] = "0001";
|
||||||
else if (in == "0111") return "1111";
|
subMap["0011"] = "0111";
|
||||||
else if (in == "1000") return "0000";
|
subMap["0100"] = "1011";
|
||||||
else if (in == "1001") return "1010";
|
subMap["0101"] = "0011";
|
||||||
else if (in == "1010") return "0100";
|
subMap["0110"] = "1101";
|
||||||
else if (in == "1011") return "1001";
|
subMap["0111"] = "1111";
|
||||||
else if (in == "1100") return "0010";
|
subMap["1000"] = "0000";
|
||||||
else if (in == "1101") return "1110";
|
subMap["1001"] = "1010";
|
||||||
else if (in == "1110") return "0101";
|
subMap["1010"] = "0100";
|
||||||
else /*if (in == "1111")*/ return "0110";
|
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)
|
void GhettoCipher::Feistel::GenerateRoundKeys(const Block& seedKey)
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#define GHETTOCRYPT_VERSION 0.12
|
#define GHETTOCRYPT_VERSION 0.13
|
||||||
|
@ -165,6 +165,7 @@ const GhettoCipher::Block GhettoCipher::Cipher::emptyBlock;
|
|||||||
|
|
||||||
/*** ./../GhettoCrypt/Feistel.cpp ***/
|
/*** ./../GhettoCrypt/Feistel.cpp ***/
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
GhettoCipher::Feistel::Feistel(const Block& key)
|
GhettoCipher::Feistel::Feistel(const Block& key)
|
||||||
{
|
{
|
||||||
@ -269,16 +270,17 @@ GhettoCipher::Block GhettoCipher::Feistel::ExpansionFunction(const Halfblock& bl
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const std::string bits = block.to_string();
|
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!
|
// We have to double the bits!
|
||||||
for (std::size_t i = 0; i < bits.size(); i += 2)
|
for (std::size_t i = 0; i < bits.size(); i += 2)
|
||||||
{
|
{
|
||||||
const std::string sub = bits.substr(i, 2);
|
const std::string sub = bits.substr(i, 2);
|
||||||
|
ss << expansionMap[sub];
|
||||||
if (sub == "00") ss << "1101";
|
|
||||||
else if (sub == "01") ss << "1000";
|
|
||||||
else if (sub == "10") ss << "0010";
|
|
||||||
else if (sub == "11") ss << "0111";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Block(ss.str());
|
return Block(ss.str());
|
||||||
@ -289,27 +291,29 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block&
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const std::string bits = block.to_string();
|
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!
|
// We have to half the bits!
|
||||||
for (std::size_t i = 0; i < bits.size(); i += 4)
|
for (std::size_t i = 0; i < bits.size(); i += 4)
|
||||||
{
|
{
|
||||||
const std::string sub = bits.substr(i, 4);
|
const std::string sub = bits.substr(i, 4);
|
||||||
|
ss << compressionMap[sub];
|
||||||
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";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Halfblock(ss.str());
|
return Halfblock(ss.str());
|
||||||
@ -317,22 +321,30 @@ GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block&
|
|||||||
|
|
||||||
std::string GhettoCipher::Feistel::SBox(const std::string& in)
|
std::string GhettoCipher::Feistel::SBox(const std::string& in)
|
||||||
{
|
{
|
||||||
if (in == "0000") return "1100";
|
static std::unordered_map<std::string, std::string> subMap;
|
||||||
else if (in == "0001") return "1000";
|
static bool mapInitialized = false;
|
||||||
else if (in == "0010") return "0001";
|
if (!mapInitialized)
|
||||||
else if (in == "0011") return "0111";
|
{
|
||||||
else if (in == "0100") return "1011";
|
subMap["0000"] = "1100";
|
||||||
else if (in == "0101") return "0011";
|
subMap["0001"] = "1000";
|
||||||
else if (in == "0110") return "1101";
|
subMap["0010"] = "0001";
|
||||||
else if (in == "0111") return "1111";
|
subMap["0011"] = "0111";
|
||||||
else if (in == "1000") return "0000";
|
subMap["0100"] = "1011";
|
||||||
else if (in == "1001") return "1010";
|
subMap["0101"] = "0011";
|
||||||
else if (in == "1010") return "0100";
|
subMap["0110"] = "1101";
|
||||||
else if (in == "1011") return "1001";
|
subMap["0111"] = "1111";
|
||||||
else if (in == "1100") return "0010";
|
subMap["1000"] = "0000";
|
||||||
else if (in == "1101") return "1110";
|
subMap["1001"] = "1010";
|
||||||
else if (in == "1110") return "0101";
|
subMap["1010"] = "0100";
|
||||||
else /*if (in == "1111")*/ return "0110";
|
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)
|
void GhettoCipher::Feistel::GenerateRoundKeys(const Block& seedKey)
|
||||||
|
@ -28,6 +28,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
/*** ./../GhettoCrypt/Version.h ***/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define GHETTOCRYPT_VERSION 0.13
|
||||||
|
|
||||||
/*** ./../GhettoCrypt/Flexblock.h ***/
|
/*** ./../GhettoCrypt/Flexblock.h ***/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -39,11 +44,6 @@ namespace GhettoCipher
|
|||||||
typedef std::string Flexblock;
|
typedef std::string Flexblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** ./../GhettoCrypt/Version.h ***/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#define GHETTOCRYPT_VERSION 0.12
|
|
||||||
|
|
||||||
/*** ./../GhettoCrypt/Config.h ***/
|
/*** ./../GhettoCrypt/Config.h ***/
|
||||||
|
|
||||||
#pragma once
|
#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 ***/
|
/*** ./../GhettoCrypt/Keyset.h ***/
|
||||||
|
|
||||||
#pragma once
|
#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 ***/
|
/*** ./../GhettoCrypt/Cipher.h ***/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
Loading…
x
Reference in New Issue
Block a user