Packages
ntru_elixir
0.0.0
libntru wrapper for elixir. NTRU is a post quantom cryptography algorithm.
Current section
Files
Jump to
Current section
Files
libntru/src/mgf.c
#include <string.h>
#ifdef WIN32
#include <stdint.h>
#include <Winsock2.h>
#else
#include <netinet/in.h>
#endif
#include "encparams.h"
#include "poly.h"
int16_t NTRU_MGF_TRIT_TBL[243][5] = {
{ 0, 0, 0, 0, 0},
{ 1, 0, 0, 0, 0},
{-1, 0, 0, 0, 0},
{ 0, 1, 0, 0, 0},
{ 1, 1, 0, 0, 0},
{-1, 1, 0, 0, 0},
{ 0, -1, 0, 0, 0},
{ 1, -1, 0, 0, 0},
{-1, -1, 0, 0, 0},
{ 0, 0, 1, 0, 0},
{ 1, 0, 1, 0, 0},
{-1, 0, 1, 0, 0},
{ 0, 1, 1, 0, 0},
{ 1, 1, 1, 0, 0},
{-1, 1, 1, 0, 0},
{ 0, -1, 1, 0, 0},
{ 1, -1, 1, 0, 0},
{-1, -1, 1, 0, 0},
{ 0, 0, -1, 0, 0},
{ 1, 0, -1, 0, 0},
{-1, 0, -1, 0, 0},
{ 0, 1, -1, 0, 0},
{ 1, 1, -1, 0, 0},
{-1, 1, -1, 0, 0},
{ 0, -1, -1, 0, 0},
{ 1, -1, -1, 0, 0},
{-1, -1, -1, 0, 0},
{ 0, 0, 0, 1, 0},
{ 1, 0, 0, 1, 0},
{-1, 0, 0, 1, 0},
{ 0, 1, 0, 1, 0},
{ 1, 1, 0, 1, 0},
{-1, 1, 0, 1, 0},
{ 0, -1, 0, 1, 0},
{ 1, -1, 0, 1, 0},
{-1, -1, 0, 1, 0},
{ 0, 0, 1, 1, 0},
{ 1, 0, 1, 1, 0},
{-1, 0, 1, 1, 0},
{ 0, 1, 1, 1, 0},
{ 1, 1, 1, 1, 0},
{-1, 1, 1, 1, 0},
{ 0, -1, 1, 1, 0},
{ 1, -1, 1, 1, 0},
{-1, -1, 1, 1, 0},
{ 0, 0, -1, 1, 0},
{ 1, 0, -1, 1, 0},
{-1, 0, -1, 1, 0},
{ 0, 1, -1, 1, 0},
{ 1, 1, -1, 1, 0},
{-1, 1, -1, 1, 0},
{ 0, -1, -1, 1, 0},
{ 1, -1, -1, 1, 0},
{-1, -1, -1, 1, 0},
{ 0, 0, 0, -1, 0},
{ 1, 0, 0, -1, 0},
{-1, 0, 0, -1, 0},
{ 0, 1, 0, -1, 0},
{ 1, 1, 0, -1, 0},
{-1, 1, 0, -1, 0},
{ 0, -1, 0, -1, 0},
{ 1, -1, 0, -1, 0},
{-1, -1, 0, -1, 0},
{ 0, 0, 1, -1, 0},
{ 1, 0, 1, -1, 0},
{-1, 0, 1, -1, 0},
{ 0, 1, 1, -1, 0},
{ 1, 1, 1, -1, 0},
{-1, 1, 1, -1, 0},
{ 0, -1, 1, -1, 0},
{ 1, -1, 1, -1, 0},
{-1, -1, 1, -1, 0},
{ 0, 0, -1, -1, 0},
{ 1, 0, -1, -1, 0},
{-1, 0, -1, -1, 0},
{ 0, 1, -1, -1, 0},
{ 1, 1, -1, -1, 0},
{-1, 1, -1, -1, 0},
{ 0, -1, -1, -1, 0},
{ 1, -1, -1, -1, 0},
{-1, -1, -1, -1, 0},
{ 0, 0, 0, 0, 1},
{ 1, 0, 0, 0, 1},
{-1, 0, 0, 0, 1},
{ 0, 1, 0, 0, 1},
{ 1, 1, 0, 0, 1},
{-1, 1, 0, 0, 1},
{ 0, -1, 0, 0, 1},
{ 1, -1, 0, 0, 1},
{-1, -1, 0, 0, 1},
{ 0, 0, 1, 0, 1},
{ 1, 0, 1, 0, 1},
{-1, 0, 1, 0, 1},
{ 0, 1, 1, 0, 1},
{ 1, 1, 1, 0, 1},
{-1, 1, 1, 0, 1},
{ 0, -1, 1, 0, 1},
{ 1, -1, 1, 0, 1},
{-1, -1, 1, 0, 1},
{ 0, 0, -1, 0, 1},
{ 1, 0, -1, 0, 1},
{-1, 0, -1, 0, 1},
{ 0, 1, -1, 0, 1},
{ 1, 1, -1, 0, 1},
{-1, 1, -1, 0, 1},
{ 0, -1, -1, 0, 1},
{ 1, -1, -1, 0, 1},
{-1, -1, -1, 0, 1},
{ 0, 0, 0, 1, 1},
{ 1, 0, 0, 1, 1},
{-1, 0, 0, 1, 1},
{ 0, 1, 0, 1, 1},
{ 1, 1, 0, 1, 1},
{-1, 1, 0, 1, 1},
{ 0, -1, 0, 1, 1},
{ 1, -1, 0, 1, 1},
{-1, -1, 0, 1, 1},
{ 0, 0, 1, 1, 1},
{ 1, 0, 1, 1, 1},
{-1, 0, 1, 1, 1},
{ 0, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1},
{-1, 1, 1, 1, 1},
{ 0, -1, 1, 1, 1},
{ 1, -1, 1, 1, 1},
{-1, -1, 1, 1, 1},
{ 0, 0, -1, 1, 1},
{ 1, 0, -1, 1, 1},
{-1, 0, -1, 1, 1},
{ 0, 1, -1, 1, 1},
{ 1, 1, -1, 1, 1},
{-1, 1, -1, 1, 1},
{ 0, -1, -1, 1, 1},
{ 1, -1, -1, 1, 1},
{-1, -1, -1, 1, 1},
{ 0, 0, 0, -1, 1},
{ 1, 0, 0, -1, 1},
{-1, 0, 0, -1, 1},
{ 0, 1, 0, -1, 1},
{ 1, 1, 0, -1, 1},
{-1, 1, 0, -1, 1},
{ 0, -1, 0, -1, 1},
{ 1, -1, 0, -1, 1},
{-1, -1, 0, -1, 1},
{ 0, 0, 1, -1, 1},
{ 1, 0, 1, -1, 1},
{-1, 0, 1, -1, 1},
{ 0, 1, 1, -1, 1},
{ 1, 1, 1, -1, 1},
{-1, 1, 1, -1, 1},
{ 0, -1, 1, -1, 1},
{ 1, -1, 1, -1, 1},
{-1, -1, 1, -1, 1},
{ 0, 0, -1, -1, 1},
{ 1, 0, -1, -1, 1},
{-1, 0, -1, -1, 1},
{ 0, 1, -1, -1, 1},
{ 1, 1, -1, -1, 1},
{-1, 1, -1, -1, 1},
{ 0, -1, -1, -1, 1},
{ 1, -1, -1, -1, 1},
{-1, -1, -1, -1, 1},
{ 0, 0, 0, 0, -1},
{ 1, 0, 0, 0, -1},
{-1, 0, 0, 0, -1},
{ 0, 1, 0, 0, -1},
{ 1, 1, 0, 0, -1},
{-1, 1, 0, 0, -1},
{ 0, -1, 0, 0, -1},
{ 1, -1, 0, 0, -1},
{-1, -1, 0, 0, -1},
{ 0, 0, 1, 0, -1},
{ 1, 0, 1, 0, -1},
{-1, 0, 1, 0, -1},
{ 0, 1, 1, 0, -1},
{ 1, 1, 1, 0, -1},
{-1, 1, 1, 0, -1},
{ 0, -1, 1, 0, -1},
{ 1, -1, 1, 0, -1},
{-1, -1, 1, 0, -1},
{ 0, 0, -1, 0, -1},
{ 1, 0, -1, 0, -1},
{-1, 0, -1, 0, -1},
{ 0, 1, -1, 0, -1},
{ 1, 1, -1, 0, -1},
{-1, 1, -1, 0, -1},
{ 0, -1, -1, 0, -1},
{ 1, -1, -1, 0, -1},
{-1, -1, -1, 0, -1},
{ 0, 0, 0, 1, -1},
{ 1, 0, 0, 1, -1},
{-1, 0, 0, 1, -1},
{ 0, 1, 0, 1, -1},
{ 1, 1, 0, 1, -1},
{-1, 1, 0, 1, -1},
{ 0, -1, 0, 1, -1},
{ 1, -1, 0, 1, -1},
{-1, -1, 0, 1, -1},
{ 0, 0, 1, 1, -1},
{ 1, 0, 1, 1, -1},
{-1, 0, 1, 1, -1},
{ 0, 1, 1, 1, -1},
{ 1, 1, 1, 1, -1},
{-1, 1, 1, 1, -1},
{ 0, -1, 1, 1, -1},
{ 1, -1, 1, 1, -1},
{-1, -1, 1, 1, -1},
{ 0, 0, -1, 1, -1},
{ 1, 0, -1, 1, -1},
{-1, 0, -1, 1, -1},
{ 0, 1, -1, 1, -1},
{ 1, 1, -1, 1, -1},
{-1, 1, -1, 1, -1},
{ 0, -1, -1, 1, -1},
{ 1, -1, -1, 1, -1},
{-1, -1, -1, 1, -1},
{ 0, 0, 0, -1, -1},
{ 1, 0, 0, -1, -1},
{-1, 0, 0, -1, -1},
{ 0, 1, 0, -1, -1},
{ 1, 1, 0, -1, -1},
{-1, 1, 0, -1, -1},
{ 0, -1, 0, -1, -1},
{ 1, -1, 0, -1, -1},
{-1, -1, 0, -1, -1},
{ 0, 0, 1, -1, -1},
{ 1, 0, 1, -1, -1},
{-1, 0, 1, -1, -1},
{ 0, 1, 1, -1, -1},
{ 1, 1, 1, -1, -1},
{-1, 1, 1, -1, -1},
{ 0, -1, 1, -1, -1},
{ 1, -1, 1, -1, -1},
{-1, -1, 1, -1, -1},
{ 0, 0, -1, -1, -1},
{ 1, 0, -1, -1, -1},
{-1, 0, -1, -1, -1},
{ 0, 1, -1, -1, -1},
{ 1, 1, -1, -1, -1},
{-1, 1, -1, -1, -1},
{ 0, -1, -1, -1, -1},
{ 1, -1, -1, -1, -1},
{-1, -1, -1, -1, -1}
};
void ntru_MGF(uint8_t *seed, uint16_t seed_len, const NtruEncParams *params, NtruIntPoly *i) {
uint16_t N = params->N;
i->N = N;
uint16_t min_calls_mask = params->min_calls_mask;
uint16_t hlen = params->hlen;
uint8_t buf[min_calls_mask * hlen];
uint16_t buf_len = 0;
uint8_t Z[hlen];
params->hash(seed, seed_len, (uint8_t*)&Z); /* hashSeed is always true */
uint16_t counter = 0;
uint8_t H[hlen];
uint16_t inp_len = hlen + sizeof counter;
uint8_t hash_inp[inp_len];
while (counter < min_calls_mask-7) {
uint8_t H_arr[8][NTRU_MAX_HASH_LEN];
uint8_t j;
uint8_t hash_inp_arr[8][inp_len];
uint8_t *hash_inp[8];
for (j=0; j<8; j++) {
uint16_t counter_endian = htons(counter); /* convert to network byte order */
memcpy(&hash_inp_arr[j], Z, sizeof Z);
memcpy((uint8_t*)&hash_inp_arr[j] + sizeof Z, &counter_endian, sizeof counter_endian);
hash_inp[j] = hash_inp_arr[j];
counter++;
}
uint8_t *H[8];
for (j=0; j<8; j++)
H[j] = H_arr[j];
params->hash_8way(hash_inp, inp_len, H);
uint16_t i;
for (j=0; j<8; j++)
for (i=0; i<hlen; i++)
if (H[j][i] < 243) { /* 243 = 3^5 */
buf[buf_len] = H[j][i];
buf_len++;
}
}
while (counter < min_calls_mask-3) {
uint8_t H_arr[4][NTRU_MAX_HASH_LEN];
uint8_t j;
uint8_t hash_inp_arr[4][inp_len];
uint8_t *hash_inp[4];
for (j=0; j<4; j++) {
uint16_t counter_endian = htons(counter); /* convert to network byte order */
memcpy(&hash_inp_arr[j], Z, sizeof Z);
memcpy((uint8_t*)&hash_inp_arr[j] + sizeof Z, &counter_endian, sizeof counter_endian);
hash_inp[j] = hash_inp_arr[j];
counter++;
}
uint8_t *H[4];
for (j=0; j<4; j++)
H[j] = H_arr[j];
params->hash_4way(hash_inp, inp_len, H);
uint16_t i;
for (j=0; j<4; j++)
for (i=0; i<hlen; i++)
if (H[j][i] < 243) { /* 243 = 3^5 */
buf[buf_len] = H[j][i];
buf_len++;
}
}
while (counter < min_calls_mask) {
uint16_t counter_endian = htons(counter); /* convert to network byte order */
memcpy(&hash_inp, Z, sizeof Z);
memcpy((uint8_t*)&hash_inp + sizeof Z, &counter_endian, sizeof counter_endian);
params->hash((uint8_t*)&hash_inp, inp_len, (uint8_t*)&H);
uint16_t i;
for (i=0; i<hlen; i++)
if (H[i] < 243) { /* 243 = 3^5 */
buf[buf_len] = H[i];
buf_len++;
}
counter++;
}
for (;;) {
uint16_t cur = 0;
uint16_t j;
for (j=0; j<buf_len; j++) {
uint8_t O = buf[j];
memcpy(&i->coeffs[cur], NTRU_MGF_TRIT_TBL[O], 10); /* copy 5 uint16_t's */
cur += 5;
if (cur >= N)
return;
}
if (cur >= N)
return;
memcpy(&hash_inp, Z, sizeof Z);
memcpy((uint8_t*)&hash_inp + hlen, &counter, sizeof counter);
params->hash((uint8_t*)&hash_inp, inp_len, (uint8_t*)&H);
memcpy(&buf, &H, hlen);
buf_len = hlen;
}
}