#ifndef GF28_CUH #define GF28_CUH #include "header.cuh" static const set irreducible_polynomials_degree_08{0x11b, 0x11d, 0x12b, 0x12d, 0x139, 0x13f, 0x14d, 0x15f, 0x163, 0x165, 0x169, 0x171, 0x177, 0x17b, 0x187, 0x18b, 0x18d, 0x19f, 0x1a3, 0x1a9, 0x1b1, 0x1bd, 0x1c3, 0x1cf, 0x1d7, 0x1dd, 0x1e7, 0x1f3, 0x1f5, 0x1f9}; class GF28 { public: GF28(base_t poly) { assert(irreducible_polynomials_degree_08.count(poly) == 1); this->poly = poly; for (size_t x = 0; x < (1 << base_deg); x++) { mul_table[x][gf28_zero] = gf28_zero; for (size_t d = 0; d < base_deg; d++) { gf28_t val = shift_left(x, d); for (size_t y = (1 << d); y < (1 << (d + 1)); y++) { mul_table[x][y] = val ^ mul_table[x][y ^ (1 << d)]; if (mul_table[x][y] == gf28_one) { inv_table[x] = y; } } } } inv_table[gf28_zero] = gf28_zero; } gf28_t mul(const gf28_t x, const gf28_t y) const { return mul_table[x][y]; } base_t mul_base(const gf28_t val, const base_t base, const size_t offset = 0) const { base_t temp = base_zero; for (size_t i = offset; i < base_num; i++) { set8(temp, mul(val, get8(base, i)), i); } return temp; } gf28_t inv(gf28_t x) { return inv_table[x]; } friend ostream &operator<<(ostream &out, const GF28 &gf); GF28() = delete; GF28(const GF28 &) = delete; GF28(GF28 &&) = delete; GF28 &operator=(const GF28 &) = delete; GF28 &operator=(GF28 &&) = delete; gf28_t mul_table[1 << base_deg][1 << base_deg]; private: gf28_t shift_left(gf28_t x, size_t d) { base_t temp = (base_t)x << d; for (size_t i = base_deg - 1 + d; i > base_deg - 1; i--) { if (temp & (1 << i)) { temp ^= poly << (i - base_deg); } } return temp; } base_t poly; gf28_t inv_table[1 << base_deg]; }; ostream &operator<<(ostream &out, const GF28 &gf) { for (size_t x = 0; x < 1 << base_deg; x++) { for (size_t y = 0; y < 1 << base_deg; y++) { printf("%02X ", gf.mul_table[x][y]); } printf("\n"); } return out; } #endif