From 8ddd9d6bfb2c7f2d866abe67e9b460be780cb30f Mon Sep 17 00:00:00 2001 From: Leonetienne Date: Thu, 26 May 2022 00:55:24 +0200 Subject: [PATCH] Replaced halfblock with instanciation of Basic_Block --- GCryptLib/include/GCrypt/Block.h | 5 +- GCryptLib/include/GCrypt/Config.h | 3 - GCryptLib/include/GCrypt/Feistel.h | 1 - GCryptLib/include/GCrypt/Halfblock.h | 9 - GCryptLib/include/GCrypt/SecureBitset.h | 292 ------------------------ GCryptLib/include/GCrypt/Util.h | 38 --- GCryptLib/src/Block.cpp | 2 +- GCryptLib/src/Feistel.cpp | 10 +- GCryptLib/src/GHash.cpp | 5 +- GCryptLib/src/GPrng.cpp | 8 +- GCryptLib/src/GWrapper.cpp | 5 +- GCryptLib/src/Key.cpp | 8 +- GCryptLib/src/Util.cpp | 4 +- 13 files changed, 25 insertions(+), 365 deletions(-) delete mode 100644 GCryptLib/include/GCrypt/Halfblock.h delete mode 100644 GCryptLib/include/GCrypt/SecureBitset.h diff --git a/GCryptLib/include/GCrypt/Block.h b/GCryptLib/include/GCrypt/Block.h index 36d856f..64038a7 100644 --- a/GCryptLib/include/GCrypt/Block.h +++ b/GCryptLib/include/GCrypt/Block.h @@ -165,6 +165,7 @@ namespace Leonetienne::GCrypt { static constexpr std::size_t CHUNK_SIZE = sizeof(T); static constexpr std::size_t CHUNK_SIZE_BITS = CHUNK_SIZE * 8; + static constexpr std::size_t BLOCK_SIZE_BITS = CHUNK_SIZE_BITS * 16; friend std::ostream& operator<<(std::ostream& os, const Basic_Block& b) { for (std::size_t i = 0; i < b.data.size(); i++) { @@ -180,13 +181,13 @@ namespace Leonetienne::GCrypt { // Instantiate templates template class Basic_Block; - //template class Basic_Block; + template class Basic_Block; //! This a full-sized 512-bit block typedef Basic_Block Block; //! This is a half-block used within the feistel class - //typedef Basic_Block Halfblock; + typedef Basic_Block Halfblock; } #endif diff --git a/GCryptLib/include/GCrypt/Config.h b/GCryptLib/include/GCrypt/Config.h index 5340563..39d44c3 100644 --- a/GCryptLib/include/GCrypt/Config.h +++ b/GCryptLib/include/GCrypt/Config.h @@ -4,9 +4,6 @@ #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 = 6; } diff --git a/GCryptLib/include/GCrypt/Feistel.h b/GCryptLib/include/GCrypt/Feistel.h index 50bd4dd..cb7d35f 100644 --- a/GCryptLib/include/GCrypt/Feistel.h +++ b/GCryptLib/include/GCrypt/Feistel.h @@ -4,7 +4,6 @@ #include "GCrypt/Keyset.h" #include "GCrypt/Block.h" #include "GCrypt/Key.h" -#include "GCrypt/Halfblock.h" namespace Leonetienne::GCrypt { /** Class to perform a feistel block chipher diff --git a/GCryptLib/include/GCrypt/Halfblock.h b/GCryptLib/include/GCrypt/Halfblock.h deleted file mode 100644 index 4be13a0..0000000 --- a/GCryptLib/include/GCrypt/Halfblock.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include -#include "GCrypt/SecureBitset.h" -#include "GCrypt/Config.h" - -namespace Leonetienne::GCrypt { - constexpr std::size_t HALFBLOCK_SIZE = (BLOCK_SIZE / 2); - typedef SecureBitset Halfblock; -} diff --git a/GCryptLib/include/GCrypt/SecureBitset.h b/GCryptLib/include/GCrypt/SecureBitset.h deleted file mode 100644 index e288b13..0000000 --- a/GCryptLib/include/GCrypt/SecureBitset.h +++ /dev/null @@ -1,292 +0,0 @@ -#ifndef GCRYPT_SECUREBITSET_H -#define GCRYPT_SECUREBITSET_H - -#include -#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) const; - 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) const { - 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(); - } -} - -#endif - diff --git a/GCryptLib/include/GCrypt/Util.h b/GCryptLib/include/GCrypt/Util.h index 5398e7f..adb1bf2 100644 --- a/GCryptLib/include/GCrypt/Util.h +++ b/GCryptLib/include/GCrypt/Util.h @@ -5,7 +5,6 @@ #include #include #include -#include "GCrypt/SecureBitset.h" #include "GCrypt/Block.h" #include "GCrypt/Flexblock.h" #include "GCrypt/Config.h" @@ -18,43 +17,6 @@ namespace Leonetienne::GCrypt { return (denominator + (numerator % denominator)) % denominator; } - inline Block Shiftl(const Block& bits, const std::size_t amount) { - std::stringstream ss; - const std::string bitss = bits.ToString(); - - for (std::size_t i = 0; i < bitss.size(); i++) { - ss << bitss[Mod((int)(i + amount), (int)bitss.size())]; - } - - return Block(ss.str()); - } - - //! Will perform a wrapping left-bitshift on a bitset - template - inline SecureBitset Shiftl(const SecureBitset& bits, const 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((int)(i + amount), (int)bitss.size())]; - } - - return SecureBitset(ss.str()); - } - - //! Will perform a wrapping right-bitshift on a bitset - template - inline SecureBitset Shiftr(const SecureBitset& bits, const 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 SecureBitset(ss.str()); - } - //! Will pad a string to a set length with a certain character std::string PadStringToLength(const std::string& str, const std::size_t len, const char pad, const bool padLeft = true); diff --git a/GCryptLib/src/Block.cpp b/GCryptLib/src/Block.cpp index 6398949..809d6bf 100644 --- a/GCryptLib/src/Block.cpp +++ b/GCryptLib/src/Block.cpp @@ -28,7 +28,7 @@ namespace Leonetienne::GCrypt { template void Basic_Block::FromString(const std::string& str) { - assert(str.length() == BLOCK_SIZE); + assert(str.length() == BLOCK_SIZE_BITS); for (std::size_t i = 0; i < data.size(); i++) { data[i] = std::bitset( diff --git a/GCryptLib/src/Feistel.cpp b/GCryptLib/src/Feistel.cpp index cca9860..57a5844 100644 --- a/GCryptLib/src/Feistel.cpp +++ b/GCryptLib/src/Feistel.cpp @@ -78,7 +78,7 @@ namespace Leonetienne::GCrypt { // Non-linearly apply subsitution boxes std::stringstream ss; const std::string m_str = m_expanded.ToString(); - for (std::size_t i = 0; i < BLOCK_SIZE; i += 4) { + for (std::size_t i = 0; i < Block::BLOCK_SIZE_BITS; i += 4) { ss << SBox(m_str.substr(i, 4)); } m_expanded = Block(ss.str()); @@ -98,12 +98,12 @@ namespace Leonetienne::GCrypt { } Block Feistel::FeistelCombine(const Halfblock& l, const Halfblock& r) { - return Block(l.to_string() + r.to_string()); + return Block(l.ToString() + r.ToString()); } Block Feistel::ExpansionFunction(const Halfblock& block) { std::stringstream ss; - const std::string bits = block.to_string(); + const std::string bits = block.ToString(); std::unordered_map expansionMap; expansionMap["00"] = "1101"; @@ -112,7 +112,7 @@ namespace Leonetienne::GCrypt { expansionMap["11"] = "0111"; // We have to double the bits! - for (std::size_t i = 0; i < HALFBLOCK_SIZE; i += 2) { + for (std::size_t i = 0; i < Halfblock::BLOCK_SIZE_BITS; i += 2) { const std::string sub = bits.substr(i, 2); ss << expansionMap[sub]; } @@ -143,7 +143,7 @@ namespace Leonetienne::GCrypt { compressionMap["1111"] = "01"; // We have to half the bits! - for (std::size_t i = 0; i < BLOCK_SIZE; i += 4) { + for (std::size_t i = 0; i < Block::BLOCK_SIZE_BITS; i += 4) { const std::string sub = bits.substr(i, 4); ss << compressionMap[sub]; } diff --git a/GCryptLib/src/GHash.cpp b/GCryptLib/src/GHash.cpp index 5ea48fa..9d1bc44 100644 --- a/GCryptLib/src/GHash.cpp +++ b/GCryptLib/src/GHash.cpp @@ -1,6 +1,7 @@ #include "GCrypt/GHash.h" #include "GCrypt/Util.h" #include "GCrypt/InitializationVector.h" +#include namespace Leonetienne::GCrypt { @@ -34,9 +35,9 @@ namespace Leonetienne::GCrypt { // Split input into blocks std::vector blocks; - for (std::size_t i = 0; i < data.size(); i += BLOCK_SIZE) { + for (std::size_t i = 0; i < data.size(); i += Block::BLOCK_SIZE_BITS) { blocks.push_back(Block( - PadStringToLength(data.substr(i, BLOCK_SIZE), BLOCK_SIZE, '0', false)) + PadStringToLength(data.substr(i, Block::BLOCK_SIZE_BITS), Block::BLOCK_SIZE_BITS, '0', false)) ); } diff --git a/GCryptLib/src/GPrng.cpp b/GCryptLib/src/GPrng.cpp index a89b9cd..f54728f 100644 --- a/GCryptLib/src/GPrng.cpp +++ b/GCryptLib/src/GPrng.cpp @@ -21,7 +21,7 @@ namespace Leonetienne::GCrypt { bool GPrng::GetBit() { // If we have no more bits to go, create new ones - if (nextBit >= BLOCK_SIZE) { + if (nextBit >= Block::BLOCK_SIZE_BITS) { AdvanceBlock(); } @@ -51,18 +51,18 @@ namespace Leonetienne::GCrypt { // Slurp up the rest of the current block std::stringstream ss; - const std::size_t bitsLeft = BLOCK_SIZE - nextBit; + const std::size_t bitsLeft = Block::BLOCK_SIZE_BITS - nextBit; ss << hasher.GetHashsum().ToString().substr(nextBit, bitsLeft); // Now we have to advance to the next block AdvanceBlock(); // Now, grab the remaining bits - const std::size_t remainingBits = BLOCK_SIZE - bitsLeft; + const std::size_t remainingBits = Block::BLOCK_SIZE_BITS - bitsLeft; ss << hasher.GetHashsum().ToString().substr(0, remainingBits); // Assert that we have the correct number of bits - assert(ss.str().length() == BLOCK_SIZE); + assert(ss.str().length() == Block::BLOCK_SIZE_BITS); // Set out bitpointer nextBit = remainingBits; diff --git a/GCryptLib/src/GWrapper.cpp b/GCryptLib/src/GWrapper.cpp index eacc8bb..76720a3 100644 --- a/GCryptLib/src/GWrapper.cpp +++ b/GCryptLib/src/GWrapper.cpp @@ -1,6 +1,7 @@ #include "GCrypt/GWrapper.h" #include "GCrypt/GCipher.h" #include "GCrypt/Util.h" +#include namespace Leonetienne::GCrypt { @@ -92,9 +93,9 @@ namespace Leonetienne::GCrypt { // Split input into blocks std::vector blocks; - for (std::size_t i = 0; i < data.size(); i += BLOCK_SIZE) { + for (std::size_t i = 0; i < data.size(); i += Block::BLOCK_SIZE_BITS) { blocks.push_back(Block( - PadStringToLength(data.substr(i, BLOCK_SIZE), BLOCK_SIZE, '0', false)) + PadStringToLength(data.substr(i, Block::BLOCK_SIZE_BITS), Block::BLOCK_SIZE_BITS, '0', false)) ); } diff --git a/GCryptLib/src/Key.cpp b/GCryptLib/src/Key.cpp index 0356b0b..97ecb4d 100644 --- a/GCryptLib/src/Key.cpp +++ b/GCryptLib/src/Key.cpp @@ -21,12 +21,12 @@ namespace Leonetienne::GCrypt { // Fetch BLOCK_SIZE bits std::stringstream ss; - for (std::size_t i = 0; i < BLOCK_SIZE / bitsPerCall; i++) { + for (std::size_t i = 0; i < Key::BLOCK_SIZE_BITS / bitsPerCall; i++) { ss << std::bitset(rng()); } // Verify that we actually have the correct size - assert(ss.str().length() == BLOCK_SIZE); + assert(ss.str().length() == Key::BLOCK_SIZE_BITS); // Return them as a key return Key(Block(ss.str())); @@ -34,7 +34,7 @@ namespace Leonetienne::GCrypt { Key Key::LoadFromFile(const std::string& path) { // Read this many chars - const std::size_t maxChars = BLOCK_SIZE / 8; + const std::size_t maxChars = Key::BLOCK_SIZE_BITS / 8; // Open ifilestream for keyfile std::ifstream ifs(path, std::ios::in | std::ios::binary); @@ -73,7 +73,7 @@ namespace Leonetienne::GCrypt { std::ofstream ofs(path, std::ios::out | std::ios::binary); // Write the key - ofs.write(keybytes.data(), BLOCK_SIZE/8); + ofs.write(keybytes.data(), Key::BLOCK_SIZE_BITS / 8); // Close the file handle ofs.close(); diff --git a/GCryptLib/src/Util.cpp b/GCryptLib/src/Util.cpp index 9c315e5..3caaa06 100644 --- a/GCryptLib/src/Util.cpp +++ b/GCryptLib/src/Util.cpp @@ -37,7 +37,7 @@ namespace Leonetienne::GCrypt { } // Pad rest with zeores - return Block(PadStringToLength(ss.str(), BLOCK_SIZE, '0', padLeft)); + return Block(PadStringToLength(ss.str(), Block::BLOCK_SIZE_BITS, '0', padLeft)); } Flexblock StringToBits(const std::string& s) { @@ -55,7 +55,7 @@ namespace Leonetienne::GCrypt { const std::string bitstring = bits.ToString(); - for (std::size_t i = 0; i < BLOCK_SIZE; i += 8) { + for (std::size_t i = 0; i < Block::BLOCK_SIZE_BITS; i += 8) { ss << (char)std::bitset<8>(bitstring.substr(i, 8)).to_ulong(); }