Xuyi Wang / wolfcrypt

Dependents:   OS

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-2017 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 <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 #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
00097     /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
00098     #define FIPS_NO_WRAPPERS
00099 
00100     #ifdef USE_WINDOWS_API
00101         #pragma code_seg(".fipsA$f")
00102         #pragma const_seg(".fipsB$f")
00103     #endif
00104 #endif
00105 
00106 #include <wolfcrypt/ecc.h>
00107 #include <wolfcrypt/asn.h>
00108 #include <wolfcrypt/error-crypt.h>
00109 #include <wolfcrypt/logging.h>
00110 #include <wolfcrypt/types.h>
00111 
00112 #ifdef WOLFSSL_HAVE_SP_ECC
00113 #include <wolfcrypt/sp.h>
00114 #endif
00115 
00116 #ifdef HAVE_ECC_ENCRYPT
00117     #include <wolfcrypt/hmac.h>
00118     #include <wolfcrypt/aes.h>
00119 #endif
00120 
00121 #ifdef HAVE_X963_KDF
00122     #include <wolfcrypt/hash.h>
00123 #endif
00124 
00125 #ifdef WOLF_CRYPTO_DEV
00126     #include <wolfcrypt/cryptodev.h>
00127 #endif
00128 
00129 #ifdef NO_INLINE
00130     #include <wolfcrypt/misc.h>
00131 #else
00132     #define WOLFSSL_MISC_INCLUDED
00133     #include <wolfcrypt/src/misc.c>
00134 #endif
00135 
00136 #if defined(FREESCALE_LTC_ECC)
00137     #include <wolfcrypt/port/nxp/ksdk_port.h>
00138 #endif
00139 
00140 #ifdef WOLFSSL_SP_MATH
00141     #define GEN_MEM_ERR MP_MEM
00142 #elif defined(USE_FAST_MATH)
00143     #define GEN_MEM_ERR FP_MEM
00144 #else
00145     #define GEN_MEM_ERR MP_MEM
00146 #endif
00147 
00148 
00149 /* internal ECC states */
00150 enum {
00151     ECC_STATE_NONE = 0,
00152 
00153     ECC_STATE_SHARED_SEC_GEN,
00154     ECC_STATE_SHARED_SEC_RES,
00155 
00156     ECC_STATE_SIGN_DO,
00157     ECC_STATE_SIGN_ENCODE,
00158 
00159     ECC_STATE_VERIFY_DECODE,
00160     ECC_STATE_VERIFY_DO,
00161     ECC_STATE_VERIFY_RES,
00162 };
00163 
00164 
00165 /* map
00166    ptmul -> mulmod
00167 */
00168 
00169 /* 256-bit curve on by default whether user curves or not */
00170 #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)
00171     #define ECC112
00172 #endif
00173 #if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)
00174     #define ECC128
00175 #endif
00176 #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
00177     #define ECC160
00178 #endif
00179 #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
00180     #define ECC192
00181 #endif
00182 #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
00183     #define ECC224
00184 #endif
00185 #if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)
00186     #define ECC239
00187 #endif
00188 #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
00189     #define ECC256
00190 #endif
00191 #if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)
00192     #define ECC320
00193 #endif
00194 #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
00195     #define ECC384
00196 #endif
00197 #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
00198     #define ECC512
00199 #endif
00200 #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
00201     #define ECC521
00202 #endif
00203 
00204 /* The encoded OID's for ECC curves */
00205 #ifdef ECC112
00206     #ifndef NO_ECC_SECP
00207         #ifdef HAVE_OID_ENCODING
00208             #define CODED_SECP112R1    {1,3,132,0,6}
00209             #define CODED_SECP112R1_SZ 5
00210         #else
00211             #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
00212             #define CODED_SECP112R1_SZ 5
00213         #endif
00214         #ifndef USE_WINDOWS_API
00215             static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
00216         #else
00217             #define ecc_oid_secp112r1 CODED_SECP112R1
00218         #endif
00219         #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
00220     #endif /* !NO_ECC_SECP */
00221     #ifdef HAVE_ECC_SECPR2
00222         #ifdef HAVE_OID_ENCODING
00223             #define CODED_SECP112R2    {1,3,132,0,7}
00224             #define CODED_SECP112R2_SZ 5
00225         #else
00226             #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
00227             #define CODED_SECP112R2_SZ 5
00228         #endif
00229         #ifndef USE_WINDOWS_API
00230             static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
00231         #else
00232             #define ecc_oid_secp112r2 CODED_SECP112R2
00233         #endif
00234         #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
00235     #endif /* HAVE_ECC_SECPR2 */
00236 #endif /* ECC112 */
00237 #ifdef ECC128
00238     #ifndef NO_ECC_SECP
00239         #ifdef HAVE_OID_ENCODING
00240             #define CODED_SECP128R1    {1,3,132,0,28}
00241             #define CODED_SECP128R1_SZ 5
00242         #else
00243             #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
00244             #define CODED_SECP128R1_SZ 5
00245         #endif
00246         #ifndef USE_WINDOWS_API
00247             static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
00248         #else
00249             #define ecc_oid_secp128r1 CODED_SECP128R1
00250         #endif
00251         #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
00252     #endif /* !NO_ECC_SECP */
00253     #ifdef HAVE_ECC_SECPR2
00254         #ifdef HAVE_OID_ENCODING
00255             #define CODED_SECP128R2    {1,3,132,0,29}
00256             #define CODED_SECP128R2_SZ 5
00257         #else
00258             #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
00259             #define CODED_SECP128R2_SZ 5
00260         #endif
00261         #ifndef USE_WINDOWS_API
00262             static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
00263         #else
00264             #define ecc_oid_secp128r2 CODED_SECP128R2
00265         #endif
00266         #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
00267     #endif /* HAVE_ECC_SECPR2 */
00268 #endif /* ECC128 */
00269 #ifdef ECC160
00270     #ifndef NO_ECC_SECP
00271         #ifdef HAVE_OID_ENCODING
00272             #define CODED_SECP160R1    {1,3,132,0,8}
00273             #define CODED_SECP160R1_SZ 5
00274         #else
00275             #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
00276             #define CODED_SECP160R1_SZ 5
00277         #endif
00278         #ifndef USE_WINDOWS_API
00279             static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
00280         #else
00281             #define ecc_oid_secp160r1 CODED_SECP160R1
00282         #endif
00283         #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
00284     #endif /* !NO_ECC_SECP */
00285     #ifdef HAVE_ECC_SECPR2
00286         #ifdef HAVE_OID_ENCODING
00287             #define CODED_SECP160R2    {1,3,132,0,30}
00288             #define CODED_SECP160R1_SZ 5
00289         #else
00290             #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
00291             #define CODED_SECP160R2_SZ 5
00292         #endif
00293         #ifndef USE_WINDOWS_API
00294             static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
00295         #else
00296             #define ecc_oid_secp160r2 CODED_SECP160R2
00297         #endif
00298         #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
00299     #endif /* HAVE_ECC_SECPR2 */
00300     #ifdef HAVE_ECC_KOBLITZ
00301         #ifdef HAVE_OID_ENCODING
00302             #define CODED_SECP160K1    {1,3,132,0,9}
00303             #define CODED_SECP160K1_SZ 5
00304         #else
00305             #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
00306             #define CODED_SECP160K1_SZ 5
00307         #endif
00308         #ifndef USE_WINDOWS_API
00309             static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
00310         #else
00311             #define ecc_oid_secp160k1 CODED_SECP160K1
00312         #endif
00313         #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
00314     #endif /* HAVE_ECC_KOBLITZ */
00315     #ifdef HAVE_ECC_BRAINPOOL
00316         #ifdef HAVE_OID_ENCODING
00317             #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
00318             #define CODED_BRAINPOOLP160R1_SZ 10
00319         #else
00320             #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
00321             #define CODED_BRAINPOOLP160R1_SZ 9
00322         #endif
00323         #ifndef USE_WINDOWS_API
00324             static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
00325         #else
00326             #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
00327         #endif
00328         #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
00329     #endif /* HAVE_ECC_BRAINPOOL */
00330 #endif /* ECC160 */
00331 #ifdef ECC192
00332     #ifndef NO_ECC_SECP
00333         #ifdef HAVE_OID_ENCODING
00334             #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
00335             #define CODED_SECP192R1_SZ 7
00336         #else
00337             #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
00338             #define CODED_SECP192R1_SZ 8
00339         #endif
00340         #ifndef USE_WINDOWS_API
00341             static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
00342         #else
00343             #define ecc_oid_secp192r1 CODED_SECP192R1
00344         #endif
00345         #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
00346     #endif /* !NO_ECC_SECP */
00347     #ifdef HAVE_ECC_SECPR2
00348         #ifdef HAVE_OID_ENCODING
00349             #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
00350             #define CODED_PRIME192V2_SZ 7
00351         #else
00352             #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
00353             #define CODED_PRIME192V2_SZ 8
00354         #endif
00355         #ifndef USE_WINDOWS_API
00356             static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
00357         #else
00358             #define ecc_oid_prime192v2 CODED_PRIME192V2
00359         #endif
00360         #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
00361     #endif /* HAVE_ECC_SECPR2 */
00362     #ifdef HAVE_ECC_SECPR3
00363         #ifdef HAVE_OID_ENCODING
00364             #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
00365             #define CODED_PRIME192V3_SZ 7
00366         #else
00367             #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
00368             #define CODED_PRIME192V3_SZ 8
00369         #endif
00370         #ifndef USE_WINDOWS_API
00371             static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
00372         #else
00373             #define ecc_oid_prime192v3 CODED_PRIME192V3
00374         #endif
00375         #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
00376     #endif /* HAVE_ECC_SECPR3 */
00377     #ifdef HAVE_ECC_KOBLITZ
00378         #ifdef HAVE_OID_ENCODING
00379             #define CODED_SECP192K1    {1,3,132,0,31}
00380             #define CODED_SECP192K1_SZ 5
00381         #else
00382             #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
00383             #define CODED_SECP192K1_SZ 5
00384         #endif
00385         #ifndef USE_WINDOWS_API
00386             static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
00387         #else
00388             #define ecc_oid_secp192k1 CODED_SECP192K1
00389         #endif
00390         #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
00391     #endif /* HAVE_ECC_KOBLITZ */
00392     #ifdef HAVE_ECC_BRAINPOOL
00393         #ifdef HAVE_OID_ENCODING
00394             #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
00395             #define CODED_BRAINPOOLP192R1_SZ 10
00396         #else
00397             #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
00398             #define CODED_BRAINPOOLP192R1_SZ 9
00399         #endif
00400         #ifndef USE_WINDOWS_API
00401             static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
00402         #else
00403             #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
00404         #endif
00405         #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
00406     #endif /* HAVE_ECC_BRAINPOOL */
00407 #endif /* ECC192 */
00408 #ifdef ECC224
00409     #ifndef NO_ECC_SECP
00410         #ifdef HAVE_OID_ENCODING
00411             #define CODED_SECP224R1    {1,3,132,0,33}
00412             #define CODED_SECP224R1_SZ 5
00413         #else
00414             #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
00415             #define CODED_SECP224R1_SZ 5
00416         #endif
00417         #ifndef USE_WINDOWS_API
00418             static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
00419         #else
00420             #define ecc_oid_secp224r1 CODED_SECP224R1
00421         #endif
00422         #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
00423     #endif /* !NO_ECC_SECP */
00424     #ifdef HAVE_ECC_KOBLITZ
00425         #ifdef HAVE_OID_ENCODING
00426             #define CODED_SECP224K1    {1,3,132,0,32}
00427             #define CODED_SECP224K1_SZ 5
00428         #else
00429             #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
00430             #define CODED_SECP224K1_SZ 5
00431         #endif
00432         #ifndef USE_WINDOWS_API
00433             static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
00434         #else
00435             #define ecc_oid_secp224k1 CODED_SECP224K1
00436         #endif
00437         #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
00438     #endif /* HAVE_ECC_KOBLITZ */
00439     #ifdef HAVE_ECC_BRAINPOOL
00440         #ifdef HAVE_OID_ENCODING
00441             #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
00442             #define CODED_BRAINPOOLP224R1_SZ 10
00443         #else
00444             #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
00445             #define CODED_BRAINPOOLP224R1_SZ 9
00446         #endif
00447         #ifndef USE_WINDOWS_API
00448             static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
00449         #else
00450             #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
00451         #endif
00452         #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
00453     #endif /* HAVE_ECC_BRAINPOOL */
00454 #endif /* ECC224 */
00455 #ifdef ECC239
00456     #ifndef NO_ECC_SECP
00457         #ifdef HAVE_OID_ENCODING
00458             #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
00459             #define CODED_PRIME239V1_SZ 7
00460         #else
00461             #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
00462             #define CODED_PRIME239V1_SZ 8
00463         #endif
00464         #ifndef USE_WINDOWS_API
00465             static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
00466         #else
00467             #define ecc_oid_prime239v1 CODED_PRIME239V1
00468         #endif
00469         #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
00470     #endif /* !NO_ECC_SECP */
00471     #ifdef HAVE_ECC_SECPR2
00472         #ifdef HAVE_OID_ENCODING
00473             #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
00474             #define CODED_PRIME239V2_SZ 7
00475         #else
00476             #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
00477             #define CODED_PRIME239V2_SZ 8
00478         #endif
00479         #ifndef USE_WINDOWS_API
00480             static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
00481         #else
00482             #define ecc_oid_prime239v2 CODED_PRIME239V2
00483         #endif
00484         #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
00485     #endif /* HAVE_ECC_SECPR2 */
00486     #ifdef HAVE_ECC_SECPR3
00487         #ifdef HAVE_OID_ENCODING
00488             #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
00489             #define CODED_PRIME239V3_SZ 7
00490         #else
00491             #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
00492             #define CODED_PRIME239V3_SZ 8
00493         #endif
00494         #ifndef USE_WINDOWS_API
00495             static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
00496         #else
00497             #define ecc_oid_prime239v3 CODED_PRIME239V3
00498         #endif
00499         #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
00500     #endif /* HAVE_ECC_SECPR3 */
00501 #endif /* ECC239 */
00502 #ifdef ECC256
00503     #ifndef NO_ECC_SECP
00504         #ifdef HAVE_OID_ENCODING
00505             #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
00506             #define CODED_SECP256R1_SZ 7
00507         #else
00508             #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
00509             #define CODED_SECP256R1_SZ 8
00510         #endif
00511         #ifndef USE_WINDOWS_API
00512             static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
00513         #else
00514             #define ecc_oid_secp256r1 CODED_SECP256R1
00515         #endif
00516         #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
00517     #endif /* !NO_ECC_SECP */
00518     #ifdef HAVE_ECC_KOBLITZ
00519         #ifdef HAVE_OID_ENCODING
00520             #define CODED_SECP256K1    {1,3,132,0,10}
00521             #define CODED_SECP256K1_SZ 5
00522         #else
00523             #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
00524             #define CODED_SECP256K1_SZ 5
00525         #endif
00526         #ifndef USE_WINDOWS_API
00527             static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
00528         #else
00529             #define ecc_oid_secp256k1 CODED_SECP256K1
00530         #endif
00531         #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
00532     #endif /* HAVE_ECC_KOBLITZ */
00533     #ifdef HAVE_ECC_BRAINPOOL
00534         #ifdef HAVE_OID_ENCODING
00535             #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
00536             #define CODED_BRAINPOOLP256R1_SZ 10
00537         #else
00538             #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
00539             #define CODED_BRAINPOOLP256R1_SZ 9
00540         #endif
00541         #ifndef USE_WINDOWS_API
00542             static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
00543         #else
00544             #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
00545         #endif
00546         #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
00547     #endif /* HAVE_ECC_BRAINPOOL */
00548 #endif /* ECC256 */
00549 #ifdef ECC320
00550     #ifdef HAVE_ECC_BRAINPOOL
00551         #ifdef HAVE_OID_ENCODING
00552             #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
00553             #define CODED_BRAINPOOLP320R1_SZ 10
00554         #else
00555             #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
00556             #define CODED_BRAINPOOLP320R1_SZ 9
00557         #endif
00558         #ifndef USE_WINDOWS_API
00559             static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
00560         #else
00561             #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
00562         #endif
00563         #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
00564     #endif /* HAVE_ECC_BRAINPOOL */
00565 #endif /* ECC320 */
00566 #ifdef ECC384
00567     #ifndef NO_ECC_SECP
00568         #ifdef HAVE_OID_ENCODING
00569             #define CODED_SECP384R1    {1,3,132,0,34}
00570             #define CODED_SECP384R1_SZ 5
00571         #else
00572             #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
00573             #define CODED_SECP384R1_SZ 5
00574         #endif
00575         #ifndef USE_WINDOWS_API
00576             static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
00577             #define CODED_SECP384R1_OID ecc_oid_secp384r1
00578         #else
00579             #define ecc_oid_secp384r1 CODED_SECP384R1
00580         #endif
00581         #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
00582     #endif /* !NO_ECC_SECP */
00583     #ifdef HAVE_ECC_BRAINPOOL
00584         #ifdef HAVE_OID_ENCODING
00585             #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
00586             #define CODED_BRAINPOOLP384R1_SZ 10
00587         #else
00588             #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
00589             #define CODED_BRAINPOOLP384R1_SZ 9
00590         #endif
00591         #ifndef USE_WINDOWS_API
00592             static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
00593         #else
00594             #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
00595         #endif
00596         #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
00597     #endif /* HAVE_ECC_BRAINPOOL */
00598 #endif /* ECC384 */
00599 #ifdef ECC512
00600     #ifdef HAVE_ECC_BRAINPOOL
00601         #ifdef HAVE_OID_ENCODING
00602             #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
00603             #define CODED_BRAINPOOLP512R1_SZ 10
00604         #else
00605             #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
00606             #define CODED_BRAINPOOLP512R1_SZ 9
00607         #endif
00608         #ifndef USE_WINDOWS_API
00609             static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
00610         #else
00611             #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
00612         #endif
00613         #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
00614     #endif /* HAVE_ECC_BRAINPOOL */
00615 #endif /* ECC512 */
00616 #ifdef ECC521
00617     #ifndef NO_ECC_SECP
00618         #ifdef HAVE_OID_ENCODING
00619             #define CODED_SECP521R1     {1,3,132,0,35}
00620             #define CODED_SECP521R1_SZ 5
00621         #else
00622             #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
00623             #define CODED_SECP521R1_SZ 5
00624         #endif
00625         #ifndef USE_WINDOWS_API
00626             static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
00627         #else
00628             #define ecc_oid_secp521r1 CODED_SECP521R1
00629         #endif
00630         #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
00631     #endif /* !NO_ECC_SECP */
00632 #endif /* ECC521 */
00633 
00634 
00635 /* This holds the key settings.
00636    ***MUST*** be organized by size from smallest to largest. */
00637 
00638 const ecc_set_type ecc_sets[] = {
00639 #ifdef ECC112
00640     #ifndef NO_ECC_SECP
00641     {
00642         14,                             /* size/bytes */
00643         ECC_SECP112R1,                  /* ID         */
00644         "SECP112R1",                    /* curve name */
00645         "DB7C2ABF62E35E668076BEAD208B", /* prime      */
00646         "DB7C2ABF62E35E668076BEAD2088", /* A          */
00647         "659EF8BA043916EEDE8911702B22", /* B          */
00648         "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
00649         "9487239995A5EE76B55F9C2F098",  /* Gx         */
00650         "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
00651         ecc_oid_secp112r1,              /* oid/oidSz  */
00652         ecc_oid_secp112r1_sz,
00653         ECC_SECP112R1_OID,              /* oid sum    */
00654         1,                              /* cofactor   */
00655     },
00656     #endif /* !NO_ECC_SECP */
00657     #ifdef HAVE_ECC_SECPR2
00658     {
00659         14,                             /* size/bytes */
00660         ECC_SECP112R2,                  /* ID         */
00661         "SECP112R2",                    /* curve name */
00662         "DB7C2ABF62E35E668076BEAD208B", /* prime      */
00663         "6127C24C05F38A0AAAF65C0EF02C", /* A          */
00664         "51DEF1815DB5ED74FCC34C85D709", /* B          */
00665         "36DF0AAFD8B8D7597CA10520D04B", /* order      */
00666         "4BA30AB5E892B4E1649DD0928643", /* Gx         */
00667         "ADCD46F5882E3747DEF36E956E97", /* Gy         */
00668         ecc_oid_secp112r2,              /* oid/oidSz  */
00669         ecc_oid_secp112r2_sz,
00670         ECC_SECP112R2_OID,              /* oid sum    */
00671         4,                              /* cofactor   */
00672     },
00673     #endif /* HAVE_ECC_SECPR2 */
00674 #endif /* ECC112 */
00675 #ifdef ECC128
00676     #ifndef NO_ECC_SECP
00677     {
00678         16,                                 /* size/bytes */
00679         ECC_SECP128R1,                      /* ID         */
00680         "SECP128R1",                        /* curve name */
00681         "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
00682         "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
00683         "E87579C11079F43DD824993C2CEE5ED3", /* B          */
00684         "FFFFFFFE0000000075A30D1B9038A115", /* order      */
00685         "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
00686         "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
00687         ecc_oid_secp128r1,                  /* oid/oidSz  */
00688         ecc_oid_secp128r1_sz,
00689         ECC_SECP128R1_OID,                  /* oid sum    */
00690         1,                                  /* cofactor   */
00691     },
00692     #endif /* !NO_ECC_SECP */
00693     #ifdef HAVE_ECC_SECPR2
00694     {
00695         16,                                 /* size/bytes */
00696         ECC_SECP128R2,                      /* ID         */
00697         "SECP128R2",                        /* curve name */
00698         "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
00699         "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
00700         "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
00701         "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
00702         "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
00703         "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
00704         ecc_oid_secp128r2,                  /* oid/oidSz  */
00705         ecc_oid_secp128r2_sz,
00706         ECC_SECP128R2_OID,                  /* oid sum    */
00707         4,                                  /* cofactor   */
00708     },
00709     #endif /* HAVE_ECC_SECPR2 */
00710 #endif /* ECC128 */
00711 #ifdef ECC160
00712     #ifndef NO_ECC_SECP
00713     {
00714         20,                                         /* size/bytes */
00715         ECC_SECP160R1,                              /* ID         */
00716         "SECP160R1",                                /* curve name */
00717         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
00718         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
00719         "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
00720         "100000000000000000001F4C8F927AED3CA752257",/* order      */
00721         "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
00722         "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
00723         ecc_oid_secp160r1,                          /* oid/oidSz  */
00724         ecc_oid_secp160r1_sz,
00725         ECC_SECP160R1_OID,                          /* oid sum    */
00726         1,                                          /* cofactor   */
00727     },
00728     #endif /* !NO_ECC_SECP */
00729     #ifdef HAVE_ECC_SECPR2
00730     {
00731         20,                                         /* size/bytes */
00732         ECC_SECP160R2,                              /* ID         */
00733         "SECP160R2",                                /* curve name */
00734         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
00735         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
00736         "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
00737         "100000000000000000000351EE786A818F3A1A16B",/* order      */
00738         "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
00739         "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
00740         ecc_oid_secp160r2,                          /* oid/oidSz  */
00741         ecc_oid_secp160r2_sz,
00742         ECC_SECP160R2_OID,                          /* oid sum    */
00743         1,                                          /* cofactor   */
00744     },
00745     #endif /* HAVE_ECC_SECPR2 */
00746     #ifdef HAVE_ECC_KOBLITZ
00747     {
00748         20,                                         /* size/bytes */
00749         ECC_SECP160K1,                              /* ID         */
00750         "SECP160K1",                                /* curve name */
00751         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
00752         "0000000000000000000000000000000000000000", /* A          */
00753         "0000000000000000000000000000000000000007", /* B          */
00754         "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
00755         "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
00756         "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
00757         ecc_oid_secp160k1,                          /* oid/oidSz  */
00758         ecc_oid_secp160k1_sz,
00759         ECC_SECP160K1_OID,                          /* oid sum    */
00760         1,                                          /* cofactor   */
00761     },
00762     #endif /* HAVE_ECC_KOBLITZ */
00763     #ifdef HAVE_ECC_BRAINPOOL
00764     {
00765         20,                                         /* size/bytes */
00766         ECC_BRAINPOOLP160R1,                        /* ID         */
00767         "BRAINPOOLP160R1",                          /* curve name */
00768         "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
00769         "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
00770         "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
00771         "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
00772         "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
00773         "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
00774         ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
00775         ecc_oid_brainpoolp160r1_sz,
00776         ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
00777         1,                                          /* cofactor   */
00778     },
00779     #endif /* HAVE_ECC_BRAINPOOL */
00780 #endif /* ECC160 */
00781 #ifdef ECC192
00782     #ifndef NO_ECC_SECP
00783     {
00784         24,                                                 /* size/bytes */
00785         ECC_SECP192R1,                                      /* ID         */
00786         "SECP192R1",                                        /* curve name */
00787         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
00788         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
00789         "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
00790         "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
00791         "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
00792         "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
00793         ecc_oid_secp192r1,                                  /* oid/oidSz  */
00794         ecc_oid_secp192r1_sz,
00795         ECC_SECP192R1_OID,                                  /* oid sum    */
00796         1,                                                  /* cofactor   */
00797     },
00798     #endif /* !NO_ECC_SECP */
00799     #ifdef HAVE_ECC_SECPR2
00800     {
00801         24,                                                 /* size/bytes */
00802         ECC_PRIME192V2,                                     /* ID         */
00803         "PRIME192V2",                                       /* curve name */
00804         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
00805         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
00806         "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
00807         "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
00808         "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
00809         "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
00810         ecc_oid_prime192v2,                                 /* oid/oidSz  */
00811         ecc_oid_prime192v2_sz,
00812         ECC_PRIME192V2_OID,                                 /* oid sum    */
00813         1,                                                  /* cofactor   */
00814     },
00815     #endif /* HAVE_ECC_SECPR2 */
00816     #ifdef HAVE_ECC_SECPR3
00817     {
00818         24,                                                 /* size/bytes */
00819         ECC_PRIME192V3,                                     /* ID         */
00820         "PRIME192V3",                                       /* curve name */
00821         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
00822         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
00823         "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
00824         "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
00825         "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
00826         "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
00827         ecc_oid_prime192v3,                                 /* oid/oidSz  */
00828         ecc_oid_prime192v3_sz,
00829         ECC_PRIME192V3_OID,                                 /* oid sum    */
00830         1,                                                  /* cofactor   */
00831     },
00832     #endif /* HAVE_ECC_SECPR3 */
00833     #ifdef HAVE_ECC_KOBLITZ
00834     {
00835         24,                                                 /* size/bytes */
00836         ECC_SECP192K1,                                      /* ID         */
00837         "SECP192K1",                                        /* curve name */
00838         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
00839         "000000000000000000000000000000000000000000000000", /* A          */
00840         "000000000000000000000000000000000000000000000003", /* B          */
00841         "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
00842         "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
00843         "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
00844         ecc_oid_secp192k1,                                  /* oid/oidSz  */
00845         ecc_oid_secp192k1_sz,
00846         ECC_SECP192K1_OID,                                  /* oid sum    */
00847         1,                                                  /* cofactor   */
00848     },
00849     #endif /* HAVE_ECC_KOBLITZ */
00850     #ifdef HAVE_ECC_BRAINPOOL
00851     {
00852         24,                                                 /* size/bytes */
00853         ECC_BRAINPOOLP192R1,                                /* ID         */
00854         "BRAINPOOLP192R1",                                  /* curve name */
00855         "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
00856         "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
00857         "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
00858         "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
00859         "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
00860         "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
00861         ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
00862         ecc_oid_brainpoolp192r1_sz,
00863         ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
00864         1,                                                  /* cofactor   */
00865     },
00866     #endif /* HAVE_ECC_BRAINPOOL */
00867 #endif /* ECC192 */
00868 #ifdef ECC224
00869     #ifndef NO_ECC_SECP
00870     {
00871         28,                                                         /* size/bytes */
00872         ECC_SECP224R1,                                              /* ID         */
00873         "SECP224R1",                                                /* curve name */
00874         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
00875         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
00876         "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
00877         "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
00878         "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
00879         "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
00880         ecc_oid_secp224r1,                                          /* oid/oidSz  */
00881         ecc_oid_secp224r1_sz,
00882         ECC_SECP224R1_OID,                                          /* oid sum    */
00883         1,                                                          /* cofactor   */
00884     },
00885     #endif /* !NO_ECC_SECP */
00886     #ifdef HAVE_ECC_KOBLITZ
00887     {
00888         28,                                                         /* size/bytes */
00889         ECC_SECP224K1,                                              /* ID         */
00890         "SECP224K1",                                                /* curve name */
00891         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
00892         "00000000000000000000000000000000000000000000000000000000", /* A          */
00893         "00000000000000000000000000000000000000000000000000000005", /* B          */
00894         "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
00895         "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
00896         "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
00897         ecc_oid_secp224k1,                                          /* oid/oidSz  */
00898         ecc_oid_secp224k1_sz,
00899         ECC_SECP224K1_OID,                                          /* oid sum    */
00900         1,                                                          /* cofactor   */
00901     },
00902     #endif /* HAVE_ECC_KOBLITZ */
00903     #ifdef HAVE_ECC_BRAINPOOL
00904     {
00905         28,                                                         /* size/bytes */
00906         ECC_BRAINPOOLP224R1,                                        /* ID         */
00907         "BRAINPOOLP224R1",                                          /* curve name */
00908         "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
00909         "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
00910         "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
00911         "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
00912         "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
00913         "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
00914         ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
00915         ecc_oid_brainpoolp224r1_sz,
00916         ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
00917         1,                                                          /* cofactor   */
00918     },
00919     #endif /* HAVE_ECC_BRAINPOOL */
00920 #endif /* ECC224 */
00921 #ifdef ECC239
00922     #ifndef NO_ECC_SECP
00923     {
00924         30,                                                             /* size/bytes */
00925         ECC_PRIME239V1,                                                 /* ID         */
00926         "PRIME239V1",                                                   /* curve name */
00927         "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
00928         "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
00929         "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
00930         "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
00931         "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
00932         "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
00933         ecc_oid_prime239v1,                                             /* oid/oidSz  */
00934         ecc_oid_prime239v1_sz,
00935         ECC_PRIME239V1_OID,                                             /* oid sum    */
00936         1,                                                              /* cofactor   */
00937     },
00938     #endif /* !NO_ECC_SECP */
00939     #ifdef HAVE_ECC_SECPR2
00940     {
00941         30,                                                             /* size/bytes */
00942         ECC_PRIME239V2,                                                 /* ID         */
00943         "PRIME239V2",                                                   /* curve name */
00944         "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
00945         "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
00946         "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
00947         "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
00948         "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
00949         "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
00950         ecc_oid_prime239v2,                                             /* oid/oidSz  */
00951         ecc_oid_prime239v2_sz,
00952         ECC_PRIME239V2_OID,                                             /* oid sum    */
00953         1,                                                              /* cofactor   */
00954     },
00955     #endif /* HAVE_ECC_SECPR2 */
00956     #ifdef HAVE_ECC_SECPR3
00957     {
00958         30,                                                             /* size/bytes */
00959         ECC_PRIME239V3,                                                 /* ID         */
00960         "PRIME239V3",                                                   /* curve name */
00961         "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
00962         "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
00963         "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
00964         "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
00965         "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
00966         "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
00967         ecc_oid_prime239v3,                                             /* oid/oidSz  */
00968         ecc_oid_prime239v3_sz,
00969         ECC_PRIME239V3_OID,                                             /* oid sum    */
00970         1,                                                              /* cofactor   */
00971     },
00972     #endif /* HAVE_ECC_SECPR3 */
00973 #endif /* ECC239 */
00974 #ifdef ECC256
00975     #ifndef NO_ECC_SECP
00976     {
00977         32,                                                                 /* size/bytes */
00978         ECC_SECP256R1,                                                      /* ID         */
00979         "SECP256R1",                                                        /* curve name */
00980         "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
00981         "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
00982         "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
00983         "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
00984         "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
00985         "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
00986         ecc_oid_secp256r1,                                                  /* oid/oidSz  */
00987         ecc_oid_secp256r1_sz,
00988         ECC_SECP256R1_OID,                                                  /* oid sum    */
00989         1,                                                                  /* cofactor   */
00990     },
00991     #endif /* !NO_ECC_SECP */
00992     #ifdef HAVE_ECC_KOBLITZ
00993     {
00994         32,                                                                 /* size/bytes */
00995         ECC_SECP256K1,                                                      /* ID         */
00996         "SECP256K1",                                                        /* curve name */
00997         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
00998         "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
00999         "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
01000         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
01001         "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
01002         "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
01003         ecc_oid_secp256k1,                                                  /* oid/oidSz  */
01004         ecc_oid_secp256k1_sz,
01005         ECC_SECP256K1_OID,                                                  /* oid sum    */
01006         1,                                                                  /* cofactor   */
01007     },
01008     #endif /* HAVE_ECC_KOBLITZ */
01009     #ifdef HAVE_ECC_BRAINPOOL
01010     {
01011         32,                                                                 /* size/bytes */
01012         ECC_BRAINPOOLP256R1,                                                /* ID         */
01013         "BRAINPOOLP256R1",                                                  /* curve name */
01014         "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
01015         "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
01016         "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
01017         "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
01018         "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
01019         "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
01020         ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
01021         ecc_oid_brainpoolp256r1_sz,
01022         ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
01023         1,                                                                  /* cofactor   */
01024     },
01025     #endif /* HAVE_ECC_BRAINPOOL */
01026 #endif /* ECC256 */
01027 #ifdef ECC320
01028     #ifdef HAVE_ECC_BRAINPOOL
01029     {
01030         40,                                                                                 /* size/bytes */
01031         ECC_BRAINPOOLP320R1,                                                                /* ID         */
01032         "BRAINPOOLP320R1",                                                                  /* curve name */
01033         "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
01034         "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
01035         "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
01036         "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
01037         "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
01038         "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
01039         ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
01040         ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
01041         1,                                                                                  /* cofactor   */
01042     },
01043     #endif /* HAVE_ECC_BRAINPOOL */
01044 #endif /* ECC320 */
01045 #ifdef ECC384
01046     #ifndef NO_ECC_SECP
01047     {
01048         48,                                                                                                 /* size/bytes */
01049         ECC_SECP384R1,                                                                                      /* ID         */
01050         "SECP384R1",                                                                                        /* curve name */
01051         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
01052         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
01053         "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
01054         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
01055         "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
01056         "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
01057         ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
01058         ECC_SECP384R1_OID,                                                                                  /* oid sum    */
01059         1,                                                                                                  /* cofactor   */
01060     },
01061     #endif /* !NO_ECC_SECP */
01062     #ifdef HAVE_ECC_BRAINPOOL
01063     {
01064         48,                                                                                                 /* size/bytes */
01065         ECC_BRAINPOOLP384R1,                                                                                /* ID         */
01066         "BRAINPOOLP384R1",                                                                                  /* curve name */
01067         "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
01068         "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
01069         "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
01070         "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
01071         "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
01072         "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
01073         ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
01074         ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
01075         1,                                                                                                  /* cofactor   */
01076     },
01077     #endif /* HAVE_ECC_BRAINPOOL */
01078 #endif /* ECC384 */
01079 #ifdef ECC512
01080     #ifdef HAVE_ECC_BRAINPOOL
01081     {
01082         64,                                                                                                                                 /* size/bytes */
01083         ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
01084         "BRAINPOOLP512R1",                                                                                                                  /* curve name */
01085         "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
01086         "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
01087         "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
01088         "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
01089         "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
01090         "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
01091         ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
01092         ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
01093         1,                                                                                                                                  /* cofactor   */
01094     },
01095     #endif /* HAVE_ECC_BRAINPOOL */
01096 #endif /* ECC512 */
01097 #ifdef ECC521
01098     #ifndef NO_ECC_SECP
01099     {
01100         66,                                                                                                                                    /* size/bytes */
01101         ECC_SECP521R1,                                                                                                                         /* ID         */
01102         "SECP521R1",                                                                                                                           /* curve name */
01103         "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
01104         "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
01105         "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
01106         "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
01107         "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
01108         "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
01109         ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
01110         ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
01111         1,                                                                                                                                     /* cofactor   */
01112     },
01113     #endif /* !NO_ECC_SECP */
01114 #endif /* ECC521 */
01115 #if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
01116     /* place holder for custom curve index for cache */
01117     {
01118         1, /* non-zero */
01119         ECC_CURVE_CUSTOM,
01120         #ifndef USE_WINDOWS_API
01121             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
01122         #else
01123             0, 0, 0, 0, 0, 0, 0, 0,
01124         #endif
01125         0, 0, 0
01126     },
01127 #endif
01128     {
01129         0, -1,
01130         #ifndef USE_WINDOWS_API
01131             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
01132         #else
01133             0, 0, 0, 0, 0, 0, 0, 0,
01134         #endif
01135         0, 0, 0
01136     }
01137 };
01138 #define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
01139 
01140 
01141 #ifdef HAVE_OID_ENCODING
01142     /* encoded OID cache */
01143     typedef struct {
01144         word32 oidSz;
01145         byte oid[ECC_MAX_OID_LEN];
01146     } oid_cache_t;
01147     static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
01148 #endif
01149 
01150 
01151 #ifdef HAVE_COMP_KEY
01152 static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
01153 #endif
01154 
01155 #ifdef WOLFSSL_ATECC508A
01156     typedef void* ecc_curve_spec;
01157 #else
01158 
01159 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)
01160 static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
01161         mp_int* prime, mp_int* order);
01162 #endif
01163 
01164 int mp_jacobi(mp_int* a, mp_int* n, int* c);
01165 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
01166 
01167 
01168 /* Curve Specs */
01169 typedef struct ecc_curve_spec {
01170     const ecc_set_type* dp;
01171 
01172     mp_int* prime;
01173     mp_int* Af;
01174     #ifdef USE_ECC_B_PARAM
01175         mp_int* Bf;
01176     #endif
01177     mp_int* order;
01178     mp_int* Gx;
01179     mp_int* Gy;
01180 
01181 #ifdef ECC_CACHE_CURVE
01182     mp_int prime_lcl;
01183     mp_int Af_lcl;
01184     #ifdef USE_ECC_B_PARAM
01185         mp_int Bf_lcl;
01186     #endif
01187     mp_int order_lcl;
01188     mp_int Gx_lcl;
01189     mp_int Gy_lcl;
01190 #else
01191     mp_int* spec_ints;
01192     word32 spec_count;
01193     word32 spec_use;
01194 #endif
01195 
01196     byte load_mask;
01197 } ecc_curve_spec;
01198 
01199 enum ecc_curve_load_mask {
01200     ECC_CURVE_FIELD_NONE    = 0x00,
01201     ECC_CURVE_FIELD_PRIME   = 0x01,
01202     ECC_CURVE_FIELD_AF      = 0x02,
01203 #ifdef USE_ECC_B_PARAM
01204     ECC_CURVE_FIELD_BF      = 0x04,
01205 #endif
01206     ECC_CURVE_FIELD_ORDER   = 0x08,
01207     ECC_CURVE_FIELD_GX      = 0x10,
01208     ECC_CURVE_FIELD_GY      = 0x20,
01209 #ifdef USE_ECC_B_PARAM
01210     ECC_CURVE_FIELD_ALL     = 0x3F,
01211     ECC_CURVE_FIELD_COUNT   = 6,
01212 #else
01213     ECC_CURVE_FIELD_ALL     = 0x3B,
01214     ECC_CURVE_FIELD_COUNT   = 5,
01215 #endif
01216 };
01217 
01218 #ifdef ECC_CACHE_CURVE
01219     /* cache (mp_int) of the curve parameters */
01220     static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
01221     #ifndef SINGLE_THREADED
01222         static wolfSSL_Mutex ecc_curve_cache_mutex;
01223     #endif
01224 
01225     #define DECLARE_CURVE_SPECS(curve, intcount) ecc_curve_spec* curve = NULL
01226     #define ALLOC_CURVE_SPECS(intcount)
01227     #define FREE_CURVE_SPECS()
01228 #elif defined(WOLFSSL_SMALL_STACK)
01229     #define DECLARE_CURVE_SPECS(curve, intcount)                        \
01230         mp_int* spec_ints = NULL;                                       \
01231         ecc_curve_spec curve_lcl;                                       \
01232         ecc_curve_spec* curve = &curve_lcl;                             \
01233         XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
01234         curve->spec_count = intcount
01235 
01236     #define ALLOC_CURVE_SPECS(intcount)                                 \
01237         spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
01238                             DYNAMIC_TYPE_ECC);                          \
01239         if (spec_ints == NULL)                                          \
01240             return MEMORY_E;                                            \
01241         curve->spec_ints = spec_ints
01242     #define FREE_CURVE_SPECS()                                          \
01243         XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
01244 #else
01245     #define DECLARE_CURVE_SPECS(curve, intcount) \
01246         mp_int spec_ints[(intcount)]; \
01247         ecc_curve_spec curve_lcl; \
01248         ecc_curve_spec* curve = &curve_lcl; \
01249         XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \
01250         curve->spec_ints = spec_ints; \
01251         curve->spec_count = intcount
01252     #define ALLOC_CURVE_SPECS(intcount)
01253     #define FREE_CURVE_SPECS()
01254 #endif /* ECC_CACHE_CURVE */
01255 
01256 static void _wc_ecc_curve_free(ecc_curve_spec* curve)
01257 {
01258     if (curve == NULL) {
01259         return;
01260     }
01261 
01262     if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
01263         mp_clear(curve->prime);
01264     if (curve->load_mask & ECC_CURVE_FIELD_AF)
01265         mp_clear(curve->Af);
01266 #ifdef USE_ECC_B_PARAM
01267     if (curve->load_mask & ECC_CURVE_FIELD_BF)
01268         mp_clear(curve->Bf);
01269 #endif
01270     if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
01271         mp_clear(curve->order);
01272     if (curve->load_mask & ECC_CURVE_FIELD_GX)
01273         mp_clear(curve->Gx);
01274     if (curve->load_mask & ECC_CURVE_FIELD_GY)
01275         mp_clear(curve->Gy);
01276 
01277     curve->load_mask = 0;
01278 }
01279 
01280 static void wc_ecc_curve_free(ecc_curve_spec* curve)
01281 {
01282     /* don't free cached curves */
01283 #ifndef ECC_CACHE_CURVE
01284     _wc_ecc_curve_free(curve);
01285 #endif
01286     (void)curve;
01287 }
01288 
01289 static int wc_ecc_curve_load_item(const char* src, mp_int** dst,
01290     ecc_curve_spec* curve, byte mask)
01291 {
01292     int err;
01293 
01294 #ifndef ECC_CACHE_CURVE
01295     /* get mp_int from temp */
01296     if (curve->spec_use >= curve->spec_count) {
01297         WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
01298         return ECC_BAD_ARG_E;
01299     }
01300     *dst = &curve->spec_ints[curve->spec_use++];
01301 #endif
01302 
01303     err = mp_init(*dst);
01304     if (err == MP_OKAY) {
01305         curve->load_mask |= mask;
01306 
01307         err = mp_read_radix(*dst, src, MP_RADIX_HEX);
01308 
01309     #ifdef HAVE_WOLF_BIGINT
01310         if (err == MP_OKAY)
01311             err = wc_mp_to_bigint(*dst, &(*dst)->raw);
01312     #endif
01313     }
01314     return err;
01315 }
01316 
01317 static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
01318     byte load_mask)
01319 {
01320     int ret = 0, x;
01321     ecc_curve_spec* curve;
01322     byte load_items = 0; /* mask of items to load */
01323 
01324     if (dp == NULL || pCurve == NULL)
01325         return BAD_FUNC_ARG;
01326 
01327 #ifdef ECC_CACHE_CURVE
01328     x = wc_ecc_get_curve_idx(dp->id);
01329     if (x == ECC_CURVE_INVALID)
01330         return ECC_BAD_ARG_E;
01331 
01332 #if !defined(SINGLE_THREADED)
01333     ret = wc_LockMutex(&ecc_curve_cache_mutex);
01334     if (ret != 0) {
01335         return ret;
01336     }
01337 #endif
01338 
01339     /* make sure cache has been allocated */
01340     if (ecc_curve_spec_cache[x] == NULL) {
01341         ecc_curve_spec_cache[x] = (ecc_curve_spec*)XMALLOC(
01342             sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
01343         if (ecc_curve_spec_cache[x] == NULL) {
01344         #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
01345             wc_UnLockMutex(&ecc_curve_cache_mutex);
01346         #endif
01347             return MEMORY_E;
01348         }
01349         XMEMSET(ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec));
01350     }
01351 
01352     /* set curve pointer to cache */
01353     *pCurve = ecc_curve_spec_cache[x];
01354 
01355 #endif /* ECC_CACHE_CURVE */
01356     curve = *pCurve;
01357 
01358     /* make sure the curve is initialized */
01359     if (curve->dp != dp) {
01360         curve->load_mask = 0;
01361 
01362     #ifdef ECC_CACHE_CURVE
01363         curve->prime = &curve->prime_lcl;
01364         curve->Af = &curve->Af_lcl;
01365         #ifdef USE_ECC_B_PARAM
01366             curve->Bf = &curve->Bf_lcl;
01367         #endif
01368         curve->order = &curve->order_lcl;
01369         curve->Gx = &curve->Gx_lcl;
01370         curve->Gy = &curve->Gy_lcl;
01371     #endif
01372     }
01373     curve->dp = dp; /* set dp info */
01374 
01375     /* determine items to load */
01376     load_items = (((byte)~(word32)curve->load_mask) & load_mask);
01377     curve->load_mask |= load_items;
01378 
01379     /* load items */
01380     x = 0;
01381     if (load_items & ECC_CURVE_FIELD_PRIME)
01382         x += wc_ecc_curve_load_item(dp->prime, &curve->prime, curve,
01383             ECC_CURVE_FIELD_PRIME);
01384     if (load_items & ECC_CURVE_FIELD_AF)
01385         x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve,
01386             ECC_CURVE_FIELD_AF);
01387 #ifdef USE_ECC_B_PARAM
01388     if (load_items & ECC_CURVE_FIELD_BF)
01389         x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve,
01390             ECC_CURVE_FIELD_BF);
01391 #endif
01392     if (load_items & ECC_CURVE_FIELD_ORDER)
01393         x += wc_ecc_curve_load_item(dp->order, &curve->order, curve,
01394             ECC_CURVE_FIELD_ORDER);
01395     if (load_items & ECC_CURVE_FIELD_GX)
01396         x += wc_ecc_curve_load_item(dp->Gx, &curve->Gx, curve,
01397             ECC_CURVE_FIELD_GX);
01398     if (load_items & ECC_CURVE_FIELD_GY)
01399         x += wc_ecc_curve_load_item(dp->Gy, &curve->Gy, curve,
01400             ECC_CURVE_FIELD_GY);
01401 
01402     /* check for error */
01403     if (x != 0) {
01404         wc_ecc_curve_free(curve);
01405         ret = MP_READ_E;
01406     }
01407 
01408 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
01409     wc_UnLockMutex(&ecc_curve_cache_mutex);
01410 #endif
01411 
01412     return ret;
01413 }
01414 
01415 #ifdef ECC_CACHE_CURVE
01416 int wc_ecc_curve_cache_init(void)
01417 {
01418     int ret = 0;
01419 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
01420     ret = wc_InitMutex(&ecc_curve_cache_mutex);
01421 #endif
01422     return ret;
01423 }
01424 
01425 void wc_ecc_curve_cache_free(void)
01426 {
01427     int x;
01428 
01429     /* free all ECC curve caches */
01430     for (x = 0; x < (int)ECC_SET_COUNT; x++) {
01431         if (ecc_curve_spec_cache[x]) {
01432             _wc_ecc_curve_free(ecc_curve_spec_cache[x]);
01433             XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
01434             ecc_curve_spec_cache[x] = NULL;
01435         }
01436     }
01437 
01438 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
01439     wc_FreeMutex(&ecc_curve_cache_mutex);
01440 #endif
01441 }
01442 #endif /* ECC_CACHE_CURVE */
01443 
01444 #endif /* WOLFSSL_ATECC508A */
01445 
01446 
01447 /* Retrieve the curve name for the ECC curve id.
01448  *
01449  * curve_id  The id of the curve.
01450  * returns the name stored from the curve if available, otherwise NULL.
01451  */
01452 const char* wc_ecc_get_name(int curve_id)
01453 {
01454     int curve_idx = wc_ecc_get_curve_idx(curve_id);
01455     if (curve_idx == ECC_CURVE_INVALID)
01456         return NULL;
01457     return ecc_sets[curve_idx].name;
01458 }
01459 
01460 int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
01461 {
01462     if (keysize <= 0 && curve_id < 0) {
01463         return BAD_FUNC_ARG;
01464     }
01465 
01466     if (keysize > ECC_MAXSIZE) {
01467         return ECC_BAD_ARG_E;
01468     }
01469 
01470     /* handle custom case */
01471     if (key->idx != ECC_CUSTOM_IDX) {
01472         int x;
01473 
01474         /* default values */
01475         key->idx = 0;
01476         key->dp = NULL;
01477 
01478         /* find ecc_set based on curve_id or key size */
01479         for (x = 0; ecc_sets[x].size != 0; x++) {
01480             if (curve_id > ECC_CURVE_DEF) {
01481                 if (curve_id == ecc_sets[x].id)
01482                   break;
01483             }
01484             else if (keysize <= ecc_sets[x].size) {
01485                 break;
01486             }
01487         }
01488         if (ecc_sets[x].size == 0) {
01489             WOLFSSL_MSG("ECC Curve not found");
01490             return ECC_CURVE_OID_E;
01491         }
01492 
01493         key->idx = x;
01494         key->dp  = &ecc_sets[x];
01495     }
01496 
01497     return 0;
01498 }
01499 
01500 
01501 #ifdef ALT_ECC_SIZE
01502 static void alt_fp_init(fp_int* a)
01503 {
01504     a->size = FP_SIZE_ECC;
01505     fp_zero(a);
01506 }
01507 #endif /* ALT_ECC_SIZE */
01508 
01509 
01510 #ifndef WOLFSSL_ATECC508A
01511 
01512 #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
01513 
01514 /**
01515    Add two ECC points
01516    P        The point to add
01517    Q        The point to add
01518    R        [out] The destination of the double
01519    a        ECC curve parameter a
01520    modulus  The modulus of the field the ECC curve is in
01521    mp       The "b" value from montgomery_setup()
01522    return   MP_OKAY on success
01523 */
01524 int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
01525                              mp_int* a, mp_int* modulus, mp_digit mp)
01526 {
01527 #ifndef WOLFSSL_SP_MATH
01528 #ifdef WOLFSSL_SMALL_STACK
01529    mp_int* t1 = NULL;
01530    mp_int* t2 = NULL;
01531 #ifdef ALT_ECC_SIZE
01532    mp_int* rx = NULL;
01533    mp_int* ry = NULL;
01534    mp_int* rz = NULL;
01535 #endif
01536 #else
01537    mp_int  t1[1], t2[1];
01538 #ifdef ALT_ECC_SIZE
01539    mp_int  rx[1], ry[1], rz[1];
01540 #endif
01541 #endif
01542    mp_int  *x, *y, *z;
01543    int     err;
01544 
01545    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
01546        return ECC_BAD_ARG_E;
01547    }
01548 
01549    /* if Q == R then swap P and Q, so we don't require a local x,y,z */
01550    if (Q == R) {
01551       ecc_point* tPt  = P;
01552       P = Q;
01553       Q = tPt;
01554    }
01555 
01556 #ifdef WOLFSSL_SMALL_STACK
01557 #ifdef WOLFSSL_SMALL_STACK_CACHE
01558    if (R->key != NULL) {
01559        t1 = R->key->t1;
01560        t2 = R->key->t2;
01561 #ifdef ALT_ECC_SIZE
01562        rx = R->key->x;
01563        ry = R->key->y;
01564        rz = R->key->z;
01565 #endif
01566    }
01567    else
01568 #endif /* WOLFSSL_SMALL_STACK_CACHE */
01569    {
01570        t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01571        t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01572        if (t1 == NULL || t2 == NULL) {
01573            XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
01574            XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
01575            return MEMORY_E;
01576        }
01577 #ifdef ALT_ECC_SIZE
01578        rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01579        ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01580        rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01581        if (rx == NULL || ry == NULL || rz == NULL) {
01582            XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
01583            XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
01584            XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
01585            XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
01586            XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
01587            return MEMORY_E;
01588        }
01589 #endif
01590    }
01591 #endif /* WOLFSSL_SMALL_STACK */
01592 
01593    if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
01594 #ifdef WOLFSSL_SMALL_STACK
01595    #ifdef WOLFSSL_SMALL_STACK_CACHE
01596        if (R->key == NULL)
01597    #endif
01598        {
01599        #ifdef ALT_ECC_SIZE
01600           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
01601           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
01602           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
01603        #endif
01604           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
01605           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
01606        }
01607 #endif
01608       return err;
01609    }
01610 
01611    /* should we dbl instead? */
01612    if (err == MP_OKAY)
01613        err = mp_sub(modulus, Q->y, t1);
01614    if (err == MP_OKAY) {
01615        if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
01616             (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
01617             (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
01618            mp_clear(t1);
01619            mp_clear(t2);
01620     #ifdef WOLFSSL_SMALL_STACK
01621        #ifdef WOLFSSL_SMALL_STACK_CACHE
01622            if (R->key == NULL)
01623        #endif
01624            {
01625             #ifdef ALT_ECC_SIZE
01626                XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
01627                XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
01628                XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
01629             #endif
01630                XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
01631                XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
01632            }
01633         #endif
01634           return ecc_projective_dbl_point(P, R, a, modulus, mp);
01635        }
01636    }
01637 
01638    if (err != MP_OKAY) {
01639       goto done;
01640    }
01641 
01642 /* If use ALT_ECC_SIZE we need to use local stack variable since
01643    ecc_point x,y,z is reduced size */
01644 #ifdef ALT_ECC_SIZE
01645    /* Use local stack variable */
01646    x = rx;
01647    y = ry;
01648    z = rz;
01649 
01650    if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
01651       goto done;
01652    }
01653 #else
01654    /* Use destination directly */
01655    x = R->x;
01656    y = R->y;
01657    z = R->z;
01658 #endif
01659 
01660    if (err == MP_OKAY)
01661        err = mp_copy(P->x, x);
01662    if (err == MP_OKAY)
01663        err = mp_copy(P->y, y);
01664    if (err == MP_OKAY)
01665        err = mp_copy(P->z, z);
01666 
01667    /* if Z is one then these are no-operations */
01668    if (err == MP_OKAY) {
01669        if (!mp_iszero(Q->z)) {
01670            /* T1 = Z' * Z' */
01671            err = mp_sqr(Q->z, t1);
01672            if (err == MP_OKAY)
01673                err = mp_montgomery_reduce(t1, modulus, mp);
01674 
01675            /* X = X * T1 */
01676            if (err == MP_OKAY)
01677                err = mp_mul(t1, x, x);
01678            if (err == MP_OKAY)
01679                err = mp_montgomery_reduce(x, modulus, mp);
01680 
01681            /* T1 = Z' * T1 */
01682            if (err == MP_OKAY)
01683                err = mp_mul(Q->z, t1, t1);
01684            if (err == MP_OKAY)
01685                err = mp_montgomery_reduce(t1, modulus, mp);
01686 
01687            /* Y = Y * T1 */
01688            if (err == MP_OKAY)
01689                err = mp_mul(t1, y, y);
01690            if (err == MP_OKAY)
01691                err = mp_montgomery_reduce(y, modulus, mp);
01692        }
01693    }
01694 
01695    /* T1 = Z*Z */
01696    if (err == MP_OKAY)
01697        err = mp_sqr(z, t1);
01698    if (err == MP_OKAY)
01699        err = mp_montgomery_reduce(t1, modulus, mp);
01700 
01701    /* T2 = X' * T1 */
01702    if (err == MP_OKAY)
01703        err = mp_mul(Q->x, t1, t2);
01704    if (err == MP_OKAY)
01705        err = mp_montgomery_reduce(t2, modulus, mp);
01706 
01707    /* T1 = Z * T1 */
01708    if (err == MP_OKAY)
01709        err = mp_mul(z, t1, t1);
01710    if (err == MP_OKAY)
01711        err = mp_montgomery_reduce(t1, modulus, mp);
01712 
01713    /* T1 = Y' * T1 */
01714    if (err == MP_OKAY)
01715        err = mp_mul(Q->y, t1, t1);
01716    if (err == MP_OKAY)
01717        err = mp_montgomery_reduce(t1, modulus, mp);
01718 
01719    /* Y = Y - T1 */
01720    if (err == MP_OKAY)
01721        err = mp_sub(y, t1, y);
01722    if (err == MP_OKAY) {
01723        if (mp_isneg(y))
01724            err = mp_add(y, modulus, y);
01725    }
01726    /* T1 = 2T1 */
01727    if (err == MP_OKAY)
01728        err = mp_add(t1, t1, t1);
01729    if (err == MP_OKAY) {
01730        if (mp_cmp(t1, modulus) != MP_LT)
01731            err = mp_sub(t1, modulus, t1);
01732    }
01733    /* T1 = Y + T1 */
01734    if (err == MP_OKAY)
01735        err = mp_add(t1, y, t1);
01736    if (err == MP_OKAY) {
01737        if (mp_cmp(t1, modulus) != MP_LT)
01738            err = mp_sub(t1, modulus, t1);
01739    }
01740    /* X = X - T2 */
01741    if (err == MP_OKAY)
01742        err = mp_sub(x, t2, x);
01743    if (err == MP_OKAY) {
01744        if (mp_isneg(x))
01745            err = mp_add(x, modulus, x);
01746    }
01747    /* T2 = 2T2 */
01748    if (err == MP_OKAY)
01749        err = mp_add(t2, t2, t2);
01750    if (err == MP_OKAY) {
01751        if (mp_cmp(t2, modulus) != MP_LT)
01752            err = mp_sub(t2, modulus, t2);
01753    }
01754    /* T2 = X + T2 */
01755    if (err == MP_OKAY)
01756        err = mp_add(t2, x, t2);
01757    if (err == MP_OKAY) {
01758        if (mp_cmp(t2, modulus) != MP_LT)
01759            err = mp_sub(t2, modulus, t2);
01760    }
01761 
01762    if (err == MP_OKAY) {
01763        if (!mp_iszero(Q->z)) {
01764            /* Z = Z * Z' */
01765            err = mp_mul(z, Q->z, z);
01766            if (err == MP_OKAY)
01767                err = mp_montgomery_reduce(z, modulus, mp);
01768        }
01769    }
01770 
01771    /* Z = Z * X */
01772    if (err == MP_OKAY)
01773        err = mp_mul(z, x, z);
01774    if (err == MP_OKAY)
01775        err = mp_montgomery_reduce(z, modulus, mp);
01776 
01777    /* T1 = T1 * X  */
01778    if (err == MP_OKAY)
01779        err = mp_mul(t1, x, t1);
01780    if (err == MP_OKAY)
01781        err = mp_montgomery_reduce(t1, modulus, mp);
01782 
01783    /* X = X * X */
01784    if (err == MP_OKAY)
01785        err = mp_sqr(x, x);
01786    if (err == MP_OKAY)
01787        err = mp_montgomery_reduce(x, modulus, mp);
01788 
01789    /* T2 = T2 * x */
01790    if (err == MP_OKAY)
01791        err = mp_mul(t2, x, t2);
01792    if (err == MP_OKAY)
01793        err = mp_montgomery_reduce(t2, modulus, mp);
01794 
01795    /* T1 = T1 * X  */
01796    if (err == MP_OKAY)
01797        err = mp_mul(t1, x, t1);
01798    if (err == MP_OKAY)
01799        err = mp_montgomery_reduce(t1, modulus, mp);
01800 
01801    /* X = Y*Y */
01802    if (err == MP_OKAY)
01803        err = mp_sqr(y, x);
01804    if (err == MP_OKAY)
01805        err = mp_montgomery_reduce(x, modulus, mp);
01806 
01807    /* X = X - T2 */
01808    if (err == MP_OKAY)
01809        err = mp_sub(x, t2, x);
01810    if (err == MP_OKAY) {
01811        if (mp_isneg(x))
01812            err = mp_add(x, modulus, x);
01813    }
01814    /* T2 = T2 - X */
01815    if (err == MP_OKAY)
01816        err = mp_sub(t2, x, t2);
01817    if (err == MP_OKAY) {
01818        if (mp_isneg(t2))
01819            err = mp_add(t2, modulus, t2);
01820    }
01821    /* T2 = T2 - X */
01822    if (err == MP_OKAY)
01823        err = mp_sub(t2, x, t2);
01824    if (err == MP_OKAY) {
01825        if (mp_isneg(t2))
01826            err = mp_add(t2, modulus, t2);
01827    }
01828    /* T2 = T2 * Y */
01829    if (err == MP_OKAY)
01830        err = mp_mul(t2, y, t2);
01831    if (err == MP_OKAY)
01832        err = mp_montgomery_reduce(t2, modulus, mp);
01833 
01834    /* Y = T2 - T1 */
01835    if (err == MP_OKAY)
01836        err = mp_sub(t2, t1, y);
01837    if (err == MP_OKAY) {
01838        if (mp_isneg(y))
01839            err = mp_add(y, modulus, y);
01840    }
01841    /* Y = Y/2 */
01842    if (err == MP_OKAY) {
01843        if (mp_isodd(y) == MP_YES)
01844            err = mp_add(y, modulus, y);
01845    }
01846    if (err == MP_OKAY)
01847        err = mp_div_2(y, y);
01848 
01849 #ifdef ALT_ECC_SIZE
01850    if (err == MP_OKAY)
01851        err = mp_copy(x, R->x);
01852    if (err == MP_OKAY)
01853        err = mp_copy(y, R->y);
01854    if (err == MP_OKAY)
01855        err = mp_copy(z, R->z);
01856 #endif
01857 
01858 done:
01859 
01860    /* clean up */
01861    mp_clear(t1);
01862    mp_clear(t2);
01863 #ifdef WOLFSSL_SMALL_STACK
01864 #ifdef WOLFSSL_SMALL_STACK_CACHE
01865    if (R->key == NULL)
01866 #endif
01867    {
01868    #ifdef ALT_ECC_SIZE
01869       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
01870       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
01871       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
01872    #endif
01873       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
01874       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
01875    }
01876 #endif
01877 
01878    return err;
01879 #else
01880     if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
01881         return ECC_BAD_ARG_E;
01882     }
01883 
01884     (void)a;
01885     (void)mp;
01886 
01887     return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
01888                                      R->x, R->y, R->z);
01889 #endif
01890 }
01891 
01892 /* ### Point doubling in Jacobian coordinate system ###
01893  *
01894  * let us have a curve:                 y^2 = x^3 + a*x + b
01895  * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
01896  *
01897  * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
01898  * Xr = M^2 - 2*S
01899  * Yr = M * (S - Xr) - 8*T
01900  * Zr = 2 * Yp * Zp
01901  *
01902  * M = 3 * Xp^2 + a*Zp^4
01903  * T = Yp^4
01904  * S = 4 * Xp * Yp^2
01905  *
01906  * SPECIAL CASE: when a == 3 we can compute M as
01907  * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
01908  */
01909 
01910 /**
01911    Double an ECC point
01912    P   The point to double
01913    R   [out] The destination of the double
01914    a   ECC curve parameter a
01915    modulus  The modulus of the field the ECC curve is in
01916    mp       The "b" value from montgomery_setup()
01917    return   MP_OKAY on success
01918 */
01919 int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
01920                                        mp_int* modulus, mp_digit mp)
01921 {
01922 #ifndef WOLFSSL_SP_MATH
01923 #ifdef WOLFSSL_SMALL_STACK
01924    mp_int* t1 = NULL;
01925    mp_int* t2 = NULL;
01926 #ifdef ALT_ECC_SIZE
01927    mp_int* rx = NULL;
01928    mp_int* ry = NULL;
01929    mp_int* rz = NULL;
01930 #endif
01931 #else
01932    mp_int  t1[1], t2[1];
01933 #ifdef ALT_ECC_SIZE
01934    mp_int  rx[1], ry[1], rz[1];
01935 #endif
01936 #endif
01937    mp_int *x, *y, *z;
01938    int    err;
01939 
01940    if (P == NULL || R == NULL || modulus == NULL)
01941        return ECC_BAD_ARG_E;
01942 
01943 #ifdef WOLFSSL_SMALL_STACK
01944 #ifdef WOLFSSL_SMALL_STACK_CACHE
01945    if (R->key != NULL) {
01946        t1 = R->key->t1;
01947        t2 = R->key->t2;
01948    #ifdef ALT_ECC_SIZE
01949        rx = R->key->x;
01950        ry = R->key->y;
01951        rz = R->key->z;
01952    #endif
01953    }
01954    else
01955 #endif /* WOLFSSL_SMALL_STACK_CACHE */
01956    {
01957        t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01958        t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01959        if (t1 == NULL || t2 == NULL) {
01960            XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
01961            XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
01962            return MEMORY_E;
01963        }
01964     #ifdef ALT_ECC_SIZE
01965        rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01966        ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01967        rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
01968        if (rx == NULL || ry == NULL || rz == NULL) {
01969            XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
01970            XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
01971            XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
01972            XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
01973            XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
01974            return MEMORY_E;
01975        }
01976     #endif
01977     }
01978 #endif
01979 
01980    if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
01981 #ifdef WOLFSSL_SMALL_STACK
01982 #ifdef WOLFSSL_SMALL_STACK_CACHE
01983     if (R->key == NULL)
01984 #endif
01985     {
01986     #ifdef ALT_ECC_SIZE
01987        XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
01988        XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
01989        XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
01990     #endif
01991        XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
01992        XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
01993      }
01994 #endif
01995       return err;
01996    }
01997 
01998 /* If use ALT_ECC_SIZE we need to use local stack variable since
01999    ecc_point x,y,z is reduced size */
02000 #ifdef ALT_ECC_SIZE
02001    /* Use local stack variable */
02002    x = rx;
02003    y = ry;
02004    z = rz;
02005 
02006    if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
02007        mp_clear(t1);
02008        mp_clear(t2);
02009     #ifdef WOLFSSL_SMALL_STACK
02010     #ifdef WOLFSSL_SMALL_STACK_CACHE
02011        if (R->key == NULL)
02012     #endif
02013        {
02014        #ifdef ALT_ECC_SIZE
02015           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
02016           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
02017           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
02018        #endif
02019           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
02020           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
02021        }
02022     #endif
02023        return err;
02024    }
02025 #else
02026    /* Use destination directly */
02027    x = R->x;
02028    y = R->y;
02029    z = R->z;
02030 #endif
02031 
02032    if (err == MP_OKAY)
02033        err = mp_copy(P->x, x);
02034    if (err == MP_OKAY)
02035        err = mp_copy(P->y, y);
02036    if (err == MP_OKAY)
02037        err = mp_copy(P->z, z);
02038 
02039    /* T1 = Z * Z */
02040    if (err == MP_OKAY)
02041        err = mp_sqr(z, t1);
02042    if (err == MP_OKAY)
02043        err = mp_montgomery_reduce(t1, modulus, mp);
02044 
02045    /* Z = Y * Z */
02046    if (err == MP_OKAY)
02047        err = mp_mul(z, y, z);
02048    if (err == MP_OKAY)
02049        err = mp_montgomery_reduce(z, modulus, mp);
02050 
02051    /* Z = 2Z */
02052    if (err == MP_OKAY)
02053        err = mp_add(z, z, z);
02054    if (err == MP_OKAY) {
02055        if (mp_cmp(z, modulus) != MP_LT)
02056            err = mp_sub(z, modulus, z);
02057    }
02058 
02059    /* Determine if curve "a" should be used in calc */
02060 #ifdef WOLFSSL_CUSTOM_CURVES
02061    if (err == MP_OKAY) {
02062       /* Use a and prime to determine if a == 3 */
02063       err = mp_submod(modulus, a, modulus, t2);
02064    }
02065    if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
02066       /* use "a" in calc */
02067 
02068       /* T2 = T1 * T1 */
02069       if (err == MP_OKAY)
02070           err = mp_sqr(t1, t2);
02071       if (err == MP_OKAY)
02072           err = mp_montgomery_reduce(t2, modulus, mp);
02073       /* T1 = T2 * a */
02074       if (err == MP_OKAY)
02075           err = mp_mulmod(t2, a, modulus, t1);
02076       /* T2 = X * X */
02077       if (err == MP_OKAY)
02078           err = mp_sqr(x, t2);
02079       if (err == MP_OKAY)
02080           err = mp_montgomery_reduce(t2, modulus, mp);
02081       /* T1 = T2 + T1 */
02082       if (err == MP_OKAY)
02083           err = mp_add(t1, t2, t1);
02084       if (err == MP_OKAY) {
02085          if (mp_cmp(t1, modulus) != MP_LT)
02086             err = mp_sub(t1, modulus, t1);
02087       }
02088       /* T1 = T2 + T1 */
02089       if (err == MP_OKAY)
02090           err = mp_add(t1, t2, t1);
02091       if (err == MP_OKAY) {
02092           if (mp_cmp(t1, modulus) != MP_LT)
02093               err = mp_sub(t1, modulus, t1);
02094       }
02095       /* T1 = T2 + T1 */
02096       if (err == MP_OKAY)
02097           err = mp_add(t1, t2, t1);
02098       if (err == MP_OKAY) {
02099          if (mp_cmp(t1, modulus) != MP_LT)
02100             err = mp_sub(t1, modulus, t1);
02101       }
02102    }
02103    else
02104 #endif /* WOLFSSL_CUSTOM_CURVES */
02105    {
02106       /* assumes "a" == 3 */
02107       (void)a;
02108 
02109       /* T2 = X - T1 */
02110       if (err == MP_OKAY)
02111           err = mp_sub(x, t1, t2);
02112       if (err == MP_OKAY) {
02113           if (mp_isneg(t2))
02114               err = mp_add(t2, modulus, t2);
02115       }
02116       /* T1 = X + T1 */
02117       if (err == MP_OKAY)
02118           err = mp_add(t1, x, t1);
02119       if (err == MP_OKAY) {
02120           if (mp_cmp(t1, modulus) != MP_LT)
02121               err = mp_sub(t1, modulus, t1);
02122       }
02123       /* T2 = T1 * T2 */
02124       if (err == MP_OKAY)
02125           err = mp_mul(t1, t2, t2);
02126       if (err == MP_OKAY)
02127           err = mp_montgomery_reduce(t2, modulus, mp);
02128 
02129       /* T1 = 2T2 */
02130       if (err == MP_OKAY)
02131           err = mp_add(t2, t2, t1);
02132       if (err == MP_OKAY) {
02133           if (mp_cmp(t1, modulus) != MP_LT)
02134               err = mp_sub(t1, modulus, t1);
02135       }
02136       /* T1 = T1 + T2 */
02137       if (err == MP_OKAY)
02138           err = mp_add(t1, t2, t1);
02139       if (err == MP_OKAY) {
02140           if (mp_cmp(t1, modulus) != MP_LT)
02141               err = mp_sub(t1, modulus, t1);
02142       }
02143    }
02144 
02145    /* Y = 2Y */
02146    if (err == MP_OKAY)
02147        err = mp_add(y, y, y);
02148    if (err == MP_OKAY) {
02149        if (mp_cmp(y, modulus) != MP_LT)
02150            err = mp_sub(y, modulus, y);
02151    }
02152    /* Y = Y * Y */
02153    if (err == MP_OKAY)
02154        err = mp_sqr(y, y);
02155    if (err == MP_OKAY)
02156        err = mp_montgomery_reduce(y, modulus, mp);
02157 
02158    /* T2 = Y * Y */
02159    if (err == MP_OKAY)
02160        err = mp_sqr(y, t2);
02161    if (err == MP_OKAY)
02162        err = mp_montgomery_reduce(t2, modulus, mp);
02163 
02164    /* T2 = T2/2 */
02165    if (err == MP_OKAY) {
02166        if (mp_isodd(t2) == MP_YES)
02167            err = mp_add(t2, modulus, t2);
02168    }
02169    if (err == MP_OKAY)
02170        err = mp_div_2(t2, t2);
02171 
02172    /* Y = Y * X */
02173    if (err == MP_OKAY)
02174        err = mp_mul(y, x, y);
02175    if (err == MP_OKAY)
02176        err = mp_montgomery_reduce(y, modulus, mp);
02177 
02178    /* X = T1 * T1 */
02179    if (err == MP_OKAY)
02180        err = mp_sqr(t1, x);
02181    if (err == MP_OKAY)
02182        err = mp_montgomery_reduce(x, modulus, mp);
02183 
02184    /* X = X - Y */
02185    if (err == MP_OKAY)
02186        err = mp_sub(x, y, x);
02187    if (err == MP_OKAY) {
02188        if (mp_isneg(x))
02189            err = mp_add(x, modulus, x);
02190    }
02191    /* X = X - Y */
02192    if (err == MP_OKAY)
02193        err = mp_sub(x, y, x);
02194    if (err == MP_OKAY) {
02195        if (mp_isneg(x))
02196            err = mp_add(x, modulus, x);
02197    }
02198 
02199    /* Y = Y - X */
02200    if (err == MP_OKAY)
02201        err = mp_sub(y, x, y);
02202    if (err == MP_OKAY) {
02203        if (mp_isneg(y))
02204            err = mp_add(y, modulus, y);
02205    }
02206    /* Y = Y * T1 */
02207    if (err == MP_OKAY)
02208        err = mp_mul(y, t1, y);
02209    if (err == MP_OKAY)
02210        err = mp_montgomery_reduce(y, modulus, mp);
02211 
02212    /* Y = Y - T2 */
02213    if (err == MP_OKAY)
02214        err = mp_sub(y, t2, y);
02215    if (err == MP_OKAY) {
02216        if (mp_isneg(y))
02217            err = mp_add(y, modulus, y);
02218    }
02219 
02220 #ifdef ALT_ECC_SIZE
02221    if (err == MP_OKAY)
02222        err = mp_copy(x, R->x);
02223    if (err == MP_OKAY)
02224        err = mp_copy(y, R->y);
02225    if (err == MP_OKAY)
02226        err = mp_copy(z, R->z);
02227 #endif
02228 
02229    /* clean up */
02230    mp_clear(t1);
02231    mp_clear(t2);
02232 
02233 #ifdef WOLFSSL_SMALL_STACK
02234 #ifdef WOLFSSL_SMALL_STACK_CACHE
02235    if (R->key == NULL)
02236 #endif
02237    {
02238     #ifdef ALT_ECC_SIZE
02239        XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
02240        XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
02241        XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
02242     #endif
02243        XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
02244        XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
02245     }
02246 #endif
02247 
02248    return err;
02249 #else
02250     if (P == NULL || R == NULL || modulus == NULL)
02251         return ECC_BAD_ARG_E;
02252 
02253     (void)a;
02254     (void)mp;
02255 
02256     return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
02257 #endif
02258 }
02259 
02260 
02261 /**
02262   Map a projective jacbobian point back to affine space
02263   P        [in/out] The point to map
02264   modulus  The modulus of the field the ECC curve is in
02265   mp       The "b" value from montgomery_setup()
02266   return   MP_OKAY on success
02267 */
02268 int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
02269 {
02270 #ifndef WOLFSSL_SP_MATH
02271 #ifdef WOLFSSL_SMALL_STACK
02272    mp_int* t1 = NULL;
02273    mp_int* t2 = NULL;
02274 #ifdef ALT_ECC_SIZE
02275    mp_int* rx = NULL;
02276    mp_int* ry = NULL;
02277    mp_int* rz = NULL;
02278 #endif
02279 #else
02280    mp_int  t1[1], t2[1];
02281 #ifdef ALT_ECC_SIZE
02282    mp_int  rx[1], ry[1], rz[1];
02283 #endif
02284 #endif /* WOLFSSL_SMALL_STACK */
02285    mp_int *x, *y, *z;
02286    int    err;
02287 
02288    if (P == NULL || modulus == NULL)
02289        return ECC_BAD_ARG_E;
02290 
02291    /* special case for point at infinity */
02292    if (mp_cmp_d(P->z, 0) == MP_EQ) {
02293        err = mp_set(P->x, 0);
02294        if (err == MP_OKAY)
02295            err = mp_set(P->y, 0);
02296        if (err == MP_OKAY)
02297            err = mp_set(P->z, 1);
02298        return err;
02299    }
02300 
02301 #ifdef WOLFSSL_SMALL_STACK
02302 #ifdef WOLFSSL_SMALL_STACK_CACHE
02303    if (P->key != NULL) {
02304        t1 = P->key->t1;
02305        t2 = P->key->t2;
02306    #ifdef ALT_ECC_SIZE
02307        rx = P->key->x;
02308        ry = P->key->y;
02309        rz = P->key->z;
02310    #endif
02311    }
02312    else
02313 #endif /* WOLFSSL_SMALL_STACK_CACHE */
02314    {
02315        t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
02316        t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
02317        if (t1 == NULL || t2 == NULL) {
02318            XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
02319            XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
02320            return MEMORY_E;
02321        }
02322 #ifdef ALT_ECC_SIZE
02323        rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
02324        ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
02325        rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
02326        if (rx == NULL || ry == NULL || rz == NULL) {
02327            XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
02328            XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
02329            XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
02330            XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
02331            XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
02332            return MEMORY_E;
02333        }
02334 #endif
02335    }
02336 #endif /* WOLFSSL_SMALL_STACK */
02337 
02338    if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
02339 #ifdef WOLFSSL_SMALL_STACK
02340 #ifdef WOLFSSL_SMALL_STACK_CACHE
02341       if (P->key == NULL)
02342 #endif
02343       {
02344       #ifdef ALT_ECC_SIZE
02345          XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
02346          XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
02347          XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
02348       #endif
02349          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
02350          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
02351       }
02352 #endif
02353       return MEMORY_E;
02354    }
02355 
02356 #ifdef ALT_ECC_SIZE
02357    /* Use local stack variable */
02358    x = rx;
02359    y = ry;
02360    z = rz;
02361 
02362    if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
02363        goto done;
02364    }
02365 
02366    if (err == MP_OKAY)
02367        err = mp_copy(P->x, x);
02368    if (err == MP_OKAY)
02369        err = mp_copy(P->y, y);
02370    if (err == MP_OKAY)
02371        err = mp_copy(P->z, z);
02372 
02373    if (err != MP_OKAY) {
02374       goto done;
02375    }
02376 #else
02377    /* Use destination directly */
02378    x = P->x;
02379    y = P->y;
02380    z = P->z;
02381 #endif
02382 
02383    /* first map z back to normal */
02384    err = mp_montgomery_reduce(z, modulus, mp);
02385 
02386    /* get 1/z */
02387    if (err == MP_OKAY)
02388        err = mp_invmod(z, modulus, t1);
02389 
02390    /* get 1/z^2 and 1/z^3 */
02391    if (err == MP_OKAY)
02392        err = mp_sqr(t1, t2);
02393    if (err == MP_OKAY)
02394        err = mp_mod(t2, modulus, t2);
02395    if (err == MP_OKAY)
02396        err = mp_mul(t1, t2, t1);
02397    if (err == MP_OKAY)
02398        err = mp_mod(t1, modulus, t1);
02399 
02400    /* multiply against x/y */
02401    if (err == MP_OKAY)
02402        err = mp_mul(x, t2, x);
02403    if (err == MP_OKAY)
02404        err = mp_montgomery_reduce(x, modulus, mp);
02405    if (err == MP_OKAY)
02406        err = mp_mul(y, t1, y);
02407    if (err == MP_OKAY)
02408        err = mp_montgomery_reduce(y, modulus, mp);
02409 
02410    if (err == MP_OKAY)
02411        err = mp_set(z, 1);
02412 
02413 #ifdef ALT_ECC_SIZE
02414    /* return result */
02415    if (err == MP_OKAY)
02416       err = mp_copy(x, P->x);
02417    if (err == MP_OKAY)
02418       err = mp_copy(y, P->y);
02419    if (err == MP_OKAY)
02420       err = mp_copy(z, P->z);
02421 
02422 done:
02423 #endif
02424 
02425    /* clean up */
02426    mp_clear(t1);
02427    mp_clear(t2);
02428 
02429 #ifdef WOLFSSL_SMALL_STACK
02430 #ifdef WOLFSSL_SMALL_STACK_CACHE
02431    if (P->key == NULL)
02432 #endif
02433    {
02434    #ifdef ALT_ECC_SIZE
02435       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
02436       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
02437       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
02438    #endif
02439       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
02440       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
02441    }
02442 #endif
02443 
02444    return err;
02445 #else
02446     if (P == NULL || modulus == NULL)
02447         return ECC_BAD_ARG_E;
02448 
02449     (void)mp;
02450 
02451     return sp_ecc_map_256(P->x, P->y, P->z);
02452 #endif
02453 }
02454 
02455 #endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
02456 
02457 #if !defined(FREESCALE_LTC_ECC)
02458 
02459 #if !defined(FP_ECC) || !defined(WOLFSSL_SP_MATH)
02460 /**
02461    Perform a point multiplication
02462    k    The scalar to multiply by
02463    G    The base point
02464    R    [out] Destination for kG
02465    a    ECC curve parameter a
02466    modulus  The modulus of the field the ECC curve is in
02467    map      Boolean whether to map back to affine or not
02468                 (1==map, 0 == leave in projective)
02469    return MP_OKAY on success
02470 */
02471 #ifdef FP_ECC
02472 static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,
02473                   mp_int* a, mp_int* modulus, int map,
02474                   void* heap)
02475 #else
02476 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
02477                   mp_int* a, mp_int* modulus, int map,
02478                   void* heap)
02479 #endif
02480 {
02481 #ifndef WOLFSSL_SP_MATH
02482 #ifndef ECC_TIMING_RESISTANT
02483    /* size of sliding window, don't change this! */
02484    #define WINSIZE  4
02485    #define M_POINTS 8
02486    int           first = 1, bitbuf = 0, bitcpy = 0, j;
02487 #else
02488    #define M_POINTS 3
02489 #endif
02490 
02491    ecc_point     *tG, *M[M_POINTS];
02492    int           i, err;
02493 #ifdef WOLFSSL_SMALL_STACK
02494    mp_int*       mu = NULL;
02495 #ifdef WOLFSSL_SMALL_STACK_CACHE
02496    ecc_key       key;
02497 #endif
02498 #else
02499    mp_int        mu[1];
02500 #endif
02501    mp_digit      mp;
02502    mp_digit      buf;
02503    int           bitcnt = 0, mode = 0, digidx = 0;
02504 
02505    if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
02506        return ECC_BAD_ARG_E;
02507    }
02508 
02509    /* init variables */
02510    tG = NULL;
02511    XMEMSET(M, 0, sizeof(M));
02512 #ifdef WOLFSSL_SMALL_STACK
02513    mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
02514    if (mu == NULL)
02515        return MEMORY_E;
02516 #endif
02517 #ifdef WOLFSSL_SMALL_STACK_CACHE
02518    key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
02519    key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
02520 #ifdef ALT_ECC_SIZE
02521    key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
02522    key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
02523    key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
02524 #endif
02525    if (key.t1 == NULL || key.t2 == NULL
02526 #ifdef ALT_ECC_SIZE
02527       || key.x == NULL || key.y == NULL || key.z == NULL
02528 #endif
02529    ) {
02530 #ifdef ALT_ECC_SIZE
02531        XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
02532        XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
02533        XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
02534 #endif
02535        XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
02536        XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
02537        XFREE(mu, heap, DYNAMIC_TYPE_ECC);
02538        return MEMORY_E;
02539    }
02540 #endif /* WOLFSSL_SMALL_STACK_CACHE */
02541 
02542    /* init montgomery reduction */
02543    if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
02544 #ifdef WOLFSSL_SMALL_STACK_CACHE
02545 #ifdef ALT_ECC_SIZE
02546        XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
02547        XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
02548        XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
02549 #endif
02550        XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
02551        XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
02552 #endif /* WOLFSSL_SMALL_STACK_CACHE */
02553 #ifdef WOLFSSL_SMALL_STACK
02554        XFREE(mu, heap, DYNAMIC_TYPE_ECC);
02555 #endif
02556        return err;
02557    }
02558 
02559    if ((err = mp_init(mu)) != MP_OKAY) {
02560 #ifdef WOLFSSL_SMALL_STACK_CACHE
02561 #ifdef ALT_ECC_SIZE
02562        XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
02563        XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
02564        XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
02565 #endif
02566        XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
02567        XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
02568 #endif /* WOLFSSL_SMALL_STACK_CACHE */
02569 #ifdef WOLFSSL_SMALL_STACK
02570        XFREE(mu, heap, DYNAMIC_TYPE_ECC);
02571 #endif
02572        return err;
02573    }
02574    if ((err = mp_montgomery_calc_normalization(mu, modulus)) != MP_OKAY) {
02575        mp_clear(mu);
02576 #ifdef WOLFSSL_SMALL_STACK_CACHE
02577 #ifdef ALT_ECC_SIZE
02578        XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
02579        XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
02580        XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
02581 #endif
02582        XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
02583        XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
02584 #endif /* WOLFSSL_SMALL_STACK_CACHE */
02585 #ifdef WOLFSSL_SMALL_STACK
02586        XFREE(mu, heap, DYNAMIC_TYPE_ECC);
02587 #endif
02588        return err;
02589    }
02590 
02591   /* alloc ram for window temps */
02592   for (i = 0; i < M_POINTS; i++) {
02593       M[i] = wc_ecc_new_point_h(heap);
02594       if (M[i] == NULL) {
02595          mp_clear(mu);
02596          err = MEMORY_E; goto exit;
02597       }
02598 #ifdef WOLFSSL_SMALL_STACK_CACHE
02599       M[i]->key = &key;
02600 #endif
02601   }
02602 
02603    /* make a copy of G in case R==G */
02604    tG = wc_ecc_new_point_h(heap);
02605    if (tG == NULL)
02606        err = MEMORY_E;
02607 
02608    /* tG = G  and convert to montgomery */
02609    if (err == MP_OKAY) {
02610        if (mp_cmp_d(mu, 1) == MP_EQ) {
02611            err = mp_copy(G->x, tG->x);
02612            if (err == MP_OKAY)
02613                err = mp_copy(G->y, tG->y);
02614            if (err == MP_OKAY)
02615                err = mp_copy(G->z, tG->z);
02616        } else {
02617            err = mp_mulmod(G->x, mu, modulus, tG->x);
02618            if (err == MP_OKAY)
02619                err = mp_mulmod(G->y, mu, modulus, tG->y);
02620            if (err == MP_OKAY)
02621                err = mp_mulmod(G->z, mu, modulus, tG->z);
02622        }
02623    }
02624 
02625    /* done with mu */
02626    mp_clear(mu);
02627 
02628 #ifdef WOLFSSL_SMALL_STACK_CACHE
02629    R->key = &key;
02630 #endif
02631 #ifndef ECC_TIMING_RESISTANT
02632 
02633    /* calc the M tab, which holds kG for k==8..15 */
02634    /* M[0] == 8G */
02635    if (err == MP_OKAY)
02636        err = ecc_projective_dbl_point(tG, M[0], a, modulus, mp);
02637    if (err == MP_OKAY)
02638        err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
02639    if (err == MP_OKAY)
02640        err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
02641 
02642    /* now find (8+k)G for k=1..7 */
02643    if (err == MP_OKAY)
02644        for (j = 9; j < 16; j++) {
02645            err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a,
02646                                                                 modulus, mp);
02647            if (err != MP_OKAY) break;
02648        }
02649 
02650    /* setup sliding window */
02651    if (err == MP_OKAY) {
02652        mode   = 0;
02653        bitcnt = 1;
02654        buf    = 0;
02655        digidx = get_digit_count(k) - 1;
02656        bitcpy = bitbuf = 0;
02657        first  = 1;
02658 
02659        /* perform ops */
02660        for (;;) {
02661            /* grab next digit as required */
02662            if (--bitcnt == 0) {
02663                if (digidx == -1) {
02664                    break;
02665                }
02666                buf    = get_digit(k, digidx);
02667                bitcnt = (int) DIGIT_BIT;
02668                --digidx;
02669            }
02670 
02671            /* grab the next msb from the ltiplicand */
02672            i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
02673            buf <<= 1;
02674 
02675            /* skip leading zero bits */
02676            if (mode == 0 && i == 0)
02677                continue;
02678 
02679            /* if the bit is zero and mode == 1 then we double */
02680            if (mode == 1 && i == 0) {
02681                err = ecc_projective_dbl_point(R, R, a, modulus, mp);
02682                if (err != MP_OKAY) break;
02683                continue;
02684            }
02685 
02686            /* else we add it to the window */
02687            bitbuf |= (i << (WINSIZE - ++bitcpy));
02688            mode = 2;
02689 
02690            if (bitcpy == WINSIZE) {
02691                /* if this is the first window we do a simple copy */
02692                if (first == 1) {
02693                    /* R = kG [k = first window] */
02694                    err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
02695                    if (err != MP_OKAY) break;
02696 
02697                    err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
02698                    if (err != MP_OKAY) break;
02699 
02700                    err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
02701                    first = 0;
02702                } else {
02703                    /* normal window */
02704                    /* ok window is filled so double as required and add  */
02705                    /* double first */
02706                    for (j = 0; j < WINSIZE; j++) {
02707                        err = ecc_projective_dbl_point(R, R, a, modulus, mp);
02708                        if (err != MP_OKAY) break;
02709                    }
02710                    if (err != MP_OKAY) break;  /* out of first for(;;) */
02711 
02712                    /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
02713                    err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a,
02714                                                                modulus, mp);
02715                }
02716                if (err != MP_OKAY) break;
02717                /* empty window and reset */
02718                bitcpy = bitbuf = 0;
02719                mode = 1;
02720            }
02721        }
02722    }
02723 
02724    /* if bits remain then double/add */
02725    if (err == MP_OKAY) {
02726        if (mode == 2 && bitcpy > 0) {
02727            /* double then add */
02728            for (j = 0; j < bitcpy; j++) {
02729                /* only double if we have had at least one add first */
02730                if (first == 0) {
02731                    err = ecc_projective_dbl_point(R, R, a, modulus, mp);
02732                    if (err != MP_OKAY) break;
02733                }
02734 
02735                bitbuf <<= 1;
02736                if ((bitbuf & (1 << WINSIZE)) != 0) {
02737                    if (first == 1) {
02738                        /* first add, so copy */
02739                        err = mp_copy(tG->x, R->x);
02740                        if (err != MP_OKAY) break;
02741 
02742                        err = mp_copy(tG->y, R->y);
02743                        if (err != MP_OKAY) break;
02744 
02745                        err = mp_copy(tG->z, R->z);
02746                        if (err != MP_OKAY) break;
02747                        first = 0;
02748                    } else {
02749                        /* then add */
02750                        err = ecc_projective_add_point(R, tG, R, a, modulus,
02751                                                                        mp);
02752                        if (err != MP_OKAY) break;
02753                    }
02754                }
02755            }
02756        }
02757    }
02758 
02759    #undef WINSIZE
02760 
02761 #else /* ECC_TIMING_RESISTANT */
02762 
02763    /* calc the M tab */
02764    /* M[0] == G */
02765    if (err == MP_OKAY)
02766        err = mp_copy(tG->x, M[0]->x);
02767    if (err == MP_OKAY)
02768        err = mp_copy(tG->y, M[0]->y);
02769    if (err == MP_OKAY)
02770        err = mp_copy(tG->z, M[0]->z);
02771 
02772    /* M[1] == 2G */
02773    if (err == MP_OKAY)
02774        err = ecc_projective_dbl_point(tG, M[1], a, modulus, mp);
02775 
02776    /* setup sliding window */
02777    mode   = 0;
02778    bitcnt = 1;
02779    buf    = 0;
02780    digidx = get_digit_count(k) - 1;
02781 
02782    /* perform ops */
02783    if (err == MP_OKAY) {
02784        for (;;) {
02785            /* grab next digit as required */
02786            if (--bitcnt == 0) {
02787                if (digidx == -1) {
02788                    break;
02789                }
02790                buf = get_digit(k, digidx);
02791                bitcnt = (int)DIGIT_BIT;
02792                --digidx;
02793            }
02794 
02795            /* grab the next msb from the multiplicand */
02796            i = (buf >> (DIGIT_BIT - 1)) & 1;
02797            buf <<= 1;
02798 
02799            if (mode == 0 && i == 0) {
02800                /* timing resistant - dummy operations */
02801                if (err == MP_OKAY)
02802                    err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
02803                                                   mp);
02804                if (err == MP_OKAY)
02805                    err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
02806                if (err == MP_OKAY)
02807                    continue;
02808            }
02809 
02810            if (mode == 0 && i == 1) {
02811                mode = 1;
02812                /* timing resistant - dummy operations */
02813                if (err == MP_OKAY)
02814                    err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
02815                                                   mp);
02816                if (err == MP_OKAY)
02817                    err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
02818                if (err == MP_OKAY)
02819                    continue;
02820            }
02821 
02822            if (err == MP_OKAY)
02823                err = ecc_projective_add_point(M[0], M[1], M[i^1], a, modulus,
02824                                                                        mp);
02825 #ifdef WC_NO_CACHE_RESISTANT
02826            if (err == MP_OKAY)
02827                err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp);
02828 #else
02829             /* instead of using M[i] for double, which leaks key bit to cache
02830              * monitor, use M[2] as temp, make sure address calc is constant,
02831              * keep M[0] and M[1] in cache */
02832            if (err == MP_OKAY)
02833                err = mp_copy((mp_int*)
02834                              ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
02835                                ((wolfssl_word)M[1]->x & wc_off_on_addr[i])),
02836                              M[2]->x);
02837            if (err == MP_OKAY)
02838                err = mp_copy((mp_int*)
02839                              ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
02840                                ((wolfssl_word)M[1]->y & wc_off_on_addr[i])),
02841                              M[2]->y);
02842            if (err == MP_OKAY)
02843                err = mp_copy((mp_int*)
02844                              ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
02845                                ((wolfssl_word)M[1]->z & wc_off_on_addr[i])),
02846                              M[2]->z);
02847            if (err == MP_OKAY)
02848                err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp);
02849            /* copy M[2] back to M[i] */
02850            if (err == MP_OKAY)
02851                err = mp_copy(M[2]->x,
02852                              (mp_int*)
02853                              ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
02854                                ((wolfssl_word)M[1]->x & wc_off_on_addr[i])) );
02855            if (err == MP_OKAY)
02856                err = mp_copy(M[2]->y,
02857                              (mp_int*)
02858                              ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
02859                                ((wolfssl_word)M[1]->y & wc_off_on_addr[i])) );
02860            if (err == MP_OKAY)
02861                err = mp_copy(M[2]->z,
02862                              (mp_int*)
02863                              ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
02864                                ((wolfssl_word)M[1]->z & wc_off_on_addr[i])) );
02865            if (err != MP_OKAY)
02866                break;
02867 #endif /* WC_NO_CACHE_RESISTANT */
02868        } /* end for */
02869    }
02870 
02871    /* copy result out */
02872    if (err == MP_OKAY)
02873        err = mp_copy(M[0]->x, R->x);
02874    if (err == MP_OKAY)
02875        err = mp_copy(M[0]->y, R->y);
02876    if (err == MP_OKAY)
02877        err = mp_copy(M[0]->z, R->z);
02878 
02879 #endif /* ECC_TIMING_RESISTANT */
02880 
02881    /* map R back from projective space */
02882    if (err == MP_OKAY && map)
02883        err = ecc_map(R, modulus, mp);
02884 
02885 exit:
02886 
02887    /* done */
02888    wc_ecc_del_point_h(tG, heap);
02889    for (i = 0; i < M_POINTS; i++) {
02890        wc_ecc_del_point_h(M[i], heap);
02891    }
02892 #ifdef WOLFSSL_SMALL_STACK_CACHE
02893    R->key = NULL;
02894 #ifdef ALT_ECC_SIZE
02895    XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
02896    XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
02897    XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
02898 #endif
02899    XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
02900    XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
02901 #endif /* WOLFSSL_SMALL_STACK_CACHE */
02902 #ifdef WOLFSSL_SMALL_STACK
02903    XFREE(mu, heap, DYNAMIC_TYPE_ECC);
02904 #endif
02905 
02906    return err;
02907 #else
02908    if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
02909        return ECC_BAD_ARG_E;
02910    }
02911 
02912    (void)a;
02913 
02914    return sp_ecc_mulmod_256(k, G, R, map, heap);
02915 #endif
02916 }
02917 
02918 #endif /* !FP_ECC || !WOLFSSL_SP_MATH */
02919 
02920 #endif /* !FREESCALE_LTC_ECC */
02921 
02922 /** ECC Fixed Point mulmod global
02923     k        The multiplicand
02924     G        Base point to multiply
02925     R        [out] Destination of product
02926     a        ECC curve parameter a
02927     modulus  The modulus for the curve
02928     map      [boolean] If non-zero maps the point back to affine co-ordinates,
02929              otherwise it's left in jacobian-montgomery form
02930     return MP_OKAY if successful
02931 */
02932 int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
02933                   mp_int* modulus, int map)
02934 {
02935     return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
02936 }
02937 
02938 #endif /* !WOLFSSL_ATECC508A */
02939 
02940 /**
02941  * use a heap hint when creating new ecc_point
02942  * return an allocated point on success or NULL on failure
02943  */
02944 ecc_point* wc_ecc_new_point_h(void* heap)
02945 {
02946    ecc_point* p;
02947 
02948    (void)heap;
02949 
02950    p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
02951    if (p == NULL) {
02952       return NULL;
02953    }
02954    XMEMSET(p, 0, sizeof(ecc_point));
02955 
02956 #ifndef ALT_ECC_SIZE
02957    if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) {
02958       XFREE(p, heap, DYNAMIC_TYPE_ECC);
02959       return NULL;
02960    }
02961 #else
02962    p->x = (mp_int*)&p->xyz[0];
02963    p->y = (mp_int*)&p->xyz[1];
02964    p->z = (mp_int*)&p->xyz[2];
02965    alt_fp_init(p->x);
02966    alt_fp_init(p->y);
02967    alt_fp_init(p->z);
02968 #endif
02969 
02970    return p;
02971 }
02972 
02973 
02974 /**
02975    Allocate a new ECC point
02976    return A newly allocated point or NULL on error
02977 */
02978 ecc_point* wc_ecc_new_point(void)
02979 {
02980   return wc_ecc_new_point_h(NULL);
02981 }
02982 
02983 
02984 void wc_ecc_del_point_h(ecc_point* p, void* heap)
02985 {
02986    /* prevents free'ing null arguments */
02987    if (p != NULL) {
02988       mp_clear(p->x);
02989       mp_clear(p->y);
02990       mp_clear(p->z);
02991       XFREE(p, heap, DYNAMIC_TYPE_ECC);
02992    }
02993    (void)heap;
02994 }
02995 
02996 
02997 /** Free an ECC point from memory
02998   p   The point to free
02999 */
03000 void wc_ecc_del_point(ecc_point* p)
03001 {
03002     wc_ecc_del_point_h(p, NULL);
03003 }
03004 
03005 
03006 /** Copy the value of a point to an other one
03007   p    The point to copy
03008   r    The created point
03009 */
03010 int wc_ecc_copy_point(ecc_point* p, ecc_point *r)
03011 {
03012     int ret;
03013 
03014     /* prevents null arguments */
03015     if (p == NULL || r == NULL)
03016         return ECC_BAD_ARG_E;
03017 
03018     ret = mp_copy(p->x, r->x);
03019     if (ret != MP_OKAY)
03020         return ret;
03021     ret = mp_copy(p->y, r->y);
03022     if (ret != MP_OKAY)
03023         return ret;
03024     ret = mp_copy(p->z, r->z);
03025     if (ret != MP_OKAY)
03026         return ret;
03027 
03028     return MP_OKAY;
03029 }
03030 
03031 /** Compare the value of a point with an other one
03032  a    The point to compare
03033  b    The other point to compare
03034 
03035  return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
03036  */
03037 int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
03038 {
03039     int ret;
03040 
03041     /* prevents null arguments */
03042     if (a == NULL || b == NULL)
03043         return BAD_FUNC_ARG;
03044 
03045     ret = mp_cmp(a->x, b->x);
03046     if (ret != MP_EQ)
03047         return ret;
03048     ret = mp_cmp(a->y, b->y);
03049     if (ret != MP_EQ)
03050         return ret;
03051     ret = mp_cmp(a->z, b->z);
03052     if (ret != MP_EQ)
03053         return ret;
03054 
03055     return MP_EQ;
03056 }
03057 
03058 
03059 /** Returns whether an ECC idx is valid or not
03060   n      The idx number to check
03061   return 1 if valid, 0 if not
03062 */
03063 int wc_ecc_is_valid_idx(int n)
03064 {
03065    int x;
03066 
03067    for (x = 0; ecc_sets[x].size != 0; x++)
03068        ;
03069    /* -1 is a valid index --- indicating that the domain params
03070       were supplied by the user */
03071    if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
03072       return 1;
03073    }
03074 
03075    return 0;
03076 }
03077 
03078 int wc_ecc_get_curve_idx(int curve_id)
03079 {
03080     int curve_idx;
03081     for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
03082         if (curve_id == ecc_sets[curve_idx].id)
03083             break;
03084     }
03085     if (ecc_sets[curve_idx].size == 0) {
03086         return ECC_CURVE_INVALID;
03087     }
03088     return curve_idx;
03089 }
03090 
03091 int wc_ecc_get_curve_id(int curve_idx)
03092 {
03093     if (wc_ecc_is_valid_idx(curve_idx)) {
03094         return ecc_sets[curve_idx].id;
03095     }
03096     return ECC_CURVE_INVALID;
03097 }
03098 
03099 /* Returns the curve size that corresponds to a given ecc_curve_id identifier
03100  *
03101  * id      curve id, from ecc_curve_id enum in ecc.h
03102  * return  curve size, from ecc_sets[] on success, negative on error
03103  */
03104 int wc_ecc_get_curve_size_from_id(int curve_id)
03105 {
03106     int curve_idx = wc_ecc_get_curve_idx(curve_id);
03107     if (curve_idx == ECC_CURVE_INVALID)
03108         return ECC_BAD_ARG_E;
03109     return ecc_sets[curve_idx].size;
03110 }
03111 
03112 /* Returns the curve index that corresponds to a given curve name in
03113  * ecc_sets[] of ecc.c
03114  *
03115  * name    curve name, from ecc_sets[].name in ecc.c
03116  * return  curve index in ecc_sets[] on success, negative on error
03117  */
03118 int wc_ecc_get_curve_idx_from_name(const char* curveName)
03119 {
03120     int curve_idx;
03121     word32 len;
03122 
03123     if (curveName == NULL)
03124         return BAD_FUNC_ARG;
03125 
03126     len = (word32)XSTRLEN(curveName);
03127 
03128     for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
03129         if (ecc_sets[curve_idx].name &&
03130                 XSTRNCASECMP(ecc_sets[curve_idx].name, curveName, len) == 0) {
03131             break;
03132         }
03133     }
03134     if (ecc_sets[curve_idx].size == 0) {
03135         WOLFSSL_MSG("ecc_set curve name not found");
03136         return ECC_CURVE_INVALID;
03137     }
03138     return curve_idx;
03139 }
03140 
03141 /* Returns the curve size that corresponds to a given curve name,
03142  * as listed in ecc_sets[] of ecc.c.
03143  *
03144  * name    curve name, from ecc_sets[].name in ecc.c
03145  * return  curve size, from ecc_sets[] on success, negative on error
03146  */
03147 int wc_ecc_get_curve_size_from_name(const char* curveName)
03148 {
03149     int curve_idx;
03150 
03151     if (curveName == NULL)
03152         return BAD_FUNC_ARG;
03153 
03154     curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
03155     if (curve_idx < 0)
03156         return curve_idx;
03157 
03158     return ecc_sets[curve_idx].size;
03159 }
03160 
03161 /* Returns the curve id that corresponds to a given curve name,
03162  * as listed in ecc_sets[] of ecc.c.
03163  *
03164  * name   curve name, from ecc_sets[].name in ecc.c
03165  * return curve id, from ecc_sets[] on success, negative on error
03166  */
03167 int wc_ecc_get_curve_id_from_name(const char* curveName)
03168 {
03169     int curve_idx;
03170 
03171     if (curveName == NULL)
03172         return BAD_FUNC_ARG;
03173 
03174     curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
03175     if (curve_idx < 0)
03176         return curve_idx;
03177 
03178     return ecc_sets[curve_idx].id;
03179 }
03180 
03181 /* Compares a curve parameter (hex, from ecc_sets[]) to given input
03182  * parameter (byte array) for equality.
03183  *
03184  * Returns MP_EQ on success, negative on error */
03185 static int wc_ecc_cmp_param(const char* curveParam,
03186                             const byte* param, word32 paramSz)
03187 {
03188     int err = MP_OKAY;
03189 #ifdef WOLFSSL_SMALL_STACK
03190     mp_int* a = NULL;
03191     mp_int* b = NULL;
03192 #else
03193     mp_int  a[1], b[1];
03194 #endif
03195 
03196     if (param == NULL || curveParam == NULL)
03197         return BAD_FUNC_ARG;
03198 
03199 #ifdef WOLFSSL_SMALL_STACK
03200     a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
03201     if (a == NULL)
03202         return MEMORY_E;
03203     b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
03204     if (b == NULL) {
03205         XFREE(a, NULL, DYNAMIC_TYPE_ECC);
03206         return MEMORY_E;
03207     }
03208 #endif
03209 
03210     if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY)
03211         return err;
03212 
03213     if (err == MP_OKAY)
03214         err = mp_read_unsigned_bin(a, param, paramSz);
03215 
03216     if (err == MP_OKAY)
03217         err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
03218 
03219     if (err == MP_OKAY) {
03220         if (mp_cmp(a, b) != MP_EQ) {
03221             err = -1;
03222         } else {
03223             err = MP_EQ;
03224         }
03225     }
03226 
03227     mp_clear(a);
03228     mp_clear(b);
03229 #ifdef WOLFSSL_SMALL_STACK
03230     XFREE(b, NULL, DYNAMIC_TYPE_ECC);
03231     XFREE(a, NULL, DYNAMIC_TYPE_ECC);
03232 #endif
03233 
03234     return err;
03235 }
03236 
03237 /* Returns the curve id in ecc_sets[] that corresponds to a given set of
03238  * curve parameters.
03239  *
03240  * fieldSize  the field size in bits
03241  * prime      prime of the finite field
03242  * primeSz    size of prime in octets
03243  * Af         first coefficient a of the curve
03244  * AfSz       size of Af in octets
03245  * Bf         second coefficient b of the curve
03246  * BfSz       size of Bf in octets
03247  * order      curve order
03248  * orderSz    size of curve in octets
03249  * Gx         affine x coordinate of base point
03250  * GxSz       size of Gx in octets
03251  * Gy         affine y coordinate of base point
03252  * GySz       size of Gy in octets
03253  * cofactor   curve cofactor
03254  *
03255  * return curve id, from ecc_sets[] on success, negative on error
03256  */
03257 int wc_ecc_get_curve_id_from_params(int fieldSize,
03258         const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
03259         const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
03260         const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
03261 {
03262     int idx;
03263     int curveSz;
03264 
03265     if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
03266         Gx == NULL || Gy == NULL)
03267         return BAD_FUNC_ARG;
03268 
03269     curveSz = (fieldSize + 1) / 8;    /* round up */
03270 
03271     for (idx = 0; ecc_sets[idx].size != 0; idx++) {
03272         if (curveSz == ecc_sets[idx].size) {
03273             if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
03274                             primeSz) == MP_EQ) &&
03275                 (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz) == MP_EQ) &&
03276                 (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz) == MP_EQ) &&
03277                 (wc_ecc_cmp_param(ecc_sets[idx].order, order,
03278                                   orderSz) == MP_EQ) &&
03279                 (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz) == MP_EQ) &&
03280                 (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz) == MP_EQ) &&
03281                 (cofactor == ecc_sets[idx].cofactor)) {
03282                     break;
03283             }
03284         }
03285     }
03286 
03287     if (ecc_sets[idx].size == 0)
03288         return ECC_CURVE_INVALID;
03289 
03290     return ecc_sets[idx].id;
03291 }
03292 
03293 
03294 #ifdef WOLFSSL_ASYNC_CRYPT
03295 static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
03296 {
03297    if (key == NULL || mp == NULL)
03298       return BAD_FUNC_ARG;
03299    if (*mp == NULL) {
03300       *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
03301       if (*mp == NULL) {
03302          return MEMORY_E;
03303       }
03304       XMEMSET(*mp, 0, sizeof(mp_int));
03305    }
03306    return 0;
03307 }
03308 static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
03309 {
03310    if (key && mp && *mp) {
03311       mp_clear(*mp);
03312       XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
03313       *mp = NULL;
03314    }
03315 }
03316 
03317 static int wc_ecc_alloc_async(ecc_key* key)
03318 {
03319     int err = wc_ecc_alloc_mpint(key, &key->r);
03320     if (err == 0)
03321         err = wc_ecc_alloc_mpint(key, &key->s);
03322     return err;
03323 }
03324 
03325 static void wc_ecc_free_async(ecc_key* key)
03326 {
03327     wc_ecc_free_mpint(key, &key->r);
03328     wc_ecc_free_mpint(key, &key->s);
03329 #ifdef HAVE_CAVIUM_V
03330     wc_ecc_free_mpint(key, &key->e);
03331     wc_ecc_free_mpint(key, &key->signK);
03332 #endif /* HAVE_CAVIUM_V */
03333 }
03334 #endif /* WOLFSSL_ASYNC_CRYPT */
03335 
03336 
03337 #ifdef HAVE_ECC_DHE
03338 /**
03339   Create an ECC shared secret between two keys
03340   private_key      The private ECC key (heap hint based off of private key)
03341   public_key       The public key
03342   out              [out] Destination of the shared secret
03343                          Conforms to EC-DH from ANSI X9.63
03344   outlen           [in/out] The max size and resulting size of the shared secret
03345   return           MP_OKAY if successful
03346 */
03347 int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
03348                       word32* outlen)
03349 {
03350    int err;
03351 
03352    if (private_key == NULL || public_key == NULL || out == NULL ||
03353                                                             outlen == NULL) {
03354        return BAD_FUNC_ARG;
03355    }
03356 
03357 #ifdef WOLF_CRYPTO_DEV
03358     if (private_key->devId != INVALID_DEVID) {
03359         err = wc_CryptoDev_Ecdh(private_key, public_key, out, outlen);
03360         if (err != NOT_COMPILED_IN)
03361             return err;
03362     }
03363 #endif
03364 
03365    /* type valid? */
03366    if (private_key->type != ECC_PRIVATEKEY &&
03367            private_key->type != ECC_PRIVATEKEY_ONLY) {
03368       return ECC_BAD_ARG_E;
03369    }
03370 
03371    /* Verify domain params supplied */
03372    if (wc_ecc_is_valid_idx(private_key->idx) == 0 ||
03373        wc_ecc_is_valid_idx(public_key->idx)  == 0) {
03374       return ECC_BAD_ARG_E;
03375    }
03376 
03377    /* Verify curve id matches */
03378    if (private_key->dp->id != public_key->dp->id) {
03379       return ECC_BAD_ARG_E;
03380    }
03381 
03382 #ifdef WOLFSSL_ATECC508A
03383    err = atcatls_ecdh(private_key->slot, public_key->pubkey_raw, out);
03384    if (err != ATCA_SUCCESS) {
03385       err = BAD_COND_E;
03386    }
03387    *outlen = private_key->dp->size;
03388 #else
03389    err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
03390 #endif /* WOLFSSL_ATECC508A */
03391 
03392    return err;
03393 }
03394 
03395 
03396 #ifndef WOLFSSL_ATECC508A
03397 
03398 static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
03399                                byte* out, word32* outlen, ecc_curve_spec* curve)
03400 {
03401     int err;
03402 #ifndef WOLFSSL_SP_MATH
03403     ecc_point* result = NULL;
03404     word32 x = 0;
03405 #endif
03406     mp_int* k = &private_key->k;
03407 #ifdef HAVE_ECC_CDH
03408     mp_int k_lcl;
03409 
03410     /* if cofactor flag has been set */
03411     if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
03412         mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
03413         /* only perform cofactor calc if not equal to 1 */
03414         if (cofactor != 1) {
03415             k = &k_lcl;
03416             if (mp_init(k) != MP_OKAY)
03417                 return MEMORY_E;
03418             /* multiply cofactor times private key "k" */
03419             err = mp_mul_d(&private_key->k, cofactor, k);
03420             if (err != MP_OKAY) {
03421                 mp_clear(k);
03422                 return err;
03423             }
03424         }
03425     }
03426 #endif
03427 
03428 #ifdef WOLFSSL_HAVE_SP_ECC
03429 #ifndef WOLFSSL_SP_NO_256
03430     if (private_key->idx != ECC_CUSTOM_IDX &&
03431                                ecc_sets[private_key->idx].id == ECC_SECP256R1) {
03432         err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
03433     }
03434     else
03435 #endif
03436 #endif
03437 #ifdef WOLFSSL_SP_MATH
03438     {
03439         err = WC_KEY_SIZE_E;
03440 
03441         (void)curve;
03442     }
03443 #else
03444     {
03445         /* make new point */
03446         result = wc_ecc_new_point_h(private_key->heap);
03447         if (result == NULL) {
03448 #ifdef HAVE_ECC_CDH
03449             if (k == &k_lcl)
03450                 mp_clear(k);
03451 #endif
03452             return MEMORY_E;
03453         }
03454 
03455         err = wc_ecc_mulmod_ex(k, point, result, curve->Af, curve->prime, 1,
03456                                                              private_key->heap);
03457         if (err == MP_OKAY) {
03458             x = mp_unsigned_bin_size(curve->prime);
03459             if (*outlen < x) {
03460                 err = BUFFER_E;
03461             }
03462         }
03463 
03464         if (err == MP_OKAY) {
03465             XMEMSET(out, 0, x);
03466             err = mp_to_unsigned_bin(result->x,out +
03467                                      (x - mp_unsigned_bin_size(result->x)));
03468         }
03469         *outlen = x;
03470 
03471         wc_ecc_del_point_h(result, private_key->heap);
03472     }
03473 #endif
03474 #ifdef HAVE_ECC_CDH
03475     if (k == &k_lcl)
03476         mp_clear(k);
03477 #endif
03478 
03479     return err;
03480 }
03481 
03482 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
03483 static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
03484             ecc_point* point, byte* out, word32 *outlen,
03485             ecc_curve_spec* curve)
03486 {
03487     int err;
03488 
03489 #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
03490 #ifdef HAVE_CAVIUM_V
03491     /* verify the curve is supported by hardware */
03492     if (NitroxEccIsCurveSupported(private_key))
03493 #endif
03494     {
03495         word32 keySz = private_key->dp->size;
03496 
03497         /* sync public key x/y */
03498         err = wc_mp_to_bigint_sz(&private_key->k, &private_key->k.raw, keySz);
03499         if (err == MP_OKAY)
03500             err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
03501         if (err == MP_OKAY)
03502             err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
03503     #ifdef HAVE_CAVIUM_V
03504         /* allocate buffer for output */
03505         if (err == MP_OKAY)
03506             err = wc_ecc_alloc_mpint(private_key, &private_key->e);
03507         if (err == MP_OKAY)
03508             err = wc_bigint_alloc(&private_key->e->raw,
03509                 NitroxEccGetSize(private_key)*2);
03510         if (err == MP_OKAY)
03511             err = NitroxEcdh(private_key,
03512                 &private_key->k.raw, &point->x->raw, &point->y->raw,
03513                 private_key->e->raw.buf, &private_key->e->raw.len,
03514                 &curve->prime->raw);
03515     #else
03516         if (err == MP_OKAY)
03517             err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
03518         if (err == MP_OKAY)
03519             err = IntelQaEcdh(&private_key->asyncDev,
03520                 &private_key->k.raw, &point->x->raw, &point->y->raw,
03521                 out, outlen,
03522                 &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
03523                 private_key->dp->cofactor);
03524     #endif
03525         return err;
03526     }
03527 #elif defined(WOLFSSL_ASYNC_CRYPT_TEST)
03528     if (wc_AsyncTestInit(&private_key->asyncDev, ASYNC_TEST_ECC_SHARED_SEC)) {
03529         WC_ASYNC_TEST* testDev = &private_key->asyncDev.test;
03530         testDev->eccSharedSec.private_key = private_key;
03531         testDev->eccSharedSec.public_point = point;
03532         testDev->eccSharedSec.out = out;
03533         testDev->eccSharedSec.outLen = outlen;
03534         return WC_PENDING_E;
03535     }
03536 #endif
03537 
03538     /* use sync in other cases */
03539     err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve);
03540 
03541     return err;
03542 }
03543 #endif /* WOLFSSL_ASYNC_CRYPT */
03544 
03545 int wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point,
03546                                                     byte* out, word32 *outlen)
03547 {
03548     int err;
03549     DECLARE_CURVE_SPECS(curve, 2);
03550 
03551     if (private_key == NULL || point == NULL || out == NULL ||
03552                                                             outlen == NULL) {
03553         return BAD_FUNC_ARG;
03554     }
03555 
03556     ALLOC_CURVE_SPECS(2);
03557 
03558     /* load curve info */
03559     err = wc_ecc_curve_load(private_key->dp, &curve,
03560         (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
03561     if (err != MP_OKAY) {
03562         FREE_CURVE_SPECS();
03563         return err;
03564     }
03565 
03566 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
03567     if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
03568         err = wc_ecc_shared_secret_gen_async(private_key, point,
03569             out, outlen, curve);
03570     }
03571     else
03572 #endif
03573     {
03574         err = wc_ecc_shared_secret_gen_sync(private_key, point,
03575             out, outlen, curve);
03576     }
03577 
03578     wc_ecc_curve_free(curve);
03579     FREE_CURVE_SPECS();
03580 
03581     return err;
03582 }
03583 
03584 /**
03585  Create an ECC shared secret between private key and public point
03586  private_key      The private ECC key (heap hint based on private key)
03587  point            The point to use (public key)
03588  out              [out] Destination of the shared secret
03589                         Conforms to EC-DH from ANSI X9.63
03590  outlen           [in/out] The max size and resulting size of the shared secret
03591  return           MP_OKAY if successful
03592 */
03593 int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
03594                             byte* out, word32 *outlen)
03595 {
03596     int err;
03597 
03598     if (private_key == NULL || point == NULL || out == NULL ||
03599                                                             outlen == NULL) {
03600         return BAD_FUNC_ARG;
03601     }
03602 
03603     /* type valid? */
03604     if (private_key->type != ECC_PRIVATEKEY &&
03605             private_key->type != ECC_PRIVATEKEY_ONLY) {
03606         return ECC_BAD_ARG_E;
03607     }
03608 
03609     /* Verify domain params supplied */
03610     if (wc_ecc_is_valid_idx(private_key->idx) == 0)
03611         return ECC_BAD_ARG_E;
03612 
03613     switch(private_key->state) {
03614         case ECC_STATE_NONE:
03615         case ECC_STATE_SHARED_SEC_GEN:
03616             private_key->state = ECC_STATE_SHARED_SEC_GEN;
03617 
03618             err = wc_ecc_shared_secret_gen(private_key, point, out, outlen);
03619             if (err < 0) {
03620                 break;
03621             }
03622             FALL_THROUGH;
03623 
03624         case ECC_STATE_SHARED_SEC_RES:
03625             private_key->state = ECC_STATE_SHARED_SEC_RES;
03626         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
03627             if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
03628             #ifdef HAVE_CAVIUM_V
03629                 /* verify the curve is supported by hardware */
03630                 if (NitroxEccIsCurveSupported(private_key)) {
03631                     /* copy output */
03632                     *outlen = private_key->dp->size;
03633                     XMEMCPY(out, private_key->e->raw.buf, *outlen);
03634                 }
03635             #endif /* HAVE_CAVIUM_V */
03636             }
03637         #endif /* WOLFSSL_ASYNC_CRYPT */
03638             err = 0;
03639             break;
03640 
03641         default:
03642             err = BAD_STATE_E;
03643     } /* switch */
03644 
03645     /* if async pending then return and skip done cleanup below */
03646     if (err == WC_PENDING_E) {
03647         private_key->state++;
03648         return err;
03649     }
03650 
03651     /* cleanup */
03652 #ifdef WOLFSSL_ASYNC_CRYPT
03653     wc_ecc_free_async(private_key);
03654 #endif
03655     private_key->state = ECC_STATE_NONE;
03656 
03657     return err;
03658 }
03659 #endif /* !WOLFSSL_ATECC508A */
03660 #endif /* HAVE_ECC_DHE */
03661 
03662 
03663 #ifndef WOLFSSL_ATECC508A
03664 /* return 1 if point is at infinity, 0 if not, < 0 on error */
03665 int wc_ecc_point_is_at_infinity(ecc_point* p)
03666 {
03667     if (p == NULL)
03668         return BAD_FUNC_ARG;
03669 
03670     if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0)
03671         return 1;
03672 
03673     return 0;
03674 }
03675 
03676 #ifndef WOLFSSL_SP_MATH
03677 /* generate random and ensure its greater than 0 and less than order */
03678 static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
03679 {
03680     int err;
03681     DECLARE_VAR(buf, byte, ECC_MAXSIZE_GEN, rng->heap);
03682 
03683     /*generate 8 extra bytes to mitigate bias from the modulo operation below*/
03684     /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/
03685     size += 8;
03686 
03687     /* make up random string */
03688     err = wc_RNG_GenerateBlock(rng, buf, size);
03689 
03690     /* load random buffer data into k */
03691     if (err == 0)
03692         err = mp_read_unsigned_bin(k, (byte*)buf, size);
03693 
03694     /* the key should be smaller than the order of base point */
03695     if (err == MP_OKAY) {
03696         if (mp_cmp(k, order) != MP_LT) {
03697             err = mp_mod(k, order, k);
03698         }
03699     }
03700 
03701     /* quick sanity check to make sure we're not dealing with a 0 key */
03702     if (err == MP_OKAY) {
03703         if (mp_iszero(k) == MP_YES)
03704           err = MP_ZERO_E;
03705     }
03706 
03707     ForceZero(buf, ECC_MAXSIZE);
03708     FREE_VAR(buf, rng->heap);
03709 
03710     return err;
03711 }
03712 #endif
03713 #endif /* !WOLFSSL_ATECC508A */
03714 
03715 static WC_INLINE void wc_ecc_reset(ecc_key* key)
03716 {
03717     /* make sure required key variables are reset */
03718     key->state = ECC_STATE_NONE;
03719 }
03720 
03721 
03722 /* create the public ECC key from a private key
03723  *
03724  * key     an initialized private key to generate public part from
03725  * curveIn [in]curve for key, can be NULL
03726  * pubOut  [out]ecc_point holding the public key, if NULL then public key part
03727  *         is cached in key instead.
03728  *
03729  * Note this function is local to the file because of the argument type
03730  *      ecc_curve_spec. Having this argument allows for not having to load the
03731  *      curve type multiple times when generating a key with wc_ecc_make_key().
03732  *
03733  * returns MP_OKAY on success
03734  */
03735 static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
03736         ecc_point* pubOut)
03737 {
03738     int err = MP_OKAY;
03739 #ifndef WOLFSSL_ATECC508A
03740 #ifndef WOLFSSL_SP_MATH
03741     ecc_point* base = NULL;
03742 #endif
03743     ecc_point* pub;
03744     DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
03745 #endif
03746 
03747     if (key == NULL) {
03748         return BAD_FUNC_ARG;
03749     }
03750 
03751 #ifndef WOLFSSL_ATECC508A
03752 
03753     /* if ecc_point passed in then use it as output for public key point */
03754     if (pubOut != NULL) {
03755         pub = pubOut;
03756     }
03757     else {
03758         /* caching public key making it a ECC_PRIVATEKEY instead of
03759            ECC_PRIVATEKEY_ONLY */
03760         pub = &key->pubkey;
03761         key->type = ECC_PRIVATEKEY_ONLY;
03762     }
03763 
03764     /* avoid loading the curve unless it is not passed in */
03765     if (curveIn != NULL) {
03766         curve = curveIn;
03767     }
03768     else {
03769         ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
03770 
03771         /* load curve info */
03772         if (err == MP_OKAY)
03773             err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
03774     }
03775 
03776     if (err == MP_OKAY) {
03777     #ifndef ALT_ECC_SIZE
03778         err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
03779     #else
03780         pub->x = (mp_int*)&pub->xyz[0];
03781         pub->y = (mp_int*)&pub->xyz[1];
03782         pub->z = (mp_int*)&pub->xyz[2];
03783         alt_fp_init(pub->x);
03784         alt_fp_init(pub->y);
03785         alt_fp_init(pub->z);
03786     #endif
03787     }
03788 
03789 
03790 #ifdef WOLFSSL_HAVE_SP_ECC
03791 #ifndef WOLFSSL_SP_NO_256
03792     if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
03793         if (err == MP_OKAY)
03794             err = sp_ecc_mulmod_base_256(&key->k, pub, 1, key->heap);
03795     }
03796     else
03797 #endif
03798 #endif
03799 #ifdef WOLFSSL_SP_MATH
03800         err = WC_KEY_SIZE_E;
03801 #else
03802     {
03803         if (err == MP_OKAY) {
03804             base = wc_ecc_new_point_h(key->heap);
03805             if (base == NULL)
03806                 err = MEMORY_E;
03807         }
03808         /* read in the x/y for this key */
03809         if (err == MP_OKAY)
03810             err = mp_copy(curve->Gx, base->x);
03811         if (err == MP_OKAY)
03812             err = mp_copy(curve->Gy, base->y);
03813         if (err == MP_OKAY)
03814             err = mp_set(base->z, 1);
03815 
03816         /* make the public key */
03817         if (err == MP_OKAY) {
03818             err = wc_ecc_mulmod_ex(&key->k, base, pub, curve->Af, curve->prime,
03819                                                                   1, key->heap);
03820         }
03821 
03822         wc_ecc_del_point_h(base, key->heap);
03823     }
03824 #endif
03825 
03826 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
03827     /* validate the public key, order * pubkey = point at infinity */
03828     if (err == MP_OKAY)
03829         err = ecc_check_pubkey_order(key, pub, curve->Af, curve->prime,
03830                 curve->order);
03831 #endif /* WOLFSSL_VALIDATE_KEYGEN */
03832 
03833     if (err != MP_OKAY) {
03834         /* clean up if failed */
03835     #ifndef ALT_ECC_SIZE
03836         mp_clear(pub->x);
03837         mp_clear(pub->y);
03838         mp_clear(pub->z);
03839     #endif
03840     }
03841 
03842     /* free up local curve */
03843     if (curveIn == NULL) {
03844         wc_ecc_curve_free(curve);
03845     #ifndef WOLFSSL_ATECC508A
03846         FREE_CURVE_SPECS();
03847     #endif
03848     }
03849 
03850 #else
03851     (void)curveIn;
03852 #endif /* WOLFSSL_ATECC508A */
03853 
03854     /* change key state if public part is cached */
03855     if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
03856         key->type = ECC_PRIVATEKEY;
03857     }
03858 
03859     return err;
03860 }
03861 
03862 
03863 /* create the public ECC key from a private key
03864  *
03865  * key     an initialized private key to generate public part from
03866  * pubOut  [out]ecc_point holding the public key, if NULL then public key part
03867  *         is cached in key instead.
03868  *
03869  *
03870  * returns MP_OKAY on success
03871  */
03872 int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
03873 {
03874     WOLFSSL_ENTER("wc_ecc_make_pub");
03875 
03876     return wc_ecc_make_pub_ex(key, NULL, pubOut);
03877 }
03878 
03879 
03880 int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
03881 {
03882     int            err;
03883 #ifndef WOLFSSL_ATECC508A
03884 #ifndef WOLFSSL_SP_MATH
03885     DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
03886 #endif
03887 #endif
03888 
03889     if (key == NULL || rng == NULL) {
03890         return BAD_FUNC_ARG;
03891     }
03892 
03893     /* make sure required variables are reset */
03894     wc_ecc_reset(key);
03895 
03896     err = wc_ecc_set_curve(key, keysize, curve_id);
03897     if (err != 0) {
03898         return err;
03899     }
03900 
03901 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
03902     if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
03903     #ifdef HAVE_CAVIUM
03904         /* TODO: Not implemented */
03905     #elif defined(HAVE_INTEL_QA)
03906         /* TODO: Not implemented */
03907     #else
03908         if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_MAKE)) {
03909             WC_ASYNC_TEST* testDev = &key->asyncDev.test;
03910             testDev->eccMake.rng = rng;
03911             testDev->eccMake.key = key;
03912             testDev->eccMake.size = keysize;
03913             testDev->eccMake.curve_id = curve_id;
03914             return WC_PENDING_E;
03915         }
03916     #endif
03917     }
03918 #endif /* WOLFSSL_ASYNC_CRYPT */
03919 
03920 #ifdef WOLFSSL_ATECC508A
03921    key->type = ECC_PRIVATEKEY;
03922    err = atcatls_create_key(key->slot, key->pubkey_raw);
03923    if (err != ATCA_SUCCESS) {
03924       err = BAD_COND_E;
03925    }
03926 
03927    /* populate key->pubkey */
03928    err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
03929                               ECC_MAX_CRYPTO_HW_SIZE);
03930    if (err == MP_OKAY)
03931        err = mp_read_unsigned_bin(key->pubkey.y,
03932                                   key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,
03933                                   ECC_MAX_CRYPTO_HW_SIZE);
03934 #else
03935 
03936 #ifdef WOLFSSL_HAVE_SP_ECC
03937 #ifndef WOLFSSL_SP_NO_256
03938     if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
03939         err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap);
03940         if (err == MP_OKAY)
03941             key->type = ECC_PRIVATEKEY;
03942     }
03943     else
03944 #endif
03945 #endif
03946 #ifdef WOLFSSL_SP_MATH
03947         err = WC_KEY_SIZE_E;
03948 #else
03949     {
03950         ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
03951 
03952         /* setup the key variables */
03953         err = mp_init(&key->k);
03954 
03955         /* load curve info */
03956         if (err == MP_OKAY)
03957             err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
03958 
03959         /* generate k */
03960         if (err == MP_OKAY)
03961             err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order);
03962 
03963         /* generate public key from k */
03964         if (err == MP_OKAY)
03965             err = wc_ecc_make_pub_ex(key, curve, NULL);
03966 
03967         if (err == MP_OKAY)
03968             key->type = ECC_PRIVATEKEY;
03969 
03970         /* cleanup these on failure case only */
03971         if (err != MP_OKAY) {
03972             /* clean up */
03973             mp_forcezero(&key->k);
03974         }
03975 
03976         /* cleanup allocations */
03977         wc_ecc_curve_free(curve);
03978     #ifndef WOLFSSL_ATECC508A
03979         FREE_CURVE_SPECS();
03980     #endif
03981     }
03982 #endif
03983 
03984 #endif /* WOLFSSL_ATECC508A */
03985 
03986     return err;
03987 }
03988 
03989 #ifdef ECC_DUMP_OID
03990 /* Optional dump of encoded OID for adding new curves */
03991 static int mOidDumpDone;
03992 static void wc_ecc_dump_oids(void)
03993 {
03994     int x;
03995 
03996     if (mOidDumpDone) {
03997         return;
03998     }
03999 
04000     /* find matching OID sum (based on encoded value) */
04001     for (x = 0; ecc_sets[x].size != 0; x++) {
04002         int i;
04003         byte* oid;
04004         word32 oidSz, sum = 0;
04005 
04006         printf("ECC %s (%d):\n", ecc_sets[x].name, x);
04007 
04008     #ifdef HAVE_OID_ENCODING
04009         byte oidEnc[ECC_MAX_OID_LEN];
04010 
04011         oid = oidEnc;
04012         oidSz = ECC_MAX_OID_LEN;
04013 
04014         printf("OID: ");
04015         for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
04016             printf("%d.", ecc_sets[x].oid[i]);
04017         }
04018         printf("\n");
04019 
04020         EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
04021     #else
04022         oid = (byte*)ecc_sets[x].oid;
04023         oidSz = ecc_sets[x].oidSz;
04024     #endif
04025 
04026         printf("OID Encoded: ");
04027         for (i = 0; i < (int)oidSz; i++) {
04028             printf("0x%02X,", oid[i]);
04029         }
04030         printf("\n");
04031 
04032         for (i = 0; i < (int)oidSz; i++) {
04033             sum += oid[i];
04034         }
04035         printf("Sum: %d\n", sum);
04036 
04037         /* validate sum */
04038         if (ecc_sets[x].oidSum != sum) {
04039             printf("  Sum %d Not Valid!\n", ecc_sets[x].oidSum);
04040         }
04041     }
04042     mOidDumpDone = 1;
04043 }
04044 #endif /* ECC_DUMP_OID */
04045 
04046 /**
04047  Make a new ECC key
04048  rng          An active RNG state
04049  keysize      The keysize for the new key (in octets from 20 to 65 bytes)
04050  key          [out] Destination of the newly created key
04051  return       MP_OKAY if successful,
04052  upon error all allocated memory will be freed
04053  */
04054 int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
04055 {
04056     return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
04057 }
04058 
04059 /* Setup dynamic pointers if using normal math for proper freeing */
04060 int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
04061 {
04062     int ret = 0;
04063 
04064     if (key == NULL) {
04065         return BAD_FUNC_ARG;
04066     }
04067 
04068 #ifdef ECC_DUMP_OID
04069     wc_ecc_dump_oids();
04070 #endif
04071 
04072     XMEMSET(key, 0, sizeof(ecc_key));
04073     key->state = ECC_STATE_NONE;
04074 
04075 #if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_DEV)
04076     key->devId = devId;
04077 #else
04078     (void)devId;
04079 #endif
04080 
04081 #ifdef WOLFSSL_ATECC508A
04082     key->slot = atmel_ecc_alloc();
04083     if (key->slot == ATECC_INVALID_SLOT) {
04084         return ECC_BAD_ARG_E;
04085     }
04086 #else
04087 #ifdef ALT_ECC_SIZE
04088     key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
04089     key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
04090     key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
04091     alt_fp_init(key->pubkey.x);
04092     alt_fp_init(key->pubkey.y);
04093     alt_fp_init(key->pubkey.z);
04094     ret = mp_init(&key->k);
04095 #else
04096     ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
04097                                                                     NULL, NULL);
04098 #endif /* ALT_ECC_SIZE */
04099     if (ret != MP_OKAY) {
04100         return MEMORY_E;
04101     }
04102 #endif /* WOLFSSL_ATECC508A */
04103 
04104 #ifdef WOLFSSL_HEAP_TEST
04105     key->heap = (void*)WOLFSSL_HEAP_TEST;
04106 #else
04107     key->heap = heap;
04108 #endif
04109 
04110 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
04111     /* handle as async */
04112     ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
04113                                                             key->heap, devId);
04114 #endif
04115 
04116     return ret;
04117 }
04118 
04119 int wc_ecc_init(ecc_key* key)
04120 {
04121     return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
04122 }
04123 
04124 int wc_ecc_set_flags(ecc_key* key, word32 flags)
04125 {
04126     if (key == NULL) {
04127         return BAD_FUNC_ARG;
04128     }
04129     key->flags |= flags;
04130     return 0;
04131 }
04132 
04133 #ifdef HAVE_ECC_SIGN
04134 
04135 #ifndef NO_ASN
04136 
04137 #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC)
04138 static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
04139     mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
04140     ecc_key* key)
04141 {
04142     int err;
04143 
04144 #ifdef PLUTON_CRYPTO_ECC
04145     if (key->devId != INVALID_DEVID) /* use hardware */
04146 #endif
04147     {
04148         word32 keysize = (word32)key->dp->size;
04149 
04150         /* Check args */
04151         if (keysize > ECC_MAX_CRYPTO_HW_SIZE || inlen != keysize ||
04152                                                 *outlen < keysize*2) {
04153             return ECC_BAD_ARG_E;
04154         }
04155 
04156     #if defined(WOLFSSL_ATECC508A)
04157         /* Sign: Result is 32-bytes of R then 32-bytes of S */
04158         err = atcatls_sign(key->slot, in, out);
04159         if (err != ATCA_SUCCESS) {
04160            return BAD_COND_E;
04161         }
04162     #elif defined(PLUTON_CRYPTO_ECC)
04163         {
04164             /* perform ECC sign */
04165             word32 raw_sig_size = *outlen;
04166             err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
04167             if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
04168                return BAD_COND_E;
04169             }
04170         }
04171     #endif
04172 
04173         /* Load R and S */
04174         err = mp_read_unsigned_bin(r, &out[0], keysize);
04175         if (err != MP_OKAY) {
04176             return err;
04177         }
04178         err = mp_read_unsigned_bin(s, &out[keysize], keysize);
04179         if (err != MP_OKAY) {
04180             return err;
04181         }
04182 
04183         /* Check for zeros */
04184         if (mp_iszero(r) || mp_iszero(s)) {
04185             return MP_ZERO_E;
04186         }
04187     }
04188 #ifdef PLUTON_CRYPTO_ECC
04189     else {
04190         err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
04191     }
04192 #endif
04193     (void)rng;
04194 
04195     return err;
04196 }
04197 #endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC */
04198 
04199 /**
04200  Sign a message digest
04201  in        The message digest to sign
04202  inlen     The length of the digest
04203  out       [out] The destination for the signature
04204  outlen    [in/out] The max size and resulting size of the signature
04205  key       A private ECC key
04206  return    MP_OKAY if successful
04207  */
04208 int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
04209                      WC_RNG* rng, ecc_key* key)
04210 {
04211     int err;
04212     mp_int *r = NULL, *s = NULL;
04213 #if !defined(WOLFSSL_ASYNC_CRYPT) && !defined(WOLFSSL_SMALL_STACK)
04214     mp_int r_lcl, s_lcl;
04215 #endif
04216 
04217     if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
04218                                                                 rng == NULL) {
04219         return ECC_BAD_ARG_E;
04220     }
04221 
04222 #ifdef WOLF_CRYPTO_DEV
04223     if (key->devId != INVALID_DEVID) {
04224         err = wc_CryptoDev_EccSign(in, inlen, out, outlen, rng, key);
04225         if (err != NOT_COMPILED_IN)
04226             return err;
04227     }
04228 #endif
04229 
04230 #ifdef WOLFSSL_ASYNC_CRYPT
04231     err = wc_ecc_alloc_async(key);
04232     if (err != 0)
04233         return err;
04234     r = key->r;
04235     s = key->s;
04236 #elif !defined(WOLFSSL_SMALL_STACK)
04237     r = &r_lcl;
04238     s = &s_lcl;
04239 #else
04240     r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
04241     if (r == NULL)
04242         return MEMORY_E;
04243     s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
04244     if (s == NULL) {
04245         XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
04246         return MEMORY_E;
04247     }
04248 #endif
04249 
04250     switch(key->state) {
04251         case ECC_STATE_NONE:
04252         case ECC_STATE_SIGN_DO:
04253             key->state = ECC_STATE_SIGN_DO;
04254 
04255             if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
04256                 break;
04257             }
04258 
04259         /* hardware crypto */
04260         #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC)
04261             err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
04262         #else
04263             err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
04264         #endif
04265             if (err < 0) {
04266                 break;
04267             }
04268 
04269             FALL_THROUGH;
04270 
04271         case ECC_STATE_SIGN_ENCODE:
04272             key->state = ECC_STATE_SIGN_ENCODE;
04273 
04274         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
04275             if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
04276                 #ifdef HAVE_CAVIUM_V
04277                     /* Nitrox requires r and s in sep buffer, so split it */
04278                     NitroxEccRsSplit(key, &r->raw, &s->raw);
04279                 #endif
04280                 #ifndef WOLFSSL_ASYNC_CRYPT_TEST
04281                     /* only do this if not simulator, since it overwrites result */
04282                     wc_bigint_to_mp(&r->raw, r);
04283                     wc_bigint_to_mp(&s->raw, s);
04284                 #endif
04285             }
04286         #endif /* WOLFSSL_ASYNC_CRYPT */
04287 
04288             /* encoded with DSA header */
04289             err = StoreECC_DSA_Sig(out, outlen, r, s);
04290 
04291             /* done with R/S */
04292             mp_clear(r);
04293             mp_clear(s);
04294         #if !defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_SMALL_STACK)
04295             XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
04296             XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
04297         #endif
04298             break;
04299 
04300         default:
04301             err = BAD_STATE_E;
04302             break;
04303     }
04304 
04305     /* if async pending then return and skip done cleanup below */
04306     if (err == WC_PENDING_E) {
04307         key->state++;
04308         return err;
04309     }
04310 
04311     /* cleanup */
04312 #ifdef WOLFSSL_ASYNC_CRYPT
04313     wc_ecc_free_async(key);
04314 #endif
04315     key->state = ECC_STATE_NONE;
04316 
04317     return err;
04318 }
04319 #endif /* !NO_ASN */
04320 
04321 #ifndef WOLFSSL_ATECC508A
04322 /**
04323   Sign a message digest
04324   in        The message digest to sign
04325   inlen     The length of the digest
04326   key       A private ECC key
04327   r         [out] The destination for r component of the signature
04328   s         [out] The destination for s component of the signature
04329   return    MP_OKAY if successful
04330 */
04331 int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
04332                      ecc_key* key, mp_int *r, mp_int *s)
04333 {
04334    int    err;
04335 #ifndef WOLFSSL_SP_MATH
04336    mp_int* e;
04337 #if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \
04338                                                    !defined(WOLFSSL_SMALL_STACK)
04339    mp_int  e_lcl;
04340 #endif
04341    DECLARE_CURVE_SPECS(curve, 1);
04342 #endif /* !WOLFSSL_SP_MATH */
04343 
04344    if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL)
04345        return ECC_BAD_ARG_E;
04346 
04347    /* is this a private key? */
04348    if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
04349       return ECC_BAD_ARG_E;
04350    }
04351 
04352    /* is the IDX valid ?  */
04353    if (wc_ecc_is_valid_idx(key->idx) != 1) {
04354       return ECC_BAD_ARG_E;
04355    }
04356 
04357 #ifdef WOLFSSL_SP_MATH
04358     if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
04359         return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap);
04360     else
04361         return WC_KEY_SIZE_E;
04362 #else
04363 #ifdef WOLFSSL_HAVE_SP_ECC
04364     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
04365            defined(WOLFSSL_ASYNC_CRYPT_TEST)
04366     if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
04367     #endif
04368     {
04369 #ifndef WOLFSSL_SP_NO_256
04370         if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
04371             return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap);
04372 #endif
04373     }
04374 #endif /* WOLFSSL_HAVE_SP_ECC */
04375 
04376 
04377 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
04378        defined(WOLFSSL_ASYNC_CRYPT_TEST)
04379     if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
04380         if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_SIGN)) {
04381             WC_ASYNC_TEST* testDev = &key->asyncDev.test;
04382             testDev->eccSign.in = in;
04383             testDev->eccSign.inSz = inlen;
04384             testDev->eccSign.rng = rng;
04385             testDev->eccSign.key = key;
04386             testDev->eccSign.r = r;
04387             testDev->eccSign.s = s;
04388             return WC_PENDING_E;
04389         }
04390     }
04391 #endif
04392 
04393    ALLOC_CURVE_SPECS(1);
04394 
04395 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
04396    err = wc_ecc_alloc_mpint(key, &key->e);
04397    if (err != 0) {
04398       FREE_CURVE_SPECS();
04399       return err;
04400    }
04401    e = key->e;
04402 #elif !defined(WOLFSSL_SMALL_STACK)
04403    e = &e_lcl;
04404 #else
04405    e = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
04406    if (e == NULL) {
04407       FREE_CURVE_SPECS();
04408       return MEMORY_E;
04409    }
04410 #endif
04411 
04412    /* get the hash and load it as a bignum into 'e' */
04413    /* init the bignums */
04414    if ((err = mp_init(e)) != MP_OKAY) {
04415    #ifdef WOLFSSL_SMALL_STACK
04416       XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
04417    #endif
04418       FREE_CURVE_SPECS();
04419       return err;
04420    }
04421 
04422    /* load curve info */
04423    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
04424 
04425    /* load digest into e */
04426    if (err == MP_OKAY) {
04427        /* we may need to truncate if hash is longer than key size */
04428        word32 orderBits = mp_count_bits(curve->order);
04429 
04430        /* truncate down to byte size, may be all that's needed */
04431        if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
04432            inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
04433        err = mp_read_unsigned_bin(e, (byte*)in, inlen);
04434 
04435        /* may still need bit truncation too */
04436        if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
04437            mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
04438    }
04439 
04440    /* make up a key and export the public copy */
04441    if (err == MP_OKAY) {
04442        int      loop_check = 0;
04443    #ifdef WOLFSSL_SMALL_STACK
04444        ecc_key* pubkey = NULL;
04445    #else
04446        ecc_key  pubkey[1];
04447    #endif
04448 
04449    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
04450         if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
04451         #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
04452         #ifdef HAVE_CAVIUM_V
04453             if (NitroxEccIsCurveSupported(key))
04454         #endif
04455             {
04456                word32 keySz = key->dp->size;
04457                mp_int* k;
04458             #ifdef HAVE_CAVIUM_V
04459                err = wc_ecc_alloc_mpint(key, &key->signK);
04460                if (err != 0)
04461                   return err;
04462                k = key->signK;
04463             #else
04464                mp_int k_lcl;
04465                k = &k_lcl;
04466             #endif
04467 
04468                err = mp_init(k);
04469 
04470                 /* make sure r and s are allocated */
04471            #ifdef HAVE_CAVIUM_V
04472                /* Nitrox V needs single buffer for R and S */
04473                if (err == MP_OKAY)
04474                    err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
04475                /* Nitrox V only needs Prime and Order */
04476                if (err == MP_OKAY)
04477                    err = wc_ecc_curve_load(key->dp, &curve,
04478                         (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
04479            #else
04480                if (err == MP_OKAY)
04481                    err = wc_bigint_alloc(&key->r->raw, key->dp->size);
04482                if (err == MP_OKAY)
04483                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
04484            #endif
04485                if (err == MP_OKAY)
04486                    err = wc_bigint_alloc(&key->s->raw, key->dp->size);
04487 
04488                /* load e and k */
04489                if (err == MP_OKAY)
04490                    err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
04491                if (err == MP_OKAY)
04492                    err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz);
04493                if (err == MP_OKAY)
04494                    err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
04495                if (err == MP_OKAY)
04496                    err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
04497 
04498            #ifdef HAVE_CAVIUM_V
04499                if (err == MP_OKAY)
04500                    err = NitroxEcdsaSign(key, &e->raw, &key->k.raw, &k->raw,
04501                     &r->raw, &s->raw, &curve->prime->raw, &curve->order->raw);
04502            #else
04503                if (err == MP_OKAY)
04504                    err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k.raw,
04505                       &k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw,
04506                       &curve->prime->raw, &curve->order->raw, &curve->Gx->raw,
04507                       &curve->Gy->raw);
04508            #endif
04509 
04510            #ifndef HAVE_CAVIUM_V
04511                mp_clear(e);
04512                mp_clear(k);
04513            #endif
04514                wc_ecc_curve_free(curve);
04515                FREE_CURVE_SPECS();
04516 
04517                return err;
04518            }
04519        #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
04520        }
04521    #endif /* WOLFSSL_ASYNC_CRYPT */
04522 
04523    #ifdef WOLFSSL_SMALL_STACK
04524        pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
04525        if (pubkey == NULL)
04526            err = MEMORY_E;
04527    #endif
04528 
04529        /* don't use async for key, since we don't support async return here */
04530        if (err == MP_OKAY && (err = wc_ecc_init_ex(pubkey, key->heap,
04531                                                    INVALID_DEVID)) == MP_OKAY) {
04532        #ifdef WOLFSSL_SMALL_STACK
04533            mp_int* b = NULL;
04534        #else
04535            mp_int  b[1];
04536        #endif
04537 
04538        #ifdef WOLFSSL_SMALL_STACK
04539            if (err == MP_OKAY) {
04540                b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
04541                                                               DYNAMIC_TYPE_ECC);
04542                if (b == NULL)
04543                    err = MEMORY_E;
04544            }
04545        #endif
04546 
04547            if (err == MP_OKAY) {
04548                err = mp_init(b);
04549            }
04550 
04551        #ifdef WOLFSSL_CUSTOM_CURVES
04552            /* if custom curve, apply params to pubkey */
04553            if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
04554                err = wc_ecc_set_custom_curve(pubkey, key->dp);
04555            }
04556        #endif
04557 
04558            if (err == MP_OKAY) {
04559                /* Generate blinding value - non-zero value. */
04560                do {
04561                    if (++loop_check > 64) {
04562                         err = RNG_FAILURE_E;
04563                         break;
04564                    }
04565 
04566                    err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
04567                }
04568                while (err == MP_ZERO_E);
04569                loop_check = 0;
04570            }
04571 
04572            for (; err == MP_OKAY;) {
04573                if (++loop_check > 64) {
04574                     err = RNG_FAILURE_E;
04575                     break;
04576                }
04577                err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey,
04578                                                                    key->dp->id);
04579                if (err != MP_OKAY) break;
04580 
04581                /* find r = x1 mod n */
04582                err = mp_mod(pubkey->pubkey.x, curve->order, r);
04583                if (err != MP_OKAY) break;
04584 
04585                if (mp_iszero(r) == MP_YES) {
04586                 #ifndef ALT_ECC_SIZE
04587                    mp_clear(pubkey->pubkey.x);
04588                    mp_clear(pubkey->pubkey.y);
04589                    mp_clear(pubkey->pubkey.z);
04590                 #endif
04591                    mp_forcezero(&pubkey->k);
04592                }
04593                else {
04594                    /* find s = (e + xr)/k
04595                              = b.(e/k.b + x.r/k.b) */
04596 
04597                    /* k = k.b */
04598                    err = mp_mulmod(&pubkey->k, b, curve->order, &pubkey->k);
04599                    if (err != MP_OKAY) break;
04600 
04601                    /* k = 1/k.b */
04602                    err = mp_invmod(&pubkey->k, curve->order, &pubkey->k);
04603                    if (err != MP_OKAY) break;
04604 
04605                    /* s = x.r */
04606                    err = mp_mulmod(&key->k, r, curve->order, s);
04607                    if (err != MP_OKAY) break;
04608 
04609                    /* s = x.r/k.b */
04610                    err = mp_mulmod(&pubkey->k, s, curve->order, s);
04611                    if (err != MP_OKAY) break;
04612 
04613                    /* e = e/k.b */
04614                    err = mp_mulmod(&pubkey->k, e, curve->order, e);
04615                    if (err != MP_OKAY) break;
04616 
04617                    /* s = e/k.b + x.r/k.b
04618                         = (e + x.r)/k.b */
04619                    err = mp_add(e, s, s);
04620                    if (err != MP_OKAY) break;
04621 
04622                    /* s = b.(e + x.r)/k.b
04623                         = (e + x.r)/k */
04624                    err = mp_mulmod(s, b, curve->order, s);
04625                    if (err != MP_OKAY) break;
04626 
04627                    /* s = (e + xr)/k */
04628                    err = mp_mod(s, curve->order, s);
04629                    if (err != MP_OKAY) break;
04630 
04631                    if (mp_iszero(s) == MP_NO)
04632                        break;
04633                 }
04634            }
04635            mp_clear(b);
04636            mp_free(b);
04637        #ifdef WOLFSSL_SMALL_STACK
04638            XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
04639        #endif
04640            wc_ecc_free(pubkey);
04641        #ifdef WOLFSSL_SMALL_STACK
04642            XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC);
04643        #endif
04644        }
04645    }
04646 
04647    mp_clear(e);
04648    wc_ecc_curve_free(curve);
04649 #ifdef WOLFSSL_SMALL_STACK
04650    XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
04651 #endif
04652    FREE_CURVE_SPECS();
04653 #endif /* WOLFSSL_SP_MATH */
04654 
04655    return err;
04656 }
04657 #endif /* WOLFSSL_ATECC508A */
04658 #endif /* HAVE_ECC_SIGN */
04659 
04660 #ifdef WOLFSSL_CUSTOM_CURVES
04661 void wc_ecc_free_curve(const ecc_set_type* curve, void* heap)
04662 {
04663     if (curve->prime != NULL)
04664         XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
04665     if (curve->Af != NULL)
04666         XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
04667     if (curve->Bf != NULL)
04668         XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
04669     if (curve->order != NULL)
04670         XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
04671     if (curve->Gx != NULL)
04672         XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
04673     if (curve->Gy != NULL)
04674         XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
04675 
04676     XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
04677 
04678     (void)heap;
04679 }
04680 #endif /* WOLFSSL_CUSTOM_CURVES */
04681 
04682 /**
04683   Free an ECC key from memory
04684   key   The key you wish to free
04685 */
04686 int wc_ecc_free(ecc_key* key)
04687 {
04688     if (key == NULL) {
04689         return 0;
04690     }
04691 
04692 #ifdef WOLFSSL_ASYNC_CRYPT
04693     #ifdef WC_ASYNC_ENABLE_ECC
04694     wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
04695     #endif
04696     wc_ecc_free_async(key);
04697 #endif
04698 
04699 #ifdef WOLFSSL_ATECC508A
04700     atmel_ecc_free(key->slot);
04701     key->slot = -1;
04702 #else
04703 
04704     mp_clear(key->pubkey.x);
04705     mp_clear(key->pubkey.y);
04706     mp_clear(key->pubkey.z);
04707 
04708     mp_forcezero(&key->k);
04709 #endif /* WOLFSSL_ATECC508A */
04710 
04711 #ifdef WOLFSSL_CUSTOM_CURVES
04712     if (key->deallocSet && key->dp != NULL)
04713         wc_ecc_free_curve(key->dp, key->heap);
04714 #endif
04715 
04716     return 0;
04717 }
04718 
04719 #if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A)
04720 #ifdef ECC_SHAMIR
04721 
04722 /** Computes kA*A + kB*B = C using Shamir's Trick
04723   A        First point to multiply
04724   kA       What to multiple A by
04725   B        Second point to multiply
04726   kB       What to multiple B by
04727   C        [out] Destination point (can overlap with A or B)
04728   a        ECC curve parameter a
04729   modulus  Modulus for curve
04730   return MP_OKAY on success
04731 */
04732 #ifdef FP_ECC
04733 static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
04734                              ecc_point* B, mp_int* kB,
04735                              ecc_point* C, mp_int* a, mp_int* modulus,
04736                              void* heap)
04737 #else
04738 int ecc_mul2add(ecc_point* A, mp_int* kA,
04739                     ecc_point* B, mp_int* kB,
04740                     ecc_point* C, mp_int* a, mp_int* modulus,
04741                     void* heap)
04742 #endif
04743 {
04744 #ifdef WOLFSSL_SMALL_STACK
04745   ecc_point**    precomp = NULL;
04746 #ifdef WOLFSSL_SMALL_STACK_CACHE
04747   ecc_key        key;
04748 #endif
04749 #else
04750   ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
04751 #endif
04752   unsigned       bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
04753   unsigned char* tA;
04754   unsigned char* tB;
04755   int            err = MP_OKAY, first, x, y;
04756   mp_digit       mp = 0;
04757 
04758   /* argchks */
04759   if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
04760                                                          modulus == NULL) {
04761      return ECC_BAD_ARG_E;
04762   }
04763 
04764   /* allocate memory */
04765   tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
04766   if (tA == NULL) {
04767      return GEN_MEM_ERR;
04768   }
04769   tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
04770   if (tB == NULL) {
04771      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
04772      return GEN_MEM_ERR;
04773   }
04774 #ifdef WOLFSSL_SMALL_STACK
04775   precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
04776                                                        DYNAMIC_TYPE_ECC_BUFFER);
04777   if (precomp == NULL) {
04778      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
04779      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
04780      return GEN_MEM_ERR;
04781   }
04782 #endif
04783 #ifdef WOLFSSL_SMALL_STACK_CACHE
04784   key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
04785   key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
04786 #ifdef ALT_ECC_SIZE
04787   key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
04788   key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
04789   key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
04790 #endif
04791   if (key.t1 == NULL || key.t2 == NULL
04792 #ifdef ALT_ECC_SIZE
04793      || key.x == NULL || key.y == NULL || key.z == NULL
04794 #endif
04795   ) {
04796 #ifdef ALT_ECC_SIZE
04797       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
04798       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
04799       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
04800 #endif
04801       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
04802       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
04803       XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
04804       XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
04805       XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
04806       return MEMORY_E;
04807   }
04808   C->key = &key;
04809 #endif /* WOLFSSL_SMALL_STACK_CACHE */
04810 
04811   /* init variables */
04812   XMEMSET(tA, 0, ECC_BUFSIZE);
04813   XMEMSET(tB, 0, ECC_BUFSIZE);
04814 #ifndef WOLFSSL_SMALL_STACK
04815   XMEMSET(precomp, 0, sizeof(precomp));
04816 #else
04817   XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
04818 #endif
04819 
04820   /* get sizes */
04821   lenA = mp_unsigned_bin_size(kA);
04822   lenB = mp_unsigned_bin_size(kB);
04823   len  = MAX(lenA, lenB);
04824 
04825   /* sanity check */
04826   if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
04827     err = BAD_FUNC_ARG;
04828   }
04829 
04830   if (err == MP_OKAY) {
04831     /* extract and justify kA */
04832     err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
04833 
04834     /* extract and justify kB */
04835     if (err == MP_OKAY)
04836         err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
04837 
04838     /* allocate the table */
04839     if (err == MP_OKAY) {
04840         for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
04841             precomp[x] = wc_ecc_new_point_h(heap);
04842             if (precomp[x] == NULL) {
04843                 err = GEN_MEM_ERR;
04844                 break;
04845             }
04846         #ifdef WOLFSSL_SMALL_STACK_CACHE
04847             precomp[x]->key = &key;
04848         #endif
04849         }
04850     }
04851   }
04852 
04853   if (err == MP_OKAY)
04854     /* init montgomery reduction */
04855     err = mp_montgomery_setup(modulus, &mp);
04856 
04857   if (err == MP_OKAY) {
04858   #ifdef WOLFSSL_SMALL_STACK
04859     mp_int* mu = NULL;
04860   #else
04861     mp_int  mu[1];
04862   #endif
04863   #ifdef WOLFSSL_SMALL_STACK
04864     mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
04865     if (mu == NULL)
04866         err = MEMORY_E;
04867   #endif
04868     if (err == MP_OKAY) {
04869         err = mp_init(mu);
04870     }
04871     if (err == MP_OKAY) {
04872       err = mp_montgomery_calc_normalization(mu, modulus);
04873 
04874       if (err == MP_OKAY)
04875         /* copy ones ... */
04876         err = mp_mulmod(A->x, mu, modulus, precomp[1]->x);
04877 
04878       if (err == MP_OKAY)
04879         err = mp_mulmod(A->y, mu, modulus, precomp[1]->y);
04880       if (err == MP_OKAY)
04881         err = mp_mulmod(A->z, mu, modulus, precomp[1]->z);
04882 
04883       if (err == MP_OKAY)
04884         err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x);
04885       if (err == MP_OKAY)
04886         err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y);
04887       if (err == MP_OKAY)
04888         err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z);
04889 
04890       /* done with mu */
04891       mp_clear(mu);
04892   #ifdef WOLFSSL_SMALL_STACK
04893       XFREE(mu, heap, DYNAMIC_TYPE_ECC);
04894   #endif
04895     }
04896   }
04897 
04898   if (err == MP_OKAY)
04899     /* precomp [i,0](A + B) table */
04900     err = ecc_projective_dbl_point(precomp[1], precomp[2], a, modulus, mp);
04901 
04902   if (err == MP_OKAY)
04903     err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3],
04904                                    a, modulus, mp);
04905   if (err == MP_OKAY)
04906     /* precomp [0,i](A + B) table */
04907     err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], a, modulus, mp);
04908 
04909   if (err == MP_OKAY)
04910     err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2],
04911                                    a, modulus, mp);
04912 
04913   if (err == MP_OKAY) {
04914     /* precomp [i,j](A + B) table (i != 0, j != 0) */
04915     for (x = 1; x < 4; x++) {
04916       for (y = 1; y < 4; y++) {
04917         if (err == MP_OKAY) {
04918           err = ecc_projective_add_point(precomp[x], precomp[(y<<2)],
04919                                              precomp[x+(y<<2)], a, modulus, mp);
04920         }
04921       }
04922     }
04923   }
04924 
04925   if (err == MP_OKAY) {
04926     nibble  = 3;
04927     first   = 1;
04928     bitbufA = tA[0];
04929     bitbufB = tB[0];
04930 
04931     /* for every byte of the multiplicands */
04932     for (x = 0;; ) {
04933         /* grab a nibble */
04934         if (++nibble == 4) {
04935             if (x == (int)len) break;
04936             bitbufA = tA[x];
04937             bitbufB = tB[x];
04938             nibble  = 0;
04939             x++;
04940         }
04941 
04942         /* extract two bits from both, shift/update */
04943         nA = (bitbufA >> 6) & 0x03;
04944         nB = (bitbufB >> 6) & 0x03;
04945         bitbufA = (bitbufA << 2) & 0xFF;
04946         bitbufB = (bitbufB << 2) & 0xFF;
04947 
04948         /* if both zero, if first, continue */
04949         if ((nA == 0) && (nB == 0) && (first == 1)) {
04950             continue;
04951         }
04952 
04953         /* double twice, only if this isn't the first */
04954         if (first == 0) {
04955             /* double twice */
04956             if (err == MP_OKAY)
04957                 err = ecc_projective_dbl_point(C, C, a, modulus, mp);
04958             if (err == MP_OKAY)
04959                 err = ecc_projective_dbl_point(C, C, a, modulus, mp);
04960             else
04961                 break;
04962         }
04963 
04964         /* if not both zero */
04965         if ((nA != 0) || (nB != 0)) {
04966             if (first == 1) {
04967                 /* if first, copy from table */
04968                 first = 0;
04969                 if (err == MP_OKAY)
04970                     err = mp_copy(precomp[nA + (nB<<2)]->x, C->x);
04971 
04972                 if (err == MP_OKAY)
04973                     err = mp_copy(precomp[nA + (nB<<2)]->y, C->y);
04974 
04975                 if (err == MP_OKAY)
04976                     err = mp_copy(precomp[nA + (nB<<2)]->z, C->z);
04977                 else
04978                     break;
04979             } else {
04980                 /* if not first, add from table */
04981                 if (err == MP_OKAY)
04982                     err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,
04983                                                    a, modulus, mp);
04984                 else
04985                     break;
04986             }
04987         }
04988     }
04989   }
04990 
04991   /* reduce to affine */
04992   if (err == MP_OKAY)
04993     err = ecc_map(C, modulus, mp);
04994 
04995   /* clean up */
04996   for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
04997      wc_ecc_del_point_h(precomp[x], heap);
04998   }
04999 
05000   ForceZero(tA, ECC_BUFSIZE);
05001   ForceZero(tB, ECC_BUFSIZE);
05002 #ifdef WOLFSSL_SMALL_STACK_CACHE
05003 #ifdef ALT_ECC_SIZE
05004   XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
05005   XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
05006   XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
05007 #endif
05008   XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
05009   XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
05010   C->key = NULL;
05011 #endif
05012 #ifdef WOLFSSL_SMALL_STACK
05013   XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
05014 #endif
05015   XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
05016   XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
05017 
05018   return err;
05019 }
05020 
05021 #endif /* ECC_SHAMIR */
05022 #endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A */
05023 
05024 
05025 #ifdef HAVE_ECC_VERIFY
05026 #ifndef NO_ASN
05027 /* verify
05028  *
05029  * w  = s^-1 mod n
05030  * u1 = xw
05031  * u2 = rw
05032  * X = u1*G + u2*Q
05033  * v = X_x1 mod n
05034  * accept if v == r
05035  */
05036 
05037 /**
05038  Verify an ECC signature
05039  sig         The signature to verify
05040  siglen      The length of the signature (octets)
05041  hash        The hash (message digest) that was signed
05042  hashlen     The length of the hash (octets)
05043  res         Result of signature, 1==valid, 0==invalid
05044  key         The corresponding public ECC key
05045  return      MP_OKAY if successful (even if the signature is not valid)
05046  */
05047 int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
05048                        word32 hashlen, int* res, ecc_key* key)
05049 {
05050     int err;
05051     mp_int *r = NULL, *s = NULL;
05052 #ifndef WOLFSSL_ASYNC_CRYPT
05053 #ifndef WOLFSSL_SMALL_STACK
05054     mp_int r_lcl[1], s_lcl[1];
05055 #endif
05056 #endif
05057 
05058     if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
05059         return ECC_BAD_ARG_E;
05060     }
05061 
05062 #ifdef WOLF_CRYPTO_DEV
05063     if (key->devId != INVALID_DEVID) {
05064         err = wc_CryptoDev_EccVerify(sig, siglen, hash, hashlen, res, key);
05065         if (err != NOT_COMPILED_IN)
05066             return err;
05067     }
05068 #endif
05069 
05070 #ifdef WOLFSSL_ASYNC_CRYPT
05071     err = wc_ecc_alloc_async(key);
05072     if (err != 0)
05073         return err;
05074     r = key->r;
05075     s = key->s;
05076 #else
05077 #ifndef WOLFSSL_SMALL_STACK
05078     r = r_lcl;
05079     s = s_lcl;
05080 #else
05081     r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
05082     if (r == NULL)
05083         return MEMORY_E;
05084     s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
05085     if (s == NULL) {
05086         XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
05087         return MEMORY_E;
05088     }
05089 #endif
05090 #endif
05091 
05092     switch(key->state) {
05093         case ECC_STATE_NONE:
05094         case ECC_STATE_VERIFY_DECODE:
05095             key->state = ECC_STATE_VERIFY_DECODE;
05096 
05097             /* default to invalid signature */
05098             *res = 0;
05099 
05100             /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
05101              * If either of those don't allocate correctly, none of
05102              * the rest of this function will execute, and everything
05103              * gets cleaned up at the end. */
05104             /* decode DSA header */
05105             err = DecodeECC_DSA_Sig(sig, siglen, r, s);
05106             if (err < 0) {
05107                 break;
05108             }
05109             FALL_THROUGH;
05110 
05111         case ECC_STATE_VERIFY_DO:
05112             key->state = ECC_STATE_VERIFY_DO;
05113 
05114             err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
05115 
05116         #ifndef WOLFSSL_ASYNC_CRYPT
05117             /* done with R/S */
05118             mp_clear(r);
05119             mp_clear(s);
05120         #ifdef WOLFSSL_SMALL_STACK
05121             XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
05122             XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
05123         #endif
05124         #endif
05125 
05126             if (err < 0) {
05127                 break;
05128             }
05129             FALL_THROUGH;
05130 
05131         case ECC_STATE_VERIFY_RES:
05132             key->state = ECC_STATE_VERIFY_RES;
05133             err = 0;
05134             break;
05135 
05136         default:
05137             err = BAD_STATE_E;
05138     }
05139 
05140     /* if async pending then return and skip done cleanup below */
05141     if (err == WC_PENDING_E) {
05142         key->state++;
05143         return err;
05144     }
05145 
05146     /* cleanup */
05147 #ifdef WOLFSSL_ASYNC_CRYPT
05148     wc_ecc_free_async(key);
05149 #endif
05150     key->state = ECC_STATE_NONE;
05151 
05152     return err;
05153 }
05154 #endif /* !NO_ASN */
05155 
05156 
05157 /**
05158    Verify an ECC signature
05159    r           The signature R component to verify
05160    s           The signature S component to verify
05161    hash        The hash (message digest) that was signed
05162    hashlen     The length of the hash (octets)
05163    res         Result of signature, 1==valid, 0==invalid
05164    key         The corresponding public ECC key
05165    return      MP_OKAY if successful (even if the signature is not valid)
05166 */
05167 int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
05168                     word32 hashlen, int* res, ecc_key* key)
05169 {
05170    int           err;
05171 #ifdef WOLFSSL_ATECC508A
05172    byte sigRS[ATECC_KEY_SIZE*2];
05173 #elif !defined(WOLFSSL_SP_MATH)
05174    int          did_init = 0;
05175    ecc_point    *mG = NULL, *mQ = NULL;
05176 #ifdef WOLFSSL_SMALL_STACK
05177    mp_int*       v = NULL;
05178    mp_int*       w = NULL;
05179    mp_int*       u1 = NULL;
05180    mp_int*       u2 = NULL;
05181 #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
05182    mp_int*       e_lcl = NULL;
05183 #endif
05184 #else /* WOLFSSL_SMALL_STACK */
05185    mp_int        v[1];
05186    mp_int        w[1];
05187    mp_int        u1[1];
05188    mp_int        u2[1];
05189 #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
05190    mp_int        e_lcl[1];
05191 #endif
05192 #endif /* WOLFSSL_SMALL_STACK */
05193    mp_int*       e;
05194    DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
05195 #endif
05196 
05197    if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
05198        return ECC_BAD_ARG_E;
05199 
05200    /* default to invalid signature */
05201    *res = 0;
05202 
05203    /* is the IDX valid ?  */
05204    if (wc_ecc_is_valid_idx(key->idx) != 1) {
05205       return ECC_BAD_ARG_E;
05206    }
05207 
05208 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
05209        defined(WOLFSSL_ASYNC_CRYPT_TEST)
05210     if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
05211         if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_VERIFY)) {
05212             WC_ASYNC_TEST* testDev = &key->asyncDev.test;
05213             testDev->eccVerify.r = r;
05214             testDev->eccVerify.s = s;
05215             testDev->eccVerify.hash = hash;
05216             testDev->eccVerify.hashlen = hashlen;
05217             testDev->eccVerify.stat = res;
05218             testDev->eccVerify.key = key;
05219             return WC_PENDING_E;
05220         }
05221     }
05222 #endif
05223 
05224 #ifdef WOLFSSL_ATECC508A
05225     /* Extract R and S */
05226     err = mp_to_unsigned_bin(r, &sigRS[0]);
05227     if (err != MP_OKAY) {
05228         return err;
05229     }
05230     err = mp_to_unsigned_bin(s, &sigRS[ATECC_KEY_SIZE]);
05231     if (err != MP_OKAY) {
05232         return err;
05233     }
05234 
05235     err = atcatls_verify(hash, sigRS, key->pubkey_raw, (bool*)res);
05236     if (err != ATCA_SUCCESS) {
05237        return BAD_COND_E;
05238     }
05239     (void)hashlen;
05240 
05241 #else
05242   /* checking if private key with no public part */
05243   if (key->type == ECC_PRIVATEKEY_ONLY) {
05244       WOLFSSL_MSG("Verify called with private key, generating public part");
05245       err = wc_ecc_make_pub_ex(key, NULL, NULL);
05246       if (err != MP_OKAY) {
05247            WOLFSSL_MSG("Unable to extract public key");
05248            return err;
05249       }
05250   }
05251 
05252 #ifdef WOLFSSL_SP_MATH
05253   if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
05254       return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,
05255                                            key->pubkey.z, r, s, res, key->heap);
05256   }
05257   else
05258       return WC_KEY_SIZE_E;
05259 #else
05260 #ifdef WOLFSSL_HAVE_SP_ECC
05261 #ifndef WOLFSSL_SP_NO_256
05262     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
05263            defined(WOLFSSL_ASYNC_CRYPT_TEST)
05264     if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
05265     #endif
05266     {
05267         if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
05268             return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,
05269                                      key->pubkey.z,r, s, res, key->heap);
05270     }
05271 #endif /* WOLFSSL_SP_NO_256 */
05272 #endif /* WOLFSSL_HAVE_SP_ECC */
05273 
05274    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
05275 
05276 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
05277    err = wc_ecc_alloc_mpint(key, &key->e);
05278    if (err != 0) {
05279       FREE_CURVE_SPECS();
05280       return err;
05281    }
05282    e = key->e;
05283 #else
05284 #ifdef WOLFSSL_SMALL_STACK
05285    e_lcl = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
05286    if (e_lcl == NULL) {
05287        FREE_CURVE_SPECS();
05288        return MEMORY_E;
05289    }
05290 #endif
05291    e = e_lcl;
05292 #endif
05293 
05294    err = mp_init(e);
05295    if (err != MP_OKAY)
05296       return MEMORY_E;
05297 
05298    /* read in the specs for this curve */
05299    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
05300 
05301    /* check for zero */
05302    if (err == MP_OKAY) {
05303        if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES ||
05304            mp_cmp(r, curve->order) != MP_LT ||
05305            mp_cmp(s, curve->order) != MP_LT) {
05306            err = MP_ZERO_E;
05307        }
05308    }
05309 
05310    /* read hash */
05311    if (err == MP_OKAY) {
05312        /* we may need to truncate if hash is longer than key size */
05313        unsigned int orderBits = mp_count_bits(curve->order);
05314 
05315        /* truncate down to byte size, may be all that's needed */
05316        if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
05317            hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
05318        err = mp_read_unsigned_bin(e, hash, hashlen);
05319 
05320        /* may still need bit truncation too */
05321        if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
05322            mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
05323    }
05324 
05325    /* check for async hardware acceleration */
05326 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
05327    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
05328    #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
05329    #ifdef HAVE_CAVIUM_V
05330       if (NitroxEccIsCurveSupported(key))
05331    #endif
05332       {
05333           word32 keySz = key->dp->size;
05334 
05335           err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
05336           if (err == MP_OKAY)
05337               err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
05338           if (err == MP_OKAY)
05339               err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
05340           if (err == MP_OKAY)
05341           #ifdef HAVE_CAVIUM_V
05342               err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
05343                     &key->pubkey.y->raw, &r->raw, &s->raw,
05344                     &curve->prime->raw, &curve->order->raw, res);
05345           #else
05346               err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
05347                     &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
05348                     &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
05349                     &curve->Gx->raw, &curve->Gy->raw, res);
05350           #endif
05351 
05352       #ifndef HAVE_CAVIUM_V
05353           mp_clear(e);
05354       #endif
05355           wc_ecc_curve_free(curve);
05356           FREE_CURVE_SPECS();
05357 
05358           return err;
05359       }
05360    #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
05361    }
05362 #endif /* WOLFSSL_ASYNC_CRYPT */
05363 
05364 #ifdef WOLFSSL_SMALL_STACK
05365    if (err == MP_OKAY) {
05366        v = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
05367        if (v == NULL)
05368            err = MEMORY_E;
05369    }
05370    if (err == MP_OKAY) {
05371        w = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
05372        if (w == NULL)
05373            err = MEMORY_E;
05374    }
05375    if (err == MP_OKAY) {
05376        u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
05377        if (u1 == NULL)
05378            err = MEMORY_E;
05379    }
05380    if (err == MP_OKAY) {
05381        u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
05382        if (u2 == NULL)
05383            err = MEMORY_E;
05384    }
05385 #endif
05386 
05387    /* allocate ints */
05388    if (err == MP_OKAY) {
05389        if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) {
05390           err = MEMORY_E;
05391        }
05392        did_init = 1;
05393    }
05394 
05395    /* allocate points */
05396    if (err == MP_OKAY) {
05397        mG = wc_ecc_new_point_h(key->heap);
05398        mQ = wc_ecc_new_point_h(key->heap);
05399        if (mQ  == NULL || mG == NULL)
05400           err = MEMORY_E;
05401    }
05402 
05403    /*  w  = s^-1 mod n */
05404    if (err == MP_OKAY)
05405        err = mp_invmod(s, curve->order, w);
05406 
05407    /* u1 = ew */
05408    if (err == MP_OKAY)
05409        err = mp_mulmod(e, w, curve->order, u1);
05410 
05411    /* u2 = rw */
05412    if (err == MP_OKAY)
05413        err = mp_mulmod(r, w, curve->order, u2);
05414 
05415    /* find mG and mQ */
05416    if (err == MP_OKAY)
05417        err = mp_copy(curve->Gx, mG->x);
05418    if (err == MP_OKAY)
05419        err = mp_copy(curve->Gy, mG->y);
05420    if (err == MP_OKAY)
05421        err = mp_set(mG->z, 1);
05422 
05423    if (err == MP_OKAY)
05424        err = mp_copy(key->pubkey.x, mQ->x);
05425    if (err == MP_OKAY)
05426        err = mp_copy(key->pubkey.y, mQ->y);
05427    if (err == MP_OKAY)
05428        err = mp_copy(key->pubkey.z, mQ->z);
05429 
05430 #ifdef FREESCALE_LTC_ECC
05431    /* use PKHA to compute u1*mG + u2*mQ */
05432    if (err == MP_OKAY)
05433        err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
05434    if (err == MP_OKAY)
05435        err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
05436    if (err == MP_OKAY)
05437        err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
05438 #else
05439 #ifndef ECC_SHAMIR
05440     {
05441         mp_digit      mp = 0;
05442 
05443         /* compute u1*mG + u2*mQ = mG */
05444         if (err == MP_OKAY) {
05445             err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
05446                                                                      key->heap);
05447         }
05448         if (err == MP_OKAY) {
05449             err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
05450                                                                      key->heap);
05451         }
05452 
05453         /* find the montgomery mp */
05454         if (err == MP_OKAY)
05455             err = mp_montgomery_setup(curve->prime, &mp);
05456 
05457         /* add them */
05458         if (err == MP_OKAY)
05459             err = ecc_projective_add_point(mQ, mG, mG, curve->Af,
05460                                                              curve->prime, mp);
05461 
05462         /* reduce */
05463         if (err == MP_OKAY)
05464             err = ecc_map(mG, curve->prime, mp);
05465     }
05466 #else
05467        /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
05468         if (err == MP_OKAY) {
05469             err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
05470                                                                     key->heap);
05471         }
05472 #endif /* ECC_SHAMIR */
05473 #endif /* FREESCALE_LTC_ECC */
05474    /* v = X_x1 mod n */
05475    if (err == MP_OKAY)
05476        err = mp_mod(mG->x, curve->order, v);
05477 
05478    /* does v == r */
05479    if (err == MP_OKAY) {
05480        if (mp_cmp(v, r) == MP_EQ)
05481            *res = 1;
05482    }
05483 
05484    /* cleanup */
05485    wc_ecc_del_point_h(mG, key->heap);
05486    wc_ecc_del_point_h(mQ, key->heap);
05487 
05488    mp_clear(e);
05489    if (did_init) {
05490        mp_clear(v);
05491        mp_clear(w);
05492        mp_clear(u1);
05493        mp_clear(u2);
05494    }
05495 #ifdef WOLFSSL_SMALL_STACK
05496    XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
05497    XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
05498    XFREE(w, key->heap, DYNAMIC_TYPE_ECC);
05499    XFREE(v, key->heap, DYNAMIC_TYPE_ECC);
05500 #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
05501    XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
05502 #endif
05503 #endif
05504 
05505    wc_ecc_curve_free(curve);
05506    FREE_CURVE_SPECS();
05507 
05508 #endif /* WOLFSSL_SP_MATH */
05509 #endif /* WOLFSSL_ATECC508A */
05510 
05511    return err;
05512 }
05513 #endif /* HAVE_ECC_VERIFY */
05514 
05515 #ifdef HAVE_ECC_KEY_IMPORT
05516 /* import point from der */
05517 int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
05518                             ecc_point* point)
05519 {
05520     int err = 0;
05521 #ifndef WOLFSSL_ATECC508A
05522     int compressed = 0;
05523     int keysize;
05524     byte pointType;
05525 
05526     if (in == NULL || point == NULL || (curve_idx < 0) ||
05527         (wc_ecc_is_valid_idx(curve_idx) == 0))
05528         return ECC_BAD_ARG_E;
05529 
05530     /* must be odd */
05531     if ((inLen & 1) == 0) {
05532         return ECC_BAD_ARG_E;
05533     }
05534 
05535     /* init point */
05536 #ifdef ALT_ECC_SIZE
05537     point->x = (mp_int*)&point->xyz[0];
05538     point->y = (mp_int*)&point->xyz[1];
05539     point->z = (mp_int*)&point->xyz[2];
05540     alt_fp_init(point->x);
05541     alt_fp_init(point->y);
05542     alt_fp_init(point->z);
05543 #else
05544     err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
05545 #endif
05546     if (err != MP_OKAY)
05547         return MEMORY_E;
05548 
05549     /* check for point type (4, 2, or 3) */
05550     pointType = in[0];
05551     if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
05552                                          pointType != ECC_POINT_COMP_ODD) {
05553         err = ASN_PARSE_E;
05554     }
05555 
05556     if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
05557 #ifdef HAVE_COMP_KEY
05558         compressed = 1;
05559 #else
05560         err = NOT_COMPILED_IN;
05561 #endif
05562     }
05563 
05564     /* adjust to skip first byte */
05565     inLen -= 1;
05566     in += 1;
05567 
05568     /* calculate key size based on inLen / 2 */
05569     keysize = inLen>>1;
05570 
05571 #ifdef WOLFSSL_ATECC508A
05572     /* populate key->pubkey_raw */
05573     XMEMCPY(key->pubkey_raw, (byte*)in, sizeof(key->pubkey_raw));
05574 #endif
05575 
05576     /* read data */
05577     if (err == MP_OKAY)
05578         err = mp_read_unsigned_bin(point->x, (byte*)in, keysize);
05579 
05580 #ifdef HAVE_COMP_KEY
05581     if (err == MP_OKAY && compressed == 1) {   /* build y */
05582 #ifndef WOLFSSL_SP_MATH
05583         int did_init = 0;
05584         mp_int t1, t2;
05585         DECLARE_CURVE_SPECS(curve, 3);
05586 
05587         ALLOC_CURVE_SPECS(3);
05588 
05589         if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
05590             err = MEMORY_E;
05591         else
05592             did_init = 1;
05593 
05594         /* load curve info */
05595         if (err == MP_OKAY)
05596             err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
05597                 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
05598                     ECC_CURVE_FIELD_BF));
05599 
05600         /* compute x^3 */
05601         if (err == MP_OKAY)
05602             err = mp_sqr(point->x, &t1);
05603         if (err == MP_OKAY)
05604             err = mp_mulmod(&t1, point->x, curve->prime, &t1);
05605 
05606         /* compute x^3 + a*x */
05607         if (err == MP_OKAY)
05608             err = mp_mulmod(curve->Af, point->x, curve->prime, &t2);
05609         if (err == MP_OKAY)
05610             err = mp_add(&t1, &t2, &t1);
05611 
05612         /* compute x^3 + a*x + b */
05613         if (err == MP_OKAY)
05614             err = mp_add(&t1, curve->Bf, &t1);
05615 
05616         /* compute sqrt(x^3 + a*x + b) */
05617         if (err == MP_OKAY)
05618             err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
05619 
05620         /* adjust y */
05621         if (err == MP_OKAY) {
05622             if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
05623                 (mp_isodd(&t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
05624                 err = mp_mod(&t2, curve->prime, point->y);
05625             }
05626             else {
05627                 err = mp_submod(curve->prime, &t2, curve->prime, point->y);
05628             }
05629         }
05630 
05631         if (did_init) {
05632             mp_clear(&t2);
05633             mp_clear(&t1);
05634         }
05635 
05636         wc_ecc_curve_free(curve);
05637         FREE_CURVE_SPECS();
05638 #else
05639         sp_ecc_uncompress_256(point->x, pointType, point->y);
05640 #endif
05641     }
05642 #endif
05643 
05644     if (err == MP_OKAY && compressed == 0)
05645         err = mp_read_unsigned_bin(point->y, (byte*)in + keysize, keysize);
05646     if (err == MP_OKAY)
05647         err = mp_set(point->z, 1);
05648 
05649     if (err != MP_OKAY) {
05650         mp_clear(point->x);
05651         mp_clear(point->y);
05652         mp_clear(point->z);
05653     }
05654 
05655 #else
05656     err = NOT_COMPILED_IN;
05657     (void)in;
05658     (void)inLen;
05659     (void)curve_idx;
05660     (void)point;
05661 #endif /* !WOLFSSL_ATECC508A */
05662 
05663     return err;
05664 }
05665 #endif /* HAVE_ECC_KEY_IMPORT */
05666 
05667 #ifdef HAVE_ECC_KEY_EXPORT
05668 /* export point to der */
05669 int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
05670                             word32* outLen)
05671 {
05672     int    ret = MP_OKAY;
05673     word32 numlen;
05674 #ifndef WOLFSSL_ATECC508A
05675 #ifdef WOLFSSL_SMALL_STACK
05676     byte*  buf;
05677 #else
05678     byte   buf[ECC_BUFSIZE];
05679 #endif
05680 #endif /* !WOLFSSL_ATECC508A */
05681 
05682     if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
05683         return ECC_BAD_ARG_E;
05684 
05685     /* return length needed only */
05686     if (point != NULL && out == NULL && outLen != NULL) {
05687         numlen = ecc_sets[curve_idx].size;
05688         *outLen = 1 + 2*numlen;
05689         return LENGTH_ONLY_E;
05690     }
05691 
05692     if (point == NULL || out == NULL || outLen == NULL)
05693         return ECC_BAD_ARG_E;
05694 
05695     numlen = ecc_sets[curve_idx].size;
05696 
05697     if (*outLen < (1 + 2*numlen)) {
05698         *outLen = 1 + 2*numlen;
05699         return BUFFER_E;
05700     }
05701 
05702 #ifdef WOLFSSL_ATECC508A
05703    /* TODO: Implement equiv call to ATECC508A */
05704    ret = BAD_COND_E;
05705 
05706 #else
05707 
05708     /* store byte point type */
05709     out[0] = ECC_POINT_UNCOMP;
05710 
05711 #ifdef WOLFSSL_SMALL_STACK
05712     buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
05713     if (buf == NULL)
05714         return MEMORY_E;
05715 #endif
05716 
05717     /* pad and store x */
05718     XMEMSET(buf, 0, ECC_BUFSIZE);
05719     ret = mp_to_unsigned_bin(point->x, buf +
05720                                  (numlen - mp_unsigned_bin_size(point->x)));
05721     if (ret != MP_OKAY)
05722         goto done;
05723     XMEMCPY(out+1, buf, numlen);
05724 
05725     /* pad and store y */
05726     XMEMSET(buf, 0, ECC_BUFSIZE);
05727     ret = mp_to_unsigned_bin(point->y, buf +
05728                                  (numlen - mp_unsigned_bin_size(point->y)));
05729     if (ret != MP_OKAY)
05730         goto done;
05731     XMEMCPY(out+1+numlen, buf, numlen);
05732 
05733     *outLen = 1 + 2*numlen;
05734 
05735 done:
05736 #ifdef WOLFSSL_SMALL_STACK
05737     XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
05738 #endif
05739 #endif /* WOLFSSL_ATECC508A */
05740 
05741     return ret;
05742 }
05743 
05744 
05745 /* export public ECC key in ANSI X9.63 format */
05746 int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
05747 {
05748    int    ret = MP_OKAY;
05749    word32 numlen;
05750 #ifdef WOLFSSL_SMALL_STACK
05751    byte*  buf;
05752 #else
05753    byte   buf[ECC_BUFSIZE];
05754 #endif
05755    word32 pubxlen, pubylen;
05756 
05757    /* return length needed only */
05758    if (key != NULL && out == NULL && outLen != NULL) {
05759       numlen = key->dp->size;
05760       *outLen = 1 + 2*numlen;
05761       return LENGTH_ONLY_E;
05762    }
05763 
05764    if (key == NULL || out == NULL || outLen == NULL)
05765       return ECC_BAD_ARG_E;
05766 
05767    if (key->type == ECC_PRIVATEKEY_ONLY)
05768        return ECC_PRIVATEONLY_E;
05769 
05770    if (wc_ecc_is_valid_idx(key->idx) == 0) {
05771       return ECC_BAD_ARG_E;
05772    }
05773    numlen = key->dp->size;
05774 
05775     /* verify room in out buffer */
05776    if (*outLen < (1 + 2*numlen)) {
05777       *outLen = 1 + 2*numlen;
05778       return BUFFER_E;
05779    }
05780 
05781    /* verify public key length is less than key size */
05782    pubxlen = mp_unsigned_bin_size(key->pubkey.x);
05783    pubylen = mp_unsigned_bin_size(key->pubkey.y);
05784    if ((pubxlen > numlen) || (pubylen > numlen)) {
05785       WOLFSSL_MSG("Public key x/y invalid!");
05786       return BUFFER_E;
05787    }
05788 
05789    /* store byte point type */
05790    out[0] = ECC_POINT_UNCOMP;
05791 
05792 #ifdef WOLFSSL_SMALL_STACK
05793    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
05794    if (buf == NULL)
05795       return MEMORY_E;
05796 #endif
05797 
05798    /* pad and store x */
05799    XMEMSET(buf, 0, ECC_BUFSIZE);
05800    ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
05801    if (ret != MP_OKAY)
05802       goto done;
05803    XMEMCPY(out+1, buf, numlen);
05804 
05805    /* pad and store y */
05806    XMEMSET(buf, 0, ECC_BUFSIZE);
05807    ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
05808    if (ret != MP_OKAY)
05809       goto done;
05810    XMEMCPY(out+1+numlen, buf, numlen);
05811 
05812    *outLen = 1 + 2*numlen;
05813 
05814 done:
05815 #ifdef WOLFSSL_SMALL_STACK
05816    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
05817 #endif
05818 
05819    return ret;
05820 }
05821 
05822 
05823 /* export public ECC key in ANSI X9.63 format, extended with
05824  * compression option */
05825 int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
05826                           int compressed)
05827 {
05828     if (compressed == 0)
05829         return wc_ecc_export_x963(key, out, outLen);
05830 #ifdef HAVE_COMP_KEY
05831     else
05832         return wc_ecc_export_x963_compressed(key, out, outLen);
05833 #else
05834     return NOT_COMPILED_IN;
05835 #endif
05836 }
05837 #endif /* HAVE_ECC_KEY_EXPORT */
05838 
05839 
05840 #ifndef WOLFSSL_ATECC508A
05841 
05842 /* is ecc point on curve described by dp ? */
05843 int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
05844 {
05845 #ifndef WOLFSSL_SP_MATH
05846    int err;
05847 #ifdef WOLFSSL_SMALL_STACK
05848    mp_int* t1 = NULL;
05849    mp_int* t2 = NULL;
05850 #else
05851    mp_int  t1[1], t2[1];
05852 #endif
05853 
05854 #ifdef WOLFSSL_SMALL_STACK
05855    t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
05856    if (t1 == NULL)
05857        return MEMORY_E;
05858    t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
05859    if (t2 == NULL) {
05860        XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
05861        return MEMORY_E;
05862    }
05863 #endif
05864 
05865    if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
05866    #ifdef WOLFSSL_SMALL_STACK
05867       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
05868       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
05869    #endif
05870       return err;
05871    }
05872 
05873    /* compute y^2 */
05874    if (err == MP_OKAY)
05875        err = mp_sqr(ecp->y, t1);
05876 
05877    /* compute x^3 */
05878    if (err == MP_OKAY)
05879        err = mp_sqr(ecp->x, t2);
05880    if (err == MP_OKAY)
05881        err = mp_mod(t2, prime, t2);
05882    if (err == MP_OKAY)
05883        err = mp_mul(ecp->x, t2, t2);
05884 
05885    /* compute y^2 - x^3 */
05886    if (err == MP_OKAY)
05887        err = mp_sub(t1, t2, t1);
05888 
05889    /* Determine if curve "a" should be used in calc */
05890 #ifdef WOLFSSL_CUSTOM_CURVES
05891    if (err == MP_OKAY) {
05892       /* Use a and prime to determine if a == 3 */
05893       err = mp_set(t2, 0);
05894       if (err == MP_OKAY)
05895           err = mp_submod(prime, a, prime, t2);
05896    }
05897    if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
05898       /* compute y^2 - x^3 + a*x */
05899       if (err == MP_OKAY)
05900           err = mp_mulmod(t2, ecp->x, prime, t2);
05901       if (err == MP_OKAY)
05902           err = mp_addmod(t1, t2, prime, t1);
05903    }
05904    else
05905 #endif /* WOLFSSL_CUSTOM_CURVES */
05906    {
05907       /* assumes "a" == 3 */
05908       (void)a;
05909 
05910       /* compute y^2 - x^3 + 3x */
05911       if (err == MP_OKAY)
05912           err = mp_add(t1, ecp->x, t1);
05913       if (err == MP_OKAY)
05914           err = mp_add(t1, ecp->x, t1);
05915       if (err == MP_OKAY)
05916           err = mp_add(t1, ecp->x, t1);
05917       if (err == MP_OKAY)
05918           err = mp_mod(t1, prime, t1);
05919   }
05920 
05921    /* adjust range (0, prime) */
05922    while (err == MP_OKAY && mp_isneg(t1)) {
05923       err = mp_add(t1, prime, t1);
05924    }
05925    while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
05926       err = mp_sub(t1, prime, t1);
05927    }
05928 
05929    /* compare to b */
05930    if (err == MP_OKAY) {
05931        if (mp_cmp(t1, b) != MP_EQ) {
05932           err = MP_VAL;
05933        } else {
05934           err = MP_OKAY;
05935        }
05936    }
05937 
05938    mp_clear(t1);
05939    mp_clear(t2);
05940 #ifdef WOLFSSL_SMALL_STACK
05941    XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
05942    XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
05943 #endif
05944 
05945    return err;
05946 #else
05947    (void)a;
05948    (void)b;
05949    (void)prime;
05950 
05951    return sp_ecc_is_point_256(ecp->x, ecp->y);
05952 #endif
05953 }
05954 
05955 #ifndef WOLFSSL_SP_MATH
05956 /* validate privkey * generator == pubkey, 0 on success */
05957 static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
05958 {
05959     int        err = MP_OKAY;
05960     ecc_point* base = NULL;
05961     ecc_point* res  = NULL;
05962     DECLARE_CURVE_SPECS(curve, 2);
05963 
05964     if (key == NULL)
05965         return BAD_FUNC_ARG;
05966 
05967     ALLOC_CURVE_SPECS(2);
05968 
05969     res = wc_ecc_new_point_h(key->heap);
05970     if (res == NULL)
05971         err = MEMORY_E;
05972 
05973 #ifdef WOLFSSL_HAVE_SP_ECC
05974 #ifndef WOLFSSL_SP_NO_256
05975     if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
05976         if (err == MP_OKAY)
05977             err = sp_ecc_mulmod_base_256(&key->k, res, 1, key->heap);
05978     }
05979     else
05980 #endif
05981 #endif
05982     {
05983         base = wc_ecc_new_point_h(key->heap);
05984         if (base == NULL)
05985             err = MEMORY_E;
05986 
05987         if (err == MP_OKAY) {
05988             /* load curve info */
05989             err = wc_ecc_curve_load(key->dp, &curve,
05990                                       (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
05991         }
05992 
05993         /* set up base generator */
05994         if (err == MP_OKAY)
05995             err = mp_copy(curve->Gx, base->x);
05996         if (err == MP_OKAY)
05997             err = mp_copy(curve->Gy, base->y);
05998         if (err == MP_OKAY)
05999             err = mp_set(base->z, 1);
06000 
06001         if (err == MP_OKAY)
06002             err = wc_ecc_mulmod_ex(&key->k, base, res, a, prime, 1, key->heap);
06003     }
06004 
06005     if (err == MP_OKAY) {
06006         /* compare result to public key */
06007         if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
06008             mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
06009             mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
06010             /* didn't match */
06011             err = ECC_PRIV_KEY_E;
06012         }
06013     }
06014 
06015     wc_ecc_curve_free(curve);
06016     wc_ecc_del_point_h(res, key->heap);
06017     wc_ecc_del_point_h(base, key->heap);
06018     FREE_CURVE_SPECS();
06019 
06020     return err;
06021 }
06022 #endif
06023 
06024 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
06025 
06026 /* check privkey generator helper, creates prime needed */
06027 static int ecc_check_privkey_gen_helper(ecc_key* key)
06028 {
06029     int    err;
06030 #ifndef WOLFSSL_ATECC508A
06031     DECLARE_CURVE_SPECS(curve, 2);
06032 #endif
06033 
06034     if (key == NULL)
06035         return BAD_FUNC_ARG;
06036 
06037 #ifdef WOLFSSL_ATECC508A
06038     /* TODO: Implement equiv call to ATECC508A */
06039     err = BAD_COND_E;
06040 
06041 #else
06042     ALLOC_CURVE_SPECS(2);
06043 
06044     /* load curve info */
06045     err = wc_ecc_curve_load(key->dp, &curve,
06046         (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
06047 
06048     if (err == MP_OKAY)
06049         err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
06050 
06051     wc_ecc_curve_free(curve);
06052     FREE_CURVE_SPECS();
06053 
06054 #endif /* WOLFSSL_ATECC508A */
06055 
06056     return err;
06057 }
06058 
06059 #endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
06060 
06061 
06062 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)
06063 /* validate order * pubkey = point at infinity, 0 on success */
06064 static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
06065         mp_int* prime, mp_int* order)
06066 {
06067     ecc_point* inf = NULL;
06068     int        err;
06069 
06070     if (key == NULL)
06071         return BAD_FUNC_ARG;
06072 
06073     inf = wc_ecc_new_point_h(key->heap);
06074     if (inf == NULL)
06075         err = MEMORY_E;
06076     else {
06077 #ifdef WOLFSSL_HAVE_SP_ECC
06078 #ifndef WOLFSSL_SP_NO_256
06079         if (key->idx != ECC_CUSTOM_IDX &&
06080                                        ecc_sets[key->idx].id == ECC_SECP256R1) {
06081             err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
06082         }
06083         else
06084 #endif
06085 #endif
06086 #ifndef WOLFSSL_SP_MATH
06087             err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
06088         if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
06089             err = ECC_INF_E;
06090 #else
06091             (void)a;
06092             (void)prime;
06093 
06094             err = WC_KEY_SIZE_E;
06095 #endif
06096     }
06097 
06098     wc_ecc_del_point_h(inf, key->heap);
06099 
06100     return err;
06101 }
06102 #endif
06103 #endif /* !WOLFSSL_ATECC508A */
06104 
06105 
06106 /* perform sanity checks on ecc key validity, 0 on success */
06107 int wc_ecc_check_key(ecc_key* key)
06108 {
06109     int    err;
06110 #ifndef WOLFSSL_SP_MATH
06111 #ifndef WOLFSSL_ATECC508A
06112     mp_int* b = NULL;
06113 #ifdef USE_ECC_B_PARAM
06114     DECLARE_CURVE_SPECS(curve, 4);
06115 #else
06116 #ifndef WOLFSSL_SMALL_STACK
06117     mp_int b_lcl;
06118 #endif
06119     DECLARE_CURVE_SPECS(curve, 3);
06120 #endif /* USE_ECC_B_PARAM */
06121 #endif /* WOLFSSL_ATECC508A */
06122 
06123     if (key == NULL)
06124         return BAD_FUNC_ARG;
06125 
06126 #ifdef WOLFSSL_ATECC508A
06127 
06128     if (key->slot == ATECC_INVALID_SLOT)
06129         return ECC_BAD_ARG_E;
06130 
06131     err = 0; /* consider key check success on ECC508A */
06132 
06133 #else
06134     #ifdef USE_ECC_B_PARAM
06135         ALLOC_CURVE_SPECS(4);
06136     #else
06137         ALLOC_CURVE_SPECS(3);
06138         #ifndef WOLFSSL_SMALL_STACK
06139             b = &b_lcl;
06140         #else
06141             b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
06142             if (b == NULL) {
06143                 FREE_CURVE_SPECS();
06144                 return MEMORY_E;
06145             }
06146         #endif
06147         XMEMSET(b, 0, sizeof(mp_int));
06148     #endif
06149 
06150     /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
06151     /* pubkey point cannot be at infinity */
06152     if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
06153     #ifdef WOLFSSL_SMALL_STACK
06154         XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
06155     #endif
06156         FREE_CURVE_SPECS();
06157         return ECC_INF_E;
06158     }
06159 
06160     /* load curve info */
06161     err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
06162             ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
06163 #ifdef USE_ECC_B_PARAM
06164             | ECC_CURVE_FIELD_BF
06165 #endif
06166     ));
06167 
06168 #ifndef USE_ECC_B_PARAM
06169     /* load curve b parameter */
06170     if (err == MP_OKAY)
06171         err = mp_init(b);
06172     if (err == MP_OKAY)
06173         err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);
06174 #else
06175     b = curve->Bf;
06176 #endif
06177 
06178     /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
06179     /* Qx must be in the range [0, p-1] */
06180     if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)
06181         err = ECC_OUT_OF_RANGE_E;
06182 
06183     /* Qy must be in the range [0, p-1] */
06184     if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT)
06185         err = ECC_OUT_OF_RANGE_E;
06186 
06187     /* SP 800-56Ar3, section 5.6.2.3.3, process steps 3 */
06188     /* make sure point is actually on curve */
06189     if (err == MP_OKAY)
06190         err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
06191 
06192     /* SP 800-56Ar3, section 5.6.2.3.3, process steps 4 */
06193     /* pubkey * order must be at infinity */
06194     if (err == MP_OKAY)
06195         err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af, curve->prime,
06196                 curve->order);
06197 
06198     /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
06199     /* private * base generator must equal pubkey */
06200     if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
06201         err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
06202 
06203     wc_ecc_curve_free(curve);
06204 
06205 #ifndef USE_ECC_B_PARAM
06206     mp_clear(b);
06207     #ifdef WOLFSSL_SMALL_STACK
06208         XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
06209     #endif
06210 #endif
06211 
06212     FREE_CURVE_SPECS();
06213 
06214 #endif /* WOLFSSL_ATECC508A */
06215 #else
06216     if (key == NULL)
06217         return BAD_FUNC_ARG;
06218 
06219     /* pubkey point cannot be at infinity */
06220     if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
06221         err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k,
06222                                                                      key->heap);
06223     }
06224     else
06225         err = WC_KEY_SIZE_E;
06226 #endif
06227 
06228     return err;
06229 }
06230 
06231 #ifdef HAVE_ECC_KEY_IMPORT
06232 /* import public ECC key in ANSI X9.63 format */
06233 int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
06234                           int curve_id)
06235 {
06236     int err = MP_OKAY;
06237     int compressed = 0;
06238     int keysize = 0;
06239     byte pointType;
06240 
06241     if (in == NULL || key == NULL)
06242         return BAD_FUNC_ARG;
06243 
06244     /* must be odd */
06245     if ((inLen & 1) == 0) {
06246         return ECC_BAD_ARG_E;
06247     }
06248 
06249     /* make sure required variables are reset */
06250     wc_ecc_reset(key);
06251 
06252     /* init key */
06253     #ifdef ALT_ECC_SIZE
06254         key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
06255         key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
06256         key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
06257         alt_fp_init(key->pubkey.x);
06258         alt_fp_init(key->pubkey.y);
06259         alt_fp_init(key->pubkey.z);
06260         err = mp_init(&key->k);
06261     #else
06262         err = mp_init_multi(&key->k,
06263                     key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL);
06264     #endif
06265     if (err != MP_OKAY)
06266         return MEMORY_E;
06267 
06268     /* check for point type (4, 2, or 3) */
06269     pointType = in[0];
06270     if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
06271                                          pointType != ECC_POINT_COMP_ODD) {
06272         err = ASN_PARSE_E;
06273     }
06274 
06275     if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
06276     #ifdef HAVE_COMP_KEY
06277         compressed = 1;
06278     #else
06279         err = NOT_COMPILED_IN;
06280     #endif
06281     }
06282 
06283     /* adjust to skip first byte */
06284     inLen -= 1;
06285     in += 1;
06286 
06287     if (err == MP_OKAY) {
06288     #ifdef HAVE_COMP_KEY
06289         /* adjust inLen if compressed */
06290         if (compressed)
06291             inLen = inLen*2 + 1;  /* used uncompressed len */
06292     #endif
06293 
06294         /* determine key size */
06295         keysize = (inLen>>1);
06296         err = wc_ecc_set_curve(key, keysize, curve_id);
06297         key->type = ECC_PUBLICKEY;
06298     }
06299 
06300     /* read data */
06301     if (err == MP_OKAY)
06302         err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in, keysize);
06303 
06304 #ifdef HAVE_COMP_KEY
06305     if (err == MP_OKAY && compressed == 1) {   /* build y */
06306 #ifndef WOLFSSL_SP_MATH
06307         mp_int t1, t2;
06308         int did_init = 0;
06309 
06310         DECLARE_CURVE_SPECS(curve, 3);
06311         ALLOC_CURVE_SPECS(3);
06312 
06313         if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
06314             err = MEMORY_E;
06315         else
06316             did_init = 1;
06317 
06318         /* load curve info */
06319         if (err == MP_OKAY)
06320             err = wc_ecc_curve_load(key->dp, &curve,
06321                 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
06322                  ECC_CURVE_FIELD_BF));
06323 
06324         /* compute x^3 */
06325         if (err == MP_OKAY)
06326             err = mp_sqr(key->pubkey.x, &t1);
06327         if (err == MP_OKAY)
06328             err = mp_mulmod(&t1, key->pubkey.x, curve->prime, &t1);
06329 
06330         /* compute x^3 + a*x */
06331         if (err == MP_OKAY)
06332             err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, &t2);
06333         if (err == MP_OKAY)
06334             err = mp_add(&t1, &t2, &t1);
06335 
06336         /* compute x^3 + a*x + b */
06337         if (err == MP_OKAY)
06338             err = mp_add(&t1, curve->Bf, &t1);
06339 
06340         /* compute sqrt(x^3 + a*x + b) */
06341         if (err == MP_OKAY)
06342             err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
06343 
06344         /* adjust y */
06345         if (err == MP_OKAY) {
06346             if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
06347                 (mp_isodd(&t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
06348                 err = mp_mod(&t2, curve->prime, &t2);
06349             }
06350             else {
06351                 err = mp_submod(curve->prime, &t2, curve->prime, &t2);
06352             }
06353             if (err == MP_OKAY)
06354                 err = mp_copy(&t2, key->pubkey.y);
06355         }
06356 
06357         if (did_init) {
06358             mp_clear(&t2);
06359             mp_clear(&t1);
06360         }
06361 
06362         wc_ecc_curve_free(curve);
06363         FREE_CURVE_SPECS();
06364 #else
06365         sp_ecc_uncompress_256(key->pubkey.x, pointType, key->pubkey.y);
06366 #endif
06367     }
06368 #endif /* HAVE_COMP_KEY */
06369 
06370     if (err == MP_OKAY && compressed == 0)
06371         err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in + keysize, keysize);
06372     if (err == MP_OKAY)
06373         err = mp_set(key->pubkey.z, 1);
06374 
06375 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
06376     if (err == MP_OKAY)
06377         err = wc_ecc_check_key(key);
06378 #endif
06379 
06380     if (err != MP_OKAY) {
06381         mp_clear(key->pubkey.x);
06382         mp_clear(key->pubkey.y);
06383         mp_clear(key->pubkey.z);
06384         mp_clear(&key->k);
06385     }
06386 
06387     return err;
06388 }
06389 
06390 int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
06391 {
06392     return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
06393 }
06394 #endif /* HAVE_ECC_KEY_IMPORT */
06395 
06396 #ifdef HAVE_ECC_KEY_EXPORT
06397 /* export ecc private key only raw, outLen is in/out size
06398    return MP_OKAY on success */
06399 int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
06400 {
06401     word32 numlen;
06402 
06403     if (key == NULL || out == NULL || outLen == NULL) {
06404         return BAD_FUNC_ARG;
06405     }
06406 
06407     if (wc_ecc_is_valid_idx(key->idx) == 0) {
06408         return ECC_BAD_ARG_E;
06409     }
06410     numlen = key->dp->size;
06411 
06412     if (*outLen < numlen) {
06413         *outLen = numlen;
06414         return BUFFER_E;
06415     }
06416     *outLen = numlen;
06417     XMEMSET(out, 0, *outLen);
06418 
06419 #ifdef WOLFSSL_ATECC508A
06420    /* TODO: Implement equiv call to ATECC508A */
06421    return BAD_COND_E;
06422 
06423 #else
06424 
06425     return mp_to_unsigned_bin(&key->k, out + (numlen -
06426                                            mp_unsigned_bin_size(&key->k)));
06427 #endif /* WOLFSSL_ATECC508A */
06428 }
06429 
06430 
06431 /* export ecc key to component form, d is optional if only exporting public
06432  * return MP_OKAY on success */
06433 static int wc_ecc_export_raw(ecc_key* key, byte* qx, word32* qxLen,
06434                              byte* qy, word32* qyLen, byte* d, word32* dLen)
06435 {
06436     int  err;
06437     byte exportPriv = 0;
06438     word32 numLen;
06439 
06440     if (key == NULL || qx == NULL || qxLen == NULL || qy == NULL ||
06441         qyLen == NULL) {
06442         return BAD_FUNC_ARG;
06443     }
06444 
06445     if (key->type == ECC_PRIVATEKEY_ONLY) {
06446         return ECC_PRIVATEONLY_E;
06447     }
06448 
06449     if (wc_ecc_is_valid_idx(key->idx) == 0) {
06450         return ECC_BAD_ARG_E;
06451     }
06452     numLen = key->dp->size;
06453 
06454     if (d != NULL) {
06455         if (dLen == NULL || key->type != ECC_PRIVATEKEY)
06456             return BAD_FUNC_ARG;
06457         exportPriv = 1;
06458     }
06459 
06460     /* check public buffer sizes */
06461     if ((*qxLen < numLen) || (*qyLen < numLen)) {
06462         *qxLen = numLen;
06463         *qyLen = numLen;
06464         return BUFFER_E;
06465     }
06466 
06467     *qxLen = numLen;
06468     *qyLen = numLen;
06469 
06470     XMEMSET(qx, 0, *qxLen);
06471     XMEMSET(qy, 0, *qyLen);
06472 
06473     /* private d component */
06474     if (exportPriv == 1) {
06475 
06476         /* check private buffer size */
06477         if (*dLen < numLen) {
06478             *dLen = numLen;
06479             return BUFFER_E;
06480         }
06481 
06482         *dLen = numLen;
06483         XMEMSET(d, 0, *dLen);
06484 
06485     #ifdef WOLFSSL_ATECC508A
06486        /* TODO: Implement equiv call to ATECC508A */
06487        return BAD_COND_E;
06488 
06489     #else
06490 
06491         /* private key, d */
06492         err = mp_to_unsigned_bin(&key->k, d +
06493                             (numLen - mp_unsigned_bin_size(&key->k)));
06494         if (err != MP_OKAY)
06495             return err;
06496     #endif /* WOLFSSL_ATECC508A */
06497     }
06498 
06499     /* public x component */
06500     err = mp_to_unsigned_bin(key->pubkey.x, qx +
06501                             (numLen - mp_unsigned_bin_size(key->pubkey.x)));
06502     if (err != MP_OKAY)
06503         return err;
06504 
06505     /* public y component */
06506     err = mp_to_unsigned_bin(key->pubkey.y, qy +
06507                             (numLen - mp_unsigned_bin_size(key->pubkey.y)));
06508     if (err != MP_OKAY)
06509         return err;
06510 
06511     return 0;
06512 }
06513 
06514 
06515 /* export public key to raw elements including public (Qx,Qy)
06516  * return MP_OKAY on success, negative on error */
06517 int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
06518                              byte* qy, word32* qyLen)
06519 {
06520     return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, NULL, NULL);
06521 }
06522 
06523 
06524 /* export ecc key to raw elements including public (Qx,Qy) and private (d)
06525  * return MP_OKAY on success, negative on error */
06526 int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
06527                               byte* qy, word32* qyLen, byte* d, word32* dLen)
06528 {
06529     /* sanitize d and dLen, other args are checked later */
06530     if (d == NULL || dLen == NULL)
06531         return BAD_FUNC_ARG;
06532 
06533     return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, d, dLen);
06534 }
06535 
06536 #endif /* HAVE_ECC_KEY_EXPORT */
06537 
06538 #ifdef HAVE_ECC_KEY_IMPORT
06539 /* import private key, public part optional if (pub) passed as NULL */
06540 int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
06541                                  const byte* pub, word32 pubSz, ecc_key* key,
06542                                  int curve_id)
06543 {
06544     int ret;
06545     word32 idx = 0;
06546 
06547     if (key == NULL || priv == NULL)
06548         return BAD_FUNC_ARG;
06549 
06550     /* public optional, NULL if only importing private */
06551     if (pub != NULL) {
06552         ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
06553         if (ret < 0)
06554             ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
06555         key->type = ECC_PRIVATEKEY;
06556     }
06557     else {
06558         /* make sure required variables are reset */
06559         wc_ecc_reset(key);
06560 
06561         /* set key size */
06562         ret = wc_ecc_set_curve(key, privSz, curve_id);
06563         key->type = ECC_PRIVATEKEY_ONLY;
06564     }
06565 
06566     if (ret != 0)
06567         return ret;
06568 
06569 #ifdef WOLFSSL_ATECC508A
06570     /* TODO: Implement equiv call to ATECC508A */
06571     return BAD_COND_E;
06572 
06573 #else
06574 
06575     ret = mp_read_unsigned_bin(&key->k, priv, privSz);
06576 
06577 #endif /* WOLFSSL_ATECC508A */
06578 
06579 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
06580     if ((pub != NULL) && (ret == MP_OKAY))
06581         /* public key needed to perform key validation */
06582         ret = ecc_check_privkey_gen_helper(key);
06583 #endif
06584 
06585     return ret;
06586 }
06587 
06588 /* ecc private key import, public key in ANSI X9.63 format, private raw */
06589 int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
06590                            word32 pubSz, ecc_key* key)
06591 {
06592     return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
06593                                                                 ECC_CURVE_DEF);
06594 }
06595 #endif /* HAVE_ECC_KEY_IMPORT */
06596 
06597 #ifndef NO_ASN
06598 /**
06599    Convert ECC R,S to signature
06600    r       R component of signature
06601    s       S component of signature
06602    out     DER-encoded ECDSA signature
06603    outlen  [in/out] output buffer size, output signature size
06604    return  MP_OKAY on success
06605 */
06606 int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
06607 {
06608     int err;
06609 #ifdef WOLFSSL_SMALL_STACK
06610     mp_int* rtmp = NULL;
06611     mp_int* stmp = NULL;
06612 #else
06613     mp_int  rtmp[1];
06614     mp_int  stmp[1];
06615 #endif
06616 
06617     if (r == NULL || s == NULL || out == NULL || outlen == NULL)
06618         return ECC_BAD_ARG_E;
06619 
06620 #ifdef WOLFSSL_SMALL_STACK
06621     rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
06622     if (rtmp == NULL)
06623         return MEMORY_E;
06624     stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
06625     if (stmp == NULL) {
06626         XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
06627         return MEMORY_E;
06628     }
06629 #endif
06630 
06631     err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
06632     if (err != MP_OKAY) {
06633     #ifdef WOLFSSL_SMALL_STACK
06634         XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
06635         XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
06636     #endif
06637         return err;
06638     }
06639 
06640     err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
06641     if (err == MP_OKAY)
06642         err = mp_read_radix(stmp, s, MP_RADIX_HEX);
06643 
06644     /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
06645     if (err == MP_OKAY)
06646         err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
06647 
06648     if (err == MP_OKAY) {
06649         if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
06650             err = MP_ZERO_E;
06651     }
06652 
06653     mp_clear(rtmp);
06654     mp_clear(stmp);
06655 #ifdef WOLFSSL_SMALL_STACK
06656     XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
06657     XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
06658 #endif
06659 
06660     return err;
06661 }
06662 
06663 /**
06664    Convert ECC R,S raw unsigned bin to signature
06665    r       R component of signature
06666    rSz     R size
06667    s       S component of signature
06668    sSz     S size
06669    out     DER-encoded ECDSA signature
06670    outlen  [in/out] output buffer size, output signature size
06671    return  MP_OKAY on success
06672 */
06673 int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
06674     byte* out, word32* outlen)
06675 {
06676     int err;
06677 #ifdef WOLFSSL_SMALL_STACK
06678     mp_int* rtmp = NULL;
06679     mp_int* stmp = NULL;
06680 #else
06681     mp_int  rtmp[1];
06682     mp_int  stmp[1];
06683 #endif
06684 
06685     if (r == NULL || s == NULL || out == NULL || outlen == NULL)
06686         return ECC_BAD_ARG_E;
06687 
06688 #ifdef WOLFSSL_SMALL_STACK
06689     rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
06690     if (rtmp == NULL)
06691         return MEMORY_E;
06692     stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
06693     if (stmp == NULL) {
06694         XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
06695         return MEMORY_E;
06696     }
06697 #endif
06698 
06699     err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
06700     if (err != MP_OKAY) {
06701     #ifdef WOLFSSL_SMALL_STACK
06702         XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
06703         XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
06704     #endif
06705         return err;
06706     }
06707 
06708     err = mp_read_unsigned_bin(rtmp, r, rSz);
06709     if (err == MP_OKAY)
06710         err = mp_read_unsigned_bin(stmp, s, sSz);
06711 
06712     /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
06713     if (err == MP_OKAY)
06714         err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
06715 
06716     if (err == MP_OKAY) {
06717         if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
06718             err = MP_ZERO_E;
06719     }
06720 
06721     mp_clear(rtmp);
06722     mp_clear(stmp);
06723 #ifdef WOLFSSL_SMALL_STACK
06724     XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
06725     XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
06726 #endif
06727 
06728     return err;
06729 }
06730 
06731 /**
06732    Convert ECC signature to R,S
06733    sig     DER-encoded ECDSA signature
06734    sigLen  length of signature in octets
06735    r       R component of signature
06736    rLen    [in/out] output "r" buffer size, output "r" size
06737    s       S component of signature
06738    sLen    [in/out] output "s" buffer size, output "s" size
06739    return  MP_OKAY on success, negative on error
06740 */
06741 int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
06742                      byte* s, word32* sLen)
06743 {
06744     int err;
06745     word32 x = 0;
06746 #ifdef WOLFSSL_SMALL_STACK
06747     mp_int* rtmp = NULL;
06748     mp_int* stmp = NULL;
06749 #else
06750     mp_int  rtmp[1];
06751     mp_int  stmp[1];
06752 #endif
06753 
06754     if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
06755         return ECC_BAD_ARG_E;
06756 
06757 #ifdef WOLFSSL_SMALL_STACK
06758     rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
06759     if (rtmp == NULL)
06760         return MEMORY_E;
06761     stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
06762     if (stmp == NULL) {
06763         XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
06764         return MEMORY_E;
06765     }
06766 #endif
06767 
06768     err = DecodeECC_DSA_Sig(sig, sigLen, rtmp, stmp);
06769 
06770     /* extract r */
06771     if (err == MP_OKAY) {
06772         x = mp_unsigned_bin_size(rtmp);
06773         if (*rLen < x)
06774             err = BUFFER_E;
06775 
06776         if (err == MP_OKAY) {
06777             *rLen = x;
06778             err = mp_to_unsigned_bin(rtmp, r);
06779         }
06780     }
06781 
06782     /* extract s */
06783     if (err == MP_OKAY) {
06784         x = mp_unsigned_bin_size(stmp);
06785         if (*sLen < x)
06786             err = BUFFER_E;
06787 
06788         if (err == MP_OKAY) {
06789             *sLen = x;
06790             err = mp_to_unsigned_bin(stmp, s);
06791         }
06792     }
06793 
06794     mp_clear(rtmp);
06795     mp_clear(stmp);
06796 #ifdef WOLFSSL_SMALL_STACK
06797     XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
06798     XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
06799 #endif
06800 
06801     return err;
06802 }
06803 #endif /* !NO_ASN */
06804 
06805 #ifdef HAVE_ECC_KEY_IMPORT
06806 static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
06807           const char* qy, const char* d, int curve_id, int encType)
06808 {
06809     int err = MP_OKAY;
06810 
06811     /* if d is NULL, only import as public key using Qx,Qy */
06812     if (key == NULL || qx == NULL || qy == NULL) {
06813         return BAD_FUNC_ARG;
06814     }
06815 
06816     /* make sure required variables are reset */
06817     wc_ecc_reset(key);
06818 
06819     /* set curve type and index */
06820     err = wc_ecc_set_curve(key, 0, curve_id);
06821     if (err != 0) {
06822         return err;
06823     }
06824 
06825 #ifdef WOLFSSL_ATECC508A
06826     /* TODO: Implement equiv call to ATECC508A */
06827     err = BAD_COND_E;
06828     (void)d;
06829     (void)encType;
06830 
06831 #else
06832 
06833     /* init key */
06834 #ifdef ALT_ECC_SIZE
06835     key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
06836     key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
06837     key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
06838     alt_fp_init(key->pubkey.x);
06839     alt_fp_init(key->pubkey.y);
06840     alt_fp_init(key->pubkey.z);
06841     err = mp_init(&key->k);
06842 #else
06843     err = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
06844                                                                   NULL, NULL);
06845 #endif
06846     if (err != MP_OKAY)
06847         return MEMORY_E;
06848 
06849     /* read Qx */
06850     if (err == MP_OKAY) {
06851         if (encType == ECC_TYPE_HEX_STR)
06852             err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
06853         else
06854             err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
06855                 key->dp->size);
06856     }
06857 
06858     /* read Qy */
06859     if (err == MP_OKAY) {
06860         if (encType == ECC_TYPE_HEX_STR)
06861             err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
06862         else
06863             err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
06864                 key->dp->size);
06865 
06866     }
06867 
06868     if (err == MP_OKAY)
06869         err = mp_set(key->pubkey.z, 1);
06870 
06871     /* import private key */
06872     if (err == MP_OKAY) {
06873         if (d != NULL) {
06874             key->type = ECC_PRIVATEKEY;
06875 
06876             if (encType == ECC_TYPE_HEX_STR)
06877                 err = mp_read_radix(&key->k, d, MP_RADIX_HEX);
06878             else
06879                 err = mp_read_unsigned_bin(&key->k, (const byte*)d,
06880                     key->dp->size);
06881 
06882         } else {
06883             key->type = ECC_PUBLICKEY;
06884         }
06885     }
06886 
06887 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
06888     if (err == MP_OKAY)
06889         err = wc_ecc_check_key(key);
06890 #endif
06891 
06892     if (err != MP_OKAY) {
06893         mp_clear(key->pubkey.x);
06894         mp_clear(key->pubkey.y);
06895         mp_clear(key->pubkey.z);
06896         mp_clear(&key->k);
06897     }
06898 #endif /* WOLFSSL_ATECC508A */
06899 
06900     return err;
06901 }
06902 
06903 /**
06904    Import raw ECC key
06905    key       The destination ecc_key structure
06906    qx        x component of the public key, as ASCII hex string
06907    qy        y component of the public key, as ASCII hex string
06908    d         private key, as ASCII hex string, optional if importing public
06909              key only
06910    dp        Custom ecc_set_type
06911    return    MP_OKAY on success
06912 */
06913 int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
06914                    const char* d, int curve_id)
06915 {
06916     return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
06917         ECC_TYPE_HEX_STR);
06918 
06919 }
06920 
06921 /* Import x, y and optional private (d) as unsigned binary */
06922 int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy,
06923                    byte* d, int curve_id)
06924 {
06925     return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
06926         (const char*)d, curve_id, ECC_TYPE_UNSIGNED_BIN);
06927 }
06928 
06929 /**
06930    Import raw ECC key
06931    key       The destination ecc_key structure
06932    qx        x component of the public key, as ASCII hex string
06933    qy        y component of the public key, as ASCII hex string
06934    d         private key, as ASCII hex string, optional if importing public
06935              key only
06936    curveName ECC curve name, from ecc_sets[]
06937    return    MP_OKAY on success
06938 */
06939 int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
06940                    const char* d, const char* curveName)
06941 {
06942     int err, x;
06943 
06944     /* if d is NULL, only import as public key using Qx,Qy */
06945     if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
06946         return BAD_FUNC_ARG;
06947     }
06948 
06949     /* set curve type and index */
06950     for (x = 0; ecc_sets[x].size != 0; x++) {
06951         if (XSTRNCMP(ecc_sets[x].name, curveName,
06952                      XSTRLEN(curveName)) == 0) {
06953             break;
06954         }
06955     }
06956 
06957     if (ecc_sets[x].size == 0) {
06958         WOLFSSL_MSG("ecc_set curve name not found");
06959         err = ASN_PARSE_E;
06960     } else {
06961         return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
06962             ECC_TYPE_HEX_STR);
06963     }
06964 
06965     return err;
06966 }
06967 #endif /* HAVE_ECC_KEY_IMPORT */
06968 
06969 /* key size in octets */
06970 int wc_ecc_size(ecc_key* key)
06971 {
06972     if (key == NULL) return 0;
06973 
06974     return key->dp->size;
06975 }
06976 
06977 int wc_ecc_sig_size_calc(int sz)
06978 {
06979     return (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
06980 }
06981 
06982 /* worst case estimate, check actual return from wc_ecc_sign_hash for actual
06983    value of signature size in octets */
06984 int wc_ecc_sig_size(ecc_key* key)
06985 {
06986     int sz = wc_ecc_size(key);
06987     if (sz <= 0)
06988         return sz;
06989 
06990     return wc_ecc_sig_size_calc(sz);
06991 }
06992 
06993 
06994 #ifdef FP_ECC
06995 
06996 /* fixed point ECC cache */
06997 /* number of entries in the cache */
06998 #ifndef FP_ENTRIES
06999     #define FP_ENTRIES 15
07000 #endif
07001 
07002 /* number of bits in LUT */
07003 #ifndef FP_LUT
07004     #define FP_LUT     8U
07005 #endif
07006 
07007 #ifdef ECC_SHAMIR
07008     /* Sharmir requires a bigger LUT, TAO */
07009     #if (FP_LUT > 12) || (FP_LUT < 4)
07010         #error FP_LUT must be between 4 and 12 inclusively
07011     #endif
07012 #else
07013     #if (FP_LUT > 12) || (FP_LUT < 2)
07014         #error FP_LUT must be between 2 and 12 inclusively
07015     #endif
07016 #endif
07017 
07018 
07019 #ifndef WOLFSSL_SP_MATH
07020 
07021 /** Our FP cache */
07022 typedef struct {
07023    ecc_point* g;               /* cached COPY of base point */
07024    ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
07025    mp_int     mu;              /* copy of the montgomery constant */
07026    int        lru_count;       /* amount of times this entry has been used */
07027    int        lock;            /* flag to indicate cache eviction */
07028                                /* permitted (0) or not (1) */
07029 } fp_cache_t;
07030 
07031 /* if HAVE_THREAD_LS this cache is per thread, no locking needed */
07032 static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
07033 
07034 #ifndef HAVE_THREAD_LS
07035     static volatile int initMutex = 0;  /* prevent multiple mutex inits */
07036     static wolfSSL_Mutex ecc_fp_lock;
07037 #endif /* HAVE_THREAD_LS */
07038 
07039 /* simple table to help direct the generation of the LUT */
07040 static const struct {
07041    int ham, terma, termb;
07042 } lut_orders[] = {
07043    { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
07044    { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
07045    { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
07046    { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
07047    { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
07048    { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
07049    { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
07050    { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
07051 #if FP_LUT > 6
07052    { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
07053    { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
07054    { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
07055    { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
07056    { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
07057    { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
07058    { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
07059    { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
07060 #if FP_LUT > 7
07061    { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
07062    { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
07063    { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
07064    { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
07065    { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
07066    { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
07067    { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
07068    { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
07069    { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
07070    { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
07071    { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
07072    { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
07073    { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
07074    { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
07075    { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
07076    { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
07077 #if FP_LUT > 8
07078    { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
07079    { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
07080    { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
07081    { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
07082    { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
07083    { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
07084    { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
07085    { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
07086    { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
07087    { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
07088    { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
07089    { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
07090    { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
07091    { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
07092    { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
07093    { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
07094    { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
07095    { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
07096    { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
07097    { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
07098    { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
07099    { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
07100    { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
07101    { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
07102    { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
07103    { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
07104    { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
07105    { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
07106    { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
07107    { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
07108    { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
07109    { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
07110 #if FP_LUT > 9
07111    { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
07112    { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
07113    { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
07114    { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
07115    { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
07116    { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
07117    { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
07118    { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
07119    { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
07120    { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
07121    { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
07122    { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
07123    { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
07124    { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
07125    { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
07126    { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
07127    { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
07128    { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
07129    { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
07130    { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
07131    { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
07132    { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
07133    { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
07134    { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
07135    { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
07136    { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
07137    { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
07138    { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
07139    { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
07140    { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
07141    { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
07142    { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
07143    { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
07144    { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
07145    { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
07146    { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
07147    { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
07148    { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
07149    { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
07150    { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
07151    { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
07152    { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
07153    { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
07154    { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
07155    { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
07156    { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
07157    { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
07158    { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
07159    { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
07160    { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
07161    { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
07162    { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
07163    { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
07164    { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
07165    { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
07166    { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
07167    { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
07168    { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
07169    { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
07170    { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
07171    { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
07172    { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
07173    { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
07174    { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
07175 #if FP_LUT > 10
07176    { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
07177    { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
07178    { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
07179    { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
07180    { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
07181    { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
07182    { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
07183    { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
07184    { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
07185    { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
07186    { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
07187    { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
07188    { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
07189    { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
07190    { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
07191    { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
07192    { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
07193    { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
07194    { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
07195    { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
07196    { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
07197    { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
07198    { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
07199    { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
07200    { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
07201    { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
07202    { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
07203    { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
07204    { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
07205    { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
07206    { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
07207    { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
07208    { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
07209    { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
07210    { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
07211    { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
07212    { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
07213    { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
07214    { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
07215    { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
07216    { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
07217    { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
07218    { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
07219    { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
07220    { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
07221    { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
07222    { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
07223    { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
07224    { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
07225    { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
07226    { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
07227    { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
07228    { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
07229    { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
07230    { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
07231    { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
07232    { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
07233    { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
07234    { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
07235    { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
07236    { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
07237    { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
07238    { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
07239    { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
07240    { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
07241    { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
07242    { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
07243    { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
07244    { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
07245    { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
07246    { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
07247    { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
07248    { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
07249    { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
07250    { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
07251    { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
07252    { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
07253    { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
07254    { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
07255    { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
07256    { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
07257    { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
07258    { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
07259    { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
07260    { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
07261    { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
07262    { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
07263    { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
07264    { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
07265    { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
07266    { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
07267    { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
07268    { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
07269    { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
07270    { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
07271    { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
07272    { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
07273    { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
07274    { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
07275    { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
07276    { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
07277    { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
07278    { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
07279    { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
07280    { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
07281    { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
07282    { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
07283    { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
07284    { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
07285    { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
07286    { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
07287    { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
07288    { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
07289    { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
07290    { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
07291    { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
07292    { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
07293    { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
07294    { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
07295    { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
07296    { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
07297    { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
07298    { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
07299    { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
07300    { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
07301    { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
07302    { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
07303    { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
07304 #if FP_LUT > 11
07305    { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
07306    { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
07307    { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
07308    { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
07309    { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
07310    { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
07311    { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
07312    { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
07313    { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
07314    { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
07315    { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
07316    { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
07317    { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
07318    { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
07319    { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
07320    { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
07321    { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
07322    { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
07323    { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
07324    { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
07325    { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
07326    { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
07327    { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
07328    { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
07329    { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
07330    { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
07331    { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
07332    { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
07333    { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
07334    { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
07335    { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
07336    { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
07337    { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
07338    { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
07339    { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
07340    { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
07341    { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
07342    { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
07343    { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
07344    { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
07345    { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
07346    { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
07347    { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
07348    { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
07349    { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
07350    { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
07351    { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
07352    { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
07353    { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
07354    { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
07355    { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
07356    { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
07357    { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
07358    { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
07359    { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
07360    { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
07361    { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
07362    { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
07363    { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
07364    { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
07365    { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
07366    { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
07367    { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
07368    { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
07369    { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
07370    { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
07371    { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
07372    { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
07373    { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
07374    { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
07375    { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
07376    { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
07377    { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
07378    { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
07379    { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
07380    { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
07381    { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
07382    { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
07383    { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
07384    { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
07385    { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
07386    { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
07387    { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
07388    { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
07389    { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
07390    { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
07391    { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
07392    { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
07393    { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
07394    { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
07395    { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
07396    { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
07397    { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
07398    { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
07399    { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
07400    { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
07401    { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
07402    { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
07403    { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
07404    { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
07405    { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
07406    { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
07407    { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
07408    { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
07409    { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
07410    { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
07411    { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
07412    { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
07413    { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
07414    { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
07415    { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
07416    { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
07417    { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
07418    { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
07419    { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
07420    { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
07421    { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
07422    { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
07423    { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
07424    { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
07425    { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
07426    { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
07427    { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
07428    { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
07429    { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
07430    { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
07431    { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
07432    { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
07433    { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
07434    { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
07435    { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
07436    { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
07437    { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
07438    { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
07439    { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
07440    { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
07441    { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
07442    { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
07443    { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
07444    { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
07445    { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
07446    { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
07447    { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
07448    { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
07449    { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
07450    { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
07451    { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
07452    { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
07453    { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
07454    { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
07455    { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
07456    { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
07457    { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
07458    { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
07459    { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
07460    { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
07461    { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
07462    { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
07463    { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
07464    { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
07465    { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
07466    { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
07467    { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
07468    { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
07469    { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
07470    { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
07471    { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
07472    { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
07473    { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
07474    { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
07475    { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
07476    { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
07477    { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
07478    { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
07479    { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
07480    { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
07481    { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
07482    { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
07483    { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
07484    { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
07485    { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
07486    { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
07487    { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
07488    { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
07489    { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
07490    { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
07491    { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
07492    { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
07493    { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
07494    { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
07495    { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
07496    { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
07497    { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
07498    { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
07499    { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
07500    { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
07501    { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
07502    { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
07503    { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
07504    { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
07505    { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
07506    { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
07507    { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
07508    { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
07509    { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
07510    { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
07511    { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
07512    { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
07513    { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
07514    { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
07515    { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
07516    { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
07517    { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
07518    { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
07519    { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
07520    { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
07521    { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
07522    { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
07523    { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
07524    { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
07525    { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
07526    { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
07527    { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
07528    { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
07529    { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
07530    { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
07531    { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
07532    { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
07533    { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
07534    { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
07535    { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
07536    { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
07537    { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
07538    { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
07539    { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
07540    { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
07541    { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
07542    { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
07543    { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
07544    { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
07545    { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
07546    { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
07547    { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
07548    { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
07549    { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
07550    { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
07551    { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
07552    { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
07553    { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
07554    { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
07555    { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
07556    { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
07557    { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
07558    { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
07559    { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
07560    { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
07561 #endif
07562 #endif
07563 #endif
07564 #endif
07565 #endif
07566 #endif
07567 };
07568 
07569 
07570 /* find a hole and free as required, return -1 if no hole found */
07571 static int find_hole(void)
07572 {
07573    unsigned x;
07574    int      y, z;
07575    for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
07576        if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
07577           z = x;
07578           y = fp_cache[x].lru_count;
07579        }
07580    }
07581 
07582    /* decrease all */
07583    for (x = 0; x < FP_ENTRIES; x++) {
07584       if (fp_cache[x].lru_count > 3) {
07585          --(fp_cache[x].lru_count);
07586       }
07587    }
07588 
07589    /* free entry z */
07590    if (z >= 0 && fp_cache[z].g) {
07591       mp_clear(&fp_cache[z].mu);
07592       wc_ecc_del_point(fp_cache[z].g);
07593       fp_cache[z].g  = NULL;
07594       for (x = 0; x < (1U<<FP_LUT); x++) {
07595          wc_ecc_del_point(fp_cache[z].LUT[x]);
07596          fp_cache[z].LUT[x] = NULL;
07597       }
07598       fp_cache[z].lru_count = 0;
07599    }
07600    return z;
07601 }
07602 
07603 /* determine if a base is already in the cache and if so, where */
07604 static int find_base(ecc_point* g)
07605 {
07606    int x;
07607    for (x = 0; x < FP_ENTRIES; x++) {
07608       if (fp_cache[x].g != NULL &&
07609           mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
07610           mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
07611           mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
07612          break;
07613       }
07614    }
07615    if (x == FP_ENTRIES) {
07616       x = -1;
07617    }
07618    return x;
07619 }
07620 
07621 /* add a new base to the cache */
07622 static int add_entry(int idx, ecc_point *g)
07623 {
07624    unsigned x, y;
07625 
07626    /* allocate base and LUT */
07627    fp_cache[idx].g = wc_ecc_new_point();
07628    if (fp_cache[idx].g == NULL) {
07629       return GEN_MEM_ERR;
07630    }
07631 
07632    /* copy x and y */
07633    if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
07634        (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
07635        (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
07636       wc_ecc_del_point(fp_cache[idx].g);
07637       fp_cache[idx].g = NULL;
07638       return GEN_MEM_ERR;
07639    }
07640 
07641    for (x = 0; x < (1U<<FP_LUT); x++) {
07642       fp_cache[idx].LUT[x] = wc_ecc_new_point();
07643       if (fp_cache[idx].LUT[x] == NULL) {
07644          for (y = 0; y < x; y++) {
07645             wc_ecc_del_point(fp_cache[idx].LUT[y]);
07646             fp_cache[idx].LUT[y] = NULL;
07647          }
07648          wc_ecc_del_point(fp_cache[idx].g);
07649          fp_cache[idx].g         = NULL;
07650          fp_cache[idx].lru_count = 0;
07651          return GEN_MEM_ERR;
07652       }
07653    }
07654 
07655    fp_cache[idx].lru_count = 0;
07656 
07657    return MP_OKAY;
07658 }
07659 #endif
07660 
07661 #ifndef WOLFSSL_SP_MATH
07662 /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
07663  *
07664  * The algorithm builds patterns in increasing bit order by first making all
07665  * single bit input patterns, then all two bit input patterns and so on
07666  */
07667 static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
07668     mp_int* mu)
07669 {
07670    int err;
07671    unsigned x, y, bitlen, lut_gap;
07672    mp_int tmp;
07673 
07674    if (mp_init(&tmp) != MP_OKAY)
07675        return GEN_MEM_ERR;
07676 
07677    /* sanity check to make sure lut_order table is of correct size,
07678       should compile out to a NOP if true */
07679    if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
07680        err = BAD_FUNC_ARG;
07681    }
07682    else {
07683     /* get bitlen and round up to next multiple of FP_LUT */
07684     bitlen  = mp_unsigned_bin_size(modulus) << 3;
07685     x       = bitlen % FP_LUT;
07686     if (x) {
07687       bitlen += FP_LUT - x;
07688     }
07689     lut_gap = bitlen / FP_LUT;
07690 
07691     /* init the mu */
07692     err = mp_init_copy(&fp_cache[idx].mu, mu);
07693    }
07694 
07695    /* copy base */
07696    if (err == MP_OKAY) {
07697      if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
07698                   fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
07699          (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
07700                   fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
07701          (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
07702                   fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
07703        err = MP_MULMOD_E;
07704      }
07705    }
07706 
07707    /* make all single bit entries */
07708    for (x = 1; x < FP_LUT; x++) {
07709       if (err != MP_OKAY)
07710           break;
07711       if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x,
07712                    fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) ||
07713           (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y,
07714                    fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) ||
07715           (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z,
07716                    fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){
07717           err = MP_INIT_E;
07718           break;
07719       } else {
07720 
07721          /* now double it bitlen/FP_LUT times */
07722          for (y = 0; y < lut_gap; y++) {
07723              if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x],
07724                             fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) {
07725                  break;
07726              }
07727          }
07728      }
07729   }
07730 
07731    /* now make all entries in increase order of hamming weight */
07732    for (x = 2; x <= FP_LUT; x++) {
07733        if (err != MP_OKAY)
07734            break;
07735        for (y = 0; y < (1UL<<FP_LUT); y++) {
07736            if (lut_orders[y].ham != (int)x) continue;
07737 
07738            /* perform the add */
07739            if ((err = ecc_projective_add_point(
07740                            fp_cache[idx].LUT[lut_orders[y].terma],
07741                            fp_cache[idx].LUT[lut_orders[y].termb],
07742                            fp_cache[idx].LUT[y], a, modulus, mp)) != MP_OKAY) {
07743               break;
07744            }
07745        }
07746    }
07747 
07748    /* now map all entries back to affine space to make point addition faster */
07749    for (x = 1; x < (1UL<<FP_LUT); x++) {
07750        if (err != MP_OKAY)
07751            break;
07752 
07753        /* convert z to normal from montgomery */
07754        err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
07755 
07756        /* invert it */
07757        if (err == MP_OKAY)
07758          err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
07759                          fp_cache[idx].LUT[x]->z);
07760 
07761        if (err == MP_OKAY)
07762          /* now square it */
07763          err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp);
07764 
07765        if (err == MP_OKAY)
07766          /* fix x */
07767          err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus,
07768                          fp_cache[idx].LUT[x]->x);
07769 
07770        if (err == MP_OKAY)
07771          /* get 1/z^3 */
07772          err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp);
07773 
07774        if (err == MP_OKAY)
07775          /* fix y */
07776          err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus,
07777                          fp_cache[idx].LUT[x]->y);
07778 
07779        if (err == MP_OKAY)
07780          /* free z */
07781          mp_clear(fp_cache[idx].LUT[x]->z);
07782    }
07783 
07784    mp_clear(&tmp);
07785 
07786    if (err == MP_OKAY)
07787      return MP_OKAY;
07788 
07789    /* err cleanup */
07790    for (y = 0; y < (1U<<FP_LUT); y++) {
07791       wc_ecc_del_point(fp_cache[idx].LUT[y]);
07792       fp_cache[idx].LUT[y] = NULL;
07793    }
07794    wc_ecc_del_point(fp_cache[idx].g);
07795    fp_cache[idx].g         = NULL;
07796    fp_cache[idx].lru_count = 0;
07797    mp_clear(&fp_cache[idx].mu);
07798 
07799    return err;
07800 }
07801 
07802 /* perform a fixed point ECC mulmod */
07803 static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a,
07804                         mp_int* modulus, mp_digit mp, int map)
07805 {
07806 #define KB_SIZE 128
07807 
07808 #ifdef WOLFSSL_SMALL_STACK
07809    unsigned char* kb = NULL;
07810 #else
07811    unsigned char kb[KB_SIZE];
07812 #endif
07813    int      x, err;
07814    unsigned y, z = 0, bitlen, bitpos, lut_gap, first;
07815    mp_int   tk, order;
07816 
07817    if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY)
07818        return MP_INIT_E;
07819 
07820    /* if it's smaller than modulus we fine */
07821    if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
07822       /* find order */
07823       y = mp_unsigned_bin_size(modulus);
07824       for (x = 0; ecc_sets[x].size; x++) {
07825          if (y <= (unsigned)ecc_sets[x].size) break;
07826       }
07827 
07828       /* back off if we are on the 521 bit curve */
07829       if (y == 66) --x;
07830 
07831       if ((err = mp_read_radix(&order, ecc_sets[x].order,
07832                                                 MP_RADIX_HEX)) != MP_OKAY) {
07833          goto done;
07834       }
07835 
07836       /* k must be less than modulus */
07837       if (mp_cmp(k, &order) != MP_LT) {
07838          if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) {
07839             goto done;
07840          }
07841       } else {
07842          if ((err = mp_copy(k, &tk)) != MP_OKAY) {
07843             goto done;
07844          }
07845       }
07846    } else {
07847       if ((err = mp_copy(k, &tk)) != MP_OKAY) {
07848          goto done;
07849       }
07850    }
07851 
07852    /* get bitlen and round up to next multiple of FP_LUT */
07853    bitlen  = mp_unsigned_bin_size(modulus) << 3;
07854    x       = bitlen % FP_LUT;
07855    if (x) {
07856       bitlen += FP_LUT - x;
07857    }
07858    lut_gap = bitlen / FP_LUT;
07859 
07860    /* get the k value */
07861    if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) {
07862       err = BUFFER_E; goto done;
07863    }
07864 
07865    /* store k */
07866 #ifdef WOLFSSL_SMALL_STACK
07867    kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
07868    if (kb == NULL) {
07869       err = MEMORY_E; goto done;
07870    }
07871 #endif
07872 
07873    XMEMSET(kb, 0, KB_SIZE);
07874    if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) {
07875       /* let's reverse kb so it's little endian */
07876       x = 0;
07877       y = mp_unsigned_bin_size(&tk);
07878       if (y > 0) {
07879           y -= 1;
07880       }
07881 
07882       while ((unsigned)x < y) {
07883          z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
07884          ++x; --y;
07885       }
07886 
07887       /* at this point we can start, yipee */
07888       first = 1;
07889       for (x = lut_gap-1; x >= 0; x--) {
07890           /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
07891              by x bits from the start */
07892           bitpos = x;
07893           for (y = z = 0; y < FP_LUT; y++) {
07894              z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y;
07895              bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
07896                                     the mult in each loop */
07897           }
07898 
07899           /* double if not first */
07900           if (!first) {
07901              if ((err = ecc_projective_dbl_point(R, R, a, modulus,
07902                                                              mp)) != MP_OKAY) {
07903                 break;
07904              }
07905           }
07906 
07907           /* add if not first, otherwise copy */
07908           if (!first && z) {
07909              if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R,
07910                                                  a, modulus, mp)) != MP_OKAY) {
07911                 break;
07912              }
07913           } else if (z) {
07914              if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
07915                  (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
07916                  (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
07917                  err = GEN_MEM_ERR;
07918                  break;
07919              }
07920                  first = 0;
07921           }
07922       }
07923    }
07924 
07925    if (err == MP_OKAY) {
07926       (void) z; /* Acknowledge the unused assignment */
07927       ForceZero(kb, KB_SIZE);
07928 
07929       /* map R back from projective space */
07930       if (map) {
07931          err = ecc_map(R, modulus, mp);
07932       } else {
07933          err = MP_OKAY;
07934       }
07935    }
07936 
07937 done:
07938    /* cleanup */
07939    mp_clear(&order);
07940    mp_clear(&tk);
07941 
07942 #ifdef WOLFSSL_SMALL_STACK
07943    XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
07944 #endif
07945 
07946 #undef KB_SIZE
07947 
07948    return err;
07949 }
07950 #endif
07951 
07952 #ifdef ECC_SHAMIR
07953 #ifndef WOLFSSL_SP_MATH
07954 /* perform a fixed point ECC mulmod */
07955 static int accel_fp_mul2add(int idx1, int idx2,
07956                             mp_int* kA, mp_int* kB,
07957                             ecc_point *R, mp_int* a,
07958                             mp_int* modulus, mp_digit mp)
07959 {
07960 #define KB_SIZE 128
07961 
07962 #ifdef WOLFSSL_SMALL_STACK
07963    unsigned char* kb[2] = {NULL, NULL};
07964 #else
07965    unsigned char kb[2][KB_SIZE];
07966 #endif
07967    int      x, err;
07968    unsigned y, z, bitlen, bitpos, lut_gap, first, zA, zB;
07969    mp_int tka, tkb, order;
07970 
07971    if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY)
07972        return MP_INIT_E;
07973 
07974    /* if it's smaller than modulus we fine */
07975    if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
07976       /* find order */
07977       y = mp_unsigned_bin_size(modulus);
07978       for (x = 0; ecc_sets[x].size; x++) {
07979          if (y <= (unsigned)ecc_sets[x].size) break;
07980       }
07981 
07982       /* back off if we are on the 521 bit curve */
07983       if (y == 66) --x;
07984 
07985       if ((err = mp_read_radix(&order, ecc_sets[x].order,
07986                                                 MP_RADIX_HEX)) != MP_OKAY) {
07987          goto done;
07988       }
07989 
07990       /* kA must be less than modulus */
07991       if (mp_cmp(kA, &order) != MP_LT) {
07992          if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) {
07993             goto done;
07994          }
07995       } else {
07996          if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
07997             goto done;
07998          }
07999       }
08000    } else {
08001       if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
08002          goto done;
08003       }
08004    }
08005 
08006    /* if it's smaller than modulus we fine */
08007    if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
08008       /* find order */
08009       y = mp_unsigned_bin_size(modulus);
08010       for (x = 0; ecc_sets[x].size; x++) {
08011          if (y <= (unsigned)ecc_sets[x].size) break;
08012       }
08013 
08014       /* back off if we are on the 521 bit curve */
08015       if (y == 66) --x;
08016 
08017       if ((err = mp_read_radix(&order, ecc_sets[x].order,
08018                                                 MP_RADIX_HEX)) != MP_OKAY) {
08019          goto done;
08020       }
08021 
08022       /* kB must be less than modulus */
08023       if (mp_cmp(kB, &order) != MP_LT) {
08024          if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) {
08025             goto done;
08026          }
08027       } else {
08028          if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
08029             goto done;
08030          }
08031       }
08032    } else {
08033       if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
08034          goto done;
08035       }
08036    }
08037 
08038    /* get bitlen and round up to next multiple of FP_LUT */
08039    bitlen  = mp_unsigned_bin_size(modulus) << 3;
08040    x       = bitlen % FP_LUT;
08041    if (x) {
08042       bitlen += FP_LUT - x;
08043    }
08044    lut_gap = bitlen / FP_LUT;
08045 
08046    /* get the k value */
08047    if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) ||
08048        (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2))  ) {
08049       err = BUFFER_E; goto done;
08050    }
08051 
08052    /* store k */
08053 #ifdef WOLFSSL_SMALL_STACK
08054    kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08055    if (kb[0] == NULL) {
08056       err = MEMORY_E; goto done;
08057    }
08058 #endif
08059 
08060    XMEMSET(kb[0], 0, KB_SIZE);
08061    if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) {
08062       goto done;
08063    }
08064 
08065    /* let's reverse kb so it's little endian */
08066    x = 0;
08067    y = mp_unsigned_bin_size(&tka);
08068    if (y > 0) {
08069        y -= 1;
08070    }
08071    mp_clear(&tka);
08072    while ((unsigned)x < y) {
08073       z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
08074       ++x; --y;
08075    }
08076 
08077    /* store b */
08078 #ifdef WOLFSSL_SMALL_STACK
08079    kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08080    if (kb[1] == NULL) {
08081       err = MEMORY_E; goto done;
08082    }
08083 #endif
08084 
08085    XMEMSET(kb[1], 0, KB_SIZE);
08086    if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) {
08087       x = 0;
08088       y = mp_unsigned_bin_size(&tkb);
08089       if (y > 0) {
08090           y -= 1;
08091       }
08092 
08093       while ((unsigned)x < y) {
08094          z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
08095          ++x; --y;
08096       }
08097 
08098       /* at this point we can start, yipee */
08099       first = 1;
08100       for (x = lut_gap-1; x >= 0; x--) {
08101           /* extract FP_LUT bits from kb spread out by lut_gap bits and
08102              offset by x bits from the start */
08103           bitpos = x;
08104           for (y = zA = zB = 0; y < FP_LUT; y++) {
08105              zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;
08106              zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;
08107              bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
08108                                       the mult in each loop */
08109           }
08110 
08111           /* double if not first */
08112           if (!first) {
08113              if ((err = ecc_projective_dbl_point(R, R, a, modulus,
08114                                                               mp)) != MP_OKAY) {
08115                 break;
08116              }
08117           }
08118 
08119           /* add if not first, otherwise copy */
08120           if (!first) {
08121              if (zA) {
08122                 if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],
08123                                                   R, a, modulus, mp)) != MP_OKAY) {
08124                    break;
08125                 }
08126              }
08127              if (zB) {
08128                 if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
08129                                                   R, a, modulus, mp)) != MP_OKAY) {
08130                    break;
08131                 }
08132              }
08133           } else {
08134              if (zA) {
08135                  if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
08136                     (mp_copy(fp_cache[idx1].LUT[zA]->y,  R->y) != MP_OKAY) ||
08137                     (mp_copy(&fp_cache[idx1].mu,         R->z) != MP_OKAY)) {
08138                      err = GEN_MEM_ERR;
08139                      break;
08140                  }
08141                     first = 0;
08142              }
08143              if (zB && first == 0) {
08144                 if (zB) {
08145                    if ((err = ecc_projective_add_point(R,
08146                            fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){
08147                       break;
08148                    }
08149                 }
08150              } else if (zB && first == 1) {
08151                  if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
08152                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
08153                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
08154                      err = GEN_MEM_ERR;
08155                      break;
08156                  }
08157                     first = 0;
08158              }
08159           }
08160       }
08161    }
08162 
08163 done:
08164    /* cleanup */
08165    mp_clear(&tkb);
08166    mp_clear(&tka);
08167    mp_clear(&order);
08168 
08169 #ifdef WOLFSSL_SMALL_STACK
08170    if (kb[0])
08171 #endif
08172       ForceZero(kb[0], KB_SIZE);
08173 #ifdef WOLFSSL_SMALL_STACK
08174    if (kb[1])
08175 #endif
08176       ForceZero(kb[1], KB_SIZE);
08177 
08178 #ifdef WOLFSSL_SMALL_STACK
08179    XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
08180    XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
08181 #endif
08182 
08183 #undef KB_SIZE
08184 
08185     if (err != MP_OKAY)
08186         return err;
08187 
08188    return ecc_map(R, modulus, mp);
08189 }
08190 
08191 
08192 /** ECC Fixed Point mulmod global with heap hint used
08193   Computes kA*A + kB*B = C using Shamir's Trick
08194   A        First point to multiply
08195   kA       What to multiple A by
08196   B        Second point to multiply
08197   kB       What to multiple B by
08198   C        [out] Destination point (can overlap with A or B)
08199   a        ECC curve parameter a
08200   modulus  Modulus for curve
08201   return MP_OKAY on success
08202 */
08203 int ecc_mul2add(ecc_point* A, mp_int* kA,
08204                 ecc_point* B, mp_int* kB,
08205                 ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
08206 {
08207    int  idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0;
08208    mp_digit mp;
08209    mp_int   mu;
08210 
08211    err = mp_init(&mu);
08212    if (err != MP_OKAY)
08213        return err;
08214 
08215 #ifndef HAVE_THREAD_LS
08216    if (initMutex == 0) {
08217         wc_InitMutex(&ecc_fp_lock);
08218         initMutex = 1;
08219    }
08220    if (wc_LockMutex(&ecc_fp_lock) != 0)
08221       return BAD_MUTEX_E;
08222 #endif /* HAVE_THREAD_LS */
08223 
08224       /* find point */
08225       idx1 = find_base(A);
08226 
08227       /* no entry? */
08228       if (idx1 == -1) {
08229          /* find hole and add it */
08230          if ((idx1 = find_hole()) >= 0) {
08231             err = add_entry(idx1, A);
08232          }
08233       }
08234       if (err == MP_OKAY && idx1 != -1) {
08235          /* increment LRU */
08236          ++(fp_cache[idx1].lru_count);
08237       }
08238 
08239       if (err == MP_OKAY)
08240         /* find point */
08241         idx2 = find_base(B);
08242 
08243       if (err == MP_OKAY) {
08244         /* no entry? */
08245         if (idx2 == -1) {
08246            /* find hole and add it */
08247            if ((idx2 = find_hole()) >= 0)
08248               err = add_entry(idx2, B);
08249          }
08250       }
08251 
08252       if (err == MP_OKAY && idx2 != -1) {
08253          /* increment LRU */
08254          ++(fp_cache[idx2].lru_count);
08255       }
08256 
08257       if (err == MP_OKAY) {
08258         /* if it's 2 build the LUT, if it's higher just use the LUT */
08259         if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {
08260            /* compute mp */
08261            err = mp_montgomery_setup(modulus, &mp);
08262 
08263            if (err == MP_OKAY) {
08264              mpInit = 1;
08265              err = mp_montgomery_calc_normalization(&mu, modulus);
08266            }
08267 
08268            if (err == MP_OKAY)
08269              /* build the LUT */
08270                err = build_lut(idx1, a, modulus, mp, &mu);
08271         }
08272       }
08273 
08274       if (err == MP_OKAY) {
08275         /* if it's 2 build the LUT, if it's higher just use the LUT */
08276         if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {
08277            if (mpInit == 0) {
08278                 /* compute mp */
08279                 err = mp_montgomery_setup(modulus, &mp);
08280                 if (err == MP_OKAY) {
08281                     mpInit = 1;
08282                     err = mp_montgomery_calc_normalization(&mu, modulus);
08283                 }
08284             }
08285 
08286             if (err == MP_OKAY)
08287             /* build the LUT */
08288               err = build_lut(idx2, a, modulus, mp, &mu);
08289         }
08290       }
08291 
08292 
08293       if (err == MP_OKAY) {
08294         if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 &&
08295                                      fp_cache[idx2].lru_count >= 2) {
08296            if (mpInit == 0) {
08297               /* compute mp */
08298               err = mp_montgomery_setup(modulus, &mp);
08299            }
08300            if (err == MP_OKAY)
08301              err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
08302         } else {
08303            err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
08304         }
08305     }
08306 
08307 #ifndef HAVE_THREAD_LS
08308     wc_UnLockMutex(&ecc_fp_lock);
08309 #endif /* HAVE_THREAD_LS */
08310     mp_clear(&mu);
08311 
08312     return err;
08313 }
08314 #endif
08315 #endif /* ECC_SHAMIR */
08316 
08317 /** ECC Fixed Point mulmod global
08318     k        The multiplicand
08319     G        Base point to multiply
08320     R        [out] Destination of product
08321     a        ECC curve parameter a
08322     modulus  The modulus for the curve
08323     map      [boolean] If non-zero maps the point back to affine co-ordinates,
08324              otherwise it's left in jacobian-montgomery form
08325     return MP_OKAY if successful
08326 */
08327 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
08328     mp_int* modulus, int map, void* heap)
08329 {
08330 #ifndef WOLFSSL_SP_MATH
08331    int   idx, err = MP_OKAY;
08332    mp_digit mp;
08333    mp_int   mu;
08334    int      mpSetup = 0;
08335 
08336    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
08337        return ECC_BAD_ARG_E;
08338    }
08339 
08340    if (mp_init(&mu) != MP_OKAY)
08341        return MP_INIT_E;
08342 
08343 #ifndef HAVE_THREAD_LS
08344    if (initMutex == 0) {
08345         wc_InitMutex(&ecc_fp_lock);
08346         initMutex = 1;
08347    }
08348 
08349    if (wc_LockMutex(&ecc_fp_lock) != 0)
08350       return BAD_MUTEX_E;
08351 #endif /* HAVE_THREAD_LS */
08352 
08353       /* find point */
08354       idx = find_base(G);
08355 
08356       /* no entry? */
08357       if (idx == -1) {
08358          /* find hole and add it */
08359          idx = find_hole();
08360 
08361          if (idx >= 0)
08362             err = add_entry(idx, G);
08363       }
08364       if (err == MP_OKAY && idx >= 0) {
08365          /* increment LRU */
08366          ++(fp_cache[idx].lru_count);
08367       }
08368 
08369 
08370       if (err == MP_OKAY) {
08371         /* if it's 2 build the LUT, if it's higher just use the LUT */
08372         if (idx >= 0 && fp_cache[idx].lru_count == 2) {
08373            /* compute mp */
08374            err = mp_montgomery_setup(modulus, &mp);
08375 
08376            if (err == MP_OKAY) {
08377              /* compute mu */
08378              mpSetup = 1;
08379              err = mp_montgomery_calc_normalization(&mu, modulus);
08380            }
08381 
08382            if (err == MP_OKAY)
08383              /* build the LUT */
08384              err = build_lut(idx, a, modulus, mp, &mu);
08385         }
08386       }
08387 
08388       if (err == MP_OKAY) {
08389         if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
08390            if (mpSetup == 0) {
08391               /* compute mp */
08392               err = mp_montgomery_setup(modulus, &mp);
08393            }
08394            if (err == MP_OKAY)
08395              err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
08396         } else {
08397            err = normal_ecc_mulmod(k, G, R, a, modulus, map, heap);
08398         }
08399      }
08400 
08401 #ifndef HAVE_THREAD_LS
08402     wc_UnLockMutex(&ecc_fp_lock);
08403 #endif /* HAVE_THREAD_LS */
08404     mp_clear(&mu);
08405 
08406     return err;
08407 #else
08408     if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
08409         return ECC_BAD_ARG_E;
08410     }
08411 
08412     return sp_ecc_mulmod_256(k, G, R, map, heap);
08413 #endif
08414 }
08415 
08416 #ifndef WOLFSSL_SP_MATH
08417 /* helper function for freeing the cache ...
08418    must be called with the cache mutex locked */
08419 static void wc_ecc_fp_free_cache(void)
08420 {
08421    unsigned x, y;
08422    for (x = 0; x < FP_ENTRIES; x++) {
08423       if (fp_cache[x].g != NULL) {
08424          for (y = 0; y < (1U<<FP_LUT); y++) {
08425             wc_ecc_del_point(fp_cache[x].LUT[y]);
08426             fp_cache[x].LUT[y] = NULL;
08427          }
08428          wc_ecc_del_point(fp_cache[x].g);
08429          fp_cache[x].g         = NULL;
08430          mp_clear(&fp_cache[x].mu);
08431          fp_cache[x].lru_count = 0;
08432          fp_cache[x].lock = 0;
08433       }
08434    }
08435 }
08436 #endif
08437 
08438 /** Free the Fixed Point cache */
08439 void wc_ecc_fp_free(void)
08440 {
08441 #ifndef WOLFSSL_SP_MATH
08442 #ifndef HAVE_THREAD_LS
08443    if (initMutex == 0) {
08444         wc_InitMutex(&ecc_fp_lock);
08445         initMutex = 1;
08446    }
08447 
08448    if (wc_LockMutex(&ecc_fp_lock) == 0) {
08449 #endif /* HAVE_THREAD_LS */
08450 
08451        wc_ecc_fp_free_cache();
08452 
08453 #ifndef HAVE_THREAD_LS
08454        wc_UnLockMutex(&ecc_fp_lock);
08455        wc_FreeMutex(&ecc_fp_lock);
08456        initMutex = 0;
08457    }
08458 #endif /* HAVE_THREAD_LS */
08459 #endif
08460 }
08461 
08462 
08463 #endif /* FP_ECC */
08464 
08465 #ifdef HAVE_ECC_ENCRYPT
08466 
08467 
08468 enum ecCliState {
08469     ecCLI_INIT      = 1,
08470     ecCLI_SALT_GET  = 2,
08471     ecCLI_SALT_SET  = 3,
08472     ecCLI_SENT_REQ  = 4,
08473     ecCLI_RECV_RESP = 5,
08474     ecCLI_BAD_STATE = 99
08475 };
08476 
08477 enum ecSrvState {
08478     ecSRV_INIT      = 1,
08479     ecSRV_SALT_GET  = 2,
08480     ecSRV_SALT_SET  = 3,
08481     ecSRV_RECV_REQ  = 4,
08482     ecSRV_SENT_RESP = 5,
08483     ecSRV_BAD_STATE = 99
08484 };
08485 
08486 
08487 struct ecEncCtx {
08488     const byte* kdfSalt;   /* optional salt for kdf */
08489     const byte* kdfInfo;   /* optional info for kdf */
08490     const byte* macSalt;   /* optional salt for mac */
08491     word32    kdfSaltSz;   /* size of kdfSalt */
08492     word32    kdfInfoSz;   /* size of kdfInfo */
08493     word32    macSaltSz;   /* size of macSalt */
08494     void*     heap;        /* heap hint for memory used */
08495     byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
08496     byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
08497     byte      encAlgo;     /* which encryption type */
08498     byte      kdfAlgo;     /* which key derivation function type */
08499     byte      macAlgo;     /* which mac function type */
08500     byte      protocol;    /* are we REQ_RESP client or server ? */
08501     byte      cliSt;       /* protocol state, for sanity checks */
08502     byte      srvSt;       /* protocol state, for sanity checks */
08503 };
08504 
08505 
08506 const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
08507 {
08508     if (ctx == NULL || ctx->protocol == 0)
08509         return NULL;
08510 
08511     if (ctx->protocol == REQ_RESP_CLIENT) {
08512         if (ctx->cliSt == ecCLI_INIT) {
08513             ctx->cliSt =  ecCLI_SALT_GET;
08514             return ctx->clientSalt;
08515         }
08516         else {
08517             ctx->cliSt = ecCLI_BAD_STATE;
08518             return NULL;
08519         }
08520     }
08521     else if (ctx->protocol == REQ_RESP_SERVER) {
08522         if (ctx->srvSt == ecSRV_INIT) {
08523             ctx->srvSt =  ecSRV_SALT_GET;
08524             return ctx->serverSalt;
08525         }
08526         else {
08527             ctx->srvSt = ecSRV_BAD_STATE;
08528             return NULL;
08529         }
08530     }
08531 
08532     return NULL;
08533 }
08534 
08535 
08536 /* optional set info, can be called before or after set_peer_salt */
08537 int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
08538 {
08539     if (ctx == NULL || info == 0 || sz < 0)
08540         return BAD_FUNC_ARG;
08541 
08542     ctx->kdfInfo   = info;
08543     ctx->kdfInfoSz = sz;
08544 
08545     return 0;
08546 }
08547 
08548 
08549 static const char* exchange_info = "Secure Message Exchange";
08550 
08551 int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
08552 {
08553     byte tmp[EXCHANGE_SALT_SZ/2];
08554     int  halfSz = EXCHANGE_SALT_SZ/2;
08555 
08556     if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
08557         return BAD_FUNC_ARG;
08558 
08559     if (ctx->protocol == REQ_RESP_CLIENT) {
08560         XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
08561         if (ctx->cliSt == ecCLI_SALT_GET)
08562             ctx->cliSt =  ecCLI_SALT_SET;
08563         else {
08564             ctx->cliSt =  ecCLI_BAD_STATE;
08565             return BAD_STATE_E;
08566         }
08567     }
08568     else {
08569         XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
08570         if (ctx->srvSt == ecSRV_SALT_GET)
08571             ctx->srvSt =  ecSRV_SALT_SET;
08572         else {
08573             ctx->srvSt =  ecSRV_BAD_STATE;
08574             return BAD_STATE_E;
08575         }
08576     }
08577 
08578     /* mix half and half */
08579     /* tmp stores 2nd half of client before overwrite */
08580     XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz);
08581     XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz);
08582     XMEMCPY(ctx->serverSalt, tmp, halfSz);
08583 
08584     ctx->kdfSalt   = ctx->clientSalt;
08585     ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
08586 
08587     ctx->macSalt   = ctx->serverSalt;
08588     ctx->macSaltSz = EXCHANGE_SALT_SZ;
08589 
08590     if (ctx->kdfInfo == NULL) {
08591         /* default info */
08592         ctx->kdfInfo   = (const byte*)exchange_info;
08593         ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
08594     }
08595 
08596     return 0;
08597 }
08598 
08599 
08600 static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng)
08601 {
08602     byte* saltBuffer = NULL;
08603 
08604     if (ctx == NULL || rng == NULL || flags == 0)
08605         return BAD_FUNC_ARG;
08606 
08607     saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
08608 
08609     return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ);
08610 }
08611 
08612 
08613 static void ecc_ctx_init(ecEncCtx* ctx, int flags)
08614 {
08615     if (ctx) {
08616         XMEMSET(ctx, 0, sizeof(ecEncCtx));
08617 
08618         ctx->encAlgo  = ecAES_128_CBC;
08619         ctx->kdfAlgo  = ecHKDF_SHA256;
08620         ctx->macAlgo  = ecHMAC_SHA256;
08621         ctx->protocol = (byte)flags;
08622 
08623         if (flags == REQ_RESP_CLIENT)
08624             ctx->cliSt = ecCLI_INIT;
08625         if (flags == REQ_RESP_SERVER)
08626             ctx->srvSt = ecSRV_INIT;
08627     }
08628 }
08629 
08630 
08631 /* allow ecc context reset so user doesn't have to init/free for reuse */
08632 int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
08633 {
08634     if (ctx == NULL || rng == NULL)
08635         return BAD_FUNC_ARG;
08636 
08637     ecc_ctx_init(ctx, ctx->protocol);
08638     return ecc_ctx_set_salt(ctx, ctx->protocol, rng);
08639 }
08640 
08641 
08642 ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
08643 {
08644     int       ret = 0;
08645     ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
08646                                                               DYNAMIC_TYPE_ECC);
08647 
08648     if (ctx) {
08649         ctx->protocol = (byte)flags;
08650         ctx->heap     = heap;
08651     }
08652 
08653     ret = wc_ecc_ctx_reset(ctx, rng);
08654     if (ret != 0) {
08655         wc_ecc_ctx_free(ctx);
08656         ctx = NULL;
08657     }
08658 
08659     return ctx;
08660 }
08661 
08662 
08663 /* alloc/init and set defaults, return new Context  */
08664 ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
08665 {
08666     return wc_ecc_ctx_new_ex(flags, rng, NULL);
08667 }
08668 
08669 
08670 /* free any resources, clear any keys */
08671 void wc_ecc_ctx_free(ecEncCtx* ctx)
08672 {
08673     if (ctx) {
08674         ForceZero(ctx, sizeof(ecEncCtx));
08675         XFREE(ctx, ctx->heap, DYNAMIC_TYPE_ECC);
08676     }
08677 }
08678 
08679 
08680 static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
08681                              int* keysLen, word32* digestSz, word32* blockSz)
08682 {
08683     if (ctx) {
08684         switch (ctx->encAlgo) {
08685             case ecAES_128_CBC:
08686                 *encKeySz = KEY_SIZE_128;
08687                 *ivSz     = IV_SIZE_128;
08688                 *blockSz  = AES_BLOCK_SIZE;
08689                 break;
08690             default:
08691                 return BAD_FUNC_ARG;
08692         }
08693 
08694         switch (ctx->macAlgo) {
08695             case ecHMAC_SHA256:
08696                 *digestSz = WC_SHA256_DIGEST_SIZE;
08697                 break;
08698             default:
08699                 return BAD_FUNC_ARG;
08700         }
08701     } else
08702         return BAD_FUNC_ARG;
08703 
08704     *keysLen  = *encKeySz + *ivSz + *digestSz;
08705 
08706     return 0;
08707 }
08708 
08709 
08710 /* ecc encrypt with shared secret run through kdf
08711    ctx holds non default algos and inputs
08712    msgSz should be the right size for encAlgo, i.e., already padded
08713    return 0 on success */
08714 int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
08715                 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
08716 {
08717     int          ret = 0;
08718     word32       blockSz;
08719     word32       digestSz;
08720     ecEncCtx     localCtx;
08721 #ifdef WOLFSSL_SMALL_STACK
08722     byte*        sharedSecret;
08723     byte*        keys;
08724 #else
08725     byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
08726     byte         keys[ECC_BUFSIZE];         /* max size */
08727 #endif
08728     word32       sharedSz = ECC_MAXSIZE;
08729     int          keysLen;
08730     int          encKeySz;
08731     int          ivSz;
08732     int          offset = 0;         /* keys offset if doing msg exchange */
08733     byte*        encKey;
08734     byte*        encIv;
08735     byte*        macKey;
08736 
08737     if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
08738                            outSz  == NULL)
08739         return BAD_FUNC_ARG;
08740 
08741     if (ctx == NULL) {  /* use defaults */
08742         ecc_ctx_init(&localCtx, 0);
08743         ctx = &localCtx;
08744     }
08745 
08746     ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
08747                             &blockSz);
08748     if (ret != 0)
08749         return ret;
08750 
08751     if (ctx->protocol == REQ_RESP_SERVER) {
08752         offset = keysLen;
08753         keysLen *= 2;
08754 
08755         if (ctx->srvSt != ecSRV_RECV_REQ)
08756             return BAD_STATE_E;
08757 
08758         ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
08759     }
08760     else if (ctx->protocol == REQ_RESP_CLIENT) {
08761         if (ctx->cliSt != ecCLI_SALT_SET)
08762             return BAD_STATE_E;
08763 
08764         ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
08765     }
08766 
08767     if (keysLen > ECC_BUFSIZE) /* keys size */
08768         return BUFFER_E;
08769 
08770     if ( (msgSz%blockSz) != 0)
08771         return BAD_PADDING_E;
08772 
08773     if (*outSz < (msgSz + digestSz))
08774         return BUFFER_E;
08775 
08776 #ifdef WOLFSSL_SMALL_STACK
08777     sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08778     if (sharedSecret == NULL)
08779         return MEMORY_E;
08780 
08781     keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08782     if (keys == NULL) {
08783         XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08784         return MEMORY_E;
08785     }
08786 #endif
08787 
08788     do {
08789     #if defined(WOLFSSL_ASYNC_CRYPT)
08790         ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
08791         if (ret != 0)
08792             break;
08793     #endif
08794         ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
08795     } while (ret == WC_PENDING_E);
08796     if (ret == 0) {
08797        switch (ctx->kdfAlgo) {
08798            case ecHKDF_SHA256 :
08799                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
08800                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
08801                           keys, keysLen);
08802                break;
08803 
08804            default:
08805                ret = BAD_FUNC_ARG;
08806                break;
08807        }
08808     }
08809 
08810     if (ret == 0) {
08811        encKey = keys + offset;
08812        encIv  = encKey + encKeySz;
08813        macKey = encKey + encKeySz + ivSz;
08814 
08815        switch (ctx->encAlgo) {
08816            case ecAES_128_CBC:
08817                {
08818                    Aes aes;
08819                    ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
08820                                                                 AES_ENCRYPTION);
08821                    if (ret != 0)
08822                        break;
08823                    ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz);
08824                 #if defined(WOLFSSL_ASYNC_CRYPT)
08825                    ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE);
08826                 #endif
08827                }
08828                break;
08829 
08830            default:
08831                ret = BAD_FUNC_ARG;
08832                break;
08833        }
08834     }
08835 
08836     if (ret == 0) {
08837        switch (ctx->macAlgo) {
08838            case ecHMAC_SHA256:
08839                {
08840                    Hmac hmac;
08841                    ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
08842                    if (ret == 0) {
08843                        ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
08844                        if (ret == 0)
08845                            ret = wc_HmacUpdate(&hmac, out, msgSz);
08846                        if (ret == 0)
08847                            ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
08848                        if (ret == 0)
08849                            ret = wc_HmacFinal(&hmac, out+msgSz);
08850                        wc_HmacFree(&hmac);
08851                    }
08852                }
08853                break;
08854 
08855            default:
08856                ret = BAD_FUNC_ARG;
08857                break;
08858        }
08859     }
08860 
08861     if (ret == 0)
08862        *outSz = msgSz + digestSz;
08863 
08864 #ifdef WOLFSSL_SMALL_STACK
08865     XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08866     XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08867 #endif
08868 
08869     return ret;
08870 }
08871 
08872 
08873 /* ecc decrypt with shared secret run through kdf
08874    ctx holds non default algos and inputs
08875    return 0 on success */
08876 int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
08877                 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
08878 {
08879     int          ret = 0;
08880     word32       blockSz;
08881     word32       digestSz;
08882     ecEncCtx     localCtx;
08883 #ifdef WOLFSSL_SMALL_STACK
08884     byte*        sharedSecret;
08885     byte*        keys;
08886 #else
08887     byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
08888     byte         keys[ECC_BUFSIZE];         /* max size */
08889 #endif
08890     word32       sharedSz = ECC_MAXSIZE;
08891     int          keysLen;
08892     int          encKeySz;
08893     int          ivSz;
08894     int          offset = 0;       /* in case using msg exchange */
08895     byte*        encKey;
08896     byte*        encIv;
08897     byte*        macKey;
08898 
08899     if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
08900                            outSz  == NULL)
08901         return BAD_FUNC_ARG;
08902 
08903     if (ctx == NULL) {  /* use defaults */
08904         ecc_ctx_init(&localCtx, 0);
08905         ctx = &localCtx;
08906     }
08907 
08908     ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
08909                             &blockSz);
08910     if (ret != 0)
08911         return ret;
08912 
08913     if (ctx->protocol == REQ_RESP_CLIENT) {
08914         offset = keysLen;
08915         keysLen *= 2;
08916 
08917         if (ctx->cliSt != ecCLI_SENT_REQ)
08918             return BAD_STATE_E;
08919 
08920         ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
08921     }
08922     else if (ctx->protocol == REQ_RESP_SERVER) {
08923         if (ctx->srvSt != ecSRV_SALT_SET)
08924             return BAD_STATE_E;
08925 
08926         ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
08927     }
08928 
08929     if (keysLen > ECC_BUFSIZE) /* keys size */
08930         return BUFFER_E;
08931 
08932     if ( ((msgSz-digestSz) % blockSz) != 0)
08933         return BAD_PADDING_E;
08934 
08935     if (*outSz < (msgSz - digestSz))
08936         return BUFFER_E;
08937 
08938 #ifdef WOLFSSL_SMALL_STACK
08939     sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08940     if (sharedSecret == NULL)
08941         return MEMORY_E;
08942 
08943     keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08944     if (keys == NULL) {
08945         XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
08946         return MEMORY_E;
08947     }
08948 #endif
08949 
08950     do {
08951     #if defined(WOLFSSL_ASYNC_CRYPT)
08952         ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
08953         if (ret != 0)
08954             break;
08955     #endif
08956         ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
08957     } while (ret == WC_PENDING_E);
08958     if (ret == 0) {
08959        switch (ctx->kdfAlgo) {
08960            case ecHKDF_SHA256 :
08961                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
08962                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
08963                           keys, keysLen);
08964                break;
08965 
08966            default:
08967                ret = BAD_FUNC_ARG;
08968                break;
08969        }
08970     }
08971 
08972     if (ret == 0) {
08973        encKey = keys + offset;
08974        encIv  = encKey + encKeySz;
08975        macKey = encKey + encKeySz + ivSz;
08976 
08977        switch (ctx->macAlgo) {
08978            case ecHMAC_SHA256:
08979            {
08980                byte verify[WC_SHA256_DIGEST_SIZE];
08981                Hmac hmac;
08982 
08983                ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
08984                if (ret == 0) {
08985                    ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
08986                    if (ret == 0)
08987                        ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz);
08988                    if (ret == 0)
08989                        ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
08990                    if (ret == 0)
08991                        ret = wc_HmacFinal(&hmac, verify);
08992                    if (ret == 0) {
08993                       if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0)
08994                           ret = -1;
08995                    }
08996 
08997                    wc_HmacFree(&hmac);
08998                }
08999                break;
09000            }
09001 
09002            default:
09003                ret = BAD_FUNC_ARG;
09004                break;
09005        }
09006     }
09007 
09008     if (ret == 0) {
09009        switch (ctx->encAlgo) {
09010     #ifdef HAVE_AES_CBC
09011            case ecAES_128_CBC:
09012                {
09013                    Aes aes;
09014                    ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
09015                                                                 AES_DECRYPTION);
09016                    if (ret != 0)
09017                        break;
09018                    ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz);
09019                 #if defined(WOLFSSL_ASYNC_CRYPT)
09020                    ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE);
09021                 #endif
09022                }
09023                break;
09024     #endif
09025            default:
09026                ret = BAD_FUNC_ARG;
09027                break;
09028        }
09029     }
09030 
09031     if (ret == 0)
09032        *outSz = msgSz - digestSz;
09033 
09034 #ifdef WOLFSSL_SMALL_STACK
09035     XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
09036     XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER);
09037 #endif
09038 
09039     return ret;
09040 }
09041 
09042 
09043 #endif /* HAVE_ECC_ENCRYPT */
09044 
09045 
09046 #ifdef HAVE_COMP_KEY
09047 #ifndef WOLFSSL_ATECC508A
09048 
09049 #ifndef WOLFSSL_SP_MATH
09050 int do_mp_jacobi(mp_int* a, mp_int* n, int* c);
09051 
09052 int do_mp_jacobi(mp_int* a, mp_int* n, int* c)
09053 {
09054   int      k, s, res;
09055   int      r = 0; /* initialize to help static analysis out */
09056   mp_digit residue;
09057 
09058   /* if a < 0 return MP_VAL */
09059   if (mp_isneg(a) == MP_YES) {
09060      return MP_VAL;
09061   }
09062 
09063   /* if n <= 0 return MP_VAL */
09064   if (mp_cmp_d(n, 0) != MP_GT) {
09065      return MP_VAL;
09066   }
09067 
09068   /* step 1. handle case of a == 0 */
09069   if (mp_iszero (a) == MP_YES) {
09070      /* special case of a == 0 and n == 1 */
09071      if (mp_cmp_d (n, 1) == MP_EQ) {
09072        *c = 1;
09073      } else {
09074        *c = 0;
09075      }
09076      return MP_OKAY;
09077   }
09078 
09079   /* step 2.  if a == 1, return 1 */
09080   if (mp_cmp_d (a, 1) == MP_EQ) {
09081     *c = 1;
09082     return MP_OKAY;
09083   }
09084 
09085   /* default */
09086   s = 0;
09087 
09088   /* divide out larger power of two */
09089   k = mp_cnt_lsb(a);
09090   res = mp_div_2d(a, k, a, NULL);
09091 
09092   if (res == MP_OKAY) {
09093     /* step 4.  if e is even set s=1 */
09094     if ((k & 1) == 0) {
09095       s = 1;
09096     } else {
09097       /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
09098       residue = n->dp[0] & 7;
09099 
09100       if (residue == 1 || residue == 7) {
09101         s = 1;
09102       } else if (residue == 3 || residue == 5) {
09103         s = -1;
09104       }
09105     }
09106 
09107     /* step 5.  if p == 3 (mod 4) *and* a == 3 (mod 4) then s = -s */
09108     if ( ((n->dp[0] & 3) == 3) && ((a->dp[0] & 3) == 3)) {
09109       s = -s;
09110     }
09111   }
09112 
09113   if (res == MP_OKAY) {
09114     /* if a == 1 we're done */
09115     if (mp_cmp_d(a, 1) == MP_EQ) {
09116       *c = s;
09117     } else {
09118       /* n1 = n mod a */
09119       res = mp_mod (n, a, n);
09120       if (res == MP_OKAY)
09121         res = do_mp_jacobi(n, a, &r);
09122 
09123       if (res == MP_OKAY)
09124         *c = s * r;
09125     }
09126   }
09127 
09128   return res;
09129 }
09130 
09131 
09132 /* computes the jacobi c = (a | n) (or Legendre if n is prime)
09133  * HAC pp. 73 Algorithm 2.149
09134  * HAC is wrong here, as the special case of (0 | 1) is not
09135  * handled correctly.
09136  */
09137 int mp_jacobi(mp_int* a, mp_int* n, int* c)
09138 {
09139     mp_int   a1, n1;
09140     int      res;
09141 
09142     /* step 3.  write a = a1 * 2**k  */
09143     if ((res = mp_init_multi(&a1, &n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
09144         return res;
09145     }
09146 
09147     if ((res = mp_copy(a, &a1)) != MP_OKAY) {
09148         goto done;
09149     }
09150 
09151     if ((res = mp_copy(n, &n1)) != MP_OKAY) {
09152         goto done;
09153     }
09154 
09155     res = do_mp_jacobi(&a1, &n1, c);
09156 
09157 done:
09158   /* cleanup */
09159   mp_clear(&n1);
09160   mp_clear(&a1);
09161 
09162   return res;
09163 }
09164 
09165 
09166 /* Solves the modular equation x^2 = n (mod p)
09167  * where prime number is greater than 2 (odd prime).
09168  * The result is returned in the third argument x
09169  * the function returns MP_OKAY on success, MP_VAL or another error on failure
09170  */
09171 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
09172 {
09173 #ifdef SQRTMOD_USE_MOD_EXP
09174   int res;
09175 
09176   mp_int e;
09177 
09178   res = mp_init(&e);
09179   if (res == MP_OKAY)
09180       res = mp_add_d(prime, 1, &e);
09181   if (res == MP_OKAY)
09182       res = mp_div_2d(&e, 2, &e, NULL);
09183   if (res == MP_OKAY)
09184       res = mp_exptmod(n, &e, prime, ret);
09185 
09186   mp_clear(&e);
09187 
09188   return res;
09189 #else
09190   int res, legendre, done = 0;
09191   mp_int t1, C, Q, S, Z, M, T, R, two;
09192   mp_digit i;
09193 
09194   /* first handle the simple cases n = 0 or n = 1 */
09195   if (mp_cmp_d(n, 0) == MP_EQ) {
09196     mp_zero(ret);
09197     return MP_OKAY;
09198   }
09199   if (mp_cmp_d(n, 1) == MP_EQ) {
09200     return mp_set(ret, 1);
09201   }
09202 
09203   /* prime must be odd */
09204   if (mp_cmp_d(prime, 2) == MP_EQ) {
09205     return MP_VAL;
09206   }
09207 
09208   /* is quadratic non-residue mod prime */
09209   if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) {
09210     return res;
09211   }
09212   if (legendre == -1) {
09213     return MP_VAL;
09214   }
09215 
09216   if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY)
09217     return res;
09218 
09219   if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL))
09220                           != MP_OKAY) {
09221     mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z);
09222     mp_clear(&M);
09223     return res;
09224   }
09225 
09226   /* SPECIAL CASE: if prime mod 4 == 3
09227    * compute directly: res = n^(prime+1)/4 mod prime
09228    * Handbook of Applied Cryptography algorithm 3.36
09229    */
09230   res = mp_mod_d(prime, 4, &i);
09231   if (res == MP_OKAY && i == 3) {
09232     res = mp_add_d(prime, 1, &t1);
09233 
09234     if (res == MP_OKAY)
09235       res = mp_div_2(&t1, &t1);
09236     if (res == MP_OKAY)
09237       res = mp_div_2(&t1, &t1);
09238     if (res == MP_OKAY)
09239       res = mp_exptmod(n, &t1, prime, ret);
09240 
09241     done = 1;
09242   }
09243 
09244   /* NOW: TonelliShanks algorithm */
09245   if (res == MP_OKAY && done == 0) {
09246 
09247     /* factor out powers of 2 from prime-1, defining Q and S
09248     *                                      as: prime-1 = Q*2^S */
09249     /* Q = prime - 1 */
09250     res = mp_copy(prime, &Q);
09251     if (res == MP_OKAY)
09252       res = mp_sub_d(&Q, 1, &Q);
09253 
09254     /* S = 0 */
09255     if (res == MP_OKAY)
09256       mp_zero(&S);
09257 
09258     while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) {
09259       /* Q = Q / 2 */
09260       res = mp_div_2(&Q, &Q);
09261 
09262       /* S = S + 1 */
09263       if (res == MP_OKAY)
09264         res = mp_add_d(&S, 1, &S);
09265     }
09266 
09267     /* find a Z such that the Legendre symbol (Z|prime) == -1 */
09268     /* Z = 2 */
09269     if (res == MP_OKAY)
09270       res = mp_set_int(&Z, 2);
09271 
09272     while (res == MP_OKAY) {
09273       res = mp_jacobi(&Z, prime, &legendre);
09274       if (res == MP_OKAY && legendre == -1)
09275         break;
09276 
09277       /* Z = Z + 1 */
09278       if (res == MP_OKAY)
09279         res = mp_add_d(&Z, 1, &Z);
09280     }
09281 
09282     /* C = Z ^ Q mod prime */
09283     if (res == MP_OKAY)
09284       res = mp_exptmod(&Z, &Q, prime, &C);
09285 
09286     /* t1 = (Q + 1) / 2 */
09287     if (res == MP_OKAY)
09288       res = mp_add_d(&Q, 1, &t1);
09289     if (res == MP_OKAY)
09290       res = mp_div_2(&t1, &t1);
09291 
09292     /* R = n ^ ((Q + 1) / 2) mod prime */
09293     if (res == MP_OKAY)
09294       res = mp_exptmod(n, &t1, prime, &R);
09295 
09296     /* T = n ^ Q mod prime */
09297     if (res == MP_OKAY)
09298       res = mp_exptmod(n, &Q, prime, &T);
09299 
09300     /* M = S */
09301     if (res == MP_OKAY)
09302       res = mp_copy(&S, &M);
09303 
09304     if (res == MP_OKAY)
09305       res = mp_set_int(&two, 2);
09306 
09307     while (res == MP_OKAY && done == 0) {
09308       res = mp_copy(&T, &t1);
09309 
09310       /* reduce to 1 and count */
09311       i = 0;
09312       while (res == MP_OKAY) {
09313         if (mp_cmp_d(&t1, 1) == MP_EQ)
09314             break;
09315         res = mp_exptmod(&t1, &two, prime, &t1);
09316         if (res == MP_OKAY)
09317           i++;
09318       }
09319       if (res == MP_OKAY && i == 0) {
09320         res = mp_copy(&R, ret);
09321         done = 1;
09322       }
09323 
09324       if (done == 0) {
09325         /* t1 = 2 ^ (M - i - 1) */
09326         if (res == MP_OKAY)
09327           res = mp_sub_d(&M, i, &t1);
09328         if (res == MP_OKAY)
09329           res = mp_sub_d(&t1, 1, &t1);
09330         if (res == MP_OKAY)
09331           res = mp_exptmod(&two, &t1, prime, &t1);
09332 
09333         /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
09334         if (res == MP_OKAY)
09335           res = mp_exptmod(&C, &t1, prime, &t1);
09336 
09337         /* C = (t1 * t1) mod prime */
09338         if (res == MP_OKAY)
09339           res = mp_sqrmod(&t1, prime, &C);
09340 
09341         /* R = (R * t1) mod prime */
09342         if (res == MP_OKAY)
09343           res = mp_mulmod(&R, &t1, prime, &R);
09344 
09345         /* T = (T * C) mod prime */
09346         if (res == MP_OKAY)
09347           res = mp_mulmod(&T, &C, prime, &T);
09348 
09349         /* M = i */
09350         if (res == MP_OKAY)
09351           res = mp_set(&M, i);
09352       }
09353     }
09354   }
09355 
09356   /* done */
09357   mp_clear(&t1);
09358   mp_clear(&C);
09359   mp_clear(&Q);
09360   mp_clear(&S);
09361   mp_clear(&Z);
09362   mp_clear(&M);
09363   mp_clear(&T);
09364   mp_clear(&R);
09365   mp_clear(&two);
09366 
09367   return res;
09368 #endif
09369 }
09370 #endif
09371 #endif /* !WOLFSSL_ATECC508A */
09372 
09373 
09374 /* export public ECC key in ANSI X9.63 format compressed */
09375 static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
09376 {
09377    word32 numlen;
09378    int    ret = MP_OKAY;
09379 
09380    if (key == NULL || out == NULL || outLen == NULL)
09381        return BAD_FUNC_ARG;
09382 
09383    if (wc_ecc_is_valid_idx(key->idx) == 0) {
09384       return ECC_BAD_ARG_E;
09385    }
09386    numlen = key->dp->size;
09387 
09388    if (*outLen < (1 + numlen)) {
09389       *outLen = 1 + numlen;
09390       return BUFFER_E;
09391    }
09392 
09393 #ifdef WOLFSSL_ATECC508A
09394    /* TODO: Implement equiv call to ATECC508A */
09395    ret = BAD_COND_E;
09396 
09397 #else
09398 
09399    /* store first byte */
09400    out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
09401 
09402    /* pad and store x */
09403    XMEMSET(out+1, 0, numlen);
09404    ret = mp_to_unsigned_bin(key->pubkey.x,
09405                        out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
09406    *outLen = 1 + numlen;
09407 
09408 #endif /* WOLFSSL_ATECC508A */
09409 
09410    return ret;
09411 }
09412 
09413 #endif /* HAVE_COMP_KEY */
09414 
09415 
09416 int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
09417 {
09418     int x;
09419 
09420     if (oidSum == 0) {
09421         return BAD_FUNC_ARG;
09422     }
09423 
09424     /* find matching OID sum (based on encoded value) */
09425     for (x = 0; ecc_sets[x].size != 0; x++) {
09426         if (ecc_sets[x].oidSum == oidSum) {
09427             int ret = 0;
09428         #ifdef HAVE_OID_ENCODING
09429             /* check cache */
09430             oid_cache_t* o = &ecc_oid_cache[x];
09431             if (o->oidSz == 0) {
09432                 o->oidSz = sizeof(o->oid);
09433                 ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
09434                                                             o->oid, &o->oidSz);
09435             }
09436             if (oidSz) {
09437                 *oidSz = o->oidSz;
09438             }
09439             if (oid) {
09440                 *oid = o->oid;
09441             }
09442         #else
09443             if (oidSz) {
09444                 *oidSz = ecc_sets[x].oidSz;
09445             }
09446             if (oid) {
09447                 *oid = ecc_sets[x].oid;
09448             }
09449         #endif
09450             /* on success return curve id */
09451             if (ret == 0) {
09452                 ret = ecc_sets[x].id;
09453             }
09454             return ret;
09455         }
09456     }
09457 
09458     return NOT_COMPILED_IN;
09459 }
09460 
09461 #ifdef WOLFSSL_CUSTOM_CURVES
09462 int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
09463 {
09464     if (key == NULL || dp == NULL) {
09465         return BAD_FUNC_ARG;
09466     }
09467 
09468     key->idx = ECC_CUSTOM_IDX;
09469     key->dp = dp;
09470 
09471     return 0;
09472 }
09473 #endif /* WOLFSSL_CUSTOM_CURVES */
09474 
09475 #ifdef HAVE_X963_KDF
09476 
09477 static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
09478 {
09479     int i;
09480 
09481     /* in network byte order so start at end and work back */
09482     for (i = 3; i >= 0; i--) {
09483         if (++inOutCtr[i])  /* we're done unless we overflow */
09484             return;
09485     }
09486 }
09487 
09488 /* ASN X9.63 Key Derivation Function (SEC1) */
09489 int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
09490                 const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
09491 {
09492     int ret, i;
09493     int digestSz, copySz;
09494     int remaining = outSz;
09495     byte* outIdx;
09496     byte  counter[4];
09497     byte  tmp[WC_MAX_DIGEST_SIZE];
09498 
09499 #ifdef WOLFSSL_SMALL_STACK
09500     wc_HashAlg* hash;
09501 #else
09502     wc_HashAlg hash[1];
09503 #endif
09504 
09505     if (secret == NULL || secretSz == 0 || out == NULL)
09506         return BAD_FUNC_ARG;
09507 
09508     /* X9.63 allowed algos only */
09509     if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
09510         type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
09511         type != WC_HASH_TYPE_SHA512)
09512         return BAD_FUNC_ARG;
09513 
09514     digestSz = wc_HashGetDigestSize(type);
09515     if (digestSz < 0)
09516         return digestSz;
09517 
09518 #ifdef WOLFSSL_SMALL_STACK
09519     hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
09520                                 DYNAMIC_TYPE_HASHES);
09521     if (hash == NULL)
09522         return MEMORY_E;
09523 #endif
09524 
09525     ret = wc_HashInit(hash, type);
09526     if (ret != 0) {
09527 #ifdef WOLFSSL_SMALL_STACK
09528         XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
09529 #endif
09530         return ret;
09531     }
09532 
09533     outIdx = out;
09534     XMEMSET(counter, 0, sizeof(counter));
09535 
09536     for (i = 1; remaining > 0; i++) {
09537 
09538         IncrementX963KdfCounter(counter);
09539 
09540         ret = wc_HashUpdate(hash, type, secret, secretSz);
09541         if (ret != 0) {
09542 #ifdef WOLFSSL_SMALL_STACK
09543             XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
09544 #endif
09545             return ret;
09546         }
09547 
09548         ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
09549         if (ret != 0) {
09550 #ifdef WOLFSSL_SMALL_STACK
09551             XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
09552 #endif
09553             return ret;
09554         }
09555 
09556         if (sinfo) {
09557             ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
09558             if (ret != 0) {
09559 #ifdef WOLFSSL_SMALL_STACK
09560                 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
09561 #endif
09562                 return ret;
09563             }
09564         }
09565 
09566         ret = wc_HashFinal(hash, type, tmp);
09567         if (ret != 0) {
09568 #ifdef WOLFSSL_SMALL_STACK
09569             XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
09570 #endif
09571             return ret;
09572         }
09573 
09574         copySz = min(remaining, digestSz);
09575         XMEMCPY(outIdx, tmp, copySz);
09576 
09577         remaining -= copySz;
09578         outIdx += copySz;
09579     }
09580 
09581 #ifdef WOLFSSL_SMALL_STACK
09582      XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
09583 #endif
09584 
09585     return 0;
09586 }
09587 #endif /* HAVE_X963_KDF */
09588 
09589 #endif /* HAVE_ECC */
09590