Last active
December 17, 2017 13:08
-
-
Save th0rex/36bc728673b537993a3430af65055a0d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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