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/tests/test_util.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "test_util.h"
#include "poly.h"
/** For equals_hash_func() */
#define HASH_INPUT_LEN 100
void rand_poly(NtruIntPoly *a, uint16_t N, uint16_t modulus) {
uint16_t i;
a->N = N;
for (i=0; i<N; i++)
a->coeffs[i] = random() % modulus;
}
uint8_t equals_one(NtruIntPoly *a) {
uint16_t i;
for (i=1; i<a->N; i++)
if (a->coeffs[i] != 0)
return 0;
return a->coeffs[0] == 1;
}
uint8_t equals_poly(NtruIntPoly *a, NtruIntPoly *b) {
if (a->N != b->N)
return 0;
uint16_t i;
for (i=0; i<a->N; i++)
if (a->coeffs[i] != b->coeffs[i])
return 0;
return 1;
}
uint8_t equals_poly_mod(NtruIntPoly *a, NtruIntPoly *b, uint16_t modulus) {
if (a->N != b->N)
return 0;
uint16_t i;
for (i=0; i<a->N; i++)
if ((a->coeffs[i]-b->coeffs[i]) % modulus)
return 0;
return 1;
}
uint8_t equals_tern(NtruTernPoly *a, NtruTernPoly *b) {
if (a->N != b->N)
return 0;
if (a->num_ones != b->num_ones)
return 0;
if (a->num_neg_ones != b->num_neg_ones)
return 0;
uint16_t i;
for (i=0; i<a->num_ones; i++)
if (a->ones[i] != b->ones[i])
return 0;
for (i=0; i<a->num_neg_ones; i++)
if (a->neg_ones[i] != b->neg_ones[i])
return 0;
return 1;
}
#ifndef NTRU_AVOID_HAMMING_WT_PATENT
uint8_t equals_prod(NtruProdPoly *a, NtruProdPoly *b) {
return a->N==b->N && equals_tern(&a->f1, &b->f1) && equals_tern(&a->f2, &b->f2) && equals_tern(&a->f3, &b->f3);
}
#endif /* NTRU_AVOID_HAMMING_WT_PATENT */
uint8_t equals_key_pair(NtruEncKeyPair *kp1, NtruEncKeyPair *kp2) {
if (kp1->priv.q != kp2->priv.q)
return 0;
#ifndef NTRU_AVOID_HAMMING_WT_PATENT
if (kp1->priv.t.prod_flag && !equals_prod(&kp1->priv.t.poly.prod, &kp2->priv.t.poly.prod))
return 0;
#endif /* NTRU_AVOID_HAMMING_WT_PATENT */
if (!kp1->priv.t.prod_flag && !equals_tern(&kp1->priv.t.poly.tern, &kp2->priv.t.poly.tern))
return 0;
if (kp1->pub.q != kp2->pub.q)
return 0;
if (!equals_poly(&kp1->pub.h, &kp2->pub.h))
return 0;
return 1;
}
uint8_t equals_arr(uint8_t *arr1, uint8_t *arr2, uint16_t len) {
uint16_t i;
for (i=0; i<len; i++)
if (arr1[i] != arr2[i])
return 0;
return 1;
}
/**
* A probabilistic test for equality of two hash functions.
* Calls the two hash functions with a random input value
* and considers the functions equal if the outputs match.
*/
int equals_hash_func(void (*func1)(uint8_t[], uint16_t, uint8_t[]), void (*func2)(uint8_t[], uint16_t, uint8_t[]), uint8_t hash_len) {
srand(0);
uint8_t input[HASH_INPUT_LEN];
uint8_t i;
for (i=0; i<HASH_INPUT_LEN; i++)
input[i] = rand();
uint8_t hash1[256];
uint8_t hash2[256];
func1(input, HASH_INPUT_LEN, hash1);
func2(input, HASH_INPUT_LEN, hash2);
return memcmp(hash1, hash2, hash_len) == 0;
}
uint8_t equals_params(NtruEncParams *params1, NtruEncParams *params2) {
uint8_t equal = 1;
equal &= strcmp(params1->name, params2->name) == 0;
equal &= params1->N == params2->N;
equal &= params1->q == params2->q;
equal &= params1->prod_flag == params2->prod_flag;
equal &= params1->df1 == params2->df1;
if (params1->prod_flag) {
equal &= params1->df2 == params2->df2;
equal &= params1->df3 == params2->df3;
}
equal &= params1->dm0 == params2->dm0;
equal &= params1->db == params2->db;
equal &= params1->c == params2->c;
equal &= params1->min_calls_r == params2->min_calls_r;
equal &= params1->min_calls_mask == params2->min_calls_mask;
equal &= params1->hash_seed == params2->hash_seed;
equal &= memcmp(params1->oid, params2->oid, sizeof(params1->oid)) == 0;
equal &= equals_hash_func(params1->hash, params2->hash, params1->hlen);
equal &= params1->hlen == params2->hlen;
equal &= params1->pklen == params2->pklen;
return equal;
}
uint8_t rand_poly_pow2(uint16_t N, uint16_t pow2q, NtruIntPoly *poly, NtruRandContext *rand_ctx) {
uint16_t rand_data[N];
if (!rand_ctx->rand_gen->generate((uint8_t*)rand_data, N*2, rand_ctx))
return 0;
poly->N = N;
uint16_t shift = 16 - pow2q;
while ((int16_t)--N >= 0)
poly->coeffs[N] = rand_data[N] >> shift;
return 1;
}
void ntru_tern_to_int(NtruTernPoly *a, NtruIntPoly *b) {
memset(&b->coeffs, 0, a->N * sizeof b->coeffs[0]);
uint16_t i;
for (i=0; i<a->num_ones; i++)
b->coeffs[a->ones[i]] = 1;
for (i=0; i<a->num_neg_ones; i++)
b->coeffs[a->neg_ones[i]] = -1;
b->N = a->N;
}
void ntru_add_tern(NtruIntPoly *a, NtruTernPoly *b) {
uint16_t i;
for (i=0; i<b->num_ones; i++)
a->coeffs[b->ones[i]]++;
for (i=0; i<b->num_neg_ones; i++)
a->coeffs[b->neg_ones[i]]--;
}
#ifndef NTRU_AVOID_HAMMING_WT_PATENT
void ntru_prod_to_int(NtruProdPoly *a, NtruIntPoly *b, uint16_t modulus) {
memset(&b->coeffs, 0, a->N * sizeof b->coeffs[0]);
b->N = a->N;
uint16_t mod_mask = modulus - 1;
NtruIntPoly c;
ntru_tern_to_int(&a->f1, &c);
ntru_mult_tern(&c, &a->f2, b, mod_mask);
ntru_add_tern(b, &a->f3);
}
#endif /* NTRU_AVOID_HAMMING_WT_PATENT */
void ntru_priv_to_int(NtruPrivPoly *a, NtruIntPoly *b, uint16_t modulus) {
#ifndef NTRU_AVOID_HAMMING_WT_PATENT
if (a->prod_flag)
ntru_prod_to_int(&a->poly.prod, b, modulus);
else
#endif /* NTRU_AVOID_HAMMING_WT_PATENT */
ntru_tern_to_int(&a->poly.tern, b);
}
void str_to_uint8(char *in, uint8_t *out) {
size_t len = strlen(in);
size_t i;
for (i=0; i<len; i++)
out[i] = (uint8_t)in[i];
}
void print_result(char *test_name, uint8_t valid) {
#ifdef WIN32
printf(" %-25s%s\n", test_name, valid?"OK":"FAIL");
#else
printf(" %-25s%s\n", test_name, valid?"✓":"FAIL");
#endif
}