Merge branch 'master' of ssh://gitlab.hasufell.de:22022/pcq/quantumcrypto

Conflicts:
	src/poly.c
	src/poly.h
	src/rand.c

merged with master repo
This commit is contained in:
malte 2014-05-13 16:54:31 +02:00
commit 10f6ebc9e6
3 changed files with 253 additions and 48 deletions

View File

@ -35,7 +35,6 @@
/*
* static declarations
*/
static unsigned int get_degree(pb_poly const * const poly);
static void pb_mod2_to_modq(pb_poly * const a,
pb_poly *Fq,
ntru_context *ctx);
@ -43,7 +42,7 @@ static void pb_mod2_to_modq(pb_poly * const a,
/**
* Initialize a mp_int and check if this was successful, the
* caller must free new_int with mp_clear().
* caller must free new_int.
*
* @param new_int a pointer to the mp_int you want to initialize
*/
@ -56,6 +55,26 @@ void init_integer(mp_int *new_int)
}
}
/**
* Initialize one ore more mp_int and check if this was successful, the
* caller must free new_int with mp_clear().
*
* @param new_int a pointer to the mp_int you want to initialize
*/
void init_integers(mp_int *new_int, ...)
{
mp_int *next_mp;
va_list args;
next_mp = new_int;
va_start(args, new_int);
while (next_mp != NULL) {
init_integer(next_mp);
next_mp = va_arg(args, mp_int*);
}
va_end(args);
}
/**
* Initialize a Polynom with a pb_poly and a mp_int as characteristic.
* Checks if everything went fine. The caller must free new_poly
@ -98,7 +117,7 @@ void init_polynom_size(pb_poly *new_poly, mp_int *chara, size_t size)
* pointer which is not clamped.
*
* If you want to fill a polyonmial of length 11 with zeros,
* call build_polynom(NULL, 11, ctx).
* call build_polynom(NULL, 11).
*
* @param c array of polynomial coefficients, can be NULL
* @param len size of the coefficient array, can be 0
@ -107,8 +126,7 @@ void init_polynom_size(pb_poly *new_poly, mp_int *chara, size_t size)
* with delete_polynom()
*/
pb_poly *build_polynom(int const * const c,
const size_t len,
ntru_context *ctx)
const size_t len)
{
pb_poly *new_poly;
mp_int chara;
@ -120,23 +138,9 @@ pb_poly *build_polynom(int const * const c,
/* fill the polynom if c is not NULL */
if (c) {
for (unsigned int i = 0; i < len; i++) {
bool sign = false;
unsigned long unsigned_c;
if (c[i] < 0) {
unsigned_c = 0 - c[i];
sign = true;
} else {
unsigned_c = c[i];
}
MP_SET_INT(&(new_poly->terms[i]), unsigned_c);
if (sign == true)
mp_neg(&(new_poly->terms[i]), &(new_poly->terms[i]));
}
} else { /* fill with zeros */
for (unsigned int i = 0; i < len; i++)
MP_SET_INT(&(new_poly->terms[i]), c[i]);
} else { /* fill with 0 */
for (unsigned int i = 0; i < len; i++)
MP_SET(&(new_poly->terms[i]), 0);
}
@ -221,7 +225,7 @@ void pb_starmultiply(pb_poly *a,
MP_SET_INT(&mp_modulus, (unsigned long)(modulus));
/* avoid side effects */
a_tmp = build_polynom(NULL, ctx->N, ctx);
a_tmp = build_polynom(NULL, ctx->N);
PB_COPY(a, a_tmp);
erase_polynom(c, ctx->N);
@ -251,6 +255,29 @@ void pb_starmultiply(pb_poly *a,
delete_polynom(a_tmp);
}
/**
* Calculate c = a * b where c and a are polynomials
* and b is an mp_int.
*
* @param a polynom
* @param b mp_int
* @param c polynom [out]
* @return error code of pb_mul()
*/
int pb_mp_mul(pb_poly *a, mp_int *b, pb_poly *c)
{
int result;
pb_poly *b_poly = build_polynom(NULL, 1);
MP_COPY(b, &(b_poly->terms[0]));
printf("u converted to poly: "); draw_polynom(b_poly);
result = pb_mul(a, b_poly, c);
delete_polynom(b_poly);
return result;
}
/**
* c = a XOR b
*
@ -273,11 +300,11 @@ void pb_xor(pb_poly *a,
* Get the degree of the polynomial.
*
* @param poly the polynomial
* @return the degree
* @return the degree, -1 if polynom is empty
*/
static unsigned int get_degree(pb_poly const * const poly)
int get_degree(pb_poly const * const poly)
{
unsigned int count = 0;
int count = -1;
for (int i = 0; i < poly->alloc; i++)
if (mp_iszero(&(poly->terms[i])) == MP_NO)
@ -304,14 +331,13 @@ static void pb_mod2_to_modq(pb_poly * const a,
pb_poly *pb_tmp,
*pb_tmp2;
mp_int tmp_v;
pb_tmp = build_polynom(NULL, ctx->N, ctx);
pb_tmp = build_polynom(NULL, ctx->N);
v = v * 2;
init_integer(&tmp_v);
MP_SET_INT(&tmp_v, v);
pb_tmp2 = build_polynom(NULL, ctx->N, ctx);
pb_tmp2 = build_polynom(NULL, ctx->N);
MP_SET_INT(&(pb_tmp2->terms[0]), 2);
/* mod after sub or before? */
pb_starmultiply(a, Fq, pb_tmp, ctx, v);
PB_SUB(pb_tmp2, pb_tmp, pb_tmp);
PB_MOD(pb_tmp, &tmp_v, pb_tmp, ctx->N);
@ -328,7 +354,7 @@ static void pb_mod2_to_modq(pb_poly * const a,
* @param a polynomial to invert (is allowed to be the same as param Fq)
* @param Fq polynomial [out]
* @param ctx NTRU context
* @return true/false for success/failure
* @return true if invertible, false if not
*/
bool pb_inverse_poly_q(pb_poly * const a,
pb_poly *Fq,
@ -337,34 +363,44 @@ bool pb_inverse_poly_q(pb_poly * const a,
int k = 0,
j = 0;
pb_poly *a_tmp, *b, *c, *f, *g;
mp_int mp_modulus;
b = build_polynom(NULL, ctx->N + 1, ctx);
/* general initialization of temp variables */
init_integer(&mp_modulus);
MP_SET_INT(&mp_modulus, (unsigned long)(ctx->q));
b = build_polynom(NULL, ctx->N + 1);
MP_SET(&(b->terms[0]), 1);
c = build_polynom(NULL, ctx->N + 1, ctx);
f = build_polynom(NULL, ctx->N + 1, ctx);
c = build_polynom(NULL, ctx->N + 1);
f = build_polynom(NULL, ctx->N + 1);
PB_COPY(a, f);
g = build_polynom(NULL, ctx->N + 1, ctx);
/* set g(x) = x^N 1 */
g = build_polynom(NULL, ctx->N + 1);
MP_SET(&(g->terms[0]), 1);
mp_neg(&(g->terms[0]), &(g->terms[0]));
MP_SET(&(g->terms[ctx->N]), 1);
/* avoid side effects */
a_tmp = build_polynom(NULL, ctx->N, ctx);
a_tmp = build_polynom(NULL, ctx->N);
PB_COPY(a, a_tmp);
erase_polynom(Fq, ctx->N);
while (1) {
while (mp_cmp_d(&(f->terms[0]), 0) == MP_EQ) {
for (unsigned int i = 1; i <= ctx->N; i++) {
/* f(x) = f(x) / x */
MP_COPY(&(f->terms[i]), &(f->terms[i - 1]));
/* c(x) = c(x) * x */
MP_COPY(&(c->terms[ctx->N - i]), &(c->terms[ctx->N + 1 - i]));
}
MP_SET(&(f->terms[ctx->N]), 0);
MP_SET(&(c->terms[0]), 0);
k++;
if (get_degree(f) == -1)
return false;
}
if (get_degree(f) == 0)
goto OUT_OF_LOOP;
break;
if (get_degree(f) < get_degree(g)) {
pb_exch(f, g);
@ -375,9 +411,12 @@ bool pb_inverse_poly_q(pb_poly * const a,
pb_xor(b, c, b, ctx->N);
}
OUT_OF_LOOP:
k = k % ctx->N;
if (mp_cmp_d(&(b->terms[ctx->N]), 0) != MP_EQ)
return false;
/* Fq(x) = x^(N-k) * b(x) */
for (int i = ctx->N - 1; i >= 0; i--) {
j = i - k;
if (j < 0)
@ -387,15 +426,144 @@ OUT_OF_LOOP:
pb_mod2_to_modq(a_tmp, Fq, ctx);
/* pull into positive space */
for (int i = ctx->N - 1; i >= 0; i--)
if (mp_cmp_d(&(Fq->terms[i]), 0) == MP_LT) {
mp_int mp_tmp;
init_integer(&mp_tmp);
MP_SET_INT(&mp_tmp, ctx->q);
MP_ADD(&(Fq->terms[i]), &mp_tmp, &(Fq->terms[i]));
mp_clear(&mp_tmp);
if (mp_cmp_d(&(Fq->terms[i]), 0) == MP_LT)
MP_ADD(&(Fq->terms[i]), &mp_modulus, &(Fq->terms[i]));
delete_polynom_multi(a_tmp, b, c, f, g, NULL);
mp_clear(&mp_modulus);
/* TODO: check if the f * Fq = 1 (mod p) condition holds true */
return true;
}
/**
* Invert the polynomial a modulo p.
*
* @param a polynomial to invert
* @param Fq polynomial [out]
* @param ctx NTRU context
*/
bool pb_inverse_poly_p(pb_poly *a,
pb_poly *Fp,
ntru_context *ctx)
{
int k = 0,
j = 0;
pb_poly *a_tmp, *b, *c, *f, *g;
mp_int mp_modulus;
/* general initialization of temp variables */
init_integer(&mp_modulus);
MP_SET_INT(&mp_modulus, (unsigned long)(ctx->p));
b = build_polynom(NULL, ctx->N + 1);
MP_SET(&(b->terms[0]), 1);
c = build_polynom(NULL, ctx->N + 1);
f = build_polynom(NULL, ctx->N + 1);
PB_COPY(a, f);
/* set g(x) = x^N 1 */
g = build_polynom(NULL, ctx->N + 1);
MP_SET_INT(&(g->terms[0]), -1);
MP_SET(&(g->terms[ctx->N]), 1);
/* avoid side effects */
a_tmp = build_polynom(NULL, ctx->N);
PB_COPY(a, a_tmp);
erase_polynom(Fp, ctx->N);
printf("f: "); draw_polynom(f);
printf("g: "); draw_polynom(g);
while (1) {
while (mp_cmp_d(&(f->terms[0]), 0) == MP_EQ) {
for (unsigned int i = 1; i <= ctx->N; i++) {
/* f(x) = f(x) / x */
MP_COPY(&(f->terms[i]), &(f->terms[i - 1]));
/* c(x) = c(x) * x */
MP_COPY(&(c->terms[ctx->N - i]), &(c->terms[ctx->N + 1 - i]));
}
MP_SET(&(f->terms[ctx->N]), 0);
MP_SET(&(c->terms[0]), 0);
k++;
}
if (get_degree(f) == 0)
break;
if (get_degree(f) < get_degree(g)) {
/* exchange f and g and exchange b and c */
pb_exch(f, g);
pb_exch(b, c);
}
{
pb_poly *c_tmp, *g_tmp;
mp_int u, mp_tmp;
init_integers(&u, &mp_tmp, NULL);
g_tmp = build_polynom(NULL, ctx->N + 1);
PB_COPY(g, g_tmp);
c_tmp = build_polynom(NULL, ctx->N + 1);
PB_COPY(c, c_tmp);
/* u = f[0] * g[0]^(-1) mod p
* = (f[0] mod p) * (g[0] inverse mod p) mod p */
MP_COPY(&(f->terms[0]), &mp_tmp);
MP_INVMOD(&(g->terms[0]), &mp_modulus, &u);
MP_MOD(&mp_tmp, &mp_modulus, &mp_tmp);
MP_MUL(&u, &mp_tmp, &u);
MP_MOD(&u, &mp_modulus, &u);
/* f = f - u * g mod p */
PB_MP_MUL(g_tmp, &u, g_tmp);
PB_SUB(f, g_tmp, f);
PB_MOD(f, &mp_modulus, f, ctx->N + 1);
/* b = b - u * c mod p */
PB_MP_MUL(c_tmp, &u, c_tmp);
PB_SUB(b, c_tmp, b);
PB_MOD(b, &mp_modulus, b, ctx->N + 1);
mp_clear(&mp_tmp);
delete_polynom_multi(c_tmp, g_tmp, NULL);
}
}
k = k % ctx->N;
/* Fp(x) = x^(N-k) * b(x) */
for (int i = ctx->N - 1; i >= 0; i--) {
/* b(X) = f[0]^(-1) * b(X) (mod p) */
{
pb_poly *poly_tmp;
poly_tmp = build_polynom(NULL, 1);
MP_INVMOD(&(f->terms[0]), &mp_modulus, &(poly_tmp->terms[0]));
MP_MOD(&(b->terms[i]), &mp_modulus, &(b->terms[i]));
MP_MUL(&(b->terms[i]), &(poly_tmp->terms[0]), &(b->terms[i]));
delete_polynom(poly_tmp);
}
j = i - k;
if (j < 0)
j = j + ctx->N;
MP_COPY(&(b->terms[i]), &(Fp->terms[j]));
/* delete_polynom(f_tmp); */
}
/* pull into positive space */
for (int i = ctx->N - 1; i >= 0; i--)
if (mp_cmp_d(&(Fp->terms[i]), 0) == MP_LT)
MP_ADD(&(Fp->terms[i]), &mp_modulus, &(Fp->terms[i]));
mp_clear(&mp_modulus);
delete_polynom_multi(a_tmp, b, c, f, g, NULL);
/* TODO: check if the f * Fq = 1 (mod p) condition holds true */

View File

@ -30,15 +30,19 @@
#include <tommath.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#define MP_SET(...) mp_set(__VA_ARGS__)
#define MP_SET_INT(...) \
#define MP_SET_INT(a, b) \
{ \
int result; \
if ((result = mp_set_int(__VA_ARGS__)) != MP_OKAY) \
if ((result = mp_set_int(a, (unsigned long)abs(b))) != MP_OKAY) \
NTRU_ABORT("Error setting long constant. %s", \
mp_error_to_string(result)); \
if ((int)b < 0) \
mp_neg(a, a); \
}
#define MP_MUL(...) \
@ -105,6 +109,14 @@
mp_error_to_string(result)); \
}
#define MP_INVMOD(...) \
{ \
int result; \
if ((result = mp_invmod(__VA_ARGS__)) != MP_OKAY) \
NTRU_ABORT("Error computing modular inverse. %s", \
mp_error_to_string(result)); \
}
#define MP_EXPT_D(...) \
{ \
int result; \
@ -121,6 +133,14 @@
mp_error_to_string(result)); \
}
#define PB_MP_MUL(...) \
{ \
int result; \
if ((result = pb_mp_mul(__VA_ARGS__)) != MP_OKAY) \
NTRU_ABORT("Error multiplying polynomial with mp_int. %s", \
mp_error_to_string(result)); \
}
#define PB_ADD(...) \
{ \
int result; \
@ -151,15 +171,17 @@
mp_error_to_string(result)); \
}
void init_integer(mp_int *new_int);
void init_integers(mp_int *new_int, ...);
void init_polynom(pb_poly *new_poly, mp_int *chara);
void init_polynom_size(pb_poly *new_poly, mp_int *chara, size_t size);
pb_poly *build_polynom(int const * const c,
const size_t len,
ntru_context *ctx);
const size_t len);
void erase_polynom(pb_poly *poly, size_t len);
@ -173,15 +195,23 @@ void pb_starmultiply(pb_poly *a,
ntru_context *ctx,
unsigned int modulus);
int pb_mp_mul(pb_poly *a, mp_int *b, pb_poly *c);
void pb_xor(pb_poly *a,
pb_poly *b,
pb_poly *c,
const size_t len);
int get_degree(pb_poly const * const poly);
bool pb_inverse_poly_q(pb_poly *a,
pb_poly *Fq,
ntru_context *ctx);
bool pb_inverse_poly_p(pb_poly *a,
pb_poly *Fp,
ntru_context *ctx);
void draw_polynom(pb_poly * const poly);
#endif /* NTRU_POLY_H */

View File

@ -25,12 +25,16 @@
#include "rand.h"
#include <math.h>
#include "poly.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <tompoly.h>
#include <tommath.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/*
@ -80,6 +84,7 @@ static mp_digit get_int_dev_urandom(void)
ssize_t result;
random_data = open("/dev/urandom", O_RDONLY);
random_data = open("/dev/urandom", O_RDONLY);
if ((result = read(random_data, &random_int, sizeof(random_int))) < 0)
NTRU_ABORT("Unable to read /dev/urandom.\n");
close(random_data);
@ -105,8 +110,10 @@ static mp_digit get_random_ternary(mp_digit random_int, int* sign)
random_int = 1;
*sign = 1;
} else {
random_int = 1;
*sign = 0;
}
return random_int;
}