Renesas / SecureDweet
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ecc.c Source File

ecc.c

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