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;
|
constexpr std::size_t BLOCK_SIZE = 512;
|
||||||
|
|
||||||
// MUST BE > 2
|
// MUST BE > 2
|
||||||
constexpr std::size_t N_ROUNDS = 400;
|
constexpr std::size_t N_ROUNDS = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef GCRYPT_VERSION_H
|
#ifndef GCRYPT_VERSION_H
|
||||||
#define GCRYPT_VERSION_H
|
#define GCRYPT_VERSION_H
|
||||||
|
|
||||||
#define GCRYPT_VERSION 0.23
|
#define GCRYPT_VERSION 0.231
|
||||||
|
|
||||||
#endif
|
#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 <unordered_map>
|
||||||
#include "GCrypt/Feistel.h"
|
#include "GCrypt/Feistel.h"
|
||||||
#include "GCrypt/Util.h"
|
#include "GCrypt/Util.h"
|
||||||
|
#include "GCrypt/BlockMatrix.h"
|
||||||
#include "GCrypt/Config.h"
|
#include "GCrypt/Config.h"
|
||||||
|
|
||||||
namespace Leonetienne::GCrypt {
|
namespace Leonetienne::GCrypt {
|
||||||
@ -69,8 +70,8 @@ namespace Leonetienne::GCrypt {
|
|||||||
// Shift to left by 1
|
// Shift to left by 1
|
||||||
m_expanded = Shiftl(m_expanded, 1);
|
m_expanded = Shiftl(m_expanded, 1);
|
||||||
|
|
||||||
// Xor with key
|
// Matrix-mult with key
|
||||||
m_expanded ^= key;
|
m_expanded = (BlockMatrix(m_expanded) * BlockMatrix(key)).ToBlock();
|
||||||
|
|
||||||
// Non-linearly apply subsitution boxes
|
// Non-linearly apply subsitution boxes
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user