Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
wolfcrypt/src/ecc.c@0:d92f9d21154c, 2015-06-26 (annotated)
- Committer:
- wolfSSL
- Date:
- Fri Jun 26 00:39:20 2015 +0000
- Revision:
- 0:d92f9d21154c
- Child:
- 3:6f956bdb3073
wolfSSL 3.6.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wolfSSL | 0:d92f9d21154c | 1 | /* ecc.c |
wolfSSL | 0:d92f9d21154c | 2 | * |
wolfSSL | 0:d92f9d21154c | 3 | * Copyright (C) 2006-2015 wolfSSL Inc. |
wolfSSL | 0:d92f9d21154c | 4 | * |
wolfSSL | 0:d92f9d21154c | 5 | * This file is part of wolfSSL. (formerly known as CyaSSL) |
wolfSSL | 0:d92f9d21154c | 6 | * |
wolfSSL | 0:d92f9d21154c | 7 | * wolfSSL is free software; you can redistribute it and/or modify |
wolfSSL | 0:d92f9d21154c | 8 | * it under the terms of the GNU General Public License as published by |
wolfSSL | 0:d92f9d21154c | 9 | * the Free Software Foundation; either version 2 of the License, or |
wolfSSL | 0:d92f9d21154c | 10 | * (at your option) any later version. |
wolfSSL | 0:d92f9d21154c | 11 | * |
wolfSSL | 0:d92f9d21154c | 12 | * wolfSSL is distributed in the hope that it will be useful, |
wolfSSL | 0:d92f9d21154c | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
wolfSSL | 0:d92f9d21154c | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
wolfSSL | 0:d92f9d21154c | 15 | * GNU General Public License for more details. |
wolfSSL | 0:d92f9d21154c | 16 | * |
wolfSSL | 0:d92f9d21154c | 17 | * You should have received a copy of the GNU General Public License |
wolfSSL | 0:d92f9d21154c | 18 | * along with this program; if not, write to the Free Software |
wolfSSL | 0:d92f9d21154c | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
wolfSSL | 0:d92f9d21154c | 20 | */ |
wolfSSL | 0:d92f9d21154c | 21 | |
wolfSSL | 0:d92f9d21154c | 22 | |
wolfSSL | 0:d92f9d21154c | 23 | #ifdef HAVE_CONFIG_H |
wolfSSL | 0:d92f9d21154c | 24 | #include <config.h> |
wolfSSL | 0:d92f9d21154c | 25 | #endif |
wolfSSL | 0:d92f9d21154c | 26 | |
wolfSSL | 0:d92f9d21154c | 27 | /* in case user set HAVE_ECC there */ |
wolfSSL | 0:d92f9d21154c | 28 | #include <wolfssl/wolfcrypt/settings.h> |
wolfSSL | 0:d92f9d21154c | 29 | |
wolfSSL | 0:d92f9d21154c | 30 | #ifdef HAVE_ECC |
wolfSSL | 0:d92f9d21154c | 31 | |
wolfSSL | 0:d92f9d21154c | 32 | #include <wolfssl/wolfcrypt/ecc.h> |
wolfSSL | 0:d92f9d21154c | 33 | #include <wolfssl/wolfcrypt/asn.h> |
wolfSSL | 0:d92f9d21154c | 34 | #include <wolfssl/wolfcrypt/error-crypt.h> |
wolfSSL | 0:d92f9d21154c | 35 | |
wolfSSL | 0:d92f9d21154c | 36 | #ifdef HAVE_ECC_ENCRYPT |
wolfSSL | 0:d92f9d21154c | 37 | #include <wolfssl/wolfcrypt/hmac.h> |
wolfSSL | 0:d92f9d21154c | 38 | #include <wolfssl/wolfcrypt/aes.h> |
wolfSSL | 0:d92f9d21154c | 39 | #endif |
wolfSSL | 0:d92f9d21154c | 40 | |
wolfSSL | 0:d92f9d21154c | 41 | #ifdef NO_INLINE |
wolfSSL | 0:d92f9d21154c | 42 | #include <wolfssl/wolfcrypt/misc.h> |
wolfSSL | 0:d92f9d21154c | 43 | #else |
wolfSSL | 0:d92f9d21154c | 44 | #include <wolfcrypt/src/misc.c> |
wolfSSL | 0:d92f9d21154c | 45 | #endif |
wolfSSL | 0:d92f9d21154c | 46 | |
wolfSSL | 0:d92f9d21154c | 47 | /* map |
wolfSSL | 0:d92f9d21154c | 48 | |
wolfSSL | 0:d92f9d21154c | 49 | ptmul -> mulmod |
wolfSSL | 0:d92f9d21154c | 50 | |
wolfSSL | 0:d92f9d21154c | 51 | */ |
wolfSSL | 0:d92f9d21154c | 52 | |
wolfSSL | 0:d92f9d21154c | 53 | |
wolfSSL | 0:d92f9d21154c | 54 | /* p256 curve on by default whether user curves or not */ |
wolfSSL | 0:d92f9d21154c | 55 | #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES) |
wolfSSL | 0:d92f9d21154c | 56 | #define ECC112 |
wolfSSL | 0:d92f9d21154c | 57 | #endif |
wolfSSL | 0:d92f9d21154c | 58 | #if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES) |
wolfSSL | 0:d92f9d21154c | 59 | #define ECC128 |
wolfSSL | 0:d92f9d21154c | 60 | #endif |
wolfSSL | 0:d92f9d21154c | 61 | #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) |
wolfSSL | 0:d92f9d21154c | 62 | #define ECC160 |
wolfSSL | 0:d92f9d21154c | 63 | #endif |
wolfSSL | 0:d92f9d21154c | 64 | #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) |
wolfSSL | 0:d92f9d21154c | 65 | #define ECC192 |
wolfSSL | 0:d92f9d21154c | 66 | #endif |
wolfSSL | 0:d92f9d21154c | 67 | #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) |
wolfSSL | 0:d92f9d21154c | 68 | #define ECC224 |
wolfSSL | 0:d92f9d21154c | 69 | #endif |
wolfSSL | 0:d92f9d21154c | 70 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 0:d92f9d21154c | 71 | #define ECC256 |
wolfSSL | 0:d92f9d21154c | 72 | #endif |
wolfSSL | 0:d92f9d21154c | 73 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 0:d92f9d21154c | 74 | #define ECC384 |
wolfSSL | 0:d92f9d21154c | 75 | #endif |
wolfSSL | 0:d92f9d21154c | 76 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 0:d92f9d21154c | 77 | #define ECC521 |
wolfSSL | 0:d92f9d21154c | 78 | #endif |
wolfSSL | 0:d92f9d21154c | 79 | |
wolfSSL | 0:d92f9d21154c | 80 | |
wolfSSL | 0:d92f9d21154c | 81 | |
wolfSSL | 0:d92f9d21154c | 82 | /* This holds the key settings. ***MUST*** be organized by size from |
wolfSSL | 0:d92f9d21154c | 83 | smallest to largest. */ |
wolfSSL | 0:d92f9d21154c | 84 | |
wolfSSL | 0:d92f9d21154c | 85 | const ecc_set_type ecc_sets[] = { |
wolfSSL | 0:d92f9d21154c | 86 | #ifdef ECC112 |
wolfSSL | 0:d92f9d21154c | 87 | { |
wolfSSL | 0:d92f9d21154c | 88 | 14, |
wolfSSL | 0:d92f9d21154c | 89 | "SECP112R1", |
wolfSSL | 0:d92f9d21154c | 90 | "DB7C2ABF62E35E668076BEAD208B", |
wolfSSL | 0:d92f9d21154c | 91 | "DB7C2ABF62E35E668076BEAD2088", |
wolfSSL | 0:d92f9d21154c | 92 | "659EF8BA043916EEDE8911702B22", |
wolfSSL | 0:d92f9d21154c | 93 | "DB7C2ABF62E35E7628DFAC6561C5", |
wolfSSL | 0:d92f9d21154c | 94 | "09487239995A5EE76B55F9C2F098", |
wolfSSL | 0:d92f9d21154c | 95 | "A89CE5AF8724C0A23E0E0FF77500" |
wolfSSL | 0:d92f9d21154c | 96 | }, |
wolfSSL | 0:d92f9d21154c | 97 | #endif |
wolfSSL | 0:d92f9d21154c | 98 | #ifdef ECC128 |
wolfSSL | 0:d92f9d21154c | 99 | { |
wolfSSL | 0:d92f9d21154c | 100 | 16, |
wolfSSL | 0:d92f9d21154c | 101 | "SECP128R1", |
wolfSSL | 0:d92f9d21154c | 102 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", |
wolfSSL | 0:d92f9d21154c | 103 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", |
wolfSSL | 0:d92f9d21154c | 104 | "E87579C11079F43DD824993C2CEE5ED3", |
wolfSSL | 0:d92f9d21154c | 105 | "FFFFFFFE0000000075A30D1B9038A115", |
wolfSSL | 0:d92f9d21154c | 106 | "161FF7528B899B2D0C28607CA52C5B86", |
wolfSSL | 0:d92f9d21154c | 107 | "CF5AC8395BAFEB13C02DA292DDED7A83", |
wolfSSL | 0:d92f9d21154c | 108 | }, |
wolfSSL | 0:d92f9d21154c | 109 | #endif |
wolfSSL | 0:d92f9d21154c | 110 | #ifdef ECC160 |
wolfSSL | 0:d92f9d21154c | 111 | { |
wolfSSL | 0:d92f9d21154c | 112 | 20, |
wolfSSL | 0:d92f9d21154c | 113 | "SECP160R1", |
wolfSSL | 0:d92f9d21154c | 114 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", |
wolfSSL | 0:d92f9d21154c | 115 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", |
wolfSSL | 0:d92f9d21154c | 116 | "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", |
wolfSSL | 0:d92f9d21154c | 117 | "0100000000000000000001F4C8F927AED3CA752257", |
wolfSSL | 0:d92f9d21154c | 118 | "4A96B5688EF573284664698968C38BB913CBFC82", |
wolfSSL | 0:d92f9d21154c | 119 | "23A628553168947D59DCC912042351377AC5FB32", |
wolfSSL | 0:d92f9d21154c | 120 | }, |
wolfSSL | 0:d92f9d21154c | 121 | #endif |
wolfSSL | 0:d92f9d21154c | 122 | #ifdef ECC192 |
wolfSSL | 0:d92f9d21154c | 123 | { |
wolfSSL | 0:d92f9d21154c | 124 | 24, |
wolfSSL | 0:d92f9d21154c | 125 | "ECC-192", |
wolfSSL | 0:d92f9d21154c | 126 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", |
wolfSSL | 0:d92f9d21154c | 127 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", |
wolfSSL | 0:d92f9d21154c | 128 | "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", |
wolfSSL | 0:d92f9d21154c | 129 | "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", |
wolfSSL | 0:d92f9d21154c | 130 | "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", |
wolfSSL | 0:d92f9d21154c | 131 | "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", |
wolfSSL | 0:d92f9d21154c | 132 | }, |
wolfSSL | 0:d92f9d21154c | 133 | #endif |
wolfSSL | 0:d92f9d21154c | 134 | #ifdef ECC224 |
wolfSSL | 0:d92f9d21154c | 135 | { |
wolfSSL | 0:d92f9d21154c | 136 | 28, |
wolfSSL | 0:d92f9d21154c | 137 | "ECC-224", |
wolfSSL | 0:d92f9d21154c | 138 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", |
wolfSSL | 0:d92f9d21154c | 139 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", |
wolfSSL | 0:d92f9d21154c | 140 | "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", |
wolfSSL | 0:d92f9d21154c | 141 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", |
wolfSSL | 0:d92f9d21154c | 142 | "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", |
wolfSSL | 0:d92f9d21154c | 143 | "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", |
wolfSSL | 0:d92f9d21154c | 144 | }, |
wolfSSL | 0:d92f9d21154c | 145 | #endif |
wolfSSL | 0:d92f9d21154c | 146 | #ifdef ECC256 |
wolfSSL | 0:d92f9d21154c | 147 | { |
wolfSSL | 0:d92f9d21154c | 148 | 32, |
wolfSSL | 0:d92f9d21154c | 149 | "ECC-256", |
wolfSSL | 0:d92f9d21154c | 150 | "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", |
wolfSSL | 0:d92f9d21154c | 151 | "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", |
wolfSSL | 0:d92f9d21154c | 152 | "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", |
wolfSSL | 0:d92f9d21154c | 153 | "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", |
wolfSSL | 0:d92f9d21154c | 154 | "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", |
wolfSSL | 0:d92f9d21154c | 155 | "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", |
wolfSSL | 0:d92f9d21154c | 156 | }, |
wolfSSL | 0:d92f9d21154c | 157 | #endif |
wolfSSL | 0:d92f9d21154c | 158 | #ifdef ECC384 |
wolfSSL | 0:d92f9d21154c | 159 | { |
wolfSSL | 0:d92f9d21154c | 160 | 48, |
wolfSSL | 0:d92f9d21154c | 161 | "ECC-384", |
wolfSSL | 0:d92f9d21154c | 162 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", |
wolfSSL | 0:d92f9d21154c | 163 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", |
wolfSSL | 0:d92f9d21154c | 164 | "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", |
wolfSSL | 0:d92f9d21154c | 165 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", |
wolfSSL | 0:d92f9d21154c | 166 | "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", |
wolfSSL | 0:d92f9d21154c | 167 | "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", |
wolfSSL | 0:d92f9d21154c | 168 | }, |
wolfSSL | 0:d92f9d21154c | 169 | #endif |
wolfSSL | 0:d92f9d21154c | 170 | #ifdef ECC521 |
wolfSSL | 0:d92f9d21154c | 171 | { |
wolfSSL | 0:d92f9d21154c | 172 | 66, |
wolfSSL | 0:d92f9d21154c | 173 | "ECC-521", |
wolfSSL | 0:d92f9d21154c | 174 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", |
wolfSSL | 0:d92f9d21154c | 175 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", |
wolfSSL | 0:d92f9d21154c | 176 | "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", |
wolfSSL | 0:d92f9d21154c | 177 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", |
wolfSSL | 0:d92f9d21154c | 178 | "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", |
wolfSSL | 0:d92f9d21154c | 179 | "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", |
wolfSSL | 0:d92f9d21154c | 180 | }, |
wolfSSL | 0:d92f9d21154c | 181 | #endif |
wolfSSL | 0:d92f9d21154c | 182 | { |
wolfSSL | 0:d92f9d21154c | 183 | 0, |
wolfSSL | 0:d92f9d21154c | 184 | NULL, NULL, NULL, NULL, NULL, NULL, NULL |
wolfSSL | 0:d92f9d21154c | 185 | } |
wolfSSL | 0:d92f9d21154c | 186 | }; |
wolfSSL | 0:d92f9d21154c | 187 | |
wolfSSL | 0:d92f9d21154c | 188 | |
wolfSSL | 0:d92f9d21154c | 189 | ecc_point* ecc_new_point(void); |
wolfSSL | 0:d92f9d21154c | 190 | void ecc_del_point(ecc_point* p); |
wolfSSL | 0:d92f9d21154c | 191 | int ecc_map(ecc_point*, mp_int*, mp_digit*); |
wolfSSL | 0:d92f9d21154c | 192 | int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, |
wolfSSL | 0:d92f9d21154c | 193 | mp_int* modulus, mp_digit* mp); |
wolfSSL | 0:d92f9d21154c | 194 | int ecc_projective_dbl_point(ecc_point* P, ecc_point* R, mp_int* modulus, |
wolfSSL | 0:d92f9d21154c | 195 | mp_digit* mp); |
wolfSSL | 0:d92f9d21154c | 196 | static int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, |
wolfSSL | 0:d92f9d21154c | 197 | int map); |
wolfSSL | 0:d92f9d21154c | 198 | static int ecc_check_pubkey_order(ecc_key* key, mp_int* prime, mp_int* order); |
wolfSSL | 0:d92f9d21154c | 199 | #ifdef ECC_SHAMIR |
wolfSSL | 0:d92f9d21154c | 200 | static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB, |
wolfSSL | 0:d92f9d21154c | 201 | ecc_point* C, mp_int* modulus); |
wolfSSL | 0:d92f9d21154c | 202 | #endif |
wolfSSL | 0:d92f9d21154c | 203 | |
wolfSSL | 0:d92f9d21154c | 204 | int mp_jacobi(mp_int* a, mp_int* p, int* c); |
wolfSSL | 0:d92f9d21154c | 205 | int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret); |
wolfSSL | 0:d92f9d21154c | 206 | int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d); |
wolfSSL | 0:d92f9d21154c | 207 | |
wolfSSL | 0:d92f9d21154c | 208 | #ifdef HAVE_COMP_KEY |
wolfSSL | 0:d92f9d21154c | 209 | static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); |
wolfSSL | 0:d92f9d21154c | 210 | #endif |
wolfSSL | 0:d92f9d21154c | 211 | |
wolfSSL | 0:d92f9d21154c | 212 | /* helper for either lib */ |
wolfSSL | 0:d92f9d21154c | 213 | static int get_digit_count(mp_int* a) |
wolfSSL | 0:d92f9d21154c | 214 | { |
wolfSSL | 0:d92f9d21154c | 215 | if (a == NULL) |
wolfSSL | 0:d92f9d21154c | 216 | return 0; |
wolfSSL | 0:d92f9d21154c | 217 | |
wolfSSL | 0:d92f9d21154c | 218 | return a->used; |
wolfSSL | 0:d92f9d21154c | 219 | } |
wolfSSL | 0:d92f9d21154c | 220 | |
wolfSSL | 0:d92f9d21154c | 221 | /* helper for either lib */ |
wolfSSL | 0:d92f9d21154c | 222 | static mp_digit get_digit(mp_int* a, int n) |
wolfSSL | 0:d92f9d21154c | 223 | { |
wolfSSL | 0:d92f9d21154c | 224 | if (a == NULL) |
wolfSSL | 0:d92f9d21154c | 225 | return 0; |
wolfSSL | 0:d92f9d21154c | 226 | |
wolfSSL | 0:d92f9d21154c | 227 | return (n >= a->used || n < 0) ? 0 : a->dp[n]; |
wolfSSL | 0:d92f9d21154c | 228 | } |
wolfSSL | 0:d92f9d21154c | 229 | |
wolfSSL | 0:d92f9d21154c | 230 | |
wolfSSL | 0:d92f9d21154c | 231 | #if defined(USE_FAST_MATH) |
wolfSSL | 0:d92f9d21154c | 232 | |
wolfSSL | 0:d92f9d21154c | 233 | /* fast math accelerated version, but not for fp ecc yet */ |
wolfSSL | 0:d92f9d21154c | 234 | |
wolfSSL | 0:d92f9d21154c | 235 | /** |
wolfSSL | 0:d92f9d21154c | 236 | Add two ECC points |
wolfSSL | 0:d92f9d21154c | 237 | P The point to add |
wolfSSL | 0:d92f9d21154c | 238 | Q The point to add |
wolfSSL | 0:d92f9d21154c | 239 | R [out] The destination of the double |
wolfSSL | 0:d92f9d21154c | 240 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 0:d92f9d21154c | 241 | mp The "b" value from montgomery_setup() |
wolfSSL | 0:d92f9d21154c | 242 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 243 | */ |
wolfSSL | 0:d92f9d21154c | 244 | int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, |
wolfSSL | 0:d92f9d21154c | 245 | mp_int* modulus, mp_digit* mp) |
wolfSSL | 0:d92f9d21154c | 246 | { |
wolfSSL | 0:d92f9d21154c | 247 | fp_int t1, t2, x, y, z; |
wolfSSL | 0:d92f9d21154c | 248 | int err; |
wolfSSL | 0:d92f9d21154c | 249 | |
wolfSSL | 0:d92f9d21154c | 250 | if (P == NULL || Q == NULL || R == NULL || modulus == NULL || mp == NULL) |
wolfSSL | 0:d92f9d21154c | 251 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 252 | |
wolfSSL | 0:d92f9d21154c | 253 | if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 254 | return err; |
wolfSSL | 0:d92f9d21154c | 255 | } |
wolfSSL | 0:d92f9d21154c | 256 | |
wolfSSL | 0:d92f9d21154c | 257 | /* should we dbl instead? */ |
wolfSSL | 0:d92f9d21154c | 258 | fp_sub(modulus, Q->y, &t1); |
wolfSSL | 0:d92f9d21154c | 259 | if ( (fp_cmp(P->x, Q->x) == FP_EQ) && |
wolfSSL | 0:d92f9d21154c | 260 | (get_digit_count(Q->z) && fp_cmp(P->z, Q->z) == FP_EQ) && |
wolfSSL | 0:d92f9d21154c | 261 | (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) { |
wolfSSL | 0:d92f9d21154c | 262 | return ecc_projective_dbl_point(P, R, modulus, mp); |
wolfSSL | 0:d92f9d21154c | 263 | } |
wolfSSL | 0:d92f9d21154c | 264 | |
wolfSSL | 0:d92f9d21154c | 265 | fp_copy(P->x, &x); |
wolfSSL | 0:d92f9d21154c | 266 | fp_copy(P->y, &y); |
wolfSSL | 0:d92f9d21154c | 267 | fp_copy(P->z, &z); |
wolfSSL | 0:d92f9d21154c | 268 | |
wolfSSL | 0:d92f9d21154c | 269 | /* if Z is one then these are no-operations */ |
wolfSSL | 0:d92f9d21154c | 270 | if (get_digit_count(Q->z)) { |
wolfSSL | 0:d92f9d21154c | 271 | /* T1 = Z' * Z' */ |
wolfSSL | 0:d92f9d21154c | 272 | fp_sqr(Q->z, &t1); |
wolfSSL | 0:d92f9d21154c | 273 | fp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 274 | /* X = X * T1 */ |
wolfSSL | 0:d92f9d21154c | 275 | fp_mul(&t1, &x, &x); |
wolfSSL | 0:d92f9d21154c | 276 | fp_montgomery_reduce(&x, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 277 | /* T1 = Z' * T1 */ |
wolfSSL | 0:d92f9d21154c | 278 | fp_mul(Q->z, &t1, &t1); |
wolfSSL | 0:d92f9d21154c | 279 | fp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 280 | /* Y = Y * T1 */ |
wolfSSL | 0:d92f9d21154c | 281 | fp_mul(&t1, &y, &y); |
wolfSSL | 0:d92f9d21154c | 282 | fp_montgomery_reduce(&y, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 283 | } |
wolfSSL | 0:d92f9d21154c | 284 | |
wolfSSL | 0:d92f9d21154c | 285 | /* T1 = Z*Z */ |
wolfSSL | 0:d92f9d21154c | 286 | fp_sqr(&z, &t1); |
wolfSSL | 0:d92f9d21154c | 287 | fp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 288 | /* T2 = X' * T1 */ |
wolfSSL | 0:d92f9d21154c | 289 | fp_mul(Q->x, &t1, &t2); |
wolfSSL | 0:d92f9d21154c | 290 | fp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 291 | /* T1 = Z * T1 */ |
wolfSSL | 0:d92f9d21154c | 292 | fp_mul(&z, &t1, &t1); |
wolfSSL | 0:d92f9d21154c | 293 | fp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 294 | /* T1 = Y' * T1 */ |
wolfSSL | 0:d92f9d21154c | 295 | fp_mul(Q->y, &t1, &t1); |
wolfSSL | 0:d92f9d21154c | 296 | fp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 297 | |
wolfSSL | 0:d92f9d21154c | 298 | /* Y = Y - T1 */ |
wolfSSL | 0:d92f9d21154c | 299 | fp_sub(&y, &t1, &y); |
wolfSSL | 0:d92f9d21154c | 300 | if (fp_cmp_d(&y, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 301 | fp_add(&y, modulus, &y); |
wolfSSL | 0:d92f9d21154c | 302 | } |
wolfSSL | 0:d92f9d21154c | 303 | /* T1 = 2T1 */ |
wolfSSL | 0:d92f9d21154c | 304 | fp_add(&t1, &t1, &t1); |
wolfSSL | 0:d92f9d21154c | 305 | if (fp_cmp(&t1, modulus) != FP_LT) { |
wolfSSL | 0:d92f9d21154c | 306 | fp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 307 | } |
wolfSSL | 0:d92f9d21154c | 308 | /* T1 = Y + T1 */ |
wolfSSL | 0:d92f9d21154c | 309 | fp_add(&t1, &y, &t1); |
wolfSSL | 0:d92f9d21154c | 310 | if (fp_cmp(&t1, modulus) != FP_LT) { |
wolfSSL | 0:d92f9d21154c | 311 | fp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 312 | } |
wolfSSL | 0:d92f9d21154c | 313 | /* X = X - T2 */ |
wolfSSL | 0:d92f9d21154c | 314 | fp_sub(&x, &t2, &x); |
wolfSSL | 0:d92f9d21154c | 315 | if (fp_cmp_d(&x, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 316 | fp_add(&x, modulus, &x); |
wolfSSL | 0:d92f9d21154c | 317 | } |
wolfSSL | 0:d92f9d21154c | 318 | /* T2 = 2T2 */ |
wolfSSL | 0:d92f9d21154c | 319 | fp_add(&t2, &t2, &t2); |
wolfSSL | 0:d92f9d21154c | 320 | if (fp_cmp(&t2, modulus) != FP_LT) { |
wolfSSL | 0:d92f9d21154c | 321 | fp_sub(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 322 | } |
wolfSSL | 0:d92f9d21154c | 323 | /* T2 = X + T2 */ |
wolfSSL | 0:d92f9d21154c | 324 | fp_add(&t2, &x, &t2); |
wolfSSL | 0:d92f9d21154c | 325 | if (fp_cmp(&t2, modulus) != FP_LT) { |
wolfSSL | 0:d92f9d21154c | 326 | fp_sub(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 327 | } |
wolfSSL | 0:d92f9d21154c | 328 | |
wolfSSL | 0:d92f9d21154c | 329 | /* if Z' != 1 */ |
wolfSSL | 0:d92f9d21154c | 330 | if (get_digit_count(Q->z)) { |
wolfSSL | 0:d92f9d21154c | 331 | /* Z = Z * Z' */ |
wolfSSL | 0:d92f9d21154c | 332 | fp_mul(&z, Q->z, &z); |
wolfSSL | 0:d92f9d21154c | 333 | fp_montgomery_reduce(&z, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 334 | } |
wolfSSL | 0:d92f9d21154c | 335 | |
wolfSSL | 0:d92f9d21154c | 336 | /* Z = Z * X */ |
wolfSSL | 0:d92f9d21154c | 337 | fp_mul(&z, &x, &z); |
wolfSSL | 0:d92f9d21154c | 338 | fp_montgomery_reduce(&z, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 339 | |
wolfSSL | 0:d92f9d21154c | 340 | /* T1 = T1 * X */ |
wolfSSL | 0:d92f9d21154c | 341 | fp_mul(&t1, &x, &t1); |
wolfSSL | 0:d92f9d21154c | 342 | fp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 343 | /* X = X * X */ |
wolfSSL | 0:d92f9d21154c | 344 | fp_sqr(&x, &x); |
wolfSSL | 0:d92f9d21154c | 345 | fp_montgomery_reduce(&x, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 346 | /* T2 = T2 * x */ |
wolfSSL | 0:d92f9d21154c | 347 | fp_mul(&t2, &x, &t2); |
wolfSSL | 0:d92f9d21154c | 348 | fp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 349 | /* T1 = T1 * X */ |
wolfSSL | 0:d92f9d21154c | 350 | fp_mul(&t1, &x, &t1); |
wolfSSL | 0:d92f9d21154c | 351 | fp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 352 | |
wolfSSL | 0:d92f9d21154c | 353 | /* X = Y*Y */ |
wolfSSL | 0:d92f9d21154c | 354 | fp_sqr(&y, &x); |
wolfSSL | 0:d92f9d21154c | 355 | fp_montgomery_reduce(&x, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 356 | /* X = X - T2 */ |
wolfSSL | 0:d92f9d21154c | 357 | fp_sub(&x, &t2, &x); |
wolfSSL | 0:d92f9d21154c | 358 | if (fp_cmp_d(&x, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 359 | fp_add(&x, modulus, &x); |
wolfSSL | 0:d92f9d21154c | 360 | } |
wolfSSL | 0:d92f9d21154c | 361 | |
wolfSSL | 0:d92f9d21154c | 362 | /* T2 = T2 - X */ |
wolfSSL | 0:d92f9d21154c | 363 | fp_sub(&t2, &x, &t2); |
wolfSSL | 0:d92f9d21154c | 364 | if (fp_cmp_d(&t2, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 365 | fp_add(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 366 | } |
wolfSSL | 0:d92f9d21154c | 367 | /* T2 = T2 - X */ |
wolfSSL | 0:d92f9d21154c | 368 | fp_sub(&t2, &x, &t2); |
wolfSSL | 0:d92f9d21154c | 369 | if (fp_cmp_d(&t2, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 370 | fp_add(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 371 | } |
wolfSSL | 0:d92f9d21154c | 372 | /* T2 = T2 * Y */ |
wolfSSL | 0:d92f9d21154c | 373 | fp_mul(&t2, &y, &t2); |
wolfSSL | 0:d92f9d21154c | 374 | fp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 375 | /* Y = T2 - T1 */ |
wolfSSL | 0:d92f9d21154c | 376 | fp_sub(&t2, &t1, &y); |
wolfSSL | 0:d92f9d21154c | 377 | if (fp_cmp_d(&y, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 378 | fp_add(&y, modulus, &y); |
wolfSSL | 0:d92f9d21154c | 379 | } |
wolfSSL | 0:d92f9d21154c | 380 | /* Y = Y/2 */ |
wolfSSL | 0:d92f9d21154c | 381 | if (fp_isodd(&y)) { |
wolfSSL | 0:d92f9d21154c | 382 | fp_add(&y, modulus, &y); |
wolfSSL | 0:d92f9d21154c | 383 | } |
wolfSSL | 0:d92f9d21154c | 384 | fp_div_2(&y, &y); |
wolfSSL | 0:d92f9d21154c | 385 | |
wolfSSL | 0:d92f9d21154c | 386 | fp_copy(&x, R->x); |
wolfSSL | 0:d92f9d21154c | 387 | fp_copy(&y, R->y); |
wolfSSL | 0:d92f9d21154c | 388 | fp_copy(&z, R->z); |
wolfSSL | 0:d92f9d21154c | 389 | |
wolfSSL | 0:d92f9d21154c | 390 | return MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 391 | } |
wolfSSL | 0:d92f9d21154c | 392 | |
wolfSSL | 0:d92f9d21154c | 393 | |
wolfSSL | 0:d92f9d21154c | 394 | /** |
wolfSSL | 0:d92f9d21154c | 395 | Double an ECC point |
wolfSSL | 0:d92f9d21154c | 396 | P The point to double |
wolfSSL | 0:d92f9d21154c | 397 | R [out] The destination of the double |
wolfSSL | 0:d92f9d21154c | 398 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 0:d92f9d21154c | 399 | mp The "b" value from montgomery_setup() |
wolfSSL | 0:d92f9d21154c | 400 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 401 | */ |
wolfSSL | 0:d92f9d21154c | 402 | int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* modulus, |
wolfSSL | 0:d92f9d21154c | 403 | mp_digit* mp) |
wolfSSL | 0:d92f9d21154c | 404 | { |
wolfSSL | 0:d92f9d21154c | 405 | fp_int t1, t2; |
wolfSSL | 0:d92f9d21154c | 406 | int err; |
wolfSSL | 0:d92f9d21154c | 407 | |
wolfSSL | 0:d92f9d21154c | 408 | if (P == NULL || R == NULL || modulus == NULL || mp == NULL) |
wolfSSL | 0:d92f9d21154c | 409 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 410 | |
wolfSSL | 0:d92f9d21154c | 411 | if (P != R) { |
wolfSSL | 0:d92f9d21154c | 412 | fp_copy(P->x, R->x); |
wolfSSL | 0:d92f9d21154c | 413 | fp_copy(P->y, R->y); |
wolfSSL | 0:d92f9d21154c | 414 | fp_copy(P->z, R->z); |
wolfSSL | 0:d92f9d21154c | 415 | } |
wolfSSL | 0:d92f9d21154c | 416 | |
wolfSSL | 0:d92f9d21154c | 417 | if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 418 | return err; |
wolfSSL | 0:d92f9d21154c | 419 | } |
wolfSSL | 0:d92f9d21154c | 420 | |
wolfSSL | 0:d92f9d21154c | 421 | /* t1 = Z * Z */ |
wolfSSL | 0:d92f9d21154c | 422 | fp_sqr(R->z, &t1); |
wolfSSL | 0:d92f9d21154c | 423 | fp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 424 | /* Z = Y * Z */ |
wolfSSL | 0:d92f9d21154c | 425 | fp_mul(R->z, R->y, R->z); |
wolfSSL | 0:d92f9d21154c | 426 | fp_montgomery_reduce(R->z, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 427 | /* Z = 2Z */ |
wolfSSL | 0:d92f9d21154c | 428 | fp_add(R->z, R->z, R->z); |
wolfSSL | 0:d92f9d21154c | 429 | if (fp_cmp(R->z, modulus) != FP_LT) { |
wolfSSL | 0:d92f9d21154c | 430 | fp_sub(R->z, modulus, R->z); |
wolfSSL | 0:d92f9d21154c | 431 | } |
wolfSSL | 0:d92f9d21154c | 432 | |
wolfSSL | 0:d92f9d21154c | 433 | /* &t2 = X - T1 */ |
wolfSSL | 0:d92f9d21154c | 434 | fp_sub(R->x, &t1, &t2); |
wolfSSL | 0:d92f9d21154c | 435 | if (fp_cmp_d(&t2, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 436 | fp_add(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 437 | } |
wolfSSL | 0:d92f9d21154c | 438 | /* T1 = X + T1 */ |
wolfSSL | 0:d92f9d21154c | 439 | fp_add(&t1, R->x, &t1); |
wolfSSL | 0:d92f9d21154c | 440 | if (fp_cmp(&t1, modulus) != FP_LT) { |
wolfSSL | 0:d92f9d21154c | 441 | fp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 442 | } |
wolfSSL | 0:d92f9d21154c | 443 | /* T2 = T1 * T2 */ |
wolfSSL | 0:d92f9d21154c | 444 | fp_mul(&t1, &t2, &t2); |
wolfSSL | 0:d92f9d21154c | 445 | fp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 446 | /* T1 = 2T2 */ |
wolfSSL | 0:d92f9d21154c | 447 | fp_add(&t2, &t2, &t1); |
wolfSSL | 0:d92f9d21154c | 448 | if (fp_cmp(&t1, modulus) != FP_LT) { |
wolfSSL | 0:d92f9d21154c | 449 | fp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 450 | } |
wolfSSL | 0:d92f9d21154c | 451 | /* T1 = T1 + T2 */ |
wolfSSL | 0:d92f9d21154c | 452 | fp_add(&t1, &t2, &t1); |
wolfSSL | 0:d92f9d21154c | 453 | if (fp_cmp(&t1, modulus) != FP_LT) { |
wolfSSL | 0:d92f9d21154c | 454 | fp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 455 | } |
wolfSSL | 0:d92f9d21154c | 456 | |
wolfSSL | 0:d92f9d21154c | 457 | /* Y = 2Y */ |
wolfSSL | 0:d92f9d21154c | 458 | fp_add(R->y, R->y, R->y); |
wolfSSL | 0:d92f9d21154c | 459 | if (fp_cmp(R->y, modulus) != FP_LT) { |
wolfSSL | 0:d92f9d21154c | 460 | fp_sub(R->y, modulus, R->y); |
wolfSSL | 0:d92f9d21154c | 461 | } |
wolfSSL | 0:d92f9d21154c | 462 | /* Y = Y * Y */ |
wolfSSL | 0:d92f9d21154c | 463 | fp_sqr(R->y, R->y); |
wolfSSL | 0:d92f9d21154c | 464 | fp_montgomery_reduce(R->y, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 465 | /* T2 = Y * Y */ |
wolfSSL | 0:d92f9d21154c | 466 | fp_sqr(R->y, &t2); |
wolfSSL | 0:d92f9d21154c | 467 | fp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 468 | /* T2 = T2/2 */ |
wolfSSL | 0:d92f9d21154c | 469 | if (fp_isodd(&t2)) { |
wolfSSL | 0:d92f9d21154c | 470 | fp_add(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 471 | } |
wolfSSL | 0:d92f9d21154c | 472 | fp_div_2(&t2, &t2); |
wolfSSL | 0:d92f9d21154c | 473 | /* Y = Y * X */ |
wolfSSL | 0:d92f9d21154c | 474 | fp_mul(R->y, R->x, R->y); |
wolfSSL | 0:d92f9d21154c | 475 | fp_montgomery_reduce(R->y, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 476 | |
wolfSSL | 0:d92f9d21154c | 477 | /* X = T1 * T1 */ |
wolfSSL | 0:d92f9d21154c | 478 | fp_sqr(&t1, R->x); |
wolfSSL | 0:d92f9d21154c | 479 | fp_montgomery_reduce(R->x, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 480 | /* X = X - Y */ |
wolfSSL | 0:d92f9d21154c | 481 | fp_sub(R->x, R->y, R->x); |
wolfSSL | 0:d92f9d21154c | 482 | if (fp_cmp_d(R->x, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 483 | fp_add(R->x, modulus, R->x); |
wolfSSL | 0:d92f9d21154c | 484 | } |
wolfSSL | 0:d92f9d21154c | 485 | /* X = X - Y */ |
wolfSSL | 0:d92f9d21154c | 486 | fp_sub(R->x, R->y, R->x); |
wolfSSL | 0:d92f9d21154c | 487 | if (fp_cmp_d(R->x, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 488 | fp_add(R->x, modulus, R->x); |
wolfSSL | 0:d92f9d21154c | 489 | } |
wolfSSL | 0:d92f9d21154c | 490 | |
wolfSSL | 0:d92f9d21154c | 491 | /* Y = Y - X */ |
wolfSSL | 0:d92f9d21154c | 492 | fp_sub(R->y, R->x, R->y); |
wolfSSL | 0:d92f9d21154c | 493 | if (fp_cmp_d(R->y, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 494 | fp_add(R->y, modulus, R->y); |
wolfSSL | 0:d92f9d21154c | 495 | } |
wolfSSL | 0:d92f9d21154c | 496 | /* Y = Y * T1 */ |
wolfSSL | 0:d92f9d21154c | 497 | fp_mul(R->y, &t1, R->y); |
wolfSSL | 0:d92f9d21154c | 498 | fp_montgomery_reduce(R->y, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 499 | /* Y = Y - T2 */ |
wolfSSL | 0:d92f9d21154c | 500 | fp_sub(R->y, &t2, R->y); |
wolfSSL | 0:d92f9d21154c | 501 | if (fp_cmp_d(R->y, 0) == FP_LT) { |
wolfSSL | 0:d92f9d21154c | 502 | fp_add(R->y, modulus, R->y); |
wolfSSL | 0:d92f9d21154c | 503 | } |
wolfSSL | 0:d92f9d21154c | 504 | |
wolfSSL | 0:d92f9d21154c | 505 | return MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 506 | } |
wolfSSL | 0:d92f9d21154c | 507 | |
wolfSSL | 0:d92f9d21154c | 508 | #else /* USE_FAST_MATH */ |
wolfSSL | 0:d92f9d21154c | 509 | |
wolfSSL | 0:d92f9d21154c | 510 | /** |
wolfSSL | 0:d92f9d21154c | 511 | Add two ECC points |
wolfSSL | 0:d92f9d21154c | 512 | P The point to add |
wolfSSL | 0:d92f9d21154c | 513 | Q The point to add |
wolfSSL | 0:d92f9d21154c | 514 | R [out] The destination of the double |
wolfSSL | 0:d92f9d21154c | 515 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 0:d92f9d21154c | 516 | mp The "b" value from montgomery_setup() |
wolfSSL | 0:d92f9d21154c | 517 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 518 | */ |
wolfSSL | 0:d92f9d21154c | 519 | int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, |
wolfSSL | 0:d92f9d21154c | 520 | mp_int* modulus, mp_digit* mp) |
wolfSSL | 0:d92f9d21154c | 521 | { |
wolfSSL | 0:d92f9d21154c | 522 | mp_int t1; |
wolfSSL | 0:d92f9d21154c | 523 | mp_int t2; |
wolfSSL | 0:d92f9d21154c | 524 | mp_int x; |
wolfSSL | 0:d92f9d21154c | 525 | mp_int y; |
wolfSSL | 0:d92f9d21154c | 526 | mp_int z; |
wolfSSL | 0:d92f9d21154c | 527 | int err; |
wolfSSL | 0:d92f9d21154c | 528 | |
wolfSSL | 0:d92f9d21154c | 529 | if (P == NULL || Q == NULL || R == NULL || modulus == NULL || mp == NULL) |
wolfSSL | 0:d92f9d21154c | 530 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 531 | |
wolfSSL | 0:d92f9d21154c | 532 | if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 533 | return err; |
wolfSSL | 0:d92f9d21154c | 534 | } |
wolfSSL | 0:d92f9d21154c | 535 | |
wolfSSL | 0:d92f9d21154c | 536 | /* should we dbl instead? */ |
wolfSSL | 0:d92f9d21154c | 537 | err = mp_sub(modulus, Q->y, &t1); |
wolfSSL | 0:d92f9d21154c | 538 | |
wolfSSL | 0:d92f9d21154c | 539 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 540 | if ( (mp_cmp(P->x, Q->x) == MP_EQ) && |
wolfSSL | 0:d92f9d21154c | 541 | (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) && |
wolfSSL | 0:d92f9d21154c | 542 | (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, &t1) == MP_EQ)) { |
wolfSSL | 0:d92f9d21154c | 543 | mp_clear(&t1); |
wolfSSL | 0:d92f9d21154c | 544 | mp_clear(&t2); |
wolfSSL | 0:d92f9d21154c | 545 | mp_clear(&x); |
wolfSSL | 0:d92f9d21154c | 546 | mp_clear(&y); |
wolfSSL | 0:d92f9d21154c | 547 | mp_clear(&z); |
wolfSSL | 0:d92f9d21154c | 548 | |
wolfSSL | 0:d92f9d21154c | 549 | return ecc_projective_dbl_point(P, R, modulus, mp); |
wolfSSL | 0:d92f9d21154c | 550 | } |
wolfSSL | 0:d92f9d21154c | 551 | } |
wolfSSL | 0:d92f9d21154c | 552 | |
wolfSSL | 0:d92f9d21154c | 553 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 554 | err = mp_copy(P->x, &x); |
wolfSSL | 0:d92f9d21154c | 555 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 556 | err = mp_copy(P->y, &y); |
wolfSSL | 0:d92f9d21154c | 557 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 558 | err = mp_copy(P->z, &z); |
wolfSSL | 0:d92f9d21154c | 559 | |
wolfSSL | 0:d92f9d21154c | 560 | /* if Z is one then these are no-operations */ |
wolfSSL | 0:d92f9d21154c | 561 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 562 | if (get_digit_count(Q->z)) { |
wolfSSL | 0:d92f9d21154c | 563 | /* T1 = Z' * Z' */ |
wolfSSL | 0:d92f9d21154c | 564 | err = mp_sqr(Q->z, &t1); |
wolfSSL | 0:d92f9d21154c | 565 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 566 | err = mp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 567 | |
wolfSSL | 0:d92f9d21154c | 568 | /* X = X * T1 */ |
wolfSSL | 0:d92f9d21154c | 569 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 570 | err = mp_mul(&t1, &x, &x); |
wolfSSL | 0:d92f9d21154c | 571 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 572 | err = mp_montgomery_reduce(&x, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 573 | |
wolfSSL | 0:d92f9d21154c | 574 | /* T1 = Z' * T1 */ |
wolfSSL | 0:d92f9d21154c | 575 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 576 | err = mp_mul(Q->z, &t1, &t1); |
wolfSSL | 0:d92f9d21154c | 577 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 578 | err = mp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 579 | |
wolfSSL | 0:d92f9d21154c | 580 | /* Y = Y * T1 */ |
wolfSSL | 0:d92f9d21154c | 581 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 582 | err = mp_mul(&t1, &y, &y); |
wolfSSL | 0:d92f9d21154c | 583 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 584 | err = mp_montgomery_reduce(&y, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 585 | } |
wolfSSL | 0:d92f9d21154c | 586 | } |
wolfSSL | 0:d92f9d21154c | 587 | |
wolfSSL | 0:d92f9d21154c | 588 | /* T1 = Z*Z */ |
wolfSSL | 0:d92f9d21154c | 589 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 590 | err = mp_sqr(&z, &t1); |
wolfSSL | 0:d92f9d21154c | 591 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 592 | err = mp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 593 | |
wolfSSL | 0:d92f9d21154c | 594 | /* T2 = X' * T1 */ |
wolfSSL | 0:d92f9d21154c | 595 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 596 | err = mp_mul(Q->x, &t1, &t2); |
wolfSSL | 0:d92f9d21154c | 597 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 598 | err = mp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 599 | |
wolfSSL | 0:d92f9d21154c | 600 | /* T1 = Z * T1 */ |
wolfSSL | 0:d92f9d21154c | 601 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 602 | err = mp_mul(&z, &t1, &t1); |
wolfSSL | 0:d92f9d21154c | 603 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 604 | err = mp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 605 | |
wolfSSL | 0:d92f9d21154c | 606 | /* T1 = Y' * T1 */ |
wolfSSL | 0:d92f9d21154c | 607 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 608 | err = mp_mul(Q->y, &t1, &t1); |
wolfSSL | 0:d92f9d21154c | 609 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 610 | err = mp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 611 | |
wolfSSL | 0:d92f9d21154c | 612 | /* Y = Y - T1 */ |
wolfSSL | 0:d92f9d21154c | 613 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 614 | err = mp_sub(&y, &t1, &y); |
wolfSSL | 0:d92f9d21154c | 615 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 616 | if (mp_cmp_d(&y, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 617 | err = mp_add(&y, modulus, &y); |
wolfSSL | 0:d92f9d21154c | 618 | } |
wolfSSL | 0:d92f9d21154c | 619 | /* T1 = 2T1 */ |
wolfSSL | 0:d92f9d21154c | 620 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 621 | err = mp_add(&t1, &t1, &t1); |
wolfSSL | 0:d92f9d21154c | 622 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 623 | if (mp_cmp(&t1, modulus) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 624 | err = mp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 625 | } |
wolfSSL | 0:d92f9d21154c | 626 | /* T1 = Y + T1 */ |
wolfSSL | 0:d92f9d21154c | 627 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 628 | err = mp_add(&t1, &y, &t1); |
wolfSSL | 0:d92f9d21154c | 629 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 630 | if (mp_cmp(&t1, modulus) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 631 | err = mp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 632 | } |
wolfSSL | 0:d92f9d21154c | 633 | /* X = X - T2 */ |
wolfSSL | 0:d92f9d21154c | 634 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 635 | err = mp_sub(&x, &t2, &x); |
wolfSSL | 0:d92f9d21154c | 636 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 637 | if (mp_cmp_d(&x, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 638 | err = mp_add(&x, modulus, &x); |
wolfSSL | 0:d92f9d21154c | 639 | } |
wolfSSL | 0:d92f9d21154c | 640 | /* T2 = 2T2 */ |
wolfSSL | 0:d92f9d21154c | 641 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 642 | err = mp_add(&t2, &t2, &t2); |
wolfSSL | 0:d92f9d21154c | 643 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 644 | if (mp_cmp(&t2, modulus) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 645 | err = mp_sub(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 646 | } |
wolfSSL | 0:d92f9d21154c | 647 | /* T2 = X + T2 */ |
wolfSSL | 0:d92f9d21154c | 648 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 649 | err = mp_add(&t2, &x, &t2); |
wolfSSL | 0:d92f9d21154c | 650 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 651 | if (mp_cmp(&t2, modulus) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 652 | err = mp_sub(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 653 | } |
wolfSSL | 0:d92f9d21154c | 654 | |
wolfSSL | 0:d92f9d21154c | 655 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 656 | if (get_digit_count(Q->z)) { |
wolfSSL | 0:d92f9d21154c | 657 | /* Z = Z * Z' */ |
wolfSSL | 0:d92f9d21154c | 658 | err = mp_mul(&z, Q->z, &z); |
wolfSSL | 0:d92f9d21154c | 659 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 660 | err = mp_montgomery_reduce(&z, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 661 | } |
wolfSSL | 0:d92f9d21154c | 662 | } |
wolfSSL | 0:d92f9d21154c | 663 | |
wolfSSL | 0:d92f9d21154c | 664 | /* Z = Z * X */ |
wolfSSL | 0:d92f9d21154c | 665 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 666 | err = mp_mul(&z, &x, &z); |
wolfSSL | 0:d92f9d21154c | 667 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 668 | err = mp_montgomery_reduce(&z, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 669 | |
wolfSSL | 0:d92f9d21154c | 670 | /* T1 = T1 * X */ |
wolfSSL | 0:d92f9d21154c | 671 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 672 | err = mp_mul(&t1, &x, &t1); |
wolfSSL | 0:d92f9d21154c | 673 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 674 | err = mp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 675 | |
wolfSSL | 0:d92f9d21154c | 676 | /* X = X * X */ |
wolfSSL | 0:d92f9d21154c | 677 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 678 | err = mp_sqr(&x, &x); |
wolfSSL | 0:d92f9d21154c | 679 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 680 | err = mp_montgomery_reduce(&x, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 681 | |
wolfSSL | 0:d92f9d21154c | 682 | /* T2 = T2 * x */ |
wolfSSL | 0:d92f9d21154c | 683 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 684 | err = mp_mul(&t2, &x, &t2); |
wolfSSL | 0:d92f9d21154c | 685 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 686 | err = mp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 687 | |
wolfSSL | 0:d92f9d21154c | 688 | /* T1 = T1 * X */ |
wolfSSL | 0:d92f9d21154c | 689 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 690 | err = mp_mul(&t1, &x, &t1); |
wolfSSL | 0:d92f9d21154c | 691 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 692 | err = mp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 693 | |
wolfSSL | 0:d92f9d21154c | 694 | /* X = Y*Y */ |
wolfSSL | 0:d92f9d21154c | 695 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 696 | err = mp_sqr(&y, &x); |
wolfSSL | 0:d92f9d21154c | 697 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 698 | err = mp_montgomery_reduce(&x, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 699 | |
wolfSSL | 0:d92f9d21154c | 700 | /* X = X - T2 */ |
wolfSSL | 0:d92f9d21154c | 701 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 702 | err = mp_sub(&x, &t2, &x); |
wolfSSL | 0:d92f9d21154c | 703 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 704 | if (mp_cmp_d(&x, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 705 | err = mp_add(&x, modulus, &x); |
wolfSSL | 0:d92f9d21154c | 706 | } |
wolfSSL | 0:d92f9d21154c | 707 | /* T2 = T2 - X */ |
wolfSSL | 0:d92f9d21154c | 708 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 709 | err = mp_sub(&t2, &x, &t2); |
wolfSSL | 0:d92f9d21154c | 710 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 711 | if (mp_cmp_d(&t2, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 712 | err = mp_add(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 713 | } |
wolfSSL | 0:d92f9d21154c | 714 | /* T2 = T2 - X */ |
wolfSSL | 0:d92f9d21154c | 715 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 716 | err = mp_sub(&t2, &x, &t2); |
wolfSSL | 0:d92f9d21154c | 717 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 718 | if (mp_cmp_d(&t2, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 719 | err = mp_add(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 720 | } |
wolfSSL | 0:d92f9d21154c | 721 | /* T2 = T2 * Y */ |
wolfSSL | 0:d92f9d21154c | 722 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 723 | err = mp_mul(&t2, &y, &t2); |
wolfSSL | 0:d92f9d21154c | 724 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 725 | err = mp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 726 | |
wolfSSL | 0:d92f9d21154c | 727 | /* Y = T2 - T1 */ |
wolfSSL | 0:d92f9d21154c | 728 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 729 | err = mp_sub(&t2, &t1, &y); |
wolfSSL | 0:d92f9d21154c | 730 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 731 | if (mp_cmp_d(&y, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 732 | err = mp_add(&y, modulus, &y); |
wolfSSL | 0:d92f9d21154c | 733 | } |
wolfSSL | 0:d92f9d21154c | 734 | /* Y = Y/2 */ |
wolfSSL | 0:d92f9d21154c | 735 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 736 | if (mp_isodd(&y)) |
wolfSSL | 0:d92f9d21154c | 737 | err = mp_add(&y, modulus, &y); |
wolfSSL | 0:d92f9d21154c | 738 | } |
wolfSSL | 0:d92f9d21154c | 739 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 740 | err = mp_div_2(&y, &y); |
wolfSSL | 0:d92f9d21154c | 741 | |
wolfSSL | 0:d92f9d21154c | 742 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 743 | err = mp_copy(&x, R->x); |
wolfSSL | 0:d92f9d21154c | 744 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 745 | err = mp_copy(&y, R->y); |
wolfSSL | 0:d92f9d21154c | 746 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 747 | err = mp_copy(&z, R->z); |
wolfSSL | 0:d92f9d21154c | 748 | |
wolfSSL | 0:d92f9d21154c | 749 | /* clean up */ |
wolfSSL | 0:d92f9d21154c | 750 | mp_clear(&t1); |
wolfSSL | 0:d92f9d21154c | 751 | mp_clear(&t2); |
wolfSSL | 0:d92f9d21154c | 752 | mp_clear(&x); |
wolfSSL | 0:d92f9d21154c | 753 | mp_clear(&y); |
wolfSSL | 0:d92f9d21154c | 754 | mp_clear(&z); |
wolfSSL | 0:d92f9d21154c | 755 | |
wolfSSL | 0:d92f9d21154c | 756 | return err; |
wolfSSL | 0:d92f9d21154c | 757 | } |
wolfSSL | 0:d92f9d21154c | 758 | |
wolfSSL | 0:d92f9d21154c | 759 | |
wolfSSL | 0:d92f9d21154c | 760 | /** |
wolfSSL | 0:d92f9d21154c | 761 | Double an ECC point |
wolfSSL | 0:d92f9d21154c | 762 | P The point to double |
wolfSSL | 0:d92f9d21154c | 763 | R [out] The destination of the double |
wolfSSL | 0:d92f9d21154c | 764 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 0:d92f9d21154c | 765 | mp The "b" value from montgomery_setup() |
wolfSSL | 0:d92f9d21154c | 766 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 767 | */ |
wolfSSL | 0:d92f9d21154c | 768 | int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* modulus, |
wolfSSL | 0:d92f9d21154c | 769 | mp_digit* mp) |
wolfSSL | 0:d92f9d21154c | 770 | { |
wolfSSL | 0:d92f9d21154c | 771 | mp_int t1; |
wolfSSL | 0:d92f9d21154c | 772 | mp_int t2; |
wolfSSL | 0:d92f9d21154c | 773 | int err; |
wolfSSL | 0:d92f9d21154c | 774 | |
wolfSSL | 0:d92f9d21154c | 775 | if (P == NULL || R == NULL || modulus == NULL || mp == NULL) |
wolfSSL | 0:d92f9d21154c | 776 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 777 | |
wolfSSL | 0:d92f9d21154c | 778 | if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 779 | return err; |
wolfSSL | 0:d92f9d21154c | 780 | } |
wolfSSL | 0:d92f9d21154c | 781 | |
wolfSSL | 0:d92f9d21154c | 782 | if (P != R) { |
wolfSSL | 0:d92f9d21154c | 783 | err = mp_copy(P->x, R->x); |
wolfSSL | 0:d92f9d21154c | 784 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 785 | err = mp_copy(P->y, R->y); |
wolfSSL | 0:d92f9d21154c | 786 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 787 | err = mp_copy(P->z, R->z); |
wolfSSL | 0:d92f9d21154c | 788 | } |
wolfSSL | 0:d92f9d21154c | 789 | |
wolfSSL | 0:d92f9d21154c | 790 | /* t1 = Z * Z */ |
wolfSSL | 0:d92f9d21154c | 791 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 792 | err = mp_sqr(R->z, &t1); |
wolfSSL | 0:d92f9d21154c | 793 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 794 | err = mp_montgomery_reduce(&t1, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 795 | |
wolfSSL | 0:d92f9d21154c | 796 | /* Z = Y * Z */ |
wolfSSL | 0:d92f9d21154c | 797 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 798 | err = mp_mul(R->z, R->y, R->z); |
wolfSSL | 0:d92f9d21154c | 799 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 800 | err = mp_montgomery_reduce(R->z, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 801 | |
wolfSSL | 0:d92f9d21154c | 802 | /* Z = 2Z */ |
wolfSSL | 0:d92f9d21154c | 803 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 804 | err = mp_add(R->z, R->z, R->z); |
wolfSSL | 0:d92f9d21154c | 805 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 806 | if (mp_cmp(R->z, modulus) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 807 | err = mp_sub(R->z, modulus, R->z); |
wolfSSL | 0:d92f9d21154c | 808 | } |
wolfSSL | 0:d92f9d21154c | 809 | |
wolfSSL | 0:d92f9d21154c | 810 | /* T2 = X - T1 */ |
wolfSSL | 0:d92f9d21154c | 811 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 812 | err = mp_sub(R->x, &t1, &t2); |
wolfSSL | 0:d92f9d21154c | 813 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 814 | if (mp_cmp_d(&t2, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 815 | err = mp_add(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 816 | } |
wolfSSL | 0:d92f9d21154c | 817 | /* T1 = X + T1 */ |
wolfSSL | 0:d92f9d21154c | 818 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 819 | err = mp_add(&t1, R->x, &t1); |
wolfSSL | 0:d92f9d21154c | 820 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 821 | if (mp_cmp(&t1, modulus) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 822 | err = mp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 823 | } |
wolfSSL | 0:d92f9d21154c | 824 | /* T2 = T1 * T2 */ |
wolfSSL | 0:d92f9d21154c | 825 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 826 | err = mp_mul(&t1, &t2, &t2); |
wolfSSL | 0:d92f9d21154c | 827 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 828 | err = mp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 829 | |
wolfSSL | 0:d92f9d21154c | 830 | /* T1 = 2T2 */ |
wolfSSL | 0:d92f9d21154c | 831 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 832 | err = mp_add(&t2, &t2, &t1); |
wolfSSL | 0:d92f9d21154c | 833 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 834 | if (mp_cmp(&t1, modulus) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 835 | err = mp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 836 | } |
wolfSSL | 0:d92f9d21154c | 837 | /* T1 = T1 + T2 */ |
wolfSSL | 0:d92f9d21154c | 838 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 839 | err = mp_add(&t1, &t2, &t1); |
wolfSSL | 0:d92f9d21154c | 840 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 841 | if (mp_cmp(&t1, modulus) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 842 | err = mp_sub(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 843 | } |
wolfSSL | 0:d92f9d21154c | 844 | /* Y = 2Y */ |
wolfSSL | 0:d92f9d21154c | 845 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 846 | err = mp_add(R->y, R->y, R->y); |
wolfSSL | 0:d92f9d21154c | 847 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 848 | if (mp_cmp(R->y, modulus) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 849 | err = mp_sub(R->y, modulus, R->y); |
wolfSSL | 0:d92f9d21154c | 850 | } |
wolfSSL | 0:d92f9d21154c | 851 | /* Y = Y * Y */ |
wolfSSL | 0:d92f9d21154c | 852 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 853 | err = mp_sqr(R->y, R->y); |
wolfSSL | 0:d92f9d21154c | 854 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 855 | err = mp_montgomery_reduce(R->y, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 856 | |
wolfSSL | 0:d92f9d21154c | 857 | /* T2 = Y * Y */ |
wolfSSL | 0:d92f9d21154c | 858 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 859 | err = mp_sqr(R->y, &t2); |
wolfSSL | 0:d92f9d21154c | 860 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 861 | err = mp_montgomery_reduce(&t2, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 862 | |
wolfSSL | 0:d92f9d21154c | 863 | /* T2 = T2/2 */ |
wolfSSL | 0:d92f9d21154c | 864 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 865 | if (mp_isodd(&t2)) |
wolfSSL | 0:d92f9d21154c | 866 | err = mp_add(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 867 | } |
wolfSSL | 0:d92f9d21154c | 868 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 869 | err = mp_div_2(&t2, &t2); |
wolfSSL | 0:d92f9d21154c | 870 | |
wolfSSL | 0:d92f9d21154c | 871 | /* Y = Y * X */ |
wolfSSL | 0:d92f9d21154c | 872 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 873 | err = mp_mul(R->y, R->x, R->y); |
wolfSSL | 0:d92f9d21154c | 874 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 875 | err = mp_montgomery_reduce(R->y, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 876 | |
wolfSSL | 0:d92f9d21154c | 877 | /* X = T1 * T1 */ |
wolfSSL | 0:d92f9d21154c | 878 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 879 | err = mp_sqr(&t1, R->x); |
wolfSSL | 0:d92f9d21154c | 880 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 881 | err = mp_montgomery_reduce(R->x, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 882 | |
wolfSSL | 0:d92f9d21154c | 883 | /* X = X - Y */ |
wolfSSL | 0:d92f9d21154c | 884 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 885 | err = mp_sub(R->x, R->y, R->x); |
wolfSSL | 0:d92f9d21154c | 886 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 887 | if (mp_cmp_d(R->x, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 888 | err = mp_add(R->x, modulus, R->x); |
wolfSSL | 0:d92f9d21154c | 889 | } |
wolfSSL | 0:d92f9d21154c | 890 | /* X = X - Y */ |
wolfSSL | 0:d92f9d21154c | 891 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 892 | err = mp_sub(R->x, R->y, R->x); |
wolfSSL | 0:d92f9d21154c | 893 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 894 | if (mp_cmp_d(R->x, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 895 | err = mp_add(R->x, modulus, R->x); |
wolfSSL | 0:d92f9d21154c | 896 | } |
wolfSSL | 0:d92f9d21154c | 897 | /* Y = Y - X */ |
wolfSSL | 0:d92f9d21154c | 898 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 899 | err = mp_sub(R->y, R->x, R->y); |
wolfSSL | 0:d92f9d21154c | 900 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 901 | if (mp_cmp_d(R->y, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 902 | err = mp_add(R->y, modulus, R->y); |
wolfSSL | 0:d92f9d21154c | 903 | } |
wolfSSL | 0:d92f9d21154c | 904 | /* Y = Y * T1 */ |
wolfSSL | 0:d92f9d21154c | 905 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 906 | err = mp_mul(R->y, &t1, R->y); |
wolfSSL | 0:d92f9d21154c | 907 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 908 | err = mp_montgomery_reduce(R->y, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 909 | |
wolfSSL | 0:d92f9d21154c | 910 | /* Y = Y - T2 */ |
wolfSSL | 0:d92f9d21154c | 911 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 912 | err = mp_sub(R->y, &t2, R->y); |
wolfSSL | 0:d92f9d21154c | 913 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 914 | if (mp_cmp_d(R->y, 0) == MP_LT) |
wolfSSL | 0:d92f9d21154c | 915 | err = mp_add(R->y, modulus, R->y); |
wolfSSL | 0:d92f9d21154c | 916 | } |
wolfSSL | 0:d92f9d21154c | 917 | |
wolfSSL | 0:d92f9d21154c | 918 | /* clean up */ |
wolfSSL | 0:d92f9d21154c | 919 | mp_clear(&t1); |
wolfSSL | 0:d92f9d21154c | 920 | mp_clear(&t2); |
wolfSSL | 0:d92f9d21154c | 921 | |
wolfSSL | 0:d92f9d21154c | 922 | return err; |
wolfSSL | 0:d92f9d21154c | 923 | } |
wolfSSL | 0:d92f9d21154c | 924 | |
wolfSSL | 0:d92f9d21154c | 925 | #endif /* USE_FAST_MATH */ |
wolfSSL | 0:d92f9d21154c | 926 | |
wolfSSL | 0:d92f9d21154c | 927 | /** |
wolfSSL | 0:d92f9d21154c | 928 | Map a projective jacbobian point back to affine space |
wolfSSL | 0:d92f9d21154c | 929 | P [in/out] The point to map |
wolfSSL | 0:d92f9d21154c | 930 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 0:d92f9d21154c | 931 | mp The "b" value from montgomery_setup() |
wolfSSL | 0:d92f9d21154c | 932 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 933 | */ |
wolfSSL | 0:d92f9d21154c | 934 | int ecc_map(ecc_point* P, mp_int* modulus, mp_digit* mp) |
wolfSSL | 0:d92f9d21154c | 935 | { |
wolfSSL | 0:d92f9d21154c | 936 | mp_int t1; |
wolfSSL | 0:d92f9d21154c | 937 | mp_int t2; |
wolfSSL | 0:d92f9d21154c | 938 | int err; |
wolfSSL | 0:d92f9d21154c | 939 | |
wolfSSL | 0:d92f9d21154c | 940 | if (P == NULL || mp == NULL || modulus == NULL) |
wolfSSL | 0:d92f9d21154c | 941 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 942 | |
wolfSSL | 0:d92f9d21154c | 943 | /* special case for point at infinity */ |
wolfSSL | 0:d92f9d21154c | 944 | if (mp_cmp_d(P->z, 0) == MP_EQ) { |
wolfSSL | 0:d92f9d21154c | 945 | mp_set(P->x, 0); |
wolfSSL | 0:d92f9d21154c | 946 | mp_set(P->y, 0); |
wolfSSL | 0:d92f9d21154c | 947 | mp_set(P->z, 1); |
wolfSSL | 0:d92f9d21154c | 948 | return MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 949 | } |
wolfSSL | 0:d92f9d21154c | 950 | |
wolfSSL | 0:d92f9d21154c | 951 | if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 952 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 953 | } |
wolfSSL | 0:d92f9d21154c | 954 | |
wolfSSL | 0:d92f9d21154c | 955 | /* first map z back to normal */ |
wolfSSL | 0:d92f9d21154c | 956 | err = mp_montgomery_reduce(P->z, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 957 | |
wolfSSL | 0:d92f9d21154c | 958 | /* get 1/z */ |
wolfSSL | 0:d92f9d21154c | 959 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 960 | err = mp_invmod(P->z, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 961 | |
wolfSSL | 0:d92f9d21154c | 962 | /* get 1/z^2 and 1/z^3 */ |
wolfSSL | 0:d92f9d21154c | 963 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 964 | err = mp_sqr(&t1, &t2); |
wolfSSL | 0:d92f9d21154c | 965 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 966 | err = mp_mod(&t2, modulus, &t2); |
wolfSSL | 0:d92f9d21154c | 967 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 968 | err = mp_mul(&t1, &t2, &t1); |
wolfSSL | 0:d92f9d21154c | 969 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 970 | err = mp_mod(&t1, modulus, &t1); |
wolfSSL | 0:d92f9d21154c | 971 | |
wolfSSL | 0:d92f9d21154c | 972 | /* multiply against x/y */ |
wolfSSL | 0:d92f9d21154c | 973 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 974 | err = mp_mul(P->x, &t2, P->x); |
wolfSSL | 0:d92f9d21154c | 975 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 976 | err = mp_montgomery_reduce(P->x, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 977 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 978 | err = mp_mul(P->y, &t1, P->y); |
wolfSSL | 0:d92f9d21154c | 979 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 980 | err = mp_montgomery_reduce(P->y, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 981 | |
wolfSSL | 0:d92f9d21154c | 982 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 983 | mp_set(P->z, 1); |
wolfSSL | 0:d92f9d21154c | 984 | |
wolfSSL | 0:d92f9d21154c | 985 | /* clean up */ |
wolfSSL | 0:d92f9d21154c | 986 | mp_clear(&t1); |
wolfSSL | 0:d92f9d21154c | 987 | mp_clear(&t2); |
wolfSSL | 0:d92f9d21154c | 988 | |
wolfSSL | 0:d92f9d21154c | 989 | return err; |
wolfSSL | 0:d92f9d21154c | 990 | } |
wolfSSL | 0:d92f9d21154c | 991 | |
wolfSSL | 0:d92f9d21154c | 992 | |
wolfSSL | 0:d92f9d21154c | 993 | #ifndef ECC_TIMING_RESISTANT |
wolfSSL | 0:d92f9d21154c | 994 | |
wolfSSL | 0:d92f9d21154c | 995 | /* size of sliding window, don't change this! */ |
wolfSSL | 0:d92f9d21154c | 996 | #define WINSIZE 4 |
wolfSSL | 0:d92f9d21154c | 997 | |
wolfSSL | 0:d92f9d21154c | 998 | /** |
wolfSSL | 0:d92f9d21154c | 999 | Perform a point multiplication |
wolfSSL | 0:d92f9d21154c | 1000 | k The scalar to multiply by |
wolfSSL | 0:d92f9d21154c | 1001 | G The base point |
wolfSSL | 0:d92f9d21154c | 1002 | R [out] Destination for kG |
wolfSSL | 0:d92f9d21154c | 1003 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 0:d92f9d21154c | 1004 | map Boolean whether to map back to affine or not |
wolfSSL | 0:d92f9d21154c | 1005 | (1==map, 0 == leave in projective) |
wolfSSL | 0:d92f9d21154c | 1006 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 1007 | */ |
wolfSSL | 0:d92f9d21154c | 1008 | #ifdef FP_ECC |
wolfSSL | 0:d92f9d21154c | 1009 | static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, |
wolfSSL | 0:d92f9d21154c | 1010 | mp_int* modulus, int map) |
wolfSSL | 0:d92f9d21154c | 1011 | #else |
wolfSSL | 0:d92f9d21154c | 1012 | static int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, |
wolfSSL | 0:d92f9d21154c | 1013 | int map) |
wolfSSL | 0:d92f9d21154c | 1014 | #endif |
wolfSSL | 0:d92f9d21154c | 1015 | { |
wolfSSL | 0:d92f9d21154c | 1016 | ecc_point *tG, *M[8]; |
wolfSSL | 0:d92f9d21154c | 1017 | int i, j, err; |
wolfSSL | 0:d92f9d21154c | 1018 | mp_int mu; |
wolfSSL | 0:d92f9d21154c | 1019 | mp_digit mp; |
wolfSSL | 0:d92f9d21154c | 1020 | mp_digit buf; |
wolfSSL | 0:d92f9d21154c | 1021 | int first = 1, bitbuf = 0, bitcpy = 0, bitcnt = 0, mode = 0, |
wolfSSL | 0:d92f9d21154c | 1022 | digidx = 0; |
wolfSSL | 0:d92f9d21154c | 1023 | |
wolfSSL | 0:d92f9d21154c | 1024 | if (k == NULL || G == NULL || R == NULL || modulus == NULL) |
wolfSSL | 0:d92f9d21154c | 1025 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1026 | |
wolfSSL | 0:d92f9d21154c | 1027 | /* init montgomery reduction */ |
wolfSSL | 0:d92f9d21154c | 1028 | if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1029 | return err; |
wolfSSL | 0:d92f9d21154c | 1030 | } |
wolfSSL | 0:d92f9d21154c | 1031 | if ((err = mp_init(&mu)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1032 | return err; |
wolfSSL | 0:d92f9d21154c | 1033 | } |
wolfSSL | 0:d92f9d21154c | 1034 | if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1035 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 1036 | return err; |
wolfSSL | 0:d92f9d21154c | 1037 | } |
wolfSSL | 0:d92f9d21154c | 1038 | |
wolfSSL | 0:d92f9d21154c | 1039 | /* alloc ram for window temps */ |
wolfSSL | 0:d92f9d21154c | 1040 | for (i = 0; i < 8; i++) { |
wolfSSL | 0:d92f9d21154c | 1041 | M[i] = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 1042 | if (M[i] == NULL) { |
wolfSSL | 0:d92f9d21154c | 1043 | for (j = 0; j < i; j++) { |
wolfSSL | 0:d92f9d21154c | 1044 | ecc_del_point(M[j]); |
wolfSSL | 0:d92f9d21154c | 1045 | } |
wolfSSL | 0:d92f9d21154c | 1046 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 1047 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 1048 | } |
wolfSSL | 0:d92f9d21154c | 1049 | } |
wolfSSL | 0:d92f9d21154c | 1050 | |
wolfSSL | 0:d92f9d21154c | 1051 | /* make a copy of G incase R==G */ |
wolfSSL | 0:d92f9d21154c | 1052 | tG = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 1053 | if (tG == NULL) |
wolfSSL | 0:d92f9d21154c | 1054 | err = MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 1055 | |
wolfSSL | 0:d92f9d21154c | 1056 | /* tG = G and convert to montgomery */ |
wolfSSL | 0:d92f9d21154c | 1057 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1058 | if (mp_cmp_d(&mu, 1) == MP_EQ) { |
wolfSSL | 0:d92f9d21154c | 1059 | err = mp_copy(G->x, tG->x); |
wolfSSL | 0:d92f9d21154c | 1060 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1061 | err = mp_copy(G->y, tG->y); |
wolfSSL | 0:d92f9d21154c | 1062 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1063 | err = mp_copy(G->z, tG->z); |
wolfSSL | 0:d92f9d21154c | 1064 | } else { |
wolfSSL | 0:d92f9d21154c | 1065 | err = mp_mulmod(G->x, &mu, modulus, tG->x); |
wolfSSL | 0:d92f9d21154c | 1066 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1067 | err = mp_mulmod(G->y, &mu, modulus, tG->y); |
wolfSSL | 0:d92f9d21154c | 1068 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1069 | err = mp_mulmod(G->z, &mu, modulus, tG->z); |
wolfSSL | 0:d92f9d21154c | 1070 | } |
wolfSSL | 0:d92f9d21154c | 1071 | } |
wolfSSL | 0:d92f9d21154c | 1072 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 1073 | |
wolfSSL | 0:d92f9d21154c | 1074 | /* calc the M tab, which holds kG for k==8..15 */ |
wolfSSL | 0:d92f9d21154c | 1075 | /* M[0] == 8G */ |
wolfSSL | 0:d92f9d21154c | 1076 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1077 | err = ecc_projective_dbl_point(tG, M[0], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1078 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1079 | err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1080 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1081 | err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1082 | |
wolfSSL | 0:d92f9d21154c | 1083 | /* now find (8+k)G for k=1..7 */ |
wolfSSL | 0:d92f9d21154c | 1084 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1085 | for (j = 9; j < 16; j++) { |
wolfSSL | 0:d92f9d21154c | 1086 | err = ecc_projective_add_point(M[j-9], tG, M[j-8], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1087 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1088 | } |
wolfSSL | 0:d92f9d21154c | 1089 | |
wolfSSL | 0:d92f9d21154c | 1090 | /* setup sliding window */ |
wolfSSL | 0:d92f9d21154c | 1091 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1092 | mode = 0; |
wolfSSL | 0:d92f9d21154c | 1093 | bitcnt = 1; |
wolfSSL | 0:d92f9d21154c | 1094 | buf = 0; |
wolfSSL | 0:d92f9d21154c | 1095 | digidx = get_digit_count(k) - 1; |
wolfSSL | 0:d92f9d21154c | 1096 | bitcpy = bitbuf = 0; |
wolfSSL | 0:d92f9d21154c | 1097 | first = 1; |
wolfSSL | 0:d92f9d21154c | 1098 | |
wolfSSL | 0:d92f9d21154c | 1099 | /* perform ops */ |
wolfSSL | 0:d92f9d21154c | 1100 | for (;;) { |
wolfSSL | 0:d92f9d21154c | 1101 | /* grab next digit as required */ |
wolfSSL | 0:d92f9d21154c | 1102 | if (--bitcnt == 0) { |
wolfSSL | 0:d92f9d21154c | 1103 | if (digidx == -1) { |
wolfSSL | 0:d92f9d21154c | 1104 | break; |
wolfSSL | 0:d92f9d21154c | 1105 | } |
wolfSSL | 0:d92f9d21154c | 1106 | buf = get_digit(k, digidx); |
wolfSSL | 0:d92f9d21154c | 1107 | bitcnt = (int) DIGIT_BIT; |
wolfSSL | 0:d92f9d21154c | 1108 | --digidx; |
wolfSSL | 0:d92f9d21154c | 1109 | } |
wolfSSL | 0:d92f9d21154c | 1110 | |
wolfSSL | 0:d92f9d21154c | 1111 | /* grab the next msb from the ltiplicand */ |
wolfSSL | 0:d92f9d21154c | 1112 | i = (int)(buf >> (DIGIT_BIT - 1)) & 1; |
wolfSSL | 0:d92f9d21154c | 1113 | buf <<= 1; |
wolfSSL | 0:d92f9d21154c | 1114 | |
wolfSSL | 0:d92f9d21154c | 1115 | /* skip leading zero bits */ |
wolfSSL | 0:d92f9d21154c | 1116 | if (mode == 0 && i == 0) |
wolfSSL | 0:d92f9d21154c | 1117 | continue; |
wolfSSL | 0:d92f9d21154c | 1118 | |
wolfSSL | 0:d92f9d21154c | 1119 | /* if the bit is zero and mode == 1 then we double */ |
wolfSSL | 0:d92f9d21154c | 1120 | if (mode == 1 && i == 0) { |
wolfSSL | 0:d92f9d21154c | 1121 | err = ecc_projective_dbl_point(R, R, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1122 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1123 | continue; |
wolfSSL | 0:d92f9d21154c | 1124 | } |
wolfSSL | 0:d92f9d21154c | 1125 | |
wolfSSL | 0:d92f9d21154c | 1126 | /* else we add it to the window */ |
wolfSSL | 0:d92f9d21154c | 1127 | bitbuf |= (i << (WINSIZE - ++bitcpy)); |
wolfSSL | 0:d92f9d21154c | 1128 | mode = 2; |
wolfSSL | 0:d92f9d21154c | 1129 | |
wolfSSL | 0:d92f9d21154c | 1130 | if (bitcpy == WINSIZE) { |
wolfSSL | 0:d92f9d21154c | 1131 | /* if this is the first window we do a simple copy */ |
wolfSSL | 0:d92f9d21154c | 1132 | if (first == 1) { |
wolfSSL | 0:d92f9d21154c | 1133 | /* R = kG [k = first window] */ |
wolfSSL | 0:d92f9d21154c | 1134 | err = mp_copy(M[bitbuf-8]->x, R->x); |
wolfSSL | 0:d92f9d21154c | 1135 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1136 | |
wolfSSL | 0:d92f9d21154c | 1137 | err = mp_copy(M[bitbuf-8]->y, R->y); |
wolfSSL | 0:d92f9d21154c | 1138 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1139 | |
wolfSSL | 0:d92f9d21154c | 1140 | err = mp_copy(M[bitbuf-8]->z, R->z); |
wolfSSL | 0:d92f9d21154c | 1141 | first = 0; |
wolfSSL | 0:d92f9d21154c | 1142 | } else { |
wolfSSL | 0:d92f9d21154c | 1143 | /* normal window */ |
wolfSSL | 0:d92f9d21154c | 1144 | /* ok window is filled so double as required and add */ |
wolfSSL | 0:d92f9d21154c | 1145 | /* double first */ |
wolfSSL | 0:d92f9d21154c | 1146 | for (j = 0; j < WINSIZE; j++) { |
wolfSSL | 0:d92f9d21154c | 1147 | err = ecc_projective_dbl_point(R, R, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1148 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1149 | } |
wolfSSL | 0:d92f9d21154c | 1150 | if (err != MP_OKAY) break; /* out of first for(;;) */ |
wolfSSL | 0:d92f9d21154c | 1151 | |
wolfSSL | 0:d92f9d21154c | 1152 | /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranted */ |
wolfSSL | 0:d92f9d21154c | 1153 | err = ecc_projective_add_point(R,M[bitbuf-8],R,modulus,&mp); |
wolfSSL | 0:d92f9d21154c | 1154 | } |
wolfSSL | 0:d92f9d21154c | 1155 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1156 | /* empty window and reset */ |
wolfSSL | 0:d92f9d21154c | 1157 | bitcpy = bitbuf = 0; |
wolfSSL | 0:d92f9d21154c | 1158 | mode = 1; |
wolfSSL | 0:d92f9d21154c | 1159 | } |
wolfSSL | 0:d92f9d21154c | 1160 | } |
wolfSSL | 0:d92f9d21154c | 1161 | } |
wolfSSL | 0:d92f9d21154c | 1162 | |
wolfSSL | 0:d92f9d21154c | 1163 | /* if bits remain then double/add */ |
wolfSSL | 0:d92f9d21154c | 1164 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1165 | if (mode == 2 && bitcpy > 0) { |
wolfSSL | 0:d92f9d21154c | 1166 | /* double then add */ |
wolfSSL | 0:d92f9d21154c | 1167 | for (j = 0; j < bitcpy; j++) { |
wolfSSL | 0:d92f9d21154c | 1168 | /* only double if we have had at least one add first */ |
wolfSSL | 0:d92f9d21154c | 1169 | if (first == 0) { |
wolfSSL | 0:d92f9d21154c | 1170 | err = ecc_projective_dbl_point(R, R, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1171 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1172 | } |
wolfSSL | 0:d92f9d21154c | 1173 | |
wolfSSL | 0:d92f9d21154c | 1174 | bitbuf <<= 1; |
wolfSSL | 0:d92f9d21154c | 1175 | if ((bitbuf & (1 << WINSIZE)) != 0) { |
wolfSSL | 0:d92f9d21154c | 1176 | if (first == 1) { |
wolfSSL | 0:d92f9d21154c | 1177 | /* first add, so copy */ |
wolfSSL | 0:d92f9d21154c | 1178 | err = mp_copy(tG->x, R->x); |
wolfSSL | 0:d92f9d21154c | 1179 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1180 | |
wolfSSL | 0:d92f9d21154c | 1181 | err = mp_copy(tG->y, R->y); |
wolfSSL | 0:d92f9d21154c | 1182 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1183 | |
wolfSSL | 0:d92f9d21154c | 1184 | err = mp_copy(tG->z, R->z); |
wolfSSL | 0:d92f9d21154c | 1185 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1186 | first = 0; |
wolfSSL | 0:d92f9d21154c | 1187 | } else { |
wolfSSL | 0:d92f9d21154c | 1188 | /* then add */ |
wolfSSL | 0:d92f9d21154c | 1189 | err = ecc_projective_add_point(R, tG, R, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1190 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1191 | } |
wolfSSL | 0:d92f9d21154c | 1192 | } |
wolfSSL | 0:d92f9d21154c | 1193 | } |
wolfSSL | 0:d92f9d21154c | 1194 | } |
wolfSSL | 0:d92f9d21154c | 1195 | } |
wolfSSL | 0:d92f9d21154c | 1196 | |
wolfSSL | 0:d92f9d21154c | 1197 | /* map R back from projective space */ |
wolfSSL | 0:d92f9d21154c | 1198 | if (err == MP_OKAY && map) |
wolfSSL | 0:d92f9d21154c | 1199 | err = ecc_map(R, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1200 | |
wolfSSL | 0:d92f9d21154c | 1201 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 1202 | ecc_del_point(tG); |
wolfSSL | 0:d92f9d21154c | 1203 | for (i = 0; i < 8; i++) { |
wolfSSL | 0:d92f9d21154c | 1204 | ecc_del_point(M[i]); |
wolfSSL | 0:d92f9d21154c | 1205 | } |
wolfSSL | 0:d92f9d21154c | 1206 | return err; |
wolfSSL | 0:d92f9d21154c | 1207 | } |
wolfSSL | 0:d92f9d21154c | 1208 | |
wolfSSL | 0:d92f9d21154c | 1209 | #undef WINSIZE |
wolfSSL | 0:d92f9d21154c | 1210 | |
wolfSSL | 0:d92f9d21154c | 1211 | #else /* ECC_TIMING_RESISTANT */ |
wolfSSL | 0:d92f9d21154c | 1212 | |
wolfSSL | 0:d92f9d21154c | 1213 | /** |
wolfSSL | 0:d92f9d21154c | 1214 | Perform a point multiplication (timing resistant) |
wolfSSL | 0:d92f9d21154c | 1215 | k The scalar to multiply by |
wolfSSL | 0:d92f9d21154c | 1216 | G The base point |
wolfSSL | 0:d92f9d21154c | 1217 | R [out] Destination for kG |
wolfSSL | 0:d92f9d21154c | 1218 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 0:d92f9d21154c | 1219 | map Boolean whether to map back to affine or not |
wolfSSL | 0:d92f9d21154c | 1220 | (1==map, 0 == leave in projective) |
wolfSSL | 0:d92f9d21154c | 1221 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 1222 | */ |
wolfSSL | 0:d92f9d21154c | 1223 | #ifdef FP_ECC |
wolfSSL | 0:d92f9d21154c | 1224 | static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, |
wolfSSL | 0:d92f9d21154c | 1225 | mp_int* modulus, int map) |
wolfSSL | 0:d92f9d21154c | 1226 | #else |
wolfSSL | 0:d92f9d21154c | 1227 | static int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, |
wolfSSL | 0:d92f9d21154c | 1228 | int map) |
wolfSSL | 0:d92f9d21154c | 1229 | #endif |
wolfSSL | 0:d92f9d21154c | 1230 | { |
wolfSSL | 0:d92f9d21154c | 1231 | ecc_point *tG, *M[3]; |
wolfSSL | 0:d92f9d21154c | 1232 | int i, j, err; |
wolfSSL | 0:d92f9d21154c | 1233 | mp_int mu; |
wolfSSL | 0:d92f9d21154c | 1234 | mp_digit mp; |
wolfSSL | 0:d92f9d21154c | 1235 | mp_digit buf; |
wolfSSL | 0:d92f9d21154c | 1236 | int bitcnt = 0, mode = 0, digidx = 0; |
wolfSSL | 0:d92f9d21154c | 1237 | |
wolfSSL | 0:d92f9d21154c | 1238 | if (k == NULL || G == NULL || R == NULL || modulus == NULL) |
wolfSSL | 0:d92f9d21154c | 1239 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1240 | |
wolfSSL | 0:d92f9d21154c | 1241 | /* init montgomery reduction */ |
wolfSSL | 0:d92f9d21154c | 1242 | if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1243 | return err; |
wolfSSL | 0:d92f9d21154c | 1244 | } |
wolfSSL | 0:d92f9d21154c | 1245 | if ((err = mp_init(&mu)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1246 | return err; |
wolfSSL | 0:d92f9d21154c | 1247 | } |
wolfSSL | 0:d92f9d21154c | 1248 | if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1249 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 1250 | return err; |
wolfSSL | 0:d92f9d21154c | 1251 | } |
wolfSSL | 0:d92f9d21154c | 1252 | |
wolfSSL | 0:d92f9d21154c | 1253 | /* alloc ram for window temps */ |
wolfSSL | 0:d92f9d21154c | 1254 | for (i = 0; i < 3; i++) { |
wolfSSL | 0:d92f9d21154c | 1255 | M[i] = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 1256 | if (M[i] == NULL) { |
wolfSSL | 0:d92f9d21154c | 1257 | for (j = 0; j < i; j++) { |
wolfSSL | 0:d92f9d21154c | 1258 | ecc_del_point(M[j]); |
wolfSSL | 0:d92f9d21154c | 1259 | } |
wolfSSL | 0:d92f9d21154c | 1260 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 1261 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 1262 | } |
wolfSSL | 0:d92f9d21154c | 1263 | } |
wolfSSL | 0:d92f9d21154c | 1264 | |
wolfSSL | 0:d92f9d21154c | 1265 | /* make a copy of G incase R==G */ |
wolfSSL | 0:d92f9d21154c | 1266 | tG = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 1267 | if (tG == NULL) |
wolfSSL | 0:d92f9d21154c | 1268 | err = MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 1269 | |
wolfSSL | 0:d92f9d21154c | 1270 | /* tG = G and convert to montgomery */ |
wolfSSL | 0:d92f9d21154c | 1271 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1272 | err = mp_mulmod(G->x, &mu, modulus, tG->x); |
wolfSSL | 0:d92f9d21154c | 1273 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1274 | err = mp_mulmod(G->y, &mu, modulus, tG->y); |
wolfSSL | 0:d92f9d21154c | 1275 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1276 | err = mp_mulmod(G->z, &mu, modulus, tG->z); |
wolfSSL | 0:d92f9d21154c | 1277 | } |
wolfSSL | 0:d92f9d21154c | 1278 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 1279 | |
wolfSSL | 0:d92f9d21154c | 1280 | /* calc the M tab */ |
wolfSSL | 0:d92f9d21154c | 1281 | /* M[0] == G */ |
wolfSSL | 0:d92f9d21154c | 1282 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1283 | err = mp_copy(tG->x, M[0]->x); |
wolfSSL | 0:d92f9d21154c | 1284 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1285 | err = mp_copy(tG->y, M[0]->y); |
wolfSSL | 0:d92f9d21154c | 1286 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1287 | err = mp_copy(tG->z, M[0]->z); |
wolfSSL | 0:d92f9d21154c | 1288 | |
wolfSSL | 0:d92f9d21154c | 1289 | /* M[1] == 2G */ |
wolfSSL | 0:d92f9d21154c | 1290 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1291 | err = ecc_projective_dbl_point(tG, M[1], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1292 | |
wolfSSL | 0:d92f9d21154c | 1293 | /* setup sliding window */ |
wolfSSL | 0:d92f9d21154c | 1294 | mode = 0; |
wolfSSL | 0:d92f9d21154c | 1295 | bitcnt = 1; |
wolfSSL | 0:d92f9d21154c | 1296 | buf = 0; |
wolfSSL | 0:d92f9d21154c | 1297 | digidx = get_digit_count(k) - 1; |
wolfSSL | 0:d92f9d21154c | 1298 | |
wolfSSL | 0:d92f9d21154c | 1299 | /* perform ops */ |
wolfSSL | 0:d92f9d21154c | 1300 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1301 | for (;;) { |
wolfSSL | 0:d92f9d21154c | 1302 | /* grab next digit as required */ |
wolfSSL | 0:d92f9d21154c | 1303 | if (--bitcnt == 0) { |
wolfSSL | 0:d92f9d21154c | 1304 | if (digidx == -1) { |
wolfSSL | 0:d92f9d21154c | 1305 | break; |
wolfSSL | 0:d92f9d21154c | 1306 | } |
wolfSSL | 0:d92f9d21154c | 1307 | buf = get_digit(k, digidx); |
wolfSSL | 0:d92f9d21154c | 1308 | bitcnt = (int) DIGIT_BIT; |
wolfSSL | 0:d92f9d21154c | 1309 | --digidx; |
wolfSSL | 0:d92f9d21154c | 1310 | } |
wolfSSL | 0:d92f9d21154c | 1311 | |
wolfSSL | 0:d92f9d21154c | 1312 | /* grab the next msb from the ltiplicand */ |
wolfSSL | 0:d92f9d21154c | 1313 | i = (buf >> (DIGIT_BIT - 1)) & 1; |
wolfSSL | 0:d92f9d21154c | 1314 | buf <<= 1; |
wolfSSL | 0:d92f9d21154c | 1315 | |
wolfSSL | 0:d92f9d21154c | 1316 | if (mode == 0 && i == 0) { |
wolfSSL | 0:d92f9d21154c | 1317 | /* dummy operations */ |
wolfSSL | 0:d92f9d21154c | 1318 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1319 | err = ecc_projective_add_point(M[0], M[1], M[2], modulus, |
wolfSSL | 0:d92f9d21154c | 1320 | &mp); |
wolfSSL | 0:d92f9d21154c | 1321 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1322 | err = ecc_projective_dbl_point(M[1], M[2], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1323 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1324 | continue; |
wolfSSL | 0:d92f9d21154c | 1325 | } |
wolfSSL | 0:d92f9d21154c | 1326 | |
wolfSSL | 0:d92f9d21154c | 1327 | if (mode == 0 && i == 1) { |
wolfSSL | 0:d92f9d21154c | 1328 | mode = 1; |
wolfSSL | 0:d92f9d21154c | 1329 | /* dummy operations */ |
wolfSSL | 0:d92f9d21154c | 1330 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1331 | err = ecc_projective_add_point(M[0], M[1], M[2], modulus, |
wolfSSL | 0:d92f9d21154c | 1332 | &mp); |
wolfSSL | 0:d92f9d21154c | 1333 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1334 | err = ecc_projective_dbl_point(M[1], M[2], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1335 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1336 | continue; |
wolfSSL | 0:d92f9d21154c | 1337 | } |
wolfSSL | 0:d92f9d21154c | 1338 | |
wolfSSL | 0:d92f9d21154c | 1339 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1340 | err = ecc_projective_add_point(M[0], M[1], M[i^1], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1341 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1342 | err = ecc_projective_dbl_point(M[i], M[i], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1343 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1344 | break; |
wolfSSL | 0:d92f9d21154c | 1345 | } /* end for */ |
wolfSSL | 0:d92f9d21154c | 1346 | } |
wolfSSL | 0:d92f9d21154c | 1347 | |
wolfSSL | 0:d92f9d21154c | 1348 | /* copy result out */ |
wolfSSL | 0:d92f9d21154c | 1349 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1350 | err = mp_copy(M[0]->x, R->x); |
wolfSSL | 0:d92f9d21154c | 1351 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1352 | err = mp_copy(M[0]->y, R->y); |
wolfSSL | 0:d92f9d21154c | 1353 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1354 | err = mp_copy(M[0]->z, R->z); |
wolfSSL | 0:d92f9d21154c | 1355 | |
wolfSSL | 0:d92f9d21154c | 1356 | /* map R back from projective space */ |
wolfSSL | 0:d92f9d21154c | 1357 | if (err == MP_OKAY && map) |
wolfSSL | 0:d92f9d21154c | 1358 | err = ecc_map(R, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1359 | |
wolfSSL | 0:d92f9d21154c | 1360 | /* done */ |
wolfSSL | 0:d92f9d21154c | 1361 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 1362 | ecc_del_point(tG); |
wolfSSL | 0:d92f9d21154c | 1363 | for (i = 0; i < 3; i++) { |
wolfSSL | 0:d92f9d21154c | 1364 | ecc_del_point(M[i]); |
wolfSSL | 0:d92f9d21154c | 1365 | } |
wolfSSL | 0:d92f9d21154c | 1366 | return err; |
wolfSSL | 0:d92f9d21154c | 1367 | } |
wolfSSL | 0:d92f9d21154c | 1368 | |
wolfSSL | 0:d92f9d21154c | 1369 | #endif /* ECC_TIMING_RESISTANT */ |
wolfSSL | 0:d92f9d21154c | 1370 | |
wolfSSL | 0:d92f9d21154c | 1371 | |
wolfSSL | 0:d92f9d21154c | 1372 | #ifdef ALT_ECC_SIZE |
wolfSSL | 0:d92f9d21154c | 1373 | |
wolfSSL | 0:d92f9d21154c | 1374 | static void alt_fp_init(fp_int* a) |
wolfSSL | 0:d92f9d21154c | 1375 | { |
wolfSSL | 0:d92f9d21154c | 1376 | a->size = FP_SIZE_ECC; |
wolfSSL | 0:d92f9d21154c | 1377 | fp_zero(a); |
wolfSSL | 0:d92f9d21154c | 1378 | } |
wolfSSL | 0:d92f9d21154c | 1379 | |
wolfSSL | 0:d92f9d21154c | 1380 | #endif /* ALT_ECC_SIZE */ |
wolfSSL | 0:d92f9d21154c | 1381 | |
wolfSSL | 0:d92f9d21154c | 1382 | |
wolfSSL | 0:d92f9d21154c | 1383 | /** |
wolfSSL | 0:d92f9d21154c | 1384 | Allocate a new ECC point |
wolfSSL | 0:d92f9d21154c | 1385 | return A newly allocated point or NULL on error |
wolfSSL | 0:d92f9d21154c | 1386 | */ |
wolfSSL | 0:d92f9d21154c | 1387 | ecc_point* ecc_new_point(void) |
wolfSSL | 0:d92f9d21154c | 1388 | { |
wolfSSL | 0:d92f9d21154c | 1389 | ecc_point* p; |
wolfSSL | 0:d92f9d21154c | 1390 | |
wolfSSL | 0:d92f9d21154c | 1391 | p = (ecc_point*)XMALLOC(sizeof(ecc_point), 0, DYNAMIC_TYPE_ECC); |
wolfSSL | 0:d92f9d21154c | 1392 | if (p == NULL) { |
wolfSSL | 0:d92f9d21154c | 1393 | return NULL; |
wolfSSL | 0:d92f9d21154c | 1394 | } |
wolfSSL | 0:d92f9d21154c | 1395 | XMEMSET(p, 0, sizeof(ecc_point)); |
wolfSSL | 0:d92f9d21154c | 1396 | |
wolfSSL | 0:d92f9d21154c | 1397 | #ifndef USE_FAST_MATH |
wolfSSL | 0:d92f9d21154c | 1398 | p->x->dp = NULL; |
wolfSSL | 0:d92f9d21154c | 1399 | p->y->dp = NULL; |
wolfSSL | 0:d92f9d21154c | 1400 | p->z->dp = NULL; |
wolfSSL | 0:d92f9d21154c | 1401 | #endif |
wolfSSL | 0:d92f9d21154c | 1402 | |
wolfSSL | 0:d92f9d21154c | 1403 | #ifndef ALT_ECC_SIZE |
wolfSSL | 0:d92f9d21154c | 1404 | if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1405 | XFREE(p, 0, DYNAMIC_TYPE_ECC); |
wolfSSL | 0:d92f9d21154c | 1406 | return NULL; |
wolfSSL | 0:d92f9d21154c | 1407 | } |
wolfSSL | 0:d92f9d21154c | 1408 | #else |
wolfSSL | 0:d92f9d21154c | 1409 | p->x = (mp_int*)&p->xyz[0]; |
wolfSSL | 0:d92f9d21154c | 1410 | p->y = (mp_int*)&p->xyz[1]; |
wolfSSL | 0:d92f9d21154c | 1411 | p->z = (mp_int*)&p->xyz[2]; |
wolfSSL | 0:d92f9d21154c | 1412 | alt_fp_init(p->x); |
wolfSSL | 0:d92f9d21154c | 1413 | alt_fp_init(p->y); |
wolfSSL | 0:d92f9d21154c | 1414 | alt_fp_init(p->z); |
wolfSSL | 0:d92f9d21154c | 1415 | #endif |
wolfSSL | 0:d92f9d21154c | 1416 | |
wolfSSL | 0:d92f9d21154c | 1417 | return p; |
wolfSSL | 0:d92f9d21154c | 1418 | } |
wolfSSL | 0:d92f9d21154c | 1419 | |
wolfSSL | 0:d92f9d21154c | 1420 | /** Free an ECC point from memory |
wolfSSL | 0:d92f9d21154c | 1421 | p The point to free |
wolfSSL | 0:d92f9d21154c | 1422 | */ |
wolfSSL | 0:d92f9d21154c | 1423 | void ecc_del_point(ecc_point* p) |
wolfSSL | 0:d92f9d21154c | 1424 | { |
wolfSSL | 0:d92f9d21154c | 1425 | /* prevents free'ing null arguments */ |
wolfSSL | 0:d92f9d21154c | 1426 | if (p != NULL) { |
wolfSSL | 0:d92f9d21154c | 1427 | mp_clear(p->x); |
wolfSSL | 0:d92f9d21154c | 1428 | mp_clear(p->y); |
wolfSSL | 0:d92f9d21154c | 1429 | mp_clear(p->z); |
wolfSSL | 0:d92f9d21154c | 1430 | XFREE(p, 0, DYNAMIC_TYPE_ECC); |
wolfSSL | 0:d92f9d21154c | 1431 | } |
wolfSSL | 0:d92f9d21154c | 1432 | } |
wolfSSL | 0:d92f9d21154c | 1433 | |
wolfSSL | 0:d92f9d21154c | 1434 | |
wolfSSL | 0:d92f9d21154c | 1435 | /** Returns whether an ECC idx is valid or not |
wolfSSL | 0:d92f9d21154c | 1436 | n The idx number to check |
wolfSSL | 0:d92f9d21154c | 1437 | return 1 if valid, 0 if not |
wolfSSL | 0:d92f9d21154c | 1438 | */ |
wolfSSL | 0:d92f9d21154c | 1439 | static int ecc_is_valid_idx(int n) |
wolfSSL | 0:d92f9d21154c | 1440 | { |
wolfSSL | 0:d92f9d21154c | 1441 | int x; |
wolfSSL | 0:d92f9d21154c | 1442 | |
wolfSSL | 0:d92f9d21154c | 1443 | for (x = 0; ecc_sets[x].size != 0; x++) |
wolfSSL | 0:d92f9d21154c | 1444 | ; |
wolfSSL | 0:d92f9d21154c | 1445 | /* -1 is a valid index --- indicating that the domain params |
wolfSSL | 0:d92f9d21154c | 1446 | were supplied by the user */ |
wolfSSL | 0:d92f9d21154c | 1447 | if ((n >= -1) && (n < x)) { |
wolfSSL | 0:d92f9d21154c | 1448 | return 1; |
wolfSSL | 0:d92f9d21154c | 1449 | } |
wolfSSL | 0:d92f9d21154c | 1450 | return 0; |
wolfSSL | 0:d92f9d21154c | 1451 | } |
wolfSSL | 0:d92f9d21154c | 1452 | |
wolfSSL | 0:d92f9d21154c | 1453 | |
wolfSSL | 0:d92f9d21154c | 1454 | /** |
wolfSSL | 0:d92f9d21154c | 1455 | Create an ECC shared secret between two keys |
wolfSSL | 0:d92f9d21154c | 1456 | private_key The private ECC key |
wolfSSL | 0:d92f9d21154c | 1457 | public_key The public key |
wolfSSL | 0:d92f9d21154c | 1458 | out [out] Destination of the shared secret |
wolfSSL | 0:d92f9d21154c | 1459 | Conforms to EC-DH from ANSI X9.63 |
wolfSSL | 0:d92f9d21154c | 1460 | outlen [in/out] The max size and resulting size of the shared secret |
wolfSSL | 0:d92f9d21154c | 1461 | return MP_OKAY if successful |
wolfSSL | 0:d92f9d21154c | 1462 | */ |
wolfSSL | 0:d92f9d21154c | 1463 | int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, |
wolfSSL | 0:d92f9d21154c | 1464 | word32* outlen) |
wolfSSL | 0:d92f9d21154c | 1465 | { |
wolfSSL | 0:d92f9d21154c | 1466 | word32 x = 0; |
wolfSSL | 0:d92f9d21154c | 1467 | ecc_point* result; |
wolfSSL | 0:d92f9d21154c | 1468 | mp_int prime; |
wolfSSL | 0:d92f9d21154c | 1469 | int err; |
wolfSSL | 0:d92f9d21154c | 1470 | |
wolfSSL | 0:d92f9d21154c | 1471 | if (private_key == NULL || public_key == NULL || out == NULL || |
wolfSSL | 0:d92f9d21154c | 1472 | outlen == NULL) |
wolfSSL | 0:d92f9d21154c | 1473 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 1474 | |
wolfSSL | 0:d92f9d21154c | 1475 | /* type valid? */ |
wolfSSL | 0:d92f9d21154c | 1476 | if (private_key->type != ECC_PRIVATEKEY) { |
wolfSSL | 0:d92f9d21154c | 1477 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1478 | } |
wolfSSL | 0:d92f9d21154c | 1479 | |
wolfSSL | 0:d92f9d21154c | 1480 | if (ecc_is_valid_idx(private_key->idx) == 0 || |
wolfSSL | 0:d92f9d21154c | 1481 | ecc_is_valid_idx(public_key->idx) == 0) |
wolfSSL | 0:d92f9d21154c | 1482 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1483 | |
wolfSSL | 0:d92f9d21154c | 1484 | if (XSTRNCMP(private_key->dp->name, public_key->dp->name, ECC_MAXNAME) != 0) |
wolfSSL | 0:d92f9d21154c | 1485 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1486 | |
wolfSSL | 0:d92f9d21154c | 1487 | /* make new point */ |
wolfSSL | 0:d92f9d21154c | 1488 | result = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 1489 | if (result == NULL) { |
wolfSSL | 0:d92f9d21154c | 1490 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 1491 | } |
wolfSSL | 0:d92f9d21154c | 1492 | |
wolfSSL | 0:d92f9d21154c | 1493 | if ((err = mp_init(&prime)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1494 | ecc_del_point(result); |
wolfSSL | 0:d92f9d21154c | 1495 | return err; |
wolfSSL | 0:d92f9d21154c | 1496 | } |
wolfSSL | 0:d92f9d21154c | 1497 | |
wolfSSL | 0:d92f9d21154c | 1498 | err = mp_read_radix(&prime, (char *)private_key->dp->prime, 16); |
wolfSSL | 0:d92f9d21154c | 1499 | |
wolfSSL | 0:d92f9d21154c | 1500 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1501 | err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime,1); |
wolfSSL | 0:d92f9d21154c | 1502 | |
wolfSSL | 0:d92f9d21154c | 1503 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1504 | x = mp_unsigned_bin_size(&prime); |
wolfSSL | 0:d92f9d21154c | 1505 | if (*outlen < x) |
wolfSSL | 0:d92f9d21154c | 1506 | err = BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 1507 | } |
wolfSSL | 0:d92f9d21154c | 1508 | |
wolfSSL | 0:d92f9d21154c | 1509 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1510 | XMEMSET(out, 0, x); |
wolfSSL | 0:d92f9d21154c | 1511 | err = mp_to_unsigned_bin(result->x,out + (x - |
wolfSSL | 0:d92f9d21154c | 1512 | mp_unsigned_bin_size(result->x))); |
wolfSSL | 0:d92f9d21154c | 1513 | *outlen = x; |
wolfSSL | 0:d92f9d21154c | 1514 | } |
wolfSSL | 0:d92f9d21154c | 1515 | |
wolfSSL | 0:d92f9d21154c | 1516 | mp_clear(&prime); |
wolfSSL | 0:d92f9d21154c | 1517 | ecc_del_point(result); |
wolfSSL | 0:d92f9d21154c | 1518 | |
wolfSSL | 0:d92f9d21154c | 1519 | return err; |
wolfSSL | 0:d92f9d21154c | 1520 | } |
wolfSSL | 0:d92f9d21154c | 1521 | |
wolfSSL | 0:d92f9d21154c | 1522 | |
wolfSSL | 0:d92f9d21154c | 1523 | /* return 1 if point is at infinity, 0 if not, < 0 on error */ |
wolfSSL | 0:d92f9d21154c | 1524 | static int ecc_point_is_at_infinity(ecc_point* p) |
wolfSSL | 0:d92f9d21154c | 1525 | { |
wolfSSL | 0:d92f9d21154c | 1526 | if (p == NULL) |
wolfSSL | 0:d92f9d21154c | 1527 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 1528 | |
wolfSSL | 0:d92f9d21154c | 1529 | if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0) |
wolfSSL | 0:d92f9d21154c | 1530 | return 1; |
wolfSSL | 0:d92f9d21154c | 1531 | |
wolfSSL | 0:d92f9d21154c | 1532 | return 0; |
wolfSSL | 0:d92f9d21154c | 1533 | } |
wolfSSL | 0:d92f9d21154c | 1534 | |
wolfSSL | 0:d92f9d21154c | 1535 | |
wolfSSL | 0:d92f9d21154c | 1536 | int wc_ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp); |
wolfSSL | 0:d92f9d21154c | 1537 | |
wolfSSL | 0:d92f9d21154c | 1538 | /** |
wolfSSL | 0:d92f9d21154c | 1539 | Make a new ECC key |
wolfSSL | 0:d92f9d21154c | 1540 | rng An active RNG state |
wolfSSL | 0:d92f9d21154c | 1541 | keysize The keysize for the new key (in octets from 20 to 65 bytes) |
wolfSSL | 0:d92f9d21154c | 1542 | key [out] Destination of the newly created key |
wolfSSL | 0:d92f9d21154c | 1543 | return MP_OKAY if successful, |
wolfSSL | 0:d92f9d21154c | 1544 | upon error all allocated memory will be freed |
wolfSSL | 0:d92f9d21154c | 1545 | */ |
wolfSSL | 0:d92f9d21154c | 1546 | int wc_ecc_make_key(RNG* rng, int keysize, ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 1547 | { |
wolfSSL | 0:d92f9d21154c | 1548 | int x, err; |
wolfSSL | 0:d92f9d21154c | 1549 | |
wolfSSL | 0:d92f9d21154c | 1550 | if (key == NULL || rng == NULL) |
wolfSSL | 0:d92f9d21154c | 1551 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1552 | |
wolfSSL | 0:d92f9d21154c | 1553 | /* find key size */ |
wolfSSL | 0:d92f9d21154c | 1554 | for (x = 0; (keysize > ecc_sets[x].size) && (ecc_sets[x].size != 0); x++) |
wolfSSL | 0:d92f9d21154c | 1555 | ; |
wolfSSL | 0:d92f9d21154c | 1556 | keysize = ecc_sets[x].size; |
wolfSSL | 0:d92f9d21154c | 1557 | |
wolfSSL | 0:d92f9d21154c | 1558 | if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) { |
wolfSSL | 0:d92f9d21154c | 1559 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 1560 | } |
wolfSSL | 0:d92f9d21154c | 1561 | err = wc_ecc_make_key_ex(rng, key, &ecc_sets[x]); |
wolfSSL | 0:d92f9d21154c | 1562 | key->idx = x; |
wolfSSL | 0:d92f9d21154c | 1563 | |
wolfSSL | 0:d92f9d21154c | 1564 | return err; |
wolfSSL | 0:d92f9d21154c | 1565 | } |
wolfSSL | 0:d92f9d21154c | 1566 | |
wolfSSL | 0:d92f9d21154c | 1567 | int wc_ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp) |
wolfSSL | 0:d92f9d21154c | 1568 | { |
wolfSSL | 0:d92f9d21154c | 1569 | int err; |
wolfSSL | 0:d92f9d21154c | 1570 | ecc_point* base; |
wolfSSL | 0:d92f9d21154c | 1571 | mp_int prime; |
wolfSSL | 0:d92f9d21154c | 1572 | mp_int order; |
wolfSSL | 0:d92f9d21154c | 1573 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 1574 | byte* buf; |
wolfSSL | 0:d92f9d21154c | 1575 | #else |
wolfSSL | 0:d92f9d21154c | 1576 | byte buf[ECC_MAXSIZE]; |
wolfSSL | 0:d92f9d21154c | 1577 | #endif |
wolfSSL | 0:d92f9d21154c | 1578 | int keysize; |
wolfSSL | 0:d92f9d21154c | 1579 | int po_init = 0; /* prime order Init flag for clear */ |
wolfSSL | 0:d92f9d21154c | 1580 | |
wolfSSL | 0:d92f9d21154c | 1581 | if (key == NULL || rng == NULL || dp == NULL) |
wolfSSL | 0:d92f9d21154c | 1582 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1583 | |
wolfSSL | 0:d92f9d21154c | 1584 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 1585 | buf = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 1586 | if (buf == NULL) |
wolfSSL | 0:d92f9d21154c | 1587 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 1588 | #endif |
wolfSSL | 0:d92f9d21154c | 1589 | |
wolfSSL | 0:d92f9d21154c | 1590 | key->idx = -1; |
wolfSSL | 0:d92f9d21154c | 1591 | key->dp = dp; |
wolfSSL | 0:d92f9d21154c | 1592 | keysize = dp->size; |
wolfSSL | 0:d92f9d21154c | 1593 | |
wolfSSL | 0:d92f9d21154c | 1594 | /* allocate ram */ |
wolfSSL | 0:d92f9d21154c | 1595 | base = NULL; |
wolfSSL | 0:d92f9d21154c | 1596 | |
wolfSSL | 0:d92f9d21154c | 1597 | /* make up random string */ |
wolfSSL | 0:d92f9d21154c | 1598 | err = wc_RNG_GenerateBlock(rng, buf, keysize); |
wolfSSL | 0:d92f9d21154c | 1599 | if (err == 0) |
wolfSSL | 0:d92f9d21154c | 1600 | buf[0] |= 0x0c; |
wolfSSL | 0:d92f9d21154c | 1601 | |
wolfSSL | 0:d92f9d21154c | 1602 | /* setup the key variables */ |
wolfSSL | 0:d92f9d21154c | 1603 | if (err == 0) { |
wolfSSL | 0:d92f9d21154c | 1604 | #ifndef ALT_ECC_SIZE |
wolfSSL | 0:d92f9d21154c | 1605 | err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, |
wolfSSL | 0:d92f9d21154c | 1606 | &key->k, &prime, &order); |
wolfSSL | 0:d92f9d21154c | 1607 | #else |
wolfSSL | 0:d92f9d21154c | 1608 | key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; |
wolfSSL | 0:d92f9d21154c | 1609 | key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; |
wolfSSL | 0:d92f9d21154c | 1610 | key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; |
wolfSSL | 0:d92f9d21154c | 1611 | alt_fp_init(key->pubkey.x); |
wolfSSL | 0:d92f9d21154c | 1612 | alt_fp_init(key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 1613 | alt_fp_init(key->pubkey.z); |
wolfSSL | 0:d92f9d21154c | 1614 | err = mp_init_multi(&key->k, &prime, &order, NULL, NULL, NULL); |
wolfSSL | 0:d92f9d21154c | 1615 | #endif |
wolfSSL | 0:d92f9d21154c | 1616 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1617 | err = MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 1618 | else |
wolfSSL | 0:d92f9d21154c | 1619 | po_init = 1; |
wolfSSL | 0:d92f9d21154c | 1620 | } |
wolfSSL | 0:d92f9d21154c | 1621 | |
wolfSSL | 0:d92f9d21154c | 1622 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1623 | base = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 1624 | if (base == NULL) |
wolfSSL | 0:d92f9d21154c | 1625 | err = MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 1626 | } |
wolfSSL | 0:d92f9d21154c | 1627 | |
wolfSSL | 0:d92f9d21154c | 1628 | /* read in the specs for this key */ |
wolfSSL | 0:d92f9d21154c | 1629 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1630 | err = mp_read_radix(&prime, (char *)key->dp->prime, 16); |
wolfSSL | 0:d92f9d21154c | 1631 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1632 | err = mp_read_radix(&order, (char *)key->dp->order, 16); |
wolfSSL | 0:d92f9d21154c | 1633 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1634 | err = mp_read_radix(base->x, (char *)key->dp->Gx, 16); |
wolfSSL | 0:d92f9d21154c | 1635 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1636 | err = mp_read_radix(base->y, (char *)key->dp->Gy, 16); |
wolfSSL | 0:d92f9d21154c | 1637 | |
wolfSSL | 0:d92f9d21154c | 1638 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1639 | mp_set(base->z, 1); |
wolfSSL | 0:d92f9d21154c | 1640 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1641 | err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize); |
wolfSSL | 0:d92f9d21154c | 1642 | |
wolfSSL | 0:d92f9d21154c | 1643 | /* the key should be smaller than the order of base point */ |
wolfSSL | 0:d92f9d21154c | 1644 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1645 | if (mp_cmp(&key->k, &order) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 1646 | err = mp_mod(&key->k, &order, &key->k); |
wolfSSL | 0:d92f9d21154c | 1647 | } |
wolfSSL | 0:d92f9d21154c | 1648 | /* make the public key */ |
wolfSSL | 0:d92f9d21154c | 1649 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1650 | err = ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1); |
wolfSSL | 0:d92f9d21154c | 1651 | |
wolfSSL | 0:d92f9d21154c | 1652 | #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN |
wolfSSL | 0:d92f9d21154c | 1653 | /* validate the public key, order * pubkey = point at infinity */ |
wolfSSL | 0:d92f9d21154c | 1654 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1655 | err = ecc_check_pubkey_order(key, &prime, &order); |
wolfSSL | 0:d92f9d21154c | 1656 | #endif /* WOLFSSL_VALIDATE_KEYGEN */ |
wolfSSL | 0:d92f9d21154c | 1657 | |
wolfSSL | 0:d92f9d21154c | 1658 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1659 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 0:d92f9d21154c | 1660 | |
wolfSSL | 0:d92f9d21154c | 1661 | if (err != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1662 | /* clean up */ |
wolfSSL | 0:d92f9d21154c | 1663 | mp_clear(key->pubkey.x); |
wolfSSL | 0:d92f9d21154c | 1664 | mp_clear(key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 1665 | mp_clear(key->pubkey.z); |
wolfSSL | 0:d92f9d21154c | 1666 | mp_clear(&key->k); |
wolfSSL | 0:d92f9d21154c | 1667 | } |
wolfSSL | 0:d92f9d21154c | 1668 | ecc_del_point(base); |
wolfSSL | 0:d92f9d21154c | 1669 | if (po_init) { |
wolfSSL | 0:d92f9d21154c | 1670 | mp_clear(&prime); |
wolfSSL | 0:d92f9d21154c | 1671 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 1672 | } |
wolfSSL | 0:d92f9d21154c | 1673 | |
wolfSSL | 0:d92f9d21154c | 1674 | ForceZero(buf, ECC_MAXSIZE); |
wolfSSL | 0:d92f9d21154c | 1675 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 1676 | XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 1677 | #endif |
wolfSSL | 0:d92f9d21154c | 1678 | |
wolfSSL | 0:d92f9d21154c | 1679 | return err; |
wolfSSL | 0:d92f9d21154c | 1680 | } |
wolfSSL | 0:d92f9d21154c | 1681 | |
wolfSSL | 0:d92f9d21154c | 1682 | |
wolfSSL | 0:d92f9d21154c | 1683 | /* Setup dynamic pointers is using normal math for proper freeing */ |
wolfSSL | 0:d92f9d21154c | 1684 | int wc_ecc_init(ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 1685 | { |
wolfSSL | 0:d92f9d21154c | 1686 | (void)key; |
wolfSSL | 0:d92f9d21154c | 1687 | |
wolfSSL | 0:d92f9d21154c | 1688 | #ifndef USE_FAST_MATH |
wolfSSL | 0:d92f9d21154c | 1689 | key->pubkey.x->dp = NULL; |
wolfSSL | 0:d92f9d21154c | 1690 | key->pubkey.y->dp = NULL; |
wolfSSL | 0:d92f9d21154c | 1691 | key->pubkey.z->dp = NULL; |
wolfSSL | 0:d92f9d21154c | 1692 | |
wolfSSL | 0:d92f9d21154c | 1693 | key->k.dp = NULL; |
wolfSSL | 0:d92f9d21154c | 1694 | #endif |
wolfSSL | 0:d92f9d21154c | 1695 | |
wolfSSL | 0:d92f9d21154c | 1696 | #ifdef ALT_ECC_SIZE |
wolfSSL | 0:d92f9d21154c | 1697 | if (mp_init(&key->k) != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1698 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 1699 | |
wolfSSL | 0:d92f9d21154c | 1700 | key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; |
wolfSSL | 0:d92f9d21154c | 1701 | key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; |
wolfSSL | 0:d92f9d21154c | 1702 | key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; |
wolfSSL | 0:d92f9d21154c | 1703 | alt_fp_init(key->pubkey.x); |
wolfSSL | 0:d92f9d21154c | 1704 | alt_fp_init(key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 1705 | alt_fp_init(key->pubkey.z); |
wolfSSL | 0:d92f9d21154c | 1706 | #endif |
wolfSSL | 0:d92f9d21154c | 1707 | |
wolfSSL | 0:d92f9d21154c | 1708 | return 0; |
wolfSSL | 0:d92f9d21154c | 1709 | } |
wolfSSL | 0:d92f9d21154c | 1710 | |
wolfSSL | 0:d92f9d21154c | 1711 | |
wolfSSL | 0:d92f9d21154c | 1712 | /** |
wolfSSL | 0:d92f9d21154c | 1713 | Sign a message digest |
wolfSSL | 0:d92f9d21154c | 1714 | in The message digest to sign |
wolfSSL | 0:d92f9d21154c | 1715 | inlen The length of the digest |
wolfSSL | 0:d92f9d21154c | 1716 | out [out] The destination for the signature |
wolfSSL | 0:d92f9d21154c | 1717 | outlen [in/out] The max size and resulting size of the signature |
wolfSSL | 0:d92f9d21154c | 1718 | key A private ECC key |
wolfSSL | 0:d92f9d21154c | 1719 | return MP_OKAY if successful |
wolfSSL | 0:d92f9d21154c | 1720 | */ |
wolfSSL | 0:d92f9d21154c | 1721 | int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, |
wolfSSL | 0:d92f9d21154c | 1722 | RNG* rng, ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 1723 | { |
wolfSSL | 0:d92f9d21154c | 1724 | mp_int r; |
wolfSSL | 0:d92f9d21154c | 1725 | mp_int s; |
wolfSSL | 0:d92f9d21154c | 1726 | mp_int e; |
wolfSSL | 0:d92f9d21154c | 1727 | mp_int p; |
wolfSSL | 0:d92f9d21154c | 1728 | int err; |
wolfSSL | 0:d92f9d21154c | 1729 | |
wolfSSL | 0:d92f9d21154c | 1730 | if (in == NULL || out == NULL || outlen == NULL || key == NULL || rng ==NULL) |
wolfSSL | 0:d92f9d21154c | 1731 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1732 | |
wolfSSL | 0:d92f9d21154c | 1733 | /* is this a private key? */ |
wolfSSL | 0:d92f9d21154c | 1734 | if (key->type != ECC_PRIVATEKEY) { |
wolfSSL | 0:d92f9d21154c | 1735 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1736 | } |
wolfSSL | 0:d92f9d21154c | 1737 | |
wolfSSL | 0:d92f9d21154c | 1738 | /* is the IDX valid ? */ |
wolfSSL | 0:d92f9d21154c | 1739 | if (ecc_is_valid_idx(key->idx) != 1) { |
wolfSSL | 0:d92f9d21154c | 1740 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1741 | } |
wolfSSL | 0:d92f9d21154c | 1742 | |
wolfSSL | 0:d92f9d21154c | 1743 | /* get the hash and load it as a bignum into 'e' */ |
wolfSSL | 0:d92f9d21154c | 1744 | /* init the bignums */ |
wolfSSL | 0:d92f9d21154c | 1745 | if ((err = mp_init_multi(&r, &s, &p, &e, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1746 | return err; |
wolfSSL | 0:d92f9d21154c | 1747 | } |
wolfSSL | 0:d92f9d21154c | 1748 | err = mp_read_radix(&p, (char *)key->dp->order, 16); |
wolfSSL | 0:d92f9d21154c | 1749 | |
wolfSSL | 0:d92f9d21154c | 1750 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1751 | /* we may need to truncate if hash is longer than key size */ |
wolfSSL | 0:d92f9d21154c | 1752 | word32 orderBits = mp_count_bits(&p); |
wolfSSL | 0:d92f9d21154c | 1753 | |
wolfSSL | 0:d92f9d21154c | 1754 | /* truncate down to byte size, may be all that's needed */ |
wolfSSL | 0:d92f9d21154c | 1755 | if ( (WOLFSSL_BIT_SIZE * inlen) > orderBits) |
wolfSSL | 0:d92f9d21154c | 1756 | inlen = (orderBits + WOLFSSL_BIT_SIZE - 1)/WOLFSSL_BIT_SIZE; |
wolfSSL | 0:d92f9d21154c | 1757 | err = mp_read_unsigned_bin(&e, (byte*)in, inlen); |
wolfSSL | 0:d92f9d21154c | 1758 | |
wolfSSL | 0:d92f9d21154c | 1759 | /* may still need bit truncation too */ |
wolfSSL | 0:d92f9d21154c | 1760 | if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits) |
wolfSSL | 0:d92f9d21154c | 1761 | mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); |
wolfSSL | 0:d92f9d21154c | 1762 | } |
wolfSSL | 0:d92f9d21154c | 1763 | |
wolfSSL | 0:d92f9d21154c | 1764 | /* make up a key and export the public copy */ |
wolfSSL | 0:d92f9d21154c | 1765 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1766 | int loop_check = 0; |
wolfSSL | 0:d92f9d21154c | 1767 | ecc_key pubkey; |
wolfSSL | 0:d92f9d21154c | 1768 | wc_ecc_init(&pubkey); |
wolfSSL | 0:d92f9d21154c | 1769 | for (;;) { |
wolfSSL | 0:d92f9d21154c | 1770 | if (++loop_check > 64) { |
wolfSSL | 0:d92f9d21154c | 1771 | err = RNG_FAILURE_E; |
wolfSSL | 0:d92f9d21154c | 1772 | break; |
wolfSSL | 0:d92f9d21154c | 1773 | } |
wolfSSL | 0:d92f9d21154c | 1774 | err = wc_ecc_make_key_ex(rng, &pubkey, key->dp); |
wolfSSL | 0:d92f9d21154c | 1775 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1776 | |
wolfSSL | 0:d92f9d21154c | 1777 | /* find r = x1 mod n */ |
wolfSSL | 0:d92f9d21154c | 1778 | err = mp_mod(pubkey.pubkey.x, &p, &r); |
wolfSSL | 0:d92f9d21154c | 1779 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1780 | |
wolfSSL | 0:d92f9d21154c | 1781 | if (mp_iszero(&r) == MP_YES) { |
wolfSSL | 0:d92f9d21154c | 1782 | mp_clear(pubkey.pubkey.x); |
wolfSSL | 0:d92f9d21154c | 1783 | mp_clear(pubkey.pubkey.y); |
wolfSSL | 0:d92f9d21154c | 1784 | mp_clear(pubkey.pubkey.z); |
wolfSSL | 0:d92f9d21154c | 1785 | mp_clear(&pubkey.k); |
wolfSSL | 0:d92f9d21154c | 1786 | } |
wolfSSL | 0:d92f9d21154c | 1787 | else { |
wolfSSL | 0:d92f9d21154c | 1788 | /* find s = (e + xr)/k */ |
wolfSSL | 0:d92f9d21154c | 1789 | err = mp_invmod(&pubkey.k, &p, &pubkey.k); |
wolfSSL | 0:d92f9d21154c | 1790 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1791 | |
wolfSSL | 0:d92f9d21154c | 1792 | err = mp_mulmod(&key->k, &r, &p, &s); /* s = xr */ |
wolfSSL | 0:d92f9d21154c | 1793 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1794 | |
wolfSSL | 0:d92f9d21154c | 1795 | err = mp_add(&e, &s, &s); /* s = e + xr */ |
wolfSSL | 0:d92f9d21154c | 1796 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1797 | |
wolfSSL | 0:d92f9d21154c | 1798 | err = mp_mod(&s, &p, &s); /* s = e + xr */ |
wolfSSL | 0:d92f9d21154c | 1799 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1800 | |
wolfSSL | 0:d92f9d21154c | 1801 | err = mp_mulmod(&s, &pubkey.k, &p, &s); /* s = (e + xr)/k */ |
wolfSSL | 0:d92f9d21154c | 1802 | if (err != MP_OKAY) break; |
wolfSSL | 0:d92f9d21154c | 1803 | |
wolfSSL | 0:d92f9d21154c | 1804 | if (mp_iszero(&s) == MP_NO) |
wolfSSL | 0:d92f9d21154c | 1805 | break; |
wolfSSL | 0:d92f9d21154c | 1806 | } |
wolfSSL | 0:d92f9d21154c | 1807 | } |
wolfSSL | 0:d92f9d21154c | 1808 | wc_ecc_free(&pubkey); |
wolfSSL | 0:d92f9d21154c | 1809 | } |
wolfSSL | 0:d92f9d21154c | 1810 | |
wolfSSL | 0:d92f9d21154c | 1811 | /* store as SEQUENCE { r, s -- integer } */ |
wolfSSL | 0:d92f9d21154c | 1812 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1813 | err = StoreECC_DSA_Sig(out, outlen, &r, &s); |
wolfSSL | 0:d92f9d21154c | 1814 | |
wolfSSL | 0:d92f9d21154c | 1815 | mp_clear(&r); |
wolfSSL | 0:d92f9d21154c | 1816 | mp_clear(&s); |
wolfSSL | 0:d92f9d21154c | 1817 | mp_clear(&p); |
wolfSSL | 0:d92f9d21154c | 1818 | mp_clear(&e); |
wolfSSL | 0:d92f9d21154c | 1819 | |
wolfSSL | 0:d92f9d21154c | 1820 | return err; |
wolfSSL | 0:d92f9d21154c | 1821 | } |
wolfSSL | 0:d92f9d21154c | 1822 | |
wolfSSL | 0:d92f9d21154c | 1823 | |
wolfSSL | 0:d92f9d21154c | 1824 | /** |
wolfSSL | 0:d92f9d21154c | 1825 | Free an ECC key from memory |
wolfSSL | 0:d92f9d21154c | 1826 | key The key you wish to free |
wolfSSL | 0:d92f9d21154c | 1827 | */ |
wolfSSL | 0:d92f9d21154c | 1828 | void wc_ecc_free(ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 1829 | { |
wolfSSL | 0:d92f9d21154c | 1830 | if (key == NULL) |
wolfSSL | 0:d92f9d21154c | 1831 | return; |
wolfSSL | 0:d92f9d21154c | 1832 | |
wolfSSL | 0:d92f9d21154c | 1833 | mp_clear(key->pubkey.x); |
wolfSSL | 0:d92f9d21154c | 1834 | mp_clear(key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 1835 | mp_clear(key->pubkey.z); |
wolfSSL | 0:d92f9d21154c | 1836 | mp_clear(&key->k); |
wolfSSL | 0:d92f9d21154c | 1837 | } |
wolfSSL | 0:d92f9d21154c | 1838 | |
wolfSSL | 0:d92f9d21154c | 1839 | |
wolfSSL | 0:d92f9d21154c | 1840 | #ifdef USE_FAST_MATH |
wolfSSL | 0:d92f9d21154c | 1841 | #define GEN_MEM_ERR FP_MEM |
wolfSSL | 0:d92f9d21154c | 1842 | #else |
wolfSSL | 0:d92f9d21154c | 1843 | #define GEN_MEM_ERR MP_MEM |
wolfSSL | 0:d92f9d21154c | 1844 | #endif |
wolfSSL | 0:d92f9d21154c | 1845 | |
wolfSSL | 0:d92f9d21154c | 1846 | #ifdef ECC_SHAMIR |
wolfSSL | 0:d92f9d21154c | 1847 | |
wolfSSL | 0:d92f9d21154c | 1848 | /** Computes kA*A + kB*B = C using Shamir's Trick |
wolfSSL | 0:d92f9d21154c | 1849 | A First point to multiply |
wolfSSL | 0:d92f9d21154c | 1850 | kA What to multiple A by |
wolfSSL | 0:d92f9d21154c | 1851 | B Second point to multiply |
wolfSSL | 0:d92f9d21154c | 1852 | kB What to multiple B by |
wolfSSL | 0:d92f9d21154c | 1853 | C [out] Destination point (can overlap with A or B) |
wolfSSL | 0:d92f9d21154c | 1854 | modulus Modulus for curve |
wolfSSL | 0:d92f9d21154c | 1855 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 1856 | */ |
wolfSSL | 0:d92f9d21154c | 1857 | #ifdef FP_ECC |
wolfSSL | 0:d92f9d21154c | 1858 | static int normal_ecc_mul2add(ecc_point* A, mp_int* kA, |
wolfSSL | 0:d92f9d21154c | 1859 | ecc_point* B, mp_int* kB, |
wolfSSL | 0:d92f9d21154c | 1860 | ecc_point* C, mp_int* modulus) |
wolfSSL | 0:d92f9d21154c | 1861 | #else |
wolfSSL | 0:d92f9d21154c | 1862 | static int ecc_mul2add(ecc_point* A, mp_int* kA, |
wolfSSL | 0:d92f9d21154c | 1863 | ecc_point* B, mp_int* kB, |
wolfSSL | 0:d92f9d21154c | 1864 | ecc_point* C, mp_int* modulus) |
wolfSSL | 0:d92f9d21154c | 1865 | #endif |
wolfSSL | 0:d92f9d21154c | 1866 | { |
wolfSSL | 0:d92f9d21154c | 1867 | ecc_point* precomp[16]; |
wolfSSL | 0:d92f9d21154c | 1868 | unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble; |
wolfSSL | 0:d92f9d21154c | 1869 | unsigned char* tA; |
wolfSSL | 0:d92f9d21154c | 1870 | unsigned char* tB; |
wolfSSL | 0:d92f9d21154c | 1871 | int err = MP_OKAY, first; |
wolfSSL | 0:d92f9d21154c | 1872 | int muInit = 0; |
wolfSSL | 0:d92f9d21154c | 1873 | int tableInit = 0; |
wolfSSL | 0:d92f9d21154c | 1874 | mp_digit mp; |
wolfSSL | 0:d92f9d21154c | 1875 | mp_int mu; |
wolfSSL | 0:d92f9d21154c | 1876 | |
wolfSSL | 0:d92f9d21154c | 1877 | /* argchks */ |
wolfSSL | 0:d92f9d21154c | 1878 | if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL || |
wolfSSL | 0:d92f9d21154c | 1879 | modulus == NULL) |
wolfSSL | 0:d92f9d21154c | 1880 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 1881 | |
wolfSSL | 0:d92f9d21154c | 1882 | |
wolfSSL | 0:d92f9d21154c | 1883 | /* allocate memory */ |
wolfSSL | 0:d92f9d21154c | 1884 | tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 1885 | if (tA == NULL) { |
wolfSSL | 0:d92f9d21154c | 1886 | return GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 1887 | } |
wolfSSL | 0:d92f9d21154c | 1888 | tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 1889 | if (tB == NULL) { |
wolfSSL | 0:d92f9d21154c | 1890 | XFREE(tA, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 1891 | return GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 1892 | } |
wolfSSL | 0:d92f9d21154c | 1893 | XMEMSET(tA, 0, ECC_BUFSIZE); |
wolfSSL | 0:d92f9d21154c | 1894 | XMEMSET(tB, 0, ECC_BUFSIZE); |
wolfSSL | 0:d92f9d21154c | 1895 | |
wolfSSL | 0:d92f9d21154c | 1896 | /* get sizes */ |
wolfSSL | 0:d92f9d21154c | 1897 | lenA = mp_unsigned_bin_size(kA); |
wolfSSL | 0:d92f9d21154c | 1898 | lenB = mp_unsigned_bin_size(kB); |
wolfSSL | 0:d92f9d21154c | 1899 | len = MAX(lenA, lenB); |
wolfSSL | 0:d92f9d21154c | 1900 | |
wolfSSL | 0:d92f9d21154c | 1901 | /* sanity check */ |
wolfSSL | 0:d92f9d21154c | 1902 | if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) { |
wolfSSL | 0:d92f9d21154c | 1903 | err = BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 1904 | } |
wolfSSL | 0:d92f9d21154c | 1905 | |
wolfSSL | 0:d92f9d21154c | 1906 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1907 | /* extract and justify kA */ |
wolfSSL | 0:d92f9d21154c | 1908 | err = mp_to_unsigned_bin(kA, (len - lenA) + tA); |
wolfSSL | 0:d92f9d21154c | 1909 | |
wolfSSL | 0:d92f9d21154c | 1910 | /* extract and justify kB */ |
wolfSSL | 0:d92f9d21154c | 1911 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1912 | err = mp_to_unsigned_bin(kB, (len - lenB) + tB); |
wolfSSL | 0:d92f9d21154c | 1913 | |
wolfSSL | 0:d92f9d21154c | 1914 | /* allocate the table */ |
wolfSSL | 0:d92f9d21154c | 1915 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1916 | for (x = 0; x < 16; x++) { |
wolfSSL | 0:d92f9d21154c | 1917 | precomp[x] = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 1918 | if (precomp[x] == NULL) { |
wolfSSL | 0:d92f9d21154c | 1919 | for (y = 0; y < x; ++y) { |
wolfSSL | 0:d92f9d21154c | 1920 | ecc_del_point(precomp[y]); |
wolfSSL | 0:d92f9d21154c | 1921 | } |
wolfSSL | 0:d92f9d21154c | 1922 | err = GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 1923 | break; |
wolfSSL | 0:d92f9d21154c | 1924 | } |
wolfSSL | 0:d92f9d21154c | 1925 | } |
wolfSSL | 0:d92f9d21154c | 1926 | } |
wolfSSL | 0:d92f9d21154c | 1927 | } |
wolfSSL | 0:d92f9d21154c | 1928 | |
wolfSSL | 0:d92f9d21154c | 1929 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1930 | tableInit = 1; |
wolfSSL | 0:d92f9d21154c | 1931 | |
wolfSSL | 0:d92f9d21154c | 1932 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1933 | /* init montgomery reduction */ |
wolfSSL | 0:d92f9d21154c | 1934 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1935 | |
wolfSSL | 0:d92f9d21154c | 1936 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1937 | err = mp_init(&mu); |
wolfSSL | 0:d92f9d21154c | 1938 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1939 | muInit = 1; |
wolfSSL | 0:d92f9d21154c | 1940 | |
wolfSSL | 0:d92f9d21154c | 1941 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1942 | err = mp_montgomery_calc_normalization(&mu, modulus); |
wolfSSL | 0:d92f9d21154c | 1943 | |
wolfSSL | 0:d92f9d21154c | 1944 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1945 | /* copy ones ... */ |
wolfSSL | 0:d92f9d21154c | 1946 | err = mp_mulmod(A->x, &mu, modulus, precomp[1]->x); |
wolfSSL | 0:d92f9d21154c | 1947 | |
wolfSSL | 0:d92f9d21154c | 1948 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1949 | err = mp_mulmod(A->y, &mu, modulus, precomp[1]->y); |
wolfSSL | 0:d92f9d21154c | 1950 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1951 | err = mp_mulmod(A->z, &mu, modulus, precomp[1]->z); |
wolfSSL | 0:d92f9d21154c | 1952 | |
wolfSSL | 0:d92f9d21154c | 1953 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1954 | err = mp_mulmod(B->x, &mu, modulus, precomp[1<<2]->x); |
wolfSSL | 0:d92f9d21154c | 1955 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1956 | err = mp_mulmod(B->y, &mu, modulus, precomp[1<<2]->y); |
wolfSSL | 0:d92f9d21154c | 1957 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1958 | err = mp_mulmod(B->z, &mu, modulus, precomp[1<<2]->z); |
wolfSSL | 0:d92f9d21154c | 1959 | |
wolfSSL | 0:d92f9d21154c | 1960 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1961 | /* precomp [i,0](A + B) table */ |
wolfSSL | 0:d92f9d21154c | 1962 | err = ecc_projective_dbl_point(precomp[1], precomp[2], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1963 | |
wolfSSL | 0:d92f9d21154c | 1964 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1965 | err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3], |
wolfSSL | 0:d92f9d21154c | 1966 | modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1967 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1968 | /* precomp [0,i](A + B) table */ |
wolfSSL | 0:d92f9d21154c | 1969 | err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1970 | |
wolfSSL | 0:d92f9d21154c | 1971 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1972 | err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2], |
wolfSSL | 0:d92f9d21154c | 1973 | modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1974 | |
wolfSSL | 0:d92f9d21154c | 1975 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1976 | /* precomp [i,j](A + B) table (i != 0, j != 0) */ |
wolfSSL | 0:d92f9d21154c | 1977 | for (x = 1; x < 4; x++) { |
wolfSSL | 0:d92f9d21154c | 1978 | for (y = 1; y < 4; y++) { |
wolfSSL | 0:d92f9d21154c | 1979 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 1980 | err = ecc_projective_add_point(precomp[x], precomp[(y<<2)], |
wolfSSL | 0:d92f9d21154c | 1981 | precomp[x+(y<<2)], modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 1982 | } |
wolfSSL | 0:d92f9d21154c | 1983 | } |
wolfSSL | 0:d92f9d21154c | 1984 | } |
wolfSSL | 0:d92f9d21154c | 1985 | |
wolfSSL | 0:d92f9d21154c | 1986 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 1987 | nibble = 3; |
wolfSSL | 0:d92f9d21154c | 1988 | first = 1; |
wolfSSL | 0:d92f9d21154c | 1989 | bitbufA = tA[0]; |
wolfSSL | 0:d92f9d21154c | 1990 | bitbufB = tB[0]; |
wolfSSL | 0:d92f9d21154c | 1991 | |
wolfSSL | 0:d92f9d21154c | 1992 | /* for every byte of the multiplicands */ |
wolfSSL | 0:d92f9d21154c | 1993 | for (x = -1;; ) { |
wolfSSL | 0:d92f9d21154c | 1994 | /* grab a nibble */ |
wolfSSL | 0:d92f9d21154c | 1995 | if (++nibble == 4) { |
wolfSSL | 0:d92f9d21154c | 1996 | ++x; if (x == len) break; |
wolfSSL | 0:d92f9d21154c | 1997 | bitbufA = tA[x]; |
wolfSSL | 0:d92f9d21154c | 1998 | bitbufB = tB[x]; |
wolfSSL | 0:d92f9d21154c | 1999 | nibble = 0; |
wolfSSL | 0:d92f9d21154c | 2000 | } |
wolfSSL | 0:d92f9d21154c | 2001 | |
wolfSSL | 0:d92f9d21154c | 2002 | /* extract two bits from both, shift/update */ |
wolfSSL | 0:d92f9d21154c | 2003 | nA = (bitbufA >> 6) & 0x03; |
wolfSSL | 0:d92f9d21154c | 2004 | nB = (bitbufB >> 6) & 0x03; |
wolfSSL | 0:d92f9d21154c | 2005 | bitbufA = (bitbufA << 2) & 0xFF; |
wolfSSL | 0:d92f9d21154c | 2006 | bitbufB = (bitbufB << 2) & 0xFF; |
wolfSSL | 0:d92f9d21154c | 2007 | |
wolfSSL | 0:d92f9d21154c | 2008 | /* if both zero, if first, continue */ |
wolfSSL | 0:d92f9d21154c | 2009 | if ((nA == 0) && (nB == 0) && (first == 1)) { |
wolfSSL | 0:d92f9d21154c | 2010 | continue; |
wolfSSL | 0:d92f9d21154c | 2011 | } |
wolfSSL | 0:d92f9d21154c | 2012 | |
wolfSSL | 0:d92f9d21154c | 2013 | /* double twice, only if this isn't the first */ |
wolfSSL | 0:d92f9d21154c | 2014 | if (first == 0) { |
wolfSSL | 0:d92f9d21154c | 2015 | /* double twice */ |
wolfSSL | 0:d92f9d21154c | 2016 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2017 | err = ecc_projective_dbl_point(C, C, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 2018 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2019 | err = ecc_projective_dbl_point(C, C, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 2020 | else |
wolfSSL | 0:d92f9d21154c | 2021 | break; |
wolfSSL | 0:d92f9d21154c | 2022 | } |
wolfSSL | 0:d92f9d21154c | 2023 | |
wolfSSL | 0:d92f9d21154c | 2024 | /* if not both zero */ |
wolfSSL | 0:d92f9d21154c | 2025 | if ((nA != 0) || (nB != 0)) { |
wolfSSL | 0:d92f9d21154c | 2026 | if (first == 1) { |
wolfSSL | 0:d92f9d21154c | 2027 | /* if first, copy from table */ |
wolfSSL | 0:d92f9d21154c | 2028 | first = 0; |
wolfSSL | 0:d92f9d21154c | 2029 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2030 | err = mp_copy(precomp[nA + (nB<<2)]->x, C->x); |
wolfSSL | 0:d92f9d21154c | 2031 | |
wolfSSL | 0:d92f9d21154c | 2032 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2033 | err = mp_copy(precomp[nA + (nB<<2)]->y, C->y); |
wolfSSL | 0:d92f9d21154c | 2034 | |
wolfSSL | 0:d92f9d21154c | 2035 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2036 | err = mp_copy(precomp[nA + (nB<<2)]->z, C->z); |
wolfSSL | 0:d92f9d21154c | 2037 | else |
wolfSSL | 0:d92f9d21154c | 2038 | break; |
wolfSSL | 0:d92f9d21154c | 2039 | } else { |
wolfSSL | 0:d92f9d21154c | 2040 | /* if not first, add from table */ |
wolfSSL | 0:d92f9d21154c | 2041 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2042 | err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C, |
wolfSSL | 0:d92f9d21154c | 2043 | modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 2044 | else |
wolfSSL | 0:d92f9d21154c | 2045 | break; |
wolfSSL | 0:d92f9d21154c | 2046 | } |
wolfSSL | 0:d92f9d21154c | 2047 | } |
wolfSSL | 0:d92f9d21154c | 2048 | } |
wolfSSL | 0:d92f9d21154c | 2049 | } |
wolfSSL | 0:d92f9d21154c | 2050 | |
wolfSSL | 0:d92f9d21154c | 2051 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2052 | /* reduce to affine */ |
wolfSSL | 0:d92f9d21154c | 2053 | err = ecc_map(C, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 2054 | |
wolfSSL | 0:d92f9d21154c | 2055 | /* clean up */ |
wolfSSL | 0:d92f9d21154c | 2056 | if (muInit) |
wolfSSL | 0:d92f9d21154c | 2057 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 2058 | |
wolfSSL | 0:d92f9d21154c | 2059 | if (tableInit) { |
wolfSSL | 0:d92f9d21154c | 2060 | for (x = 0; x < 16; x++) { |
wolfSSL | 0:d92f9d21154c | 2061 | ecc_del_point(precomp[x]); |
wolfSSL | 0:d92f9d21154c | 2062 | } |
wolfSSL | 0:d92f9d21154c | 2063 | } |
wolfSSL | 0:d92f9d21154c | 2064 | ForceZero(tA, ECC_BUFSIZE); |
wolfSSL | 0:d92f9d21154c | 2065 | ForceZero(tB, ECC_BUFSIZE); |
wolfSSL | 0:d92f9d21154c | 2066 | XFREE(tA, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 2067 | XFREE(tB, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 2068 | |
wolfSSL | 0:d92f9d21154c | 2069 | return err; |
wolfSSL | 0:d92f9d21154c | 2070 | } |
wolfSSL | 0:d92f9d21154c | 2071 | |
wolfSSL | 0:d92f9d21154c | 2072 | |
wolfSSL | 0:d92f9d21154c | 2073 | #endif /* ECC_SHAMIR */ |
wolfSSL | 0:d92f9d21154c | 2074 | |
wolfSSL | 0:d92f9d21154c | 2075 | |
wolfSSL | 0:d92f9d21154c | 2076 | |
wolfSSL | 0:d92f9d21154c | 2077 | /* verify |
wolfSSL | 0:d92f9d21154c | 2078 | * |
wolfSSL | 0:d92f9d21154c | 2079 | * w = s^-1 mod n |
wolfSSL | 0:d92f9d21154c | 2080 | * u1 = xw |
wolfSSL | 0:d92f9d21154c | 2081 | * u2 = rw |
wolfSSL | 0:d92f9d21154c | 2082 | * X = u1*G + u2*Q |
wolfSSL | 0:d92f9d21154c | 2083 | * v = X_x1 mod n |
wolfSSL | 0:d92f9d21154c | 2084 | * accept if v == r |
wolfSSL | 0:d92f9d21154c | 2085 | */ |
wolfSSL | 0:d92f9d21154c | 2086 | |
wolfSSL | 0:d92f9d21154c | 2087 | /** |
wolfSSL | 0:d92f9d21154c | 2088 | Verify an ECC signature |
wolfSSL | 0:d92f9d21154c | 2089 | sig The signature to verify |
wolfSSL | 0:d92f9d21154c | 2090 | siglen The length of the signature (octets) |
wolfSSL | 0:d92f9d21154c | 2091 | hash The hash (message digest) that was signed |
wolfSSL | 0:d92f9d21154c | 2092 | hashlen The length of the hash (octets) |
wolfSSL | 0:d92f9d21154c | 2093 | stat Result of signature, 1==valid, 0==invalid |
wolfSSL | 0:d92f9d21154c | 2094 | key The corresponding public ECC key |
wolfSSL | 0:d92f9d21154c | 2095 | return MP_OKAY if successful (even if the signature is not valid) |
wolfSSL | 0:d92f9d21154c | 2096 | */ |
wolfSSL | 0:d92f9d21154c | 2097 | int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, |
wolfSSL | 0:d92f9d21154c | 2098 | word32 hashlen, int* stat, ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 2099 | { |
wolfSSL | 0:d92f9d21154c | 2100 | ecc_point *mG, *mQ; |
wolfSSL | 0:d92f9d21154c | 2101 | mp_int r; |
wolfSSL | 0:d92f9d21154c | 2102 | mp_int s; |
wolfSSL | 0:d92f9d21154c | 2103 | mp_int v; |
wolfSSL | 0:d92f9d21154c | 2104 | mp_int w; |
wolfSSL | 0:d92f9d21154c | 2105 | mp_int u1; |
wolfSSL | 0:d92f9d21154c | 2106 | mp_int u2; |
wolfSSL | 0:d92f9d21154c | 2107 | mp_int e; |
wolfSSL | 0:d92f9d21154c | 2108 | mp_int p; |
wolfSSL | 0:d92f9d21154c | 2109 | mp_int m; |
wolfSSL | 0:d92f9d21154c | 2110 | int err; |
wolfSSL | 0:d92f9d21154c | 2111 | |
wolfSSL | 0:d92f9d21154c | 2112 | if (sig == NULL || hash == NULL || stat == NULL || key == NULL) |
wolfSSL | 0:d92f9d21154c | 2113 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2114 | |
wolfSSL | 0:d92f9d21154c | 2115 | /* default to invalid signature */ |
wolfSSL | 0:d92f9d21154c | 2116 | *stat = 0; |
wolfSSL | 0:d92f9d21154c | 2117 | |
wolfSSL | 0:d92f9d21154c | 2118 | /* is the IDX valid ? */ |
wolfSSL | 0:d92f9d21154c | 2119 | if (ecc_is_valid_idx(key->idx) != 1) { |
wolfSSL | 0:d92f9d21154c | 2120 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2121 | } |
wolfSSL | 0:d92f9d21154c | 2122 | |
wolfSSL | 0:d92f9d21154c | 2123 | /* allocate ints */ |
wolfSSL | 0:d92f9d21154c | 2124 | if ((err = mp_init_multi(&v, &w, &u1, &u2, &p, &e)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2125 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2126 | } |
wolfSSL | 0:d92f9d21154c | 2127 | |
wolfSSL | 0:d92f9d21154c | 2128 | if ((err = mp_init(&m)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2129 | mp_clear(&v); |
wolfSSL | 0:d92f9d21154c | 2130 | mp_clear(&w); |
wolfSSL | 0:d92f9d21154c | 2131 | mp_clear(&u1); |
wolfSSL | 0:d92f9d21154c | 2132 | mp_clear(&u2); |
wolfSSL | 0:d92f9d21154c | 2133 | mp_clear(&p); |
wolfSSL | 0:d92f9d21154c | 2134 | mp_clear(&e); |
wolfSSL | 0:d92f9d21154c | 2135 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2136 | } |
wolfSSL | 0:d92f9d21154c | 2137 | |
wolfSSL | 0:d92f9d21154c | 2138 | /* allocate points */ |
wolfSSL | 0:d92f9d21154c | 2139 | mG = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 2140 | mQ = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 2141 | if (mQ == NULL || mG == NULL) |
wolfSSL | 0:d92f9d21154c | 2142 | err = MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2143 | |
wolfSSL | 0:d92f9d21154c | 2144 | /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s. |
wolfSSL | 0:d92f9d21154c | 2145 | * If either of those don't allocate correctly, none of |
wolfSSL | 0:d92f9d21154c | 2146 | * the rest of this function will execute, and everything |
wolfSSL | 0:d92f9d21154c | 2147 | * gets cleaned up at the end. */ |
wolfSSL | 0:d92f9d21154c | 2148 | XMEMSET(&r, 0, sizeof(r)); |
wolfSSL | 0:d92f9d21154c | 2149 | XMEMSET(&s, 0, sizeof(s)); |
wolfSSL | 0:d92f9d21154c | 2150 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2151 | err = DecodeECC_DSA_Sig(sig, siglen, &r, &s); |
wolfSSL | 0:d92f9d21154c | 2152 | |
wolfSSL | 0:d92f9d21154c | 2153 | /* get the order */ |
wolfSSL | 0:d92f9d21154c | 2154 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2155 | err = mp_read_radix(&p, (char *)key->dp->order, 16); |
wolfSSL | 0:d92f9d21154c | 2156 | |
wolfSSL | 0:d92f9d21154c | 2157 | /* get the modulus */ |
wolfSSL | 0:d92f9d21154c | 2158 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2159 | err = mp_read_radix(&m, (char *)key->dp->prime, 16); |
wolfSSL | 0:d92f9d21154c | 2160 | |
wolfSSL | 0:d92f9d21154c | 2161 | /* check for zero */ |
wolfSSL | 0:d92f9d21154c | 2162 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2163 | if (mp_iszero(&r) || mp_iszero(&s) || mp_cmp(&r, &p) != MP_LT || |
wolfSSL | 0:d92f9d21154c | 2164 | mp_cmp(&s, &p) != MP_LT) |
wolfSSL | 0:d92f9d21154c | 2165 | err = MP_ZERO_E; |
wolfSSL | 0:d92f9d21154c | 2166 | } |
wolfSSL | 0:d92f9d21154c | 2167 | /* read hash */ |
wolfSSL | 0:d92f9d21154c | 2168 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2169 | /* we may need to truncate if hash is longer than key size */ |
wolfSSL | 0:d92f9d21154c | 2170 | unsigned int orderBits = mp_count_bits(&p); |
wolfSSL | 0:d92f9d21154c | 2171 | |
wolfSSL | 0:d92f9d21154c | 2172 | /* truncate down to byte size, may be all that's needed */ |
wolfSSL | 0:d92f9d21154c | 2173 | if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits) |
wolfSSL | 0:d92f9d21154c | 2174 | hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1)/WOLFSSL_BIT_SIZE; |
wolfSSL | 0:d92f9d21154c | 2175 | err = mp_read_unsigned_bin(&e, hash, hashlen); |
wolfSSL | 0:d92f9d21154c | 2176 | |
wolfSSL | 0:d92f9d21154c | 2177 | /* may still need bit truncation too */ |
wolfSSL | 0:d92f9d21154c | 2178 | if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits) |
wolfSSL | 0:d92f9d21154c | 2179 | mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); |
wolfSSL | 0:d92f9d21154c | 2180 | } |
wolfSSL | 0:d92f9d21154c | 2181 | |
wolfSSL | 0:d92f9d21154c | 2182 | /* w = s^-1 mod n */ |
wolfSSL | 0:d92f9d21154c | 2183 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2184 | err = mp_invmod(&s, &p, &w); |
wolfSSL | 0:d92f9d21154c | 2185 | |
wolfSSL | 0:d92f9d21154c | 2186 | /* u1 = ew */ |
wolfSSL | 0:d92f9d21154c | 2187 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2188 | err = mp_mulmod(&e, &w, &p, &u1); |
wolfSSL | 0:d92f9d21154c | 2189 | |
wolfSSL | 0:d92f9d21154c | 2190 | /* u2 = rw */ |
wolfSSL | 0:d92f9d21154c | 2191 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2192 | err = mp_mulmod(&r, &w, &p, &u2); |
wolfSSL | 0:d92f9d21154c | 2193 | |
wolfSSL | 0:d92f9d21154c | 2194 | /* find mG and mQ */ |
wolfSSL | 0:d92f9d21154c | 2195 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2196 | err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16); |
wolfSSL | 0:d92f9d21154c | 2197 | |
wolfSSL | 0:d92f9d21154c | 2198 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2199 | err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16); |
wolfSSL | 0:d92f9d21154c | 2200 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2201 | mp_set(mG->z, 1); |
wolfSSL | 0:d92f9d21154c | 2202 | |
wolfSSL | 0:d92f9d21154c | 2203 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2204 | err = mp_copy(key->pubkey.x, mQ->x); |
wolfSSL | 0:d92f9d21154c | 2205 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2206 | err = mp_copy(key->pubkey.y, mQ->y); |
wolfSSL | 0:d92f9d21154c | 2207 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2208 | err = mp_copy(key->pubkey.z, mQ->z); |
wolfSSL | 0:d92f9d21154c | 2209 | |
wolfSSL | 0:d92f9d21154c | 2210 | #ifndef ECC_SHAMIR |
wolfSSL | 0:d92f9d21154c | 2211 | { |
wolfSSL | 0:d92f9d21154c | 2212 | mp_digit mp; |
wolfSSL | 0:d92f9d21154c | 2213 | |
wolfSSL | 0:d92f9d21154c | 2214 | /* compute u1*mG + u2*mQ = mG */ |
wolfSSL | 0:d92f9d21154c | 2215 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2216 | err = ecc_mulmod(&u1, mG, mG, &m, 0); |
wolfSSL | 0:d92f9d21154c | 2217 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2218 | err = ecc_mulmod(&u2, mQ, mQ, &m, 0); |
wolfSSL | 0:d92f9d21154c | 2219 | |
wolfSSL | 0:d92f9d21154c | 2220 | /* find the montgomery mp */ |
wolfSSL | 0:d92f9d21154c | 2221 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2222 | err = mp_montgomery_setup(&m, &mp); |
wolfSSL | 0:d92f9d21154c | 2223 | |
wolfSSL | 0:d92f9d21154c | 2224 | /* add them */ |
wolfSSL | 0:d92f9d21154c | 2225 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2226 | err = ecc_projective_add_point(mQ, mG, mG, &m, &mp); |
wolfSSL | 0:d92f9d21154c | 2227 | |
wolfSSL | 0:d92f9d21154c | 2228 | /* reduce */ |
wolfSSL | 0:d92f9d21154c | 2229 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2230 | err = ecc_map(mG, &m, &mp); |
wolfSSL | 0:d92f9d21154c | 2231 | } |
wolfSSL | 0:d92f9d21154c | 2232 | #else |
wolfSSL | 0:d92f9d21154c | 2233 | /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */ |
wolfSSL | 0:d92f9d21154c | 2234 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2235 | err = ecc_mul2add(mG, &u1, mQ, &u2, mG, &m); |
wolfSSL | 0:d92f9d21154c | 2236 | #endif /* ECC_SHAMIR */ |
wolfSSL | 0:d92f9d21154c | 2237 | |
wolfSSL | 0:d92f9d21154c | 2238 | /* v = X_x1 mod n */ |
wolfSSL | 0:d92f9d21154c | 2239 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2240 | err = mp_mod(mG->x, &p, &v); |
wolfSSL | 0:d92f9d21154c | 2241 | |
wolfSSL | 0:d92f9d21154c | 2242 | /* does v == r */ |
wolfSSL | 0:d92f9d21154c | 2243 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2244 | if (mp_cmp(&v, &r) == MP_EQ) |
wolfSSL | 0:d92f9d21154c | 2245 | *stat = 1; |
wolfSSL | 0:d92f9d21154c | 2246 | } |
wolfSSL | 0:d92f9d21154c | 2247 | |
wolfSSL | 0:d92f9d21154c | 2248 | ecc_del_point(mG); |
wolfSSL | 0:d92f9d21154c | 2249 | ecc_del_point(mQ); |
wolfSSL | 0:d92f9d21154c | 2250 | |
wolfSSL | 0:d92f9d21154c | 2251 | mp_clear(&r); |
wolfSSL | 0:d92f9d21154c | 2252 | mp_clear(&s); |
wolfSSL | 0:d92f9d21154c | 2253 | mp_clear(&v); |
wolfSSL | 0:d92f9d21154c | 2254 | mp_clear(&w); |
wolfSSL | 0:d92f9d21154c | 2255 | mp_clear(&u1); |
wolfSSL | 0:d92f9d21154c | 2256 | mp_clear(&u2); |
wolfSSL | 0:d92f9d21154c | 2257 | mp_clear(&p); |
wolfSSL | 0:d92f9d21154c | 2258 | mp_clear(&e); |
wolfSSL | 0:d92f9d21154c | 2259 | mp_clear(&m); |
wolfSSL | 0:d92f9d21154c | 2260 | |
wolfSSL | 0:d92f9d21154c | 2261 | return err; |
wolfSSL | 0:d92f9d21154c | 2262 | } |
wolfSSL | 0:d92f9d21154c | 2263 | |
wolfSSL | 0:d92f9d21154c | 2264 | |
wolfSSL | 0:d92f9d21154c | 2265 | /* export public ECC key in ANSI X9.63 format */ |
wolfSSL | 0:d92f9d21154c | 2266 | int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) |
wolfSSL | 0:d92f9d21154c | 2267 | { |
wolfSSL | 0:d92f9d21154c | 2268 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 2269 | byte* buf; |
wolfSSL | 0:d92f9d21154c | 2270 | #else |
wolfSSL | 0:d92f9d21154c | 2271 | byte buf[ECC_BUFSIZE]; |
wolfSSL | 0:d92f9d21154c | 2272 | #endif |
wolfSSL | 0:d92f9d21154c | 2273 | word32 numlen; |
wolfSSL | 0:d92f9d21154c | 2274 | int ret = MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 2275 | |
wolfSSL | 0:d92f9d21154c | 2276 | /* return length needed only */ |
wolfSSL | 0:d92f9d21154c | 2277 | if (key != NULL && out == NULL && outLen != NULL) { |
wolfSSL | 0:d92f9d21154c | 2278 | numlen = key->dp->size; |
wolfSSL | 0:d92f9d21154c | 2279 | *outLen = 1 + 2*numlen; |
wolfSSL | 0:d92f9d21154c | 2280 | return LENGTH_ONLY_E; |
wolfSSL | 0:d92f9d21154c | 2281 | } |
wolfSSL | 0:d92f9d21154c | 2282 | |
wolfSSL | 0:d92f9d21154c | 2283 | if (key == NULL || out == NULL || outLen == NULL) |
wolfSSL | 0:d92f9d21154c | 2284 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2285 | |
wolfSSL | 0:d92f9d21154c | 2286 | if (ecc_is_valid_idx(key->idx) == 0) { |
wolfSSL | 0:d92f9d21154c | 2287 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2288 | } |
wolfSSL | 0:d92f9d21154c | 2289 | numlen = key->dp->size; |
wolfSSL | 0:d92f9d21154c | 2290 | |
wolfSSL | 0:d92f9d21154c | 2291 | if (*outLen < (1 + 2*numlen)) { |
wolfSSL | 0:d92f9d21154c | 2292 | *outLen = 1 + 2*numlen; |
wolfSSL | 0:d92f9d21154c | 2293 | return BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 2294 | } |
wolfSSL | 0:d92f9d21154c | 2295 | |
wolfSSL | 0:d92f9d21154c | 2296 | /* store byte 0x04 */ |
wolfSSL | 0:d92f9d21154c | 2297 | out[0] = 0x04; |
wolfSSL | 0:d92f9d21154c | 2298 | |
wolfSSL | 0:d92f9d21154c | 2299 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 2300 | buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 2301 | if (buf == NULL) |
wolfSSL | 0:d92f9d21154c | 2302 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2303 | #endif |
wolfSSL | 0:d92f9d21154c | 2304 | |
wolfSSL | 0:d92f9d21154c | 2305 | do { |
wolfSSL | 0:d92f9d21154c | 2306 | /* pad and store x */ |
wolfSSL | 0:d92f9d21154c | 2307 | XMEMSET(buf, 0, ECC_BUFSIZE); |
wolfSSL | 0:d92f9d21154c | 2308 | ret = mp_to_unsigned_bin(key->pubkey.x, |
wolfSSL | 0:d92f9d21154c | 2309 | buf + (numlen - mp_unsigned_bin_size(key->pubkey.x))); |
wolfSSL | 0:d92f9d21154c | 2310 | if (ret != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2311 | break; |
wolfSSL | 0:d92f9d21154c | 2312 | XMEMCPY(out+1, buf, numlen); |
wolfSSL | 0:d92f9d21154c | 2313 | |
wolfSSL | 0:d92f9d21154c | 2314 | /* pad and store y */ |
wolfSSL | 0:d92f9d21154c | 2315 | XMEMSET(buf, 0, ECC_BUFSIZE); |
wolfSSL | 0:d92f9d21154c | 2316 | ret = mp_to_unsigned_bin(key->pubkey.y, |
wolfSSL | 0:d92f9d21154c | 2317 | buf + (numlen - mp_unsigned_bin_size(key->pubkey.y))); |
wolfSSL | 0:d92f9d21154c | 2318 | if (ret != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2319 | break; |
wolfSSL | 0:d92f9d21154c | 2320 | XMEMCPY(out+1+numlen, buf, numlen); |
wolfSSL | 0:d92f9d21154c | 2321 | |
wolfSSL | 0:d92f9d21154c | 2322 | *outLen = 1 + 2*numlen; |
wolfSSL | 0:d92f9d21154c | 2323 | } while (0); |
wolfSSL | 0:d92f9d21154c | 2324 | |
wolfSSL | 0:d92f9d21154c | 2325 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 2326 | XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 2327 | #endif |
wolfSSL | 0:d92f9d21154c | 2328 | |
wolfSSL | 0:d92f9d21154c | 2329 | return ret; |
wolfSSL | 0:d92f9d21154c | 2330 | } |
wolfSSL | 0:d92f9d21154c | 2331 | |
wolfSSL | 0:d92f9d21154c | 2332 | |
wolfSSL | 0:d92f9d21154c | 2333 | /* export public ECC key in ANSI X9.63 format, extended with |
wolfSSL | 0:d92f9d21154c | 2334 | * compression option */ |
wolfSSL | 0:d92f9d21154c | 2335 | int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, int compressed) |
wolfSSL | 0:d92f9d21154c | 2336 | { |
wolfSSL | 0:d92f9d21154c | 2337 | if (compressed == 0) |
wolfSSL | 0:d92f9d21154c | 2338 | return wc_ecc_export_x963(key, out, outLen); |
wolfSSL | 0:d92f9d21154c | 2339 | #ifdef HAVE_COMP_KEY |
wolfSSL | 0:d92f9d21154c | 2340 | else |
wolfSSL | 0:d92f9d21154c | 2341 | return wc_ecc_export_x963_compressed(key, out, outLen); |
wolfSSL | 0:d92f9d21154c | 2342 | #endif |
wolfSSL | 0:d92f9d21154c | 2343 | |
wolfSSL | 0:d92f9d21154c | 2344 | return NOT_COMPILED_IN; |
wolfSSL | 0:d92f9d21154c | 2345 | } |
wolfSSL | 0:d92f9d21154c | 2346 | |
wolfSSL | 0:d92f9d21154c | 2347 | |
wolfSSL | 0:d92f9d21154c | 2348 | /* is ec point on curve descriped by dp ? */ |
wolfSSL | 0:d92f9d21154c | 2349 | static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime) |
wolfSSL | 0:d92f9d21154c | 2350 | { |
wolfSSL | 0:d92f9d21154c | 2351 | mp_int b, t1, t2; |
wolfSSL | 0:d92f9d21154c | 2352 | int err; |
wolfSSL | 0:d92f9d21154c | 2353 | |
wolfSSL | 0:d92f9d21154c | 2354 | if ((err = mp_init_multi(&b, &t1, &t2, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2355 | return err; |
wolfSSL | 0:d92f9d21154c | 2356 | } |
wolfSSL | 0:d92f9d21154c | 2357 | |
wolfSSL | 0:d92f9d21154c | 2358 | /* load b */ |
wolfSSL | 0:d92f9d21154c | 2359 | err = mp_read_radix(&b, dp->Bf, 16); |
wolfSSL | 0:d92f9d21154c | 2360 | |
wolfSSL | 0:d92f9d21154c | 2361 | /* compute y^2 */ |
wolfSSL | 0:d92f9d21154c | 2362 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2363 | err = mp_sqr(ecp->y, &t1); |
wolfSSL | 0:d92f9d21154c | 2364 | |
wolfSSL | 0:d92f9d21154c | 2365 | /* compute x^3 */ |
wolfSSL | 0:d92f9d21154c | 2366 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2367 | err = mp_sqr(ecp->x, &t2); |
wolfSSL | 0:d92f9d21154c | 2368 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2369 | err = mp_mod(&t2, prime, &t2); |
wolfSSL | 0:d92f9d21154c | 2370 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2371 | err = mp_mul(ecp->x, &t2, &t2); |
wolfSSL | 0:d92f9d21154c | 2372 | |
wolfSSL | 0:d92f9d21154c | 2373 | /* compute y^2 - x^3 */ |
wolfSSL | 0:d92f9d21154c | 2374 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2375 | err = mp_sub(&t1, &t2, &t1); |
wolfSSL | 0:d92f9d21154c | 2376 | |
wolfSSL | 0:d92f9d21154c | 2377 | /* compute y^2 - x^3 + 3x */ |
wolfSSL | 0:d92f9d21154c | 2378 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2379 | err = mp_add(&t1, ecp->x, &t1); |
wolfSSL | 0:d92f9d21154c | 2380 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2381 | err = mp_add(&t1, ecp->x, &t1); |
wolfSSL | 0:d92f9d21154c | 2382 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2383 | err = mp_add(&t1, ecp->x, &t1); |
wolfSSL | 0:d92f9d21154c | 2384 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2385 | err = mp_mod(&t1, prime, &t1); |
wolfSSL | 0:d92f9d21154c | 2386 | |
wolfSSL | 0:d92f9d21154c | 2387 | while (err == MP_OKAY && mp_cmp_d(&t1, 0) == MP_LT) { |
wolfSSL | 0:d92f9d21154c | 2388 | err = mp_add(&t1, prime, &t1); |
wolfSSL | 0:d92f9d21154c | 2389 | } |
wolfSSL | 0:d92f9d21154c | 2390 | while (err == MP_OKAY && mp_cmp(&t1, prime) != MP_LT) { |
wolfSSL | 0:d92f9d21154c | 2391 | err = mp_sub(&t1, prime, &t1); |
wolfSSL | 0:d92f9d21154c | 2392 | } |
wolfSSL | 0:d92f9d21154c | 2393 | |
wolfSSL | 0:d92f9d21154c | 2394 | /* compare to b */ |
wolfSSL | 0:d92f9d21154c | 2395 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2396 | if (mp_cmp(&t1, &b) != MP_EQ) { |
wolfSSL | 0:d92f9d21154c | 2397 | err = MP_VAL; |
wolfSSL | 0:d92f9d21154c | 2398 | } else { |
wolfSSL | 0:d92f9d21154c | 2399 | err = MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 2400 | } |
wolfSSL | 0:d92f9d21154c | 2401 | } |
wolfSSL | 0:d92f9d21154c | 2402 | |
wolfSSL | 0:d92f9d21154c | 2403 | mp_clear(&b); |
wolfSSL | 0:d92f9d21154c | 2404 | mp_clear(&t1); |
wolfSSL | 0:d92f9d21154c | 2405 | mp_clear(&t2); |
wolfSSL | 0:d92f9d21154c | 2406 | |
wolfSSL | 0:d92f9d21154c | 2407 | return err; |
wolfSSL | 0:d92f9d21154c | 2408 | } |
wolfSSL | 0:d92f9d21154c | 2409 | |
wolfSSL | 0:d92f9d21154c | 2410 | |
wolfSSL | 0:d92f9d21154c | 2411 | /* validate privkey * generator == pubkey, 0 on success */ |
wolfSSL | 0:d92f9d21154c | 2412 | static int ecc_check_privkey_gen(ecc_key* key, mp_int* prime) |
wolfSSL | 0:d92f9d21154c | 2413 | { |
wolfSSL | 0:d92f9d21154c | 2414 | ecc_point* base = NULL; |
wolfSSL | 0:d92f9d21154c | 2415 | ecc_point* res = NULL; |
wolfSSL | 0:d92f9d21154c | 2416 | int err; |
wolfSSL | 0:d92f9d21154c | 2417 | |
wolfSSL | 0:d92f9d21154c | 2418 | if (key == NULL) |
wolfSSL | 0:d92f9d21154c | 2419 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 2420 | |
wolfSSL | 0:d92f9d21154c | 2421 | base = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 2422 | if (base == NULL) |
wolfSSL | 0:d92f9d21154c | 2423 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2424 | |
wolfSSL | 0:d92f9d21154c | 2425 | /* set up base generator */ |
wolfSSL | 0:d92f9d21154c | 2426 | err = mp_read_radix(base->x, (char*)key->dp->Gx, 16); |
wolfSSL | 0:d92f9d21154c | 2427 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2428 | err = mp_read_radix(base->y, (char*)key->dp->Gy, 16); |
wolfSSL | 0:d92f9d21154c | 2429 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2430 | mp_set(base->z, 1); |
wolfSSL | 0:d92f9d21154c | 2431 | |
wolfSSL | 0:d92f9d21154c | 2432 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2433 | res = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 2434 | if (res == NULL) |
wolfSSL | 0:d92f9d21154c | 2435 | err = MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2436 | else { |
wolfSSL | 0:d92f9d21154c | 2437 | err = ecc_mulmod(&key->k, base, res, prime, 1); |
wolfSSL | 0:d92f9d21154c | 2438 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2439 | /* compare result to public key */ |
wolfSSL | 0:d92f9d21154c | 2440 | if (mp_cmp(res->x, key->pubkey.x) != MP_EQ || |
wolfSSL | 0:d92f9d21154c | 2441 | mp_cmp(res->y, key->pubkey.y) != MP_EQ || |
wolfSSL | 0:d92f9d21154c | 2442 | mp_cmp(res->z, key->pubkey.z) != MP_EQ) { |
wolfSSL | 0:d92f9d21154c | 2443 | /* didn't match */ |
wolfSSL | 0:d92f9d21154c | 2444 | err = ECC_PRIV_KEY_E; |
wolfSSL | 0:d92f9d21154c | 2445 | } |
wolfSSL | 0:d92f9d21154c | 2446 | } |
wolfSSL | 0:d92f9d21154c | 2447 | } |
wolfSSL | 0:d92f9d21154c | 2448 | } |
wolfSSL | 0:d92f9d21154c | 2449 | |
wolfSSL | 0:d92f9d21154c | 2450 | ecc_del_point(res); |
wolfSSL | 0:d92f9d21154c | 2451 | ecc_del_point(base); |
wolfSSL | 0:d92f9d21154c | 2452 | |
wolfSSL | 0:d92f9d21154c | 2453 | return err; |
wolfSSL | 0:d92f9d21154c | 2454 | } |
wolfSSL | 0:d92f9d21154c | 2455 | |
wolfSSL | 0:d92f9d21154c | 2456 | |
wolfSSL | 0:d92f9d21154c | 2457 | #ifdef WOLFSSL_VALIDATE_ECC_IMPORT |
wolfSSL | 0:d92f9d21154c | 2458 | |
wolfSSL | 0:d92f9d21154c | 2459 | /* check privkey generator helper, creates prime needed */ |
wolfSSL | 0:d92f9d21154c | 2460 | static int ecc_check_privkey_gen_helper(ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 2461 | { |
wolfSSL | 0:d92f9d21154c | 2462 | mp_int prime; |
wolfSSL | 0:d92f9d21154c | 2463 | int err; |
wolfSSL | 0:d92f9d21154c | 2464 | |
wolfSSL | 0:d92f9d21154c | 2465 | if (key == NULL) |
wolfSSL | 0:d92f9d21154c | 2466 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 2467 | |
wolfSSL | 0:d92f9d21154c | 2468 | err = mp_init(&prime); |
wolfSSL | 0:d92f9d21154c | 2469 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2470 | return err; |
wolfSSL | 0:d92f9d21154c | 2471 | |
wolfSSL | 0:d92f9d21154c | 2472 | err = mp_read_radix(&prime, (char*)key->dp->prime, 16); |
wolfSSL | 0:d92f9d21154c | 2473 | |
wolfSSL | 0:d92f9d21154c | 2474 | if (err == MP_OKAY); |
wolfSSL | 0:d92f9d21154c | 2475 | err = ecc_check_privkey_gen(key, &prime); |
wolfSSL | 0:d92f9d21154c | 2476 | |
wolfSSL | 0:d92f9d21154c | 2477 | mp_clear(&prime); |
wolfSSL | 0:d92f9d21154c | 2478 | |
wolfSSL | 0:d92f9d21154c | 2479 | return err; |
wolfSSL | 0:d92f9d21154c | 2480 | } |
wolfSSL | 0:d92f9d21154c | 2481 | |
wolfSSL | 0:d92f9d21154c | 2482 | #endif /* WOLFSSL_VALIDATE_ECC_IMPORT */ |
wolfSSL | 0:d92f9d21154c | 2483 | |
wolfSSL | 0:d92f9d21154c | 2484 | |
wolfSSL | 0:d92f9d21154c | 2485 | /* validate order * pubkey = point at infinity, 0 on success */ |
wolfSSL | 0:d92f9d21154c | 2486 | static int ecc_check_pubkey_order(ecc_key* key, mp_int* prime, mp_int* order) |
wolfSSL | 0:d92f9d21154c | 2487 | { |
wolfSSL | 0:d92f9d21154c | 2488 | ecc_point* inf = NULL; |
wolfSSL | 0:d92f9d21154c | 2489 | int err; |
wolfSSL | 0:d92f9d21154c | 2490 | |
wolfSSL | 0:d92f9d21154c | 2491 | if (key == NULL) |
wolfSSL | 0:d92f9d21154c | 2492 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 2493 | |
wolfSSL | 0:d92f9d21154c | 2494 | inf = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 2495 | if (inf == NULL) |
wolfSSL | 0:d92f9d21154c | 2496 | err = MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2497 | else { |
wolfSSL | 0:d92f9d21154c | 2498 | err = ecc_mulmod(order, &key->pubkey, inf, prime, 1); |
wolfSSL | 0:d92f9d21154c | 2499 | if (err == MP_OKAY && !ecc_point_is_at_infinity(inf)) |
wolfSSL | 0:d92f9d21154c | 2500 | err = ECC_INF_E; |
wolfSSL | 0:d92f9d21154c | 2501 | } |
wolfSSL | 0:d92f9d21154c | 2502 | |
wolfSSL | 0:d92f9d21154c | 2503 | ecc_del_point(inf); |
wolfSSL | 0:d92f9d21154c | 2504 | |
wolfSSL | 0:d92f9d21154c | 2505 | return err; |
wolfSSL | 0:d92f9d21154c | 2506 | } |
wolfSSL | 0:d92f9d21154c | 2507 | |
wolfSSL | 0:d92f9d21154c | 2508 | |
wolfSSL | 0:d92f9d21154c | 2509 | /* perform sanity checks on ec key validity, 0 on success */ |
wolfSSL | 0:d92f9d21154c | 2510 | int wc_ecc_check_key(ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 2511 | { |
wolfSSL | 0:d92f9d21154c | 2512 | mp_int prime; /* used by multiple calls so let's cache */ |
wolfSSL | 0:d92f9d21154c | 2513 | mp_int order; /* other callers have, so let's gen here */ |
wolfSSL | 0:d92f9d21154c | 2514 | int err; |
wolfSSL | 0:d92f9d21154c | 2515 | |
wolfSSL | 0:d92f9d21154c | 2516 | if (key == NULL) |
wolfSSL | 0:d92f9d21154c | 2517 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 2518 | |
wolfSSL | 0:d92f9d21154c | 2519 | /* pubkey point cannot be at inifinity */ |
wolfSSL | 0:d92f9d21154c | 2520 | if (ecc_point_is_at_infinity(&key->pubkey)) |
wolfSSL | 0:d92f9d21154c | 2521 | return ECC_INF_E; |
wolfSSL | 0:d92f9d21154c | 2522 | |
wolfSSL | 0:d92f9d21154c | 2523 | err = mp_init_multi(&prime, &order, NULL, NULL, NULL, NULL); |
wolfSSL | 0:d92f9d21154c | 2524 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2525 | return err; |
wolfSSL | 0:d92f9d21154c | 2526 | |
wolfSSL | 0:d92f9d21154c | 2527 | err = mp_read_radix(&prime, (char*)key->dp->prime, 16); |
wolfSSL | 0:d92f9d21154c | 2528 | |
wolfSSL | 0:d92f9d21154c | 2529 | /* make sure point is actually on curve */ |
wolfSSL | 0:d92f9d21154c | 2530 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2531 | err = ecc_is_point(key->dp, &key->pubkey, &prime); |
wolfSSL | 0:d92f9d21154c | 2532 | |
wolfSSL | 0:d92f9d21154c | 2533 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2534 | err = mp_read_radix(&order, (char*)key->dp->order, 16); |
wolfSSL | 0:d92f9d21154c | 2535 | |
wolfSSL | 0:d92f9d21154c | 2536 | /* pubkey * order must be at infinity */ |
wolfSSL | 0:d92f9d21154c | 2537 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2538 | err = ecc_check_pubkey_order(key, &prime, &order); |
wolfSSL | 0:d92f9d21154c | 2539 | |
wolfSSL | 0:d92f9d21154c | 2540 | /* private * base generator must equal pubkey */ |
wolfSSL | 0:d92f9d21154c | 2541 | if (err == MP_OKAY && key->type == ECC_PRIVATEKEY) |
wolfSSL | 0:d92f9d21154c | 2542 | err = ecc_check_privkey_gen(key, &prime); |
wolfSSL | 0:d92f9d21154c | 2543 | |
wolfSSL | 0:d92f9d21154c | 2544 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 2545 | mp_clear(&prime); |
wolfSSL | 0:d92f9d21154c | 2546 | |
wolfSSL | 0:d92f9d21154c | 2547 | return err; |
wolfSSL | 0:d92f9d21154c | 2548 | } |
wolfSSL | 0:d92f9d21154c | 2549 | |
wolfSSL | 0:d92f9d21154c | 2550 | |
wolfSSL | 0:d92f9d21154c | 2551 | /* import public ECC key in ANSI X9.63 format */ |
wolfSSL | 0:d92f9d21154c | 2552 | int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 2553 | { |
wolfSSL | 0:d92f9d21154c | 2554 | int x, err; |
wolfSSL | 0:d92f9d21154c | 2555 | int compressed = 0; |
wolfSSL | 0:d92f9d21154c | 2556 | |
wolfSSL | 0:d92f9d21154c | 2557 | if (in == NULL || key == NULL) |
wolfSSL | 0:d92f9d21154c | 2558 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2559 | |
wolfSSL | 0:d92f9d21154c | 2560 | /* must be odd */ |
wolfSSL | 0:d92f9d21154c | 2561 | if ((inLen & 1) == 0) { |
wolfSSL | 0:d92f9d21154c | 2562 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2563 | } |
wolfSSL | 0:d92f9d21154c | 2564 | |
wolfSSL | 0:d92f9d21154c | 2565 | /* init key */ |
wolfSSL | 0:d92f9d21154c | 2566 | #ifdef ALT_ECC_SIZE |
wolfSSL | 0:d92f9d21154c | 2567 | key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; |
wolfSSL | 0:d92f9d21154c | 2568 | key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; |
wolfSSL | 0:d92f9d21154c | 2569 | key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; |
wolfSSL | 0:d92f9d21154c | 2570 | alt_fp_init(key->pubkey.x); |
wolfSSL | 0:d92f9d21154c | 2571 | alt_fp_init(key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 2572 | alt_fp_init(key->pubkey.z); |
wolfSSL | 0:d92f9d21154c | 2573 | err = mp_init(&key->k); |
wolfSSL | 0:d92f9d21154c | 2574 | #else |
wolfSSL | 0:d92f9d21154c | 2575 | err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k, |
wolfSSL | 0:d92f9d21154c | 2576 | NULL, NULL); |
wolfSSL | 0:d92f9d21154c | 2577 | #endif |
wolfSSL | 0:d92f9d21154c | 2578 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2579 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2580 | |
wolfSSL | 0:d92f9d21154c | 2581 | /* check for 4, 2, or 3 */ |
wolfSSL | 0:d92f9d21154c | 2582 | if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) { |
wolfSSL | 0:d92f9d21154c | 2583 | err = ASN_PARSE_E; |
wolfSSL | 0:d92f9d21154c | 2584 | } |
wolfSSL | 0:d92f9d21154c | 2585 | |
wolfSSL | 0:d92f9d21154c | 2586 | if (in[0] == 0x02 || in[0] == 0x03) { |
wolfSSL | 0:d92f9d21154c | 2587 | #ifdef HAVE_COMP_KEY |
wolfSSL | 0:d92f9d21154c | 2588 | compressed = 1; |
wolfSSL | 0:d92f9d21154c | 2589 | #else |
wolfSSL | 0:d92f9d21154c | 2590 | err = NOT_COMPILED_IN; |
wolfSSL | 0:d92f9d21154c | 2591 | #endif |
wolfSSL | 0:d92f9d21154c | 2592 | } |
wolfSSL | 0:d92f9d21154c | 2593 | |
wolfSSL | 0:d92f9d21154c | 2594 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2595 | /* determine the idx */ |
wolfSSL | 0:d92f9d21154c | 2596 | |
wolfSSL | 0:d92f9d21154c | 2597 | if (compressed) |
wolfSSL | 0:d92f9d21154c | 2598 | inLen = (inLen-1)*2 + 1; /* used uncompressed len */ |
wolfSSL | 0:d92f9d21154c | 2599 | |
wolfSSL | 0:d92f9d21154c | 2600 | for (x = 0; ecc_sets[x].size != 0; x++) { |
wolfSSL | 0:d92f9d21154c | 2601 | if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) { |
wolfSSL | 0:d92f9d21154c | 2602 | break; |
wolfSSL | 0:d92f9d21154c | 2603 | } |
wolfSSL | 0:d92f9d21154c | 2604 | } |
wolfSSL | 0:d92f9d21154c | 2605 | if (ecc_sets[x].size == 0) { |
wolfSSL | 0:d92f9d21154c | 2606 | err = ASN_PARSE_E; |
wolfSSL | 0:d92f9d21154c | 2607 | } else { |
wolfSSL | 0:d92f9d21154c | 2608 | /* set the idx */ |
wolfSSL | 0:d92f9d21154c | 2609 | key->idx = x; |
wolfSSL | 0:d92f9d21154c | 2610 | key->dp = &ecc_sets[x]; |
wolfSSL | 0:d92f9d21154c | 2611 | key->type = ECC_PUBLICKEY; |
wolfSSL | 0:d92f9d21154c | 2612 | } |
wolfSSL | 0:d92f9d21154c | 2613 | } |
wolfSSL | 0:d92f9d21154c | 2614 | |
wolfSSL | 0:d92f9d21154c | 2615 | /* read data */ |
wolfSSL | 0:d92f9d21154c | 2616 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2617 | err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in+1, (inLen-1)>>1); |
wolfSSL | 0:d92f9d21154c | 2618 | |
wolfSSL | 0:d92f9d21154c | 2619 | #ifdef HAVE_COMP_KEY |
wolfSSL | 0:d92f9d21154c | 2620 | if (err == MP_OKAY && compressed == 1) { /* build y */ |
wolfSSL | 0:d92f9d21154c | 2621 | mp_int t1, t2, prime, a, b; |
wolfSSL | 0:d92f9d21154c | 2622 | |
wolfSSL | 0:d92f9d21154c | 2623 | if (mp_init_multi(&t1, &t2, &prime, &a, &b, NULL) != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2624 | err = MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2625 | |
wolfSSL | 0:d92f9d21154c | 2626 | /* load prime */ |
wolfSSL | 0:d92f9d21154c | 2627 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2628 | err = mp_read_radix(&prime, (char *)key->dp->prime, 16); |
wolfSSL | 0:d92f9d21154c | 2629 | |
wolfSSL | 0:d92f9d21154c | 2630 | /* load a */ |
wolfSSL | 0:d92f9d21154c | 2631 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2632 | err = mp_read_radix(&a, (char *)key->dp->Af, 16); |
wolfSSL | 0:d92f9d21154c | 2633 | |
wolfSSL | 0:d92f9d21154c | 2634 | /* load b */ |
wolfSSL | 0:d92f9d21154c | 2635 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2636 | err = mp_read_radix(&b, (char *)key->dp->Bf, 16); |
wolfSSL | 0:d92f9d21154c | 2637 | |
wolfSSL | 0:d92f9d21154c | 2638 | /* compute x^3 */ |
wolfSSL | 0:d92f9d21154c | 2639 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2640 | err = mp_sqr(key->pubkey.x, &t1); |
wolfSSL | 0:d92f9d21154c | 2641 | |
wolfSSL | 0:d92f9d21154c | 2642 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2643 | err = mp_mulmod(&t1, key->pubkey.x, &prime, &t1); |
wolfSSL | 0:d92f9d21154c | 2644 | |
wolfSSL | 0:d92f9d21154c | 2645 | /* compute x^3 + a*x */ |
wolfSSL | 0:d92f9d21154c | 2646 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2647 | err = mp_mulmod(&a, key->pubkey.x, &prime, &t2); |
wolfSSL | 0:d92f9d21154c | 2648 | |
wolfSSL | 0:d92f9d21154c | 2649 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2650 | err = mp_add(&t1, &t2, &t1); |
wolfSSL | 0:d92f9d21154c | 2651 | |
wolfSSL | 0:d92f9d21154c | 2652 | /* compute x^3 + a*x + b */ |
wolfSSL | 0:d92f9d21154c | 2653 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2654 | err = mp_add(&t1, &b, &t1); |
wolfSSL | 0:d92f9d21154c | 2655 | |
wolfSSL | 0:d92f9d21154c | 2656 | /* compute sqrt(x^3 + a*x + b) */ |
wolfSSL | 0:d92f9d21154c | 2657 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2658 | err = mp_sqrtmod_prime(&t1, &prime, &t2); |
wolfSSL | 0:d92f9d21154c | 2659 | |
wolfSSL | 0:d92f9d21154c | 2660 | /* adjust y */ |
wolfSSL | 0:d92f9d21154c | 2661 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2662 | if ((mp_isodd(&t2) && in[0] == 0x03) || |
wolfSSL | 0:d92f9d21154c | 2663 | (!mp_isodd(&t2) && in[0] == 0x02)) { |
wolfSSL | 0:d92f9d21154c | 2664 | err = mp_mod(&t2, &prime, key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 2665 | } |
wolfSSL | 0:d92f9d21154c | 2666 | else { |
wolfSSL | 0:d92f9d21154c | 2667 | err = mp_submod(&prime, &t2, &prime, key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 2668 | } |
wolfSSL | 0:d92f9d21154c | 2669 | } |
wolfSSL | 0:d92f9d21154c | 2670 | |
wolfSSL | 0:d92f9d21154c | 2671 | mp_clear(&a); |
wolfSSL | 0:d92f9d21154c | 2672 | mp_clear(&b); |
wolfSSL | 0:d92f9d21154c | 2673 | mp_clear(&prime); |
wolfSSL | 0:d92f9d21154c | 2674 | mp_clear(&t2); |
wolfSSL | 0:d92f9d21154c | 2675 | mp_clear(&t1); |
wolfSSL | 0:d92f9d21154c | 2676 | } |
wolfSSL | 0:d92f9d21154c | 2677 | #endif |
wolfSSL | 0:d92f9d21154c | 2678 | |
wolfSSL | 0:d92f9d21154c | 2679 | if (err == MP_OKAY && compressed == 0) |
wolfSSL | 0:d92f9d21154c | 2680 | err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in+1+((inLen-1)>>1), |
wolfSSL | 0:d92f9d21154c | 2681 | (inLen-1)>>1); |
wolfSSL | 0:d92f9d21154c | 2682 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2683 | mp_set(key->pubkey.z, 1); |
wolfSSL | 0:d92f9d21154c | 2684 | |
wolfSSL | 0:d92f9d21154c | 2685 | #ifdef WOLFSSL_VALIDATE_ECC_IMPORT |
wolfSSL | 0:d92f9d21154c | 2686 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2687 | err = wc_ecc_check_key(key); |
wolfSSL | 0:d92f9d21154c | 2688 | #endif |
wolfSSL | 0:d92f9d21154c | 2689 | |
wolfSSL | 0:d92f9d21154c | 2690 | if (err != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2691 | mp_clear(key->pubkey.x); |
wolfSSL | 0:d92f9d21154c | 2692 | mp_clear(key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 2693 | mp_clear(key->pubkey.z); |
wolfSSL | 0:d92f9d21154c | 2694 | mp_clear(&key->k); |
wolfSSL | 0:d92f9d21154c | 2695 | } |
wolfSSL | 0:d92f9d21154c | 2696 | |
wolfSSL | 0:d92f9d21154c | 2697 | return err; |
wolfSSL | 0:d92f9d21154c | 2698 | } |
wolfSSL | 0:d92f9d21154c | 2699 | |
wolfSSL | 0:d92f9d21154c | 2700 | |
wolfSSL | 0:d92f9d21154c | 2701 | /* export ecc private key only raw, outLen is in/out size |
wolfSSL | 0:d92f9d21154c | 2702 | return MP_OKAY on success */ |
wolfSSL | 0:d92f9d21154c | 2703 | int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen) |
wolfSSL | 0:d92f9d21154c | 2704 | { |
wolfSSL | 0:d92f9d21154c | 2705 | word32 numlen; |
wolfSSL | 0:d92f9d21154c | 2706 | |
wolfSSL | 0:d92f9d21154c | 2707 | if (key == NULL || out == NULL || outLen == NULL) |
wolfSSL | 0:d92f9d21154c | 2708 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2709 | |
wolfSSL | 0:d92f9d21154c | 2710 | if (ecc_is_valid_idx(key->idx) == 0) { |
wolfSSL | 0:d92f9d21154c | 2711 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2712 | } |
wolfSSL | 0:d92f9d21154c | 2713 | numlen = key->dp->size; |
wolfSSL | 0:d92f9d21154c | 2714 | |
wolfSSL | 0:d92f9d21154c | 2715 | if (*outLen < numlen) { |
wolfSSL | 0:d92f9d21154c | 2716 | *outLen = numlen; |
wolfSSL | 0:d92f9d21154c | 2717 | return BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 2718 | } |
wolfSSL | 0:d92f9d21154c | 2719 | *outLen = numlen; |
wolfSSL | 0:d92f9d21154c | 2720 | XMEMSET(out, 0, *outLen); |
wolfSSL | 0:d92f9d21154c | 2721 | return mp_to_unsigned_bin(&key->k, out + (numlen - |
wolfSSL | 0:d92f9d21154c | 2722 | mp_unsigned_bin_size(&key->k))); |
wolfSSL | 0:d92f9d21154c | 2723 | } |
wolfSSL | 0:d92f9d21154c | 2724 | |
wolfSSL | 0:d92f9d21154c | 2725 | |
wolfSSL | 0:d92f9d21154c | 2726 | /* ecc private key import, public key in ANSI X9.63 format, private raw */ |
wolfSSL | 0:d92f9d21154c | 2727 | int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, |
wolfSSL | 0:d92f9d21154c | 2728 | word32 pubSz, ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 2729 | { |
wolfSSL | 0:d92f9d21154c | 2730 | int ret = wc_ecc_import_x963(pub, pubSz, key); |
wolfSSL | 0:d92f9d21154c | 2731 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 2732 | return ret; |
wolfSSL | 0:d92f9d21154c | 2733 | |
wolfSSL | 0:d92f9d21154c | 2734 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 0:d92f9d21154c | 2735 | |
wolfSSL | 0:d92f9d21154c | 2736 | ret = mp_read_unsigned_bin(&key->k, priv, privSz); |
wolfSSL | 0:d92f9d21154c | 2737 | |
wolfSSL | 0:d92f9d21154c | 2738 | #ifdef WOLFSSL_VALIDATE_ECC_IMPORT |
wolfSSL | 0:d92f9d21154c | 2739 | if (ret == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2740 | ret = ecc_check_privkey_gen_helper(key); |
wolfSSL | 0:d92f9d21154c | 2741 | #endif |
wolfSSL | 0:d92f9d21154c | 2742 | |
wolfSSL | 0:d92f9d21154c | 2743 | return ret; |
wolfSSL | 0:d92f9d21154c | 2744 | } |
wolfSSL | 0:d92f9d21154c | 2745 | |
wolfSSL | 0:d92f9d21154c | 2746 | /** |
wolfSSL | 0:d92f9d21154c | 2747 | Convert ECC R,S to signature |
wolfSSL | 0:d92f9d21154c | 2748 | r R component of signature |
wolfSSL | 0:d92f9d21154c | 2749 | s S component of signature |
wolfSSL | 0:d92f9d21154c | 2750 | out DER-encoded ECDSA signature |
wolfSSL | 0:d92f9d21154c | 2751 | outlen [in/out] output buffer size, output signature size |
wolfSSL | 0:d92f9d21154c | 2752 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 2753 | */ |
wolfSSL | 0:d92f9d21154c | 2754 | int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen) |
wolfSSL | 0:d92f9d21154c | 2755 | { |
wolfSSL | 0:d92f9d21154c | 2756 | int err; |
wolfSSL | 0:d92f9d21154c | 2757 | mp_int rtmp; |
wolfSSL | 0:d92f9d21154c | 2758 | mp_int stmp; |
wolfSSL | 0:d92f9d21154c | 2759 | |
wolfSSL | 0:d92f9d21154c | 2760 | if (r == NULL || s == NULL || out == NULL || outlen == NULL) |
wolfSSL | 0:d92f9d21154c | 2761 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2762 | |
wolfSSL | 0:d92f9d21154c | 2763 | err = mp_init_multi(&rtmp, &stmp, NULL, NULL, NULL, NULL); |
wolfSSL | 0:d92f9d21154c | 2764 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2765 | return err; |
wolfSSL | 0:d92f9d21154c | 2766 | |
wolfSSL | 0:d92f9d21154c | 2767 | err = mp_read_radix(&rtmp, r, 16); |
wolfSSL | 0:d92f9d21154c | 2768 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2769 | err = mp_read_radix(&stmp, s, 16); |
wolfSSL | 0:d92f9d21154c | 2770 | |
wolfSSL | 0:d92f9d21154c | 2771 | /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */ |
wolfSSL | 0:d92f9d21154c | 2772 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2773 | err = StoreECC_DSA_Sig(out, outlen, &rtmp, &stmp); |
wolfSSL | 0:d92f9d21154c | 2774 | |
wolfSSL | 0:d92f9d21154c | 2775 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2776 | if (mp_iszero(&rtmp) || mp_iszero(&stmp)) |
wolfSSL | 0:d92f9d21154c | 2777 | err = MP_ZERO_E; |
wolfSSL | 0:d92f9d21154c | 2778 | } |
wolfSSL | 0:d92f9d21154c | 2779 | |
wolfSSL | 0:d92f9d21154c | 2780 | mp_clear(&rtmp); |
wolfSSL | 0:d92f9d21154c | 2781 | mp_clear(&stmp); |
wolfSSL | 0:d92f9d21154c | 2782 | |
wolfSSL | 0:d92f9d21154c | 2783 | return err; |
wolfSSL | 0:d92f9d21154c | 2784 | } |
wolfSSL | 0:d92f9d21154c | 2785 | |
wolfSSL | 0:d92f9d21154c | 2786 | /** |
wolfSSL | 0:d92f9d21154c | 2787 | Import raw ECC key |
wolfSSL | 0:d92f9d21154c | 2788 | key The destination ecc_key structure |
wolfSSL | 0:d92f9d21154c | 2789 | qx x component of base point, as ASCII hex string |
wolfSSL | 0:d92f9d21154c | 2790 | qy y component of base point, as ASCII hex string |
wolfSSL | 0:d92f9d21154c | 2791 | d private key, as ASCII hex string |
wolfSSL | 0:d92f9d21154c | 2792 | curveName ECC curve name, from ecc_sets[] |
wolfSSL | 0:d92f9d21154c | 2793 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 2794 | */ |
wolfSSL | 0:d92f9d21154c | 2795 | int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy, |
wolfSSL | 0:d92f9d21154c | 2796 | const char* d, const char* curveName) |
wolfSSL | 0:d92f9d21154c | 2797 | { |
wolfSSL | 0:d92f9d21154c | 2798 | int err, x; |
wolfSSL | 0:d92f9d21154c | 2799 | |
wolfSSL | 0:d92f9d21154c | 2800 | if (key == NULL || qx == NULL || qy == NULL || d == NULL || |
wolfSSL | 0:d92f9d21154c | 2801 | curveName == NULL) |
wolfSSL | 0:d92f9d21154c | 2802 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 2803 | |
wolfSSL | 0:d92f9d21154c | 2804 | /* init key */ |
wolfSSL | 0:d92f9d21154c | 2805 | #ifdef ALT_ECC_SIZE |
wolfSSL | 0:d92f9d21154c | 2806 | key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; |
wolfSSL | 0:d92f9d21154c | 2807 | key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; |
wolfSSL | 0:d92f9d21154c | 2808 | key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; |
wolfSSL | 0:d92f9d21154c | 2809 | alt_fp_init(key->pubkey.x); |
wolfSSL | 0:d92f9d21154c | 2810 | alt_fp_init(key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 2811 | alt_fp_init(key->pubkey.z); |
wolfSSL | 0:d92f9d21154c | 2812 | err = mp_init(&key->k); |
wolfSSL | 0:d92f9d21154c | 2813 | #else |
wolfSSL | 0:d92f9d21154c | 2814 | err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k, |
wolfSSL | 0:d92f9d21154c | 2815 | NULL, NULL); |
wolfSSL | 0:d92f9d21154c | 2816 | #endif |
wolfSSL | 0:d92f9d21154c | 2817 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2818 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 2819 | |
wolfSSL | 0:d92f9d21154c | 2820 | /* read Qx */ |
wolfSSL | 0:d92f9d21154c | 2821 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2822 | err = mp_read_radix(key->pubkey.x, qx, 16); |
wolfSSL | 0:d92f9d21154c | 2823 | |
wolfSSL | 0:d92f9d21154c | 2824 | /* read Qy */ |
wolfSSL | 0:d92f9d21154c | 2825 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2826 | err = mp_read_radix(key->pubkey.y, qy, 16); |
wolfSSL | 0:d92f9d21154c | 2827 | |
wolfSSL | 0:d92f9d21154c | 2828 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2829 | mp_set(key->pubkey.z, 1); |
wolfSSL | 0:d92f9d21154c | 2830 | |
wolfSSL | 0:d92f9d21154c | 2831 | /* read and set the curve */ |
wolfSSL | 0:d92f9d21154c | 2832 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2833 | for (x = 0; ecc_sets[x].size != 0; x++) { |
wolfSSL | 0:d92f9d21154c | 2834 | if (XSTRNCMP(ecc_sets[x].name, curveName, |
wolfSSL | 0:d92f9d21154c | 2835 | XSTRLEN(curveName)) == 0) { |
wolfSSL | 0:d92f9d21154c | 2836 | break; |
wolfSSL | 0:d92f9d21154c | 2837 | } |
wolfSSL | 0:d92f9d21154c | 2838 | } |
wolfSSL | 0:d92f9d21154c | 2839 | if (ecc_sets[x].size == 0) { |
wolfSSL | 0:d92f9d21154c | 2840 | err = ASN_PARSE_E; |
wolfSSL | 0:d92f9d21154c | 2841 | } else { |
wolfSSL | 0:d92f9d21154c | 2842 | /* set the curve */ |
wolfSSL | 0:d92f9d21154c | 2843 | key->idx = x; |
wolfSSL | 0:d92f9d21154c | 2844 | key->dp = &ecc_sets[x]; |
wolfSSL | 0:d92f9d21154c | 2845 | key->type = ECC_PUBLICKEY; |
wolfSSL | 0:d92f9d21154c | 2846 | } |
wolfSSL | 0:d92f9d21154c | 2847 | } |
wolfSSL | 0:d92f9d21154c | 2848 | |
wolfSSL | 0:d92f9d21154c | 2849 | /* import private key */ |
wolfSSL | 0:d92f9d21154c | 2850 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2851 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 0:d92f9d21154c | 2852 | err = mp_read_radix(&key->k, d, 16); |
wolfSSL | 0:d92f9d21154c | 2853 | } |
wolfSSL | 0:d92f9d21154c | 2854 | |
wolfSSL | 0:d92f9d21154c | 2855 | #ifdef WOLFSSL_VALIDATE_ECC_IMPORT |
wolfSSL | 0:d92f9d21154c | 2856 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 2857 | err = wc_ecc_check_key(key); |
wolfSSL | 0:d92f9d21154c | 2858 | #endif |
wolfSSL | 0:d92f9d21154c | 2859 | |
wolfSSL | 0:d92f9d21154c | 2860 | if (err != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 2861 | mp_clear(key->pubkey.x); |
wolfSSL | 0:d92f9d21154c | 2862 | mp_clear(key->pubkey.y); |
wolfSSL | 0:d92f9d21154c | 2863 | mp_clear(key->pubkey.z); |
wolfSSL | 0:d92f9d21154c | 2864 | mp_clear(&key->k); |
wolfSSL | 0:d92f9d21154c | 2865 | } |
wolfSSL | 0:d92f9d21154c | 2866 | |
wolfSSL | 0:d92f9d21154c | 2867 | return err; |
wolfSSL | 0:d92f9d21154c | 2868 | } |
wolfSSL | 0:d92f9d21154c | 2869 | |
wolfSSL | 0:d92f9d21154c | 2870 | |
wolfSSL | 0:d92f9d21154c | 2871 | /* key size in octets */ |
wolfSSL | 0:d92f9d21154c | 2872 | int wc_ecc_size(ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 2873 | { |
wolfSSL | 0:d92f9d21154c | 2874 | if (key == NULL) return 0; |
wolfSSL | 0:d92f9d21154c | 2875 | |
wolfSSL | 0:d92f9d21154c | 2876 | return key->dp->size; |
wolfSSL | 0:d92f9d21154c | 2877 | } |
wolfSSL | 0:d92f9d21154c | 2878 | |
wolfSSL | 0:d92f9d21154c | 2879 | |
wolfSSL | 0:d92f9d21154c | 2880 | /* worst case estimate, check actual return from wc_ecc_sign_hash for actual value |
wolfSSL | 0:d92f9d21154c | 2881 | of signature size in octets */ |
wolfSSL | 0:d92f9d21154c | 2882 | int wc_ecc_sig_size(ecc_key* key) |
wolfSSL | 0:d92f9d21154c | 2883 | { |
wolfSSL | 0:d92f9d21154c | 2884 | int sz = wc_ecc_size(key); |
wolfSSL | 0:d92f9d21154c | 2885 | if (sz <= 0) |
wolfSSL | 0:d92f9d21154c | 2886 | return sz; |
wolfSSL | 0:d92f9d21154c | 2887 | |
wolfSSL | 0:d92f9d21154c | 2888 | return sz * 2 + SIG_HEADER_SZ + 4; /* (4) worst case estimate */ |
wolfSSL | 0:d92f9d21154c | 2889 | } |
wolfSSL | 0:d92f9d21154c | 2890 | |
wolfSSL | 0:d92f9d21154c | 2891 | |
wolfSSL | 0:d92f9d21154c | 2892 | #ifdef FP_ECC |
wolfSSL | 0:d92f9d21154c | 2893 | |
wolfSSL | 0:d92f9d21154c | 2894 | /* fixed point ECC cache */ |
wolfSSL | 0:d92f9d21154c | 2895 | /* number of entries in the cache */ |
wolfSSL | 0:d92f9d21154c | 2896 | #ifndef FP_ENTRIES |
wolfSSL | 0:d92f9d21154c | 2897 | #define FP_ENTRIES 16 |
wolfSSL | 0:d92f9d21154c | 2898 | #endif |
wolfSSL | 0:d92f9d21154c | 2899 | |
wolfSSL | 0:d92f9d21154c | 2900 | /* number of bits in LUT */ |
wolfSSL | 0:d92f9d21154c | 2901 | #ifndef FP_LUT |
wolfSSL | 0:d92f9d21154c | 2902 | #define FP_LUT 8U |
wolfSSL | 0:d92f9d21154c | 2903 | #endif |
wolfSSL | 0:d92f9d21154c | 2904 | |
wolfSSL | 0:d92f9d21154c | 2905 | #ifdef ECC_SHAMIR |
wolfSSL | 0:d92f9d21154c | 2906 | /* Sharmir requires a bigger LUT, TAO */ |
wolfSSL | 0:d92f9d21154c | 2907 | #if (FP_LUT > 12) || (FP_LUT < 4) |
wolfSSL | 0:d92f9d21154c | 2908 | #error FP_LUT must be between 4 and 12 inclusively |
wolfSSL | 0:d92f9d21154c | 2909 | #endif |
wolfSSL | 0:d92f9d21154c | 2910 | #else |
wolfSSL | 0:d92f9d21154c | 2911 | #if (FP_LUT > 12) || (FP_LUT < 2) |
wolfSSL | 0:d92f9d21154c | 2912 | #error FP_LUT must be between 2 and 12 inclusively |
wolfSSL | 0:d92f9d21154c | 2913 | #endif |
wolfSSL | 0:d92f9d21154c | 2914 | #endif |
wolfSSL | 0:d92f9d21154c | 2915 | |
wolfSSL | 0:d92f9d21154c | 2916 | |
wolfSSL | 0:d92f9d21154c | 2917 | /** Our FP cache */ |
wolfSSL | 0:d92f9d21154c | 2918 | typedef struct { |
wolfSSL | 0:d92f9d21154c | 2919 | ecc_point* g; /* cached COPY of base point */ |
wolfSSL | 0:d92f9d21154c | 2920 | ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */ |
wolfSSL | 0:d92f9d21154c | 2921 | mp_int mu; /* copy of the montgomery constant */ |
wolfSSL | 0:d92f9d21154c | 2922 | int lru_count; /* amount of times this entry has been used */ |
wolfSSL | 0:d92f9d21154c | 2923 | int lock; /* flag to indicate cache eviction */ |
wolfSSL | 0:d92f9d21154c | 2924 | /* permitted (0) or not (1) */ |
wolfSSL | 0:d92f9d21154c | 2925 | } fp_cache_t; |
wolfSSL | 0:d92f9d21154c | 2926 | |
wolfSSL | 0:d92f9d21154c | 2927 | /* if HAVE_THREAD_LS this cache is per thread, no locking needed */ |
wolfSSL | 0:d92f9d21154c | 2928 | static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES]; |
wolfSSL | 0:d92f9d21154c | 2929 | |
wolfSSL | 0:d92f9d21154c | 2930 | #ifndef HAVE_THREAD_LS |
wolfSSL | 0:d92f9d21154c | 2931 | static volatile int initMutex = 0; /* prevent multiple mutex inits */ |
wolfSSL | 0:d92f9d21154c | 2932 | static wolfSSL_Mutex ecc_fp_lock; |
wolfSSL | 0:d92f9d21154c | 2933 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 0:d92f9d21154c | 2934 | |
wolfSSL | 0:d92f9d21154c | 2935 | /* simple table to help direct the generation of the LUT */ |
wolfSSL | 0:d92f9d21154c | 2936 | static const struct { |
wolfSSL | 0:d92f9d21154c | 2937 | int ham, terma, termb; |
wolfSSL | 0:d92f9d21154c | 2938 | } lut_orders[] = { |
wolfSSL | 0:d92f9d21154c | 2939 | { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 }, |
wolfSSL | 0:d92f9d21154c | 2940 | { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 }, |
wolfSSL | 0:d92f9d21154c | 2941 | { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 }, |
wolfSSL | 0:d92f9d21154c | 2942 | { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 }, |
wolfSSL | 0:d92f9d21154c | 2943 | { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 }, |
wolfSSL | 0:d92f9d21154c | 2944 | { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 }, |
wolfSSL | 0:d92f9d21154c | 2945 | { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 }, |
wolfSSL | 0:d92f9d21154c | 2946 | { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 }, |
wolfSSL | 0:d92f9d21154c | 2947 | #if FP_LUT > 6 |
wolfSSL | 0:d92f9d21154c | 2948 | { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 }, |
wolfSSL | 0:d92f9d21154c | 2949 | { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 }, |
wolfSSL | 0:d92f9d21154c | 2950 | { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 }, |
wolfSSL | 0:d92f9d21154c | 2951 | { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 }, |
wolfSSL | 0:d92f9d21154c | 2952 | { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 }, |
wolfSSL | 0:d92f9d21154c | 2953 | { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 }, |
wolfSSL | 0:d92f9d21154c | 2954 | { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 }, |
wolfSSL | 0:d92f9d21154c | 2955 | { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 }, |
wolfSSL | 0:d92f9d21154c | 2956 | #if FP_LUT > 7 |
wolfSSL | 0:d92f9d21154c | 2957 | { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 }, |
wolfSSL | 0:d92f9d21154c | 2958 | { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 }, |
wolfSSL | 0:d92f9d21154c | 2959 | { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 }, |
wolfSSL | 0:d92f9d21154c | 2960 | { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 }, |
wolfSSL | 0:d92f9d21154c | 2961 | { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 }, |
wolfSSL | 0:d92f9d21154c | 2962 | { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 }, |
wolfSSL | 0:d92f9d21154c | 2963 | { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 }, |
wolfSSL | 0:d92f9d21154c | 2964 | { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 }, |
wolfSSL | 0:d92f9d21154c | 2965 | { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 }, |
wolfSSL | 0:d92f9d21154c | 2966 | { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 }, |
wolfSSL | 0:d92f9d21154c | 2967 | { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 }, |
wolfSSL | 0:d92f9d21154c | 2968 | { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 }, |
wolfSSL | 0:d92f9d21154c | 2969 | { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 }, |
wolfSSL | 0:d92f9d21154c | 2970 | { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 }, |
wolfSSL | 0:d92f9d21154c | 2971 | { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 }, |
wolfSSL | 0:d92f9d21154c | 2972 | { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 }, |
wolfSSL | 0:d92f9d21154c | 2973 | #if FP_LUT > 8 |
wolfSSL | 0:d92f9d21154c | 2974 | { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 }, |
wolfSSL | 0:d92f9d21154c | 2975 | { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 }, |
wolfSSL | 0:d92f9d21154c | 2976 | { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 }, |
wolfSSL | 0:d92f9d21154c | 2977 | { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 }, |
wolfSSL | 0:d92f9d21154c | 2978 | { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 }, |
wolfSSL | 0:d92f9d21154c | 2979 | { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 }, |
wolfSSL | 0:d92f9d21154c | 2980 | { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 }, |
wolfSSL | 0:d92f9d21154c | 2981 | { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 }, |
wolfSSL | 0:d92f9d21154c | 2982 | { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 }, |
wolfSSL | 0:d92f9d21154c | 2983 | { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 }, |
wolfSSL | 0:d92f9d21154c | 2984 | { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 }, |
wolfSSL | 0:d92f9d21154c | 2985 | { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 }, |
wolfSSL | 0:d92f9d21154c | 2986 | { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 }, |
wolfSSL | 0:d92f9d21154c | 2987 | { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 }, |
wolfSSL | 0:d92f9d21154c | 2988 | { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 }, |
wolfSSL | 0:d92f9d21154c | 2989 | { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 }, |
wolfSSL | 0:d92f9d21154c | 2990 | { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 }, |
wolfSSL | 0:d92f9d21154c | 2991 | { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 }, |
wolfSSL | 0:d92f9d21154c | 2992 | { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 }, |
wolfSSL | 0:d92f9d21154c | 2993 | { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 }, |
wolfSSL | 0:d92f9d21154c | 2994 | { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 }, |
wolfSSL | 0:d92f9d21154c | 2995 | { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 }, |
wolfSSL | 0:d92f9d21154c | 2996 | { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 }, |
wolfSSL | 0:d92f9d21154c | 2997 | { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 }, |
wolfSSL | 0:d92f9d21154c | 2998 | { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 }, |
wolfSSL | 0:d92f9d21154c | 2999 | { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 }, |
wolfSSL | 0:d92f9d21154c | 3000 | { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 }, |
wolfSSL | 0:d92f9d21154c | 3001 | { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 }, |
wolfSSL | 0:d92f9d21154c | 3002 | { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 }, |
wolfSSL | 0:d92f9d21154c | 3003 | { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 }, |
wolfSSL | 0:d92f9d21154c | 3004 | { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 }, |
wolfSSL | 0:d92f9d21154c | 3005 | { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 }, |
wolfSSL | 0:d92f9d21154c | 3006 | #if FP_LUT > 9 |
wolfSSL | 0:d92f9d21154c | 3007 | { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 }, |
wolfSSL | 0:d92f9d21154c | 3008 | { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 }, |
wolfSSL | 0:d92f9d21154c | 3009 | { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 }, |
wolfSSL | 0:d92f9d21154c | 3010 | { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 }, |
wolfSSL | 0:d92f9d21154c | 3011 | { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 }, |
wolfSSL | 0:d92f9d21154c | 3012 | { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 }, |
wolfSSL | 0:d92f9d21154c | 3013 | { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 }, |
wolfSSL | 0:d92f9d21154c | 3014 | { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 }, |
wolfSSL | 0:d92f9d21154c | 3015 | { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 }, |
wolfSSL | 0:d92f9d21154c | 3016 | { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 }, |
wolfSSL | 0:d92f9d21154c | 3017 | { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 }, |
wolfSSL | 0:d92f9d21154c | 3018 | { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 }, |
wolfSSL | 0:d92f9d21154c | 3019 | { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 }, |
wolfSSL | 0:d92f9d21154c | 3020 | { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 }, |
wolfSSL | 0:d92f9d21154c | 3021 | { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 }, |
wolfSSL | 0:d92f9d21154c | 3022 | { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 }, |
wolfSSL | 0:d92f9d21154c | 3023 | { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 }, |
wolfSSL | 0:d92f9d21154c | 3024 | { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 }, |
wolfSSL | 0:d92f9d21154c | 3025 | { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 }, |
wolfSSL | 0:d92f9d21154c | 3026 | { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 }, |
wolfSSL | 0:d92f9d21154c | 3027 | { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 }, |
wolfSSL | 0:d92f9d21154c | 3028 | { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 }, |
wolfSSL | 0:d92f9d21154c | 3029 | { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 }, |
wolfSSL | 0:d92f9d21154c | 3030 | { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 }, |
wolfSSL | 0:d92f9d21154c | 3031 | { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 }, |
wolfSSL | 0:d92f9d21154c | 3032 | { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 }, |
wolfSSL | 0:d92f9d21154c | 3033 | { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 }, |
wolfSSL | 0:d92f9d21154c | 3034 | { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 }, |
wolfSSL | 0:d92f9d21154c | 3035 | { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 }, |
wolfSSL | 0:d92f9d21154c | 3036 | { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 }, |
wolfSSL | 0:d92f9d21154c | 3037 | { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 }, |
wolfSSL | 0:d92f9d21154c | 3038 | { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 }, |
wolfSSL | 0:d92f9d21154c | 3039 | { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 }, |
wolfSSL | 0:d92f9d21154c | 3040 | { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 }, |
wolfSSL | 0:d92f9d21154c | 3041 | { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 }, |
wolfSSL | 0:d92f9d21154c | 3042 | { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 }, |
wolfSSL | 0:d92f9d21154c | 3043 | { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 }, |
wolfSSL | 0:d92f9d21154c | 3044 | { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 }, |
wolfSSL | 0:d92f9d21154c | 3045 | { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 }, |
wolfSSL | 0:d92f9d21154c | 3046 | { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 }, |
wolfSSL | 0:d92f9d21154c | 3047 | { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 }, |
wolfSSL | 0:d92f9d21154c | 3048 | { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 }, |
wolfSSL | 0:d92f9d21154c | 3049 | { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 }, |
wolfSSL | 0:d92f9d21154c | 3050 | { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 }, |
wolfSSL | 0:d92f9d21154c | 3051 | { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 }, |
wolfSSL | 0:d92f9d21154c | 3052 | { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 }, |
wolfSSL | 0:d92f9d21154c | 3053 | { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 }, |
wolfSSL | 0:d92f9d21154c | 3054 | { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 }, |
wolfSSL | 0:d92f9d21154c | 3055 | { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 }, |
wolfSSL | 0:d92f9d21154c | 3056 | { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 }, |
wolfSSL | 0:d92f9d21154c | 3057 | { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 }, |
wolfSSL | 0:d92f9d21154c | 3058 | { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 }, |
wolfSSL | 0:d92f9d21154c | 3059 | { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 }, |
wolfSSL | 0:d92f9d21154c | 3060 | { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 }, |
wolfSSL | 0:d92f9d21154c | 3061 | { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 }, |
wolfSSL | 0:d92f9d21154c | 3062 | { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 }, |
wolfSSL | 0:d92f9d21154c | 3063 | { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 }, |
wolfSSL | 0:d92f9d21154c | 3064 | { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 }, |
wolfSSL | 0:d92f9d21154c | 3065 | { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 }, |
wolfSSL | 0:d92f9d21154c | 3066 | { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 }, |
wolfSSL | 0:d92f9d21154c | 3067 | { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 }, |
wolfSSL | 0:d92f9d21154c | 3068 | { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 }, |
wolfSSL | 0:d92f9d21154c | 3069 | { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 }, |
wolfSSL | 0:d92f9d21154c | 3070 | { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 }, |
wolfSSL | 0:d92f9d21154c | 3071 | #if FP_LUT > 10 |
wolfSSL | 0:d92f9d21154c | 3072 | { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3073 | { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3074 | { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3075 | { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3076 | { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3077 | { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3078 | { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3079 | { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3080 | { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3081 | { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3082 | { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3083 | { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3084 | { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3085 | { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3086 | { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3087 | { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3088 | { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3089 | { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3090 | { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3091 | { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3092 | { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3093 | { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3094 | { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3095 | { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3096 | { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3097 | { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3098 | { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3099 | { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3100 | { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3101 | { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3102 | { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3103 | { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3104 | { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3105 | { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3106 | { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3107 | { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3108 | { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3109 | { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3110 | { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3111 | { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3112 | { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3113 | { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3114 | { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3115 | { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3116 | { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3117 | { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3118 | { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3119 | { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3120 | { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3121 | { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3122 | { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3123 | { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3124 | { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3125 | { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3126 | { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3127 | { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3128 | { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3129 | { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3130 | { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3131 | { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3132 | { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3133 | { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3134 | { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3135 | { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3136 | { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3137 | { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3138 | { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3139 | { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3140 | { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3141 | { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3142 | { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3143 | { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3144 | { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3145 | { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3146 | { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3147 | { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3148 | { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3149 | { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3150 | { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3151 | { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3152 | { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3153 | { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3154 | { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3155 | { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3156 | { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3157 | { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3158 | { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3159 | { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3160 | { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3161 | { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3162 | { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3163 | { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3164 | { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3165 | { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3166 | { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3167 | { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3168 | { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3169 | { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3170 | { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3171 | { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3172 | { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3173 | { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3174 | { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3175 | { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3176 | { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3177 | { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3178 | { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3179 | { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3180 | { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3181 | { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3182 | { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3183 | { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3184 | { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3185 | { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3186 | { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3187 | { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3188 | { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3189 | { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3190 | { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3191 | { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3192 | { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3193 | { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3194 | { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3195 | { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3196 | { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3197 | { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3198 | { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3199 | { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 }, |
wolfSSL | 0:d92f9d21154c | 3200 | #if FP_LUT > 11 |
wolfSSL | 0:d92f9d21154c | 3201 | { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3202 | { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3203 | { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3204 | { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3205 | { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3206 | { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3207 | { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3208 | { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3209 | { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3210 | { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3211 | { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3212 | { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3213 | { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3214 | { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3215 | { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3216 | { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3217 | { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3218 | { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3219 | { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3220 | { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3221 | { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3222 | { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3223 | { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3224 | { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3225 | { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3226 | { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3227 | { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3228 | { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3229 | { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3230 | { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3231 | { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3232 | { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3233 | { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3234 | { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3235 | { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3236 | { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3237 | { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3238 | { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3239 | { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3240 | { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3241 | { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3242 | { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3243 | { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3244 | { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3245 | { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3246 | { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3247 | { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3248 | { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3249 | { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3250 | { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3251 | { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3252 | { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3253 | { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3254 | { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3255 | { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3256 | { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3257 | { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3258 | { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3259 | { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3260 | { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3261 | { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3262 | { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3263 | { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3264 | { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3265 | { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3266 | { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3267 | { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3268 | { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3269 | { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3270 | { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3271 | { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3272 | { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3273 | { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3274 | { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3275 | { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3276 | { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3277 | { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3278 | { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3279 | { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3280 | { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3281 | { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3282 | { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3283 | { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3284 | { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3285 | { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3286 | { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3287 | { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3288 | { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3289 | { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3290 | { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3291 | { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3292 | { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3293 | { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3294 | { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3295 | { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3296 | { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3297 | { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3298 | { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3299 | { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3300 | { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3301 | { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3302 | { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3303 | { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3304 | { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3305 | { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3306 | { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3307 | { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3308 | { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3309 | { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3310 | { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3311 | { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3312 | { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3313 | { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3314 | { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3315 | { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3316 | { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3317 | { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3318 | { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3319 | { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3320 | { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3321 | { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3322 | { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3323 | { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3324 | { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3325 | { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3326 | { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3327 | { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3328 | { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3329 | { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3330 | { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3331 | { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3332 | { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3333 | { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3334 | { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3335 | { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3336 | { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3337 | { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3338 | { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3339 | { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3340 | { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3341 | { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3342 | { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3343 | { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3344 | { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3345 | { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3346 | { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3347 | { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3348 | { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3349 | { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3350 | { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3351 | { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3352 | { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3353 | { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3354 | { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3355 | { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3356 | { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3357 | { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3358 | { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3359 | { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3360 | { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3361 | { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3362 | { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3363 | { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3364 | { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3365 | { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3366 | { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3367 | { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3368 | { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3369 | { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3370 | { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3371 | { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3372 | { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3373 | { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3374 | { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3375 | { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3376 | { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3377 | { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3378 | { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3379 | { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3380 | { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3381 | { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3382 | { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3383 | { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3384 | { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3385 | { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3386 | { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3387 | { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3388 | { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3389 | { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3390 | { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3391 | { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3392 | { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3393 | { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3394 | { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3395 | { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3396 | { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3397 | { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3398 | { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3399 | { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3400 | { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3401 | { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3402 | { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3403 | { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3404 | { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3405 | { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3406 | { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3407 | { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3408 | { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3409 | { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3410 | { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3411 | { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3412 | { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3413 | { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3414 | { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3415 | { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3416 | { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3417 | { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3418 | { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3419 | { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3420 | { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3421 | { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3422 | { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3423 | { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3424 | { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3425 | { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3426 | { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3427 | { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3428 | { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3429 | { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3430 | { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3431 | { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3432 | { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3433 | { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3434 | { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3435 | { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3436 | { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3437 | { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3438 | { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3439 | { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3440 | { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3441 | { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3442 | { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3443 | { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3444 | { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3445 | { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3446 | { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3447 | { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3448 | { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3449 | { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3450 | { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3451 | { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3452 | { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3453 | { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3454 | { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3455 | { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3456 | { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 }, |
wolfSSL | 0:d92f9d21154c | 3457 | #endif |
wolfSSL | 0:d92f9d21154c | 3458 | #endif |
wolfSSL | 0:d92f9d21154c | 3459 | #endif |
wolfSSL | 0:d92f9d21154c | 3460 | #endif |
wolfSSL | 0:d92f9d21154c | 3461 | #endif |
wolfSSL | 0:d92f9d21154c | 3462 | #endif |
wolfSSL | 0:d92f9d21154c | 3463 | }; |
wolfSSL | 0:d92f9d21154c | 3464 | |
wolfSSL | 0:d92f9d21154c | 3465 | /* find a hole and free as required, return -1 if no hole found */ |
wolfSSL | 0:d92f9d21154c | 3466 | static int find_hole(void) |
wolfSSL | 0:d92f9d21154c | 3467 | { |
wolfSSL | 0:d92f9d21154c | 3468 | unsigned x; |
wolfSSL | 0:d92f9d21154c | 3469 | int y, z; |
wolfSSL | 0:d92f9d21154c | 3470 | for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { |
wolfSSL | 0:d92f9d21154c | 3471 | if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { |
wolfSSL | 0:d92f9d21154c | 3472 | z = x; |
wolfSSL | 0:d92f9d21154c | 3473 | y = fp_cache[x].lru_count; |
wolfSSL | 0:d92f9d21154c | 3474 | } |
wolfSSL | 0:d92f9d21154c | 3475 | } |
wolfSSL | 0:d92f9d21154c | 3476 | |
wolfSSL | 0:d92f9d21154c | 3477 | /* decrease all */ |
wolfSSL | 0:d92f9d21154c | 3478 | for (x = 0; x < FP_ENTRIES; x++) { |
wolfSSL | 0:d92f9d21154c | 3479 | if (fp_cache[x].lru_count > 3) { |
wolfSSL | 0:d92f9d21154c | 3480 | --(fp_cache[x].lru_count); |
wolfSSL | 0:d92f9d21154c | 3481 | } |
wolfSSL | 0:d92f9d21154c | 3482 | } |
wolfSSL | 0:d92f9d21154c | 3483 | |
wolfSSL | 0:d92f9d21154c | 3484 | /* free entry z */ |
wolfSSL | 0:d92f9d21154c | 3485 | if (z >= 0 && fp_cache[z].g) { |
wolfSSL | 0:d92f9d21154c | 3486 | mp_clear(&fp_cache[z].mu); |
wolfSSL | 0:d92f9d21154c | 3487 | ecc_del_point(fp_cache[z].g); |
wolfSSL | 0:d92f9d21154c | 3488 | fp_cache[z].g = NULL; |
wolfSSL | 0:d92f9d21154c | 3489 | for (x = 0; x < (1U<<FP_LUT); x++) { |
wolfSSL | 0:d92f9d21154c | 3490 | ecc_del_point(fp_cache[z].LUT[x]); |
wolfSSL | 0:d92f9d21154c | 3491 | fp_cache[z].LUT[x] = NULL; |
wolfSSL | 0:d92f9d21154c | 3492 | } |
wolfSSL | 0:d92f9d21154c | 3493 | fp_cache[z].lru_count = 0; |
wolfSSL | 0:d92f9d21154c | 3494 | } |
wolfSSL | 0:d92f9d21154c | 3495 | return z; |
wolfSSL | 0:d92f9d21154c | 3496 | } |
wolfSSL | 0:d92f9d21154c | 3497 | |
wolfSSL | 0:d92f9d21154c | 3498 | /* determine if a base is already in the cache and if so, where */ |
wolfSSL | 0:d92f9d21154c | 3499 | static int find_base(ecc_point* g) |
wolfSSL | 0:d92f9d21154c | 3500 | { |
wolfSSL | 0:d92f9d21154c | 3501 | int x; |
wolfSSL | 0:d92f9d21154c | 3502 | for (x = 0; x < FP_ENTRIES; x++) { |
wolfSSL | 0:d92f9d21154c | 3503 | if (fp_cache[x].g != NULL && |
wolfSSL | 0:d92f9d21154c | 3504 | mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ && |
wolfSSL | 0:d92f9d21154c | 3505 | mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ && |
wolfSSL | 0:d92f9d21154c | 3506 | mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) { |
wolfSSL | 0:d92f9d21154c | 3507 | break; |
wolfSSL | 0:d92f9d21154c | 3508 | } |
wolfSSL | 0:d92f9d21154c | 3509 | } |
wolfSSL | 0:d92f9d21154c | 3510 | if (x == FP_ENTRIES) { |
wolfSSL | 0:d92f9d21154c | 3511 | x = -1; |
wolfSSL | 0:d92f9d21154c | 3512 | } |
wolfSSL | 0:d92f9d21154c | 3513 | return x; |
wolfSSL | 0:d92f9d21154c | 3514 | } |
wolfSSL | 0:d92f9d21154c | 3515 | |
wolfSSL | 0:d92f9d21154c | 3516 | /* add a new base to the cache */ |
wolfSSL | 0:d92f9d21154c | 3517 | static int add_entry(int idx, ecc_point *g) |
wolfSSL | 0:d92f9d21154c | 3518 | { |
wolfSSL | 0:d92f9d21154c | 3519 | unsigned x, y; |
wolfSSL | 0:d92f9d21154c | 3520 | |
wolfSSL | 0:d92f9d21154c | 3521 | /* allocate base and LUT */ |
wolfSSL | 0:d92f9d21154c | 3522 | fp_cache[idx].g = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 3523 | if (fp_cache[idx].g == NULL) { |
wolfSSL | 0:d92f9d21154c | 3524 | return GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 3525 | } |
wolfSSL | 0:d92f9d21154c | 3526 | |
wolfSSL | 0:d92f9d21154c | 3527 | /* copy x and y */ |
wolfSSL | 0:d92f9d21154c | 3528 | if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 3529 | (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 3530 | (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) { |
wolfSSL | 0:d92f9d21154c | 3531 | ecc_del_point(fp_cache[idx].g); |
wolfSSL | 0:d92f9d21154c | 3532 | fp_cache[idx].g = NULL; |
wolfSSL | 0:d92f9d21154c | 3533 | return GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 3534 | } |
wolfSSL | 0:d92f9d21154c | 3535 | |
wolfSSL | 0:d92f9d21154c | 3536 | for (x = 0; x < (1U<<FP_LUT); x++) { |
wolfSSL | 0:d92f9d21154c | 3537 | fp_cache[idx].LUT[x] = ecc_new_point(); |
wolfSSL | 0:d92f9d21154c | 3538 | if (fp_cache[idx].LUT[x] == NULL) { |
wolfSSL | 0:d92f9d21154c | 3539 | for (y = 0; y < x; y++) { |
wolfSSL | 0:d92f9d21154c | 3540 | ecc_del_point(fp_cache[idx].LUT[y]); |
wolfSSL | 0:d92f9d21154c | 3541 | fp_cache[idx].LUT[y] = NULL; |
wolfSSL | 0:d92f9d21154c | 3542 | } |
wolfSSL | 0:d92f9d21154c | 3543 | ecc_del_point(fp_cache[idx].g); |
wolfSSL | 0:d92f9d21154c | 3544 | fp_cache[idx].g = NULL; |
wolfSSL | 0:d92f9d21154c | 3545 | fp_cache[idx].lru_count = 0; |
wolfSSL | 0:d92f9d21154c | 3546 | return GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 3547 | } |
wolfSSL | 0:d92f9d21154c | 3548 | } |
wolfSSL | 0:d92f9d21154c | 3549 | |
wolfSSL | 0:d92f9d21154c | 3550 | fp_cache[idx].lru_count = 0; |
wolfSSL | 0:d92f9d21154c | 3551 | |
wolfSSL | 0:d92f9d21154c | 3552 | return MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 3553 | } |
wolfSSL | 0:d92f9d21154c | 3554 | |
wolfSSL | 0:d92f9d21154c | 3555 | /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart |
wolfSSL | 0:d92f9d21154c | 3556 | * |
wolfSSL | 0:d92f9d21154c | 3557 | * The algorithm builds patterns in increasing bit order by first making all |
wolfSSL | 0:d92f9d21154c | 3558 | * single bit input patterns, then all two bit input patterns and so on |
wolfSSL | 0:d92f9d21154c | 3559 | */ |
wolfSSL | 0:d92f9d21154c | 3560 | static int build_lut(int idx, mp_int* modulus, mp_digit* mp, mp_int* mu) |
wolfSSL | 0:d92f9d21154c | 3561 | { |
wolfSSL | 0:d92f9d21154c | 3562 | unsigned x, y, err, bitlen, lut_gap; |
wolfSSL | 0:d92f9d21154c | 3563 | mp_int tmp; |
wolfSSL | 0:d92f9d21154c | 3564 | |
wolfSSL | 0:d92f9d21154c | 3565 | if (mp_init(&tmp) != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3566 | return GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 3567 | |
wolfSSL | 0:d92f9d21154c | 3568 | /* sanity check to make sure lut_order table is of correct size, |
wolfSSL | 0:d92f9d21154c | 3569 | should compile out to a NOP if true */ |
wolfSSL | 0:d92f9d21154c | 3570 | if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) { |
wolfSSL | 0:d92f9d21154c | 3571 | err = BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 3572 | } |
wolfSSL | 0:d92f9d21154c | 3573 | else { |
wolfSSL | 0:d92f9d21154c | 3574 | /* get bitlen and round up to next multiple of FP_LUT */ |
wolfSSL | 0:d92f9d21154c | 3575 | bitlen = mp_unsigned_bin_size(modulus) << 3; |
wolfSSL | 0:d92f9d21154c | 3576 | x = bitlen % FP_LUT; |
wolfSSL | 0:d92f9d21154c | 3577 | if (x) { |
wolfSSL | 0:d92f9d21154c | 3578 | bitlen += FP_LUT - x; |
wolfSSL | 0:d92f9d21154c | 3579 | } |
wolfSSL | 0:d92f9d21154c | 3580 | lut_gap = bitlen / FP_LUT; |
wolfSSL | 0:d92f9d21154c | 3581 | |
wolfSSL | 0:d92f9d21154c | 3582 | /* init the mu */ |
wolfSSL | 0:d92f9d21154c | 3583 | err = mp_init_copy(&fp_cache[idx].mu, mu); |
wolfSSL | 0:d92f9d21154c | 3584 | } |
wolfSSL | 0:d92f9d21154c | 3585 | |
wolfSSL | 0:d92f9d21154c | 3586 | /* copy base */ |
wolfSSL | 0:d92f9d21154c | 3587 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3588 | if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus, |
wolfSSL | 0:d92f9d21154c | 3589 | fp_cache[idx].LUT[1]->x) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 3590 | (mp_mulmod(fp_cache[idx].g->y, mu, modulus, |
wolfSSL | 0:d92f9d21154c | 3591 | fp_cache[idx].LUT[1]->y) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 3592 | (mp_mulmod(fp_cache[idx].g->z, mu, modulus, |
wolfSSL | 0:d92f9d21154c | 3593 | fp_cache[idx].LUT[1]->z) != MP_OKAY)) { |
wolfSSL | 0:d92f9d21154c | 3594 | err = MP_MULMOD_E; |
wolfSSL | 0:d92f9d21154c | 3595 | } |
wolfSSL | 0:d92f9d21154c | 3596 | } |
wolfSSL | 0:d92f9d21154c | 3597 | |
wolfSSL | 0:d92f9d21154c | 3598 | /* make all single bit entries */ |
wolfSSL | 0:d92f9d21154c | 3599 | for (x = 1; x < FP_LUT; x++) { |
wolfSSL | 0:d92f9d21154c | 3600 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3601 | break; |
wolfSSL | 0:d92f9d21154c | 3602 | if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, |
wolfSSL | 0:d92f9d21154c | 3603 | fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 3604 | (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, |
wolfSSL | 0:d92f9d21154c | 3605 | fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 3606 | (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, |
wolfSSL | 0:d92f9d21154c | 3607 | fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){ |
wolfSSL | 0:d92f9d21154c | 3608 | err = MP_INIT_E; |
wolfSSL | 0:d92f9d21154c | 3609 | break; |
wolfSSL | 0:d92f9d21154c | 3610 | } else { |
wolfSSL | 0:d92f9d21154c | 3611 | |
wolfSSL | 0:d92f9d21154c | 3612 | /* now double it bitlen/FP_LUT times */ |
wolfSSL | 0:d92f9d21154c | 3613 | for (y = 0; y < lut_gap; y++) { |
wolfSSL | 0:d92f9d21154c | 3614 | if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x], |
wolfSSL | 0:d92f9d21154c | 3615 | fp_cache[idx].LUT[1<<x], modulus, mp)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3616 | break; |
wolfSSL | 0:d92f9d21154c | 3617 | } |
wolfSSL | 0:d92f9d21154c | 3618 | } |
wolfSSL | 0:d92f9d21154c | 3619 | } |
wolfSSL | 0:d92f9d21154c | 3620 | } |
wolfSSL | 0:d92f9d21154c | 3621 | |
wolfSSL | 0:d92f9d21154c | 3622 | /* now make all entries in increase order of hamming weight */ |
wolfSSL | 0:d92f9d21154c | 3623 | for (x = 2; x <= FP_LUT; x++) { |
wolfSSL | 0:d92f9d21154c | 3624 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3625 | break; |
wolfSSL | 0:d92f9d21154c | 3626 | for (y = 0; y < (1UL<<FP_LUT); y++) { |
wolfSSL | 0:d92f9d21154c | 3627 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3628 | break; |
wolfSSL | 0:d92f9d21154c | 3629 | if (lut_orders[y].ham != (int)x) continue; |
wolfSSL | 0:d92f9d21154c | 3630 | |
wolfSSL | 0:d92f9d21154c | 3631 | /* perform the add */ |
wolfSSL | 0:d92f9d21154c | 3632 | if ((err = ecc_projective_add_point( |
wolfSSL | 0:d92f9d21154c | 3633 | fp_cache[idx].LUT[lut_orders[y].terma], |
wolfSSL | 0:d92f9d21154c | 3634 | fp_cache[idx].LUT[lut_orders[y].termb], |
wolfSSL | 0:d92f9d21154c | 3635 | fp_cache[idx].LUT[y], modulus, mp)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3636 | break; |
wolfSSL | 0:d92f9d21154c | 3637 | } |
wolfSSL | 0:d92f9d21154c | 3638 | } |
wolfSSL | 0:d92f9d21154c | 3639 | } |
wolfSSL | 0:d92f9d21154c | 3640 | |
wolfSSL | 0:d92f9d21154c | 3641 | /* now map all entries back to affine space to make point addition faster */ |
wolfSSL | 0:d92f9d21154c | 3642 | for (x = 1; x < (1UL<<FP_LUT); x++) { |
wolfSSL | 0:d92f9d21154c | 3643 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3644 | break; |
wolfSSL | 0:d92f9d21154c | 3645 | |
wolfSSL | 0:d92f9d21154c | 3646 | /* convert z to normal from montgomery */ |
wolfSSL | 0:d92f9d21154c | 3647 | err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, *mp); |
wolfSSL | 0:d92f9d21154c | 3648 | |
wolfSSL | 0:d92f9d21154c | 3649 | /* invert it */ |
wolfSSL | 0:d92f9d21154c | 3650 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3651 | err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, |
wolfSSL | 0:d92f9d21154c | 3652 | fp_cache[idx].LUT[x]->z); |
wolfSSL | 0:d92f9d21154c | 3653 | |
wolfSSL | 0:d92f9d21154c | 3654 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3655 | /* now square it */ |
wolfSSL | 0:d92f9d21154c | 3656 | err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp); |
wolfSSL | 0:d92f9d21154c | 3657 | |
wolfSSL | 0:d92f9d21154c | 3658 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3659 | /* fix x */ |
wolfSSL | 0:d92f9d21154c | 3660 | err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus, |
wolfSSL | 0:d92f9d21154c | 3661 | fp_cache[idx].LUT[x]->x); |
wolfSSL | 0:d92f9d21154c | 3662 | |
wolfSSL | 0:d92f9d21154c | 3663 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3664 | /* get 1/z^3 */ |
wolfSSL | 0:d92f9d21154c | 3665 | err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp); |
wolfSSL | 0:d92f9d21154c | 3666 | |
wolfSSL | 0:d92f9d21154c | 3667 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3668 | /* fix y */ |
wolfSSL | 0:d92f9d21154c | 3669 | err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus, |
wolfSSL | 0:d92f9d21154c | 3670 | fp_cache[idx].LUT[x]->y); |
wolfSSL | 0:d92f9d21154c | 3671 | |
wolfSSL | 0:d92f9d21154c | 3672 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3673 | /* free z */ |
wolfSSL | 0:d92f9d21154c | 3674 | mp_clear(fp_cache[idx].LUT[x]->z); |
wolfSSL | 0:d92f9d21154c | 3675 | } |
wolfSSL | 0:d92f9d21154c | 3676 | mp_clear(&tmp); |
wolfSSL | 0:d92f9d21154c | 3677 | |
wolfSSL | 0:d92f9d21154c | 3678 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3679 | return MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 3680 | |
wolfSSL | 0:d92f9d21154c | 3681 | /* err cleanup */ |
wolfSSL | 0:d92f9d21154c | 3682 | for (y = 0; y < (1U<<FP_LUT); y++) { |
wolfSSL | 0:d92f9d21154c | 3683 | ecc_del_point(fp_cache[idx].LUT[y]); |
wolfSSL | 0:d92f9d21154c | 3684 | fp_cache[idx].LUT[y] = NULL; |
wolfSSL | 0:d92f9d21154c | 3685 | } |
wolfSSL | 0:d92f9d21154c | 3686 | ecc_del_point(fp_cache[idx].g); |
wolfSSL | 0:d92f9d21154c | 3687 | fp_cache[idx].g = NULL; |
wolfSSL | 0:d92f9d21154c | 3688 | fp_cache[idx].lru_count = 0; |
wolfSSL | 0:d92f9d21154c | 3689 | mp_clear(&fp_cache[idx].mu); |
wolfSSL | 0:d92f9d21154c | 3690 | mp_clear(&tmp); |
wolfSSL | 0:d92f9d21154c | 3691 | |
wolfSSL | 0:d92f9d21154c | 3692 | return err; |
wolfSSL | 0:d92f9d21154c | 3693 | } |
wolfSSL | 0:d92f9d21154c | 3694 | |
wolfSSL | 0:d92f9d21154c | 3695 | /* perform a fixed point ECC mulmod */ |
wolfSSL | 0:d92f9d21154c | 3696 | static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* modulus, |
wolfSSL | 0:d92f9d21154c | 3697 | mp_digit* mp, int map) |
wolfSSL | 0:d92f9d21154c | 3698 | { |
wolfSSL | 0:d92f9d21154c | 3699 | #define KB_SIZE 128 |
wolfSSL | 0:d92f9d21154c | 3700 | |
wolfSSL | 0:d92f9d21154c | 3701 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 3702 | unsigned char* kb; |
wolfSSL | 0:d92f9d21154c | 3703 | #else |
wolfSSL | 0:d92f9d21154c | 3704 | unsigned char kb[128]; |
wolfSSL | 0:d92f9d21154c | 3705 | #endif |
wolfSSL | 0:d92f9d21154c | 3706 | int x; |
wolfSSL | 0:d92f9d21154c | 3707 | unsigned y, z, err, bitlen, bitpos, lut_gap, first; |
wolfSSL | 0:d92f9d21154c | 3708 | mp_int tk; |
wolfSSL | 0:d92f9d21154c | 3709 | |
wolfSSL | 0:d92f9d21154c | 3710 | if (mp_init(&tk) != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3711 | return MP_INIT_E; |
wolfSSL | 0:d92f9d21154c | 3712 | |
wolfSSL | 0:d92f9d21154c | 3713 | /* if it's smaller than modulus we fine */ |
wolfSSL | 0:d92f9d21154c | 3714 | if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) { |
wolfSSL | 0:d92f9d21154c | 3715 | mp_int order; |
wolfSSL | 0:d92f9d21154c | 3716 | if (mp_init(&order) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3717 | mp_clear(&tk); |
wolfSSL | 0:d92f9d21154c | 3718 | return MP_INIT_E; |
wolfSSL | 0:d92f9d21154c | 3719 | } |
wolfSSL | 0:d92f9d21154c | 3720 | |
wolfSSL | 0:d92f9d21154c | 3721 | /* find order */ |
wolfSSL | 0:d92f9d21154c | 3722 | y = mp_unsigned_bin_size(modulus); |
wolfSSL | 0:d92f9d21154c | 3723 | for (x = 0; ecc_sets[x].size; x++) { |
wolfSSL | 0:d92f9d21154c | 3724 | if (y <= (unsigned)ecc_sets[x].size) break; |
wolfSSL | 0:d92f9d21154c | 3725 | } |
wolfSSL | 0:d92f9d21154c | 3726 | |
wolfSSL | 0:d92f9d21154c | 3727 | /* back off if we are on the 521 bit curve */ |
wolfSSL | 0:d92f9d21154c | 3728 | if (y == 66) --x; |
wolfSSL | 0:d92f9d21154c | 3729 | |
wolfSSL | 0:d92f9d21154c | 3730 | if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3731 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 3732 | mp_clear(&tk); |
wolfSSL | 0:d92f9d21154c | 3733 | return err; |
wolfSSL | 0:d92f9d21154c | 3734 | } |
wolfSSL | 0:d92f9d21154c | 3735 | |
wolfSSL | 0:d92f9d21154c | 3736 | /* k must be less than modulus */ |
wolfSSL | 0:d92f9d21154c | 3737 | if (mp_cmp(k, &order) != MP_LT) { |
wolfSSL | 0:d92f9d21154c | 3738 | if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3739 | mp_clear(&tk); |
wolfSSL | 0:d92f9d21154c | 3740 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 3741 | return err; |
wolfSSL | 0:d92f9d21154c | 3742 | } |
wolfSSL | 0:d92f9d21154c | 3743 | } else { |
wolfSSL | 0:d92f9d21154c | 3744 | mp_copy(k, &tk); |
wolfSSL | 0:d92f9d21154c | 3745 | } |
wolfSSL | 0:d92f9d21154c | 3746 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 3747 | } else { |
wolfSSL | 0:d92f9d21154c | 3748 | mp_copy(k, &tk); |
wolfSSL | 0:d92f9d21154c | 3749 | } |
wolfSSL | 0:d92f9d21154c | 3750 | |
wolfSSL | 0:d92f9d21154c | 3751 | /* get bitlen and round up to next multiple of FP_LUT */ |
wolfSSL | 0:d92f9d21154c | 3752 | bitlen = mp_unsigned_bin_size(modulus) << 3; |
wolfSSL | 0:d92f9d21154c | 3753 | x = bitlen % FP_LUT; |
wolfSSL | 0:d92f9d21154c | 3754 | if (x) { |
wolfSSL | 0:d92f9d21154c | 3755 | bitlen += FP_LUT - x; |
wolfSSL | 0:d92f9d21154c | 3756 | } |
wolfSSL | 0:d92f9d21154c | 3757 | lut_gap = bitlen / FP_LUT; |
wolfSSL | 0:d92f9d21154c | 3758 | |
wolfSSL | 0:d92f9d21154c | 3759 | /* get the k value */ |
wolfSSL | 0:d92f9d21154c | 3760 | if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) { |
wolfSSL | 0:d92f9d21154c | 3761 | mp_clear(&tk); |
wolfSSL | 0:d92f9d21154c | 3762 | return BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 3763 | } |
wolfSSL | 0:d92f9d21154c | 3764 | |
wolfSSL | 0:d92f9d21154c | 3765 | /* store k */ |
wolfSSL | 0:d92f9d21154c | 3766 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 3767 | kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 3768 | if (kb == NULL) |
wolfSSL | 0:d92f9d21154c | 3769 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 3770 | #endif |
wolfSSL | 0:d92f9d21154c | 3771 | |
wolfSSL | 0:d92f9d21154c | 3772 | XMEMSET(kb, 0, KB_SIZE); |
wolfSSL | 0:d92f9d21154c | 3773 | if ((err = mp_to_unsigned_bin(&tk, kb)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3774 | mp_clear(&tk); |
wolfSSL | 0:d92f9d21154c | 3775 | } |
wolfSSL | 0:d92f9d21154c | 3776 | else { |
wolfSSL | 0:d92f9d21154c | 3777 | /* let's reverse kb so it's little endian */ |
wolfSSL | 0:d92f9d21154c | 3778 | x = 0; |
wolfSSL | 0:d92f9d21154c | 3779 | y = mp_unsigned_bin_size(&tk) - 1; |
wolfSSL | 0:d92f9d21154c | 3780 | mp_clear(&tk); |
wolfSSL | 0:d92f9d21154c | 3781 | |
wolfSSL | 0:d92f9d21154c | 3782 | while ((unsigned)x < y) { |
wolfSSL | 0:d92f9d21154c | 3783 | z = kb[x]; kb[x] = kb[y]; kb[y] = z; |
wolfSSL | 0:d92f9d21154c | 3784 | ++x; --y; |
wolfSSL | 0:d92f9d21154c | 3785 | } |
wolfSSL | 0:d92f9d21154c | 3786 | |
wolfSSL | 0:d92f9d21154c | 3787 | /* at this point we can start, yipee */ |
wolfSSL | 0:d92f9d21154c | 3788 | first = 1; |
wolfSSL | 0:d92f9d21154c | 3789 | for (x = lut_gap-1; x >= 0; x--) { |
wolfSSL | 0:d92f9d21154c | 3790 | /* extract FP_LUT bits from kb spread out by lut_gap bits and offset |
wolfSSL | 0:d92f9d21154c | 3791 | by x bits from the start */ |
wolfSSL | 0:d92f9d21154c | 3792 | bitpos = x; |
wolfSSL | 0:d92f9d21154c | 3793 | for (y = z = 0; y < FP_LUT; y++) { |
wolfSSL | 0:d92f9d21154c | 3794 | z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y; |
wolfSSL | 0:d92f9d21154c | 3795 | bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid |
wolfSSL | 0:d92f9d21154c | 3796 | the mult in each loop */ |
wolfSSL | 0:d92f9d21154c | 3797 | } |
wolfSSL | 0:d92f9d21154c | 3798 | |
wolfSSL | 0:d92f9d21154c | 3799 | /* double if not first */ |
wolfSSL | 0:d92f9d21154c | 3800 | if (!first) { |
wolfSSL | 0:d92f9d21154c | 3801 | if ((err = ecc_projective_dbl_point(R, R, modulus, |
wolfSSL | 0:d92f9d21154c | 3802 | mp)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3803 | break; |
wolfSSL | 0:d92f9d21154c | 3804 | } |
wolfSSL | 0:d92f9d21154c | 3805 | } |
wolfSSL | 0:d92f9d21154c | 3806 | |
wolfSSL | 0:d92f9d21154c | 3807 | /* add if not first, otherwise copy */ |
wolfSSL | 0:d92f9d21154c | 3808 | if (!first && z) { |
wolfSSL | 0:d92f9d21154c | 3809 | if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, |
wolfSSL | 0:d92f9d21154c | 3810 | modulus, mp)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3811 | break; |
wolfSSL | 0:d92f9d21154c | 3812 | } |
wolfSSL | 0:d92f9d21154c | 3813 | } else if (z) { |
wolfSSL | 0:d92f9d21154c | 3814 | if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 3815 | (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 3816 | (mp_copy(&fp_cache[idx].mu, R->z) != MP_OKAY)) { |
wolfSSL | 0:d92f9d21154c | 3817 | err = GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 3818 | break; |
wolfSSL | 0:d92f9d21154c | 3819 | } |
wolfSSL | 0:d92f9d21154c | 3820 | first = 0; |
wolfSSL | 0:d92f9d21154c | 3821 | } |
wolfSSL | 0:d92f9d21154c | 3822 | } |
wolfSSL | 0:d92f9d21154c | 3823 | } |
wolfSSL | 0:d92f9d21154c | 3824 | |
wolfSSL | 0:d92f9d21154c | 3825 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3826 | z = 0; |
wolfSSL | 0:d92f9d21154c | 3827 | ForceZero(kb, KB_SIZE); |
wolfSSL | 0:d92f9d21154c | 3828 | /* map R back from projective space */ |
wolfSSL | 0:d92f9d21154c | 3829 | if (map) { |
wolfSSL | 0:d92f9d21154c | 3830 | err = ecc_map(R, modulus, mp); |
wolfSSL | 0:d92f9d21154c | 3831 | } else { |
wolfSSL | 0:d92f9d21154c | 3832 | err = MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 3833 | } |
wolfSSL | 0:d92f9d21154c | 3834 | } |
wolfSSL | 0:d92f9d21154c | 3835 | |
wolfSSL | 0:d92f9d21154c | 3836 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 3837 | XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 3838 | #endif |
wolfSSL | 0:d92f9d21154c | 3839 | |
wolfSSL | 0:d92f9d21154c | 3840 | #undef KB_SIZE |
wolfSSL | 0:d92f9d21154c | 3841 | |
wolfSSL | 0:d92f9d21154c | 3842 | return err; |
wolfSSL | 0:d92f9d21154c | 3843 | } |
wolfSSL | 0:d92f9d21154c | 3844 | |
wolfSSL | 0:d92f9d21154c | 3845 | #ifdef ECC_SHAMIR |
wolfSSL | 0:d92f9d21154c | 3846 | /* perform a fixed point ECC mulmod */ |
wolfSSL | 0:d92f9d21154c | 3847 | static int accel_fp_mul2add(int idx1, int idx2, |
wolfSSL | 0:d92f9d21154c | 3848 | mp_int* kA, mp_int* kB, |
wolfSSL | 0:d92f9d21154c | 3849 | ecc_point *R, mp_int* modulus, mp_digit* mp) |
wolfSSL | 0:d92f9d21154c | 3850 | { |
wolfSSL | 0:d92f9d21154c | 3851 | #define KB_SIZE 128 |
wolfSSL | 0:d92f9d21154c | 3852 | |
wolfSSL | 0:d92f9d21154c | 3853 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 3854 | unsigned char* kb[2]; |
wolfSSL | 0:d92f9d21154c | 3855 | #else |
wolfSSL | 0:d92f9d21154c | 3856 | unsigned char kb[2][128]; |
wolfSSL | 0:d92f9d21154c | 3857 | #endif |
wolfSSL | 0:d92f9d21154c | 3858 | int x; |
wolfSSL | 0:d92f9d21154c | 3859 | unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB; |
wolfSSL | 0:d92f9d21154c | 3860 | mp_int tka; |
wolfSSL | 0:d92f9d21154c | 3861 | mp_int tkb; |
wolfSSL | 0:d92f9d21154c | 3862 | mp_int order; |
wolfSSL | 0:d92f9d21154c | 3863 | |
wolfSSL | 0:d92f9d21154c | 3864 | if (mp_init_multi(&tka, &tkb, 0, 0, 0, 0) != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 3865 | return MP_INIT_E; |
wolfSSL | 0:d92f9d21154c | 3866 | |
wolfSSL | 0:d92f9d21154c | 3867 | /* if it's smaller than modulus we fine */ |
wolfSSL | 0:d92f9d21154c | 3868 | if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { |
wolfSSL | 0:d92f9d21154c | 3869 | /* find order */ |
wolfSSL | 0:d92f9d21154c | 3870 | y = mp_unsigned_bin_size(modulus); |
wolfSSL | 0:d92f9d21154c | 3871 | for (x = 0; ecc_sets[x].size; x++) { |
wolfSSL | 0:d92f9d21154c | 3872 | if (y <= (unsigned)ecc_sets[x].size) break; |
wolfSSL | 0:d92f9d21154c | 3873 | } |
wolfSSL | 0:d92f9d21154c | 3874 | |
wolfSSL | 0:d92f9d21154c | 3875 | /* back off if we are on the 521 bit curve */ |
wolfSSL | 0:d92f9d21154c | 3876 | if (y == 66) --x; |
wolfSSL | 0:d92f9d21154c | 3877 | |
wolfSSL | 0:d92f9d21154c | 3878 | if ((err = mp_init(&order)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3879 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 3880 | mp_clear(&tka); |
wolfSSL | 0:d92f9d21154c | 3881 | return err; |
wolfSSL | 0:d92f9d21154c | 3882 | } |
wolfSSL | 0:d92f9d21154c | 3883 | if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3884 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 3885 | mp_clear(&tka); |
wolfSSL | 0:d92f9d21154c | 3886 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 3887 | return err; |
wolfSSL | 0:d92f9d21154c | 3888 | } |
wolfSSL | 0:d92f9d21154c | 3889 | |
wolfSSL | 0:d92f9d21154c | 3890 | /* kA must be less than modulus */ |
wolfSSL | 0:d92f9d21154c | 3891 | if (mp_cmp(kA, &order) != MP_LT) { |
wolfSSL | 0:d92f9d21154c | 3892 | if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3893 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 3894 | mp_clear(&tka); |
wolfSSL | 0:d92f9d21154c | 3895 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 3896 | return err; |
wolfSSL | 0:d92f9d21154c | 3897 | } |
wolfSSL | 0:d92f9d21154c | 3898 | } else { |
wolfSSL | 0:d92f9d21154c | 3899 | mp_copy(kA, &tka); |
wolfSSL | 0:d92f9d21154c | 3900 | } |
wolfSSL | 0:d92f9d21154c | 3901 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 3902 | } else { |
wolfSSL | 0:d92f9d21154c | 3903 | mp_copy(kA, &tka); |
wolfSSL | 0:d92f9d21154c | 3904 | } |
wolfSSL | 0:d92f9d21154c | 3905 | |
wolfSSL | 0:d92f9d21154c | 3906 | /* if it's smaller than modulus we fine */ |
wolfSSL | 0:d92f9d21154c | 3907 | if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { |
wolfSSL | 0:d92f9d21154c | 3908 | /* find order */ |
wolfSSL | 0:d92f9d21154c | 3909 | y = mp_unsigned_bin_size(modulus); |
wolfSSL | 0:d92f9d21154c | 3910 | for (x = 0; ecc_sets[x].size; x++) { |
wolfSSL | 0:d92f9d21154c | 3911 | if (y <= (unsigned)ecc_sets[x].size) break; |
wolfSSL | 0:d92f9d21154c | 3912 | } |
wolfSSL | 0:d92f9d21154c | 3913 | |
wolfSSL | 0:d92f9d21154c | 3914 | /* back off if we are on the 521 bit curve */ |
wolfSSL | 0:d92f9d21154c | 3915 | if (y == 66) --x; |
wolfSSL | 0:d92f9d21154c | 3916 | |
wolfSSL | 0:d92f9d21154c | 3917 | if ((err = mp_init(&order)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3918 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 3919 | mp_clear(&tka); |
wolfSSL | 0:d92f9d21154c | 3920 | return err; |
wolfSSL | 0:d92f9d21154c | 3921 | } |
wolfSSL | 0:d92f9d21154c | 3922 | if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3923 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 3924 | mp_clear(&tka); |
wolfSSL | 0:d92f9d21154c | 3925 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 3926 | return err; |
wolfSSL | 0:d92f9d21154c | 3927 | } |
wolfSSL | 0:d92f9d21154c | 3928 | |
wolfSSL | 0:d92f9d21154c | 3929 | /* kB must be less than modulus */ |
wolfSSL | 0:d92f9d21154c | 3930 | if (mp_cmp(kB, &order) != MP_LT) { |
wolfSSL | 0:d92f9d21154c | 3931 | if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3932 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 3933 | mp_clear(&tka); |
wolfSSL | 0:d92f9d21154c | 3934 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 3935 | return err; |
wolfSSL | 0:d92f9d21154c | 3936 | } |
wolfSSL | 0:d92f9d21154c | 3937 | } else { |
wolfSSL | 0:d92f9d21154c | 3938 | mp_copy(kB, &tkb); |
wolfSSL | 0:d92f9d21154c | 3939 | } |
wolfSSL | 0:d92f9d21154c | 3940 | mp_clear(&order); |
wolfSSL | 0:d92f9d21154c | 3941 | } else { |
wolfSSL | 0:d92f9d21154c | 3942 | mp_copy(kB, &tkb); |
wolfSSL | 0:d92f9d21154c | 3943 | } |
wolfSSL | 0:d92f9d21154c | 3944 | |
wolfSSL | 0:d92f9d21154c | 3945 | /* get bitlen and round up to next multiple of FP_LUT */ |
wolfSSL | 0:d92f9d21154c | 3946 | bitlen = mp_unsigned_bin_size(modulus) << 3; |
wolfSSL | 0:d92f9d21154c | 3947 | x = bitlen % FP_LUT; |
wolfSSL | 0:d92f9d21154c | 3948 | if (x) { |
wolfSSL | 0:d92f9d21154c | 3949 | bitlen += FP_LUT - x; |
wolfSSL | 0:d92f9d21154c | 3950 | } |
wolfSSL | 0:d92f9d21154c | 3951 | lut_gap = bitlen / FP_LUT; |
wolfSSL | 0:d92f9d21154c | 3952 | |
wolfSSL | 0:d92f9d21154c | 3953 | /* get the k value */ |
wolfSSL | 0:d92f9d21154c | 3954 | if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) || |
wolfSSL | 0:d92f9d21154c | 3955 | (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) { |
wolfSSL | 0:d92f9d21154c | 3956 | mp_clear(&tka); |
wolfSSL | 0:d92f9d21154c | 3957 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 3958 | return BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 3959 | } |
wolfSSL | 0:d92f9d21154c | 3960 | |
wolfSSL | 0:d92f9d21154c | 3961 | /* store k */ |
wolfSSL | 0:d92f9d21154c | 3962 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 3963 | kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 3964 | if (kb[0] == NULL) |
wolfSSL | 0:d92f9d21154c | 3965 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 3966 | #endif |
wolfSSL | 0:d92f9d21154c | 3967 | |
wolfSSL | 0:d92f9d21154c | 3968 | XMEMSET(kb[0], 0, KB_SIZE); |
wolfSSL | 0:d92f9d21154c | 3969 | if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3970 | mp_clear(&tka); |
wolfSSL | 0:d92f9d21154c | 3971 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 3972 | XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 3973 | return err; |
wolfSSL | 0:d92f9d21154c | 3974 | } |
wolfSSL | 0:d92f9d21154c | 3975 | |
wolfSSL | 0:d92f9d21154c | 3976 | /* let's reverse kb so it's little endian */ |
wolfSSL | 0:d92f9d21154c | 3977 | x = 0; |
wolfSSL | 0:d92f9d21154c | 3978 | y = mp_unsigned_bin_size(&tka) - 1; |
wolfSSL | 0:d92f9d21154c | 3979 | mp_clear(&tka); |
wolfSSL | 0:d92f9d21154c | 3980 | while ((unsigned)x < y) { |
wolfSSL | 0:d92f9d21154c | 3981 | z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z; |
wolfSSL | 0:d92f9d21154c | 3982 | ++x; --y; |
wolfSSL | 0:d92f9d21154c | 3983 | } |
wolfSSL | 0:d92f9d21154c | 3984 | |
wolfSSL | 0:d92f9d21154c | 3985 | /* store b */ |
wolfSSL | 0:d92f9d21154c | 3986 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 3987 | kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 3988 | if (kb[1] == NULL) { |
wolfSSL | 0:d92f9d21154c | 3989 | XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 3990 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 3991 | } |
wolfSSL | 0:d92f9d21154c | 3992 | #endif |
wolfSSL | 0:d92f9d21154c | 3993 | |
wolfSSL | 0:d92f9d21154c | 3994 | XMEMSET(kb[1], 0, KB_SIZE); |
wolfSSL | 0:d92f9d21154c | 3995 | if ((err = mp_to_unsigned_bin(&tkb, kb[1])) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 3996 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 3997 | } |
wolfSSL | 0:d92f9d21154c | 3998 | else { |
wolfSSL | 0:d92f9d21154c | 3999 | x = 0; |
wolfSSL | 0:d92f9d21154c | 4000 | y = mp_unsigned_bin_size(&tkb) - 1; |
wolfSSL | 0:d92f9d21154c | 4001 | mp_clear(&tkb); |
wolfSSL | 0:d92f9d21154c | 4002 | while ((unsigned)x < y) { |
wolfSSL | 0:d92f9d21154c | 4003 | z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z; |
wolfSSL | 0:d92f9d21154c | 4004 | ++x; --y; |
wolfSSL | 0:d92f9d21154c | 4005 | } |
wolfSSL | 0:d92f9d21154c | 4006 | |
wolfSSL | 0:d92f9d21154c | 4007 | /* at this point we can start, yipee */ |
wolfSSL | 0:d92f9d21154c | 4008 | first = 1; |
wolfSSL | 0:d92f9d21154c | 4009 | for (x = lut_gap-1; x >= 0; x--) { |
wolfSSL | 0:d92f9d21154c | 4010 | /* extract FP_LUT bits from kb spread out by lut_gap bits and |
wolfSSL | 0:d92f9d21154c | 4011 | offset by x bits from the start */ |
wolfSSL | 0:d92f9d21154c | 4012 | bitpos = x; |
wolfSSL | 0:d92f9d21154c | 4013 | for (y = zA = zB = 0; y < FP_LUT; y++) { |
wolfSSL | 0:d92f9d21154c | 4014 | zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y; |
wolfSSL | 0:d92f9d21154c | 4015 | zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y; |
wolfSSL | 0:d92f9d21154c | 4016 | bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid |
wolfSSL | 0:d92f9d21154c | 4017 | the mult in each loop */ |
wolfSSL | 0:d92f9d21154c | 4018 | } |
wolfSSL | 0:d92f9d21154c | 4019 | |
wolfSSL | 0:d92f9d21154c | 4020 | /* double if not first */ |
wolfSSL | 0:d92f9d21154c | 4021 | if (!first) { |
wolfSSL | 0:d92f9d21154c | 4022 | if ((err = ecc_projective_dbl_point(R, R, modulus, |
wolfSSL | 0:d92f9d21154c | 4023 | mp)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4024 | break; |
wolfSSL | 0:d92f9d21154c | 4025 | } |
wolfSSL | 0:d92f9d21154c | 4026 | } |
wolfSSL | 0:d92f9d21154c | 4027 | |
wolfSSL | 0:d92f9d21154c | 4028 | /* add if not first, otherwise copy */ |
wolfSSL | 0:d92f9d21154c | 4029 | if (!first) { |
wolfSSL | 0:d92f9d21154c | 4030 | if (zA) { |
wolfSSL | 0:d92f9d21154c | 4031 | if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA], |
wolfSSL | 0:d92f9d21154c | 4032 | R, modulus, mp)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4033 | break; |
wolfSSL | 0:d92f9d21154c | 4034 | } |
wolfSSL | 0:d92f9d21154c | 4035 | } |
wolfSSL | 0:d92f9d21154c | 4036 | if (zB) { |
wolfSSL | 0:d92f9d21154c | 4037 | if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB], |
wolfSSL | 0:d92f9d21154c | 4038 | R, modulus, mp)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4039 | break; |
wolfSSL | 0:d92f9d21154c | 4040 | } |
wolfSSL | 0:d92f9d21154c | 4041 | } |
wolfSSL | 0:d92f9d21154c | 4042 | } else { |
wolfSSL | 0:d92f9d21154c | 4043 | if (zA) { |
wolfSSL | 0:d92f9d21154c | 4044 | if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 4045 | (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 4046 | (mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) { |
wolfSSL | 0:d92f9d21154c | 4047 | err = GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 4048 | break; |
wolfSSL | 0:d92f9d21154c | 4049 | } |
wolfSSL | 0:d92f9d21154c | 4050 | first = 0; |
wolfSSL | 0:d92f9d21154c | 4051 | } |
wolfSSL | 0:d92f9d21154c | 4052 | if (zB && first == 0) { |
wolfSSL | 0:d92f9d21154c | 4053 | if (zB) { |
wolfSSL | 0:d92f9d21154c | 4054 | if ((err = ecc_projective_add_point(R, |
wolfSSL | 0:d92f9d21154c | 4055 | fp_cache[idx2].LUT[zB], R, modulus, mp)) != MP_OKAY){ |
wolfSSL | 0:d92f9d21154c | 4056 | break; |
wolfSSL | 0:d92f9d21154c | 4057 | } |
wolfSSL | 0:d92f9d21154c | 4058 | } |
wolfSSL | 0:d92f9d21154c | 4059 | } else if (zB && first == 1) { |
wolfSSL | 0:d92f9d21154c | 4060 | if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 4061 | (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) || |
wolfSSL | 0:d92f9d21154c | 4062 | (mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) { |
wolfSSL | 0:d92f9d21154c | 4063 | err = GEN_MEM_ERR; |
wolfSSL | 0:d92f9d21154c | 4064 | break; |
wolfSSL | 0:d92f9d21154c | 4065 | } |
wolfSSL | 0:d92f9d21154c | 4066 | first = 0; |
wolfSSL | 0:d92f9d21154c | 4067 | } |
wolfSSL | 0:d92f9d21154c | 4068 | } |
wolfSSL | 0:d92f9d21154c | 4069 | } |
wolfSSL | 0:d92f9d21154c | 4070 | } |
wolfSSL | 0:d92f9d21154c | 4071 | |
wolfSSL | 0:d92f9d21154c | 4072 | ForceZero(kb[0], KB_SIZE); |
wolfSSL | 0:d92f9d21154c | 4073 | ForceZero(kb[1], KB_SIZE); |
wolfSSL | 0:d92f9d21154c | 4074 | |
wolfSSL | 0:d92f9d21154c | 4075 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 4076 | XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4077 | XFREE(kb[1], NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4078 | #endif |
wolfSSL | 0:d92f9d21154c | 4079 | |
wolfSSL | 0:d92f9d21154c | 4080 | #undef KB_SIZE |
wolfSSL | 0:d92f9d21154c | 4081 | |
wolfSSL | 0:d92f9d21154c | 4082 | return ecc_map(R, modulus, mp); |
wolfSSL | 0:d92f9d21154c | 4083 | } |
wolfSSL | 0:d92f9d21154c | 4084 | |
wolfSSL | 0:d92f9d21154c | 4085 | /** ECC Fixed Point mulmod global |
wolfSSL | 0:d92f9d21154c | 4086 | Computes kA*A + kB*B = C using Shamir's Trick |
wolfSSL | 0:d92f9d21154c | 4087 | A First point to multiply |
wolfSSL | 0:d92f9d21154c | 4088 | kA What to multiple A by |
wolfSSL | 0:d92f9d21154c | 4089 | B Second point to multiply |
wolfSSL | 0:d92f9d21154c | 4090 | kB What to multiple B by |
wolfSSL | 0:d92f9d21154c | 4091 | C [out] Destination point (can overlap with A or B) |
wolfSSL | 0:d92f9d21154c | 4092 | modulus Modulus for curve |
wolfSSL | 0:d92f9d21154c | 4093 | return MP_OKAY on success |
wolfSSL | 0:d92f9d21154c | 4094 | */ |
wolfSSL | 0:d92f9d21154c | 4095 | int ecc_mul2add(ecc_point* A, mp_int* kA, |
wolfSSL | 0:d92f9d21154c | 4096 | ecc_point* B, mp_int* kB, |
wolfSSL | 0:d92f9d21154c | 4097 | ecc_point* C, mp_int* modulus) |
wolfSSL | 0:d92f9d21154c | 4098 | { |
wolfSSL | 0:d92f9d21154c | 4099 | int idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0; |
wolfSSL | 0:d92f9d21154c | 4100 | mp_digit mp; |
wolfSSL | 0:d92f9d21154c | 4101 | mp_int mu; |
wolfSSL | 0:d92f9d21154c | 4102 | |
wolfSSL | 0:d92f9d21154c | 4103 | err = mp_init(&mu); |
wolfSSL | 0:d92f9d21154c | 4104 | if (err != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4105 | return err; |
wolfSSL | 0:d92f9d21154c | 4106 | |
wolfSSL | 0:d92f9d21154c | 4107 | #ifndef HAVE_THREAD_LS |
wolfSSL | 0:d92f9d21154c | 4108 | if (initMutex == 0) { |
wolfSSL | 0:d92f9d21154c | 4109 | InitMutex(&ecc_fp_lock); |
wolfSSL | 0:d92f9d21154c | 4110 | initMutex = 1; |
wolfSSL | 0:d92f9d21154c | 4111 | } |
wolfSSL | 0:d92f9d21154c | 4112 | if (LockMutex(&ecc_fp_lock) != 0) |
wolfSSL | 0:d92f9d21154c | 4113 | return BAD_MUTEX_E; |
wolfSSL | 0:d92f9d21154c | 4114 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 0:d92f9d21154c | 4115 | |
wolfSSL | 0:d92f9d21154c | 4116 | /* find point */ |
wolfSSL | 0:d92f9d21154c | 4117 | idx1 = find_base(A); |
wolfSSL | 0:d92f9d21154c | 4118 | |
wolfSSL | 0:d92f9d21154c | 4119 | /* no entry? */ |
wolfSSL | 0:d92f9d21154c | 4120 | if (idx1 == -1) { |
wolfSSL | 0:d92f9d21154c | 4121 | /* find hole and add it */ |
wolfSSL | 0:d92f9d21154c | 4122 | if ((idx1 = find_hole()) >= 0) { |
wolfSSL | 0:d92f9d21154c | 4123 | err = add_entry(idx1, A); |
wolfSSL | 0:d92f9d21154c | 4124 | } |
wolfSSL | 0:d92f9d21154c | 4125 | } |
wolfSSL | 0:d92f9d21154c | 4126 | if (err == MP_OKAY && idx1 != -1) { |
wolfSSL | 0:d92f9d21154c | 4127 | /* increment LRU */ |
wolfSSL | 0:d92f9d21154c | 4128 | ++(fp_cache[idx1].lru_count); |
wolfSSL | 0:d92f9d21154c | 4129 | } |
wolfSSL | 0:d92f9d21154c | 4130 | |
wolfSSL | 0:d92f9d21154c | 4131 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4132 | /* find point */ |
wolfSSL | 0:d92f9d21154c | 4133 | idx2 = find_base(B); |
wolfSSL | 0:d92f9d21154c | 4134 | |
wolfSSL | 0:d92f9d21154c | 4135 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4136 | /* no entry? */ |
wolfSSL | 0:d92f9d21154c | 4137 | if (idx2 == -1) { |
wolfSSL | 0:d92f9d21154c | 4138 | /* find hole and add it */ |
wolfSSL | 0:d92f9d21154c | 4139 | if ((idx2 = find_hole()) >= 0) |
wolfSSL | 0:d92f9d21154c | 4140 | err = add_entry(idx2, B); |
wolfSSL | 0:d92f9d21154c | 4141 | } |
wolfSSL | 0:d92f9d21154c | 4142 | } |
wolfSSL | 0:d92f9d21154c | 4143 | |
wolfSSL | 0:d92f9d21154c | 4144 | if (err == MP_OKAY && idx2 != -1) { |
wolfSSL | 0:d92f9d21154c | 4145 | /* increment LRU */ |
wolfSSL | 0:d92f9d21154c | 4146 | ++(fp_cache[idx2].lru_count); |
wolfSSL | 0:d92f9d21154c | 4147 | } |
wolfSSL | 0:d92f9d21154c | 4148 | |
wolfSSL | 0:d92f9d21154c | 4149 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4150 | /* if it's 2 build the LUT, if it's higher just use the LUT */ |
wolfSSL | 0:d92f9d21154c | 4151 | if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { |
wolfSSL | 0:d92f9d21154c | 4152 | /* compute mp */ |
wolfSSL | 0:d92f9d21154c | 4153 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 4154 | |
wolfSSL | 0:d92f9d21154c | 4155 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4156 | mpInit = 1; |
wolfSSL | 0:d92f9d21154c | 4157 | err = mp_montgomery_calc_normalization(&mu, modulus); |
wolfSSL | 0:d92f9d21154c | 4158 | } |
wolfSSL | 0:d92f9d21154c | 4159 | |
wolfSSL | 0:d92f9d21154c | 4160 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4161 | /* build the LUT */ |
wolfSSL | 0:d92f9d21154c | 4162 | err = build_lut(idx1, modulus, &mp, &mu); |
wolfSSL | 0:d92f9d21154c | 4163 | } |
wolfSSL | 0:d92f9d21154c | 4164 | } |
wolfSSL | 0:d92f9d21154c | 4165 | |
wolfSSL | 0:d92f9d21154c | 4166 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4167 | /* if it's 2 build the LUT, if it's higher just use the LUT */ |
wolfSSL | 0:d92f9d21154c | 4168 | if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { |
wolfSSL | 0:d92f9d21154c | 4169 | if (mpInit == 0) { |
wolfSSL | 0:d92f9d21154c | 4170 | /* compute mp */ |
wolfSSL | 0:d92f9d21154c | 4171 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 4172 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4173 | mpInit = 1; |
wolfSSL | 0:d92f9d21154c | 4174 | err = mp_montgomery_calc_normalization(&mu, modulus); |
wolfSSL | 0:d92f9d21154c | 4175 | } |
wolfSSL | 0:d92f9d21154c | 4176 | } |
wolfSSL | 0:d92f9d21154c | 4177 | |
wolfSSL | 0:d92f9d21154c | 4178 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4179 | /* build the LUT */ |
wolfSSL | 0:d92f9d21154c | 4180 | err = build_lut(idx2, modulus, &mp, &mu); |
wolfSSL | 0:d92f9d21154c | 4181 | } |
wolfSSL | 0:d92f9d21154c | 4182 | } |
wolfSSL | 0:d92f9d21154c | 4183 | |
wolfSSL | 0:d92f9d21154c | 4184 | |
wolfSSL | 0:d92f9d21154c | 4185 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4186 | if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && |
wolfSSL | 0:d92f9d21154c | 4187 | fp_cache[idx2].lru_count >= 2) { |
wolfSSL | 0:d92f9d21154c | 4188 | if (mpInit == 0) { |
wolfSSL | 0:d92f9d21154c | 4189 | /* compute mp */ |
wolfSSL | 0:d92f9d21154c | 4190 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 4191 | } |
wolfSSL | 0:d92f9d21154c | 4192 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4193 | err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 4194 | } else { |
wolfSSL | 0:d92f9d21154c | 4195 | err = normal_ecc_mul2add(A, kA, B, kB, C, modulus); |
wolfSSL | 0:d92f9d21154c | 4196 | } |
wolfSSL | 0:d92f9d21154c | 4197 | } |
wolfSSL | 0:d92f9d21154c | 4198 | |
wolfSSL | 0:d92f9d21154c | 4199 | #ifndef HAVE_THREAD_LS |
wolfSSL | 0:d92f9d21154c | 4200 | UnLockMutex(&ecc_fp_lock); |
wolfSSL | 0:d92f9d21154c | 4201 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 0:d92f9d21154c | 4202 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 4203 | |
wolfSSL | 0:d92f9d21154c | 4204 | return err; |
wolfSSL | 0:d92f9d21154c | 4205 | } |
wolfSSL | 0:d92f9d21154c | 4206 | #endif |
wolfSSL | 0:d92f9d21154c | 4207 | |
wolfSSL | 0:d92f9d21154c | 4208 | /** ECC Fixed Point mulmod global |
wolfSSL | 0:d92f9d21154c | 4209 | k The multiplicand |
wolfSSL | 0:d92f9d21154c | 4210 | G Base point to multiply |
wolfSSL | 0:d92f9d21154c | 4211 | R [out] Destination of product |
wolfSSL | 0:d92f9d21154c | 4212 | modulus The modulus for the curve |
wolfSSL | 0:d92f9d21154c | 4213 | map [boolean] If non-zero maps the point back to affine co-ordinates, |
wolfSSL | 0:d92f9d21154c | 4214 | otherwise it's left in jacobian-montgomery form |
wolfSSL | 0:d92f9d21154c | 4215 | return MP_OKAY if successful |
wolfSSL | 0:d92f9d21154c | 4216 | */ |
wolfSSL | 0:d92f9d21154c | 4217 | int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, |
wolfSSL | 0:d92f9d21154c | 4218 | int map) |
wolfSSL | 0:d92f9d21154c | 4219 | { |
wolfSSL | 0:d92f9d21154c | 4220 | int idx, err = MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 4221 | mp_digit mp; |
wolfSSL | 0:d92f9d21154c | 4222 | mp_int mu; |
wolfSSL | 0:d92f9d21154c | 4223 | int mpSetup = 0; |
wolfSSL | 0:d92f9d21154c | 4224 | |
wolfSSL | 0:d92f9d21154c | 4225 | if (mp_init(&mu) != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4226 | return MP_INIT_E; |
wolfSSL | 0:d92f9d21154c | 4227 | |
wolfSSL | 0:d92f9d21154c | 4228 | #ifndef HAVE_THREAD_LS |
wolfSSL | 0:d92f9d21154c | 4229 | if (initMutex == 0) { |
wolfSSL | 0:d92f9d21154c | 4230 | InitMutex(&ecc_fp_lock); |
wolfSSL | 0:d92f9d21154c | 4231 | initMutex = 1; |
wolfSSL | 0:d92f9d21154c | 4232 | } |
wolfSSL | 0:d92f9d21154c | 4233 | |
wolfSSL | 0:d92f9d21154c | 4234 | if (LockMutex(&ecc_fp_lock) != 0) |
wolfSSL | 0:d92f9d21154c | 4235 | return BAD_MUTEX_E; |
wolfSSL | 0:d92f9d21154c | 4236 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 0:d92f9d21154c | 4237 | |
wolfSSL | 0:d92f9d21154c | 4238 | /* find point */ |
wolfSSL | 0:d92f9d21154c | 4239 | idx = find_base(G); |
wolfSSL | 0:d92f9d21154c | 4240 | |
wolfSSL | 0:d92f9d21154c | 4241 | /* no entry? */ |
wolfSSL | 0:d92f9d21154c | 4242 | if (idx == -1) { |
wolfSSL | 0:d92f9d21154c | 4243 | /* find hole and add it */ |
wolfSSL | 0:d92f9d21154c | 4244 | idx = find_hole(); |
wolfSSL | 0:d92f9d21154c | 4245 | |
wolfSSL | 0:d92f9d21154c | 4246 | if (idx >= 0) |
wolfSSL | 0:d92f9d21154c | 4247 | err = add_entry(idx, G); |
wolfSSL | 0:d92f9d21154c | 4248 | } |
wolfSSL | 0:d92f9d21154c | 4249 | if (err == MP_OKAY && idx >= 0) { |
wolfSSL | 0:d92f9d21154c | 4250 | /* increment LRU */ |
wolfSSL | 0:d92f9d21154c | 4251 | ++(fp_cache[idx].lru_count); |
wolfSSL | 0:d92f9d21154c | 4252 | } |
wolfSSL | 0:d92f9d21154c | 4253 | |
wolfSSL | 0:d92f9d21154c | 4254 | |
wolfSSL | 0:d92f9d21154c | 4255 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4256 | /* if it's 2 build the LUT, if it's higher just use the LUT */ |
wolfSSL | 0:d92f9d21154c | 4257 | if (idx >= 0 && fp_cache[idx].lru_count == 2) { |
wolfSSL | 0:d92f9d21154c | 4258 | /* compute mp */ |
wolfSSL | 0:d92f9d21154c | 4259 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 4260 | |
wolfSSL | 0:d92f9d21154c | 4261 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4262 | /* compute mu */ |
wolfSSL | 0:d92f9d21154c | 4263 | mpSetup = 1; |
wolfSSL | 0:d92f9d21154c | 4264 | err = mp_montgomery_calc_normalization(&mu, modulus); |
wolfSSL | 0:d92f9d21154c | 4265 | } |
wolfSSL | 0:d92f9d21154c | 4266 | |
wolfSSL | 0:d92f9d21154c | 4267 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4268 | /* build the LUT */ |
wolfSSL | 0:d92f9d21154c | 4269 | err = build_lut(idx, modulus, &mp, &mu); |
wolfSSL | 0:d92f9d21154c | 4270 | } |
wolfSSL | 0:d92f9d21154c | 4271 | } |
wolfSSL | 0:d92f9d21154c | 4272 | |
wolfSSL | 0:d92f9d21154c | 4273 | if (err == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4274 | if (idx >= 0 && fp_cache[idx].lru_count >= 2) { |
wolfSSL | 0:d92f9d21154c | 4275 | if (mpSetup == 0) { |
wolfSSL | 0:d92f9d21154c | 4276 | /* compute mp */ |
wolfSSL | 0:d92f9d21154c | 4277 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 0:d92f9d21154c | 4278 | } |
wolfSSL | 0:d92f9d21154c | 4279 | if (err == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4280 | err = accel_fp_mul(idx, k, R, modulus, &mp, map); |
wolfSSL | 0:d92f9d21154c | 4281 | } else { |
wolfSSL | 0:d92f9d21154c | 4282 | err = normal_ecc_mulmod(k, G, R, modulus, map); |
wolfSSL | 0:d92f9d21154c | 4283 | } |
wolfSSL | 0:d92f9d21154c | 4284 | } |
wolfSSL | 0:d92f9d21154c | 4285 | |
wolfSSL | 0:d92f9d21154c | 4286 | #ifndef HAVE_THREAD_LS |
wolfSSL | 0:d92f9d21154c | 4287 | UnLockMutex(&ecc_fp_lock); |
wolfSSL | 0:d92f9d21154c | 4288 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 0:d92f9d21154c | 4289 | mp_clear(&mu); |
wolfSSL | 0:d92f9d21154c | 4290 | |
wolfSSL | 0:d92f9d21154c | 4291 | return err; |
wolfSSL | 0:d92f9d21154c | 4292 | } |
wolfSSL | 0:d92f9d21154c | 4293 | |
wolfSSL | 0:d92f9d21154c | 4294 | /* helper function for freeing the cache ... |
wolfSSL | 0:d92f9d21154c | 4295 | must be called with the cache mutex locked */ |
wolfSSL | 0:d92f9d21154c | 4296 | static void wc_ecc_fp_free_cache(void) |
wolfSSL | 0:d92f9d21154c | 4297 | { |
wolfSSL | 0:d92f9d21154c | 4298 | unsigned x, y; |
wolfSSL | 0:d92f9d21154c | 4299 | for (x = 0; x < FP_ENTRIES; x++) { |
wolfSSL | 0:d92f9d21154c | 4300 | if (fp_cache[x].g != NULL) { |
wolfSSL | 0:d92f9d21154c | 4301 | for (y = 0; y < (1U<<FP_LUT); y++) { |
wolfSSL | 0:d92f9d21154c | 4302 | ecc_del_point(fp_cache[x].LUT[y]); |
wolfSSL | 0:d92f9d21154c | 4303 | fp_cache[x].LUT[y] = NULL; |
wolfSSL | 0:d92f9d21154c | 4304 | } |
wolfSSL | 0:d92f9d21154c | 4305 | ecc_del_point(fp_cache[x].g); |
wolfSSL | 0:d92f9d21154c | 4306 | fp_cache[x].g = NULL; |
wolfSSL | 0:d92f9d21154c | 4307 | mp_clear(&fp_cache[x].mu); |
wolfSSL | 0:d92f9d21154c | 4308 | fp_cache[x].lru_count = 0; |
wolfSSL | 0:d92f9d21154c | 4309 | fp_cache[x].lock = 0; |
wolfSSL | 0:d92f9d21154c | 4310 | } |
wolfSSL | 0:d92f9d21154c | 4311 | } |
wolfSSL | 0:d92f9d21154c | 4312 | } |
wolfSSL | 0:d92f9d21154c | 4313 | |
wolfSSL | 0:d92f9d21154c | 4314 | /** Free the Fixed Point cache */ |
wolfSSL | 0:d92f9d21154c | 4315 | void wc_ecc_fp_free(void) |
wolfSSL | 0:d92f9d21154c | 4316 | { |
wolfSSL | 0:d92f9d21154c | 4317 | #ifndef HAVE_THREAD_LS |
wolfSSL | 0:d92f9d21154c | 4318 | if (initMutex == 0) { |
wolfSSL | 0:d92f9d21154c | 4319 | InitMutex(&ecc_fp_lock); |
wolfSSL | 0:d92f9d21154c | 4320 | initMutex = 1; |
wolfSSL | 0:d92f9d21154c | 4321 | } |
wolfSSL | 0:d92f9d21154c | 4322 | |
wolfSSL | 0:d92f9d21154c | 4323 | if (LockMutex(&ecc_fp_lock) == 0) { |
wolfSSL | 0:d92f9d21154c | 4324 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 0:d92f9d21154c | 4325 | |
wolfSSL | 0:d92f9d21154c | 4326 | wc_ecc_fp_free_cache(); |
wolfSSL | 0:d92f9d21154c | 4327 | |
wolfSSL | 0:d92f9d21154c | 4328 | #ifndef HAVE_THREAD_LS |
wolfSSL | 0:d92f9d21154c | 4329 | UnLockMutex(&ecc_fp_lock); |
wolfSSL | 0:d92f9d21154c | 4330 | FreeMutex(&ecc_fp_lock); |
wolfSSL | 0:d92f9d21154c | 4331 | initMutex = 0; |
wolfSSL | 0:d92f9d21154c | 4332 | } |
wolfSSL | 0:d92f9d21154c | 4333 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 0:d92f9d21154c | 4334 | } |
wolfSSL | 0:d92f9d21154c | 4335 | |
wolfSSL | 0:d92f9d21154c | 4336 | |
wolfSSL | 0:d92f9d21154c | 4337 | #endif /* FP_ECC */ |
wolfSSL | 0:d92f9d21154c | 4338 | |
wolfSSL | 0:d92f9d21154c | 4339 | #ifdef HAVE_ECC_ENCRYPT |
wolfSSL | 0:d92f9d21154c | 4340 | |
wolfSSL | 0:d92f9d21154c | 4341 | |
wolfSSL | 0:d92f9d21154c | 4342 | enum ecCliState { |
wolfSSL | 0:d92f9d21154c | 4343 | ecCLI_INIT = 1, |
wolfSSL | 0:d92f9d21154c | 4344 | ecCLI_SALT_GET = 2, |
wolfSSL | 0:d92f9d21154c | 4345 | ecCLI_SALT_SET = 3, |
wolfSSL | 0:d92f9d21154c | 4346 | ecCLI_SENT_REQ = 4, |
wolfSSL | 0:d92f9d21154c | 4347 | ecCLI_RECV_RESP = 5, |
wolfSSL | 0:d92f9d21154c | 4348 | ecCLI_BAD_STATE = 99 |
wolfSSL | 0:d92f9d21154c | 4349 | }; |
wolfSSL | 0:d92f9d21154c | 4350 | |
wolfSSL | 0:d92f9d21154c | 4351 | enum ecSrvState { |
wolfSSL | 0:d92f9d21154c | 4352 | ecSRV_INIT = 1, |
wolfSSL | 0:d92f9d21154c | 4353 | ecSRV_SALT_GET = 2, |
wolfSSL | 0:d92f9d21154c | 4354 | ecSRV_SALT_SET = 3, |
wolfSSL | 0:d92f9d21154c | 4355 | ecSRV_RECV_REQ = 4, |
wolfSSL | 0:d92f9d21154c | 4356 | ecSRV_SENT_RESP = 5, |
wolfSSL | 0:d92f9d21154c | 4357 | ecSRV_BAD_STATE = 99 |
wolfSSL | 0:d92f9d21154c | 4358 | }; |
wolfSSL | 0:d92f9d21154c | 4359 | |
wolfSSL | 0:d92f9d21154c | 4360 | |
wolfSSL | 0:d92f9d21154c | 4361 | struct ecEncCtx { |
wolfSSL | 0:d92f9d21154c | 4362 | const byte* kdfSalt; /* optional salt for kdf */ |
wolfSSL | 0:d92f9d21154c | 4363 | const byte* kdfInfo; /* optional info for kdf */ |
wolfSSL | 0:d92f9d21154c | 4364 | const byte* macSalt; /* optional salt for mac */ |
wolfSSL | 0:d92f9d21154c | 4365 | word32 kdfSaltSz; /* size of kdfSalt */ |
wolfSSL | 0:d92f9d21154c | 4366 | word32 kdfInfoSz; /* size of kdfInfo */ |
wolfSSL | 0:d92f9d21154c | 4367 | word32 macSaltSz; /* size of macSalt */ |
wolfSSL | 0:d92f9d21154c | 4368 | byte clientSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ |
wolfSSL | 0:d92f9d21154c | 4369 | byte serverSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ |
wolfSSL | 0:d92f9d21154c | 4370 | byte encAlgo; /* which encryption type */ |
wolfSSL | 0:d92f9d21154c | 4371 | byte kdfAlgo; /* which key derivation function type */ |
wolfSSL | 0:d92f9d21154c | 4372 | byte macAlgo; /* which mac function type */ |
wolfSSL | 0:d92f9d21154c | 4373 | byte protocol; /* are we REQ_RESP client or server ? */ |
wolfSSL | 0:d92f9d21154c | 4374 | byte cliSt; /* protocol state, for sanity checks */ |
wolfSSL | 0:d92f9d21154c | 4375 | byte srvSt; /* protocol state, for sanity checks */ |
wolfSSL | 0:d92f9d21154c | 4376 | }; |
wolfSSL | 0:d92f9d21154c | 4377 | |
wolfSSL | 0:d92f9d21154c | 4378 | |
wolfSSL | 0:d92f9d21154c | 4379 | const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx) |
wolfSSL | 0:d92f9d21154c | 4380 | { |
wolfSSL | 0:d92f9d21154c | 4381 | if (ctx == NULL || ctx->protocol == 0) |
wolfSSL | 0:d92f9d21154c | 4382 | return NULL; |
wolfSSL | 0:d92f9d21154c | 4383 | |
wolfSSL | 0:d92f9d21154c | 4384 | if (ctx->protocol == REQ_RESP_CLIENT) { |
wolfSSL | 0:d92f9d21154c | 4385 | if (ctx->cliSt == ecCLI_INIT) { |
wolfSSL | 0:d92f9d21154c | 4386 | ctx->cliSt = ecCLI_SALT_GET; |
wolfSSL | 0:d92f9d21154c | 4387 | return ctx->clientSalt; |
wolfSSL | 0:d92f9d21154c | 4388 | } |
wolfSSL | 0:d92f9d21154c | 4389 | else { |
wolfSSL | 0:d92f9d21154c | 4390 | ctx->cliSt = ecCLI_BAD_STATE; |
wolfSSL | 0:d92f9d21154c | 4391 | return NULL; |
wolfSSL | 0:d92f9d21154c | 4392 | } |
wolfSSL | 0:d92f9d21154c | 4393 | } |
wolfSSL | 0:d92f9d21154c | 4394 | else if (ctx->protocol == REQ_RESP_SERVER) { |
wolfSSL | 0:d92f9d21154c | 4395 | if (ctx->srvSt == ecSRV_INIT) { |
wolfSSL | 0:d92f9d21154c | 4396 | ctx->srvSt = ecSRV_SALT_GET; |
wolfSSL | 0:d92f9d21154c | 4397 | return ctx->serverSalt; |
wolfSSL | 0:d92f9d21154c | 4398 | } |
wolfSSL | 0:d92f9d21154c | 4399 | else { |
wolfSSL | 0:d92f9d21154c | 4400 | ctx->srvSt = ecSRV_BAD_STATE; |
wolfSSL | 0:d92f9d21154c | 4401 | return NULL; |
wolfSSL | 0:d92f9d21154c | 4402 | } |
wolfSSL | 0:d92f9d21154c | 4403 | } |
wolfSSL | 0:d92f9d21154c | 4404 | |
wolfSSL | 0:d92f9d21154c | 4405 | return NULL; |
wolfSSL | 0:d92f9d21154c | 4406 | } |
wolfSSL | 0:d92f9d21154c | 4407 | |
wolfSSL | 0:d92f9d21154c | 4408 | |
wolfSSL | 0:d92f9d21154c | 4409 | /* optional set info, can be called before or after set_peer_salt */ |
wolfSSL | 0:d92f9d21154c | 4410 | int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz) |
wolfSSL | 0:d92f9d21154c | 4411 | { |
wolfSSL | 0:d92f9d21154c | 4412 | if (ctx == NULL || info == 0 || sz < 0) |
wolfSSL | 0:d92f9d21154c | 4413 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4414 | |
wolfSSL | 0:d92f9d21154c | 4415 | ctx->kdfInfo = info; |
wolfSSL | 0:d92f9d21154c | 4416 | ctx->kdfInfoSz = sz; |
wolfSSL | 0:d92f9d21154c | 4417 | |
wolfSSL | 0:d92f9d21154c | 4418 | return 0; |
wolfSSL | 0:d92f9d21154c | 4419 | } |
wolfSSL | 0:d92f9d21154c | 4420 | |
wolfSSL | 0:d92f9d21154c | 4421 | |
wolfSSL | 0:d92f9d21154c | 4422 | static const char* exchange_info = "Secure Message Exchange"; |
wolfSSL | 0:d92f9d21154c | 4423 | |
wolfSSL | 0:d92f9d21154c | 4424 | int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) |
wolfSSL | 0:d92f9d21154c | 4425 | { |
wolfSSL | 0:d92f9d21154c | 4426 | byte tmp[EXCHANGE_SALT_SZ/2]; |
wolfSSL | 0:d92f9d21154c | 4427 | int halfSz = EXCHANGE_SALT_SZ/2; |
wolfSSL | 0:d92f9d21154c | 4428 | |
wolfSSL | 0:d92f9d21154c | 4429 | if (ctx == NULL || ctx->protocol == 0 || salt == NULL) |
wolfSSL | 0:d92f9d21154c | 4430 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4431 | |
wolfSSL | 0:d92f9d21154c | 4432 | if (ctx->protocol == REQ_RESP_CLIENT) { |
wolfSSL | 0:d92f9d21154c | 4433 | XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ); |
wolfSSL | 0:d92f9d21154c | 4434 | if (ctx->cliSt == ecCLI_SALT_GET) |
wolfSSL | 0:d92f9d21154c | 4435 | ctx->cliSt = ecCLI_SALT_SET; |
wolfSSL | 0:d92f9d21154c | 4436 | else { |
wolfSSL | 0:d92f9d21154c | 4437 | ctx->cliSt = ecCLI_BAD_STATE; |
wolfSSL | 0:d92f9d21154c | 4438 | return BAD_ENC_STATE_E; |
wolfSSL | 0:d92f9d21154c | 4439 | } |
wolfSSL | 0:d92f9d21154c | 4440 | } |
wolfSSL | 0:d92f9d21154c | 4441 | else { |
wolfSSL | 0:d92f9d21154c | 4442 | XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ); |
wolfSSL | 0:d92f9d21154c | 4443 | if (ctx->srvSt == ecSRV_SALT_GET) |
wolfSSL | 0:d92f9d21154c | 4444 | ctx->srvSt = ecSRV_SALT_SET; |
wolfSSL | 0:d92f9d21154c | 4445 | else { |
wolfSSL | 0:d92f9d21154c | 4446 | ctx->srvSt = ecSRV_BAD_STATE; |
wolfSSL | 0:d92f9d21154c | 4447 | return BAD_ENC_STATE_E; |
wolfSSL | 0:d92f9d21154c | 4448 | } |
wolfSSL | 0:d92f9d21154c | 4449 | } |
wolfSSL | 0:d92f9d21154c | 4450 | |
wolfSSL | 0:d92f9d21154c | 4451 | /* mix half and half */ |
wolfSSL | 0:d92f9d21154c | 4452 | /* tmp stores 2nd half of client before overwrite */ |
wolfSSL | 0:d92f9d21154c | 4453 | XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz); |
wolfSSL | 0:d92f9d21154c | 4454 | XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz); |
wolfSSL | 0:d92f9d21154c | 4455 | XMEMCPY(ctx->serverSalt, tmp, halfSz); |
wolfSSL | 0:d92f9d21154c | 4456 | |
wolfSSL | 0:d92f9d21154c | 4457 | ctx->kdfSalt = ctx->clientSalt; |
wolfSSL | 0:d92f9d21154c | 4458 | ctx->kdfSaltSz = EXCHANGE_SALT_SZ; |
wolfSSL | 0:d92f9d21154c | 4459 | |
wolfSSL | 0:d92f9d21154c | 4460 | ctx->macSalt = ctx->serverSalt; |
wolfSSL | 0:d92f9d21154c | 4461 | ctx->macSaltSz = EXCHANGE_SALT_SZ; |
wolfSSL | 0:d92f9d21154c | 4462 | |
wolfSSL | 0:d92f9d21154c | 4463 | if (ctx->kdfInfo == NULL) { |
wolfSSL | 0:d92f9d21154c | 4464 | /* default info */ |
wolfSSL | 0:d92f9d21154c | 4465 | ctx->kdfInfo = (const byte*)exchange_info; |
wolfSSL | 0:d92f9d21154c | 4466 | ctx->kdfInfoSz = EXCHANGE_INFO_SZ; |
wolfSSL | 0:d92f9d21154c | 4467 | } |
wolfSSL | 0:d92f9d21154c | 4468 | |
wolfSSL | 0:d92f9d21154c | 4469 | return 0; |
wolfSSL | 0:d92f9d21154c | 4470 | } |
wolfSSL | 0:d92f9d21154c | 4471 | |
wolfSSL | 0:d92f9d21154c | 4472 | |
wolfSSL | 0:d92f9d21154c | 4473 | static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, RNG* rng) |
wolfSSL | 0:d92f9d21154c | 4474 | { |
wolfSSL | 0:d92f9d21154c | 4475 | byte* saltBuffer = NULL; |
wolfSSL | 0:d92f9d21154c | 4476 | |
wolfSSL | 0:d92f9d21154c | 4477 | if (ctx == NULL || rng == NULL || flags == 0) |
wolfSSL | 0:d92f9d21154c | 4478 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4479 | |
wolfSSL | 0:d92f9d21154c | 4480 | saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt; |
wolfSSL | 0:d92f9d21154c | 4481 | |
wolfSSL | 0:d92f9d21154c | 4482 | return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ); |
wolfSSL | 0:d92f9d21154c | 4483 | } |
wolfSSL | 0:d92f9d21154c | 4484 | |
wolfSSL | 0:d92f9d21154c | 4485 | |
wolfSSL | 0:d92f9d21154c | 4486 | static void ecc_ctx_init(ecEncCtx* ctx, int flags) |
wolfSSL | 0:d92f9d21154c | 4487 | { |
wolfSSL | 0:d92f9d21154c | 4488 | if (ctx) { |
wolfSSL | 0:d92f9d21154c | 4489 | XMEMSET(ctx, 0, sizeof(ecEncCtx)); |
wolfSSL | 0:d92f9d21154c | 4490 | |
wolfSSL | 0:d92f9d21154c | 4491 | ctx->encAlgo = ecAES_128_CBC; |
wolfSSL | 0:d92f9d21154c | 4492 | ctx->kdfAlgo = ecHKDF_SHA256; |
wolfSSL | 0:d92f9d21154c | 4493 | ctx->macAlgo = ecHMAC_SHA256; |
wolfSSL | 0:d92f9d21154c | 4494 | ctx->protocol = (byte)flags; |
wolfSSL | 0:d92f9d21154c | 4495 | |
wolfSSL | 0:d92f9d21154c | 4496 | if (flags == REQ_RESP_CLIENT) |
wolfSSL | 0:d92f9d21154c | 4497 | ctx->cliSt = ecCLI_INIT; |
wolfSSL | 0:d92f9d21154c | 4498 | if (flags == REQ_RESP_SERVER) |
wolfSSL | 0:d92f9d21154c | 4499 | ctx->srvSt = ecSRV_INIT; |
wolfSSL | 0:d92f9d21154c | 4500 | } |
wolfSSL | 0:d92f9d21154c | 4501 | } |
wolfSSL | 0:d92f9d21154c | 4502 | |
wolfSSL | 0:d92f9d21154c | 4503 | |
wolfSSL | 0:d92f9d21154c | 4504 | /* allow ecc context reset so user doesn't have to init/free for resue */ |
wolfSSL | 0:d92f9d21154c | 4505 | int wc_ecc_ctx_reset(ecEncCtx* ctx, RNG* rng) |
wolfSSL | 0:d92f9d21154c | 4506 | { |
wolfSSL | 0:d92f9d21154c | 4507 | if (ctx == NULL || rng == NULL) |
wolfSSL | 0:d92f9d21154c | 4508 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4509 | |
wolfSSL | 0:d92f9d21154c | 4510 | ecc_ctx_init(ctx, ctx->protocol); |
wolfSSL | 0:d92f9d21154c | 4511 | return ecc_ctx_set_salt(ctx, ctx->protocol, rng); |
wolfSSL | 0:d92f9d21154c | 4512 | } |
wolfSSL | 0:d92f9d21154c | 4513 | |
wolfSSL | 0:d92f9d21154c | 4514 | |
wolfSSL | 0:d92f9d21154c | 4515 | /* alloc/init and set defaults, return new Context */ |
wolfSSL | 0:d92f9d21154c | 4516 | ecEncCtx* wc_ecc_ctx_new(int flags, RNG* rng) |
wolfSSL | 0:d92f9d21154c | 4517 | { |
wolfSSL | 0:d92f9d21154c | 4518 | int ret = 0; |
wolfSSL | 0:d92f9d21154c | 4519 | ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), 0, DYNAMIC_TYPE_ECC); |
wolfSSL | 0:d92f9d21154c | 4520 | |
wolfSSL | 0:d92f9d21154c | 4521 | if (ctx) |
wolfSSL | 0:d92f9d21154c | 4522 | ctx->protocol = (byte)flags; |
wolfSSL | 0:d92f9d21154c | 4523 | |
wolfSSL | 0:d92f9d21154c | 4524 | ret = wc_ecc_ctx_reset(ctx, rng); |
wolfSSL | 0:d92f9d21154c | 4525 | if (ret != 0) { |
wolfSSL | 0:d92f9d21154c | 4526 | wc_ecc_ctx_free(ctx); |
wolfSSL | 0:d92f9d21154c | 4527 | ctx = NULL; |
wolfSSL | 0:d92f9d21154c | 4528 | } |
wolfSSL | 0:d92f9d21154c | 4529 | |
wolfSSL | 0:d92f9d21154c | 4530 | return ctx; |
wolfSSL | 0:d92f9d21154c | 4531 | } |
wolfSSL | 0:d92f9d21154c | 4532 | |
wolfSSL | 0:d92f9d21154c | 4533 | |
wolfSSL | 0:d92f9d21154c | 4534 | /* free any resources, clear any keys */ |
wolfSSL | 0:d92f9d21154c | 4535 | void wc_ecc_ctx_free(ecEncCtx* ctx) |
wolfSSL | 0:d92f9d21154c | 4536 | { |
wolfSSL | 0:d92f9d21154c | 4537 | if (ctx) { |
wolfSSL | 0:d92f9d21154c | 4538 | ForceZero(ctx, sizeof(ecEncCtx)); |
wolfSSL | 0:d92f9d21154c | 4539 | XFREE(ctx, 0, DYNAMIC_TYPE_ECC); |
wolfSSL | 0:d92f9d21154c | 4540 | } |
wolfSSL | 0:d92f9d21154c | 4541 | } |
wolfSSL | 0:d92f9d21154c | 4542 | |
wolfSSL | 0:d92f9d21154c | 4543 | |
wolfSSL | 0:d92f9d21154c | 4544 | static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz, |
wolfSSL | 0:d92f9d21154c | 4545 | int* keysLen, word32* digestSz, word32* blockSz) |
wolfSSL | 0:d92f9d21154c | 4546 | { |
wolfSSL | 0:d92f9d21154c | 4547 | if (ctx) { |
wolfSSL | 0:d92f9d21154c | 4548 | switch (ctx->encAlgo) { |
wolfSSL | 0:d92f9d21154c | 4549 | case ecAES_128_CBC: |
wolfSSL | 0:d92f9d21154c | 4550 | *encKeySz = KEY_SIZE_128; |
wolfSSL | 0:d92f9d21154c | 4551 | *ivSz = IV_SIZE_64; |
wolfSSL | 0:d92f9d21154c | 4552 | *blockSz = AES_BLOCK_SIZE; |
wolfSSL | 0:d92f9d21154c | 4553 | break; |
wolfSSL | 0:d92f9d21154c | 4554 | default: |
wolfSSL | 0:d92f9d21154c | 4555 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4556 | } |
wolfSSL | 0:d92f9d21154c | 4557 | |
wolfSSL | 0:d92f9d21154c | 4558 | switch (ctx->macAlgo) { |
wolfSSL | 0:d92f9d21154c | 4559 | case ecHMAC_SHA256: |
wolfSSL | 0:d92f9d21154c | 4560 | *digestSz = SHA256_DIGEST_SIZE; |
wolfSSL | 0:d92f9d21154c | 4561 | break; |
wolfSSL | 0:d92f9d21154c | 4562 | default: |
wolfSSL | 0:d92f9d21154c | 4563 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4564 | } |
wolfSSL | 0:d92f9d21154c | 4565 | } else |
wolfSSL | 0:d92f9d21154c | 4566 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4567 | |
wolfSSL | 0:d92f9d21154c | 4568 | *keysLen = *encKeySz + *ivSz + *digestSz; |
wolfSSL | 0:d92f9d21154c | 4569 | |
wolfSSL | 0:d92f9d21154c | 4570 | return 0; |
wolfSSL | 0:d92f9d21154c | 4571 | } |
wolfSSL | 0:d92f9d21154c | 4572 | |
wolfSSL | 0:d92f9d21154c | 4573 | |
wolfSSL | 0:d92f9d21154c | 4574 | /* ecc encrypt with shared secret run through kdf |
wolfSSL | 0:d92f9d21154c | 4575 | ctx holds non default algos and inputs |
wolfSSL | 0:d92f9d21154c | 4576 | msgSz should be the right size for encAlgo, i.e., already padded |
wolfSSL | 0:d92f9d21154c | 4577 | return 0 on success */ |
wolfSSL | 0:d92f9d21154c | 4578 | int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, |
wolfSSL | 0:d92f9d21154c | 4579 | word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) |
wolfSSL | 0:d92f9d21154c | 4580 | { |
wolfSSL | 0:d92f9d21154c | 4581 | int ret; |
wolfSSL | 0:d92f9d21154c | 4582 | word32 blockSz; |
wolfSSL | 0:d92f9d21154c | 4583 | word32 digestSz; |
wolfSSL | 0:d92f9d21154c | 4584 | ecEncCtx localCtx; |
wolfSSL | 0:d92f9d21154c | 4585 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 4586 | byte* sharedSecret; |
wolfSSL | 0:d92f9d21154c | 4587 | byte* keys; |
wolfSSL | 0:d92f9d21154c | 4588 | #else |
wolfSSL | 0:d92f9d21154c | 4589 | byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ |
wolfSSL | 0:d92f9d21154c | 4590 | byte keys[ECC_BUFSIZE]; /* max size */ |
wolfSSL | 0:d92f9d21154c | 4591 | #endif |
wolfSSL | 0:d92f9d21154c | 4592 | word32 sharedSz = ECC_MAXSIZE; |
wolfSSL | 0:d92f9d21154c | 4593 | int keysLen; |
wolfSSL | 0:d92f9d21154c | 4594 | int encKeySz; |
wolfSSL | 0:d92f9d21154c | 4595 | int ivSz; |
wolfSSL | 0:d92f9d21154c | 4596 | int offset = 0; /* keys offset if doing msg exchange */ |
wolfSSL | 0:d92f9d21154c | 4597 | byte* encKey; |
wolfSSL | 0:d92f9d21154c | 4598 | byte* encIv; |
wolfSSL | 0:d92f9d21154c | 4599 | byte* macKey; |
wolfSSL | 0:d92f9d21154c | 4600 | |
wolfSSL | 0:d92f9d21154c | 4601 | if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || |
wolfSSL | 0:d92f9d21154c | 4602 | outSz == NULL) |
wolfSSL | 0:d92f9d21154c | 4603 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4604 | |
wolfSSL | 0:d92f9d21154c | 4605 | if (ctx == NULL) { /* use defaults */ |
wolfSSL | 0:d92f9d21154c | 4606 | ecc_ctx_init(&localCtx, 0); |
wolfSSL | 0:d92f9d21154c | 4607 | ctx = &localCtx; |
wolfSSL | 0:d92f9d21154c | 4608 | } |
wolfSSL | 0:d92f9d21154c | 4609 | |
wolfSSL | 0:d92f9d21154c | 4610 | ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, |
wolfSSL | 0:d92f9d21154c | 4611 | &blockSz); |
wolfSSL | 0:d92f9d21154c | 4612 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4613 | return ret; |
wolfSSL | 0:d92f9d21154c | 4614 | |
wolfSSL | 0:d92f9d21154c | 4615 | if (ctx->protocol == REQ_RESP_SERVER) { |
wolfSSL | 0:d92f9d21154c | 4616 | offset = keysLen; |
wolfSSL | 0:d92f9d21154c | 4617 | keysLen *= 2; |
wolfSSL | 0:d92f9d21154c | 4618 | |
wolfSSL | 0:d92f9d21154c | 4619 | if (ctx->srvSt != ecSRV_RECV_REQ) |
wolfSSL | 0:d92f9d21154c | 4620 | return BAD_ENC_STATE_E; |
wolfSSL | 0:d92f9d21154c | 4621 | |
wolfSSL | 0:d92f9d21154c | 4622 | ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ |
wolfSSL | 0:d92f9d21154c | 4623 | } |
wolfSSL | 0:d92f9d21154c | 4624 | else if (ctx->protocol == REQ_RESP_CLIENT) { |
wolfSSL | 0:d92f9d21154c | 4625 | if (ctx->cliSt != ecCLI_SALT_SET) |
wolfSSL | 0:d92f9d21154c | 4626 | return BAD_ENC_STATE_E; |
wolfSSL | 0:d92f9d21154c | 4627 | |
wolfSSL | 0:d92f9d21154c | 4628 | ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */ |
wolfSSL | 0:d92f9d21154c | 4629 | } |
wolfSSL | 0:d92f9d21154c | 4630 | |
wolfSSL | 0:d92f9d21154c | 4631 | if (keysLen > ECC_BUFSIZE) /* keys size */ |
wolfSSL | 0:d92f9d21154c | 4632 | return BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 4633 | |
wolfSSL | 0:d92f9d21154c | 4634 | if ( (msgSz%blockSz) != 0) |
wolfSSL | 0:d92f9d21154c | 4635 | return BAD_PADDING_E; |
wolfSSL | 0:d92f9d21154c | 4636 | |
wolfSSL | 0:d92f9d21154c | 4637 | if (*outSz < (msgSz + digestSz)) |
wolfSSL | 0:d92f9d21154c | 4638 | return BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 4639 | |
wolfSSL | 0:d92f9d21154c | 4640 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 4641 | sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4642 | if (sharedSecret == NULL) |
wolfSSL | 0:d92f9d21154c | 4643 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 4644 | |
wolfSSL | 0:d92f9d21154c | 4645 | keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4646 | if (keys == NULL) { |
wolfSSL | 0:d92f9d21154c | 4647 | XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4648 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 4649 | } |
wolfSSL | 0:d92f9d21154c | 4650 | #endif |
wolfSSL | 0:d92f9d21154c | 4651 | |
wolfSSL | 0:d92f9d21154c | 4652 | ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); |
wolfSSL | 0:d92f9d21154c | 4653 | |
wolfSSL | 0:d92f9d21154c | 4654 | if (ret == 0) { |
wolfSSL | 0:d92f9d21154c | 4655 | switch (ctx->kdfAlgo) { |
wolfSSL | 0:d92f9d21154c | 4656 | case ecHKDF_SHA256 : |
wolfSSL | 0:d92f9d21154c | 4657 | ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt, |
wolfSSL | 0:d92f9d21154c | 4658 | ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, |
wolfSSL | 0:d92f9d21154c | 4659 | keys, keysLen); |
wolfSSL | 0:d92f9d21154c | 4660 | break; |
wolfSSL | 0:d92f9d21154c | 4661 | |
wolfSSL | 0:d92f9d21154c | 4662 | default: |
wolfSSL | 0:d92f9d21154c | 4663 | ret = BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4664 | break; |
wolfSSL | 0:d92f9d21154c | 4665 | } |
wolfSSL | 0:d92f9d21154c | 4666 | } |
wolfSSL | 0:d92f9d21154c | 4667 | |
wolfSSL | 0:d92f9d21154c | 4668 | if (ret == 0) { |
wolfSSL | 0:d92f9d21154c | 4669 | encKey = keys + offset; |
wolfSSL | 0:d92f9d21154c | 4670 | encIv = encKey + encKeySz; |
wolfSSL | 0:d92f9d21154c | 4671 | macKey = encKey + encKeySz + ivSz; |
wolfSSL | 0:d92f9d21154c | 4672 | |
wolfSSL | 0:d92f9d21154c | 4673 | switch (ctx->encAlgo) { |
wolfSSL | 0:d92f9d21154c | 4674 | case ecAES_128_CBC: |
wolfSSL | 0:d92f9d21154c | 4675 | { |
wolfSSL | 0:d92f9d21154c | 4676 | Aes aes; |
wolfSSL | 0:d92f9d21154c | 4677 | ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, |
wolfSSL | 0:d92f9d21154c | 4678 | AES_ENCRYPTION); |
wolfSSL | 0:d92f9d21154c | 4679 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4680 | break; |
wolfSSL | 0:d92f9d21154c | 4681 | ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz); |
wolfSSL | 0:d92f9d21154c | 4682 | } |
wolfSSL | 0:d92f9d21154c | 4683 | break; |
wolfSSL | 0:d92f9d21154c | 4684 | |
wolfSSL | 0:d92f9d21154c | 4685 | default: |
wolfSSL | 0:d92f9d21154c | 4686 | ret = BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4687 | break; |
wolfSSL | 0:d92f9d21154c | 4688 | } |
wolfSSL | 0:d92f9d21154c | 4689 | } |
wolfSSL | 0:d92f9d21154c | 4690 | |
wolfSSL | 0:d92f9d21154c | 4691 | if (ret == 0) { |
wolfSSL | 0:d92f9d21154c | 4692 | switch (ctx->macAlgo) { |
wolfSSL | 0:d92f9d21154c | 4693 | case ecHMAC_SHA256: |
wolfSSL | 0:d92f9d21154c | 4694 | { |
wolfSSL | 0:d92f9d21154c | 4695 | Hmac hmac; |
wolfSSL | 0:d92f9d21154c | 4696 | ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); |
wolfSSL | 0:d92f9d21154c | 4697 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4698 | break; |
wolfSSL | 0:d92f9d21154c | 4699 | ret = wc_HmacUpdate(&hmac, out, msgSz); |
wolfSSL | 0:d92f9d21154c | 4700 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4701 | break; |
wolfSSL | 0:d92f9d21154c | 4702 | ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); |
wolfSSL | 0:d92f9d21154c | 4703 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4704 | break; |
wolfSSL | 0:d92f9d21154c | 4705 | ret = wc_HmacFinal(&hmac, out+msgSz); |
wolfSSL | 0:d92f9d21154c | 4706 | } |
wolfSSL | 0:d92f9d21154c | 4707 | break; |
wolfSSL | 0:d92f9d21154c | 4708 | |
wolfSSL | 0:d92f9d21154c | 4709 | default: |
wolfSSL | 0:d92f9d21154c | 4710 | ret = BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4711 | break; |
wolfSSL | 0:d92f9d21154c | 4712 | } |
wolfSSL | 0:d92f9d21154c | 4713 | } |
wolfSSL | 0:d92f9d21154c | 4714 | |
wolfSSL | 0:d92f9d21154c | 4715 | if (ret == 0) |
wolfSSL | 0:d92f9d21154c | 4716 | *outSz = msgSz + digestSz; |
wolfSSL | 0:d92f9d21154c | 4717 | |
wolfSSL | 0:d92f9d21154c | 4718 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 4719 | XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4720 | XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4721 | #endif |
wolfSSL | 0:d92f9d21154c | 4722 | |
wolfSSL | 0:d92f9d21154c | 4723 | return ret; |
wolfSSL | 0:d92f9d21154c | 4724 | } |
wolfSSL | 0:d92f9d21154c | 4725 | |
wolfSSL | 0:d92f9d21154c | 4726 | |
wolfSSL | 0:d92f9d21154c | 4727 | /* ecc decrypt with shared secret run through kdf |
wolfSSL | 0:d92f9d21154c | 4728 | ctx holds non default algos and inputs |
wolfSSL | 0:d92f9d21154c | 4729 | return 0 on success */ |
wolfSSL | 0:d92f9d21154c | 4730 | int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, |
wolfSSL | 0:d92f9d21154c | 4731 | word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) |
wolfSSL | 0:d92f9d21154c | 4732 | { |
wolfSSL | 0:d92f9d21154c | 4733 | int ret; |
wolfSSL | 0:d92f9d21154c | 4734 | word32 blockSz; |
wolfSSL | 0:d92f9d21154c | 4735 | word32 digestSz; |
wolfSSL | 0:d92f9d21154c | 4736 | ecEncCtx localCtx; |
wolfSSL | 0:d92f9d21154c | 4737 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 4738 | byte* sharedSecret; |
wolfSSL | 0:d92f9d21154c | 4739 | byte* keys; |
wolfSSL | 0:d92f9d21154c | 4740 | #else |
wolfSSL | 0:d92f9d21154c | 4741 | byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ |
wolfSSL | 0:d92f9d21154c | 4742 | byte keys[ECC_BUFSIZE]; /* max size */ |
wolfSSL | 0:d92f9d21154c | 4743 | #endif |
wolfSSL | 0:d92f9d21154c | 4744 | word32 sharedSz = ECC_MAXSIZE; |
wolfSSL | 0:d92f9d21154c | 4745 | int keysLen; |
wolfSSL | 0:d92f9d21154c | 4746 | int encKeySz; |
wolfSSL | 0:d92f9d21154c | 4747 | int ivSz; |
wolfSSL | 0:d92f9d21154c | 4748 | int offset = 0; /* in case using msg exchange */ |
wolfSSL | 0:d92f9d21154c | 4749 | byte* encKey; |
wolfSSL | 0:d92f9d21154c | 4750 | byte* encIv; |
wolfSSL | 0:d92f9d21154c | 4751 | byte* macKey; |
wolfSSL | 0:d92f9d21154c | 4752 | |
wolfSSL | 0:d92f9d21154c | 4753 | if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || |
wolfSSL | 0:d92f9d21154c | 4754 | outSz == NULL) |
wolfSSL | 0:d92f9d21154c | 4755 | return BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4756 | |
wolfSSL | 0:d92f9d21154c | 4757 | if (ctx == NULL) { /* use defaults */ |
wolfSSL | 0:d92f9d21154c | 4758 | ecc_ctx_init(&localCtx, 0); |
wolfSSL | 0:d92f9d21154c | 4759 | ctx = &localCtx; |
wolfSSL | 0:d92f9d21154c | 4760 | } |
wolfSSL | 0:d92f9d21154c | 4761 | |
wolfSSL | 0:d92f9d21154c | 4762 | ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, |
wolfSSL | 0:d92f9d21154c | 4763 | &blockSz); |
wolfSSL | 0:d92f9d21154c | 4764 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4765 | return ret; |
wolfSSL | 0:d92f9d21154c | 4766 | |
wolfSSL | 0:d92f9d21154c | 4767 | if (ctx->protocol == REQ_RESP_CLIENT) { |
wolfSSL | 0:d92f9d21154c | 4768 | offset = keysLen; |
wolfSSL | 0:d92f9d21154c | 4769 | keysLen *= 2; |
wolfSSL | 0:d92f9d21154c | 4770 | |
wolfSSL | 0:d92f9d21154c | 4771 | if (ctx->cliSt != ecCLI_SENT_REQ) |
wolfSSL | 0:d92f9d21154c | 4772 | return BAD_ENC_STATE_E; |
wolfSSL | 0:d92f9d21154c | 4773 | |
wolfSSL | 0:d92f9d21154c | 4774 | ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ |
wolfSSL | 0:d92f9d21154c | 4775 | } |
wolfSSL | 0:d92f9d21154c | 4776 | else if (ctx->protocol == REQ_RESP_SERVER) { |
wolfSSL | 0:d92f9d21154c | 4777 | if (ctx->srvSt != ecSRV_SALT_SET) |
wolfSSL | 0:d92f9d21154c | 4778 | return BAD_ENC_STATE_E; |
wolfSSL | 0:d92f9d21154c | 4779 | |
wolfSSL | 0:d92f9d21154c | 4780 | ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */ |
wolfSSL | 0:d92f9d21154c | 4781 | } |
wolfSSL | 0:d92f9d21154c | 4782 | |
wolfSSL | 0:d92f9d21154c | 4783 | if (keysLen > ECC_BUFSIZE) /* keys size */ |
wolfSSL | 0:d92f9d21154c | 4784 | return BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 4785 | |
wolfSSL | 0:d92f9d21154c | 4786 | if ( ((msgSz-digestSz) % blockSz) != 0) |
wolfSSL | 0:d92f9d21154c | 4787 | return BAD_PADDING_E; |
wolfSSL | 0:d92f9d21154c | 4788 | |
wolfSSL | 0:d92f9d21154c | 4789 | if (*outSz < (msgSz - digestSz)) |
wolfSSL | 0:d92f9d21154c | 4790 | return BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 4791 | |
wolfSSL | 0:d92f9d21154c | 4792 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 4793 | sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4794 | if (sharedSecret == NULL) |
wolfSSL | 0:d92f9d21154c | 4795 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 4796 | |
wolfSSL | 0:d92f9d21154c | 4797 | keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4798 | if (keys == NULL) { |
wolfSSL | 0:d92f9d21154c | 4799 | XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4800 | return MEMORY_E; |
wolfSSL | 0:d92f9d21154c | 4801 | } |
wolfSSL | 0:d92f9d21154c | 4802 | #endif |
wolfSSL | 0:d92f9d21154c | 4803 | |
wolfSSL | 0:d92f9d21154c | 4804 | ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); |
wolfSSL | 0:d92f9d21154c | 4805 | |
wolfSSL | 0:d92f9d21154c | 4806 | if (ret == 0) { |
wolfSSL | 0:d92f9d21154c | 4807 | switch (ctx->kdfAlgo) { |
wolfSSL | 0:d92f9d21154c | 4808 | case ecHKDF_SHA256 : |
wolfSSL | 0:d92f9d21154c | 4809 | ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt, |
wolfSSL | 0:d92f9d21154c | 4810 | ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, |
wolfSSL | 0:d92f9d21154c | 4811 | keys, keysLen); |
wolfSSL | 0:d92f9d21154c | 4812 | break; |
wolfSSL | 0:d92f9d21154c | 4813 | |
wolfSSL | 0:d92f9d21154c | 4814 | default: |
wolfSSL | 0:d92f9d21154c | 4815 | ret = BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4816 | break; |
wolfSSL | 0:d92f9d21154c | 4817 | } |
wolfSSL | 0:d92f9d21154c | 4818 | } |
wolfSSL | 0:d92f9d21154c | 4819 | |
wolfSSL | 0:d92f9d21154c | 4820 | if (ret == 0) { |
wolfSSL | 0:d92f9d21154c | 4821 | encKey = keys + offset; |
wolfSSL | 0:d92f9d21154c | 4822 | encIv = encKey + encKeySz; |
wolfSSL | 0:d92f9d21154c | 4823 | macKey = encKey + encKeySz + ivSz; |
wolfSSL | 0:d92f9d21154c | 4824 | |
wolfSSL | 0:d92f9d21154c | 4825 | switch (ctx->macAlgo) { |
wolfSSL | 0:d92f9d21154c | 4826 | case ecHMAC_SHA256: |
wolfSSL | 0:d92f9d21154c | 4827 | { |
wolfSSL | 0:d92f9d21154c | 4828 | byte verify[SHA256_DIGEST_SIZE]; |
wolfSSL | 0:d92f9d21154c | 4829 | Hmac hmac; |
wolfSSL | 0:d92f9d21154c | 4830 | ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); |
wolfSSL | 0:d92f9d21154c | 4831 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4832 | break; |
wolfSSL | 0:d92f9d21154c | 4833 | ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz); |
wolfSSL | 0:d92f9d21154c | 4834 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4835 | break; |
wolfSSL | 0:d92f9d21154c | 4836 | ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); |
wolfSSL | 0:d92f9d21154c | 4837 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4838 | break; |
wolfSSL | 0:d92f9d21154c | 4839 | ret = wc_HmacFinal(&hmac, verify); |
wolfSSL | 0:d92f9d21154c | 4840 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4841 | break; |
wolfSSL | 0:d92f9d21154c | 4842 | if (memcmp(verify, msg + msgSz - digestSz, digestSz) != 0) |
wolfSSL | 0:d92f9d21154c | 4843 | ret = -1; |
wolfSSL | 0:d92f9d21154c | 4844 | } |
wolfSSL | 0:d92f9d21154c | 4845 | break; |
wolfSSL | 0:d92f9d21154c | 4846 | |
wolfSSL | 0:d92f9d21154c | 4847 | default: |
wolfSSL | 0:d92f9d21154c | 4848 | ret = BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4849 | break; |
wolfSSL | 0:d92f9d21154c | 4850 | } |
wolfSSL | 0:d92f9d21154c | 4851 | } |
wolfSSL | 0:d92f9d21154c | 4852 | |
wolfSSL | 0:d92f9d21154c | 4853 | if (ret == 0) { |
wolfSSL | 0:d92f9d21154c | 4854 | switch (ctx->encAlgo) { |
wolfSSL | 0:d92f9d21154c | 4855 | case ecAES_128_CBC: |
wolfSSL | 0:d92f9d21154c | 4856 | { |
wolfSSL | 0:d92f9d21154c | 4857 | Aes aes; |
wolfSSL | 0:d92f9d21154c | 4858 | ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, |
wolfSSL | 0:d92f9d21154c | 4859 | AES_DECRYPTION); |
wolfSSL | 0:d92f9d21154c | 4860 | if (ret != 0) |
wolfSSL | 0:d92f9d21154c | 4861 | break; |
wolfSSL | 0:d92f9d21154c | 4862 | ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz); |
wolfSSL | 0:d92f9d21154c | 4863 | } |
wolfSSL | 0:d92f9d21154c | 4864 | break; |
wolfSSL | 0:d92f9d21154c | 4865 | |
wolfSSL | 0:d92f9d21154c | 4866 | default: |
wolfSSL | 0:d92f9d21154c | 4867 | ret = BAD_FUNC_ARG; |
wolfSSL | 0:d92f9d21154c | 4868 | break; |
wolfSSL | 0:d92f9d21154c | 4869 | } |
wolfSSL | 0:d92f9d21154c | 4870 | } |
wolfSSL | 0:d92f9d21154c | 4871 | |
wolfSSL | 0:d92f9d21154c | 4872 | if (ret == 0) |
wolfSSL | 0:d92f9d21154c | 4873 | *outSz = msgSz - digestSz; |
wolfSSL | 0:d92f9d21154c | 4874 | |
wolfSSL | 0:d92f9d21154c | 4875 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 0:d92f9d21154c | 4876 | XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4877 | XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
wolfSSL | 0:d92f9d21154c | 4878 | #endif |
wolfSSL | 0:d92f9d21154c | 4879 | |
wolfSSL | 0:d92f9d21154c | 4880 | return ret; |
wolfSSL | 0:d92f9d21154c | 4881 | } |
wolfSSL | 0:d92f9d21154c | 4882 | |
wolfSSL | 0:d92f9d21154c | 4883 | |
wolfSSL | 0:d92f9d21154c | 4884 | #endif /* HAVE_ECC_ENCRYPT */ |
wolfSSL | 0:d92f9d21154c | 4885 | |
wolfSSL | 0:d92f9d21154c | 4886 | |
wolfSSL | 0:d92f9d21154c | 4887 | #ifdef HAVE_COMP_KEY |
wolfSSL | 0:d92f9d21154c | 4888 | |
wolfSSL | 0:d92f9d21154c | 4889 | /* computes the jacobi c = (a | n) (or Legendre if n is prime) |
wolfSSL | 0:d92f9d21154c | 4890 | * HAC pp. 73 Algorithm 2.149 |
wolfSSL | 0:d92f9d21154c | 4891 | */ |
wolfSSL | 0:d92f9d21154c | 4892 | int mp_jacobi(mp_int* a, mp_int* p, int* c) |
wolfSSL | 0:d92f9d21154c | 4893 | { |
wolfSSL | 0:d92f9d21154c | 4894 | mp_int a1, p1; |
wolfSSL | 0:d92f9d21154c | 4895 | int k, s, r, res; |
wolfSSL | 0:d92f9d21154c | 4896 | mp_digit residue; |
wolfSSL | 0:d92f9d21154c | 4897 | |
wolfSSL | 0:d92f9d21154c | 4898 | /* if p <= 0 return MP_VAL */ |
wolfSSL | 0:d92f9d21154c | 4899 | if (mp_cmp_d(p, 0) != MP_GT) { |
wolfSSL | 0:d92f9d21154c | 4900 | return MP_VAL; |
wolfSSL | 0:d92f9d21154c | 4901 | } |
wolfSSL | 0:d92f9d21154c | 4902 | |
wolfSSL | 0:d92f9d21154c | 4903 | /* step 1. if a == 0, return 0 */ |
wolfSSL | 0:d92f9d21154c | 4904 | if (mp_iszero (a) == 1) { |
wolfSSL | 0:d92f9d21154c | 4905 | *c = 0; |
wolfSSL | 0:d92f9d21154c | 4906 | return MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 4907 | } |
wolfSSL | 0:d92f9d21154c | 4908 | |
wolfSSL | 0:d92f9d21154c | 4909 | /* step 2. if a == 1, return 1 */ |
wolfSSL | 0:d92f9d21154c | 4910 | if (mp_cmp_d (a, 1) == MP_EQ) { |
wolfSSL | 0:d92f9d21154c | 4911 | *c = 1; |
wolfSSL | 0:d92f9d21154c | 4912 | return MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 4913 | } |
wolfSSL | 0:d92f9d21154c | 4914 | |
wolfSSL | 0:d92f9d21154c | 4915 | /* default */ |
wolfSSL | 0:d92f9d21154c | 4916 | s = 0; |
wolfSSL | 0:d92f9d21154c | 4917 | |
wolfSSL | 0:d92f9d21154c | 4918 | /* step 3. write a = a1 * 2**k */ |
wolfSSL | 0:d92f9d21154c | 4919 | if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4920 | return res; |
wolfSSL | 0:d92f9d21154c | 4921 | } |
wolfSSL | 0:d92f9d21154c | 4922 | |
wolfSSL | 0:d92f9d21154c | 4923 | if ((res = mp_init (&p1)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4924 | mp_clear(&a1); |
wolfSSL | 0:d92f9d21154c | 4925 | return res; |
wolfSSL | 0:d92f9d21154c | 4926 | } |
wolfSSL | 0:d92f9d21154c | 4927 | |
wolfSSL | 0:d92f9d21154c | 4928 | /* divide out larger power of two */ |
wolfSSL | 0:d92f9d21154c | 4929 | k = mp_cnt_lsb(&a1); |
wolfSSL | 0:d92f9d21154c | 4930 | res = mp_div_2d(&a1, k, &a1, NULL); |
wolfSSL | 0:d92f9d21154c | 4931 | |
wolfSSL | 0:d92f9d21154c | 4932 | if (res == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4933 | /* step 4. if e is even set s=1 */ |
wolfSSL | 0:d92f9d21154c | 4934 | if ((k & 1) == 0) { |
wolfSSL | 0:d92f9d21154c | 4935 | s = 1; |
wolfSSL | 0:d92f9d21154c | 4936 | } else { |
wolfSSL | 0:d92f9d21154c | 4937 | /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ |
wolfSSL | 0:d92f9d21154c | 4938 | residue = p->dp[0] & 7; |
wolfSSL | 0:d92f9d21154c | 4939 | |
wolfSSL | 0:d92f9d21154c | 4940 | if (residue == 1 || residue == 7) { |
wolfSSL | 0:d92f9d21154c | 4941 | s = 1; |
wolfSSL | 0:d92f9d21154c | 4942 | } else if (residue == 3 || residue == 5) { |
wolfSSL | 0:d92f9d21154c | 4943 | s = -1; |
wolfSSL | 0:d92f9d21154c | 4944 | } |
wolfSSL | 0:d92f9d21154c | 4945 | } |
wolfSSL | 0:d92f9d21154c | 4946 | |
wolfSSL | 0:d92f9d21154c | 4947 | /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ |
wolfSSL | 0:d92f9d21154c | 4948 | if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { |
wolfSSL | 0:d92f9d21154c | 4949 | s = -s; |
wolfSSL | 0:d92f9d21154c | 4950 | } |
wolfSSL | 0:d92f9d21154c | 4951 | } |
wolfSSL | 0:d92f9d21154c | 4952 | |
wolfSSL | 0:d92f9d21154c | 4953 | if (res == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4954 | /* if a1 == 1 we're done */ |
wolfSSL | 0:d92f9d21154c | 4955 | if (mp_cmp_d (&a1, 1) == MP_EQ) { |
wolfSSL | 0:d92f9d21154c | 4956 | *c = s; |
wolfSSL | 0:d92f9d21154c | 4957 | } else { |
wolfSSL | 0:d92f9d21154c | 4958 | /* n1 = n mod a1 */ |
wolfSSL | 0:d92f9d21154c | 4959 | res = mp_mod (p, &a1, &p1); |
wolfSSL | 0:d92f9d21154c | 4960 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4961 | res = mp_jacobi (&p1, &a1, &r); |
wolfSSL | 0:d92f9d21154c | 4962 | |
wolfSSL | 0:d92f9d21154c | 4963 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4964 | *c = s * r; |
wolfSSL | 0:d92f9d21154c | 4965 | } |
wolfSSL | 0:d92f9d21154c | 4966 | } |
wolfSSL | 0:d92f9d21154c | 4967 | |
wolfSSL | 0:d92f9d21154c | 4968 | /* done */ |
wolfSSL | 0:d92f9d21154c | 4969 | mp_clear (&p1); |
wolfSSL | 0:d92f9d21154c | 4970 | mp_clear (&a1); |
wolfSSL | 0:d92f9d21154c | 4971 | |
wolfSSL | 0:d92f9d21154c | 4972 | return res; |
wolfSSL | 0:d92f9d21154c | 4973 | } |
wolfSSL | 0:d92f9d21154c | 4974 | |
wolfSSL | 0:d92f9d21154c | 4975 | |
wolfSSL | 0:d92f9d21154c | 4976 | int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) |
wolfSSL | 0:d92f9d21154c | 4977 | { |
wolfSSL | 0:d92f9d21154c | 4978 | int res, legendre, done = 0; |
wolfSSL | 0:d92f9d21154c | 4979 | mp_int t1, C, Q, S, Z, M, T, R, two; |
wolfSSL | 0:d92f9d21154c | 4980 | mp_digit i; |
wolfSSL | 0:d92f9d21154c | 4981 | |
wolfSSL | 0:d92f9d21154c | 4982 | /* first handle the simple cases */ |
wolfSSL | 0:d92f9d21154c | 4983 | if (mp_cmp_d(n, 0) == MP_EQ) { |
wolfSSL | 0:d92f9d21154c | 4984 | mp_zero(ret); |
wolfSSL | 0:d92f9d21154c | 4985 | return MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 4986 | } |
wolfSSL | 0:d92f9d21154c | 4987 | if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */ |
wolfSSL | 0:d92f9d21154c | 4988 | /* TAO removed |
wolfSSL | 0:d92f9d21154c | 4989 | if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; |
wolfSSL | 0:d92f9d21154c | 4990 | if (legendre == -1) return MP_VAL; */ /* quadratic non-residue mod prime */ |
wolfSSL | 0:d92f9d21154c | 4991 | |
wolfSSL | 0:d92f9d21154c | 4992 | if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 4993 | return res; |
wolfSSL | 0:d92f9d21154c | 4994 | |
wolfSSL | 0:d92f9d21154c | 4995 | if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL)) |
wolfSSL | 0:d92f9d21154c | 4996 | != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 4997 | mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z); |
wolfSSL | 0:d92f9d21154c | 4998 | mp_clear(&M); |
wolfSSL | 0:d92f9d21154c | 4999 | return res; |
wolfSSL | 0:d92f9d21154c | 5000 | } |
wolfSSL | 0:d92f9d21154c | 5001 | |
wolfSSL | 0:d92f9d21154c | 5002 | /* SPECIAL CASE: if prime mod 4 == 3 |
wolfSSL | 0:d92f9d21154c | 5003 | * compute directly: res = n^(prime+1)/4 mod prime |
wolfSSL | 0:d92f9d21154c | 5004 | * Handbook of Applied Cryptography algorithm 3.36 |
wolfSSL | 0:d92f9d21154c | 5005 | */ |
wolfSSL | 0:d92f9d21154c | 5006 | res = mp_mod_d(prime, 4, &i); |
wolfSSL | 0:d92f9d21154c | 5007 | if (res == MP_OKAY && i == 3) { |
wolfSSL | 0:d92f9d21154c | 5008 | res = mp_add_d(prime, 1, &t1); |
wolfSSL | 0:d92f9d21154c | 5009 | |
wolfSSL | 0:d92f9d21154c | 5010 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5011 | res = mp_div_2(&t1, &t1); |
wolfSSL | 0:d92f9d21154c | 5012 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5013 | res = mp_div_2(&t1, &t1); |
wolfSSL | 0:d92f9d21154c | 5014 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5015 | res = mp_exptmod(n, &t1, prime, ret); |
wolfSSL | 0:d92f9d21154c | 5016 | |
wolfSSL | 0:d92f9d21154c | 5017 | done = 1; |
wolfSSL | 0:d92f9d21154c | 5018 | } |
wolfSSL | 0:d92f9d21154c | 5019 | |
wolfSSL | 0:d92f9d21154c | 5020 | /* NOW: TonelliShanks algorithm */ |
wolfSSL | 0:d92f9d21154c | 5021 | |
wolfSSL | 0:d92f9d21154c | 5022 | if (res == MP_OKAY && done == 0) { |
wolfSSL | 0:d92f9d21154c | 5023 | |
wolfSSL | 0:d92f9d21154c | 5024 | /* factor out powers of 2 from prime-1, defining Q and S |
wolfSSL | 0:d92f9d21154c | 5025 | * as: prime-1 = Q*2^S */ |
wolfSSL | 0:d92f9d21154c | 5026 | res = mp_copy(prime, &Q); |
wolfSSL | 0:d92f9d21154c | 5027 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5028 | res = mp_sub_d(&Q, 1, &Q); |
wolfSSL | 0:d92f9d21154c | 5029 | /* Q = prime - 1 */ |
wolfSSL | 0:d92f9d21154c | 5030 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5031 | mp_zero(&S); |
wolfSSL | 0:d92f9d21154c | 5032 | /* S = 0 */ |
wolfSSL | 0:d92f9d21154c | 5033 | while (res == MP_OKAY && mp_iseven(&Q)) { |
wolfSSL | 0:d92f9d21154c | 5034 | res = mp_div_2(&Q, &Q); |
wolfSSL | 0:d92f9d21154c | 5035 | /* Q = Q / 2 */ |
wolfSSL | 0:d92f9d21154c | 5036 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5037 | res = mp_add_d(&S, 1, &S); |
wolfSSL | 0:d92f9d21154c | 5038 | /* S = S + 1 */ |
wolfSSL | 0:d92f9d21154c | 5039 | } |
wolfSSL | 0:d92f9d21154c | 5040 | |
wolfSSL | 0:d92f9d21154c | 5041 | /* find a Z such that the Legendre symbol (Z|prime) == -1 */ |
wolfSSL | 0:d92f9d21154c | 5042 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5043 | res = mp_set_int(&Z, 2); |
wolfSSL | 0:d92f9d21154c | 5044 | /* Z = 2 */ |
wolfSSL | 0:d92f9d21154c | 5045 | while (res == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 5046 | res = mp_jacobi(&Z, prime, &legendre); |
wolfSSL | 0:d92f9d21154c | 5047 | if (res == MP_OKAY && legendre == -1) |
wolfSSL | 0:d92f9d21154c | 5048 | break; |
wolfSSL | 0:d92f9d21154c | 5049 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5050 | res = mp_add_d(&Z, 1, &Z); |
wolfSSL | 0:d92f9d21154c | 5051 | /* Z = Z + 1 */ |
wolfSSL | 0:d92f9d21154c | 5052 | } |
wolfSSL | 0:d92f9d21154c | 5053 | |
wolfSSL | 0:d92f9d21154c | 5054 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5055 | res = mp_exptmod(&Z, &Q, prime, &C); |
wolfSSL | 0:d92f9d21154c | 5056 | /* C = Z ^ Q mod prime */ |
wolfSSL | 0:d92f9d21154c | 5057 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5058 | res = mp_add_d(&Q, 1, &t1); |
wolfSSL | 0:d92f9d21154c | 5059 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5060 | res = mp_div_2(&t1, &t1); |
wolfSSL | 0:d92f9d21154c | 5061 | /* t1 = (Q + 1) / 2 */ |
wolfSSL | 0:d92f9d21154c | 5062 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5063 | res = mp_exptmod(n, &t1, prime, &R); |
wolfSSL | 0:d92f9d21154c | 5064 | /* R = n ^ ((Q + 1) / 2) mod prime */ |
wolfSSL | 0:d92f9d21154c | 5065 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5066 | res = mp_exptmod(n, &Q, prime, &T); |
wolfSSL | 0:d92f9d21154c | 5067 | /* T = n ^ Q mod prime */ |
wolfSSL | 0:d92f9d21154c | 5068 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5069 | res = mp_copy(&S, &M); |
wolfSSL | 0:d92f9d21154c | 5070 | /* M = S */ |
wolfSSL | 0:d92f9d21154c | 5071 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5072 | res = mp_set_int(&two, 2); |
wolfSSL | 0:d92f9d21154c | 5073 | |
wolfSSL | 0:d92f9d21154c | 5074 | while (res == MP_OKAY && done == 0) { |
wolfSSL | 0:d92f9d21154c | 5075 | res = mp_copy(&T, &t1); |
wolfSSL | 0:d92f9d21154c | 5076 | i = 0; |
wolfSSL | 0:d92f9d21154c | 5077 | while (res == MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 5078 | if (mp_cmp_d(&t1, 1) == MP_EQ) |
wolfSSL | 0:d92f9d21154c | 5079 | break; |
wolfSSL | 0:d92f9d21154c | 5080 | res = mp_exptmod(&t1, &two, prime, &t1); |
wolfSSL | 0:d92f9d21154c | 5081 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5082 | i++; |
wolfSSL | 0:d92f9d21154c | 5083 | } |
wolfSSL | 0:d92f9d21154c | 5084 | if (res == MP_OKAY && i == 0) { |
wolfSSL | 0:d92f9d21154c | 5085 | mp_copy(&R, ret); |
wolfSSL | 0:d92f9d21154c | 5086 | res = MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 5087 | done = 1; |
wolfSSL | 0:d92f9d21154c | 5088 | } |
wolfSSL | 0:d92f9d21154c | 5089 | |
wolfSSL | 0:d92f9d21154c | 5090 | if (done == 0) { |
wolfSSL | 0:d92f9d21154c | 5091 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5092 | res = mp_sub_d(&M, i, &t1); |
wolfSSL | 0:d92f9d21154c | 5093 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5094 | res = mp_sub_d(&t1, 1, &t1); |
wolfSSL | 0:d92f9d21154c | 5095 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5096 | res = mp_exptmod(&two, &t1, prime, &t1); |
wolfSSL | 0:d92f9d21154c | 5097 | /* t1 = 2 ^ (M - i - 1) */ |
wolfSSL | 0:d92f9d21154c | 5098 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5099 | res = mp_exptmod(&C, &t1, prime, &t1); |
wolfSSL | 0:d92f9d21154c | 5100 | /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ |
wolfSSL | 0:d92f9d21154c | 5101 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5102 | res = mp_sqrmod(&t1, prime, &C); |
wolfSSL | 0:d92f9d21154c | 5103 | /* C = (t1 * t1) mod prime */ |
wolfSSL | 0:d92f9d21154c | 5104 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5105 | res = mp_mulmod(&R, &t1, prime, &R); |
wolfSSL | 0:d92f9d21154c | 5106 | /* R = (R * t1) mod prime */ |
wolfSSL | 0:d92f9d21154c | 5107 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5108 | res = mp_mulmod(&T, &C, prime, &T); |
wolfSSL | 0:d92f9d21154c | 5109 | /* T = (T * C) mod prime */ |
wolfSSL | 0:d92f9d21154c | 5110 | if (res == MP_OKAY) |
wolfSSL | 0:d92f9d21154c | 5111 | mp_set(&M, i); |
wolfSSL | 0:d92f9d21154c | 5112 | /* M = i */ |
wolfSSL | 0:d92f9d21154c | 5113 | } |
wolfSSL | 0:d92f9d21154c | 5114 | } |
wolfSSL | 0:d92f9d21154c | 5115 | } |
wolfSSL | 0:d92f9d21154c | 5116 | |
wolfSSL | 0:d92f9d21154c | 5117 | /* done */ |
wolfSSL | 0:d92f9d21154c | 5118 | mp_clear(&t1); |
wolfSSL | 0:d92f9d21154c | 5119 | mp_clear(&C); |
wolfSSL | 0:d92f9d21154c | 5120 | mp_clear(&Q); |
wolfSSL | 0:d92f9d21154c | 5121 | mp_clear(&S); |
wolfSSL | 0:d92f9d21154c | 5122 | mp_clear(&Z); |
wolfSSL | 0:d92f9d21154c | 5123 | mp_clear(&M); |
wolfSSL | 0:d92f9d21154c | 5124 | mp_clear(&T); |
wolfSSL | 0:d92f9d21154c | 5125 | mp_clear(&R); |
wolfSSL | 0:d92f9d21154c | 5126 | mp_clear(&two); |
wolfSSL | 0:d92f9d21154c | 5127 | |
wolfSSL | 0:d92f9d21154c | 5128 | return res; |
wolfSSL | 0:d92f9d21154c | 5129 | } |
wolfSSL | 0:d92f9d21154c | 5130 | |
wolfSSL | 0:d92f9d21154c | 5131 | |
wolfSSL | 0:d92f9d21154c | 5132 | /* export public ECC key in ANSI X9.63 format compressed */ |
wolfSSL | 0:d92f9d21154c | 5133 | int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen) |
wolfSSL | 0:d92f9d21154c | 5134 | { |
wolfSSL | 0:d92f9d21154c | 5135 | word32 numlen; |
wolfSSL | 0:d92f9d21154c | 5136 | int ret = MP_OKAY; |
wolfSSL | 0:d92f9d21154c | 5137 | |
wolfSSL | 0:d92f9d21154c | 5138 | if (key == NULL || out == NULL || outLen == NULL) |
wolfSSL | 0:d92f9d21154c | 5139 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 5140 | |
wolfSSL | 0:d92f9d21154c | 5141 | if (ecc_is_valid_idx(key->idx) == 0) { |
wolfSSL | 0:d92f9d21154c | 5142 | return ECC_BAD_ARG_E; |
wolfSSL | 0:d92f9d21154c | 5143 | } |
wolfSSL | 0:d92f9d21154c | 5144 | numlen = key->dp->size; |
wolfSSL | 0:d92f9d21154c | 5145 | |
wolfSSL | 0:d92f9d21154c | 5146 | if (*outLen < (1 + numlen)) { |
wolfSSL | 0:d92f9d21154c | 5147 | *outLen = 1 + numlen; |
wolfSSL | 0:d92f9d21154c | 5148 | return BUFFER_E; |
wolfSSL | 0:d92f9d21154c | 5149 | } |
wolfSSL | 0:d92f9d21154c | 5150 | |
wolfSSL | 0:d92f9d21154c | 5151 | /* store first byte */ |
wolfSSL | 0:d92f9d21154c | 5152 | out[0] = mp_isodd(key->pubkey.y) ? 0x03 : 0x02; |
wolfSSL | 0:d92f9d21154c | 5153 | |
wolfSSL | 0:d92f9d21154c | 5154 | /* pad and store x */ |
wolfSSL | 0:d92f9d21154c | 5155 | XMEMSET(out+1, 0, numlen); |
wolfSSL | 0:d92f9d21154c | 5156 | ret = mp_to_unsigned_bin(key->pubkey.x, |
wolfSSL | 0:d92f9d21154c | 5157 | out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x))); |
wolfSSL | 0:d92f9d21154c | 5158 | *outLen = 1 + numlen; |
wolfSSL | 0:d92f9d21154c | 5159 | return ret; |
wolfSSL | 0:d92f9d21154c | 5160 | } |
wolfSSL | 0:d92f9d21154c | 5161 | |
wolfSSL | 0:d92f9d21154c | 5162 | |
wolfSSL | 0:d92f9d21154c | 5163 | /* d = a - b (mod c) */ |
wolfSSL | 0:d92f9d21154c | 5164 | int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d) |
wolfSSL | 0:d92f9d21154c | 5165 | { |
wolfSSL | 0:d92f9d21154c | 5166 | int res; |
wolfSSL | 0:d92f9d21154c | 5167 | mp_int t; |
wolfSSL | 0:d92f9d21154c | 5168 | |
wolfSSL | 0:d92f9d21154c | 5169 | if ((res = mp_init (&t)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 5170 | return res; |
wolfSSL | 0:d92f9d21154c | 5171 | } |
wolfSSL | 0:d92f9d21154c | 5172 | |
wolfSSL | 0:d92f9d21154c | 5173 | if ((res = mp_sub (a, b, &t)) != MP_OKAY) { |
wolfSSL | 0:d92f9d21154c | 5174 | mp_clear (&t); |
wolfSSL | 0:d92f9d21154c | 5175 | return res; |
wolfSSL | 0:d92f9d21154c | 5176 | } |
wolfSSL | 0:d92f9d21154c | 5177 | res = mp_mod (&t, c, d); |
wolfSSL | 0:d92f9d21154c | 5178 | mp_clear (&t); |
wolfSSL | 0:d92f9d21154c | 5179 | |
wolfSSL | 0:d92f9d21154c | 5180 | return res; |
wolfSSL | 0:d92f9d21154c | 5181 | } |
wolfSSL | 0:d92f9d21154c | 5182 | |
wolfSSL | 0:d92f9d21154c | 5183 | |
wolfSSL | 0:d92f9d21154c | 5184 | #endif /* HAVE_COMP_KEY */ |
wolfSSL | 0:d92f9d21154c | 5185 | |
wolfSSL | 0:d92f9d21154c | 5186 | #endif /* HAVE_ECC */ |
wolfSSL | 0:d92f9d21154c | 5187 |