wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ecc.c Source File

ecc.c

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