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