From ece632b5c2b40d89bad71084989cf42d85c422be Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:50:49 +0200 Subject: [PATCH 01/27] MEM: introduce use our own ntru_malloc() function Use this instead of malloc(). --- src/mem.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mem.h | 29 +++++++++++++++++++++++++++++ src/poly.c | 3 ++- 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/mem.c create mode 100644 src/mem.h diff --git a/src/mem.c b/src/mem.c new file mode 100644 index 0000000..7a63f58 --- /dev/null +++ b/src/mem.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 FH Bielefeld + * + * This file is part of a FH Bielefeld project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "mem.h" + +#include +#include + + +/** + * Allocate memory of size and return + * a void pointer. + * + * @param size of the memory to allocate in bytes + * @return void pointer to the beginning of the allocated memory block + */ +void *ntru_malloc(size_t size) +{ + void *ptr; + + ptr = malloc(size); + + if (size) + if (!ptr) { + fprintf(stderr, "failed to allocate memory, aborting!"); + abort(); + } + + return ptr; +} diff --git a/src/mem.h b/src/mem.h new file mode 100644 index 0000000..eabe1e9 --- /dev/null +++ b/src/mem.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 FH Bielefeld + * + * This file is part of a FH Bielefeld project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef NTRU_MEM_H +#define NTRU_MEM_H + +#include + +void *ntru_malloc(size_t size); + +#endif /* NTRU_MEM_H */ diff --git a/src/poly.c b/src/poly.c index e4c1d43..05b2522 100644 --- a/src/poly.c +++ b/src/poly.c @@ -21,6 +21,7 @@ #include "context.h" #include "err.h" +#include "mem.h" #include "poly.h" #include @@ -108,7 +109,7 @@ pb_poly *build_polynom(int const * const c, pb_poly *new_poly; mp_int chara; - new_poly = malloc(sizeof(*new_poly)); + new_poly = ntru_malloc(sizeof(*new_poly)); init_integer(&chara); init_polynom_size(new_poly, &chara, len); mp_clear(&chara); From babdf64d0f5dd0945238673c8635997b3d5e562b Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:51:45 +0200 Subject: [PATCH 02/27] BUILD: update Makefile for mem.o --- src/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 9d0df37..6fc357d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,8 +37,8 @@ endif LIBS += -L. # objects -PQC_OBJS = rand.o poly.o -PQC_HEADERS = err.h rand.h poly.h context.h +PQC_OBJS = rand.o poly.o keypair.o mem.o +PQC_HEADERS = err.h rand.h poly.h context.h keypair.h # CUNIT_OBJS = cunit.o # includes From 60b003c9d900e29a1517b9aa3a3731c1c8e5cf9b Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:53:30 +0200 Subject: [PATCH 03/27] POLY: use our MACROS for error handling All mp_* and pb_* functions that return an error code should only be called via a MACRO which handles the error. --- src/poly.c | 20 ++++++++++---------- src/poly.h | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/poly.c b/src/poly.c index 05b2522..f7cacec 100644 --- a/src/poly.c +++ b/src/poly.c @@ -127,14 +127,14 @@ pb_poly *build_polynom(int const * const c, unsigned_c = c[i]; } - mp_set_int(&(new_poly->terms[i]), unsigned_c); + 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(&(new_poly->terms[i]), 0); + MP_SET(&(new_poly->terms[i]), 0); } new_poly->used = len; @@ -151,7 +151,7 @@ pb_poly *build_polynom(int const * const c, void erase_polynom(pb_poly *poly, size_t len) { for (unsigned int i = 0; i < len ; i++) { - mp_set(&(poly->terms[i]), 0); + MP_SET(&(poly->terms[i]), 0); mp_abs(&(poly->terms[i]), &(poly->terms[i])); } } @@ -190,7 +190,7 @@ void pb_starmultiply(pb_poly *a, mp_int mp_modulus; init_integer(&mp_modulus); - mp_set_int(&mp_modulus, (unsigned long)(modulus)); + MP_SET_INT(&mp_modulus, (unsigned long)(modulus)); /* avoid side effects */ a_tmp = build_polynom(NULL, ctx->N, ctx); @@ -276,14 +276,14 @@ bool pb_inverse_poly_q(pb_poly * const a, pb_poly *a_tmp, *b, *c, *f, *g; b = build_polynom(NULL, ctx->N + 1, ctx); - mp_set(&(b->terms[0]), 1); + MP_SET(&(b->terms[0]), 1); 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 + 1, ctx); - mp_set(&(g->terms[0]), 1); + MP_SET(&(g->terms[0]), 1); mp_neg(&(g->terms[0]), &(g->terms[0])); - mp_set(&(g->terms[ctx->N]), 1); + MP_SET(&(g->terms[ctx->N]), 1); /* avoid side effects */ a_tmp = build_polynom(NULL, ctx->N, ctx); PB_COPY(a, a_tmp); @@ -295,8 +295,8 @@ bool pb_inverse_poly_q(pb_poly * const a, 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); + MP_SET(&(f->terms[ctx->N]), 0); + MP_SET(&(c->terms[0]), 0); k++; } @@ -348,7 +348,7 @@ OUT_OF_LOOP: 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_SET_INT(&mp_tmp, ctx->q); 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 f60ab26..4d9aa04 100644 --- a/src/poly.h +++ b/src/poly.h @@ -30,6 +30,16 @@ #include #include +#define MP_SET(...) mp_set(__VA_ARGS__) + +#define MP_SET_INT(...) \ +{ \ + int result; \ + if ((result = mp_set_int(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error setting long constant. %s", \ + mp_error_to_string(result)); \ +} + #define MP_MUL(...) \ { \ int result; \ @@ -86,6 +96,22 @@ mp_error_to_string(result)); \ } +#define MP_EXPTMOD(...) \ +{ \ + int result; \ + if ((result = mp_exptmod(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error computing modular exponentiation. %s", \ + mp_error_to_string(result)); \ +} + +#define MP_EXPT_D(...) \ +{ \ + int result; \ + if ((result = mp_expt_d(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error computing modular exponentiation. %s", \ + mp_error_to_string(result)); \ +} + #define PB_MUL(...) \ { \ int result; \ From 1968b8207f053996a1dbed002fcc5133d579777e Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:55:30 +0200 Subject: [PATCH 04/27] POLY: introduce delete_polynom_multi() Just a wrapper around delete_polynom() to handle multiple args. Must be called with NULL as last argument! --- src/poly.c | 31 ++++++++++++++++++++++++++----- src/poly.h | 3 +++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/poly.c b/src/poly.c index f7cacec..7f5ffcc 100644 --- a/src/poly.c +++ b/src/poly.c @@ -24,6 +24,7 @@ #include "mem.h" #include "poly.h" +#include #include #include #include @@ -170,6 +171,30 @@ void delete_polynom(pb_poly *poly) free(poly); } +/** + * This deletes the internal structure of all polynomials, + * and frees the pointers. Don't call this on stack variables, + * this is intended for use after ntru_ functions, that + * return a polynomial pointer. + * You must call this with NULL as last argument! + * + * @param poly the polynomial to delete + * @param ... follow up polynomials + */ +void delete_polynom_multi(pb_poly *poly, ...) +{ + pb_poly *next_poly; + va_list args; + + next_poly = poly; + va_start(args, poly); + while (next_poly != NULL) { + delete_polynom(next_poly); + next_poly = va_arg(args, pb_poly*); + } + va_end(args); +} + /** * Starmultiplication, as follows: * c = a * b mod (x^N − 1) @@ -353,11 +378,7 @@ OUT_OF_LOOP: mp_clear(&mp_tmp); } - delete_polynom(a_tmp); - delete_polynom(b); - delete_polynom(c); - delete_polynom(f); - delete_polynom(g); + delete_polynom_multi(a_tmp, b, c, f, g, NULL); /* TODO: check if the f * Fq = 1 (mod p) condition holds true */ diff --git a/src/poly.h b/src/poly.h index 4d9aa04..77a9b54 100644 --- a/src/poly.h +++ b/src/poly.h @@ -28,6 +28,7 @@ #include #include +#include #include #define MP_SET(...) mp_set(__VA_ARGS__) @@ -164,6 +165,8 @@ void erase_polynom(pb_poly *poly, size_t len); void delete_polynom(pb_poly *new_poly); +void delete_polynom_multi(pb_poly *poly, ...); + void pb_starmultiply(pb_poly *a, pb_poly *b, pb_poly *c, From cabc81dfd95284f5b2981092ff37819fac4e4b4a Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:57:45 +0200 Subject: [PATCH 05/27] POLY: add pb_mod2_to_modq() This should make pb_inverse_poly_q() a bit more readable. TODO: make the algorithm more descriptive in general. --- src/poly.c | 65 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/src/poly.c b/src/poly.c index 7f5ffcc..2c69ebe 100644 --- a/src/poly.c +++ b/src/poly.c @@ -36,6 +36,9 @@ * 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); /** @@ -283,6 +286,43 @@ static unsigned int get_degree(pb_poly const * const poly) return count; } +/** + * Find the inverse polynomial modulo a power of 2, + * which is 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 + */ +static void pb_mod2_to_modq(pb_poly * const a, + pb_poly *Fq, + ntru_context *ctx) +{ + int v = 2; + + while (v < (int)(ctx->q)) { + pb_poly *pb_tmp, + *pb_tmp2; + mp_int tmp_v; + pb_tmp = build_polynom(NULL, ctx->N, ctx); + v = v * 2; + 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); + + /* 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); + pb_starmultiply(Fq, pb_tmp, Fq, ctx, v); + + mp_clear(&tmp_v); + delete_polynom_multi(pb_tmp, pb_tmp2, NULL); + } +} + /** * Invert the polynomial a modulo q. * @@ -296,8 +336,7 @@ bool pb_inverse_poly_q(pb_poly * const a, ntru_context *ctx) { int k = 0, - j = 0, - v = 2; + j = 0; pb_poly *a_tmp, *b, *c, *f, *g; b = build_polynom(NULL, ctx->N + 1, ctx); @@ -347,27 +386,7 @@ OUT_OF_LOOP: MP_COPY(&(b->terms[i]), &(Fq->terms[j])); } - while (v < (int)(ctx->q)) { - pb_poly *pb_tmp, - *pb_tmp2; - mp_int tmp_v; - pb_tmp = build_polynom(NULL, ctx->N, ctx); - v = v * 2; - 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, &tmp_v, pb_tmp, ctx->N); - pb_starmultiply(Fq, pb_tmp, Fq, ctx, v); - - mp_clear(&tmp_v); - delete_polynom(pb_tmp); - delete_polynom(pb_tmp2); - } + pb_mod2_to_modq(a_tmp, Fq, ctx); for (int i = ctx->N - 1; i >= 0; i--) if (mp_cmp_d(&(Fq->terms[i]), 0) == MP_LT) { From 22ffd560720cd8536c308b630e2167b6558b0ffd Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 20:06:49 +0200 Subject: [PATCH 06/27] BUILD: ignore -Wunused-function... this is a library --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 6fc357d..1f2182f 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 -Wno-unused-parameter +CFLAGS += -std=c99 -pedantic -Wall -Wextra -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-unused-function ifeq ($(shell $(CC) -v 2>&1 | grep 'gcc version' &>/dev/null && echo 1),1) CFLAGS += -Wno-unused-but-set-variable endif From 13b59c28bc838084fe20259a492846053b1f135b Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 20:54:15 +0200 Subject: [PATCH 07/27] DOC: fix doxygen comment in pb_mod2_to_modq() --- src/poly.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/poly.c b/src/poly.c index 2c69ebe..25c80a0 100644 --- a/src/poly.c +++ b/src/poly.c @@ -290,10 +290,9 @@ static unsigned int get_degree(pb_poly const * const poly) * Find the inverse polynomial modulo a power of 2, * which is q. * - * @param a polynomial to invert (is allowed to be the same as param Fq) + * @param a polynomial to invert * @param Fq polynomial [out] * @param ctx NTRU context - * @return true/false for success/failure */ static void pb_mod2_to_modq(pb_poly * const a, pb_poly *Fq, From 5d875ca847a80fff22908994414a6958168cec9a Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:50:49 +0200 Subject: [PATCH 08/27] MEM: introduce our own ntru_malloc() function Use this instead of malloc(). --- src/mem.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mem.h | 29 +++++++++++++++++++++++++++++ src/poly.c | 3 ++- 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/mem.c create mode 100644 src/mem.h diff --git a/src/mem.c b/src/mem.c new file mode 100644 index 0000000..7a63f58 --- /dev/null +++ b/src/mem.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 FH Bielefeld + * + * This file is part of a FH Bielefeld project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "mem.h" + +#include +#include + + +/** + * Allocate memory of size and return + * a void pointer. + * + * @param size of the memory to allocate in bytes + * @return void pointer to the beginning of the allocated memory block + */ +void *ntru_malloc(size_t size) +{ + void *ptr; + + ptr = malloc(size); + + if (size) + if (!ptr) { + fprintf(stderr, "failed to allocate memory, aborting!"); + abort(); + } + + return ptr; +} diff --git a/src/mem.h b/src/mem.h new file mode 100644 index 0000000..eabe1e9 --- /dev/null +++ b/src/mem.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 FH Bielefeld + * + * This file is part of a FH Bielefeld project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef NTRU_MEM_H +#define NTRU_MEM_H + +#include + +void *ntru_malloc(size_t size); + +#endif /* NTRU_MEM_H */ diff --git a/src/poly.c b/src/poly.c index e4c1d43..05b2522 100644 --- a/src/poly.c +++ b/src/poly.c @@ -21,6 +21,7 @@ #include "context.h" #include "err.h" +#include "mem.h" #include "poly.h" #include @@ -108,7 +109,7 @@ pb_poly *build_polynom(int const * const c, pb_poly *new_poly; mp_int chara; - new_poly = malloc(sizeof(*new_poly)); + new_poly = ntru_malloc(sizeof(*new_poly)); init_integer(&chara); init_polynom_size(new_poly, &chara, len); mp_clear(&chara); From f8c3dc9790e3bff287743267942a0fe34285c92b Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:51:45 +0200 Subject: [PATCH 09/27] BUILD: update Makefile for mem.o --- src/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 9d0df37..6fc357d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,8 +37,8 @@ endif LIBS += -L. # objects -PQC_OBJS = rand.o poly.o -PQC_HEADERS = err.h rand.h poly.h context.h +PQC_OBJS = rand.o poly.o keypair.o mem.o +PQC_HEADERS = err.h rand.h poly.h context.h keypair.h # CUNIT_OBJS = cunit.o # includes From 5459f94937f0dd6da29c32c936574e1bbc5621c4 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:53:30 +0200 Subject: [PATCH 10/27] POLY: use our MACROS for error handling All mp_* and pb_* functions that return an error code should only be called via a MACRO which handles the error. --- src/poly.c | 20 ++++++++++---------- src/poly.h | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/poly.c b/src/poly.c index 05b2522..f7cacec 100644 --- a/src/poly.c +++ b/src/poly.c @@ -127,14 +127,14 @@ pb_poly *build_polynom(int const * const c, unsigned_c = c[i]; } - mp_set_int(&(new_poly->terms[i]), unsigned_c); + 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(&(new_poly->terms[i]), 0); + MP_SET(&(new_poly->terms[i]), 0); } new_poly->used = len; @@ -151,7 +151,7 @@ pb_poly *build_polynom(int const * const c, void erase_polynom(pb_poly *poly, size_t len) { for (unsigned int i = 0; i < len ; i++) { - mp_set(&(poly->terms[i]), 0); + MP_SET(&(poly->terms[i]), 0); mp_abs(&(poly->terms[i]), &(poly->terms[i])); } } @@ -190,7 +190,7 @@ void pb_starmultiply(pb_poly *a, mp_int mp_modulus; init_integer(&mp_modulus); - mp_set_int(&mp_modulus, (unsigned long)(modulus)); + MP_SET_INT(&mp_modulus, (unsigned long)(modulus)); /* avoid side effects */ a_tmp = build_polynom(NULL, ctx->N, ctx); @@ -276,14 +276,14 @@ bool pb_inverse_poly_q(pb_poly * const a, pb_poly *a_tmp, *b, *c, *f, *g; b = build_polynom(NULL, ctx->N + 1, ctx); - mp_set(&(b->terms[0]), 1); + MP_SET(&(b->terms[0]), 1); 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 + 1, ctx); - mp_set(&(g->terms[0]), 1); + MP_SET(&(g->terms[0]), 1); mp_neg(&(g->terms[0]), &(g->terms[0])); - mp_set(&(g->terms[ctx->N]), 1); + MP_SET(&(g->terms[ctx->N]), 1); /* avoid side effects */ a_tmp = build_polynom(NULL, ctx->N, ctx); PB_COPY(a, a_tmp); @@ -295,8 +295,8 @@ bool pb_inverse_poly_q(pb_poly * const a, 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); + MP_SET(&(f->terms[ctx->N]), 0); + MP_SET(&(c->terms[0]), 0); k++; } @@ -348,7 +348,7 @@ OUT_OF_LOOP: 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_SET_INT(&mp_tmp, ctx->q); 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 f60ab26..4d9aa04 100644 --- a/src/poly.h +++ b/src/poly.h @@ -30,6 +30,16 @@ #include #include +#define MP_SET(...) mp_set(__VA_ARGS__) + +#define MP_SET_INT(...) \ +{ \ + int result; \ + if ((result = mp_set_int(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error setting long constant. %s", \ + mp_error_to_string(result)); \ +} + #define MP_MUL(...) \ { \ int result; \ @@ -86,6 +96,22 @@ mp_error_to_string(result)); \ } +#define MP_EXPTMOD(...) \ +{ \ + int result; \ + if ((result = mp_exptmod(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error computing modular exponentiation. %s", \ + mp_error_to_string(result)); \ +} + +#define MP_EXPT_D(...) \ +{ \ + int result; \ + if ((result = mp_expt_d(__VA_ARGS__)) != MP_OKAY) \ + NTRU_ABORT("Error computing modular exponentiation. %s", \ + mp_error_to_string(result)); \ +} + #define PB_MUL(...) \ { \ int result; \ From 6c0f94435e6cc5e4515b24b2e07c21b94dc270c5 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:55:30 +0200 Subject: [PATCH 11/27] POLY: introduce delete_polynom_multi() Just a wrapper around delete_polynom() to handle multiple args. Must be called with NULL as last argument! --- src/poly.c | 31 ++++++++++++++++++++++++++----- src/poly.h | 3 +++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/poly.c b/src/poly.c index f7cacec..7f5ffcc 100644 --- a/src/poly.c +++ b/src/poly.c @@ -24,6 +24,7 @@ #include "mem.h" #include "poly.h" +#include #include #include #include @@ -170,6 +171,30 @@ void delete_polynom(pb_poly *poly) free(poly); } +/** + * This deletes the internal structure of all polynomials, + * and frees the pointers. Don't call this on stack variables, + * this is intended for use after ntru_ functions, that + * return a polynomial pointer. + * You must call this with NULL as last argument! + * + * @param poly the polynomial to delete + * @param ... follow up polynomials + */ +void delete_polynom_multi(pb_poly *poly, ...) +{ + pb_poly *next_poly; + va_list args; + + next_poly = poly; + va_start(args, poly); + while (next_poly != NULL) { + delete_polynom(next_poly); + next_poly = va_arg(args, pb_poly*); + } + va_end(args); +} + /** * Starmultiplication, as follows: * c = a * b mod (x^N − 1) @@ -353,11 +378,7 @@ OUT_OF_LOOP: mp_clear(&mp_tmp); } - delete_polynom(a_tmp); - delete_polynom(b); - delete_polynom(c); - delete_polynom(f); - delete_polynom(g); + delete_polynom_multi(a_tmp, b, c, f, g, NULL); /* TODO: check if the f * Fq = 1 (mod p) condition holds true */ diff --git a/src/poly.h b/src/poly.h index 4d9aa04..77a9b54 100644 --- a/src/poly.h +++ b/src/poly.h @@ -28,6 +28,7 @@ #include #include +#include #include #define MP_SET(...) mp_set(__VA_ARGS__) @@ -164,6 +165,8 @@ void erase_polynom(pb_poly *poly, size_t len); void delete_polynom(pb_poly *new_poly); +void delete_polynom_multi(pb_poly *poly, ...); + void pb_starmultiply(pb_poly *a, pb_poly *b, pb_poly *c, From abd2727215961425f07b25afb3bebd43c8ffe915 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 19:57:45 +0200 Subject: [PATCH 12/27] POLY: add pb_mod2_to_modq() This should make pb_inverse_poly_q() a bit more readable. TODO: make the algorithm more descriptive in general. --- src/poly.c | 65 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/src/poly.c b/src/poly.c index 7f5ffcc..2c69ebe 100644 --- a/src/poly.c +++ b/src/poly.c @@ -36,6 +36,9 @@ * 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); /** @@ -283,6 +286,43 @@ static unsigned int get_degree(pb_poly const * const poly) return count; } +/** + * Find the inverse polynomial modulo a power of 2, + * which is 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 + */ +static void pb_mod2_to_modq(pb_poly * const a, + pb_poly *Fq, + ntru_context *ctx) +{ + int v = 2; + + while (v < (int)(ctx->q)) { + pb_poly *pb_tmp, + *pb_tmp2; + mp_int tmp_v; + pb_tmp = build_polynom(NULL, ctx->N, ctx); + v = v * 2; + 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); + + /* 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); + pb_starmultiply(Fq, pb_tmp, Fq, ctx, v); + + mp_clear(&tmp_v); + delete_polynom_multi(pb_tmp, pb_tmp2, NULL); + } +} + /** * Invert the polynomial a modulo q. * @@ -296,8 +336,7 @@ bool pb_inverse_poly_q(pb_poly * const a, ntru_context *ctx) { int k = 0, - j = 0, - v = 2; + j = 0; pb_poly *a_tmp, *b, *c, *f, *g; b = build_polynom(NULL, ctx->N + 1, ctx); @@ -347,27 +386,7 @@ OUT_OF_LOOP: MP_COPY(&(b->terms[i]), &(Fq->terms[j])); } - while (v < (int)(ctx->q)) { - pb_poly *pb_tmp, - *pb_tmp2; - mp_int tmp_v; - pb_tmp = build_polynom(NULL, ctx->N, ctx); - v = v * 2; - 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, &tmp_v, pb_tmp, ctx->N); - pb_starmultiply(Fq, pb_tmp, Fq, ctx, v); - - mp_clear(&tmp_v); - delete_polynom(pb_tmp); - delete_polynom(pb_tmp2); - } + pb_mod2_to_modq(a_tmp, Fq, ctx); for (int i = ctx->N - 1; i >= 0; i--) if (mp_cmp_d(&(Fq->terms[i]), 0) == MP_LT) { From 2763b22374937e3db3726c63a5e02b4f9017aefa Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 20:06:49 +0200 Subject: [PATCH 13/27] BUILD: ignore -Wunused-function... this is a library --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 6fc357d..1f2182f 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 -Wno-unused-parameter +CFLAGS += -std=c99 -pedantic -Wall -Wextra -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-unused-function ifeq ($(shell $(CC) -v 2>&1 | grep 'gcc version' &>/dev/null && echo 1),1) CFLAGS += -Wno-unused-but-set-variable endif From 12b8b087000d7a06364135e826361fb2ef3be6d7 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 20 Apr 2014 20:54:15 +0200 Subject: [PATCH 14/27] DOC: fix doxygen comment in pb_mod2_to_modq() --- src/poly.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/poly.c b/src/poly.c index 2c69ebe..25c80a0 100644 --- a/src/poly.c +++ b/src/poly.c @@ -290,10 +290,9 @@ static unsigned int get_degree(pb_poly const * const poly) * Find the inverse polynomial modulo a power of 2, * which is q. * - * @param a polynomial to invert (is allowed to be the same as param Fq) + * @param a polynomial to invert * @param Fq polynomial [out] * @param ctx NTRU context - * @return true/false for success/failure */ static void pb_mod2_to_modq(pb_poly * const a, pb_poly *Fq, From 777a086c53bf5767c7982a9dcfe07d4153481f4f Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 29 Apr 2014 14:27:15 +0200 Subject: [PATCH 15/27] DOC: improve inline comments in pb_inverse_poly_q() These should also match the actual mathematical computations. --- src/poly.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/poly.c b/src/poly.c index 25c80a0..7cb10f9 100644 --- a/src/poly.c +++ b/src/poly.c @@ -136,7 +136,7 @@ pb_poly *build_polynom(int const * const c, if (sign == true) mp_neg(&(new_poly->terms[i]), &(new_poly->terms[i])); } - } else { /* fill with zeros */ + } else { /* fill with 0 */ for (unsigned int i = 0; i < len; i++) MP_SET(&(new_poly->terms[i]), 0); } @@ -311,7 +311,6 @@ static void pb_mod2_to_modq(pb_poly * const a, pb_tmp2 = build_polynom(NULL, ctx->N, ctx); 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); @@ -338,15 +337,19 @@ bool pb_inverse_poly_q(pb_poly * const a, j = 0; pb_poly *a_tmp, *b, *c, *f, *g; + /* general initialization of temp variables */ b = build_polynom(NULL, ctx->N + 1, ctx); MP_SET(&(b->terms[0]), 1); c = build_polynom(NULL, ctx->N + 1, ctx); f = build_polynom(NULL, ctx->N + 1, ctx); PB_COPY(a, f); + + /* set g(x) = x^N − 1 */ 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); @@ -355,7 +358,9 @@ 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++) { + /* 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); @@ -378,6 +383,7 @@ bool pb_inverse_poly_q(pb_poly * const a, OUT_OF_LOOP: k = k % ctx->N; + /* Fq(x) = x^(N-k) * b(x) */ for (int i = ctx->N - 1; i >= 0; i--) { j = i - k; if (j < 0) @@ -387,6 +393,7 @@ 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; From 4d5f44c900e775b7dc6bad465719a9713843def5 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 29 Apr 2014 14:27:52 +0200 Subject: [PATCH 16/27] POLY: first try of implementing pb_inverse_poly_p() This ends up as an infinite loop though. --- src/poly.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/poly.h | 12 +++++ 2 files changed, 158 insertions(+) diff --git a/src/poly.c b/src/poly.c index 7cb10f9..d813310 100644 --- a/src/poly.c +++ b/src/poly.c @@ -409,6 +409,152 @@ OUT_OF_LOOP: 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, mp_minus; + + /* general initialization of temp variables */ + init_integer(&mp_modulus); + init_integer(&mp_minus); + MP_SET_INT(&mp_modulus, (unsigned long)(ctx->p)); + MP_SET_INT(&mp_minus, 1); + mp_neg(&mp_minus, &mp_minus); + b = build_polynom(NULL, ctx->N + 1, ctx); + MP_SET(&(b->terms[0]), 1); + c = build_polynom(NULL, ctx->N + 1, ctx); + f = build_polynom(NULL, ctx->N + 1, ctx); + PB_COPY(a, f); + + /* set g(x) = x^N − 1 */ + 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); + 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) { + printf("blah\n"); + 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) + goto OUT_OF_LOOP2; + + if (get_degree(f) < get_degree(g)) { + pb_exch(f, g); + pb_exch(b, c); + } + + { + pb_poly *u, *c_tmp, *g_tmp; + mp_int mp_tmp; + + init_integer(&mp_tmp); + u = build_polynom(NULL, ctx->N, ctx); + g_tmp = build_polynom(NULL, ctx->N + 1, ctx); + PB_COPY(g, g_tmp); + c_tmp = build_polynom(NULL, ctx->N + 1, ctx); + PB_COPY(c, c_tmp); + + /* u = ((f[0] mod p) * (g[0] inverse mod p) mod p) */ + printf("u before: "); draw_polynom(u); + MP_COPY(&(f->terms[0]), &mp_tmp); /* don't change f[0] */ + MP_INVMOD(&(g->terms[0]), &mp_modulus, &(u->terms[0])); + MP_MOD(&mp_tmp, &mp_modulus, &mp_tmp); + MP_MUL(&(u->terms[0]), &mp_tmp, &(u->terms[0])); + MP_MOD(&(u->terms[0]), &mp_modulus, &(u->terms[0])); + + /* f = f - u * g mod p */ + printf("f before: "); draw_polynom(f); + PB_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 */ + printf("b before: "); draw_polynom(b); + PB_MUL(c_tmp, u, c_tmp); + PB_SUB(b, c_tmp, b); + PB_MOD(b, &mp_modulus, b, ctx->N + 1); + printf("u after: "); draw_polynom(u); + printf("f after: "); draw_polynom(f); + printf("g after: "); draw_polynom(g); + printf("b after: "); draw_polynom(b); + + mp_clear(&mp_tmp); + delete_polynom_multi(u, c_tmp, g_tmp, NULL); + } + } + +OUT_OF_LOOP2: + 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, ctx->N + 1, ctx); + + 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 */ + + 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 77a9b54..4f3beea 100644 --- a/src/poly.h +++ b/src/poly.h @@ -105,6 +105,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; \ @@ -182,6 +190,10 @@ 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 */ From 942f90a0eff540385115df2125b777f121e77b87 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 29 Apr 2014 19:59:59 +0200 Subject: [PATCH 17/27] POLY: small cleanup * rm printf stuff * rename goto-statements * improve inline doc * rm unused variables --- src/poly.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/poly.c b/src/poly.c index d813310..3ee3341 100644 --- a/src/poly.c +++ b/src/poly.c @@ -369,7 +369,7 @@ bool pb_inverse_poly_q(pb_poly * const a, } if (get_degree(f) == 0) - goto OUT_OF_LOOP; + goto OUT_OF_LOOP_Q; if (get_degree(f) < get_degree(g)) { pb_exch(f, g); @@ -380,7 +380,7 @@ bool pb_inverse_poly_q(pb_poly * const a, pb_xor(b, c, b, ctx->N); } -OUT_OF_LOOP: +OUT_OF_LOOP_Q: k = k % ctx->N; /* Fq(x) = x^(N-k) * b(x) */ @@ -424,14 +424,11 @@ bool pb_inverse_poly_p(pb_poly *a, int k = 0, j = 0; pb_poly *a_tmp, *b, *c, *f, *g; - mp_int mp_modulus, mp_minus; + mp_int mp_modulus; /* general initialization of temp variables */ init_integer(&mp_modulus); - init_integer(&mp_minus); MP_SET_INT(&mp_modulus, (unsigned long)(ctx->p)); - MP_SET_INT(&mp_minus, 1); - mp_neg(&mp_minus, &mp_minus); b = build_polynom(NULL, ctx->N + 1, ctx); MP_SET(&(b->terms[0]), 1); c = build_polynom(NULL, ctx->N + 1, ctx); @@ -454,7 +451,6 @@ bool pb_inverse_poly_p(pb_poly *a, while (1) { while (mp_cmp_d(&(f->terms[0]), 0) == MP_EQ) { - printf("blah\n"); for (unsigned int i = 1; i <= ctx->N; i++) { /* f(x) = f(x) / x */ MP_COPY(&(f->terms[i]), &(f->terms[i - 1])); @@ -467,9 +463,10 @@ bool pb_inverse_poly_p(pb_poly *a, } if (get_degree(f) == 0) - goto OUT_OF_LOOP2; + goto OUT_OF_LOOP_P; if (get_degree(f) < get_degree(g)) { + /* exchange f and g and exchange b and c */ pb_exch(f, g); pb_exch(b, c); } @@ -485,36 +482,30 @@ bool pb_inverse_poly_p(pb_poly *a, c_tmp = build_polynom(NULL, ctx->N + 1, ctx); PB_COPY(c, c_tmp); - /* u = ((f[0] mod p) * (g[0] inverse mod p) mod p) */ - printf("u before: "); draw_polynom(u); - MP_COPY(&(f->terms[0]), &mp_tmp); /* don't change f[0] */ + /* 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); /* don't change f[0] */ MP_INVMOD(&(g->terms[0]), &mp_modulus, &(u->terms[0])); MP_MOD(&mp_tmp, &mp_modulus, &mp_tmp); MP_MUL(&(u->terms[0]), &mp_tmp, &(u->terms[0])); MP_MOD(&(u->terms[0]), &mp_modulus, &(u->terms[0])); /* f = f - u * g mod p */ - printf("f before: "); draw_polynom(f); PB_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 */ - printf("b before: "); draw_polynom(b); PB_MUL(c_tmp, u, c_tmp); PB_SUB(b, c_tmp, b); PB_MOD(b, &mp_modulus, b, ctx->N + 1); - printf("u after: "); draw_polynom(u); - printf("f after: "); draw_polynom(f); - printf("g after: "); draw_polynom(g); - printf("b after: "); draw_polynom(b); mp_clear(&mp_tmp); delete_polynom_multi(u, c_tmp, g_tmp, NULL); } } -OUT_OF_LOOP2: +OUT_OF_LOOP_P: k = k % ctx->N; /* Fp(x) = x^(N-k) * b(x) */ From 12fa21f5b2ca0523504e0e9428e67263e66a5732 Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 30 Apr 2014 17:16:50 +0200 Subject: [PATCH 18/27] POLY: make get_degree() public --- src/poly.c | 3 +-- src/poly.h | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/poly.c b/src/poly.c index 3ee3341..b5b6dd7 100644 --- a/src/poly.c +++ b/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); @@ -275,7 +274,7 @@ void pb_xor(pb_poly *a, * @param poly the polynomial * @return the degree */ -static unsigned int get_degree(pb_poly const * const poly) +unsigned int get_degree(pb_poly const * const poly) { unsigned int count = 0; diff --git a/src/poly.h b/src/poly.h index 4f3beea..9c2f988 100644 --- a/src/poly.h +++ b/src/poly.h @@ -31,6 +31,9 @@ #include #include + +unsigned int get_degree(pb_poly const * const poly); + #define MP_SET(...) mp_set(__VA_ARGS__) #define MP_SET_INT(...) \ From 9c89b796278e102c5349528e1c3f21511ad14db1 Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 30 Apr 2014 17:18:08 +0200 Subject: [PATCH 19/27] POLY: add init_integers() --- src/poly.c | 20 ++++++++++++++++++++ src/poly.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/src/poly.c b/src/poly.c index b5b6dd7..c60b24b 100644 --- a/src/poly.c +++ b/src/poly.c @@ -55,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 diff --git a/src/poly.h b/src/poly.h index 9c2f988..20132cb 100644 --- a/src/poly.h +++ b/src/poly.h @@ -32,6 +32,9 @@ #include + +void init_integers(mp_int *new_int, ...); + unsigned int get_degree(pb_poly const * const poly); #define MP_SET(...) mp_set(__VA_ARGS__) From f2b4183c688b57fec4848ffebfd4c9e9a03e5fdd Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 30 Apr 2014 17:19:58 +0200 Subject: [PATCH 20/27] POLY: add pb_mp_mul() --- src/poly.c | 23 +++++++++++++++++++++++ src/poly.h | 10 ++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/poly.c b/src/poly.c index c60b24b..66b6898 100644 --- a/src/poly.c +++ b/src/poly.c @@ -270,6 +270,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 * diff --git a/src/poly.h b/src/poly.h index 20132cb..b8589a6 100644 --- a/src/poly.h +++ b/src/poly.h @@ -135,6 +135,14 @@ unsigned int get_degree(pb_poly const * const poly); 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; \ @@ -187,6 +195,8 @@ 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, From afa06ce0b9d1354b2491959e5b9d60a9ea8a3ea9 Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 30 Apr 2014 17:22:25 +0200 Subject: [PATCH 21/27] POLY: remove unused context parameter of build_polynom() --- src/poly.c | 37 ++++++++++++++++++------------------- src/poly.h | 3 +-- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/poly.c b/src/poly.c index 66b6898..b945470 100644 --- a/src/poly.c +++ b/src/poly.c @@ -117,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 @@ -126,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; @@ -240,7 +239,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); @@ -346,11 +345,11 @@ 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); pb_starmultiply(a, Fq, pb_tmp, ctx, v); @@ -380,20 +379,20 @@ bool pb_inverse_poly_q(pb_poly * const a, pb_poly *a_tmp, *b, *c, *f, *g; /* general initialization of temp variables */ - b = build_polynom(NULL, ctx->N + 1, ctx); + 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); /* set g(x) = x^N − 1 */ - g = build_polynom(NULL, ctx->N + 1, ctx); + 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); @@ -471,20 +470,20 @@ bool pb_inverse_poly_p(pb_poly *a, /* 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, ctx); + 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); /* set g(x) = x^N − 1 */ - g = build_polynom(NULL, ctx->N + 1, ctx); + 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(Fp, ctx->N); @@ -519,9 +518,9 @@ bool pb_inverse_poly_p(pb_poly *a, init_integer(&mp_tmp); u = build_polynom(NULL, ctx->N, ctx); - g_tmp = build_polynom(NULL, ctx->N + 1, ctx); + g_tmp = build_polynom(NULL, ctx->N + 1); PB_COPY(g, g_tmp); - c_tmp = build_polynom(NULL, ctx->N + 1, ctx); + c_tmp = build_polynom(NULL, ctx->N + 1); PB_COPY(c, c_tmp); /* u = f[0] * g[0]^(-1) mod p @@ -557,7 +556,7 @@ OUT_OF_LOOP_P: { pb_poly *poly_tmp; - poly_tmp = build_polynom(NULL, ctx->N + 1, ctx); + 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])); diff --git a/src/poly.h b/src/poly.h index b8589a6..1f81767 100644 --- a/src/poly.h +++ b/src/poly.h @@ -180,8 +180,7 @@ 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); From 8817cd79b2a856a09089752a9393080b65a00012 Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 30 Apr 2014 17:22:57 +0200 Subject: [PATCH 22/27] POLY: use break instead of goto --- src/poly.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/poly.c b/src/poly.c index b945470..6010c8a 100644 --- a/src/poly.c +++ b/src/poly.c @@ -410,7 +410,7 @@ bool pb_inverse_poly_q(pb_poly * const a, } if (get_degree(f) == 0) - goto OUT_OF_LOOP_Q; + break; if (get_degree(f) < get_degree(g)) { pb_exch(f, g); @@ -421,7 +421,6 @@ bool pb_inverse_poly_q(pb_poly * const a, pb_xor(b, c, b, ctx->N); } -OUT_OF_LOOP_Q: k = k % ctx->N; /* Fq(x) = x^(N-k) * b(x) */ @@ -504,7 +503,7 @@ bool pb_inverse_poly_p(pb_poly *a, } if (get_degree(f) == 0) - goto OUT_OF_LOOP_P; + break; if (get_degree(f) < get_degree(g)) { /* exchange f and g and exchange b and c */ @@ -546,7 +545,6 @@ bool pb_inverse_poly_p(pb_poly *a, } } -OUT_OF_LOOP_P: k = k % ctx->N; /* Fp(x) = x^(N-k) * b(x) */ From f6b5c8de19ea2a3ed5df32e1ff6034168d3a540a Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 30 Apr 2014 17:23:24 +0200 Subject: [PATCH 23/27] POLY: simplify pb_inverse_poly_q() a bit --- src/poly.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/poly.c b/src/poly.c index 6010c8a..a13b481 100644 --- a/src/poly.c +++ b/src/poly.c @@ -377,8 +377,11 @@ 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; /* 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); @@ -435,15 +438,11 @@ bool pb_inverse_poly_q(pb_poly * const a, /* 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 */ From 8fbcbe41440f4e9cefdb8f9efe00dd8340ecc2cb Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 30 Apr 2014 17:23:39 +0200 Subject: [PATCH 24/27] POLY: rearrange header declarations --- src/poly.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/poly.h b/src/poly.h index 1f81767..fdf7450 100644 --- a/src/poly.h +++ b/src/poly.h @@ -32,11 +32,6 @@ #include - -void init_integers(mp_int *new_int, ...); - -unsigned int get_degree(pb_poly const * const poly); - #define MP_SET(...) mp_set(__VA_ARGS__) #define MP_SET_INT(...) \ @@ -173,8 +168,11 @@ unsigned int get_degree(pb_poly const * const poly); 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); @@ -201,6 +199,8 @@ void pb_xor(pb_poly *a, pb_poly *c, const size_t len); +unsigned int get_degree(pb_poly const * const poly); + bool pb_inverse_poly_q(pb_poly *a, pb_poly *Fq, ntru_context *ctx); @@ -211,4 +211,5 @@ bool pb_inverse_poly_p(pb_poly *a, void draw_polynom(pb_poly * const poly); + #endif /* NTRU_POLY_H */ From e29064a666914ea9fa69ccbd13d3fce22991ce22 Mon Sep 17 00:00:00 2001 From: hasufell Date: Wed, 30 Apr 2014 17:29:16 +0200 Subject: [PATCH 25/27] POLY: fix pb_inverse_poly_p and convert to pb_mp_mul() Was still using the old build_polynom() API. --- src/poly.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/poly.c b/src/poly.c index a13b481..5dd64c8 100644 --- a/src/poly.c +++ b/src/poly.c @@ -511,11 +511,10 @@ bool pb_inverse_poly_p(pb_poly *a, } { - pb_poly *u, *c_tmp, *g_tmp; - mp_int mp_tmp; + pb_poly *c_tmp, *g_tmp; + mp_int u, mp_tmp; - init_integer(&mp_tmp); - u = build_polynom(NULL, ctx->N, ctx); + 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); @@ -523,24 +522,24 @@ bool pb_inverse_poly_p(pb_poly *a, /* 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); /* don't change f[0] */ - MP_INVMOD(&(g->terms[0]), &mp_modulus, &(u->terms[0])); + 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->terms[0]), &mp_tmp, &(u->terms[0])); - MP_MOD(&(u->terms[0]), &mp_modulus, &(u->terms[0])); + MP_MUL(&u, &mp_tmp, &u); + MP_MOD(&u, &mp_modulus, &u); /* f = f - u * g mod p */ - PB_MUL(g_tmp, u, g_tmp); + 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_MUL(c_tmp, u, c_tmp); + 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(u, c_tmp, g_tmp, NULL); + delete_polynom_multi(c_tmp, g_tmp, NULL); } } From 30e18177e8aba8e3c5b4835379e3919f1aaf8323 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 13 May 2014 00:12:03 +0200 Subject: [PATCH 26/27] POLY: allow signed int in MP_SET_INT Now you can pass MP_SET_INT(&foo, -1) without having to call mp_neg() later etc. --- src/poly.c | 22 +++------------------- src/poly.h | 7 +++++-- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/src/poly.c b/src/poly.c index 5dd64c8..7f3aabd 100644 --- a/src/poly.c +++ b/src/poly.c @@ -138,22 +138,8 @@ 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])); - } + 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); @@ -391,7 +377,6 @@ bool pb_inverse_poly_q(pb_poly * const a, /* 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 */ @@ -476,8 +461,7 @@ bool pb_inverse_poly_p(pb_poly *a, /* 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_INT(&(g->terms[0]), -1); MP_SET(&(g->terms[ctx->N]), 1); /* avoid side effects */ diff --git a/src/poly.h b/src/poly.h index fdf7450..7eacb21 100644 --- a/src/poly.h +++ b/src/poly.h @@ -30,16 +30,19 @@ #include #include #include +#include #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(...) \ From 782ccf05244eff14e9bc8f3a258c8f3210e85331 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 13 May 2014 00:20:46 +0200 Subject: [PATCH 27/27] POLY: improve error handling --- src/poly.c | 13 +++++++++---- src/poly.h | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/poly.c b/src/poly.c index 7f3aabd..5a152a5 100644 --- a/src/poly.c +++ b/src/poly.c @@ -300,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 */ -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) @@ -354,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, @@ -395,6 +395,8 @@ bool pb_inverse_poly_q(pb_poly * const a, 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) @@ -411,6 +413,9 @@ bool pb_inverse_poly_q(pb_poly * const a, 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; diff --git a/src/poly.h b/src/poly.h index 7eacb21..6f675c6 100644 --- a/src/poly.h +++ b/src/poly.h @@ -202,7 +202,7 @@ void pb_xor(pb_poly *a, pb_poly *c, const size_t len); -unsigned int get_degree(pb_poly const * const poly); +int get_degree(pb_poly const * const poly); bool pb_inverse_poly_q(pb_poly *a, pb_poly *Fq,