From 5e7c980831033ee6a0f4bc5a7a5b30157bb29c8b Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 16:56:38 +0200 Subject: [PATCH 01/22] DOC: improve memory handling instructions --- src/poly.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/poly.c b/src/poly.c index b6dfe14..01dade9 100644 --- a/src/poly.c +++ b/src/poly.c @@ -27,7 +27,7 @@ /** * Initialize a mp_int and check if this was successful, the - * caller must free new_int. + * caller must free new_int with mp_clear(). * * @param new_int a pointer to the mp_int you want to initialize */ @@ -42,7 +42,8 @@ void init_integer(mp_int *new_int) /** * Initialize a Polynom with a pb_poly and a mp_int as characteristic. - * Checks if everything went fine. The caller must free new_poly. + * Checks if everything went fine. The caller must free new_poly + * with pb_clear(). * * @param new_poly the pb_poly you want to initialize * @param chara the characteristic @@ -59,7 +60,7 @@ void init_polynom(pb_poly *new_poly, mp_int *chara) /** * Initialize a Polynom with a pb_poly adn a mp_int as characteristic * with size. Checks if everything went fine. The caller must free - * new_poly. + * new_poly with pb_clear(). * * @param new_poly the pb_poly you want to initialize * @param chara the characteristic From 783858a52c44d6fc134469b9b616a115780f2e09 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 18:20:08 +0200 Subject: [PATCH 02/22] POLY: use size_t --- src/poly.c | 2 +- src/poly.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/poly.c b/src/poly.c index 01dade9..8625a13 100644 --- a/src/poly.c +++ b/src/poly.c @@ -66,7 +66,7 @@ void init_polynom(pb_poly *new_poly, mp_int *chara) * @param chara the characteristic * @param size the size of the polynomial */ -void init_polynom_size(pb_poly *new_poly, mp_int *chara, int size) +void init_polynom_size(pb_poly *new_poly, mp_int *chara, size_t size) { int result; if ((result = pb_init_size(new_poly, chara, size)) != MP_OKAY) { diff --git a/src/poly.h b/src/poly.h index 6bca69d..7b534ba 100644 --- a/src/poly.h +++ b/src/poly.h @@ -31,7 +31,7 @@ void init_integer(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, int size); +void init_polynom_size(pb_poly *new_poly, mp_int *chara, size_t size); void delete_polynom(pb_poly *new_poly); From 91c5ea7b82652706ab30395b76bebc1bd3ef4b76 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 18:21:42 +0200 Subject: [PATCH 03/22] RAND: use unsigned long instead of mp_digit if we use mp_set_int() instead of mp_set(), then we can use full unsigned long integers instead of single digits. This seems a lot safer, especially for future versions of the random algorithm. --- src/rand.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rand.c b/src/rand.c index d698164..c33bfa7 100644 --- a/src/rand.c +++ b/src/rand.c @@ -36,7 +36,7 @@ /* * static declarations */ -static mp_digit get_urnd_int_small(int *sign); +static unsigned long get_urnd_int_small(int *sign); /** @@ -46,7 +46,7 @@ static mp_digit get_urnd_int_small(int *sign); * @param sign stores the signness [out] * @return random small integer */ -static mp_digit get_urnd_int_small(int *sign) +static unsigned long get_urnd_int_small(int *sign) { int random_data; mp_digit random_int; @@ -86,11 +86,11 @@ pb_poly *ntru_get_urnd_poly_small(ntru_context *ctx) init_polynom_size(poly, &chara, ctx->N); mp_clear(&chara); - for (int i = 0; i < ctx->N; i++) { + for (unsigned int i = 0; i < ctx->N; i++) { int sign; - int c = get_urnd_int_small(&sign); + unsigned long c = get_urnd_int_small(&sign); - mp_set(&(poly->terms[i]), (mp_digit)c); + mp_set_int(&(poly->terms[i]), c); if (sign == 1) poly->terms[i].sign = 1; From 2b8eb4f1fa77e5534fe57b0ccb66cf48cce0ff5c Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 18:47:39 +0200 Subject: [PATCH 04/22] BUILD: ignore -Wunused-parameter Can happen in callback functions and so forth. --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 95b5320..4632fcc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,7 +4,7 @@ PKG_CONFIG ?= pkg-config # flags CFLAGS ?= -march=native -O2 -pipe -CFLAGS += -std=c99 -pedantic -Wall -Wextra -Werror -Wno-unused-variable +CFLAGS += -std=c99 -pedantic -Wall -Wextra -Werror -Wno-unused-variable -Wno-unused-parameter ifeq ($(shell $(CC) -v 2>&1 | grep 'gcc version' &>/dev/null && echo 1),1) CFLAGS += -Wno-unused-but-set-variable endif From b7b4ffbbea6239a125dc292a9f0556e81c111bed Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 18:47:58 +0200 Subject: [PATCH 05/22] DOC: fix typo --- src/poly.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/poly.c b/src/poly.c index 8625a13..18ca829 100644 --- a/src/poly.c +++ b/src/poly.c @@ -58,7 +58,7 @@ void init_polynom(pb_poly *new_poly, mp_int *chara) } /** - * Initialize a Polynom with a pb_poly adn a mp_int as characteristic + * Initialize a Polynom with a pb_poly and an mp_int as characteristic * with size. Checks if everything went fine. The caller must free * new_poly with pb_clear(). * From e60d9c9bac1020b8b859fd97d0be26947edf6969 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 18:49:17 +0200 Subject: [PATCH 06/22] POLY: add build_polynom() method We can build a polynom via an array of integers or just an empty one, so that it is initialized and properly allocated. --- src/poly.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/poly.h | 6 ++++++ 2 files changed, 57 insertions(+) diff --git a/src/poly.c b/src/poly.c index 18ca829..d6efb4c 100644 --- a/src/poly.c +++ b/src/poly.c @@ -19,8 +19,10 @@ * MA 02110-1301 USA */ +#include "context.h" #include "err.h" +#include #include #include #include @@ -75,6 +77,55 @@ void init_polynom_size(pb_poly *new_poly, mp_int *chara, size_t size) } } +/** + * Initializes and builds a polynomial with the + * coefficient values of c[] of size len within NTRU + * context ctx and returns a newly allocated polynomial + * pointer. + * + * @param c array of polynomial coefficients, can be NULL + * @param len size of the coefficient array, can be 0 + * @param ctx NTRU context + * @return newly allocated polynomial pointer, must be freed + * with delete_polynom() + */ +pb_poly *build_polynom(int const * const c, + const size_t len, + ntru_context *ctx) +{ + pb_poly *new_poly; + mp_int chara; + + new_poly = malloc(sizeof(*new_poly)); + init_integer(&chara); + init_polynom_size(new_poly, &chara, len); + mp_clear(&chara); + + /* 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) + new_poly->terms[i].sign = 1; + } + new_poly->used = len; + pb_clamp(new_poly); + } + + return new_poly; +} + /** * This deletes the internal structure of a polynomial, * and frees the pointer. Don't call this on stack variables, diff --git a/src/poly.h b/src/poly.h index 7b534ba..37cf639 100644 --- a/src/poly.h +++ b/src/poly.h @@ -23,6 +23,8 @@ #ifndef NTRU_POLY_H #define NTRU_POLY_H +#include "context.h" + #include #include @@ -33,6 +35,10 @@ 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); + void delete_polynom(pb_poly *new_poly); void draw_polynom(pb_poly * const poly); From 050dab62434bb2f29b3ad57f1dd5d6610dbd0751 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 18:49:33 +0200 Subject: [PATCH 07/22] ALL: set context members to unsigned int --- src/context.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/context.h b/src/context.h index ecc94f1..e0e0883 100644 --- a/src/context.h +++ b/src/context.h @@ -32,15 +32,15 @@ typedef struct { * maximal degree N - 1 for * all polynomials */ - int N; + unsigned int N; /** * large modulus */ - int q; + unsigned int q; /** * small modulus */ - int p; + unsigned int p; } ntru_context; #endif /* NTRU_CONTEXT_H */ From abf047a264731f381674f4c0e1da029ca457f4a3 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 22:50:11 +0200 Subject: [PATCH 08/22] POLY: don't clamp polyonmial in build_polynom() Otherwise we might hit problems when using this as an out-polynom in a arithmetic functions. The caller can clamp it himself, if he needs so. --- src/poly.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/poly.c b/src/poly.c index d6efb4c..01b03ff 100644 --- a/src/poly.c +++ b/src/poly.c @@ -81,7 +81,10 @@ void init_polynom_size(pb_poly *new_poly, mp_int *chara, size_t size) * Initializes and builds a polynomial with the * coefficient values of c[] of size len within NTRU * context ctx and returns a newly allocated polynomial - * pointer. + * pointer which is not clamped. + * + * If you want to fill a polyonmial of length 11 with zeros, + * call build_polynom(NULL, 11, ctx). * * @param c array of polynomial coefficients, can be NULL * @param len size of the coefficient array, can be 0 @@ -119,10 +122,13 @@ pb_poly *build_polynom(int const * const c, if (sign == true) new_poly->terms[i].sign = 1; } - new_poly->used = len; - pb_clamp(new_poly); + } else { /* fill with zeros */ + for (unsigned int i = 0; i < len; i++) + mp_set(&(new_poly->terms[i]), 0); } + new_poly->used = len; + return new_poly; } From df1df23e091dad6447f36e1b3d4bf8234b84bb44 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 22:50:42 +0200 Subject: [PATCH 09/22] POLY: first try of pb_starmultiply() --- src/poly.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/poly.h | 6 ++++++ 2 files changed, 60 insertions(+) diff --git a/src/poly.c b/src/poly.c index 01b03ff..2a999dd 100644 --- a/src/poly.c +++ b/src/poly.c @@ -146,6 +146,60 @@ void delete_polynom(pb_poly *poly) free(poly); } +/** + * Starmultiplication, as follows: + * c = a * b mod x^(N − 1) + * + * @param a polynom to multiply + * @param b polynom to multiply + * @param c polynom [out] + * @param ctx NTRU context + * @param modulus whether we use p or q + */ +void pb_starmultiply(pb_poly *a, + pb_poly *b, + pb_poly *c, + ntru_context *ctx, + unsigned int modulus) +{ + for (int k = ctx->N - 1; k >= 0; k--) { + int j; + j = k + 1; + + for (int i = ctx->N - 1; i >= 0; i--) { + if (j == (int)(ctx->N)) + j = 0; + if (mp_cmp_d(&(a->terms[i]), (mp_digit)0) != MP_EQ && + mp_cmp_d(&(b->terms[j]), (mp_digit)0) != MP_EQ) { + int result; + mp_int mp_modulus; + mp_int mp_tmp; + + init_integer(&mp_tmp); + init_integer(&mp_modulus); + mp_set_int(&mp_modulus, (unsigned long)(modulus)); + + if ((result = mp_mul(&(a->terms[i]), + &(b->terms[j]), &mp_tmp)) != MP_OKAY) + NTRU_ABORT("Error multiplying terms. %s", + mp_error_to_string(result)); + if ((result = mp_add(&(c->terms[k]), + &mp_tmp, &(c->terms[k]))) != MP_OKAY) + NTRU_ABORT("Error multiplying terms. %s", + mp_error_to_string(result)); + if ((result = mp_mod(&(c->terms[k]), + &mp_modulus, &(c->terms[k]))) != MP_OKAY) + NTRU_ABORT("Error multiplying terms. %s", + mp_error_to_string(result)); + + mp_clear(&mp_modulus); + mp_clear(&mp_tmp); + } + j++; + } + } +} + /** * Print the polynomial in a human readable format to stdout. * diff --git a/src/poly.h b/src/poly.h index 37cf639..ef9700d 100644 --- a/src/poly.h +++ b/src/poly.h @@ -41,6 +41,12 @@ pb_poly *build_polynom(int const * const c, void delete_polynom(pb_poly *new_poly); +void pb_starmultiply(pb_poly *a, + pb_poly *b, + pb_poly *c, + ntru_context *ctx, + unsigned int modulus); + void draw_polynom(pb_poly * const poly); #endif /* NTRU_POLY_H */ From cb4d274c58370b02e412aef02e0ebf0a3f12186e Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 22:54:11 +0200 Subject: [PATCH 10/22] POLY: fix error messages --- src/poly.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/poly.c b/src/poly.c index 2a999dd..16d8fe1 100644 --- a/src/poly.c +++ b/src/poly.c @@ -185,11 +185,11 @@ void pb_starmultiply(pb_poly *a, mp_error_to_string(result)); if ((result = mp_add(&(c->terms[k]), &mp_tmp, &(c->terms[k]))) != MP_OKAY) - NTRU_ABORT("Error multiplying terms. %s", + NTRU_ABORT("Error adding terms. %s", mp_error_to_string(result)); if ((result = mp_mod(&(c->terms[k]), &mp_modulus, &(c->terms[k]))) != MP_OKAY) - NTRU_ABORT("Error multiplying terms. %s", + NTRU_ABORT("Error redrucing term by modulo. %s", mp_error_to_string(result)); mp_clear(&mp_modulus); From e4cf4331d99eb92bbb55b089b6b9c99bbb103ce0 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 15 Apr 2014 23:11:55 +0200 Subject: [PATCH 11/22] BUILD: fix linker errors when playing in main.c --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 4632fcc..07299e0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -80,7 +80,7 @@ libpqc.so: libpqc.a $(PQC_HEADERS) $(LIBTOMMATH) $(LIBTOMPOLY) main: main.o libpqc.a $(LIBTOMMATH) $(LIBTOMPOLY) $(CC) $(CFLAGS) -o $@ $(LDFLAGS) \ - main.o libpqc.a $(LIBTOMMATH) $(LIBTOMPOLY) $(LIBS) + main.o $(LIBTOMPOLY) libpqc.a $(LIBTOMMATH) $(LIBS) install: $(INSTALL_DIR) "$(DESTDIR)$(INSTALL_BINDIR)" From 1179082ac1e86f4b14ed88032eb5afe2017c3ee9 Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 16 Apr 2014 23:17:48 +0200 Subject: [PATCH 12/22] POLY: fix typo --- src/poly.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/poly.c b/src/poly.c index 16d8fe1..ac7d4d4 100644 --- a/src/poly.c +++ b/src/poly.c @@ -189,7 +189,7 @@ void pb_starmultiply(pb_poly *a, mp_error_to_string(result)); if ((result = mp_mod(&(c->terms[k]), &mp_modulus, &(c->terms[k]))) != MP_OKAY) - NTRU_ABORT("Error redrucing term by modulo. %s", + NTRU_ABORT("Error reducing term by modulo. %s", mp_error_to_string(result)); mp_clear(&mp_modulus); From 2a16102b9f6db5cae2424d41327297872a3436de Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 16 Apr 2014 23:18:38 +0200 Subject: [PATCH 13/22] POLY: rm unnecessary cast --- src/poly.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/poly.c b/src/poly.c index ac7d4d4..56ad436 100644 --- a/src/poly.c +++ b/src/poly.c @@ -169,8 +169,8 @@ void pb_starmultiply(pb_poly *a, for (int i = ctx->N - 1; i >= 0; i--) { if (j == (int)(ctx->N)) j = 0; - if (mp_cmp_d(&(a->terms[i]), (mp_digit)0) != MP_EQ && - mp_cmp_d(&(b->terms[j]), (mp_digit)0) != MP_EQ) { + if (mp_cmp_d(&(a->terms[i]), 0) != MP_EQ && + mp_cmp_d(&(b->terms[j]), 0) != MP_EQ) { int result; mp_int mp_modulus; mp_int mp_tmp; From 56b20220ba3e80c799b58b50653759589d926008 Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 16 Apr 2014 23:23:41 +0200 Subject: [PATCH 14/22] POLY: first try of inverting polynomials --- src/poly.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/poly.h | 10 ++++ 2 files changed, 144 insertions(+) diff --git a/src/poly.c b/src/poly.c index 56ad436..b1d98ec 100644 --- a/src/poly.c +++ b/src/poly.c @@ -21,11 +21,13 @@ #include "context.h" #include "err.h" +#include "poly.h" #include #include #include #include +#include /** * Initialize a mp_int and check if this was successful, the @@ -201,6 +203,138 @@ void pb_starmultiply(pb_poly *a, } /** + * c = a XOR b + * + * @param a polynom (is allowed to be the same as param c) + * @param b polynom + * @param c polynom [out] + * @param len max size of the polynoms, make sure all are + * properly allocated + */ +void pb_xor(pb_poly *a, + pb_poly *b, + pb_poly *c, + const size_t len) +{ + for (unsigned int i = 0; i < len; i++) + mp_xor(&(a->terms[i]), &(b->terms[i]), &(c->terms[i])); +} + +/** + * Invert the polynomial a modulo q. + * + * @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 + */ +bool pb_inverse_poly_q(pb_poly * const a, + pb_poly *Fq, + ntru_context *ctx) +{ + int k = 0, + j = 0, + v = 2; + int zero_poly_val = 1; + pb_poly *a_tmp, *b, *c, *f, *g, *degree_zero_poly; + + degree_zero_poly = build_polynom(&zero_poly_val, 1, ctx); + b = build_polynom(NULL, ctx->N, ctx); + mp_set(&(b->terms[0]), 1); + c = build_polynom(NULL, ctx->N, ctx); + f = build_polynom(NULL, ctx->N, ctx); + pb_copy(a, f); + a_tmp = build_polynom(NULL, ctx->N, ctx); + pb_copy(a, a_tmp); + g = build_polynom(NULL, ctx->N, ctx); + mp_set(&(g->terms[0]), 1); + g->terms[0].sign = 1; + mp_set(&(g->terms[ctx->N]), 1); + + while (1) { + while (mp_cmp_d(&(f->terms[0]), 0) == MP_EQ) { + for (unsigned int i = 1; i <= ctx->N; i++) { + mp_copy(&(f->terms[i]), &(f->terms[i - 1])); + 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++; + } + + /* hope this does not blow up in our face */ + pb_clamp(degree_zero_poly); + pb_clamp(f); + if (pb_cmp(f, degree_zero_poly) == PB_DEG_EQ) + goto OUT_OF_LOOP; + + pb_clamp(g); + if (pb_cmp(f, g) == PB_DEG_LT) { + pb_exch(f, g); + pb_exch(b, c); + } + + /* draw_polynom(f); */ + /* draw_polynom(b); */ + pb_xor(f, g, f, ctx->N); + pb_xor(b, c, b, ctx->N); + /* draw_polynom(f); */ + /* draw_polynom(b); */ + } + +OUT_OF_LOOP: + k = k % ctx->N; + + for (int i = ctx->N - 1; i >= 0; i--) { + j = i - k; + if (j < 0) + j = j + ctx->N; + mp_copy(&(b->terms[i]), &(Fq->terms[j])); + } + draw_polynom(Fq); + + while (v < (int)(ctx->q)) { + pb_poly *pb_tmp, + *pb_tmp_v, + *pb_tmp2; + pb_tmp = build_polynom(NULL, ctx->N, ctx); + v = v * 2; + pb_tmp_v = build_polynom(NULL, ctx->N, ctx); + mp_set_int(&(pb_tmp_v->terms[0]), v); + pb_tmp2 = build_polynom(NULL, ctx->N, ctx); + mp_set_int(&(pb_tmp2->terms[0]), 2); + + /* hope this does not blow up in our face */ + pb_starmultiply(a_tmp, Fq, pb_tmp, ctx, v); + pb_sub(pb_tmp2, pb_tmp, pb_tmp); + pb_mod(pb_tmp, pb_tmp_v, pb_tmp); + pb_starmultiply(Fq, pb_tmp, Fq, ctx, v); + + delete_polynom(pb_tmp); + delete_polynom(pb_tmp_v); + delete_polynom(pb_tmp2); + } + + 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); + } + + delete_polynom(a_tmp); + delete_polynom(b); + delete_polynom(c); + delete_polynom(f); + delete_polynom(g); + delete_polynom(degree_zero_poly); + + /* TODO: check if the f * Fq = 1 (mod p) condition holds true */ + + return true; +} * Print the polynomial in a human readable format to stdout. * * @param poly to draw diff --git a/src/poly.h b/src/poly.h index ef9700d..cdef091 100644 --- a/src/poly.h +++ b/src/poly.h @@ -27,6 +27,7 @@ #include #include +#include void init_integer(mp_int *new_int); @@ -47,6 +48,15 @@ void pb_starmultiply(pb_poly *a, ntru_context *ctx, unsigned int modulus); +void pb_xor(pb_poly *a, + pb_poly *b, + pb_poly *c, + const size_t len); + +bool pb_inverse_poly_q(pb_poly *a, + pb_poly *Fq, + ntru_context *ctx); + void draw_polynom(pb_poly * const poly); #endif /* NTRU_POLY_H */ From a49a5d2e8c152479baa2dc697486b1109faea735 Mon Sep 17 00:00:00 2001 From: hasufell Date: Thu, 17 Apr 2014 02:09:49 +0200 Subject: [PATCH 15/22] POLY: improve error handling Use MP_ADD, MP_MUL, PB_ADD, PB_MUL etc instead of the mp_add,... functions to make use of error handling. --- src/poly.c | 41 ++++++++++---------------- src/poly.h | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 25 deletions(-) diff --git a/src/poly.c b/src/poly.c index b1d98ec..03668e5 100644 --- a/src/poly.c +++ b/src/poly.c @@ -181,18 +181,9 @@ void pb_starmultiply(pb_poly *a, init_integer(&mp_modulus); mp_set_int(&mp_modulus, (unsigned long)(modulus)); - if ((result = mp_mul(&(a->terms[i]), - &(b->terms[j]), &mp_tmp)) != MP_OKAY) - NTRU_ABORT("Error multiplying terms. %s", - mp_error_to_string(result)); - if ((result = mp_add(&(c->terms[k]), - &mp_tmp, &(c->terms[k]))) != MP_OKAY) - NTRU_ABORT("Error adding terms. %s", - mp_error_to_string(result)); - if ((result = mp_mod(&(c->terms[k]), - &mp_modulus, &(c->terms[k]))) != MP_OKAY) - NTRU_ABORT("Error reducing term by modulo. %s", - mp_error_to_string(result)); + MP_MUL(&(a->terms[i]), &(b->terms[j]), &mp_tmp); + MP_ADD(&(c->terms[k]), &mp_tmp, &(c->terms[k])); + MP_MOD(&(c->terms[k]), &mp_modulus, &(c->terms[k])); mp_clear(&mp_modulus); mp_clear(&mp_tmp); @@ -217,7 +208,7 @@ void pb_xor(pb_poly *a, const size_t len) { for (unsigned int i = 0; i < len; i++) - mp_xor(&(a->terms[i]), &(b->terms[i]), &(c->terms[i])); + MP_XOR(&(a->terms[i]), &(b->terms[i]), &(c->terms[i])); } /** @@ -243,9 +234,9 @@ bool pb_inverse_poly_q(pb_poly * const a, mp_set(&(b->terms[0]), 1); c = build_polynom(NULL, ctx->N, ctx); f = build_polynom(NULL, ctx->N, ctx); - pb_copy(a, f); + PB_COPY(a, f); a_tmp = build_polynom(NULL, ctx->N, ctx); - pb_copy(a, a_tmp); + PB_COPY(a, a_tmp); g = build_polynom(NULL, ctx->N, ctx); mp_set(&(g->terms[0]), 1); g->terms[0].sign = 1; @@ -254,8 +245,8 @@ bool pb_inverse_poly_q(pb_poly * const a, while (1) { while (mp_cmp_d(&(f->terms[0]), 0) == MP_EQ) { for (unsigned int i = 1; i <= ctx->N; i++) { - mp_copy(&(f->terms[i]), &(f->terms[i - 1])); - mp_copy(&(c->terms[ctx->N - i]), &(c->terms[ctx->N + 1 - i])); + MP_COPY(&(f->terms[i]), &(f->terms[i - 1])); + 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); @@ -289,29 +280,29 @@ OUT_OF_LOOP: j = i - k; if (j < 0) j = j + ctx->N; - mp_copy(&(b->terms[i]), &(Fq->terms[j])); + MP_COPY(&(b->terms[i]), &(Fq->terms[j])); } draw_polynom(Fq); while (v < (int)(ctx->q)) { pb_poly *pb_tmp, - *pb_tmp_v, *pb_tmp2; + mp_int tmp_v; pb_tmp = build_polynom(NULL, ctx->N, ctx); v = v * 2; - pb_tmp_v = build_polynom(NULL, ctx->N, ctx); - mp_set_int(&(pb_tmp_v->terms[0]), v); + init_integer(&tmp_v); + mp_set_int(&tmp_v, v); pb_tmp2 = build_polynom(NULL, ctx->N, ctx); mp_set_int(&(pb_tmp2->terms[0]), 2); /* hope this does not blow up in our face */ pb_starmultiply(a_tmp, Fq, pb_tmp, ctx, v); - pb_sub(pb_tmp2, pb_tmp, pb_tmp); - pb_mod(pb_tmp, pb_tmp_v, pb_tmp); + PB_SUB(pb_tmp2, pb_tmp, pb_tmp); + PB_MOD(pb_tmp, &tmp_v, pb_tmp, ctx); pb_starmultiply(Fq, pb_tmp, Fq, ctx, v); + mp_clear(&tmp_v); delete_polynom(pb_tmp); - delete_polynom(pb_tmp_v); delete_polynom(pb_tmp2); } @@ -320,7 +311,7 @@ OUT_OF_LOOP: 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_ADD(&(Fq->terms[i]), &mp_tmp, &(Fq->terms[i])); mp_clear(&mp_tmp); } diff --git a/src/poly.h b/src/poly.h index cdef091..c3edab1 100644 --- a/src/poly.h +++ b/src/poly.h @@ -24,11 +24,97 @@ #define NTRU_POLY_H #include "context.h" +#include "err.h" #include #include #include +#define MP_MUL(...) \ +{ \ + int result; \ + if ((result = mp_mul(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error multiplying terms. %s", \ + mp_error_to_string(result)); \ +} + +#define MP_ADD(...) \ +{ \ + int result; \ + if ((result = mp_add(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error adding terms. %s", \ + mp_error_to_string(result)); \ +} + +#define MP_SUB(...) \ +{ \ + int result; \ + if ((result = mp_sub(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error substracting terms. %s", \ + mp_error_to_string(result)); \ +} + +#define MP_MOD(...) \ +{ \ + int result; \ + if ((result = mp_mod(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error reducing term by modulo. %s", \ + mp_error_to_string(result)); \ +} + +#define MP_COPY(...) \ +{ \ + int result; \ + if ((result = mp_copy(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error copying terms. %s", \ + mp_error_to_string(result)); \ +} + +#define MP_XOR(...) \ +{ \ + int result; \ + if ((result = mp_xor(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error XORing terms. %s", \ + mp_error_to_string(result)); \ +} + +#define PB_MUL(...) \ +{ \ + int result; \ + if ((result = pb_mul(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error multiplying polynomials. %s", \ + mp_error_to_string(result)); \ +} + +#define PB_ADD(...) \ +{ \ + int result; \ + if ((result = pb_add(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error adding polynomials. %s", \ + mp_error_to_string(result)); \ +} + +#define PB_SUB(...) \ +{ \ + int result; \ + if ((result = pb_sub(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error substracting polynomials. %s", \ + mp_error_to_string(result)); \ +} + +#define PB_MOD(poly_a, mp_int, poly_out, context) \ +{ \ + for (unsigned int i = 0; i < context->N; i++) \ + MP_MOD(&(poly_a->terms[i]), mp_int, &(poly_out->terms[i])); \ +} + +#define PB_COPY(...) \ +{ \ + int result; \ + if ((result = pb_copy(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error copying polynomial. %s", \ + mp_error_to_string(result)); \ +} void init_integer(mp_int *new_int); From 8ea687bdf57f820570da50ffbf60b9df70901b84 Mon Sep 17 00:00:00 2001 From: hasufell Date: Thu, 17 Apr 2014 17:33:05 +0200 Subject: [PATCH 16/22] POLY: use mp_neg() instead of directly modifying struct --- src/poly.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/poly.c b/src/poly.c index 03668e5..a1894a0 100644 --- a/src/poly.c +++ b/src/poly.c @@ -122,7 +122,7 @@ pb_poly *build_polynom(int const * const c, mp_set_int(&(new_poly->terms[i]), unsigned_c); if (sign == true) - new_poly->terms[i].sign = 1; + mp_neg(&(new_poly->terms[i]), &(new_poly->terms[i])); } } else { /* fill with zeros */ for (unsigned int i = 0; i < len; i++) @@ -239,7 +239,7 @@ bool pb_inverse_poly_q(pb_poly * const a, PB_COPY(a, a_tmp); g = build_polynom(NULL, ctx->N, ctx); mp_set(&(g->terms[0]), 1); - g->terms[0].sign = 1; + mp_neg(&(g->terms[0]), &(g->terms[0])); mp_set(&(g->terms[ctx->N]), 1); while (1) { From 2300587fecf9f580d29d02c65e4c0fd8a23a4936 Mon Sep 17 00:00:00 2001 From: hasufell Date: Thu, 17 Apr 2014 17:34:48 +0200 Subject: [PATCH 17/22] POLY: add erase_polynom() function --- src/poly.c | 14 ++++++++++++++ src/poly.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/poly.c b/src/poly.c index a1894a0..7d5934c 100644 --- a/src/poly.c +++ b/src/poly.c @@ -134,6 +134,20 @@ pb_poly *build_polynom(int const * const c, return new_poly; } +/** + * Sets all the polynomial coefficients to +0. + * + * @param poly the polynomial + * @param len the length of the polynomial + */ +void erase_polynom(pb_poly *poly, size_t len) +{ + for (unsigned int i = 0; i < len ; i++) { + mp_set(&(poly->terms[i]), 0); + mp_abs(&(poly->terms[i]), &(poly->terms[i])); + } +} + /** * This deletes the internal structure of a polynomial, * and frees the pointer. Don't call this on stack variables, diff --git a/src/poly.h b/src/poly.h index c3edab1..3f95e37 100644 --- a/src/poly.h +++ b/src/poly.h @@ -126,6 +126,8 @@ pb_poly *build_polynom(int const * const c, const size_t len, ntru_context *ctx); +void erase_polynom(pb_poly *poly, size_t len); + void delete_polynom(pb_poly *new_poly); void pb_starmultiply(pb_poly *a, From 03a05f2dad7b43527136ce9606db097f15c4f0e7 Mon Sep 17 00:00:00 2001 From: hasufell Date: Thu, 17 Apr 2014 17:35:20 +0200 Subject: [PATCH 18/22] DOC: fix doxygen comment in delete_polynom() --- src/poly.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/poly.c b/src/poly.c index 7d5934c..6131d7a 100644 --- a/src/poly.c +++ b/src/poly.c @@ -164,9 +164,9 @@ void delete_polynom(pb_poly *poly) /** * Starmultiplication, as follows: - * c = a * b mod x^(N − 1) + * c = a * b mod (x^N − 1) * - * @param a polynom to multiply + * @param a polynom to multiply (can be the same as c) * @param b polynom to multiply * @param c polynom [out] * @param ctx NTRU context From cc82e4e3bd75b03c4d0a8f7dab565f83fbff356b Mon Sep 17 00:00:00 2001 From: hasufell Date: Thu, 17 Apr 2014 17:36:57 +0200 Subject: [PATCH 19/22] POLY: cleanup pb_starmultiply() * avoid side effects * use MP_DIV instead of MP_MOD * move mp_modulus initialization to outer scope --- src/poly.c | 24 ++++++++++++++++-------- src/poly.h | 8 ++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/poly.c b/src/poly.c index 6131d7a..7bf5eb2 100644 --- a/src/poly.c +++ b/src/poly.c @@ -178,6 +178,17 @@ void pb_starmultiply(pb_poly *a, ntru_context *ctx, unsigned int modulus) { + pb_poly *a_tmp; + mp_int mp_modulus; + + init_integer(&mp_modulus); + mp_set_int(&mp_modulus, (unsigned long)(modulus)); + + /* avoid side effects */ + a_tmp = build_polynom(NULL, ctx->N, ctx); + PB_COPY(a, a_tmp); + erase_polynom(c, ctx->N); + for (int k = ctx->N - 1; k >= 0; k--) { int j; j = k + 1; @@ -185,26 +196,23 @@ void pb_starmultiply(pb_poly *a, for (int i = ctx->N - 1; i >= 0; i--) { if (j == (int)(ctx->N)) j = 0; - if (mp_cmp_d(&(a->terms[i]), 0) != MP_EQ && + if (mp_cmp_d(&(a_tmp->terms[i]), 0) != MP_EQ && mp_cmp_d(&(b->terms[j]), 0) != MP_EQ) { - int result; - mp_int mp_modulus; mp_int mp_tmp; init_integer(&mp_tmp); - init_integer(&mp_modulus); - mp_set_int(&mp_modulus, (unsigned long)(modulus)); - MP_MUL(&(a->terms[i]), &(b->terms[j]), &mp_tmp); + MP_MUL(&(a_tmp->terms[i]), &(b->terms[j]), &mp_tmp); MP_ADD(&(c->terms[k]), &mp_tmp, &(c->terms[k])); - MP_MOD(&(c->terms[k]), &mp_modulus, &(c->terms[k])); + MP_DIV(&(c->terms[k]), &mp_modulus, NULL, &(c->terms[k])); - mp_clear(&mp_modulus); mp_clear(&mp_tmp); } j++; } } + mp_clear(&mp_modulus); + delete_polynom(a_tmp); } /** diff --git a/src/poly.h b/src/poly.h index 3f95e37..9eb7a40 100644 --- a/src/poly.h +++ b/src/poly.h @@ -38,6 +38,14 @@ mp_error_to_string(result)); \ } +#define MP_DIV(...) \ +{ \ + int result; \ + if ((result = mp_div(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error dividing terms. %s", \ + mp_error_to_string(result)); \ +} + #define MP_ADD(...) \ { \ int result; \ From 4bd341e83e74959dac175ed2b455298f29c02f10 Mon Sep 17 00:00:00 2001 From: hasufell Date: Thu, 17 Apr 2014 17:37:30 +0200 Subject: [PATCH 20/22] POLY: cleanup pb_inverse_poly_q() Also avoid side effects. --- src/poly.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/poly.c b/src/poly.c index 7bf5eb2..d78b379 100644 --- a/src/poly.c +++ b/src/poly.c @@ -257,13 +257,16 @@ bool pb_inverse_poly_q(pb_poly * const a, c = build_polynom(NULL, ctx->N, ctx); f = build_polynom(NULL, ctx->N, ctx); PB_COPY(a, f); - a_tmp = build_polynom(NULL, ctx->N, ctx); - PB_COPY(a, a_tmp); g = build_polynom(NULL, ctx->N, ctx); 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); + 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++) { @@ -287,12 +290,8 @@ bool pb_inverse_poly_q(pb_poly * const a, pb_exch(b, c); } - /* draw_polynom(f); */ - /* draw_polynom(b); */ pb_xor(f, g, f, ctx->N); pb_xor(b, c, b, ctx->N); - /* draw_polynom(f); */ - /* draw_polynom(b); */ } OUT_OF_LOOP: @@ -304,7 +303,6 @@ OUT_OF_LOOP: j = j + ctx->N; MP_COPY(&(b->terms[i]), &(Fq->terms[j])); } - draw_polynom(Fq); while (v < (int)(ctx->q)) { pb_poly *pb_tmp, From 3428dedc2c77bcc63556a1bbd04647255fe72dc1 Mon Sep 17 00:00:00 2001 From: hasufell Date: Thu, 17 Apr 2014 17:37:44 +0200 Subject: [PATCH 21/22] BUILD: fix possible linker errors --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 07299e0..9d0df37 100644 --- a/src/Makefile +++ b/src/Makefile @@ -80,7 +80,7 @@ libpqc.so: libpqc.a $(PQC_HEADERS) $(LIBTOMMATH) $(LIBTOMPOLY) main: main.o libpqc.a $(LIBTOMMATH) $(LIBTOMPOLY) $(CC) $(CFLAGS) -o $@ $(LDFLAGS) \ - main.o $(LIBTOMPOLY) libpqc.a $(LIBTOMMATH) $(LIBS) + main.o $(LIBTOMPOLY) libpqc.a $(LIBTOMPOLY) $(LIBTOMMATH) $(LIBS) install: $(INSTALL_DIR) "$(DESTDIR)$(INSTALL_BINDIR)" From 302cd5e4d89464941085b04f4bdbe3fd5fb8d7b4 Mon Sep 17 00:00:00 2001 From: hasufell Date: Thu, 17 Apr 2014 23:43:29 +0200 Subject: [PATCH 22/22] POLY: fix pb_inverse_poly_q() Should be correct now. Had to add get_degree(), because pb_clamp() in conjunction with pb_cmp() does not give expected results, see https://github.com/libtom/libtompoly/issues/3 ...so don't use it. --- src/poly.c | 48 ++++++++++++++++++++++++++++++++---------------- src/poly.h | 6 +++--- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/poly.c b/src/poly.c index d78b379..e4c1d43 100644 --- a/src/poly.c +++ b/src/poly.c @@ -29,6 +29,13 @@ #include #include + +/* + * static declarations + */ +static unsigned int get_degree(pb_poly const * const poly); + + /** * Initialize a mp_int and check if this was successful, the * caller must free new_int with mp_clear(). @@ -233,6 +240,23 @@ void pb_xor(pb_poly *a, MP_XOR(&(a->terms[i]), &(b->terms[i]), &(c->terms[i])); } +/** + * Get the degree of the polynomial. + * + * @param poly the polynomial + * @return the degree + */ +static unsigned int get_degree(pb_poly const * const poly) +{ + unsigned int count = 0; + + for (int i = 0; i < poly->alloc; i++) + if (mp_iszero(&(poly->terms[i])) == MP_NO) + count = i; + + return count; +} + /** * Invert the polynomial a modulo q. * @@ -248,20 +272,17 @@ bool pb_inverse_poly_q(pb_poly * const a, int k = 0, j = 0, v = 2; - int zero_poly_val = 1; - pb_poly *a_tmp, *b, *c, *f, *g, *degree_zero_poly; + pb_poly *a_tmp, *b, *c, *f, *g; - degree_zero_poly = build_polynom(&zero_poly_val, 1, ctx); - b = build_polynom(NULL, ctx->N, ctx); + b = build_polynom(NULL, ctx->N + 1, ctx); mp_set(&(b->terms[0]), 1); - c = build_polynom(NULL, ctx->N, ctx); - f = build_polynom(NULL, ctx->N, ctx); + c = build_polynom(NULL, ctx->N + 1, ctx); + f = build_polynom(NULL, ctx->N + 1, ctx); PB_COPY(a, f); - g = build_polynom(NULL, ctx->N, ctx); + g = build_polynom(NULL, ctx->N + 1, ctx); 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); PB_COPY(a, a_tmp); @@ -278,14 +299,10 @@ bool pb_inverse_poly_q(pb_poly * const a, k++; } - /* hope this does not blow up in our face */ - pb_clamp(degree_zero_poly); - pb_clamp(f); - if (pb_cmp(f, degree_zero_poly) == PB_DEG_EQ) + if (get_degree(f) == 0) goto OUT_OF_LOOP; - pb_clamp(g); - if (pb_cmp(f, g) == PB_DEG_LT) { + if (get_degree(f) < get_degree(g)) { pb_exch(f, g); pb_exch(b, c); } @@ -318,7 +335,7 @@ OUT_OF_LOOP: /* hope this does not blow up in our face */ pb_starmultiply(a_tmp, Fq, pb_tmp, ctx, v); PB_SUB(pb_tmp2, pb_tmp, pb_tmp); - PB_MOD(pb_tmp, &tmp_v, pb_tmp, ctx); + PB_MOD(pb_tmp, &tmp_v, pb_tmp, ctx->N); pb_starmultiply(Fq, pb_tmp, Fq, ctx, v); mp_clear(&tmp_v); @@ -340,7 +357,6 @@ OUT_OF_LOOP: delete_polynom(c); delete_polynom(f); delete_polynom(g); - delete_polynom(degree_zero_poly); /* TODO: check if the f * Fq = 1 (mod p) condition holds true */ diff --git a/src/poly.h b/src/poly.h index 9eb7a40..f60ab26 100644 --- a/src/poly.h +++ b/src/poly.h @@ -110,10 +110,10 @@ mp_error_to_string(result)); \ } -#define PB_MOD(poly_a, mp_int, poly_out, context) \ +#define PB_MOD(poly_a, mp_int, poly_out, len) \ { \ - for (unsigned int i = 0; i < context->N; i++) \ - MP_MOD(&(poly_a->terms[i]), mp_int, &(poly_out->terms[i])); \ + for (unsigned int i = 0; i < len; i++) \ + MP_DIV(&(poly_a->terms[i]), mp_int, NULL, &(poly_out->terms[i])); \ } #define PB_COPY(...) \