diff --git a/src/Makefile b/src/Makefile index eefa212..aa5d76b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,7 +34,7 @@ else PQC_LIBS = libpqc.a endif # CUNIT_LIBS = -lcunit -LIBS += -L. -lgmp -lmpfr -lm +LIBS += -L. -lgmp -lmpfr -lm $(shell $(PKG_CONFIG) --libs glib-2.0) # objects PQC_OBJS = poly.o mem.o encrypt.o decrypt.o keypair.o ascii_poly.o file.o \ @@ -44,7 +44,7 @@ PQC_HEADERS = err.h poly.h context.h encrypt.h decrypt.h keypair.h \ # CUNIT_OBJS = cunit.o # includes -INCS = -I. +INCS = -I. $(shell $(PKG_CONFIG) --cflags glib-2.0) ifndef UNBUNDLE LIBFLINT = ../external/flint-2.4.3/libflint.a diff --git a/src/ascii_poly.c b/src/ascii_poly.c index 781669f..9b3c885 100644 --- a/src/ascii_poly.c +++ b/src/ascii_poly.c @@ -19,6 +19,9 @@ * MA 02110-1301 USA */ +/* TODO: clean up some iterators */ +/* TODO: ascii_to_bin_poly() should accept a string, not a c_str */ + /** * @file ascii_poly.c * This file allows to convert between ascii strings @@ -33,6 +36,8 @@ #include "ntru_string.h" #include "poly.h" +#include + #include #include #include @@ -93,18 +98,17 @@ get_bin_arr_to_ascii(char *binary_rep) { const size_t int_arr_size = strlen(binary_rep) / ASCII_BITS; uint8_t int_arr[int_arr_size]; - char *tmp_string = binary_rep; uint32_t i = 0; char *int_string; - while (*tmp_string) { + while (*binary_rep) { int_arr[i] = 0; for (uint32_t j = 0; j < ASCII_BITS; j++) { - if (*tmp_string == '1') + if (*binary_rep == '1') int_arr[i] = int_arr[i] * 2 + 1; - else if (*tmp_string == '0') + else if (*binary_rep == '0') int_arr[i] *= 2; - tmp_string++; + binary_rep++; } i++; } @@ -118,7 +122,7 @@ get_bin_arr_to_ascii(char *binary_rep) } fmpz_poly_t * -ascii_to_tern_poly(char *to_poly, ntru_context *ctx) +ascii_bin_to_bin_poly(char *to_poly, ntru_context *ctx) { uint32_t i = 0; uint32_t j = 0; @@ -145,7 +149,7 @@ ascii_to_tern_poly(char *to_poly, ntru_context *ctx) } fmpz_poly_t ** -ascii_to_tern_poly_arr(char *to_poly, ntru_context *ctx) +ascii_to_bin_poly_arr(char *to_poly, ntru_context *ctx) { uint32_t polyc = 0; char *cur = to_poly; @@ -174,7 +178,7 @@ ascii_to_tern_poly_arr(char *to_poly, ntru_context *ctx) memcpy(chunk, out + i, real_chunk_size); chunk[real_chunk_size] = '\0'; - poly_array[polyc] = ascii_to_tern_poly(chunk, ctx); + poly_array[polyc] = ascii_bin_to_bin_poly(chunk, ctx); polyc++; } @@ -186,67 +190,8 @@ ascii_to_tern_poly_arr(char *to_poly, ntru_context *ctx) return poly_array; } -fmpz_poly_t * -ascii_to_poly(string *to_poly, ntru_context *ctx) -{ - uint32_t i = 0; - uint32_t j = 0; - fmpz_poly_t *new_poly = ntru_malloc(sizeof(*new_poly)); - - fmpz_poly_init(*new_poly); - - while (i < to_poly->len && j < ctx->N) { - fmpz_poly_set_coeff_si(*new_poly, - j, - (uint8_t)(to_poly->ptr[i])); - i++; - j++; - } - - /* fill the last poly with q (which is a non-standard - * coefficient) */ - for (uint32_t i = j; i < ctx->N; i++) { - fmpz_poly_set_coeff_si(*new_poly, - i, - ctx->q); - } - - return new_poly; -} - -fmpz_poly_t ** -ascii_to_poly_arr(string *to_poly, ntru_context *ctx) -{ - uint32_t polyc = 0; - fmpz_poly_t **poly_array; - - poly_array = ntru_malloc(sizeof(**poly_array) * - (strlen(to_poly->ptr) / ctx->N)); - - for (uint32_t i = 0; i < to_poly->len; i += ctx->N) { - char chunk[ctx->N + 1]; - string string_chunk; - size_t real_chunk_size; - - real_chunk_size = - ((to_poly->len - i) > ctx->N) ? ctx->N : (to_poly->len - i); - - memcpy(chunk, to_poly->ptr + i, real_chunk_size); - - string_chunk.ptr = chunk; - string_chunk.len = real_chunk_size; - poly_array[polyc] = ascii_to_poly(&string_chunk, ctx); - - polyc++; - } - - poly_array[polyc] = NULL; - - return poly_array; -} - string * -tern_poly_to_ascii(fmpz_poly_t poly, +bin_poly_to_ascii(fmpz_poly_t poly, ntru_context *ctx) { string *result_string = ntru_malloc(sizeof(*result_string)); @@ -274,12 +219,12 @@ tern_poly_to_ascii(fmpz_poly_t poly, } string * -tern_poly_arr_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx) +bin_poly_arr_to_ascii(fmpz_poly_t **bin_poly_arr, ntru_context *ctx) { fmpz_poly_t *ascii_poly; char *binary_rep = NULL; size_t string_len = 0; - char *ascii_string; + char *ascii_string = NULL; string *result_string = ntru_malloc(sizeof(*result_string)); size_t old_length = 0, new_length; @@ -288,7 +233,7 @@ tern_poly_arr_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx) * parse the polynomial coefficients into a string */ binary_rep = ntru_calloc(1, CHAR_SIZE * (ctx->N + 1)); - while ((ascii_poly = *tern_poly_arr++)) { + while ((ascii_poly = *bin_poly_arr++)) { string *single_poly_string; new_length = CHAR_SIZE * (ctx->N + 1); @@ -300,31 +245,90 @@ tern_poly_arr_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx) old_length += new_length; - single_poly_string = tern_poly_to_ascii(*ascii_poly, ctx); + single_poly_string = bin_poly_to_ascii(*ascii_poly, ctx); memcpy(binary_rep + string_len, single_poly_string->ptr, single_poly_string->len); string_len += single_poly_string->len; + + string_delete(single_poly_string); } binary_rep[string_len] = '\0'; ascii_string = get_bin_arr_to_ascii(binary_rep); - free(binary_rep); result_string->ptr = ascii_string; - result_string->len = string_len; + result_string->len = strlen(ascii_string); - return result_string;} + free(binary_rep); + return result_string; +} + +fmpz_poly_t ** +base64_to_poly_arr(string *to_poly, ntru_context *ctx) +{ + uint32_t i = 0, + polyc = 0; + gsize out_len; + guchar *base64_decoded; + string *new_string = ntru_malloc(sizeof(*new_string)); + fmpz_poly_t **poly_array; + char tmp[to_poly->len + 1]; + + /* g_base64_decode() needs it null-terminated */ + memcpy(tmp, to_poly->ptr, to_poly->len); + tmp[to_poly->len] = '\0'; + + base64_decoded = g_base64_decode((const gchar *)tmp, &out_len); + new_string->ptr = (char *)base64_decoded; + new_string->len = (unsigned long)(out_len); + + poly_array = ntru_malloc(sizeof(**poly_array) * + (strlen(new_string->ptr) / ctx->N)); + + while (i < new_string->len) { + uint32_t j = 0; + fmpz_poly_t *new_poly = ntru_malloc(sizeof(*new_poly)); + + fmpz_poly_init(*new_poly); + + while (j < ctx->N) { + fmpz_poly_set_coeff_si(*new_poly, + j, + (uint8_t)(base64_decoded[i])); + j++; + i++; + } + + /* fill the last poly with q (which is a non-standard + * coefficient) */ + for (uint32_t k = j; k < ctx->N; k++) { + fmpz_poly_set_coeff_si(*new_poly, + k, + ctx->q); + } + + poly_array[polyc] = new_poly; + polyc++; + } + + poly_array[polyc] = NULL; + + string_delete(new_string); + + return poly_array; +} string * -poly_to_ascii(fmpz_poly_t poly, +poly_to_base64(fmpz_poly_t poly, ntru_context *ctx) { string *result_string = ntru_malloc(sizeof(*result_string)); char *string_rep = ntru_malloc(CHAR_SIZE * (ctx->N)); uint32_t i = 0; + gchar *base64_string = NULL; for (uint32_t j = 0; j < ctx->N; j++) { uint8_t coeff = fmpz_poly_get_coeff_ui(poly, j); @@ -335,14 +339,18 @@ poly_to_ascii(fmpz_poly_t poly, i++; } - result_string->ptr = string_rep; - result_string->len = i; + base64_string = g_base64_encode((const guchar *)string_rep, i); + + result_string->ptr = base64_string; + result_string->len = strlen(base64_string); + + free(string_rep); return result_string; } string * -poly_arr_to_ascii(fmpz_poly_t **poly_array, +poly_arr_to_base64(fmpz_poly_t **poly_array, ntru_context *ctx) { fmpz_poly_t *ascii_poly; @@ -357,22 +365,22 @@ poly_arr_to_ascii(fmpz_poly_t **poly_array, */ string_rep = ntru_calloc(1, CHAR_SIZE * (ctx->N + 1)); while ((ascii_poly = *poly_array++)) { - string *single_poly_string; + string *poly_str; - new_length = CHAR_SIZE * (ctx->N + 1); + poly_str = poly_to_base64(*ascii_poly, ctx); + new_length = CHAR_SIZE * poly_str->len; REALLOC(string_rep, old_length + - new_length + - 1); /* trailing null byte */ - + new_length); old_length += new_length; - single_poly_string = poly_to_ascii(*ascii_poly, ctx); memcpy(string_rep + string_len, - single_poly_string->ptr, - single_poly_string->len); - string_len += single_poly_string->len; + poly_str->ptr, + poly_str->len); + string_len += poly_str->len; + + string_delete(poly_str); } result_string->ptr = string_rep; diff --git a/src/ascii_poly.h b/src/ascii_poly.h index 0b1148c..6626c9f 100644 --- a/src/ascii_poly.h +++ b/src/ascii_poly.h @@ -38,7 +38,7 @@ /** - * Convert an ascii string to a ternary polyomial. + * Convert a "binary" ascii string to a binary polyomial. * The ascii string will be converted to a binary representation * and the following mapping will apply between binary -> poly: * @@ -47,17 +47,17 @@ * 0 => -1 * * If the polynomial is of degree less than N -1, then it will - * be filled with trailing 2's for later use in tern_poly_to_ascii(). + * be filled with trailing 2's for later use in bin_poly_to_ascii(). * - * @param to_poly the string to get into ternary polynomial format + * @param to_poly the string to get into binary polynomial format * @param ctx the NTRUEncrypt context - * @return newly allocated array of ternary polynomials + * @return newly allocated array of binary polynomials */ fmpz_poly_t * -ascii_to_tern_poly(char *to_poly, ntru_context *ctx); +ascii_bin_to_bin_poly(char *to_poly, ntru_context *ctx); /** - * Convert an ascii string to an array of ternary polyomials. + * Convert an ascii string to an array of binary polyomials. * The ascii string will be converted to a binary representation * and the following mapping will apply between binary -> poly: * @@ -66,53 +66,17 @@ ascii_to_tern_poly(char *to_poly, ntru_context *ctx); * 0 => -1 * * If the last polynomial is of degree less than N -1, then it will - * be filled with trailing 2's for later use in tern_poly_arr_to_ascii(). + * be filled with trailing 2's for later use in bin_poly_arr_to_ascii(). * - * @param to_poly the string to get into ternary polynomial format + * @param to_poly the string to get into binary polynomial format * @param ctx the NTRUEncrypt context - * @return newly allocated array of ternary polynomials + * @return newly allocated array of binary polynomials */ fmpz_poly_t ** -ascii_to_tern_poly_arr(char *to_poly, ntru_context *ctx); +ascii_to_bin_poly_arr(char *to_poly, ntru_context *ctx); /** - * Convert an ascii string to a polyomial with coefficients - * which are expected to be in the range [0, q-1]. - * The chars will be converted to their integer representation and - * directly put into the coefficients. - * - * If the polynomial is of degree less than N -1, then it will - * be filled with trailing q's for later user in poly_to_ascii(). - * - * @param to_poly the string to get into polynomial format, - * which is of type string, so we can iterate safely over it - * (the string might have null-bytes in the middle of it) - * @param ctx the NTRUEncrypt context - * @return newly allocated polynomial - */ -fmpz_poly_t * -ascii_to_poly(string *to_poly, ntru_context *ctx); - -/** - * Convert an ascii string to an array of polyomials with coefficients - * which are expected to be in the range [0, q-1]. - * The chars will be converted to their integer representation and - * directly put into the coefficients. - * - * If the last polynomial is of degree less than N -1, then it will - * be filled with trailing q's for later user in poly_arr_to_ascii(). - * - * @param to_poly the string to get into polynomial format, - * which is of type string, so we can iterate safely over it - * (the string might have null-bytes in the middle of it) - * @param ctx the NTRUEncrypt context - * @return newly allocated array of polynomials - */ -fmpz_poly_t ** -ascii_to_poly_arr(string *to_poly, ntru_context *ctx); - -/** - * Convert an single ternary polynomial back to a real string. + * Convert a single binary polynomial back to a real string. * The polynomial coefficients represent a binary format of the * ascii string with the following mapping: * @@ -126,16 +90,16 @@ ascii_to_poly_arr(string *to_poly, ntru_context *ctx); * so they will just end up as '\0's at the end of the string and will * not confuse the result. * - * @param poly the polynomial to convert + * @param poly the binary polynomial to convert * @param ctx the NTRUEncrypt context * @return the real string, newly allocated */ string * -tern_poly_to_ascii(fmpz_poly_t poly, +bin_poly_to_ascii(fmpz_poly_t poly, ntru_context *ctx); /** - * Convert an array of ternary polynomials back to a real string. + * Convert an array of binary polynomials back to a real string. * The polynomial coefficients represent a binary format of the * ascii string with the following mapping: * @@ -149,53 +113,63 @@ tern_poly_to_ascii(fmpz_poly_t poly, * just end up as '\0's at the end of the string and will not confuse * the result. * - * @param tern_poly_arr the array of polynomials + * @param bin_poly_arr the array of polynomials * @param ctx the NTRUEncrypt context * @return the real string, newly allocated */ string * -tern_poly_arr_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx); +bin_poly_arr_to_ascii(fmpz_poly_t **bin_poly_arr, ntru_context *ctx); /** - * Convert a single polynom back to a real string. + * Convert an base64 encoded string to an array of polyomials with + * coefficients which are expected to be in the range [0, q-1]. + * The chars will be converted (after decoding) to their integer + * representation and directly put into the coefficients. + * + * If the last polynomial is of degree less than N -1, then it will + * be filled with trailing q's for later user in poly_arr_to_base64(). + * + * @param to_poly the string to get into polynomial format, + * which is of type string, so we can iterate safely over it + * (the string might have null-bytes in the middle of it) + * @param ctx the NTRUEncrypt context + * @return newly allocated array of polynomials + */ +fmpz_poly_t ** +base64_to_poly_arr(string *to_poly, ntru_context *ctx); + +/** + * Convert a single polynom back to a real string which is + * base64 encoded. * The polynomial coefficients are expected to be in the range * [0, q-1] and will be casted back to chars without any mapping. * - * Trailing q's are only used for filling up the rest of a polynomial, - * so they will just end up as '\0's at the end of the string and - * will not confuse the result. - * - * A struct of type string is returned, because we cannot - * rely on null-termination in ascii_to_poly(), since there - * may be null-bytes in the middle of the string as well. + * Trailing q coefficients are only used for filling up the rest of + * a polynomial with '\0', so they will not confuse the result. * * @param poly the polynomial to convert * @param ctx the NTRUEncrypt context * @return the real string, newly allocated */ string * -poly_to_ascii(fmpz_poly_t poly, +poly_to_base64(fmpz_poly_t poly, ntru_context *ctx); /** - * Convert an array of polynomials back to a real string. + * Convert an array of polynomials back to a real string which + * is base64 encoded. * The polynomial coefficients are expected to be in the range * [0, q-1] and will be casted back to chars without any mapping. * - * Trailing q's are only used for filling up the last polynomial, - * so they will just end up as '\0's at the end of the string and - * will not confuse the result. - * - * A struct of type string is returned, because we cannot - * rely on null-termination in ascii_to_poly_arr(), since there - * may be null-bytes in the middle of the string as well. + * Trailing q coefficients are only used for filling up the rest of + * a polynomial with '\0', so they will not confuse the result. * * @param poly_arr the array of polynomials * @param ctx the NTRUEncrypt context * @return the real string, newly allocated */ string * -poly_arr_to_ascii(fmpz_poly_t **poly_arr, ntru_context *ctx); +poly_arr_to_base64(fmpz_poly_t **poly_arr, ntru_context *ctx); #endif /* NTRU_ASCII_POLY_H_ */ diff --git a/src/decrypt.c b/src/decrypt.c index 336a30e..67bfe0e 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -41,7 +41,7 @@ ntru_decrypt_poly( fmpz_poly_t encr_msg, fmpz_poly_t priv_key, fmpz_poly_t priv_key_inv, - fmpz_poly_t out_tern, + fmpz_poly_t out_bin, ntru_context *ctx) { fmpz_poly_t a; @@ -51,8 +51,8 @@ ntru_decrypt_poly( poly_starmultiply(priv_key, encr_msg, a, ctx, ctx->q); fmpz_poly_mod(a, ctx->q); - poly_starmultiply(a, priv_key_inv, out_tern, ctx, ctx->p); - fmpz_poly_mod(out_tern, ctx->p); + poly_starmultiply(a, priv_key_inv, out_bin, ctx, ctx->p); + fmpz_poly_mod(out_bin, ctx->p); fmpz_poly_clear(a); } @@ -68,7 +68,7 @@ ntru_decrypt_string( string *decr_msg; fmpz_poly_t **poly_array; - poly_array = ascii_to_poly_arr(encr_msg, ctx); + poly_array = base64_to_poly_arr(encr_msg, ctx); while (*poly_array[i]) { ntru_decrypt_poly(*poly_array[i], priv_key, priv_key_inv, @@ -76,7 +76,7 @@ ntru_decrypt_string( i++; } - decr_msg = tern_poly_arr_to_ascii(poly_array, ctx); + decr_msg = bin_poly_arr_to_ascii(poly_array, ctx); poly_delete_array(poly_array); diff --git a/src/encrypt.c b/src/encrypt.c index 413ff31..8d270a5 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -39,7 +39,7 @@ void ntru_encrypt_poly( - fmpz_poly_t msg_tern, + fmpz_poly_t msg_bin, fmpz_poly_t pub_key, fmpz_poly_t rnd, fmpz_poly_t out, @@ -48,7 +48,7 @@ ntru_encrypt_poly( /* allow aliasing */ fmpz_poly_t tmp_poly_msg; fmpz_poly_init(tmp_poly_msg); - fmpz_poly_set(tmp_poly_msg, msg_tern); + fmpz_poly_set(tmp_poly_msg, msg_bin); fmpz_poly_zero(out); poly_starmultiply(pub_key, rnd, out, ctx, ctx->q); @@ -69,14 +69,14 @@ ntru_encrypt_string( string *enc_msg; fmpz_poly_t **poly_array; - poly_array = ascii_to_tern_poly_arr(msg, ctx); + poly_array = ascii_to_bin_poly_arr(msg, ctx); while (*poly_array[i]) { ntru_encrypt_poly(*poly_array[i], pub_key, rnd, *poly_array[i], ctx); i++; } - enc_msg = poly_arr_to_ascii(poly_array, ctx); + enc_msg = poly_arr_to_base64(poly_array, ctx); poly_delete_array(poly_array);