- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
// https://habr.com/ru/post/451830/ Кратко с реализацией о AES 128 ECB
// ...
byte_t hex(char ch) { return (ch - '0') % 39; }
byte_t sbox(byte_t x, bool decrypt = false) {
std::string s = (decrypt ? INV_SBOX : SBOX)[x >> 4][x & 15];
return hex(s[0]) << 4 | hex(s[1]);
}
byte_t mult_by_2(byte_t x) { return (x < 128) ? x << 1 : (x << 1 & 0xff) ^ 0x1b; }
byte_t mult_by_8(byte_t x) { return mult_by_2(mult_by_2(mult_by_2(x))); }
const std::unordered_map<byte_t, std::function<byte_t(byte_t)>> mapper = {
{0x1, [](byte_t x) { return x; }},
{0x2, mult_by_2},
{0x3, [](byte_t x) { return mult_by_2(x) ^ x; }},
{0x9, [](byte_t x) { return mult_by_8(x) ^ x; }},
{0xb, [](byte_t x) { return mult_by_8(x) ^ mult_by_2(x) ^ x; }},
{0xd, [](byte_t x) { return mult_by_8(x) ^ mult_by_2(mult_by_2(x)) ^ x; }},
{0xe, [](byte_t x) { return mult_by_8(x) ^ mult_by_2(mult_by_2(x)) ^ mult_by_2(x); }},
};
byte_t vector_mult(const std::array<byte_t, 4>& v1, std::array<byte_t, 4>&& v2) {
std::transform(begin(v1), end(v1), begin(v2), begin(v2),
[](byte_t x, byte_t y) { return mapper.at(y)(x); });
return std::accumulate(begin(v2), end(v2), byte_t(0), std::bit_xor<byte_t>());
}
const std::vector<std::vector<std::string>> SBOX = { // блядь сука долбоеб нахуя это так делать?
{ "63", "7c", "77", "7b", "f2", "6b", "6f", "c5", "30", "01", "67", "2b", "fe", "d7", "ab", "76" },
{ "ca", "82", "c9", "7d", "fa", "59", "47", "f0", "ad", "d4", "a2", "af", "9c", "a4", "72", "c0" },
{ "b7", "fd", "93", "26", "36", "3f", "f7", "cc", "34", "a5", "e5", "f1", "71", "d8", "31", "15" },
{ "04", "c7", "23", "c3", "18", "96", "05", "9a", "07", "12", "80", "e2", "eb", "27", "b2", "75" },
{ "09", "83", "2c", "1a", "1b", "6e", "5a", "a0", "52", "3b", "d6", "b3", "29", "e3", "2f", "84" },
// ...