diff --git a/GhettoCrypt/exec/main.cpp b/GhettoCrypt/exec/main.cpp index 0ec5d82..28a9fb1 100644 --- a/GhettoCrypt/exec/main.cpp +++ b/GhettoCrypt/exec/main.cpp @@ -4,7 +4,7 @@ #include #include -using namespace GhettoCipher; +using namespace Leonetienne::GCrypt; void ExampleString() { std::cout << "Example on how to encrypt & decrypt a string:" << std::endl; diff --git a/GhettoCrypt/include/Block.h b/GhettoCrypt/include/Block.h index 921a190..053b3bd 100644 --- a/GhettoCrypt/include/Block.h +++ b/GhettoCrypt/include/Block.h @@ -1,8 +1,8 @@ -#pragma once -#include "SecureBitset.h" -#include "Config.h" - -namespace GhettoCipher { - typedef SecureBitset Block; -} - +#pragma once +#include "SecureBitset.h" +#include "Config.h" + +namespace Leonetienne::GCrypt { + typedef SecureBitset Block; +} + diff --git a/GhettoCrypt/include/Cipher.h b/GhettoCrypt/include/Cipher.h index a7fb231..2f38e55 100644 --- a/GhettoCrypt/include/Cipher.h +++ b/GhettoCrypt/include/Cipher.h @@ -1,39 +1,39 @@ -#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 - Block initializationVector; - }; -} +#pragma once +#include "Feistel.h" +#include "Flexblock.h" + +namespace Leonetienne::GCrypt { + /** 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 + Block initializationVector; + }; +} diff --git a/GhettoCrypt/include/Config.h b/GhettoCrypt/include/Config.h index 1f47f3b..0560a19 100644 --- a/GhettoCrypt/include/Config.h +++ b/GhettoCrypt/include/Config.h @@ -1,10 +1,10 @@ -#pragma once -#include - -namespace GhettoCipher { - // MUST BE A POWER OF 2 > 4 - constexpr std::size_t BLOCK_SIZE = 512; - - // MUST BE > 2 - constexpr std::size_t N_ROUNDS = 64; -} +#pragma once +#include + +namespace Leonetienne::GCrypt { + // MUST BE A POWER OF 2 > 4 + constexpr std::size_t BLOCK_SIZE = 512; + + // MUST BE > 2 + constexpr std::size_t N_ROUNDS = 64; +} diff --git a/GhettoCrypt/include/Feistel.h b/GhettoCrypt/include/Feistel.h index 063a890..e205227 100644 --- a/GhettoCrypt/include/Feistel.h +++ b/GhettoCrypt/include/Feistel.h @@ -1,59 +1,59 @@ -#pragma once -#include "Keyset.h" -#include "Block.h" -#include "Halfblock.h" - -namespace GhettoCipher { - /** 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(); - - //! 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); - - //! Will decipher a data block via the set seed-key - Block Decipher(const Block& data); - - private: - //! Will run the feistel rounds, with either regular key - //! order or reversed key order - Block Run(const Block& data, bool reverseKeys); - - //! 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); - - //! 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 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); - - //! Will generate a the round keys - void GenerateRoundKeys(const Block& seedKey); - - //! Will zero the memory used by the keyset - void ZeroKeyMemory(); - - Keyset roundKeys; - }; -} +#pragma once +#include "Keyset.h" +#include "Block.h" +#include "Halfblock.h" + +namespace Leonetienne::GCrypt { + /** 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(); + + //! 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); + + //! Will decipher a data block via the set seed-key + Block Decipher(const Block& data); + + private: + //! Will run the feistel rounds, with either regular key + //! order or reversed key order + Block Run(const Block& data, bool reverseKeys); + + //! 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); + + //! 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 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); + + //! Will generate a the round keys + void GenerateRoundKeys(const Block& seedKey); + + //! Will zero the memory used by the keyset + void ZeroKeyMemory(); + + Keyset roundKeys; + }; +} diff --git a/GhettoCrypt/include/Flexblock.h b/GhettoCrypt/include/Flexblock.h index aa7d733..2873f74 100644 --- a/GhettoCrypt/include/Flexblock.h +++ b/GhettoCrypt/include/Flexblock.h @@ -1,7 +1,7 @@ -#pragma once -#include - -namespace GhettoCipher { - //! A "bitset" of variable length - typedef std::string Flexblock; -} +#pragma once +#include + +namespace Leonetienne::GCrypt { + //! A "bitset" of variable length + typedef std::string Flexblock; +} diff --git a/GhettoCrypt/include/GhettoCryptWrapper.h b/GhettoCrypt/include/GhettoCryptWrapper.h index 363dae8..3490b5d 100644 --- a/GhettoCrypt/include/GhettoCryptWrapper.h +++ b/GhettoCrypt/include/GhettoCryptWrapper.h @@ -1,32 +1,32 @@ -#pragma once -#include - -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(); - }; -} +#pragma once +#include + +namespace Leonetienne::GCrypt { + /** 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(); + }; +} diff --git a/GhettoCrypt/include/Halfblock.h b/GhettoCrypt/include/Halfblock.h index 65f689f..bceafbe 100644 --- a/GhettoCrypt/include/Halfblock.h +++ b/GhettoCrypt/include/Halfblock.h @@ -1,9 +1,9 @@ -#pragma once -#include "SecureBitset.h" -#include -#include "Config.h" - -namespace GhettoCipher { - constexpr std::size_t HALFBLOCK_SIZE = (BLOCK_SIZE / 2); - typedef SecureBitset Halfblock; -} +#pragma once +#include "SecureBitset.h" +#include +#include "Config.h" + +namespace Leonetienne::GCrypt { + constexpr std::size_t HALFBLOCK_SIZE = (BLOCK_SIZE / 2); + typedef SecureBitset Halfblock; +} diff --git a/GhettoCrypt/include/InitializationVector.h b/GhettoCrypt/include/InitializationVector.h index a54f36c..9d216bb 100644 --- a/GhettoCrypt/include/InitializationVector.h +++ b/GhettoCrypt/include/InitializationVector.h @@ -1,17 +1,17 @@ -#pragma once -#include "Config.h" -#include "Block.h" - -namespace GhettoCipher { - /** Will create a sudo-random Block based on a seed - */ - class InitializationVector { - public: - InitializationVector(const GhettoCipher::Block& seed); - - operator GhettoCipher::Block() const; - - private: - GhettoCipher::Block iv; - }; -} +#pragma once +#include "Config.h" +#include "Block.h" + +namespace Leonetienne::GCrypt { + /** Will create a sudo-random Block based on a seed + */ + class InitializationVector { + public: + InitializationVector(const Block& seed); + + operator Block() const; + + private: + Block iv; + }; +} diff --git a/GhettoCrypt/include/Keyset.h b/GhettoCrypt/include/Keyset.h index 25f4b7a..a545dd1 100644 --- a/GhettoCrypt/include/Keyset.h +++ b/GhettoCrypt/include/Keyset.h @@ -1,8 +1,8 @@ -#pragma once -#include -#include "Block.h" -#include "Config.h" - -namespace GhettoCipher { - typedef std::array Keyset; -} +#pragma once +#include +#include "Block.h" +#include "Config.h" + +namespace Leonetienne::GCrypt { + typedef std::array Keyset; +} diff --git a/GhettoCrypt/include/SecureBitset.h b/GhettoCrypt/include/SecureBitset.h index 5802634..927d6ab 100644 --- a/GhettoCrypt/include/SecureBitset.h +++ b/GhettoCrypt/include/SecureBitset.h @@ -1,286 +1,286 @@ -#pragma once -#include -#include -#include - -namespace GhettoCipher { - /** Wrapper for std::bitset that zeroes memory upon deletion. - * This does not include ALL methods, but the ones needed. - * - * Just creating a specialization of std::bitset does not work. - */ - template - class SecureBitset { - public: - explicit SecureBitset(); - explicit SecureBitset(const std::string& str); - explicit SecureBitset(const long long int i); - - ~SecureBitset(); - - bool operator==(const SecureBitset& other) const; - bool operator!=(const SecureBitset& other) const; - bool operator[](const std::size_t) const; - bool test(const std::size_t index) const; - bool all() const; - bool any() const; - bool none() const; - std::size_t count() const; - std::size_t size() const; - SecureBitset& operator&=(const SecureBitset& other); - SecureBitset& operator|=(const SecureBitset& other); - SecureBitset& operator^=(const SecureBitset& other); - SecureBitset operator&(const SecureBitset& other); - SecureBitset operator|(const SecureBitset& other); - SecureBitset operator^(const SecureBitset& other); - SecureBitset operator~() const; - SecureBitset& operator<<=(const std::size_t offset); - SecureBitset& operator>>=(const std::size_t offset); - SecureBitset operator<<(const std::size_t offset) const; - SecureBitset operator>>(const std::size_t offset) const; - SecureBitset& set(); - SecureBitset& set(const std::size_t index, bool value = true); - SecureBitset& reset(); - SecureBitset& reset(const std::size_t index); - SecureBitset& flip(); - SecureBitset& flip(const std::size_t index); - std::string to_string() const; - unsigned long to_ulong() const; - unsigned long long to_ullong() const; - - std::bitset& Get(); - const std::bitset& Get() const; - - private: - std::bitset bitset; -}; - - template - inline SecureBitset::SecureBitset() - : - bitset() { - return; - } - - template - inline SecureBitset::SecureBitset(const std::string& str) - : - bitset(str) { - return; - } - - template - inline SecureBitset::SecureBitset(const long long int i) - : - bitset(i) { - return; - } - - - // Don't optimize the destructor out!!! - // 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 - template - inline SecureBitset::~SecureBitset() { - bitset.reset(); - return; - } -#if defined _WIN32 || defined _WIN64 -#pragma optimize("", on ) -#elif defined __GNUG__ -#pragma GCC pop_options -#endif - - template - inline bool SecureBitset::operator==(const SecureBitset& other) const { - return bitset == other.bitset; - } - - template - inline bool SecureBitset::operator!=(const SecureBitset& other) const { - return bitset != other.bitset; - } - - template - inline bool SecureBitset::operator[](const std::size_t index) const { - return bitset[index]; - } - - template - inline bool SecureBitset::test(const std::size_t index) const { - return bitset.test(index); - } - - template - inline bool SecureBitset::all() const { - return bitset.all(); - } - - template - inline bool SecureBitset::any() const { - return bitset.any(); - } - - template - inline bool SecureBitset::none() const { - return bitset.none(); - } - - template - inline std::size_t SecureBitset::count() const { - return bitset.count(); - } - - template - inline std::size_t SecureBitset::size() const { - return bitset.count(); - } - - template - inline SecureBitset& SecureBitset::operator&=(const SecureBitset& other) { - bitset &= other.bitset; - return *this; - } - - template - inline SecureBitset& SecureBitset::operator|=(const SecureBitset& other) { - bitset |= other.bitset; - return *this; - } - - template - inline SecureBitset& SecureBitset::operator^=(const SecureBitset& other) { - bitset ^= other.bitset; - return *this; - } - - template - inline SecureBitset SecureBitset::operator&(const SecureBitset& other) { - SecureBitset bs; - bs.bitset = bitset & other.bitset; - return bs; - } - - template - inline SecureBitset SecureBitset::operator|(const SecureBitset& other) { - SecureBitset bs; - bs.bitset = bitset | other.bitset; - return bs; - } - - template - inline SecureBitset SecureBitset::operator^(const SecureBitset& other) { - SecureBitset bs; - bs.bitset = bitset ^ other.bitset; - return bs; - } - - template - inline SecureBitset SecureBitset::operator~() const { - SecureBitset bs; - bs.bitset = ~bitset; - return bs; - } - - template - inline SecureBitset& SecureBitset::operator<<=(const std::size_t offset) { - bitset <<= offset; - return *this; - } - - template - inline SecureBitset& SecureBitset::operator>>=(const std::size_t offset) { - bitset >>= offset; - return *this; - } - - template - inline SecureBitset SecureBitset::operator<<(const std::size_t offset) const { - SecureBitset bs; - bs.bitset = bitset << offset; - return bs; - } - - template - inline SecureBitset SecureBitset::operator>>(const std::size_t offset) const { - SecureBitset bs; - bs.bitset = bitset >> offset; - return bs; - } - - template - inline SecureBitset& SecureBitset::set() { - bitset.set(); - return *this; - } - - template - inline SecureBitset& SecureBitset::set(const std::size_t index, bool value) { - bitset.set(index, value); - return *this; - } - - template - inline SecureBitset& SecureBitset::reset() { - bitset.reset(); - return *this; - } - - template - inline SecureBitset& SecureBitset::reset(const std::size_t index) { - bitset.reset(index); - return *this; - } - - template - inline SecureBitset& SecureBitset::flip() { - bitset.flip(); - return *this; - } - - template - inline SecureBitset& SecureBitset::flip(const std::size_t index) { - bitset.flip(index); - return *this; - } - - template - inline std::string SecureBitset::to_string() const { - return bitset.to_string(); - } - - template - inline unsigned long SecureBitset::to_ulong() const { - return bitset.to_ulong(); - } - - template - inline unsigned long long SecureBitset::to_ullong() const { - return bitset.to_ullong(); - } - - template - inline std::bitset& SecureBitset::Get() { - return bitset; - } - - template - inline const std::bitset& SecureBitset::Get() const { - return bitset; - } - - template - inline std::ostream& operator<<(std::ostream& ofs, const SecureBitset& bs) { - return ofs << bs.Get(); - } - - template - inline std::istream& operator>>(std::istream& ifs, const SecureBitset& bs) { - return ifs >> bs.Get(); - } -} +#pragma once +#include +#include +#include + +namespace Leonetienne::GCrypt { + /** Wrapper for std::bitset that zeroes memory upon deletion. + * This does not include ALL methods, but the ones needed. + * + * Just creating a specialization of std::bitset does not work. + */ + template + class SecureBitset { + public: + explicit SecureBitset(); + explicit SecureBitset(const std::string& str); + explicit SecureBitset(const long long int i); + + ~SecureBitset(); + + bool operator==(const SecureBitset& other) const; + bool operator!=(const SecureBitset& other) const; + bool operator[](const std::size_t) const; + bool test(const std::size_t index) const; + bool all() const; + bool any() const; + bool none() const; + std::size_t count() const; + std::size_t size() const; + SecureBitset& operator&=(const SecureBitset& other); + SecureBitset& operator|=(const SecureBitset& other); + SecureBitset& operator^=(const SecureBitset& other); + SecureBitset operator&(const SecureBitset& other); + SecureBitset operator|(const SecureBitset& other); + SecureBitset operator^(const SecureBitset& other); + SecureBitset operator~() const; + SecureBitset& operator<<=(const std::size_t offset); + SecureBitset& operator>>=(const std::size_t offset); + SecureBitset operator<<(const std::size_t offset) const; + SecureBitset operator>>(const std::size_t offset) const; + SecureBitset& set(); + SecureBitset& set(const std::size_t index, bool value = true); + SecureBitset& reset(); + SecureBitset& reset(const std::size_t index); + SecureBitset& flip(); + SecureBitset& flip(const std::size_t index); + std::string to_string() const; + unsigned long to_ulong() const; + unsigned long long to_ullong() const; + + std::bitset& Get(); + const std::bitset& Get() const; + + private: + std::bitset bitset; +}; + + template + inline SecureBitset::SecureBitset() + : + bitset() { + return; + } + + template + inline SecureBitset::SecureBitset(const std::string& str) + : + bitset(str) { + return; + } + + template + inline SecureBitset::SecureBitset(const long long int i) + : + bitset(i) { + return; + } + + + // Don't optimize the destructor out!!! + // 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 + template + inline SecureBitset::~SecureBitset() { + bitset.reset(); + return; + } +#if defined _WIN32 || defined _WIN64 +#pragma optimize("", on ) +#elif defined __GNUG__ +#pragma GCC pop_options +#endif + + template + inline bool SecureBitset::operator==(const SecureBitset& other) const { + return bitset == other.bitset; + } + + template + inline bool SecureBitset::operator!=(const SecureBitset& other) const { + return bitset != other.bitset; + } + + template + inline bool SecureBitset::operator[](const std::size_t index) const { + return bitset[index]; + } + + template + inline bool SecureBitset::test(const std::size_t index) const { + return bitset.test(index); + } + + template + inline bool SecureBitset::all() const { + return bitset.all(); + } + + template + inline bool SecureBitset::any() const { + return bitset.any(); + } + + template + inline bool SecureBitset::none() const { + return bitset.none(); + } + + template + inline std::size_t SecureBitset::count() const { + return bitset.count(); + } + + template + inline std::size_t SecureBitset::size() const { + return bitset.count(); + } + + template + inline SecureBitset& SecureBitset::operator&=(const SecureBitset& other) { + bitset &= other.bitset; + return *this; + } + + template + inline SecureBitset& SecureBitset::operator|=(const SecureBitset& other) { + bitset |= other.bitset; + return *this; + } + + template + inline SecureBitset& SecureBitset::operator^=(const SecureBitset& other) { + bitset ^= other.bitset; + return *this; + } + + template + inline SecureBitset SecureBitset::operator&(const SecureBitset& other) { + SecureBitset bs; + bs.bitset = bitset & other.bitset; + return bs; + } + + template + inline SecureBitset SecureBitset::operator|(const SecureBitset& other) { + SecureBitset bs; + bs.bitset = bitset | other.bitset; + return bs; + } + + template + inline SecureBitset SecureBitset::operator^(const SecureBitset& other) { + SecureBitset bs; + bs.bitset = bitset ^ other.bitset; + return bs; + } + + template + inline SecureBitset SecureBitset::operator~() const { + SecureBitset bs; + bs.bitset = ~bitset; + return bs; + } + + template + inline SecureBitset& SecureBitset::operator<<=(const std::size_t offset) { + bitset <<= offset; + return *this; + } + + template + inline SecureBitset& SecureBitset::operator>>=(const std::size_t offset) { + bitset >>= offset; + return *this; + } + + template + inline SecureBitset SecureBitset::operator<<(const std::size_t offset) const { + SecureBitset bs; + bs.bitset = bitset << offset; + return bs; + } + + template + inline SecureBitset SecureBitset::operator>>(const std::size_t offset) const { + SecureBitset bs; + bs.bitset = bitset >> offset; + return bs; + } + + template + inline SecureBitset& SecureBitset::set() { + bitset.set(); + return *this; + } + + template + inline SecureBitset& SecureBitset::set(const std::size_t index, bool value) { + bitset.set(index, value); + return *this; + } + + template + inline SecureBitset& SecureBitset::reset() { + bitset.reset(); + return *this; + } + + template + inline SecureBitset& SecureBitset::reset(const std::size_t index) { + bitset.reset(index); + return *this; + } + + template + inline SecureBitset& SecureBitset::flip() { + bitset.flip(); + return *this; + } + + template + inline SecureBitset& SecureBitset::flip(const std::size_t index) { + bitset.flip(index); + return *this; + } + + template + inline std::string SecureBitset::to_string() const { + return bitset.to_string(); + } + + template + inline unsigned long SecureBitset::to_ulong() const { + return bitset.to_ulong(); + } + + template + inline unsigned long long SecureBitset::to_ullong() const { + return bitset.to_ullong(); + } + + template + inline std::bitset& SecureBitset::Get() { + return bitset; + } + + template + inline const std::bitset& SecureBitset::Get() const { + return bitset; + } + + template + inline std::ostream& operator<<(std::ostream& ofs, const SecureBitset& bs) { + return ofs << bs.Get(); + } + + template + inline std::istream& operator>>(std::istream& ifs, const SecureBitset& bs) { + return ifs >> bs.Get(); + } +} diff --git a/GhettoCrypt/include/Util.h b/GhettoCrypt/include/Util.h index 788bd3b..8b3690a 100644 --- a/GhettoCrypt/include/Util.h +++ b/GhettoCrypt/include/Util.h @@ -10,7 +10,7 @@ #include "Cipher.h" #include "InitializationVector.h" -namespace GhettoCipher { +namespace Leonetienne::GCrypt { //! Mod-operator that works with negative values inline int Mod(const int numerator, const int denominator) { return (denominator + (numerator % denominator)) % denominator; diff --git a/GhettoCrypt/include/Version.h b/GhettoCrypt/include/Version.h index 48e51ef..b44ffda 100644 --- a/GhettoCrypt/include/Version.h +++ b/GhettoCrypt/include/Version.h @@ -1,3 +1,3 @@ -#pragma once -#define GHETTOCRYPT_VERSION 0.21 - +#pragma once +#define GHETTOCRYPT_VERSION 0.21 + diff --git a/GhettoCrypt/src/Cipher.cpp b/GhettoCrypt/src/Cipher.cpp index 632c421..992267d 100644 --- a/GhettoCrypt/src/Cipher.cpp +++ b/GhettoCrypt/src/Cipher.cpp @@ -1,131 +1,135 @@ -#include -#include -#include "Cipher.h" -#include "Util.h" -#include "InitializationVector.h" - -GhettoCipher::Cipher::Cipher(const Block& key) - : - key { key }, - initializationVector(InitializationVector(key)) { - - return; -} - -GhettoCipher::Cipher::Cipher(const std::string& password) - : - key { PasswordToKey(password) }, - initializationVector(InitializationVector(key)) { - return; -} - -GhettoCipher::Cipher::~Cipher() { - // Clear key memory - ZeroKeyMemory(); - - return; -} - -void GhettoCipher::Cipher::SetKey(const Block& key) { - ZeroKeyMemory(); - - this->key = key; - return; -} - -void GhettoCipher::Cipher::SetPassword(const std::string& password) { - ZeroKeyMemory(); - - key = PasswordToKey(password); - return; -} - -GhettoCipher::Flexblock GhettoCipher::Cipher::Encipher(const Flexblock& data, bool printProgress) const { - // Split cleartext into blocks - std::vector blocks; - - for (std::size_t i = 0; i < data.size(); i += BLOCK_SIZE) { - blocks.push_back(Block( - PadStringToLength(data.substr(i, BLOCK_SIZE), BLOCK_SIZE, '0', false)) - ); - } - - // Encrypt individual blocks using cipher block chaining - Feistel feistel(key); - - for (std::size_t i = 0; i < blocks.size(); i++) { - // Print reports if desired. If we have > 1000 blocks, print one report every 100 blocks. Otherwise for every 10th block. - if ((i % ((blocks.size() > 1000)? 100 : 10) == 0) && (printProgress)) { - std::cout << "Encrypting... (Block " << i << " / " << blocks.size() << " - " << ((float)i*100 / blocks.size()) << "%)" << std::endl; - } - - const Block& lastBlock = (i>0) ? blocks[i-1] : initializationVector; - blocks[i] = feistel.Encipher(blocks[i] ^ lastBlock); // Xor last cipher block with new clear text block before E() - } - - // Concatenate ciphertext blocks back into a flexblock - std::stringstream ss; - for (Block& b : blocks) { - ss << b; - } - - // Return it - return ss.str(); -} - -GhettoCipher::Flexblock GhettoCipher::Cipher::Decipher(const Flexblock& data, bool printProgress) const { - // Split ciphertext into blocks - std::vector blocks; - - for (std::size_t i = 0; i < data.size(); i += BLOCK_SIZE) { - blocks.push_back(Block( - PadStringToLength(data.substr(i, BLOCK_SIZE), BLOCK_SIZE, '0', false)) - ); - } - - // Decrypt individual blocks - Feistel feistel(key); - - // We can't do this in-loop for decryption, because we are decrypting the blocks in-place. - Block lastBlock = initializationVector; - - for (std::size_t i = 0; i < blocks.size(); i++) { - // Print reports if desired. If we have > 1000 blocks, print one report every 100 blocks. Otherwise for every 10th block. - if ((i % ((blocks.size() > 1000) ? 100 : 10) == 0) && (printProgress)) { - std::cout << "Decrypting... (Block " << i << " / " << blocks.size() << " - " << ((float)i*100/ blocks.size()) << "%)" << std::endl; - } - - Block tmpCopy = blocks[i]; - - blocks[i] = feistel.Decipher(blocks[i]) ^ lastBlock; // Decipher cipher block [i] and then xor it with the last cipher block [i-1] we've had - - lastBlock = std::move(tmpCopy); - } - - // Concatenate ciphertext blocks back into a flexblock - std::stringstream ss; - for (Block& b : blocks) { - ss << b; - } - - // Return it - return ss.str(); -} - -// 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 GhettoCipher::Cipher::ZeroKeyMemory() { - key.reset(); - return; -} -#if defined _WIN32 || defined _WIN64 -#pragma optimize("", on ) -#elif defined __GNUG__ -#pragma GCC pop_options -#endif - +#include +#include +#include "Cipher.h" +#include "Util.h" +#include "InitializationVector.h" + +namespace Leonetienne::GCrypt { + + Cipher::Cipher(const Block& key) + : + key { key }, + initializationVector(InitializationVector(key)) { + + return; + } + + Cipher::Cipher(const std::string& password) + : + key { PasswordToKey(password) }, + initializationVector(InitializationVector(key)) { + return; + } + + Cipher::~Cipher() { + // Clear key memory + ZeroKeyMemory(); + + return; + } + + void Cipher::SetKey(const Block& key) { + ZeroKeyMemory(); + + this->key = key; + return; + } + + void Cipher::SetPassword(const std::string& password) { + ZeroKeyMemory(); + + key = PasswordToKey(password); + return; + } + + Flexblock Cipher::Encipher(const Flexblock& data, bool printProgress) const { + // Split cleartext into blocks + std::vector blocks; + + for (std::size_t i = 0; i < data.size(); i += BLOCK_SIZE) { + blocks.push_back(Block( + PadStringToLength(data.substr(i, BLOCK_SIZE), BLOCK_SIZE, '0', false)) + ); + } + + // Encrypt individual blocks using cipher block chaining + Feistel feistel(key); + + for (std::size_t i = 0; i < blocks.size(); i++) { + // Print reports if desired. If we have > 1000 blocks, print one report every 100 blocks. Otherwise for every 10th block. + if ((i % ((blocks.size() > 1000)? 100 : 10) == 0) && (printProgress)) { + std::cout << "Encrypting... (Block " << i << " / " << blocks.size() << " - " << ((float)i*100 / blocks.size()) << "%)" << std::endl; + } + + const Block& lastBlock = (i>0) ? blocks[i-1] : initializationVector; + blocks[i] = feistel.Encipher(blocks[i] ^ lastBlock); // Xor last cipher block with new clear text block before E() + } + + // Concatenate ciphertext blocks back into a flexblock + std::stringstream ss; + for (Block& b : blocks) { + ss << b; + } + + // Return it + return ss.str(); + } + + Flexblock Cipher::Decipher(const Flexblock& data, bool printProgress) const { + // Split ciphertext into blocks + std::vector blocks; + + for (std::size_t i = 0; i < data.size(); i += BLOCK_SIZE) { + blocks.push_back(Block( + PadStringToLength(data.substr(i, BLOCK_SIZE), BLOCK_SIZE, '0', false)) + ); + } + + // Decrypt individual blocks + Feistel feistel(key); + + // We can't do this in-loop for decryption, because we are decrypting the blocks in-place. + Block lastBlock = initializationVector; + + for (std::size_t i = 0; i < blocks.size(); i++) { + // Print reports if desired. If we have > 1000 blocks, print one report every 100 blocks. Otherwise for every 10th block. + if ((i % ((blocks.size() > 1000) ? 100 : 10) == 0) && (printProgress)) { + std::cout << "Decrypting... (Block " << i << " / " << blocks.size() << " - " << ((float)i*100/ blocks.size()) << "%)" << std::endl; + } + + Block tmpCopy = blocks[i]; + + blocks[i] = feistel.Decipher(blocks[i]) ^ lastBlock; // Decipher cipher block [i] and then xor it with the last cipher block [i-1] we've had + + lastBlock = std::move(tmpCopy); + } + + // Concatenate ciphertext blocks back into a flexblock + std::stringstream ss; + for (Block& b : blocks) { + ss << b; + } + + // Return it + return ss.str(); + } + + // 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 Cipher::ZeroKeyMemory() { + key.reset(); + return; + } +#if defined _WIN32 || defined _WIN64 +#pragma optimize("", on ) +#elif defined __GNUG__ +#pragma GCC pop_options +#endif + +} + diff --git a/GhettoCrypt/src/Feistel.cpp b/GhettoCrypt/src/Feistel.cpp index 8c6bfa6..73135c6 100644 --- a/GhettoCrypt/src/Feistel.cpp +++ b/GhettoCrypt/src/Feistel.cpp @@ -3,258 +3,262 @@ #include "Util.h" #include "Config.h" -GhettoCipher::Feistel::Feistel(const Block& key) { - SetKey(key); - return; -} +namespace Leonetienne::GCrypt { -GhettoCipher::Feistel::~Feistel() { - ZeroKeyMemory(); + Feistel::Feistel(const Block& key) { + SetKey(key); + return; + } - return; -} + Feistel::~Feistel() { + ZeroKeyMemory(); -void GhettoCipher::Feistel::SetKey(const Block& key) { - GenerateRoundKeys(key); - return; -} + return; + } -GhettoCipher::Block GhettoCipher::Feistel::Encipher(const Block& data) { - return Run(data, false); -} + void Feistel::SetKey(const Block& key) { + GenerateRoundKeys(key); + return; + } -GhettoCipher::Block GhettoCipher::Feistel::Decipher(const Block& data) { - return Run(data, true); -} + Block Feistel::Encipher(const Block& data) { + return Run(data, false); + } -GhettoCipher::Block GhettoCipher::Feistel::Run(const Block& data, bool reverseKeys) { - const auto splitData = FeistelSplit(data); - GhettoCipher::Halfblock l = splitData.first; - GhettoCipher::Halfblock r = splitData.second; + Block Feistel::Decipher(const Block& data) { + return Run(data, true); + } - Halfblock tmp; + Block Feistel::Run(const Block& data, bool reverseKeys) { + const auto splitData = FeistelSplit(data); + Halfblock l = splitData.first; + Halfblock r = splitData.second; - for (std::size_t i = 0; i < N_ROUNDS; i++) { - // Calculate key index - std::size_t keyIndex; - if (reverseKeys) { - keyIndex = N_ROUNDS - i - 1; - } - else { - keyIndex = i; - } + Halfblock tmp; - // Do a feistel round - tmp = r; - r = l ^ F(r, roundKeys[keyIndex]); - l = tmp; - } + for (std::size_t i = 0; i < N_ROUNDS; i++) { + // Calculate key index + std::size_t keyIndex; + if (reverseKeys) { + keyIndex = N_ROUNDS - i - 1; + } + else { + keyIndex = i; + } - // Block has finished de*ciphering. - // Let's generate a new set of round keys. - GenerateRoundKeys((Block)roundKeys.back()); + // Do a feistel round + tmp = r; + r = l ^ F(r, roundKeys[keyIndex]); + l = tmp; + } - return FeistelCombine(r, l); -} + // Block has finished de*ciphering. + // Let's generate a new set of round keys. + GenerateRoundKeys((Block)roundKeys.back()); -GhettoCipher::Halfblock GhettoCipher::Feistel::F(Halfblock m, const Block& key) { - // Made-up F function + return FeistelCombine(r, l); + } - // Expand to full bitwidth - Block m_expanded = ExpansionFunction(m); + Halfblock Feistel::F(Halfblock m, const Block& key) { + // Made-up F function - // Shift to left by 1 - m_expanded = Shiftl(m_expanded, 1); + // Expand to full bitwidth + Block m_expanded = ExpansionFunction(m); - // Xor with key - m_expanded ^= key; + // Shift to left by 1 + m_expanded = Shiftl(m_expanded, 1); - // Non-linearly apply subsitution boxes - std::stringstream ss; - const std::string m_str = m_expanded.to_string(); + // Xor with key + m_expanded ^= key; - for (std::size_t i = 0; i < BLOCK_SIZE; i += 4) { - ss << SBox(m_str.substr(i, 4)); - } + // Non-linearly apply subsitution boxes + std::stringstream ss; + const std::string m_str = m_expanded.to_string(); - m_expanded = Block(ss.str()); + for (std::size_t i = 0; i < BLOCK_SIZE; i += 4) { + ss << SBox(m_str.substr(i, 4)); + } - // Return the compressed version - return CompressionFunction(m_expanded); -} + m_expanded = Block(ss.str()); -std::pair GhettoCipher::Feistel::FeistelSplit(const Block& block) { - const std::string bits = block.to_string(); + // Return the compressed version + return CompressionFunction(m_expanded); + } - Halfblock l(bits.substr(0, bits.size() / 2)); - Halfblock r(bits.substr(bits.size() / 2)); + std::pair Feistel::FeistelSplit(const Block& block) { + const std::string bits = block.to_string(); - return std::make_pair(l, r); -} + Halfblock l(bits.substr(0, bits.size() / 2)); + Halfblock r(bits.substr(bits.size() / 2)); -GhettoCipher::Block GhettoCipher::Feistel::FeistelCombine(const Halfblock& l, const Halfblock& r) { - return Block(l.to_string() + r.to_string()); -} + return std::make_pair(l, r); + } -GhettoCipher::Block GhettoCipher::Feistel::ExpansionFunction(const Halfblock& block) { - std::stringstream ss; - const std::string bits = block.to_string(); + Block Feistel::FeistelCombine(const Halfblock& l, const Halfblock& r) { + return Block(l.to_string() + r.to_string()); + } - std::unordered_map expansionMap; - expansionMap["00"] = "1101"; - expansionMap["01"] = "1000"; - expansionMap["10"] = "0010"; - expansionMap["11"] = "0111"; + Block Feistel::ExpansionFunction(const Halfblock& block) { + std::stringstream ss; + const std::string bits = block.to_string(); - // We have to double the bits! - for (std::size_t i = 0; i < HALFBLOCK_SIZE; i += 2) { - const std::string sub = bits.substr(i, 2); - ss << expansionMap[sub]; - } + std::unordered_map expansionMap; + expansionMap["00"] = "1101"; + expansionMap["01"] = "1000"; + expansionMap["10"] = "0010"; + expansionMap["11"] = "0111"; - return Block(ss.str()); -} + // We have to double the bits! + for (std::size_t i = 0; i < HALFBLOCK_SIZE; i += 2) { + const std::string sub = bits.substr(i, 2); + ss << expansionMap[sub]; + } -GhettoCipher::Halfblock GhettoCipher::Feistel::CompressionFunction(const Block& block) { - std::stringstream ss; - const std::string bits = block.to_string(); + return Block(ss.str()); + } - std::unordered_map 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"; + Halfblock Feistel::CompressionFunction(const Block& block) { + std::stringstream ss; + const std::string bits = block.to_string(); - // We have to half the bits! - for (std::size_t i = 0; i < BLOCK_SIZE; i += 4) { - const std::string sub = bits.substr(i, 4); - ss << compressionMap[sub]; - } + std::unordered_map 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"; - return Halfblock(ss.str()); -} + // We have to half the bits! + for (std::size_t i = 0; i < BLOCK_SIZE; i += 4) { + const std::string sub = bits.substr(i, 4); + ss << compressionMap[sub]; + } -std::string GhettoCipher::Feistel::SBox(const std::string& in) { - static std::unordered_map 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 Halfblock(ss.str()); + } - return subMap[in]; -} + std::string Feistel::SBox(const std::string& in) { + static std::unordered_map 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; + } -void GhettoCipher::Feistel::GenerateRoundKeys(const Block& seedKey) { - // Clear initial key memory - ZeroKeyMemory(); - roundKeys = Keyset(); + return subMap[in]; + } - // Derive the initial two round keys + void Feistel::GenerateRoundKeys(const Block& seedKey) { + // Clear initial key memory + ZeroKeyMemory(); + roundKeys = Keyset(); - // Compress- substitute, and expand the seed key to form the initial and the second-initial round key - // This action is non-linear and irreversible, and thus strenghtens security. - Halfblock compressedSeed1 = CompressionFunction(seedKey); - Halfblock compressedSeed2 = CompressionFunction(Shiftl(seedKey, 1)); // Shifting one key by 1 will result in a completely different compression + // Derive the initial two round keys - // To add further confusion, let's shift seed1 by 1 aswell (after compression, but before substitution) - // but only if the total number of bits set are a multiple of 3 - // if it is a multiple of 4, we'll shift it by 1 into the opposite direction - const std::size_t setBits1 = compressedSeed1.count(); + // Compress- substitute, and expand the seed key to form the initial and the second-initial round key + // This action is non-linear and irreversible, and thus strenghtens security. + Halfblock compressedSeed1 = CompressionFunction(seedKey); + Halfblock compressedSeed2 = CompressionFunction(Shiftl(seedKey, 1)); // Shifting one key by 1 will result in a completely different compression - if (setBits1 % 4 == 0) { - compressedSeed1 = Shiftr(compressedSeed1, 1); - } - else if (setBits1 % 3 == 0) { - compressedSeed1 = Shiftl(compressedSeed1, 1); - } + // To add further confusion, let's shift seed1 by 1 aswell (after compression, but before substitution) + // but only if the total number of bits set are a multiple of 3 + // if it is a multiple of 4, we'll shift it by 1 into the opposite direction + const std::size_t setBits1 = compressedSeed1.count(); - // Now apply substitution - std::stringstream ssKey1; - std::stringstream ssKey2; - const std::string bitsKey1 = compressedSeed1.to_string(); - const std::string bitsKey2 = compressedSeed2.to_string(); + if (setBits1 % 4 == 0) { + compressedSeed1 = Shiftr(compressedSeed1, 1); + } + else if (setBits1 % 3 == 0) { + compressedSeed1 = Shiftl(compressedSeed1, 1); + } - for (std::size_t i = 0; i < HALFBLOCK_SIZE; i += 4) { - ssKey1 << SBox(bitsKey1.substr(i, 4)); - ssKey2 << SBox(bitsKey2.substr(i, 4)); - } + // Now apply substitution + std::stringstream ssKey1; + std::stringstream ssKey2; + const std::string bitsKey1 = compressedSeed1.to_string(); + const std::string bitsKey2 = compressedSeed2.to_string(); - compressedSeed1 = Halfblock(ssKey1.str()); - compressedSeed2 = Halfblock(ssKey2.str()); + for (std::size_t i = 0; i < HALFBLOCK_SIZE; i += 4) { + ssKey1 << SBox(bitsKey1.substr(i, 4)); + ssKey2 << SBox(bitsKey2.substr(i, 4)); + } - // Now extrapolate them to BLOCK_SIZE (key size) again - // Xor with the original seed key to get rid of the repititions caused by the expansion - roundKeys[0] = ExpansionFunction(compressedSeed1) ^ seedKey; - roundKeys[1] = ExpansionFunction(compressedSeed2) ^ seedKey; + compressedSeed1 = Halfblock(ssKey1.str()); + compressedSeed2 = Halfblock(ssKey2.str()); - // Now derive all other round keys + // Now extrapolate them to BLOCK_SIZE (key size) again + // Xor with the original seed key to get rid of the repititions caused by the expansion + roundKeys[0] = ExpansionFunction(compressedSeed1) ^ seedKey; + roundKeys[1] = ExpansionFunction(compressedSeed2) ^ seedKey; - for (std::size_t i = 2; i < roundKeys.size(); i++) { - // Initialize new round key with last round key - Block newKey = roundKeys[i - 1]; + // Now derive all other round keys - // Shift to left by how many bits are set, modulo 8 - newKey = Shiftl(newKey, newKey.count() % 8); // This action is irreversible + for (std::size_t i = 2; i < roundKeys.size(); i++) { + // Initialize new round key with last round key + Block newKey = roundKeys[i - 1]; - // Split into two halfblocks, - // apply F() to one halfblock with rk[i-2], - // xor the other one with it - // and put them back together - auto halfkeys = FeistelSplit(newKey); - 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. + // Shift to left by how many bits are set, modulo 8 + newKey = Shiftl(newKey, newKey.count() % 8); // This action is irreversible - roundKeys[i] = FeistelCombine(halfkey1, halfkey2); - } + // Split into two halfblocks, + // apply F() to one halfblock with rk[i-2], + // xor the other one with it + // and put them back together + auto halfkeys = FeistelSplit(newKey); + 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. - return; -} + roundKeys[i] = FeistelCombine(halfkey1, halfkey2); + } -// These pragmas only work for MSVC and g++, as far as i know. Beware!!! + return; + } + + // 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 GhettoCipher::Feistel::ZeroKeyMemory() { - for (Block& key : roundKeys) { - key.reset(); - } + void Feistel::ZeroKeyMemory() { + for (Block& key : roundKeys) { + key.reset(); + } - return; -} + return; + } #if defined _WIN32 || defined _WIN64 #pragma optimize("", on ) #elif defined __GNUG__ #pragma GCC pop_options #endif +} + diff --git a/GhettoCrypt/src/GhettoCryptWrapper.cpp b/GhettoCrypt/src/GhettoCryptWrapper.cpp index 6860b1b..ff7021e 100644 --- a/GhettoCrypt/src/GhettoCryptWrapper.cpp +++ b/GhettoCrypt/src/GhettoCryptWrapper.cpp @@ -1,84 +1,88 @@ -#include "GhettoCryptWrapper.h" -#include "Cipher.h" -#include "Util.h" - -std::string GhettoCipher::GhettoCryptWrapper::EncryptString(const std::string& cleartext, const std::string& password) { - // Instanciate our cipher and supply a key - const Block key = PasswordToKey(password); - Cipher cipher(key); - - // Recode the ascii-string to bits - const Flexblock cleartext_bits = StringToBits(cleartext); - - // Encrypt our cleartext bits - const Flexblock ciphertext_bits = cipher.Encipher(cleartext_bits); - - // Recode the ciphertext bits to a hex-string - const std::string ciphertext = BitsToHexstring(ciphertext_bits); - - // Return it - return ciphertext; -} - -std::string GhettoCipher::GhettoCryptWrapper::DecryptString(const std::string& ciphertext, const std::string& password) { - // Instanciate our cipher and supply a key - const Block key = PasswordToKey(password); - Cipher cipher(key); - - // Recode the hex-string to bits - const Flexblock ciphertext_bits = HexstringToBits(ciphertext); - - // Decrypt the ciphertext bits - const std::string cleartext_bits = cipher.Decipher(ciphertext_bits); - - // Recode the cleartext bits to an ascii-string - const std::string cleartext = BitsToString(cleartext_bits); - - // Return it - return cleartext; -} - -bool GhettoCipher::GhettoCryptWrapper::EncryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport) { - try { - // Read the file to bits - const Flexblock cleartext_bits = ReadFileToBits(filename_in); - - // Instanciate our cipher and supply a key - const Block key = PasswordToKey(password); - Cipher cipher(key); - - // Encrypt our cleartext bits - const Flexblock ciphertext_bits = cipher.Encipher(cleartext_bits, printProgressReport); - - // Write our ciphertext bits to file - WriteBitsToFile(filename_out, ciphertext_bits); - - return true; - } - catch (std::runtime_error&) { - return false; - } -} - -bool GhettoCipher::GhettoCryptWrapper::DecryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport) { - try { - // Read the file to bits - const Flexblock ciphertext_bits = ReadFileToBits(filename_in); - - // Instanciate our cipher and supply a key - const Block key = PasswordToKey(password); - Cipher cipher(key); - - // Decrypt the ciphertext bits - const Flexblock cleartext_bits = cipher.Decipher(ciphertext_bits, printProgressReport); - - // Write our cleartext bits to file - WriteBitsToFile(filename_out, cleartext_bits); - - return true; - } - catch (std::runtime_error&) { - return false; - } -} - +#include "GhettoCryptWrapper.h" +#include "Cipher.h" +#include "Util.h" + +namespace Leonetienne::GCrypt { + + std::string GhettoCryptWrapper::EncryptString(const std::string& cleartext, const std::string& password) { + // Instanciate our cipher and supply a key + const Block key = PasswordToKey(password); + Cipher cipher(key); + + // Recode the ascii-string to bits + const Flexblock cleartext_bits = StringToBits(cleartext); + + // Encrypt our cleartext bits + const Flexblock ciphertext_bits = cipher.Encipher(cleartext_bits); + + // Recode the ciphertext bits to a hex-string + const std::string ciphertext = BitsToHexstring(ciphertext_bits); + + // Return it + return ciphertext; + } + + std::string GhettoCryptWrapper::DecryptString(const std::string& ciphertext, const std::string& password) { + // Instanciate our cipher and supply a key + const Block key = PasswordToKey(password); + Cipher cipher(key); + + // Recode the hex-string to bits + const Flexblock ciphertext_bits = HexstringToBits(ciphertext); + + // Decrypt the ciphertext bits + const std::string cleartext_bits = cipher.Decipher(ciphertext_bits); + + // Recode the cleartext bits to an ascii-string + const std::string cleartext = BitsToString(cleartext_bits); + + // Return it + return cleartext; + } + + bool GhettoCryptWrapper::EncryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport) { + try { + // Read the file to bits + const Flexblock cleartext_bits = ReadFileToBits(filename_in); + + // Instanciate our cipher and supply a key + const Block key = PasswordToKey(password); + Cipher cipher(key); + + // Encrypt our cleartext bits + const Flexblock ciphertext_bits = cipher.Encipher(cleartext_bits, printProgressReport); + + // Write our ciphertext bits to file + WriteBitsToFile(filename_out, ciphertext_bits); + + return true; + } + catch (std::runtime_error&) { + return false; + } + } + + bool GhettoCryptWrapper::DecryptFile(const std::string& filename_in, const std::string& filename_out, const std::string& password, bool printProgressReport) { + try { + // Read the file to bits + const Flexblock ciphertext_bits = ReadFileToBits(filename_in); + + // Instanciate our cipher and supply a key + const Block key = PasswordToKey(password); + Cipher cipher(key); + + // Decrypt the ciphertext bits + const Flexblock cleartext_bits = cipher.Decipher(ciphertext_bits, printProgressReport); + + // Write our cleartext bits to file + WriteBitsToFile(filename_out, cleartext_bits); + + return true; + } + catch (std::runtime_error&) { + return false; + } + } + +} + diff --git a/GhettoCrypt/src/InitializationVector.cpp b/GhettoCrypt/src/InitializationVector.cpp index 9ad7f3b..2c30e82 100644 --- a/GhettoCrypt/src/InitializationVector.cpp +++ b/GhettoCrypt/src/InitializationVector.cpp @@ -1,13 +1,17 @@ -#include "InitializationVector.h" -#include "Feistel.h" - -GhettoCipher::InitializationVector::InitializationVector(const Block& seed) { - // We'll generate our initialization vector by encrypting our seed with itself as a key - // iv = E(M=seed, K=seed) - iv = Feistel(seed).Encipher(seed); -} - -GhettoCipher::InitializationVector::operator GhettoCipher::Block() const { - return iv; -} - +#include "InitializationVector.h" +#include "Feistel.h" + +namespace Leonetienne::GCrypt { + + InitializationVector::InitializationVector(const Block& seed) { + // We'll generate our initialization vector by encrypting our seed with itself as a key + // iv = E(M=seed, K=seed) + iv = Feistel(seed).Encipher(seed); + } + + InitializationVector::operator Block() const { + return iv; + } + +} +