ASCII->POLY: refactor

Use base64 (via glib) instead of plain char cast.

Remove ascii_to_poly() since it's unreliable (we don't
really know how many polynomials we will need
for a string).
This commit is contained in:
hasufell 2014-05-28 01:09:52 +02:00
parent 8b9134628c
commit 9f6b7319bb
No known key found for this signature in database
GPG Key ID: 220CD1C5BDEED020
5 changed files with 151 additions and 169 deletions

View File

@ -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

View File

@ -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 <glib.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@ -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;

View File

@ -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_ */

View File

@ -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);

View File

@ -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);