128 lines
3.1 KiB
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);
|
|
} |