Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of wolfSSL by
ecc.c
00001 /* ecc.c 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 00024 #ifdef HAVE_CONFIG_H 00025 #include <config.h> 00026 #endif 00027 00028 /* in case user set HAVE_ECC there */ 00029 #include <wolfssl/wolfcrypt/settings.h> 00030 00031 /* 00032 Possible ECC enable options: 00033 * HAVE_ECC: Overall control of ECC default: on 00034 * HAVE_ECC_ENCRYPT: ECC encrypt/decrypt w/AES and HKDF default: off 00035 * HAVE_ECC_SIGN: ECC sign default: on 00036 * HAVE_ECC_VERIFY: ECC verify default: on 00037 * HAVE_ECC_DHE: ECC build shared secret default: on 00038 * HAVE_ECC_CDH: ECC cofactor DH shared secret default: off 00039 * HAVE_ECC_KEY_IMPORT: ECC Key import default: on 00040 * HAVE_ECC_KEY_EXPORT: ECC Key export default: on 00041 * ECC_SHAMIR: Enables Shamir calc method default: on 00042 * HAVE_COMP_KEY: Enables compressed key default: off 00043 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import default: off 00044 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen default: off 00045 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves. default: off 00046 * Includes the curve "a" variable in calculation 00047 * ECC_DUMP_OID: Enables dump of OID encoding and sum default: off 00048 * ECC_CACHE_CURVE: Enables cache of curve info to improve perofrmance 00049 default: off 00050 * FP_ECC: ECC Fixed Point Cache default: off 00051 * USE_ECC_B_PARAM: Enable ECC curve B param default: off 00052 (on for HAVE_COMP_KEY) 00053 */ 00054 00055 /* 00056 ECC Curve Types: 00057 * NO_ECC_SECP Disables SECP curves default: off (not defined) 00058 * HAVE_ECC_SECPR2 Enables SECP R2 curves default: off 00059 * HAVE_ECC_SECPR3 Enables SECP R3 curves default: off 00060 * HAVE_ECC_BRAINPOOL Enables Brainpool curves default: off 00061 * HAVE_ECC_KOBLITZ Enables Koblitz curves default: off 00062 */ 00063 00064 /* 00065 ECC Curve Sizes: 00066 * ECC_USER_CURVES: Allows custom combination of key sizes below 00067 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined) 00068 * HAVE_ECC112: 112 bit key 00069 * HAVE_ECC128: 128 bit key 00070 * HAVE_ECC160: 160 bit key 00071 * HAVE_ECC192: 192 bit key 00072 * HAVE_ECC224: 224 bit key 00073 * HAVE_ECC239: 239 bit key 00074 * NO_ECC256: Disables 256 bit key (on by default) 00075 * HAVE_ECC320: 320 bit key 00076 * HAVE_ECC384: 384 bit key 00077 * HAVE_ECC512: 512 bit key 00078 * HAVE_ECC521: 521 bit key 00079 */ 00080 00081 00082 #ifdef HAVE_ECC 00083 00084 /* Make sure custom curves is enabled for Brainpool or Koblitz curve types */ 00085 #if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\ 00086 !defined(WOLFSSL_CUSTOM_CURVES) 00087 #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES 00088 #endif 00089 00090 /* Make sure ASN is enabled for ECC sign/verify */ 00091 #if (defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)) && defined(NO_ASN) 00092 #error ASN must be enabled for ECC sign/verify 00093 #endif 00094 00095 00096 #include <wolfssl/wolfcrypt/ecc.h> 00097 #include <wolfssl/wolfcrypt/asn.h> 00098 #include <wolfssl/wolfcrypt/error-crypt.h> 00099 #include <wolfssl/wolfcrypt/logging.h> 00100 00101 #ifdef HAVE_ECC_ENCRYPT 00102 #include <wolfssl/wolfcrypt/hmac.h> 00103 #include <wolfssl/wolfcrypt/aes.h> 00104 #endif 00105 00106 #ifdef HAVE_X963_KDF 00107 #include <wolfssl/wolfcrypt/hash.h> 00108 #endif 00109 00110 #ifdef NO_INLINE 00111 #include <wolfssl/wolfcrypt/misc.h> 00112 #else 00113 #define WOLFSSL_MISC_INCLUDED 00114 #include <wolfcrypt/src/misc.c> 00115 #endif 00116 00117 #if defined(FREESCALE_LTC_ECC) 00118 #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h> 00119 #endif 00120 00121 #ifdef USE_FAST_MATH 00122 #define GEN_MEM_ERR FP_MEM 00123 #else 00124 #define GEN_MEM_ERR MP_MEM 00125 #endif 00126 00127 00128 /* internal ECC states */ 00129 enum { 00130 ECC_STATE_NONE = 0, 00131 00132 ECC_STATE_SHARED_SEC_GEN, 00133 ECC_STATE_SHARED_SEC_RES, 00134 00135 ECC_STATE_SIGN_DO, 00136 ECC_STATE_SIGN_ENCODE, 00137 00138 ECC_STATE_VERIFY_DECODE, 00139 ECC_STATE_VERIFY_DO, 00140 ECC_STATE_VERIFY_RES, 00141 }; 00142 00143 00144 /* map 00145 ptmul -> mulmod 00146 */ 00147 00148 /* 256-bit curve on by default whether user curves or not */ 00149 #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES) 00150 #define ECC112 00151 #endif 00152 #if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES) 00153 #define ECC128 00154 #endif 00155 #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) 00156 #define ECC160 00157 #endif 00158 #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) 00159 #define ECC192 00160 #endif 00161 #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) 00162 #define ECC224 00163 #endif 00164 #if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES) 00165 #define ECC239 00166 #endif 00167 #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) 00168 #define ECC256 00169 #endif 00170 #if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES) 00171 #define ECC320 00172 #endif 00173 #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) 00174 #define ECC384 00175 #endif 00176 #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) 00177 #define ECC512 00178 #endif 00179 #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) 00180 #define ECC521 00181 #endif 00182 00183 00184 /* The encoded OID's for ECC curves */ 00185 #ifdef ECC112 00186 #ifndef NO_ECC_SECP 00187 static const ecc_oid_t ecc_oid_secp112r1[] = { 00188 #ifdef HAVE_OID_ENCODING 00189 1,3,132,0,6 00190 #else 00191 0x2B,0x81,0x04,0x00,0x06 00192 #endif 00193 }; 00194 #endif /* !NO_ECC_SECP */ 00195 #ifdef HAVE_ECC_SECPR2 00196 static const ecc_oid_t ecc_oid_secp112r2[] = { 00197 #ifdef HAVE_OID_ENCODING 00198 1,3,132,0,7 00199 #else 00200 0x2B,0x81,0x04,0x00,0x07 00201 #endif 00202 }; 00203 #endif /* HAVE_ECC_SECPR2 */ 00204 #endif /* ECC112 */ 00205 #ifdef ECC128 00206 #ifndef NO_ECC_SECP 00207 static const ecc_oid_t ecc_oid_secp128r1[] = { 00208 #ifdef HAVE_OID_ENCODING 00209 1,3,132,0,28 00210 #else 00211 0x2B,0x81,0x04,0x00,0x1C 00212 #endif 00213 }; 00214 #endif /* !NO_ECC_SECP */ 00215 #ifdef HAVE_ECC_SECPR2 00216 static const ecc_oid_t ecc_oid_secp128r2[] = { 00217 #ifdef HAVE_OID_ENCODING 00218 1,3,132,0,29 00219 #else 00220 0x2B,0x81,0x04,0x00,0x1D 00221 #endif 00222 }; 00223 #endif /* HAVE_ECC_SECPR2 */ 00224 #endif /* ECC128 */ 00225 #ifdef ECC160 00226 #ifndef NO_ECC_SECP 00227 static const ecc_oid_t ecc_oid_secp160r1[] = { 00228 #ifdef HAVE_OID_ENCODING 00229 1,3,132,0,8 00230 #else 00231 0x2B,0x81,0x04,0x00,0x08 00232 #endif 00233 }; 00234 #endif /* !NO_ECC_SECP */ 00235 #ifdef HAVE_ECC_SECPR2 00236 static const ecc_oid_t ecc_oid_secp160r2[] = { 00237 #ifdef HAVE_OID_ENCODING 00238 1,3,132,0,30 00239 #else 00240 0x2B,0x81,0x04,0x00,0x1E 00241 #endif 00242 }; 00243 #endif /* HAVE_ECC_SECPR2 */ 00244 #ifdef HAVE_ECC_KOBLITZ 00245 static const ecc_oid_t ecc_oid_secp160k1[] = { 00246 #ifdef HAVE_OID_ENCODING 00247 1,3,132,0,9 00248 #else 00249 0x2B,0x81,0x04,0x00,0x09 00250 #endif 00251 }; 00252 #endif /* HAVE_ECC_KOBLITZ */ 00253 #ifdef HAVE_ECC_BRAINPOOL 00254 static const ecc_oid_t ecc_oid_brainpoolp160r1[] = { 00255 #ifdef HAVE_OID_ENCODING 00256 1,3,36,3,3,2,8,1,1,1 00257 #else 00258 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01 00259 #endif 00260 }; 00261 #endif /* HAVE_ECC_BRAINPOOL */ 00262 #endif /* ECC160 */ 00263 #ifdef ECC192 00264 #ifndef NO_ECC_SECP 00265 static const ecc_oid_t ecc_oid_secp192r1[] = { 00266 #ifdef HAVE_OID_ENCODING 00267 1,2,840,10045,3,1,1 00268 #else 00269 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01 00270 #endif 00271 }; 00272 #endif /* !NO_ECC_SECP */ 00273 #ifdef HAVE_ECC_SECPR2 00274 static const ecc_oid_t ecc_oid_prime192v2[] = { 00275 #ifdef HAVE_OID_ENCODING 00276 1,2,840,10045,3,1,2 00277 #else 00278 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02 00279 #endif 00280 }; 00281 #endif /* HAVE_ECC_SECPR2 */ 00282 #ifdef HAVE_ECC_SECPR3 00283 static const ecc_oid_t ecc_oid_prime192v3[] = { 00284 #ifdef HAVE_OID_ENCODING 00285 1,2,840,10045,3,1,3 00286 #else 00287 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03 00288 #endif 00289 }; 00290 #endif /* HAVE_ECC_SECPR3 */ 00291 #ifdef HAVE_ECC_KOBLITZ 00292 static const ecc_oid_t ecc_oid_secp192k1[] = { 00293 #ifdef HAVE_OID_ENCODING 00294 1,3,132,0,31 00295 #else 00296 0x2B,0x81,0x04,0x00,0x1F 00297 #endif 00298 }; 00299 #endif /* HAVE_ECC_KOBLITZ */ 00300 #ifdef HAVE_ECC_BRAINPOOL 00301 static const ecc_oid_t ecc_oid_brainpoolp192r1[] = { 00302 #ifdef HAVE_OID_ENCODING 00303 1,3,36,3,3,2,8,1,1,3 00304 #else 00305 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03 00306 #endif 00307 }; 00308 #endif /* HAVE_ECC_BRAINPOOL */ 00309 #endif /* ECC192 */ 00310 #ifdef ECC224 00311 #ifndef NO_ECC_SECP 00312 static const ecc_oid_t ecc_oid_secp224r1[] = { 00313 #ifdef HAVE_OID_ENCODING 00314 1,3,132,0,33 00315 #else 00316 0x2B,0x81,0x04,0x00,0x21 00317 #endif 00318 }; 00319 #endif /* !NO_ECC_SECP */ 00320 #ifdef HAVE_ECC_KOBLITZ 00321 static const ecc_oid_t ecc_oid_secp224k1[] = { 00322 #ifdef HAVE_OID_ENCODING 00323 1,3,132,0,32 00324 #else 00325 0x2B,0x81,0x04,0x00,0x20 00326 #endif 00327 }; 00328 #endif /* HAVE_ECC_KOBLITZ */ 00329 #ifdef HAVE_ECC_BRAINPOOL 00330 static const ecc_oid_t ecc_oid_brainpoolp224r1[] = { 00331 #ifdef HAVE_OID_ENCODING 00332 1,3,36,3,3,2,8,1,1,5 00333 #else 00334 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05 00335 #endif 00336 }; 00337 #endif /* HAVE_ECC_BRAINPOOL */ 00338 #endif /* ECC224 */ 00339 #ifdef ECC239 00340 #ifndef NO_ECC_SECP 00341 static const ecc_oid_t ecc_oid_prime239v1[] = { 00342 #ifdef HAVE_OID_ENCODING 00343 1,2,840,10045,3,1,4 00344 #else 00345 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04 00346 #endif 00347 }; 00348 #endif /* !NO_ECC_SECP */ 00349 #ifdef HAVE_ECC_SECPR2 00350 static const ecc_oid_t ecc_oid_prime239v2[] = { 00351 #ifdef HAVE_OID_ENCODING 00352 1,2,840,10045,3,1,5 00353 #else 00354 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05 00355 #endif 00356 }; 00357 #endif /* HAVE_ECC_SECPR2 */ 00358 #ifdef HAVE_ECC_SECPR3 00359 static const ecc_oid_t ecc_oid_prime239v3[] = { 00360 #ifdef HAVE_OID_ENCODING 00361 1,2,840,10045,3,1,6 00362 #else 00363 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06 00364 #endif 00365 }; 00366 #endif /* HAVE_ECC_SECPR3 */ 00367 #endif /* ECC239 */ 00368 #ifdef ECC256 00369 #ifndef NO_ECC_SECP 00370 static const ecc_oid_t ecc_oid_secp256r1[] = { 00371 #ifdef HAVE_OID_ENCODING 00372 1,2,840,10045,3,1,7 00373 #else 00374 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07 00375 #endif 00376 }; 00377 #endif /* !NO_ECC_SECP */ 00378 #ifdef HAVE_ECC_KOBLITZ 00379 static const ecc_oid_t ecc_oid_secp256k1[] = { 00380 #ifdef HAVE_OID_ENCODING 00381 1,3,132,0,10 00382 #else 00383 0x2B,0x81,0x04,0x00,0x0A 00384 #endif 00385 }; 00386 #endif /* HAVE_ECC_KOBLITZ */ 00387 #ifdef HAVE_ECC_BRAINPOOL 00388 static const ecc_oid_t ecc_oid_brainpoolp256r1[] = { 00389 #ifdef HAVE_OID_ENCODING 00390 1,3,36,3,3,2,8,1,1,7 00391 #else 00392 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07 00393 #endif 00394 }; 00395 #endif /* HAVE_ECC_BRAINPOOL */ 00396 #endif /* ECC256 */ 00397 #ifdef ECC320 00398 #ifdef HAVE_ECC_BRAINPOOL 00399 static const ecc_oid_t ecc_oid_brainpoolp320r1[] = { 00400 #ifdef HAVE_OID_ENCODING 00401 1,3,36,3,3,2,8,1,1,9 00402 #else 00403 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09 00404 #endif 00405 }; 00406 #endif /* HAVE_ECC_BRAINPOOL */ 00407 #endif /* ECC320 */ 00408 #ifdef ECC384 00409 #ifndef NO_ECC_SECP 00410 static const ecc_oid_t ecc_oid_secp384r1[] = { 00411 #ifdef HAVE_OID_ENCODING 00412 1,3,132,0,34 00413 #else 00414 0x2B,0x81,0x04,0x00,0x22 00415 #endif 00416 }; 00417 #endif /* !NO_ECC_SECP */ 00418 #ifdef HAVE_ECC_BRAINPOOL 00419 static const ecc_oid_t ecc_oid_brainpoolp384r1[] = { 00420 #ifdef HAVE_OID_ENCODING 00421 1,3,36,3,3,2,8,1,1,11 00422 #else 00423 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B 00424 #endif 00425 }; 00426 #endif /* HAVE_ECC_BRAINPOOL */ 00427 #endif /* ECC384 */ 00428 #ifdef ECC512 00429 #ifdef HAVE_ECC_BRAINPOOL 00430 static const ecc_oid_t ecc_oid_brainpoolp512r1[] = { 00431 #ifdef HAVE_OID_ENCODING 00432 1,3,36,3,3,2,8,1,1,13 00433 #else 00434 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D 00435 #endif 00436 }; 00437 #endif /* HAVE_ECC_BRAINPOOL */ 00438 #endif /* ECC512 */ 00439 #ifdef ECC521 00440 #ifndef NO_ECC_SECP 00441 static const ecc_oid_t ecc_oid_secp521r1[] = { 00442 #ifdef HAVE_OID_ENCODING 00443 1,3,132,0,35 00444 #else 00445 0x2B,0x81,0x04,0x00,0x23 00446 #endif 00447 }; 00448 #endif /* !NO_ECC_SECP */ 00449 #endif /* ECC521 */ 00450 00451 00452 /* This holds the key settings. 00453 ***MUST*** be organized by size from smallest to largest. */ 00454 00455 const ecc_set_type ecc_sets[] = { 00456 #ifdef ECC112 00457 #ifndef NO_ECC_SECP 00458 { 00459 14, /* size/bytes */ 00460 ECC_SECP112R1, /* ID */ 00461 "SECP112R1", /* curve name */ 00462 "DB7C2ABF62E35E668076BEAD208B", /* prime */ 00463 "DB7C2ABF62E35E668076BEAD2088", /* A */ 00464 "659EF8BA043916EEDE8911702B22", /* B */ 00465 "DB7C2ABF62E35E7628DFAC6561C5", /* order */ 00466 "9487239995A5EE76B55F9C2F098", /* Gx */ 00467 "A89CE5AF8724C0A23E0E0FF77500", /* Gy */ 00468 ecc_oid_secp112r1, /* oid/oidSz */ 00469 sizeof(ecc_oid_secp112r1) / sizeof(ecc_oid_t), 00470 ECC_SECP112R1_OID, /* oid sum */ 00471 1, /* cofactor */ 00472 }, 00473 #endif /* !NO_ECC_SECP */ 00474 #ifdef HAVE_ECC_SECPR2 00475 { 00476 14, /* size/bytes */ 00477 ECC_SECP112R2, /* ID */ 00478 "SECP112R2", /* curve name */ 00479 "DB7C2ABF62E35E668076BEAD208B", /* prime */ 00480 "6127C24C05F38A0AAAF65C0EF02C", /* A */ 00481 "51DEF1815DB5ED74FCC34C85D709", /* B */ 00482 "36DF0AAFD8B8D7597CA10520D04B", /* order */ 00483 "4BA30AB5E892B4E1649DD0928643", /* Gx */ 00484 "ADCD46F5882E3747DEF36E956E97", /* Gy */ 00485 ecc_oid_secp112r2, /* oid/oidSz */ 00486 sizeof(ecc_oid_secp112r2) / sizeof(ecc_oid_t), 00487 ECC_SECP112R2_OID, /* oid sum */ 00488 4, /* cofactor */ 00489 }, 00490 #endif /* HAVE_ECC_SECPR2 */ 00491 #endif /* ECC112 */ 00492 #ifdef ECC128 00493 #ifndef NO_ECC_SECP 00494 { 00495 16, /* size/bytes */ 00496 ECC_SECP128R1, /* ID */ 00497 "SECP128R1", /* curve name */ 00498 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ 00499 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A */ 00500 "E87579C11079F43DD824993C2CEE5ED3", /* B */ 00501 "FFFFFFFE0000000075A30D1B9038A115", /* order */ 00502 "161FF7528B899B2D0C28607CA52C5B86", /* Gx */ 00503 "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy */ 00504 ecc_oid_secp128r1, /* oid/oidSz */ 00505 sizeof(ecc_oid_secp128r1) / sizeof(ecc_oid_t), 00506 ECC_SECP128R1_OID, /* oid sum */ 00507 1, /* cofactor */ 00508 }, 00509 #endif /* !NO_ECC_SECP */ 00510 #ifdef HAVE_ECC_SECPR2 00511 { 00512 16, /* size/bytes */ 00513 ECC_SECP128R2, /* ID */ 00514 "SECP128R2", /* curve name */ 00515 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ 00516 "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A */ 00517 "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B */ 00518 "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order */ 00519 "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx */ 00520 "27B6916A894D3AEE7106FE805FC34B44", /* Gy */ 00521 ecc_oid_secp128r2, /* oid/oidSz */ 00522 sizeof(ecc_oid_secp128r2) / sizeof(ecc_oid_t), 00523 ECC_SECP128R2_OID, /* oid sum */ 00524 4, /* cofactor */ 00525 }, 00526 #endif /* HAVE_ECC_SECPR2 */ 00527 #endif /* ECC128 */ 00528 #ifdef ECC160 00529 #ifndef NO_ECC_SECP 00530 { 00531 20, /* size/bytes */ 00532 ECC_SECP160R1, /* ID */ 00533 "SECP160R1", /* curve name */ 00534 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime */ 00535 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A */ 00536 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B */ 00537 "100000000000000000001F4C8F927AED3CA752257",/* order */ 00538 "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx */ 00539 "23A628553168947D59DCC912042351377AC5FB32", /* Gy */ 00540 ecc_oid_secp160r1, /* oid/oidSz */ 00541 sizeof(ecc_oid_secp160r1) / sizeof(ecc_oid_t), 00542 ECC_SECP160R1_OID, /* oid sum */ 00543 1, /* cofactor */ 00544 }, 00545 #endif /* !NO_ECC_SECP */ 00546 #ifdef HAVE_ECC_SECPR2 00547 { 00548 20, /* size/bytes */ 00549 ECC_SECP160R2, /* ID */ 00550 "SECP160R2", /* curve name */ 00551 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */ 00552 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A */ 00553 "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B */ 00554 "100000000000000000000351EE786A818F3A1A16B",/* order */ 00555 "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx */ 00556 "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy */ 00557 ecc_oid_secp160r2, /* oid/oidSz */ 00558 sizeof(ecc_oid_secp160r2) / sizeof(ecc_oid_t), 00559 ECC_SECP160R2_OID, /* oid sum */ 00560 1, /* cofactor */ 00561 }, 00562 #endif /* HAVE_ECC_SECPR2 */ 00563 #ifdef HAVE_ECC_KOBLITZ 00564 { 00565 20, /* size/bytes */ 00566 ECC_SECP160K1, /* ID */ 00567 "SECP160K1", /* curve name */ 00568 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */ 00569 "0000000000000000000000000000000000000000", /* A */ 00570 "0000000000000000000000000000000000000007", /* B */ 00571 "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order */ 00572 "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx */ 00573 "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy */ 00574 ecc_oid_secp160k1, /* oid/oidSz */ 00575 sizeof(ecc_oid_secp160k1) / sizeof(ecc_oid_t), 00576 ECC_SECP160K1_OID, /* oid sum */ 00577 1, /* cofactor */ 00578 }, 00579 #endif /* HAVE_ECC_KOBLITZ */ 00580 #ifdef HAVE_ECC_BRAINPOOL 00581 { 00582 20, /* size/bytes */ 00583 ECC_BRAINPOOLP160R1, /* ID */ 00584 "BRAINPOOLP160R1", /* curve name */ 00585 "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime */ 00586 "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A */ 00587 "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B */ 00588 "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order */ 00589 "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx */ 00590 "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy */ 00591 ecc_oid_brainpoolp160r1, /* oid/oidSz */ 00592 sizeof(ecc_oid_brainpoolp160r1) / sizeof(ecc_oid_t), 00593 ECC_BRAINPOOLP160R1_OID, /* oid sum */ 00594 1, /* cofactor */ 00595 }, 00596 #endif /* HAVE_ECC_BRAINPOOL */ 00597 #endif /* ECC160 */ 00598 #ifdef ECC192 00599 #ifndef NO_ECC_SECP 00600 { 00601 24, /* size/bytes */ 00602 ECC_SECP192R1, /* ID */ 00603 "SECP192R1", /* curve name */ 00604 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ 00605 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ 00606 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B */ 00607 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order */ 00608 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx */ 00609 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", /* Gy */ 00610 ecc_oid_secp192r1, /* oid/oidSz */ 00611 sizeof(ecc_oid_secp192r1) / sizeof(ecc_oid_t), 00612 ECC_SECP192R1_OID, /* oid sum */ 00613 1, /* cofactor */ 00614 }, 00615 #endif /* !NO_ECC_SECP */ 00616 #ifdef HAVE_ECC_SECPR2 00617 { 00618 24, /* size/bytes */ 00619 ECC_PRIME192V2, /* ID */ 00620 "PRIME192V2", /* curve name */ 00621 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ 00622 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ 00623 "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B */ 00624 "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order */ 00625 "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx */ 00626 "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy */ 00627 ecc_oid_prime192v2, /* oid/oidSz */ 00628 sizeof(ecc_oid_prime192v2) / sizeof(ecc_oid_t), 00629 ECC_PRIME192V2_OID, /* oid sum */ 00630 1, /* cofactor */ 00631 }, 00632 #endif /* HAVE_ECC_SECPR2 */ 00633 #ifdef HAVE_ECC_SECPR3 00634 { 00635 24, /* size/bytes */ 00636 ECC_PRIME192V3, /* ID */ 00637 "PRIME192V3", /* curve name */ 00638 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ 00639 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ 00640 "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B */ 00641 "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order */ 00642 "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx */ 00643 "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy */ 00644 ecc_oid_prime192v3, /* oid/oidSz */ 00645 sizeof(ecc_oid_prime192v3) / sizeof(ecc_oid_t), 00646 ECC_PRIME192V3_OID, /* oid sum */ 00647 1, /* cofactor */ 00648 }, 00649 #endif /* HAVE_ECC_SECPR3 */ 00650 #ifdef HAVE_ECC_KOBLITZ 00651 { 00652 24, /* size/bytes */ 00653 ECC_SECP192K1, /* ID */ 00654 "SECP192K1", /* curve name */ 00655 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime */ 00656 "000000000000000000000000000000000000000000000000", /* A */ 00657 "000000000000000000000000000000000000000000000003", /* B */ 00658 "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order */ 00659 "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx */ 00660 "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy */ 00661 ecc_oid_secp192k1, /* oid/oidSz */ 00662 sizeof(ecc_oid_secp192k1) / sizeof(ecc_oid_t), 00663 ECC_SECP192K1_OID, /* oid sum */ 00664 1, /* cofactor */ 00665 }, 00666 #endif /* HAVE_ECC_KOBLITZ */ 00667 #ifdef HAVE_ECC_BRAINPOOL 00668 { 00669 24, /* size/bytes */ 00670 ECC_BRAINPOOLP192R1, /* ID */ 00671 "BRAINPOOLP192R1", /* curve name */ 00672 "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime */ 00673 "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A */ 00674 "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B */ 00675 "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order */ 00676 "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx */ 00677 "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy */ 00678 ecc_oid_brainpoolp192r1, /* oid/oidSz */ 00679 sizeof(ecc_oid_brainpoolp192r1) / sizeof(ecc_oid_t), 00680 ECC_BRAINPOOLP192R1_OID, /* oid sum */ 00681 1, /* cofactor */ 00682 }, 00683 #endif /* HAVE_ECC_BRAINPOOL */ 00684 #endif /* ECC192 */ 00685 #ifdef ECC224 00686 #ifndef NO_ECC_SECP 00687 { 00688 28, /* size/bytes */ 00689 ECC_SECP224R1, /* ID */ 00690 "SECP224R1", /* curve name */ 00691 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime */ 00692 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A */ 00693 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B */ 00694 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */ 00695 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */ 00696 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */ 00697 ecc_oid_secp224r1, /* oid/oidSz */ 00698 sizeof(ecc_oid_secp224r1) / sizeof(ecc_oid_t), 00699 ECC_SECP224R1_OID, /* oid sum */ 00700 1, /* cofactor */ 00701 }, 00702 #endif /* !NO_ECC_SECP */ 00703 #ifdef HAVE_ECC_KOBLITZ 00704 { 00705 28, /* size/bytes */ 00706 ECC_SECP224K1, /* ID */ 00707 "SECP224K1", /* curve name */ 00708 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime */ 00709 "00000000000000000000000000000000000000000000000000000000", /* A */ 00710 "00000000000000000000000000000000000000000000000000000005", /* B */ 00711 "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order */ 00712 "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx */ 00713 "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy */ 00714 ecc_oid_secp224k1, /* oid/oidSz */ 00715 sizeof(ecc_oid_secp224k1) / sizeof(ecc_oid_t), 00716 ECC_SECP224K1_OID, /* oid sum */ 00717 1, /* cofactor */ 00718 }, 00719 #endif /* HAVE_ECC_KOBLITZ */ 00720 #ifdef HAVE_ECC_BRAINPOOL 00721 { 00722 28, /* size/bytes */ 00723 ECC_BRAINPOOLP224R1, /* ID */ 00724 "BRAINPOOLP224R1", /* curve name */ 00725 "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime */ 00726 "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A */ 00727 "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B */ 00728 "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order */ 00729 "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx */ 00730 "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy */ 00731 ecc_oid_brainpoolp224r1, /* oid/oidSz */ 00732 sizeof(ecc_oid_brainpoolp224r1) / sizeof(ecc_oid_t), 00733 ECC_BRAINPOOLP224R1_OID, /* oid sum */ 00734 1, /* cofactor */ 00735 }, 00736 #endif /* HAVE_ECC_BRAINPOOL */ 00737 #endif /* ECC224 */ 00738 #ifdef ECC239 00739 #ifndef NO_ECC_SECP 00740 { 00741 30, /* size/bytes */ 00742 ECC_PRIME239V1, /* ID */ 00743 "PRIME239V1", /* curve name */ 00744 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ 00745 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ 00746 "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B */ 00747 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order */ 00748 "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx */ 00749 "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy */ 00750 ecc_oid_prime239v1, /* oid/oidSz */ 00751 sizeof(ecc_oid_prime239v1) / sizeof(ecc_oid_t), 00752 ECC_PRIME239V1_OID, /* oid sum */ 00753 1, /* cofactor */ 00754 }, 00755 #endif /* !NO_ECC_SECP */ 00756 #ifdef HAVE_ECC_SECPR2 00757 { 00758 30, /* size/bytes */ 00759 ECC_PRIME239V2, /* ID */ 00760 "PRIME239V2", /* curve name */ 00761 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ 00762 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ 00763 "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B */ 00764 "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order */ 00765 "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx */ 00766 "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy */ 00767 ecc_oid_prime239v2, /* oid/oidSz */ 00768 sizeof(ecc_oid_prime239v2) / sizeof(ecc_oid_t), 00769 ECC_PRIME239V2_OID, /* oid sum */ 00770 1, /* cofactor */ 00771 }, 00772 #endif /* HAVE_ECC_SECPR2 */ 00773 #ifdef HAVE_ECC_SECPR3 00774 { 00775 30, /* size/bytes */ 00776 ECC_PRIME239V3, /* ID */ 00777 "PRIME239V3", /* curve name */ 00778 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ 00779 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ 00780 "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B */ 00781 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order */ 00782 "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx */ 00783 "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy */ 00784 ecc_oid_prime239v3, /* oid/oidSz */ 00785 sizeof(ecc_oid_prime239v3) / sizeof(ecc_oid_t), 00786 ECC_PRIME239V3_OID, /* oid sum */ 00787 1, /* cofactor */ 00788 }, 00789 #endif /* HAVE_ECC_SECPR3 */ 00790 #endif /* ECC239 */ 00791 #ifdef ECC256 00792 #ifndef NO_ECC_SECP 00793 { 00794 32, /* size/bytes */ 00795 ECC_SECP256R1, /* ID */ 00796 "SECP256R1", /* curve name */ 00797 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ 00798 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A */ 00799 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B */ 00800 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order */ 00801 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx */ 00802 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy */ 00803 ecc_oid_secp256r1, /* oid/oidSz */ 00804 sizeof(ecc_oid_secp256r1) / sizeof(ecc_oid_t), 00805 ECC_SECP256R1_OID, /* oid sum */ 00806 1, /* cofactor */ 00807 }, 00808 #endif /* !NO_ECC_SECP */ 00809 #ifdef HAVE_ECC_KOBLITZ 00810 { 00811 32, /* size/bytes */ 00812 ECC_SECP256K1, /* ID */ 00813 "SECP256K1", /* curve name */ 00814 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime */ 00815 "0000000000000000000000000000000000000000000000000000000000000000", /* A */ 00816 "0000000000000000000000000000000000000000000000000000000000000007", /* B */ 00817 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order */ 00818 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx */ 00819 "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy */ 00820 ecc_oid_secp256k1, /* oid/oidSz */ 00821 sizeof(ecc_oid_secp256k1) / sizeof(ecc_oid_t), 00822 ECC_SECP256K1_OID, /* oid sum */ 00823 1, /* cofactor */ 00824 }, 00825 #endif /* HAVE_ECC_KOBLITZ */ 00826 #ifdef HAVE_ECC_BRAINPOOL 00827 { 00828 32, /* size/bytes */ 00829 ECC_BRAINPOOLP256R1, /* ID */ 00830 "BRAINPOOLP256R1", /* curve name */ 00831 "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime */ 00832 "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */ 00833 "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */ 00834 "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order */ 00835 "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */ 00836 "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */ 00837 ecc_oid_brainpoolp256r1, /* oid/oidSz */ 00838 sizeof(ecc_oid_brainpoolp256r1) / sizeof(ecc_oid_t), 00839 ECC_BRAINPOOLP256R1_OID, /* oid sum */ 00840 1, /* cofactor */ 00841 }, 00842 #endif /* HAVE_ECC_BRAINPOOL */ 00843 #endif /* ECC256 */ 00844 #ifdef ECC320 00845 #ifdef HAVE_ECC_BRAINPOOL 00846 { 00847 40, /* size/bytes */ 00848 ECC_BRAINPOOLP320R1, /* ID */ 00849 "BRAINPOOLP320R1", /* curve name */ 00850 "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime */ 00851 "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A */ 00852 "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B */ 00853 "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order */ 00854 "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx */ 00855 "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy */ 00856 ecc_oid_brainpoolp320r1, sizeof(ecc_oid_brainpoolp320r1) / sizeof(ecc_oid_t), /* oid/oidSz */ 00857 ECC_BRAINPOOLP320R1_OID, /* oid sum */ 00858 1, /* cofactor */ 00859 }, 00860 #endif /* HAVE_ECC_BRAINPOOL */ 00861 #endif /* ECC320 */ 00862 #ifdef ECC384 00863 #ifndef NO_ECC_SECP 00864 { 00865 48, /* size/bytes */ 00866 ECC_SECP384R1, /* ID */ 00867 "SECP384R1", /* curve name */ 00868 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime */ 00869 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A */ 00870 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B */ 00871 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order */ 00872 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx */ 00873 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy */ 00874 ecc_oid_secp384r1, sizeof(ecc_oid_secp384r1) / sizeof(ecc_oid_t), /* oid/oidSz */ 00875 ECC_SECP384R1_OID, /* oid sum */ 00876 1, /* cofactor */ 00877 }, 00878 #endif /* !NO_ECC_SECP */ 00879 #ifdef HAVE_ECC_BRAINPOOL 00880 { 00881 48, /* size/bytes */ 00882 ECC_BRAINPOOLP384R1, /* ID */ 00883 "BRAINPOOLP384R1", /* curve name */ 00884 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime */ 00885 "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A */ 00886 "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B */ 00887 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order */ 00888 "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx */ 00889 "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy */ 00890 ecc_oid_brainpoolp384r1, sizeof(ecc_oid_brainpoolp384r1) / sizeof(ecc_oid_t), /* oid/oidSz */ 00891 ECC_BRAINPOOLP384R1_OID, /* oid sum */ 00892 1, /* cofactor */ 00893 }, 00894 #endif /* HAVE_ECC_BRAINPOOL */ 00895 #endif /* ECC384 */ 00896 #ifdef ECC512 00897 #ifdef HAVE_ECC_BRAINPOOL 00898 { 00899 64, /* size/bytes */ 00900 ECC_BRAINPOOLP512R1, /* ID */ 00901 "BRAINPOOLP512R1", /* curve name */ 00902 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime */ 00903 "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A */ 00904 "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B */ 00905 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order */ 00906 "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx */ 00907 "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy */ 00908 ecc_oid_brainpoolp512r1, sizeof(ecc_oid_brainpoolp512r1) / sizeof(ecc_oid_t), /* oid/oidSz */ 00909 ECC_BRAINPOOLP512R1_OID, /* oid sum */ 00910 1, /* cofactor */ 00911 }, 00912 #endif /* HAVE_ECC_BRAINPOOL */ 00913 #endif /* ECC512 */ 00914 #ifdef ECC521 00915 #ifndef NO_ECC_SECP 00916 { 00917 66, /* size/bytes */ 00918 ECC_SECP521R1, /* ID */ 00919 "SECP521R1", /* curve name */ 00920 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ 00921 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A */ 00922 "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", /* B */ 00923 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order */ 00924 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", /* Gx */ 00925 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy */ 00926 ecc_oid_secp521r1, sizeof(ecc_oid_secp521r1) / sizeof(ecc_oid_t), /* oid/oidSz */ 00927 ECC_SECP521R1_OID, /* oid sum */ 00928 1, /* cofactor */ 00929 }, 00930 #endif /* !NO_ECC_SECP */ 00931 #endif /* ECC521 */ 00932 { 00933 0, -1, 00934 NULL, NULL, NULL, NULL, NULL, NULL, NULL, 00935 NULL, 0, 0, 0 00936 } 00937 }; 00938 #define ECC_SET_COUNT (sizeof(ecc_sets)/sizeof(ecc_set_type)) 00939 00940 #ifdef HAVE_OID_ENCODING 00941 /* encoded OID cache */ 00942 typedef struct { 00943 word32 oidSz; 00944 byte oid[ECC_MAX_OID_LEN]; 00945 } oid_cache_t; 00946 static oid_cache_t ecc_oid_cache[ECC_SET_COUNT]; 00947 #endif 00948 00949 00950 #ifdef HAVE_COMP_KEY 00951 static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); 00952 #endif 00953 00954 #ifndef WOLFSSL_ATECC508A 00955 00956 static int ecc_check_pubkey_order(ecc_key* key, mp_int* a, mp_int* prime, mp_int* order); 00957 #ifdef ECC_SHAMIR 00958 static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB, 00959 ecc_point* C, mp_int* a, mp_int* modulus, void* heap); 00960 #endif 00961 00962 int mp_jacobi(mp_int* a, mp_int* n, int* c); 00963 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret); 00964 00965 00966 /* Curve Specs */ 00967 typedef struct ecc_curve_spec { 00968 const ecc_set_type* dp; 00969 00970 mp_int* prime; 00971 mp_int* Af; 00972 #ifdef USE_ECC_B_PARAM 00973 mp_int* Bf; 00974 #endif 00975 mp_int* order; 00976 mp_int* Gx; 00977 mp_int* Gy; 00978 00979 #ifdef ECC_CACHE_CURVE 00980 mp_int prime_lcl; 00981 mp_int Af_lcl; 00982 #ifdef USE_ECC_B_PARAM 00983 mp_int Bf_lcl; 00984 #endif 00985 mp_int order_lcl; 00986 mp_int Gx_lcl; 00987 mp_int Gy_lcl; 00988 #else 00989 mp_int* spec_ints; 00990 word32 spec_count; 00991 word32 spec_use; 00992 #endif 00993 00994 byte load_mask; 00995 } ecc_curve_spec; 00996 00997 enum ecc_curve_load_mask { 00998 ECC_CURVE_FIELD_NONE = 0x00, 00999 ECC_CURVE_FIELD_PRIME = 0x01, 01000 ECC_CURVE_FIELD_AF = 0x02, 01001 #ifdef USE_ECC_B_PARAM 01002 ECC_CURVE_FIELD_BF = 0x04, 01003 #endif 01004 ECC_CURVE_FIELD_ORDER = 0x08, 01005 ECC_CURVE_FIELD_GX = 0x10, 01006 ECC_CURVE_FIELD_GY = 0x20, 01007 #ifdef USE_ECC_B_PARAM 01008 ECC_CURVE_FIELD_ALL = 0x3F, 01009 ECC_CURVE_FIELD_COUNT = 6, 01010 #else 01011 ECC_CURVE_FIELD_ALL = 0x3B, 01012 ECC_CURVE_FIELD_COUNT = 5, 01013 #endif 01014 }; 01015 01016 #ifdef ECC_CACHE_CURVE 01017 /* cache (mp_int) of the curve parameters */ 01018 static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT]; 01019 #ifndef SINGLE_THREADED 01020 static wolfSSL_Mutex ecc_curve_cache_mutex; 01021 #endif 01022 01023 #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL; 01024 #else 01025 #define DECLARE_CURVE_SPECS(intcount) \ 01026 mp_int spec_ints[(intcount)]; \ 01027 ecc_curve_spec curve_lcl; \ 01028 ecc_curve_spec* curve = &curve_lcl; \ 01029 XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \ 01030 curve->spec_ints = spec_ints; \ 01031 curve->spec_count = intcount; 01032 #endif /* ECC_CACHE_CURVE */ 01033 01034 static void _wc_ecc_curve_free(ecc_curve_spec* curve) 01035 { 01036 if (curve == NULL) { 01037 return; 01038 } 01039 01040 if (curve->load_mask & ECC_CURVE_FIELD_PRIME) 01041 mp_clear(curve->prime); 01042 if (curve->load_mask & ECC_CURVE_FIELD_AF) 01043 mp_clear(curve->Af); 01044 #ifdef USE_ECC_B_PARAM 01045 if (curve->load_mask & ECC_CURVE_FIELD_BF) 01046 mp_clear(curve->Bf); 01047 #endif 01048 if (curve->load_mask & ECC_CURVE_FIELD_ORDER) 01049 mp_clear(curve->order); 01050 if (curve->load_mask & ECC_CURVE_FIELD_GX) 01051 mp_clear(curve->Gx); 01052 if (curve->load_mask & ECC_CURVE_FIELD_GY) 01053 mp_clear(curve->Gy); 01054 01055 curve->load_mask = 0; 01056 } 01057 01058 static void wc_ecc_curve_free(ecc_curve_spec* curve) 01059 { 01060 /* don't free cached curves */ 01061 #ifndef ECC_CACHE_CURVE 01062 _wc_ecc_curve_free(curve); 01063 #endif 01064 (void)curve; 01065 } 01066 01067 static int wc_ecc_curve_load_item(const char* src, mp_int** dst, 01068 ecc_curve_spec* curve, byte mask) 01069 { 01070 int err; 01071 01072 #ifndef ECC_CACHE_CURVE 01073 /* get mp_int from temp */ 01074 if (curve->spec_use >= curve->spec_count) { 01075 WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count"); 01076 return ECC_BAD_ARG_E; 01077 } 01078 *dst = &curve->spec_ints[curve->spec_use++]; 01079 #endif 01080 01081 err = mp_init(*dst); 01082 if (err == MP_OKAY) { 01083 curve->load_mask |= mask; 01084 01085 err = mp_read_radix(*dst, src, 16); 01086 01087 #ifdef HAVE_WOLF_BIGINT 01088 if (err == MP_OKAY) 01089 err = wc_mp_to_bigint(*dst, &(*dst)->raw); 01090 #endif 01091 } 01092 return err; 01093 } 01094 01095 static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve, 01096 byte load_mask) 01097 { 01098 int ret = 0, x; 01099 ecc_curve_spec* curve; 01100 byte load_items = 0; /* mask of items to load */ 01101 01102 if (dp == NULL || pCurve == NULL) 01103 return BAD_FUNC_ARG; 01104 01105 #ifdef ECC_CACHE_CURVE 01106 x = wc_ecc_get_curve_idx(dp->id); 01107 if (x == ECC_CURVE_INVALID) 01108 return ECC_BAD_ARG_E; 01109 01110 /* make sure cache has been allocated */ 01111 if (ecc_curve_spec_cache[x] == NULL) { 01112 ecc_curve_spec_cache[x] = (ecc_curve_spec*)XMALLOC( 01113 sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC); 01114 if (ecc_curve_spec_cache[x] == NULL) 01115 return MEMORY_E; 01116 XMEMSET(ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec)); 01117 } 01118 01119 /* set curve pointer to cache */ 01120 *pCurve = ecc_curve_spec_cache[x]; 01121 01122 #endif /* ECC_CACHE_CURVE */ 01123 curve = *pCurve; 01124 01125 /* make sure the curve is initialized */ 01126 if (curve->dp != dp) { 01127 curve->load_mask = 0; 01128 01129 #ifdef ECC_CACHE_CURVE 01130 curve->prime = &curve->prime_lcl; 01131 curve->Af = &curve->Af_lcl; 01132 #ifdef USE_ECC_B_PARAM 01133 curve->Bf = &curve->Bf_lcl; 01134 #endif 01135 curve->order = &curve->order_lcl; 01136 curve->Gx = &curve->Gx_lcl; 01137 curve->Gy = &curve->Gy_lcl; 01138 #endif 01139 } 01140 curve->dp = dp; /* set dp info */ 01141 01142 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) 01143 ret = wc_LockMutex(&ecc_curve_cache_mutex); 01144 if (ret != 0) { 01145 return MEMORY_E; 01146 } 01147 #endif 01148 01149 /* determine items to load */ 01150 load_items = (~curve->load_mask & load_mask); 01151 curve->load_mask |= load_items; 01152 01153 /* load items */ 01154 x = 0; 01155 if (load_items & ECC_CURVE_FIELD_PRIME) 01156 x += wc_ecc_curve_load_item(dp->prime, &curve->prime, curve, 01157 ECC_CURVE_FIELD_PRIME); 01158 if (load_items & ECC_CURVE_FIELD_AF) 01159 x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve, 01160 ECC_CURVE_FIELD_AF); 01161 #ifdef USE_ECC_B_PARAM 01162 if (load_items & ECC_CURVE_FIELD_BF) 01163 x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve, 01164 ECC_CURVE_FIELD_BF); 01165 #endif 01166 if (load_items & ECC_CURVE_FIELD_ORDER) 01167 x += wc_ecc_curve_load_item(dp->order, &curve->order, curve, 01168 ECC_CURVE_FIELD_ORDER); 01169 if (load_items & ECC_CURVE_FIELD_GX) 01170 x += wc_ecc_curve_load_item(dp->Gx, &curve->Gx, curve, 01171 ECC_CURVE_FIELD_GX); 01172 if (load_items & ECC_CURVE_FIELD_GY) 01173 x += wc_ecc_curve_load_item(dp->Gy, &curve->Gy, curve, 01174 ECC_CURVE_FIELD_GY); 01175 01176 /* check for error */ 01177 if (x != 0) { 01178 wc_ecc_curve_free(curve); 01179 ret = MP_READ_E; 01180 } 01181 01182 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) 01183 wc_UnLockMutex(&ecc_curve_cache_mutex); 01184 #endif 01185 01186 return ret; 01187 } 01188 01189 #ifdef ECC_CACHE_CURVE 01190 int wc_ecc_curve_cache_init(void) 01191 { 01192 int ret = 0; 01193 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) 01194 ret = wc_InitMutex(&ecc_curve_cache_mutex); 01195 #endif 01196 return ret; 01197 } 01198 01199 void wc_ecc_curve_cache_free(void) 01200 { 01201 int x; 01202 01203 /* free all ECC curve caches */ 01204 for (x = 0; x < (int)ECC_SET_COUNT; x++) { 01205 if (ecc_curve_spec_cache[x]) { 01206 _wc_ecc_curve_free(ecc_curve_spec_cache[x]); 01207 XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC); 01208 ecc_curve_spec_cache[x] = NULL; 01209 } 01210 } 01211 01212 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) 01213 wc_FreeMutex(&ecc_curve_cache_mutex); 01214 #endif 01215 } 01216 #endif /* ECC_CACHE_CURVE */ 01217 01218 #endif /* WOLFSSL_ATECC508A */ 01219 01220 01221 /* Retrieve the curve name for the ECC curve id. 01222 * 01223 * curve_id The id of the curve. 01224 * returns the name stored from the curve if available, otherwise NULL. 01225 */ 01226 const char* wc_ecc_get_name(int curve_id) 01227 { 01228 int curve_idx = wc_ecc_get_curve_idx(curve_id); 01229 if (curve_idx == ECC_CURVE_INVALID) 01230 return NULL; 01231 return ecc_sets[curve_idx].name; 01232 } 01233 01234 int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id) 01235 { 01236 if (keysize <= 0 && curve_id <= 0) { 01237 return BAD_FUNC_ARG; 01238 } 01239 01240 if (keysize > ECC_MAXSIZE) { 01241 return ECC_BAD_ARG_E; 01242 } 01243 01244 /* handle custom case */ 01245 if (key->idx != ECC_CUSTOM_IDX) { 01246 int x; 01247 01248 /* find ecc_set based on curve_id or key size */ 01249 for (x = 0; ecc_sets[x].size != 0; x++) { 01250 if (curve_id > ECC_CURVE_DEF) { 01251 if (curve_id == ecc_sets[x].id) 01252 break; 01253 } 01254 else if (keysize <= ecc_sets[x].size) { 01255 break; 01256 } 01257 } 01258 if (ecc_sets[x].size == 0) { 01259 WOLFSSL_MSG("ECC Curve not found"); 01260 return ECC_CURVE_OID_E; 01261 } 01262 01263 key->idx = x; 01264 key->dp = &ecc_sets[x]; 01265 } 01266 01267 return 0; 01268 } 01269 01270 #ifndef WOLFSSL_ATECC508A 01271 01272 /** 01273 Add two ECC points 01274 P The point to add 01275 Q The point to add 01276 R [out] The destination of the double 01277 a ECC curve parameter a 01278 modulus The modulus of the field the ECC curve is in 01279 mp The "b" value from montgomery_setup() 01280 return MP_OKAY on success 01281 */ 01282 int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, 01283 mp_int* a, mp_int* modulus, mp_digit mp) 01284 { 01285 mp_int t1, t2; 01286 #ifdef ALT_ECC_SIZE 01287 mp_int rx, ry, rz; 01288 #endif 01289 mp_int *x, *y, *z; 01290 int err; 01291 01292 if (P == NULL || Q == NULL || R == NULL || modulus == NULL) { 01293 return ECC_BAD_ARG_E; 01294 } 01295 01296 /* if Q == R then swap P and Q, so we don't require a local x,y,z */ 01297 if (Q == R) { 01298 ecc_point* tPt = P; 01299 P = Q; 01300 Q = tPt; 01301 } 01302 01303 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 01304 return err; 01305 } 01306 01307 /* should we dbl instead? */ 01308 if (err == MP_OKAY) 01309 err = mp_sub(modulus, Q->y, &t1); 01310 if (err == MP_OKAY) { 01311 if ( (mp_cmp(P->x, Q->x) == MP_EQ) && 01312 (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) && 01313 (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, &t1) == MP_EQ)) { 01314 mp_clear(&t1); 01315 mp_clear(&t2); 01316 return ecc_projective_dbl_point(P, R, a, modulus, mp); 01317 } 01318 } 01319 01320 if (err != MP_OKAY) { 01321 goto done; 01322 } 01323 01324 /* If use ALT_ECC_SIZE we need to use local stack variable since 01325 ecc_point x,y,z is reduced size */ 01326 #ifdef ALT_ECC_SIZE 01327 /* Use local stack variable */ 01328 x = ℞ 01329 y = &ry; 01330 z = &rz; 01331 01332 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { 01333 goto done; 01334 } 01335 #else 01336 /* Use destination directly */ 01337 x = R->x; 01338 y = R->y; 01339 z = R->z; 01340 #endif 01341 01342 if (err == MP_OKAY) 01343 err = mp_copy(P->x, x); 01344 if (err == MP_OKAY) 01345 err = mp_copy(P->y, y); 01346 if (err == MP_OKAY) 01347 err = mp_copy(P->z, z); 01348 01349 /* if Z is one then these are no-operations */ 01350 if (err == MP_OKAY) { 01351 if (!mp_iszero(Q->z)) { 01352 /* T1 = Z' * Z' */ 01353 err = mp_sqr(Q->z, &t1); 01354 if (err == MP_OKAY) 01355 err = mp_montgomery_reduce(&t1, modulus, mp); 01356 01357 /* X = X * T1 */ 01358 if (err == MP_OKAY) 01359 err = mp_mul(&t1, x, x); 01360 if (err == MP_OKAY) 01361 err = mp_montgomery_reduce(x, modulus, mp); 01362 01363 /* T1 = Z' * T1 */ 01364 if (err == MP_OKAY) 01365 err = mp_mul(Q->z, &t1, &t1); 01366 if (err == MP_OKAY) 01367 err = mp_montgomery_reduce(&t1, modulus, mp); 01368 01369 /* Y = Y * T1 */ 01370 if (err == MP_OKAY) 01371 err = mp_mul(&t1, y, y); 01372 if (err == MP_OKAY) 01373 err = mp_montgomery_reduce(y, modulus, mp); 01374 } 01375 } 01376 01377 /* T1 = Z*Z */ 01378 if (err == MP_OKAY) 01379 err = mp_sqr(z, &t1); 01380 if (err == MP_OKAY) 01381 err = mp_montgomery_reduce(&t1, modulus, mp); 01382 01383 /* T2 = X' * T1 */ 01384 if (err == MP_OKAY) 01385 err = mp_mul(Q->x, &t1, &t2); 01386 if (err == MP_OKAY) 01387 err = mp_montgomery_reduce(&t2, modulus, mp); 01388 01389 /* T1 = Z * T1 */ 01390 if (err == MP_OKAY) 01391 err = mp_mul(z, &t1, &t1); 01392 if (err == MP_OKAY) 01393 err = mp_montgomery_reduce(&t1, modulus, mp); 01394 01395 /* T1 = Y' * T1 */ 01396 if (err == MP_OKAY) 01397 err = mp_mul(Q->y, &t1, &t1); 01398 if (err == MP_OKAY) 01399 err = mp_montgomery_reduce(&t1, modulus, mp); 01400 01401 /* Y = Y - T1 */ 01402 if (err == MP_OKAY) 01403 err = mp_sub(y, &t1, y); 01404 if (err == MP_OKAY) { 01405 if (mp_isneg(y)) 01406 err = mp_add(y, modulus, y); 01407 } 01408 /* T1 = 2T1 */ 01409 if (err == MP_OKAY) 01410 err = mp_add(&t1, &t1, &t1); 01411 if (err == MP_OKAY) { 01412 if (mp_cmp(&t1, modulus) != MP_LT) 01413 err = mp_sub(&t1, modulus, &t1); 01414 } 01415 /* T1 = Y + T1 */ 01416 if (err == MP_OKAY) 01417 err = mp_add(&t1, y, &t1); 01418 if (err == MP_OKAY) { 01419 if (mp_cmp(&t1, modulus) != MP_LT) 01420 err = mp_sub(&t1, modulus, &t1); 01421 } 01422 /* X = X - T2 */ 01423 if (err == MP_OKAY) 01424 err = mp_sub(x, &t2, x); 01425 if (err == MP_OKAY) { 01426 if (mp_isneg(x)) 01427 err = mp_add(x, modulus, x); 01428 } 01429 /* T2 = 2T2 */ 01430 if (err == MP_OKAY) 01431 err = mp_add(&t2, &t2, &t2); 01432 if (err == MP_OKAY) { 01433 if (mp_cmp(&t2, modulus) != MP_LT) 01434 err = mp_sub(&t2, modulus, &t2); 01435 } 01436 /* T2 = X + T2 */ 01437 if (err == MP_OKAY) 01438 err = mp_add(&t2, x, &t2); 01439 if (err == MP_OKAY) { 01440 if (mp_cmp(&t2, modulus) != MP_LT) 01441 err = mp_sub(&t2, modulus, &t2); 01442 } 01443 01444 if (err == MP_OKAY) { 01445 if (!mp_iszero(Q->z)) { 01446 /* Z = Z * Z' */ 01447 err = mp_mul(z, Q->z, z); 01448 if (err == MP_OKAY) 01449 err = mp_montgomery_reduce(z, modulus, mp); 01450 } 01451 } 01452 01453 /* Z = Z * X */ 01454 if (err == MP_OKAY) 01455 err = mp_mul(z, x, z); 01456 if (err == MP_OKAY) 01457 err = mp_montgomery_reduce(z, modulus, mp); 01458 01459 /* T1 = T1 * X */ 01460 if (err == MP_OKAY) 01461 err = mp_mul(&t1, x, &t1); 01462 if (err == MP_OKAY) 01463 err = mp_montgomery_reduce(&t1, modulus, mp); 01464 01465 /* X = X * X */ 01466 if (err == MP_OKAY) 01467 err = mp_sqr(x, x); 01468 if (err == MP_OKAY) 01469 err = mp_montgomery_reduce(x, modulus, mp); 01470 01471 /* T2 = T2 * x */ 01472 if (err == MP_OKAY) 01473 err = mp_mul(&t2, x, &t2); 01474 if (err == MP_OKAY) 01475 err = mp_montgomery_reduce(&t2, modulus, mp); 01476 01477 /* T1 = T1 * X */ 01478 if (err == MP_OKAY) 01479 err = mp_mul(&t1, x, &t1); 01480 if (err == MP_OKAY) 01481 err = mp_montgomery_reduce(&t1, modulus, mp); 01482 01483 /* X = Y*Y */ 01484 if (err == MP_OKAY) 01485 err = mp_sqr(y, x); 01486 if (err == MP_OKAY) 01487 err = mp_montgomery_reduce(x, modulus, mp); 01488 01489 /* X = X - T2 */ 01490 if (err == MP_OKAY) 01491 err = mp_sub(x, &t2, x); 01492 if (err == MP_OKAY) { 01493 if (mp_isneg(x)) 01494 err = mp_add(x, modulus, x); 01495 } 01496 /* T2 = T2 - X */ 01497 if (err == MP_OKAY) 01498 err = mp_sub(&t2, x, &t2); 01499 if (err == MP_OKAY) { 01500 if (mp_isneg(&t2)) 01501 err = mp_add(&t2, modulus, &t2); 01502 } 01503 /* T2 = T2 - X */ 01504 if (err == MP_OKAY) 01505 err = mp_sub(&t2, x, &t2); 01506 if (err == MP_OKAY) { 01507 if (mp_isneg(&t2)) 01508 err = mp_add(&t2, modulus, &t2); 01509 } 01510 /* T2 = T2 * Y */ 01511 if (err == MP_OKAY) 01512 err = mp_mul(&t2, y, &t2); 01513 if (err == MP_OKAY) 01514 err = mp_montgomery_reduce(&t2, modulus, mp); 01515 01516 /* Y = T2 - T1 */ 01517 if (err == MP_OKAY) 01518 err = mp_sub(&t2, &t1, y); 01519 if (err == MP_OKAY) { 01520 if (mp_isneg(y)) 01521 err = mp_add(y, modulus, y); 01522 } 01523 /* Y = Y/2 */ 01524 if (err == MP_OKAY) { 01525 if (mp_isodd(y) == MP_YES) 01526 err = mp_add(y, modulus, y); 01527 } 01528 if (err == MP_OKAY) 01529 err = mp_div_2(y, y); 01530 01531 #ifdef ALT_ECC_SIZE 01532 if (err == MP_OKAY) 01533 err = mp_copy(x, R->x); 01534 if (err == MP_OKAY) 01535 err = mp_copy(y, R->y); 01536 if (err == MP_OKAY) 01537 err = mp_copy(z, R->z); 01538 #endif 01539 01540 done: 01541 01542 /* clean up */ 01543 mp_clear(&t1); 01544 mp_clear(&t2); 01545 01546 return err; 01547 } 01548 01549 /* ### Point doubling in Jacobian coordinate system ### 01550 * 01551 * let us have a curve: y^2 = x^3 + a*x + b 01552 * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6 01553 * 01554 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where: 01555 * Xr = M^2 - 2*S 01556 * Yr = M * (S - Xr) - 8*T 01557 * Zr = 2 * Yp * Zp 01558 * 01559 * M = 3 * Xp^2 + a*Zp^4 01560 * T = Yp^4 01561 * S = 4 * Xp * Yp^2 01562 * 01563 * SPECIAL CASE: when a == 3 we can compute M as 01564 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2) 01565 */ 01566 01567 /** 01568 Double an ECC point 01569 P The point to double 01570 R [out] The destination of the double 01571 a ECC curve parameter a 01572 modulus The modulus of the field the ECC curve is in 01573 mp The "b" value from montgomery_setup() 01574 return MP_OKAY on success 01575 */ 01576 int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, 01577 mp_int* modulus, mp_digit mp) 01578 { 01579 mp_int t1, t2; 01580 #ifdef ALT_ECC_SIZE 01581 mp_int rx, ry, rz; 01582 #endif 01583 mp_int *x, *y, *z; 01584 int err; 01585 01586 if (P == NULL || R == NULL || modulus == NULL) 01587 return ECC_BAD_ARG_E; 01588 01589 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 01590 return err; 01591 } 01592 01593 /* If use ALT_ECC_SIZE we need to use local stack variable since 01594 ecc_point x,y,z is reduced size */ 01595 #ifdef ALT_ECC_SIZE 01596 /* Use local stack variable */ 01597 x = ℞ 01598 y = &ry; 01599 z = &rz; 01600 01601 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { 01602 mp_clear(&t1); 01603 mp_clear(&t2); 01604 return err; 01605 } 01606 #else 01607 /* Use destination directly */ 01608 x = R->x; 01609 y = R->y; 01610 z = R->z; 01611 #endif 01612 01613 if (err == MP_OKAY) 01614 err = mp_copy(P->x, x); 01615 if (err == MP_OKAY) 01616 err = mp_copy(P->y, y); 01617 if (err == MP_OKAY) 01618 err = mp_copy(P->z, z); 01619 01620 /* T1 = Z * Z */ 01621 if (err == MP_OKAY) 01622 err = mp_sqr(z, &t1); 01623 if (err == MP_OKAY) 01624 err = mp_montgomery_reduce(&t1, modulus, mp); 01625 01626 /* Z = Y * Z */ 01627 if (err == MP_OKAY) 01628 err = mp_mul(z, y, z); 01629 if (err == MP_OKAY) 01630 err = mp_montgomery_reduce(z, modulus, mp); 01631 01632 /* Z = 2Z */ 01633 if (err == MP_OKAY) 01634 err = mp_add(z, z, z); 01635 if (err == MP_OKAY) { 01636 if (mp_cmp(z, modulus) != MP_LT) 01637 err = mp_sub(z, modulus, z); 01638 } 01639 01640 /* Determine if curve "a" should be used in calc */ 01641 #ifdef WOLFSSL_CUSTOM_CURVES 01642 if (err == MP_OKAY) { 01643 /* Use a and prime to determine if a == 3 */ 01644 err = mp_submod(modulus, a, modulus, &t2); 01645 } 01646 if (err == MP_OKAY && mp_cmp_d(&t2, 3) != MP_EQ) { 01647 /* use "a" in calc */ 01648 01649 /* T2 = T1 * T1 */ 01650 if (err == MP_OKAY) 01651 err = mp_sqr(&t1, &t2); 01652 if (err == MP_OKAY) 01653 err = mp_montgomery_reduce(&t2, modulus, mp); 01654 /* T1 = T2 * a */ 01655 if (err == MP_OKAY) 01656 err = mp_mulmod(&t2, a, modulus, &t1); 01657 /* T2 = X * X */ 01658 if (err == MP_OKAY) 01659 err = mp_sqr(x, &t2); 01660 if (err == MP_OKAY) 01661 err = mp_montgomery_reduce(&t2, modulus, mp); 01662 /* T1 = T2 + T1 */ 01663 if (err == MP_OKAY) 01664 err = mp_add(&t1, &t2, &t1); 01665 if (err == MP_OKAY) { 01666 if (mp_cmp(&t1, modulus) != MP_LT) 01667 err = mp_sub(&t1, modulus, &t1); 01668 } 01669 /* T1 = T2 + T1 */ 01670 if (err == MP_OKAY) 01671 err = mp_add(&t1, &t2, &t1); 01672 if (err == MP_OKAY) { 01673 if (mp_cmp(&t1, modulus) != MP_LT) 01674 err = mp_sub(&t1, modulus, &t1); 01675 } 01676 /* T1 = T2 + T1 */ 01677 if (err == MP_OKAY) 01678 err = mp_add(&t1, &t2, &t1); 01679 if (err == MP_OKAY) { 01680 if (mp_cmp(&t1, modulus) != MP_LT) 01681 err = mp_sub(&t1, modulus, &t1); 01682 } 01683 } 01684 else 01685 #endif /* WOLFSSL_CUSTOM_CURVES */ 01686 { 01687 /* assumes "a" == 3 */ 01688 (void)a; 01689 01690 /* T2 = X - T1 */ 01691 if (err == MP_OKAY) 01692 err = mp_sub(x, &t1, &t2); 01693 if (err == MP_OKAY) { 01694 if (mp_isneg(&t2)) 01695 err = mp_add(&t2, modulus, &t2); 01696 } 01697 /* T1 = X + T1 */ 01698 if (err == MP_OKAY) 01699 err = mp_add(&t1, x, &t1); 01700 if (err == MP_OKAY) { 01701 if (mp_cmp(&t1, modulus) != MP_LT) 01702 err = mp_sub(&t1, modulus, &t1); 01703 } 01704 /* T2 = T1 * T2 */ 01705 if (err == MP_OKAY) 01706 err = mp_mul(&t1, &t2, &t2); 01707 if (err == MP_OKAY) 01708 err = mp_montgomery_reduce(&t2, modulus, mp); 01709 01710 /* T1 = 2T2 */ 01711 if (err == MP_OKAY) 01712 err = mp_add(&t2, &t2, &t1); 01713 if (err == MP_OKAY) { 01714 if (mp_cmp(&t1, modulus) != MP_LT) 01715 err = mp_sub(&t1, modulus, &t1); 01716 } 01717 /* T1 = T1 + T2 */ 01718 if (err == MP_OKAY) 01719 err = mp_add(&t1, &t2, &t1); 01720 if (err == MP_OKAY) { 01721 if (mp_cmp(&t1, modulus) != MP_LT) 01722 err = mp_sub(&t1, modulus, &t1); 01723 } 01724 } 01725 01726 /* Y = 2Y */ 01727 if (err == MP_OKAY) 01728 err = mp_add(y, y, y); 01729 if (err == MP_OKAY) { 01730 if (mp_cmp(y, modulus) != MP_LT) 01731 err = mp_sub(y, modulus, y); 01732 } 01733 /* Y = Y * Y */ 01734 if (err == MP_OKAY) 01735 err = mp_sqr(y, y); 01736 if (err == MP_OKAY) 01737 err = mp_montgomery_reduce(y, modulus, mp); 01738 01739 /* T2 = Y * Y */ 01740 if (err == MP_OKAY) 01741 err = mp_sqr(y, &t2); 01742 if (err == MP_OKAY) 01743 err = mp_montgomery_reduce(&t2, modulus, mp); 01744 01745 /* T2 = T2/2 */ 01746 if (err == MP_OKAY) { 01747 if (mp_isodd(&t2) == MP_YES) 01748 err = mp_add(&t2, modulus, &t2); 01749 } 01750 if (err == MP_OKAY) 01751 err = mp_div_2(&t2, &t2); 01752 01753 /* Y = Y * X */ 01754 if (err == MP_OKAY) 01755 err = mp_mul(y, x, y); 01756 if (err == MP_OKAY) 01757 err = mp_montgomery_reduce(y, modulus, mp); 01758 01759 /* X = T1 * T1 */ 01760 if (err == MP_OKAY) 01761 err = mp_sqr(&t1, x); 01762 if (err == MP_OKAY) 01763 err = mp_montgomery_reduce(x, modulus, mp); 01764 01765 /* X = X - Y */ 01766 if (err == MP_OKAY) 01767 err = mp_sub(x, y, x); 01768 if (err == MP_OKAY) { 01769 if (mp_isneg(x)) 01770 err = mp_add(x, modulus, x); 01771 } 01772 /* X = X - Y */ 01773 if (err == MP_OKAY) 01774 err = mp_sub(x, y, x); 01775 if (err == MP_OKAY) { 01776 if (mp_isneg(x)) 01777 err = mp_add(x, modulus, x); 01778 } 01779 01780 /* Y = Y - X */ 01781 if (err == MP_OKAY) 01782 err = mp_sub(y, x, y); 01783 if (err == MP_OKAY) { 01784 if (mp_isneg(y)) 01785 err = mp_add(y, modulus, y); 01786 } 01787 /* Y = Y * T1 */ 01788 if (err == MP_OKAY) 01789 err = mp_mul(y, &t1, y); 01790 if (err == MP_OKAY) 01791 err = mp_montgomery_reduce(y, modulus, mp); 01792 01793 /* Y = Y - T2 */ 01794 if (err == MP_OKAY) 01795 err = mp_sub(y, &t2, y); 01796 if (err == MP_OKAY) { 01797 if (mp_isneg(y)) 01798 err = mp_add(y, modulus, y); 01799 } 01800 01801 #ifdef ALT_ECC_SIZE 01802 if (err == MP_OKAY) 01803 err = mp_copy(x, R->x); 01804 if (err == MP_OKAY) 01805 err = mp_copy(y, R->y); 01806 if (err == MP_OKAY) 01807 err = mp_copy(z, R->z); 01808 #endif 01809 01810 /* clean up */ 01811 mp_clear(&t1); 01812 mp_clear(&t2); 01813 01814 return err; 01815 } 01816 01817 01818 /** 01819 Map a projective jacbobian point back to affine space 01820 P [in/out] The point to map 01821 modulus The modulus of the field the ECC curve is in 01822 mp The "b" value from montgomery_setup() 01823 return MP_OKAY on success 01824 */ 01825 int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) 01826 { 01827 mp_int t1, t2; 01828 #ifdef ALT_ECC_SIZE 01829 mp_int rx, ry, rz; 01830 #endif 01831 mp_int *x, *y, *z; 01832 int err; 01833 01834 if (P == NULL || modulus == NULL) 01835 return ECC_BAD_ARG_E; 01836 01837 /* special case for point at infinity */ 01838 if (mp_cmp_d(P->z, 0) == MP_EQ) { 01839 err = mp_set(P->x, 0); 01840 if (err == MP_OKAY) 01841 err = mp_set(P->y, 0); 01842 if (err == MP_OKAY) 01843 err = mp_set(P->z, 1); 01844 return err; 01845 } 01846 01847 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 01848 return MEMORY_E; 01849 } 01850 01851 #ifdef ALT_ECC_SIZE 01852 /* Use local stack variable */ 01853 x = ℞ 01854 y = &ry; 01855 z = &rz; 01856 01857 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { 01858 goto done; 01859 } 01860 01861 if (err == MP_OKAY) 01862 err = mp_copy(P->x, x); 01863 if (err == MP_OKAY) 01864 err = mp_copy(P->y, y); 01865 if (err == MP_OKAY) 01866 err = mp_copy(P->z, z); 01867 01868 if (err != MP_OKAY) { 01869 goto done; 01870 } 01871 #else 01872 /* Use destination directly */ 01873 x = P->x; 01874 y = P->y; 01875 z = P->z; 01876 #endif 01877 01878 /* first map z back to normal */ 01879 err = mp_montgomery_reduce(z, modulus, mp); 01880 01881 /* get 1/z */ 01882 if (err == MP_OKAY) 01883 err = mp_invmod(z, modulus, &t1); 01884 01885 /* get 1/z^2 and 1/z^3 */ 01886 if (err == MP_OKAY) 01887 err = mp_sqr(&t1, &t2); 01888 if (err == MP_OKAY) 01889 err = mp_mod(&t2, modulus, &t2); 01890 if (err == MP_OKAY) 01891 err = mp_mul(&t1, &t2, &t1); 01892 if (err == MP_OKAY) 01893 err = mp_mod(&t1, modulus, &t1); 01894 01895 /* multiply against x/y */ 01896 if (err == MP_OKAY) 01897 err = mp_mul(x, &t2, x); 01898 if (err == MP_OKAY) 01899 err = mp_montgomery_reduce(x, modulus, mp); 01900 if (err == MP_OKAY) 01901 err = mp_mul(y, &t1, y); 01902 if (err == MP_OKAY) 01903 err = mp_montgomery_reduce(y, modulus, mp); 01904 01905 if (err == MP_OKAY) 01906 err = mp_set(z, 1); 01907 01908 #ifdef ALT_ECC_SIZE 01909 /* return result */ 01910 if (err == MP_OKAY) 01911 err = mp_copy(x, P->x); 01912 if (err == MP_OKAY) 01913 err = mp_copy(y, P->y); 01914 if (err == MP_OKAY) 01915 err = mp_copy(z, P->z); 01916 01917 done: 01918 #endif 01919 01920 /* clean up */ 01921 mp_clear(&t1); 01922 mp_clear(&t2); 01923 01924 return err; 01925 } 01926 01927 #if !defined(FREESCALE_LTC_ECC) 01928 01929 #ifndef WC_NO_CACHE_RESISTANT 01930 #if defined(TFM_TIMING_RESISTANT) && defined(USE_FAST_MATH) && \ 01931 !defined(__cplusplus) 01932 /* let's use the one we already have */ 01933 extern const wolfssl_word wc_off_on_addr[2]; 01934 #else 01935 static const wolfssl_word wc_off_on_addr[2] = 01936 { 01937 #if defined(WC_64BIT_CPU) 01938 W64LIT(0x0000000000000000), 01939 W64LIT(0xffffffffffffffff) 01940 #elif defined(WC_16BIT_CPU) 01941 0x0000U, 01942 0xffffU 01943 #else 01944 /* 32 bit */ 01945 0x00000000U, 01946 0xffffffffU 01947 #endif 01948 }; 01949 #endif /* TFM_TIMING_RESISTANT && USE_FAST_MATH */ 01950 #endif /* WC_NO_CACHE_RESISTANT */ 01951 01952 /** 01953 Perform a point multiplication 01954 k The scalar to multiply by 01955 G The base point 01956 R [out] Destination for kG 01957 a ECC curve parameter a 01958 modulus The modulus of the field the ECC curve is in 01959 map Boolean whether to map back to affine or not 01960 (1==map, 0 == leave in projective) 01961 return MP_OKAY on success 01962 */ 01963 #ifdef FP_ECC 01964 static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, 01965 mp_int* a, mp_int* modulus, int map, 01966 void* heap) 01967 #else 01968 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, 01969 mp_int* a, mp_int* modulus, int map, 01970 void* heap) 01971 #endif 01972 { 01973 #ifndef ECC_TIMING_RESISTANT 01974 /* size of sliding window, don't change this! */ 01975 #define WINSIZE 4 01976 #define M_POINTS 8 01977 int first = 1, bitbuf = 0, bitcpy = 0, j; 01978 #else 01979 #define M_POINTS 3 01980 #endif 01981 01982 ecc_point *tG, *M[M_POINTS]; 01983 int i, err; 01984 mp_int mu; 01985 mp_digit mp; 01986 mp_digit buf; 01987 int bitcnt = 0, mode = 0, digidx = 0; 01988 01989 if (k == NULL || G == NULL || R == NULL || modulus == NULL) { 01990 return ECC_BAD_ARG_E; 01991 } 01992 01993 /* init variables */ 01994 tG = NULL; 01995 XMEMSET(M, 0, sizeof(M)); 01996 01997 /* init montgomery reduction */ 01998 if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { 01999 return err; 02000 } 02001 02002 if ((err = mp_init(&mu)) != MP_OKAY) { 02003 return err; 02004 } 02005 if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) { 02006 mp_clear(&mu); 02007 return err; 02008 } 02009 02010 /* alloc ram for window temps */ 02011 for (i = 0; i < M_POINTS; i++) { 02012 M[i] = wc_ecc_new_point_h(heap); 02013 if (M[i] == NULL) { 02014 mp_clear(&mu); 02015 err = MEMORY_E; goto exit; 02016 } 02017 } 02018 02019 /* make a copy of G in case R==G */ 02020 tG = wc_ecc_new_point_h(heap); 02021 if (tG == NULL) 02022 err = MEMORY_E; 02023 02024 /* tG = G and convert to montgomery */ 02025 if (err == MP_OKAY) { 02026 if (mp_cmp_d(&mu, 1) == MP_EQ) { 02027 err = mp_copy(G->x, tG->x); 02028 if (err == MP_OKAY) 02029 err = mp_copy(G->y, tG->y); 02030 if (err == MP_OKAY) 02031 err = mp_copy(G->z, tG->z); 02032 } else { 02033 err = mp_mulmod(G->x, &mu, modulus, tG->x); 02034 if (err == MP_OKAY) 02035 err = mp_mulmod(G->y, &mu, modulus, tG->y); 02036 if (err == MP_OKAY) 02037 err = mp_mulmod(G->z, &mu, modulus, tG->z); 02038 } 02039 } 02040 02041 /* done with mu */ 02042 mp_clear(&mu); 02043 02044 #ifndef ECC_TIMING_RESISTANT 02045 02046 /* calc the M tab, which holds kG for k==8..15 */ 02047 /* M[0] == 8G */ 02048 if (err == MP_OKAY) 02049 err = ecc_projective_dbl_point(tG, M[0], a, modulus, mp); 02050 if (err == MP_OKAY) 02051 err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp); 02052 if (err == MP_OKAY) 02053 err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp); 02054 02055 /* now find (8+k)G for k=1..7 */ 02056 if (err == MP_OKAY) 02057 for (j = 9; j < 16; j++) { 02058 err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, 02059 modulus, mp); 02060 if (err != MP_OKAY) break; 02061 } 02062 02063 /* setup sliding window */ 02064 if (err == MP_OKAY) { 02065 mode = 0; 02066 bitcnt = 1; 02067 buf = 0; 02068 digidx = get_digit_count(k) - 1; 02069 bitcpy = bitbuf = 0; 02070 first = 1; 02071 02072 /* perform ops */ 02073 for (;;) { 02074 /* grab next digit as required */ 02075 if (--bitcnt == 0) { 02076 if (digidx == -1) { 02077 break; 02078 } 02079 buf = get_digit(k, digidx); 02080 bitcnt = (int) DIGIT_BIT; 02081 --digidx; 02082 } 02083 02084 /* grab the next msb from the ltiplicand */ 02085 i = (int)(buf >> (DIGIT_BIT - 1)) & 1; 02086 buf <<= 1; 02087 02088 /* skip leading zero bits */ 02089 if (mode == 0 && i == 0) 02090 continue; 02091 02092 /* if the bit is zero and mode == 1 then we double */ 02093 if (mode == 1 && i == 0) { 02094 err = ecc_projective_dbl_point(R, R, a, modulus, mp); 02095 if (err != MP_OKAY) break; 02096 continue; 02097 } 02098 02099 /* else we add it to the window */ 02100 bitbuf |= (i << (WINSIZE - ++bitcpy)); 02101 mode = 2; 02102 02103 if (bitcpy == WINSIZE) { 02104 /* if this is the first window we do a simple copy */ 02105 if (first == 1) { 02106 /* R = kG [k = first window] */ 02107 err = mp_copy(M[bitbuf-M_POINTS]->x, R->x); 02108 if (err != MP_OKAY) break; 02109 02110 err = mp_copy(M[bitbuf-M_POINTS]->y, R->y); 02111 if (err != MP_OKAY) break; 02112 02113 err = mp_copy(M[bitbuf-M_POINTS]->z, R->z); 02114 first = 0; 02115 } else { 02116 /* normal window */ 02117 /* ok window is filled so double as required and add */ 02118 /* double first */ 02119 for (j = 0; j < WINSIZE; j++) { 02120 err = ecc_projective_dbl_point(R, R, a, modulus, mp); 02121 if (err != MP_OKAY) break; 02122 } 02123 if (err != MP_OKAY) break; /* out of first for(;;) */ 02124 02125 /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ 02126 err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a, 02127 modulus, mp); 02128 } 02129 if (err != MP_OKAY) break; 02130 /* empty window and reset */ 02131 bitcpy = bitbuf = 0; 02132 mode = 1; 02133 } 02134 } 02135 } 02136 02137 /* if bits remain then double/add */ 02138 if (err == MP_OKAY) { 02139 if (mode == 2 && bitcpy > 0) { 02140 /* double then add */ 02141 for (j = 0; j < bitcpy; j++) { 02142 /* only double if we have had at least one add first */ 02143 if (first == 0) { 02144 err = ecc_projective_dbl_point(R, R, a, modulus, mp); 02145 if (err != MP_OKAY) break; 02146 } 02147 02148 bitbuf <<= 1; 02149 if ((bitbuf & (1 << WINSIZE)) != 0) { 02150 if (first == 1) { 02151 /* first add, so copy */ 02152 err = mp_copy(tG->x, R->x); 02153 if (err != MP_OKAY) break; 02154 02155 err = mp_copy(tG->y, R->y); 02156 if (err != MP_OKAY) break; 02157 02158 err = mp_copy(tG->z, R->z); 02159 if (err != MP_OKAY) break; 02160 first = 0; 02161 } else { 02162 /* then add */ 02163 err = ecc_projective_add_point(R, tG, R, a, modulus, 02164 mp); 02165 if (err != MP_OKAY) break; 02166 } 02167 } 02168 } 02169 } 02170 } 02171 02172 #undef WINSIZE 02173 02174 #else /* ECC_TIMING_RESISTANT */ 02175 02176 /* calc the M tab */ 02177 /* M[0] == G */ 02178 if (err == MP_OKAY) 02179 err = mp_copy(tG->x, M[0]->x); 02180 if (err == MP_OKAY) 02181 err = mp_copy(tG->y, M[0]->y); 02182 if (err == MP_OKAY) 02183 err = mp_copy(tG->z, M[0]->z); 02184 02185 /* M[1] == 2G */ 02186 if (err == MP_OKAY) 02187 err = ecc_projective_dbl_point(tG, M[1], a, modulus, mp); 02188 02189 /* setup sliding window */ 02190 mode = 0; 02191 bitcnt = 1; 02192 buf = 0; 02193 digidx = get_digit_count(k) - 1; 02194 02195 /* perform ops */ 02196 if (err == MP_OKAY) { 02197 for (;;) { 02198 /* grab next digit as required */ 02199 if (--bitcnt == 0) { 02200 if (digidx == -1) { 02201 break; 02202 } 02203 buf = get_digit(k, digidx); 02204 bitcnt = (int)DIGIT_BIT; 02205 --digidx; 02206 } 02207 02208 /* grab the next msb from the multiplicand */ 02209 i = (buf >> (DIGIT_BIT - 1)) & 1; 02210 buf <<= 1; 02211 02212 if (mode == 0 && i == 0) { 02213 /* timing resistant - dummy operations */ 02214 if (err == MP_OKAY) 02215 err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus, 02216 mp); 02217 if (err == MP_OKAY) 02218 err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp); 02219 if (err == MP_OKAY) 02220 continue; 02221 } 02222 02223 if (mode == 0 && i == 1) { 02224 mode = 1; 02225 /* timing resistant - dummy operations */ 02226 if (err == MP_OKAY) 02227 err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus, 02228 mp); 02229 if (err == MP_OKAY) 02230 err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp); 02231 if (err == MP_OKAY) 02232 continue; 02233 } 02234 02235 if (err == MP_OKAY) 02236 err = ecc_projective_add_point(M[0], M[1], M[i^1], a, modulus, 02237 mp); 02238 #ifdef WC_NO_CACHE_RESISTANT 02239 if (err == MP_OKAY) 02240 err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp); 02241 #else 02242 /* instead of using M[i] for double, which leaks key bit to cache 02243 * monitor, use M[2] as temp, make sure address calc is constant, 02244 * keep M[0] and M[1] in cache */ 02245 if (err == MP_OKAY) 02246 err = mp_copy((mp_int*) 02247 ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) + 02248 ((wolfssl_word)M[1]->x & wc_off_on_addr[i])), 02249 M[2]->x); 02250 if (err == MP_OKAY) 02251 err = mp_copy((mp_int*) 02252 ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) + 02253 ((wolfssl_word)M[1]->y & wc_off_on_addr[i])), 02254 M[2]->y); 02255 if (err == MP_OKAY) 02256 err = mp_copy((mp_int*) 02257 ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) + 02258 ((wolfssl_word)M[1]->z & wc_off_on_addr[i])), 02259 M[2]->z); 02260 if (err == MP_OKAY) 02261 err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp); 02262 /* copy M[2] back to M[i] */ 02263 if (err == MP_OKAY) 02264 err = mp_copy(M[2]->x, 02265 (mp_int*) 02266 ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) + 02267 ((wolfssl_word)M[1]->x & wc_off_on_addr[i])) ); 02268 if (err == MP_OKAY) 02269 err = mp_copy(M[2]->y, 02270 (mp_int*) 02271 ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) + 02272 ((wolfssl_word)M[1]->y & wc_off_on_addr[i])) ); 02273 if (err == MP_OKAY) 02274 err = mp_copy(M[2]->z, 02275 (mp_int*) 02276 ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) + 02277 ((wolfssl_word)M[1]->z & wc_off_on_addr[i])) ); 02278 if (err != MP_OKAY) 02279 break; 02280 #endif /* WC_NO_CACHE_RESISTANT */ 02281 } /* end for */ 02282 } 02283 02284 /* copy result out */ 02285 if (err == MP_OKAY) 02286 err = mp_copy(M[0]->x, R->x); 02287 if (err == MP_OKAY) 02288 err = mp_copy(M[0]->y, R->y); 02289 if (err == MP_OKAY) 02290 err = mp_copy(M[0]->z, R->z); 02291 02292 #endif /* ECC_TIMING_RESISTANT */ 02293 02294 /* map R back from projective space */ 02295 if (err == MP_OKAY && map) 02296 err = ecc_map(R, modulus, mp); 02297 02298 exit: 02299 02300 /* done */ 02301 wc_ecc_del_point_h(tG, heap); 02302 for (i = 0; i < M_POINTS; i++) { 02303 wc_ecc_del_point_h(M[i], heap); 02304 } 02305 02306 return err; 02307 } 02308 02309 /** ECC Fixed Point mulmod global 02310 k The multiplicand 02311 G Base point to multiply 02312 R [out] Destination of product 02313 a ECC curve parameter a 02314 modulus The modulus for the curve 02315 map [boolean] If non-zero maps the point back to affine co-ordinates, 02316 otherwise it's left in jacobian-montgomery form 02317 return MP_OKAY if successful 02318 */ 02319 int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, 02320 mp_int* modulus, int map) 02321 { 02322 return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL); 02323 } 02324 02325 #endif /* !FREESCALE_LTC_ECC */ 02326 02327 02328 #ifdef ALT_ECC_SIZE 02329 02330 static void alt_fp_init(fp_int* a) 02331 { 02332 a->size = FP_SIZE_ECC; 02333 fp_zero(a); 02334 } 02335 02336 #endif /* ALT_ECC_SIZE */ 02337 02338 02339 /** 02340 * use a heap hint when creating new ecc_point 02341 * return an allocated point on success or NULL on failure 02342 */ 02343 ecc_point* wc_ecc_new_point_h(void* heap) 02344 { 02345 ecc_point* p; 02346 02347 p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC); 02348 if (p == NULL) { 02349 return NULL; 02350 } 02351 XMEMSET(p, 0, sizeof(ecc_point)); 02352 02353 #ifndef ALT_ECC_SIZE 02354 if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) { 02355 XFREE(p, heap, DYNAMIC_TYPE_ECC); 02356 return NULL; 02357 } 02358 #else 02359 p->x = (mp_int*)&p->xyz[0]; 02360 p->y = (mp_int*)&p->xyz[1]; 02361 p->z = (mp_int*)&p->xyz[2]; 02362 alt_fp_init(p->x); 02363 alt_fp_init(p->y); 02364 alt_fp_init(p->z); 02365 #endif 02366 02367 return p; 02368 } 02369 02370 02371 /** 02372 Allocate a new ECC point 02373 return A newly allocated point or NULL on error 02374 */ 02375 ecc_point* wc_ecc_new_point(void) 02376 { 02377 return wc_ecc_new_point_h(NULL); 02378 } 02379 02380 02381 void wc_ecc_del_point_h(ecc_point* p, void* heap) 02382 { 02383 /* prevents free'ing null arguments */ 02384 if (p != NULL) { 02385 mp_clear(p->x); 02386 mp_clear(p->y); 02387 mp_clear(p->z); 02388 XFREE(p, heap, DYNAMIC_TYPE_ECC); 02389 } 02390 (void)heap; 02391 } 02392 02393 02394 /** Free an ECC point from memory 02395 p The point to free 02396 */ 02397 void wc_ecc_del_point(ecc_point* p) 02398 { 02399 wc_ecc_del_point_h(p, NULL); 02400 } 02401 02402 02403 /** Copy the value of a point to an other one 02404 p The point to copy 02405 r The created point 02406 */ 02407 int wc_ecc_copy_point(ecc_point* p, ecc_point *r) 02408 { 02409 int ret; 02410 02411 /* prevents null arguments */ 02412 if (p == NULL || r == NULL) 02413 return ECC_BAD_ARG_E; 02414 02415 ret = mp_copy(p->x, r->x); 02416 if (ret != MP_OKAY) 02417 return ret; 02418 ret = mp_copy(p->y, r->y); 02419 if (ret != MP_OKAY) 02420 return ret; 02421 ret = mp_copy(p->z, r->z); 02422 if (ret != MP_OKAY) 02423 return ret; 02424 02425 return MP_OKAY; 02426 } 02427 02428 /** Compare the value of a point with an other one 02429 a The point to compare 02430 b The other point to compare 02431 02432 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error 02433 */ 02434 int wc_ecc_cmp_point(ecc_point* a, ecc_point *b) 02435 { 02436 int ret; 02437 02438 /* prevents null arguments */ 02439 if (a == NULL || b == NULL) 02440 return BAD_FUNC_ARG; 02441 02442 ret = mp_cmp(a->x, b->x); 02443 if (ret != MP_EQ) 02444 return ret; 02445 ret = mp_cmp(a->y, b->y); 02446 if (ret != MP_EQ) 02447 return ret; 02448 ret = mp_cmp(a->z, b->z); 02449 if (ret != MP_EQ) 02450 return ret; 02451 02452 return MP_EQ; 02453 } 02454 02455 #endif /* !WOLFSSL_ATECC508A */ 02456 02457 02458 /** Returns whether an ECC idx is valid or not 02459 n The idx number to check 02460 return 1 if valid, 0 if not 02461 */ 02462 int wc_ecc_is_valid_idx(int n) 02463 { 02464 int x; 02465 02466 for (x = 0; ecc_sets[x].size != 0; x++) 02467 ; 02468 /* -1 is a valid index --- indicating that the domain params 02469 were supplied by the user */ 02470 if ((n >= ECC_CUSTOM_IDX) && (n < x)) { 02471 return 1; 02472 } 02473 02474 return 0; 02475 } 02476 02477 int wc_ecc_get_curve_idx(int curve_id) 02478 { 02479 int curve_idx; 02480 for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) { 02481 if (curve_id == ecc_sets[curve_idx].id) 02482 break; 02483 } 02484 if (ecc_sets[curve_idx].size == 0) { 02485 return ECC_CURVE_INVALID; 02486 } 02487 return curve_idx; 02488 } 02489 02490 int wc_ecc_get_curve_id(int curve_idx) 02491 { 02492 if (wc_ecc_is_valid_idx(curve_idx)) { 02493 return ecc_sets[curve_idx].id; 02494 } 02495 return ECC_CURVE_INVALID; 02496 } 02497 02498 /* Returns the curve size that corresponds to a given ecc_curve_id identifier 02499 * 02500 * id curve id, from ecc_curve_id enum in ecc.h 02501 * return curve size, from ecc_sets[] on success, negative on error 02502 */ 02503 int wc_ecc_get_curve_size_from_id(int curve_id) 02504 { 02505 int curve_idx = wc_ecc_get_curve_idx(curve_id); 02506 if (curve_idx == ECC_CURVE_INVALID) 02507 return ECC_BAD_ARG_E; 02508 return ecc_sets[curve_idx].size; 02509 } 02510 02511 /* Returns the curve index that corresponds to a given curve name in 02512 * ecc_sets[] of ecc.c 02513 * 02514 * name curve name, from ecc_sets[].name in ecc.c 02515 * return curve index in ecc_sets[] on success, negative on error 02516 */ 02517 int wc_ecc_get_curve_idx_from_name(const char* curveName) 02518 { 02519 int curve_idx; 02520 word32 len; 02521 02522 if (curveName == NULL) 02523 return BAD_FUNC_ARG; 02524 02525 len = (word32)XSTRLEN(curveName); 02526 02527 for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) { 02528 if (XSTRNCASECMP(ecc_sets[curve_idx].name, curveName, len) == 0) { 02529 break; 02530 } 02531 } 02532 if (ecc_sets[curve_idx].size == 0) { 02533 WOLFSSL_MSG("ecc_set curve name not found"); 02534 return ECC_CURVE_INVALID; 02535 } 02536 return curve_idx; 02537 } 02538 02539 /* Returns the curve size that corresponds to a given curve name, 02540 * as listed in ecc_sets[] of ecc.c. 02541 * 02542 * name curve name, from ecc_sets[].name in ecc.c 02543 * return curve size, from ecc_sets[] on success, negative on error 02544 */ 02545 int wc_ecc_get_curve_size_from_name(const char* curveName) 02546 { 02547 int curve_idx; 02548 02549 if (curveName == NULL) 02550 return BAD_FUNC_ARG; 02551 02552 curve_idx = wc_ecc_get_curve_idx_from_name(curveName); 02553 if (curve_idx < 0) 02554 return curve_idx; 02555 02556 return ecc_sets[curve_idx].size; 02557 } 02558 02559 /* Returns the curve id that corresponds to a given curve name, 02560 * as listed in ecc_sets[] of ecc.c. 02561 * 02562 * name curve name, from ecc_sets[].name in ecc.c 02563 * return curve id, from ecc_sets[] on success, negative on error 02564 */ 02565 int wc_ecc_get_curve_id_from_name(const char* curveName) 02566 { 02567 int curve_idx; 02568 02569 if (curveName == NULL) 02570 return BAD_FUNC_ARG; 02571 02572 curve_idx = wc_ecc_get_curve_idx_from_name(curveName); 02573 if (curve_idx < 0) 02574 return curve_idx; 02575 02576 return ecc_sets[curve_idx].id; 02577 } 02578 02579 /* Compares a curve parameter (hex, from ecc_sets[]) to given input 02580 * parameter (byte array) for equality. 02581 * 02582 * Returns MP_EQ on success, negative on error */ 02583 static int wc_ecc_cmp_param(const char* curveParam, 02584 const byte* param, word32 paramSz) 02585 { 02586 int err = MP_OKAY; 02587 mp_int a, b; 02588 02589 if (param == NULL || curveParam == NULL) 02590 return BAD_FUNC_ARG; 02591 02592 if ((err = mp_init_multi(&a, &b, NULL, NULL, NULL, NULL)) != MP_OKAY) 02593 return err; 02594 02595 if (err == MP_OKAY) 02596 err = mp_read_unsigned_bin(&a, param, paramSz); 02597 02598 if (err == MP_OKAY) 02599 err = mp_read_radix(&b, curveParam, 16); 02600 02601 if (err == MP_OKAY) { 02602 if (mp_cmp(&a, &b) != MP_EQ) { 02603 err = -1; 02604 } else { 02605 err = MP_EQ; 02606 } 02607 } 02608 02609 #ifndef USE_FAST_MATH 02610 mp_clear(&a); 02611 mp_clear(&b); 02612 #endif 02613 02614 return err; 02615 } 02616 02617 /* Returns the curve id in ecc_sets[] that corresponds to a given set of 02618 * curve parameters. 02619 * 02620 * fieldSize the field size in bits 02621 * prime prime of the finite field 02622 * primeSz size of prime in octets 02623 * Af first coefficient a of the curve 02624 * AfSz size of Af in octets 02625 * Bf second coefficient b of the curve 02626 * BfSz size of Bf in octets 02627 * order curve order 02628 * orderSz size of curve in octets 02629 * Gx affine x coordinate of base point 02630 * GxSz size of Gx in octets 02631 * Gy affine y coordinate of base point 02632 * GySz size of Gy in octets 02633 * cofactor curve cofactor 02634 * 02635 * return curve id, from ecc_sets[] on success, negative on error 02636 */ 02637 int wc_ecc_get_curve_id_from_params(int fieldSize, 02638 const byte* prime, word32 primeSz, const byte* Af, word32 AfSz, 02639 const byte* Bf, word32 BfSz, const byte* order, word32 orderSz, 02640 const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor) 02641 { 02642 int idx; 02643 int curveSz; 02644 02645 if (prime == NULL || Af == NULL || Bf == NULL || order == NULL || 02646 Gx == NULL || Gy == NULL) 02647 return BAD_FUNC_ARG; 02648 02649 curveSz = (fieldSize + 1) / 8; /* round up */ 02650 02651 for (idx = 0; ecc_sets[idx].size != 0; idx++) { 02652 if (curveSz == ecc_sets[idx].size) { 02653 if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime, 02654 primeSz) == MP_EQ) && 02655 (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz) == MP_EQ) && 02656 (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz) == MP_EQ) && 02657 (wc_ecc_cmp_param(ecc_sets[idx].order, order, 02658 orderSz) == MP_EQ) && 02659 (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz) == MP_EQ) && 02660 (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz) == MP_EQ) && 02661 (cofactor == ecc_sets[idx].cofactor)) { 02662 break; 02663 } 02664 } 02665 } 02666 02667 if (ecc_sets[idx].size == 0) 02668 return ECC_CURVE_INVALID; 02669 02670 return ecc_sets[idx].id; 02671 } 02672 02673 02674 #ifdef HAVE_ECC_DHE 02675 /** 02676 Create an ECC shared secret between two keys 02677 private_key The private ECC key (heap hint based off of private key) 02678 public_key The public key 02679 out [out] Destination of the shared secret 02680 Conforms to EC-DH from ANSI X9.63 02681 outlen [in/out] The max size and resulting size of the shared secret 02682 return MP_OKAY if successful 02683 */ 02684 int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, 02685 word32* outlen) 02686 { 02687 int err; 02688 02689 if (private_key == NULL || public_key == NULL || out == NULL || 02690 outlen == NULL) { 02691 return BAD_FUNC_ARG; 02692 } 02693 02694 /* type valid? */ 02695 if (private_key->type != ECC_PRIVATEKEY) { 02696 return ECC_BAD_ARG_E; 02697 } 02698 02699 /* Verify domain params supplied */ 02700 if (wc_ecc_is_valid_idx(private_key->idx) == 0 || 02701 wc_ecc_is_valid_idx(public_key->idx) == 0) { 02702 return ECC_BAD_ARG_E; 02703 } 02704 02705 /* Verify curve id matches */ 02706 if (private_key->dp->id != public_key->dp->id) { 02707 return ECC_BAD_ARG_E; 02708 } 02709 02710 #ifdef WOLFSSL_ATECC508A 02711 err = atcatls_ecdh(private_key->slot, public_key->pubkey, out); 02712 if (err != ATCA_SUCCESS) { 02713 err = BAD_COND_E; 02714 } 02715 *outlen = private_key->dp->size; 02716 #else 02717 err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen); 02718 #endif /* WOLFSSL_ATECC508A */ 02719 02720 return err; 02721 } 02722 02723 02724 #ifndef WOLFSSL_ATECC508A 02725 02726 static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point, 02727 byte* out, word32 *outlen, ecc_curve_spec* curve) 02728 { 02729 int err; 02730 ecc_point* result = NULL; 02731 word32 x = 0; 02732 mp_int* k = &private_key->k; 02733 #ifdef HAVE_ECC_CDH 02734 mp_int k_lcl; 02735 02736 /* if cofactor flag has been set */ 02737 if (private_key->flags & WC_ECC_FLAG_COFACTOR) { 02738 mp_digit cofactor = (mp_digit)private_key->dp->cofactor; 02739 /* only perform cofactor calc if not equal to 1 */ 02740 if (cofactor != 1) { 02741 k = &k_lcl; 02742 if (mp_init(k) != MP_OKAY) 02743 return MEMORY_E; 02744 /* multiply cofactor times private key "k" */ 02745 err = mp_mul_d(&private_key->k, cofactor, k); 02746 if (err != MP_OKAY) { 02747 mp_clear(k); 02748 return err; 02749 } 02750 } 02751 } 02752 #endif 02753 02754 /* make new point */ 02755 result = wc_ecc_new_point_h(private_key->heap); 02756 if (result == NULL) { 02757 #ifdef HAVE_ECC_CDH 02758 if (k == &k_lcl) 02759 mp_clear(k); 02760 #endif 02761 return MEMORY_E; 02762 } 02763 02764 err = wc_ecc_mulmod_ex(k, point, result, 02765 curve->Af, curve->prime, 1, private_key->heap); 02766 if (err == MP_OKAY) { 02767 x = mp_unsigned_bin_size(curve->prime); 02768 if (*outlen < x) { 02769 err = BUFFER_E; 02770 } 02771 } 02772 02773 if (err == MP_OKAY) { 02774 XMEMSET(out, 0, x); 02775 err = mp_to_unsigned_bin(result->x,out + 02776 (x - mp_unsigned_bin_size(result->x))); 02777 } 02778 *outlen = x; 02779 02780 wc_ecc_del_point_h(result, private_key->heap); 02781 #ifdef HAVE_ECC_CDH 02782 if (k == &k_lcl) 02783 mp_clear(k); 02784 #endif 02785 02786 return err; 02787 } 02788 02789 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 02790 static int wc_ecc_shared_secret_gen_async(ecc_key* private_key, 02791 ecc_point* point, byte* out, word32 *outlen, 02792 ecc_curve_spec* curve) 02793 { 02794 int err; 02795 02796 #ifdef HAVE_CAVIUM 02797 /* TODO: Not implemented - use software for now */ 02798 err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve); 02799 02800 #elif defined(HAVE_INTEL_QA) 02801 /* sync public key x/y */ 02802 err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF); 02803 if (err == MP_OKAY) 02804 err = wc_mp_to_bigint(&private_key->k, &private_key->k.raw); 02805 if (err == MP_OKAY) 02806 err = wc_mp_to_bigint(point->x, &point->x->raw); 02807 if (err == MP_OKAY) 02808 err = wc_mp_to_bigint(point->y, &point->y->raw); 02809 if (err == MP_OKAY) 02810 err = IntelQaEcdh(&private_key->asyncDev, 02811 &private_key->k.raw, &point->x->raw, &point->y->raw, 02812 out, outlen, 02813 &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw, 02814 private_key->dp->cofactor); 02815 #else /* WOLFSSL_ASYNC_CRYPT_TEST */ 02816 WC_ASYNC_TEST* testDev = &private_key->asyncDev.test; 02817 if (testDev->type == ASYNC_TEST_NONE) { 02818 testDev->type = ASYNC_TEST_ECC_SHARED_SEC; 02819 testDev->eccSharedSec.private_key = private_key; 02820 testDev->eccSharedSec.public_point = point; 02821 testDev->eccSharedSec.out = out; 02822 testDev->eccSharedSec.outLen = outlen; 02823 return WC_PENDING_E; 02824 } 02825 err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve); 02826 #endif 02827 02828 return err; 02829 } 02830 #endif /* WOLFSSL_ASYNC_CRYPT */ 02831 02832 int wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point, 02833 byte* out, word32 *outlen) 02834 { 02835 int err; 02836 DECLARE_CURVE_SPECS(2) 02837 02838 if (private_key == NULL || point == NULL || out == NULL || 02839 outlen == NULL) { 02840 return BAD_FUNC_ARG; 02841 } 02842 02843 /* load curve info */ 02844 err = wc_ecc_curve_load(private_key->dp, &curve, 02845 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF)); 02846 if (err != MP_OKAY) 02847 return err; 02848 02849 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 02850 if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 02851 err = wc_ecc_shared_secret_gen_async(private_key, point, 02852 out, outlen, curve); 02853 } 02854 else 02855 #endif 02856 { 02857 err = wc_ecc_shared_secret_gen_sync(private_key, point, 02858 out, outlen, curve); 02859 } 02860 02861 wc_ecc_curve_free(curve); 02862 02863 return err; 02864 } 02865 02866 /** 02867 Create an ECC shared secret between private key and public point 02868 private_key The private ECC key (heap hint based on private key) 02869 point The point to use (public key) 02870 out [out] Destination of the shared secret 02871 Conforms to EC-DH from ANSI X9.63 02872 outlen [in/out] The max size and resulting size of the shared secret 02873 return MP_OKAY if successful 02874 */ 02875 int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, 02876 byte* out, word32 *outlen) 02877 { 02878 int err; 02879 02880 if (private_key == NULL || point == NULL || out == NULL || 02881 outlen == NULL) { 02882 return BAD_FUNC_ARG; 02883 } 02884 02885 /* type valid? */ 02886 if (private_key->type != ECC_PRIVATEKEY) { 02887 return ECC_BAD_ARG_E; 02888 } 02889 02890 /* Verify domain params supplied */ 02891 if (wc_ecc_is_valid_idx(private_key->idx) == 0) 02892 return ECC_BAD_ARG_E; 02893 02894 switch(private_key->state) { 02895 case ECC_STATE_NONE: 02896 case ECC_STATE_SHARED_SEC_GEN: 02897 private_key->state = ECC_STATE_SHARED_SEC_GEN; 02898 02899 err = wc_ecc_shared_secret_gen(private_key, point, out, outlen); 02900 if (err < 0) { 02901 break; 02902 } 02903 02904 /* fall through */ 02905 case ECC_STATE_SHARED_SEC_RES: 02906 private_key->state = ECC_STATE_SHARED_SEC_RES; 02907 err = 0; 02908 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 02909 if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 02910 #if defined(HAVE_CAVIUM) || defined(HAVE_INTEL_QA) 02911 err = private_key->asyncDev.event.ret; 02912 #endif 02913 } 02914 #endif 02915 break; 02916 02917 default: 02918 err = BAD_STATE_E; 02919 } /* switch */ 02920 02921 /* if async pending then return and skip done cleanup below */ 02922 if (err == WC_PENDING_E) { 02923 private_key->state++; 02924 return err; 02925 } 02926 02927 private_key->state = ECC_STATE_NONE; 02928 02929 return err; 02930 } 02931 #endif /* !WOLFSSL_ATECC508A */ 02932 #endif /* HAVE_ECC_DHE */ 02933 02934 02935 #ifndef WOLFSSL_ATECC508A 02936 /* return 1 if point is at infinity, 0 if not, < 0 on error */ 02937 int wc_ecc_point_is_at_infinity(ecc_point* p) 02938 { 02939 if (p == NULL) 02940 return BAD_FUNC_ARG; 02941 02942 if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0) 02943 return 1; 02944 02945 return 0; 02946 } 02947 02948 /* generate random and ensure its greater than 0 and less than order */ 02949 static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order) 02950 { 02951 int err; 02952 #ifdef WOLFSSL_SMALL_STACK 02953 byte* buf; 02954 #else 02955 byte buf[ECC_MAXSIZE_GEN]; 02956 #endif 02957 02958 #ifdef WOLFSSL_SMALL_STACK 02959 buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02960 if (buf == NULL) 02961 return MEMORY_E; 02962 #endif 02963 02964 /*generate 8 extra bytes to mitigate bias from the modulo operation below*/ 02965 /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/ 02966 size += 8; 02967 02968 /* make up random string */ 02969 err = wc_RNG_GenerateBlock(rng, buf, size); 02970 02971 /* load random buffer data into k */ 02972 if (err == 0) 02973 err = mp_read_unsigned_bin(k, (byte*)buf, size); 02974 02975 /* quick sanity check to make sure we're not dealing with a 0 key */ 02976 if (err == MP_OKAY) { 02977 if (mp_iszero(k) == MP_YES) 02978 err = MP_ZERO_E; 02979 } 02980 02981 /* the key should be smaller than the order of base point */ 02982 if (err == MP_OKAY) { 02983 if (mp_cmp(k, order) != MP_LT) { 02984 err = mp_mod(k, order, k); 02985 } 02986 } 02987 02988 ForceZero(buf, ECC_MAXSIZE); 02989 #ifdef WOLFSSL_SMALL_STACK 02990 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02991 #endif 02992 02993 return err; 02994 } 02995 #endif /* !WOLFSSL_ATECC508A */ 02996 02997 int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) 02998 { 02999 int err; 03000 #ifndef WOLFSSL_ATECC508A 03001 ecc_point* base = NULL; 03002 DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT) 03003 #endif 03004 03005 if (key == NULL || rng == NULL) { 03006 return BAD_FUNC_ARG; 03007 } 03008 03009 /* make sure required key variables are reset */ 03010 key->state = ECC_STATE_NONE; 03011 key->idx = 0; 03012 key->dp = NULL; 03013 03014 err = wc_ecc_set_curve(key, keysize, curve_id); 03015 if (err != 0) { 03016 return err; 03017 } 03018 03019 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 03020 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 03021 #ifdef HAVE_CAVIUM 03022 /* TODO: Not implemented */ 03023 #elif defined(HAVE_INTEL_QA) 03024 /* TODO: Not implemented */ 03025 #else 03026 WC_ASYNC_TEST* testDev = &key->asyncDev.test; 03027 if (testDev->type == ASYNC_TEST_NONE) { 03028 testDev->type = ASYNC_TEST_ECC_MAKE; 03029 testDev->eccMake.rng = rng; 03030 testDev->eccMake.key = key; 03031 testDev->eccMake.size = keysize; 03032 testDev->eccMake.curve_id = curve_id; 03033 return WC_PENDING_E; 03034 } 03035 #endif 03036 } 03037 #endif /* WOLFSSL_ASYNC_CRYPT */ 03038 03039 #ifdef WOLFSSL_ATECC508A 03040 key->type = ECC_PRIVATEKEY; 03041 err = atcatls_create_key(key->slot, key->pubkey); 03042 if (err != ATCA_SUCCESS) { 03043 err = BAD_COND_E; 03044 } 03045 03046 #else 03047 03048 /* setup the key variables */ 03049 err = mp_init(&key->k); 03050 if (err == MP_OKAY) { 03051 #ifndef ALT_ECC_SIZE 03052 err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, 03053 NULL, NULL, NULL); 03054 #else 03055 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 03056 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 03057 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 03058 alt_fp_init(key->pubkey.x); 03059 alt_fp_init(key->pubkey.y); 03060 alt_fp_init(key->pubkey.z); 03061 #endif 03062 } 03063 03064 if (err == MP_OKAY) { 03065 base = wc_ecc_new_point_h(key->heap); 03066 if (base == NULL) 03067 err = MEMORY_E; 03068 } 03069 03070 /* load curve info */ 03071 if (err == MP_OKAY) 03072 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); 03073 03074 /* read in the x/y for this key */ 03075 if (err == MP_OKAY) 03076 err = mp_copy(curve->Gx, base->x); 03077 if (err == MP_OKAY) 03078 err = mp_copy(curve->Gy, base->y); 03079 if (err == MP_OKAY) 03080 err = mp_set(base->z, 1); 03081 03082 /* generate k */ 03083 if (err == MP_OKAY) 03084 err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order); 03085 03086 /* make the public key */ 03087 if (err == MP_OKAY) 03088 err = wc_ecc_mulmod_ex(&key->k, base, &key->pubkey, 03089 curve->Af, curve->prime, 1, key->heap); 03090 03091 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN 03092 /* validate the public key, order * pubkey = point at infinity */ 03093 if (err == MP_OKAY) 03094 err = ecc_check_pubkey_order(key, curve->Af, curve->prime, curve->order); 03095 #endif /* WOLFSSL_VALIDATE_KEYGEN */ 03096 03097 if (err == MP_OKAY) 03098 key->type = ECC_PRIVATEKEY; 03099 03100 /* cleanup these on failure case only */ 03101 if (err != MP_OKAY) { 03102 /* clean up */ 03103 #ifndef ALT_ECC_SIZE 03104 mp_clear(key->pubkey.x); 03105 mp_clear(key->pubkey.y); 03106 mp_clear(key->pubkey.z); 03107 #endif 03108 mp_forcezero(&key->k); 03109 } 03110 03111 /* cleanup allocations */ 03112 wc_ecc_del_point_h(base, key->heap); 03113 wc_ecc_curve_free(curve); 03114 03115 #endif /* WOLFSSL_ATECC508A */ 03116 03117 return err; 03118 } 03119 03120 #ifdef ECC_DUMP_OID 03121 /* Optional dump of encoded OID for adding new curves */ 03122 static int mOidDumpDone; 03123 static void wc_ecc_dump_oids(void) 03124 { 03125 int x; 03126 03127 if (mOidDumpDone) { 03128 return; 03129 } 03130 03131 /* find matching OID sum (based on encoded value) */ 03132 for (x = 0; ecc_sets[x].size != 0; x++) { 03133 int i; 03134 byte* oid; 03135 word32 oidSz, sum = 0; 03136 03137 printf("ECC %s (%d):\n", ecc_sets[x].name, x); 03138 03139 #ifdef HAVE_OID_ENCODING 03140 byte oidEnc[ECC_MAX_OID_LEN]; 03141 03142 oid = oidEnc; 03143 oidSz = ECC_MAX_OID_LEN; 03144 03145 printf("OID: "); 03146 for (i = 0; i < (int)ecc_sets[x].oidSz; i++) { 03147 printf("%d.", ecc_sets[x].oid[i]); 03148 } 03149 printf("\n"); 03150 03151 EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz); 03152 #else 03153 oid = (byte*)ecc_sets[x].oid; 03154 oidSz = ecc_sets[x].oidSz; 03155 #endif 03156 03157 printf("OID Encoded: "); 03158 for (i = 0; i < (int)oidSz; i++) { 03159 printf("0x%02X,", oid[i]); 03160 } 03161 printf("\n"); 03162 03163 for (i = 0; i < (int)oidSz; i++) { 03164 sum += oid[i]; 03165 } 03166 printf("Sum: %d\n", sum); 03167 03168 /* validate sum */ 03169 if (ecc_sets[x].oidSum != sum) { 03170 printf(" Sum %d Not Valid!\n", ecc_sets[x].oidSum); 03171 } 03172 } 03173 mOidDumpDone = 1; 03174 } 03175 #endif /* ECC_DUMP_OID */ 03176 03177 /** 03178 Make a new ECC key 03179 rng An active RNG state 03180 keysize The keysize for the new key (in octets from 20 to 65 bytes) 03181 key [out] Destination of the newly created key 03182 return MP_OKAY if successful, 03183 upon error all allocated memory will be freed 03184 */ 03185 int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key) 03186 { 03187 return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF); 03188 } 03189 03190 static INLINE int wc_ecc_alloc_rs(ecc_key* key, mp_int** r, mp_int** s) 03191 { 03192 int err = 0; 03193 03194 #ifndef WOLFSSL_ASYNC_CRYPT 03195 (void)key; 03196 #endif 03197 03198 if (*r == NULL) { 03199 #ifdef WOLFSSL_ASYNC_CRYPT 03200 *r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT); 03201 if (*r == NULL) { 03202 return MEMORY_E; 03203 } 03204 key->r = *r; 03205 #endif 03206 } 03207 if (*s == NULL) { 03208 #ifdef WOLFSSL_ASYNC_CRYPT 03209 *s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT); 03210 if (*s == NULL) { 03211 XFREE(*r, key->heap, DYNAMIC_TYPE_BIGINT); 03212 return MEMORY_E; 03213 } 03214 key->s = *s; 03215 #endif 03216 } 03217 03218 /* initialize mp_int */ 03219 if (*r) 03220 XMEMSET(*r, 0, sizeof(mp_int)); 03221 if (*s) 03222 XMEMSET(*s, 0, sizeof(mp_int)); 03223 03224 return err; 03225 } 03226 03227 static INLINE void wc_ecc_free_rs(ecc_key* key, mp_int** r, mp_int** s) 03228 { 03229 if (*r) { 03230 mp_clear(*r); 03231 03232 #ifdef WOLFSSL_ASYNC_CRYPT 03233 XFREE(*r, key->heap, DYNAMIC_TYPE_BIGINT); 03234 key->r = NULL; 03235 #endif 03236 *r = NULL; 03237 } 03238 if (*s) { 03239 mp_clear(*s); 03240 03241 #ifdef WOLFSSL_ASYNC_CRYPT 03242 XFREE(*s, key->heap, DYNAMIC_TYPE_BIGINT); 03243 key->s = NULL; 03244 #endif 03245 *s = NULL; 03246 } 03247 (void)key; 03248 } 03249 03250 /* Setup dynamic pointers if using normal math for proper freeing */ 03251 int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) 03252 { 03253 int ret = 0; 03254 03255 if (key == NULL) { 03256 return BAD_FUNC_ARG; 03257 } 03258 03259 #ifdef ECC_DUMP_OID 03260 wc_ecc_dump_oids(); 03261 #endif 03262 03263 XMEMSET(key, 0, sizeof(ecc_key)); 03264 key->state = ECC_STATE_NONE; 03265 03266 #ifdef WOLFSSL_ATECC508A 03267 key->slot = atmel_ecc_alloc(); 03268 if (key->slot == ATECC_INVALID_SLOT) { 03269 return ECC_BAD_ARG_E; 03270 } 03271 #else 03272 #ifdef ALT_ECC_SIZE 03273 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 03274 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 03275 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 03276 alt_fp_init(key->pubkey.x); 03277 alt_fp_init(key->pubkey.y); 03278 alt_fp_init(key->pubkey.z); 03279 ret = mp_init(&key->k); 03280 #else 03281 ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z, 03282 NULL, NULL); 03283 #endif /* ALT_ECC_SIZE */ 03284 if (ret != MP_OKAY) { 03285 return MEMORY_E; 03286 } 03287 #endif /* WOLFSSL_ATECC508A */ 03288 03289 #ifdef WOLFSSL_HEAP_TEST 03290 key->heap = (void*)WOLFSSL_HEAP_TEST; 03291 #else 03292 key->heap = heap; 03293 #endif 03294 03295 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 03296 /* handle as async */ 03297 ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC, 03298 key->heap, devId); 03299 #else 03300 (void)devId; 03301 #endif 03302 03303 return ret; 03304 } 03305 03306 int wc_ecc_init(ecc_key* key) 03307 { 03308 return wc_ecc_init_ex(key, NULL, INVALID_DEVID); 03309 } 03310 03311 int wc_ecc_set_flags(ecc_key* key, word32 flags) 03312 { 03313 if (key == NULL) { 03314 return BAD_FUNC_ARG; 03315 } 03316 key->flags |= flags; 03317 return 0; 03318 } 03319 03320 #ifdef HAVE_ECC_SIGN 03321 03322 #ifndef NO_ASN 03323 /** 03324 Sign a message digest 03325 in The message digest to sign 03326 inlen The length of the digest 03327 out [out] The destination for the signature 03328 outlen [in/out] The max size and resulting size of the signature 03329 key A private ECC key 03330 return MP_OKAY if successful 03331 */ 03332 int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, 03333 WC_RNG* rng, ecc_key* key) 03334 { 03335 int err; 03336 mp_int *r = NULL, *s = NULL; 03337 #ifndef WOLFSSL_ASYNC_CRYPT 03338 mp_int r_lcl, s_lcl; 03339 r = &r_lcl; 03340 s = &s_lcl; 03341 #endif 03342 03343 if (in == NULL || out == NULL || outlen == NULL || key == NULL || 03344 rng == NULL) { 03345 return ECC_BAD_ARG_E; 03346 } 03347 03348 switch(key->state) { 03349 case ECC_STATE_NONE: 03350 case ECC_STATE_SIGN_DO: 03351 key->state = ECC_STATE_SIGN_DO; 03352 03353 err = wc_ecc_alloc_rs(key, &r, &s); 03354 if (err != 0) 03355 break; 03356 03357 if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){ 03358 break; 03359 } 03360 03361 #ifdef WOLFSSL_ATECC508A 03362 /* Check args */ 03363 if (inlen != ATECC_KEY_SIZE || *outlen < SIGN_RSP_SIZE) { 03364 return ECC_BAD_ARG_E; 03365 } 03366 03367 /* Sign: Result is 32-bytes of R then 32-bytes of S */ 03368 err = atcatls_sign(key->slot, in, out); 03369 if (err != ATCA_SUCCESS) { 03370 return BAD_COND_E; 03371 } 03372 03373 /* Load R and S */ 03374 err = mp_read_unsigned_bin(r, &out[0], ATECC_KEY_SIZE); 03375 if (err != MP_OKAY) { 03376 return err; 03377 } 03378 err = mp_read_unsigned_bin(s, &out[ATECC_KEY_SIZE], ATECC_KEY_SIZE); 03379 if (err != MP_OKAY) { 03380 return err; 03381 } 03382 03383 /* Check for zeros */ 03384 if (mp_iszero(r) || mp_iszero(s)) { 03385 return MP_ZERO_E; 03386 } 03387 03388 #else 03389 03390 err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); 03391 if (err < 0) { 03392 break; 03393 } 03394 03395 #endif /* WOLFSSL_ATECC508A */ 03396 03397 /* fall through */ 03398 case ECC_STATE_SIGN_ENCODE: 03399 key->state = ECC_STATE_SIGN_ENCODE; 03400 03401 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 03402 /* restore r/s */ 03403 r = key->r; 03404 s = key->s; 03405 03406 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 03407 /* only do this if not simulator, since it overwrites result */ 03408 #ifndef WOLFSSL_ASYNC_CRYPT_TEST 03409 wc_bigint_to_mp(&r->raw, r); 03410 wc_bigint_to_mp(&s->raw, s); 03411 #endif 03412 } 03413 #endif /* WOLFSSL_ASYNC_CRYPT */ 03414 03415 /* encoded with DSA header */ 03416 err = StoreECC_DSA_Sig(out, outlen, r, s); 03417 03418 /* always free r/s */ 03419 mp_clear(r); 03420 mp_clear(s); 03421 break; 03422 03423 default: 03424 err = BAD_STATE_E; 03425 } 03426 03427 /* if async pending then return and skip done cleanup below */ 03428 if (err == WC_PENDING_E) { 03429 key->state++; 03430 return err; 03431 } 03432 03433 /* cleanup */ 03434 wc_ecc_free_rs(key, &r, &s); 03435 key->state = ECC_STATE_NONE; 03436 03437 return err; 03438 } 03439 #endif /* !NO_ASN */ 03440 03441 #ifndef WOLFSSL_ATECC508A 03442 /** 03443 Sign a message digest 03444 in The message digest to sign 03445 inlen The length of the digest 03446 key A private ECC key 03447 r [out] The destination for r component of the signature 03448 s [out] The destination for s component of the signature 03449 return MP_OKAY if successful 03450 */ 03451 int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, 03452 ecc_key* key, mp_int *r, mp_int *s) 03453 { 03454 int err; 03455 mp_int e; 03456 DECLARE_CURVE_SPECS(1) 03457 03458 if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) 03459 return ECC_BAD_ARG_E; 03460 03461 /* is this a private key? */ 03462 if (key->type != ECC_PRIVATEKEY) { 03463 return ECC_BAD_ARG_E; 03464 } 03465 03466 /* is the IDX valid ? */ 03467 if (wc_ecc_is_valid_idx(key->idx) != 1) { 03468 return ECC_BAD_ARG_E; 03469 } 03470 03471 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ 03472 defined(WOLFSSL_ASYNC_CRYPT_TEST) 03473 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 03474 WC_ASYNC_TEST* testDev = &key->asyncDev.test; 03475 if (testDev->type == ASYNC_TEST_NONE) { 03476 testDev->type = ASYNC_TEST_ECC_SIGN; 03477 testDev->eccSign.in = in; 03478 testDev->eccSign.inSz = inlen; 03479 testDev->eccSign.rng = rng; 03480 testDev->eccSign.key = key; 03481 testDev->eccSign.r = r; 03482 testDev->eccSign.s = s; 03483 return WC_PENDING_E; 03484 } 03485 } 03486 #endif 03487 03488 /* get the hash and load it as a bignum into 'e' */ 03489 /* init the bignums */ 03490 if ((err = mp_init(&e)) != MP_OKAY) { 03491 return err; 03492 } 03493 03494 /* load curve info */ 03495 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER); 03496 03497 /* load digest into e */ 03498 if (err == MP_OKAY) { 03499 /* we may need to truncate if hash is longer than key size */ 03500 word32 orderBits = mp_count_bits(curve->order); 03501 03502 /* truncate down to byte size, may be all that's needed */ 03503 if ((WOLFSSL_BIT_SIZE * inlen) > orderBits) 03504 inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; 03505 err = mp_read_unsigned_bin(&e, (byte*)in, inlen); 03506 03507 /* may still need bit truncation too */ 03508 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits) 03509 mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); 03510 } 03511 03512 /* make up a key and export the public copy */ 03513 if (err == MP_OKAY) { 03514 int loop_check = 0; 03515 ecc_key pubkey; 03516 03517 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 03518 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 03519 #ifdef HAVE_CAVIUM 03520 /* TODO: Not implemented */ 03521 #elif defined(HAVE_INTEL_QA) 03522 mp_int k; 03523 03524 err = mp_init(&k); 03525 /* make sure r and s are allocated */ 03526 if (err == MP_OKAY) 03527 err = wc_bigint_alloc(&key->r->raw, key->dp->size); 03528 if (err == MP_OKAY) 03529 err = wc_bigint_alloc(&key->s->raw, key->dp->size); 03530 /* load e and k */ 03531 if (err == MP_OKAY) 03532 err = wc_mp_to_bigint(&e, &e.raw); 03533 if (err == MP_OKAY) 03534 err = wc_mp_to_bigint(&key->k, &key->k.raw); 03535 if (err == MP_OKAY) 03536 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); 03537 if (err == MP_OKAY) 03538 err = wc_ecc_gen_k(rng, key->dp->size, &k, curve->order); 03539 if (err == MP_OKAY) 03540 err = wc_mp_to_bigint(&k, &k.raw); 03541 if (err == MP_OKAY) 03542 err = IntelQaEcdsaSign(&key->asyncDev, &e.raw, &key->k.raw, 03543 &k.raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw, 03544 &curve->prime->raw, &curve->order->raw, &curve->Gx->raw, 03545 &curve->Gy->raw); 03546 03547 mp_clear(&e); 03548 mp_clear(&k); 03549 wc_ecc_curve_free(curve); 03550 03551 return err; 03552 #endif 03553 } 03554 #endif /* WOLFSSL_ASYNC_CRYPT */ 03555 03556 /* don't use async for key, since we don't support async return here */ 03557 if (wc_ecc_init_ex(&pubkey, key->heap, INVALID_DEVID) == MP_OKAY) { 03558 for (;;) { 03559 if (++loop_check > 64) { 03560 err = RNG_FAILURE_E; 03561 break; 03562 } 03563 err = wc_ecc_make_key_ex(rng, key->dp->size, &pubkey, 03564 key->dp->id); 03565 if (err != MP_OKAY) break; 03566 03567 /* find r = x1 mod n */ 03568 err = mp_mod(pubkey.pubkey.x, curve->order, r); 03569 if (err != MP_OKAY) break; 03570 03571 if (mp_iszero(r) == MP_YES) { 03572 #ifndef ALT_ECC_SIZE 03573 mp_clear(pubkey.pubkey.x); 03574 mp_clear(pubkey.pubkey.y); 03575 mp_clear(pubkey.pubkey.z); 03576 #endif 03577 mp_forcezero(&pubkey.k); 03578 } 03579 else { 03580 /* find s = (e + xr)/k */ 03581 err = mp_invmod(&pubkey.k, curve->order, &pubkey.k); 03582 if (err != MP_OKAY) break; 03583 03584 /* s = xr */ 03585 err = mp_mulmod(&key->k, r, curve->order, s); 03586 if (err != MP_OKAY) break; 03587 03588 /* s = e + xr */ 03589 err = mp_add(&e, s, s); 03590 if (err != MP_OKAY) break; 03591 03592 /* s = e + xr */ 03593 err = mp_mod(s, curve->order, s); 03594 if (err != MP_OKAY) break; 03595 03596 /* s = (e + xr)/k */ 03597 err = mp_mulmod(s, &pubkey.k, curve->order, s); 03598 03599 if (mp_iszero(s) == MP_NO) 03600 break; 03601 } 03602 } 03603 wc_ecc_free(&pubkey); 03604 } 03605 } 03606 03607 mp_clear(&e); 03608 wc_ecc_curve_free(curve); 03609 03610 return err; 03611 } 03612 #endif /* WOLFSSL_ATECC508A */ 03613 #endif /* HAVE_ECC_SIGN */ 03614 03615 /** 03616 Free an ECC key from memory 03617 key The key you wish to free 03618 */ 03619 void wc_ecc_free(ecc_key* key) 03620 { 03621 if (key == NULL) { 03622 return; 03623 } 03624 03625 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 03626 wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC); 03627 wc_ecc_free_rs(key, &key->r, &key->s); 03628 #endif 03629 03630 #ifdef WOLFSSL_ATECC508A 03631 atmel_ecc_free(key->slot); 03632 key->slot = -1; 03633 #else 03634 03635 mp_clear(key->pubkey.x); 03636 mp_clear(key->pubkey.y); 03637 mp_clear(key->pubkey.z); 03638 03639 mp_forcezero(&key->k); 03640 #endif /* WOLFSSL_ATECC508A */ 03641 } 03642 03643 #ifdef ECC_SHAMIR 03644 03645 /** Computes kA*A + kB*B = C using Shamir's Trick 03646 A First point to multiply 03647 kA What to multiple A by 03648 B Second point to multiply 03649 kB What to multiple B by 03650 C [out] Destination point (can overlap with A or B) 03651 a ECC curve parameter a 03652 modulus Modulus for curve 03653 return MP_OKAY on success 03654 */ 03655 #ifdef FP_ECC 03656 static int normal_ecc_mul2add(ecc_point* A, mp_int* kA, 03657 ecc_point* B, mp_int* kB, 03658 ecc_point* C, mp_int* a, mp_int* modulus, 03659 void* heap) 03660 #else 03661 static int ecc_mul2add(ecc_point* A, mp_int* kA, 03662 ecc_point* B, mp_int* kB, 03663 ecc_point* C, mp_int* a, mp_int* modulus, 03664 void* heap) 03665 #endif 03666 { 03667 ecc_point* precomp[16]; 03668 unsigned bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble; 03669 unsigned char* tA; 03670 unsigned char* tB; 03671 int err = MP_OKAY, first, x, y; 03672 mp_digit mp; 03673 03674 /* argchks */ 03675 if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL || 03676 modulus == NULL) { 03677 return ECC_BAD_ARG_E; 03678 } 03679 03680 /* allocate memory */ 03681 tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); 03682 if (tA == NULL) { 03683 return GEN_MEM_ERR; 03684 } 03685 tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); 03686 if (tB == NULL) { 03687 XFREE(tA, heap, DYNAMIC_TYPE_TMP_BUFFER); 03688 return GEN_MEM_ERR; 03689 } 03690 03691 /* init variables */ 03692 XMEMSET(tA, 0, ECC_BUFSIZE); 03693 XMEMSET(tB, 0, ECC_BUFSIZE); 03694 XMEMSET(precomp, 0, sizeof(precomp)); 03695 03696 /* get sizes */ 03697 lenA = mp_unsigned_bin_size(kA); 03698 lenB = mp_unsigned_bin_size(kB); 03699 len = MAX(lenA, lenB); 03700 03701 /* sanity check */ 03702 if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) { 03703 err = BAD_FUNC_ARG; 03704 } 03705 03706 if (err == MP_OKAY) { 03707 /* extract and justify kA */ 03708 err = mp_to_unsigned_bin(kA, (len - lenA) + tA); 03709 03710 /* extract and justify kB */ 03711 if (err == MP_OKAY) 03712 err = mp_to_unsigned_bin(kB, (len - lenB) + tB); 03713 03714 /* allocate the table */ 03715 if (err == MP_OKAY) { 03716 for (x = 0; x < 16; x++) { 03717 precomp[x] = wc_ecc_new_point_h(heap); 03718 if (precomp[x] == NULL) { 03719 err = GEN_MEM_ERR; 03720 break; 03721 } 03722 } 03723 } 03724 } 03725 03726 if (err == MP_OKAY) 03727 /* init montgomery reduction */ 03728 err = mp_montgomery_setup(modulus, &mp); 03729 03730 if (err == MP_OKAY) { 03731 mp_int mu; 03732 err = mp_init(&mu); 03733 if (err == MP_OKAY) { 03734 err = mp_montgomery_calc_normalization(&mu, modulus); 03735 03736 if (err == MP_OKAY) 03737 /* copy ones ... */ 03738 err = mp_mulmod(A->x, &mu, modulus, precomp[1]->x); 03739 03740 if (err == MP_OKAY) 03741 err = mp_mulmod(A->y, &mu, modulus, precomp[1]->y); 03742 if (err == MP_OKAY) 03743 err = mp_mulmod(A->z, &mu, modulus, precomp[1]->z); 03744 03745 if (err == MP_OKAY) 03746 err = mp_mulmod(B->x, &mu, modulus, precomp[1<<2]->x); 03747 if (err == MP_OKAY) 03748 err = mp_mulmod(B->y, &mu, modulus, precomp[1<<2]->y); 03749 if (err == MP_OKAY) 03750 err = mp_mulmod(B->z, &mu, modulus, precomp[1<<2]->z); 03751 03752 /* done with mu */ 03753 mp_clear(&mu); 03754 } 03755 } 03756 03757 if (err == MP_OKAY) 03758 /* precomp [i,0](A + B) table */ 03759 err = ecc_projective_dbl_point(precomp[1], precomp[2], a, modulus, mp); 03760 03761 if (err == MP_OKAY) 03762 err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3], 03763 a, modulus, mp); 03764 if (err == MP_OKAY) 03765 /* precomp [0,i](A + B) table */ 03766 err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], a, modulus, mp); 03767 03768 if (err == MP_OKAY) 03769 err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2], 03770 a, modulus, mp); 03771 03772 if (err == MP_OKAY) { 03773 /* precomp [i,j](A + B) table (i != 0, j != 0) */ 03774 for (x = 1; x < 4; x++) { 03775 for (y = 1; y < 4; y++) { 03776 if (err == MP_OKAY) 03777 err = ecc_projective_add_point(precomp[x], precomp[(y<<2)], 03778 precomp[x+(y<<2)], a, modulus, mp); 03779 } 03780 } 03781 } 03782 03783 if (err == MP_OKAY) { 03784 nibble = 3; 03785 first = 1; 03786 bitbufA = tA[0]; 03787 bitbufB = tB[0]; 03788 03789 /* for every byte of the multiplicands */ 03790 for (x = 0;; ) { 03791 /* grab a nibble */ 03792 if (++nibble == 4) { 03793 if (x == (int)len) break; 03794 bitbufA = tA[x]; 03795 bitbufB = tB[x]; 03796 nibble = 0; 03797 x++; 03798 } 03799 03800 /* extract two bits from both, shift/update */ 03801 nA = (bitbufA >> 6) & 0x03; 03802 nB = (bitbufB >> 6) & 0x03; 03803 bitbufA = (bitbufA << 2) & 0xFF; 03804 bitbufB = (bitbufB << 2) & 0xFF; 03805 03806 /* if both zero, if first, continue */ 03807 if ((nA == 0) && (nB == 0) && (first == 1)) { 03808 continue; 03809 } 03810 03811 /* double twice, only if this isn't the first */ 03812 if (first == 0) { 03813 /* double twice */ 03814 if (err == MP_OKAY) 03815 err = ecc_projective_dbl_point(C, C, a, modulus, mp); 03816 if (err == MP_OKAY) 03817 err = ecc_projective_dbl_point(C, C, a, modulus, mp); 03818 else 03819 break; 03820 } 03821 03822 /* if not both zero */ 03823 if ((nA != 0) || (nB != 0)) { 03824 if (first == 1) { 03825 /* if first, copy from table */ 03826 first = 0; 03827 if (err == MP_OKAY) 03828 err = mp_copy(precomp[nA + (nB<<2)]->x, C->x); 03829 03830 if (err == MP_OKAY) 03831 err = mp_copy(precomp[nA + (nB<<2)]->y, C->y); 03832 03833 if (err == MP_OKAY) 03834 err = mp_copy(precomp[nA + (nB<<2)]->z, C->z); 03835 else 03836 break; 03837 } else { 03838 /* if not first, add from table */ 03839 if (err == MP_OKAY) 03840 err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C, 03841 a, modulus, mp); 03842 else 03843 break; 03844 } 03845 } 03846 } 03847 } 03848 03849 /* reduce to affine */ 03850 if (err == MP_OKAY) 03851 err = ecc_map(C, modulus, mp); 03852 03853 /* clean up */ 03854 for (x = 0; x < 16; x++) { 03855 wc_ecc_del_point_h(precomp[x], heap); 03856 } 03857 03858 ForceZero(tA, ECC_BUFSIZE); 03859 ForceZero(tB, ECC_BUFSIZE); 03860 XFREE(tA, heap, DYNAMIC_TYPE_TMP_BUFFER); 03861 XFREE(tB, heap, DYNAMIC_TYPE_TMP_BUFFER); 03862 03863 return err; 03864 } 03865 03866 #endif /* ECC_SHAMIR */ 03867 03868 03869 #ifdef HAVE_ECC_VERIFY 03870 #ifndef NO_ASN 03871 /* verify 03872 * 03873 * w = s^-1 mod n 03874 * u1 = xw 03875 * u2 = rw 03876 * X = u1*G + u2*Q 03877 * v = X_x1 mod n 03878 * accept if v == r 03879 */ 03880 03881 /** 03882 Verify an ECC signature 03883 sig The signature to verify 03884 siglen The length of the signature (octets) 03885 hash The hash (message digest) that was signed 03886 hashlen The length of the hash (octets) 03887 res Result of signature, 1==valid, 0==invalid 03888 key The corresponding public ECC key 03889 return MP_OKAY if successful (even if the signature is not valid) 03890 */ 03891 int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, 03892 word32 hashlen, int* res, ecc_key* key) 03893 { 03894 int err; 03895 mp_int *r = NULL, *s = NULL; 03896 #ifndef WOLFSSL_ASYNC_CRYPT 03897 mp_int r_lcl, s_lcl; 03898 r = &r_lcl; 03899 s = &s_lcl; 03900 #endif 03901 03902 if (sig == NULL || hash == NULL || res == NULL || key == NULL) { 03903 return ECC_BAD_ARG_E; 03904 } 03905 03906 switch(key->state) { 03907 case ECC_STATE_NONE: 03908 case ECC_STATE_VERIFY_DECODE: 03909 key->state = ECC_STATE_VERIFY_DECODE; 03910 03911 /* default to invalid signature */ 03912 *res = 0; 03913 03914 /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s. 03915 * If either of those don't allocate correctly, none of 03916 * the rest of this function will execute, and everything 03917 * gets cleaned up at the end. */ 03918 err = wc_ecc_alloc_rs(key, &r, &s); 03919 if (err != 0) 03920 break; 03921 03922 /* decode DSA header */ 03923 err = DecodeECC_DSA_Sig(sig, siglen, r, s); 03924 if (err < 0) { 03925 break; 03926 } 03927 03928 /* fall through */ 03929 case ECC_STATE_VERIFY_DO: 03930 key->state = ECC_STATE_VERIFY_DO; 03931 03932 err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key); 03933 if (err < 0) { 03934 break; 03935 } 03936 03937 /* fall through */ 03938 case ECC_STATE_VERIFY_RES: 03939 key->state = ECC_STATE_VERIFY_RES; 03940 err = 0; 03941 03942 #ifdef WOLFSSL_ASYNC_CRYPT 03943 /* restore r/s */ 03944 r = key->r; 03945 s = key->s; 03946 #endif 03947 03948 /* done with R/S */ 03949 mp_clear(r); 03950 mp_clear(s); 03951 break; 03952 03953 default: 03954 err = BAD_STATE_E; 03955 } 03956 03957 /* if async pending then return and skip done cleanup below */ 03958 if (err == WC_PENDING_E) { 03959 key->state++; 03960 return err; 03961 } 03962 03963 /* cleanup */ 03964 wc_ecc_free_rs(key, &r, &s); 03965 key->state = ECC_STATE_NONE; 03966 03967 return err; 03968 } 03969 #endif /* !NO_ASN */ 03970 03971 03972 /** 03973 Verify an ECC signature 03974 r The signature R component to verify 03975 s The signature S component to verify 03976 hash The hash (message digest) that was signed 03977 hashlen The length of the hash (octets) 03978 res Result of signature, 1==valid, 0==invalid 03979 key The corresponding public ECC key 03980 return MP_OKAY if successful (even if the signature is not valid) 03981 */ 03982 int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, 03983 word32 hashlen, int* res, ecc_key* key) 03984 { 03985 int err; 03986 #ifndef WOLFSSL_ATECC508A 03987 int did_init = 0; 03988 ecc_point *mG = NULL, *mQ = NULL; 03989 mp_int v; 03990 mp_int w; 03991 mp_int u1; 03992 mp_int u2; 03993 mp_int e; 03994 DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT) 03995 #else 03996 byte sigRS[ATECC_KEY_SIZE*2]; 03997 #endif 03998 03999 if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) 04000 return ECC_BAD_ARG_E; 04001 04002 /* default to invalid signature */ 04003 *res = 0; 04004 04005 /* is the IDX valid ? */ 04006 if (wc_ecc_is_valid_idx(key->idx) != 1) { 04007 return ECC_BAD_ARG_E; 04008 } 04009 04010 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ 04011 defined(WOLFSSL_ASYNC_CRYPT_TEST) 04012 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 04013 WC_ASYNC_TEST* testDev = &key->asyncDev.test; 04014 if (testDev->type == ASYNC_TEST_NONE) { 04015 testDev->type = ASYNC_TEST_ECC_VERIFY; 04016 testDev->eccVerify.r = r; 04017 testDev->eccVerify.s = s; 04018 testDev->eccVerify.hash = hash; 04019 testDev->eccVerify.hashlen = hashlen; 04020 testDev->eccVerify.stat = res; 04021 testDev->eccVerify.key = key; 04022 return WC_PENDING_E; 04023 } 04024 } 04025 #endif 04026 04027 #ifdef WOLFSSL_ATECC508A 04028 /* Extract R and S */ 04029 err = mp_to_unsigned_bin(r, &sigRS[0]); 04030 if (err != MP_OKAY) { 04031 return err; 04032 } 04033 err = mp_to_unsigned_bin(s, &sigRS[ATECC_KEY_SIZE]); 04034 if (err != MP_OKAY) { 04035 return err; 04036 } 04037 04038 err = atcatls_verify(hash, sigRS, key->pubkey, (bool*)res); 04039 if (err != ATCA_SUCCESS) { 04040 return BAD_COND_E; 04041 } 04042 04043 #else 04044 04045 err = mp_init(&e); 04046 if (err != MP_OKAY) 04047 return MEMORY_E; 04048 04049 /* read in the specs for this curve */ 04050 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); 04051 04052 /* check for zero */ 04053 if (err == MP_OKAY) { 04054 if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES || 04055 mp_cmp(r, curve->order) != MP_LT || 04056 mp_cmp(s, curve->order) != MP_LT) { 04057 err = MP_ZERO_E; 04058 } 04059 } 04060 04061 /* read hash */ 04062 if (err == MP_OKAY) { 04063 /* we may need to truncate if hash is longer than key size */ 04064 unsigned int orderBits = mp_count_bits(curve->order); 04065 04066 /* truncate down to byte size, may be all that's needed */ 04067 if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits) 04068 hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; 04069 err = mp_read_unsigned_bin(&e, hash, hashlen); 04070 04071 /* may still need bit truncation too */ 04072 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits) 04073 mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); 04074 } 04075 04076 /* check for async hardware acceleration */ 04077 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 04078 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 04079 #ifdef HAVE_CAVIUM 04080 /* TODO: Not implemented */ 04081 #elif defined(HAVE_INTEL_QA) 04082 err = wc_mp_to_bigint(&e, &e.raw); 04083 if (err == MP_OKAY) 04084 err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw); 04085 if (err == MP_OKAY) 04086 err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw); 04087 if (err == MP_OKAY) 04088 err = IntelQaEcdsaVerify(&key->asyncDev, &e.raw, &key->pubkey.x->raw, 04089 &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw, 04090 &curve->Bf->raw, &curve->prime->raw, &curve->order->raw, 04091 &curve->Gx->raw, &curve->Gy->raw, res); 04092 04093 mp_clear(&e); 04094 04095 wc_ecc_curve_free(curve); 04096 04097 return err; 04098 #endif 04099 } 04100 #endif /* WOLFSSL_ASYNC_CRYPT */ 04101 04102 /* allocate ints */ 04103 if (err == MP_OKAY) { 04104 if ((err = mp_init_multi(&v, &w, &u1, &u2, NULL, NULL)) != MP_OKAY) { 04105 err = MEMORY_E; 04106 } 04107 did_init = 1; 04108 } 04109 04110 /* allocate points */ 04111 if (err == MP_OKAY) { 04112 mG = wc_ecc_new_point_h(key->heap); 04113 mQ = wc_ecc_new_point_h(key->heap); 04114 if (mQ == NULL || mG == NULL) 04115 err = MEMORY_E; 04116 } 04117 04118 /* w = s^-1 mod n */ 04119 if (err == MP_OKAY) 04120 err = mp_invmod(s, curve->order, &w); 04121 04122 /* u1 = ew */ 04123 if (err == MP_OKAY) 04124 err = mp_mulmod(&e, &w, curve->order, &u1); 04125 04126 /* u2 = rw */ 04127 if (err == MP_OKAY) 04128 err = mp_mulmod(r, &w, curve->order, &u2); 04129 04130 /* find mG and mQ */ 04131 if (err == MP_OKAY) 04132 err = mp_copy(curve->Gx, mG->x); 04133 if (err == MP_OKAY) 04134 err = mp_copy(curve->Gy, mG->y); 04135 if (err == MP_OKAY) 04136 err = mp_set(mG->z, 1); 04137 04138 if (err == MP_OKAY) 04139 err = mp_copy(key->pubkey.x, mQ->x); 04140 if (err == MP_OKAY) 04141 err = mp_copy(key->pubkey.y, mQ->y); 04142 if (err == MP_OKAY) 04143 err = mp_copy(key->pubkey.z, mQ->z); 04144 04145 #ifdef FREESCALE_LTC_ECC 04146 /* use PKHA to compute u1*mG + u2*mQ */ 04147 if (err == MP_OKAY) 04148 err = wc_ecc_mulmod_ex(&u1, mG, mG, curve->Af, curve->prime, 0, key->heap); 04149 if (err == MP_OKAY) 04150 err = wc_ecc_mulmod_ex(&u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap); 04151 if (err == MP_OKAY) 04152 err = wc_ecc_point_add(mG, mQ, mG, curve->prime); 04153 #else /* FREESCALE_LTC_ECC */ 04154 #ifndef ECC_SHAMIR 04155 { 04156 mp_digit mp; 04157 04158 /* compute u1*mG + u2*mQ = mG */ 04159 if (err == MP_OKAY) 04160 err = wc_ecc_mulmod_ex(&u1, mG, mG, curve->Af, curve->prime, 0, key->heap); 04161 if (err == MP_OKAY) 04162 err = wc_ecc_mulmod_ex(&u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap); 04163 04164 /* find the montgomery mp */ 04165 if (err == MP_OKAY) 04166 err = mp_montgomery_setup(curve->prime, &mp); 04167 04168 /* add them */ 04169 if (err == MP_OKAY) 04170 err = ecc_projective_add_point(mQ, mG, mG, curve->Af, 04171 curve->prime, mp); 04172 04173 /* reduce */ 04174 if (err == MP_OKAY) 04175 err = ecc_map(mG, curve->prime, mp); 04176 } 04177 #else 04178 /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */ 04179 if (err == MP_OKAY) 04180 err = ecc_mul2add(mG, &u1, mQ, &u2, mG, curve->Af, curve->prime, 04181 key->heap); 04182 #endif /* ECC_SHAMIR */ 04183 #endif /* FREESCALE_LTC_ECC */ 04184 /* v = X_x1 mod n */ 04185 if (err == MP_OKAY) 04186 err = mp_mod(mG->x, curve->order, &v); 04187 04188 /* does v == r */ 04189 if (err == MP_OKAY) { 04190 if (mp_cmp(&v, r) == MP_EQ) 04191 *res = 1; 04192 } 04193 04194 /* cleanup */ 04195 wc_ecc_del_point_h(mG, key->heap); 04196 wc_ecc_del_point_h(mQ, key->heap); 04197 04198 mp_clear(&e); 04199 if (did_init) { 04200 mp_clear(&v); 04201 mp_clear(&w); 04202 mp_clear(&u1); 04203 mp_clear(&u2); 04204 } 04205 04206 wc_ecc_curve_free(curve); 04207 04208 #endif /* WOLFSSL_ATECC508A */ 04209 04210 return err; 04211 } 04212 #endif /* HAVE_ECC_VERIFY */ 04213 04214 #ifdef HAVE_ECC_KEY_IMPORT 04215 #ifndef WOLFSSL_ATECC508A 04216 /* import point from der */ 04217 int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, 04218 ecc_point* point) 04219 { 04220 int err = 0; 04221 int compressed = 0; 04222 04223 if (in == NULL || point == NULL || (curve_idx < 0) || 04224 (wc_ecc_is_valid_idx(curve_idx) == 0)) 04225 return ECC_BAD_ARG_E; 04226 04227 /* must be odd */ 04228 if ((inLen & 1) == 0) { 04229 return ECC_BAD_ARG_E; 04230 } 04231 04232 /* init point */ 04233 #ifdef ALT_ECC_SIZE 04234 point->x = (mp_int*)&point->xyz[0]; 04235 point->y = (mp_int*)&point->xyz[1]; 04236 point->z = (mp_int*)&point->xyz[2]; 04237 alt_fp_init(point->x); 04238 alt_fp_init(point->y); 04239 alt_fp_init(point->z); 04240 #else 04241 err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL); 04242 #endif 04243 if (err != MP_OKAY) 04244 return MEMORY_E; 04245 04246 /* check for 4, 2, or 3 */ 04247 if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) { 04248 err = ASN_PARSE_E; 04249 } 04250 04251 if (in[0] == 0x02 || in[0] == 0x03) { 04252 #ifdef HAVE_COMP_KEY 04253 compressed = 1; 04254 #else 04255 err = NOT_COMPILED_IN; 04256 #endif 04257 } 04258 04259 /* read data */ 04260 if (err == MP_OKAY) 04261 err = mp_read_unsigned_bin(point->x, (byte*)in+1, (inLen-1)>>1); 04262 04263 #ifdef HAVE_COMP_KEY 04264 if (err == MP_OKAY && compressed == 1) { /* build y */ 04265 int did_init = 0; 04266 mp_int t1, t2; 04267 DECLARE_CURVE_SPECS(3) 04268 04269 if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY) 04270 err = MEMORY_E; 04271 else 04272 did_init = 1; 04273 04274 /* load curve info */ 04275 if (err == MP_OKAY) 04276 err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve, 04277 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | 04278 ECC_CURVE_FIELD_BF)); 04279 04280 /* compute x^3 */ 04281 if (err == MP_OKAY) 04282 err = mp_sqr(point->x, &t1); 04283 if (err == MP_OKAY) 04284 err = mp_mulmod(&t1, point->x, curve->prime, &t1); 04285 04286 /* compute x^3 + a*x */ 04287 if (err == MP_OKAY) 04288 err = mp_mulmod(curve->Af, point->x, curve->prime, &t2); 04289 if (err == MP_OKAY) 04290 err = mp_add(&t1, &t2, &t1); 04291 04292 /* compute x^3 + a*x + b */ 04293 if (err == MP_OKAY) 04294 err = mp_add(&t1, curve->Bf, &t1); 04295 04296 /* compute sqrt(x^3 + a*x + b) */ 04297 if (err == MP_OKAY) 04298 err = mp_sqrtmod_prime(&t1, curve->prime, &t2); 04299 04300 /* adjust y */ 04301 if (err == MP_OKAY) { 04302 if ((mp_isodd(&t2) == MP_YES && in[0] == 0x03) || 04303 (mp_isodd(&t2) == MP_NO && in[0] == 0x02)) { 04304 err = mp_mod(&t2, curve->prime, point->y); 04305 } 04306 else { 04307 err = mp_submod(curve->prime, &t2, curve->prime, point->y); 04308 } 04309 } 04310 04311 if (did_init) { 04312 mp_clear(&t2); 04313 mp_clear(&t1); 04314 } 04315 04316 wc_ecc_curve_free(curve); 04317 } 04318 #endif 04319 04320 if (err == MP_OKAY && compressed == 0) 04321 err = mp_read_unsigned_bin(point->y, 04322 (byte*)in+1+((inLen-1)>>1), (inLen-1)>>1); 04323 if (err == MP_OKAY) 04324 err = mp_set(point->z, 1); 04325 04326 if (err != MP_OKAY) { 04327 mp_clear(point->x); 04328 mp_clear(point->y); 04329 mp_clear(point->z); 04330 } 04331 04332 return err; 04333 } 04334 #endif /* !WOLFSSL_ATECC508A */ 04335 #endif /* HAVE_ECC_KEY_IMPORT */ 04336 04337 #ifdef HAVE_ECC_KEY_EXPORT 04338 /* export point to der */ 04339 int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out, 04340 word32* outLen) 04341 { 04342 int ret = MP_OKAY; 04343 word32 numlen; 04344 #ifndef WOLFSSL_ATECC508A 04345 #ifdef WOLFSSL_SMALL_STACK 04346 byte* buf; 04347 #else 04348 byte buf[ECC_BUFSIZE]; 04349 #endif 04350 #endif /* !WOLFSSL_ATECC508A */ 04351 04352 if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0)) 04353 return ECC_BAD_ARG_E; 04354 04355 /* return length needed only */ 04356 if (point != NULL && out == NULL && outLen != NULL) { 04357 numlen = ecc_sets[curve_idx].size; 04358 *outLen = 1 + 2*numlen; 04359 return LENGTH_ONLY_E; 04360 } 04361 04362 if (point == NULL || out == NULL || outLen == NULL) 04363 return ECC_BAD_ARG_E; 04364 04365 numlen = ecc_sets[curve_idx].size; 04366 04367 if (*outLen < (1 + 2*numlen)) { 04368 *outLen = 1 + 2*numlen; 04369 return BUFFER_E; 04370 } 04371 04372 #ifdef WOLFSSL_ATECC508A 04373 /* TODO: Implement equiv call to ATECC508A */ 04374 ret = BAD_COND_E; 04375 04376 #else 04377 04378 /* store byte 0x04 */ 04379 out[0] = 0x04; 04380 04381 #ifdef WOLFSSL_SMALL_STACK 04382 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 04383 if (buf == NULL) 04384 return MEMORY_E; 04385 #endif 04386 04387 /* pad and store x */ 04388 XMEMSET(buf, 0, ECC_BUFSIZE); 04389 ret = mp_to_unsigned_bin(point->x, buf + 04390 (numlen - mp_unsigned_bin_size(point->x))); 04391 if (ret != MP_OKAY) 04392 goto done; 04393 XMEMCPY(out+1, buf, numlen); 04394 04395 /* pad and store y */ 04396 XMEMSET(buf, 0, ECC_BUFSIZE); 04397 ret = mp_to_unsigned_bin(point->y, buf + 04398 (numlen - mp_unsigned_bin_size(point->y))); 04399 if (ret != MP_OKAY) 04400 goto done; 04401 XMEMCPY(out+1+numlen, buf, numlen); 04402 04403 *outLen = 1 + 2*numlen; 04404 04405 done: 04406 #ifdef WOLFSSL_SMALL_STACK 04407 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); 04408 #endif 04409 #endif /* WOLFSSL_ATECC508A */ 04410 04411 return ret; 04412 } 04413 04414 04415 /* export public ECC key in ANSI X9.63 format */ 04416 int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) 04417 { 04418 int ret = MP_OKAY; 04419 word32 numlen; 04420 #ifndef WOLFSSL_ATECC508A 04421 #ifdef WOLFSSL_SMALL_STACK 04422 byte* buf; 04423 #else 04424 byte buf[ECC_BUFSIZE]; 04425 #endif 04426 word32 pubxlen, pubylen; 04427 #endif /* WOLFSSL_ATECC508A */ 04428 04429 /* return length needed only */ 04430 if (key != NULL && out == NULL && outLen != NULL) { 04431 numlen = key->dp->size; 04432 *outLen = 1 + 2*numlen; 04433 return LENGTH_ONLY_E; 04434 } 04435 04436 if (key == NULL || out == NULL || outLen == NULL) 04437 return ECC_BAD_ARG_E; 04438 04439 if (wc_ecc_is_valid_idx(key->idx) == 0) { 04440 return ECC_BAD_ARG_E; 04441 } 04442 numlen = key->dp->size; 04443 04444 /* verify room in out buffer */ 04445 if (*outLen < (1 + 2*numlen)) { 04446 *outLen = 1 + 2*numlen; 04447 return BUFFER_E; 04448 } 04449 04450 #ifdef WOLFSSL_ATECC508A 04451 /* TODO: Implement equiv call to ATECC508A */ 04452 ret = BAD_COND_E; 04453 04454 #else 04455 04456 /* verify public key length is less than key size */ 04457 pubxlen = mp_unsigned_bin_size(key->pubkey.x); 04458 pubylen = mp_unsigned_bin_size(key->pubkey.y); 04459 if ((pubxlen > numlen) || (pubylen > numlen)) { 04460 WOLFSSL_MSG("Public key x/y invalid!"); 04461 return BUFFER_E; 04462 } 04463 04464 /* store byte 0x04 */ 04465 out[0] = 0x04; 04466 04467 #ifdef WOLFSSL_SMALL_STACK 04468 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 04469 if (buf == NULL) 04470 return MEMORY_E; 04471 #endif 04472 04473 /* pad and store x */ 04474 XMEMSET(buf, 0, ECC_BUFSIZE); 04475 ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen)); 04476 if (ret != MP_OKAY) 04477 goto done; 04478 XMEMCPY(out+1, buf, numlen); 04479 04480 /* pad and store y */ 04481 XMEMSET(buf, 0, ECC_BUFSIZE); 04482 ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen)); 04483 if (ret != MP_OKAY) 04484 goto done; 04485 XMEMCPY(out+1+numlen, buf, numlen); 04486 04487 *outLen = 1 + 2*numlen; 04488 04489 done: 04490 #ifdef WOLFSSL_SMALL_STACK 04491 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); 04492 #endif 04493 #endif /* WOLFSSL_ATECC508A */ 04494 04495 return ret; 04496 } 04497 04498 04499 /* export public ECC key in ANSI X9.63 format, extended with 04500 * compression option */ 04501 int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, 04502 int compressed) 04503 { 04504 if (compressed == 0) 04505 return wc_ecc_export_x963(key, out, outLen); 04506 #ifdef HAVE_COMP_KEY 04507 else 04508 return wc_ecc_export_x963_compressed(key, out, outLen); 04509 #else 04510 return NOT_COMPILED_IN; 04511 #endif 04512 } 04513 #endif /* HAVE_ECC_KEY_EXPORT */ 04514 04515 04516 #ifndef WOLFSSL_ATECC508A 04517 04518 /* is ecc point on curve described by dp ? */ 04519 int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) 04520 { 04521 int err; 04522 mp_int t1, t2; 04523 04524 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 04525 return err; 04526 } 04527 04528 /* compute y^2 */ 04529 if (err == MP_OKAY) 04530 err = mp_sqr(ecp->y, &t1); 04531 04532 /* compute x^3 */ 04533 if (err == MP_OKAY) 04534 err = mp_sqr(ecp->x, &t2); 04535 if (err == MP_OKAY) 04536 err = mp_mod(&t2, prime, &t2); 04537 if (err == MP_OKAY) 04538 err = mp_mul(ecp->x, &t2, &t2); 04539 04540 /* compute y^2 - x^3 */ 04541 if (err == MP_OKAY) 04542 err = mp_sub(&t1, &t2, &t1); 04543 04544 /* Determine if curve "a" should be used in calc */ 04545 #ifdef WOLFSSL_CUSTOM_CURVES 04546 if (err == MP_OKAY) { 04547 /* Use a and prime to determine if a == 3 */ 04548 err = mp_set(&t2, 0); 04549 if (err == MP_OKAY) 04550 err = mp_submod(prime, a, prime, &t2); 04551 } 04552 if (err == MP_OKAY && mp_cmp_d(&t2, 3) != MP_EQ) { 04553 /* compute y^2 - x^3 + a*x */ 04554 if (err == MP_OKAY) 04555 err = mp_mulmod(&t2, ecp->x, prime, &t2); 04556 if (err == MP_OKAY) 04557 err = mp_addmod(&t1, &t2, prime, &t1); 04558 } 04559 else 04560 #endif /* WOLFSSL_CUSTOM_CURVES */ 04561 { 04562 /* assumes "a" == 3 */ 04563 (void)a; 04564 04565 /* compute y^2 - x^3 + 3x */ 04566 if (err == MP_OKAY) 04567 err = mp_add(&t1, ecp->x, &t1); 04568 if (err == MP_OKAY) 04569 err = mp_add(&t1, ecp->x, &t1); 04570 if (err == MP_OKAY) 04571 err = mp_add(&t1, ecp->x, &t1); 04572 if (err == MP_OKAY) 04573 err = mp_mod(&t1, prime, &t1); 04574 } 04575 04576 /* adjust range (0, prime) */ 04577 while (err == MP_OKAY && mp_isneg(&t1)) { 04578 err = mp_add(&t1, prime, &t1); 04579 } 04580 while (err == MP_OKAY && mp_cmp(&t1, prime) != MP_LT) { 04581 err = mp_sub(&t1, prime, &t1); 04582 } 04583 04584 /* compare to b */ 04585 if (err == MP_OKAY) { 04586 if (mp_cmp(&t1, b) != MP_EQ) { 04587 err = MP_VAL; 04588 } else { 04589 err = MP_OKAY; 04590 } 04591 } 04592 04593 mp_clear(&t1); 04594 mp_clear(&t2); 04595 04596 return err; 04597 } 04598 04599 04600 /* validate privkey * generator == pubkey, 0 on success */ 04601 static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime) 04602 { 04603 int err = MP_OKAY; 04604 ecc_point* base = NULL; 04605 ecc_point* res = NULL; 04606 DECLARE_CURVE_SPECS(2) 04607 04608 if (key == NULL) 04609 return BAD_FUNC_ARG; 04610 04611 base = wc_ecc_new_point_h(key->heap); 04612 if (base == NULL) 04613 return MEMORY_E; 04614 04615 /* load curve info */ 04616 err = wc_ecc_curve_load(key->dp, &curve, 04617 (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY)); 04618 04619 /* set up base generator */ 04620 if (err == MP_OKAY) 04621 err = mp_copy(curve->Gx, base->x); 04622 if (err == MP_OKAY) 04623 err = mp_copy(curve->Gy, base->y); 04624 if (err == MP_OKAY) 04625 err = mp_set(base->z, 1); 04626 04627 if (err == MP_OKAY) { 04628 res = wc_ecc_new_point_h(key->heap); 04629 if (res == NULL) 04630 err = MEMORY_E; 04631 else { 04632 err = wc_ecc_mulmod_ex(&key->k, base, res, a, prime, 1, key->heap); 04633 if (err == MP_OKAY) { 04634 /* compare result to public key */ 04635 if (mp_cmp(res->x, key->pubkey.x) != MP_EQ || 04636 mp_cmp(res->y, key->pubkey.y) != MP_EQ || 04637 mp_cmp(res->z, key->pubkey.z) != MP_EQ) { 04638 /* didn't match */ 04639 err = ECC_PRIV_KEY_E; 04640 } 04641 } 04642 } 04643 } 04644 04645 wc_ecc_curve_free(curve); 04646 wc_ecc_del_point_h(res, key->heap); 04647 wc_ecc_del_point_h(base, key->heap); 04648 04649 return err; 04650 } 04651 04652 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 04653 04654 /* check privkey generator helper, creates prime needed */ 04655 static int ecc_check_privkey_gen_helper(ecc_key* key) 04656 { 04657 int err; 04658 #ifndef WOLFSSL_ATECC508A 04659 DECLARE_CURVE_SPECS(2) 04660 #endif 04661 04662 if (key == NULL) 04663 return BAD_FUNC_ARG; 04664 04665 #ifdef WOLFSSL_ATECC508A 04666 /* TODO: Implement equiv call to ATECC508A */ 04667 err = BAD_COND_E; 04668 04669 #else 04670 04671 /* load curve info */ 04672 err = wc_ecc_curve_load(key->dp, &curve, 04673 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF)); 04674 04675 if (err == MP_OKAY) 04676 err = ecc_check_privkey_gen(key, curve->Af, curve->prime); 04677 04678 wc_ecc_curve_free(curve); 04679 04680 #endif /* WOLFSSL_ATECC508A */ 04681 04682 return err; 04683 } 04684 04685 #endif /* WOLFSSL_VALIDATE_ECC_IMPORT */ 04686 04687 04688 /* validate order * pubkey = point at infinity, 0 on success */ 04689 static int ecc_check_pubkey_order(ecc_key* key, mp_int* a, mp_int* prime, 04690 mp_int* order) 04691 { 04692 ecc_point* inf = NULL; 04693 int err; 04694 04695 if (key == NULL) 04696 return BAD_FUNC_ARG; 04697 04698 inf = wc_ecc_new_point_h(key->heap); 04699 if (inf == NULL) 04700 err = MEMORY_E; 04701 else { 04702 err = wc_ecc_mulmod_ex(order, &key->pubkey, inf, a, prime, 1, key->heap); 04703 if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf)) 04704 err = ECC_INF_E; 04705 } 04706 04707 wc_ecc_del_point_h(inf, key->heap); 04708 04709 return err; 04710 } 04711 04712 #endif /* !WOLFSSL_ATECC508A */ 04713 04714 04715 /* perform sanity checks on ecc key validity, 0 on success */ 04716 int wc_ecc_check_key(ecc_key* key) 04717 { 04718 int err; 04719 #ifndef WOLFSSL_ATECC508A 04720 mp_int* b; 04721 #ifdef USE_ECC_B_PARAM 04722 DECLARE_CURVE_SPECS(4) 04723 #else 04724 mp_int b_lcl; 04725 DECLARE_CURVE_SPECS(3) 04726 b = &b_lcl; 04727 XMEMSET(b, 0, sizeof(mp_int)); 04728 #endif 04729 #endif /* WOLFSSL_ATECC508A */ 04730 04731 if (key == NULL) 04732 return BAD_FUNC_ARG; 04733 04734 #ifdef WOLFSSL_ATECC508A 04735 /* TODO: Implement equiv call to ATECC508A */ 04736 err = BAD_COND_E; 04737 04738 #else 04739 04740 /* pubkey point cannot be at infinity */ 04741 if (wc_ecc_point_is_at_infinity(&key->pubkey)) 04742 return ECC_INF_E; 04743 04744 /* load curve info */ 04745 err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME | 04746 ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER 04747 #ifdef USE_ECC_B_PARAM 04748 | ECC_CURVE_FIELD_BF 04749 #endif 04750 )); 04751 04752 #ifndef USE_ECC_B_PARAM 04753 /* load curve b parameter */ 04754 if (err == MP_OKAY) 04755 err = mp_init(b); 04756 if (err == MP_OKAY) 04757 err = mp_read_radix(b, key->dp->Bf, 16); 04758 #else 04759 b = curve->Bf; 04760 #endif 04761 04762 /* Qx must be in the range [0, p-1] */ 04763 if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT) 04764 err = ECC_OUT_OF_RANGE_E; 04765 04766 /* Qy must be in the range [0, p-1] */ 04767 if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT) 04768 err = ECC_OUT_OF_RANGE_E; 04769 04770 /* make sure point is actually on curve */ 04771 if (err == MP_OKAY) 04772 err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime); 04773 04774 /* pubkey * order must be at infinity */ 04775 if (err == MP_OKAY) 04776 err = ecc_check_pubkey_order(key, curve->Af, curve->prime, curve->order); 04777 04778 /* private * base generator must equal pubkey */ 04779 if (err == MP_OKAY && key->type == ECC_PRIVATEKEY) 04780 err = ecc_check_privkey_gen(key, curve->Af, curve->prime); 04781 04782 wc_ecc_curve_free(curve); 04783 04784 #ifndef USE_ECC_B_PARAM 04785 mp_clear(b); 04786 #endif 04787 04788 #endif /* WOLFSSL_ATECC508A */ 04789 04790 return err; 04791 } 04792 04793 #ifdef HAVE_ECC_KEY_IMPORT 04794 /* import public ECC key in ANSI X9.63 format */ 04795 int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, 04796 int curve_id) 04797 { 04798 int err = MP_OKAY; 04799 #ifndef WOLFSSL_ATECC508A 04800 int compressed = 0; 04801 #endif /* !WOLFSSL_ATECC508A */ 04802 void* heap; 04803 04804 if (in == NULL || key == NULL) 04805 return BAD_FUNC_ARG; 04806 04807 /* must be odd */ 04808 if ((inLen & 1) == 0) { 04809 return ECC_BAD_ARG_E; 04810 } 04811 04812 heap = key->heap; /* save heap */ 04813 XMEMSET(key, 0, sizeof(ecc_key)); 04814 key->heap = heap; /* restore heap */ 04815 04816 #ifdef WOLFSSL_ATECC508A 04817 /* TODO: Implement equiv call to ATECC508A */ 04818 err = BAD_COND_E; 04819 04820 #else 04821 04822 /* init key */ 04823 #ifdef ALT_ECC_SIZE 04824 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 04825 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 04826 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 04827 alt_fp_init(key->pubkey.x); 04828 alt_fp_init(key->pubkey.y); 04829 alt_fp_init(key->pubkey.z); 04830 err = mp_init(&key->k); 04831 #else 04832 err = mp_init_multi(&key->k, 04833 key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL); 04834 #endif 04835 if (err != MP_OKAY) 04836 return MEMORY_E; 04837 04838 /* check for 4, 2, or 3 */ 04839 if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) { 04840 err = ASN_PARSE_E; 04841 } 04842 04843 if (in[0] == 0x02 || in[0] == 0x03) { 04844 #ifdef HAVE_COMP_KEY 04845 compressed = 1; 04846 #else 04847 err = NOT_COMPILED_IN; 04848 #endif 04849 } 04850 04851 if (err == MP_OKAY) { 04852 int keysize; 04853 /* adjust inLen if compressed */ 04854 if (compressed) 04855 inLen = (inLen-1)*2 + 1; /* used uncompressed len */ 04856 04857 /* determine key size */ 04858 keysize = ((inLen-1)>>1); 04859 err = wc_ecc_set_curve(key, keysize, curve_id); 04860 key->type = ECC_PUBLICKEY; 04861 } 04862 04863 /* read data */ 04864 if (err == MP_OKAY) 04865 err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in+1, (inLen-1)>>1); 04866 04867 #ifdef HAVE_COMP_KEY 04868 if (err == MP_OKAY && compressed == 1) { /* build y */ 04869 mp_int t1, t2; 04870 int did_init = 0; 04871 04872 DECLARE_CURVE_SPECS(3) 04873 04874 if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY) 04875 err = MEMORY_E; 04876 else 04877 did_init = 1; 04878 04879 /* load curve info */ 04880 if (err == MP_OKAY) 04881 err = wc_ecc_curve_load(key->dp, &curve, 04882 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | 04883 ECC_CURVE_FIELD_BF)); 04884 04885 /* compute x^3 */ 04886 if (err == MP_OKAY) 04887 err = mp_sqr(key->pubkey.x, &t1); 04888 if (err == MP_OKAY) 04889 err = mp_mulmod(&t1, key->pubkey.x, curve->prime, &t1); 04890 04891 /* compute x^3 + a*x */ 04892 if (err == MP_OKAY) 04893 err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, &t2); 04894 if (err == MP_OKAY) 04895 err = mp_add(&t1, &t2, &t1); 04896 04897 /* compute x^3 + a*x + b */ 04898 if (err == MP_OKAY) 04899 err = mp_add(&t1, curve->Bf, &t1); 04900 04901 /* compute sqrt(x^3 + a*x + b) */ 04902 if (err == MP_OKAY) 04903 err = mp_sqrtmod_prime(&t1, curve->prime, &t2); 04904 04905 /* adjust y */ 04906 if (err == MP_OKAY) { 04907 if ((mp_isodd(&t2) == MP_YES && in[0] == 0x03) || 04908 (mp_isodd(&t2) == MP_NO && in[0] == 0x02)) { 04909 err = mp_mod(&t2, curve->prime, &t2); 04910 } 04911 else { 04912 err = mp_submod(curve->prime, &t2, curve->prime, &t2); 04913 } 04914 if (err == MP_OKAY) 04915 err = mp_copy(&t2, key->pubkey.y); 04916 } 04917 04918 if (did_init) { 04919 mp_clear(&t2); 04920 mp_clear(&t1); 04921 } 04922 04923 wc_ecc_curve_free(curve); 04924 } 04925 #endif /* HAVE_COMP_KEY */ 04926 04927 if (err == MP_OKAY && compressed == 0) 04928 err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in+1+((inLen-1)>>1), 04929 (inLen-1)>>1); 04930 if (err == MP_OKAY) 04931 err = mp_set(key->pubkey.z, 1); 04932 04933 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 04934 if (err == MP_OKAY) 04935 err = wc_ecc_check_key(key); 04936 #endif 04937 04938 if (err != MP_OKAY) { 04939 mp_clear(key->pubkey.x); 04940 mp_clear(key->pubkey.y); 04941 mp_clear(key->pubkey.z); 04942 mp_clear(&key->k); 04943 } 04944 #endif /* WOLFSSL_ATECC508A */ 04945 04946 return err; 04947 } 04948 04949 int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) 04950 { 04951 return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF); 04952 } 04953 #endif /* HAVE_ECC_KEY_IMPORT */ 04954 04955 #ifdef HAVE_ECC_KEY_EXPORT 04956 /* export ecc private key only raw, outLen is in/out size 04957 return MP_OKAY on success */ 04958 int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen) 04959 { 04960 word32 numlen; 04961 04962 if (key == NULL || out == NULL || outLen == NULL) { 04963 return BAD_FUNC_ARG; 04964 } 04965 04966 if (wc_ecc_is_valid_idx(key->idx) == 0) { 04967 return ECC_BAD_ARG_E; 04968 } 04969 numlen = key->dp->size; 04970 04971 if (*outLen < numlen) { 04972 *outLen = numlen; 04973 return BUFFER_E; 04974 } 04975 *outLen = numlen; 04976 XMEMSET(out, 0, *outLen); 04977 04978 #ifdef WOLFSSL_ATECC508A 04979 /* TODO: Implement equiv call to ATECC508A */ 04980 return BAD_COND_E; 04981 04982 #else 04983 04984 return mp_to_unsigned_bin(&key->k, out + (numlen - 04985 mp_unsigned_bin_size(&key->k))); 04986 #endif /* WOLFSSL_ATECC508A */ 04987 } 04988 04989 04990 /* export ecc key to component form, d is optional if only exporting public 04991 * return MP_OKAY on success */ 04992 static int wc_ecc_export_raw(ecc_key* key, byte* qx, word32* qxLen, 04993 byte* qy, word32* qyLen, byte* d, word32* dLen) 04994 { 04995 int err; 04996 byte exportPriv = 0; 04997 word32 numLen; 04998 04999 if (key == NULL || qx == NULL || qxLen == NULL || qy == NULL || 05000 qyLen == NULL) { 05001 return BAD_FUNC_ARG; 05002 } 05003 05004 if (wc_ecc_is_valid_idx(key->idx) == 0) { 05005 return ECC_BAD_ARG_E; 05006 } 05007 numLen = key->dp->size; 05008 05009 if (d != NULL) { 05010 if (dLen == NULL || key->type != ECC_PRIVATEKEY) 05011 return BAD_FUNC_ARG; 05012 exportPriv = 1; 05013 } 05014 05015 /* check public buffer sizes */ 05016 if ((*qxLen < numLen) || (*qyLen < numLen)) { 05017 *qxLen = numLen; 05018 *qyLen = numLen; 05019 return BUFFER_E; 05020 } 05021 05022 *qxLen = numLen; 05023 *qyLen = numLen; 05024 05025 XMEMSET(qx, 0, *qxLen); 05026 XMEMSET(qy, 0, *qyLen); 05027 05028 /* private d component */ 05029 if (exportPriv == 1) { 05030 05031 /* check private buffer size */ 05032 if (*dLen < numLen) { 05033 *dLen = numLen; 05034 return BUFFER_E; 05035 } 05036 05037 *dLen = numLen; 05038 XMEMSET(d, 0, *dLen); 05039 05040 /* private key, d */ 05041 err = mp_to_unsigned_bin(&key->k, d + 05042 (numLen - mp_unsigned_bin_size(&key->k))); 05043 if (err != MP_OKAY) 05044 return err; 05045 } 05046 05047 /* public x component */ 05048 err = mp_to_unsigned_bin(key->pubkey.x, qx + 05049 (numLen - mp_unsigned_bin_size(key->pubkey.x))); 05050 if (err != MP_OKAY) 05051 return err; 05052 05053 /* public y component */ 05054 err = mp_to_unsigned_bin(key->pubkey.y, qy + 05055 (numLen - mp_unsigned_bin_size(key->pubkey.y))); 05056 if (err != MP_OKAY) 05057 return err; 05058 05059 return 0; 05060 } 05061 05062 05063 /* export public key to raw elements including public (Qx,Qy) 05064 * return MP_OKAY on success, negative on error */ 05065 int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen, 05066 byte* qy, word32* qyLen) 05067 { 05068 return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, NULL, NULL); 05069 } 05070 05071 05072 /* export ecc key to raw elements including public (Qx,Qy) and private (d) 05073 * return MP_OKAY on success, negative on error */ 05074 int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen, 05075 byte* qy, word32* qyLen, byte* d, word32* dLen) 05076 { 05077 /* sanitize d and dLen, other args are checked later */ 05078 if (d == NULL || dLen == NULL) 05079 return BAD_FUNC_ARG; 05080 05081 return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, d, dLen); 05082 } 05083 05084 #endif /* HAVE_ECC_KEY_EXPORT */ 05085 05086 #ifdef HAVE_ECC_KEY_IMPORT 05087 /* import private key, public part optional if (pub) passed as NULL */ 05088 int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, 05089 const byte* pub, word32 pubSz, ecc_key* key, 05090 int curve_id) 05091 { 05092 int ret; 05093 05094 /* public optional, NULL if only importing private */ 05095 if (pub != NULL) { 05096 05097 ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id); 05098 05099 } else { 05100 05101 if (key == NULL || priv == NULL) 05102 return BAD_FUNC_ARG; 05103 05104 /* make sure required key variables are reset */ 05105 key->state = ECC_STATE_NONE; 05106 key->idx = 0; 05107 key->dp = NULL; 05108 05109 /* set key size */ 05110 ret = wc_ecc_set_curve(key, privSz, curve_id); 05111 } 05112 05113 if (ret != 0) 05114 return ret; 05115 05116 key->type = ECC_PRIVATEKEY; 05117 05118 #ifdef WOLFSSL_ATECC508A 05119 /* TODO: Implement equiv call to ATECC508A */ 05120 return BAD_COND_E; 05121 05122 #else 05123 05124 ret = mp_read_unsigned_bin(&key->k, priv, privSz); 05125 05126 #endif /* WOLFSSL_ATECC508A */ 05127 05128 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 05129 if (ret == MP_OKAY) 05130 ret = ecc_check_privkey_gen_helper(key); 05131 #endif 05132 05133 return ret; 05134 } 05135 05136 /* ecc private key import, public key in ANSI X9.63 format, private raw */ 05137 int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, 05138 word32 pubSz, ecc_key* key) 05139 { 05140 return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key, 05141 ECC_CURVE_DEF); 05142 } 05143 #endif /* HAVE_ECC_KEY_IMPORT */ 05144 05145 #ifndef NO_ASN 05146 /** 05147 Convert ECC R,S to signature 05148 r R component of signature 05149 s S component of signature 05150 out DER-encoded ECDSA signature 05151 outlen [in/out] output buffer size, output signature size 05152 return MP_OKAY on success 05153 */ 05154 int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen) 05155 { 05156 int err; 05157 mp_int rtmp; 05158 mp_int stmp; 05159 05160 if (r == NULL || s == NULL || out == NULL || outlen == NULL) 05161 return ECC_BAD_ARG_E; 05162 05163 err = mp_init_multi(&rtmp, &stmp, NULL, NULL, NULL, NULL); 05164 if (err != MP_OKAY) 05165 return err; 05166 05167 err = mp_read_radix(&rtmp, r, 16); 05168 if (err == MP_OKAY) 05169 err = mp_read_radix(&stmp, s, 16); 05170 05171 /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */ 05172 if (err == MP_OKAY) 05173 err = StoreECC_DSA_Sig(out, outlen, &rtmp, &stmp); 05174 05175 if (err == MP_OKAY) { 05176 if (mp_iszero(&rtmp) == MP_YES || mp_iszero(&stmp) == MP_YES) 05177 err = MP_ZERO_E; 05178 } 05179 05180 mp_clear(&rtmp); 05181 mp_clear(&stmp); 05182 05183 return err; 05184 } 05185 05186 05187 /** 05188 Convert ECC signature to R,S 05189 sig DER-encoded ECDSA signature 05190 sigLen length of signature in octets 05191 r R component of signature 05192 rLen [in/out] output "r" buffer size, output "r" size 05193 s S component of signature 05194 sLen [in/out] output "s" buffer size, output "s" size 05195 return MP_OKAY on success, negative on error 05196 */ 05197 int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen, 05198 byte* s, word32* sLen) 05199 { 05200 int err; 05201 word32 x = 0; 05202 mp_int rtmp; 05203 mp_int stmp; 05204 05205 if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL) 05206 return ECC_BAD_ARG_E; 05207 05208 err = DecodeECC_DSA_Sig(sig, sigLen, &rtmp, &stmp); 05209 05210 /* extract r */ 05211 if (err == MP_OKAY) { 05212 x = mp_unsigned_bin_size(&rtmp); 05213 if (*rLen < x) 05214 err = BUFFER_E; 05215 05216 if (err == MP_OKAY) { 05217 *rLen = x; 05218 err = mp_to_unsigned_bin(&rtmp, r); 05219 } 05220 } 05221 05222 /* extract s */ 05223 if (err == MP_OKAY) { 05224 x = mp_unsigned_bin_size(&stmp); 05225 if (*sLen < x) 05226 err = BUFFER_E; 05227 05228 if (err == MP_OKAY) { 05229 *sLen = x; 05230 err = mp_to_unsigned_bin(&stmp, s); 05231 } 05232 } 05233 05234 mp_clear(&rtmp); 05235 mp_clear(&stmp); 05236 05237 return err; 05238 } 05239 #endif /* !NO_ASN */ 05240 05241 #ifdef HAVE_ECC_KEY_IMPORT 05242 static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, 05243 const char* qy, const char* d, int curve_id) 05244 { 05245 int err = MP_OKAY; 05246 void* heap; 05247 05248 /* if d is NULL, only import as public key using Qx,Qy */ 05249 if (key == NULL || qx == NULL || qy == NULL) { 05250 return BAD_FUNC_ARG; 05251 } 05252 05253 heap = key->heap; /* save heap */ 05254 XMEMSET(key, 0, sizeof(ecc_key)); 05255 key->heap = heap; /* restore heap */ 05256 05257 /* set curve type and index */ 05258 err = wc_ecc_set_curve(key, 0, curve_id); 05259 if (err != 0) { 05260 return err; 05261 } 05262 05263 #ifdef WOLFSSL_ATECC508A 05264 /* TODO: Implement equiv call to ATECC508A */ 05265 err = BAD_COND_E; 05266 05267 #else 05268 05269 /* init key */ 05270 #ifdef ALT_ECC_SIZE 05271 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 05272 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 05273 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 05274 alt_fp_init(key->pubkey.x); 05275 alt_fp_init(key->pubkey.y); 05276 alt_fp_init(key->pubkey.z); 05277 err = mp_init(&key->k); 05278 #else 05279 err = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z, 05280 NULL, NULL); 05281 #endif 05282 if (err != MP_OKAY) 05283 return MEMORY_E; 05284 05285 /* read Qx */ 05286 if (err == MP_OKAY) 05287 err = mp_read_radix(key->pubkey.x, qx, 16); 05288 05289 /* read Qy */ 05290 if (err == MP_OKAY) 05291 err = mp_read_radix(key->pubkey.y, qy, 16); 05292 05293 if (err == MP_OKAY) 05294 err = mp_set(key->pubkey.z, 1); 05295 05296 /* import private key */ 05297 if (err == MP_OKAY) { 05298 if (d != NULL) { 05299 key->type = ECC_PRIVATEKEY; 05300 err = mp_read_radix(&key->k, d, 16); 05301 } else { 05302 key->type = ECC_PUBLICKEY; 05303 } 05304 } 05305 05306 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 05307 if (err == MP_OKAY) 05308 err = wc_ecc_check_key(key); 05309 #endif 05310 05311 if (err != MP_OKAY) { 05312 mp_clear(key->pubkey.x); 05313 mp_clear(key->pubkey.y); 05314 mp_clear(key->pubkey.z); 05315 mp_clear(&key->k); 05316 } 05317 #endif /* WOLFSSL_ATECC508A */ 05318 05319 return err; 05320 } 05321 05322 /** 05323 Import raw ECC key 05324 key The destination ecc_key structure 05325 qx x component of the public key, as ASCII hex string 05326 qy y component of the public key, as ASCII hex string 05327 d private key, as ASCII hex string, optional if importing public 05328 key only 05329 dp Custom ecc_set_type 05330 return MP_OKAY on success 05331 */ 05332 int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy, 05333 const char* d, int curve_id) 05334 { 05335 return wc_ecc_import_raw_private(key, qx, qy, d, curve_id); 05336 05337 } 05338 05339 /** 05340 Import raw ECC key 05341 key The destination ecc_key structure 05342 qx x component of the public key, as ASCII hex string 05343 qy y component of the public key, as ASCII hex string 05344 d private key, as ASCII hex string, optional if importing public 05345 key only 05346 curveName ECC curve name, from ecc_sets[] 05347 return MP_OKAY on success 05348 */ 05349 int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy, 05350 const char* d, const char* curveName) 05351 { 05352 int err, x; 05353 05354 /* if d is NULL, only import as public key using Qx,Qy */ 05355 if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) { 05356 return BAD_FUNC_ARG; 05357 } 05358 05359 /* set curve type and index */ 05360 for (x = 0; ecc_sets[x].size != 0; x++) { 05361 if (XSTRNCMP(ecc_sets[x].name, curveName, 05362 XSTRLEN(curveName)) == 0) { 05363 break; 05364 } 05365 } 05366 05367 if (ecc_sets[x].size == 0) { 05368 WOLFSSL_MSG("ecc_set curve name not found"); 05369 err = ASN_PARSE_E; 05370 } else { 05371 return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id); 05372 } 05373 05374 return err; 05375 } 05376 #endif /* HAVE_ECC_KEY_IMPORT */ 05377 05378 /* key size in octets */ 05379 int wc_ecc_size(ecc_key* key) 05380 { 05381 if (key == NULL) return 0; 05382 05383 return key->dp->size; 05384 } 05385 05386 05387 /* worst case estimate, check actual return from wc_ecc_sign_hash for actual 05388 value of signature size in octets */ 05389 int wc_ecc_sig_size(ecc_key* key) 05390 { 05391 int sz = wc_ecc_size(key); 05392 if (sz <= 0) 05393 return sz; 05394 05395 return (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ; 05396 } 05397 05398 05399 #ifdef FP_ECC 05400 05401 /* fixed point ECC cache */ 05402 /* number of entries in the cache */ 05403 #ifndef FP_ENTRIES 05404 #define FP_ENTRIES 15 05405 #endif 05406 05407 /* number of bits in LUT */ 05408 #ifndef FP_LUT 05409 #define FP_LUT 8U 05410 #endif 05411 05412 #ifdef ECC_SHAMIR 05413 /* Sharmir requires a bigger LUT, TAO */ 05414 #if (FP_LUT > 12) || (FP_LUT < 4) 05415 #error FP_LUT must be between 4 and 12 inclusively 05416 #endif 05417 #else 05418 #if (FP_LUT > 12) || (FP_LUT < 2) 05419 #error FP_LUT must be between 2 and 12 inclusively 05420 #endif 05421 #endif 05422 05423 05424 /** Our FP cache */ 05425 typedef struct { 05426 ecc_point* g; /* cached COPY of base point */ 05427 ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */ 05428 mp_int mu; /* copy of the montgomery constant */ 05429 int lru_count; /* amount of times this entry has been used */ 05430 int lock; /* flag to indicate cache eviction */ 05431 /* permitted (0) or not (1) */ 05432 } fp_cache_t; 05433 05434 /* if HAVE_THREAD_LS this cache is per thread, no locking needed */ 05435 static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES]; 05436 05437 #ifndef HAVE_THREAD_LS 05438 static volatile int initMutex = 0; /* prevent multiple mutex inits */ 05439 static wolfSSL_Mutex ecc_fp_lock; 05440 #endif /* HAVE_THREAD_LS */ 05441 05442 /* simple table to help direct the generation of the LUT */ 05443 static const struct { 05444 int ham, terma, termb; 05445 } lut_orders[] = { 05446 { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 }, 05447 { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 }, 05448 { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 }, 05449 { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 }, 05450 { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 }, 05451 { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 }, 05452 { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 }, 05453 { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 }, 05454 #if FP_LUT > 6 05455 { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 }, 05456 { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 }, 05457 { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 }, 05458 { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 }, 05459 { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 }, 05460 { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 }, 05461 { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 }, 05462 { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 }, 05463 #if FP_LUT > 7 05464 { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 }, 05465 { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 }, 05466 { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 }, 05467 { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 }, 05468 { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 }, 05469 { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 }, 05470 { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 }, 05471 { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 }, 05472 { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 }, 05473 { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 }, 05474 { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 }, 05475 { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 }, 05476 { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 }, 05477 { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 }, 05478 { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 }, 05479 { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 }, 05480 #if FP_LUT > 8 05481 { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 }, 05482 { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 }, 05483 { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 }, 05484 { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 }, 05485 { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 }, 05486 { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 }, 05487 { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 }, 05488 { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 }, 05489 { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 }, 05490 { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 }, 05491 { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 }, 05492 { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 }, 05493 { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 }, 05494 { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 }, 05495 { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 }, 05496 { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 }, 05497 { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 }, 05498 { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 }, 05499 { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 }, 05500 { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 }, 05501 { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 }, 05502 { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 }, 05503 { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 }, 05504 { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 }, 05505 { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 }, 05506 { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 }, 05507 { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 }, 05508 { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 }, 05509 { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 }, 05510 { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 }, 05511 { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 }, 05512 { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 }, 05513 #if FP_LUT > 9 05514 { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 }, 05515 { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 }, 05516 { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 }, 05517 { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 }, 05518 { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 }, 05519 { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 }, 05520 { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 }, 05521 { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 }, 05522 { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 }, 05523 { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 }, 05524 { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 }, 05525 { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 }, 05526 { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 }, 05527 { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 }, 05528 { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 }, 05529 { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 }, 05530 { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 }, 05531 { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 }, 05532 { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 }, 05533 { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 }, 05534 { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 }, 05535 { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 }, 05536 { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 }, 05537 { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 }, 05538 { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 }, 05539 { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 }, 05540 { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 }, 05541 { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 }, 05542 { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 }, 05543 { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 }, 05544 { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 }, 05545 { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 }, 05546 { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 }, 05547 { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 }, 05548 { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 }, 05549 { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 }, 05550 { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 }, 05551 { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 }, 05552 { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 }, 05553 { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 }, 05554 { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 }, 05555 { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 }, 05556 { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 }, 05557 { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 }, 05558 { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 }, 05559 { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 }, 05560 { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 }, 05561 { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 }, 05562 { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 }, 05563 { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 }, 05564 { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 }, 05565 { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 }, 05566 { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 }, 05567 { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 }, 05568 { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 }, 05569 { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 }, 05570 { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 }, 05571 { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 }, 05572 { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 }, 05573 { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 }, 05574 { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 }, 05575 { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 }, 05576 { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 }, 05577 { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 }, 05578 #if FP_LUT > 10 05579 { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 }, 05580 { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 }, 05581 { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 }, 05582 { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 }, 05583 { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 }, 05584 { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 }, 05585 { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 }, 05586 { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 }, 05587 { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 }, 05588 { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 }, 05589 { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 }, 05590 { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 }, 05591 { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 }, 05592 { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 }, 05593 { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 }, 05594 { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 }, 05595 { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 }, 05596 { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 }, 05597 { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 }, 05598 { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 }, 05599 { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 }, 05600 { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 }, 05601 { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 }, 05602 { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 }, 05603 { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 }, 05604 { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 }, 05605 { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 }, 05606 { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 }, 05607 { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 }, 05608 { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 }, 05609 { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 }, 05610 { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 }, 05611 { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 }, 05612 { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 }, 05613 { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 }, 05614 { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 }, 05615 { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 }, 05616 { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 }, 05617 { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 }, 05618 { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 }, 05619 { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 }, 05620 { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 }, 05621 { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 }, 05622 { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 }, 05623 { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 }, 05624 { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 }, 05625 { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 }, 05626 { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 }, 05627 { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 }, 05628 { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 }, 05629 { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 }, 05630 { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 }, 05631 { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 }, 05632 { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 }, 05633 { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 }, 05634 { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 }, 05635 { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 }, 05636 { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 }, 05637 { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 }, 05638 { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 }, 05639 { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 }, 05640 { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 }, 05641 { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 }, 05642 { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 }, 05643 { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 }, 05644 { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 }, 05645 { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 }, 05646 { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 }, 05647 { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 }, 05648 { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 }, 05649 { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 }, 05650 { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 }, 05651 { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 }, 05652 { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 }, 05653 { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 }, 05654 { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 }, 05655 { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 }, 05656 { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 }, 05657 { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 }, 05658 { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 }, 05659 { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 }, 05660 { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 }, 05661 { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 }, 05662 { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 }, 05663 { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 }, 05664 { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 }, 05665 { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 }, 05666 { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 }, 05667 { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 }, 05668 { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 }, 05669 { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 }, 05670 { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 }, 05671 { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 }, 05672 { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 }, 05673 { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 }, 05674 { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 }, 05675 { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 }, 05676 { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 }, 05677 { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 }, 05678 { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 }, 05679 { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 }, 05680 { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 }, 05681 { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 }, 05682 { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 }, 05683 { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 }, 05684 { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 }, 05685 { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 }, 05686 { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 }, 05687 { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 }, 05688 { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 }, 05689 { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 }, 05690 { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 }, 05691 { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 }, 05692 { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 }, 05693 { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 }, 05694 { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 }, 05695 { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 }, 05696 { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 }, 05697 { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 }, 05698 { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 }, 05699 { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 }, 05700 { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 }, 05701 { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 }, 05702 { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 }, 05703 { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 }, 05704 { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 }, 05705 { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 }, 05706 { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 }, 05707 #if FP_LUT > 11 05708 { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 }, 05709 { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 }, 05710 { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 }, 05711 { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 }, 05712 { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 }, 05713 { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 }, 05714 { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 }, 05715 { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 }, 05716 { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 }, 05717 { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 }, 05718 { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 }, 05719 { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 }, 05720 { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 }, 05721 { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 }, 05722 { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 }, 05723 { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 }, 05724 { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 }, 05725 { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 }, 05726 { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 }, 05727 { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 }, 05728 { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 }, 05729 { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 }, 05730 { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 }, 05731 { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 }, 05732 { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 }, 05733 { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 }, 05734 { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 }, 05735 { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 }, 05736 { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 }, 05737 { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 }, 05738 { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 }, 05739 { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 }, 05740 { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 }, 05741 { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 }, 05742 { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 }, 05743 { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 }, 05744 { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 }, 05745 { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 }, 05746 { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 }, 05747 { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 }, 05748 { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 }, 05749 { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 }, 05750 { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 }, 05751 { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 }, 05752 { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 }, 05753 { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 }, 05754 { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 }, 05755 { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 }, 05756 { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 }, 05757 { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 }, 05758 { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 }, 05759 { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 }, 05760 { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 }, 05761 { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 }, 05762 { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 }, 05763 { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 }, 05764 { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 }, 05765 { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 }, 05766 { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 }, 05767 { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 }, 05768 { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 }, 05769 { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 }, 05770 { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 }, 05771 { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 }, 05772 { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 }, 05773 { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 }, 05774 { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 }, 05775 { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 }, 05776 { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 }, 05777 { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 }, 05778 { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 }, 05779 { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 }, 05780 { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 }, 05781 { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 }, 05782 { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 }, 05783 { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 }, 05784 { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 }, 05785 { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 }, 05786 { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 }, 05787 { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 }, 05788 { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 }, 05789 { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 }, 05790 { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 }, 05791 { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 }, 05792 { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 }, 05793 { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 }, 05794 { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 }, 05795 { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 }, 05796 { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 }, 05797 { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 }, 05798 { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 }, 05799 { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 }, 05800 { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 }, 05801 { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 }, 05802 { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 }, 05803 { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 }, 05804 { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 }, 05805 { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 }, 05806 { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 }, 05807 { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 }, 05808 { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 }, 05809 { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 }, 05810 { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 }, 05811 { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 }, 05812 { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 }, 05813 { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 }, 05814 { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 }, 05815 { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 }, 05816 { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 }, 05817 { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 }, 05818 { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 }, 05819 { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 }, 05820 { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 }, 05821 { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 }, 05822 { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 }, 05823 { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 }, 05824 { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 }, 05825 { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 }, 05826 { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 }, 05827 { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 }, 05828 { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 }, 05829 { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 }, 05830 { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 }, 05831 { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 }, 05832 { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 }, 05833 { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 }, 05834 { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 }, 05835 { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 }, 05836 { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 }, 05837 { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 }, 05838 { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 }, 05839 { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 }, 05840 { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 }, 05841 { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 }, 05842 { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 }, 05843 { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 }, 05844 { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 }, 05845 { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 }, 05846 { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 }, 05847 { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 }, 05848 { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 }, 05849 { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 }, 05850 { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 }, 05851 { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 }, 05852 { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 }, 05853 { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 }, 05854 { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 }, 05855 { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 }, 05856 { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 }, 05857 { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 }, 05858 { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 }, 05859 { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 }, 05860 { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 }, 05861 { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 }, 05862 { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 }, 05863 { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 }, 05864 { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 }, 05865 { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 }, 05866 { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 }, 05867 { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 }, 05868 { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 }, 05869 { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 }, 05870 { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 }, 05871 { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 }, 05872 { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 }, 05873 { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 }, 05874 { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 }, 05875 { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 }, 05876 { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 }, 05877 { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 }, 05878 { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 }, 05879 { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 }, 05880 { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 }, 05881 { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 }, 05882 { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 }, 05883 { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 }, 05884 { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 }, 05885 { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 }, 05886 { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 }, 05887 { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 }, 05888 { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 }, 05889 { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 }, 05890 { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 }, 05891 { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 }, 05892 { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 }, 05893 { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 }, 05894 { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 }, 05895 { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 }, 05896 { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 }, 05897 { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 }, 05898 { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 }, 05899 { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 }, 05900 { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 }, 05901 { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 }, 05902 { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 }, 05903 { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 }, 05904 { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 }, 05905 { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 }, 05906 { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 }, 05907 { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 }, 05908 { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 }, 05909 { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 }, 05910 { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 }, 05911 { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 }, 05912 { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 }, 05913 { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 }, 05914 { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 }, 05915 { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 }, 05916 { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 }, 05917 { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 }, 05918 { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 }, 05919 { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 }, 05920 { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 }, 05921 { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 }, 05922 { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 }, 05923 { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 }, 05924 { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 }, 05925 { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 }, 05926 { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 }, 05927 { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 }, 05928 { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 }, 05929 { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 }, 05930 { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 }, 05931 { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 }, 05932 { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 }, 05933 { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 }, 05934 { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 }, 05935 { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 }, 05936 { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 }, 05937 { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 }, 05938 { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 }, 05939 { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 }, 05940 { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 }, 05941 { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 }, 05942 { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 }, 05943 { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 }, 05944 { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 }, 05945 { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 }, 05946 { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 }, 05947 { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 }, 05948 { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 }, 05949 { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 }, 05950 { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 }, 05951 { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 }, 05952 { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 }, 05953 { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 }, 05954 { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 }, 05955 { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 }, 05956 { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 }, 05957 { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 }, 05958 { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 }, 05959 { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 }, 05960 { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 }, 05961 { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 }, 05962 { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 }, 05963 { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 }, 05964 #endif 05965 #endif 05966 #endif 05967 #endif 05968 #endif 05969 #endif 05970 }; 05971 05972 /* find a hole and free as required, return -1 if no hole found */ 05973 static int find_hole(void) 05974 { 05975 unsigned x; 05976 int y, z; 05977 for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { 05978 if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { 05979 z = x; 05980 y = fp_cache[x].lru_count; 05981 } 05982 } 05983 05984 /* decrease all */ 05985 for (x = 0; x < FP_ENTRIES; x++) { 05986 if (fp_cache[x].lru_count > 3) { 05987 --(fp_cache[x].lru_count); 05988 } 05989 } 05990 05991 /* free entry z */ 05992 if (z >= 0 && fp_cache[z].g) { 05993 mp_clear(&fp_cache[z].mu); 05994 wc_ecc_del_point(fp_cache[z].g); 05995 fp_cache[z].g = NULL; 05996 for (x = 0; x < (1U<<FP_LUT); x++) { 05997 wc_ecc_del_point(fp_cache[z].LUT[x]); 05998 fp_cache[z].LUT[x] = NULL; 05999 } 06000 fp_cache[z].lru_count = 0; 06001 } 06002 return z; 06003 } 06004 06005 /* determine if a base is already in the cache and if so, where */ 06006 static int find_base(ecc_point* g) 06007 { 06008 int x; 06009 for (x = 0; x < FP_ENTRIES; x++) { 06010 if (fp_cache[x].g != NULL && 06011 mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ && 06012 mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ && 06013 mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) { 06014 break; 06015 } 06016 } 06017 if (x == FP_ENTRIES) { 06018 x = -1; 06019 } 06020 return x; 06021 } 06022 06023 /* add a new base to the cache */ 06024 static int add_entry(int idx, ecc_point *g) 06025 { 06026 unsigned x, y; 06027 06028 /* allocate base and LUT */ 06029 fp_cache[idx].g = wc_ecc_new_point(); 06030 if (fp_cache[idx].g == NULL) { 06031 return GEN_MEM_ERR; 06032 } 06033 06034 /* copy x and y */ 06035 if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) || 06036 (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) || 06037 (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) { 06038 wc_ecc_del_point(fp_cache[idx].g); 06039 fp_cache[idx].g = NULL; 06040 return GEN_MEM_ERR; 06041 } 06042 06043 for (x = 0; x < (1U<<FP_LUT); x++) { 06044 fp_cache[idx].LUT[x] = wc_ecc_new_point(); 06045 if (fp_cache[idx].LUT[x] == NULL) { 06046 for (y = 0; y < x; y++) { 06047 wc_ecc_del_point(fp_cache[idx].LUT[y]); 06048 fp_cache[idx].LUT[y] = NULL; 06049 } 06050 wc_ecc_del_point(fp_cache[idx].g); 06051 fp_cache[idx].g = NULL; 06052 fp_cache[idx].lru_count = 0; 06053 return GEN_MEM_ERR; 06054 } 06055 } 06056 06057 fp_cache[idx].lru_count = 0; 06058 06059 return MP_OKAY; 06060 } 06061 06062 /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart 06063 * 06064 * The algorithm builds patterns in increasing bit order by first making all 06065 * single bit input patterns, then all two bit input patterns and so on 06066 */ 06067 static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp, 06068 mp_int* mu) 06069 { 06070 int err; 06071 unsigned x, y, bitlen, lut_gap; 06072 mp_int tmp; 06073 06074 if (mp_init(&tmp) != MP_OKAY) 06075 return GEN_MEM_ERR; 06076 06077 /* sanity check to make sure lut_order table is of correct size, 06078 should compile out to a NOP if true */ 06079 if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) { 06080 err = BAD_FUNC_ARG; 06081 } 06082 else { 06083 /* get bitlen and round up to next multiple of FP_LUT */ 06084 bitlen = mp_unsigned_bin_size(modulus) << 3; 06085 x = bitlen % FP_LUT; 06086 if (x) { 06087 bitlen += FP_LUT - x; 06088 } 06089 lut_gap = bitlen / FP_LUT; 06090 06091 /* init the mu */ 06092 err = mp_init_copy(&fp_cache[idx].mu, mu); 06093 } 06094 06095 /* copy base */ 06096 if (err == MP_OKAY) { 06097 if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus, 06098 fp_cache[idx].LUT[1]->x) != MP_OKAY) || 06099 (mp_mulmod(fp_cache[idx].g->y, mu, modulus, 06100 fp_cache[idx].LUT[1]->y) != MP_OKAY) || 06101 (mp_mulmod(fp_cache[idx].g->z, mu, modulus, 06102 fp_cache[idx].LUT[1]->z) != MP_OKAY)) { 06103 err = MP_MULMOD_E; 06104 } 06105 } 06106 06107 /* make all single bit entries */ 06108 for (x = 1; x < FP_LUT; x++) { 06109 if (err != MP_OKAY) 06110 break; 06111 if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, 06112 fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) || 06113 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, 06114 fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) || 06115 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, 06116 fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){ 06117 err = MP_INIT_E; 06118 break; 06119 } else { 06120 06121 /* now double it bitlen/FP_LUT times */ 06122 for (y = 0; y < lut_gap; y++) { 06123 if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x], 06124 fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) { 06125 break; 06126 } 06127 } 06128 } 06129 } 06130 06131 /* now make all entries in increase order of hamming weight */ 06132 for (x = 2; x <= FP_LUT; x++) { 06133 if (err != MP_OKAY) 06134 break; 06135 for (y = 0; y < (1UL<<FP_LUT); y++) { 06136 if (lut_orders[y].ham != (int)x) continue; 06137 06138 /* perform the add */ 06139 if ((err = ecc_projective_add_point( 06140 fp_cache[idx].LUT[lut_orders[y].terma], 06141 fp_cache[idx].LUT[lut_orders[y].termb], 06142 fp_cache[idx].LUT[y], a, modulus, mp)) != MP_OKAY) { 06143 break; 06144 } 06145 } 06146 } 06147 06148 /* now map all entries back to affine space to make point addition faster */ 06149 for (x = 1; x < (1UL<<FP_LUT); x++) { 06150 if (err != MP_OKAY) 06151 break; 06152 06153 /* convert z to normal from montgomery */ 06154 err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp); 06155 06156 /* invert it */ 06157 if (err == MP_OKAY) 06158 err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, 06159 fp_cache[idx].LUT[x]->z); 06160 06161 if (err == MP_OKAY) 06162 /* now square it */ 06163 err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp); 06164 06165 if (err == MP_OKAY) 06166 /* fix x */ 06167 err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus, 06168 fp_cache[idx].LUT[x]->x); 06169 06170 if (err == MP_OKAY) 06171 /* get 1/z^3 */ 06172 err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp); 06173 06174 if (err == MP_OKAY) 06175 /* fix y */ 06176 err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus, 06177 fp_cache[idx].LUT[x]->y); 06178 06179 if (err == MP_OKAY) 06180 /* free z */ 06181 mp_clear(fp_cache[idx].LUT[x]->z); 06182 } 06183 06184 mp_clear(&tmp); 06185 06186 if (err == MP_OKAY) 06187 return MP_OKAY; 06188 06189 /* err cleanup */ 06190 for (y = 0; y < (1U<<FP_LUT); y++) { 06191 wc_ecc_del_point(fp_cache[idx].LUT[y]); 06192 fp_cache[idx].LUT[y] = NULL; 06193 } 06194 wc_ecc_del_point(fp_cache[idx].g); 06195 fp_cache[idx].g = NULL; 06196 fp_cache[idx].lru_count = 0; 06197 mp_clear(&fp_cache[idx].mu); 06198 06199 return err; 06200 } 06201 06202 /* perform a fixed point ECC mulmod */ 06203 static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, 06204 mp_int* modulus, mp_digit mp, int map) 06205 { 06206 #define KB_SIZE 128 06207 06208 #ifdef WOLFSSL_SMALL_STACK 06209 unsigned char* kb = NULL; 06210 #else 06211 unsigned char kb[KB_SIZE]; 06212 #endif 06213 int x, err; 06214 unsigned y, z = 0, bitlen, bitpos, lut_gap, first; 06215 mp_int tk, order; 06216 06217 if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY) 06218 return MP_INIT_E; 06219 06220 /* if it's smaller than modulus we fine */ 06221 if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) { 06222 /* find order */ 06223 y = mp_unsigned_bin_size(modulus); 06224 for (x = 0; ecc_sets[x].size; x++) { 06225 if (y <= (unsigned)ecc_sets[x].size) break; 06226 } 06227 06228 /* back off if we are on the 521 bit curve */ 06229 if (y == 66) --x; 06230 06231 if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { 06232 goto done; 06233 } 06234 06235 /* k must be less than modulus */ 06236 if (mp_cmp(k, &order) != MP_LT) { 06237 if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) { 06238 goto done; 06239 } 06240 } else { 06241 if ((err = mp_copy(k, &tk)) != MP_OKAY) { 06242 goto done; 06243 } 06244 } 06245 } else { 06246 if ((err = mp_copy(k, &tk)) != MP_OKAY) { 06247 goto done; 06248 } 06249 } 06250 06251 /* get bitlen and round up to next multiple of FP_LUT */ 06252 bitlen = mp_unsigned_bin_size(modulus) << 3; 06253 x = bitlen % FP_LUT; 06254 if (x) { 06255 bitlen += FP_LUT - x; 06256 } 06257 lut_gap = bitlen / FP_LUT; 06258 06259 /* get the k value */ 06260 if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) { 06261 err = BUFFER_E; goto done; 06262 } 06263 06264 /* store k */ 06265 #ifdef WOLFSSL_SMALL_STACK 06266 kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 06267 if (kb == NULL) { 06268 err = MEMORY_E; goto done; 06269 } 06270 #endif 06271 06272 XMEMSET(kb, 0, KB_SIZE); 06273 if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) { 06274 /* let's reverse kb so it's little endian */ 06275 x = 0; 06276 y = mp_unsigned_bin_size(&tk); 06277 if (y > 0) { 06278 y -= 1; 06279 } 06280 06281 while ((unsigned)x < y) { 06282 z = kb[x]; kb[x] = kb[y]; kb[y] = z; 06283 ++x; --y; 06284 } 06285 06286 /* at this point we can start, yipee */ 06287 first = 1; 06288 for (x = lut_gap-1; x >= 0; x--) { 06289 /* extract FP_LUT bits from kb spread out by lut_gap bits and offset 06290 by x bits from the start */ 06291 bitpos = x; 06292 for (y = z = 0; y < FP_LUT; y++) { 06293 z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y; 06294 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid 06295 the mult in each loop */ 06296 } 06297 06298 /* double if not first */ 06299 if (!first) { 06300 if ((err = ecc_projective_dbl_point(R, R, a, modulus, 06301 mp)) != MP_OKAY) { 06302 break; 06303 } 06304 } 06305 06306 /* add if not first, otherwise copy */ 06307 if (!first && z) { 06308 if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, 06309 a, modulus, mp)) != MP_OKAY) { 06310 break; 06311 } 06312 } else if (z) { 06313 if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) || 06314 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) || 06315 (mp_copy(&fp_cache[idx].mu, R->z) != MP_OKAY)) { 06316 err = GEN_MEM_ERR; 06317 break; 06318 } 06319 first = 0; 06320 } 06321 } 06322 } 06323 06324 if (err == MP_OKAY) { 06325 (void) z; /* Acknowledge the unused assignment */ 06326 ForceZero(kb, KB_SIZE); 06327 06328 /* map R back from projective space */ 06329 if (map) { 06330 err = ecc_map(R, modulus, mp); 06331 } else { 06332 err = MP_OKAY; 06333 } 06334 } 06335 06336 done: 06337 /* cleanup */ 06338 mp_clear(&order); 06339 mp_clear(&tk); 06340 06341 #ifdef WOLFSSL_SMALL_STACK 06342 XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER); 06343 #endif 06344 06345 #undef KB_SIZE 06346 06347 return err; 06348 } 06349 06350 #ifdef ECC_SHAMIR 06351 /* perform a fixed point ECC mulmod */ 06352 static int accel_fp_mul2add(int idx1, int idx2, 06353 mp_int* kA, mp_int* kB, 06354 ecc_point *R, mp_int* a, 06355 mp_int* modulus, mp_digit mp) 06356 { 06357 #define KB_SIZE 128 06358 06359 #ifdef WOLFSSL_SMALL_STACK 06360 unsigned char* kb[2] = {NULL, NULL}; 06361 #else 06362 unsigned char kb[2][KB_SIZE]; 06363 #endif 06364 int x, err; 06365 unsigned y, z, bitlen, bitpos, lut_gap, first, zA, zB; 06366 mp_int tka, tkb, order; 06367 06368 if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY) 06369 return MP_INIT_E; 06370 06371 /* if it's smaller than modulus we fine */ 06372 if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { 06373 /* find order */ 06374 y = mp_unsigned_bin_size(modulus); 06375 for (x = 0; ecc_sets[x].size; x++) { 06376 if (y <= (unsigned)ecc_sets[x].size) break; 06377 } 06378 06379 /* back off if we are on the 521 bit curve */ 06380 if (y == 66) --x; 06381 06382 if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { 06383 goto done; 06384 } 06385 06386 /* kA must be less than modulus */ 06387 if (mp_cmp(kA, &order) != MP_LT) { 06388 if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) { 06389 goto done; 06390 } 06391 } else { 06392 if ((err = mp_copy(kA, &tka)) != MP_OKAY) { 06393 goto done; 06394 } 06395 } 06396 } else { 06397 if ((err = mp_copy(kA, &tka)) != MP_OKAY) { 06398 goto done; 06399 } 06400 } 06401 06402 /* if it's smaller than modulus we fine */ 06403 if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { 06404 /* find order */ 06405 y = mp_unsigned_bin_size(modulus); 06406 for (x = 0; ecc_sets[x].size; x++) { 06407 if (y <= (unsigned)ecc_sets[x].size) break; 06408 } 06409 06410 /* back off if we are on the 521 bit curve */ 06411 if (y == 66) --x; 06412 06413 if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { 06414 goto done; 06415 } 06416 06417 /* kB must be less than modulus */ 06418 if (mp_cmp(kB, &order) != MP_LT) { 06419 if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) { 06420 goto done; 06421 } 06422 } else { 06423 if ((err = mp_copy(kB, &tkb)) != MP_OKAY) { 06424 goto done; 06425 } 06426 } 06427 } else { 06428 if ((err = mp_copy(kB, &tkb)) != MP_OKAY) { 06429 goto done; 06430 } 06431 } 06432 06433 /* get bitlen and round up to next multiple of FP_LUT */ 06434 bitlen = mp_unsigned_bin_size(modulus) << 3; 06435 x = bitlen % FP_LUT; 06436 if (x) { 06437 bitlen += FP_LUT - x; 06438 } 06439 lut_gap = bitlen / FP_LUT; 06440 06441 /* get the k value */ 06442 if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) || 06443 (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) { 06444 err = BUFFER_E; goto done; 06445 } 06446 06447 /* store k */ 06448 #ifdef WOLFSSL_SMALL_STACK 06449 kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 06450 if (kb[0] == NULL) { 06451 err = MEMORY_E; goto done; 06452 } 06453 #endif 06454 06455 XMEMSET(kb[0], 0, KB_SIZE); 06456 if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) { 06457 goto done; 06458 } 06459 06460 /* let's reverse kb so it's little endian */ 06461 x = 0; 06462 y = mp_unsigned_bin_size(&tka); 06463 if (y > 0) { 06464 y -= 1; 06465 } 06466 mp_clear(&tka); 06467 while ((unsigned)x < y) { 06468 z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z; 06469 ++x; --y; 06470 } 06471 06472 /* store b */ 06473 #ifdef WOLFSSL_SMALL_STACK 06474 kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 06475 if (kb[1] == NULL) { 06476 err = MEMORY_E; goto done; 06477 } 06478 #endif 06479 06480 XMEMSET(kb[1], 0, KB_SIZE); 06481 if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) { 06482 x = 0; 06483 y = mp_unsigned_bin_size(&tkb); 06484 if (y > 0) { 06485 y -= 1; 06486 } 06487 06488 while ((unsigned)x < y) { 06489 z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z; 06490 ++x; --y; 06491 } 06492 06493 /* at this point we can start, yipee */ 06494 first = 1; 06495 for (x = lut_gap-1; x >= 0; x--) { 06496 /* extract FP_LUT bits from kb spread out by lut_gap bits and 06497 offset by x bits from the start */ 06498 bitpos = x; 06499 for (y = zA = zB = 0; y < FP_LUT; y++) { 06500 zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y; 06501 zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y; 06502 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid 06503 the mult in each loop */ 06504 } 06505 06506 /* double if not first */ 06507 if (!first) { 06508 if ((err = ecc_projective_dbl_point(R, R, a, modulus, 06509 mp)) != MP_OKAY) { 06510 break; 06511 } 06512 } 06513 06514 /* add if not first, otherwise copy */ 06515 if (!first) { 06516 if (zA) { 06517 if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA], 06518 R, a, modulus, mp)) != MP_OKAY) { 06519 break; 06520 } 06521 } 06522 if (zB) { 06523 if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB], 06524 R, a, modulus, mp)) != MP_OKAY) { 06525 break; 06526 } 06527 } 06528 } else { 06529 if (zA) { 06530 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) || 06531 (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) || 06532 (mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) { 06533 err = GEN_MEM_ERR; 06534 break; 06535 } 06536 first = 0; 06537 } 06538 if (zB && first == 0) { 06539 if (zB) { 06540 if ((err = ecc_projective_add_point(R, 06541 fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){ 06542 break; 06543 } 06544 } 06545 } else if (zB && first == 1) { 06546 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) || 06547 (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) || 06548 (mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) { 06549 err = GEN_MEM_ERR; 06550 break; 06551 } 06552 first = 0; 06553 } 06554 } 06555 } 06556 } 06557 06558 done: 06559 /* cleanup */ 06560 mp_clear(&tkb); 06561 mp_clear(&tka); 06562 mp_clear(&order); 06563 06564 #ifdef WOLFSSL_SMALL_STACK 06565 if (kb[0]) 06566 #endif 06567 ForceZero(kb[0], KB_SIZE); 06568 #ifdef WOLFSSL_SMALL_STACK 06569 if (kb[1]) 06570 #endif 06571 ForceZero(kb[1], KB_SIZE); 06572 06573 #ifdef WOLFSSL_SMALL_STACK 06574 XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); 06575 XFREE(kb[1], NULL, DYNAMIC_TYPE_TMP_BUFFER); 06576 #endif 06577 06578 #undef KB_SIZE 06579 06580 if (err != MP_OKAY) 06581 return err; 06582 06583 return ecc_map(R, modulus, mp); 06584 } 06585 06586 06587 /** ECC Fixed Point mulmod global with heap hint used 06588 Computes kA*A + kB*B = C using Shamir's Trick 06589 A First point to multiply 06590 kA What to multiple A by 06591 B Second point to multiply 06592 kB What to multiple B by 06593 C [out] Destination point (can overlap with A or B) 06594 a ECC curve parameter a 06595 modulus Modulus for curve 06596 return MP_OKAY on success 06597 */ 06598 int ecc_mul2add(ecc_point* A, mp_int* kA, 06599 ecc_point* B, mp_int* kB, 06600 ecc_point* C, mp_int* a, mp_int* modulus, void* heap) 06601 { 06602 int idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0; 06603 mp_digit mp; 06604 mp_int mu; 06605 06606 err = mp_init(&mu); 06607 if (err != MP_OKAY) 06608 return err; 06609 06610 #ifndef HAVE_THREAD_LS 06611 if (initMutex == 0) { 06612 wc_InitMutex(&ecc_fp_lock); 06613 initMutex = 1; 06614 } 06615 if (wc_LockMutex(&ecc_fp_lock) != 0) 06616 return BAD_MUTEX_E; 06617 #endif /* HAVE_THREAD_LS */ 06618 06619 /* find point */ 06620 idx1 = find_base(A); 06621 06622 /* no entry? */ 06623 if (idx1 == -1) { 06624 /* find hole and add it */ 06625 if ((idx1 = find_hole()) >= 0) { 06626 err = add_entry(idx1, A); 06627 } 06628 } 06629 if (err == MP_OKAY && idx1 != -1) { 06630 /* increment LRU */ 06631 ++(fp_cache[idx1].lru_count); 06632 } 06633 06634 if (err == MP_OKAY) 06635 /* find point */ 06636 idx2 = find_base(B); 06637 06638 if (err == MP_OKAY) { 06639 /* no entry? */ 06640 if (idx2 == -1) { 06641 /* find hole and add it */ 06642 if ((idx2 = find_hole()) >= 0) 06643 err = add_entry(idx2, B); 06644 } 06645 } 06646 06647 if (err == MP_OKAY && idx2 != -1) { 06648 /* increment LRU */ 06649 ++(fp_cache[idx2].lru_count); 06650 } 06651 06652 if (err == MP_OKAY) { 06653 /* if it's 2 build the LUT, if it's higher just use the LUT */ 06654 if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { 06655 /* compute mp */ 06656 err = mp_montgomery_setup(modulus, &mp); 06657 06658 if (err == MP_OKAY) { 06659 mpInit = 1; 06660 err = mp_montgomery_calc_normalization(&mu, modulus); 06661 } 06662 06663 if (err == MP_OKAY) 06664 /* build the LUT */ 06665 err = build_lut(idx1, a, modulus, mp, &mu); 06666 } 06667 } 06668 06669 if (err == MP_OKAY) { 06670 /* if it's 2 build the LUT, if it's higher just use the LUT */ 06671 if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { 06672 if (mpInit == 0) { 06673 /* compute mp */ 06674 err = mp_montgomery_setup(modulus, &mp); 06675 if (err == MP_OKAY) { 06676 mpInit = 1; 06677 err = mp_montgomery_calc_normalization(&mu, modulus); 06678 } 06679 } 06680 06681 if (err == MP_OKAY) 06682 /* build the LUT */ 06683 err = build_lut(idx2, a, modulus, mp, &mu); 06684 } 06685 } 06686 06687 06688 if (err == MP_OKAY) { 06689 if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && 06690 fp_cache[idx2].lru_count >= 2) { 06691 if (mpInit == 0) { 06692 /* compute mp */ 06693 err = mp_montgomery_setup(modulus, &mp); 06694 } 06695 if (err == MP_OKAY) 06696 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp); 06697 } else { 06698 err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap); 06699 } 06700 } 06701 06702 #ifndef HAVE_THREAD_LS 06703 wc_UnLockMutex(&ecc_fp_lock); 06704 #endif /* HAVE_THREAD_LS */ 06705 mp_clear(&mu); 06706 06707 return err; 06708 } 06709 #endif /* ECC_SHAMIR */ 06710 06711 /** ECC Fixed Point mulmod global 06712 k The multiplicand 06713 G Base point to multiply 06714 R [out] Destination of product 06715 a ECC curve parameter a 06716 modulus The modulus for the curve 06717 map [boolean] If non-zero maps the point back to affine co-ordinates, 06718 otherwise it's left in jacobian-montgomery form 06719 return MP_OKAY if successful 06720 */ 06721 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, 06722 mp_int* modulus, int map, void* heap) 06723 { 06724 int idx, err = MP_OKAY; 06725 mp_digit mp; 06726 mp_int mu; 06727 int mpSetup = 0; 06728 06729 if (mp_init(&mu) != MP_OKAY) 06730 return MP_INIT_E; 06731 06732 #ifndef HAVE_THREAD_LS 06733 if (initMutex == 0) { 06734 wc_InitMutex(&ecc_fp_lock); 06735 initMutex = 1; 06736 } 06737 06738 if (wc_LockMutex(&ecc_fp_lock) != 0) 06739 return BAD_MUTEX_E; 06740 #endif /* HAVE_THREAD_LS */ 06741 06742 /* find point */ 06743 idx = find_base(G); 06744 06745 /* no entry? */ 06746 if (idx == -1) { 06747 /* find hole and add it */ 06748 idx = find_hole(); 06749 06750 if (idx >= 0) 06751 err = add_entry(idx, G); 06752 } 06753 if (err == MP_OKAY && idx >= 0) { 06754 /* increment LRU */ 06755 ++(fp_cache[idx].lru_count); 06756 } 06757 06758 06759 if (err == MP_OKAY) { 06760 /* if it's 2 build the LUT, if it's higher just use the LUT */ 06761 if (idx >= 0 && fp_cache[idx].lru_count == 2) { 06762 /* compute mp */ 06763 err = mp_montgomery_setup(modulus, &mp); 06764 06765 if (err == MP_OKAY) { 06766 /* compute mu */ 06767 mpSetup = 1; 06768 err = mp_montgomery_calc_normalization(&mu, modulus); 06769 } 06770 06771 if (err == MP_OKAY) 06772 /* build the LUT */ 06773 err = build_lut(idx, a, modulus, mp, &mu); 06774 } 06775 } 06776 06777 if (err == MP_OKAY) { 06778 if (idx >= 0 && fp_cache[idx].lru_count >= 2) { 06779 if (mpSetup == 0) { 06780 /* compute mp */ 06781 err = mp_montgomery_setup(modulus, &mp); 06782 } 06783 if (err == MP_OKAY) 06784 err = accel_fp_mul(idx, k, R, a, modulus, mp, map); 06785 } else { 06786 err = normal_ecc_mulmod(k, G, R, a, modulus, map, heap); 06787 } 06788 } 06789 06790 #ifndef HAVE_THREAD_LS 06791 wc_UnLockMutex(&ecc_fp_lock); 06792 #endif /* HAVE_THREAD_LS */ 06793 mp_clear(&mu); 06794 06795 return err; 06796 } 06797 06798 /* helper function for freeing the cache ... 06799 must be called with the cache mutex locked */ 06800 static void wc_ecc_fp_free_cache(void) 06801 { 06802 unsigned x, y; 06803 for (x = 0; x < FP_ENTRIES; x++) { 06804 if (fp_cache[x].g != NULL) { 06805 for (y = 0; y < (1U<<FP_LUT); y++) { 06806 wc_ecc_del_point(fp_cache[x].LUT[y]); 06807 fp_cache[x].LUT[y] = NULL; 06808 } 06809 wc_ecc_del_point(fp_cache[x].g); 06810 fp_cache[x].g = NULL; 06811 mp_clear(&fp_cache[x].mu); 06812 fp_cache[x].lru_count = 0; 06813 fp_cache[x].lock = 0; 06814 } 06815 } 06816 } 06817 06818 /** Free the Fixed Point cache */ 06819 void wc_ecc_fp_free(void) 06820 { 06821 #ifndef HAVE_THREAD_LS 06822 if (initMutex == 0) { 06823 wc_InitMutex(&ecc_fp_lock); 06824 initMutex = 1; 06825 } 06826 06827 if (wc_LockMutex(&ecc_fp_lock) == 0) { 06828 #endif /* HAVE_THREAD_LS */ 06829 06830 wc_ecc_fp_free_cache(); 06831 06832 #ifndef HAVE_THREAD_LS 06833 wc_UnLockMutex(&ecc_fp_lock); 06834 wc_FreeMutex(&ecc_fp_lock); 06835 initMutex = 0; 06836 } 06837 #endif /* HAVE_THREAD_LS */ 06838 } 06839 06840 06841 #endif /* FP_ECC */ 06842 06843 #ifdef HAVE_ECC_ENCRYPT 06844 06845 06846 enum ecCliState { 06847 ecCLI_INIT = 1, 06848 ecCLI_SALT_GET = 2, 06849 ecCLI_SALT_SET = 3, 06850 ecCLI_SENT_REQ = 4, 06851 ecCLI_RECV_RESP = 5, 06852 ecCLI_BAD_STATE = 99 06853 }; 06854 06855 enum ecSrvState { 06856 ecSRV_INIT = 1, 06857 ecSRV_SALT_GET = 2, 06858 ecSRV_SALT_SET = 3, 06859 ecSRV_RECV_REQ = 4, 06860 ecSRV_SENT_RESP = 5, 06861 ecSRV_BAD_STATE = 99 06862 }; 06863 06864 06865 struct ecEncCtx { 06866 const byte* kdfSalt; /* optional salt for kdf */ 06867 const byte* kdfInfo; /* optional info for kdf */ 06868 const byte* macSalt; /* optional salt for mac */ 06869 word32 kdfSaltSz; /* size of kdfSalt */ 06870 word32 kdfInfoSz; /* size of kdfInfo */ 06871 word32 macSaltSz; /* size of macSalt */ 06872 void* heap; /* heap hint for memory used */ 06873 byte clientSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ 06874 byte serverSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ 06875 byte encAlgo; /* which encryption type */ 06876 byte kdfAlgo; /* which key derivation function type */ 06877 byte macAlgo; /* which mac function type */ 06878 byte protocol; /* are we REQ_RESP client or server ? */ 06879 byte cliSt; /* protocol state, for sanity checks */ 06880 byte srvSt; /* protocol state, for sanity checks */ 06881 }; 06882 06883 06884 const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx) 06885 { 06886 if (ctx == NULL || ctx->protocol == 0) 06887 return NULL; 06888 06889 if (ctx->protocol == REQ_RESP_CLIENT) { 06890 if (ctx->cliSt == ecCLI_INIT) { 06891 ctx->cliSt = ecCLI_SALT_GET; 06892 return ctx->clientSalt; 06893 } 06894 else { 06895 ctx->cliSt = ecCLI_BAD_STATE; 06896 return NULL; 06897 } 06898 } 06899 else if (ctx->protocol == REQ_RESP_SERVER) { 06900 if (ctx->srvSt == ecSRV_INIT) { 06901 ctx->srvSt = ecSRV_SALT_GET; 06902 return ctx->serverSalt; 06903 } 06904 else { 06905 ctx->srvSt = ecSRV_BAD_STATE; 06906 return NULL; 06907 } 06908 } 06909 06910 return NULL; 06911 } 06912 06913 06914 /* optional set info, can be called before or after set_peer_salt */ 06915 int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz) 06916 { 06917 if (ctx == NULL || info == 0 || sz < 0) 06918 return BAD_FUNC_ARG; 06919 06920 ctx->kdfInfo = info; 06921 ctx->kdfInfoSz = sz; 06922 06923 return 0; 06924 } 06925 06926 06927 static const char* exchange_info = "Secure Message Exchange"; 06928 06929 int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) 06930 { 06931 byte tmp[EXCHANGE_SALT_SZ/2]; 06932 int halfSz = EXCHANGE_SALT_SZ/2; 06933 06934 if (ctx == NULL || ctx->protocol == 0 || salt == NULL) 06935 return BAD_FUNC_ARG; 06936 06937 if (ctx->protocol == REQ_RESP_CLIENT) { 06938 XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ); 06939 if (ctx->cliSt == ecCLI_SALT_GET) 06940 ctx->cliSt = ecCLI_SALT_SET; 06941 else { 06942 ctx->cliSt = ecCLI_BAD_STATE; 06943 return BAD_STATE_E; 06944 } 06945 } 06946 else { 06947 XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ); 06948 if (ctx->srvSt == ecSRV_SALT_GET) 06949 ctx->srvSt = ecSRV_SALT_SET; 06950 else { 06951 ctx->srvSt = ecSRV_BAD_STATE; 06952 return BAD_STATE_E; 06953 } 06954 } 06955 06956 /* mix half and half */ 06957 /* tmp stores 2nd half of client before overwrite */ 06958 XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz); 06959 XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz); 06960 XMEMCPY(ctx->serverSalt, tmp, halfSz); 06961 06962 ctx->kdfSalt = ctx->clientSalt; 06963 ctx->kdfSaltSz = EXCHANGE_SALT_SZ; 06964 06965 ctx->macSalt = ctx->serverSalt; 06966 ctx->macSaltSz = EXCHANGE_SALT_SZ; 06967 06968 if (ctx->kdfInfo == NULL) { 06969 /* default info */ 06970 ctx->kdfInfo = (const byte*)exchange_info; 06971 ctx->kdfInfoSz = EXCHANGE_INFO_SZ; 06972 } 06973 06974 return 0; 06975 } 06976 06977 06978 static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng) 06979 { 06980 byte* saltBuffer = NULL; 06981 06982 if (ctx == NULL || rng == NULL || flags == 0) 06983 return BAD_FUNC_ARG; 06984 06985 saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt; 06986 06987 return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ); 06988 } 06989 06990 06991 static void ecc_ctx_init(ecEncCtx* ctx, int flags) 06992 { 06993 if (ctx) { 06994 XMEMSET(ctx, 0, sizeof(ecEncCtx)); 06995 06996 ctx->encAlgo = ecAES_128_CBC; 06997 ctx->kdfAlgo = ecHKDF_SHA256; 06998 ctx->macAlgo = ecHMAC_SHA256; 06999 ctx->protocol = (byte)flags; 07000 07001 if (flags == REQ_RESP_CLIENT) 07002 ctx->cliSt = ecCLI_INIT; 07003 if (flags == REQ_RESP_SERVER) 07004 ctx->srvSt = ecSRV_INIT; 07005 } 07006 } 07007 07008 07009 /* allow ecc context reset so user doesn't have to init/free for reuse */ 07010 int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng) 07011 { 07012 if (ctx == NULL || rng == NULL) 07013 return BAD_FUNC_ARG; 07014 07015 ecc_ctx_init(ctx, ctx->protocol); 07016 return ecc_ctx_set_salt(ctx, ctx->protocol, rng); 07017 } 07018 07019 07020 ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap) 07021 { 07022 int ret = 0; 07023 ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap, 07024 DYNAMIC_TYPE_ECC); 07025 07026 if (ctx) { 07027 ctx->protocol = (byte)flags; 07028 ctx->heap = heap; 07029 } 07030 07031 ret = wc_ecc_ctx_reset(ctx, rng); 07032 if (ret != 0) { 07033 wc_ecc_ctx_free(ctx); 07034 ctx = NULL; 07035 } 07036 07037 return ctx; 07038 } 07039 07040 07041 /* alloc/init and set defaults, return new Context */ 07042 ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng) 07043 { 07044 return wc_ecc_ctx_new_ex(flags, rng, NULL); 07045 } 07046 07047 07048 /* free any resources, clear any keys */ 07049 void wc_ecc_ctx_free(ecEncCtx* ctx) 07050 { 07051 if (ctx) { 07052 ForceZero(ctx, sizeof(ecEncCtx)); 07053 XFREE(ctx, ctx->heap, DYNAMIC_TYPE_ECC); 07054 } 07055 } 07056 07057 07058 static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz, 07059 int* keysLen, word32* digestSz, word32* blockSz) 07060 { 07061 if (ctx) { 07062 switch (ctx->encAlgo) { 07063 case ecAES_128_CBC: 07064 *encKeySz = KEY_SIZE_128; 07065 *ivSz = IV_SIZE_128; 07066 *blockSz = AES_BLOCK_SIZE; 07067 break; 07068 default: 07069 return BAD_FUNC_ARG; 07070 } 07071 07072 switch (ctx->macAlgo) { 07073 case ecHMAC_SHA256: 07074 *digestSz = SHA256_DIGEST_SIZE; 07075 break; 07076 default: 07077 return BAD_FUNC_ARG; 07078 } 07079 } else 07080 return BAD_FUNC_ARG; 07081 07082 *keysLen = *encKeySz + *ivSz + *digestSz; 07083 07084 return 0; 07085 } 07086 07087 07088 /* ecc encrypt with shared secret run through kdf 07089 ctx holds non default algos and inputs 07090 msgSz should be the right size for encAlgo, i.e., already padded 07091 return 0 on success */ 07092 int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, 07093 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) 07094 { 07095 int ret; 07096 word32 blockSz; 07097 word32 digestSz; 07098 ecEncCtx localCtx; 07099 #ifdef WOLFSSL_SMALL_STACK 07100 byte* sharedSecret; 07101 byte* keys; 07102 #else 07103 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ 07104 byte keys[ECC_BUFSIZE]; /* max size */ 07105 #endif 07106 word32 sharedSz = ECC_MAXSIZE; 07107 int keysLen; 07108 int encKeySz; 07109 int ivSz; 07110 int offset = 0; /* keys offset if doing msg exchange */ 07111 byte* encKey; 07112 byte* encIv; 07113 byte* macKey; 07114 07115 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || 07116 outSz == NULL) 07117 return BAD_FUNC_ARG; 07118 07119 if (ctx == NULL) { /* use defaults */ 07120 ecc_ctx_init(&localCtx, 0); 07121 ctx = &localCtx; 07122 } 07123 07124 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, 07125 &blockSz); 07126 if (ret != 0) 07127 return ret; 07128 07129 if (ctx->protocol == REQ_RESP_SERVER) { 07130 offset = keysLen; 07131 keysLen *= 2; 07132 07133 if (ctx->srvSt != ecSRV_RECV_REQ) 07134 return BAD_STATE_E; 07135 07136 ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ 07137 } 07138 else if (ctx->protocol == REQ_RESP_CLIENT) { 07139 if (ctx->cliSt != ecCLI_SALT_SET) 07140 return BAD_STATE_E; 07141 07142 ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */ 07143 } 07144 07145 if (keysLen > ECC_BUFSIZE) /* keys size */ 07146 return BUFFER_E; 07147 07148 if ( (msgSz%blockSz) != 0) 07149 return BAD_PADDING_E; 07150 07151 if (*outSz < (msgSz + digestSz)) 07152 return BUFFER_E; 07153 07154 #ifdef WOLFSSL_SMALL_STACK 07155 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07156 if (sharedSecret == NULL) 07157 return MEMORY_E; 07158 07159 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07160 if (keys == NULL) { 07161 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07162 return MEMORY_E; 07163 } 07164 #endif 07165 07166 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); 07167 07168 if (ret == 0) { 07169 switch (ctx->kdfAlgo) { 07170 case ecHKDF_SHA256 : 07171 ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt, 07172 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, 07173 keys, keysLen); 07174 break; 07175 07176 default: 07177 ret = BAD_FUNC_ARG; 07178 break; 07179 } 07180 } 07181 07182 if (ret == 0) { 07183 encKey = keys + offset; 07184 encIv = encKey + encKeySz; 07185 macKey = encKey + encKeySz + ivSz; 07186 07187 switch (ctx->encAlgo) { 07188 case ecAES_128_CBC: 07189 { 07190 Aes aes; 07191 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, 07192 AES_ENCRYPTION); 07193 if (ret != 0) 07194 break; 07195 ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz); 07196 } 07197 break; 07198 07199 default: 07200 ret = BAD_FUNC_ARG; 07201 break; 07202 } 07203 } 07204 07205 if (ret == 0) { 07206 switch (ctx->macAlgo) { 07207 case ecHMAC_SHA256: 07208 { 07209 Hmac hmac; 07210 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); 07211 if (ret == 0) { 07212 ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); 07213 if (ret == 0) 07214 ret = wc_HmacUpdate(&hmac, out, msgSz); 07215 if (ret == 0) 07216 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); 07217 if (ret == 0) 07218 ret = wc_HmacFinal(&hmac, out+msgSz); 07219 wc_HmacFree(&hmac); 07220 } 07221 } 07222 break; 07223 07224 default: 07225 ret = BAD_FUNC_ARG; 07226 break; 07227 } 07228 } 07229 07230 if (ret == 0) 07231 *outSz = msgSz + digestSz; 07232 07233 #ifdef WOLFSSL_SMALL_STACK 07234 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07235 XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07236 #endif 07237 07238 return ret; 07239 } 07240 07241 07242 /* ecc decrypt with shared secret run through kdf 07243 ctx holds non default algos and inputs 07244 return 0 on success */ 07245 int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, 07246 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) 07247 { 07248 int ret; 07249 word32 blockSz; 07250 word32 digestSz; 07251 ecEncCtx localCtx; 07252 #ifdef WOLFSSL_SMALL_STACK 07253 byte* sharedSecret; 07254 byte* keys; 07255 #else 07256 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ 07257 byte keys[ECC_BUFSIZE]; /* max size */ 07258 #endif 07259 word32 sharedSz = ECC_MAXSIZE; 07260 int keysLen; 07261 int encKeySz; 07262 int ivSz; 07263 int offset = 0; /* in case using msg exchange */ 07264 byte* encKey; 07265 byte* encIv; 07266 byte* macKey; 07267 07268 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || 07269 outSz == NULL) 07270 return BAD_FUNC_ARG; 07271 07272 if (ctx == NULL) { /* use defaults */ 07273 ecc_ctx_init(&localCtx, 0); 07274 ctx = &localCtx; 07275 } 07276 07277 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, 07278 &blockSz); 07279 if (ret != 0) 07280 return ret; 07281 07282 if (ctx->protocol == REQ_RESP_CLIENT) { 07283 offset = keysLen; 07284 keysLen *= 2; 07285 07286 if (ctx->cliSt != ecCLI_SENT_REQ) 07287 return BAD_STATE_E; 07288 07289 ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ 07290 } 07291 else if (ctx->protocol == REQ_RESP_SERVER) { 07292 if (ctx->srvSt != ecSRV_SALT_SET) 07293 return BAD_STATE_E; 07294 07295 ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */ 07296 } 07297 07298 if (keysLen > ECC_BUFSIZE) /* keys size */ 07299 return BUFFER_E; 07300 07301 if ( ((msgSz-digestSz) % blockSz) != 0) 07302 return BAD_PADDING_E; 07303 07304 if (*outSz < (msgSz - digestSz)) 07305 return BUFFER_E; 07306 07307 #ifdef WOLFSSL_SMALL_STACK 07308 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07309 if (sharedSecret == NULL) 07310 return MEMORY_E; 07311 07312 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07313 if (keys == NULL) { 07314 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07315 return MEMORY_E; 07316 } 07317 #endif 07318 07319 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); 07320 07321 if (ret == 0) { 07322 switch (ctx->kdfAlgo) { 07323 case ecHKDF_SHA256 : 07324 ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt, 07325 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, 07326 keys, keysLen); 07327 break; 07328 07329 default: 07330 ret = BAD_FUNC_ARG; 07331 break; 07332 } 07333 } 07334 07335 if (ret == 0) { 07336 encKey = keys + offset; 07337 encIv = encKey + encKeySz; 07338 macKey = encKey + encKeySz + ivSz; 07339 07340 switch (ctx->macAlgo) { 07341 case ecHMAC_SHA256: 07342 { 07343 byte verify[SHA256_DIGEST_SIZE]; 07344 Hmac hmac; 07345 07346 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); 07347 if (ret == 0) { 07348 ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); 07349 if (ret == 0) 07350 ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz); 07351 if (ret == 0) 07352 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); 07353 if (ret == 0) 07354 ret = wc_HmacFinal(&hmac, verify); 07355 if (ret == 0) { 07356 if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0) 07357 ret = -1; 07358 } 07359 07360 wc_HmacFree(&hmac); 07361 } 07362 break; 07363 } 07364 07365 default: 07366 ret = BAD_FUNC_ARG; 07367 break; 07368 } 07369 } 07370 07371 if (ret == 0) { 07372 switch (ctx->encAlgo) { 07373 #ifdef HAVE_AES_CBC 07374 case ecAES_128_CBC: 07375 { 07376 Aes aes; 07377 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, 07378 AES_DECRYPTION); 07379 if (ret != 0) 07380 break; 07381 ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz); 07382 } 07383 break; 07384 #endif 07385 default: 07386 ret = BAD_FUNC_ARG; 07387 break; 07388 } 07389 } 07390 07391 if (ret == 0) 07392 *outSz = msgSz - digestSz; 07393 07394 #ifdef WOLFSSL_SMALL_STACK 07395 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07396 XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07397 #endif 07398 07399 return ret; 07400 } 07401 07402 07403 #endif /* HAVE_ECC_ENCRYPT */ 07404 07405 07406 #ifdef HAVE_COMP_KEY 07407 #ifndef WOLFSSL_ATECC508A 07408 07409 int do_mp_jacobi(mp_int* a, mp_int* n, int* c); 07410 07411 int do_mp_jacobi(mp_int* a, mp_int* n, int* c) 07412 { 07413 int k, s, res; 07414 int r = 0; /* initialize to help static analysis out */ 07415 mp_digit residue; 07416 07417 /* if a < 0 return MP_VAL */ 07418 if (mp_isneg(a) == MP_YES) { 07419 return MP_VAL; 07420 } 07421 07422 /* if n <= 0 return MP_VAL */ 07423 if (mp_cmp_d(n, 0) != MP_GT) { 07424 return MP_VAL; 07425 } 07426 07427 /* step 1. handle case of a == 0 */ 07428 if (mp_iszero (a) == MP_YES) { 07429 /* special case of a == 0 and n == 1 */ 07430 if (mp_cmp_d (n, 1) == MP_EQ) { 07431 *c = 1; 07432 } else { 07433 *c = 0; 07434 } 07435 return MP_OKAY; 07436 } 07437 07438 /* step 2. if a == 1, return 1 */ 07439 if (mp_cmp_d (a, 1) == MP_EQ) { 07440 *c = 1; 07441 return MP_OKAY; 07442 } 07443 07444 /* default */ 07445 s = 0; 07446 07447 /* divide out larger power of two */ 07448 k = mp_cnt_lsb(a); 07449 res = mp_div_2d(a, k, a, NULL); 07450 07451 if (res == MP_OKAY) { 07452 /* step 4. if e is even set s=1 */ 07453 if ((k & 1) == 0) { 07454 s = 1; 07455 } else { 07456 /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ 07457 residue = n->dp[0] & 7; 07458 07459 if (residue == 1 || residue == 7) { 07460 s = 1; 07461 } else if (residue == 3 || residue == 5) { 07462 s = -1; 07463 } 07464 } 07465 07466 /* step 5. if p == 3 (mod 4) *and* a == 3 (mod 4) then s = -s */ 07467 if ( ((n->dp[0] & 3) == 3) && ((a->dp[0] & 3) == 3)) { 07468 s = -s; 07469 } 07470 } 07471 07472 if (res == MP_OKAY) { 07473 /* if a == 1 we're done */ 07474 if (mp_cmp_d(a, 1) == MP_EQ) { 07475 *c = s; 07476 } else { 07477 /* n1 = n mod a */ 07478 res = mp_mod (n, a, n); 07479 if (res == MP_OKAY) 07480 res = do_mp_jacobi(n, a, &r); 07481 07482 if (res == MP_OKAY) 07483 *c = s * r; 07484 } 07485 } 07486 07487 return res; 07488 } 07489 07490 07491 /* computes the jacobi c = (a | n) (or Legendre if n is prime) 07492 * HAC pp. 73 Algorithm 2.149 07493 * HAC is wrong here, as the special case of (0 | 1) is not 07494 * handled correctly. 07495 */ 07496 int mp_jacobi(mp_int* a, mp_int* n, int* c) 07497 { 07498 mp_int a1, n1; 07499 int res; 07500 07501 /* step 3. write a = a1 * 2**k */ 07502 if ((res = mp_init_multi(&a1, &n1, NULL, NULL, NULL, NULL)) != MP_OKAY) { 07503 return res; 07504 } 07505 07506 if ((res = mp_copy(a, &a1)) != MP_OKAY) { 07507 goto done; 07508 } 07509 07510 if ((res = mp_copy(n, &n1)) != MP_OKAY) { 07511 goto done; 07512 } 07513 07514 res = do_mp_jacobi(&a1, &n1, c); 07515 07516 done: 07517 /* cleanup */ 07518 mp_clear(&n1); 07519 mp_clear(&a1); 07520 07521 return res; 07522 } 07523 07524 07525 /* Solves the modular equation x^2 = n (mod p) 07526 * where prime number is greater than 2 (odd prime). 07527 * The result is returned in the third argument x 07528 * the function returns MP_OKAY on success, MP_VAL or another error on failure 07529 */ 07530 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) 07531 { 07532 int res, legendre, done = 0; 07533 mp_int t1, C, Q, S, Z, M, T, R, two; 07534 mp_digit i; 07535 07536 /* first handle the simple cases n = 0 or n = 1 */ 07537 if (mp_cmp_d(n, 0) == MP_EQ) { 07538 mp_zero(ret); 07539 return MP_OKAY; 07540 } 07541 if (mp_cmp_d(n, 1) == MP_EQ) { 07542 return mp_set(ret, 1); 07543 } 07544 07545 /* prime must be odd */ 07546 if (mp_cmp_d(prime, 2) == MP_EQ) { 07547 return MP_VAL; 07548 } 07549 07550 /* is quadratic non-residue mod prime */ 07551 if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) { 07552 return res; 07553 } 07554 if (legendre == -1) { 07555 return MP_VAL; 07556 } 07557 07558 if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY) 07559 return res; 07560 07561 if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL)) 07562 != MP_OKAY) { 07563 mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z); 07564 mp_clear(&M); 07565 return res; 07566 } 07567 07568 /* SPECIAL CASE: if prime mod 4 == 3 07569 * compute directly: res = n^(prime+1)/4 mod prime 07570 * Handbook of Applied Cryptography algorithm 3.36 07571 */ 07572 res = mp_mod_d(prime, 4, &i); 07573 if (res == MP_OKAY && i == 3) { 07574 res = mp_add_d(prime, 1, &t1); 07575 07576 if (res == MP_OKAY) 07577 res = mp_div_2(&t1, &t1); 07578 if (res == MP_OKAY) 07579 res = mp_div_2(&t1, &t1); 07580 if (res == MP_OKAY) 07581 res = mp_exptmod(n, &t1, prime, ret); 07582 07583 done = 1; 07584 } 07585 07586 /* NOW: TonelliShanks algorithm */ 07587 if (res == MP_OKAY && done == 0) { 07588 07589 /* factor out powers of 2 from prime-1, defining Q and S 07590 * as: prime-1 = Q*2^S */ 07591 /* Q = prime - 1 */ 07592 res = mp_copy(prime, &Q); 07593 if (res == MP_OKAY) 07594 res = mp_sub_d(&Q, 1, &Q); 07595 07596 /* S = 0 */ 07597 if (res == MP_OKAY) 07598 mp_zero(&S); 07599 07600 while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) { 07601 /* Q = Q / 2 */ 07602 res = mp_div_2(&Q, &Q); 07603 07604 /* S = S + 1 */ 07605 if (res == MP_OKAY) 07606 res = mp_add_d(&S, 1, &S); 07607 } 07608 07609 /* find a Z such that the Legendre symbol (Z|prime) == -1 */ 07610 /* Z = 2 */ 07611 if (res == MP_OKAY) 07612 res = mp_set_int(&Z, 2); 07613 07614 while (res == MP_OKAY) { 07615 res = mp_jacobi(&Z, prime, &legendre); 07616 if (res == MP_OKAY && legendre == -1) 07617 break; 07618 07619 /* Z = Z + 1 */ 07620 if (res == MP_OKAY) 07621 res = mp_add_d(&Z, 1, &Z); 07622 } 07623 07624 /* C = Z ^ Q mod prime */ 07625 if (res == MP_OKAY) 07626 res = mp_exptmod(&Z, &Q, prime, &C); 07627 07628 /* t1 = (Q + 1) / 2 */ 07629 if (res == MP_OKAY) 07630 res = mp_add_d(&Q, 1, &t1); 07631 if (res == MP_OKAY) 07632 res = mp_div_2(&t1, &t1); 07633 07634 /* R = n ^ ((Q + 1) / 2) mod prime */ 07635 if (res == MP_OKAY) 07636 res = mp_exptmod(n, &t1, prime, &R); 07637 07638 /* T = n ^ Q mod prime */ 07639 if (res == MP_OKAY) 07640 res = mp_exptmod(n, &Q, prime, &T); 07641 07642 /* M = S */ 07643 if (res == MP_OKAY) 07644 res = mp_copy(&S, &M); 07645 07646 if (res == MP_OKAY) 07647 res = mp_set_int(&two, 2); 07648 07649 while (res == MP_OKAY && done == 0) { 07650 res = mp_copy(&T, &t1); 07651 07652 /* reduce to 1 and count */ 07653 i = 0; 07654 while (res == MP_OKAY) { 07655 if (mp_cmp_d(&t1, 1) == MP_EQ) 07656 break; 07657 res = mp_exptmod(&t1, &two, prime, &t1); 07658 if (res == MP_OKAY) 07659 i++; 07660 } 07661 if (res == MP_OKAY && i == 0) { 07662 res = mp_copy(&R, ret); 07663 done = 1; 07664 } 07665 07666 if (done == 0) { 07667 /* t1 = 2 ^ (M - i - 1) */ 07668 if (res == MP_OKAY) 07669 res = mp_sub_d(&M, i, &t1); 07670 if (res == MP_OKAY) 07671 res = mp_sub_d(&t1, 1, &t1); 07672 if (res == MP_OKAY) 07673 res = mp_exptmod(&two, &t1, prime, &t1); 07674 07675 /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ 07676 if (res == MP_OKAY) 07677 res = mp_exptmod(&C, &t1, prime, &t1); 07678 07679 /* C = (t1 * t1) mod prime */ 07680 if (res == MP_OKAY) 07681 res = mp_sqrmod(&t1, prime, &C); 07682 07683 /* R = (R * t1) mod prime */ 07684 if (res == MP_OKAY) 07685 res = mp_mulmod(&R, &t1, prime, &R); 07686 07687 /* T = (T * C) mod prime */ 07688 if (res == MP_OKAY) 07689 res = mp_mulmod(&T, &C, prime, &T); 07690 07691 /* M = i */ 07692 if (res == MP_OKAY) 07693 res = mp_set(&M, i); 07694 } 07695 } 07696 } 07697 07698 /* done */ 07699 mp_clear(&t1); 07700 mp_clear(&C); 07701 mp_clear(&Q); 07702 mp_clear(&S); 07703 mp_clear(&Z); 07704 mp_clear(&M); 07705 mp_clear(&T); 07706 mp_clear(&R); 07707 mp_clear(&two); 07708 07709 return res; 07710 } 07711 #endif /* !WOLFSSL_ATECC508A */ 07712 07713 07714 /* export public ECC key in ANSI X9.63 format compressed */ 07715 static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen) 07716 { 07717 word32 numlen; 07718 int ret = MP_OKAY; 07719 07720 if (key == NULL || out == NULL || outLen == NULL) 07721 return BAD_FUNC_ARG; 07722 07723 if (wc_ecc_is_valid_idx(key->idx) == 0) { 07724 return ECC_BAD_ARG_E; 07725 } 07726 numlen = key->dp->size; 07727 07728 if (*outLen < (1 + numlen)) { 07729 *outLen = 1 + numlen; 07730 return BUFFER_E; 07731 } 07732 07733 #ifdef WOLFSSL_ATECC508A 07734 /* TODO: Implement equiv call to ATECC508A */ 07735 ret = BAD_COND_E; 07736 07737 #else 07738 07739 /* store first byte */ 07740 out[0] = mp_isodd(key->pubkey.y) == MP_YES ? 0x03 : 0x02; 07741 07742 /* pad and store x */ 07743 XMEMSET(out+1, 0, numlen); 07744 ret = mp_to_unsigned_bin(key->pubkey.x, 07745 out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x))); 07746 *outLen = 1 + numlen; 07747 07748 #endif /* WOLFSSL_ATECC508A */ 07749 07750 return ret; 07751 } 07752 07753 #endif /* HAVE_COMP_KEY */ 07754 07755 07756 int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz) 07757 { 07758 int x; 07759 07760 if (oidSum == 0) { 07761 return BAD_FUNC_ARG; 07762 } 07763 07764 /* find matching OID sum (based on encoded value) */ 07765 for (x = 0; ecc_sets[x].size != 0; x++) { 07766 if (ecc_sets[x].oidSum == oidSum) { 07767 int ret = 0; 07768 #ifdef HAVE_OID_ENCODING 07769 /* check cache */ 07770 oid_cache_t* o = &ecc_oid_cache[x]; 07771 if (o->oidSz == 0) { 07772 o->oidSz = sizeof(o->oid); 07773 ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, 07774 o->oid, &o->oidSz); 07775 } 07776 if (oidSz) { 07777 *oidSz = o->oidSz; 07778 } 07779 if (oid) { 07780 *oid = o->oid; 07781 } 07782 #else 07783 if (oidSz) { 07784 *oidSz = ecc_sets[x].oidSz; 07785 } 07786 if (oid) { 07787 *oid = ecc_sets[x].oid; 07788 } 07789 #endif 07790 /* on success return curve id */ 07791 if (ret == 0) { 07792 ret = ecc_sets[x].id; 07793 } 07794 return ret; 07795 } 07796 } 07797 07798 return NOT_COMPILED_IN; 07799 } 07800 07801 #ifdef WOLFSSL_CUSTOM_CURVES 07802 int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp) 07803 { 07804 if (key == NULL || dp == NULL) { 07805 return BAD_FUNC_ARG; 07806 } 07807 07808 key->idx = ECC_CUSTOM_IDX; 07809 key->dp = dp; 07810 07811 return 0; 07812 } 07813 #endif /* WOLFSSL_CUSTOM_CURVES */ 07814 07815 #ifdef HAVE_X963_KDF 07816 07817 static INLINE void IncrementX963KdfCounter(byte* inOutCtr) 07818 { 07819 int i; 07820 07821 /* in network byte order so start at end and work back */ 07822 for (i = 3; i >= 0; i--) { 07823 if (++inOutCtr[i]) /* we're done unless we overflow */ 07824 return; 07825 } 07826 } 07827 07828 /* ASN X9.63 Key Derivation Function (SEC1) */ 07829 int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz, 07830 const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz) 07831 { 07832 int ret, i; 07833 int digestSz, copySz; 07834 int remaining = outSz; 07835 byte* outIdx; 07836 byte counter[4]; 07837 byte tmp[WC_MAX_DIGEST_SIZE]; 07838 07839 #ifdef WOLFSSL_SMALL_STACK 07840 wc_HashAlg* hash; 07841 #else 07842 wc_HashAlg hash[1]; 07843 #endif 07844 07845 if (secret == NULL || secretSz == 0 || out == NULL) 07846 return BAD_FUNC_ARG; 07847 07848 /* X9.63 allowed algos only */ 07849 if (type != WC_HASH_TYPE_SHA && type != WC_HASH_TYPE_SHA224 && 07850 type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 && 07851 type != WC_HASH_TYPE_SHA512) 07852 return BAD_FUNC_ARG; 07853 07854 digestSz = wc_HashGetDigestSize(type); 07855 if (digestSz < 0) 07856 return digestSz; 07857 07858 #ifdef WOLFSSL_SMALL_STACK 07859 hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL, 07860 DYNAMIC_TYPE_TMP_BUFFER); 07861 if (hash == NULL) 07862 return MEMORY_E; 07863 #endif 07864 07865 ret = wc_HashInit(hash, type); 07866 if (ret != 0) { 07867 #ifdef WOLFSSL_SMALL_STACK 07868 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07869 #endif 07870 return ret; 07871 } 07872 07873 outIdx = out; 07874 XMEMSET(counter, 0, sizeof(counter)); 07875 07876 for (i = 1; remaining > 0; i++) { 07877 07878 IncrementX963KdfCounter(counter); 07879 07880 ret = wc_HashUpdate(hash, type, secret, secretSz); 07881 if (ret != 0) { 07882 #ifdef WOLFSSL_SMALL_STACK 07883 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07884 #endif 07885 return ret; 07886 } 07887 07888 ret = wc_HashUpdate(hash, type, counter, sizeof(counter)); 07889 if (ret != 0) { 07890 #ifdef WOLFSSL_SMALL_STACK 07891 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07892 #endif 07893 return ret; 07894 } 07895 07896 if (sinfo) { 07897 ret = wc_HashUpdate(hash, type, sinfo, sinfoSz); 07898 if (ret != 0) { 07899 #ifdef WOLFSSL_SMALL_STACK 07900 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07901 #endif 07902 return ret; 07903 } 07904 } 07905 07906 ret = wc_HashFinal(hash, type, tmp); 07907 if (ret != 0) { 07908 #ifdef WOLFSSL_SMALL_STACK 07909 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07910 #endif 07911 return ret; 07912 } 07913 07914 copySz = min(remaining, digestSz); 07915 XMEMCPY(outIdx, tmp, copySz); 07916 07917 remaining -= copySz; 07918 outIdx += copySz; 07919 } 07920 07921 #ifdef WOLFSSL_SMALL_STACK 07922 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); 07923 #endif 07924 07925 return 0; 07926 } 07927 #endif /* HAVE_X963_KDF */ 07928 07929 #endif /* HAVE_ECC */ 07930
Generated on Tue Jul 12 2022 23:30:55 by
1.7.2
