From f7d80936682d69f9077e23817a876863c239da03 Mon Sep 17 00:00:00 2001 From: Leonetienne Date: Wed, 25 May 2022 16:38:16 +0200 Subject: [PATCH] Templatified block class --- GCryptLib/include/GCrypt/Block.h | 99 ++++++++------- GCryptLib/src/Block.cpp | 207 +++++++++++++++++++------------ 2 files changed, 183 insertions(+), 123 deletions(-) diff --git a/GCryptLib/include/GCrypt/Block.h b/GCryptLib/include/GCrypt/Block.h index b28748a..e87d337 100644 --- a/GCryptLib/include/GCrypt/Block.h +++ b/GCryptLib/include/GCrypt/Block.h @@ -5,24 +5,26 @@ #include #include #include +#include namespace Leonetienne::GCrypt { /* This class represents a block of data, * and provides functions to manipulate it */ - class Block { + template + class Basic_Block { public: //! Will constuct an uninitialized data block - Block(); + Basic_Block(); //! Will construct this block from a string like "101010".. Length MUST be 512. - Block(const std::string& other); + Basic_Block(const std::string& other); //! Copy-ctor - Block(const Block& other); + Basic_Block(const Basic_Block& other); - ~Block(); + ~Basic_Block(); //! Will construct this block from a string like "011101..". Length MUST be 512. void FromString(const std::string& str); @@ -35,90 +37,90 @@ namespace Leonetienne::GCrypt { //! Since the matrices values are pretty much sudo-random, //! they will most likely integer-overflow. //! So see this as a one-way function. - [[nodiscard]] Block MMul(const Block& other) const; - [[nodiscard]] Block operator*(const Block& other) const; + [[nodiscard]] Basic_Block MMul(const Basic_Block& other) const; + [[nodiscard]] Basic_Block operator*(const Basic_Block& other) const; //! Will matrix-multiply two blocks together, //! and directly write into this same block. //! Since the matrices values are pretty much sudo-random, //! they will most likely integer-overflow. //! So see this as a one-way function. - void MMulInplace(const Block& other); - Block& operator*=(const Block& other); + void MMulInplace(const Basic_Block& other); + Basic_Block& operator*=(const Basic_Block& other); //! Will xor two blocks together - [[nodiscard]] Block Xor(const Block& other) const; + [[nodiscard]] Basic_Block Xor(const Basic_Block& other) const; //! Will xor two blocks together - [[nodiscard]] Block operator^(const Block& other) const; + [[nodiscard]] Basic_Block operator^(const Basic_Block& other) const; //! Will xor two blocks together, inplace - void XorInplace(const Block& other); + void XorInplace(const Basic_Block& other); //! Will xor two blocks together, inplace - Block& operator^=(const Block& other); + Basic_Block& operator^=(const Basic_Block& other); //! Will add all the integer making up this block, one by one - [[nodiscard]] Block Add(const Block& other) const; + [[nodiscard]] Basic_Block Add(const Basic_Block& other) const; //! Will add all the integer making up this block, one by one - [[nodiscard]] Block operator+(const Block& other) const; + [[nodiscard]] Basic_Block operator+(const Basic_Block& other) const; //! Will add all the integer making up this block, one by one, inplace - void AddInplace(const Block& other); + void AddInplace(const Basic_Block& other); //! Will add all the integer making up this block, one by one, inplace - Block& operator+=(const Block& other); + Basic_Block& operator+=(const Basic_Block& other); //! Will subtract all the integer making up this block, one by one - [[nodiscard]] Block Sub(const Block& other) const; + [[nodiscard]] Basic_Block Sub(const Basic_Block& other) const; //! Will subtract all the integer making up this block, one by one - [[nodiscard]] Block operator-(const Block& other) const; + [[nodiscard]] Basic_Block operator-(const Basic_Block& other) const; //! Will subtract all the integer making up this block, one by one, inplace - void SubInplace(const Block& other); + void SubInplace(const Basic_Block& other); //! Will subtract all the integer making up this block, one by one, inplace - Block& operator-=(const Block& other); + Basic_Block& operator-=(const Basic_Block& other); //! Will shift rows upwards by 1 - [[nodiscard]] Block ShiftRowsUp() const; + [[nodiscard]] Basic_Block ShiftRowsUp() const; //! Will shift rows upwards by 1 void ShiftRowsUpInplace(); //! Will shift matrix rows downwards by 1 - [[nodiscard]] Block ShiftRowsDown() const; + [[nodiscard]] Basic_Block ShiftRowsDown() const; //! Will shift matrix rows downwards by 1 void ShiftRowsDownInplace(); //! Will shift matrix columns to the left by 1 - [[nodiscard]] Block ShiftColumnsLeft() const; + [[nodiscard]] Basic_Block ShiftColumnsLeft() const; //! Will shift matrix columns to the left by 1 void ShiftColumnsLeftInplace(); //! Will shift matrix columns to the right by 1 - [[nodiscard]] Block ShiftColumnsRight() const; + [[nodiscard]] Basic_Block ShiftColumnsRight() const; //! Will shift matrix columns to the right by 1 void ShiftColumnsRightInplace(); //! Will shift array cells to the left by 1 - [[nodiscard]] Block ShiftCellsLeft() const; + [[nodiscard]] Basic_Block ShiftCellsLeft() const; //! Will shift array cells to the left by 1 void ShiftCellsLeftInplace(); //! Will shift array cells to the right by 1 - [[nodiscard]] Block ShiftCellsRight() const; + [[nodiscard]] Basic_Block ShiftCellsRight() const; //! Will shift array cells to the right by 1 void ShiftCellsRightInplace(); //! Will copy a block - Block& operator=(const Block& other); + Basic_Block& operator=(const Basic_Block& other); //! Will compare whether or not two blocks are equal - [[nodiscard]] bool operator==(const Block& other) const; + [[nodiscard]] bool operator==(const Basic_Block& other) const; //! Will compare whether or not two blocks are unequal - [[nodiscard]] bool operator!=(const Block& other) const; + [[nodiscard]] bool operator!=(const Basic_Block& other) const; //! Will zero all data void Reset(); @@ -133,46 +135,59 @@ namespace Leonetienne::GCrypt { void FlipBit(const std::size_t index); //! Will shift all bits to the left by 1 - [[nodiscard]] Block ShiftBitsLeft() const; + [[nodiscard]] Basic_Block ShiftBitsLeft() const; //! Will shift all bits to the left by 1, inplace void ShiftBitsLeftInplace(); //! Will shift all bits to the right by 1 - [[nodiscard]] Block ShiftBitsRight() const; + [[nodiscard]] Basic_Block ShiftBitsRight() const; //! Will shift all bits to the right by 1, inplace void ShiftBitsRightInplace(); //! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3) - [[nodiscard]] std::uint32_t& Get(const std::uint8_t row, const std::uint8_t column); + [[nodiscard]] T& Get(const std::uint8_t row, const std::uint8_t column); //! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3) - [[nodiscard]] const std::uint32_t& Get(const std::uint8_t row, const std::uint8_t column) const; + [[nodiscard]] const T& Get(const std::uint8_t row, const std::uint8_t column) const; //! Returns 32-bit chunks of data, indexed by a 1d-index (0-16) - [[nodiscard]] std::uint32_t& Get(const std::uint8_t index); + [[nodiscard]] T& Get(const std::uint8_t index); //! Returns 32-bit chunks of data, indexed by a 1d-index (0-16) - [[nodiscard]] const std::uint32_t& Get(const std::uint8_t index) const; + [[nodiscard]] const T& Get(const std::uint8_t index) const; //! Returns 32-bit chunks of data, indexed by a 1d-index (0-16) - [[nodiscard]] std::uint32_t& operator[](const std::uint8_t index); + [[nodiscard]] T& operator[](const std::uint8_t index); //! Returns 32-bit chunks of data, indexed by a 1d-index (0-16) - [[nodiscard]] const std::uint32_t& operator[](const std::uint8_t index) const; + [[nodiscard]] const T& operator[](const std::uint8_t index) const; - static constexpr std::size_t CHUNK_SIZE = sizeof(std::uint32_t); + static constexpr std::size_t CHUNK_SIZE = sizeof(T); static constexpr std::size_t CHUNK_SIZE_BITS = CHUNK_SIZE * 8; - friend std::ostream& operator<<(std::ostream& os, const Block& b); + friend std::ostream& operator<<(std::ostream& os, const Basic_Block& b) { + for (std::size_t i = 0; i < b.data.size(); i++) { + os << std::bitset::CHUNK_SIZE_BITS>(b.data[i]).to_string(); + } + return os; + } private: - std::array data; + std::array data; }; -} + // Instantiate templates + template class Basic_Block; + //template class Basic_Block; + //! This a full-sizes 512-bit block + typedef Basic_Block Block; + + //! This is a half-block used within the feistel class + //typedef Basic_Block Halfblock; +} #endif diff --git a/GCryptLib/src/Block.cpp b/GCryptLib/src/Block.cpp index 39cf60b..6398949 100644 --- a/GCryptLib/src/Block.cpp +++ b/GCryptLib/src/Block.cpp @@ -2,7 +2,6 @@ #include "GCrypt/Config.h" #include "GCrypt/Util.h" #include -#include #include #include @@ -12,18 +11,22 @@ namespace Leonetienne::GCrypt { - Block::Block() { + template + Basic_Block::Basic_Block() { } - Block::Block(const std::string& str) { + template + Basic_Block::Basic_Block(const std::string& str) { FromString(str); } - Block::Block(const Block& other) { + template + Basic_Block::Basic_Block(const Basic_Block& other) { data = other.data; } - void Block::FromString(const std::string& str) { + template + void Basic_Block::FromString(const std::string& str) { assert(str.length() == BLOCK_SIZE); @@ -36,7 +39,8 @@ namespace Leonetienne::GCrypt { return; } - std::string Block::ToString() const { + template + std::string Basic_Block::ToString() const { std::stringstream ss; for (std::size_t i = 0; i < data.size(); i++) { @@ -45,9 +49,10 @@ namespace Leonetienne::GCrypt { return ss.str(); } - Block Block::MMul(const Block& o) const { + template + Basic_Block Basic_Block::MMul(const Basic_Block& o) const { - Block m; + Basic_Block m; // Maybe pre-calculate the 1d-index...? @@ -74,13 +79,15 @@ namespace Leonetienne::GCrypt { return m; } - Block Block::operator*(const Block& other) const { + template + Basic_Block Basic_Block::operator*(const Basic_Block& other) const { return this->MMul(other); } - void Block::MMulInplace(const Block& o) { + template + void Basic_Block::MMulInplace(const Basic_Block& o) { - Block m = *this; + Basic_Block m = *this; // Maybe pre-calculate the 1d-index...? @@ -107,86 +114,102 @@ namespace Leonetienne::GCrypt { return; } - Block& Block::operator*=(const Block& other) { + template + Basic_Block& Basic_Block::operator*=(const Basic_Block& other) { MMulInplace(other); return *this; } - Block Block::Xor(const Block& other) const { + template + Basic_Block Basic_Block::Xor(const Basic_Block& other) const { - Block m; + Basic_Block m; for (std::size_t i = 0; i < data.size(); i++) { m.Get(i) = this->Get(i) ^ other.Get(i); } return m; } - Block Block::operator^(const Block& other) const { + template + Basic_Block Basic_Block::operator^(const Basic_Block& other) const { return Xor(other); } - void Block::XorInplace(const Block& other) { + template + void Basic_Block::XorInplace(const Basic_Block& other) { for (std::size_t i = 0; i < data.size(); i++) { this->Get(i) ^= other.Get(i); } return; } - Block& Block::operator^=(const Block& other) { + template + Basic_Block& Basic_Block::operator^=(const Basic_Block& other) { XorInplace(other); - return *this; } - Block Block::Add(const Block& other) const { + return *this; + } - Block m; + template + Basic_Block Basic_Block::Add(const Basic_Block& other) const { + + Basic_Block m; for (std::size_t i = 0; i < data.size(); i++) { m.Get(i) = this->Get(i) + other.Get(i); } return m; } - Block Block::operator+(const Block& other) const { + template + Basic_Block Basic_Block::operator+(const Basic_Block& other) const { return Add(other); } - void Block::AddInplace(const Block& other) { + template + void Basic_Block::AddInplace(const Basic_Block& other) { for (std::size_t i = 0; i < data.size(); i++) { this->Get(i) += other.Get(i); } return; } - Block& Block::operator+=(const Block& other) { + template + Basic_Block& Basic_Block::operator+=(const Basic_Block& other) { AddInplace(other); return *this; } - Block Block::Sub(const Block& other) const { + template + Basic_Block Basic_Block::Sub(const Basic_Block& other) const { - Block m; + Basic_Block m; for (std::size_t i = 0; i < data.size(); i++) { m.Get(i) = this->Get(i) - other.Get(i); } return m; } - Block Block::operator-(const Block& other) const { + template + Basic_Block Basic_Block::operator-(const Basic_Block& other) const { return Sub(other); } - void Block::SubInplace(const Block& other) { + template + void Basic_Block::SubInplace(const Basic_Block& other) { for (std::size_t i = 0; i < data.size(); i++) { this->Get(i) -= other.Get(i); } return; } - Block& Block::operator-=(const Block& other) { + template + Basic_Block& Basic_Block::operator-=(const Basic_Block& other) { SubInplace(other); return *this; } - void Block::ShiftRowsUpInplace() { - Block tmp = *this; + template + void Basic_Block::ShiftRowsUpInplace() { + Basic_Block tmp = *this; Get(MAT_INDEX(0, 0)) = tmp.Get(MAT_INDEX(1, 0)); Get(MAT_INDEX(0, 1)) = tmp.Get(MAT_INDEX(1, 1)); @@ -211,8 +234,9 @@ namespace Leonetienne::GCrypt { return; } - Block Block::ShiftRowsUp() const { - Block b; + template + Basic_Block Basic_Block::ShiftRowsUp() const { + Basic_Block b; b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(1, 0)); b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(1, 1)); @@ -237,8 +261,9 @@ namespace Leonetienne::GCrypt { return b; } - void Block::ShiftRowsDownInplace() { - Block tmp = *this; + template + void Basic_Block::ShiftRowsDownInplace() { + Basic_Block tmp = *this; Get(MAT_INDEX(0, 0)) = tmp.Get(MAT_INDEX(3, 0)); Get(MAT_INDEX(0, 1)) = tmp.Get(MAT_INDEX(3, 1)); @@ -263,8 +288,9 @@ namespace Leonetienne::GCrypt { return; } - Block Block::ShiftRowsDown() const { - Block b; + template + Basic_Block Basic_Block::ShiftRowsDown() const { + Basic_Block b; b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(3, 0)); b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(3, 1)); @@ -289,8 +315,9 @@ namespace Leonetienne::GCrypt { return b; } - void Block::ShiftColumnsLeftInplace() { - Block tmp = *this; + template + void Basic_Block::ShiftColumnsLeftInplace() { + Basic_Block tmp = *this; Get(MAT_INDEX(0, 0)) = tmp.Get(MAT_INDEX(0, 1)); Get(MAT_INDEX(1, 0)) = tmp.Get(MAT_INDEX(1, 1)); @@ -315,8 +342,9 @@ namespace Leonetienne::GCrypt { return; } - Block Block::ShiftColumnsLeft() const { - Block b; + template + Basic_Block Basic_Block::ShiftColumnsLeft() const { + Basic_Block b; b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(0, 1)); b.Get(MAT_INDEX(1, 0)) = Get(MAT_INDEX(1, 1)); @@ -341,8 +369,9 @@ namespace Leonetienne::GCrypt { return b; } - void Block::ShiftColumnsRightInplace() { - Block tmp = *this; + template + void Basic_Block::ShiftColumnsRightInplace() { + Basic_Block tmp = *this; Get(MAT_INDEX(0, 1)) = tmp.Get(MAT_INDEX(0, 0)); Get(MAT_INDEX(1, 1)) = tmp.Get(MAT_INDEX(1, 0)); @@ -367,8 +396,9 @@ namespace Leonetienne::GCrypt { return; } - Block Block::ShiftColumnsRight() const { - Block b; + template + Basic_Block Basic_Block::ShiftColumnsRight() const { + Basic_Block b; b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(0, 0)); b.Get(MAT_INDEX(1, 1)) = Get(MAT_INDEX(1, 0)); @@ -393,8 +423,9 @@ namespace Leonetienne::GCrypt { return b; } - void Block::ShiftCellsLeftInplace() { - Block tmp = *this; + template + void Basic_Block::ShiftCellsLeftInplace() { + Basic_Block tmp = *this; Get(15) = tmp.Get(0); @@ -405,8 +436,9 @@ namespace Leonetienne::GCrypt { return; } - Block Block::ShiftCellsLeft() const { - Block b; + template + Basic_Block Basic_Block::ShiftCellsLeft() const { + Basic_Block b; b.Get(15) = Get(0); @@ -417,8 +449,9 @@ namespace Leonetienne::GCrypt { return b; } - void Block::ShiftCellsRightInplace() { - Block tmp = *this; + template + void Basic_Block::ShiftCellsRightInplace() { + Basic_Block tmp = *this; Get(0) = tmp.Get(15); @@ -429,8 +462,9 @@ namespace Leonetienne::GCrypt { return; } - Block Block::ShiftCellsRight() const { - Block b; + template + Basic_Block Basic_Block::ShiftCellsRight() const { + Basic_Block b; b.Get(0) = Get(15); @@ -441,12 +475,14 @@ namespace Leonetienne::GCrypt { return b; } - Block& Block::operator=(const Block& other) { + template + Basic_Block& Basic_Block::operator=(const Basic_Block& other) { data = other.data; return *this; } - bool Block::GetBit(const std::size_t index) const { + template + bool Basic_Block::GetBit(const std::size_t index) const { // Fetch index of integer the bit is located in const std::size_t intIndex = index / CHUNK_SIZE_BITS; @@ -459,7 +495,8 @@ namespace Leonetienne::GCrypt { return data[intIndex] & bitmask; } - void Block::SetBit(const std::size_t index, const bool state) { + template + void Basic_Block::SetBit(const std::size_t index, const bool state) { // Fetch index of integer the bit is located in const std::size_t intIndex = index / CHUNK_SIZE_BITS; @@ -481,7 +518,8 @@ namespace Leonetienne::GCrypt { return; } - void Block::FlipBit(const std::size_t index) { + template + void Basic_Block::FlipBit(const std::size_t index) { // Fetch index of integer the bit is located in const std::size_t intIndex = index / CHUNK_SIZE_BITS; @@ -496,8 +534,9 @@ namespace Leonetienne::GCrypt { return; } - Block Block::ShiftBitsLeft() const { - Block b; + template + Basic_Block Basic_Block::ShiftBitsLeft() const { + Basic_Block b; // First, copy this block over b = *this; @@ -529,8 +568,9 @@ namespace Leonetienne::GCrypt { return b; } - void Block::ShiftBitsLeftInplace() { - Block tmp = *this; + template + void Basic_Block::ShiftBitsLeftInplace() { + Basic_Block tmp = *this; // Then, shift all integers individually for (std::size_t i = 0; i < data.size(); i++) { @@ -559,8 +599,9 @@ namespace Leonetienne::GCrypt { return; } - Block Block::ShiftBitsRight() const { - Block b; + template + Basic_Block Basic_Block::ShiftBitsRight() const { + Basic_Block b; // First, copy this block over b = *this; @@ -592,8 +633,9 @@ namespace Leonetienne::GCrypt { return b; } - void Block::ShiftBitsRightInplace() { - Block tmp = *this; + template + void Basic_Block::ShiftBitsRightInplace() { + Basic_Block tmp = *this; // Then, shift all integers individually for (std::size_t i = 0; i < data.size(); i++) { @@ -622,56 +664,59 @@ namespace Leonetienne::GCrypt { return; } - std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column){ + template + T& Basic_Block::Get(const std::uint8_t row, const std::uint8_t column){ return data[MAT_INDEX(row, column)]; } - const std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column) const { + template + const T& Basic_Block::Get(const std::uint8_t row, const std::uint8_t column) const { return data[MAT_INDEX(row, column)]; } - std::uint32_t& Block::Get(const std::uint8_t index) { + template + T& Basic_Block::Get(const std::uint8_t index) { return data[index]; } - const std::uint32_t& Block::Get(const std::uint8_t index) const { + template + const T& Basic_Block::Get(const std::uint8_t index) const { return data[index]; } - std::uint32_t& Block::operator[](const std::uint8_t index) { + template + T& Basic_Block::operator[](const std::uint8_t index) { return data[index]; } - const std::uint32_t& Block::operator[](const std::uint8_t index) const { + template + const T& Basic_Block::operator[](const std::uint8_t index) const { return data[index]; } - bool Block::operator==(const Block& other) const { + template + bool Basic_Block::operator==(const Basic_Block& other) const { return data == other.data; } - bool Block::operator!=(const Block& other) const { + template + bool Basic_Block::operator!=(const Basic_Block& other) const { return data != other.data; } - std::ostream& operator<<(std::ostream& os, const Block& b) { - for (std::size_t i = 0; i < b.data.size(); i++) { - os << std::bitset(b.data[i]).to_string(); - } - return os; - } - #if defined _WIN32 || defined _WIN64 #pragma optimize("", off ) #elif defined __GNUG__ #pragma GCC push_options #pragma GCC optimize ("O0") #endif - Block::~Block() { + template + Basic_Block::~Basic_Block() { Reset(); } - void Block::Reset() { + template + void Basic_Block::Reset() { memset(data.data(), 0, CHUNK_SIZE*data.size()); return; }