// // Created by zemon on 22.07.2022. // #include "Galois256.h" #include #include "stdint.h" int32_t inline iGalois256Add(tGalois256 *env, int one, int two) { return one ^ two; } int32_t inline iGalois256Sub(tGalois256 *env, int one, int two) { return one ^ two; } int32_t iGalois256PowValue(tGalois256 *env, int degree) { int deg_in_bounds; if (degree < 0) { deg_in_bounds = env->field_elements_limit - ((degree * -1) % env->field_elements_limit); } else { deg_in_bounds = degree % env->field_elements_limit; } return env->pow_table[deg_in_bounds]; } int32_t iGalois256LogValue(tGalois256 *env, int degree) { if ((degree <= 0) || (degree > env->field_elements_limit)) { // printf("ERROR! Log out of bounds deg:%i in field len %i", degree, env->field_elements_limit); return -1; } return env->log_table[degree]; } int32_t iGalois256Mul(tGalois256 *env, int one, int two) { if (0 == one || 0 == two) { return 0; } return iGalois256PowValue(env, iGalois256LogValue(env, one) + iGalois256LogValue(env, two)); } int32_t iGalois256Div(tGalois256 *env, int dividable, int divider) { if (divider == 0) { // printf("Division by zero %i/%i", dividable, divider); return -1; } if (dividable == 0) { return 0; } return iGalois256PowValue( env, iGalois256LogValue(env, dividable) - iGalois256LogValue(env, divider) ); } int32_t iGalois256Pow(tGalois256 *env, int base, int degree) { if (degree == 0) { return 1; } if (base == 0) { return 0; } int base_log = iGalois256LogValue(env, base); return iGalois256PowValue(env, degree * base_log); } void iGalois256GenTables(tGalois256 *env) { memset(env->log_table, 0, (env->field_elements_limit + 1) * sizeof(int32_t)); memset(env->pow_table, 0, (env->field_elements_limit + 1) * sizeof(int32_t)); int mask = 1; env->pow_table[env->base_degree] = 0; for (int i = 0; i < env->base_degree; i++) { env->pow_table[i] = mask; env->log_table[env->pow_table[i]] = i; if (env->irreducible_polynomial[i] != 0) { env->pow_table[env->base_degree] ^= mask; } mask <<= 1; } env->log_table[env->pow_table[env->base_degree]] = env->base_degree; mask >>= 1; for (int i = env->base_degree + 1; i < env->field_elements_limit; i++) { if (env->pow_table[i - 1] >= mask) { env->pow_table[i] = env->pow_table[env->base_degree] ^ ((env->pow_table[i - 1] ^ mask) << 1); } else { env->pow_table[i] = env->pow_table[i - 1] << 1; } env->log_table[env->pow_table[i]] = i; } env->log_table[0] = -1; } static const uint8_t iGalois256BaseDegree = 8; static const uint8_t iGalois256IrreduciblePolynomial[] = {1, 0, 1, 1, 1, 0, 0, 0, 1}; void iGalois256Init(tGalois256 *env) { env->base_degree = iGalois256BaseDegree; env->irreducible_polynomial = (uint8_t *) iGalois256IrreduciblePolynomial; env->field_elements_limit = (0x01 << (uint16_t) iGalois256BaseDegree) - 1; iGalois256GenTables(env); }