Galois256/Galois256.c

128 lines
3.1 KiB
C

//
// Created by zemon on 22.07.2022.
//
#include "Galois256.h"
#include <memory.h>
#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);
}