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.
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_KEY_IMPORT: ECC Key import default: on 00039 * HAVE_ECC_KEY_EXPORT: ECC Key export default: on 00040 * ECC_SHAMIR: Enables Shamir calc method default: on 00041 * HAVE_COMP_KEY: Enables compressed key default: off 00042 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import default: off 00043 */ 00044 00045 /* 00046 ECC Curves: 00047 * ECC_USER_CURVES: Allows custom combination of key sizes below 00048 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined) 00049 * HAVE_ECC112: 112 bit key 00050 * HAVE_ECC128: 128 bit key 00051 * HAVE_ECC160: 160 bit key 00052 * HAVE_ECC192: 192 bit key 00053 * HAVE_ECC224: 224 bit key 00054 * NO_ECC256: Disables 256 bit key (on by default) 00055 * HAVE_ECC384: 384 bit key 00056 * HAVE_ECC521: 521 bit key 00057 */ 00058 00059 #ifdef HAVE_ECC 00060 00061 #if (defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)) && defined(NO_ASN) 00062 #error ASN must be enabled for ECC sign/verify 00063 #endif 00064 00065 #include <wolfssl/wolfcrypt/ecc.h> 00066 #include <wolfssl/openssl/ec.h> 00067 #include <wolfssl/wolfcrypt/asn.h> 00068 #include <wolfssl/wolfcrypt/error-crypt.h> 00069 #include <wolfssl/wolfcrypt/logging.h> 00070 00071 #ifdef HAVE_ECC_ENCRYPT 00072 #include <wolfssl/wolfcrypt/hmac.h> 00073 #include <wolfssl/wolfcrypt/aes.h> 00074 #endif 00075 00076 #ifdef NO_INLINE 00077 #include <wolfssl/wolfcrypt/misc.h> 00078 #else 00079 #include <wolfcrypt/src/misc.c> 00080 #endif 00081 00082 /* map 00083 00084 ptmul -> mulmod 00085 00086 */ 00087 00088 00089 /* p256 curve on by default whether user curves or not */ 00090 #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES) 00091 #define ECC112 00092 #endif 00093 #if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES) 00094 #define ECC128 00095 #endif 00096 #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) 00097 #define ECC160 00098 #endif 00099 #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) 00100 #define ECC192 00101 #endif 00102 #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) 00103 #define ECC224 00104 #endif 00105 #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) 00106 #define ECC256 00107 #endif 00108 #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) 00109 #define ECC384 00110 #endif 00111 #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) 00112 #define ECC521 00113 #endif 00114 00115 00116 00117 /* This holds the key settings. ***MUST*** be organized by size from 00118 smallest to largest. */ 00119 00120 const ecc_set_type ecc_sets[] = { 00121 #ifdef ECC112 00122 { 00123 14, 00124 NID_secp111r1, 00125 "SECP112R1", 00126 "DB7C2ABF62E35E668076BEAD208B", 00127 "DB7C2ABF62E35E668076BEAD2088", 00128 "659EF8BA043916EEDE8911702B22", 00129 "DB7C2ABF62E35E7628DFAC6561C5", 00130 "09487239995A5EE76B55F9C2F098", 00131 "A89CE5AF8724C0A23E0E0FF77500" 00132 }, 00133 #endif 00134 #ifdef ECC128 00135 { 00136 16, 00137 NID_secp128r1, 00138 "SECP128R1", 00139 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", 00140 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", 00141 "E87579C11079F43DD824993C2CEE5ED3", 00142 "FFFFFFFE0000000075A30D1B9038A115", 00143 "161FF7528B899B2D0C28607CA52C5B86", 00144 "CF5AC8395BAFEB13C02DA292DDED7A83", 00145 }, 00146 #endif 00147 #ifdef ECC160 00148 { 00149 20, 00150 NID_secp160r1, 00151 "SECP160R1", 00152 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", 00153 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", 00154 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", 00155 "0100000000000000000001F4C8F927AED3CA752257", 00156 "4A96B5688EF573284664698968C38BB913CBFC82", 00157 "23A628553168947D59DCC912042351377AC5FB32", 00158 }, 00159 #endif 00160 #ifdef ECC192 00161 { 00162 24, 00163 NID_cert192, 00164 "ECC-192", 00165 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 00166 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", 00167 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", 00168 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 00169 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", 00170 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", 00171 }, 00172 #endif 00173 #ifdef ECC224 00174 { 00175 28, 00176 NID_cert224, 00177 "ECC-224", 00178 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", 00179 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", 00180 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", 00181 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 00182 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", 00183 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", 00184 }, 00185 #endif 00186 #ifdef ECC256 00187 { 00188 32, 00189 NID_X9_62_prime256v1, 00190 "nistp256", 00191 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 00192 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 00193 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", 00194 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 00195 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", 00196 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", 00197 }, 00198 #endif 00199 #ifdef ECC384 00200 { 00201 48, 00202 NID_secp384r1, 00203 "nistp384", 00204 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", 00205 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", 00206 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", 00207 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", 00208 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", 00209 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", 00210 }, 00211 #endif 00212 #ifdef ECC521 00213 { 00214 66, 00215 NID_secp521r1, 00216 "nistp521", 00217 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 00218 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 00219 "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 00220 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 00221 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", 00222 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", 00223 }, 00224 #endif 00225 { 00226 0, -1, 00227 NULL, NULL, NULL, NULL, NULL, NULL, NULL 00228 } 00229 }; 00230 00231 00232 int ecc_map(ecc_point*, mp_int*, mp_digit*); 00233 int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, 00234 mp_int* modulus, mp_digit* mp); 00235 int ecc_projective_dbl_point(ecc_point* P, ecc_point* R, mp_int* modulus, 00236 mp_digit* mp); 00237 static int ecc_check_pubkey_order(ecc_key* key, mp_int* prime, mp_int* order); 00238 #ifdef ECC_SHAMIR 00239 static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB, 00240 ecc_point* C, mp_int* modulus); 00241 #endif 00242 00243 int mp_jacobi(mp_int* a, mp_int* p, int* c); 00244 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret); 00245 int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d); 00246 00247 #ifdef HAVE_COMP_KEY 00248 static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); 00249 #endif 00250 00251 /* helper for either lib */ 00252 static int get_digit_count(mp_int* a) 00253 { 00254 if (a == NULL) 00255 return 0; 00256 00257 return a->used; 00258 } 00259 00260 /* helper for either lib */ 00261 static mp_digit get_digit(mp_int* a, int n) 00262 { 00263 if (a == NULL) 00264 return 0; 00265 00266 return (n >= a->used || n < 0) ? 0 : a->dp[n]; 00267 } 00268 00269 00270 #if defined(USE_FAST_MATH) 00271 00272 /* fast math accelerated version, but not for fp ecc yet */ 00273 00274 /** 00275 Add two ECC points 00276 P The point to add 00277 Q The point to add 00278 R [out] The destination of the double 00279 modulus The modulus of the field the ECC curve is in 00280 mp The "b" value from montgomery_setup() 00281 return MP_OKAY on success 00282 */ 00283 int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, 00284 mp_int* modulus, mp_digit* mp) 00285 { 00286 fp_int t1, t2, x, y, z; 00287 int err; 00288 00289 if (P == NULL || Q == NULL || R == NULL || modulus == NULL || mp == NULL) 00290 return ECC_BAD_ARG_E; 00291 00292 if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) { 00293 return err; 00294 } 00295 00296 /* should we dbl instead? */ 00297 fp_sub(modulus, Q->y, &t1); 00298 if ( (fp_cmp(P->x, Q->x) == FP_EQ) && 00299 (get_digit_count(Q->z) && fp_cmp(P->z, Q->z) == FP_EQ) && 00300 (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) { 00301 return ecc_projective_dbl_point(P, R, modulus, mp); 00302 } 00303 00304 fp_copy(P->x, &x); 00305 fp_copy(P->y, &y); 00306 fp_copy(P->z, &z); 00307 00308 /* if Z is one then these are no-operations */ 00309 if (get_digit_count(Q->z)) { 00310 /* T1 = Z' * Z' */ 00311 fp_sqr(Q->z, &t1); 00312 fp_montgomery_reduce(&t1, modulus, *mp); 00313 /* X = X * T1 */ 00314 fp_mul(&t1, &x, &x); 00315 fp_montgomery_reduce(&x, modulus, *mp); 00316 /* T1 = Z' * T1 */ 00317 fp_mul(Q->z, &t1, &t1); 00318 fp_montgomery_reduce(&t1, modulus, *mp); 00319 /* Y = Y * T1 */ 00320 fp_mul(&t1, &y, &y); 00321 fp_montgomery_reduce(&y, modulus, *mp); 00322 } 00323 00324 /* T1 = Z*Z */ 00325 fp_sqr(&z, &t1); 00326 fp_montgomery_reduce(&t1, modulus, *mp); 00327 /* T2 = X' * T1 */ 00328 fp_mul(Q->x, &t1, &t2); 00329 fp_montgomery_reduce(&t2, modulus, *mp); 00330 /* T1 = Z * T1 */ 00331 fp_mul(&z, &t1, &t1); 00332 fp_montgomery_reduce(&t1, modulus, *mp); 00333 /* T1 = Y' * T1 */ 00334 fp_mul(Q->y, &t1, &t1); 00335 fp_montgomery_reduce(&t1, modulus, *mp); 00336 00337 /* Y = Y - T1 */ 00338 fp_sub(&y, &t1, &y); 00339 if (fp_cmp_d(&y, 0) == FP_LT) { 00340 fp_add(&y, modulus, &y); 00341 } 00342 /* T1 = 2T1 */ 00343 fp_add(&t1, &t1, &t1); 00344 if (fp_cmp(&t1, modulus) != FP_LT) { 00345 fp_sub(&t1, modulus, &t1); 00346 } 00347 /* T1 = Y + T1 */ 00348 fp_add(&t1, &y, &t1); 00349 if (fp_cmp(&t1, modulus) != FP_LT) { 00350 fp_sub(&t1, modulus, &t1); 00351 } 00352 /* X = X - T2 */ 00353 fp_sub(&x, &t2, &x); 00354 if (fp_cmp_d(&x, 0) == FP_LT) { 00355 fp_add(&x, modulus, &x); 00356 } 00357 /* T2 = 2T2 */ 00358 fp_add(&t2, &t2, &t2); 00359 if (fp_cmp(&t2, modulus) != FP_LT) { 00360 fp_sub(&t2, modulus, &t2); 00361 } 00362 /* T2 = X + T2 */ 00363 fp_add(&t2, &x, &t2); 00364 if (fp_cmp(&t2, modulus) != FP_LT) { 00365 fp_sub(&t2, modulus, &t2); 00366 } 00367 00368 /* if Z' != 1 */ 00369 if (get_digit_count(Q->z)) { 00370 /* Z = Z * Z' */ 00371 fp_mul(&z, Q->z, &z); 00372 fp_montgomery_reduce(&z, modulus, *mp); 00373 } 00374 00375 /* Z = Z * X */ 00376 fp_mul(&z, &x, &z); 00377 fp_montgomery_reduce(&z, modulus, *mp); 00378 00379 /* T1 = T1 * X */ 00380 fp_mul(&t1, &x, &t1); 00381 fp_montgomery_reduce(&t1, modulus, *mp); 00382 /* X = X * X */ 00383 fp_sqr(&x, &x); 00384 fp_montgomery_reduce(&x, modulus, *mp); 00385 /* T2 = T2 * x */ 00386 fp_mul(&t2, &x, &t2); 00387 fp_montgomery_reduce(&t2, modulus, *mp); 00388 /* T1 = T1 * X */ 00389 fp_mul(&t1, &x, &t1); 00390 fp_montgomery_reduce(&t1, modulus, *mp); 00391 00392 /* X = Y*Y */ 00393 fp_sqr(&y, &x); 00394 fp_montgomery_reduce(&x, modulus, *mp); 00395 /* X = X - T2 */ 00396 fp_sub(&x, &t2, &x); 00397 if (fp_cmp_d(&x, 0) == FP_LT) { 00398 fp_add(&x, modulus, &x); 00399 } 00400 00401 /* T2 = T2 - X */ 00402 fp_sub(&t2, &x, &t2); 00403 if (fp_cmp_d(&t2, 0) == FP_LT) { 00404 fp_add(&t2, modulus, &t2); 00405 } 00406 /* T2 = T2 - X */ 00407 fp_sub(&t2, &x, &t2); 00408 if (fp_cmp_d(&t2, 0) == FP_LT) { 00409 fp_add(&t2, modulus, &t2); 00410 } 00411 /* T2 = T2 * Y */ 00412 fp_mul(&t2, &y, &t2); 00413 fp_montgomery_reduce(&t2, modulus, *mp); 00414 /* Y = T2 - T1 */ 00415 fp_sub(&t2, &t1, &y); 00416 if (fp_cmp_d(&y, 0) == FP_LT) { 00417 fp_add(&y, modulus, &y); 00418 } 00419 /* Y = Y/2 */ 00420 if (fp_isodd(&y)) { 00421 fp_add(&y, modulus, &y); 00422 } 00423 fp_div_2(&y, &y); 00424 00425 fp_copy(&x, R->x); 00426 fp_copy(&y, R->y); 00427 fp_copy(&z, R->z); 00428 00429 return MP_OKAY; 00430 } 00431 00432 00433 /** 00434 Double an ECC point 00435 P The point to double 00436 R [out] The destination of the double 00437 modulus The modulus of the field the ECC curve is in 00438 mp The "b" value from montgomery_setup() 00439 return MP_OKAY on success 00440 */ 00441 int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* modulus, 00442 mp_digit* mp) 00443 { 00444 fp_int t1, t2; 00445 int err; 00446 00447 if (P == NULL || R == NULL || modulus == NULL || mp == NULL) 00448 return ECC_BAD_ARG_E; 00449 00450 if (P != R) { 00451 fp_copy(P->x, R->x); 00452 fp_copy(P->y, R->y); 00453 fp_copy(P->z, R->z); 00454 } 00455 00456 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 00457 return err; 00458 } 00459 00460 /* t1 = Z * Z */ 00461 fp_sqr(R->z, &t1); 00462 fp_montgomery_reduce(&t1, modulus, *mp); 00463 /* Z = Y * Z */ 00464 fp_mul(R->z, R->y, R->z); 00465 fp_montgomery_reduce(R->z, modulus, *mp); 00466 /* Z = 2Z */ 00467 fp_add(R->z, R->z, R->z); 00468 if (fp_cmp(R->z, modulus) != FP_LT) { 00469 fp_sub(R->z, modulus, R->z); 00470 } 00471 00472 /* &t2 = X - T1 */ 00473 fp_sub(R->x, &t1, &t2); 00474 if (fp_cmp_d(&t2, 0) == FP_LT) { 00475 fp_add(&t2, modulus, &t2); 00476 } 00477 /* T1 = X + T1 */ 00478 fp_add(&t1, R->x, &t1); 00479 if (fp_cmp(&t1, modulus) != FP_LT) { 00480 fp_sub(&t1, modulus, &t1); 00481 } 00482 /* T2 = T1 * T2 */ 00483 fp_mul(&t1, &t2, &t2); 00484 fp_montgomery_reduce(&t2, modulus, *mp); 00485 /* T1 = 2T2 */ 00486 fp_add(&t2, &t2, &t1); 00487 if (fp_cmp(&t1, modulus) != FP_LT) { 00488 fp_sub(&t1, modulus, &t1); 00489 } 00490 /* T1 = T1 + T2 */ 00491 fp_add(&t1, &t2, &t1); 00492 if (fp_cmp(&t1, modulus) != FP_LT) { 00493 fp_sub(&t1, modulus, &t1); 00494 } 00495 00496 /* Y = 2Y */ 00497 fp_add(R->y, R->y, R->y); 00498 if (fp_cmp(R->y, modulus) != FP_LT) { 00499 fp_sub(R->y, modulus, R->y); 00500 } 00501 /* Y = Y * Y */ 00502 fp_sqr(R->y, R->y); 00503 fp_montgomery_reduce(R->y, modulus, *mp); 00504 /* T2 = Y * Y */ 00505 fp_sqr(R->y, &t2); 00506 fp_montgomery_reduce(&t2, modulus, *mp); 00507 /* T2 = T2/2 */ 00508 if (fp_isodd(&t2)) { 00509 fp_add(&t2, modulus, &t2); 00510 } 00511 fp_div_2(&t2, &t2); 00512 /* Y = Y * X */ 00513 fp_mul(R->y, R->x, R->y); 00514 fp_montgomery_reduce(R->y, modulus, *mp); 00515 00516 /* X = T1 * T1 */ 00517 fp_sqr(&t1, R->x); 00518 fp_montgomery_reduce(R->x, modulus, *mp); 00519 /* X = X - Y */ 00520 fp_sub(R->x, R->y, R->x); 00521 if (fp_cmp_d(R->x, 0) == FP_LT) { 00522 fp_add(R->x, modulus, R->x); 00523 } 00524 /* X = X - Y */ 00525 fp_sub(R->x, R->y, R->x); 00526 if (fp_cmp_d(R->x, 0) == FP_LT) { 00527 fp_add(R->x, modulus, R->x); 00528 } 00529 00530 /* Y = Y - X */ 00531 fp_sub(R->y, R->x, R->y); 00532 if (fp_cmp_d(R->y, 0) == FP_LT) { 00533 fp_add(R->y, modulus, R->y); 00534 } 00535 /* Y = Y * T1 */ 00536 fp_mul(R->y, &t1, R->y); 00537 fp_montgomery_reduce(R->y, modulus, *mp); 00538 /* Y = Y - T2 */ 00539 fp_sub(R->y, &t2, R->y); 00540 if (fp_cmp_d(R->y, 0) == FP_LT) { 00541 fp_add(R->y, modulus, R->y); 00542 } 00543 00544 return MP_OKAY; 00545 } 00546 00547 #else /* USE_FAST_MATH */ 00548 00549 /** 00550 Add two ECC points 00551 P The point to add 00552 Q The point to add 00553 R [out] The destination of the double 00554 modulus The modulus of the field the ECC curve is in 00555 mp The "b" value from montgomery_setup() 00556 return MP_OKAY on success 00557 */ 00558 int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, 00559 mp_int* modulus, mp_digit* mp) 00560 { 00561 mp_int t1; 00562 mp_int t2; 00563 mp_int x; 00564 mp_int y; 00565 mp_int z; 00566 int err; 00567 00568 if (P == NULL || Q == NULL || R == NULL || modulus == NULL || mp == NULL) 00569 return ECC_BAD_ARG_E; 00570 00571 if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) { 00572 return err; 00573 } 00574 00575 /* should we dbl instead? */ 00576 err = mp_sub(modulus, Q->y, &t1); 00577 00578 if (err == MP_OKAY) { 00579 if ( (mp_cmp(P->x, Q->x) == MP_EQ) && 00580 (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) && 00581 (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, &t1) == MP_EQ)) { 00582 mp_clear(&t1); 00583 mp_clear(&t2); 00584 mp_clear(&x); 00585 mp_clear(&y); 00586 mp_clear(&z); 00587 00588 return ecc_projective_dbl_point(P, R, modulus, mp); 00589 } 00590 } 00591 00592 if (err == MP_OKAY) 00593 err = mp_copy(P->x, &x); 00594 if (err == MP_OKAY) 00595 err = mp_copy(P->y, &y); 00596 if (err == MP_OKAY) 00597 err = mp_copy(P->z, &z); 00598 00599 /* if Z is one then these are no-operations */ 00600 if (err == MP_OKAY) { 00601 if (get_digit_count(Q->z)) { 00602 /* T1 = Z' * Z' */ 00603 err = mp_sqr(Q->z, &t1); 00604 if (err == MP_OKAY) 00605 err = mp_montgomery_reduce(&t1, modulus, *mp); 00606 00607 /* X = X * T1 */ 00608 if (err == MP_OKAY) 00609 err = mp_mul(&t1, &x, &x); 00610 if (err == MP_OKAY) 00611 err = mp_montgomery_reduce(&x, modulus, *mp); 00612 00613 /* T1 = Z' * T1 */ 00614 if (err == MP_OKAY) 00615 err = mp_mul(Q->z, &t1, &t1); 00616 if (err == MP_OKAY) 00617 err = mp_montgomery_reduce(&t1, modulus, *mp); 00618 00619 /* Y = Y * T1 */ 00620 if (err == MP_OKAY) 00621 err = mp_mul(&t1, &y, &y); 00622 if (err == MP_OKAY) 00623 err = mp_montgomery_reduce(&y, modulus, *mp); 00624 } 00625 } 00626 00627 /* T1 = Z*Z */ 00628 if (err == MP_OKAY) 00629 err = mp_sqr(&z, &t1); 00630 if (err == MP_OKAY) 00631 err = mp_montgomery_reduce(&t1, modulus, *mp); 00632 00633 /* T2 = X' * T1 */ 00634 if (err == MP_OKAY) 00635 err = mp_mul(Q->x, &t1, &t2); 00636 if (err == MP_OKAY) 00637 err = mp_montgomery_reduce(&t2, modulus, *mp); 00638 00639 /* T1 = Z * T1 */ 00640 if (err == MP_OKAY) 00641 err = mp_mul(&z, &t1, &t1); 00642 if (err == MP_OKAY) 00643 err = mp_montgomery_reduce(&t1, modulus, *mp); 00644 00645 /* T1 = Y' * T1 */ 00646 if (err == MP_OKAY) 00647 err = mp_mul(Q->y, &t1, &t1); 00648 if (err == MP_OKAY) 00649 err = mp_montgomery_reduce(&t1, modulus, *mp); 00650 00651 /* Y = Y - T1 */ 00652 if (err == MP_OKAY) 00653 err = mp_sub(&y, &t1, &y); 00654 if (err == MP_OKAY) { 00655 if (mp_cmp_d(&y, 0) == MP_LT) 00656 err = mp_add(&y, modulus, &y); 00657 } 00658 /* T1 = 2T1 */ 00659 if (err == MP_OKAY) 00660 err = mp_add(&t1, &t1, &t1); 00661 if (err == MP_OKAY) { 00662 if (mp_cmp(&t1, modulus) != MP_LT) 00663 err = mp_sub(&t1, modulus, &t1); 00664 } 00665 /* T1 = Y + T1 */ 00666 if (err == MP_OKAY) 00667 err = mp_add(&t1, &y, &t1); 00668 if (err == MP_OKAY) { 00669 if (mp_cmp(&t1, modulus) != MP_LT) 00670 err = mp_sub(&t1, modulus, &t1); 00671 } 00672 /* X = X - T2 */ 00673 if (err == MP_OKAY) 00674 err = mp_sub(&x, &t2, &x); 00675 if (err == MP_OKAY) { 00676 if (mp_cmp_d(&x, 0) == MP_LT) 00677 err = mp_add(&x, modulus, &x); 00678 } 00679 /* T2 = 2T2 */ 00680 if (err == MP_OKAY) 00681 err = mp_add(&t2, &t2, &t2); 00682 if (err == MP_OKAY) { 00683 if (mp_cmp(&t2, modulus) != MP_LT) 00684 err = mp_sub(&t2, modulus, &t2); 00685 } 00686 /* T2 = X + T2 */ 00687 if (err == MP_OKAY) 00688 err = mp_add(&t2, &x, &t2); 00689 if (err == MP_OKAY) { 00690 if (mp_cmp(&t2, modulus) != MP_LT) 00691 err = mp_sub(&t2, modulus, &t2); 00692 } 00693 00694 if (err == MP_OKAY) { 00695 if (get_digit_count(Q->z)) { 00696 /* Z = Z * Z' */ 00697 err = mp_mul(&z, Q->z, &z); 00698 if (err == MP_OKAY) 00699 err = mp_montgomery_reduce(&z, modulus, *mp); 00700 } 00701 } 00702 00703 /* Z = Z * X */ 00704 if (err == MP_OKAY) 00705 err = mp_mul(&z, &x, &z); 00706 if (err == MP_OKAY) 00707 err = mp_montgomery_reduce(&z, modulus, *mp); 00708 00709 /* T1 = T1 * X */ 00710 if (err == MP_OKAY) 00711 err = mp_mul(&t1, &x, &t1); 00712 if (err == MP_OKAY) 00713 err = mp_montgomery_reduce(&t1, modulus, *mp); 00714 00715 /* X = X * X */ 00716 if (err == MP_OKAY) 00717 err = mp_sqr(&x, &x); 00718 if (err == MP_OKAY) 00719 err = mp_montgomery_reduce(&x, modulus, *mp); 00720 00721 /* T2 = T2 * x */ 00722 if (err == MP_OKAY) 00723 err = mp_mul(&t2, &x, &t2); 00724 if (err == MP_OKAY) 00725 err = mp_montgomery_reduce(&t2, modulus, *mp); 00726 00727 /* T1 = T1 * X */ 00728 if (err == MP_OKAY) 00729 err = mp_mul(&t1, &x, &t1); 00730 if (err == MP_OKAY) 00731 err = mp_montgomery_reduce(&t1, modulus, *mp); 00732 00733 /* X = Y*Y */ 00734 if (err == MP_OKAY) 00735 err = mp_sqr(&y, &x); 00736 if (err == MP_OKAY) 00737 err = mp_montgomery_reduce(&x, modulus, *mp); 00738 00739 /* X = X - T2 */ 00740 if (err == MP_OKAY) 00741 err = mp_sub(&x, &t2, &x); 00742 if (err == MP_OKAY) { 00743 if (mp_cmp_d(&x, 0) == MP_LT) 00744 err = mp_add(&x, modulus, &x); 00745 } 00746 /* T2 = T2 - X */ 00747 if (err == MP_OKAY) 00748 err = mp_sub(&t2, &x, &t2); 00749 if (err == MP_OKAY) { 00750 if (mp_cmp_d(&t2, 0) == MP_LT) 00751 err = mp_add(&t2, modulus, &t2); 00752 } 00753 /* T2 = T2 - X */ 00754 if (err == MP_OKAY) 00755 err = mp_sub(&t2, &x, &t2); 00756 if (err == MP_OKAY) { 00757 if (mp_cmp_d(&t2, 0) == MP_LT) 00758 err = mp_add(&t2, modulus, &t2); 00759 } 00760 /* T2 = T2 * Y */ 00761 if (err == MP_OKAY) 00762 err = mp_mul(&t2, &y, &t2); 00763 if (err == MP_OKAY) 00764 err = mp_montgomery_reduce(&t2, modulus, *mp); 00765 00766 /* Y = T2 - T1 */ 00767 if (err == MP_OKAY) 00768 err = mp_sub(&t2, &t1, &y); 00769 if (err == MP_OKAY) { 00770 if (mp_cmp_d(&y, 0) == MP_LT) 00771 err = mp_add(&y, modulus, &y); 00772 } 00773 /* Y = Y/2 */ 00774 if (err == MP_OKAY) { 00775 if (mp_isodd(&y)) 00776 err = mp_add(&y, modulus, &y); 00777 } 00778 if (err == MP_OKAY) 00779 err = mp_div_2(&y, &y); 00780 00781 if (err == MP_OKAY) 00782 err = mp_copy(&x, R->x); 00783 if (err == MP_OKAY) 00784 err = mp_copy(&y, R->y); 00785 if (err == MP_OKAY) 00786 err = mp_copy(&z, R->z); 00787 00788 /* clean up */ 00789 mp_clear(&t1); 00790 mp_clear(&t2); 00791 mp_clear(&x); 00792 mp_clear(&y); 00793 mp_clear(&z); 00794 00795 return err; 00796 } 00797 00798 00799 /** 00800 Double an ECC point 00801 P The point to double 00802 R [out] The destination of the double 00803 modulus The modulus of the field the ECC curve is in 00804 mp The "b" value from montgomery_setup() 00805 return MP_OKAY on success 00806 */ 00807 int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* modulus, 00808 mp_digit* mp) 00809 { 00810 mp_int t1; 00811 mp_int t2; 00812 int err; 00813 00814 if (P == NULL || R == NULL || modulus == NULL || mp == NULL) 00815 return ECC_BAD_ARG_E; 00816 00817 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 00818 return err; 00819 } 00820 00821 if (P != R) { 00822 err = mp_copy(P->x, R->x); 00823 if (err == MP_OKAY) 00824 err = mp_copy(P->y, R->y); 00825 if (err == MP_OKAY) 00826 err = mp_copy(P->z, R->z); 00827 } 00828 00829 /* t1 = Z * Z */ 00830 if (err == MP_OKAY) 00831 err = mp_sqr(R->z, &t1); 00832 if (err == MP_OKAY) 00833 err = mp_montgomery_reduce(&t1, modulus, *mp); 00834 00835 /* Z = Y * Z */ 00836 if (err == MP_OKAY) 00837 err = mp_mul(R->z, R->y, R->z); 00838 if (err == MP_OKAY) 00839 err = mp_montgomery_reduce(R->z, modulus, *mp); 00840 00841 /* Z = 2Z */ 00842 if (err == MP_OKAY) 00843 err = mp_add(R->z, R->z, R->z); 00844 if (err == MP_OKAY) { 00845 if (mp_cmp(R->z, modulus) != MP_LT) 00846 err = mp_sub(R->z, modulus, R->z); 00847 } 00848 00849 /* T2 = X - T1 */ 00850 if (err == MP_OKAY) 00851 err = mp_sub(R->x, &t1, &t2); 00852 if (err == MP_OKAY) { 00853 if (mp_cmp_d(&t2, 0) == MP_LT) 00854 err = mp_add(&t2, modulus, &t2); 00855 } 00856 /* T1 = X + T1 */ 00857 if (err == MP_OKAY) 00858 err = mp_add(&t1, R->x, &t1); 00859 if (err == MP_OKAY) { 00860 if (mp_cmp(&t1, modulus) != MP_LT) 00861 err = mp_sub(&t1, modulus, &t1); 00862 } 00863 /* T2 = T1 * T2 */ 00864 if (err == MP_OKAY) 00865 err = mp_mul(&t1, &t2, &t2); 00866 if (err == MP_OKAY) 00867 err = mp_montgomery_reduce(&t2, modulus, *mp); 00868 00869 /* T1 = 2T2 */ 00870 if (err == MP_OKAY) 00871 err = mp_add(&t2, &t2, &t1); 00872 if (err == MP_OKAY) { 00873 if (mp_cmp(&t1, modulus) != MP_LT) 00874 err = mp_sub(&t1, modulus, &t1); 00875 } 00876 /* T1 = T1 + T2 */ 00877 if (err == MP_OKAY) 00878 err = mp_add(&t1, &t2, &t1); 00879 if (err == MP_OKAY) { 00880 if (mp_cmp(&t1, modulus) != MP_LT) 00881 err = mp_sub(&t1, modulus, &t1); 00882 } 00883 /* Y = 2Y */ 00884 if (err == MP_OKAY) 00885 err = mp_add(R->y, R->y, R->y); 00886 if (err == MP_OKAY) { 00887 if (mp_cmp(R->y, modulus) != MP_LT) 00888 err = mp_sub(R->y, modulus, R->y); 00889 } 00890 /* Y = Y * Y */ 00891 if (err == MP_OKAY) 00892 err = mp_sqr(R->y, R->y); 00893 if (err == MP_OKAY) 00894 err = mp_montgomery_reduce(R->y, modulus, *mp); 00895 00896 /* T2 = Y * Y */ 00897 if (err == MP_OKAY) 00898 err = mp_sqr(R->y, &t2); 00899 if (err == MP_OKAY) 00900 err = mp_montgomery_reduce(&t2, modulus, *mp); 00901 00902 /* T2 = T2/2 */ 00903 if (err == MP_OKAY) { 00904 if (mp_isodd(&t2)) 00905 err = mp_add(&t2, modulus, &t2); 00906 } 00907 if (err == MP_OKAY) 00908 err = mp_div_2(&t2, &t2); 00909 00910 /* Y = Y * X */ 00911 if (err == MP_OKAY) 00912 err = mp_mul(R->y, R->x, R->y); 00913 if (err == MP_OKAY) 00914 err = mp_montgomery_reduce(R->y, modulus, *mp); 00915 00916 /* X = T1 * T1 */ 00917 if (err == MP_OKAY) 00918 err = mp_sqr(&t1, R->x); 00919 if (err == MP_OKAY) 00920 err = mp_montgomery_reduce(R->x, modulus, *mp); 00921 00922 /* X = X - Y */ 00923 if (err == MP_OKAY) 00924 err = mp_sub(R->x, R->y, R->x); 00925 if (err == MP_OKAY) { 00926 if (mp_cmp_d(R->x, 0) == MP_LT) 00927 err = mp_add(R->x, modulus, R->x); 00928 } 00929 /* X = X - Y */ 00930 if (err == MP_OKAY) 00931 err = mp_sub(R->x, R->y, R->x); 00932 if (err == MP_OKAY) { 00933 if (mp_cmp_d(R->x, 0) == MP_LT) 00934 err = mp_add(R->x, modulus, R->x); 00935 } 00936 /* Y = Y - X */ 00937 if (err == MP_OKAY) 00938 err = mp_sub(R->y, R->x, R->y); 00939 if (err == MP_OKAY) { 00940 if (mp_cmp_d(R->y, 0) == MP_LT) 00941 err = mp_add(R->y, modulus, R->y); 00942 } 00943 /* Y = Y * T1 */ 00944 if (err == MP_OKAY) 00945 err = mp_mul(R->y, &t1, R->y); 00946 if (err == MP_OKAY) 00947 err = mp_montgomery_reduce(R->y, modulus, *mp); 00948 00949 /* Y = Y - T2 */ 00950 if (err == MP_OKAY) 00951 err = mp_sub(R->y, &t2, R->y); 00952 if (err == MP_OKAY) { 00953 if (mp_cmp_d(R->y, 0) == MP_LT) 00954 err = mp_add(R->y, modulus, R->y); 00955 } 00956 00957 /* clean up */ 00958 mp_clear(&t1); 00959 mp_clear(&t2); 00960 00961 return err; 00962 } 00963 00964 #endif /* USE_FAST_MATH */ 00965 00966 /** 00967 Map a projective jacbobian point back to affine space 00968 P [in/out] The point to map 00969 modulus The modulus of the field the ECC curve is in 00970 mp The "b" value from montgomery_setup() 00971 return MP_OKAY on success 00972 */ 00973 int ecc_map(ecc_point* P, mp_int* modulus, mp_digit* mp) 00974 { 00975 mp_int t1; 00976 mp_int t2; 00977 int err; 00978 00979 if (P == NULL || mp == NULL || modulus == NULL) 00980 return ECC_BAD_ARG_E; 00981 00982 /* special case for point at infinity */ 00983 if (mp_cmp_d(P->z, 0) == MP_EQ) { 00984 mp_set(P->x, 0); 00985 mp_set(P->y, 0); 00986 mp_set(P->z, 1); 00987 return MP_OKAY; 00988 } 00989 00990 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 00991 return MEMORY_E; 00992 } 00993 00994 /* first map z back to normal */ 00995 err = mp_montgomery_reduce(P->z, modulus, *mp); 00996 00997 /* get 1/z */ 00998 if (err == MP_OKAY) 00999 err = mp_invmod(P->z, modulus, &t1); 01000 01001 /* get 1/z^2 and 1/z^3 */ 01002 if (err == MP_OKAY) 01003 err = mp_sqr(&t1, &t2); 01004 if (err == MP_OKAY) 01005 err = mp_mod(&t2, modulus, &t2); 01006 if (err == MP_OKAY) 01007 err = mp_mul(&t1, &t2, &t1); 01008 if (err == MP_OKAY) 01009 err = mp_mod(&t1, modulus, &t1); 01010 01011 /* multiply against x/y */ 01012 if (err == MP_OKAY) 01013 err = mp_mul(P->x, &t2, P->x); 01014 if (err == MP_OKAY) 01015 err = mp_montgomery_reduce(P->x, modulus, *mp); 01016 if (err == MP_OKAY) 01017 err = mp_mul(P->y, &t1, P->y); 01018 if (err == MP_OKAY) 01019 err = mp_montgomery_reduce(P->y, modulus, *mp); 01020 01021 if (err == MP_OKAY) 01022 mp_set(P->z, 1); 01023 01024 /* clean up */ 01025 mp_clear(&t1); 01026 mp_clear(&t2); 01027 01028 return err; 01029 } 01030 01031 01032 #ifndef ECC_TIMING_RESISTANT 01033 01034 /* size of sliding window, don't change this! */ 01035 #define WINSIZE 4 01036 01037 /** 01038 Perform a point multiplication 01039 k The scalar to multiply by 01040 G The base point 01041 R [out] Destination for kG 01042 modulus The modulus of the field the ECC curve is in 01043 map Boolean whether to map back to affine or not 01044 (1==map, 0 == leave in projective) 01045 return MP_OKAY on success 01046 */ 01047 #ifdef FP_ECC 01048 static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, 01049 mp_int* modulus, int map) 01050 #else 01051 int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, 01052 int map) 01053 #endif 01054 { 01055 ecc_point *tG, *M[8]; 01056 int i, j, err; 01057 mp_int mu; 01058 mp_digit mp; 01059 mp_digit buf; 01060 int first = 1, bitbuf = 0, bitcpy = 0, bitcnt = 0, mode = 0, 01061 digidx = 0; 01062 01063 if (k == NULL || G == NULL || R == NULL || modulus == NULL) 01064 return ECC_BAD_ARG_E; 01065 01066 /* init montgomery reduction */ 01067 if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { 01068 return err; 01069 } 01070 if ((err = mp_init(&mu)) != MP_OKAY) { 01071 return err; 01072 } 01073 if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) { 01074 mp_clear(&mu); 01075 return err; 01076 } 01077 01078 /* alloc ram for window temps */ 01079 for (i = 0; i < 8; i++) { 01080 M[i] = wc_ecc_new_point(); 01081 if (M[i] == NULL) { 01082 for (j = 0; j < i; j++) { 01083 wc_ecc_del_point(M[j]); 01084 } 01085 mp_clear(&mu); 01086 return MEMORY_E; 01087 } 01088 } 01089 01090 /* make a copy of G in case R==G */ 01091 tG = wc_ecc_new_point(); 01092 if (tG == NULL) 01093 err = MEMORY_E; 01094 01095 /* tG = G and convert to montgomery */ 01096 if (err == MP_OKAY) { 01097 if (mp_cmp_d(&mu, 1) == MP_EQ) { 01098 err = mp_copy(G->x, tG->x); 01099 if (err == MP_OKAY) 01100 err = mp_copy(G->y, tG->y); 01101 if (err == MP_OKAY) 01102 err = mp_copy(G->z, tG->z); 01103 } else { 01104 err = mp_mulmod(G->x, &mu, modulus, tG->x); 01105 if (err == MP_OKAY) 01106 err = mp_mulmod(G->y, &mu, modulus, tG->y); 01107 if (err == MP_OKAY) 01108 err = mp_mulmod(G->z, &mu, modulus, tG->z); 01109 } 01110 } 01111 mp_clear(&mu); 01112 01113 /* calc the M tab, which holds kG for k==8..15 */ 01114 /* M[0] == 8G */ 01115 if (err == MP_OKAY) 01116 err = ecc_projective_dbl_point(tG, M[0], modulus, &mp); 01117 if (err == MP_OKAY) 01118 err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp); 01119 if (err == MP_OKAY) 01120 err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp); 01121 01122 /* now find (8+k)G for k=1..7 */ 01123 if (err == MP_OKAY) 01124 for (j = 9; j < 16; j++) { 01125 err = ecc_projective_add_point(M[j-9], tG, M[j-8], modulus, &mp); 01126 if (err != MP_OKAY) break; 01127 } 01128 01129 /* setup sliding window */ 01130 if (err == MP_OKAY) { 01131 mode = 0; 01132 bitcnt = 1; 01133 buf = 0; 01134 digidx = get_digit_count(k) - 1; 01135 bitcpy = bitbuf = 0; 01136 first = 1; 01137 01138 /* perform ops */ 01139 for (;;) { 01140 /* grab next digit as required */ 01141 if (--bitcnt == 0) { 01142 if (digidx == -1) { 01143 break; 01144 } 01145 buf = get_digit(k, digidx); 01146 bitcnt = (int) DIGIT_BIT; 01147 --digidx; 01148 } 01149 01150 /* grab the next msb from the ltiplicand */ 01151 i = (int)(buf >> (DIGIT_BIT - 1)) & 1; 01152 buf <<= 1; 01153 01154 /* skip leading zero bits */ 01155 if (mode == 0 && i == 0) 01156 continue; 01157 01158 /* if the bit is zero and mode == 1 then we double */ 01159 if (mode == 1 && i == 0) { 01160 err = ecc_projective_dbl_point(R, R, modulus, &mp); 01161 if (err != MP_OKAY) break; 01162 continue; 01163 } 01164 01165 /* else we add it to the window */ 01166 bitbuf |= (i << (WINSIZE - ++bitcpy)); 01167 mode = 2; 01168 01169 if (bitcpy == WINSIZE) { 01170 /* if this is the first window we do a simple copy */ 01171 if (first == 1) { 01172 /* R = kG [k = first window] */ 01173 err = mp_copy(M[bitbuf-8]->x, R->x); 01174 if (err != MP_OKAY) break; 01175 01176 err = mp_copy(M[bitbuf-8]->y, R->y); 01177 if (err != MP_OKAY) break; 01178 01179 err = mp_copy(M[bitbuf-8]->z, R->z); 01180 first = 0; 01181 } else { 01182 /* normal window */ 01183 /* ok window is filled so double as required and add */ 01184 /* double first */ 01185 for (j = 0; j < WINSIZE; j++) { 01186 err = ecc_projective_dbl_point(R, R, modulus, &mp); 01187 if (err != MP_OKAY) break; 01188 } 01189 if (err != MP_OKAY) break; /* out of first for(;;) */ 01190 01191 /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ 01192 err = ecc_projective_add_point(R,M[bitbuf-8],R,modulus,&mp); 01193 } 01194 if (err != MP_OKAY) break; 01195 /* empty window and reset */ 01196 bitcpy = bitbuf = 0; 01197 mode = 1; 01198 } 01199 } 01200 } 01201 01202 /* if bits remain then double/add */ 01203 if (err == MP_OKAY) { 01204 if (mode == 2 && bitcpy > 0) { 01205 /* double then add */ 01206 for (j = 0; j < bitcpy; j++) { 01207 /* only double if we have had at least one add first */ 01208 if (first == 0) { 01209 err = ecc_projective_dbl_point(R, R, modulus, &mp); 01210 if (err != MP_OKAY) break; 01211 } 01212 01213 bitbuf <<= 1; 01214 if ((bitbuf & (1 << WINSIZE)) != 0) { 01215 if (first == 1) { 01216 /* first add, so copy */ 01217 err = mp_copy(tG->x, R->x); 01218 if (err != MP_OKAY) break; 01219 01220 err = mp_copy(tG->y, R->y); 01221 if (err != MP_OKAY) break; 01222 01223 err = mp_copy(tG->z, R->z); 01224 if (err != MP_OKAY) break; 01225 first = 0; 01226 } else { 01227 /* then add */ 01228 err = ecc_projective_add_point(R, tG, R, modulus, &mp); 01229 if (err != MP_OKAY) break; 01230 } 01231 } 01232 } 01233 } 01234 } 01235 01236 /* map R back from projective space */ 01237 if (err == MP_OKAY && map) 01238 err = ecc_map(R, modulus, &mp); 01239 01240 mp_clear(&mu); 01241 wc_ecc_del_point(tG); 01242 for (i = 0; i < 8; i++) { 01243 wc_ecc_del_point(M[i]); 01244 } 01245 return err; 01246 } 01247 01248 #undef WINSIZE 01249 01250 #else /* ECC_TIMING_RESISTANT */ 01251 01252 /** 01253 Perform a point multiplication (timing resistant) 01254 k The scalar to multiply by 01255 G The base point 01256 R [out] Destination for kG 01257 modulus The modulus of the field the ECC curve is in 01258 map Boolean whether to map back to affine or not 01259 (1==map, 0 == leave in projective) 01260 return MP_OKAY on success 01261 */ 01262 #ifdef FP_ECC 01263 static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, 01264 mp_int* modulus, int map) 01265 #else 01266 int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, 01267 int map) 01268 #endif 01269 { 01270 ecc_point *tG, *M[3]; 01271 int i, j, err; 01272 mp_int mu; 01273 mp_digit mp; 01274 mp_digit buf; 01275 int bitcnt = 0, mode = 0, digidx = 0; 01276 01277 if (k == NULL || G == NULL || R == NULL || modulus == NULL) 01278 return ECC_BAD_ARG_E; 01279 01280 /* init montgomery reduction */ 01281 if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { 01282 return err; 01283 } 01284 if ((err = mp_init(&mu)) != MP_OKAY) { 01285 return err; 01286 } 01287 if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) { 01288 mp_clear(&mu); 01289 return err; 01290 } 01291 01292 /* alloc ram for window temps */ 01293 for (i = 0; i < 3; i++) { 01294 M[i] = wc_ecc_new_point(); 01295 if (M[i] == NULL) { 01296 for (j = 0; j < i; j++) { 01297 wc_ecc_del_point(M[j]); 01298 } 01299 mp_clear(&mu); 01300 return MEMORY_E; 01301 } 01302 } 01303 01304 /* make a copy of G in case R==G */ 01305 tG = wc_ecc_new_point(); 01306 if (tG == NULL) 01307 err = MEMORY_E; 01308 01309 /* tG = G and convert to montgomery */ 01310 if (err == MP_OKAY) { 01311 err = mp_mulmod(G->x, &mu, modulus, tG->x); 01312 if (err == MP_OKAY) 01313 err = mp_mulmod(G->y, &mu, modulus, tG->y); 01314 if (err == MP_OKAY) 01315 err = mp_mulmod(G->z, &mu, modulus, tG->z); 01316 } 01317 mp_clear(&mu); 01318 01319 /* calc the M tab */ 01320 /* M[0] == G */ 01321 if (err == MP_OKAY) 01322 err = mp_copy(tG->x, M[0]->x); 01323 if (err == MP_OKAY) 01324 err = mp_copy(tG->y, M[0]->y); 01325 if (err == MP_OKAY) 01326 err = mp_copy(tG->z, M[0]->z); 01327 01328 /* M[1] == 2G */ 01329 if (err == MP_OKAY) 01330 err = ecc_projective_dbl_point(tG, M[1], modulus, &mp); 01331 01332 /* setup sliding window */ 01333 mode = 0; 01334 bitcnt = 1; 01335 buf = 0; 01336 digidx = get_digit_count(k) - 1; 01337 01338 /* perform ops */ 01339 if (err == MP_OKAY) { 01340 for (;;) { 01341 /* grab next digit as required */ 01342 if (--bitcnt == 0) { 01343 if (digidx == -1) { 01344 break; 01345 } 01346 buf = get_digit(k, digidx); 01347 bitcnt = (int) DIGIT_BIT; 01348 --digidx; 01349 } 01350 01351 /* grab the next msb from the ltiplicand */ 01352 i = (buf >> (DIGIT_BIT - 1)) & 1; 01353 buf <<= 1; 01354 01355 if (mode == 0 && i == 0) { 01356 /* dummy operations */ 01357 if (err == MP_OKAY) 01358 err = ecc_projective_add_point(M[0], M[1], M[2], modulus, 01359 &mp); 01360 if (err == MP_OKAY) 01361 err = ecc_projective_dbl_point(M[1], M[2], modulus, &mp); 01362 if (err == MP_OKAY) 01363 continue; 01364 } 01365 01366 if (mode == 0 && i == 1) { 01367 mode = 1; 01368 /* dummy operations */ 01369 if (err == MP_OKAY) 01370 err = ecc_projective_add_point(M[0], M[1], M[2], modulus, 01371 &mp); 01372 if (err == MP_OKAY) 01373 err = ecc_projective_dbl_point(M[1], M[2], modulus, &mp); 01374 if (err == MP_OKAY) 01375 continue; 01376 } 01377 01378 if (err == MP_OKAY) 01379 err = ecc_projective_add_point(M[0], M[1], M[i^1], modulus, &mp); 01380 if (err == MP_OKAY) 01381 err = ecc_projective_dbl_point(M[i], M[i], modulus, &mp); 01382 if (err != MP_OKAY) 01383 break; 01384 } /* end for */ 01385 } 01386 01387 /* copy result out */ 01388 if (err == MP_OKAY) 01389 err = mp_copy(M[0]->x, R->x); 01390 if (err == MP_OKAY) 01391 err = mp_copy(M[0]->y, R->y); 01392 if (err == MP_OKAY) 01393 err = mp_copy(M[0]->z, R->z); 01394 01395 /* map R back from projective space */ 01396 if (err == MP_OKAY && map) 01397 err = ecc_map(R, modulus, &mp); 01398 01399 /* done */ 01400 mp_clear(&mu); 01401 wc_ecc_del_point(tG); 01402 for (i = 0; i < 3; i++) { 01403 wc_ecc_del_point(M[i]); 01404 } 01405 return err; 01406 } 01407 01408 #endif /* ECC_TIMING_RESISTANT */ 01409 01410 01411 #ifdef ALT_ECC_SIZE 01412 01413 static void alt_fp_init(fp_int* a) 01414 { 01415 a->size = FP_SIZE_ECC; 01416 fp_zero(a); 01417 } 01418 01419 #endif /* ALT_ECC_SIZE */ 01420 01421 01422 /** 01423 Allocate a new ECC point 01424 return A newly allocated point or NULL on error 01425 */ 01426 ecc_point* wc_ecc_new_point(void) 01427 { 01428 ecc_point* p; 01429 01430 p = (ecc_point*)XMALLOC(sizeof(ecc_point), 0, DYNAMIC_TYPE_ECC); 01431 if (p == NULL) { 01432 return NULL; 01433 } 01434 XMEMSET(p, 0, sizeof(ecc_point)); 01435 01436 #ifndef USE_FAST_MATH 01437 p->x->dp = NULL; 01438 p->y->dp = NULL; 01439 p->z->dp = NULL; 01440 #endif 01441 01442 #ifndef ALT_ECC_SIZE 01443 if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) { 01444 XFREE(p, 0, DYNAMIC_TYPE_ECC); 01445 return NULL; 01446 } 01447 #else 01448 p->x = (mp_int*)&p->xyz[0]; 01449 p->y = (mp_int*)&p->xyz[1]; 01450 p->z = (mp_int*)&p->xyz[2]; 01451 alt_fp_init(p->x); 01452 alt_fp_init(p->y); 01453 alt_fp_init(p->z); 01454 #endif 01455 01456 return p; 01457 } 01458 01459 /** Free an ECC point from memory 01460 p The point to free 01461 */ 01462 void wc_ecc_del_point(ecc_point* p) 01463 { 01464 /* prevents free'ing null arguments */ 01465 if (p != NULL) { 01466 mp_clear(p->x); 01467 mp_clear(p->y); 01468 mp_clear(p->z); 01469 XFREE(p, 0, DYNAMIC_TYPE_ECC); 01470 } 01471 } 01472 01473 /** Copy the value of a point to an other one 01474 p The point to copy 01475 r The created point 01476 */ 01477 int wc_ecc_copy_point(ecc_point* p, ecc_point *r) 01478 { 01479 int ret; 01480 01481 /* prevents null arguments */ 01482 if (p == NULL || r == NULL) 01483 return ECC_BAD_ARG_E; 01484 01485 ret = mp_copy(p->x, r->x); 01486 if (ret != MP_OKAY) 01487 return ret; 01488 ret = mp_copy(p->y, r->y); 01489 if (ret != MP_OKAY) 01490 return ret; 01491 ret = mp_copy(p->z, r->z); 01492 if (ret != MP_OKAY) 01493 return ret; 01494 01495 return MP_OKAY; 01496 } 01497 01498 /** Compare the value of a point with an other one 01499 a The point to compare 01500 b The other point to compare 01501 01502 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error 01503 */ 01504 int wc_ecc_cmp_point(ecc_point* a, ecc_point *b) 01505 { 01506 int ret; 01507 01508 /* prevents null arguments */ 01509 if (a == NULL || b == NULL) 01510 return BAD_FUNC_ARG; 01511 01512 ret = mp_cmp(a->x, b->x); 01513 if (ret != MP_EQ) 01514 return ret; 01515 ret = mp_cmp(a->y, b->y); 01516 if (ret != MP_EQ) 01517 return ret; 01518 ret = mp_cmp(a->z, b->z); 01519 if (ret != MP_EQ) 01520 return ret; 01521 01522 return MP_EQ; 01523 } 01524 01525 /** Returns whether an ECC idx is valid or not 01526 n The idx number to check 01527 return 1 if valid, 0 if not 01528 */ 01529 int wc_ecc_is_valid_idx(int n) 01530 { 01531 int x; 01532 01533 for (x = 0; ecc_sets[x].size != 0; x++) 01534 ; 01535 /* -1 is a valid index --- indicating that the domain params 01536 were supplied by the user */ 01537 if ((n >= -1) && (n < x)) { 01538 return 1; 01539 } 01540 return 0; 01541 } 01542 01543 #ifdef HAVE_ECC_DHE 01544 /** 01545 Create an ECC shared secret between two keys 01546 private_key The private ECC key 01547 public_key The public key 01548 out [out] Destination of the shared secret 01549 Conforms to EC-DH from ANSI X9.63 01550 outlen [in/out] The max size and resulting size of the shared secret 01551 return MP_OKAY if successful 01552 */ 01553 int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, 01554 word32* outlen) 01555 { 01556 word32 x = 0; 01557 ecc_point* result; 01558 mp_int prime; 01559 int err; 01560 01561 if (private_key == NULL || public_key == NULL || out == NULL || 01562 outlen == NULL) 01563 return BAD_FUNC_ARG; 01564 01565 /* type valid? */ 01566 if (private_key->type != ECC_PRIVATEKEY) { 01567 return ECC_BAD_ARG_E; 01568 } 01569 01570 /* Verify domain params supplied */ 01571 if (wc_ecc_is_valid_idx(private_key->idx) == 0 || 01572 wc_ecc_is_valid_idx(public_key->idx) == 0) 01573 return ECC_BAD_ARG_E; 01574 01575 /* Verify curve name matches */ 01576 if (XSTRNCMP(private_key->dp->name, public_key->dp->name, ECC_MAXNAME) != 0) 01577 return ECC_BAD_ARG_E; 01578 01579 /* make new point */ 01580 result = wc_ecc_new_point(); 01581 if (result == NULL) { 01582 return MEMORY_E; 01583 } 01584 01585 if ((err = mp_init(&prime)) != MP_OKAY) { 01586 wc_ecc_del_point(result); 01587 return err; 01588 } 01589 01590 err = mp_read_radix(&prime, (char *)private_key->dp->prime, 16); 01591 01592 if (err == MP_OKAY) 01593 err = wc_ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime,1); 01594 01595 if (err == MP_OKAY) { 01596 x = mp_unsigned_bin_size(&prime); 01597 if (*outlen < x) 01598 err = BUFFER_E; 01599 } 01600 01601 if (err == MP_OKAY) { 01602 XMEMSET(out, 0, x); 01603 err = mp_to_unsigned_bin(result->x,out + (x - 01604 mp_unsigned_bin_size(result->x))); 01605 *outlen = x; 01606 } 01607 01608 mp_clear(&prime); 01609 wc_ecc_del_point(result); 01610 01611 return err; 01612 } 01613 01614 /** 01615 Create an ECC shared secret between private key and public point 01616 private_key The private ECC key 01617 point The point to use (public key) 01618 out [out] Destination of the shared secret 01619 Conforms to EC-DH from ANSI X9.63 01620 outlen [in/out] The max size and resulting size of the shared secret 01621 return MP_OKAY if successful 01622 */ 01623 int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point, 01624 byte* out, word32 *outlen) 01625 { 01626 word32 x = 0; 01627 ecc_point* result; 01628 mp_int prime; 01629 int err; 01630 01631 if (private_key == NULL || point == NULL || out == NULL || outlen == NULL) 01632 return BAD_FUNC_ARG; 01633 01634 /* type valid? */ 01635 if (private_key->type != ECC_PRIVATEKEY) { 01636 return ECC_BAD_ARG_E; 01637 } 01638 01639 /* Verify domain params supplied */ 01640 if (wc_ecc_is_valid_idx(private_key->idx) == 0) 01641 return ECC_BAD_ARG_E; 01642 01643 /* make new point */ 01644 result = wc_ecc_new_point(); 01645 if (result == NULL) { 01646 return MEMORY_E; 01647 } 01648 01649 if ((err = mp_init(&prime)) != MP_OKAY) { 01650 wc_ecc_del_point(result); 01651 return err; 01652 } 01653 01654 err = mp_read_radix(&prime, (char *)private_key->dp->prime, 16); 01655 01656 if (err == MP_OKAY) 01657 err = wc_ecc_mulmod(&private_key->k, point, result, &prime, 1); 01658 01659 if (err == MP_OKAY) { 01660 x = mp_unsigned_bin_size(&prime); 01661 if (*outlen < x) 01662 err = BUFFER_E; 01663 } 01664 01665 if (err == MP_OKAY) { 01666 XMEMSET(out, 0, x); 01667 err = mp_to_unsigned_bin(result->x,out + 01668 (x - mp_unsigned_bin_size(result->x))); 01669 *outlen = x; 01670 } 01671 01672 mp_clear(&prime); 01673 wc_ecc_del_point(result); 01674 01675 return err; 01676 } 01677 #endif /* HAVE_ECC_DHE */ 01678 01679 /* return 1 if point is at infinity, 0 if not, < 0 on error */ 01680 int wc_ecc_point_is_at_infinity(ecc_point* p) 01681 { 01682 if (p == NULL) 01683 return BAD_FUNC_ARG; 01684 01685 if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0) 01686 return 1; 01687 01688 return 0; 01689 } 01690 01691 01692 static int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp) 01693 { 01694 int err; 01695 ecc_point* base; 01696 mp_int prime; 01697 mp_int order; 01698 #ifdef WOLFSSL_SMALL_STACK 01699 byte* buf; 01700 #else 01701 byte buf[ECC_MAXSIZE_GEN]; 01702 #endif 01703 int keysize; 01704 int po_init = 0; /* prime order Init flag for clear */ 01705 01706 if (key == NULL || rng == NULL || dp == NULL) 01707 return ECC_BAD_ARG_E; 01708 01709 #ifdef WOLFSSL_SMALL_STACK 01710 buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01711 if (buf == NULL) 01712 return MEMORY_E; 01713 #endif 01714 01715 key->idx = -1; 01716 key->dp = dp; 01717 01718 /*generate 8 extra bytes to mitigate bias from the modulo operation below*/ 01719 /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/ 01720 keysize = dp->size + 8; 01721 01722 /* allocate ram */ 01723 base = NULL; 01724 01725 /* make up random string */ 01726 err = wc_RNG_GenerateBlock(rng, buf, keysize); 01727 01728 /* setup the key variables */ 01729 if (err == 0) { 01730 #ifndef ALT_ECC_SIZE 01731 err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, 01732 &key->k, &prime, &order); 01733 #else 01734 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 01735 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 01736 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 01737 alt_fp_init(key->pubkey.x); 01738 alt_fp_init(key->pubkey.y); 01739 alt_fp_init(key->pubkey.z); 01740 err = mp_init_multi(&key->k, &prime, &order, NULL, NULL, NULL); 01741 #endif 01742 if (err != MP_OKAY) 01743 err = MEMORY_E; 01744 else 01745 po_init = 1; 01746 } 01747 01748 if (err == MP_OKAY) { 01749 base = wc_ecc_new_point(); 01750 if (base == NULL) 01751 err = MEMORY_E; 01752 } 01753 01754 /* read in the specs for this key */ 01755 if (err == MP_OKAY) 01756 err = mp_read_radix(&prime, (char *)key->dp->prime, 16); 01757 if (err == MP_OKAY) 01758 err = mp_read_radix(&order, (char *)key->dp->order, 16); 01759 if (err == MP_OKAY) 01760 err = mp_read_radix(base->x, (char *)key->dp->Gx, 16); 01761 if (err == MP_OKAY) 01762 err = mp_read_radix(base->y, (char *)key->dp->Gy, 16); 01763 01764 if (err == MP_OKAY) 01765 mp_set(base->z, 1); 01766 if (err == MP_OKAY) 01767 err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize); 01768 01769 /* quick sanity check to make sure we're not dealing with a 0 key */ 01770 if (err == MP_OKAY) { 01771 if (MP_YES == mp_iszero(&key->k)) 01772 err = MP_ZERO_E; 01773 } 01774 01775 /* the key should be smaller than the order of base point */ 01776 if (err == MP_OKAY) { 01777 if (mp_cmp(&key->k, &order) != MP_LT) 01778 err = mp_mod(&key->k, &order, &key->k); 01779 } 01780 /* make the public key */ 01781 if (err == MP_OKAY) 01782 err = wc_ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1); 01783 01784 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN 01785 /* validate the public key, order * pubkey = point at infinity */ 01786 if (err == MP_OKAY) 01787 err = ecc_check_pubkey_order(key, &prime, &order); 01788 #endif /* WOLFSSL_VALIDATE_KEYGEN */ 01789 01790 if (err == MP_OKAY) 01791 key->type = ECC_PRIVATEKEY; 01792 01793 if (err != MP_OKAY) { 01794 /* clean up */ 01795 mp_clear(key->pubkey.x); 01796 mp_clear(key->pubkey.y); 01797 mp_clear(key->pubkey.z); 01798 mp_clear(&key->k); 01799 } 01800 wc_ecc_del_point(base); 01801 if (po_init) { 01802 mp_clear(&prime); 01803 mp_clear(&order); 01804 } 01805 01806 ForceZero(buf, ECC_MAXSIZE); 01807 #ifdef WOLFSSL_SMALL_STACK 01808 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); 01809 #endif 01810 01811 return err; 01812 } 01813 01814 /** 01815 Make a new ECC key 01816 rng An active RNG state 01817 keysize The keysize for the new key (in octets from 20 to 65 bytes) 01818 key [out] Destination of the newly created key 01819 return MP_OKAY if successful, 01820 upon error all allocated memory will be freed 01821 */ 01822 int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key) 01823 { 01824 int x, err; 01825 01826 if (key == NULL || rng == NULL) 01827 return ECC_BAD_ARG_E; 01828 01829 /* find key size */ 01830 for (x = 0; (keysize > ecc_sets[x].size) && (ecc_sets[x].size != 0); x++) 01831 ; 01832 keysize = ecc_sets[x].size; 01833 01834 if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) { 01835 return BAD_FUNC_ARG; 01836 } 01837 err = wc_ecc_make_key_ex(rng, key, &ecc_sets[x]); 01838 key->idx = x; 01839 01840 return err; 01841 } 01842 01843 /* Setup dynamic pointers is using normal math for proper freeing */ 01844 int wc_ecc_init(ecc_key* key) 01845 { 01846 (void)key; 01847 01848 #ifndef USE_FAST_MATH 01849 key->pubkey.x->dp = NULL; 01850 key->pubkey.y->dp = NULL; 01851 key->pubkey.z->dp = NULL; 01852 01853 key->k.dp = NULL; 01854 #endif 01855 01856 #ifdef ALT_ECC_SIZE 01857 if (mp_init(&key->k) != MP_OKAY) 01858 return MEMORY_E; 01859 01860 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 01861 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 01862 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 01863 alt_fp_init(key->pubkey.x); 01864 alt_fp_init(key->pubkey.y); 01865 alt_fp_init(key->pubkey.z); 01866 #endif 01867 01868 return MP_OKAY; 01869 } 01870 01871 01872 #ifdef HAVE_ECC_SIGN 01873 01874 #ifndef NO_ASN 01875 /** 01876 Sign a message digest 01877 in The message digest to sign 01878 inlen The length of the digest 01879 out [out] The destination for the signature 01880 outlen [in/out] The max size and resulting size of the signature 01881 key A private ECC key 01882 return MP_OKAY if successful 01883 */ 01884 int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, 01885 WC_RNG* rng, ecc_key* key) 01886 { 01887 mp_int r; 01888 mp_int s; 01889 int err; 01890 01891 if (in == NULL || out == NULL || outlen == NULL || 01892 key == NULL || rng == NULL) 01893 return ECC_BAD_ARG_E; 01894 01895 if ((err = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL)) != MP_OKAY) { 01896 return err; 01897 } 01898 01899 err = wc_ecc_sign_hash_ex(in, inlen, rng, key, &r, &s); 01900 if (err == MP_OKAY) 01901 err = StoreECC_DSA_Sig(out, outlen, &r, &s); 01902 01903 mp_clear(&r); 01904 mp_clear(&s); 01905 01906 return err; 01907 } 01908 #endif /* !NO_ASN */ 01909 01910 /** 01911 Sign a message digest 01912 in The message digest to sign 01913 inlen The length of the digest 01914 out [out] The destination for the signature 01915 outlen [in/out] The max size and resulting size of the signature 01916 key A private ECC key 01917 r [out] The destination for r component of the signature 01918 s [out] The destination for s component of the signature 01919 return MP_OKAY if successful 01920 */ 01921 int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, 01922 ecc_key* key, mp_int *r, mp_int *s) 01923 { 01924 mp_int e; 01925 mp_int p; 01926 int err; 01927 01928 if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) 01929 return ECC_BAD_ARG_E; 01930 01931 /* is this a private key? */ 01932 if (key->type != ECC_PRIVATEKEY) { 01933 return ECC_BAD_ARG_E; 01934 } 01935 01936 /* is the IDX valid ? */ 01937 if (wc_ecc_is_valid_idx(key->idx) != 1) { 01938 return ECC_BAD_ARG_E; 01939 } 01940 01941 /* get the hash and load it as a bignum into 'e' */ 01942 /* init the bignums */ 01943 if ((err = mp_init_multi(&p, &e, NULL, NULL, NULL, NULL)) != MP_OKAY) { 01944 return err; 01945 } 01946 err = mp_read_radix(&p, (char *)key->dp->order, 16); 01947 01948 if (err == MP_OKAY) { 01949 /* we may need to truncate if hash is longer than key size */ 01950 word32 orderBits = mp_count_bits(&p); 01951 01952 /* truncate down to byte size, may be all that's needed */ 01953 if ( (WOLFSSL_BIT_SIZE * inlen) > orderBits) 01954 inlen = (orderBits + WOLFSSL_BIT_SIZE - 1)/WOLFSSL_BIT_SIZE; 01955 err = mp_read_unsigned_bin(&e, (byte*)in, inlen); 01956 01957 /* may still need bit truncation too */ 01958 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits) 01959 mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); 01960 } 01961 01962 /* make up a key and export the public copy */ 01963 if (err == MP_OKAY) { 01964 int loop_check = 0; 01965 ecc_key pubkey; 01966 if (wc_ecc_init(&pubkey) == MP_OKAY) { 01967 for (;;) { 01968 if (++loop_check > 64) { 01969 err = RNG_FAILURE_E; 01970 break; 01971 } 01972 err = wc_ecc_make_key_ex(rng, &pubkey, key->dp); 01973 if (err != MP_OKAY) break; 01974 01975 /* find r = x1 mod n */ 01976 err = mp_mod(pubkey.pubkey.x, &p, r); 01977 if (err != MP_OKAY) break; 01978 01979 if (mp_iszero(r) == MP_YES) { 01980 mp_clear(pubkey.pubkey.x); 01981 mp_clear(pubkey.pubkey.y); 01982 mp_clear(pubkey.pubkey.z); 01983 mp_clear(&pubkey.k); 01984 } 01985 else { 01986 /* find s = (e + xr)/k */ 01987 err = mp_invmod(&pubkey.k, &p, &pubkey.k); 01988 if (err != MP_OKAY) break; 01989 01990 err = mp_mulmod(&key->k, r, &p, s); /* s = xr */ 01991 if (err != MP_OKAY) break; 01992 01993 err = mp_add(&e, s, s); /* s = e + xr */ 01994 if (err != MP_OKAY) break; 01995 01996 err = mp_mod(s, &p, s); /* s = e + xr */ 01997 if (err != MP_OKAY) break; 01998 01999 err = mp_mulmod(s, &pubkey.k, &p, s); /* s = (e + xr)/k */ 02000 if (err != MP_OKAY) break; 02001 02002 if (mp_iszero(s) == MP_NO) 02003 break; 02004 } 02005 } 02006 wc_ecc_free(&pubkey); 02007 } 02008 } 02009 02010 mp_clear(&p); 02011 mp_clear(&e); 02012 02013 return err; 02014 } 02015 #endif /* HAVE_ECC_SIGN */ 02016 02017 /** 02018 Free an ECC key from memory 02019 key The key you wish to free 02020 */ 02021 void wc_ecc_free(ecc_key* key) 02022 { 02023 if (key == NULL) 02024 return; 02025 02026 mp_clear(key->pubkey.x); 02027 mp_clear(key->pubkey.y); 02028 mp_clear(key->pubkey.z); 02029 mp_clear(&key->k); 02030 } 02031 02032 02033 #ifdef USE_FAST_MATH 02034 #define GEN_MEM_ERR FP_MEM 02035 #else 02036 #define GEN_MEM_ERR MP_MEM 02037 #endif 02038 02039 #ifdef ECC_SHAMIR 02040 02041 /** Computes kA*A + kB*B = C using Shamir's Trick 02042 A First point to multiply 02043 kA What to multiple A by 02044 B Second point to multiply 02045 kB What to multiple B by 02046 C [out] Destination point (can overlap with A or B) 02047 modulus Modulus for curve 02048 return MP_OKAY on success 02049 */ 02050 #ifdef FP_ECC 02051 static int normal_ecc_mul2add(ecc_point* A, mp_int* kA, 02052 ecc_point* B, mp_int* kB, 02053 ecc_point* C, mp_int* modulus) 02054 #else 02055 static int ecc_mul2add(ecc_point* A, mp_int* kA, 02056 ecc_point* B, mp_int* kB, 02057 ecc_point* C, mp_int* modulus) 02058 #endif 02059 { 02060 ecc_point* precomp[16]; 02061 unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble; 02062 unsigned char* tA; 02063 unsigned char* tB; 02064 int err = MP_OKAY, first; 02065 int muInit = 0; 02066 int tableInit = 0; 02067 mp_digit mp; 02068 mp_int mu; 02069 02070 /* argchks */ 02071 if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL || 02072 modulus == NULL) 02073 return ECC_BAD_ARG_E; 02074 02075 02076 /* allocate memory */ 02077 tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02078 if (tA == NULL) { 02079 return GEN_MEM_ERR; 02080 } 02081 tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02082 if (tB == NULL) { 02083 XFREE(tA, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02084 return GEN_MEM_ERR; 02085 } 02086 XMEMSET(tA, 0, ECC_BUFSIZE); 02087 XMEMSET(tB, 0, ECC_BUFSIZE); 02088 02089 /* get sizes */ 02090 lenA = mp_unsigned_bin_size(kA); 02091 lenB = mp_unsigned_bin_size(kB); 02092 len = MAX(lenA, lenB); 02093 02094 /* sanity check */ 02095 if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) { 02096 err = BAD_FUNC_ARG; 02097 } 02098 02099 if (err == MP_OKAY) { 02100 /* extract and justify kA */ 02101 err = mp_to_unsigned_bin(kA, (len - lenA) + tA); 02102 02103 /* extract and justify kB */ 02104 if (err == MP_OKAY) 02105 err = mp_to_unsigned_bin(kB, (len - lenB) + tB); 02106 02107 /* allocate the table */ 02108 if (err == MP_OKAY) { 02109 for (x = 0; x < 16; x++) { 02110 precomp[x] = wc_ecc_new_point(); 02111 if (precomp[x] == NULL) { 02112 for (y = 0; y < x; ++y) { 02113 wc_ecc_del_point(precomp[y]); 02114 } 02115 err = GEN_MEM_ERR; 02116 break; 02117 } 02118 } 02119 } 02120 } 02121 02122 if (err == MP_OKAY) 02123 tableInit = 1; 02124 02125 if (err == MP_OKAY) 02126 /* init montgomery reduction */ 02127 err = mp_montgomery_setup(modulus, &mp); 02128 02129 if (err == MP_OKAY) 02130 err = mp_init(&mu); 02131 if (err == MP_OKAY) 02132 muInit = 1; 02133 02134 if (err == MP_OKAY) 02135 err = mp_montgomery_calc_normalization(&mu, modulus); 02136 02137 if (err == MP_OKAY) 02138 /* copy ones ... */ 02139 err = mp_mulmod(A->x, &mu, modulus, precomp[1]->x); 02140 02141 if (err == MP_OKAY) 02142 err = mp_mulmod(A->y, &mu, modulus, precomp[1]->y); 02143 if (err == MP_OKAY) 02144 err = mp_mulmod(A->z, &mu, modulus, precomp[1]->z); 02145 02146 if (err == MP_OKAY) 02147 err = mp_mulmod(B->x, &mu, modulus, precomp[1<<2]->x); 02148 if (err == MP_OKAY) 02149 err = mp_mulmod(B->y, &mu, modulus, precomp[1<<2]->y); 02150 if (err == MP_OKAY) 02151 err = mp_mulmod(B->z, &mu, modulus, precomp[1<<2]->z); 02152 02153 if (err == MP_OKAY) 02154 /* precomp [i,0](A + B) table */ 02155 err = ecc_projective_dbl_point(precomp[1], precomp[2], modulus, &mp); 02156 02157 if (err == MP_OKAY) 02158 err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3], 02159 modulus, &mp); 02160 if (err == MP_OKAY) 02161 /* precomp [0,i](A + B) table */ 02162 err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], modulus, &mp); 02163 02164 if (err == MP_OKAY) 02165 err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2], 02166 modulus, &mp); 02167 02168 if (err == MP_OKAY) { 02169 /* precomp [i,j](A + B) table (i != 0, j != 0) */ 02170 for (x = 1; x < 4; x++) { 02171 for (y = 1; y < 4; y++) { 02172 if (err == MP_OKAY) 02173 err = ecc_projective_add_point(precomp[x], precomp[(y<<2)], 02174 precomp[x+(y<<2)], modulus, &mp); 02175 } 02176 } 02177 } 02178 02179 if (err == MP_OKAY) { 02180 nibble = 3; 02181 first = 1; 02182 bitbufA = tA[0]; 02183 bitbufB = tB[0]; 02184 02185 /* for every byte of the multiplicands */ 02186 for (x = (unsigned)-1;; ) { 02187 /* grab a nibble */ 02188 if (++nibble == 4) { 02189 ++x; if (x == len) break; 02190 bitbufA = tA[x]; 02191 bitbufB = tB[x]; 02192 nibble = 0; 02193 } 02194 02195 /* extract two bits from both, shift/update */ 02196 nA = (bitbufA >> 6) & 0x03; 02197 nB = (bitbufB >> 6) & 0x03; 02198 bitbufA = (bitbufA << 2) & 0xFF; 02199 bitbufB = (bitbufB << 2) & 0xFF; 02200 02201 /* if both zero, if first, continue */ 02202 if ((nA == 0) && (nB == 0) && (first == 1)) { 02203 continue; 02204 } 02205 02206 /* double twice, only if this isn't the first */ 02207 if (first == 0) { 02208 /* double twice */ 02209 if (err == MP_OKAY) 02210 err = ecc_projective_dbl_point(C, C, modulus, &mp); 02211 if (err == MP_OKAY) 02212 err = ecc_projective_dbl_point(C, C, modulus, &mp); 02213 else 02214 break; 02215 } 02216 02217 /* if not both zero */ 02218 if ((nA != 0) || (nB != 0)) { 02219 if (first == 1) { 02220 /* if first, copy from table */ 02221 first = 0; 02222 if (err == MP_OKAY) 02223 err = mp_copy(precomp[nA + (nB<<2)]->x, C->x); 02224 02225 if (err == MP_OKAY) 02226 err = mp_copy(precomp[nA + (nB<<2)]->y, C->y); 02227 02228 if (err == MP_OKAY) 02229 err = mp_copy(precomp[nA + (nB<<2)]->z, C->z); 02230 else 02231 break; 02232 } else { 02233 /* if not first, add from table */ 02234 if (err == MP_OKAY) 02235 err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C, 02236 modulus, &mp); 02237 else 02238 break; 02239 } 02240 } 02241 } 02242 } 02243 02244 if (err == MP_OKAY) 02245 /* reduce to affine */ 02246 err = ecc_map(C, modulus, &mp); 02247 02248 /* clean up */ 02249 if (muInit) 02250 mp_clear(&mu); 02251 02252 if (tableInit) { 02253 for (x = 0; x < 16; x++) { 02254 wc_ecc_del_point(precomp[x]); 02255 } 02256 } 02257 ForceZero(tA, ECC_BUFSIZE); 02258 ForceZero(tB, ECC_BUFSIZE); 02259 XFREE(tA, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02260 XFREE(tB, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02261 02262 return err; 02263 } 02264 02265 02266 #endif /* ECC_SHAMIR */ 02267 02268 02269 #ifdef HAVE_ECC_VERIFY 02270 #ifndef NO_ASN 02271 /* verify 02272 * 02273 * w = s^-1 mod n 02274 * u1 = xw 02275 * u2 = rw 02276 * X = u1*G + u2*Q 02277 * v = X_x1 mod n 02278 * accept if v == r 02279 */ 02280 02281 /** 02282 Verify an ECC signature 02283 sig The signature to verify 02284 siglen The length of the signature (octets) 02285 hash The hash (message digest) that was signed 02286 hashlen The length of the hash (octets) 02287 stat Result of signature, 1==valid, 0==invalid 02288 key The corresponding public ECC key 02289 return MP_OKAY if successful (even if the signature is not valid) 02290 */ 02291 int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, 02292 word32 hashlen, int* stat, ecc_key* key) 02293 { 02294 mp_int r; 02295 mp_int s; 02296 int err; 02297 02298 if (sig == NULL || hash == NULL || stat == NULL || key == NULL) 02299 return ECC_BAD_ARG_E; 02300 02301 /* default to invalid signature */ 02302 *stat = 0; 02303 02304 /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s. 02305 * If either of those don't allocate correctly, none of 02306 * the rest of this function will execute, and everything 02307 * gets cleaned up at the end. */ 02308 XMEMSET(&r, 0, sizeof(r)); 02309 XMEMSET(&s, 0, sizeof(s)); 02310 02311 err = DecodeECC_DSA_Sig(sig, siglen, &r, &s); 02312 02313 if (err == MP_OKAY) 02314 err = wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, stat, key); 02315 02316 mp_clear(&r); 02317 mp_clear(&s); 02318 02319 return err; 02320 } 02321 #endif /* !NO_ASN */ 02322 02323 /** 02324 Verify an ECC signature 02325 r The signature R component to verify 02326 s The signature S component to verify 02327 hash The hash (message digest) that was signed 02328 hashlen The length of the hash (octets) 02329 stat Result of signature, 1==valid, 0==invalid 02330 key The corresponding public ECC key 02331 return MP_OKAY if successful (even if the signature is not valid) 02332 */ 02333 int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, 02334 word32 hashlen, int* stat, ecc_key* key) 02335 { 02336 ecc_point *mG, *mQ; 02337 mp_int v; 02338 mp_int w; 02339 mp_int u1; 02340 mp_int u2; 02341 mp_int e; 02342 mp_int p; 02343 mp_int m; 02344 int err; 02345 02346 if (r == NULL || s == NULL || hash == NULL || stat == NULL || key == NULL) 02347 return ECC_BAD_ARG_E; 02348 02349 /* default to invalid signature */ 02350 *stat = 0; 02351 02352 /* is the IDX valid ? */ 02353 if (wc_ecc_is_valid_idx(key->idx) != 1) { 02354 return ECC_BAD_ARG_E; 02355 } 02356 02357 /* allocate ints */ 02358 if ((err = mp_init_multi(&v, &w, &u1, &u2, &p, &e)) != MP_OKAY) { 02359 return MEMORY_E; 02360 } 02361 02362 if ((err = mp_init(&m)) != MP_OKAY) { 02363 mp_clear(&v); 02364 mp_clear(&w); 02365 mp_clear(&u1); 02366 mp_clear(&u2); 02367 mp_clear(&p); 02368 mp_clear(&e); 02369 return MEMORY_E; 02370 } 02371 02372 /* allocate points */ 02373 mG = wc_ecc_new_point(); 02374 mQ = wc_ecc_new_point(); 02375 if (mQ == NULL || mG == NULL) 02376 err = MEMORY_E; 02377 02378 /* get the order */ 02379 if (err == MP_OKAY) 02380 err = mp_read_radix(&p, (char *)key->dp->order, 16); 02381 02382 /* get the modulus */ 02383 if (err == MP_OKAY) 02384 err = mp_read_radix(&m, (char *)key->dp->prime, 16); 02385 02386 /* check for zero */ 02387 if (err == MP_OKAY) { 02388 if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, &p) != MP_LT || 02389 mp_cmp(s, &p) != MP_LT) 02390 err = MP_ZERO_E; 02391 } 02392 /* read hash */ 02393 if (err == MP_OKAY) { 02394 /* we may need to truncate if hash is longer than key size */ 02395 unsigned int orderBits = mp_count_bits(&p); 02396 02397 /* truncate down to byte size, may be all that's needed */ 02398 if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits) 02399 hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1)/WOLFSSL_BIT_SIZE; 02400 err = mp_read_unsigned_bin(&e, hash, hashlen); 02401 02402 /* may still need bit truncation too */ 02403 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits) 02404 mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); 02405 } 02406 02407 /* w = s^-1 mod n */ 02408 if (err == MP_OKAY) 02409 err = mp_invmod(s, &p, &w); 02410 02411 /* u1 = ew */ 02412 if (err == MP_OKAY) 02413 err = mp_mulmod(&e, &w, &p, &u1); 02414 02415 /* u2 = rw */ 02416 if (err == MP_OKAY) 02417 err = mp_mulmod(r, &w, &p, &u2); 02418 02419 /* find mG and mQ */ 02420 if (err == MP_OKAY) 02421 err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16); 02422 02423 if (err == MP_OKAY) 02424 err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16); 02425 if (err == MP_OKAY) 02426 mp_set(mG->z, 1); 02427 02428 if (err == MP_OKAY) 02429 err = mp_copy(key->pubkey.x, mQ->x); 02430 if (err == MP_OKAY) 02431 err = mp_copy(key->pubkey.y, mQ->y); 02432 if (err == MP_OKAY) 02433 err = mp_copy(key->pubkey.z, mQ->z); 02434 02435 #ifndef ECC_SHAMIR 02436 { 02437 mp_digit mp; 02438 02439 /* compute u1*mG + u2*mQ = mG */ 02440 if (err == MP_OKAY) 02441 err = wc_ecc_mulmod(&u1, mG, mG, &m, 0); 02442 if (err == MP_OKAY) 02443 err = wc_ecc_mulmod(&u2, mQ, mQ, &m, 0); 02444 02445 /* find the montgomery mp */ 02446 if (err == MP_OKAY) 02447 err = mp_montgomery_setup(&m, &mp); 02448 02449 /* add them */ 02450 if (err == MP_OKAY) 02451 err = ecc_projective_add_point(mQ, mG, mG, &m, &mp); 02452 02453 /* reduce */ 02454 if (err == MP_OKAY) 02455 err = ecc_map(mG, &m, &mp); 02456 } 02457 #else 02458 /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */ 02459 if (err == MP_OKAY) 02460 err = ecc_mul2add(mG, &u1, mQ, &u2, mG, &m); 02461 #endif /* ECC_SHAMIR */ 02462 02463 /* v = X_x1 mod n */ 02464 if (err == MP_OKAY) 02465 err = mp_mod(mG->x, &p, &v); 02466 02467 /* does v == r */ 02468 if (err == MP_OKAY) { 02469 if (mp_cmp(&v, r) == MP_EQ) 02470 *stat = 1; 02471 } 02472 02473 wc_ecc_del_point(mG); 02474 wc_ecc_del_point(mQ); 02475 02476 mp_clear(&v); 02477 mp_clear(&w); 02478 mp_clear(&u1); 02479 mp_clear(&u2); 02480 mp_clear(&p); 02481 mp_clear(&e); 02482 mp_clear(&m); 02483 02484 return err; 02485 } 02486 #endif /* HAVE_ECC_VERIFY */ 02487 02488 #ifdef HAVE_ECC_KEY_IMPORT 02489 /* import point from der */ 02490 int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, 02491 ecc_point* point) 02492 { 02493 int err = 0; 02494 int compressed = 0; 02495 02496 if (in == NULL || point == NULL || (curve_idx < 0) || 02497 (wc_ecc_is_valid_idx(curve_idx) == 0)) 02498 return ECC_BAD_ARG_E; 02499 02500 /* must be odd */ 02501 if ((inLen & 1) == 0) { 02502 return ECC_BAD_ARG_E; 02503 } 02504 02505 /* init point */ 02506 #ifdef ALT_ECC_SIZE 02507 point->x = (mp_int*)&point->xyz[0]; 02508 point->y = (mp_int*)&point->xyz[1]; 02509 point->z = (mp_int*)&point->xyz[2]; 02510 alt_fp_init(point->x); 02511 alt_fp_init(point->y); 02512 alt_fp_init(point->z); 02513 #else 02514 err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL); 02515 #endif 02516 if (err != MP_OKAY) 02517 return MEMORY_E; 02518 02519 /* check for 4, 2, or 3 */ 02520 if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) { 02521 err = ASN_PARSE_E; 02522 } 02523 02524 if (in[0] == 0x02 || in[0] == 0x03) { 02525 #ifdef HAVE_COMP_KEY 02526 compressed = 1; 02527 #else 02528 err = NOT_COMPILED_IN; 02529 #endif 02530 } 02531 02532 /* read data */ 02533 if (err == MP_OKAY) 02534 err = mp_read_unsigned_bin(point->x, (byte*)in+1, (inLen-1)>>1); 02535 02536 #ifdef HAVE_COMP_KEY 02537 if (err == MP_OKAY && compressed == 1) { /* build y */ 02538 mp_int t1, t2, prime, a, b; 02539 02540 if (mp_init_multi(&t1, &t2, &prime, &a, &b, NULL) != MP_OKAY) 02541 err = MEMORY_E; 02542 02543 /* load prime */ 02544 if (err == MP_OKAY) 02545 err = mp_read_radix(&prime, (char *)ecc_sets[curve_idx].prime, 16); 02546 02547 /* load a */ 02548 if (err == MP_OKAY) 02549 err = mp_read_radix(&a, (char *)ecc_sets[curve_idx].Af, 16); 02550 02551 /* load b */ 02552 if (err == MP_OKAY) 02553 err = mp_read_radix(&b, (char *)ecc_sets[curve_idx].Bf, 16); 02554 02555 /* compute x^3 */ 02556 if (err == MP_OKAY) 02557 err = mp_sqr(point->x, &t1); 02558 02559 if (err == MP_OKAY) 02560 err = mp_mulmod(&t1, point->x, &prime, &t1); 02561 02562 /* compute x^3 + a*x */ 02563 if (err == MP_OKAY) 02564 err = mp_mulmod(&a, point->x, &prime, &t2); 02565 02566 if (err == MP_OKAY) 02567 err = mp_add(&t1, &t2, &t1); 02568 02569 /* compute x^3 + a*x + b */ 02570 if (err == MP_OKAY) 02571 err = mp_add(&t1, &b, &t1); 02572 02573 /* compute sqrt(x^3 + a*x + b) */ 02574 if (err == MP_OKAY) 02575 err = mp_sqrtmod_prime(&t1, &prime, &t2); 02576 02577 /* adjust y */ 02578 if (err == MP_OKAY) { 02579 if ((mp_isodd(&t2) && in[0] == 0x03) || 02580 (!mp_isodd(&t2) && in[0] == 0x02)) { 02581 err = mp_mod(&t2, &prime, point->y); 02582 } 02583 else { 02584 err = mp_submod(&prime, &t2, &prime, point->y); 02585 } 02586 } 02587 02588 mp_clear(&a); 02589 mp_clear(&b); 02590 mp_clear(&prime); 02591 mp_clear(&t2); 02592 mp_clear(&t1); 02593 } 02594 #endif 02595 02596 if (err == MP_OKAY && compressed == 0) 02597 err = mp_read_unsigned_bin(point->y, 02598 (byte*)in+1+((inLen-1)>>1), (inLen-1)>>1); 02599 if (err == MP_OKAY) 02600 mp_set(point->z, 1); 02601 02602 if (err != MP_OKAY) { 02603 mp_clear(point->x); 02604 mp_clear(point->y); 02605 mp_clear(point->z); 02606 } 02607 02608 return err; 02609 } 02610 #endif /* HAVE_ECC_KEY_IMPORT */ 02611 02612 #ifdef HAVE_ECC_KEY_EXPORT 02613 /* export point to der */ 02614 int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out, 02615 word32* outLen) 02616 { 02617 #ifdef WOLFSSL_SMALL_STACK 02618 byte* buf; 02619 #else 02620 byte buf[ECC_BUFSIZE]; 02621 #endif 02622 word32 numlen; 02623 int ret = MP_OKAY; 02624 02625 if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0)) 02626 return ECC_BAD_ARG_E; 02627 02628 /* return length needed only */ 02629 if (point != NULL && out == NULL && outLen != NULL) { 02630 numlen = ecc_sets[curve_idx].size; 02631 *outLen = 1 + 2*numlen; 02632 return LENGTH_ONLY_E; 02633 } 02634 02635 if (point == NULL || out == NULL || outLen == NULL) 02636 return ECC_BAD_ARG_E; 02637 02638 numlen = ecc_sets[curve_idx].size; 02639 02640 if (*outLen < (1 + 2*numlen)) { 02641 *outLen = 1 + 2*numlen; 02642 return BUFFER_E; 02643 } 02644 02645 /* store byte 0x04 */ 02646 out[0] = 0x04; 02647 02648 #ifdef WOLFSSL_SMALL_STACK 02649 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02650 if (buf == NULL) 02651 return MEMORY_E; 02652 #endif 02653 02654 /* pad and store x */ 02655 XMEMSET(buf, 0, ECC_BUFSIZE); 02656 ret = mp_to_unsigned_bin(point->x, buf + 02657 (numlen - mp_unsigned_bin_size(point->x))); 02658 if (ret != MP_OKAY) 02659 goto done; 02660 XMEMCPY(out+1, buf, numlen); 02661 02662 /* pad and store y */ 02663 XMEMSET(buf, 0, ECC_BUFSIZE); 02664 ret = mp_to_unsigned_bin(point->y, buf + 02665 (numlen - mp_unsigned_bin_size(point->y))); 02666 if (ret != MP_OKAY) 02667 goto done; 02668 XMEMCPY(out+1+numlen, buf, numlen); 02669 02670 *outLen = 1 + 2*numlen; 02671 02672 done: 02673 #ifdef WOLFSSL_SMALL_STACK 02674 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02675 #endif 02676 02677 return ret; 02678 } 02679 02680 02681 /* export public ECC key in ANSI X9.63 format */ 02682 int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) 02683 { 02684 #ifdef WOLFSSL_SMALL_STACK 02685 byte* buf; 02686 #else 02687 byte buf[ECC_BUFSIZE]; 02688 #endif 02689 word32 numlen; 02690 int ret = MP_OKAY; 02691 02692 /* return length needed only */ 02693 if (key != NULL && out == NULL && outLen != NULL) { 02694 numlen = key->dp->size; 02695 *outLen = 1 + 2*numlen; 02696 return LENGTH_ONLY_E; 02697 } 02698 02699 if (key == NULL || out == NULL || outLen == NULL) 02700 return ECC_BAD_ARG_E; 02701 02702 if (wc_ecc_is_valid_idx(key->idx) == 0) { 02703 return ECC_BAD_ARG_E; 02704 } 02705 numlen = key->dp->size; 02706 02707 if (*outLen < (1 + 2*numlen)) { 02708 *outLen = 1 + 2*numlen; 02709 return BUFFER_E; 02710 } 02711 02712 /* store byte 0x04 */ 02713 out[0] = 0x04; 02714 02715 #ifdef WOLFSSL_SMALL_STACK 02716 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02717 if (buf == NULL) 02718 return MEMORY_E; 02719 #endif 02720 02721 /* pad and store x */ 02722 XMEMSET(buf, 0, ECC_BUFSIZE); 02723 ret = mp_to_unsigned_bin(key->pubkey.x, 02724 buf + (numlen - mp_unsigned_bin_size(key->pubkey.x))); 02725 if (ret != MP_OKAY) 02726 goto done; 02727 XMEMCPY(out+1, buf, numlen); 02728 02729 /* pad and store y */ 02730 XMEMSET(buf, 0, ECC_BUFSIZE); 02731 ret = mp_to_unsigned_bin(key->pubkey.y, 02732 buf + (numlen - mp_unsigned_bin_size(key->pubkey.y))); 02733 if (ret != MP_OKAY) 02734 goto done; 02735 XMEMCPY(out+1+numlen, buf, numlen); 02736 02737 *outLen = 1 + 2*numlen; 02738 02739 done: 02740 #ifdef WOLFSSL_SMALL_STACK 02741 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); 02742 #endif 02743 02744 return ret; 02745 } 02746 02747 02748 /* export public ECC key in ANSI X9.63 format, extended with 02749 * compression option */ 02750 int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, 02751 int compressed) 02752 { 02753 if (compressed == 0) 02754 return wc_ecc_export_x963(key, out, outLen); 02755 #ifdef HAVE_COMP_KEY 02756 else 02757 return wc_ecc_export_x963_compressed(key, out, outLen); 02758 #endif 02759 02760 return NOT_COMPILED_IN; 02761 } 02762 #endif /* HAVE_ECC_KEY_EXPORT */ 02763 02764 /* is ec point on curve described by dp ? */ 02765 static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime) 02766 { 02767 mp_int b, t1, t2; 02768 int err; 02769 02770 if ((err = mp_init_multi(&b, &t1, &t2, NULL, NULL, NULL)) != MP_OKAY) { 02771 return err; 02772 } 02773 02774 /* load b */ 02775 err = mp_read_radix(&b, dp->Bf, 16); 02776 02777 /* compute y^2 */ 02778 if (err == MP_OKAY) 02779 err = mp_sqr(ecp->y, &t1); 02780 02781 /* compute x^3 */ 02782 if (err == MP_OKAY) 02783 err = mp_sqr(ecp->x, &t2); 02784 if (err == MP_OKAY) 02785 err = mp_mod(&t2, prime, &t2); 02786 if (err == MP_OKAY) 02787 err = mp_mul(ecp->x, &t2, &t2); 02788 02789 /* compute y^2 - x^3 */ 02790 if (err == MP_OKAY) 02791 err = mp_sub(&t1, &t2, &t1); 02792 02793 /* compute y^2 - x^3 + 3x */ 02794 if (err == MP_OKAY) 02795 err = mp_add(&t1, ecp->x, &t1); 02796 if (err == MP_OKAY) 02797 err = mp_add(&t1, ecp->x, &t1); 02798 if (err == MP_OKAY) 02799 err = mp_add(&t1, ecp->x, &t1); 02800 if (err == MP_OKAY) 02801 err = mp_mod(&t1, prime, &t1); 02802 02803 while (err == MP_OKAY && mp_cmp_d(&t1, 0) == MP_LT) { 02804 err = mp_add(&t1, prime, &t1); 02805 } 02806 while (err == MP_OKAY && mp_cmp(&t1, prime) != MP_LT) { 02807 err = mp_sub(&t1, prime, &t1); 02808 } 02809 02810 /* compare to b */ 02811 if (err == MP_OKAY) { 02812 if (mp_cmp(&t1, &b) != MP_EQ) { 02813 err = MP_VAL; 02814 } else { 02815 err = MP_OKAY; 02816 } 02817 } 02818 02819 mp_clear(&b); 02820 mp_clear(&t1); 02821 mp_clear(&t2); 02822 02823 return err; 02824 } 02825 02826 02827 /* validate privkey * generator == pubkey, 0 on success */ 02828 static int ecc_check_privkey_gen(ecc_key* key, mp_int* prime) 02829 { 02830 ecc_point* base = NULL; 02831 ecc_point* res = NULL; 02832 int err; 02833 02834 if (key == NULL) 02835 return BAD_FUNC_ARG; 02836 02837 base = wc_ecc_new_point(); 02838 if (base == NULL) 02839 return MEMORY_E; 02840 02841 /* set up base generator */ 02842 err = mp_read_radix(base->x, (char*)key->dp->Gx, 16); 02843 if (err == MP_OKAY) 02844 err = mp_read_radix(base->y, (char*)key->dp->Gy, 16); 02845 if (err == MP_OKAY) 02846 mp_set(base->z, 1); 02847 02848 if (err == MP_OKAY) { 02849 res = wc_ecc_new_point(); 02850 if (res == NULL) 02851 err = MEMORY_E; 02852 else { 02853 err = wc_ecc_mulmod(&key->k, base, res, prime, 1); 02854 if (err == MP_OKAY) { 02855 /* compare result to public key */ 02856 if (mp_cmp(res->x, key->pubkey.x) != MP_EQ || 02857 mp_cmp(res->y, key->pubkey.y) != MP_EQ || 02858 mp_cmp(res->z, key->pubkey.z) != MP_EQ) { 02859 /* didn't match */ 02860 err = ECC_PRIV_KEY_E; 02861 } 02862 } 02863 } 02864 } 02865 02866 wc_ecc_del_point(res); 02867 wc_ecc_del_point(base); 02868 02869 return err; 02870 } 02871 02872 02873 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 02874 02875 /* check privkey generator helper, creates prime needed */ 02876 static int ecc_check_privkey_gen_helper(ecc_key* key) 02877 { 02878 mp_int prime; 02879 int err; 02880 02881 if (key == NULL) 02882 return BAD_FUNC_ARG; 02883 02884 err = mp_init(&prime); 02885 if (err != MP_OKAY) 02886 return err; 02887 02888 err = mp_read_radix(&prime, (char*)key->dp->prime, 16); 02889 02890 if (err == MP_OKAY); 02891 err = ecc_check_privkey_gen(key, &prime); 02892 02893 mp_clear(&prime); 02894 02895 return err; 02896 } 02897 02898 #endif /* WOLFSSL_VALIDATE_ECC_IMPORT */ 02899 02900 02901 /* validate order * pubkey = point at infinity, 0 on success */ 02902 static int ecc_check_pubkey_order(ecc_key* key, mp_int* prime, mp_int* order) 02903 { 02904 ecc_point* inf = NULL; 02905 int err; 02906 02907 if (key == NULL) 02908 return BAD_FUNC_ARG; 02909 02910 inf = wc_ecc_new_point(); 02911 if (inf == NULL) 02912 err = MEMORY_E; 02913 else { 02914 err = wc_ecc_mulmod(order, &key->pubkey, inf, prime, 1); 02915 if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf)) 02916 err = ECC_INF_E; 02917 } 02918 02919 wc_ecc_del_point(inf); 02920 02921 return err; 02922 } 02923 02924 02925 /* perform sanity checks on ec key validity, 0 on success */ 02926 int wc_ecc_check_key(ecc_key* key) 02927 { 02928 mp_int prime; /* used by multiple calls so let's cache */ 02929 mp_int order; /* other callers have, so let's gen here */ 02930 int err; 02931 02932 if (key == NULL) 02933 return BAD_FUNC_ARG; 02934 02935 /* pubkey point cannot be at infinity */ 02936 if (wc_ecc_point_is_at_infinity(&key->pubkey)) 02937 return ECC_INF_E; 02938 02939 err = mp_init_multi(&prime, &order, NULL, NULL, NULL, NULL); 02940 if (err != MP_OKAY) 02941 return err; 02942 02943 err = mp_read_radix(&prime, (char*)key->dp->prime, 16); 02944 02945 /* make sure point is actually on curve */ 02946 if (err == MP_OKAY) 02947 err = ecc_is_point(key->dp, &key->pubkey, &prime); 02948 02949 if (err == MP_OKAY) 02950 err = mp_read_radix(&order, (char*)key->dp->order, 16); 02951 02952 /* pubkey * order must be at infinity */ 02953 if (err == MP_OKAY) 02954 err = ecc_check_pubkey_order(key, &prime, &order); 02955 02956 /* private * base generator must equal pubkey */ 02957 if (err == MP_OKAY && key->type == ECC_PRIVATEKEY) 02958 err = ecc_check_privkey_gen(key, &prime); 02959 02960 mp_clear(&order); 02961 mp_clear(&prime); 02962 02963 return err; 02964 } 02965 02966 #ifdef HAVE_ECC_KEY_IMPORT 02967 /* import public ECC key in ANSI X9.63 format */ 02968 int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) 02969 { 02970 int x, err; 02971 int compressed = 0; 02972 02973 if (in == NULL || key == NULL) 02974 return ECC_BAD_ARG_E; 02975 02976 /* must be odd */ 02977 if ((inLen & 1) == 0) { 02978 return ECC_BAD_ARG_E; 02979 } 02980 02981 /* init key */ 02982 #ifdef ALT_ECC_SIZE 02983 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 02984 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 02985 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 02986 alt_fp_init(key->pubkey.x); 02987 alt_fp_init(key->pubkey.y); 02988 alt_fp_init(key->pubkey.z); 02989 err = mp_init(&key->k); 02990 #else 02991 err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k, 02992 NULL, NULL); 02993 #endif 02994 if (err != MP_OKAY) 02995 return MEMORY_E; 02996 02997 /* check for 4, 2, or 3 */ 02998 if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) { 02999 err = ASN_PARSE_E; 03000 } 03001 03002 if (in[0] == 0x02 || in[0] == 0x03) { 03003 #ifdef HAVE_COMP_KEY 03004 compressed = 1; 03005 #else 03006 err = NOT_COMPILED_IN; 03007 #endif 03008 } 03009 03010 if (err == MP_OKAY) { 03011 /* determine the idx */ 03012 03013 if (compressed) 03014 inLen = (inLen-1)*2 + 1; /* used uncompressed len */ 03015 03016 for (x = 0; ecc_sets[x].size != 0; x++) { 03017 if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) { 03018 break; 03019 } 03020 } 03021 if (ecc_sets[x].size == 0) { 03022 WOLFSSL_MSG("ecc_set size not found"); 03023 err = ASN_PARSE_E; 03024 } else { 03025 /* set the idx */ 03026 key->idx = x; 03027 key->dp = &ecc_sets[x]; 03028 key->type = ECC_PUBLICKEY; 03029 } 03030 } 03031 03032 /* read data */ 03033 if (err == MP_OKAY) 03034 err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in+1, (inLen-1)>>1); 03035 03036 #ifdef HAVE_COMP_KEY 03037 if (err == MP_OKAY && compressed == 1) { /* build y */ 03038 mp_int t1, t2, prime, a, b; 03039 03040 if (mp_init_multi(&t1, &t2, &prime, &a, &b, NULL) != MP_OKAY) 03041 err = MEMORY_E; 03042 03043 /* load prime */ 03044 if (err == MP_OKAY) 03045 err = mp_read_radix(&prime, (char *)key->dp->prime, 16); 03046 03047 /* load a */ 03048 if (err == MP_OKAY) 03049 err = mp_read_radix(&a, (char *)key->dp->Af, 16); 03050 03051 /* load b */ 03052 if (err == MP_OKAY) 03053 err = mp_read_radix(&b, (char *)key->dp->Bf, 16); 03054 03055 /* compute x^3 */ 03056 if (err == MP_OKAY) 03057 err = mp_sqr(key->pubkey.x, &t1); 03058 03059 if (err == MP_OKAY) 03060 err = mp_mulmod(&t1, key->pubkey.x, &prime, &t1); 03061 03062 /* compute x^3 + a*x */ 03063 if (err == MP_OKAY) 03064 err = mp_mulmod(&a, key->pubkey.x, &prime, &t2); 03065 03066 if (err == MP_OKAY) 03067 err = mp_add(&t1, &t2, &t1); 03068 03069 /* compute x^3 + a*x + b */ 03070 if (err == MP_OKAY) 03071 err = mp_add(&t1, &b, &t1); 03072 03073 /* compute sqrt(x^3 + a*x + b) */ 03074 if (err == MP_OKAY) 03075 err = mp_sqrtmod_prime(&t1, &prime, &t2); 03076 03077 /* adjust y */ 03078 if (err == MP_OKAY) { 03079 if ((mp_isodd(&t2) && in[0] == 0x03) || 03080 (!mp_isodd(&t2) && in[0] == 0x02)) { 03081 err = mp_mod(&t2, &prime, key->pubkey.y); 03082 } 03083 else { 03084 err = mp_submod(&prime, &t2, &prime, key->pubkey.y); 03085 } 03086 } 03087 03088 mp_clear(&a); 03089 mp_clear(&b); 03090 mp_clear(&prime); 03091 mp_clear(&t2); 03092 mp_clear(&t1); 03093 } 03094 #endif 03095 03096 if (err == MP_OKAY && compressed == 0) 03097 err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in+1+((inLen-1)>>1), 03098 (inLen-1)>>1); 03099 if (err == MP_OKAY) 03100 mp_set(key->pubkey.z, 1); 03101 03102 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 03103 if (err == MP_OKAY) 03104 err = wc_ecc_check_key(key); 03105 #endif 03106 03107 if (err != MP_OKAY) { 03108 mp_clear(key->pubkey.x); 03109 mp_clear(key->pubkey.y); 03110 mp_clear(key->pubkey.z); 03111 mp_clear(&key->k); 03112 } 03113 03114 return err; 03115 } 03116 #endif /* HAVE_ECC_KEY_IMPORT */ 03117 03118 #ifdef HAVE_ECC_KEY_EXPORT 03119 /* export ecc private key only raw, outLen is in/out size 03120 return MP_OKAY on success */ 03121 int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen) 03122 { 03123 word32 numlen; 03124 03125 if (key == NULL || out == NULL || outLen == NULL) 03126 return ECC_BAD_ARG_E; 03127 03128 if (wc_ecc_is_valid_idx(key->idx) == 0) { 03129 return ECC_BAD_ARG_E; 03130 } 03131 numlen = key->dp->size; 03132 03133 if (*outLen < numlen) { 03134 *outLen = numlen; 03135 return BUFFER_E; 03136 } 03137 *outLen = numlen; 03138 XMEMSET(out, 0, *outLen); 03139 return mp_to_unsigned_bin(&key->k, out + (numlen - 03140 mp_unsigned_bin_size(&key->k))); 03141 } 03142 #endif /* HAVE_ECC_KEY_EXPORT */ 03143 03144 #ifdef HAVE_ECC_KEY_IMPORT 03145 /* ecc private key import, public key in ANSI X9.63 format, private raw */ 03146 int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, 03147 word32 pubSz, ecc_key* key) 03148 { 03149 int ret = wc_ecc_import_x963(pub, pubSz, key); 03150 if (ret != 0) 03151 return ret; 03152 03153 key->type = ECC_PRIVATEKEY; 03154 03155 ret = mp_read_unsigned_bin(&key->k, priv, privSz); 03156 03157 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 03158 if (ret == MP_OKAY) 03159 ret = ecc_check_privkey_gen_helper(key); 03160 #endif 03161 03162 return ret; 03163 } 03164 #endif /* HAVE_ECC_KEY_IMPORT */ 03165 03166 #ifndef NO_ASN 03167 /** 03168 Convert ECC R,S to signature 03169 r R component of signature 03170 s S component of signature 03171 out DER-encoded ECDSA signature 03172 outlen [in/out] output buffer size, output signature size 03173 return MP_OKAY on success 03174 */ 03175 int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen) 03176 { 03177 int err; 03178 mp_int rtmp; 03179 mp_int stmp; 03180 03181 if (r == NULL || s == NULL || out == NULL || outlen == NULL) 03182 return ECC_BAD_ARG_E; 03183 03184 err = mp_init_multi(&rtmp, &stmp, NULL, NULL, NULL, NULL); 03185 if (err != MP_OKAY) 03186 return err; 03187 03188 err = mp_read_radix(&rtmp, r, 16); 03189 if (err == MP_OKAY) 03190 err = mp_read_radix(&stmp, s, 16); 03191 03192 /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */ 03193 if (err == MP_OKAY) 03194 err = StoreECC_DSA_Sig(out, outlen, &rtmp, &stmp); 03195 03196 if (err == MP_OKAY) { 03197 if (mp_iszero(&rtmp) || mp_iszero(&stmp)) 03198 err = MP_ZERO_E; 03199 } 03200 03201 mp_clear(&rtmp); 03202 mp_clear(&stmp); 03203 03204 return err; 03205 } 03206 #endif /* !NO_ASN */ 03207 03208 #ifdef HAVE_ECC_KEY_IMPORT 03209 /** 03210 Import raw ECC key 03211 key The destination ecc_key structure 03212 qx x component of base point, as ASCII hex string 03213 qy y component of base point, as ASCII hex string 03214 d private key, as ASCII hex string 03215 curveName ECC curve name, from ecc_sets[] 03216 return MP_OKAY on success 03217 */ 03218 int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy, 03219 const char* d, const char* curveName) 03220 { 03221 int err, x; 03222 03223 if (key == NULL || qx == NULL || qy == NULL || d == NULL || 03224 curveName == NULL) 03225 return ECC_BAD_ARG_E; 03226 03227 /* init key */ 03228 #ifdef ALT_ECC_SIZE 03229 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 03230 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 03231 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 03232 alt_fp_init(key->pubkey.x); 03233 alt_fp_init(key->pubkey.y); 03234 alt_fp_init(key->pubkey.z); 03235 err = mp_init(&key->k); 03236 #else 03237 err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k, 03238 NULL, NULL); 03239 #endif 03240 if (err != MP_OKAY) 03241 return MEMORY_E; 03242 03243 /* read Qx */ 03244 if (err == MP_OKAY) 03245 err = mp_read_radix(key->pubkey.x, qx, 16); 03246 03247 /* read Qy */ 03248 if (err == MP_OKAY) 03249 err = mp_read_radix(key->pubkey.y, qy, 16); 03250 03251 if (err == MP_OKAY) 03252 mp_set(key->pubkey.z, 1); 03253 03254 /* read and set the curve */ 03255 if (err == MP_OKAY) { 03256 for (x = 0; ecc_sets[x].size != 0; x++) { 03257 if (XSTRNCMP(ecc_sets[x].name, curveName, 03258 XSTRLEN(curveName)) == 0) { 03259 break; 03260 } 03261 } 03262 if (ecc_sets[x].size == 0) { 03263 WOLFSSL_MSG("ecc_set curve name not found"); 03264 err = ASN_PARSE_E; 03265 } else { 03266 /* set the curve */ 03267 key->idx = x; 03268 key->dp = &ecc_sets[x]; 03269 key->type = ECC_PUBLICKEY; 03270 } 03271 } 03272 03273 /* import private key */ 03274 if (err == MP_OKAY) { 03275 key->type = ECC_PRIVATEKEY; 03276 err = mp_read_radix(&key->k, d, 16); 03277 } 03278 03279 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 03280 if (err == MP_OKAY) 03281 err = wc_ecc_check_key(key); 03282 #endif 03283 03284 if (err != MP_OKAY) { 03285 mp_clear(key->pubkey.x); 03286 mp_clear(key->pubkey.y); 03287 mp_clear(key->pubkey.z); 03288 mp_clear(&key->k); 03289 } 03290 03291 return err; 03292 } 03293 #endif /* HAVE_ECC_KEY_IMPORT */ 03294 03295 /* key size in octets */ 03296 int wc_ecc_size(ecc_key* key) 03297 { 03298 if (key == NULL) return 0; 03299 03300 return key->dp->size; 03301 } 03302 03303 03304 /* worst case estimate, check actual return from wc_ecc_sign_hash for actual 03305 value of signature size in octets */ 03306 int wc_ecc_sig_size(ecc_key* key) 03307 { 03308 int sz = wc_ecc_size(key); 03309 if (sz <= 0) 03310 return sz; 03311 03312 return (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ; 03313 } 03314 03315 03316 #ifdef FP_ECC 03317 03318 /* fixed point ECC cache */ 03319 /* number of entries in the cache */ 03320 #ifndef FP_ENTRIES 03321 #define FP_ENTRIES 16 03322 #endif 03323 03324 /* number of bits in LUT */ 03325 #ifndef FP_LUT 03326 #define FP_LUT 8U 03327 #endif 03328 03329 #ifdef ECC_SHAMIR 03330 /* Sharmir requires a bigger LUT, TAO */ 03331 #if (FP_LUT > 12) || (FP_LUT < 4) 03332 #error FP_LUT must be between 4 and 12 inclusively 03333 #endif 03334 #else 03335 #if (FP_LUT > 12) || (FP_LUT < 2) 03336 #error FP_LUT must be between 2 and 12 inclusively 03337 #endif 03338 #endif 03339 03340 03341 /** Our FP cache */ 03342 typedef struct { 03343 ecc_point* g; /* cached COPY of base point */ 03344 ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */ 03345 mp_int mu; /* copy of the montgomery constant */ 03346 int lru_count; /* amount of times this entry has been used */ 03347 int lock; /* flag to indicate cache eviction */ 03348 /* permitted (0) or not (1) */ 03349 } fp_cache_t; 03350 03351 /* if HAVE_THREAD_LS this cache is per thread, no locking needed */ 03352 static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES]; 03353 03354 #ifndef HAVE_THREAD_LS 03355 static volatile int initMutex = 0; /* prevent multiple mutex inits */ 03356 static wolfSSL_Mutex ecc_fp_lock; 03357 #endif /* HAVE_THREAD_LS */ 03358 03359 /* simple table to help direct the generation of the LUT */ 03360 static const struct { 03361 int ham, terma, termb; 03362 } lut_orders[] = { 03363 { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 }, 03364 { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 }, 03365 { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 }, 03366 { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 }, 03367 { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 }, 03368 { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 }, 03369 { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 }, 03370 { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 }, 03371 #if FP_LUT > 6 03372 { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 }, 03373 { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 }, 03374 { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 }, 03375 { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 }, 03376 { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 }, 03377 { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 }, 03378 { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 }, 03379 { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 }, 03380 #if FP_LUT > 7 03381 { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 }, 03382 { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 }, 03383 { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 }, 03384 { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 }, 03385 { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 }, 03386 { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 }, 03387 { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 }, 03388 { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 }, 03389 { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 }, 03390 { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 }, 03391 { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 }, 03392 { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 }, 03393 { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 }, 03394 { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 }, 03395 { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 }, 03396 { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 }, 03397 #if FP_LUT > 8 03398 { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 }, 03399 { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 }, 03400 { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 }, 03401 { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 }, 03402 { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 }, 03403 { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 }, 03404 { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 }, 03405 { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 }, 03406 { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 }, 03407 { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 }, 03408 { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 }, 03409 { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 }, 03410 { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 }, 03411 { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 }, 03412 { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 }, 03413 { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 }, 03414 { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 }, 03415 { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 }, 03416 { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 }, 03417 { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 }, 03418 { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 }, 03419 { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 }, 03420 { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 }, 03421 { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 }, 03422 { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 }, 03423 { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 }, 03424 { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 }, 03425 { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 }, 03426 { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 }, 03427 { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 }, 03428 { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 }, 03429 { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 }, 03430 #if FP_LUT > 9 03431 { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 }, 03432 { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 }, 03433 { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 }, 03434 { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 }, 03435 { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 }, 03436 { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 }, 03437 { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 }, 03438 { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 }, 03439 { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 }, 03440 { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 }, 03441 { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 }, 03442 { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 }, 03443 { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 }, 03444 { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 }, 03445 { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 }, 03446 { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 }, 03447 { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 }, 03448 { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 }, 03449 { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 }, 03450 { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 }, 03451 { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 }, 03452 { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 }, 03453 { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 }, 03454 { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 }, 03455 { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 }, 03456 { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 }, 03457 { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 }, 03458 { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 }, 03459 { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 }, 03460 { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 }, 03461 { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 }, 03462 { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 }, 03463 { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 }, 03464 { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 }, 03465 { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 }, 03466 { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 }, 03467 { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 }, 03468 { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 }, 03469 { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 }, 03470 { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 }, 03471 { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 }, 03472 { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 }, 03473 { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 }, 03474 { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 }, 03475 { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 }, 03476 { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 }, 03477 { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 }, 03478 { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 }, 03479 { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 }, 03480 { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 }, 03481 { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 }, 03482 { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 }, 03483 { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 }, 03484 { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 }, 03485 { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 }, 03486 { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 }, 03487 { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 }, 03488 { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 }, 03489 { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 }, 03490 { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 }, 03491 { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 }, 03492 { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 }, 03493 { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 }, 03494 { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 }, 03495 #if FP_LUT > 10 03496 { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 }, 03497 { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 }, 03498 { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 }, 03499 { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 }, 03500 { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 }, 03501 { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 }, 03502 { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 }, 03503 { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 }, 03504 { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 }, 03505 { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 }, 03506 { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 }, 03507 { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 }, 03508 { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 }, 03509 { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 }, 03510 { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 }, 03511 { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 }, 03512 { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 }, 03513 { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 }, 03514 { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 }, 03515 { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 }, 03516 { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 }, 03517 { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 }, 03518 { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 }, 03519 { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 }, 03520 { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 }, 03521 { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 }, 03522 { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 }, 03523 { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 }, 03524 { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 }, 03525 { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 }, 03526 { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 }, 03527 { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 }, 03528 { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 }, 03529 { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 }, 03530 { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 }, 03531 { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 }, 03532 { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 }, 03533 { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 }, 03534 { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 }, 03535 { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 }, 03536 { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 }, 03537 { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 }, 03538 { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 }, 03539 { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 }, 03540 { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 }, 03541 { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 }, 03542 { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 }, 03543 { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 }, 03544 { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 }, 03545 { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 }, 03546 { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 }, 03547 { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 }, 03548 { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 }, 03549 { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 }, 03550 { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 }, 03551 { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 }, 03552 { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 }, 03553 { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 }, 03554 { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 }, 03555 { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 }, 03556 { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 }, 03557 { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 }, 03558 { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 }, 03559 { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 }, 03560 { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 }, 03561 { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 }, 03562 { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 }, 03563 { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 }, 03564 { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 }, 03565 { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 }, 03566 { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 }, 03567 { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 }, 03568 { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 }, 03569 { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 }, 03570 { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 }, 03571 { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 }, 03572 { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 }, 03573 { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 }, 03574 { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 }, 03575 { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 }, 03576 { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 }, 03577 { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 }, 03578 { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 }, 03579 { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 }, 03580 { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 }, 03581 { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 }, 03582 { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 }, 03583 { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 }, 03584 { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 }, 03585 { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 }, 03586 { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 }, 03587 { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 }, 03588 { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 }, 03589 { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 }, 03590 { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 }, 03591 { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 }, 03592 { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 }, 03593 { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 }, 03594 { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 }, 03595 { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 }, 03596 { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 }, 03597 { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 }, 03598 { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 }, 03599 { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 }, 03600 { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 }, 03601 { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 }, 03602 { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 }, 03603 { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 }, 03604 { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 }, 03605 { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 }, 03606 { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 }, 03607 { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 }, 03608 { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 }, 03609 { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 }, 03610 { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 }, 03611 { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 }, 03612 { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 }, 03613 { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 }, 03614 { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 }, 03615 { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 }, 03616 { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 }, 03617 { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 }, 03618 { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 }, 03619 { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 }, 03620 { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 }, 03621 { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 }, 03622 { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 }, 03623 { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 }, 03624 #if FP_LUT > 11 03625 { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 }, 03626 { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 }, 03627 { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 }, 03628 { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 }, 03629 { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 }, 03630 { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 }, 03631 { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 }, 03632 { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 }, 03633 { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 }, 03634 { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 }, 03635 { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 }, 03636 { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 }, 03637 { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 }, 03638 { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 }, 03639 { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 }, 03640 { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 }, 03641 { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 }, 03642 { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 }, 03643 { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 }, 03644 { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 }, 03645 { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 }, 03646 { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 }, 03647 { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 }, 03648 { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 }, 03649 { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 }, 03650 { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 }, 03651 { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 }, 03652 { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 }, 03653 { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 }, 03654 { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 }, 03655 { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 }, 03656 { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 }, 03657 { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 }, 03658 { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 }, 03659 { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 }, 03660 { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 }, 03661 { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 }, 03662 { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 }, 03663 { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 }, 03664 { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 }, 03665 { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 }, 03666 { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 }, 03667 { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 }, 03668 { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 }, 03669 { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 }, 03670 { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 }, 03671 { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 }, 03672 { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 }, 03673 { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 }, 03674 { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 }, 03675 { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 }, 03676 { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 }, 03677 { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 }, 03678 { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 }, 03679 { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 }, 03680 { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 }, 03681 { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 }, 03682 { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 }, 03683 { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 }, 03684 { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 }, 03685 { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 }, 03686 { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 }, 03687 { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 }, 03688 { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 }, 03689 { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 }, 03690 { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 }, 03691 { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 }, 03692 { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 }, 03693 { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 }, 03694 { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 }, 03695 { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 }, 03696 { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 }, 03697 { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 }, 03698 { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 }, 03699 { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 }, 03700 { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 }, 03701 { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 }, 03702 { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 }, 03703 { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 }, 03704 { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 }, 03705 { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 }, 03706 { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 }, 03707 { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 }, 03708 { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 }, 03709 { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 }, 03710 { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 }, 03711 { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 }, 03712 { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 }, 03713 { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 }, 03714 { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 }, 03715 { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 }, 03716 { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 }, 03717 { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 }, 03718 { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 }, 03719 { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 }, 03720 { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 }, 03721 { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 }, 03722 { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 }, 03723 { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 }, 03724 { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 }, 03725 { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 }, 03726 { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 }, 03727 { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 }, 03728 { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 }, 03729 { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 }, 03730 { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 }, 03731 { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 }, 03732 { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 }, 03733 { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 }, 03734 { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 }, 03735 { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 }, 03736 { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 }, 03737 { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 }, 03738 { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 }, 03739 { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 }, 03740 { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 }, 03741 { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 }, 03742 { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 }, 03743 { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 }, 03744 { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 }, 03745 { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 }, 03746 { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 }, 03747 { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 }, 03748 { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 }, 03749 { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 }, 03750 { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 }, 03751 { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 }, 03752 { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 }, 03753 { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 }, 03754 { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 }, 03755 { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 }, 03756 { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 }, 03757 { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 }, 03758 { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 }, 03759 { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 }, 03760 { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 }, 03761 { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 }, 03762 { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 }, 03763 { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 }, 03764 { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 }, 03765 { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 }, 03766 { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 }, 03767 { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 }, 03768 { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 }, 03769 { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 }, 03770 { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 }, 03771 { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 }, 03772 { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 }, 03773 { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 }, 03774 { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 }, 03775 { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 }, 03776 { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 }, 03777 { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 }, 03778 { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 }, 03779 { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 }, 03780 { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 }, 03781 { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 }, 03782 { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 }, 03783 { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 }, 03784 { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 }, 03785 { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 }, 03786 { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 }, 03787 { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 }, 03788 { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 }, 03789 { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 }, 03790 { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 }, 03791 { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 }, 03792 { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 }, 03793 { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 }, 03794 { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 }, 03795 { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 }, 03796 { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 }, 03797 { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 }, 03798 { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 }, 03799 { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 }, 03800 { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 }, 03801 { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 }, 03802 { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 }, 03803 { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 }, 03804 { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 }, 03805 { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 }, 03806 { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 }, 03807 { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 }, 03808 { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 }, 03809 { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 }, 03810 { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 }, 03811 { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 }, 03812 { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 }, 03813 { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 }, 03814 { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 }, 03815 { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 }, 03816 { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 }, 03817 { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 }, 03818 { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 }, 03819 { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 }, 03820 { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 }, 03821 { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 }, 03822 { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 }, 03823 { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 }, 03824 { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 }, 03825 { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 }, 03826 { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 }, 03827 { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 }, 03828 { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 }, 03829 { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 }, 03830 { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 }, 03831 { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 }, 03832 { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 }, 03833 { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 }, 03834 { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 }, 03835 { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 }, 03836 { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 }, 03837 { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 }, 03838 { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 }, 03839 { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 }, 03840 { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 }, 03841 { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 }, 03842 { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 }, 03843 { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 }, 03844 { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 }, 03845 { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 }, 03846 { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 }, 03847 { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 }, 03848 { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 }, 03849 { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 }, 03850 { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 }, 03851 { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 }, 03852 { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 }, 03853 { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 }, 03854 { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 }, 03855 { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 }, 03856 { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 }, 03857 { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 }, 03858 { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 }, 03859 { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 }, 03860 { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 }, 03861 { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 }, 03862 { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 }, 03863 { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 }, 03864 { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 }, 03865 { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 }, 03866 { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 }, 03867 { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 }, 03868 { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 }, 03869 { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 }, 03870 { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 }, 03871 { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 }, 03872 { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 }, 03873 { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 }, 03874 { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 }, 03875 { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 }, 03876 { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 }, 03877 { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 }, 03878 { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 }, 03879 { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 }, 03880 { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 }, 03881 #endif 03882 #endif 03883 #endif 03884 #endif 03885 #endif 03886 #endif 03887 }; 03888 03889 /* find a hole and free as required, return -1 if no hole found */ 03890 static int find_hole(void) 03891 { 03892 unsigned x; 03893 int y, z; 03894 for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { 03895 if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { 03896 z = x; 03897 y = fp_cache[x].lru_count; 03898 } 03899 } 03900 03901 /* decrease all */ 03902 for (x = 0; x < FP_ENTRIES; x++) { 03903 if (fp_cache[x].lru_count > 3) { 03904 --(fp_cache[x].lru_count); 03905 } 03906 } 03907 03908 /* free entry z */ 03909 if (z >= 0 && fp_cache[z].g) { 03910 mp_clear(&fp_cache[z].mu); 03911 wc_ecc_del_point(fp_cache[z].g); 03912 fp_cache[z].g = NULL; 03913 for (x = 0; x < (1U<<FP_LUT); x++) { 03914 wc_ecc_del_point(fp_cache[z].LUT[x]); 03915 fp_cache[z].LUT[x] = NULL; 03916 } 03917 fp_cache[z].lru_count = 0; 03918 } 03919 return z; 03920 } 03921 03922 /* determine if a base is already in the cache and if so, where */ 03923 static int find_base(ecc_point* g) 03924 { 03925 int x; 03926 for (x = 0; x < FP_ENTRIES; x++) { 03927 if (fp_cache[x].g != NULL && 03928 mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ && 03929 mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ && 03930 mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) { 03931 break; 03932 } 03933 } 03934 if (x == FP_ENTRIES) { 03935 x = -1; 03936 } 03937 return x; 03938 } 03939 03940 /* add a new base to the cache */ 03941 static int add_entry(int idx, ecc_point *g) 03942 { 03943 unsigned x, y; 03944 03945 /* allocate base and LUT */ 03946 fp_cache[idx].g = wc_ecc_new_point(); 03947 if (fp_cache[idx].g == NULL) { 03948 return GEN_MEM_ERR; 03949 } 03950 03951 /* copy x and y */ 03952 if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) || 03953 (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) || 03954 (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) { 03955 wc_ecc_del_point(fp_cache[idx].g); 03956 fp_cache[idx].g = NULL; 03957 return GEN_MEM_ERR; 03958 } 03959 03960 for (x = 0; x < (1U<<FP_LUT); x++) { 03961 fp_cache[idx].LUT[x] = wc_ecc_new_point(); 03962 if (fp_cache[idx].LUT[x] == NULL) { 03963 for (y = 0; y < x; y++) { 03964 wc_ecc_del_point(fp_cache[idx].LUT[y]); 03965 fp_cache[idx].LUT[y] = NULL; 03966 } 03967 wc_ecc_del_point(fp_cache[idx].g); 03968 fp_cache[idx].g = NULL; 03969 fp_cache[idx].lru_count = 0; 03970 return GEN_MEM_ERR; 03971 } 03972 } 03973 03974 fp_cache[idx].lru_count = 0; 03975 03976 return MP_OKAY; 03977 } 03978 03979 /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart 03980 * 03981 * The algorithm builds patterns in increasing bit order by first making all 03982 * single bit input patterns, then all two bit input patterns and so on 03983 */ 03984 static int build_lut(int idx, mp_int* modulus, mp_digit* mp, mp_int* mu) 03985 { 03986 unsigned x, y, err, bitlen, lut_gap; 03987 mp_int tmp; 03988 03989 if (mp_init(&tmp) != MP_OKAY) 03990 return GEN_MEM_ERR; 03991 03992 /* sanity check to make sure lut_order table is of correct size, 03993 should compile out to a NOP if true */ 03994 if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) { 03995 err = BAD_FUNC_ARG; 03996 } 03997 else { 03998 /* get bitlen and round up to next multiple of FP_LUT */ 03999 bitlen = mp_unsigned_bin_size(modulus) << 3; 04000 x = bitlen % FP_LUT; 04001 if (x) { 04002 bitlen += FP_LUT - x; 04003 } 04004 lut_gap = bitlen / FP_LUT; 04005 04006 /* init the mu */ 04007 err = mp_init_copy(&fp_cache[idx].mu, mu); 04008 } 04009 04010 /* copy base */ 04011 if (err == MP_OKAY) { 04012 if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus, 04013 fp_cache[idx].LUT[1]->x) != MP_OKAY) || 04014 (mp_mulmod(fp_cache[idx].g->y, mu, modulus, 04015 fp_cache[idx].LUT[1]->y) != MP_OKAY) || 04016 (mp_mulmod(fp_cache[idx].g->z, mu, modulus, 04017 fp_cache[idx].LUT[1]->z) != MP_OKAY)) { 04018 err = MP_MULMOD_E; 04019 } 04020 } 04021 04022 /* make all single bit entries */ 04023 for (x = 1; x < FP_LUT; x++) { 04024 if (err != MP_OKAY) 04025 break; 04026 if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, 04027 fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) || 04028 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, 04029 fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) || 04030 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, 04031 fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){ 04032 err = MP_INIT_E; 04033 break; 04034 } else { 04035 04036 /* now double it bitlen/FP_LUT times */ 04037 for (y = 0; y < lut_gap; y++) { 04038 if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x], 04039 fp_cache[idx].LUT[1<<x], modulus, mp)) != MP_OKAY) { 04040 break; 04041 } 04042 } 04043 } 04044 } 04045 04046 /* now make all entries in increase order of hamming weight */ 04047 for (x = 2; x <= FP_LUT; x++) { 04048 if (err != MP_OKAY) 04049 break; 04050 for (y = 0; y < (1UL<<FP_LUT); y++) { 04051 if (err != MP_OKAY) 04052 break; 04053 if (lut_orders[y].ham != (int)x) continue; 04054 04055 /* perform the add */ 04056 if ((err = ecc_projective_add_point( 04057 fp_cache[idx].LUT[lut_orders[y].terma], 04058 fp_cache[idx].LUT[lut_orders[y].termb], 04059 fp_cache[idx].LUT[y], modulus, mp)) != MP_OKAY) { 04060 break; 04061 } 04062 } 04063 } 04064 04065 /* now map all entries back to affine space to make point addition faster */ 04066 for (x = 1; x < (1UL<<FP_LUT); x++) { 04067 if (err != MP_OKAY) 04068 break; 04069 04070 /* convert z to normal from montgomery */ 04071 err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, *mp); 04072 04073 /* invert it */ 04074 if (err == MP_OKAY) 04075 err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, 04076 fp_cache[idx].LUT[x]->z); 04077 04078 if (err == MP_OKAY) 04079 /* now square it */ 04080 err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp); 04081 04082 if (err == MP_OKAY) 04083 /* fix x */ 04084 err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus, 04085 fp_cache[idx].LUT[x]->x); 04086 04087 if (err == MP_OKAY) 04088 /* get 1/z^3 */ 04089 err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp); 04090 04091 if (err == MP_OKAY) 04092 /* fix y */ 04093 err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus, 04094 fp_cache[idx].LUT[x]->y); 04095 04096 if (err == MP_OKAY) 04097 /* free z */ 04098 mp_clear(fp_cache[idx].LUT[x]->z); 04099 } 04100 mp_clear(&tmp); 04101 04102 if (err == MP_OKAY) 04103 return MP_OKAY; 04104 04105 /* err cleanup */ 04106 for (y = 0; y < (1U<<FP_LUT); y++) { 04107 wc_ecc_del_point(fp_cache[idx].LUT[y]); 04108 fp_cache[idx].LUT[y] = NULL; 04109 } 04110 wc_ecc_del_point(fp_cache[idx].g); 04111 fp_cache[idx].g = NULL; 04112 fp_cache[idx].lru_count = 0; 04113 mp_clear(&fp_cache[idx].mu); 04114 mp_clear(&tmp); 04115 04116 return err; 04117 } 04118 04119 /* perform a fixed point ECC mulmod */ 04120 static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* modulus, 04121 mp_digit* mp, int map) 04122 { 04123 #define KB_SIZE 128 04124 04125 #ifdef WOLFSSL_SMALL_STACK 04126 unsigned char* kb; 04127 #else 04128 unsigned char kb[128]; 04129 #endif 04130 int x; 04131 unsigned y, z, err, bitlen, bitpos, lut_gap, first; 04132 mp_int tk; 04133 04134 if (mp_init(&tk) != MP_OKAY) 04135 return MP_INIT_E; 04136 04137 /* if it's smaller than modulus we fine */ 04138 if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) { 04139 mp_int order; 04140 if (mp_init(&order) != MP_OKAY) { 04141 mp_clear(&tk); 04142 return MP_INIT_E; 04143 } 04144 04145 /* find order */ 04146 y = mp_unsigned_bin_size(modulus); 04147 for (x = 0; ecc_sets[x].size; x++) { 04148 if (y <= (unsigned)ecc_sets[x].size) break; 04149 } 04150 04151 /* back off if we are on the 521 bit curve */ 04152 if (y == 66) --x; 04153 04154 if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { 04155 mp_clear(&order); 04156 mp_clear(&tk); 04157 return err; 04158 } 04159 04160 /* k must be less than modulus */ 04161 if (mp_cmp(k, &order) != MP_LT) { 04162 if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) { 04163 mp_clear(&tk); 04164 mp_clear(&order); 04165 return err; 04166 } 04167 } else { 04168 mp_copy(k, &tk); 04169 } 04170 mp_clear(&order); 04171 } else { 04172 mp_copy(k, &tk); 04173 } 04174 04175 /* get bitlen and round up to next multiple of FP_LUT */ 04176 bitlen = mp_unsigned_bin_size(modulus) << 3; 04177 x = bitlen % FP_LUT; 04178 if (x) { 04179 bitlen += FP_LUT - x; 04180 } 04181 lut_gap = bitlen / FP_LUT; 04182 04183 /* get the k value */ 04184 if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) { 04185 mp_clear(&tk); 04186 return BUFFER_E; 04187 } 04188 04189 /* store k */ 04190 #ifdef WOLFSSL_SMALL_STACK 04191 kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 04192 if (kb == NULL) 04193 return MEMORY_E; 04194 #endif 04195 04196 XMEMSET(kb, 0, KB_SIZE); 04197 if ((err = mp_to_unsigned_bin(&tk, kb)) != MP_OKAY) { 04198 mp_clear(&tk); 04199 } 04200 else { 04201 /* let's reverse kb so it's little endian */ 04202 x = 0; 04203 y = mp_unsigned_bin_size(&tk); 04204 if (y > 0) { 04205 y -= 1; 04206 } 04207 mp_clear(&tk); 04208 04209 while ((unsigned)x < y) { 04210 z = kb[x]; kb[x] = kb[y]; kb[y] = z; 04211 ++x; --y; 04212 } 04213 04214 /* at this point we can start, yipee */ 04215 first = 1; 04216 for (x = lut_gap-1; x >= 0; x--) { 04217 /* extract FP_LUT bits from kb spread out by lut_gap bits and offset 04218 by x bits from the start */ 04219 bitpos = x; 04220 for (y = z = 0; y < FP_LUT; y++) { 04221 z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y; 04222 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid 04223 the mult in each loop */ 04224 } 04225 04226 /* double if not first */ 04227 if (!first) { 04228 if ((err = ecc_projective_dbl_point(R, R, modulus, 04229 mp)) != MP_OKAY) { 04230 break; 04231 } 04232 } 04233 04234 /* add if not first, otherwise copy */ 04235 if (!first && z) { 04236 if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, 04237 modulus, mp)) != MP_OKAY) { 04238 break; 04239 } 04240 } else if (z) { 04241 if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) || 04242 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) || 04243 (mp_copy(&fp_cache[idx].mu, R->z) != MP_OKAY)) { 04244 err = GEN_MEM_ERR; 04245 break; 04246 } 04247 first = 0; 04248 } 04249 } 04250 } 04251 04252 if (err == MP_OKAY) { 04253 z = 0; /* mp_to_unsigned_bin != MP_OKAY z will be declared/not set */ 04254 (void) z; /* Acknowledge the unused assignment */ 04255 ForceZero(kb, KB_SIZE); 04256 /* map R back from projective space */ 04257 if (map) { 04258 err = ecc_map(R, modulus, mp); 04259 } else { 04260 err = MP_OKAY; 04261 } 04262 } 04263 04264 #ifdef WOLFSSL_SMALL_STACK 04265 XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER); 04266 #endif 04267 04268 #undef KB_SIZE 04269 04270 return err; 04271 } 04272 04273 #ifdef ECC_SHAMIR 04274 /* perform a fixed point ECC mulmod */ 04275 static int accel_fp_mul2add(int idx1, int idx2, 04276 mp_int* kA, mp_int* kB, 04277 ecc_point *R, mp_int* modulus, mp_digit* mp) 04278 { 04279 #define KB_SIZE 128 04280 04281 #ifdef WOLFSSL_SMALL_STACK 04282 unsigned char* kb[2]; 04283 #else 04284 unsigned char kb[2][128]; 04285 #endif 04286 int x; 04287 unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB; 04288 mp_int tka; 04289 mp_int tkb; 04290 mp_int order; 04291 04292 if (mp_init_multi(&tka, &tkb, 0, 0, 0, 0) != MP_OKAY) 04293 return MP_INIT_E; 04294 04295 /* if it's smaller than modulus we fine */ 04296 if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { 04297 /* find order */ 04298 y = mp_unsigned_bin_size(modulus); 04299 for (x = 0; ecc_sets[x].size; x++) { 04300 if (y <= (unsigned)ecc_sets[x].size) break; 04301 } 04302 04303 /* back off if we are on the 521 bit curve */ 04304 if (y == 66) --x; 04305 04306 if ((err = mp_init(&order)) != MP_OKAY) { 04307 mp_clear(&tkb); 04308 mp_clear(&tka); 04309 return err; 04310 } 04311 if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { 04312 mp_clear(&tkb); 04313 mp_clear(&tka); 04314 mp_clear(&order); 04315 return err; 04316 } 04317 04318 /* kA must be less than modulus */ 04319 if (mp_cmp(kA, &order) != MP_LT) { 04320 if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) { 04321 mp_clear(&tkb); 04322 mp_clear(&tka); 04323 mp_clear(&order); 04324 return err; 04325 } 04326 } else { 04327 mp_copy(kA, &tka); 04328 } 04329 mp_clear(&order); 04330 } else { 04331 mp_copy(kA, &tka); 04332 } 04333 04334 /* if it's smaller than modulus we fine */ 04335 if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { 04336 /* find order */ 04337 y = mp_unsigned_bin_size(modulus); 04338 for (x = 0; ecc_sets[x].size; x++) { 04339 if (y <= (unsigned)ecc_sets[x].size) break; 04340 } 04341 04342 /* back off if we are on the 521 bit curve */ 04343 if (y == 66) --x; 04344 04345 if ((err = mp_init(&order)) != MP_OKAY) { 04346 mp_clear(&tkb); 04347 mp_clear(&tka); 04348 return err; 04349 } 04350 if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { 04351 mp_clear(&tkb); 04352 mp_clear(&tka); 04353 mp_clear(&order); 04354 return err; 04355 } 04356 04357 /* kB must be less than modulus */ 04358 if (mp_cmp(kB, &order) != MP_LT) { 04359 if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) { 04360 mp_clear(&tkb); 04361 mp_clear(&tka); 04362 mp_clear(&order); 04363 return err; 04364 } 04365 } else { 04366 mp_copy(kB, &tkb); 04367 } 04368 mp_clear(&order); 04369 } else { 04370 mp_copy(kB, &tkb); 04371 } 04372 04373 /* get bitlen and round up to next multiple of FP_LUT */ 04374 bitlen = mp_unsigned_bin_size(modulus) << 3; 04375 x = bitlen % FP_LUT; 04376 if (x) { 04377 bitlen += FP_LUT - x; 04378 } 04379 lut_gap = bitlen / FP_LUT; 04380 04381 /* get the k value */ 04382 if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) || 04383 (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) { 04384 mp_clear(&tka); 04385 mp_clear(&tkb); 04386 return BUFFER_E; 04387 } 04388 04389 /* store k */ 04390 #ifdef WOLFSSL_SMALL_STACK 04391 kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 04392 if (kb[0] == NULL) 04393 return MEMORY_E; 04394 #endif 04395 04396 XMEMSET(kb[0], 0, KB_SIZE); 04397 if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) { 04398 mp_clear(&tka); 04399 mp_clear(&tkb); 04400 #ifdef WOLFSSL_SMALL_STACK 04401 XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); 04402 #endif 04403 return err; 04404 } 04405 04406 /* let's reverse kb so it's little endian */ 04407 x = 0; 04408 y = mp_unsigned_bin_size(&tka); 04409 if (y > 0) { 04410 y -= 1; 04411 } 04412 mp_clear(&tka); 04413 while ((unsigned)x < y) { 04414 z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z; 04415 ++x; --y; 04416 } 04417 04418 /* store b */ 04419 #ifdef WOLFSSL_SMALL_STACK 04420 kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 04421 if (kb[1] == NULL) { 04422 XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); 04423 return MEMORY_E; 04424 } 04425 #endif 04426 04427 XMEMSET(kb[1], 0, KB_SIZE); 04428 if ((err = mp_to_unsigned_bin(&tkb, kb[1])) != MP_OKAY) { 04429 mp_clear(&tkb); 04430 } 04431 else { 04432 x = 0; 04433 y = mp_unsigned_bin_size(&tkb); 04434 if (y > 0) { 04435 y -= 1; 04436 } 04437 mp_clear(&tkb); 04438 while ((unsigned)x < y) { 04439 z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z; 04440 ++x; --y; 04441 } 04442 04443 /* at this point we can start, yipee */ 04444 first = 1; 04445 for (x = lut_gap-1; x >= 0; x--) { 04446 /* extract FP_LUT bits from kb spread out by lut_gap bits and 04447 offset by x bits from the start */ 04448 bitpos = x; 04449 for (y = zA = zB = 0; y < FP_LUT; y++) { 04450 zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y; 04451 zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y; 04452 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid 04453 the mult in each loop */ 04454 } 04455 04456 /* double if not first */ 04457 if (!first) { 04458 if ((err = ecc_projective_dbl_point(R, R, modulus, 04459 mp)) != MP_OKAY) { 04460 break; 04461 } 04462 } 04463 04464 /* add if not first, otherwise copy */ 04465 if (!first) { 04466 if (zA) { 04467 if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA], 04468 R, modulus, mp)) != MP_OKAY) { 04469 break; 04470 } 04471 } 04472 if (zB) { 04473 if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB], 04474 R, modulus, mp)) != MP_OKAY) { 04475 break; 04476 } 04477 } 04478 } else { 04479 if (zA) { 04480 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) || 04481 (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) || 04482 (mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) { 04483 err = GEN_MEM_ERR; 04484 break; 04485 } 04486 first = 0; 04487 } 04488 if (zB && first == 0) { 04489 if (zB) { 04490 if ((err = ecc_projective_add_point(R, 04491 fp_cache[idx2].LUT[zB], R, modulus, mp)) != MP_OKAY){ 04492 break; 04493 } 04494 } 04495 } else if (zB && first == 1) { 04496 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) || 04497 (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) || 04498 (mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) { 04499 err = GEN_MEM_ERR; 04500 break; 04501 } 04502 first = 0; 04503 } 04504 } 04505 } 04506 } 04507 04508 ForceZero(kb[0], KB_SIZE); 04509 ForceZero(kb[1], KB_SIZE); 04510 04511 #ifdef WOLFSSL_SMALL_STACK 04512 XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); 04513 XFREE(kb[1], NULL, DYNAMIC_TYPE_TMP_BUFFER); 04514 #endif 04515 04516 #undef KB_SIZE 04517 04518 if (err != MP_OKAY) 04519 return err; 04520 04521 return ecc_map(R, modulus, mp); 04522 } 04523 04524 /** ECC Fixed Point mulmod global 04525 Computes kA*A + kB*B = C using Shamir's Trick 04526 A First point to multiply 04527 kA What to multiple A by 04528 B Second point to multiply 04529 kB What to multiple B by 04530 C [out] Destination point (can overlap with A or B) 04531 modulus Modulus for curve 04532 return MP_OKAY on success 04533 */ 04534 int ecc_mul2add(ecc_point* A, mp_int* kA, 04535 ecc_point* B, mp_int* kB, 04536 ecc_point* C, mp_int* modulus) 04537 { 04538 int idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0; 04539 mp_digit mp; 04540 mp_int mu; 04541 04542 err = mp_init(&mu); 04543 if (err != MP_OKAY) 04544 return err; 04545 04546 #ifndef HAVE_THREAD_LS 04547 if (initMutex == 0) { 04548 InitMutex(&ecc_fp_lock); 04549 initMutex = 1; 04550 } 04551 if (LockMutex(&ecc_fp_lock) != 0) 04552 return BAD_MUTEX_E; 04553 #endif /* HAVE_THREAD_LS */ 04554 04555 /* find point */ 04556 idx1 = find_base(A); 04557 04558 /* no entry? */ 04559 if (idx1 == -1) { 04560 /* find hole and add it */ 04561 if ((idx1 = find_hole()) >= 0) { 04562 err = add_entry(idx1, A); 04563 } 04564 } 04565 if (err == MP_OKAY && idx1 != -1) { 04566 /* increment LRU */ 04567 ++(fp_cache[idx1].lru_count); 04568 } 04569 04570 if (err == MP_OKAY) 04571 /* find point */ 04572 idx2 = find_base(B); 04573 04574 if (err == MP_OKAY) { 04575 /* no entry? */ 04576 if (idx2 == -1) { 04577 /* find hole and add it */ 04578 if ((idx2 = find_hole()) >= 0) 04579 err = add_entry(idx2, B); 04580 } 04581 } 04582 04583 if (err == MP_OKAY && idx2 != -1) { 04584 /* increment LRU */ 04585 ++(fp_cache[idx2].lru_count); 04586 } 04587 04588 if (err == MP_OKAY) { 04589 /* if it's 2 build the LUT, if it's higher just use the LUT */ 04590 if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { 04591 /* compute mp */ 04592 err = mp_montgomery_setup(modulus, &mp); 04593 04594 if (err == MP_OKAY) { 04595 mpInit = 1; 04596 err = mp_montgomery_calc_normalization(&mu, modulus); 04597 } 04598 04599 if (err == MP_OKAY) 04600 /* build the LUT */ 04601 err = build_lut(idx1, modulus, &mp, &mu); 04602 } 04603 } 04604 04605 if (err == MP_OKAY) { 04606 /* if it's 2 build the LUT, if it's higher just use the LUT */ 04607 if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { 04608 if (mpInit == 0) { 04609 /* compute mp */ 04610 err = mp_montgomery_setup(modulus, &mp); 04611 if (err == MP_OKAY) { 04612 mpInit = 1; 04613 err = mp_montgomery_calc_normalization(&mu, modulus); 04614 } 04615 } 04616 04617 if (err == MP_OKAY) 04618 /* build the LUT */ 04619 err = build_lut(idx2, modulus, &mp, &mu); 04620 } 04621 } 04622 04623 04624 if (err == MP_OKAY) { 04625 if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && 04626 fp_cache[idx2].lru_count >= 2) { 04627 if (mpInit == 0) { 04628 /* compute mp */ 04629 err = mp_montgomery_setup(modulus, &mp); 04630 } 04631 if (err == MP_OKAY) 04632 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, &mp); 04633 } else { 04634 err = normal_ecc_mul2add(A, kA, B, kB, C, modulus); 04635 } 04636 } 04637 04638 #ifndef HAVE_THREAD_LS 04639 UnLockMutex(&ecc_fp_lock); 04640 #endif /* HAVE_THREAD_LS */ 04641 mp_clear(&mu); 04642 04643 return err; 04644 } 04645 #endif /* ECC_SHAMIR */ 04646 04647 /** ECC Fixed Point mulmod global 04648 k The multiplicand 04649 G Base point to multiply 04650 R [out] Destination of product 04651 modulus The modulus for the curve 04652 map [boolean] If non-zero maps the point back to affine co-ordinates, 04653 otherwise it's left in jacobian-montgomery form 04654 return MP_OKAY if successful 04655 */ 04656 int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, 04657 int map) 04658 { 04659 int idx, err = MP_OKAY; 04660 mp_digit mp; 04661 mp_int mu; 04662 int mpSetup = 0; 04663 04664 if (mp_init(&mu) != MP_OKAY) 04665 return MP_INIT_E; 04666 04667 #ifndef HAVE_THREAD_LS 04668 if (initMutex == 0) { 04669 InitMutex(&ecc_fp_lock); 04670 initMutex = 1; 04671 } 04672 04673 if (LockMutex(&ecc_fp_lock) != 0) 04674 return BAD_MUTEX_E; 04675 #endif /* HAVE_THREAD_LS */ 04676 04677 /* find point */ 04678 idx = find_base(G); 04679 04680 /* no entry? */ 04681 if (idx == -1) { 04682 /* find hole and add it */ 04683 idx = find_hole(); 04684 04685 if (idx >= 0) 04686 err = add_entry(idx, G); 04687 } 04688 if (err == MP_OKAY && idx >= 0) { 04689 /* increment LRU */ 04690 ++(fp_cache[idx].lru_count); 04691 } 04692 04693 04694 if (err == MP_OKAY) { 04695 /* if it's 2 build the LUT, if it's higher just use the LUT */ 04696 if (idx >= 0 && fp_cache[idx].lru_count == 2) { 04697 /* compute mp */ 04698 err = mp_montgomery_setup(modulus, &mp); 04699 04700 if (err == MP_OKAY) { 04701 /* compute mu */ 04702 mpSetup = 1; 04703 err = mp_montgomery_calc_normalization(&mu, modulus); 04704 } 04705 04706 if (err == MP_OKAY) 04707 /* build the LUT */ 04708 err = build_lut(idx, modulus, &mp, &mu); 04709 } 04710 } 04711 04712 if (err == MP_OKAY) { 04713 if (idx >= 0 && fp_cache[idx].lru_count >= 2) { 04714 if (mpSetup == 0) { 04715 /* compute mp */ 04716 err = mp_montgomery_setup(modulus, &mp); 04717 } 04718 if (err == MP_OKAY) 04719 err = accel_fp_mul(idx, k, R, modulus, &mp, map); 04720 } else { 04721 err = normal_ecc_mulmod(k, G, R, modulus, map); 04722 } 04723 } 04724 04725 #ifndef HAVE_THREAD_LS 04726 UnLockMutex(&ecc_fp_lock); 04727 #endif /* HAVE_THREAD_LS */ 04728 mp_clear(&mu); 04729 04730 return err; 04731 } 04732 04733 /* helper function for freeing the cache ... 04734 must be called with the cache mutex locked */ 04735 static void wc_ecc_fp_free_cache(void) 04736 { 04737 unsigned x, y; 04738 for (x = 0; x < FP_ENTRIES; x++) { 04739 if (fp_cache[x].g != NULL) { 04740 for (y = 0; y < (1U<<FP_LUT); y++) { 04741 wc_ecc_del_point(fp_cache[x].LUT[y]); 04742 fp_cache[x].LUT[y] = NULL; 04743 } 04744 wc_ecc_del_point(fp_cache[x].g); 04745 fp_cache[x].g = NULL; 04746 mp_clear(&fp_cache[x].mu); 04747 fp_cache[x].lru_count = 0; 04748 fp_cache[x].lock = 0; 04749 } 04750 } 04751 } 04752 04753 /** Free the Fixed Point cache */ 04754 void wc_ecc_fp_free(void) 04755 { 04756 #ifndef HAVE_THREAD_LS 04757 if (initMutex == 0) { 04758 InitMutex(&ecc_fp_lock); 04759 initMutex = 1; 04760 } 04761 04762 if (LockMutex(&ecc_fp_lock) == 0) { 04763 #endif /* HAVE_THREAD_LS */ 04764 04765 wc_ecc_fp_free_cache(); 04766 04767 #ifndef HAVE_THREAD_LS 04768 UnLockMutex(&ecc_fp_lock); 04769 FreeMutex(&ecc_fp_lock); 04770 initMutex = 0; 04771 } 04772 #endif /* HAVE_THREAD_LS */ 04773 } 04774 04775 04776 #endif /* FP_ECC */ 04777 04778 #ifdef HAVE_ECC_ENCRYPT 04779 04780 04781 enum ecCliState { 04782 ecCLI_INIT = 1, 04783 ecCLI_SALT_GET = 2, 04784 ecCLI_SALT_SET = 3, 04785 ecCLI_SENT_REQ = 4, 04786 ecCLI_RECV_RESP = 5, 04787 ecCLI_BAD_STATE = 99 04788 }; 04789 04790 enum ecSrvState { 04791 ecSRV_INIT = 1, 04792 ecSRV_SALT_GET = 2, 04793 ecSRV_SALT_SET = 3, 04794 ecSRV_RECV_REQ = 4, 04795 ecSRV_SENT_RESP = 5, 04796 ecSRV_BAD_STATE = 99 04797 }; 04798 04799 04800 struct ecEncCtx { 04801 const byte* kdfSalt; /* optional salt for kdf */ 04802 const byte* kdfInfo; /* optional info for kdf */ 04803 const byte* macSalt; /* optional salt for mac */ 04804 word32 kdfSaltSz; /* size of kdfSalt */ 04805 word32 kdfInfoSz; /* size of kdfInfo */ 04806 word32 macSaltSz; /* size of macSalt */ 04807 byte clientSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ 04808 byte serverSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ 04809 byte encAlgo; /* which encryption type */ 04810 byte kdfAlgo; /* which key derivation function type */ 04811 byte macAlgo; /* which mac function type */ 04812 byte protocol; /* are we REQ_RESP client or server ? */ 04813 byte cliSt; /* protocol state, for sanity checks */ 04814 byte srvSt; /* protocol state, for sanity checks */ 04815 }; 04816 04817 04818 const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx) 04819 { 04820 if (ctx == NULL || ctx->protocol == 0) 04821 return NULL; 04822 04823 if (ctx->protocol == REQ_RESP_CLIENT) { 04824 if (ctx->cliSt == ecCLI_INIT) { 04825 ctx->cliSt = ecCLI_SALT_GET; 04826 return ctx->clientSalt; 04827 } 04828 else { 04829 ctx->cliSt = ecCLI_BAD_STATE; 04830 return NULL; 04831 } 04832 } 04833 else if (ctx->protocol == REQ_RESP_SERVER) { 04834 if (ctx->srvSt == ecSRV_INIT) { 04835 ctx->srvSt = ecSRV_SALT_GET; 04836 return ctx->serverSalt; 04837 } 04838 else { 04839 ctx->srvSt = ecSRV_BAD_STATE; 04840 return NULL; 04841 } 04842 } 04843 04844 return NULL; 04845 } 04846 04847 04848 /* optional set info, can be called before or after set_peer_salt */ 04849 int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz) 04850 { 04851 if (ctx == NULL || info == 0 || sz < 0) 04852 return BAD_FUNC_ARG; 04853 04854 ctx->kdfInfo = info; 04855 ctx->kdfInfoSz = sz; 04856 04857 return 0; 04858 } 04859 04860 04861 static const char* exchange_info = "Secure Message Exchange"; 04862 04863 int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) 04864 { 04865 byte tmp[EXCHANGE_SALT_SZ/2]; 04866 int halfSz = EXCHANGE_SALT_SZ/2; 04867 04868 if (ctx == NULL || ctx->protocol == 0 || salt == NULL) 04869 return BAD_FUNC_ARG; 04870 04871 if (ctx->protocol == REQ_RESP_CLIENT) { 04872 XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ); 04873 if (ctx->cliSt == ecCLI_SALT_GET) 04874 ctx->cliSt = ecCLI_SALT_SET; 04875 else { 04876 ctx->cliSt = ecCLI_BAD_STATE; 04877 return BAD_ENC_STATE_E; 04878 } 04879 } 04880 else { 04881 XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ); 04882 if (ctx->srvSt == ecSRV_SALT_GET) 04883 ctx->srvSt = ecSRV_SALT_SET; 04884 else { 04885 ctx->srvSt = ecSRV_BAD_STATE; 04886 return BAD_ENC_STATE_E; 04887 } 04888 } 04889 04890 /* mix half and half */ 04891 /* tmp stores 2nd half of client before overwrite */ 04892 XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz); 04893 XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz); 04894 XMEMCPY(ctx->serverSalt, tmp, halfSz); 04895 04896 ctx->kdfSalt = ctx->clientSalt; 04897 ctx->kdfSaltSz = EXCHANGE_SALT_SZ; 04898 04899 ctx->macSalt = ctx->serverSalt; 04900 ctx->macSaltSz = EXCHANGE_SALT_SZ; 04901 04902 if (ctx->kdfInfo == NULL) { 04903 /* default info */ 04904 ctx->kdfInfo = (const byte*)exchange_info; 04905 ctx->kdfInfoSz = EXCHANGE_INFO_SZ; 04906 } 04907 04908 return 0; 04909 } 04910 04911 04912 static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng) 04913 { 04914 byte* saltBuffer = NULL; 04915 04916 if (ctx == NULL || rng == NULL || flags == 0) 04917 return BAD_FUNC_ARG; 04918 04919 saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt; 04920 04921 return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ); 04922 } 04923 04924 04925 static void ecc_ctx_init(ecEncCtx* ctx, int flags) 04926 { 04927 if (ctx) { 04928 XMEMSET(ctx, 0, sizeof(ecEncCtx)); 04929 04930 ctx->encAlgo = ecAES_128_CBC; 04931 ctx->kdfAlgo = ecHKDF_SHA256; 04932 ctx->macAlgo = ecHMAC_SHA256; 04933 ctx->protocol = (byte)flags; 04934 04935 if (flags == REQ_RESP_CLIENT) 04936 ctx->cliSt = ecCLI_INIT; 04937 if (flags == REQ_RESP_SERVER) 04938 ctx->srvSt = ecSRV_INIT; 04939 } 04940 } 04941 04942 04943 /* allow ecc context reset so user doesn't have to init/free for reuse */ 04944 int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng) 04945 { 04946 if (ctx == NULL || rng == NULL) 04947 return BAD_FUNC_ARG; 04948 04949 ecc_ctx_init(ctx, ctx->protocol); 04950 return ecc_ctx_set_salt(ctx, ctx->protocol, rng); 04951 } 04952 04953 04954 /* alloc/init and set defaults, return new Context */ 04955 ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng) 04956 { 04957 int ret = 0; 04958 ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), 0, DYNAMIC_TYPE_ECC); 04959 04960 if (ctx) 04961 ctx->protocol = (byte)flags; 04962 04963 ret = wc_ecc_ctx_reset(ctx, rng); 04964 if (ret != 0) { 04965 wc_ecc_ctx_free(ctx); 04966 ctx = NULL; 04967 } 04968 04969 return ctx; 04970 } 04971 04972 04973 /* free any resources, clear any keys */ 04974 void wc_ecc_ctx_free(ecEncCtx* ctx) 04975 { 04976 if (ctx) { 04977 ForceZero(ctx, sizeof(ecEncCtx)); 04978 XFREE(ctx, 0, DYNAMIC_TYPE_ECC); 04979 } 04980 } 04981 04982 04983 static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz, 04984 int* keysLen, word32* digestSz, word32* blockSz) 04985 { 04986 if (ctx) { 04987 switch (ctx->encAlgo) { 04988 case ecAES_128_CBC: 04989 *encKeySz = KEY_SIZE_128; 04990 *ivSz = IV_SIZE_128; 04991 *blockSz = AES_BLOCK_SIZE; 04992 break; 04993 default: 04994 return BAD_FUNC_ARG; 04995 } 04996 04997 switch (ctx->macAlgo) { 04998 case ecHMAC_SHA256: 04999 *digestSz = SHA256_DIGEST_SIZE; 05000 break; 05001 default: 05002 return BAD_FUNC_ARG; 05003 } 05004 } else 05005 return BAD_FUNC_ARG; 05006 05007 *keysLen = *encKeySz + *ivSz + *digestSz; 05008 05009 return 0; 05010 } 05011 05012 05013 /* ecc encrypt with shared secret run through kdf 05014 ctx holds non default algos and inputs 05015 msgSz should be the right size for encAlgo, i.e., already padded 05016 return 0 on success */ 05017 int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, 05018 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) 05019 { 05020 int ret; 05021 word32 blockSz; 05022 word32 digestSz; 05023 ecEncCtx localCtx; 05024 #ifdef WOLFSSL_SMALL_STACK 05025 byte* sharedSecret; 05026 byte* keys; 05027 #else 05028 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ 05029 byte keys[ECC_BUFSIZE]; /* max size */ 05030 #endif 05031 word32 sharedSz = ECC_MAXSIZE; 05032 int keysLen; 05033 int encKeySz; 05034 int ivSz; 05035 int offset = 0; /* keys offset if doing msg exchange */ 05036 byte* encKey; 05037 byte* encIv; 05038 byte* macKey; 05039 05040 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || 05041 outSz == NULL) 05042 return BAD_FUNC_ARG; 05043 05044 if (ctx == NULL) { /* use defaults */ 05045 ecc_ctx_init(&localCtx, 0); 05046 ctx = &localCtx; 05047 } 05048 05049 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, 05050 &blockSz); 05051 if (ret != 0) 05052 return ret; 05053 05054 if (ctx->protocol == REQ_RESP_SERVER) { 05055 offset = keysLen; 05056 keysLen *= 2; 05057 05058 if (ctx->srvSt != ecSRV_RECV_REQ) 05059 return BAD_ENC_STATE_E; 05060 05061 ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ 05062 } 05063 else if (ctx->protocol == REQ_RESP_CLIENT) { 05064 if (ctx->cliSt != ecCLI_SALT_SET) 05065 return BAD_ENC_STATE_E; 05066 05067 ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */ 05068 } 05069 05070 if (keysLen > ECC_BUFSIZE) /* keys size */ 05071 return BUFFER_E; 05072 05073 if ( (msgSz%blockSz) != 0) 05074 return BAD_PADDING_E; 05075 05076 if (*outSz < (msgSz + digestSz)) 05077 return BUFFER_E; 05078 05079 #ifdef WOLFSSL_SMALL_STACK 05080 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05081 if (sharedSecret == NULL) 05082 return MEMORY_E; 05083 05084 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05085 if (keys == NULL) { 05086 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05087 return MEMORY_E; 05088 } 05089 #endif 05090 05091 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); 05092 05093 if (ret == 0) { 05094 switch (ctx->kdfAlgo) { 05095 case ecHKDF_SHA256 : 05096 ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt, 05097 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, 05098 keys, keysLen); 05099 break; 05100 05101 default: 05102 ret = BAD_FUNC_ARG; 05103 break; 05104 } 05105 } 05106 05107 if (ret == 0) { 05108 encKey = keys + offset; 05109 encIv = encKey + encKeySz; 05110 macKey = encKey + encKeySz + ivSz; 05111 05112 switch (ctx->encAlgo) { 05113 case ecAES_128_CBC: 05114 { 05115 Aes aes; 05116 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, 05117 AES_ENCRYPTION); 05118 if (ret != 0) 05119 break; 05120 ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz); 05121 } 05122 break; 05123 05124 default: 05125 ret = BAD_FUNC_ARG; 05126 break; 05127 } 05128 } 05129 05130 if (ret == 0) { 05131 switch (ctx->macAlgo) { 05132 case ecHMAC_SHA256: 05133 { 05134 Hmac hmac; 05135 ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); 05136 if (ret != 0) 05137 break; 05138 ret = wc_HmacUpdate(&hmac, out, msgSz); 05139 if (ret != 0) 05140 break; 05141 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); 05142 if (ret != 0) 05143 break; 05144 ret = wc_HmacFinal(&hmac, out+msgSz); 05145 } 05146 break; 05147 05148 default: 05149 ret = BAD_FUNC_ARG; 05150 break; 05151 } 05152 } 05153 05154 if (ret == 0) 05155 *outSz = msgSz + digestSz; 05156 05157 #ifdef WOLFSSL_SMALL_STACK 05158 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05159 XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05160 #endif 05161 05162 return ret; 05163 } 05164 05165 05166 /* ecc decrypt with shared secret run through kdf 05167 ctx holds non default algos and inputs 05168 return 0 on success */ 05169 int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, 05170 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) 05171 { 05172 int ret; 05173 word32 blockSz; 05174 word32 digestSz; 05175 ecEncCtx localCtx; 05176 #ifdef WOLFSSL_SMALL_STACK 05177 byte* sharedSecret; 05178 byte* keys; 05179 #else 05180 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ 05181 byte keys[ECC_BUFSIZE]; /* max size */ 05182 #endif 05183 word32 sharedSz = ECC_MAXSIZE; 05184 int keysLen; 05185 int encKeySz; 05186 int ivSz; 05187 int offset = 0; /* in case using msg exchange */ 05188 byte* encKey; 05189 byte* encIv; 05190 byte* macKey; 05191 05192 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || 05193 outSz == NULL) 05194 return BAD_FUNC_ARG; 05195 05196 if (ctx == NULL) { /* use defaults */ 05197 ecc_ctx_init(&localCtx, 0); 05198 ctx = &localCtx; 05199 } 05200 05201 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, 05202 &blockSz); 05203 if (ret != 0) 05204 return ret; 05205 05206 if (ctx->protocol == REQ_RESP_CLIENT) { 05207 offset = keysLen; 05208 keysLen *= 2; 05209 05210 if (ctx->cliSt != ecCLI_SENT_REQ) 05211 return BAD_ENC_STATE_E; 05212 05213 ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ 05214 } 05215 else if (ctx->protocol == REQ_RESP_SERVER) { 05216 if (ctx->srvSt != ecSRV_SALT_SET) 05217 return BAD_ENC_STATE_E; 05218 05219 ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */ 05220 } 05221 05222 if (keysLen > ECC_BUFSIZE) /* keys size */ 05223 return BUFFER_E; 05224 05225 if ( ((msgSz-digestSz) % blockSz) != 0) 05226 return BAD_PADDING_E; 05227 05228 if (*outSz < (msgSz - digestSz)) 05229 return BUFFER_E; 05230 05231 #ifdef WOLFSSL_SMALL_STACK 05232 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05233 if (sharedSecret == NULL) 05234 return MEMORY_E; 05235 05236 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05237 if (keys == NULL) { 05238 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05239 return MEMORY_E; 05240 } 05241 #endif 05242 05243 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); 05244 05245 if (ret == 0) { 05246 switch (ctx->kdfAlgo) { 05247 case ecHKDF_SHA256 : 05248 ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt, 05249 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, 05250 keys, keysLen); 05251 break; 05252 05253 default: 05254 ret = BAD_FUNC_ARG; 05255 break; 05256 } 05257 } 05258 05259 if (ret == 0) { 05260 encKey = keys + offset; 05261 encIv = encKey + encKeySz; 05262 macKey = encKey + encKeySz + ivSz; 05263 05264 switch (ctx->macAlgo) { 05265 case ecHMAC_SHA256: 05266 { 05267 byte verify[SHA256_DIGEST_SIZE]; 05268 Hmac hmac; 05269 ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); 05270 if (ret != 0) 05271 break; 05272 ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz); 05273 if (ret != 0) 05274 break; 05275 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); 05276 if (ret != 0) 05277 break; 05278 ret = wc_HmacFinal(&hmac, verify); 05279 if (ret != 0) 05280 break; 05281 if (memcmp(verify, msg + msgSz - digestSz, digestSz) != 0) 05282 ret = -1; 05283 } 05284 break; 05285 05286 default: 05287 ret = BAD_FUNC_ARG; 05288 break; 05289 } 05290 } 05291 05292 if (ret == 0) { 05293 switch (ctx->encAlgo) { 05294 #ifdef HAVE_AES_CBC 05295 case ecAES_128_CBC: 05296 { 05297 Aes aes; 05298 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, 05299 AES_DECRYPTION); 05300 if (ret != 0) 05301 break; 05302 ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz); 05303 } 05304 break; 05305 #endif 05306 default: 05307 ret = BAD_FUNC_ARG; 05308 break; 05309 } 05310 } 05311 05312 if (ret == 0) 05313 *outSz = msgSz - digestSz; 05314 05315 #ifdef WOLFSSL_SMALL_STACK 05316 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05317 XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER); 05318 #endif 05319 05320 return ret; 05321 } 05322 05323 05324 #endif /* HAVE_ECC_ENCRYPT */ 05325 05326 05327 #ifdef HAVE_COMP_KEY 05328 05329 /* computes the jacobi c = (a | n) (or Legendre if n is prime) 05330 * HAC pp. 73 Algorithm 2.149 05331 */ 05332 int mp_jacobi(mp_int* a, mp_int* p, int* c) 05333 { 05334 mp_int a1, p1; 05335 int k, s, r, res; 05336 mp_digit residue; 05337 05338 /* if p <= 0 return MP_VAL */ 05339 if (mp_cmp_d(p, 0) != MP_GT) { 05340 return MP_VAL; 05341 } 05342 05343 /* step 1. if a == 0, return 0 */ 05344 if (mp_iszero (a) == 1) { 05345 *c = 0; 05346 return MP_OKAY; 05347 } 05348 05349 /* step 2. if a == 1, return 1 */ 05350 if (mp_cmp_d (a, 1) == MP_EQ) { 05351 *c = 1; 05352 return MP_OKAY; 05353 } 05354 05355 /* default */ 05356 s = 0; 05357 05358 /* step 3. write a = a1 * 2**k */ 05359 if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { 05360 return res; 05361 } 05362 05363 if ((res = mp_init (&p1)) != MP_OKAY) { 05364 mp_clear(&a1); 05365 return res; 05366 } 05367 05368 /* divide out larger power of two */ 05369 k = mp_cnt_lsb(&a1); 05370 res = mp_div_2d(&a1, k, &a1, NULL); 05371 05372 if (res == MP_OKAY) { 05373 /* step 4. if e is even set s=1 */ 05374 if ((k & 1) == 0) { 05375 s = 1; 05376 } else { 05377 /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ 05378 residue = p->dp[0] & 7; 05379 05380 if (residue == 1 || residue == 7) { 05381 s = 1; 05382 } else if (residue == 3 || residue == 5) { 05383 s = -1; 05384 } 05385 } 05386 05387 /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ 05388 if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { 05389 s = -s; 05390 } 05391 } 05392 05393 if (res == MP_OKAY) { 05394 /* if a1 == 1 we're done */ 05395 if (mp_cmp_d (&a1, 1) == MP_EQ) { 05396 *c = s; 05397 } else { 05398 /* n1 = n mod a1 */ 05399 res = mp_mod (p, &a1, &p1); 05400 if (res == MP_OKAY) 05401 res = mp_jacobi (&p1, &a1, &r); 05402 05403 if (res == MP_OKAY) 05404 *c = s * r; 05405 } 05406 } 05407 05408 /* done */ 05409 mp_clear (&p1); 05410 mp_clear (&a1); 05411 05412 return res; 05413 } 05414 05415 05416 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) 05417 { 05418 int res, legendre, done = 0; 05419 mp_int t1, C, Q, S, Z, M, T, R, two; 05420 mp_digit i; 05421 05422 /* first handle the simple cases */ 05423 if (mp_cmp_d(n, 0) == MP_EQ) { 05424 mp_zero(ret); 05425 return MP_OKAY; 05426 } 05427 if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */ 05428 /* TAO removed 05429 if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; 05430 if (legendre == -1) return MP_VAL; */ /* quadratic non-residue mod prime */ 05431 05432 if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY) 05433 return res; 05434 05435 if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL)) 05436 != MP_OKAY) { 05437 mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z); 05438 mp_clear(&M); 05439 return res; 05440 } 05441 05442 /* SPECIAL CASE: if prime mod 4 == 3 05443 * compute directly: res = n^(prime+1)/4 mod prime 05444 * Handbook of Applied Cryptography algorithm 3.36 05445 */ 05446 res = mp_mod_d(prime, 4, &i); 05447 if (res == MP_OKAY && i == 3) { 05448 res = mp_add_d(prime, 1, &t1); 05449 05450 if (res == MP_OKAY) 05451 res = mp_div_2(&t1, &t1); 05452 if (res == MP_OKAY) 05453 res = mp_div_2(&t1, &t1); 05454 if (res == MP_OKAY) 05455 res = mp_exptmod(n, &t1, prime, ret); 05456 05457 done = 1; 05458 } 05459 05460 /* NOW: TonelliShanks algorithm */ 05461 05462 if (res == MP_OKAY && done == 0) { 05463 05464 /* factor out powers of 2 from prime-1, defining Q and S 05465 * as: prime-1 = Q*2^S */ 05466 res = mp_copy(prime, &Q); 05467 if (res == MP_OKAY) 05468 res = mp_sub_d(&Q, 1, &Q); 05469 /* Q = prime - 1 */ 05470 if (res == MP_OKAY) 05471 mp_zero(&S); 05472 /* S = 0 */ 05473 while (res == MP_OKAY && mp_iseven(&Q)) { 05474 res = mp_div_2(&Q, &Q); 05475 /* Q = Q / 2 */ 05476 if (res == MP_OKAY) 05477 res = mp_add_d(&S, 1, &S); 05478 /* S = S + 1 */ 05479 } 05480 05481 /* find a Z such that the Legendre symbol (Z|prime) == -1 */ 05482 if (res == MP_OKAY) 05483 res = mp_set_int(&Z, 2); 05484 /* Z = 2 */ 05485 while (res == MP_OKAY) { 05486 res = mp_jacobi(&Z, prime, &legendre); 05487 if (res == MP_OKAY && legendre == -1) 05488 break; 05489 if (res == MP_OKAY) 05490 res = mp_add_d(&Z, 1, &Z); 05491 /* Z = Z + 1 */ 05492 } 05493 05494 if (res == MP_OKAY) 05495 res = mp_exptmod(&Z, &Q, prime, &C); 05496 /* C = Z ^ Q mod prime */ 05497 if (res == MP_OKAY) 05498 res = mp_add_d(&Q, 1, &t1); 05499 if (res == MP_OKAY) 05500 res = mp_div_2(&t1, &t1); 05501 /* t1 = (Q + 1) / 2 */ 05502 if (res == MP_OKAY) 05503 res = mp_exptmod(n, &t1, prime, &R); 05504 /* R = n ^ ((Q + 1) / 2) mod prime */ 05505 if (res == MP_OKAY) 05506 res = mp_exptmod(n, &Q, prime, &T); 05507 /* T = n ^ Q mod prime */ 05508 if (res == MP_OKAY) 05509 res = mp_copy(&S, &M); 05510 /* M = S */ 05511 if (res == MP_OKAY) 05512 res = mp_set_int(&two, 2); 05513 05514 while (res == MP_OKAY && done == 0) { 05515 res = mp_copy(&T, &t1); 05516 i = 0; 05517 while (res == MP_OKAY) { 05518 if (mp_cmp_d(&t1, 1) == MP_EQ) 05519 break; 05520 res = mp_exptmod(&t1, &two, prime, &t1); 05521 if (res == MP_OKAY) 05522 i++; 05523 } 05524 if (res == MP_OKAY && i == 0) { 05525 mp_copy(&R, ret); 05526 res = MP_OKAY; 05527 done = 1; 05528 } 05529 05530 if (done == 0) { 05531 if (res == MP_OKAY) 05532 res = mp_sub_d(&M, i, &t1); 05533 if (res == MP_OKAY) 05534 res = mp_sub_d(&t1, 1, &t1); 05535 if (res == MP_OKAY) 05536 res = mp_exptmod(&two, &t1, prime, &t1); 05537 /* t1 = 2 ^ (M - i - 1) */ 05538 if (res == MP_OKAY) 05539 res = mp_exptmod(&C, &t1, prime, &t1); 05540 /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ 05541 if (res == MP_OKAY) 05542 res = mp_sqrmod(&t1, prime, &C); 05543 /* C = (t1 * t1) mod prime */ 05544 if (res == MP_OKAY) 05545 res = mp_mulmod(&R, &t1, prime, &R); 05546 /* R = (R * t1) mod prime */ 05547 if (res == MP_OKAY) 05548 res = mp_mulmod(&T, &C, prime, &T); 05549 /* T = (T * C) mod prime */ 05550 if (res == MP_OKAY) 05551 mp_set(&M, i); 05552 /* M = i */ 05553 } 05554 } 05555 } 05556 05557 /* done */ 05558 mp_clear(&t1); 05559 mp_clear(&C); 05560 mp_clear(&Q); 05561 mp_clear(&S); 05562 mp_clear(&Z); 05563 mp_clear(&M); 05564 mp_clear(&T); 05565 mp_clear(&R); 05566 mp_clear(&two); 05567 05568 return res; 05569 } 05570 05571 05572 /* export public ECC key in ANSI X9.63 format compressed */ 05573 int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen) 05574 { 05575 word32 numlen; 05576 int ret = MP_OKAY; 05577 05578 if (key == NULL || out == NULL || outLen == NULL) 05579 return ECC_BAD_ARG_E; 05580 05581 if (wc_ecc_is_valid_idx(key->idx) == 0) { 05582 return ECC_BAD_ARG_E; 05583 } 05584 numlen = key->dp->size; 05585 05586 if (*outLen < (1 + numlen)) { 05587 *outLen = 1 + numlen; 05588 return BUFFER_E; 05589 } 05590 05591 /* store first byte */ 05592 out[0] = mp_isodd(key->pubkey.y) ? 0x03 : 0x02; 05593 05594 /* pad and store x */ 05595 XMEMSET(out+1, 0, numlen); 05596 ret = mp_to_unsigned_bin(key->pubkey.x, 05597 out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x))); 05598 *outLen = 1 + numlen; 05599 return ret; 05600 } 05601 05602 05603 /* d = a - b (mod c) */ 05604 int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d) 05605 { 05606 int res; 05607 mp_int t; 05608 05609 if ((res = mp_init (&t)) != MP_OKAY) { 05610 return res; 05611 } 05612 05613 if ((res = mp_sub (a, b, &t)) != MP_OKAY) { 05614 mp_clear (&t); 05615 return res; 05616 } 05617 res = mp_mod (&t, c, d); 05618 mp_clear (&t); 05619 05620 return res; 05621 } 05622 05623 05624 #endif /* HAVE_COMP_KEY */ 05625 05626 #endif /* HAVE_ECC */ 05627
Generated on Tue Jul 12 2022 15:55:18 by
1.7.2