[Progress:] Completely re-done Block class to not use bitsets, and provide custom operators.

This commit is contained in:
Leonetienne
2022-05-24 01:02:06 +02:00
parent ed45b69342
commit 939df4731b
11 changed files with 619 additions and 191 deletions

220
GCryptLib/src/Block.cpp Normal file
View File

@@ -0,0 +1,220 @@
#include "GCrypt/Block.h"
#include "GCrypt/Config.h"
#include <sstream>
#include <bitset>
#include <cassert>
#include <cstring>
namespace Leonetienne::GCrypt {
Block::Block() {
}
Block::Block(const std::string& str) {
FromString(str);
}
Block::Block(const Block& other) {
data = other.data;
}
void Block::FromString(const std::string& str) {
assert(str.length() == BLOCK_SIZE);
for (std::size_t i = 0; i < data.size(); i++) {
data[i] = std::bitset<CHUNK_SIZE_BITS>(
str.substr(i*CHUNK_SIZE_BITS, CHUNK_SIZE_BITS)
).to_ulong();
}
return;
}
std::string Block::ToString() const {
std::stringstream ss;
for (std::size_t i = 0; i < data.size(); i++) {
ss << std::bitset<CHUNK_SIZE_BITS>(data[i]).to_string();
}
return ss.str();
}
Block Block::MMul(const Block& o) const {
Block m;
m.Get(0, 0) = (this->Get(0, 0) * o.Get(0, 0)) + (this->Get(0, 1) * o.Get(1, 0)) + (this->Get(0, 2) * o.Get(2, 0)) + (this->Get(0, 3) * o.Get(3, 0));
m.Get(0, 1) = (this->Get(0, 0) * o.Get(0, 1)) + (this->Get(0, 1) * o.Get(1, 1)) + (this->Get(0, 2) * o.Get(2, 1)) + (this->Get(0, 3) * o.Get(3, 1));
m.Get(0, 2) = (this->Get(0, 0) * o.Get(0, 2)) + (this->Get(0, 1) * o.Get(1, 2)) + (this->Get(0, 2) * o.Get(2, 2)) + (this->Get(0, 3) * o.Get(3, 2));
m.Get(0, 3) = (this->Get(0, 0) * o.Get(0, 3)) + (this->Get(0, 1) * o.Get(1, 3)) + (this->Get(0, 2) * o.Get(2, 3)) + (this->Get(0, 3) * o.Get(3, 3));
m.Get(1, 0) = (this->Get(1, 0) * o.Get(0, 0)) + (this->Get(1, 1) * o.Get(1, 0)) + (this->Get(1, 2) * o.Get(2, 0)) + (this->Get(1, 3) * o.Get(3, 0));
m.Get(1, 1) = (this->Get(1, 0) * o.Get(0, 1)) + (this->Get(1, 1) * o.Get(1, 1)) + (this->Get(1, 2) * o.Get(2, 1)) + (this->Get(1, 3) * o.Get(3, 1));
m.Get(1, 2) = (this->Get(1, 0) * o.Get(0, 2)) + (this->Get(1, 1) * o.Get(1, 2)) + (this->Get(1, 2) * o.Get(2, 2)) + (this->Get(1, 3) * o.Get(3, 2));
m.Get(1, 3) = (this->Get(1, 0) * o.Get(0, 3)) + (this->Get(1, 1) * o.Get(1, 3)) + (this->Get(1, 2) * o.Get(2, 3)) + (this->Get(1, 3) * o.Get(3, 3));
m.Get(2, 0) = (this->Get(2, 0) * o.Get(0, 0)) + (this->Get(2, 1) * o.Get(1, 0)) + (this->Get(2, 2) * o.Get(2, 0)) + (this->Get(2, 3) * o.Get(3, 0));
m.Get(2, 1) = (this->Get(2, 0) * o.Get(0, 1)) + (this->Get(2, 1) * o.Get(1, 1)) + (this->Get(2, 2) * o.Get(2, 1)) + (this->Get(2, 3) * o.Get(3, 1));
m.Get(2, 2) = (this->Get(2, 0) * o.Get(0, 2)) + (this->Get(2, 1) * o.Get(1, 2)) + (this->Get(2, 2) * o.Get(2, 2)) + (this->Get(2, 3) * o.Get(3, 2));
m.Get(2, 3) = (this->Get(2, 0) * o.Get(0, 3)) + (this->Get(2, 1) * o.Get(1, 3)) + (this->Get(2, 2) * o.Get(2, 3)) + (this->Get(2, 3) * o.Get(3, 3));
m.Get(3, 0) = (this->Get(3, 0) * o.Get(0, 0)) + (this->Get(3, 1) * o.Get(1, 0)) + (this->Get(3, 2) * o.Get(2, 0)) + (this->Get(3, 3) * o.Get(3, 0));
m.Get(3, 1) = (this->Get(3, 0) * o.Get(0, 1)) + (this->Get(3, 1) * o.Get(1, 1)) + (this->Get(3, 2) * o.Get(2, 1)) + (this->Get(3, 3) * o.Get(3, 1));
m.Get(3, 2) = (this->Get(3, 0) * o.Get(0, 2)) + (this->Get(3, 1) * o.Get(1, 2)) + (this->Get(3, 2) * o.Get(2, 2)) + (this->Get(3, 3) * o.Get(3, 2));
m.Get(3, 3) = (this->Get(3, 0) * o.Get(0, 3)) + (this->Get(3, 1) * o.Get(1, 3)) + (this->Get(3, 2) * o.Get(2, 3)) + (this->Get(3, 3) * o.Get(3, 3));
return m;
}
Block Block::operator*(const Block& other) const {
return this->MMul(other);
}
void Block::MMulInplace(const Block& o) {
Block m = *this;
this->Get(0, 0) = (m.Get(0, 0) * o.Get(0, 0)) + (m.Get(0, 1) * o.Get(1, 0)) + (m.Get(0, 2) * o.Get(2, 0)) + (m.Get(0, 3) * o.Get(3, 0));
this->Get(0, 1) = (m.Get(0, 0) * o.Get(0, 1)) + (m.Get(0, 1) * o.Get(1, 1)) + (m.Get(0, 2) * o.Get(2, 1)) + (m.Get(0, 3) * o.Get(3, 1));
this->Get(0, 2) = (m.Get(0, 0) * o.Get(0, 2)) + (m.Get(0, 1) * o.Get(1, 2)) + (m.Get(0, 2) * o.Get(2, 2)) + (m.Get(0, 3) * o.Get(3, 2));
this->Get(0, 3) = (m.Get(0, 0) * o.Get(0, 3)) + (m.Get(0, 1) * o.Get(1, 3)) + (m.Get(0, 2) * o.Get(2, 3)) + (m.Get(0, 3) * o.Get(3, 3));
this->Get(1, 0) = (m.Get(1, 0) * o.Get(0, 0)) + (m.Get(1, 1) * o.Get(1, 0)) + (m.Get(1, 2) * o.Get(2, 0)) + (m.Get(1, 3) * o.Get(3, 0));
this->Get(1, 1) = (m.Get(1, 0) * o.Get(0, 1)) + (m.Get(1, 1) * o.Get(1, 1)) + (m.Get(1, 2) * o.Get(2, 1)) + (m.Get(1, 3) * o.Get(3, 1));
this->Get(1, 2) = (m.Get(1, 0) * o.Get(0, 2)) + (m.Get(1, 1) * o.Get(1, 2)) + (m.Get(1, 2) * o.Get(2, 2)) + (m.Get(1, 3) * o.Get(3, 2));
this->Get(1, 3) = (m.Get(1, 0) * o.Get(0, 3)) + (m.Get(1, 1) * o.Get(1, 3)) + (m.Get(1, 2) * o.Get(2, 3)) + (m.Get(1, 3) * o.Get(3, 3));
this->Get(2, 0) = (m.Get(2, 0) * o.Get(0, 0)) + (m.Get(2, 1) * o.Get(1, 0)) + (m.Get(2, 2) * o.Get(2, 0)) + (m.Get(2, 3) * o.Get(3, 0));
this->Get(2, 1) = (m.Get(2, 0) * o.Get(0, 1)) + (m.Get(2, 1) * o.Get(1, 1)) + (m.Get(2, 2) * o.Get(2, 1)) + (m.Get(2, 3) * o.Get(3, 1));
this->Get(2, 2) = (m.Get(2, 0) * o.Get(0, 2)) + (m.Get(2, 1) * o.Get(1, 2)) + (m.Get(2, 2) * o.Get(2, 2)) + (m.Get(2, 3) * o.Get(3, 2));
this->Get(2, 3) = (m.Get(2, 0) * o.Get(0, 3)) + (m.Get(2, 1) * o.Get(1, 3)) + (m.Get(2, 2) * o.Get(2, 3)) + (m.Get(2, 3) * o.Get(3, 3));
this->Get(3, 0) = (m.Get(3, 0) * o.Get(0, 0)) + (m.Get(3, 1) * o.Get(1, 0)) + (m.Get(3, 2) * o.Get(2, 0)) + (m.Get(3, 3) * o.Get(3, 0));
this->Get(3, 1) = (m.Get(3, 0) * o.Get(0, 1)) + (m.Get(3, 1) * o.Get(1, 1)) + (m.Get(3, 2) * o.Get(2, 1)) + (m.Get(3, 3) * o.Get(3, 1));
this->Get(3, 2) = (m.Get(3, 0) * o.Get(0, 2)) + (m.Get(3, 1) * o.Get(1, 2)) + (m.Get(3, 2) * o.Get(2, 2)) + (m.Get(3, 3) * o.Get(3, 2));
this->Get(3, 3) = (m.Get(3, 0) * o.Get(0, 3)) + (m.Get(3, 1) * o.Get(1, 3)) + (m.Get(3, 2) * o.Get(2, 3)) + (m.Get(3, 3) * o.Get(3, 3));
return;
}
Block& Block::operator*=(const Block& other) {
MMulInplace(other);
return *this;
}
Block Block::Xor(const Block& other) const {
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 {
return Xor(other);
}
void Block::XorInplace(const 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) {
XorInplace(other);
return *this;
}
void ShiftRowsUp(const std::size_t n) {
// TO BE IMPLEMENTED
}
void ShiftRowsDown(const std::size_t n) {
// TO BE IMPLEMENTED
}
void ShiftColumnsLeft(const std::size_t n) {
// TO BE IMPLEMENTED
}
void ShiftColumnsRight(const std::size_t n) {
// TO BE IMPLEMENTED
}
void ShiftCellsLeft(const std::size_t n) {
// TO BE IMPLEMENTED
}
void ShiftCellsRight(const std::size_t n) {
// TO BE IMPLEMENTED
}
Block& Block::operator=(const Block& other) {
data = other.data;
return *this;
}
std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column){
return data[column*4 + row];
}
const std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column) const {
return data[column*4 + row];
}
std::uint32_t& Block::Get(const std::uint8_t index) {
return data[index];
}
const std::uint32_t& Block::Get(const std::uint8_t index) const {
return data[index];
}
std::uint32_t& Block::operator[](const std::uint8_t index) {
return data[index];
}
const std::uint32_t& Block::operator[](const std::uint8_t index) const {
return data[index];
}
bool Block::operator==(const Block& other) const {
return data == other.data;
}
bool Block::operator!=(const 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.CHUNK_SIZE_BITS>(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() {
Reset();
}
void Block::Reset() {
memset(data.data(), 0, CHUNK_SIZE*data.size());
return;
}
#if defined _WIN32 || defined _WIN64
#pragma optimize("", on )
#elif defined __GNUG__
#pragma GCC pop_options
#endif
}

View File

@@ -1,114 +0,0 @@
#include "GCrypt/BlockMatrix.h"
#include <sstream>
namespace Leonetienne::GCrypt {
BlockMatrix::BlockMatrix() {
}
BlockMatrix::BlockMatrix(const Block& block) {
FromBlock(block);
}
BlockMatrix::BlockMatrix(const BlockMatrix& other) {
data = other.data;
}
void BlockMatrix::FromBlock(const Block& block) {
const std::string blockstr = block.to_string();
constexpr std::size_t cellSize = sizeof(std::uint32_t)*8;
for (std::size_t i = 0; i < 16; i++) {
data[i] = std::bitset<cellSize>(blockstr.substr(i*cellSize, cellSize)).to_ulong();
}
return;
}
Block BlockMatrix::ToBlock() const {
std::stringstream ss;
constexpr std::size_t cellSize = sizeof(std::uint32_t)*8;
for (std::size_t i = 0; i < 16; i++) {
ss << std::bitset<cellSize>(data[i]).to_string();
}
return Block(ss.str());
}
BlockMatrix BlockMatrix::MMult(const BlockMatrix& o) const {
BlockMatrix m;
m.Get(0, 0) = (this->Get(0, 0) * o.Get(0, 0)) + (this->Get(0, 1) * o.Get(1, 0)) + (this->Get(0, 2) * o.Get(2, 0)) + (this->Get(0, 3) * o.Get(3, 0));
m.Get(0, 1) = (this->Get(0, 0) * o.Get(0, 1)) + (this->Get(0, 1) * o.Get(1, 1)) + (this->Get(0, 2) * o.Get(2, 1)) + (this->Get(0, 3) * o.Get(3, 1));
m.Get(0, 2) = (this->Get(0, 0) * o.Get(0, 2)) + (this->Get(0, 1) * o.Get(1, 2)) + (this->Get(0, 2) * o.Get(2, 2)) + (this->Get(0, 3) * o.Get(3, 2));
m.Get(0, 3) = (this->Get(0, 0) * o.Get(0, 3)) + (this->Get(0, 1) * o.Get(1, 3)) + (this->Get(0, 2) * o.Get(2, 3)) + (this->Get(0, 3) * o.Get(3, 3));
m.Get(1, 0) = (this->Get(1, 0) * o.Get(0, 0)) + (this->Get(1, 1) * o.Get(1, 0)) + (this->Get(1, 2) * o.Get(2, 0)) + (this->Get(1, 3) * o.Get(3, 0));
m.Get(1, 1) = (this->Get(1, 0) * o.Get(0, 1)) + (this->Get(1, 1) * o.Get(1, 1)) + (this->Get(1, 2) * o.Get(2, 1)) + (this->Get(1, 3) * o.Get(3, 1));
m.Get(1, 2) = (this->Get(1, 0) * o.Get(0, 2)) + (this->Get(1, 1) * o.Get(1, 2)) + (this->Get(1, 2) * o.Get(2, 2)) + (this->Get(1, 3) * o.Get(3, 2));
m.Get(1, 3) = (this->Get(1, 0) * o.Get(0, 3)) + (this->Get(1, 1) * o.Get(1, 3)) + (this->Get(1, 2) * o.Get(2, 3)) + (this->Get(1, 3) * o.Get(3, 3));
m.Get(2, 0) = (this->Get(2, 0) * o.Get(0, 0)) + (this->Get(2, 1) * o.Get(1, 0)) + (this->Get(2, 2) * o.Get(2, 0)) + (this->Get(2, 3) * o.Get(3, 0));
m.Get(2, 1) = (this->Get(2, 0) * o.Get(0, 1)) + (this->Get(2, 1) * o.Get(1, 1)) + (this->Get(2, 2) * o.Get(2, 1)) + (this->Get(2, 3) * o.Get(3, 1));
m.Get(2, 2) = (this->Get(2, 0) * o.Get(0, 2)) + (this->Get(2, 1) * o.Get(1, 2)) + (this->Get(2, 2) * o.Get(2, 2)) + (this->Get(2, 3) * o.Get(3, 2));
m.Get(2, 3) = (this->Get(2, 0) * o.Get(0, 3)) + (this->Get(2, 1) * o.Get(1, 3)) + (this->Get(2, 2) * o.Get(2, 3)) + (this->Get(2, 3) * o.Get(3, 3));
m.Get(3, 0) = (this->Get(3, 0) * o.Get(0, 0)) + (this->Get(3, 1) * o.Get(1, 0)) + (this->Get(3, 2) * o.Get(2, 0)) + (this->Get(3, 3) * o.Get(3, 0));
m.Get(3, 1) = (this->Get(3, 0) * o.Get(0, 1)) + (this->Get(3, 1) * o.Get(1, 1)) + (this->Get(3, 2) * o.Get(2, 1)) + (this->Get(3, 3) * o.Get(3, 1));
m.Get(3, 2) = (this->Get(3, 0) * o.Get(0, 2)) + (this->Get(3, 1) * o.Get(1, 2)) + (this->Get(3, 2) * o.Get(2, 2)) + (this->Get(3, 3) * o.Get(3, 2));
m.Get(3, 3) = (this->Get(3, 0) * o.Get(0, 3)) + (this->Get(3, 1) * o.Get(1, 3)) + (this->Get(3, 2) * o.Get(2, 3)) + (this->Get(3, 3) * o.Get(3, 3));
return m;
}
BlockMatrix BlockMatrix::operator*(const BlockMatrix& other) const {
return this->MMult(other);
}
BlockMatrix BlockMatrix::MXor(const BlockMatrix& o) const {
BlockMatrix m;
m.Get(0, 0) = this->Get(0, 0) ^ o.Get(0, 0) ^ this->Get(0, 1) ^ o.Get(1, 0) ^ this->Get(0, 2) ^ o.Get(2, 0) ^ this->Get(0, 3) ^ o.Get(3, 0);
m.Get(0, 1) = this->Get(0, 0) ^ o.Get(0, 1) ^ this->Get(0, 1) ^ o.Get(1, 1) ^ this->Get(0, 2) ^ o.Get(2, 1) ^ this->Get(0, 3) ^ o.Get(3, 1);
m.Get(0, 2) = this->Get(0, 0) ^ o.Get(0, 2) ^ this->Get(0, 1) ^ o.Get(1, 2) ^ this->Get(0, 2) ^ o.Get(2, 2) ^ this->Get(0, 3) ^ o.Get(3, 2);
m.Get(0, 3) = this->Get(0, 0) ^ o.Get(0, 3) ^ this->Get(0, 1) ^ o.Get(1, 3) ^ this->Get(0, 2) ^ o.Get(2, 3) ^ this->Get(0, 3) ^ o.Get(3, 3);
m.Get(1, 0) = this->Get(1, 0) ^ o.Get(0, 0) ^ this->Get(1, 1) ^ o.Get(1, 0) ^ this->Get(1, 2) ^ o.Get(2, 0) ^ this->Get(1, 3) ^ o.Get(3, 0);
m.Get(1, 1) = this->Get(1, 0) ^ o.Get(0, 1) ^ this->Get(1, 1) ^ o.Get(1, 1) ^ this->Get(1, 2) ^ o.Get(2, 1) ^ this->Get(1, 3) ^ o.Get(3, 1);
m.Get(1, 2) = this->Get(1, 0) ^ o.Get(0, 2) ^ this->Get(1, 1) ^ o.Get(1, 2) ^ this->Get(1, 2) ^ o.Get(2, 2) ^ this->Get(1, 3) ^ o.Get(3, 2);
m.Get(1, 3) = this->Get(1, 0) ^ o.Get(0, 3) ^ this->Get(1, 1) ^ o.Get(1, 3) ^ this->Get(1, 2) ^ o.Get(2, 3) ^ this->Get(1, 3) ^ o.Get(3, 3);
m.Get(2, 0) = this->Get(2, 0) ^ o.Get(0, 0) ^ this->Get(2, 1) ^ o.Get(1, 0) ^ this->Get(2, 2) ^ o.Get(2, 0) ^ this->Get(2, 3) ^ o.Get(3, 0);
m.Get(2, 1) = this->Get(2, 0) ^ o.Get(0, 1) ^ this->Get(2, 1) ^ o.Get(1, 1) ^ this->Get(2, 2) ^ o.Get(2, 1) ^ this->Get(2, 3) ^ o.Get(3, 1);
m.Get(2, 2) = this->Get(2, 0) ^ o.Get(0, 2) ^ this->Get(2, 1) ^ o.Get(1, 2) ^ this->Get(2, 2) ^ o.Get(2, 2) ^ this->Get(2, 3) ^ o.Get(3, 2);
m.Get(2, 3) = this->Get(2, 0) ^ o.Get(0, 3) ^ this->Get(2, 1) ^ o.Get(1, 3) ^ this->Get(2, 2) ^ o.Get(2, 3) ^ this->Get(2, 3) ^ o.Get(3, 3);
m.Get(3, 0) = this->Get(3, 0) ^ o.Get(0, 0) ^ this->Get(3, 1) ^ o.Get(1, 0) ^ this->Get(3, 2) ^ o.Get(2, 0) ^ this->Get(3, 3) ^ o.Get(3, 0);
m.Get(3, 1) = this->Get(3, 0) ^ o.Get(0, 1) ^ this->Get(3, 1) ^ o.Get(1, 1) ^ this->Get(3, 2) ^ o.Get(2, 1) ^ this->Get(3, 3) ^ o.Get(3, 1);
m.Get(3, 2) = this->Get(3, 0) ^ o.Get(0, 2) ^ this->Get(3, 1) ^ o.Get(1, 2) ^ this->Get(3, 2) ^ o.Get(2, 2) ^ this->Get(3, 3) ^ o.Get(3, 2);
m.Get(3, 3) = this->Get(3, 0) ^ o.Get(0, 3) ^ this->Get(3, 1) ^ o.Get(1, 3) ^ this->Get(3, 2) ^ o.Get(2, 3) ^ this->Get(3, 3) ^ o.Get(3, 3);
return m;
}
const std::uint32_t& BlockMatrix::Get(const std::uint8_t row, const std::uint8_t column) const {
return data[column*4 + row];
}
std::uint32_t& BlockMatrix::Get(const std::uint8_t row, const std::uint8_t column){
return data[column*4 + row];
}
bool BlockMatrix::operator==(const BlockMatrix& other) const {
return data == other.data;
}
bool BlockMatrix::operator!=(const BlockMatrix& other) const {
return data != other.data;
}
}

View File

@@ -68,25 +68,27 @@ namespace Leonetienne::GCrypt {
Block m_expanded = ExpansionFunction(m);
// Shift to left by 1
m_expanded = Shiftl(m_expanded, 1);
//m_expanded = Shiftl(m_expanded, 1);
m_expanded = (m_expanded);
// Matrix-mult with key
m_expanded = (BlockMatrix(m_expanded) * BlockMatrix(key)).ToBlock();
m_expanded *= key;
// Non-linearly apply subsitution boxes
std::stringstream ss;
const std::string m_str = m_expanded.to_string();
const std::string m_str = m_expanded.ToString();
for (std::size_t i = 0; i < BLOCK_SIZE; i += 4) {
ss << SBox(m_str.substr(i, 4));
}
m_expanded = Block(ss.str());
// Return the compressed version, shifted by 3
return Shiftl(CompressionFunction(m_expanded), 3);
//return Shiftl(CompressionFunction(m_expanded), 3);
return (CompressionFunction(m_expanded));
}
std::pair<Halfblock, Halfblock> Feistel::FeistelSplit(const Block& block) {
const std::string bits = block.to_string();
const std::string bits = block.ToString();
Halfblock l(bits.substr(0, bits.size() / 2));
Halfblock r(bits.substr(bits.size() / 2));
@@ -119,7 +121,7 @@ namespace Leonetienne::GCrypt {
Halfblock Feistel::CompressionFunction(const Block& block) {
std::stringstream ss;
const std::string bits = block.to_string();
const std::string bits = block.ToString();
std::unordered_map<std::string, std::string> compressionMap;
compressionMap["0000"] = "10";
@@ -184,7 +186,8 @@ namespace Leonetienne::GCrypt {
// 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
//Halfblock compressedSeed2 = CompressionFunction(Shiftl(seedKey, 1)); // Shifting one key by 1 will result in a completely different compression
Halfblock compressedSeed2 = CompressionFunction((seedKey)); // Shifting one key by 1 will result in a completely different compression
// 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
@@ -192,10 +195,11 @@ namespace Leonetienne::GCrypt {
const std::size_t setBits1 = compressedSeed1.count();
if (setBits1 % 4 == 0) {
compressedSeed1 = Shiftr(compressedSeed1, 1);
//compressedSeed1 = Shiftr(compressedSeed1, 1);
compressedSeed1 = (compressedSeed1);
}
else if (setBits1 % 3 == 0) {
compressedSeed1 = Shiftl(compressedSeed1, 1);
compressedSeed1 = (compressedSeed1);
}
// Now apply substitution
@@ -224,7 +228,8 @@ namespace Leonetienne::GCrypt {
Block newKey = roundKeys[i - 1];
// Shift to left by how many bits are set, modulo 8
newKey = Shiftl(newKey, newKey.count() % 8); // This action is irreversible
//newKey = Shiftl(newKey, newKey.count() % 8); // This action is irreversible
newKey = (newKey); // This action is irreversible
// Split into two halfblocks,
// apply F() to one halfblock with rk[i-2],
@@ -255,7 +260,7 @@ namespace Leonetienne::GCrypt {
#endif
void Feistel::ZeroKeyMemory() {
for (Key& key : roundKeys) {
key.reset();
key.Reset();
}
return;

View File

@@ -52,14 +52,14 @@ namespace Leonetienne::GCrypt {
// Slurp up the rest of the current block
std::stringstream ss;
const std::size_t bitsLeft = BLOCK_SIZE - nextBit;
ss << hasher.GetHashsum().to_string().substr(nextBit, bitsLeft);
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;
ss << hasher.GetHashsum().to_string().substr(0, remainingBits);
ss << hasher.GetHashsum().ToString().substr(0, remainingBits);
// Assert that we have the correct number of bits
assert(ss.str().length() == BLOCK_SIZE);

View File

@@ -67,7 +67,7 @@ namespace Leonetienne::GCrypt {
void Key::WriteToFile(const std::string& path) {
// Transform key to bytes
const std::string keybytes = BitsToBytes(to_string());
const std::string keybytes = BitsToBytes(ToString());
// Create an ofilestream
std::ofstream ofs(path, std::ios::out | std::ios::binary);

View File

@@ -53,7 +53,7 @@ namespace Leonetienne::GCrypt {
std::string BitblockToBytes(const Block& bits) {
std::stringstream ss;
const std::string bitstring = bits.to_string();
const std::string bitstring = bits.ToString();
for (std::size_t i = 0; i < BLOCK_SIZE; i += 8) {
ss << (char)std::bitset<8>(bitstring.substr(i, 8)).to_ulong();
@@ -97,7 +97,7 @@ namespace Leonetienne::GCrypt {
std::string BitblockToHexstring(const Block& b) {
std::stringstream ss;
const std::string charset = "0123456789abcdef";
const std::string bstr = b.to_string();
const std::string bstr = b.ToString();
for (std::size_t i = 0; i < bstr.size(); i += 4) {
ss << charset[std::bitset<4>(bstr.substr(i, 4)).to_ulong()];
@@ -139,7 +139,7 @@ namespace Leonetienne::GCrypt {
}
// Append to our bits
ss << std::bitset<4>(value);
ss << std::bitset<4>(value).to_string();
}
return Block(ss.str());
@@ -166,7 +166,7 @@ namespace Leonetienne::GCrypt {
}
// Append to our bits
ss << std::bitset<4>(value);
ss << std::bitset<4>(value).to_string();
}
return ss.str();