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_file.h" 00031 #include "ntru_keypair.h" 00032 #include "ntru_params.h" 00033 #include "ntru_poly.h" 00034 #include "ntru_poly_ascii.h" 00035 #include "ntru_string.h" 00036 00037 #include <fmpz_poly.h> 00038 #include <fmpz.h> 00039 00040 #include <stdbool.h> 00041 #include <string.h> 00042 00043 00044 /*------------------------------------------------------------------------*/ 00045 00046 bool 00047 ntru_create_keypair( 00048 fmpz_poly_t f, 00049 fmpz_poly_t g, 00050 keypair *pair, 00051 ntru_params *params) 00052 { 00053 bool retval = false; 00054 fmpz_poly_t Fq, 00055 Fp, 00056 pub; 00057 00058 if (!f || !g || !params) 00059 goto _return; 00060 00061 fmpz_poly_init(Fq); 00062 fmpz_poly_init(Fp); 00063 fmpz_poly_init(pub); 00064 00065 if (!poly_inverse_poly_q(f, Fq, params)) 00066 goto _cleanup; 00067 00068 if (!poly_inverse_poly_p(f, Fp, params)) 00069 goto _cleanup; 00070 00071 poly_starmultiply(Fq, g, pub, params, params->q); 00072 fmpz_poly_scalar_mul_ui(pub, pub, params->p); 00073 fmpz_poly_mod_unsigned(pub, params->q); 00074 00075 fmpz_poly_init(pair->priv); 00076 fmpz_poly_init(pair->priv_inv); 00077 fmpz_poly_init(pair->pub); 00078 00079 fmpz_poly_set(pair->priv, f); 00080 fmpz_poly_set(pair->priv_inv, Fp); 00081 fmpz_poly_set(pair->pub, pub); 00082 00083 retval = true; 00084 00085 _cleanup: 00086 fmpz_poly_clear(Fq); 00087 fmpz_poly_clear(Fp); 00088 fmpz_poly_clear(pub); 00089 _return: 00090 return retval; 00091 } 00092 00093 /*------------------------------------------------------------------------*/ 00094 00095 void 00096 export_public_key(char const * const filename, 00097 fmpz_poly_t pub, 00098 ntru_params *params) 00099 { 00100 string *pub_string; 00101 00102 pub_string = poly_to_base64(pub, params); 00103 write_file(pub_string, filename); 00104 00105 string_delete(pub_string); 00106 } 00107 00108 /*------------------------------------------------------------------------*/ 00109 00110 void 00111 export_priv_key(char const * const filename, 00112 fmpz_poly_t priv, 00113 ntru_params *params) 00114 { 00115 string *priv_string; 00116 fmpz_poly_t priv_u; 00117 00118 fmpz_poly_init(priv_u); 00119 fmpz_poly_set(priv_u, priv); 00120 fmpz_poly_mod_unsigned(priv_u, params->p); 00121 00122 priv_string = poly_to_base64(priv_u, params); 00123 write_file(priv_string, filename); 00124 00125 fmpz_poly_clear(priv_u); 00126 string_delete(priv_string); 00127 } 00128 00129 /*------------------------------------------------------------------------*/ 00130 00131 void 00132 import_public_key(char const * const filename, 00133 fmpz_poly_t pub, 00134 ntru_params *params) 00135 { 00136 string *pub_string; 00137 fmpz_poly_t **imported; 00138 00139 pub_string = read_file(filename); 00140 imported = base64_to_poly_arr(pub_string, params); 00141 00142 /* if the array exceeds one element, then something 00143 * went horribly wrong */ 00144 if (*imported[1]) 00145 NTRU_ABORT_DEBUG("Failed importing public key!"); 00146 00147 fmpz_poly_set(pub, **imported); 00148 00149 string_delete(pub_string); 00150 poly_delete_array(imported); 00151 free(imported); 00152 } 00153 00154 /*------------------------------------------------------------------------*/ 00155 00156 void 00157 import_priv_key(char const * const filename, 00158 fmpz_poly_t priv, 00159 fmpz_poly_t priv_inv, 00160 ntru_params *params) 00161 { 00162 string *pub_string; 00163 fmpz_poly_t **imported, 00164 Fp; 00165 00166 fmpz_poly_init(Fp); 00167 00168 pub_string = read_file(filename); 00169 00170 imported = base64_to_poly_arr(pub_string, params); 00171 fmpz_poly_mod(**imported, params->p); 00172 00173 /* if the array exceeds one element, then something 00174 * went horribly wrong */ 00175 if (*imported[1]) 00176 NTRU_ABORT_DEBUG("Failed importing private key!"); 00177 00178 fmpz_poly_set(priv, **imported); 00179 00180 if (!poly_inverse_poly_p(priv, Fp, params)) 00181 goto cleanup; 00182 00183 fmpz_poly_mod(Fp, params->p); 00184 00185 fmpz_poly_set(priv_inv, Fp); 00186 fmpz_poly_clear(Fp); 00187 00188 cleanup: 00189 string_delete(pub_string); 00190 poly_delete_array(imported); 00191 free(imported); 00192 } 00193 00194 /*------------------------------------------------------------------------*/ 00195 00196 void 00197 ntru_delete_keypair(keypair *pair) 00198 { 00199 fmpz_poly_clear(pair->priv_inv); 00200 fmpz_poly_clear(pair->priv); 00201 fmpz_poly_clear(pair->pub); 00202 } 00203 00204 /*------------------------------------------------------------------------*/