post quantum cryptography
Highly optimized implementation of the NTRUEncrypt algorithm
|
00001 /* 00002 * Copyright (C) 2014 FH Bielefeld 00003 * 00004 * This file is part of a FH Bielefeld project. 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00019 * MA 02110-1301 USA 00020 */ 00021 00029 #include "ntru_ascii_poly.h" 00030 #include "ntru_common.h" 00031 #include "ntru_mem.h" 00032 #include "ntru_params.h" 00033 #include "ntru_poly.h" 00034 #include "ntru_string.h" 00035 00036 #include <glib.h> 00037 00038 #include <stdint.h> 00039 #include <stdlib.h> 00040 #include <string.h> 00041 00042 #include <fmpz_poly.h> 00043 #include <fmpz.h> 00044 00045 00055 static char * 00056 get_int_to_bin_str(uint8_t value); 00057 00058 00059 /*------------------------------------------------------------------------*/ 00060 00061 static char * 00062 get_int_to_bin_str(uint8_t value) 00063 { 00064 int i; 00065 const size_t bin_string_size = ASCII_BITS + 1; 00066 char *bin_string = ntru_malloc(sizeof(*bin_string) * 00067 (bin_string_size)); /* account for trailing null-byte */ 00068 00069 /* terminate properly */ 00070 bin_string[bin_string_size - 1] = '\0'; 00071 00072 for (i = ASCII_BITS - 1; i >= 0; --i, value >>= 1) 00073 bin_string[i] = (value & 1) + '0'; 00074 00075 return bin_string; 00076 } 00077 00078 /*------------------------------------------------------------------------*/ 00079 00080 fmpz_poly_t * 00081 ascii_bin_to_bin_poly(const char *to_poly, const ntru_params *params) 00082 { 00083 uint32_t i = 0; 00084 fmpz_poly_t *new_poly = ntru_malloc(sizeof(*new_poly)); 00085 00086 fmpz_poly_init(*new_poly); 00087 00088 while (to_poly[i] && i < params->N) { 00089 fmpz_poly_set_coeff_si(*new_poly, 00090 i, 00091 (to_poly[i] == '0') ? -1 : 1); 00092 i++; 00093 } 00094 00095 return new_poly; 00096 } 00097 00098 /*------------------------------------------------------------------------*/ 00099 00100 fmpz_poly_t ** 00101 ascii_to_bin_poly_arr(const string *to_poly, const ntru_params *params) 00102 { 00103 char *cur = to_poly->ptr; 00104 char *out = ntru_malloc(CHAR_SIZE * (to_poly->len * ASCII_BITS + 1)); 00105 uint32_t polyc = 0; 00106 size_t out_len = 0; 00107 fmpz_poly_t **poly_array; 00108 00109 for (uint32_t i = 0; i < to_poly->len; i++) { 00110 char *tmp_string = get_int_to_bin_str((int)(*cur)); 00111 memcpy(out + out_len, tmp_string, ASCII_BITS); 00112 out_len += ASCII_BITS; 00113 cur++; 00114 free(tmp_string); 00115 } 00116 out[out_len] = '\0'; 00117 00118 poly_array = ntru_malloc(sizeof(**poly_array) * 00119 (strlen(out) / params->N + 1)); 00120 00121 for (uint32_t i = 0; i < out_len; i += params->N) { 00122 char chunk[params->N + 1]; 00123 size_t real_chunk_size; 00124 00125 real_chunk_size = 00126 (out_len - i > params->N) ? params->N : out_len - i; 00127 00128 memcpy(chunk, out + i, real_chunk_size); 00129 chunk[real_chunk_size] = '\0'; 00130 00131 poly_array[polyc] = ascii_bin_to_bin_poly(chunk, params); 00132 00133 polyc++; 00134 } 00135 00136 free(out); 00137 00138 poly_array[polyc] = NULL; 00139 00140 return poly_array; 00141 } 00142 00143 /*------------------------------------------------------------------------*/ 00144 00145 fmpz_poly_t ** 00146 base64_to_poly_arr(const string *to_poly, const ntru_params *params) 00147 { 00148 uint32_t i = 0, 00149 polyc = 0; 00150 gsize out_len; 00151 guchar *base64_decoded = NULL, 00152 *base_tmp = NULL; 00153 string *new_string = ntru_malloc(sizeof(*new_string)); 00154 fmpz_poly_t **poly_array; 00155 char *tmp = ntru_malloc(sizeof(char) * (to_poly->len + 1)); 00156 00157 /* g_base64_decode() needs it null-terminated */ 00158 memcpy(tmp, to_poly->ptr, to_poly->len); 00159 tmp[to_poly->len] = '\0'; 00160 00161 base_tmp = g_base64_decode((const gchar *)tmp, &out_len); 00162 00163 /* g_base64_decode() needs it null-terminated */ 00164 REALLOC(tmp, sizeof(char) * (out_len + 1)); 00165 memcpy(tmp, base_tmp, out_len); 00166 tmp[out_len] = '\0'; 00167 00168 base64_decoded = g_base64_decode((const gchar *)tmp, &out_len); 00169 00170 new_string->ptr = (char *)base64_decoded; 00171 new_string->len = (unsigned long)(out_len); 00172 00173 poly_array = ntru_malloc(sizeof(**poly_array) * 00174 (new_string->len / params->N)); 00175 00176 while (i < new_string->len) { 00177 uint32_t j = 0; 00178 fmpz_poly_t *new_poly = ntru_malloc(sizeof(*new_poly)); 00179 00180 fmpz_poly_init(*new_poly); 00181 00182 while (j < params->N) { 00183 fmpz_poly_set_coeff_si(*new_poly, 00184 j, 00185 (uint8_t)(base64_decoded[i])); 00186 j++; 00187 i++; 00188 } 00189 00190 /* fill the last poly with q (which is a non-standard 00191 * coefficient) */ 00192 for (uint32_t k = j; k < params->N; k++) { 00193 fmpz_poly_set_coeff_si(*new_poly, 00194 k, 00195 params->q); 00196 } 00197 00198 poly_array[polyc] = new_poly; 00199 polyc++; 00200 } 00201 00202 poly_array[polyc] = NULL; 00203 00204 string_delete(new_string); 00205 free(base_tmp); 00206 free(tmp); 00207 00208 return poly_array; 00209 }