wolf SSL / CyaSSL

Dependents:   HTTPClient-SSL HTTPClient HTTPClient-SSL http_access ... more

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