diff --git a/src/ascii_poly.c b/src/ascii_poly.c index 5ab4d16..781669f 100644 --- a/src/ascii_poly.c +++ b/src/ascii_poly.c @@ -117,11 +117,37 @@ get_bin_arr_to_ascii(char *binary_rep) return int_string; } -fmpz_poly_t ** +fmpz_poly_t * ascii_to_tern_poly(char *to_poly, ntru_context *ctx) { - uint32_t i = 0, - polyc = 0; + uint32_t i = 0; + uint32_t j = 0; + fmpz_poly_t *new_poly = ntru_malloc(sizeof(*new_poly)); + + fmpz_poly_init(*new_poly); + + while (to_poly[i] && j < ctx->N) { + fmpz_poly_set_coeff_si(*new_poly, + j, + (to_poly[i] == '0') ? -1 : 1); + i++; + j++; + } + + /* fill the last poly with 2 */ + for (uint32_t i = j; i < ctx->N; i++) { + fmpz_poly_set_coeff_si(*new_poly, + i, + 2); + } + + return new_poly; +} + +fmpz_poly_t ** +ascii_to_tern_poly_arr(char *to_poly, ntru_context *ctx) +{ + uint32_t polyc = 0; char *cur = to_poly; size_t out_size = CHAR_SIZE * (strlen(to_poly) * ASCII_BITS + 1); char *out = ntru_malloc(out_size); @@ -138,27 +164,17 @@ ascii_to_tern_poly(char *to_poly, ntru_context *ctx) poly_array = ntru_malloc(sizeof(**poly_array) * (strlen(out) / ctx->N)); - while (out[i]) { - uint32_t j = 0; - fmpz_poly_t *new_poly = ntru_malloc(sizeof(*new_poly)); + for (uint32_t i = 0; i < strlen(out); i += ctx->N) { + char chunk[ctx->N + 1]; + size_t real_chunk_size; - fmpz_poly_init(*new_poly); - poly_array[polyc] = new_poly; + real_chunk_size = + (strlen(out + i) > ctx->N) ? ctx->N : strlen(out + i); - while (out[i] && j < ctx->N) { - fmpz_poly_set_coeff_si(*new_poly, - j, - (out[i] == '0') ? -1 : 1); - i++; - j++; - } + memcpy(chunk, out + i, real_chunk_size); + chunk[real_chunk_size] = '\0'; - /* fill the last poly with 2 */ - for (uint32_t i = j; i < ctx->N; i++) { - fmpz_poly_set_coeff_si(*new_poly, - i, - 2); - } + poly_array[polyc] = ascii_to_tern_poly(chunk, ctx); polyc++; } @@ -170,41 +186,58 @@ ascii_to_tern_poly(char *to_poly, ntru_context *ctx) return poly_array; } -fmpz_poly_t ** +fmpz_poly_t * ascii_to_poly(string *to_poly, ntru_context *ctx) { - uint32_t i = 0, - polyc = 0; + 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)); - while (i < to_poly->len) { - uint32_t j = 0; - fmpz_poly_t *new_poly = ntru_malloc(sizeof(*new_poly)); + 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; - fmpz_poly_init(*new_poly); - poly_array[polyc] = new_poly; + real_chunk_size = + ((to_poly->len - i) > ctx->N) ? ctx->N : (to_poly->len - i); - while (i < to_poly->len && j < ctx->N) { - fmpz_poly_set_coeff_si(*new_poly, - j, - (uint8_t)(to_poly->ptr[i])); - i++; - j++; - } + memcpy(chunk, to_poly->ptr + i, real_chunk_size); - /* 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); - } + string_chunk.ptr = chunk; + string_chunk.len = real_chunk_size; + poly_array[polyc] = ascii_to_poly(&string_chunk, ctx); polyc++; - } poly_array[polyc] = NULL; @@ -212,21 +245,52 @@ ascii_to_poly(string *to_poly, ntru_context *ctx) return poly_array; } -char * -tern_poly_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx) +string * +tern_poly_to_ascii(fmpz_poly_t poly, + ntru_context *ctx) +{ + string *result_string = ntru_malloc(sizeof(*result_string)); + char *binary_rep = ntru_malloc(CHAR_SIZE * (ctx->N)); + uint32_t i = 0; + + for (uint32_t j = 0; j < ctx->N; j++) { + fmpz *coeff = fmpz_poly_get_coeff_ptr(poly, j); + + if (coeff) { + if (fmpz_cmp_si(coeff, 1)) + binary_rep[i] = '0'; + else if (fmpz_cmp_si(coeff, -1)) + binary_rep[i] = '1'; + else if (fmpz_cmp_si(coeff, 2)) + binary_rep[i] = '0'; + } + i++; + } + + result_string->ptr = binary_rep; + result_string->len = i; + + return result_string; +} + +string * +tern_poly_arr_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx) { fmpz_poly_t *ascii_poly; char *binary_rep = NULL; + size_t string_len = 0; char *ascii_string; - uint32_t i = 0; + string *result_string = ntru_malloc(sizeof(*result_string)); size_t old_length = 0, new_length; /* * parse the polynomial coefficients into a string */ - binary_rep = ntru_malloc(CHAR_SIZE * (ctx->N + 1)); + binary_rep = ntru_calloc(1, CHAR_SIZE * (ctx->N + 1)); while ((ascii_poly = *tern_poly_arr++)) { + string *single_poly_string; + new_length = CHAR_SIZE * (ctx->N + 1); REALLOC(binary_rep, @@ -236,45 +300,65 @@ tern_poly_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx) old_length += new_length; - for (uint32_t j = 0; j < ctx->N; j++) { - fmpz *coeff = fmpz_poly_get_coeff_ptr(*ascii_poly, j); - - if (coeff) { - if (fmpz_cmp_si(coeff, 1)) - binary_rep[i] = '0'; - else if (fmpz_cmp_si(coeff, -1)) - binary_rep[i] = '1'; - else if (fmpz_cmp_si(coeff, 2)) - binary_rep[i] = '0'; - } - i++; - } + single_poly_string = tern_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; } - binary_rep[i] = '\0'; + binary_rep[string_len] = '\0'; ascii_string = get_bin_arr_to_ascii(binary_rep); free(binary_rep); - return ascii_string; + result_string->ptr = ascii_string; + result_string->len = string_len; + + return result_string;} + + +string * +poly_to_ascii(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; + + for (uint32_t j = 0; j < ctx->N; j++) { + uint8_t coeff = fmpz_poly_get_coeff_ui(poly, j); + if (coeff == ctx->q) + string_rep[i] = '\0'; + else + string_rep[i] = (char)coeff; + i++; + } + + result_string->ptr = string_rep; + result_string->len = i; + + return result_string; } string * -poly_to_ascii(fmpz_poly_t **poly_array, +poly_arr_to_ascii(fmpz_poly_t **poly_array, ntru_context *ctx) { fmpz_poly_t *ascii_poly; char *string_rep = NULL; + size_t string_len = 0; string *result_string = ntru_malloc(sizeof(*result_string)); - uint32_t i = 0; size_t old_length = 0, new_length; /* * parse the polynomial coefficients into a string */ - string_rep = ntru_malloc(CHAR_SIZE * (ctx->N + 1)); + string_rep = ntru_calloc(1, CHAR_SIZE * (ctx->N + 1)); while ((ascii_poly = *poly_array++)) { + string *single_poly_string; + new_length = CHAR_SIZE * (ctx->N + 1); REALLOC(string_rep, @@ -284,20 +368,15 @@ poly_to_ascii(fmpz_poly_t **poly_array, old_length += new_length; - for (uint32_t j = 0; j < ctx->N; j++) { - uint8_t coeff = fmpz_poly_get_coeff_ui(*ascii_poly, j); - if (coeff == ctx->q) - string_rep[i] = '\0'; - else - string_rep[i] = (char)coeff; - i++; - } + 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; } - string_rep[i] = '\0'; - result_string->ptr = string_rep; - result_string->len = i; + result_string->len = string_len; return result_string; } diff --git a/src/ascii_poly.h b/src/ascii_poly.h index 6b153f4..0b1148c 100644 --- a/src/ascii_poly.h +++ b/src/ascii_poly.h @@ -37,6 +37,25 @@ #include +/** + * Convert an ascii string to a ternary polyomial. + * The ascii string will be converted to a binary representation + * and the following mapping will apply between binary -> poly: + * + * 1 => 1 + * + * 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(). + * + * @param to_poly the string to get into ternary polynomial format + * @param ctx the NTRUEncrypt context + * @return newly allocated array of ternary polynomials + */ +fmpz_poly_t * +ascii_to_tern_poly(char *to_poly, ntru_context *ctx); + /** * Convert an ascii string to an array of ternary polyomials. * The ascii string will be converted to a binary representation @@ -47,23 +66,41 @@ * 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_to_ascii(). + * be filled with trailing 2's for later use in tern_poly_arr_to_ascii(). * * @param to_poly the string to get into ternary polynomial format * @param ctx the NTRUEncrypt context * @return newly allocated array of ternary polynomials */ fmpz_poly_t ** -ascii_to_tern_poly(char *to_poly, ntru_context *ctx); +ascii_to_tern_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}. + * 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_to_ascii(). + * 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 @@ -72,7 +109,30 @@ ascii_to_tern_poly(char *to_poly, ntru_context *ctx); * @return newly allocated array of polynomials */ fmpz_poly_t ** -ascii_to_poly(string *to_poly, ntru_context *ctx); +ascii_to_poly_arr(string *to_poly, ntru_context *ctx); + +/** + * Convert an single ternary polynomial back to a real string. + * The polynomial coefficients represent a binary format of the + * ascii string with the following mapping: + * + * 1 => 1 + * + * -1 => 0 + * + * 2 => 0 + * + * The 2's are only used for filling up the rest of the polynomial, + * 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 ctx the NTRUEncrypt context + * @return the real string, newly allocated + */ +string * +tern_poly_to_ascii(fmpz_poly_t poly, + ntru_context *ctx); /** * Convert an array of ternary polynomials back to a real string. @@ -93,15 +153,15 @@ ascii_to_poly(string *to_poly, ntru_context *ctx); * @param ctx the NTRUEncrypt context * @return the real string, newly allocated */ -char * -tern_poly_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx); +string * +tern_poly_arr_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx); /** - * Convert an array of polynomials back to a real string. + * Convert a single polynom back to a real string. * The polynomial coefficients are expected to be in the range - * {0, q-1} and will be casted back to chars without any mapping. + * [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, + * 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. * @@ -109,12 +169,33 @@ tern_poly_to_ascii(fmpz_poly_t **tern_poly_arr, ntru_context *ctx); * rely on null-termination in ascii_to_poly(), since there * may be null-bytes in the middle of the string as well. * + * @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, + ntru_context *ctx); + +/** + * Convert an array of polynomials back to a real string. + * 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. + * * @param poly_arr the array of polynomials * @param ctx the NTRUEncrypt context * @return the real string, newly allocated */ string * -poly_to_ascii(fmpz_poly_t **poly_arr, ntru_context *ctx); +poly_arr_to_ascii(fmpz_poly_t **poly_arr, ntru_context *ctx); #endif /* NTRU_ASCII_POLY_H_ */ diff --git a/src/decrypt.c b/src/decrypt.c index 7d8c8f2..336a30e 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -57,7 +57,7 @@ ntru_decrypt_poly( fmpz_poly_clear(a); } -char * +string * ntru_decrypt_string( string *encr_msg, fmpz_poly_t priv_key, @@ -65,10 +65,10 @@ ntru_decrypt_string( ntru_context *ctx) { uint32_t i = 0; - char *decr_msg; + string *decr_msg; fmpz_poly_t **poly_array; - poly_array = ascii_to_poly(encr_msg, ctx); + poly_array = ascii_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_to_ascii(poly_array, ctx); + decr_msg = tern_poly_arr_to_ascii(poly_array, ctx); poly_delete_array(poly_array); diff --git a/src/decrypt.h b/src/decrypt.h index 5e1f15b..48b665b 100644 --- a/src/decrypt.h +++ b/src/decrypt.h @@ -65,7 +65,7 @@ ntru_decrypt_poly( * @param priv_key_inv the inverse polynome to the private key * @param ctx the ntru_context */ -char * +string * ntru_decrypt_string( string *encr_msg, fmpz_poly_t priv_key, diff --git a/src/encrypt.c b/src/encrypt.c index 3fdb1b8..413ff31 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -69,14 +69,14 @@ ntru_encrypt_string( string *enc_msg; fmpz_poly_t **poly_array; - poly_array = ascii_to_tern_poly(msg, ctx); + poly_array = ascii_to_tern_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_to_ascii(poly_array, ctx); + enc_msg = poly_arr_to_ascii(poly_array, ctx); poly_delete_array(poly_array);