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:
commit
10f6ebc9e6
256
src/poly.c
256
src/poly.c
@ -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 */
|
||||
|
38
src/poly.h
38
src/poly.h
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user