From e4b6ca84e5defabd196d12b99a614a89d890f2ee Mon Sep 17 00:00:00 2001 From: hasufell Date: Mon, 9 Jun 2014 22:11:07 +0200 Subject: [PATCH] ENC/DEC: implement compression via lz4 This speeds up encryption/decryption considerably, but also causes complete failure for any non-recoverable char in a message, since the decompression will fail then. Also remove the double base64 encode/decode. --- README.md | 1 + include/doxygen.dox | 1 + src/Makefile | 2 +- src/doxygen.dox | 1 + src/ntru_ascii_poly.c | 11 +-------- src/ntru_decrypt.c | 53 +++++++++++++++++++++++++++++++++++++++++-- src/ntru_encrypt.c | 46 ++++++++++++++++++++++++++++++++++++- src/ntru_poly_ascii.c | 17 ++++---------- 8 files changed, 106 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index c3f2457..f99231c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ implementation with the primary goal of learning. * FLINT (compiled with gmp and mpfr) * glib-2.0 +* lz4 (https://code.google.com/p/lz4) * pkgconfig (for the build only) ### Compiling the library diff --git a/include/doxygen.dox b/include/doxygen.dox index 0483ef7..3ec468c 100644 --- a/include/doxygen.dox +++ b/include/doxygen.dox @@ -31,6 +31,7 @@ Further work is based on FLINT-2.4.3 or later (compiled with gmp and mpfr) \* glib-2.0 + \* lz4 \* pkg-config (for the build only) \section install_sec Installation diff --git a/src/Makefile b/src/Makefile index 127dbd1..d30ee32 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,7 +34,7 @@ PQC_HEADERS = \ # libs -LIBS += -L. -lgmp -lmpfr -lflint $(shell $(PKG_CONFIG) --libs glib-2.0) -lm +LIBS += -L. -llz4 -lgmp -lmpfr -lflint $(shell $(PKG_CONFIG) --libs glib-2.0) -lm # includes INCS = -I. -I/usr/include/flint $(shell $(PKG_CONFIG) --cflags glib-2.0) diff --git a/src/doxygen.dox b/src/doxygen.dox index 986e439..9173bf9 100644 --- a/src/doxygen.dox +++ b/src/doxygen.dox @@ -21,6 +21,7 @@ Further work is based on FLINT-2.4.3 or later (compiled with gmp and mpfr) \* glib-2.0 + \* lz4 \* pkg-config (for the build only) \section install_sec Installation diff --git a/src/ntru_ascii_poly.c b/src/ntru_ascii_poly.c index 2ac66a6..acb3f1c 100644 --- a/src/ntru_ascii_poly.c +++ b/src/ntru_ascii_poly.c @@ -146,8 +146,7 @@ base64_to_poly_arr(const string *to_poly, const ntru_params *params) uint32_t i = 0, polyc = 0; gsize out_len; - guchar *base64_decoded = NULL, - *base_tmp = NULL; + guchar *base64_decoded = NULL; string *new_string = ntru_malloc(sizeof(*new_string)); fmpz_poly_t **poly_array; char *tmp = ntru_malloc(sizeof(char) * (to_poly->len + 1)); @@ -156,13 +155,6 @@ base64_to_poly_arr(const string *to_poly, const ntru_params *params) memcpy(tmp, to_poly->ptr, to_poly->len); tmp[to_poly->len] = '\0'; - base_tmp = g_base64_decode((const gchar *)tmp, &out_len); - - /* g_base64_decode() needs it null-terminated */ - REALLOC(tmp, sizeof(char) * (out_len + 1)); - memcpy(tmp, base_tmp, out_len); - tmp[out_len] = '\0'; - base64_decoded = g_base64_decode((const gchar *)tmp, &out_len); new_string->ptr = (char *)base64_decoded; @@ -200,7 +192,6 @@ base64_to_poly_arr(const string *to_poly, const ntru_params *params) poly_array[polyc] = NULL; string_delete(new_string); - free(base_tmp); free(tmp); return poly_array; diff --git a/src/ntru_decrypt.c b/src/ntru_decrypt.c index aedd3c5..ced90d8 100644 --- a/src/ntru_decrypt.c +++ b/src/ntru_decrypt.c @@ -28,11 +28,13 @@ #include "ntru_ascii_poly.h" #include "ntru_decrypt.h" +#include "ntru_mem.h" #include "ntru_params.h" #include "ntru_poly.h" #include "ntru_poly_ascii.h" #include "ntru_string.h" +#include #include #include @@ -40,6 +42,49 @@ #include +/** + * Decompress a string and return it, newly allocated. + * + * @param compr_str the compressed string to decompress + * @return the decompressed string, newly allocated + */ +static string * +get_decompressed_str(const string *compr_str); + + +/*------------------------------------------------------------------------*/ + +static string * +get_decompressed_str(const string *compr_str) +{ + int out_len = 0; + const uint32_t max_lz4_ratio = 3; + uint32_t max_out_len = 0; + string *decompressed_msg = NULL; + + if (!compr_str) + NTRU_ABORT_DEBUG("Unexpected NULL parameters"); + + max_out_len = compr_str->len * max_lz4_ratio; + decompressed_msg = ntru_malloc(sizeof(string)); + decompressed_msg->ptr = ntru_malloc( + /* this is more than needed, but safe */ + sizeof(char) * max_out_len); + + out_len = LZ4_decompress_safe( + (const char *)compr_str->ptr, + decompressed_msg->ptr, + compr_str->len, + max_out_len); + + if (out_len > 0) + decompressed_msg->len = out_len; + else + NTRU_ABORT_DEBUG("Failed decompressing the message"); + + return decompressed_msg; +} + /*------------------------------------------------------------------------*/ void @@ -98,6 +143,7 @@ ntru_decrypt_string( uint32_t i = 0; string *decr_msg; fmpz_poly_t **poly_array; + string *decompressed_msg = NULL; if (!encr_msg || !encr_msg->len) NTRU_ABORT_DEBUG("Unexpected NULL parameters"); @@ -116,9 +162,12 @@ ntru_decrypt_string( decr_msg = bin_poly_arr_to_ascii((const fmpz_poly_t **)poly_array, i, params); - poly_delete_array(poly_array); + decompressed_msg = get_decompressed_str(decr_msg); - return decr_msg; + poly_delete_array(poly_array); + string_delete(decr_msg); + + return decompressed_msg; } /*------------------------------------------------------------------------*/ diff --git a/src/ntru_encrypt.c b/src/ntru_encrypt.c index ca7f398..172c366 100644 --- a/src/ntru_encrypt.c +++ b/src/ntru_encrypt.c @@ -34,12 +34,52 @@ #include "ntru_poly_ascii.h" #include "ntru_string.h" +#include #include #include #include +/** + * Compress a string and return it, newly allocated. + * + * @param str the string to compress + * @return the compressed string, newly allocated + */ +static string * +get_compressed_str(const string *str); + + +/*------------------------------------------------------------------------*/ + +static string * +get_compressed_str(const string *str) +{ + int out_len = 0; + string *compressed_str; + uint32_t max_output_size; + + if (!str) + NTRU_ABORT_DEBUG("Unexpected NULL parameters"); + + max_output_size = str->len; + compressed_str = ntru_malloc(sizeof(string)); + compressed_str->ptr = ntru_malloc( + sizeof(char) * max_output_size); + out_len = LZ4_compress( + (const char*) str->ptr, + compressed_str->ptr, + str->len); + + if (out_len > 0) + compressed_str->len = out_len; + else + NTRU_ABORT_DEBUG("Failed compressing the message"); + + return compressed_str; +} + /*------------------------------------------------------------------------*/ void @@ -80,11 +120,14 @@ ntru_encrypt_string( uint32_t i = 0; string *enc_msg; fmpz_poly_t **poly_array; + string *compressed_msg; if (!msg || !msg->len) NTRU_ABORT_DEBUG("Unexpected NULL parameters"); - poly_array = ascii_to_bin_poly_arr(msg, params); + compressed_msg = get_compressed_str(msg); + + poly_array = ascii_to_bin_poly_arr(compressed_msg, params); while (*poly_array[i]) { ntru_encrypt_poly(*poly_array[i], @@ -99,6 +142,7 @@ ntru_encrypt_string( i, params); poly_delete_array(poly_array); + string_delete(compressed_msg); return enc_msg; } diff --git a/src/ntru_poly_ascii.c b/src/ntru_poly_ascii.c index 6300967..6caa8ea 100644 --- a/src/ntru_poly_ascii.c +++ b/src/ntru_poly_ascii.c @@ -239,21 +239,17 @@ poly_to_base64(const fmpz_poly_t poly, { string *result_string = ntru_malloc(sizeof(*result_string)); string *string_rep = NULL; - gchar *base64_string = NULL, - *tmp = NULL; + gchar *base64_string = NULL; string_rep = poly_to_ascii(poly, params); - tmp = g_base64_encode((const guchar *)string_rep->ptr, + base64_string = g_base64_encode((const guchar *)string_rep->ptr, string_rep->len); - base64_string = g_base64_encode((const guchar *)tmp, - strlen(tmp)); result_string->ptr = base64_string; result_string->len = strlen(base64_string); string_delete(string_rep); - free(tmp); return result_string; } @@ -268,20 +264,17 @@ poly_arr_to_base64(const fmpz_poly_t **poly_array, string *string_rep; string *result_string = ntru_malloc(sizeof(*result_string)); - gchar *base64_string = NULL, - *tmp = NULL; + gchar *base64_string = NULL; string_rep = poly_arr_to_ascii(poly_array, poly_c, params); - tmp = g_base64_encode((const guchar *)string_rep->ptr, string_rep->len); - base64_string = g_base64_encode((const guchar *)tmp, - strlen(tmp)); + base64_string = g_base64_encode((const guchar *)string_rep->ptr, + string_rep->len); result_string->ptr = base64_string; result_string->len = strlen(base64_string); string_delete(string_rep); - free(tmp); return result_string; }