diff --git a/src/ascii_poly.c b/src/ascii_poly.c new file mode 100644 index 0000000..105311a --- /dev/null +++ b/src/ascii_poly.c @@ -0,0 +1,125 @@ +/* + * 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 "context.h" +#include "err.h" +#include "mem.h" +#include "poly.h" +#include "ascii_poly.h" + +#include +#include +#include +#include +#include +#include +#include + +#define ASCII_DIGITS 7 + +/** + * Converts a string into a pb_poly of the size strlen(to_poly) * 7. + * 7 bit per ASCII symbol. + * + * @param to_poly the string + * @return the newly allocated polynom. + */ +pb_poly *ascii_to_poly(char *to_poly) +{ + size_t length = (strlen(to_poly) * ASCII_DIGITS); + char *tmp_ptr = to_poly; + u_int8_t binary_Number[ASCII_DIGITS + 1]; + + if (!to_poly) { + return NULL; + } + + mp_int chara; + init_integer(&chara); + + 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; +} + +/** + * Converts a polynom into a newly allocated string. + * + * @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 + */ +char *polynom_to_ascii(pb_poly *to_ascii) +{ + if (!to_ascii) { + return NULL; + } + + 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; + + /* 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; + } + /* 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; + } + /* char into string */ + *tmp_ptr++ = (char) ascii_value; + /* reset for next char */ + ascii_value = 0; + } + return string; +} diff --git a/src/ascii_poly.h b/src/ascii_poly.h new file mode 100644 index 0000000..ee8b9d2 --- /dev/null +++ b/src/ascii_poly.h @@ -0,0 +1,28 @@ +/* + * 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 ASCII_POLY_H_ +#define ASCII_POLY_H_ + +pb_poly *ascii_to_poly(char *to_poly); +char *polynom_to_ascii(pb_poly *to_ascii); + +#endif /* ASCII_POLY_H_ */ diff --git a/src/poly.c b/src/poly.c index 5a152a5..e435abe 100644 --- a/src/poly.c +++ b/src/poly.c @@ -42,7 +42,7 @@ static void pb_mod2_to_modq(pb_poly * const a, /** * Initialize a mp_int and check if this was successful, the - * caller must free new_int with mp_clear(). + * caller must free new_int. * * @param new_int a pointer to the mp_int you want to initialize */ diff --git a/src/poly.h b/src/poly.h index 6f675c6..acfb35d 100644 --- a/src/poly.h +++ b/src/poly.h @@ -214,5 +214,4 @@ bool pb_inverse_poly_p(pb_poly *a, void draw_polynom(pb_poly * const poly); - #endif /* NTRU_POLY_H */ diff --git a/src/rand.c b/src/rand.c index c33bfa7..5d4d430 100644 --- a/src/rand.c +++ b/src/rand.c @@ -21,11 +21,15 @@ #include "context.h" #include "err.h" +#include #include "rand.h" +#include #include "poly.h" #include #include +#include +#include #include #include #include @@ -36,31 +40,73 @@ /* * static declarations */ -static unsigned long get_urnd_int_small(int *sign); - +static mp_digit get_int_dev_random(void); +static mp_digit get_int_dev_urandom(void); +static mp_digit get_random_ternary(mp_digit random_int, int* sign); +static mp_int *get_random_bigint(mp_int *upper_bound, mp_int *lower_bound, + int entropy_source); +static unsigned int check_allowed_zeros(pb_poly *polynom); /** - * Gets randomly a small integer - * from the set {-1, 0, 1} using /dev/urandom. - * - * @param sign stores the signness [out] - * @return random small integer + * Reads a single mp_digit out of /dev/random and returns this mp_digit + * + * @return the randomly chosen integer */ -static unsigned long get_urnd_int_small(int *sign) +static mp_digit get_int_dev_random(void) +{ + int random_data; + mp_digit random_int; + size_t random_DataLen = 0; + random_data = open("/dev/random", O_RDONLY); + + while (random_DataLen < sizeof(random_int)) { + ssize_t result = read(random_data, + ((char*) &random_int) + random_DataLen, + (sizeof(random_int)) - random_DataLen); + if (result < 0) { + NTRU_ABORT("Unable to read /dev/random.\n"); + } + random_DataLen += result; + } + close(random_data); + return random_int; +} + +/** + * Reads a single mp_digit out of /dev/urandom and returns this mp_digit + * + * @return the randomly chosen integer + */ +static mp_digit get_int_dev_urandom(void) { int random_data; mp_digit random_int; ssize_t result; + random_data = open("/dev/urandom", O_RDONLY); random_data = open("/dev/urandom", O_RDONLY); if ((result = read(random_data, &random_int, sizeof(random_int))) < 0) - NTRU_ABORT("Unable to read /dev/urandom"); + NTRU_ABORT("Unable to read /dev/urandom.\n"); close(random_data); + return random_int; +} - if ((random_int % 2) == 0) { - random_int = 0; +/** + * Makes a small integer from the set {-1, 0, 1} + * out of a randomly chosen integer. + * A zero is signed positiv. + * + * @param random_int a randomly chosen mp_digit + * @param sign an integer to store the sign (1==positiv) [out] + * @return random small integer from the set {-1, 0, 1} + */ +static mp_digit get_random_ternary(mp_digit random_int, int* sign) +{ + random_int = random_int % 3; + + if (random_int == 1) { *sign = 0; - } else if (random_int % 3) { + } else if (random_int == 2) { random_int = 1; *sign = 1; } else { @@ -72,32 +118,89 @@ static unsigned long get_urnd_int_small(int *sign) } /** - * Gets a random polynomial with coefficients - * from the set {-1 ,0 ,1} using /dev/urandom. + * Makes a big integer from the borders of upper_bound + * and lower_bound out of a randomly chosen integer. * - * @param ctx the NTRU context + * @param upper_bound the maximal upper border of the resulting mp_int [out] + * @param lower_bound the minimal lower border of the resulting mp_int [out] + * entropy_source random_int TODO + * @return a mp_int with the random number + */ +static mp_int *get_random_bigint(mp_int *upper_bound, mp_int *lower_bound, + int entropy_source) +{ + mp_int result; + init_integer(&result); + + //TODO + + return result; +} + +/** + * Checks if the coefficients of a polynom are less than + * PERCENTAGE_OF_ZERO_ALLOWED zero + * + * @param polynom a pointer to the polynom you want to test [out] + * @return 0 if the polynom zero coefficients are under + * PERCENTAGE_OF_ZERO_ALLOWED percent + * -1 if the polynom zero coefficients are over + * PERCENTAGE_OF_ZERO_ALLOWED percent + */ +static unsigned int check_allowed_zeros(pb_poly *polynom) +{ + unsigned int result = -1; + //TODO + return result; +} + +/** + * Gets a random polynomial with coefficients + * from the set {-1 ,0 ,1} using the given entropy source + * + * @param length the amount of coefficients + * @param entropy_source the source of entropy you want * @return newly allocated polynomial, must be freed with delete_polynom() */ -pb_poly *ntru_get_urnd_poly_small(ntru_context *ctx) +pb_poly *ntru_get_random_poly_ternary(size_t length, int entropy_source) { mp_int chara; init_integer(&chara); + + mp_digit coefficient; pb_poly *poly = malloc(sizeof(pb_poly)); - init_polynom_size(poly, &chara, ctx->N); + + init_polynom_size(poly, &chara, length); mp_clear(&chara); - for (unsigned int i = 0; i < ctx->N; i++) { + for (unsigned int i = 0; i < length; i++) { int sign; - unsigned long c = get_urnd_int_small(&sign); - - mp_set_int(&(poly->terms[i]), c); - + if (entropy_source == GET_INT_FROM_RRAND) { + coefficient = get_int_dev_random(); + } else if (entropy_source == GET_INT_FROM_URAND) { + coefficient = get_int_dev_urandom(); + } else { + NTRU_ABORT("No suitable entropy source selectetd.\n"); + } + coefficient = get_random_ternary(coefficient, &sign); + mp_set(&(poly->terms[i]), coefficient); if (sign == 1) poly->terms[i].sign = 1; } - poly->used = ctx->N; - pb_clamp(poly); - + poly->used = length; return poly; } +/** + * Gets a random polynomial with coefficients + * from the the borders of lower_bound to upper_bound using the given entropy source + * + * @param length the amount of coefficients + * @param entropy_source the source of entropy you want + * @return newly allocated polynomial, must be freed with delete_polynom() + */ +pb_poly *ntru_get_random_poly(int length, int entropy_source, mp_int *upper_bound, + mp_int *lower_bound) +{ + //TODO +} diff --git a/src/rand.h b/src/rand.h index adafdf8..b4b073f 100644 --- a/src/rand.h +++ b/src/rand.h @@ -19,7 +19,6 @@ * MA 02110-1301 USA */ - #ifndef NTRU_RAND_H #define NTRU_RAND_H @@ -27,7 +26,18 @@ #include +/** + * Use the /dev/urandom device as entropy source. + */ +#define GET_INT_FROM_URAND 2 -pb_poly *ntru_get_urnd_poly_small(ntru_context *ctx); +/** + * Use the /dev/random device as entropy source. + */ +#define GET_INT_FROM_RRAND 3 + +pb_poly *ntru_get_random_poly_ternary(int length, int entropy_source); +pb_poly *ntru_get_random_poly(size_t length, int entropy_source, mp_int *upper_bound, + mp_int *lower_bound); #endif /* NTRU_RAND_H */