From 70425d94ef329453642431d08dc9af5681ea8e7c Mon Sep 17 00:00:00 2001 From: Leonetienne Date: Mon, 6 Dec 2021 02:20:47 +0100 Subject: [PATCH] Namespacified --- Block.h | 5 +- GhettoCipher.cpp => Cipher.cpp | 20 +- Cipher.h | 41 +++ Config.h | 7 +- Feistel.cpp | 32 +-- Feistel.h | 75 +++--- Feistel.vcxproj | 5 +- Feistel.vcxproj.filters | 11 +- Flexblock.h | 7 +- GhettoCipher.h | 38 --- GhettoCipherWrapper.cpp | 18 +- GhettoCipherWrapper.h | 47 ++-- Halfblock.h | 8 +- Keyset.h | 5 +- Util.h | 449 +++++++++++++++++---------------- Version.h | 2 + main.cpp | 10 +- 17 files changed, 407 insertions(+), 373 deletions(-) rename GhettoCipher.cpp => Cipher.cpp (77%) create mode 100644 Cipher.h delete mode 100644 GhettoCipher.h create mode 100644 Version.h diff --git a/Block.h b/Block.h index eadcd10..100f338 100644 --- a/Block.h +++ b/Block.h @@ -2,4 +2,7 @@ #include #include "Config.h" -typedef std::bitset Block; +namespace GhettoCipher +{ + typedef std::bitset Block; +} diff --git a/GhettoCipher.cpp b/Cipher.cpp similarity index 77% rename from GhettoCipher.cpp rename to Cipher.cpp index b79317d..27a32dd 100644 --- a/GhettoCipher.cpp +++ b/Cipher.cpp @@ -1,8 +1,8 @@ -#include "GhettoCipher.h" +#include "Cipher.h" #include "Util.h" #include -GhettoCipher::GhettoCipher(const Block& key) +GhettoCipher::Cipher::Cipher(const Block& key) : key { key } { @@ -10,14 +10,14 @@ GhettoCipher::GhettoCipher(const Block& key) return; } -GhettoCipher::GhettoCipher(const std::string& password) +GhettoCipher::Cipher::Cipher(const std::string& password) { key = PasswordToKey(password); return; } -GhettoCipher::~GhettoCipher() +GhettoCipher::Cipher::~Cipher() { // Clear key memory ZeroKeyMemory(); @@ -25,7 +25,7 @@ GhettoCipher::~GhettoCipher() return; } -void GhettoCipher::SetKey(const Block& key) +void GhettoCipher::Cipher::SetKey(const Block& key) { ZeroKeyMemory(); @@ -33,7 +33,7 @@ void GhettoCipher::SetKey(const Block& key) return; } -void GhettoCipher::SetPassword(const std::string& password) +void GhettoCipher::Cipher::SetPassword(const std::string& password) { ZeroKeyMemory(); @@ -41,7 +41,7 @@ void GhettoCipher::SetPassword(const std::string& password) return; } -Flexblock GhettoCipher::Encipher(const Flexblock& data, bool printProgress) const +GhettoCipher::Flexblock GhettoCipher::Cipher::Encipher(const Flexblock& data, bool printProgress) const { // Split cleartext into blocks std::vector blocks; @@ -73,7 +73,7 @@ Flexblock GhettoCipher::Encipher(const Flexblock& data, bool printProgress) cons return ss.str(); } -Flexblock GhettoCipher::Decipher(const Flexblock& data, bool printProgress) const +GhettoCipher::Flexblock GhettoCipher::Cipher::Decipher(const Flexblock& data, bool printProgress) const { // Split ciphertext into blocks std::vector blocks; @@ -112,11 +112,11 @@ Flexblock GhettoCipher::Decipher(const Flexblock& data, bool printProgress) cons } #pragma optimize("", off ) -void GhettoCipher::ZeroKeyMemory() +void GhettoCipher::Cipher::ZeroKeyMemory() { key.reset(); return; } #pragma optimize("", on ) -const Block GhettoCipher::emptyBlock; +const GhettoCipher::Block GhettoCipher::Cipher::emptyBlock; diff --git a/Cipher.h b/Cipher.h new file mode 100644 index 0000000..8db9cc9 --- /dev/null +++ b/Cipher.h @@ -0,0 +1,41 @@ +#pragma once +#include "Feistel.h" +#include "Flexblock.h" + +namespace GhettoCipher +{ + /** Class to apply a block cipher to messages of arbitrary length in a distributed manner + */ + class Cipher + { + public: + explicit Cipher(const Block& key); + explicit Cipher(const std::string& password); + + Cipher(const Cipher& other) = delete; + Cipher(Cipher&& other) noexcept = delete; + + ~Cipher(); + + //! Will set the key + void SetKey(const Block& key); + + //! Will set the key from a password + void SetPassword(const std::string& password); + + //! Will encipher a flexblock of data + Flexblock Encipher(const Flexblock& data, bool printProgress = false) const; + + //! Will decipher a flexblock of data + Flexblock Decipher(const Flexblock& data, bool printProgress = false) const; + + private: + Block key; + + //! Will zero the memory used by the key + void ZeroKeyMemory(); + + // Initial value for cipher block chaining + static const Block emptyBlock; + }; +} diff --git a/Config.h b/Config.h index db98223..8798a53 100644 --- a/Config.h +++ b/Config.h @@ -1,4 +1,7 @@ #pragma once -#define BLOCK_SIZE 128 -#define N_ROUNDS 64 +namespace GhettoCipher +{ + constexpr int BLOCK_SIZE = 128; + constexpr int N_ROUNDS = 64; +} diff --git a/Feistel.cpp b/Feistel.cpp index ab825ec..1ecd2b7 100644 --- a/Feistel.cpp +++ b/Feistel.cpp @@ -2,40 +2,40 @@ #include "Util.h" #include "Config.h" -Feistel::Feistel(const Block& key) +GhettoCipher::Feistel::Feistel(const Block& key) { SetKey(key); return; } -Feistel::~Feistel() +GhettoCipher::Feistel::~Feistel() { ZeroKeyMemory(); return; } -void Feistel::SetKey(const Block& key) +void GhettoCipher::Feistel::SetKey(const Block& key) { GenerateRoundKeys(key); return; } -Block Feistel::Encipher(const Block& data) const +GhettoCipher::Block GhettoCipher::Feistel::Encipher(const Block& data) const { return Run(data, false); } -Block Feistel::Decipher(const Block& data) const +GhettoCipher::Block GhettoCipher::Feistel::Decipher(const Block& data) const { return Run(data, true); } -Block Feistel::Run(const Block& data, bool reverseKeys) const +GhettoCipher::Block GhettoCipher::Feistel::Run(const Block& data, bool reverseKeys) const { const auto splitData = FeistelSplit(data); - Halfblock l = splitData.first; - Halfblock r = splitData.second; + GhettoCipher::Halfblock l = splitData.first; + GhettoCipher::Halfblock r = splitData.second; Halfblock tmp; @@ -57,7 +57,7 @@ Block Feistel::Run(const Block& data, bool reverseKeys) const return FeistelCombine(r, l); } -Halfblock Feistel::F(Halfblock m, const Block& key) +GhettoCipher::Halfblock GhettoCipher::Feistel::F(Halfblock m, const Block& key) { // Made-up F function @@ -85,7 +85,7 @@ Halfblock Feistel::F(Halfblock m, const Block& key) return CompressionFunction(m_expanded); } -std::pair Feistel::FeistelSplit(const Block& block) +std::pair GhettoCipher::Feistel::FeistelSplit(const Block& block) { const std::string bits = block.to_string(); @@ -95,12 +95,12 @@ std::pair Feistel::FeistelSplit(const Block& block) return std::make_pair(l, r); } -Block Feistel::FeistelCombine(const Halfblock& l, const Halfblock& r) +GhettoCipher::Block GhettoCipher::Feistel::FeistelCombine(const Halfblock& l, const Halfblock& r) { return Block(l.to_string() + r.to_string()); } -Block Feistel::ExpansionFunction(const Halfblock& block) +GhettoCipher::Block GhettoCipher::Feistel::ExpansionFunction(const Halfblock& block) { std::stringstream ss; const std::string bits = block.to_string(); @@ -120,7 +120,7 @@ Block Feistel::ExpansionFunction(const Halfblock& block) return Block(ss.str()); } -Halfblock Feistel::CompressionFunction(const Block& block) +GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block& block) { std::stringstream ss; const std::string bits = block.to_string(); @@ -151,7 +151,7 @@ Halfblock Feistel::CompressionFunction(const Block& block) return Halfblock(ss.str()); } -std::string Feistel::SBox(const std::string& in) +std::string GhettoCipher::Feistel::SBox(const std::string& in) { if (in == "0000") return "1100"; else if (in == "0001") return "1000"; @@ -171,7 +171,7 @@ std::string Feistel::SBox(const std::string& in) else /*if (in == "1111")*/ return "0110"; } -void Feistel::GenerateRoundKeys(const Block& seedKey) +void GhettoCipher::Feistel::GenerateRoundKeys(const Block& seedKey) { // Generate round keys via output feedback modus (OFM) method @@ -193,7 +193,7 @@ void Feistel::GenerateRoundKeys(const Block& seedKey) // These pragmas only work for MSVC, as far as i know. Beware!!! #pragma optimize("", off ) -void Feistel::ZeroKeyMemory() +void GhettoCipher::Feistel::ZeroKeyMemory() { for (Block& key : roundKeys) key.reset(); diff --git a/Feistel.h b/Feistel.h index d133131..2dbc297 100644 --- a/Feistel.h +++ b/Feistel.h @@ -3,55 +3,58 @@ #include "Block.h" #include "Halfblock.h" -/** Class to perform a feistel block chipher -*/ -class Feistel +namespace GhettoCipher { -public: - explicit Feistel(const Block& key); + /** Class to perform a feistel block chipher + */ + class Feistel + { + public: + explicit Feistel(const Block& key); - Feistel(const Feistel& other) = delete; - Feistel(Feistel&& other) noexcept = delete; + Feistel(const Feistel& other) = delete; + Feistel(Feistel&& other) noexcept = delete; - ~Feistel(); + ~Feistel(); - //! Will set the seed-key for this feistel network. - //! Roundkeys will be derived from this. - void SetKey(const Block& key); + //! Will set the seed-key for this feistel network. + //! Roundkeys will be derived from this. + void SetKey(const Block& key); - //! Will encipher a data block via the set seed-key - Block Encipher(const Block& data) const; + //! Will encipher a data block via the set seed-key + Block Encipher(const Block& data) const; - //! Will decipher a data block via the set seed-key - Block Decipher(const Block& data) const; + //! Will decipher a data block via the set seed-key + Block Decipher(const Block& data) const; -private: - //! Will run the feistel rounds, with either regular key order or reversed key order - Block Run(const Block& data, bool reverseKeys) const; + private: + //! Will run the feistel rounds, with either regular key order or reversed key order + Block Run(const Block& data, bool reverseKeys) const; - //! Arbitrary cipher function - static Halfblock F(Halfblock m, const Block& key); + //! Arbitrary cipher function + static Halfblock F(Halfblock m, const Block& key); - //! Split a data block into two half blocks (into L and R) - static std::pair FeistelSplit(const Block& block); + //! Split a data block into two half blocks (into L and R) + static std::pair FeistelSplit(const Block& block); - //! Combine two half blocks (L and R) into a regular data block - static Block FeistelCombine(const Halfblock& l, const Halfblock& r); + //! Combine two half blocks (L and R) into a regular data block + static Block FeistelCombine(const Halfblock& l, const Halfblock& r); - //! Will expand a halfblock to a fullblock - static Block ExpansionFunction(const Halfblock& block); + //! Will expand a halfblock to a fullblock + static Block ExpansionFunction(const Halfblock& block); - //! Will compress a fullblock to a halfblock - static Halfblock CompressionFunction(const Block& block); + //! Will compress a fullblock to a halfblock + static Halfblock CompressionFunction(const Block& block); - //! Substitutes four bits by static random others - static std::string SBox(const std::string& in); + //! Substitutes four bits by static random others + static std::string SBox(const std::string& in); - //! Will generate a the round keys - void GenerateRoundKeys(const Block& seedKey); + //! Will generate a the round keys + void GenerateRoundKeys(const Block& seedKey); - //! Will zero the memory used by the keyset - void ZeroKeyMemory(); + //! Will zero the memory used by the keyset + void ZeroKeyMemory(); - Keyset roundKeys; -}; + Keyset roundKeys; + }; +} diff --git a/Feistel.vcxproj b/Feistel.vcxproj index 6b61143..cc94d20 100644 --- a/Feistel.vcxproj +++ b/Feistel.vcxproj @@ -141,7 +141,7 @@ - + @@ -149,11 +149,12 @@ - + + diff --git a/Feistel.vcxproj.filters b/Feistel.vcxproj.filters index 12ea42d..a2b2106 100644 --- a/Feistel.vcxproj.filters +++ b/Feistel.vcxproj.filters @@ -21,10 +21,10 @@ Quelldateien - + Quelldateien - + Quelldateien @@ -50,10 +50,13 @@ Headerdateien - + Headerdateien - + + Headerdateien + + Headerdateien diff --git a/Flexblock.h b/Flexblock.h index 66c75e0..c2b0280 100644 --- a/Flexblock.h +++ b/Flexblock.h @@ -1,5 +1,8 @@ #pragma once #include -//! A "bitset" of variable length -typedef std::string Flexblock; +namespace GhettoCipher +{ + //! A "bitset" of variable length + typedef std::string Flexblock; +} diff --git a/GhettoCipher.h b/GhettoCipher.h deleted file mode 100644 index 8c99a52..0000000 --- a/GhettoCipher.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include "Feistel.h" -#include "Flexblock.h" - -/** Class to apply a block cipher to messages of arbitrary length in a distributed manner -*/ -class GhettoCipher -{ -public: - explicit GhettoCipher(const Block& key); - explicit GhettoCipher(const std::string& password); - - GhettoCipher(const GhettoCipher& other) = delete; - GhettoCipher(GhettoCipher&& other) noexcept = delete; - - ~GhettoCipher(); - - //! Will set the key - void SetKey(const Block& key); - - //! Will set the key from a password - void SetPassword(const std::string& password); - - //! Will encipher a flexblock of data - Flexblock Encipher(const Flexblock& data, bool printProgress = false) const; - - //! Will decipher a flexblock of data - Flexblock Decipher(const Flexblock& data, bool printProgress = false) const; - -private: - Block key; - - //! Will zero the memory used by the key - void ZeroKeyMemory(); - - // Initial value for cipher block chaining - static const Block emptyBlock; -}; diff --git a/GhettoCipherWrapper.cpp b/GhettoCipherWrapper.cpp index 2aeee23..b40e6c2 100644 --- a/GhettoCipherWrapper.cpp +++ b/GhettoCipherWrapper.cpp @@ -1,11 +1,11 @@ #include "GhettoCipherWrapper.h" -#include "GhettoCipher.h" +#include "Cipher.h" #include "Util.h" -std::string GhettoCipherWrapper::EncryptString(const std::string& cleartext, const std::string& password) +std::string GhettoCipher::GhettoCryptWrapper::EncryptString(const std::string& cleartext, const std::string& password) { // Instanciate our cipher and supply a key - GhettoCipher cipher(password); + Cipher cipher(password); // Recode the ascii-string to bits const Flexblock cleartext_bits = StringToBits(cleartext); @@ -20,10 +20,10 @@ std::string GhettoCipherWrapper::EncryptString(const std::string& cleartext, con return ciphertext; } -std::string GhettoCipherWrapper::DecryptString(const std::string& ciphertext, const std::string& password) +std::string GhettoCipher::GhettoCryptWrapper::DecryptString(const std::string& ciphertext, const std::string& password) { // Instanciate our cipher and supply a key - GhettoCipher cipher(password); + Cipher cipher(password); // Recode the hex-string to bits const Flexblock ciphertext_bits = HexstringToBits(ciphertext); @@ -38,7 +38,7 @@ std::string GhettoCipherWrapper::DecryptString(const std::string& ciphertext, co return cleartext; } -bool GhettoCipherWrapper::EncryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password) +bool GhettoCipher::GhettoCryptWrapper::EncryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password) { try { @@ -46,7 +46,7 @@ bool GhettoCipherWrapper::EncryptFile(const std::string& filename_in, const std: const Flexblock cleartext_bits = ReadFileToBits(filename_in); // Instanciate our cipher and supply a key - GhettoCipher cipher(password); + Cipher cipher(password); // Encrypt our cleartext bits const Flexblock ciphertext_bits = cipher.Encipher(cleartext_bits); @@ -62,7 +62,7 @@ bool GhettoCipherWrapper::EncryptFile(const std::string& filename_in, const std: } } -bool GhettoCipherWrapper::DecryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password) +bool GhettoCipher::GhettoCryptWrapper::DecryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password) { try { @@ -70,7 +70,7 @@ bool GhettoCipherWrapper::DecryptFile(const std::string& filename_in, const std: const Flexblock ciphertext_bits = ReadFileToBits(filename_in); // Instanciate our cipher and supply a key - GhettoCipher cipher(password); + Cipher cipher(password); // Decrypt the ciphertext bits const Flexblock cleartext_bits = cipher.Decipher(ciphertext_bits); diff --git a/GhettoCipherWrapper.h b/GhettoCipherWrapper.h index 79b4824..430564f 100644 --- a/GhettoCipherWrapper.h +++ b/GhettoCipherWrapper.h @@ -1,30 +1,33 @@ #pragma once #include -/** This class is a wrapper to make working with the GhettoCipher super easy with a python-like syntax -*/ -class GhettoCipherWrapper +namespace GhettoCipher { -public: - //! Will encrypt a string and return it hexadecimally encoded. - static std::string EncryptString(const std::string& cleartext, const std::string& password); + /** 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 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); + //! 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); - //! 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); + //! 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); -private: - // No instanciation! >:( - GhettoCipherWrapper(); -}; + private: + // No instanciation! >:( + GhettoCryptWrapper(); + }; +} diff --git a/Halfblock.h b/Halfblock.h index fbd2bd8..f11151b 100644 --- a/Halfblock.h +++ b/Halfblock.h @@ -2,6 +2,8 @@ #include #include "Config.h" -#define HALFBLOCK_SIZE (BLOCK_SIZE / 2) - -typedef std::bitset Halfblock; +namespace GhettoCipher +{ + constexpr int HALFBLOCK_SIZE = (BLOCK_SIZE / 2); + typedef std::bitset Halfblock; +} diff --git a/Keyset.h b/Keyset.h index 19a9b11..0cd1f43 100644 --- a/Keyset.h +++ b/Keyset.h @@ -3,4 +3,7 @@ #include "Block.h" #include "Config.h" -typedef std::array Keyset; +namespace GhettoCipher +{ + typedef std::array Keyset; +} diff --git a/Util.h b/Util.h index ca0db72..e125596 100644 --- a/Util.h +++ b/Util.h @@ -5,248 +5,251 @@ #include "Block.h" #include "Flexblock.h" -//! Mod-operator that works with negative values -inline int Mod(int numerator, int denominator) +namespace GhettoCipher { - return (denominator + (numerator % denominator)) % denominator; -} - -//! Will perform a wrapping left-bitshift on a bitset -template -inline std::bitset Shiftl(const std::bitset& bits, std::size_t amount) -{ - std::stringstream ss; - const std::string bitss = bits.to_string(); - - for (std::size_t i = 0; i < bitss.size(); i++) - ss << bitss[Mod((i + amount), bitss.size())]; - - return std::bitset(ss.str()); -} - -//! Will perform a wrapping right-bitshift on a bitset -template -inline std::bitset Shiftr(const std::bitset& bits, std::size_t amount) -{ - std::stringstream ss; - const std::string bitss = bits.to_string(); - - for (std::size_t i = 0; i < bitss.size(); i++) - ss << bitss[Mod((i - amount), bitss.size())]; - - return std::bitset(ss.str()); -} - -inline std::string PadStringToLength(const std::string& str, const std::size_t len, const char pad, const bool padLeft = true) -{ - // Fast-reject: Already above padded length - if (str.length() >= len) - return str; - - std::stringstream ss; - - // Pad left: - if (padLeft) + //! Mod-operator that works with negative values + inline int Mod(int numerator, int denominator) { - for (std::size_t i = 0; i < len - str.size(); i++) - ss << pad; - ss << str; - } - // Pad right: - else - { - ss << str; - for (std::size_t i = 0; i < len - str.size(); i++) - ss << pad; + return (denominator + (numerator % denominator)) % denominator; } - return ss.str(); -} - -//! Will convert a string to a fixed data block -inline Block StringToBitblock(const std::string& s) -{ - std::stringstream ss; - - for (std::size_t i = 0; i < s.size(); i++) - ss << std::bitset<8>(s[i]); - - // Pad rest with zeores - return Block(PadStringToLength(ss.str(), 128, '0', false)); -} - -//! Will convert a string to a flexible data block -inline Flexblock StringToBits(const std::string& s) -{ - std::stringstream ss; - - for (std::size_t i = 0; i < s.size(); i++) - ss << std::bitset<8>(s[i]); - - return Flexblock(ss.str()); -} - -//! Will convert a fixed data block to a string -inline std::string BitblockToString(const Block& bits) -{ - std::stringstream ss; - - const std::string bitstring = bits.to_string(); - - for (std::size_t i = 0; i < BLOCK_SIZE; i += 8) + //! Will perform a wrapping left-bitshift on a bitset + template + inline std::bitset Shiftl(const std::bitset& bits, std::size_t amount) { - ss << (char)std::bitset<8>(bitstring.substr(i, 8)).to_ulong(); + std::stringstream ss; + const std::string bitss = bits.to_string(); + + for (std::size_t i = 0; i < bitss.size(); i++) + ss << bitss[Mod((i + amount), bitss.size())]; + + return std::bitset(ss.str()); } - return ss.str(); -} - -//! Will convert a flexible data block to a string -inline std::string BitsToString(const Flexblock& bits) -{ - std::stringstream ss; - - const std::string bitstring = bits; - - for (std::size_t i = 0; i < bits.size(); i += 8) + //! Will perform a wrapping right-bitshift on a bitset + template + inline std::bitset Shiftr(const std::bitset& bits, std::size_t amount) { - ss << (char)std::bitset<8>(bitstring.substr(i, 8)).to_ulong(); + std::stringstream ss; + const std::string bitss = bits.to_string(); + + for (std::size_t i = 0; i < bitss.size(); i++) + ss << bitss[Mod((i - amount), bitss.size())]; + + return std::bitset(ss.str()); } - return ss.str(); -} - -//! Turns a fixed data block into a hex-string -inline std::string BitblockToHexstring(const Block& b) -{ - std::stringstream ss; - const std::string charset = "0123456789abcdef"; - const std::string bstr = b.to_string(); - - for (std::size_t i = 0; i < bstr.size(); i += 4) - ss << charset[std::bitset<4>(bstr.substr(i, 4)).to_ulong()]; - - return ss.str(); -} - -//! Turns a flexible data block into a hex-string -inline std::string BitsToHexstring(const Flexblock& b) -{ - std::stringstream ss; - const std::string charset = "0123456789abcdef"; - const std::string bstr = b; - - for (std::size_t i = 0; i < bstr.size(); i += 4) - ss << charset[std::bitset<4>(bstr.substr(i, 4)).to_ulong()]; - - return ss.str(); -} - - -//! Turns a hex string into a fixed data block -inline Block HexstringToBitblock(const std::string& hexstring) -{ - std::stringstream ss; - - for (std::size_t i = 0; i < hexstring.size(); i ++) + inline std::string PadStringToLength(const std::string& str, const std::size_t len, const char pad, const bool padLeft = true) { - const char c = hexstring[i]; + // Fast-reject: Already above padded length + if (str.length() >= len) + return str; - // Get value - std::size_t value; - if ((c >= '0') && (c <= '9')) - // Is it a number? - value = (c - '0') + 0; - else if ((c >= 'a') && (c <= 'f')) - // Else, it is a lowercase letter - value = (c - 'a') + 10; + std::stringstream ss; + + // Pad left: + if (padLeft) + { + for (std::size_t i = 0; i < len - str.size(); i++) + ss << pad; + ss << str; + } + // Pad right: else - throw std::logic_error("non-hex string detected in HexstringToBits()"); + { + ss << str; + for (std::size_t i = 0; i < len - str.size(); i++) + ss << pad; + } - // Append to our bits - ss << std::bitset<4>(value); + return ss.str(); } - return Block(ss.str()); -} - -//! Turns a hex string into a flexible data block -inline Flexblock HexstringToBits(const std::string& hexstring) -{ - std::stringstream ss; - - for (std::size_t i = 0; i < hexstring.size(); i++) + //! Will convert a string to a fixed data block + inline Block StringToBitblock(const std::string& s) { - const char c = hexstring[i]; + std::stringstream ss; - // Get value - std::size_t value; - if ((c >= '0') && (c <= '9')) - // Is it a number? - value = (c - '0') + 0; - else if ((c >= 'a') && (c <= 'f')) - // Else, it is a lowercase letter - value = (c - 'a') + 10; - else - throw std::logic_error("non-hex string detected in HexstringToBits()"); + for (std::size_t i = 0; i < s.size(); i++) + ss << std::bitset<8>(s[i]); - // Append to our bits - ss << std::bitset<4>(value); + // Pad rest with zeores + return Block(PadStringToLength(ss.str(), 128, '0', false)); } - return ss.str(); -} - -//! Creates a key of size key-size from a password of arbitrary length. -inline Block PasswordToKey(const std::string& in) -{ - Block b; - - // Segment the password in segments of key-size, and xor them together. - for (std::size_t i = 0; i < in.size(); i += BLOCK_SIZE / 8) - b ^= StringToBitblock(in.substr(i, BLOCK_SIZE / 8)); - - return b; -} - -//! Will read a file into a flexblock -inline Flexblock ReadFileToBits(const std::string& filepath) -{ - // Read file - std::ifstream ifs(filepath, std::ios::binary); - - if (!ifs.good()) - throw std::runtime_error("Unable to open ifilestream!"); - - std::stringstream ss; - std::copy( - std::istreambuf_iterator(ifs), - std::istreambuf_iterator(), - std::ostreambuf_iterator(ss) - ); - - ifs.close(); - - const std::string bytes = ss.str(); - - // Convert bytes to bits - return StringToBits(bytes); -} - -//! Will save bits to a binary file -inline void WriteBitsToFile(const std::string& filepath, const Flexblock& bits) -{ - // Convert bits to bytes - const std::string bytes = BitsToString(bits); - - // Write bits to file - std::ofstream ofs(filepath, std::ios::binary); - - if (!ofs.good()) - throw std::runtime_error("Unable to open ofilestream!"); - - ofs.write(bytes.data(), bytes.length()); - ofs.close(); - - return; + //! Will convert a string to a flexible data block + inline Flexblock StringToBits(const std::string& s) + { + std::stringstream ss; + + for (std::size_t i = 0; i < s.size(); i++) + ss << std::bitset<8>(s[i]); + + return Flexblock(ss.str()); + } + + //! Will convert a fixed data block to a string + inline std::string BitblockToString(const Block& bits) + { + std::stringstream ss; + + const std::string bitstring = bits.to_string(); + + for (std::size_t i = 0; i < BLOCK_SIZE; i += 8) + { + ss << (char)std::bitset<8>(bitstring.substr(i, 8)).to_ulong(); + } + + return ss.str(); + } + + //! Will convert a flexible data block to a string + inline std::string BitsToString(const Flexblock& bits) + { + std::stringstream ss; + + const std::string bitstring = bits; + + for (std::size_t i = 0; i < bits.size(); i += 8) + { + ss << (char)std::bitset<8>(bitstring.substr(i, 8)).to_ulong(); + } + + return ss.str(); + } + + //! Turns a fixed data block into a hex-string + inline std::string BitblockToHexstring(const Block& b) + { + std::stringstream ss; + const std::string charset = "0123456789abcdef"; + const std::string bstr = b.to_string(); + + for (std::size_t i = 0; i < bstr.size(); i += 4) + ss << charset[std::bitset<4>(bstr.substr(i, 4)).to_ulong()]; + + return ss.str(); + } + + //! Turns a flexible data block into a hex-string + inline std::string BitsToHexstring(const Flexblock& b) + { + std::stringstream ss; + const std::string charset = "0123456789abcdef"; + const std::string bstr = b; + + for (std::size_t i = 0; i < bstr.size(); i += 4) + ss << charset[std::bitset<4>(bstr.substr(i, 4)).to_ulong()]; + + return ss.str(); + } + + + //! Turns a hex string into a fixed data block + inline Block HexstringToBitblock(const std::string& hexstring) + { + std::stringstream ss; + + for (std::size_t i = 0; i < hexstring.size(); i++) + { + const char c = hexstring[i]; + + // Get value + std::size_t value; + if ((c >= '0') && (c <= '9')) + // Is it a number? + value = (c - '0') + 0; + else if ((c >= 'a') && (c <= 'f')) + // Else, it is a lowercase letter + value = (c - 'a') + 10; + else + throw std::logic_error("non-hex string detected in HexstringToBits()"); + + // Append to our bits + ss << std::bitset<4>(value); + } + + return Block(ss.str()); + } + + //! Turns a hex string into a flexible data block + inline Flexblock HexstringToBits(const std::string& hexstring) + { + std::stringstream ss; + + for (std::size_t i = 0; i < hexstring.size(); i++) + { + const char c = hexstring[i]; + + // Get value + std::size_t value; + if ((c >= '0') && (c <= '9')) + // Is it a number? + value = (c - '0') + 0; + else if ((c >= 'a') && (c <= 'f')) + // Else, it is a lowercase letter + value = (c - 'a') + 10; + else + throw std::logic_error("non-hex string detected in HexstringToBits()"); + + // Append to our bits + ss << std::bitset<4>(value); + } + + return ss.str(); + } + + //! Creates a key of size key-size from a password of arbitrary length. + inline Block PasswordToKey(const std::string& in) + { + Block b; + + // Segment the password in segments of key-size, and xor them together. + for (std::size_t i = 0; i < in.size(); i += BLOCK_SIZE / 8) + b ^= StringToBitblock(in.substr(i, BLOCK_SIZE / 8)); + + return b; + } + + //! Will read a file into a flexblock + inline Flexblock ReadFileToBits(const std::string& filepath) + { + // Read file + std::ifstream ifs(filepath, std::ios::binary); + + if (!ifs.good()) + throw std::runtime_error("Unable to open ifilestream!"); + + std::stringstream ss; + std::copy( + std::istreambuf_iterator(ifs), + std::istreambuf_iterator(), + std::ostreambuf_iterator(ss) + ); + + ifs.close(); + + const std::string bytes = ss.str(); + + // Convert bytes to bits + return StringToBits(bytes); + } + + //! Will save bits to a binary file + inline void WriteBitsToFile(const std::string& filepath, const Flexblock& bits) + { + // Convert bits to bytes + const std::string bytes = BitsToString(bits); + + // Write bits to file + std::ofstream ofs(filepath, std::ios::binary); + + if (!ofs.good()) + throw std::runtime_error("Unable to open ofilestream!"); + + ofs.write(bytes.data(), bytes.length()); + ofs.close(); + + return; + } } diff --git a/Version.h b/Version.h new file mode 100644 index 0000000..e606a79 --- /dev/null +++ b/Version.h @@ -0,0 +1,2 @@ +#pragma once +#define GHETTOCRYPT_VERSION 0.1 diff --git a/main.cpp b/main.cpp index c603c80..9c46abf 100644 --- a/main.cpp +++ b/main.cpp @@ -3,6 +3,8 @@ #include "Util.h" #include "GhettoCipherWrapper.h" +using namespace GhettoCipher; + void ExampleString() { std::cout << "Example on how to encrypt & decrypt a string:" << std::endl; @@ -12,11 +14,11 @@ void ExampleString() std::cout << input << std::endl; // Encrypt - const std::string encrypted = GhettoCipherWrapper::EncryptString(input, "password1"); + const std::string encrypted = GhettoCryptWrapper::EncryptString(input, "password1"); std::cout << encrypted << std::endl; // Decrypt - const std::string decrypted = GhettoCipherWrapper::DecryptString(encrypted, "password1"); + const std::string decrypted = GhettoCryptWrapper::DecryptString(encrypted, "password1"); std::cout << decrypted << std::endl; return; @@ -27,10 +29,10 @@ void ExampleFiles() std::cout << "Example on how to encrypt & decrypt any file:" << std::endl; // Encrypt - GhettoCipherWrapper::EncryptFile("main.cpp", "main.cpp.crypt", "password1"); + GhettoCryptWrapper::EncryptFile("main.cpp", "main.cpp.crypt", "password1"); // Decrypt - GhettoCipherWrapper::DecryptFile("main.cpp.crypt", "main.cpp.clear", "password1"); + GhettoCryptWrapper::DecryptFile("main.cpp.crypt", "main.cpp.clear", "password1"); return; }