diff --git a/src/Makefile b/src/Makefile index ce3136b..b07ff04 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,8 +37,8 @@ endif LIBS += -L. -lgmp -lmpfr -lm # objects -PQC_OBJS = poly.o mem.o encrypt.o decrypt.o keypair.o -PQC_HEADERS = err.h poly.h context.h encrypt.h decrypt.h keypair.h +PQC_OBJS = poly.o mem.o encrypt.o decrypt.o keypair.o ascii_poly.o +PQC_HEADERS = err.h poly.h context.h encrypt.h decrypt.h keypair.h ascii_poly.h common.h # CUNIT_OBJS = cunit.o # includes diff --git a/src/ascii_poly.c b/src/ascii_poly.c index 105311a..33a129f 100644 --- a/src/ascii_poly.c +++ b/src/ascii_poly.c @@ -19,107 +19,193 @@ * MA 02110-1301 USA */ +/** + * @file ascii_poly.c + * This file allows to convert between ascii strings + * and polynomials. + * @brief asci->poly and poly->ascii + */ + +#include "common.h" #include "context.h" -#include "err.h" #include "mem.h" #include "poly.h" #include "ascii_poly.h" -#include -#include +#include #include #include -#include -#include -#include -#define ASCII_DIGITS 7 +#include +#include + + +/* + * static function declaration + */ +static char *get_int_to_bin_str(uint8_t value); +static char *get_bin_arr_to_ascii(char *binary_rep); + /** - * Converts a string into a pb_poly of the size strlen(to_poly) * 7. - * 7 bit per ASCII symbol. + * Convert an integer to it's binary representation + * as a string and return it. * - * @param to_poly the string - * @return the newly allocated polynom. + * @param value the integer to convert + * @return the binary representation as a newly allocated string */ -pb_poly *ascii_to_poly(char *to_poly) +static char *get_int_to_bin_str(uint8_t value) { - size_t length = (strlen(to_poly) * ASCII_DIGITS); - char *tmp_ptr = to_poly; - u_int8_t binary_Number[ASCII_DIGITS + 1]; + int i; + const size_t bin_string_size = ASCII_BITS + 1; + char *bin_string = ntru_malloc(sizeof(*bin_string) * + (bin_string_size)); /* account for trailing null-byte */ - if (!to_poly) { - return NULL; - } + /* terminate properly */ + bin_string[bin_string_size - 1] = '\0'; - mp_int chara; - init_integer(&chara); + for (i = ASCII_BITS - 1; i >= 0; --i, value >>= 1) + bin_string[i] = (value & 1) + '0'; - pb_poly *poly = ntru_malloc(sizeof(pb_poly)); - init_polynom_size(poly, &chara, length); - - /* for every char */ - for (u_int32_t j = 0; j < strlen(to_poly); j++) { - u_int8_t quotient = (u_int8_t) *tmp_ptr++; - u_int8_t k = ASCII_DIGITS; - for (u_int8_t i = 1; i <= ASCII_DIGITS; i++) { - /* gets the least significant bit in an array*/ - binary_Number[k--] = quotient % 2; - /* bitshift so the next bit becomes the lsb*/ - quotient >>= 1; - } - for (u_int8_t i = 1; i <= ASCII_DIGITS; i++) { - /* the actual position of the bit in the polynom */ - u_int32_t coefficient = (i - 1) + (j * ASCII_DIGITS); - MP_SET(&(poly->terms[coefficient]), binary_Number[i]); - /* set the array to 0 so the next run is garbage free */ - binary_Number[i] = 0; - poly->terms[i].sign = 0; - } - } - poly->used = (int) length; - mp_clear(&chara); - return poly; + return bin_string; } /** - * Converts a polynom into a newly allocated string. + * Converts a binary representation of multiple concatenated + * integers to the corresponding array of ascii chars, which + * is NULL-terminated. * - * @param to_ascii the polynom you want to make a string of. - * @return a pointer to the string ore a NULL pointer in the error case + * @param binary_rep the binary representation of multiple + * integers concatenated + * @return NULL-terminated array of corresponding ascii-chars, + * newly allocated */ -char *polynom_to_ascii(pb_poly *to_ascii) +static char *get_bin_arr_to_ascii(char *binary_rep) { - if (!to_ascii) { - return NULL; + const size_t int_arr_size = strlen(binary_rep) / 8; + uint8_t int_arr[int_arr_size]; + char *tmp_string = binary_rep; + uint32_t i = 0; + + char *int_string; + + while (*tmp_string) { + int_arr[i] = 0; + for (uint32_t j = 0; j < ASCII_BITS; j++) { + if (*tmp_string == '1') + int_arr[i] = int_arr[i] * 2 + 1; + else if (*tmp_string == '0') + int_arr[i] *= 2; + tmp_string++; + } + i++; } - size_t length_poly = (size_t) to_ascii->used; - size_t length_string = (size_t) (length_poly / ASCII_DIGITS); - char *string = (char*) ntru_malloc(length_string); - char bit_buffer; - char *tmp_ptr = string; - u_int8_t ascii_value = 0; + int_string = ntru_calloc(1, CHAR_SIZE * (i + 1)); - /* every char */ - for (u_int32_t i = 0; i < length_poly; i += ASCII_DIGITS) { - /* every bit*/ - for (u_int32_t j = 0; j < ASCII_DIGITS; j++) { - /* get the bit */ - if (mp_toradix(&(to_ascii->terms[i + j]), &bit_buffer, 2)) { - return NULL; + for (uint32_t j = 0; j < i; j++) + int_string[j] = (char) int_arr[j]; + + return int_string; +} + +/** + * Convert an ascii string to an array of polyomials. + * + * @param to_poly the string to get into polynomial format + * @param ctx the NTRUEncrypt context + * @return newly allocated array of polynomials + */ +fmpz_poly_t **ascii_to_poly(char *to_poly, ntru_context *ctx) +{ + uint32_t i = 0, + polyc = 0; + char *cur = to_poly; + size_t out_size = CHAR_SIZE * (strlen(to_poly) * 8 + 1); + char *out = ntru_malloc(out_size); + fmpz_poly_t **poly_array; + + *out = '\0'; + + while (*cur) { + char *tmp_string = get_int_to_bin_str((int)(*cur)); + strcat(out, tmp_string); + cur++; + free(tmp_string); + } + + 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)); + fmpz_poly_init(*new_poly); + poly_array[polyc] = new_poly; + + while (out[i] && j < ctx->N) { + fmpz_poly_set_coeff_si(*new_poly, + j, + (out[i] == '0') ? -1 : 1); + i++; + j++; + } + polyc++; + } + + free(out); + + poly_array[polyc] = NULL; + + return poly_array; +} + +/** + * Convert an array of polynomials back to a real string. + * + * @param poly_array the array of polynomials + * @param ctx the NTRUEncrypt context + * @return the real string + */ +char *poly_to_ascii(fmpz_poly_t **poly_array, ntru_context *ctx) +{ + fmpz_poly_t *ascii_poly; + char *binary_rep = NULL; + char *ascii_string; + uint32_t i = 0; + size_t old_length = 0, + new_length; + + /* + * parse the polynomial coefficients into a string + */ + binary_rep = ntru_malloc(CHAR_SIZE * (ctx->N + 1)); + while ((ascii_poly = *poly_array++)) { + new_length = CHAR_SIZE * (ctx->N + 1); + + REALLOC(binary_rep, + old_length + + new_length + + 1); /* trailing null byte */ + + 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'; } - /* bit as integer */ - u_int8_t bit = atoi(&bit_buffer); - /* bitshift to the left */ - ascii_value <<= 1; - /* set the new bit and keep the other */ - ascii_value |= bit; + i++; } - /* char into string */ - *tmp_ptr++ = (char) ascii_value; - /* reset for next char */ - ascii_value = 0; } - return string; + + binary_rep[i] = '\0'; + + ascii_string = get_bin_arr_to_ascii(binary_rep); + free(binary_rep); + + return ascii_string; } diff --git a/src/ascii_poly.h b/src/ascii_poly.h index ee8b9d2..59c32f3 100644 --- a/src/ascii_poly.h +++ b/src/ascii_poly.h @@ -19,10 +19,24 @@ * MA 02110-1301 USA */ -#ifndef ASCII_POLY_H_ -#define ASCII_POLY_H_ +/** + * @file ascii_poly.h + * Header for the internal API of ascii_poly.c. + * @brief header for ascii_poly.c + */ -pb_poly *ascii_to_poly(char *to_poly); -char *polynom_to_ascii(pb_poly *to_ascii); +#ifndef NTRU_ASCII_POLY_H_ +#define NTRU_ASCII_POLY_H_ -#endif /* ASCII_POLY_H_ */ + +#include "context.h" + +#include +#include + + +fmpz_poly_t **ascii_to_poly(char *to_poly, ntru_context *ctx); +char *poly_to_ascii(fmpz_poly_t **poly_array, ntru_context *ctx); + + +#endif /* NTRU_ASCII_POLY_H_ */ diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..d8dc4d0 --- /dev/null +++ b/src/common.h @@ -0,0 +1,38 @@ +/* + * 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 + */ + +/** + * @file common.h + * This file holds common macros and functions + * shared throughout the whole codebase without + * any particular purpose. + * @brief common macros/functions + */ + +#ifndef NTRU_COMMON_H +#define NTRU_COMMON_H + + +#define CHAR_SIZE sizeof(char) +#define ASCII_BITS 8 + + +#endif /* NTRU_COMMON_H */ diff --git a/src/mem.c b/src/mem.c index 49429cc..f17fa61 100644 --- a/src/mem.c +++ b/src/mem.c @@ -53,3 +53,26 @@ void *ntru_malloc(size_t size) return ptr; } + +/** + * Allocate memory of size and return + * a void pointer. The memory is zeroed. + * + * @param nmemb amount of blocks to allocate + * @param size of the memory blocks to allocate in bytes + * @return void pointer to the beginning of the allocated memory block + */ +void *ntru_calloc(size_t nmemb, size_t size) +{ + void *ptr; + + ptr = calloc(nmemb, 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 index 8c0ca3c..42e9a50 100644 --- a/src/mem.h +++ b/src/mem.h @@ -30,6 +30,25 @@ #include + +/** + * Realloc macro which checks if reallocation + * worked via a temporary pointer. + */ +#define REALLOC(ptr, size) \ +{ \ + void *tmp_ptr = NULL; \ + tmp_ptr = realloc(ptr, size); \ + if (tmp_ptr == NULL) { \ + fprintf(stderr,"NULL Pointer in %s [%d]",__FILE__,__LINE__); \ + abort(); \ + } \ + ptr = tmp_ptr; \ +} + + void *ntru_malloc(size_t size); +void *ntru_calloc(size_t nmemb, size_t size); + #endif /* NTRU_MEM_H */ diff --git a/src/poly.c b/src/poly.c index dfe4da1..be9f522 100644 --- a/src/poly.c +++ b/src/poly.c @@ -35,7 +35,8 @@ #include #include #include -#include +#include +#include #include #include @@ -109,9 +110,7 @@ void poly_new(fmpz_poly_t new_poly, /** * This deletes the internal structure of a polynomial, - * and frees the pointer. Don't call this on stack variables, - * this is intended for use after ntru_ functions, that - * return a polynomial pointer. + * and frees the pointer. * * @param poly the polynomial to delete */ @@ -120,11 +119,29 @@ void poly_delete(fmpz_poly_t poly) fmpz_poly_clear(poly); } +/** + * Delete the internal structure of a polynomial + * array which must be NULL terminated. It is expected + * that poly_array is not on the stack and was obtained + * by a function like ascii_to_poly(). + * + * @param poly_array the polynomial array + */ +void poly_delete_array(fmpz_poly_t **poly_array) +{ + unsigned int i = 0; + + while(poly_array[i]) { + poly_delete(*(poly_array[i])); + free(*(poly_array[i])); + i++; + } + free(poly_array); +} + /** * 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. + * and frees the pointers. * You must call this with NULL as last argument! * * @param poly the polynomial to delete diff --git a/src/poly.h b/src/poly.h index 61667d1..50d3600 100644 --- a/src/poly.h +++ b/src/poly.h @@ -44,6 +44,8 @@ void poly_new(fmpz_poly_t new_poly, void poly_delete(fmpz_poly_t poly); +void poly_delete_array(fmpz_poly_t **poly_array); + void poly_delete_all(fmpz_poly_t poly, ...); void fmpz_poly_mod_unsigned(fmpz_poly_t a,