Implemented remaining operands for block class
This commit is contained in:
parent
83854e42cb
commit
db0add6e6e
@ -35,8 +35,8 @@ namespace Leonetienne::GCrypt {
|
|||||||
//! Since the matrices values are pretty much sudo-random,
|
//! Since the matrices values are pretty much sudo-random,
|
||||||
//! they will most likely integer-overflow.
|
//! they will most likely integer-overflow.
|
||||||
//! So see this as a one-way function.
|
//! So see this as a one-way function.
|
||||||
Block MMul(const Block& other) const;
|
[[nodiscard]] Block MMul(const Block& other) const;
|
||||||
Block operator*(const Block& other) const;
|
[[nodiscard]] Block operator*(const Block& other) const;
|
||||||
|
|
||||||
//! Will matrix-multiply two blocks together,
|
//! Will matrix-multiply two blocks together,
|
||||||
//! and directly write into this same block.
|
//! and directly write into this same block.
|
||||||
@ -47,67 +47,98 @@ namespace Leonetienne::GCrypt {
|
|||||||
Block& operator*=(const Block& other);
|
Block& operator*=(const Block& other);
|
||||||
|
|
||||||
//! Will xor two blocks together
|
//! Will xor two blocks together
|
||||||
Block Xor(const Block& other) const;
|
[[nodiscard]] Block Xor(const Block& other) const;
|
||||||
//! Will xor two blocks together
|
//! Will xor two blocks together
|
||||||
Block operator^(const Block& other) const;
|
[[nodiscard]] Block operator^(const Block& other) const;
|
||||||
|
|
||||||
//! Will xor two blocks together, inplace
|
//! Will xor two blocks together, inplace
|
||||||
void XorInplace(const Block& other);
|
void XorInplace(const Block& other);
|
||||||
//! Will xor two blocks together, inplace
|
//! Will xor two blocks together, inplace
|
||||||
Block& operator^=(const Block& other);
|
Block& operator^=(const Block& other);
|
||||||
|
|
||||||
// # TO BE IMPLEMENTED
|
//! Will add all the integer making up this block, one by one
|
||||||
//! Will shift rows upwards by n
|
[[nodiscard]] Block Add(const Block& other) const;
|
||||||
void ShiftRowsUp(const std::size_t n);
|
//! Will add all the integer making up this block, one by one
|
||||||
|
[[nodiscard]] Block operator+(const Block& other) const;
|
||||||
|
|
||||||
// # TO BE IMPLEMENTED
|
//! Will add all the integer making up this block, one by one, inplace
|
||||||
//! Will shift matrix rows downwards by n
|
void AddInplace(const Block& other);
|
||||||
void ShiftRowsDown(const std::size_t n);
|
//! Will add all the integer making up this block, one by one, inplace
|
||||||
|
Block& operator+=(const Block& other);
|
||||||
|
|
||||||
// # TO BE IMPLEMENTED
|
//! Will subtract all the integer making up this block, one by one
|
||||||
//! Will shift matrix columns to the left by n
|
[[nodiscard]] Block Sub(const Block& other) const;
|
||||||
void ShiftColumnsLeft(const std::size_t n);
|
//! Will subtract all the integer making up this block, one by one
|
||||||
|
[[nodiscard]] Block operator-(const Block& other) const;
|
||||||
|
|
||||||
// # TO BE IMPLEMENTED
|
//! Will subtract all the integer making up this block, one by one, inplace
|
||||||
//! Will shift matrix columns to the right by n
|
void SubInplace(const Block& other);
|
||||||
void ShiftColumnsRight(const std::size_t n);
|
//! Will subtract all the integer making up this block, one by one, inplace
|
||||||
|
Block& operator-=(const Block& other);
|
||||||
|
|
||||||
// # TO BE IMPLEMENTED
|
//! Will shift rows upwards by 1
|
||||||
//! Will shift array cells to the left by n
|
[[nodiscard]] Block ShiftRowsUp() const;
|
||||||
void ShiftCellsLeft(const std::size_t n);
|
|
||||||
|
|
||||||
// # TO BE IMPLEMENTED
|
//! Will shift rows upwards by 1
|
||||||
//! Will shift array cells to the right by n
|
void ShiftRowsUpInplace();
|
||||||
void ShiftCellsRight(const std::size_t n);
|
|
||||||
|
//! Will shift matrix rows downwards by 1
|
||||||
|
[[nodiscard]] 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;
|
||||||
|
|
||||||
|
//! Will shift matrix columns to the left by 1
|
||||||
|
void ShiftColumnsLeftInplace();
|
||||||
|
|
||||||
|
//! Will shift matrix columns to the right by 1
|
||||||
|
[[nodiscard]] 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;
|
||||||
|
|
||||||
|
//! Will shift array cells to the left by 1
|
||||||
|
void ShiftCellsLeftInplace();
|
||||||
|
|
||||||
|
//! Will shift array cells to the right by 1
|
||||||
|
[[nodiscard]] Block ShiftCellsRight() const;
|
||||||
|
|
||||||
|
//! Will shift array cells to the right by 1
|
||||||
|
void ShiftCellsRightInplace();
|
||||||
|
|
||||||
//! Will copy a block
|
//! Will copy a block
|
||||||
Block& operator=(const Block& other);
|
Block& operator=(const Block& other);
|
||||||
|
|
||||||
//! Will compare whether or not two blocks are equal
|
//! Will compare whether or not two blocks are equal
|
||||||
bool operator==(const Block& other) const;
|
[[nodiscard]] bool operator==(const Block& other) const;
|
||||||
//! Will compare whether or not two blocks are unequal
|
//! Will compare whether or not two blocks are unequal
|
||||||
bool operator!=(const Block& other) const;
|
[[nodiscard]] bool operator!=(const Block& other) const;
|
||||||
|
|
||||||
//! Will zero all data
|
//! Will zero all data
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
|
|
||||||
//! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3)
|
//! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3)
|
||||||
std::uint32_t& Get(const std::uint8_t row, const std::uint8_t column);
|
[[nodiscard]] std::uint32_t& Get(const std::uint8_t row, const std::uint8_t column);
|
||||||
//! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3)
|
//! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3)
|
||||||
const std::uint32_t& Get(const std::uint8_t row, const std::uint8_t column) const;
|
[[nodiscard]] const std::uint32_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)
|
//! Returns 32-bit chunks of data, indexed by a 1d-index (0-16)
|
||||||
std::uint32_t& Get(const std::uint8_t index);
|
[[nodiscard]] std::uint32_t& Get(const std::uint8_t index);
|
||||||
|
|
||||||
//! Returns 32-bit chunks of data, indexed by a 1d-index (0-16)
|
//! Returns 32-bit chunks of data, indexed by a 1d-index (0-16)
|
||||||
const std::uint32_t& Get(const std::uint8_t index) const;
|
[[nodiscard]] const std::uint32_t& Get(const std::uint8_t index) const;
|
||||||
|
|
||||||
//! Returns 32-bit chunks of data, indexed by a 1d-index (0-16)
|
//! Returns 32-bit chunks of data, indexed by a 1d-index (0-16)
|
||||||
std::uint32_t& operator[](const std::uint8_t index);
|
[[nodiscard]] std::uint32_t& operator[](const std::uint8_t index);
|
||||||
|
|
||||||
//! Returns 32-bit chunks of data, indexed by a 1d-index (0-16)
|
//! Returns 32-bit chunks of data, indexed by a 1d-index (0-16)
|
||||||
const std::uint32_t& operator[](const std::uint8_t index) const;
|
[[nodiscard]] const std::uint32_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(std::uint32_t);
|
||||||
static constexpr std::size_t CHUNK_SIZE_BITS = CHUNK_SIZE * 8;
|
static constexpr std::size_t CHUNK_SIZE_BITS = CHUNK_SIZE * 8;
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
// Just to be sure, the compiler will optimize this
|
||||||
|
// little formula out, let's do it in the preprocessor
|
||||||
|
#define MAT_INDEX(row, column) (column*4 + row)
|
||||||
|
|
||||||
namespace Leonetienne::GCrypt {
|
namespace Leonetienne::GCrypt {
|
||||||
|
|
||||||
Block::Block() {
|
Block::Block() {
|
||||||
@ -132,28 +136,310 @@ namespace Leonetienne::GCrypt {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftRowsUp(const std::size_t n) {
|
Block Block::Add(const Block& other) const {
|
||||||
// TO BE IMPLEMENTED
|
|
||||||
|
Block m;
|
||||||
|
for (std::size_t i = 0; i < data.size(); i++) {
|
||||||
|
m.Get(i) = this->Get(i) + other.Get(i);
|
||||||
|
}
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftRowsDown(const std::size_t n) {
|
Block Block::operator+(const Block& other) const {
|
||||||
// TO BE IMPLEMENTED
|
return Add(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftColumnsLeft(const std::size_t n) {
|
void Block::AddInplace(const Block& other) {
|
||||||
// TO BE IMPLEMENTED
|
for (std::size_t i = 0; i < data.size(); i++) {
|
||||||
|
this->Get(i) += other.Get(i);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftColumnsRight(const std::size_t n) {
|
Block& Block::operator+=(const Block& other) {
|
||||||
// TO BE IMPLEMENTED
|
AddInplace(other);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftCellsLeft(const std::size_t n) {
|
Block Block::Sub(const Block& other) const {
|
||||||
// TO BE IMPLEMENTED
|
|
||||||
|
Block m;
|
||||||
|
for (std::size_t i = 0; i < data.size(); i++) {
|
||||||
|
m.Get(i) = this->Get(i) - other.Get(i);
|
||||||
|
}
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftCellsRight(const std::size_t n) {
|
Block Block::operator-(const Block& other) const {
|
||||||
// TO BE IMPLEMENTED
|
return Sub(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::SubInplace(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) {
|
||||||
|
SubInplace(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::ShiftRowsUpInplace() {
|
||||||
|
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));
|
||||||
|
Get(MAT_INDEX(0, 2)) = tmp.Get(MAT_INDEX(1, 2));
|
||||||
|
Get(MAT_INDEX(0, 3)) = tmp.Get(MAT_INDEX(1, 3));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(1, 0)) = tmp.Get(MAT_INDEX(2, 0));
|
||||||
|
Get(MAT_INDEX(1, 1)) = tmp.Get(MAT_INDEX(2, 1));
|
||||||
|
Get(MAT_INDEX(1, 2)) = tmp.Get(MAT_INDEX(2, 2));
|
||||||
|
Get(MAT_INDEX(1, 3)) = tmp.Get(MAT_INDEX(2, 3));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(2, 0)) = tmp.Get(MAT_INDEX(3, 0));
|
||||||
|
Get(MAT_INDEX(2, 1)) = tmp.Get(MAT_INDEX(3, 1));
|
||||||
|
Get(MAT_INDEX(2, 2)) = tmp.Get(MAT_INDEX(3, 2));
|
||||||
|
Get(MAT_INDEX(2, 3)) = tmp.Get(MAT_INDEX(3, 3));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(3, 0)) = tmp.Get(MAT_INDEX(0, 0));
|
||||||
|
Get(MAT_INDEX(3, 1)) = tmp.Get(MAT_INDEX(0, 1));
|
||||||
|
Get(MAT_INDEX(3, 2)) = tmp.Get(MAT_INDEX(0, 2));
|
||||||
|
Get(MAT_INDEX(3, 3)) = tmp.Get(MAT_INDEX(0, 3));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::ShiftRowsUp() const {
|
||||||
|
Block b;
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(1, 0));
|
||||||
|
b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(1, 1));
|
||||||
|
b.Get(MAT_INDEX(0, 2)) = Get(MAT_INDEX(1, 2));
|
||||||
|
b.Get(MAT_INDEX(0, 3)) = Get(MAT_INDEX(1, 3));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(1, 0)) = Get(MAT_INDEX(2, 0));
|
||||||
|
b.Get(MAT_INDEX(1, 1)) = Get(MAT_INDEX(2, 1));
|
||||||
|
b.Get(MAT_INDEX(1, 2)) = Get(MAT_INDEX(2, 2));
|
||||||
|
b.Get(MAT_INDEX(1, 3)) = Get(MAT_INDEX(2, 3));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(2, 0)) = Get(MAT_INDEX(3, 0));
|
||||||
|
b.Get(MAT_INDEX(2, 1)) = Get(MAT_INDEX(3, 1));
|
||||||
|
b.Get(MAT_INDEX(2, 2)) = Get(MAT_INDEX(3, 2));
|
||||||
|
b.Get(MAT_INDEX(2, 3)) = Get(MAT_INDEX(3, 3));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(3, 0)) = Get(MAT_INDEX(0, 0));
|
||||||
|
b.Get(MAT_INDEX(3, 1)) = Get(MAT_INDEX(0, 1));
|
||||||
|
b.Get(MAT_INDEX(3, 2)) = Get(MAT_INDEX(0, 2));
|
||||||
|
b.Get(MAT_INDEX(3, 3)) = Get(MAT_INDEX(0, 3));
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::ShiftRowsDownInplace() {
|
||||||
|
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));
|
||||||
|
Get(MAT_INDEX(0, 2)) = tmp.Get(MAT_INDEX(3, 2));
|
||||||
|
Get(MAT_INDEX(0, 3)) = tmp.Get(MAT_INDEX(3, 3));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(1, 0)) = tmp.Get(MAT_INDEX(0, 0));
|
||||||
|
Get(MAT_INDEX(1, 1)) = tmp.Get(MAT_INDEX(0, 1));
|
||||||
|
Get(MAT_INDEX(1, 2)) = tmp.Get(MAT_INDEX(0, 2));
|
||||||
|
Get(MAT_INDEX(1, 3)) = tmp.Get(MAT_INDEX(0, 3));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(2, 0)) = tmp.Get(MAT_INDEX(1, 0));
|
||||||
|
Get(MAT_INDEX(2, 1)) = tmp.Get(MAT_INDEX(1, 1));
|
||||||
|
Get(MAT_INDEX(2, 2)) = tmp.Get(MAT_INDEX(1, 2));
|
||||||
|
Get(MAT_INDEX(2, 3)) = tmp.Get(MAT_INDEX(1, 3));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(3, 0)) = tmp.Get(MAT_INDEX(2, 0));
|
||||||
|
Get(MAT_INDEX(3, 1)) = tmp.Get(MAT_INDEX(2, 1));
|
||||||
|
Get(MAT_INDEX(3, 2)) = tmp.Get(MAT_INDEX(2, 2));
|
||||||
|
Get(MAT_INDEX(3, 3)) = tmp.Get(MAT_INDEX(2, 3));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::ShiftRowsDown() const {
|
||||||
|
Block b;
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(3, 0));
|
||||||
|
b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(3, 1));
|
||||||
|
b.Get(MAT_INDEX(0, 2)) = Get(MAT_INDEX(3, 2));
|
||||||
|
b.Get(MAT_INDEX(0, 3)) = Get(MAT_INDEX(3, 3));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(1, 0)) = Get(MAT_INDEX(0, 0));
|
||||||
|
b.Get(MAT_INDEX(1, 1)) = Get(MAT_INDEX(0, 1));
|
||||||
|
b.Get(MAT_INDEX(1, 2)) = Get(MAT_INDEX(0, 2));
|
||||||
|
b.Get(MAT_INDEX(1, 3)) = Get(MAT_INDEX(0, 3));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(2, 0)) = Get(MAT_INDEX(1, 0));
|
||||||
|
b.Get(MAT_INDEX(2, 1)) = Get(MAT_INDEX(1, 1));
|
||||||
|
b.Get(MAT_INDEX(2, 2)) = Get(MAT_INDEX(1, 2));
|
||||||
|
b.Get(MAT_INDEX(2, 3)) = Get(MAT_INDEX(1, 3));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(3, 0)) = Get(MAT_INDEX(2, 0));
|
||||||
|
b.Get(MAT_INDEX(3, 1)) = Get(MAT_INDEX(2, 1));
|
||||||
|
b.Get(MAT_INDEX(3, 2)) = Get(MAT_INDEX(2, 2));
|
||||||
|
b.Get(MAT_INDEX(3, 3)) = Get(MAT_INDEX(2, 3));
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::ShiftColumnsLeftInplace() {
|
||||||
|
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));
|
||||||
|
Get(MAT_INDEX(2, 0)) = tmp.Get(MAT_INDEX(2, 1));
|
||||||
|
Get(MAT_INDEX(3, 0)) = tmp.Get(MAT_INDEX(3, 1));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(0, 1)) = tmp.Get(MAT_INDEX(0, 2));
|
||||||
|
Get(MAT_INDEX(1, 1)) = tmp.Get(MAT_INDEX(1, 2));
|
||||||
|
Get(MAT_INDEX(2, 1)) = tmp.Get(MAT_INDEX(2, 2));
|
||||||
|
Get(MAT_INDEX(3, 1)) = tmp.Get(MAT_INDEX(3, 2));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(0, 2)) = tmp.Get(MAT_INDEX(0, 3));
|
||||||
|
Get(MAT_INDEX(1, 2)) = tmp.Get(MAT_INDEX(1, 3));
|
||||||
|
Get(MAT_INDEX(2, 2)) = tmp.Get(MAT_INDEX(2, 3));
|
||||||
|
Get(MAT_INDEX(3, 2)) = tmp.Get(MAT_INDEX(3, 3));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(0, 3)) = tmp.Get(MAT_INDEX(0, 0));
|
||||||
|
Get(MAT_INDEX(1, 3)) = tmp.Get(MAT_INDEX(1, 0));
|
||||||
|
Get(MAT_INDEX(2, 3)) = tmp.Get(MAT_INDEX(2, 0));
|
||||||
|
Get(MAT_INDEX(3, 3)) = tmp.Get(MAT_INDEX(3, 0));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::ShiftColumnsLeft() const {
|
||||||
|
Block b;
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(0, 1));
|
||||||
|
b.Get(MAT_INDEX(1, 0)) = Get(MAT_INDEX(1, 1));
|
||||||
|
b.Get(MAT_INDEX(2, 0)) = Get(MAT_INDEX(2, 1));
|
||||||
|
b.Get(MAT_INDEX(3, 0)) = Get(MAT_INDEX(3, 1));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(0, 2));
|
||||||
|
b.Get(MAT_INDEX(1, 1)) = Get(MAT_INDEX(1, 2));
|
||||||
|
b.Get(MAT_INDEX(2, 1)) = Get(MAT_INDEX(2, 2));
|
||||||
|
b.Get(MAT_INDEX(3, 1)) = Get(MAT_INDEX(3, 2));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 2)) = Get(MAT_INDEX(0, 3));
|
||||||
|
b.Get(MAT_INDEX(1, 2)) = Get(MAT_INDEX(1, 3));
|
||||||
|
b.Get(MAT_INDEX(2, 2)) = Get(MAT_INDEX(2, 3));
|
||||||
|
b.Get(MAT_INDEX(3, 2)) = Get(MAT_INDEX(3, 3));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 3)) = Get(MAT_INDEX(0, 0));
|
||||||
|
b.Get(MAT_INDEX(1, 3)) = Get(MAT_INDEX(1, 0));
|
||||||
|
b.Get(MAT_INDEX(2, 3)) = Get(MAT_INDEX(2, 0));
|
||||||
|
b.Get(MAT_INDEX(3, 3)) = Get(MAT_INDEX(3, 0));
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::ShiftColumnsRightInplace() {
|
||||||
|
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));
|
||||||
|
Get(MAT_INDEX(2, 1)) = tmp.Get(MAT_INDEX(2, 0));
|
||||||
|
Get(MAT_INDEX(3, 1)) = tmp.Get(MAT_INDEX(3, 0));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(0, 2)) = tmp.Get(MAT_INDEX(0, 1));
|
||||||
|
Get(MAT_INDEX(1, 2)) = tmp.Get(MAT_INDEX(1, 1));
|
||||||
|
Get(MAT_INDEX(2, 2)) = tmp.Get(MAT_INDEX(2, 1));
|
||||||
|
Get(MAT_INDEX(3, 2)) = tmp.Get(MAT_INDEX(3, 1));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(0, 3)) = tmp.Get(MAT_INDEX(0, 2));
|
||||||
|
Get(MAT_INDEX(1, 3)) = tmp.Get(MAT_INDEX(1, 2));
|
||||||
|
Get(MAT_INDEX(2, 3)) = tmp.Get(MAT_INDEX(2, 2));
|
||||||
|
Get(MAT_INDEX(3, 3)) = tmp.Get(MAT_INDEX(3, 2));
|
||||||
|
|
||||||
|
Get(MAT_INDEX(0, 0)) = tmp.Get(MAT_INDEX(0, 3));
|
||||||
|
Get(MAT_INDEX(1, 0)) = tmp.Get(MAT_INDEX(1, 3));
|
||||||
|
Get(MAT_INDEX(2, 0)) = tmp.Get(MAT_INDEX(2, 3));
|
||||||
|
Get(MAT_INDEX(3, 0)) = tmp.Get(MAT_INDEX(3, 3));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::ShiftColumnsRight() const {
|
||||||
|
Block b;
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 1)) = Get(MAT_INDEX(0, 0));
|
||||||
|
b.Get(MAT_INDEX(1, 1)) = Get(MAT_INDEX(1, 0));
|
||||||
|
b.Get(MAT_INDEX(2, 1)) = Get(MAT_INDEX(2, 0));
|
||||||
|
b.Get(MAT_INDEX(3, 1)) = Get(MAT_INDEX(3, 0));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 2)) = Get(MAT_INDEX(0, 1));
|
||||||
|
b.Get(MAT_INDEX(1, 2)) = Get(MAT_INDEX(1, 1));
|
||||||
|
b.Get(MAT_INDEX(2, 2)) = Get(MAT_INDEX(2, 1));
|
||||||
|
b.Get(MAT_INDEX(3, 2)) = Get(MAT_INDEX(3, 1));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 3)) = Get(MAT_INDEX(0, 2));
|
||||||
|
b.Get(MAT_INDEX(1, 3)) = Get(MAT_INDEX(1, 2));
|
||||||
|
b.Get(MAT_INDEX(2, 3)) = Get(MAT_INDEX(2, 2));
|
||||||
|
b.Get(MAT_INDEX(3, 3)) = Get(MAT_INDEX(3, 2));
|
||||||
|
|
||||||
|
b.Get(MAT_INDEX(0, 0)) = Get(MAT_INDEX(0, 3));
|
||||||
|
b.Get(MAT_INDEX(1, 0)) = Get(MAT_INDEX(1, 3));
|
||||||
|
b.Get(MAT_INDEX(2, 0)) = Get(MAT_INDEX(2, 3));
|
||||||
|
b.Get(MAT_INDEX(3, 0)) = Get(MAT_INDEX(3, 3));
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::ShiftCellsLeftInplace() {
|
||||||
|
Block tmp = *this;
|
||||||
|
|
||||||
|
Get(15) = tmp.Get(0);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < 15; i++) {
|
||||||
|
Get(i) = tmp.Get(i+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::ShiftCellsLeft() const {
|
||||||
|
Block b;
|
||||||
|
|
||||||
|
b.Get(15) = Get(0);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < 15; i++) {
|
||||||
|
b.Get(i) = Get(i+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::ShiftCellsRightInplace() {
|
||||||
|
Block tmp = *this;
|
||||||
|
|
||||||
|
Get(0) = tmp.Get(15);
|
||||||
|
|
||||||
|
for (std::size_t i = 1; i < 16; i++) {
|
||||||
|
Get(i) = tmp.Get(i-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::ShiftCellsRight() const {
|
||||||
|
Block b;
|
||||||
|
|
||||||
|
b.Get(0) = Get(15);
|
||||||
|
|
||||||
|
for (std::size_t i = 1; i < 16; i++) {
|
||||||
|
b.Get(i) = Get(i-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
Block& Block::operator=(const Block& other) {
|
Block& Block::operator=(const Block& other) {
|
||||||
@ -162,11 +448,11 @@ namespace Leonetienne::GCrypt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column){
|
std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column){
|
||||||
return data[column*4 + row];
|
return data[MAT_INDEX(row, column)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column) const {
|
const std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column) const {
|
||||||
return data[column*4 + row];
|
return data[MAT_INDEX(row, column)];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t& Block::Get(const std::uint8_t index) {
|
std::uint32_t& Block::Get(const std::uint8_t index) {
|
||||||
@ -222,3 +508,5 @@ namespace Leonetienne::GCrypt {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef MAT_INDEX
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#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 {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <GCrypt/Block.h>
|
#include <GCrypt/Block.h>
|
||||||
|
#include <GCrypt/Key.h>
|
||||||
#include "Catch2.h"
|
#include "Catch2.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -148,6 +149,116 @@ TEST_CASE(__FILE__"/operator^&=", "[Block]") {
|
|||||||
REQUIRE(block1 == block3);
|
REQUIRE(block1 == block3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that operator+ (add) works
|
||||||
|
TEST_CASE(__FILE__"/add", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block block;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
block.Get(i) = i * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block addRH;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
addRH.Get(i) = i * 5099;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
Block result = block + addRH;
|
||||||
|
|
||||||
|
Block manualResult;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
manualResult.Get(i) = (i * 1024) + (i * 5099);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(result == manualResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that operator+ is the same as +=
|
||||||
|
TEST_CASE(__FILE__"/operator+&=", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block block1;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
block1.Get(i) = i * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block block2;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
block2.Get(i) = i * 5099 * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
Block block3 = block1 + block2;
|
||||||
|
block1 += block2;
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(block1 == block3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that operator- (subtract) works
|
||||||
|
TEST_CASE(__FILE__"/subtract", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block block;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
block.Get(i) = i * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block subRH;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
subRH.Get(i) = i * 5099;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
Block result = block - subRH;
|
||||||
|
|
||||||
|
Block manualResult;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
manualResult.Get(i) = (i * 1024) - (i * 5099);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(result == manualResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that operator- is the same as -=
|
||||||
|
TEST_CASE(__FILE__"/operator-&=", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block block1;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
block1.Get(i) = i * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block block2;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
block2.Get(i) = i * 5099 * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
Block block3 = block1 - block2;
|
||||||
|
block1 -= block2;
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(block1 == block3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that subtraction undoes addition, and vica versa
|
||||||
|
TEST_CASE(__FILE__"/subtraction-undoes-addition", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
const Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block b = Key::FromPassword("Ananas");
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
const Block a_plus_b = a + b;
|
||||||
|
const Block a_plus_b_minus_b = a_plus_b - b;
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == a_plus_b_minus_b);
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that operator== works correctly
|
// Tests that operator== works correctly
|
||||||
TEST_CASE(__FILE__"/operator==", "[Block]") {
|
TEST_CASE(__FILE__"/operator==", "[Block]") {
|
||||||
|
|
||||||
@ -249,3 +360,276 @@ TEST_CASE(__FILE__"/reset", "[Block]") {
|
|||||||
REQUIRE(block[i] == 0);
|
REQUIRE(block[i] == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that shift rows up works
|
||||||
|
TEST_CASE(__FILE__"/shift-rows-up", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block a;
|
||||||
|
a.Get(0,0) = 10; a.Get(0,1) = 11; a.Get(0,2) = 12; a.Get(0,3) = 13;
|
||||||
|
a.Get(1,0) = 20; a.Get(1,1) = 21; a.Get(1,2) = 22; a.Get(1,3) = 23;
|
||||||
|
a.Get(2,0) = 30; a.Get(2,1) = 31; a.Get(2,2) = 32; a.Get(2,3) = 33;
|
||||||
|
a.Get(3,0) = 40; a.Get(3,1) = 41; a.Get(3,2) = 42; a.Get(3,3) = 43;
|
||||||
|
|
||||||
|
Block e; /* expected */
|
||||||
|
e.Get(0,0) = 20; e.Get(0,1) = 21; e.Get(0,2) = 22; e.Get(0,3) = 23;
|
||||||
|
e.Get(1,0) = 30; e.Get(1,1) = 31; e.Get(1,2) = 32; e.Get(1,3) = 33;
|
||||||
|
e.Get(2,0) = 40; e.Get(2,1) = 41; e.Get(2,2) = 42; e.Get(2,3) = 43;
|
||||||
|
e.Get(3,0) = 10; e.Get(3,1) = 11; e.Get(3,2) = 12; e.Get(3,3) = 13;
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.ShiftRowsUpInplace();
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that ShiftRowsUpInplace() does the exact same thing as ShiftRowsUp()
|
||||||
|
TEST_CASE(__FILE__"/shift-rows-up-same-as-inplace", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise and verify
|
||||||
|
a.ShiftRowsUpInplace();
|
||||||
|
REQUIRE(a == initial_a.ShiftRowsUp());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that shift rows down works
|
||||||
|
TEST_CASE(__FILE__"/shift-rows-down", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block a;
|
||||||
|
a.Get(0,0) = 10; a.Get(0,1) = 11; a.Get(0,2) = 12; a.Get(0,3) = 13;
|
||||||
|
a.Get(1,0) = 20; a.Get(1,1) = 21; a.Get(1,2) = 22; a.Get(1,3) = 23;
|
||||||
|
a.Get(2,0) = 30; a.Get(2,1) = 31; a.Get(2,2) = 32; a.Get(2,3) = 33;
|
||||||
|
a.Get(3,0) = 40; a.Get(3,1) = 41; a.Get(3,2) = 42; a.Get(3,3) = 43;
|
||||||
|
|
||||||
|
Block e; /* expected */
|
||||||
|
e.Get(0,0) = 40; e.Get(0,1) = 41; e.Get(0,2) = 42; e.Get(0,3) = 43;
|
||||||
|
e.Get(1,0) = 10; e.Get(1,1) = 11; e.Get(1,2) = 12; e.Get(1,3) = 13;
|
||||||
|
e.Get(2,0) = 20; e.Get(2,1) = 21; e.Get(2,2) = 22; e.Get(2,3) = 23;
|
||||||
|
e.Get(3,0) = 30; e.Get(3,1) = 31; e.Get(3,2) = 32; e.Get(3,3) = 33;
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.ShiftRowsDownInplace();
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that ShiftRowsDownInplace() does the exact same thing as ShiftRowsDown()
|
||||||
|
TEST_CASE(__FILE__"/shift-rows-down-same-as-inplace", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise and verify
|
||||||
|
a.ShiftRowsDownInplace();
|
||||||
|
REQUIRE(a == initial_a.ShiftRowsDown());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that shift columns left works
|
||||||
|
TEST_CASE(__FILE__"/shift-columns-left", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block a;
|
||||||
|
a.Get(0,0) = 10; a.Get(0,1) = 11; a.Get(0,2) = 12; a.Get(0,3) = 13;
|
||||||
|
a.Get(1,0) = 20; a.Get(1,1) = 21; a.Get(1,2) = 22; a.Get(1,3) = 23;
|
||||||
|
a.Get(2,0) = 30; a.Get(2,1) = 31; a.Get(2,2) = 32; a.Get(2,3) = 33;
|
||||||
|
a.Get(3,0) = 40; a.Get(3,1) = 41; a.Get(3,2) = 42; a.Get(3,3) = 43;
|
||||||
|
|
||||||
|
Block e; /* expected */
|
||||||
|
e.Get(0,0) = 11; e.Get(0,1) = 12; e.Get(0,2) = 13; e.Get(0,3) = 10;
|
||||||
|
e.Get(1,0) = 21; e.Get(1,1) = 22; e.Get(1,2) = 23; e.Get(1,3) = 20;
|
||||||
|
e.Get(2,0) = 31; e.Get(2,1) = 32; e.Get(2,2) = 33; e.Get(2,3) = 30;
|
||||||
|
e.Get(3,0) = 41; e.Get(3,1) = 42; e.Get(3,2) = 43; e.Get(3,3) = 40;
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.ShiftColumnsLeftInplace();
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that ShiftColumnsLeftInplace()() does the exact same thing as ShiftColumnsLeft()
|
||||||
|
TEST_CASE(__FILE__"/shift-columns-left-same-as-inplace", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise and verify
|
||||||
|
a.ShiftColumnsLeftInplace();
|
||||||
|
REQUIRE(a == initial_a.ShiftColumnsLeft());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that shift columns right works
|
||||||
|
TEST_CASE(__FILE__"/shift-columns-right", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block a;
|
||||||
|
a.Get(0,0) = 10; a.Get(0,1) = 11; a.Get(0,2) = 12; a.Get(0,3) = 13;
|
||||||
|
a.Get(1,0) = 20; a.Get(1,1) = 21; a.Get(1,2) = 22; a.Get(1,3) = 23;
|
||||||
|
a.Get(2,0) = 30; a.Get(2,1) = 31; a.Get(2,2) = 32; a.Get(2,3) = 33;
|
||||||
|
a.Get(3,0) = 40; a.Get(3,1) = 41; a.Get(3,2) = 42; a.Get(3,3) = 43;
|
||||||
|
|
||||||
|
Block e; /* expected */
|
||||||
|
e.Get(0,0) = 13; e.Get(0,1) = 10; e.Get(0,2) = 11; e.Get(0,3) = 12;
|
||||||
|
e.Get(1,0) = 23; e.Get(1,1) = 20; e.Get(1,2) = 21; e.Get(1,3) = 22;
|
||||||
|
e.Get(2,0) = 33; e.Get(2,1) = 30; e.Get(2,2) = 31; e.Get(2,3) = 32;
|
||||||
|
e.Get(3,0) = 43; e.Get(3,1) = 40; e.Get(3,2) = 41; e.Get(3,3) = 42;
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.ShiftColumnsRightInplace();
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that ShiftColumnsRightInplace()() does the exact same thing as ShiftColumnsRight()
|
||||||
|
TEST_CASE(__FILE__"/shift-columns-right-same-as-inplace", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise and verify
|
||||||
|
a.ShiftColumnsRightInplace();
|
||||||
|
REQUIRE(a == initial_a.ShiftColumnsRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that shift cells left works
|
||||||
|
TEST_CASE(__FILE__"/shift-cells-left", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block a;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
a.Get(i) = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block expected;
|
||||||
|
for (std::size_t i = 0; i < 15; i++) {
|
||||||
|
expected.Get(i) = i+1;
|
||||||
|
}
|
||||||
|
expected.Get(15) = 0;
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.ShiftCellsLeftInplace();
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that ShiftCellsLeftInplace()() does the exact same thing as ShiftCellsLeft()
|
||||||
|
TEST_CASE(__FILE__"/shift-cells-left-same-as-inplace", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise and verify
|
||||||
|
a.ShiftCellsLeftInplace();
|
||||||
|
REQUIRE(a == initial_a.ShiftCellsLeft());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that shift cells right works
|
||||||
|
TEST_CASE(__FILE__"/shift-cells-right", "[Block]") {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Block a;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
a.Get(i) = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block expected;
|
||||||
|
for (std::size_t i = 1; i < 16; i++) {
|
||||||
|
expected.Get(i) = i-1;
|
||||||
|
}
|
||||||
|
expected.Get(0) = 15;
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.ShiftCellsRightInplace();
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that ShiftCellsRightInplace()() does the exact same thing as ShiftCellsRight()
|
||||||
|
TEST_CASE(__FILE__"/shift-cells-right-same-as-inplace", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise and verify
|
||||||
|
a.ShiftCellsRightInplace();
|
||||||
|
REQUIRE(a == initial_a.ShiftCellsRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that shifting down undoes shifting up, and vica versa
|
||||||
|
TEST_CASE(__FILE__"/shift-down-undoes-shift-up", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.ShiftRowsUpInplace();
|
||||||
|
a.ShiftRowsDownInplace();
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == initial_a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that shifting left undoes shifting right, and vica versa
|
||||||
|
TEST_CASE(__FILE__"/shift-left-undoes-shift-right", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.ShiftColumnsRightInplace();
|
||||||
|
a.ShiftColumnsLeftInplace();
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == initial_a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that shifting cells left undoes shifting cells right, and vica versa
|
||||||
|
TEST_CASE(__FILE__"/cellshift-left-undoes-cellshift-right", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.ShiftCellsRightInplace();
|
||||||
|
a.ShiftCellsLeftInplace();
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == initial_a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that multiple, combined shifts and additions can be undone
|
||||||
|
TEST_CASE(__FILE__"/multiple-combined-shifts-and-additions-can-be-undone", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
Block key = Key::FromPassword("Papaya");
|
||||||
|
|
||||||
|
const Block initial_a = a;
|
||||||
|
|
||||||
|
// Exercise (mix-up)
|
||||||
|
for (std::size_t i = 0; i < 64; i++) {
|
||||||
|
a.ShiftRowsUpInplace();
|
||||||
|
a.ShiftColumnsLeftInplace();
|
||||||
|
a += key;
|
||||||
|
a.ShiftCellsRightInplace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exercise (un-mix)
|
||||||
|
for (std::size_t i = 0; i < 64; i++) {
|
||||||
|
a.ShiftCellsLeftInplace();
|
||||||
|
a -= key;
|
||||||
|
a.ShiftColumnsRightInplace();
|
||||||
|
a.ShiftRowsDownInplace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a == initial_a);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user