Skip to content

Instantly share code, notes, and snippets.

@th0rex
Last active December 17, 2017 13:08
Show Gist options
  • Save th0rex/36bc728673b537993a3430af65055a0d to your computer and use it in GitHub Desktop.
Save th0rex/36bc728673b537993a3430af65055a0d to your computer and use it in GitHub Desktop.
// Compile with: clang++ -std=c++17 -O3 matrix_mul.cpp -o matrix_mul
// Run with: ./matrix_mul
// Produces:
// result: [
// 1, 0, 0, 0,
// 0, 1, 0, 0,
// 0, 0, 1, 0,
// 0, 0, 0, 1,
// ]
#include <stdint.h>
#include <array>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
template <unsigned I, typename T>
constexpr T bit_get(T input) noexcept {
return (input & (1 << I)) >> I;
}
template <unsigned I, typename T>
constexpr void bit_set(T& input, T value) noexcept {
input |= (value & 1) << I;
}
// Von Aufgabe 5b)
constexpr uint8_t mul2(uint8_t i) noexcept {
uint8_t ret = 0;
bit_set<7>(ret, bit_get<6>(i));
bit_set<6>(ret, bit_get<5>(i));
bit_set<5>(ret, bit_get<4>(i));
bit_set<4>(ret, (uint8_t)(bit_get<3>(i) ^ bit_get<7>(i)));
bit_set<3>(ret, (uint8_t)(bit_get<2>(i) ^ bit_get<7>(i)));
bit_set<2>(ret, bit_get<1>(i));
bit_set<1>(ret, (uint8_t)(bit_get<0>(i) ^ bit_get<7>(i)));
bit_set<0>(ret, bit_get<7>(i));
return ret;
}
// Von Aufgabe 5c)
constexpr uint8_t mul3(uint8_t i) noexcept {
uint8_t ret = 0;
bit_set<7>(ret, (uint8_t)(bit_get<6>(i) ^ bit_get<7>(i)));
bit_set<6>(ret, (uint8_t)(bit_get<5>(i) ^ bit_get<6>(i)));
bit_set<5>(ret, (uint8_t)(bit_get<4>(i) ^ bit_get<5>(i)));
bit_set<4>(ret, (uint8_t)(bit_get<3>(i) ^ bit_get<4>(i) ^ bit_get<7>(i)));
bit_set<3>(ret, (uint8_t)(bit_get<2>(i) ^ bit_get<3>(i) ^ bit_get<7>(i)));
bit_set<2>(ret, (uint8_t)(bit_get<1>(i) ^ bit_get<2>(i)));
bit_set<1>(ret, (uint8_t)(bit_get<0>(i) ^ bit_get<1>(i) ^ bit_get<7>(i)));
bit_set<0>(ret, (uint8_t)(bit_get<0>(i) ^ bit_get<7>(i)));
return ret;
}
// * 1 mod P(x)
constexpr uint8_t identity(uint8_t x) noexcept { return x; }
// clang-format off
// Matrix M, partially applied functions.
static std::array<std::function<uint8_t(uint8_t)>, 16> M = {
mul2, mul3, identity, identity,
identity, mul2, mul3, identity,
identity, identity, mul2, mul3,
mul3, identity, identity, mul2
};
static std::array<uint8_t, 16> M_inv = {
0xE, 0xB, 0xD, 0x9,
0x9, 0xE, 0xB, 0xD,
0xD, 0x9, 0xE, 0xB,
0xB, 0xD, 0x9, 0xE
};
// clang-format on
constexpr uint8_t mul_row_column(int row, int column) noexcept {
uint8_t ret = 0;
for (auto i = 0; i < 4; ++i) {
ret ^= M[row * 4 + i](M_inv[i * 4 + column]);
}
return ret;
}
// M * M^{-1}
std::array<uint8_t, 16> matrix_mul() noexcept {
std::array<uint8_t, 16> ret = {0};
for (auto i = 0; i < 16; ++i) {
ret[i] = mul_row_column(i / 4, i % 4);
}
return ret;
}
int main() {
auto result = matrix_mul();
std::cout << "result: [\n";
for (auto j = 0; j < 4; ++j) {
std::cout << "\t";
for (auto i = 0; i < 4; ++i) {
std::cout << (unsigned)result[j * 4 + i] << ", ";
}
std::cout << '\n';
}
std::cout << "]" << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment