pqc/crypto_kem/hqc-rmrs-128/clean/gf.c
2020-09-09 16:05:44 -04:00

77 lines
1.9 KiB
C

#include "gf.h"
#include "parameters.h"
#include <stdint.h>
/**
* @file gf.c
* Galois field implementation with multiplication using lookup tables
*/
/**
* Returns the integer i such that elt = a^i
* where a is the primitive element of GF(2^PARAM_M).
* @returns the logarithm of the given element
*/
uint16_t PQCLEAN_HQCRMRS128_CLEAN_gf_log(uint16_t elt) {
return log[elt];
}
/**
* Multiplies nonzero element 'a' by element 'b'.
* @returns the product a*b
* @param[in] a First element of GF(2^PARAM_M) to multiply (cannot be zero)
* @param[in] b Second element of GF(2^PARAM_M) to multiply (cannot be zero)
*/
uint16_t PQCLEAN_HQCRMRS128_CLEAN_gf_mul(uint16_t a, uint16_t b) {
uint16_t mask;
mask = (uint16_t) (-((int32_t) a) >> 31); // a != 0
mask &= (uint16_t) (-((int32_t) b) >> 31); // b != 0
return mask & exp[PQCLEAN_HQCRMRS128_CLEAN_gf_mod(log[a] + log[b])];
}
/**
* Squares an element of GF(2^PARAM_M).
* @returns a^2
* @param[in] a Element of GF(2^PARAM_M)
*/
uint16_t PQCLEAN_HQCRMRS128_CLEAN_gf_square(uint16_t a) {
int16_t mask = (uint16_t) (-((int32_t) a) >> 31); // a != 0
return mask & exp[PQCLEAN_HQCRMRS128_CLEAN_gf_mod(2 * log[a])];
}
/**
* Computes the inverse of an element of GF(2^PARAM_M).
* @returns the inverse of a
* @param[in] a Element of GF(2^PARAM_M)
*/
uint16_t PQCLEAN_HQCRMRS128_CLEAN_gf_inverse(uint16_t a) {
int16_t mask = (uint16_t) (-((int32_t) a) >> 31); // a != 0
return mask & exp[PARAM_GF_MUL_ORDER - log[a]];
}
/**
* Returns i modulo 2^PARAM_M-1.
* i must be less than 2*(2^PARAM_M-1).
* Therefore, the return value is either i or i-2^PARAM_M+1.
* @returns i mod (2^PARAM_M-1)
* @param[in] i The integer whose modulo is taken
*/
uint16_t PQCLEAN_HQCRMRS128_CLEAN_gf_mod(uint16_t i) {
uint16_t tmp = (uint16_t) (i - PARAM_GF_MUL_ORDER);
// mask = 0xffff if(i < PARAM_GF_MUL_ORDER)
uint16_t mask = -(tmp >> 15);
return tmp + (mask & PARAM_GF_MUL_ORDER);
}