Experimentally implement matrix-mult

This commit is contained in:
Leonetienne 2022-05-23 22:42:14 +02:00
parent 3819fbe693
commit ed45b69342
No known key found for this signature in database
GPG Key ID: C33879CD92E9708C
5 changed files with 168 additions and 4 deletions

View File

@ -0,0 +1,49 @@
#ifndef GCRYPT_BLOCKMATRIX_H
#define GCRYPT_BLOCKMATRIX_H
#include "GCrypt/Block.h"
#include <cstdint>
#include <array>
namespace Leonetienne::GCrypt {
/* This class represents a block as a matrix,
* providing typical matrix operations
*/
class BlockMatrix {
public:
BlockMatrix();
BlockMatrix(const Block& block);
BlockMatrix(const BlockMatrix& other);
//! Will calculate the product of two matrices.
//! Since the matrices values are pretty much sudo-random,
//! they will most likely integer-overflow.
//! So see this as a one-way function.
BlockMatrix MMult(const BlockMatrix& other) const;
BlockMatrix operator*(const BlockMatrix& other) const;
//! Will do a regular matrix-mult, but instead of
//! adding, and multiplying, all ints get xored.
BlockMatrix MXor(const BlockMatrix& other) const;
bool operator==(const BlockMatrix& other) const;
bool operator!=(const BlockMatrix& other) const;
void FromBlock(const Block& block);
Block ToBlock() const;
private:
//! Returns items of data, indexed by 4x4 coordinates
std::uint32_t& Get(const std::uint8_t row, const std::uint8_t column);
//! Returns items of data, indexed by 4x4 coordinates
const std::uint32_t& Get(const std::uint8_t row, const std::uint8_t column) const;
std::array<std::uint32_t, 16> data;
};
}
#endif

View File

@ -8,7 +8,7 @@ namespace Leonetienne::GCrypt {
constexpr std::size_t BLOCK_SIZE = 512;
// MUST BE > 2
constexpr std::size_t N_ROUNDS = 400;
constexpr std::size_t N_ROUNDS = 10;
}
#endif

View File

@ -1,7 +1,7 @@
#ifndef GCRYPT_VERSION_H
#define GCRYPT_VERSION_H
#define GCRYPT_VERSION 0.23
#define GCRYPT_VERSION 0.231
#endif

View File

@ -0,0 +1,114 @@
#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

@ -1,6 +1,7 @@
#include <unordered_map>
#include "GCrypt/Feistel.h"
#include "GCrypt/Util.h"
#include "GCrypt/BlockMatrix.h"
#include "GCrypt/Config.h"
namespace Leonetienne::GCrypt {
@ -69,8 +70,8 @@ namespace Leonetienne::GCrypt {
// Shift to left by 1
m_expanded = Shiftl(m_expanded, 1);
// Xor with key
m_expanded ^= key;
// Matrix-mult with key
m_expanded = (BlockMatrix(m_expanded) * BlockMatrix(key)).ToBlock();
// Non-linearly apply subsitution boxes
std::stringstream ss;