Experimentally implement matrix-mult
This commit is contained in:
parent
3819fbe693
commit
ed45b69342
49
GCryptLib/include/GCrypt/BlockMatrix.h
Normal file
49
GCryptLib/include/GCrypt/BlockMatrix.h
Normal 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
|
||||
|
@ -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
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef GCRYPT_VERSION_H
|
||||
#define GCRYPT_VERSION_H
|
||||
|
||||
#define GCRYPT_VERSION 0.23
|
||||
#define GCRYPT_VERSION 0.231
|
||||
|
||||
#endif
|
||||
|
||||
|
114
GCryptLib/src/BlockMatrix.cpp
Normal file
114
GCryptLib/src/BlockMatrix.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user