#include "mq.h" #include "params.h" /* Computes all products x_i * x_j, returns in reduced form */ inline static void generate_quadratic_terms( gf31 * xij , const gf31 * x ) { int i, j, k; k=0; for(i=0;i> 1]; int r[M] = {0}; generate_quadratic_terms(_xij, x); for (i = 0; i < N; i += 2) { for (j = 0; j < M; j++) { r[j] += ((int)x[i])*((int)F[i*M + 2*j]) + ((int)x[i+1])*((int)F[i*M + 2*j + 1]); } } for (i = 0; i < (N*(N+1)) >> 1; i += 2) { for (j = 0; j < M; j++) { r[j] += ((int)_xij[i])*((int)F[N*M + i*M + 2*j]) + ((int)_xij[i+1])*((int)F[N*M + i*M + 2*j + 1]); } } for (i = 0; i < M; i++) { fx[i] = PQCLEAN_MQDSS48_CLEAN_mod31((gf31)((r[i] >> 15) + (r[i] & 0x7FFF))); } } /* Evaluates the bilinear polar form of the MQ function (i.e. G) on a vector of N gf31 elements x (expected to be in reduced 5-bit representation). Expects the coefficients in F to be in signed representation (i.e. [-15, 15], packed bytewise). Outputs M gf31 elements in unique 16-bit representation as fx. */ void PQCLEAN_MQDSS48_CLEAN_G(gf31 *fx, const gf31 *x, const gf31 *y, const signed char *F) { int i, j; gf31 _xij[N*(N+1) >> 1]; int r[M] = {0}; generate_xiyj_p_xjyi_terms(_xij, x, y); for (i = 0; i < (N*(N+1)) >> 1; i += 2) { for (j = 0; j < M; j++) { r[j] += ((int)_xij[i])*((int)F[N*M + i*M + 2*j]) + ((int)_xij[i+1])*((int)F[N*M + i*M + 2*j + 1]); } } for (i = 0; i < M; i++) { fx[i] = PQCLEAN_MQDSS48_CLEAN_mod31((gf31)((r[i] >> 15) + (r[i] & 0x7FFF))); } }