Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
sPymbed
Date:
Tue Nov 19 14:32:16 2019 +0000
Revision:
16:048e5e270a58
Parent:
14:167253f4e170
working ssl

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 14:167253f4e170 1 /* sp.c
wolfSSL 14:167253f4e170 2 *
wolfSSL 14:167253f4e170 3 * Copyright (C) 2006-2018 wolfSSL Inc.
wolfSSL 14:167253f4e170 4 *
wolfSSL 14:167253f4e170 5 * This file is part of wolfSSL.
wolfSSL 14:167253f4e170 6 *
wolfSSL 14:167253f4e170 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 14:167253f4e170 8 * it under the terms of the GNU General Public License as published by
wolfSSL 14:167253f4e170 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 14:167253f4e170 10 * (at your option) any later version.
wolfSSL 14:167253f4e170 11 *
wolfSSL 14:167253f4e170 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 14:167253f4e170 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 14:167253f4e170 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 14:167253f4e170 15 * GNU General Public License for more details.
wolfSSL 14:167253f4e170 16 *
wolfSSL 14:167253f4e170 17 * You should have received a copy of the GNU General Public License
wolfSSL 14:167253f4e170 18 * along with this program; if not, write to the Free Software
wolfSSL 14:167253f4e170 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 14:167253f4e170 20 */
wolfSSL 14:167253f4e170 21
wolfSSL 14:167253f4e170 22 /* Implementation by Sean Parkinson. */
wolfSSL 14:167253f4e170 23
wolfSSL 14:167253f4e170 24 #ifdef HAVE_CONFIG_H
wolfSSL 14:167253f4e170 25 #include <config.h>
wolfSSL 14:167253f4e170 26 #endif
wolfSSL 14:167253f4e170 27
wolfSSL 14:167253f4e170 28 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 14:167253f4e170 29 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 14:167253f4e170 30 #include <wolfssl/wolfcrypt/cpuid.h>
wolfSSL 14:167253f4e170 31 #ifdef NO_INLINE
wolfSSL 14:167253f4e170 32 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 14:167253f4e170 33 #else
wolfSSL 14:167253f4e170 34 #define WOLFSSL_MISC_INCLUDED
wolfSSL 14:167253f4e170 35 #include <wolfcrypt/src/misc.c>
wolfSSL 14:167253f4e170 36 #endif
wolfSSL 14:167253f4e170 37
wolfSSL 14:167253f4e170 38 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \
wolfSSL 14:167253f4e170 39 defined(WOLFSSL_HAVE_SP_ECC)
wolfSSL 14:167253f4e170 40
wolfSSL 14:167253f4e170 41 #ifdef RSA_LOW_MEM
wolfSSL 14:167253f4e170 42 #define SP_RSA_PRIVATE_EXP_D
wolfSSL 14:167253f4e170 43
wolfSSL 14:167253f4e170 44 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 45 #define WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 46 #endif
wolfSSL 14:167253f4e170 47 #endif
wolfSSL 14:167253f4e170 48
wolfSSL 14:167253f4e170 49 #include <wolfssl/wolfcrypt/sp.h>
wolfSSL 14:167253f4e170 50
wolfSSL 14:167253f4e170 51 #ifndef WOLFSSL_SP_ASM
wolfSSL 14:167253f4e170 52 #if SP_WORD_SIZE == 32
wolfSSL 14:167253f4e170 53 #if defined(WOLFSSL_SP_CACHE_RESISTANT) || defined(WOLFSSL_SP_SMALL)
wolfSSL 14:167253f4e170 54 /* Mask for address to obfuscate which of the two address will be used. */
wolfSSL 14:167253f4e170 55 static const size_t addr_mask[2] = { 0, (size_t)-1 };
wolfSSL 14:167253f4e170 56 #endif
wolfSSL 14:167253f4e170 57
wolfSSL 14:167253f4e170 58 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 14:167253f4e170 59 #ifndef WOLFSSL_SP_NO_2048
wolfSSL 14:167253f4e170 60 /* Read big endian unsigned byte aray into r.
wolfSSL 14:167253f4e170 61 *
wolfSSL 14:167253f4e170 62 * r A single precision integer.
wolfSSL 14:167253f4e170 63 * a Byte array.
wolfSSL 14:167253f4e170 64 * n Number of bytes in array to read.
wolfSSL 14:167253f4e170 65 */
wolfSSL 14:167253f4e170 66 static void sp_2048_from_bin(sp_digit* r, int max, const byte* a, int n)
wolfSSL 14:167253f4e170 67 {
wolfSSL 14:167253f4e170 68 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 69
wolfSSL 14:167253f4e170 70 r[0] = 0;
wolfSSL 14:167253f4e170 71 for (i = n-1; i >= 0; i--) {
wolfSSL 14:167253f4e170 72 r[j] |= ((sp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 73 if (s >= 15) {
wolfSSL 14:167253f4e170 74 r[j] &= 0x7fffff;
wolfSSL 14:167253f4e170 75 s = 23 - s;
wolfSSL 14:167253f4e170 76 if (j + 1 >= max)
wolfSSL 14:167253f4e170 77 break;
wolfSSL 14:167253f4e170 78 r[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 79 s = 8 - s;
wolfSSL 14:167253f4e170 80 }
wolfSSL 14:167253f4e170 81 else
wolfSSL 14:167253f4e170 82 s += 8;
wolfSSL 14:167253f4e170 83 }
wolfSSL 14:167253f4e170 84
wolfSSL 14:167253f4e170 85 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 86 r[j] = 0;
wolfSSL 14:167253f4e170 87 }
wolfSSL 14:167253f4e170 88
wolfSSL 14:167253f4e170 89 /* Convert an mp_int to an array of sp_digit.
wolfSSL 14:167253f4e170 90 *
wolfSSL 14:167253f4e170 91 * r A single precision integer.
wolfSSL 14:167253f4e170 92 * a A multi-precision integer.
wolfSSL 14:167253f4e170 93 */
wolfSSL 14:167253f4e170 94 static void sp_2048_from_mp(sp_digit* r, int max, mp_int* a)
wolfSSL 14:167253f4e170 95 {
wolfSSL 14:167253f4e170 96 #if DIGIT_BIT == 23
wolfSSL 14:167253f4e170 97 int j;
wolfSSL 14:167253f4e170 98
wolfSSL 14:167253f4e170 99 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 14:167253f4e170 100
wolfSSL 14:167253f4e170 101 for (j = a->used; j < max; j++)
wolfSSL 14:167253f4e170 102 r[j] = 0;
wolfSSL 14:167253f4e170 103 #elif DIGIT_BIT > 23
wolfSSL 14:167253f4e170 104 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 105
wolfSSL 14:167253f4e170 106 r[0] = 0;
wolfSSL 14:167253f4e170 107 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 108 r[j] |= a->dp[i] << s;
wolfSSL 14:167253f4e170 109 r[j] &= 0x7fffff;
wolfSSL 14:167253f4e170 110 s = 23 - s;
wolfSSL 14:167253f4e170 111 if (j + 1 >= max)
wolfSSL 14:167253f4e170 112 break;
wolfSSL 14:167253f4e170 113 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 114 while (s + 23 <= DIGIT_BIT) {
wolfSSL 14:167253f4e170 115 s += 23;
wolfSSL 14:167253f4e170 116 r[j] &= 0x7fffff;
wolfSSL 14:167253f4e170 117 if (j + 1 >= max)
wolfSSL 14:167253f4e170 118 break;
wolfSSL 14:167253f4e170 119 if (s < DIGIT_BIT)
wolfSSL 14:167253f4e170 120 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 121 else
wolfSSL 14:167253f4e170 122 r[++j] = 0;
wolfSSL 14:167253f4e170 123 }
wolfSSL 14:167253f4e170 124 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 125 }
wolfSSL 14:167253f4e170 126
wolfSSL 14:167253f4e170 127 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 128 r[j] = 0;
wolfSSL 14:167253f4e170 129 #else
wolfSSL 14:167253f4e170 130 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 131
wolfSSL 14:167253f4e170 132 r[0] = 0;
wolfSSL 14:167253f4e170 133 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 134 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 14:167253f4e170 135 if (s + DIGIT_BIT >= 23) {
wolfSSL 14:167253f4e170 136 r[j] &= 0x7fffff;
wolfSSL 14:167253f4e170 137 if (j + 1 >= max)
wolfSSL 14:167253f4e170 138 break;
wolfSSL 14:167253f4e170 139 s = 23 - s;
wolfSSL 14:167253f4e170 140 if (s == DIGIT_BIT) {
wolfSSL 14:167253f4e170 141 r[++j] = 0;
wolfSSL 14:167253f4e170 142 s = 0;
wolfSSL 14:167253f4e170 143 }
wolfSSL 14:167253f4e170 144 else {
wolfSSL 14:167253f4e170 145 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 146 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 147 }
wolfSSL 14:167253f4e170 148 }
wolfSSL 14:167253f4e170 149 else
wolfSSL 14:167253f4e170 150 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 151 }
wolfSSL 14:167253f4e170 152
wolfSSL 14:167253f4e170 153 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 154 r[j] = 0;
wolfSSL 14:167253f4e170 155 #endif
wolfSSL 14:167253f4e170 156 }
wolfSSL 14:167253f4e170 157
wolfSSL 14:167253f4e170 158 /* Write r as big endian to byte aray.
wolfSSL 14:167253f4e170 159 * Fixed length number of bytes written: 256
wolfSSL 14:167253f4e170 160 *
wolfSSL 14:167253f4e170 161 * r A single precision integer.
wolfSSL 14:167253f4e170 162 * a Byte array.
wolfSSL 14:167253f4e170 163 */
wolfSSL 14:167253f4e170 164 static void sp_2048_to_bin(sp_digit* r, byte* a)
wolfSSL 14:167253f4e170 165 {
wolfSSL 14:167253f4e170 166 int i, j, s = 0, b;
wolfSSL 14:167253f4e170 167
wolfSSL 14:167253f4e170 168 for (i=0; i<89; i++) {
wolfSSL 14:167253f4e170 169 r[i+1] += r[i] >> 23;
wolfSSL 14:167253f4e170 170 r[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 171 }
wolfSSL 14:167253f4e170 172 j = 2048 / 8 - 1;
wolfSSL 14:167253f4e170 173 a[j] = 0;
wolfSSL 14:167253f4e170 174 for (i=0; i<90 && j>=0; i++) {
wolfSSL 14:167253f4e170 175 b = 0;
wolfSSL 14:167253f4e170 176 a[j--] |= r[i] << s; b += 8 - s;
wolfSSL 14:167253f4e170 177 if (j < 0)
wolfSSL 14:167253f4e170 178 break;
wolfSSL 14:167253f4e170 179 while (b < 23) {
wolfSSL 14:167253f4e170 180 a[j--] = r[i] >> b; b += 8;
wolfSSL 14:167253f4e170 181 if (j < 0)
wolfSSL 14:167253f4e170 182 break;
wolfSSL 14:167253f4e170 183 }
wolfSSL 14:167253f4e170 184 s = 8 - (b - 23);
wolfSSL 14:167253f4e170 185 if (j >= 0)
wolfSSL 14:167253f4e170 186 a[j] = 0;
wolfSSL 14:167253f4e170 187 if (s != 0)
wolfSSL 14:167253f4e170 188 j++;
wolfSSL 14:167253f4e170 189 }
wolfSSL 14:167253f4e170 190 }
wolfSSL 14:167253f4e170 191
wolfSSL 14:167253f4e170 192 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 193 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 194 *
wolfSSL 14:167253f4e170 195 * r A single precision integer.
wolfSSL 14:167253f4e170 196 * a A single precision integer.
wolfSSL 14:167253f4e170 197 * b A single precision integer.
wolfSSL 14:167253f4e170 198 */
wolfSSL 14:167253f4e170 199 SP_NOINLINE static void sp_2048_mul_15(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 200 const sp_digit* b)
wolfSSL 14:167253f4e170 201 {
wolfSSL 14:167253f4e170 202 int64_t t0 = ((int64_t)a[ 0]) * b[ 0];
wolfSSL 14:167253f4e170 203 int64_t t1 = ((int64_t)a[ 0]) * b[ 1]
wolfSSL 14:167253f4e170 204 + ((int64_t)a[ 1]) * b[ 0];
wolfSSL 14:167253f4e170 205 int64_t t2 = ((int64_t)a[ 0]) * b[ 2]
wolfSSL 14:167253f4e170 206 + ((int64_t)a[ 1]) * b[ 1]
wolfSSL 14:167253f4e170 207 + ((int64_t)a[ 2]) * b[ 0];
wolfSSL 14:167253f4e170 208 int64_t t3 = ((int64_t)a[ 0]) * b[ 3]
wolfSSL 14:167253f4e170 209 + ((int64_t)a[ 1]) * b[ 2]
wolfSSL 14:167253f4e170 210 + ((int64_t)a[ 2]) * b[ 1]
wolfSSL 14:167253f4e170 211 + ((int64_t)a[ 3]) * b[ 0];
wolfSSL 14:167253f4e170 212 int64_t t4 = ((int64_t)a[ 0]) * b[ 4]
wolfSSL 14:167253f4e170 213 + ((int64_t)a[ 1]) * b[ 3]
wolfSSL 14:167253f4e170 214 + ((int64_t)a[ 2]) * b[ 2]
wolfSSL 14:167253f4e170 215 + ((int64_t)a[ 3]) * b[ 1]
wolfSSL 14:167253f4e170 216 + ((int64_t)a[ 4]) * b[ 0];
wolfSSL 14:167253f4e170 217 int64_t t5 = ((int64_t)a[ 0]) * b[ 5]
wolfSSL 14:167253f4e170 218 + ((int64_t)a[ 1]) * b[ 4]
wolfSSL 14:167253f4e170 219 + ((int64_t)a[ 2]) * b[ 3]
wolfSSL 14:167253f4e170 220 + ((int64_t)a[ 3]) * b[ 2]
wolfSSL 14:167253f4e170 221 + ((int64_t)a[ 4]) * b[ 1]
wolfSSL 14:167253f4e170 222 + ((int64_t)a[ 5]) * b[ 0];
wolfSSL 14:167253f4e170 223 int64_t t6 = ((int64_t)a[ 0]) * b[ 6]
wolfSSL 14:167253f4e170 224 + ((int64_t)a[ 1]) * b[ 5]
wolfSSL 14:167253f4e170 225 + ((int64_t)a[ 2]) * b[ 4]
wolfSSL 14:167253f4e170 226 + ((int64_t)a[ 3]) * b[ 3]
wolfSSL 14:167253f4e170 227 + ((int64_t)a[ 4]) * b[ 2]
wolfSSL 14:167253f4e170 228 + ((int64_t)a[ 5]) * b[ 1]
wolfSSL 14:167253f4e170 229 + ((int64_t)a[ 6]) * b[ 0];
wolfSSL 14:167253f4e170 230 int64_t t7 = ((int64_t)a[ 0]) * b[ 7]
wolfSSL 14:167253f4e170 231 + ((int64_t)a[ 1]) * b[ 6]
wolfSSL 14:167253f4e170 232 + ((int64_t)a[ 2]) * b[ 5]
wolfSSL 14:167253f4e170 233 + ((int64_t)a[ 3]) * b[ 4]
wolfSSL 14:167253f4e170 234 + ((int64_t)a[ 4]) * b[ 3]
wolfSSL 14:167253f4e170 235 + ((int64_t)a[ 5]) * b[ 2]
wolfSSL 14:167253f4e170 236 + ((int64_t)a[ 6]) * b[ 1]
wolfSSL 14:167253f4e170 237 + ((int64_t)a[ 7]) * b[ 0];
wolfSSL 14:167253f4e170 238 int64_t t8 = ((int64_t)a[ 0]) * b[ 8]
wolfSSL 14:167253f4e170 239 + ((int64_t)a[ 1]) * b[ 7]
wolfSSL 14:167253f4e170 240 + ((int64_t)a[ 2]) * b[ 6]
wolfSSL 14:167253f4e170 241 + ((int64_t)a[ 3]) * b[ 5]
wolfSSL 14:167253f4e170 242 + ((int64_t)a[ 4]) * b[ 4]
wolfSSL 14:167253f4e170 243 + ((int64_t)a[ 5]) * b[ 3]
wolfSSL 14:167253f4e170 244 + ((int64_t)a[ 6]) * b[ 2]
wolfSSL 14:167253f4e170 245 + ((int64_t)a[ 7]) * b[ 1]
wolfSSL 14:167253f4e170 246 + ((int64_t)a[ 8]) * b[ 0];
wolfSSL 14:167253f4e170 247 int64_t t9 = ((int64_t)a[ 0]) * b[ 9]
wolfSSL 14:167253f4e170 248 + ((int64_t)a[ 1]) * b[ 8]
wolfSSL 14:167253f4e170 249 + ((int64_t)a[ 2]) * b[ 7]
wolfSSL 14:167253f4e170 250 + ((int64_t)a[ 3]) * b[ 6]
wolfSSL 14:167253f4e170 251 + ((int64_t)a[ 4]) * b[ 5]
wolfSSL 14:167253f4e170 252 + ((int64_t)a[ 5]) * b[ 4]
wolfSSL 14:167253f4e170 253 + ((int64_t)a[ 6]) * b[ 3]
wolfSSL 14:167253f4e170 254 + ((int64_t)a[ 7]) * b[ 2]
wolfSSL 14:167253f4e170 255 + ((int64_t)a[ 8]) * b[ 1]
wolfSSL 14:167253f4e170 256 + ((int64_t)a[ 9]) * b[ 0];
wolfSSL 14:167253f4e170 257 int64_t t10 = ((int64_t)a[ 0]) * b[10]
wolfSSL 14:167253f4e170 258 + ((int64_t)a[ 1]) * b[ 9]
wolfSSL 14:167253f4e170 259 + ((int64_t)a[ 2]) * b[ 8]
wolfSSL 14:167253f4e170 260 + ((int64_t)a[ 3]) * b[ 7]
wolfSSL 14:167253f4e170 261 + ((int64_t)a[ 4]) * b[ 6]
wolfSSL 14:167253f4e170 262 + ((int64_t)a[ 5]) * b[ 5]
wolfSSL 14:167253f4e170 263 + ((int64_t)a[ 6]) * b[ 4]
wolfSSL 14:167253f4e170 264 + ((int64_t)a[ 7]) * b[ 3]
wolfSSL 14:167253f4e170 265 + ((int64_t)a[ 8]) * b[ 2]
wolfSSL 14:167253f4e170 266 + ((int64_t)a[ 9]) * b[ 1]
wolfSSL 14:167253f4e170 267 + ((int64_t)a[10]) * b[ 0];
wolfSSL 14:167253f4e170 268 int64_t t11 = ((int64_t)a[ 0]) * b[11]
wolfSSL 14:167253f4e170 269 + ((int64_t)a[ 1]) * b[10]
wolfSSL 14:167253f4e170 270 + ((int64_t)a[ 2]) * b[ 9]
wolfSSL 14:167253f4e170 271 + ((int64_t)a[ 3]) * b[ 8]
wolfSSL 14:167253f4e170 272 + ((int64_t)a[ 4]) * b[ 7]
wolfSSL 14:167253f4e170 273 + ((int64_t)a[ 5]) * b[ 6]
wolfSSL 14:167253f4e170 274 + ((int64_t)a[ 6]) * b[ 5]
wolfSSL 14:167253f4e170 275 + ((int64_t)a[ 7]) * b[ 4]
wolfSSL 14:167253f4e170 276 + ((int64_t)a[ 8]) * b[ 3]
wolfSSL 14:167253f4e170 277 + ((int64_t)a[ 9]) * b[ 2]
wolfSSL 14:167253f4e170 278 + ((int64_t)a[10]) * b[ 1]
wolfSSL 14:167253f4e170 279 + ((int64_t)a[11]) * b[ 0];
wolfSSL 14:167253f4e170 280 int64_t t12 = ((int64_t)a[ 0]) * b[12]
wolfSSL 14:167253f4e170 281 + ((int64_t)a[ 1]) * b[11]
wolfSSL 14:167253f4e170 282 + ((int64_t)a[ 2]) * b[10]
wolfSSL 14:167253f4e170 283 + ((int64_t)a[ 3]) * b[ 9]
wolfSSL 14:167253f4e170 284 + ((int64_t)a[ 4]) * b[ 8]
wolfSSL 14:167253f4e170 285 + ((int64_t)a[ 5]) * b[ 7]
wolfSSL 14:167253f4e170 286 + ((int64_t)a[ 6]) * b[ 6]
wolfSSL 14:167253f4e170 287 + ((int64_t)a[ 7]) * b[ 5]
wolfSSL 14:167253f4e170 288 + ((int64_t)a[ 8]) * b[ 4]
wolfSSL 14:167253f4e170 289 + ((int64_t)a[ 9]) * b[ 3]
wolfSSL 14:167253f4e170 290 + ((int64_t)a[10]) * b[ 2]
wolfSSL 14:167253f4e170 291 + ((int64_t)a[11]) * b[ 1]
wolfSSL 14:167253f4e170 292 + ((int64_t)a[12]) * b[ 0];
wolfSSL 14:167253f4e170 293 int64_t t13 = ((int64_t)a[ 0]) * b[13]
wolfSSL 14:167253f4e170 294 + ((int64_t)a[ 1]) * b[12]
wolfSSL 14:167253f4e170 295 + ((int64_t)a[ 2]) * b[11]
wolfSSL 14:167253f4e170 296 + ((int64_t)a[ 3]) * b[10]
wolfSSL 14:167253f4e170 297 + ((int64_t)a[ 4]) * b[ 9]
wolfSSL 14:167253f4e170 298 + ((int64_t)a[ 5]) * b[ 8]
wolfSSL 14:167253f4e170 299 + ((int64_t)a[ 6]) * b[ 7]
wolfSSL 14:167253f4e170 300 + ((int64_t)a[ 7]) * b[ 6]
wolfSSL 14:167253f4e170 301 + ((int64_t)a[ 8]) * b[ 5]
wolfSSL 14:167253f4e170 302 + ((int64_t)a[ 9]) * b[ 4]
wolfSSL 14:167253f4e170 303 + ((int64_t)a[10]) * b[ 3]
wolfSSL 14:167253f4e170 304 + ((int64_t)a[11]) * b[ 2]
wolfSSL 14:167253f4e170 305 + ((int64_t)a[12]) * b[ 1]
wolfSSL 14:167253f4e170 306 + ((int64_t)a[13]) * b[ 0];
wolfSSL 14:167253f4e170 307 int64_t t14 = ((int64_t)a[ 0]) * b[14]
wolfSSL 14:167253f4e170 308 + ((int64_t)a[ 1]) * b[13]
wolfSSL 14:167253f4e170 309 + ((int64_t)a[ 2]) * b[12]
wolfSSL 14:167253f4e170 310 + ((int64_t)a[ 3]) * b[11]
wolfSSL 14:167253f4e170 311 + ((int64_t)a[ 4]) * b[10]
wolfSSL 14:167253f4e170 312 + ((int64_t)a[ 5]) * b[ 9]
wolfSSL 14:167253f4e170 313 + ((int64_t)a[ 6]) * b[ 8]
wolfSSL 14:167253f4e170 314 + ((int64_t)a[ 7]) * b[ 7]
wolfSSL 14:167253f4e170 315 + ((int64_t)a[ 8]) * b[ 6]
wolfSSL 14:167253f4e170 316 + ((int64_t)a[ 9]) * b[ 5]
wolfSSL 14:167253f4e170 317 + ((int64_t)a[10]) * b[ 4]
wolfSSL 14:167253f4e170 318 + ((int64_t)a[11]) * b[ 3]
wolfSSL 14:167253f4e170 319 + ((int64_t)a[12]) * b[ 2]
wolfSSL 14:167253f4e170 320 + ((int64_t)a[13]) * b[ 1]
wolfSSL 14:167253f4e170 321 + ((int64_t)a[14]) * b[ 0];
wolfSSL 14:167253f4e170 322 int64_t t15 = ((int64_t)a[ 1]) * b[14]
wolfSSL 14:167253f4e170 323 + ((int64_t)a[ 2]) * b[13]
wolfSSL 14:167253f4e170 324 + ((int64_t)a[ 3]) * b[12]
wolfSSL 14:167253f4e170 325 + ((int64_t)a[ 4]) * b[11]
wolfSSL 14:167253f4e170 326 + ((int64_t)a[ 5]) * b[10]
wolfSSL 14:167253f4e170 327 + ((int64_t)a[ 6]) * b[ 9]
wolfSSL 14:167253f4e170 328 + ((int64_t)a[ 7]) * b[ 8]
wolfSSL 14:167253f4e170 329 + ((int64_t)a[ 8]) * b[ 7]
wolfSSL 14:167253f4e170 330 + ((int64_t)a[ 9]) * b[ 6]
wolfSSL 14:167253f4e170 331 + ((int64_t)a[10]) * b[ 5]
wolfSSL 14:167253f4e170 332 + ((int64_t)a[11]) * b[ 4]
wolfSSL 14:167253f4e170 333 + ((int64_t)a[12]) * b[ 3]
wolfSSL 14:167253f4e170 334 + ((int64_t)a[13]) * b[ 2]
wolfSSL 14:167253f4e170 335 + ((int64_t)a[14]) * b[ 1];
wolfSSL 14:167253f4e170 336 int64_t t16 = ((int64_t)a[ 2]) * b[14]
wolfSSL 14:167253f4e170 337 + ((int64_t)a[ 3]) * b[13]
wolfSSL 14:167253f4e170 338 + ((int64_t)a[ 4]) * b[12]
wolfSSL 14:167253f4e170 339 + ((int64_t)a[ 5]) * b[11]
wolfSSL 14:167253f4e170 340 + ((int64_t)a[ 6]) * b[10]
wolfSSL 14:167253f4e170 341 + ((int64_t)a[ 7]) * b[ 9]
wolfSSL 14:167253f4e170 342 + ((int64_t)a[ 8]) * b[ 8]
wolfSSL 14:167253f4e170 343 + ((int64_t)a[ 9]) * b[ 7]
wolfSSL 14:167253f4e170 344 + ((int64_t)a[10]) * b[ 6]
wolfSSL 14:167253f4e170 345 + ((int64_t)a[11]) * b[ 5]
wolfSSL 14:167253f4e170 346 + ((int64_t)a[12]) * b[ 4]
wolfSSL 14:167253f4e170 347 + ((int64_t)a[13]) * b[ 3]
wolfSSL 14:167253f4e170 348 + ((int64_t)a[14]) * b[ 2];
wolfSSL 14:167253f4e170 349 int64_t t17 = ((int64_t)a[ 3]) * b[14]
wolfSSL 14:167253f4e170 350 + ((int64_t)a[ 4]) * b[13]
wolfSSL 14:167253f4e170 351 + ((int64_t)a[ 5]) * b[12]
wolfSSL 14:167253f4e170 352 + ((int64_t)a[ 6]) * b[11]
wolfSSL 14:167253f4e170 353 + ((int64_t)a[ 7]) * b[10]
wolfSSL 14:167253f4e170 354 + ((int64_t)a[ 8]) * b[ 9]
wolfSSL 14:167253f4e170 355 + ((int64_t)a[ 9]) * b[ 8]
wolfSSL 14:167253f4e170 356 + ((int64_t)a[10]) * b[ 7]
wolfSSL 14:167253f4e170 357 + ((int64_t)a[11]) * b[ 6]
wolfSSL 14:167253f4e170 358 + ((int64_t)a[12]) * b[ 5]
wolfSSL 14:167253f4e170 359 + ((int64_t)a[13]) * b[ 4]
wolfSSL 14:167253f4e170 360 + ((int64_t)a[14]) * b[ 3];
wolfSSL 14:167253f4e170 361 int64_t t18 = ((int64_t)a[ 4]) * b[14]
wolfSSL 14:167253f4e170 362 + ((int64_t)a[ 5]) * b[13]
wolfSSL 14:167253f4e170 363 + ((int64_t)a[ 6]) * b[12]
wolfSSL 14:167253f4e170 364 + ((int64_t)a[ 7]) * b[11]
wolfSSL 14:167253f4e170 365 + ((int64_t)a[ 8]) * b[10]
wolfSSL 14:167253f4e170 366 + ((int64_t)a[ 9]) * b[ 9]
wolfSSL 14:167253f4e170 367 + ((int64_t)a[10]) * b[ 8]
wolfSSL 14:167253f4e170 368 + ((int64_t)a[11]) * b[ 7]
wolfSSL 14:167253f4e170 369 + ((int64_t)a[12]) * b[ 6]
wolfSSL 14:167253f4e170 370 + ((int64_t)a[13]) * b[ 5]
wolfSSL 14:167253f4e170 371 + ((int64_t)a[14]) * b[ 4];
wolfSSL 14:167253f4e170 372 int64_t t19 = ((int64_t)a[ 5]) * b[14]
wolfSSL 14:167253f4e170 373 + ((int64_t)a[ 6]) * b[13]
wolfSSL 14:167253f4e170 374 + ((int64_t)a[ 7]) * b[12]
wolfSSL 14:167253f4e170 375 + ((int64_t)a[ 8]) * b[11]
wolfSSL 14:167253f4e170 376 + ((int64_t)a[ 9]) * b[10]
wolfSSL 14:167253f4e170 377 + ((int64_t)a[10]) * b[ 9]
wolfSSL 14:167253f4e170 378 + ((int64_t)a[11]) * b[ 8]
wolfSSL 14:167253f4e170 379 + ((int64_t)a[12]) * b[ 7]
wolfSSL 14:167253f4e170 380 + ((int64_t)a[13]) * b[ 6]
wolfSSL 14:167253f4e170 381 + ((int64_t)a[14]) * b[ 5];
wolfSSL 14:167253f4e170 382 int64_t t20 = ((int64_t)a[ 6]) * b[14]
wolfSSL 14:167253f4e170 383 + ((int64_t)a[ 7]) * b[13]
wolfSSL 14:167253f4e170 384 + ((int64_t)a[ 8]) * b[12]
wolfSSL 14:167253f4e170 385 + ((int64_t)a[ 9]) * b[11]
wolfSSL 14:167253f4e170 386 + ((int64_t)a[10]) * b[10]
wolfSSL 14:167253f4e170 387 + ((int64_t)a[11]) * b[ 9]
wolfSSL 14:167253f4e170 388 + ((int64_t)a[12]) * b[ 8]
wolfSSL 14:167253f4e170 389 + ((int64_t)a[13]) * b[ 7]
wolfSSL 14:167253f4e170 390 + ((int64_t)a[14]) * b[ 6];
wolfSSL 14:167253f4e170 391 int64_t t21 = ((int64_t)a[ 7]) * b[14]
wolfSSL 14:167253f4e170 392 + ((int64_t)a[ 8]) * b[13]
wolfSSL 14:167253f4e170 393 + ((int64_t)a[ 9]) * b[12]
wolfSSL 14:167253f4e170 394 + ((int64_t)a[10]) * b[11]
wolfSSL 14:167253f4e170 395 + ((int64_t)a[11]) * b[10]
wolfSSL 14:167253f4e170 396 + ((int64_t)a[12]) * b[ 9]
wolfSSL 14:167253f4e170 397 + ((int64_t)a[13]) * b[ 8]
wolfSSL 14:167253f4e170 398 + ((int64_t)a[14]) * b[ 7];
wolfSSL 14:167253f4e170 399 int64_t t22 = ((int64_t)a[ 8]) * b[14]
wolfSSL 14:167253f4e170 400 + ((int64_t)a[ 9]) * b[13]
wolfSSL 14:167253f4e170 401 + ((int64_t)a[10]) * b[12]
wolfSSL 14:167253f4e170 402 + ((int64_t)a[11]) * b[11]
wolfSSL 14:167253f4e170 403 + ((int64_t)a[12]) * b[10]
wolfSSL 14:167253f4e170 404 + ((int64_t)a[13]) * b[ 9]
wolfSSL 14:167253f4e170 405 + ((int64_t)a[14]) * b[ 8];
wolfSSL 14:167253f4e170 406 int64_t t23 = ((int64_t)a[ 9]) * b[14]
wolfSSL 14:167253f4e170 407 + ((int64_t)a[10]) * b[13]
wolfSSL 14:167253f4e170 408 + ((int64_t)a[11]) * b[12]
wolfSSL 14:167253f4e170 409 + ((int64_t)a[12]) * b[11]
wolfSSL 14:167253f4e170 410 + ((int64_t)a[13]) * b[10]
wolfSSL 14:167253f4e170 411 + ((int64_t)a[14]) * b[ 9];
wolfSSL 14:167253f4e170 412 int64_t t24 = ((int64_t)a[10]) * b[14]
wolfSSL 14:167253f4e170 413 + ((int64_t)a[11]) * b[13]
wolfSSL 14:167253f4e170 414 + ((int64_t)a[12]) * b[12]
wolfSSL 14:167253f4e170 415 + ((int64_t)a[13]) * b[11]
wolfSSL 14:167253f4e170 416 + ((int64_t)a[14]) * b[10];
wolfSSL 14:167253f4e170 417 int64_t t25 = ((int64_t)a[11]) * b[14]
wolfSSL 14:167253f4e170 418 + ((int64_t)a[12]) * b[13]
wolfSSL 14:167253f4e170 419 + ((int64_t)a[13]) * b[12]
wolfSSL 14:167253f4e170 420 + ((int64_t)a[14]) * b[11];
wolfSSL 14:167253f4e170 421 int64_t t26 = ((int64_t)a[12]) * b[14]
wolfSSL 14:167253f4e170 422 + ((int64_t)a[13]) * b[13]
wolfSSL 14:167253f4e170 423 + ((int64_t)a[14]) * b[12];
wolfSSL 14:167253f4e170 424 int64_t t27 = ((int64_t)a[13]) * b[14]
wolfSSL 14:167253f4e170 425 + ((int64_t)a[14]) * b[13];
wolfSSL 14:167253f4e170 426 int64_t t28 = ((int64_t)a[14]) * b[14];
wolfSSL 14:167253f4e170 427
wolfSSL 14:167253f4e170 428 t1 += t0 >> 23; r[ 0] = t0 & 0x7fffff;
wolfSSL 14:167253f4e170 429 t2 += t1 >> 23; r[ 1] = t1 & 0x7fffff;
wolfSSL 14:167253f4e170 430 t3 += t2 >> 23; r[ 2] = t2 & 0x7fffff;
wolfSSL 14:167253f4e170 431 t4 += t3 >> 23; r[ 3] = t3 & 0x7fffff;
wolfSSL 14:167253f4e170 432 t5 += t4 >> 23; r[ 4] = t4 & 0x7fffff;
wolfSSL 14:167253f4e170 433 t6 += t5 >> 23; r[ 5] = t5 & 0x7fffff;
wolfSSL 14:167253f4e170 434 t7 += t6 >> 23; r[ 6] = t6 & 0x7fffff;
wolfSSL 14:167253f4e170 435 t8 += t7 >> 23; r[ 7] = t7 & 0x7fffff;
wolfSSL 14:167253f4e170 436 t9 += t8 >> 23; r[ 8] = t8 & 0x7fffff;
wolfSSL 14:167253f4e170 437 t10 += t9 >> 23; r[ 9] = t9 & 0x7fffff;
wolfSSL 14:167253f4e170 438 t11 += t10 >> 23; r[10] = t10 & 0x7fffff;
wolfSSL 14:167253f4e170 439 t12 += t11 >> 23; r[11] = t11 & 0x7fffff;
wolfSSL 14:167253f4e170 440 t13 += t12 >> 23; r[12] = t12 & 0x7fffff;
wolfSSL 14:167253f4e170 441 t14 += t13 >> 23; r[13] = t13 & 0x7fffff;
wolfSSL 14:167253f4e170 442 t15 += t14 >> 23; r[14] = t14 & 0x7fffff;
wolfSSL 14:167253f4e170 443 t16 += t15 >> 23; r[15] = t15 & 0x7fffff;
wolfSSL 14:167253f4e170 444 t17 += t16 >> 23; r[16] = t16 & 0x7fffff;
wolfSSL 14:167253f4e170 445 t18 += t17 >> 23; r[17] = t17 & 0x7fffff;
wolfSSL 14:167253f4e170 446 t19 += t18 >> 23; r[18] = t18 & 0x7fffff;
wolfSSL 14:167253f4e170 447 t20 += t19 >> 23; r[19] = t19 & 0x7fffff;
wolfSSL 14:167253f4e170 448 t21 += t20 >> 23; r[20] = t20 & 0x7fffff;
wolfSSL 14:167253f4e170 449 t22 += t21 >> 23; r[21] = t21 & 0x7fffff;
wolfSSL 14:167253f4e170 450 t23 += t22 >> 23; r[22] = t22 & 0x7fffff;
wolfSSL 14:167253f4e170 451 t24 += t23 >> 23; r[23] = t23 & 0x7fffff;
wolfSSL 14:167253f4e170 452 t25 += t24 >> 23; r[24] = t24 & 0x7fffff;
wolfSSL 14:167253f4e170 453 t26 += t25 >> 23; r[25] = t25 & 0x7fffff;
wolfSSL 14:167253f4e170 454 t27 += t26 >> 23; r[26] = t26 & 0x7fffff;
wolfSSL 14:167253f4e170 455 t28 += t27 >> 23; r[27] = t27 & 0x7fffff;
wolfSSL 14:167253f4e170 456 r[29] = (sp_digit)(t28 >> 23);
wolfSSL 14:167253f4e170 457 r[28] = t28 & 0x7fffff;
wolfSSL 14:167253f4e170 458 }
wolfSSL 14:167253f4e170 459
wolfSSL 14:167253f4e170 460 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 461 *
wolfSSL 14:167253f4e170 462 * r A single precision integer.
wolfSSL 14:167253f4e170 463 * a A single precision integer.
wolfSSL 14:167253f4e170 464 */
wolfSSL 14:167253f4e170 465 SP_NOINLINE static void sp_2048_sqr_15(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 466 {
wolfSSL 14:167253f4e170 467 int64_t t0 = ((int64_t)a[ 0]) * a[ 0];
wolfSSL 14:167253f4e170 468 int64_t t1 = (((int64_t)a[ 0]) * a[ 1]) * 2;
wolfSSL 14:167253f4e170 469 int64_t t2 = (((int64_t)a[ 0]) * a[ 2]) * 2
wolfSSL 14:167253f4e170 470 + ((int64_t)a[ 1]) * a[ 1];
wolfSSL 14:167253f4e170 471 int64_t t3 = (((int64_t)a[ 0]) * a[ 3]
wolfSSL 14:167253f4e170 472 + ((int64_t)a[ 1]) * a[ 2]) * 2;
wolfSSL 14:167253f4e170 473 int64_t t4 = (((int64_t)a[ 0]) * a[ 4]
wolfSSL 14:167253f4e170 474 + ((int64_t)a[ 1]) * a[ 3]) * 2
wolfSSL 14:167253f4e170 475 + ((int64_t)a[ 2]) * a[ 2];
wolfSSL 14:167253f4e170 476 int64_t t5 = (((int64_t)a[ 0]) * a[ 5]
wolfSSL 14:167253f4e170 477 + ((int64_t)a[ 1]) * a[ 4]
wolfSSL 14:167253f4e170 478 + ((int64_t)a[ 2]) * a[ 3]) * 2;
wolfSSL 14:167253f4e170 479 int64_t t6 = (((int64_t)a[ 0]) * a[ 6]
wolfSSL 14:167253f4e170 480 + ((int64_t)a[ 1]) * a[ 5]
wolfSSL 14:167253f4e170 481 + ((int64_t)a[ 2]) * a[ 4]) * 2
wolfSSL 14:167253f4e170 482 + ((int64_t)a[ 3]) * a[ 3];
wolfSSL 14:167253f4e170 483 int64_t t7 = (((int64_t)a[ 0]) * a[ 7]
wolfSSL 14:167253f4e170 484 + ((int64_t)a[ 1]) * a[ 6]
wolfSSL 14:167253f4e170 485 + ((int64_t)a[ 2]) * a[ 5]
wolfSSL 14:167253f4e170 486 + ((int64_t)a[ 3]) * a[ 4]) * 2;
wolfSSL 14:167253f4e170 487 int64_t t8 = (((int64_t)a[ 0]) * a[ 8]
wolfSSL 14:167253f4e170 488 + ((int64_t)a[ 1]) * a[ 7]
wolfSSL 14:167253f4e170 489 + ((int64_t)a[ 2]) * a[ 6]
wolfSSL 14:167253f4e170 490 + ((int64_t)a[ 3]) * a[ 5]) * 2
wolfSSL 14:167253f4e170 491 + ((int64_t)a[ 4]) * a[ 4];
wolfSSL 14:167253f4e170 492 int64_t t9 = (((int64_t)a[ 0]) * a[ 9]
wolfSSL 14:167253f4e170 493 + ((int64_t)a[ 1]) * a[ 8]
wolfSSL 14:167253f4e170 494 + ((int64_t)a[ 2]) * a[ 7]
wolfSSL 14:167253f4e170 495 + ((int64_t)a[ 3]) * a[ 6]
wolfSSL 14:167253f4e170 496 + ((int64_t)a[ 4]) * a[ 5]) * 2;
wolfSSL 14:167253f4e170 497 int64_t t10 = (((int64_t)a[ 0]) * a[10]
wolfSSL 14:167253f4e170 498 + ((int64_t)a[ 1]) * a[ 9]
wolfSSL 14:167253f4e170 499 + ((int64_t)a[ 2]) * a[ 8]
wolfSSL 14:167253f4e170 500 + ((int64_t)a[ 3]) * a[ 7]
wolfSSL 14:167253f4e170 501 + ((int64_t)a[ 4]) * a[ 6]) * 2
wolfSSL 14:167253f4e170 502 + ((int64_t)a[ 5]) * a[ 5];
wolfSSL 14:167253f4e170 503 int64_t t11 = (((int64_t)a[ 0]) * a[11]
wolfSSL 14:167253f4e170 504 + ((int64_t)a[ 1]) * a[10]
wolfSSL 14:167253f4e170 505 + ((int64_t)a[ 2]) * a[ 9]
wolfSSL 14:167253f4e170 506 + ((int64_t)a[ 3]) * a[ 8]
wolfSSL 14:167253f4e170 507 + ((int64_t)a[ 4]) * a[ 7]
wolfSSL 14:167253f4e170 508 + ((int64_t)a[ 5]) * a[ 6]) * 2;
wolfSSL 14:167253f4e170 509 int64_t t12 = (((int64_t)a[ 0]) * a[12]
wolfSSL 14:167253f4e170 510 + ((int64_t)a[ 1]) * a[11]
wolfSSL 14:167253f4e170 511 + ((int64_t)a[ 2]) * a[10]
wolfSSL 14:167253f4e170 512 + ((int64_t)a[ 3]) * a[ 9]
wolfSSL 14:167253f4e170 513 + ((int64_t)a[ 4]) * a[ 8]
wolfSSL 14:167253f4e170 514 + ((int64_t)a[ 5]) * a[ 7]) * 2
wolfSSL 14:167253f4e170 515 + ((int64_t)a[ 6]) * a[ 6];
wolfSSL 14:167253f4e170 516 int64_t t13 = (((int64_t)a[ 0]) * a[13]
wolfSSL 14:167253f4e170 517 + ((int64_t)a[ 1]) * a[12]
wolfSSL 14:167253f4e170 518 + ((int64_t)a[ 2]) * a[11]
wolfSSL 14:167253f4e170 519 + ((int64_t)a[ 3]) * a[10]
wolfSSL 14:167253f4e170 520 + ((int64_t)a[ 4]) * a[ 9]
wolfSSL 14:167253f4e170 521 + ((int64_t)a[ 5]) * a[ 8]
wolfSSL 14:167253f4e170 522 + ((int64_t)a[ 6]) * a[ 7]) * 2;
wolfSSL 14:167253f4e170 523 int64_t t14 = (((int64_t)a[ 0]) * a[14]
wolfSSL 14:167253f4e170 524 + ((int64_t)a[ 1]) * a[13]
wolfSSL 14:167253f4e170 525 + ((int64_t)a[ 2]) * a[12]
wolfSSL 14:167253f4e170 526 + ((int64_t)a[ 3]) * a[11]
wolfSSL 14:167253f4e170 527 + ((int64_t)a[ 4]) * a[10]
wolfSSL 14:167253f4e170 528 + ((int64_t)a[ 5]) * a[ 9]
wolfSSL 14:167253f4e170 529 + ((int64_t)a[ 6]) * a[ 8]) * 2
wolfSSL 14:167253f4e170 530 + ((int64_t)a[ 7]) * a[ 7];
wolfSSL 14:167253f4e170 531 int64_t t15 = (((int64_t)a[ 1]) * a[14]
wolfSSL 14:167253f4e170 532 + ((int64_t)a[ 2]) * a[13]
wolfSSL 14:167253f4e170 533 + ((int64_t)a[ 3]) * a[12]
wolfSSL 14:167253f4e170 534 + ((int64_t)a[ 4]) * a[11]
wolfSSL 14:167253f4e170 535 + ((int64_t)a[ 5]) * a[10]
wolfSSL 14:167253f4e170 536 + ((int64_t)a[ 6]) * a[ 9]
wolfSSL 14:167253f4e170 537 + ((int64_t)a[ 7]) * a[ 8]) * 2;
wolfSSL 14:167253f4e170 538 int64_t t16 = (((int64_t)a[ 2]) * a[14]
wolfSSL 14:167253f4e170 539 + ((int64_t)a[ 3]) * a[13]
wolfSSL 14:167253f4e170 540 + ((int64_t)a[ 4]) * a[12]
wolfSSL 14:167253f4e170 541 + ((int64_t)a[ 5]) * a[11]
wolfSSL 14:167253f4e170 542 + ((int64_t)a[ 6]) * a[10]
wolfSSL 14:167253f4e170 543 + ((int64_t)a[ 7]) * a[ 9]) * 2
wolfSSL 14:167253f4e170 544 + ((int64_t)a[ 8]) * a[ 8];
wolfSSL 14:167253f4e170 545 int64_t t17 = (((int64_t)a[ 3]) * a[14]
wolfSSL 14:167253f4e170 546 + ((int64_t)a[ 4]) * a[13]
wolfSSL 14:167253f4e170 547 + ((int64_t)a[ 5]) * a[12]
wolfSSL 14:167253f4e170 548 + ((int64_t)a[ 6]) * a[11]
wolfSSL 14:167253f4e170 549 + ((int64_t)a[ 7]) * a[10]
wolfSSL 14:167253f4e170 550 + ((int64_t)a[ 8]) * a[ 9]) * 2;
wolfSSL 14:167253f4e170 551 int64_t t18 = (((int64_t)a[ 4]) * a[14]
wolfSSL 14:167253f4e170 552 + ((int64_t)a[ 5]) * a[13]
wolfSSL 14:167253f4e170 553 + ((int64_t)a[ 6]) * a[12]
wolfSSL 14:167253f4e170 554 + ((int64_t)a[ 7]) * a[11]
wolfSSL 14:167253f4e170 555 + ((int64_t)a[ 8]) * a[10]) * 2
wolfSSL 14:167253f4e170 556 + ((int64_t)a[ 9]) * a[ 9];
wolfSSL 14:167253f4e170 557 int64_t t19 = (((int64_t)a[ 5]) * a[14]
wolfSSL 14:167253f4e170 558 + ((int64_t)a[ 6]) * a[13]
wolfSSL 14:167253f4e170 559 + ((int64_t)a[ 7]) * a[12]
wolfSSL 14:167253f4e170 560 + ((int64_t)a[ 8]) * a[11]
wolfSSL 14:167253f4e170 561 + ((int64_t)a[ 9]) * a[10]) * 2;
wolfSSL 14:167253f4e170 562 int64_t t20 = (((int64_t)a[ 6]) * a[14]
wolfSSL 14:167253f4e170 563 + ((int64_t)a[ 7]) * a[13]
wolfSSL 14:167253f4e170 564 + ((int64_t)a[ 8]) * a[12]
wolfSSL 14:167253f4e170 565 + ((int64_t)a[ 9]) * a[11]) * 2
wolfSSL 14:167253f4e170 566 + ((int64_t)a[10]) * a[10];
wolfSSL 14:167253f4e170 567 int64_t t21 = (((int64_t)a[ 7]) * a[14]
wolfSSL 14:167253f4e170 568 + ((int64_t)a[ 8]) * a[13]
wolfSSL 14:167253f4e170 569 + ((int64_t)a[ 9]) * a[12]
wolfSSL 14:167253f4e170 570 + ((int64_t)a[10]) * a[11]) * 2;
wolfSSL 14:167253f4e170 571 int64_t t22 = (((int64_t)a[ 8]) * a[14]
wolfSSL 14:167253f4e170 572 + ((int64_t)a[ 9]) * a[13]
wolfSSL 14:167253f4e170 573 + ((int64_t)a[10]) * a[12]) * 2
wolfSSL 14:167253f4e170 574 + ((int64_t)a[11]) * a[11];
wolfSSL 14:167253f4e170 575 int64_t t23 = (((int64_t)a[ 9]) * a[14]
wolfSSL 14:167253f4e170 576 + ((int64_t)a[10]) * a[13]
wolfSSL 14:167253f4e170 577 + ((int64_t)a[11]) * a[12]) * 2;
wolfSSL 14:167253f4e170 578 int64_t t24 = (((int64_t)a[10]) * a[14]
wolfSSL 14:167253f4e170 579 + ((int64_t)a[11]) * a[13]) * 2
wolfSSL 14:167253f4e170 580 + ((int64_t)a[12]) * a[12];
wolfSSL 14:167253f4e170 581 int64_t t25 = (((int64_t)a[11]) * a[14]
wolfSSL 14:167253f4e170 582 + ((int64_t)a[12]) * a[13]) * 2;
wolfSSL 14:167253f4e170 583 int64_t t26 = (((int64_t)a[12]) * a[14]) * 2
wolfSSL 14:167253f4e170 584 + ((int64_t)a[13]) * a[13];
wolfSSL 14:167253f4e170 585 int64_t t27 = (((int64_t)a[13]) * a[14]) * 2;
wolfSSL 14:167253f4e170 586 int64_t t28 = ((int64_t)a[14]) * a[14];
wolfSSL 14:167253f4e170 587
wolfSSL 14:167253f4e170 588 t1 += t0 >> 23; r[ 0] = t0 & 0x7fffff;
wolfSSL 14:167253f4e170 589 t2 += t1 >> 23; r[ 1] = t1 & 0x7fffff;
wolfSSL 14:167253f4e170 590 t3 += t2 >> 23; r[ 2] = t2 & 0x7fffff;
wolfSSL 14:167253f4e170 591 t4 += t3 >> 23; r[ 3] = t3 & 0x7fffff;
wolfSSL 14:167253f4e170 592 t5 += t4 >> 23; r[ 4] = t4 & 0x7fffff;
wolfSSL 14:167253f4e170 593 t6 += t5 >> 23; r[ 5] = t5 & 0x7fffff;
wolfSSL 14:167253f4e170 594 t7 += t6 >> 23; r[ 6] = t6 & 0x7fffff;
wolfSSL 14:167253f4e170 595 t8 += t7 >> 23; r[ 7] = t7 & 0x7fffff;
wolfSSL 14:167253f4e170 596 t9 += t8 >> 23; r[ 8] = t8 & 0x7fffff;
wolfSSL 14:167253f4e170 597 t10 += t9 >> 23; r[ 9] = t9 & 0x7fffff;
wolfSSL 14:167253f4e170 598 t11 += t10 >> 23; r[10] = t10 & 0x7fffff;
wolfSSL 14:167253f4e170 599 t12 += t11 >> 23; r[11] = t11 & 0x7fffff;
wolfSSL 14:167253f4e170 600 t13 += t12 >> 23; r[12] = t12 & 0x7fffff;
wolfSSL 14:167253f4e170 601 t14 += t13 >> 23; r[13] = t13 & 0x7fffff;
wolfSSL 14:167253f4e170 602 t15 += t14 >> 23; r[14] = t14 & 0x7fffff;
wolfSSL 14:167253f4e170 603 t16 += t15 >> 23; r[15] = t15 & 0x7fffff;
wolfSSL 14:167253f4e170 604 t17 += t16 >> 23; r[16] = t16 & 0x7fffff;
wolfSSL 14:167253f4e170 605 t18 += t17 >> 23; r[17] = t17 & 0x7fffff;
wolfSSL 14:167253f4e170 606 t19 += t18 >> 23; r[18] = t18 & 0x7fffff;
wolfSSL 14:167253f4e170 607 t20 += t19 >> 23; r[19] = t19 & 0x7fffff;
wolfSSL 14:167253f4e170 608 t21 += t20 >> 23; r[20] = t20 & 0x7fffff;
wolfSSL 14:167253f4e170 609 t22 += t21 >> 23; r[21] = t21 & 0x7fffff;
wolfSSL 14:167253f4e170 610 t23 += t22 >> 23; r[22] = t22 & 0x7fffff;
wolfSSL 14:167253f4e170 611 t24 += t23 >> 23; r[23] = t23 & 0x7fffff;
wolfSSL 14:167253f4e170 612 t25 += t24 >> 23; r[24] = t24 & 0x7fffff;
wolfSSL 14:167253f4e170 613 t26 += t25 >> 23; r[25] = t25 & 0x7fffff;
wolfSSL 14:167253f4e170 614 t27 += t26 >> 23; r[26] = t26 & 0x7fffff;
wolfSSL 14:167253f4e170 615 t28 += t27 >> 23; r[27] = t27 & 0x7fffff;
wolfSSL 14:167253f4e170 616 r[29] = (sp_digit)(t28 >> 23);
wolfSSL 14:167253f4e170 617 r[28] = t28 & 0x7fffff;
wolfSSL 14:167253f4e170 618 }
wolfSSL 14:167253f4e170 619
wolfSSL 14:167253f4e170 620 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 621 *
wolfSSL 14:167253f4e170 622 * r A single precision integer.
wolfSSL 14:167253f4e170 623 * a A single precision integer.
wolfSSL 14:167253f4e170 624 * b A single precision integer.
wolfSSL 14:167253f4e170 625 */
wolfSSL 14:167253f4e170 626 SP_NOINLINE static int sp_2048_add_15(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 627 const sp_digit* b)
wolfSSL 14:167253f4e170 628 {
wolfSSL 14:167253f4e170 629 r[ 0] = a[ 0] + b[ 0];
wolfSSL 14:167253f4e170 630 r[ 1] = a[ 1] + b[ 1];
wolfSSL 14:167253f4e170 631 r[ 2] = a[ 2] + b[ 2];
wolfSSL 14:167253f4e170 632 r[ 3] = a[ 3] + b[ 3];
wolfSSL 14:167253f4e170 633 r[ 4] = a[ 4] + b[ 4];
wolfSSL 14:167253f4e170 634 r[ 5] = a[ 5] + b[ 5];
wolfSSL 14:167253f4e170 635 r[ 6] = a[ 6] + b[ 6];
wolfSSL 14:167253f4e170 636 r[ 7] = a[ 7] + b[ 7];
wolfSSL 14:167253f4e170 637 r[ 8] = a[ 8] + b[ 8];
wolfSSL 14:167253f4e170 638 r[ 9] = a[ 9] + b[ 9];
wolfSSL 14:167253f4e170 639 r[10] = a[10] + b[10];
wolfSSL 14:167253f4e170 640 r[11] = a[11] + b[11];
wolfSSL 14:167253f4e170 641 r[12] = a[12] + b[12];
wolfSSL 14:167253f4e170 642 r[13] = a[13] + b[13];
wolfSSL 14:167253f4e170 643 r[14] = a[14] + b[14];
wolfSSL 14:167253f4e170 644
wolfSSL 14:167253f4e170 645 return 0;
wolfSSL 14:167253f4e170 646 }
wolfSSL 14:167253f4e170 647
wolfSSL 14:167253f4e170 648 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 649 *
wolfSSL 14:167253f4e170 650 * r A single precision integer.
wolfSSL 14:167253f4e170 651 * a A single precision integer.
wolfSSL 14:167253f4e170 652 * b A single precision integer.
wolfSSL 14:167253f4e170 653 */
wolfSSL 14:167253f4e170 654 SP_NOINLINE static int sp_2048_sub_30(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 655 const sp_digit* b)
wolfSSL 14:167253f4e170 656 {
wolfSSL 14:167253f4e170 657 int i;
wolfSSL 14:167253f4e170 658
wolfSSL 14:167253f4e170 659 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 660 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 661 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 662 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 663 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 664 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 665 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 666 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 667 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 668 }
wolfSSL 14:167253f4e170 669 r[24] = a[24] - b[24];
wolfSSL 14:167253f4e170 670 r[25] = a[25] - b[25];
wolfSSL 14:167253f4e170 671 r[26] = a[26] - b[26];
wolfSSL 14:167253f4e170 672 r[27] = a[27] - b[27];
wolfSSL 14:167253f4e170 673 r[28] = a[28] - b[28];
wolfSSL 14:167253f4e170 674 r[29] = a[29] - b[29];
wolfSSL 14:167253f4e170 675
wolfSSL 14:167253f4e170 676 return 0;
wolfSSL 14:167253f4e170 677 }
wolfSSL 14:167253f4e170 678
wolfSSL 14:167253f4e170 679 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 680 *
wolfSSL 14:167253f4e170 681 * r A single precision integer.
wolfSSL 14:167253f4e170 682 * a A single precision integer.
wolfSSL 14:167253f4e170 683 * b A single precision integer.
wolfSSL 14:167253f4e170 684 */
wolfSSL 14:167253f4e170 685 SP_NOINLINE static int sp_2048_add_30(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 686 const sp_digit* b)
wolfSSL 14:167253f4e170 687 {
wolfSSL 14:167253f4e170 688 int i;
wolfSSL 14:167253f4e170 689
wolfSSL 14:167253f4e170 690 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 691 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 692 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 693 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 694 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 695 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 696 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 697 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 698 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 699 }
wolfSSL 14:167253f4e170 700 r[24] = a[24] + b[24];
wolfSSL 14:167253f4e170 701 r[25] = a[25] + b[25];
wolfSSL 14:167253f4e170 702 r[26] = a[26] + b[26];
wolfSSL 14:167253f4e170 703 r[27] = a[27] + b[27];
wolfSSL 14:167253f4e170 704 r[28] = a[28] + b[28];
wolfSSL 14:167253f4e170 705 r[29] = a[29] + b[29];
wolfSSL 14:167253f4e170 706
wolfSSL 14:167253f4e170 707 return 0;
wolfSSL 14:167253f4e170 708 }
wolfSSL 14:167253f4e170 709
wolfSSL 14:167253f4e170 710 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 711 *
wolfSSL 14:167253f4e170 712 * r A single precision integer.
wolfSSL 14:167253f4e170 713 * a A single precision integer.
wolfSSL 14:167253f4e170 714 * b A single precision integer.
wolfSSL 14:167253f4e170 715 */
wolfSSL 14:167253f4e170 716 SP_NOINLINE static void sp_2048_mul_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 717 const sp_digit* b)
wolfSSL 14:167253f4e170 718 {
wolfSSL 14:167253f4e170 719 sp_digit p0[30];
wolfSSL 14:167253f4e170 720 sp_digit p1[30];
wolfSSL 14:167253f4e170 721 sp_digit p2[30];
wolfSSL 14:167253f4e170 722 sp_digit p3[30];
wolfSSL 14:167253f4e170 723 sp_digit p4[30];
wolfSSL 14:167253f4e170 724 sp_digit p5[30];
wolfSSL 14:167253f4e170 725 sp_digit t0[30];
wolfSSL 14:167253f4e170 726 sp_digit t1[30];
wolfSSL 14:167253f4e170 727 sp_digit t2[30];
wolfSSL 14:167253f4e170 728 sp_digit a0[15];
wolfSSL 14:167253f4e170 729 sp_digit a1[15];
wolfSSL 14:167253f4e170 730 sp_digit a2[15];
wolfSSL 14:167253f4e170 731 sp_digit b0[15];
wolfSSL 14:167253f4e170 732 sp_digit b1[15];
wolfSSL 14:167253f4e170 733 sp_digit b2[15];
wolfSSL 14:167253f4e170 734 sp_2048_add_15(a0, a, &a[15]);
wolfSSL 14:167253f4e170 735 sp_2048_add_15(b0, b, &b[15]);
wolfSSL 14:167253f4e170 736 sp_2048_add_15(a1, &a[15], &a[30]);
wolfSSL 14:167253f4e170 737 sp_2048_add_15(b1, &b[15], &b[30]);
wolfSSL 14:167253f4e170 738 sp_2048_add_15(a2, a0, &a[30]);
wolfSSL 14:167253f4e170 739 sp_2048_add_15(b2, b0, &b[30]);
wolfSSL 14:167253f4e170 740 sp_2048_mul_15(p0, a, b);
wolfSSL 14:167253f4e170 741 sp_2048_mul_15(p2, &a[15], &b[15]);
wolfSSL 14:167253f4e170 742 sp_2048_mul_15(p4, &a[30], &b[30]);
wolfSSL 14:167253f4e170 743 sp_2048_mul_15(p1, a0, b0);
wolfSSL 14:167253f4e170 744 sp_2048_mul_15(p3, a1, b1);
wolfSSL 14:167253f4e170 745 sp_2048_mul_15(p5, a2, b2);
wolfSSL 14:167253f4e170 746 XMEMSET(r, 0, sizeof(*r)*2*45);
wolfSSL 14:167253f4e170 747 sp_2048_sub_30(t0, p3, p2);
wolfSSL 14:167253f4e170 748 sp_2048_sub_30(t1, p1, p2);
wolfSSL 14:167253f4e170 749 sp_2048_sub_30(t2, p5, t0);
wolfSSL 14:167253f4e170 750 sp_2048_sub_30(t2, t2, t1);
wolfSSL 14:167253f4e170 751 sp_2048_sub_30(t0, t0, p4);
wolfSSL 14:167253f4e170 752 sp_2048_sub_30(t1, t1, p0);
wolfSSL 14:167253f4e170 753 sp_2048_add_30(r, r, p0);
wolfSSL 14:167253f4e170 754 sp_2048_add_30(&r[15], &r[15], t1);
wolfSSL 14:167253f4e170 755 sp_2048_add_30(&r[30], &r[30], t2);
wolfSSL 14:167253f4e170 756 sp_2048_add_30(&r[45], &r[45], t0);
wolfSSL 14:167253f4e170 757 sp_2048_add_30(&r[60], &r[60], p4);
wolfSSL 14:167253f4e170 758 }
wolfSSL 14:167253f4e170 759
wolfSSL 14:167253f4e170 760 /* Square a into r. (r = a * a)
wolfSSL 14:167253f4e170 761 *
wolfSSL 14:167253f4e170 762 * r A single precision integer.
wolfSSL 14:167253f4e170 763 * a A single precision integer.
wolfSSL 14:167253f4e170 764 */
wolfSSL 14:167253f4e170 765 SP_NOINLINE static void sp_2048_sqr_45(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 766 {
wolfSSL 14:167253f4e170 767 sp_digit p0[30];
wolfSSL 14:167253f4e170 768 sp_digit p1[30];
wolfSSL 14:167253f4e170 769 sp_digit p2[30];
wolfSSL 14:167253f4e170 770 sp_digit p3[30];
wolfSSL 14:167253f4e170 771 sp_digit p4[30];
wolfSSL 14:167253f4e170 772 sp_digit p5[30];
wolfSSL 14:167253f4e170 773 sp_digit t0[30];
wolfSSL 14:167253f4e170 774 sp_digit t1[30];
wolfSSL 14:167253f4e170 775 sp_digit t2[30];
wolfSSL 14:167253f4e170 776 sp_digit a0[15];
wolfSSL 14:167253f4e170 777 sp_digit a1[15];
wolfSSL 14:167253f4e170 778 sp_digit a2[15];
wolfSSL 14:167253f4e170 779 sp_2048_add_15(a0, a, &a[15]);
wolfSSL 14:167253f4e170 780 sp_2048_add_15(a1, &a[15], &a[30]);
wolfSSL 14:167253f4e170 781 sp_2048_add_15(a2, a0, &a[30]);
wolfSSL 14:167253f4e170 782 sp_2048_sqr_15(p0, a);
wolfSSL 14:167253f4e170 783 sp_2048_sqr_15(p2, &a[15]);
wolfSSL 14:167253f4e170 784 sp_2048_sqr_15(p4, &a[30]);
wolfSSL 14:167253f4e170 785 sp_2048_sqr_15(p1, a0);
wolfSSL 14:167253f4e170 786 sp_2048_sqr_15(p3, a1);
wolfSSL 14:167253f4e170 787 sp_2048_sqr_15(p5, a2);
wolfSSL 14:167253f4e170 788 XMEMSET(r, 0, sizeof(*r)*2*45);
wolfSSL 14:167253f4e170 789 sp_2048_sub_30(t0, p3, p2);
wolfSSL 14:167253f4e170 790 sp_2048_sub_30(t1, p1, p2);
wolfSSL 14:167253f4e170 791 sp_2048_sub_30(t2, p5, t0);
wolfSSL 14:167253f4e170 792 sp_2048_sub_30(t2, t2, t1);
wolfSSL 14:167253f4e170 793 sp_2048_sub_30(t0, t0, p4);
wolfSSL 14:167253f4e170 794 sp_2048_sub_30(t1, t1, p0);
wolfSSL 14:167253f4e170 795 sp_2048_add_30(r, r, p0);
wolfSSL 14:167253f4e170 796 sp_2048_add_30(&r[15], &r[15], t1);
wolfSSL 14:167253f4e170 797 sp_2048_add_30(&r[30], &r[30], t2);
wolfSSL 14:167253f4e170 798 sp_2048_add_30(&r[45], &r[45], t0);
wolfSSL 14:167253f4e170 799 sp_2048_add_30(&r[60], &r[60], p4);
wolfSSL 14:167253f4e170 800 }
wolfSSL 14:167253f4e170 801
wolfSSL 14:167253f4e170 802 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 803 *
wolfSSL 14:167253f4e170 804 * r A single precision integer.
wolfSSL 14:167253f4e170 805 * a A single precision integer.
wolfSSL 14:167253f4e170 806 * b A single precision integer.
wolfSSL 14:167253f4e170 807 */
wolfSSL 14:167253f4e170 808 SP_NOINLINE static int sp_2048_add_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 809 const sp_digit* b)
wolfSSL 14:167253f4e170 810 {
wolfSSL 14:167253f4e170 811 int i;
wolfSSL 14:167253f4e170 812
wolfSSL 14:167253f4e170 813 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 814 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 815 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 816 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 817 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 818 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 819 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 820 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 821 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 822 }
wolfSSL 14:167253f4e170 823 r[40] = a[40] + b[40];
wolfSSL 14:167253f4e170 824 r[41] = a[41] + b[41];
wolfSSL 14:167253f4e170 825 r[42] = a[42] + b[42];
wolfSSL 14:167253f4e170 826 r[43] = a[43] + b[43];
wolfSSL 14:167253f4e170 827 r[44] = a[44] + b[44];
wolfSSL 14:167253f4e170 828
wolfSSL 14:167253f4e170 829 return 0;
wolfSSL 14:167253f4e170 830 }
wolfSSL 14:167253f4e170 831
wolfSSL 14:167253f4e170 832 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 833 *
wolfSSL 14:167253f4e170 834 * r A single precision integer.
wolfSSL 14:167253f4e170 835 * a A single precision integer.
wolfSSL 14:167253f4e170 836 * b A single precision integer.
wolfSSL 14:167253f4e170 837 */
wolfSSL 14:167253f4e170 838 SP_NOINLINE static int sp_2048_add_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 839 const sp_digit* b)
wolfSSL 14:167253f4e170 840 {
wolfSSL 14:167253f4e170 841 int i;
wolfSSL 14:167253f4e170 842
wolfSSL 14:167253f4e170 843 for (i = 0; i < 88; i += 8) {
wolfSSL 14:167253f4e170 844 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 845 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 846 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 847 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 848 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 849 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 850 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 851 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 852 }
wolfSSL 14:167253f4e170 853 r[88] = a[88] + b[88];
wolfSSL 14:167253f4e170 854 r[89] = a[89] + b[89];
wolfSSL 14:167253f4e170 855
wolfSSL 14:167253f4e170 856 return 0;
wolfSSL 14:167253f4e170 857 }
wolfSSL 14:167253f4e170 858
wolfSSL 14:167253f4e170 859 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 860 *
wolfSSL 14:167253f4e170 861 * r A single precision integer.
wolfSSL 14:167253f4e170 862 * a A single precision integer.
wolfSSL 14:167253f4e170 863 * b A single precision integer.
wolfSSL 14:167253f4e170 864 */
wolfSSL 14:167253f4e170 865 SP_NOINLINE static int sp_2048_sub_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 866 const sp_digit* b)
wolfSSL 14:167253f4e170 867 {
wolfSSL 14:167253f4e170 868 int i;
wolfSSL 14:167253f4e170 869
wolfSSL 14:167253f4e170 870 for (i = 0; i < 88; i += 8) {
wolfSSL 14:167253f4e170 871 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 872 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 873 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 874 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 875 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 876 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 877 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 878 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 879 }
wolfSSL 14:167253f4e170 880 r[88] = a[88] - b[88];
wolfSSL 14:167253f4e170 881 r[89] = a[89] - b[89];
wolfSSL 14:167253f4e170 882
wolfSSL 14:167253f4e170 883 return 0;
wolfSSL 14:167253f4e170 884 }
wolfSSL 14:167253f4e170 885
wolfSSL 14:167253f4e170 886 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 887 *
wolfSSL 14:167253f4e170 888 * r A single precision integer.
wolfSSL 14:167253f4e170 889 * a A single precision integer.
wolfSSL 14:167253f4e170 890 * b A single precision integer.
wolfSSL 14:167253f4e170 891 */
wolfSSL 14:167253f4e170 892 SP_NOINLINE static void sp_2048_mul_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 893 const sp_digit* b)
wolfSSL 14:167253f4e170 894 {
wolfSSL 14:167253f4e170 895 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 896 sp_digit z1[90];
wolfSSL 14:167253f4e170 897 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 898 sp_digit b1[45];
wolfSSL 14:167253f4e170 899 sp_digit* z2 = r + 90;
wolfSSL 14:167253f4e170 900 sp_2048_add_45(a1, a, &a[45]);
wolfSSL 14:167253f4e170 901 sp_2048_add_45(b1, b, &b[45]);
wolfSSL 14:167253f4e170 902 sp_2048_mul_45(z2, &a[45], &b[45]);
wolfSSL 14:167253f4e170 903 sp_2048_mul_45(z0, a, b);
wolfSSL 14:167253f4e170 904 sp_2048_mul_45(z1, a1, b1);
wolfSSL 14:167253f4e170 905 sp_2048_sub_90(z1, z1, z2);
wolfSSL 14:167253f4e170 906 sp_2048_sub_90(z1, z1, z0);
wolfSSL 14:167253f4e170 907 sp_2048_add_90(r + 45, r + 45, z1);
wolfSSL 14:167253f4e170 908 }
wolfSSL 14:167253f4e170 909
wolfSSL 14:167253f4e170 910 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 911 *
wolfSSL 14:167253f4e170 912 * r A single precision integer.
wolfSSL 14:167253f4e170 913 * a A single precision integer.
wolfSSL 14:167253f4e170 914 */
wolfSSL 14:167253f4e170 915 SP_NOINLINE static void sp_2048_sqr_90(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 916 {
wolfSSL 14:167253f4e170 917 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 918 sp_digit z1[90];
wolfSSL 14:167253f4e170 919 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 920 sp_digit* z2 = r + 90;
wolfSSL 14:167253f4e170 921 sp_2048_add_45(a1, a, &a[45]);
wolfSSL 14:167253f4e170 922 sp_2048_sqr_45(z2, &a[45]);
wolfSSL 14:167253f4e170 923 sp_2048_sqr_45(z0, a);
wolfSSL 14:167253f4e170 924 sp_2048_sqr_45(z1, a1);
wolfSSL 14:167253f4e170 925 sp_2048_sub_90(z1, z1, z2);
wolfSSL 14:167253f4e170 926 sp_2048_sub_90(z1, z1, z0);
wolfSSL 14:167253f4e170 927 sp_2048_add_90(r + 45, r + 45, z1);
wolfSSL 14:167253f4e170 928 }
wolfSSL 14:167253f4e170 929
wolfSSL 14:167253f4e170 930 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 931 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 932 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 933 *
wolfSSL 14:167253f4e170 934 * r A single precision integer.
wolfSSL 14:167253f4e170 935 * a A single precision integer.
wolfSSL 14:167253f4e170 936 * b A single precision integer.
wolfSSL 14:167253f4e170 937 */
wolfSSL 14:167253f4e170 938 SP_NOINLINE static int sp_2048_add_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 939 const sp_digit* b)
wolfSSL 14:167253f4e170 940 {
wolfSSL 14:167253f4e170 941 int i;
wolfSSL 14:167253f4e170 942
wolfSSL 14:167253f4e170 943 for (i = 0; i < 90; i++)
wolfSSL 14:167253f4e170 944 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 945
wolfSSL 14:167253f4e170 946 return 0;
wolfSSL 14:167253f4e170 947 }
wolfSSL 14:167253f4e170 948 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 949 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 950 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 951 *
wolfSSL 14:167253f4e170 952 * r A single precision integer.
wolfSSL 14:167253f4e170 953 * a A single precision integer.
wolfSSL 14:167253f4e170 954 * b A single precision integer.
wolfSSL 14:167253f4e170 955 */
wolfSSL 14:167253f4e170 956 SP_NOINLINE static int sp_2048_sub_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 957 const sp_digit* b)
wolfSSL 14:167253f4e170 958 {
wolfSSL 14:167253f4e170 959 int i;
wolfSSL 14:167253f4e170 960
wolfSSL 14:167253f4e170 961 for (i = 0; i < 90; i++)
wolfSSL 14:167253f4e170 962 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 963
wolfSSL 14:167253f4e170 964 return 0;
wolfSSL 14:167253f4e170 965 }
wolfSSL 14:167253f4e170 966
wolfSSL 14:167253f4e170 967 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 968 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 969 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 970 *
wolfSSL 14:167253f4e170 971 * r A single precision integer.
wolfSSL 14:167253f4e170 972 * a A single precision integer.
wolfSSL 14:167253f4e170 973 * b A single precision integer.
wolfSSL 14:167253f4e170 974 */
wolfSSL 14:167253f4e170 975 SP_NOINLINE static void sp_2048_mul_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 976 const sp_digit* b)
wolfSSL 14:167253f4e170 977 {
wolfSSL 14:167253f4e170 978 int i, j, k;
wolfSSL 14:167253f4e170 979 int64_t c;
wolfSSL 14:167253f4e170 980
wolfSSL 14:167253f4e170 981 c = ((int64_t)a[89]) * b[89];
wolfSSL 14:167253f4e170 982 r[179] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 983 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 984 for (k = 177; k >= 0; k--) {
wolfSSL 14:167253f4e170 985 for (i = 89; i >= 0; i--) {
wolfSSL 14:167253f4e170 986 j = k - i;
wolfSSL 14:167253f4e170 987 if (j >= 90)
wolfSSL 14:167253f4e170 988 break;
wolfSSL 14:167253f4e170 989 if (j < 0)
wolfSSL 14:167253f4e170 990 continue;
wolfSSL 14:167253f4e170 991
wolfSSL 14:167253f4e170 992 c += ((int64_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 993 }
wolfSSL 14:167253f4e170 994 r[k + 2] += c >> 46;
wolfSSL 14:167253f4e170 995 r[k + 1] = (c >> 23) & 0x7fffff;
wolfSSL 14:167253f4e170 996 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 997 }
wolfSSL 14:167253f4e170 998 r[0] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 999 }
wolfSSL 14:167253f4e170 1000
wolfSSL 14:167253f4e170 1001 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 1002 *
wolfSSL 14:167253f4e170 1003 * r A single precision integer.
wolfSSL 14:167253f4e170 1004 * a A single precision integer.
wolfSSL 14:167253f4e170 1005 */
wolfSSL 14:167253f4e170 1006 SP_NOINLINE static void sp_2048_sqr_90(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 1007 {
wolfSSL 14:167253f4e170 1008 int i, j, k;
wolfSSL 14:167253f4e170 1009 int64_t c;
wolfSSL 14:167253f4e170 1010
wolfSSL 14:167253f4e170 1011 c = ((int64_t)a[89]) * a[89];
wolfSSL 14:167253f4e170 1012 r[179] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 1013 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 1014 for (k = 177; k >= 0; k--) {
wolfSSL 14:167253f4e170 1015 for (i = 89; i >= 0; i--) {
wolfSSL 14:167253f4e170 1016 j = k - i;
wolfSSL 14:167253f4e170 1017 if (j >= 90 || i <= j)
wolfSSL 14:167253f4e170 1018 break;
wolfSSL 14:167253f4e170 1019 if (j < 0)
wolfSSL 14:167253f4e170 1020 continue;
wolfSSL 14:167253f4e170 1021
wolfSSL 14:167253f4e170 1022 c += ((int64_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 1023 }
wolfSSL 14:167253f4e170 1024 if (i == j)
wolfSSL 14:167253f4e170 1025 c += ((int64_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 1026
wolfSSL 14:167253f4e170 1027 r[k + 2] += c >> 46;
wolfSSL 14:167253f4e170 1028 r[k + 1] = (c >> 23) & 0x7fffff;
wolfSSL 14:167253f4e170 1029 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 1030 }
wolfSSL 14:167253f4e170 1031 r[0] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 1032 }
wolfSSL 14:167253f4e170 1033
wolfSSL 14:167253f4e170 1034 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1035 #if !defined(SP_RSA_PRIVATE_EXP_D) && defined(WOLFSSL_HAVE_SP_RSA)
wolfSSL 14:167253f4e170 1036 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1037 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 1038 *
wolfSSL 14:167253f4e170 1039 * r A single precision integer.
wolfSSL 14:167253f4e170 1040 * a A single precision integer.
wolfSSL 14:167253f4e170 1041 * b A single precision integer.
wolfSSL 14:167253f4e170 1042 */
wolfSSL 14:167253f4e170 1043 SP_NOINLINE static int sp_2048_add_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1044 const sp_digit* b)
wolfSSL 14:167253f4e170 1045 {
wolfSSL 14:167253f4e170 1046 int i;
wolfSSL 14:167253f4e170 1047
wolfSSL 14:167253f4e170 1048 for (i = 0; i < 45; i++)
wolfSSL 14:167253f4e170 1049 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 1050
wolfSSL 14:167253f4e170 1051 return 0;
wolfSSL 14:167253f4e170 1052 }
wolfSSL 14:167253f4e170 1053 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1054 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1055 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 1056 *
wolfSSL 14:167253f4e170 1057 * r A single precision integer.
wolfSSL 14:167253f4e170 1058 * a A single precision integer.
wolfSSL 14:167253f4e170 1059 * b A single precision integer.
wolfSSL 14:167253f4e170 1060 */
wolfSSL 14:167253f4e170 1061 SP_NOINLINE static int sp_2048_sub_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1062 const sp_digit* b)
wolfSSL 14:167253f4e170 1063 {
wolfSSL 14:167253f4e170 1064 int i;
wolfSSL 14:167253f4e170 1065
wolfSSL 14:167253f4e170 1066 for (i = 0; i < 45; i++)
wolfSSL 14:167253f4e170 1067 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 1068
wolfSSL 14:167253f4e170 1069 return 0;
wolfSSL 14:167253f4e170 1070 }
wolfSSL 14:167253f4e170 1071
wolfSSL 14:167253f4e170 1072 #else
wolfSSL 14:167253f4e170 1073 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 1074 *
wolfSSL 14:167253f4e170 1075 * r A single precision integer.
wolfSSL 14:167253f4e170 1076 * a A single precision integer.
wolfSSL 14:167253f4e170 1077 * b A single precision integer.
wolfSSL 14:167253f4e170 1078 */
wolfSSL 14:167253f4e170 1079 SP_NOINLINE static int sp_2048_sub_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1080 const sp_digit* b)
wolfSSL 14:167253f4e170 1081 {
wolfSSL 14:167253f4e170 1082 int i;
wolfSSL 14:167253f4e170 1083
wolfSSL 14:167253f4e170 1084 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 1085 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 1086 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 1087 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 1088 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 1089 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 1090 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 1091 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 1092 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 1093 }
wolfSSL 14:167253f4e170 1094 r[40] = a[40] - b[40];
wolfSSL 14:167253f4e170 1095 r[41] = a[41] - b[41];
wolfSSL 14:167253f4e170 1096 r[42] = a[42] - b[42];
wolfSSL 14:167253f4e170 1097 r[43] = a[43] - b[43];
wolfSSL 14:167253f4e170 1098 r[44] = a[44] - b[44];
wolfSSL 14:167253f4e170 1099
wolfSSL 14:167253f4e170 1100 return 0;
wolfSSL 14:167253f4e170 1101 }
wolfSSL 14:167253f4e170 1102
wolfSSL 14:167253f4e170 1103 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1104 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1105 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 1106 *
wolfSSL 14:167253f4e170 1107 * r A single precision integer.
wolfSSL 14:167253f4e170 1108 * a A single precision integer.
wolfSSL 14:167253f4e170 1109 * b A single precision integer.
wolfSSL 14:167253f4e170 1110 */
wolfSSL 14:167253f4e170 1111 SP_NOINLINE static void sp_2048_mul_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1112 const sp_digit* b)
wolfSSL 14:167253f4e170 1113 {
wolfSSL 14:167253f4e170 1114 int i, j, k;
wolfSSL 14:167253f4e170 1115 int64_t c;
wolfSSL 14:167253f4e170 1116
wolfSSL 14:167253f4e170 1117 c = ((int64_t)a[44]) * b[44];
wolfSSL 14:167253f4e170 1118 r[89] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 1119 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 1120 for (k = 87; k >= 0; k--) {
wolfSSL 14:167253f4e170 1121 for (i = 44; i >= 0; i--) {
wolfSSL 14:167253f4e170 1122 j = k - i;
wolfSSL 14:167253f4e170 1123 if (j >= 45)
wolfSSL 14:167253f4e170 1124 break;
wolfSSL 14:167253f4e170 1125 if (j < 0)
wolfSSL 14:167253f4e170 1126 continue;
wolfSSL 14:167253f4e170 1127
wolfSSL 14:167253f4e170 1128 c += ((int64_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 1129 }
wolfSSL 14:167253f4e170 1130 r[k + 2] += c >> 46;
wolfSSL 14:167253f4e170 1131 r[k + 1] = (c >> 23) & 0x7fffff;
wolfSSL 14:167253f4e170 1132 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 1133 }
wolfSSL 14:167253f4e170 1134 r[0] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 1135 }
wolfSSL 14:167253f4e170 1136
wolfSSL 14:167253f4e170 1137 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 1138 *
wolfSSL 14:167253f4e170 1139 * r A single precision integer.
wolfSSL 14:167253f4e170 1140 * a A single precision integer.
wolfSSL 14:167253f4e170 1141 */
wolfSSL 14:167253f4e170 1142 SP_NOINLINE static void sp_2048_sqr_45(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 1143 {
wolfSSL 14:167253f4e170 1144 int i, j, k;
wolfSSL 14:167253f4e170 1145 int64_t c;
wolfSSL 14:167253f4e170 1146
wolfSSL 14:167253f4e170 1147 c = ((int64_t)a[44]) * a[44];
wolfSSL 14:167253f4e170 1148 r[89] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 1149 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 1150 for (k = 87; k >= 0; k--) {
wolfSSL 14:167253f4e170 1151 for (i = 44; i >= 0; i--) {
wolfSSL 14:167253f4e170 1152 j = k - i;
wolfSSL 14:167253f4e170 1153 if (j >= 45 || i <= j)
wolfSSL 14:167253f4e170 1154 break;
wolfSSL 14:167253f4e170 1155 if (j < 0)
wolfSSL 14:167253f4e170 1156 continue;
wolfSSL 14:167253f4e170 1157
wolfSSL 14:167253f4e170 1158 c += ((int64_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 1159 }
wolfSSL 14:167253f4e170 1160 if (i == j)
wolfSSL 14:167253f4e170 1161 c += ((int64_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 1162
wolfSSL 14:167253f4e170 1163 r[k + 2] += c >> 46;
wolfSSL 14:167253f4e170 1164 r[k + 1] = (c >> 23) & 0x7fffff;
wolfSSL 14:167253f4e170 1165 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 1166 }
wolfSSL 14:167253f4e170 1167 r[0] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 1168 }
wolfSSL 14:167253f4e170 1169
wolfSSL 14:167253f4e170 1170 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1171 #endif /* !SP_RSA_PRIVATE_EXP_D && WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 1172
wolfSSL 14:167253f4e170 1173 /* Caclulate the bottom digit of -1/a mod 2^n.
wolfSSL 14:167253f4e170 1174 *
wolfSSL 14:167253f4e170 1175 * a A single precision number.
wolfSSL 14:167253f4e170 1176 * rho Bottom word of inverse.
wolfSSL 14:167253f4e170 1177 */
wolfSSL 14:167253f4e170 1178 static void sp_2048_mont_setup(sp_digit* a, sp_digit* rho)
wolfSSL 14:167253f4e170 1179 {
wolfSSL 14:167253f4e170 1180 sp_digit x, b;
wolfSSL 14:167253f4e170 1181
wolfSSL 14:167253f4e170 1182 b = a[0];
wolfSSL 14:167253f4e170 1183 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
wolfSSL 14:167253f4e170 1184 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
wolfSSL 14:167253f4e170 1185 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
wolfSSL 14:167253f4e170 1186 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
wolfSSL 14:167253f4e170 1187 x &= 0x7fffff;
wolfSSL 14:167253f4e170 1188
wolfSSL 14:167253f4e170 1189 /* rho = -1/m mod b */
wolfSSL 14:167253f4e170 1190 *rho = (1L << 23) - x;
wolfSSL 14:167253f4e170 1191 }
wolfSSL 14:167253f4e170 1192
wolfSSL 14:167253f4e170 1193 #if !defined(SP_RSA_PRIVATE_EXP_D) && defined(WOLFSSL_HAVE_SP_RSA)
wolfSSL 14:167253f4e170 1194 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 14:167253f4e170 1195 * Given m must be 2048 bits, just need to subtract.
wolfSSL 14:167253f4e170 1196 *
wolfSSL 14:167253f4e170 1197 * r A single precision number.
wolfSSL 14:167253f4e170 1198 * m A signle precision number.
wolfSSL 14:167253f4e170 1199 */
wolfSSL 14:167253f4e170 1200 static void sp_2048_mont_norm_45(sp_digit* r, sp_digit* m)
wolfSSL 14:167253f4e170 1201 {
wolfSSL 14:167253f4e170 1202 /* Set r = 2^n - 1. */
wolfSSL 14:167253f4e170 1203 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1204 int i;
wolfSSL 14:167253f4e170 1205
wolfSSL 14:167253f4e170 1206 for (i=0; i<44; i++)
wolfSSL 14:167253f4e170 1207 r[i] = 0x7fffff;
wolfSSL 14:167253f4e170 1208 #else
wolfSSL 14:167253f4e170 1209 int i;
wolfSSL 14:167253f4e170 1210
wolfSSL 14:167253f4e170 1211 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 1212 r[i + 0] = 0x7fffff;
wolfSSL 14:167253f4e170 1213 r[i + 1] = 0x7fffff;
wolfSSL 14:167253f4e170 1214 r[i + 2] = 0x7fffff;
wolfSSL 14:167253f4e170 1215 r[i + 3] = 0x7fffff;
wolfSSL 14:167253f4e170 1216 r[i + 4] = 0x7fffff;
wolfSSL 14:167253f4e170 1217 r[i + 5] = 0x7fffff;
wolfSSL 14:167253f4e170 1218 r[i + 6] = 0x7fffff;
wolfSSL 14:167253f4e170 1219 r[i + 7] = 0x7fffff;
wolfSSL 14:167253f4e170 1220 }
wolfSSL 14:167253f4e170 1221 r[40] = 0x7fffff;
wolfSSL 14:167253f4e170 1222 r[41] = 0x7fffff;
wolfSSL 14:167253f4e170 1223 r[42] = 0x7fffff;
wolfSSL 14:167253f4e170 1224 r[43] = 0x7fffff;
wolfSSL 14:167253f4e170 1225 #endif
wolfSSL 14:167253f4e170 1226 r[44] = 0xfffl;
wolfSSL 14:167253f4e170 1227
wolfSSL 14:167253f4e170 1228 /* r = (2^n - 1) mod n */
wolfSSL 14:167253f4e170 1229 sp_2048_sub_45(r, r, m);
wolfSSL 14:167253f4e170 1230
wolfSSL 14:167253f4e170 1231 /* Add one so r = 2^n mod m */
wolfSSL 14:167253f4e170 1232 r[0] += 1;
wolfSSL 14:167253f4e170 1233 }
wolfSSL 14:167253f4e170 1234
wolfSSL 14:167253f4e170 1235 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 1236 *
wolfSSL 14:167253f4e170 1237 * a A single precision integer.
wolfSSL 14:167253f4e170 1238 * b A single precision integer.
wolfSSL 14:167253f4e170 1239 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 1240 * respectively.
wolfSSL 14:167253f4e170 1241 */
wolfSSL 14:167253f4e170 1242 static sp_digit sp_2048_cmp_45(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 1243 {
wolfSSL 14:167253f4e170 1244 sp_digit r = 0;
wolfSSL 14:167253f4e170 1245 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1246 int i;
wolfSSL 14:167253f4e170 1247
wolfSSL 14:167253f4e170 1248 for (i=44; i>=0; i--)
wolfSSL 14:167253f4e170 1249 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 1250 #else
wolfSSL 14:167253f4e170 1251 int i;
wolfSSL 14:167253f4e170 1252
wolfSSL 14:167253f4e170 1253 r |= (a[44] - b[44]) & (0 - !r);
wolfSSL 14:167253f4e170 1254 r |= (a[43] - b[43]) & (0 - !r);
wolfSSL 14:167253f4e170 1255 r |= (a[42] - b[42]) & (0 - !r);
wolfSSL 14:167253f4e170 1256 r |= (a[41] - b[41]) & (0 - !r);
wolfSSL 14:167253f4e170 1257 r |= (a[40] - b[40]) & (0 - !r);
wolfSSL 14:167253f4e170 1258 for (i = 32; i >= 0; i -= 8) {
wolfSSL 14:167253f4e170 1259 r |= (a[i + 7] - b[i + 7]) & (0 - !r);
wolfSSL 14:167253f4e170 1260 r |= (a[i + 6] - b[i + 6]) & (0 - !r);
wolfSSL 14:167253f4e170 1261 r |= (a[i + 5] - b[i + 5]) & (0 - !r);
wolfSSL 14:167253f4e170 1262 r |= (a[i + 4] - b[i + 4]) & (0 - !r);
wolfSSL 14:167253f4e170 1263 r |= (a[i + 3] - b[i + 3]) & (0 - !r);
wolfSSL 14:167253f4e170 1264 r |= (a[i + 2] - b[i + 2]) & (0 - !r);
wolfSSL 14:167253f4e170 1265 r |= (a[i + 1] - b[i + 1]) & (0 - !r);
wolfSSL 14:167253f4e170 1266 r |= (a[i + 0] - b[i + 0]) & (0 - !r);
wolfSSL 14:167253f4e170 1267 }
wolfSSL 14:167253f4e170 1268 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1269
wolfSSL 14:167253f4e170 1270 return r;
wolfSSL 14:167253f4e170 1271 }
wolfSSL 14:167253f4e170 1272
wolfSSL 14:167253f4e170 1273 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 1274 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 1275 *
wolfSSL 14:167253f4e170 1276 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 1277 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 1278 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 1279 * m Mask value to apply.
wolfSSL 14:167253f4e170 1280 */
wolfSSL 14:167253f4e170 1281 static void sp_2048_cond_sub_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1282 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 1283 {
wolfSSL 14:167253f4e170 1284 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1285 int i;
wolfSSL 14:167253f4e170 1286
wolfSSL 14:167253f4e170 1287 for (i = 0; i < 45; i++)
wolfSSL 14:167253f4e170 1288 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 1289 #else
wolfSSL 14:167253f4e170 1290 int i;
wolfSSL 14:167253f4e170 1291
wolfSSL 14:167253f4e170 1292 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 1293 r[i + 0] = a[i + 0] - (b[i + 0] & m);
wolfSSL 14:167253f4e170 1294 r[i + 1] = a[i + 1] - (b[i + 1] & m);
wolfSSL 14:167253f4e170 1295 r[i + 2] = a[i + 2] - (b[i + 2] & m);
wolfSSL 14:167253f4e170 1296 r[i + 3] = a[i + 3] - (b[i + 3] & m);
wolfSSL 14:167253f4e170 1297 r[i + 4] = a[i + 4] - (b[i + 4] & m);
wolfSSL 14:167253f4e170 1298 r[i + 5] = a[i + 5] - (b[i + 5] & m);
wolfSSL 14:167253f4e170 1299 r[i + 6] = a[i + 6] - (b[i + 6] & m);
wolfSSL 14:167253f4e170 1300 r[i + 7] = a[i + 7] - (b[i + 7] & m);
wolfSSL 14:167253f4e170 1301 }
wolfSSL 14:167253f4e170 1302 r[40] = a[40] - (b[40] & m);
wolfSSL 14:167253f4e170 1303 r[41] = a[41] - (b[41] & m);
wolfSSL 14:167253f4e170 1304 r[42] = a[42] - (b[42] & m);
wolfSSL 14:167253f4e170 1305 r[43] = a[43] - (b[43] & m);
wolfSSL 14:167253f4e170 1306 r[44] = a[44] - (b[44] & m);
wolfSSL 14:167253f4e170 1307 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1308 }
wolfSSL 14:167253f4e170 1309
wolfSSL 14:167253f4e170 1310 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 1311 *
wolfSSL 14:167253f4e170 1312 * r A single precision integer.
wolfSSL 14:167253f4e170 1313 * a A single precision integer.
wolfSSL 14:167253f4e170 1314 * b A scalar.
wolfSSL 14:167253f4e170 1315 */
wolfSSL 14:167253f4e170 1316 SP_NOINLINE static void sp_2048_mul_add_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1317 const sp_digit b)
wolfSSL 14:167253f4e170 1318 {
wolfSSL 14:167253f4e170 1319 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1320 int64_t tb = b;
wolfSSL 14:167253f4e170 1321 int64_t t = 0;
wolfSSL 14:167253f4e170 1322 int i;
wolfSSL 14:167253f4e170 1323
wolfSSL 14:167253f4e170 1324 for (i = 0; i < 45; i++) {
wolfSSL 14:167253f4e170 1325 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 1326 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 1327 t >>= 23;
wolfSSL 14:167253f4e170 1328 }
wolfSSL 14:167253f4e170 1329 r[45] += t;
wolfSSL 14:167253f4e170 1330 #else
wolfSSL 14:167253f4e170 1331 int64_t tb = b;
wolfSSL 14:167253f4e170 1332 int64_t t[8];
wolfSSL 14:167253f4e170 1333 int i;
wolfSSL 14:167253f4e170 1334
wolfSSL 14:167253f4e170 1335 t[0] = tb * a[0]; r[0] += t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 1336 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 1337 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 1338 r[i+1] += (t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 1339 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 1340 r[i+2] += (t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 1341 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 1342 r[i+3] += (t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 1343 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 1344 r[i+4] += (t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 1345 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 1346 r[i+5] += (t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 1347 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 1348 r[i+6] += (t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 1349 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 1350 r[i+7] += (t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 1351 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 1352 r[i+8] += (t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 1353 }
wolfSSL 14:167253f4e170 1354 t[1] = tb * a[41]; r[41] += (t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 1355 t[2] = tb * a[42]; r[42] += (t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 1356 t[3] = tb * a[43]; r[43] += (t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 1357 t[4] = tb * a[44]; r[44] += (t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 1358 r[45] += t[4] >> 23;
wolfSSL 14:167253f4e170 1359 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1360 }
wolfSSL 14:167253f4e170 1361
wolfSSL 14:167253f4e170 1362 /* Normalize the values in each word to 23.
wolfSSL 14:167253f4e170 1363 *
wolfSSL 14:167253f4e170 1364 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 1365 */
wolfSSL 14:167253f4e170 1366 static void sp_2048_norm_45(sp_digit* a)
wolfSSL 14:167253f4e170 1367 {
wolfSSL 14:167253f4e170 1368 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1369 int i;
wolfSSL 14:167253f4e170 1370 for (i = 0; i < 44; i++) {
wolfSSL 14:167253f4e170 1371 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 1372 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 1373 }
wolfSSL 14:167253f4e170 1374 #else
wolfSSL 14:167253f4e170 1375 int i;
wolfSSL 14:167253f4e170 1376 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 1377 a[i+1] += a[i+0] >> 23; a[i+0] &= 0x7fffff;
wolfSSL 14:167253f4e170 1378 a[i+2] += a[i+1] >> 23; a[i+1] &= 0x7fffff;
wolfSSL 14:167253f4e170 1379 a[i+3] += a[i+2] >> 23; a[i+2] &= 0x7fffff;
wolfSSL 14:167253f4e170 1380 a[i+4] += a[i+3] >> 23; a[i+3] &= 0x7fffff;
wolfSSL 14:167253f4e170 1381 a[i+5] += a[i+4] >> 23; a[i+4] &= 0x7fffff;
wolfSSL 14:167253f4e170 1382 a[i+6] += a[i+5] >> 23; a[i+5] &= 0x7fffff;
wolfSSL 14:167253f4e170 1383 a[i+7] += a[i+6] >> 23; a[i+6] &= 0x7fffff;
wolfSSL 14:167253f4e170 1384 a[i+8] += a[i+7] >> 23; a[i+7] &= 0x7fffff;
wolfSSL 14:167253f4e170 1385 a[i+9] += a[i+8] >> 23; a[i+8] &= 0x7fffff;
wolfSSL 14:167253f4e170 1386 }
wolfSSL 14:167253f4e170 1387 a[40+1] += a[40] >> 23;
wolfSSL 14:167253f4e170 1388 a[40] &= 0x7fffff;
wolfSSL 14:167253f4e170 1389 a[41+1] += a[41] >> 23;
wolfSSL 14:167253f4e170 1390 a[41] &= 0x7fffff;
wolfSSL 14:167253f4e170 1391 a[42+1] += a[42] >> 23;
wolfSSL 14:167253f4e170 1392 a[42] &= 0x7fffff;
wolfSSL 14:167253f4e170 1393 a[43+1] += a[43] >> 23;
wolfSSL 14:167253f4e170 1394 a[43] &= 0x7fffff;
wolfSSL 14:167253f4e170 1395 #endif
wolfSSL 14:167253f4e170 1396 }
wolfSSL 14:167253f4e170 1397
wolfSSL 14:167253f4e170 1398 /* Shift the result in the high 1024 bits down to the bottom.
wolfSSL 14:167253f4e170 1399 *
wolfSSL 14:167253f4e170 1400 * r A single precision number.
wolfSSL 14:167253f4e170 1401 * a A single precision number.
wolfSSL 14:167253f4e170 1402 */
wolfSSL 14:167253f4e170 1403 static void sp_2048_mont_shift_45(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 1404 {
wolfSSL 14:167253f4e170 1405 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1406 int i;
wolfSSL 14:167253f4e170 1407 int64_t n = a[44] >> 12;
wolfSSL 14:167253f4e170 1408 n += ((int64_t)a[45]) << 11;
wolfSSL 14:167253f4e170 1409
wolfSSL 14:167253f4e170 1410 for (i = 0; i < 44; i++) {
wolfSSL 14:167253f4e170 1411 r[i] = n & 0x7fffff;
wolfSSL 14:167253f4e170 1412 n >>= 23;
wolfSSL 14:167253f4e170 1413 n += ((int64_t)a[46 + i]) << 11;
wolfSSL 14:167253f4e170 1414 }
wolfSSL 14:167253f4e170 1415 r[44] = (sp_digit)n;
wolfSSL 14:167253f4e170 1416 #else
wolfSSL 14:167253f4e170 1417 int i;
wolfSSL 14:167253f4e170 1418 int64_t n = a[44] >> 12;
wolfSSL 14:167253f4e170 1419 n += ((int64_t)a[45]) << 11;
wolfSSL 14:167253f4e170 1420 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 1421 r[i + 0] = n & 0x7fffff;
wolfSSL 14:167253f4e170 1422 n >>= 23; n += ((int64_t)a[i + 46]) << 11;
wolfSSL 14:167253f4e170 1423 r[i + 1] = n & 0x7fffff;
wolfSSL 14:167253f4e170 1424 n >>= 23; n += ((int64_t)a[i + 47]) << 11;
wolfSSL 14:167253f4e170 1425 r[i + 2] = n & 0x7fffff;
wolfSSL 14:167253f4e170 1426 n >>= 23; n += ((int64_t)a[i + 48]) << 11;
wolfSSL 14:167253f4e170 1427 r[i + 3] = n & 0x7fffff;
wolfSSL 14:167253f4e170 1428 n >>= 23; n += ((int64_t)a[i + 49]) << 11;
wolfSSL 14:167253f4e170 1429 r[i + 4] = n & 0x7fffff;
wolfSSL 14:167253f4e170 1430 n >>= 23; n += ((int64_t)a[i + 50]) << 11;
wolfSSL 14:167253f4e170 1431 r[i + 5] = n & 0x7fffff;
wolfSSL 14:167253f4e170 1432 n >>= 23; n += ((int64_t)a[i + 51]) << 11;
wolfSSL 14:167253f4e170 1433 r[i + 6] = n & 0x7fffff;
wolfSSL 14:167253f4e170 1434 n >>= 23; n += ((int64_t)a[i + 52]) << 11;
wolfSSL 14:167253f4e170 1435 r[i + 7] = n & 0x7fffff;
wolfSSL 14:167253f4e170 1436 n >>= 23; n += ((int64_t)a[i + 53]) << 11;
wolfSSL 14:167253f4e170 1437 }
wolfSSL 14:167253f4e170 1438 r[40] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[86]) << 11;
wolfSSL 14:167253f4e170 1439 r[41] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[87]) << 11;
wolfSSL 14:167253f4e170 1440 r[42] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[88]) << 11;
wolfSSL 14:167253f4e170 1441 r[43] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[89]) << 11;
wolfSSL 14:167253f4e170 1442 r[44] = (sp_digit)n;
wolfSSL 14:167253f4e170 1443 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1444 XMEMSET(&r[45], 0, sizeof(*r) * 45);
wolfSSL 14:167253f4e170 1445 }
wolfSSL 14:167253f4e170 1446
wolfSSL 14:167253f4e170 1447 /* Reduce the number back to 2048 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 1448 *
wolfSSL 14:167253f4e170 1449 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 1450 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 1451 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 1452 */
wolfSSL 14:167253f4e170 1453 static void sp_2048_mont_reduce_45(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 1454 {
wolfSSL 14:167253f4e170 1455 int i;
wolfSSL 14:167253f4e170 1456 sp_digit mu;
wolfSSL 14:167253f4e170 1457
wolfSSL 14:167253f4e170 1458 for (i=0; i<44; i++) {
wolfSSL 14:167253f4e170 1459 mu = (a[i] * mp) & 0x7fffff;
wolfSSL 14:167253f4e170 1460 sp_2048_mul_add_45(a+i, m, mu);
wolfSSL 14:167253f4e170 1461 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 1462 }
wolfSSL 14:167253f4e170 1463 mu = (a[i] * mp) & 0xfffl;
wolfSSL 14:167253f4e170 1464 sp_2048_mul_add_45(a+i, m, mu);
wolfSSL 14:167253f4e170 1465 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 1466 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 1467
wolfSSL 14:167253f4e170 1468 sp_2048_mont_shift_45(a, a);
wolfSSL 14:167253f4e170 1469 sp_2048_cond_sub_45(a, a, m, 0 - ((a[44] >> 12) > 0));
wolfSSL 14:167253f4e170 1470 sp_2048_norm_45(a);
wolfSSL 14:167253f4e170 1471 }
wolfSSL 14:167253f4e170 1472
wolfSSL 14:167253f4e170 1473 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 1474 * (r = a * b mod m)
wolfSSL 14:167253f4e170 1475 *
wolfSSL 14:167253f4e170 1476 * r Result of multiplication.
wolfSSL 14:167253f4e170 1477 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 1478 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 1479 * m Modulus (prime).
wolfSSL 14:167253f4e170 1480 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 1481 */
wolfSSL 14:167253f4e170 1482 static void sp_2048_mont_mul_45(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 1483 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 1484 {
wolfSSL 14:167253f4e170 1485 sp_2048_mul_45(r, a, b);
wolfSSL 14:167253f4e170 1486 sp_2048_mont_reduce_45(r, m, mp);
wolfSSL 14:167253f4e170 1487 }
wolfSSL 14:167253f4e170 1488
wolfSSL 14:167253f4e170 1489 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 1490 *
wolfSSL 14:167253f4e170 1491 * r Result of squaring.
wolfSSL 14:167253f4e170 1492 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 1493 * m Modulus (prime).
wolfSSL 14:167253f4e170 1494 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 1495 */
wolfSSL 14:167253f4e170 1496 static void sp_2048_mont_sqr_45(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 1497 sp_digit mp)
wolfSSL 14:167253f4e170 1498 {
wolfSSL 14:167253f4e170 1499 sp_2048_sqr_45(r, a);
wolfSSL 14:167253f4e170 1500 sp_2048_mont_reduce_45(r, m, mp);
wolfSSL 14:167253f4e170 1501 }
wolfSSL 14:167253f4e170 1502
wolfSSL 14:167253f4e170 1503 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 1504 *
wolfSSL 14:167253f4e170 1505 * r A single precision integer.
wolfSSL 14:167253f4e170 1506 * a A single precision integer.
wolfSSL 14:167253f4e170 1507 * b A scalar.
wolfSSL 14:167253f4e170 1508 */
wolfSSL 14:167253f4e170 1509 SP_NOINLINE static void sp_2048_mul_d_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1510 const sp_digit b)
wolfSSL 14:167253f4e170 1511 {
wolfSSL 14:167253f4e170 1512 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1513 int64_t tb = b;
wolfSSL 14:167253f4e170 1514 int64_t t = 0;
wolfSSL 14:167253f4e170 1515 int i;
wolfSSL 14:167253f4e170 1516
wolfSSL 14:167253f4e170 1517 for (i = 0; i < 45; i++) {
wolfSSL 14:167253f4e170 1518 t += tb * a[i];
wolfSSL 14:167253f4e170 1519 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 1520 t >>= 23;
wolfSSL 14:167253f4e170 1521 }
wolfSSL 14:167253f4e170 1522 r[45] = (sp_digit)t;
wolfSSL 14:167253f4e170 1523 #else
wolfSSL 14:167253f4e170 1524 int64_t tb = b;
wolfSSL 14:167253f4e170 1525 int64_t t[8];
wolfSSL 14:167253f4e170 1526 int i;
wolfSSL 14:167253f4e170 1527
wolfSSL 14:167253f4e170 1528 t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 1529 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 1530 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 1531 r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 1532 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 1533 r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 1534 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 1535 r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 1536 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 1537 r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 1538 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 1539 r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 1540 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 1541 r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 1542 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 1543 r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 1544 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 1545 r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 1546 }
wolfSSL 14:167253f4e170 1547 t[1] = tb * a[41];
wolfSSL 14:167253f4e170 1548 r[41] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 1549 t[2] = tb * a[42];
wolfSSL 14:167253f4e170 1550 r[42] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 1551 t[3] = tb * a[43];
wolfSSL 14:167253f4e170 1552 r[43] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 1553 t[4] = tb * a[44];
wolfSSL 14:167253f4e170 1554 r[44] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 1555 r[45] = (sp_digit)(t[4] >> 23);
wolfSSL 14:167253f4e170 1556 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1557 }
wolfSSL 14:167253f4e170 1558
wolfSSL 14:167253f4e170 1559 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 1560 *
wolfSSL 14:167253f4e170 1561 * r A single precision integer.
wolfSSL 14:167253f4e170 1562 * a A single precision integer.
wolfSSL 14:167253f4e170 1563 * b A scalar.
wolfSSL 14:167253f4e170 1564 */
wolfSSL 14:167253f4e170 1565 SP_NOINLINE static void sp_2048_mul_d_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1566 const sp_digit b)
wolfSSL 14:167253f4e170 1567 {
wolfSSL 14:167253f4e170 1568 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1569 int64_t tb = b;
wolfSSL 14:167253f4e170 1570 int64_t t = 0;
wolfSSL 14:167253f4e170 1571 int i;
wolfSSL 14:167253f4e170 1572
wolfSSL 14:167253f4e170 1573 for (i = 0; i < 90; i++) {
wolfSSL 14:167253f4e170 1574 t += tb * a[i];
wolfSSL 14:167253f4e170 1575 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 1576 t >>= 23;
wolfSSL 14:167253f4e170 1577 }
wolfSSL 14:167253f4e170 1578 r[90] = (sp_digit)t;
wolfSSL 14:167253f4e170 1579 #else
wolfSSL 14:167253f4e170 1580 int64_t tb = b;
wolfSSL 14:167253f4e170 1581 int64_t t[8];
wolfSSL 14:167253f4e170 1582 int i;
wolfSSL 14:167253f4e170 1583
wolfSSL 14:167253f4e170 1584 t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 1585 for (i = 0; i < 88; i += 8) {
wolfSSL 14:167253f4e170 1586 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 1587 r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 1588 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 1589 r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 1590 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 1591 r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 1592 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 1593 r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 1594 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 1595 r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 1596 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 1597 r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 1598 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 1599 r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 1600 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 1601 r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 1602 }
wolfSSL 14:167253f4e170 1603 t[1] = tb * a[89];
wolfSSL 14:167253f4e170 1604 r[89] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 1605 r[90] = (sp_digit)(t[1] >> 23);
wolfSSL 14:167253f4e170 1606 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1607 }
wolfSSL 14:167253f4e170 1608
wolfSSL 14:167253f4e170 1609 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 1610 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 1611 *
wolfSSL 14:167253f4e170 1612 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 1613 * a A single precision number to add with.
wolfSSL 14:167253f4e170 1614 * b A single precision number to add.
wolfSSL 14:167253f4e170 1615 * m Mask value to apply.
wolfSSL 14:167253f4e170 1616 */
wolfSSL 14:167253f4e170 1617 static void sp_2048_cond_add_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1618 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 1619 {
wolfSSL 14:167253f4e170 1620 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1621 int i;
wolfSSL 14:167253f4e170 1622
wolfSSL 14:167253f4e170 1623 for (i = 0; i < 45; i++)
wolfSSL 14:167253f4e170 1624 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 1625 #else
wolfSSL 14:167253f4e170 1626 int i;
wolfSSL 14:167253f4e170 1627
wolfSSL 14:167253f4e170 1628 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 1629 r[i + 0] = a[i + 0] + (b[i + 0] & m);
wolfSSL 14:167253f4e170 1630 r[i + 1] = a[i + 1] + (b[i + 1] & m);
wolfSSL 14:167253f4e170 1631 r[i + 2] = a[i + 2] + (b[i + 2] & m);
wolfSSL 14:167253f4e170 1632 r[i + 3] = a[i + 3] + (b[i + 3] & m);
wolfSSL 14:167253f4e170 1633 r[i + 4] = a[i + 4] + (b[i + 4] & m);
wolfSSL 14:167253f4e170 1634 r[i + 5] = a[i + 5] + (b[i + 5] & m);
wolfSSL 14:167253f4e170 1635 r[i + 6] = a[i + 6] + (b[i + 6] & m);
wolfSSL 14:167253f4e170 1636 r[i + 7] = a[i + 7] + (b[i + 7] & m);
wolfSSL 14:167253f4e170 1637 }
wolfSSL 14:167253f4e170 1638 r[40] = a[40] + (b[40] & m);
wolfSSL 14:167253f4e170 1639 r[41] = a[41] + (b[41] & m);
wolfSSL 14:167253f4e170 1640 r[42] = a[42] + (b[42] & m);
wolfSSL 14:167253f4e170 1641 r[43] = a[43] + (b[43] & m);
wolfSSL 14:167253f4e170 1642 r[44] = a[44] + (b[44] & m);
wolfSSL 14:167253f4e170 1643 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1644 }
wolfSSL 14:167253f4e170 1645
wolfSSL 14:167253f4e170 1646 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 1647 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 1648 *
wolfSSL 14:167253f4e170 1649 * r A single precision integer.
wolfSSL 14:167253f4e170 1650 * a A single precision integer.
wolfSSL 14:167253f4e170 1651 * b A single precision integer.
wolfSSL 14:167253f4e170 1652 */
wolfSSL 14:167253f4e170 1653 SP_NOINLINE static int sp_2048_add_45(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1654 const sp_digit* b)
wolfSSL 14:167253f4e170 1655 {
wolfSSL 14:167253f4e170 1656 int i;
wolfSSL 14:167253f4e170 1657
wolfSSL 14:167253f4e170 1658 for (i = 0; i < 45; i++)
wolfSSL 14:167253f4e170 1659 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 1660
wolfSSL 14:167253f4e170 1661 return 0;
wolfSSL 14:167253f4e170 1662 }
wolfSSL 14:167253f4e170 1663 #endif
wolfSSL 14:167253f4e170 1664 SP_NOINLINE static void sp_2048_rshift_45(sp_digit* r, sp_digit* a, byte n)
wolfSSL 14:167253f4e170 1665 {
wolfSSL 14:167253f4e170 1666 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1667 int i;
wolfSSL 14:167253f4e170 1668
wolfSSL 14:167253f4e170 1669 for (i=0; i<44; i++)
wolfSSL 14:167253f4e170 1670 r[i] = ((a[i] >> n) | (a[i + 1] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1671 #else
wolfSSL 14:167253f4e170 1672 r[0] = ((a[0] >> n) | (a[1] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1673 r[1] = ((a[1] >> n) | (a[2] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1674 r[2] = ((a[2] >> n) | (a[3] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1675 r[3] = ((a[3] >> n) | (a[4] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1676 r[4] = ((a[4] >> n) | (a[5] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1677 r[5] = ((a[5] >> n) | (a[6] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1678 r[6] = ((a[6] >> n) | (a[7] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1679 r[7] = ((a[7] >> n) | (a[8] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1680 r[8] = ((a[8] >> n) | (a[9] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1681 r[9] = ((a[9] >> n) | (a[10] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1682 r[10] = ((a[10] >> n) | (a[11] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1683 r[11] = ((a[11] >> n) | (a[12] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1684 r[12] = ((a[12] >> n) | (a[13] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1685 r[13] = ((a[13] >> n) | (a[14] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1686 r[14] = ((a[14] >> n) | (a[15] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1687 r[15] = ((a[15] >> n) | (a[16] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1688 r[16] = ((a[16] >> n) | (a[17] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1689 r[17] = ((a[17] >> n) | (a[18] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1690 r[18] = ((a[18] >> n) | (a[19] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1691 r[19] = ((a[19] >> n) | (a[20] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1692 r[20] = ((a[20] >> n) | (a[21] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1693 r[21] = ((a[21] >> n) | (a[22] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1694 r[22] = ((a[22] >> n) | (a[23] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1695 r[23] = ((a[23] >> n) | (a[24] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1696 r[24] = ((a[24] >> n) | (a[25] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1697 r[25] = ((a[25] >> n) | (a[26] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1698 r[26] = ((a[26] >> n) | (a[27] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1699 r[27] = ((a[27] >> n) | (a[28] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1700 r[28] = ((a[28] >> n) | (a[29] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1701 r[29] = ((a[29] >> n) | (a[30] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1702 r[30] = ((a[30] >> n) | (a[31] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1703 r[31] = ((a[31] >> n) | (a[32] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1704 r[32] = ((a[32] >> n) | (a[33] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1705 r[33] = ((a[33] >> n) | (a[34] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1706 r[34] = ((a[34] >> n) | (a[35] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1707 r[35] = ((a[35] >> n) | (a[36] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1708 r[36] = ((a[36] >> n) | (a[37] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1709 r[37] = ((a[37] >> n) | (a[38] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1710 r[38] = ((a[38] >> n) | (a[39] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1711 r[39] = ((a[39] >> n) | (a[40] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1712 r[40] = ((a[40] >> n) | (a[41] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1713 r[41] = ((a[41] >> n) | (a[42] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1714 r[42] = ((a[42] >> n) | (a[43] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1715 r[43] = ((a[43] >> n) | (a[44] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 1716 #endif
wolfSSL 14:167253f4e170 1717 r[44] = a[44] >> n;
wolfSSL 14:167253f4e170 1718 }
wolfSSL 14:167253f4e170 1719
wolfSSL 14:167253f4e170 1720 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 1721 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 1722 *
wolfSSL 14:167253f4e170 1723 * a Nmber to be divided.
wolfSSL 14:167253f4e170 1724 * d Number to divide with.
wolfSSL 14:167253f4e170 1725 * m Multiplier result.
wolfSSL 14:167253f4e170 1726 * r Remainder from the division.
wolfSSL 14:167253f4e170 1727 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 1728 */
wolfSSL 14:167253f4e170 1729 static int sp_2048_div_45(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 1730 sp_digit* r)
wolfSSL 14:167253f4e170 1731 {
wolfSSL 14:167253f4e170 1732 int i;
wolfSSL 14:167253f4e170 1733 int64_t d1;
wolfSSL 14:167253f4e170 1734 sp_digit div, r1;
wolfSSL 14:167253f4e170 1735 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 1736 sp_digit* td;
wolfSSL 14:167253f4e170 1737 #else
wolfSSL 14:167253f4e170 1738 sp_digit t1d[90 + 1], t2d[45 + 1], sdd[45 + 1];
wolfSSL 14:167253f4e170 1739 #endif
wolfSSL 14:167253f4e170 1740 sp_digit* t1;
wolfSSL 14:167253f4e170 1741 sp_digit* t2;
wolfSSL 14:167253f4e170 1742 sp_digit* sd;
wolfSSL 14:167253f4e170 1743 int err = MP_OKAY;
wolfSSL 14:167253f4e170 1744
wolfSSL 14:167253f4e170 1745 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 1746 td = XMALLOC(sizeof(sp_digit) * (4 * 45 + 3), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1747 if (td != NULL) {
wolfSSL 14:167253f4e170 1748 t1 = td;
wolfSSL 14:167253f4e170 1749 t2 = td + 90 + 1;
wolfSSL 14:167253f4e170 1750 sd = t2 + 45 + 1;
wolfSSL 14:167253f4e170 1751 }
wolfSSL 14:167253f4e170 1752 else
wolfSSL 14:167253f4e170 1753 err = MEMORY_E;
wolfSSL 14:167253f4e170 1754 #else
wolfSSL 14:167253f4e170 1755 t1 = t1d;
wolfSSL 14:167253f4e170 1756 t2 = t2d;
wolfSSL 14:167253f4e170 1757 sd = sdd;
wolfSSL 14:167253f4e170 1758 #endif
wolfSSL 14:167253f4e170 1759
wolfSSL 14:167253f4e170 1760 (void)m;
wolfSSL 14:167253f4e170 1761
wolfSSL 14:167253f4e170 1762 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1763 sp_2048_mul_d_45(sd, d, 1 << 11);
wolfSSL 14:167253f4e170 1764 sp_2048_mul_d_90(t1, a, 1 << 11);
wolfSSL 14:167253f4e170 1765 div = sd[44];
wolfSSL 14:167253f4e170 1766 for (i=45; i>=0; i--) {
wolfSSL 14:167253f4e170 1767 t1[45 + i] += t1[45 + i - 1] >> 23;
wolfSSL 14:167253f4e170 1768 t1[45 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 1769 d1 = t1[45 + i];
wolfSSL 14:167253f4e170 1770 d1 <<= 23;
wolfSSL 14:167253f4e170 1771 d1 += t1[45 + i - 1];
wolfSSL 14:167253f4e170 1772 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 1773
wolfSSL 14:167253f4e170 1774 sp_2048_mul_d_45(t2, sd, r1);
wolfSSL 14:167253f4e170 1775 sp_2048_sub_45(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 1776 t1[45 + i] -= t2[45];
wolfSSL 14:167253f4e170 1777 t1[45 + i] += t1[45 + i - 1] >> 23;
wolfSSL 14:167253f4e170 1778 t1[45 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 1779 r1 = (((-t1[45 + i]) << 23) - t1[45 + i - 1]) / div;
wolfSSL 14:167253f4e170 1780 r1 -= t1[45 + i];
wolfSSL 14:167253f4e170 1781 sp_2048_mul_d_45(t2, sd, r1);
wolfSSL 14:167253f4e170 1782 sp_2048_add_45(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 1783 t1[45 + i] += t1[45 + i - 1] >> 23;
wolfSSL 14:167253f4e170 1784 t1[45 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 1785 }
wolfSSL 14:167253f4e170 1786 t1[45 - 1] += t1[45 - 2] >> 23;
wolfSSL 14:167253f4e170 1787 t1[45 - 2] &= 0x7fffff;
wolfSSL 14:167253f4e170 1788 d1 = t1[45 - 1];
wolfSSL 14:167253f4e170 1789 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 1790
wolfSSL 14:167253f4e170 1791 sp_2048_mul_d_45(t2, sd, r1);
wolfSSL 14:167253f4e170 1792 sp_2048_sub_45(t1, t1, t2);
wolfSSL 14:167253f4e170 1793 XMEMCPY(r, t1, sizeof(*r) * 2 * 45);
wolfSSL 14:167253f4e170 1794 for (i=0; i<43; i++) {
wolfSSL 14:167253f4e170 1795 r[i+1] += r[i] >> 23;
wolfSSL 14:167253f4e170 1796 r[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 1797 }
wolfSSL 14:167253f4e170 1798 sp_2048_cond_add_45(r, r, sd, 0 - (r[44] < 0));
wolfSSL 14:167253f4e170 1799 }
wolfSSL 14:167253f4e170 1800
wolfSSL 14:167253f4e170 1801 sp_2048_rshift_45(r, r, 11);
wolfSSL 14:167253f4e170 1802
wolfSSL 14:167253f4e170 1803 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 1804 if (td != NULL)
wolfSSL 14:167253f4e170 1805 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1806 #endif
wolfSSL 14:167253f4e170 1807
wolfSSL 14:167253f4e170 1808 return err;
wolfSSL 14:167253f4e170 1809 }
wolfSSL 14:167253f4e170 1810
wolfSSL 14:167253f4e170 1811 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 1812 *
wolfSSL 14:167253f4e170 1813 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 1814 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 1815 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 1816 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 1817 */
wolfSSL 14:167253f4e170 1818 static int sp_2048_mod_45(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 1819 {
wolfSSL 14:167253f4e170 1820 return sp_2048_div_45(a, m, NULL, r);
wolfSSL 14:167253f4e170 1821 }
wolfSSL 14:167253f4e170 1822
wolfSSL 14:167253f4e170 1823 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 14:167253f4e170 1824 *
wolfSSL 14:167253f4e170 1825 * r A single precision number that is the result of the operation.
wolfSSL 14:167253f4e170 1826 * a A single precision number being exponentiated.
wolfSSL 14:167253f4e170 1827 * e A single precision number that is the exponent.
wolfSSL 14:167253f4e170 1828 * bits The number of bits in the exponent.
wolfSSL 14:167253f4e170 1829 * m A single precision number that is the modulus.
wolfSSL 14:167253f4e170 1830 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 14:167253f4e170 1831 */
wolfSSL 14:167253f4e170 1832 static int sp_2048_mod_exp_45(sp_digit* r, sp_digit* a, sp_digit* e, int bits,
wolfSSL 14:167253f4e170 1833 sp_digit* m, int reduceA)
wolfSSL 14:167253f4e170 1834 {
wolfSSL 14:167253f4e170 1835 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1836 sp_digit* td;
wolfSSL 14:167253f4e170 1837 sp_digit* t[3];
wolfSSL 14:167253f4e170 1838 sp_digit* norm;
wolfSSL 14:167253f4e170 1839 sp_digit mp = 1;
wolfSSL 14:167253f4e170 1840 sp_digit n;
wolfSSL 14:167253f4e170 1841 int i;
wolfSSL 14:167253f4e170 1842 int c, y;
wolfSSL 14:167253f4e170 1843 int err = MP_OKAY;
wolfSSL 14:167253f4e170 1844
wolfSSL 14:167253f4e170 1845 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 45 * 2, NULL,
wolfSSL 14:167253f4e170 1846 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1847 if (td == NULL)
wolfSSL 14:167253f4e170 1848 err = MEMORY_E;
wolfSSL 14:167253f4e170 1849
wolfSSL 14:167253f4e170 1850 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1851 XMEMSET(td, 0, sizeof(*td) * 3 * 45 * 2);
wolfSSL 14:167253f4e170 1852
wolfSSL 14:167253f4e170 1853 norm = t[0] = td;
wolfSSL 14:167253f4e170 1854 t[1] = &td[45 * 2];
wolfSSL 14:167253f4e170 1855 t[2] = &td[2 * 45 * 2];
wolfSSL 14:167253f4e170 1856
wolfSSL 14:167253f4e170 1857 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 1858 sp_2048_mont_norm_45(norm, m);
wolfSSL 14:167253f4e170 1859
wolfSSL 14:167253f4e170 1860 if (reduceA)
wolfSSL 14:167253f4e170 1861 err = sp_2048_mod_45(t[1], a, m);
wolfSSL 14:167253f4e170 1862 else
wolfSSL 14:167253f4e170 1863 XMEMCPY(t[1], a, sizeof(sp_digit) * 45);
wolfSSL 14:167253f4e170 1864 }
wolfSSL 14:167253f4e170 1865 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1866 sp_2048_mul_45(t[1], t[1], norm);
wolfSSL 14:167253f4e170 1867 err = sp_2048_mod_45(t[1], t[1], m);
wolfSSL 14:167253f4e170 1868 }
wolfSSL 14:167253f4e170 1869
wolfSSL 14:167253f4e170 1870 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1871 i = bits / 23;
wolfSSL 14:167253f4e170 1872 c = bits % 23;
wolfSSL 14:167253f4e170 1873 n = e[i--] << (23 - c);
wolfSSL 14:167253f4e170 1874 for (; ; c--) {
wolfSSL 14:167253f4e170 1875 if (c == 0) {
wolfSSL 14:167253f4e170 1876 if (i == -1)
wolfSSL 14:167253f4e170 1877 break;
wolfSSL 14:167253f4e170 1878
wolfSSL 14:167253f4e170 1879 n = e[i--];
wolfSSL 14:167253f4e170 1880 c = 23;
wolfSSL 14:167253f4e170 1881 }
wolfSSL 14:167253f4e170 1882
wolfSSL 14:167253f4e170 1883 y = (n >> 22) & 1;
wolfSSL 14:167253f4e170 1884 n <<= 1;
wolfSSL 14:167253f4e170 1885
wolfSSL 14:167253f4e170 1886 sp_2048_mont_mul_45(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 1887
wolfSSL 14:167253f4e170 1888 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 1889 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 1890 sizeof(*t[2]) * 45 * 2);
wolfSSL 14:167253f4e170 1891 sp_2048_mont_sqr_45(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 1892 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 1893 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 1894 sizeof(*t[2]) * 45 * 2);
wolfSSL 14:167253f4e170 1895 }
wolfSSL 14:167253f4e170 1896
wolfSSL 14:167253f4e170 1897 sp_2048_mont_reduce_45(t[0], m, mp);
wolfSSL 14:167253f4e170 1898 n = sp_2048_cmp_45(t[0], m);
wolfSSL 14:167253f4e170 1899 sp_2048_cond_sub_45(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 1900 XMEMCPY(r, t[0], sizeof(*r) * 45 * 2);
wolfSSL 14:167253f4e170 1901
wolfSSL 14:167253f4e170 1902 }
wolfSSL 14:167253f4e170 1903
wolfSSL 14:167253f4e170 1904 if (td != NULL)
wolfSSL 14:167253f4e170 1905 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1906
wolfSSL 14:167253f4e170 1907 return err;
wolfSSL 14:167253f4e170 1908 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 1909 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1910 sp_digit t[3][90];
wolfSSL 14:167253f4e170 1911 #else
wolfSSL 14:167253f4e170 1912 sp_digit* td;
wolfSSL 14:167253f4e170 1913 sp_digit* t[3];
wolfSSL 14:167253f4e170 1914 #endif
wolfSSL 14:167253f4e170 1915 sp_digit* norm;
wolfSSL 14:167253f4e170 1916 sp_digit mp = 1;
wolfSSL 14:167253f4e170 1917 sp_digit n;
wolfSSL 14:167253f4e170 1918 int i;
wolfSSL 14:167253f4e170 1919 int c, y;
wolfSSL 14:167253f4e170 1920 int err = MP_OKAY;
wolfSSL 14:167253f4e170 1921
wolfSSL 14:167253f4e170 1922 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1923 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 45 * 2, NULL,
wolfSSL 14:167253f4e170 1924 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1925 if (td == NULL)
wolfSSL 14:167253f4e170 1926 err = MEMORY_E;
wolfSSL 14:167253f4e170 1927
wolfSSL 14:167253f4e170 1928 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1929 t[0] = td;
wolfSSL 14:167253f4e170 1930 t[1] = &td[45 * 2];
wolfSSL 14:167253f4e170 1931 t[2] = &td[2 * 45 * 2];
wolfSSL 14:167253f4e170 1932 norm = t[0];
wolfSSL 14:167253f4e170 1933 }
wolfSSL 14:167253f4e170 1934 #else
wolfSSL 14:167253f4e170 1935 norm = t[0];
wolfSSL 14:167253f4e170 1936 #endif
wolfSSL 14:167253f4e170 1937
wolfSSL 14:167253f4e170 1938 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1939 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 1940 sp_2048_mont_norm_45(norm, m);
wolfSSL 14:167253f4e170 1941
wolfSSL 14:167253f4e170 1942 if (reduceA) {
wolfSSL 14:167253f4e170 1943 err = sp_2048_mod_45(t[1], a, m);
wolfSSL 14:167253f4e170 1944 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1945 sp_2048_mul_45(t[1], t[1], norm);
wolfSSL 14:167253f4e170 1946 err = sp_2048_mod_45(t[1], t[1], m);
wolfSSL 14:167253f4e170 1947 }
wolfSSL 14:167253f4e170 1948 }
wolfSSL 14:167253f4e170 1949 else {
wolfSSL 14:167253f4e170 1950 sp_2048_mul_45(t[1], a, norm);
wolfSSL 14:167253f4e170 1951 err = sp_2048_mod_45(t[1], t[1], m);
wolfSSL 14:167253f4e170 1952 }
wolfSSL 14:167253f4e170 1953 }
wolfSSL 14:167253f4e170 1954
wolfSSL 14:167253f4e170 1955 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1956 i = bits / 23;
wolfSSL 14:167253f4e170 1957 c = bits % 23;
wolfSSL 14:167253f4e170 1958 n = e[i--] << (23 - c);
wolfSSL 14:167253f4e170 1959 for (; ; c--) {
wolfSSL 14:167253f4e170 1960 if (c == 0) {
wolfSSL 14:167253f4e170 1961 if (i == -1)
wolfSSL 14:167253f4e170 1962 break;
wolfSSL 14:167253f4e170 1963
wolfSSL 14:167253f4e170 1964 n = e[i--];
wolfSSL 14:167253f4e170 1965 c = 23;
wolfSSL 14:167253f4e170 1966 }
wolfSSL 14:167253f4e170 1967
wolfSSL 14:167253f4e170 1968 y = (n >> 22) & 1;
wolfSSL 14:167253f4e170 1969 n <<= 1;
wolfSSL 14:167253f4e170 1970
wolfSSL 14:167253f4e170 1971 sp_2048_mont_mul_45(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 1972
wolfSSL 14:167253f4e170 1973 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 1974 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 1975 sp_2048_mont_sqr_45(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 1976 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 1977 ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 1978 }
wolfSSL 14:167253f4e170 1979
wolfSSL 14:167253f4e170 1980 sp_2048_mont_reduce_45(t[0], m, mp);
wolfSSL 14:167253f4e170 1981 n = sp_2048_cmp_45(t[0], m);
wolfSSL 14:167253f4e170 1982 sp_2048_cond_sub_45(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 1983 XMEMCPY(r, t[0], sizeof(t[0]));
wolfSSL 14:167253f4e170 1984 }
wolfSSL 14:167253f4e170 1985
wolfSSL 14:167253f4e170 1986 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1987 if (td != NULL)
wolfSSL 14:167253f4e170 1988 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1989 #endif
wolfSSL 14:167253f4e170 1990
wolfSSL 14:167253f4e170 1991 return err;
wolfSSL 14:167253f4e170 1992 #else
wolfSSL 14:167253f4e170 1993 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1994 sp_digit t[32][90];
wolfSSL 14:167253f4e170 1995 #else
wolfSSL 14:167253f4e170 1996 sp_digit* t[32];
wolfSSL 14:167253f4e170 1997 sp_digit* td;
wolfSSL 14:167253f4e170 1998 #endif
wolfSSL 14:167253f4e170 1999 sp_digit* norm;
wolfSSL 14:167253f4e170 2000 sp_digit rt[90];
wolfSSL 14:167253f4e170 2001 sp_digit mp = 1;
wolfSSL 14:167253f4e170 2002 sp_digit n;
wolfSSL 14:167253f4e170 2003 int i;
wolfSSL 14:167253f4e170 2004 int c, y;
wolfSSL 14:167253f4e170 2005 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2006
wolfSSL 14:167253f4e170 2007 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2008 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 90, NULL,
wolfSSL 14:167253f4e170 2009 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2010 if (td == NULL)
wolfSSL 14:167253f4e170 2011 err = MEMORY_E;
wolfSSL 14:167253f4e170 2012
wolfSSL 14:167253f4e170 2013 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2014 for (i=0; i<32; i++)
wolfSSL 14:167253f4e170 2015 t[i] = td + i * 90;
wolfSSL 14:167253f4e170 2016 norm = t[0];
wolfSSL 14:167253f4e170 2017 }
wolfSSL 14:167253f4e170 2018 #else
wolfSSL 14:167253f4e170 2019 norm = t[0];
wolfSSL 14:167253f4e170 2020 #endif
wolfSSL 14:167253f4e170 2021
wolfSSL 14:167253f4e170 2022 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2023 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 2024 sp_2048_mont_norm_45(norm, m);
wolfSSL 14:167253f4e170 2025
wolfSSL 14:167253f4e170 2026 if (reduceA) {
wolfSSL 14:167253f4e170 2027 err = sp_2048_mod_45(t[1], a, m);
wolfSSL 14:167253f4e170 2028 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2029 sp_2048_mul_45(t[1], t[1], norm);
wolfSSL 14:167253f4e170 2030 err = sp_2048_mod_45(t[1], t[1], m);
wolfSSL 14:167253f4e170 2031 }
wolfSSL 14:167253f4e170 2032 }
wolfSSL 14:167253f4e170 2033 else {
wolfSSL 14:167253f4e170 2034 sp_2048_mul_45(t[1], a, norm);
wolfSSL 14:167253f4e170 2035 err = sp_2048_mod_45(t[1], t[1], m);
wolfSSL 14:167253f4e170 2036 }
wolfSSL 14:167253f4e170 2037 }
wolfSSL 14:167253f4e170 2038
wolfSSL 14:167253f4e170 2039 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2040 sp_2048_mont_sqr_45(t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 2041 sp_2048_mont_mul_45(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 2042 sp_2048_mont_sqr_45(t[ 4], t[ 2], m, mp);
wolfSSL 14:167253f4e170 2043 sp_2048_mont_mul_45(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 14:167253f4e170 2044 sp_2048_mont_sqr_45(t[ 6], t[ 3], m, mp);
wolfSSL 14:167253f4e170 2045 sp_2048_mont_mul_45(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 14:167253f4e170 2046 sp_2048_mont_sqr_45(t[ 8], t[ 4], m, mp);
wolfSSL 14:167253f4e170 2047 sp_2048_mont_mul_45(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 14:167253f4e170 2048 sp_2048_mont_sqr_45(t[10], t[ 5], m, mp);
wolfSSL 14:167253f4e170 2049 sp_2048_mont_mul_45(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 14:167253f4e170 2050 sp_2048_mont_sqr_45(t[12], t[ 6], m, mp);
wolfSSL 14:167253f4e170 2051 sp_2048_mont_mul_45(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 14:167253f4e170 2052 sp_2048_mont_sqr_45(t[14], t[ 7], m, mp);
wolfSSL 14:167253f4e170 2053 sp_2048_mont_mul_45(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 14:167253f4e170 2054 sp_2048_mont_sqr_45(t[16], t[ 8], m, mp);
wolfSSL 14:167253f4e170 2055 sp_2048_mont_mul_45(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 14:167253f4e170 2056 sp_2048_mont_sqr_45(t[18], t[ 9], m, mp);
wolfSSL 14:167253f4e170 2057 sp_2048_mont_mul_45(t[19], t[10], t[ 9], m, mp);
wolfSSL 14:167253f4e170 2058 sp_2048_mont_sqr_45(t[20], t[10], m, mp);
wolfSSL 14:167253f4e170 2059 sp_2048_mont_mul_45(t[21], t[11], t[10], m, mp);
wolfSSL 14:167253f4e170 2060 sp_2048_mont_sqr_45(t[22], t[11], m, mp);
wolfSSL 14:167253f4e170 2061 sp_2048_mont_mul_45(t[23], t[12], t[11], m, mp);
wolfSSL 14:167253f4e170 2062 sp_2048_mont_sqr_45(t[24], t[12], m, mp);
wolfSSL 14:167253f4e170 2063 sp_2048_mont_mul_45(t[25], t[13], t[12], m, mp);
wolfSSL 14:167253f4e170 2064 sp_2048_mont_sqr_45(t[26], t[13], m, mp);
wolfSSL 14:167253f4e170 2065 sp_2048_mont_mul_45(t[27], t[14], t[13], m, mp);
wolfSSL 14:167253f4e170 2066 sp_2048_mont_sqr_45(t[28], t[14], m, mp);
wolfSSL 14:167253f4e170 2067 sp_2048_mont_mul_45(t[29], t[15], t[14], m, mp);
wolfSSL 14:167253f4e170 2068 sp_2048_mont_sqr_45(t[30], t[15], m, mp);
wolfSSL 14:167253f4e170 2069 sp_2048_mont_mul_45(t[31], t[16], t[15], m, mp);
wolfSSL 14:167253f4e170 2070
wolfSSL 14:167253f4e170 2071 bits = ((bits + 4) / 5) * 5;
wolfSSL 14:167253f4e170 2072 i = ((bits + 22) / 23) - 1;
wolfSSL 14:167253f4e170 2073 c = bits % 23;
wolfSSL 14:167253f4e170 2074 if (c == 0)
wolfSSL 14:167253f4e170 2075 c = 23;
wolfSSL 14:167253f4e170 2076 if (i < 45)
wolfSSL 14:167253f4e170 2077 n = e[i--] << (32 - c);
wolfSSL 14:167253f4e170 2078 else {
wolfSSL 14:167253f4e170 2079 n = 0;
wolfSSL 14:167253f4e170 2080 i--;
wolfSSL 14:167253f4e170 2081 }
wolfSSL 14:167253f4e170 2082 if (c < 5) {
wolfSSL 14:167253f4e170 2083 n |= e[i--] << (9 - c);
wolfSSL 14:167253f4e170 2084 c += 23;
wolfSSL 14:167253f4e170 2085 }
wolfSSL 14:167253f4e170 2086 y = n >> 27;
wolfSSL 14:167253f4e170 2087 n <<= 5;
wolfSSL 14:167253f4e170 2088 c -= 5;
wolfSSL 14:167253f4e170 2089 XMEMCPY(rt, t[y], sizeof(rt));
wolfSSL 14:167253f4e170 2090 for (; i>=0 || c>=5; ) {
wolfSSL 14:167253f4e170 2091 if (c < 5) {
wolfSSL 14:167253f4e170 2092 n |= e[i--] << (9 - c);
wolfSSL 14:167253f4e170 2093 c += 23;
wolfSSL 14:167253f4e170 2094 }
wolfSSL 14:167253f4e170 2095 y = (n >> 27) & 0x1f;
wolfSSL 14:167253f4e170 2096 n <<= 5;
wolfSSL 14:167253f4e170 2097 c -= 5;
wolfSSL 14:167253f4e170 2098
wolfSSL 14:167253f4e170 2099 sp_2048_mont_sqr_45(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2100 sp_2048_mont_sqr_45(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2101 sp_2048_mont_sqr_45(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2102 sp_2048_mont_sqr_45(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2103 sp_2048_mont_sqr_45(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2104
wolfSSL 14:167253f4e170 2105 sp_2048_mont_mul_45(rt, rt, t[y], m, mp);
wolfSSL 14:167253f4e170 2106 }
wolfSSL 14:167253f4e170 2107
wolfSSL 14:167253f4e170 2108 sp_2048_mont_reduce_45(rt, m, mp);
wolfSSL 14:167253f4e170 2109 n = sp_2048_cmp_45(rt, m);
wolfSSL 14:167253f4e170 2110 sp_2048_cond_sub_45(rt, rt, m, (n < 0) - 1);
wolfSSL 14:167253f4e170 2111 XMEMCPY(r, rt, sizeof(rt));
wolfSSL 14:167253f4e170 2112 }
wolfSSL 14:167253f4e170 2113
wolfSSL 14:167253f4e170 2114 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2115 if (td != NULL)
wolfSSL 14:167253f4e170 2116 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2117 #endif
wolfSSL 14:167253f4e170 2118
wolfSSL 14:167253f4e170 2119 return err;
wolfSSL 14:167253f4e170 2120 #endif
wolfSSL 14:167253f4e170 2121 }
wolfSSL 14:167253f4e170 2122
wolfSSL 14:167253f4e170 2123 #endif /* !SP_RSA_PRIVATE_EXP_D && WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 2124
wolfSSL 14:167253f4e170 2125 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 14:167253f4e170 2126 * Given m must be 2048 bits, just need to subtract.
wolfSSL 14:167253f4e170 2127 *
wolfSSL 14:167253f4e170 2128 * r A single precision number.
wolfSSL 14:167253f4e170 2129 * m A signle precision number.
wolfSSL 14:167253f4e170 2130 */
wolfSSL 14:167253f4e170 2131 static void sp_2048_mont_norm_90(sp_digit* r, sp_digit* m)
wolfSSL 14:167253f4e170 2132 {
wolfSSL 14:167253f4e170 2133 /* Set r = 2^n - 1. */
wolfSSL 14:167253f4e170 2134 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2135 int i;
wolfSSL 14:167253f4e170 2136
wolfSSL 14:167253f4e170 2137 for (i=0; i<89; i++)
wolfSSL 14:167253f4e170 2138 r[i] = 0x7fffff;
wolfSSL 14:167253f4e170 2139 #else
wolfSSL 14:167253f4e170 2140 int i;
wolfSSL 14:167253f4e170 2141
wolfSSL 14:167253f4e170 2142 for (i = 0; i < 88; i += 8) {
wolfSSL 14:167253f4e170 2143 r[i + 0] = 0x7fffff;
wolfSSL 14:167253f4e170 2144 r[i + 1] = 0x7fffff;
wolfSSL 14:167253f4e170 2145 r[i + 2] = 0x7fffff;
wolfSSL 14:167253f4e170 2146 r[i + 3] = 0x7fffff;
wolfSSL 14:167253f4e170 2147 r[i + 4] = 0x7fffff;
wolfSSL 14:167253f4e170 2148 r[i + 5] = 0x7fffff;
wolfSSL 14:167253f4e170 2149 r[i + 6] = 0x7fffff;
wolfSSL 14:167253f4e170 2150 r[i + 7] = 0x7fffff;
wolfSSL 14:167253f4e170 2151 }
wolfSSL 14:167253f4e170 2152 r[88] = 0x7fffff;
wolfSSL 14:167253f4e170 2153 #endif
wolfSSL 14:167253f4e170 2154 r[89] = 0x1l;
wolfSSL 14:167253f4e170 2155
wolfSSL 14:167253f4e170 2156 /* r = (2^n - 1) mod n */
wolfSSL 14:167253f4e170 2157 sp_2048_sub_90(r, r, m);
wolfSSL 14:167253f4e170 2158
wolfSSL 14:167253f4e170 2159 /* Add one so r = 2^n mod m */
wolfSSL 14:167253f4e170 2160 r[0] += 1;
wolfSSL 14:167253f4e170 2161 }
wolfSSL 14:167253f4e170 2162
wolfSSL 14:167253f4e170 2163 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 2164 *
wolfSSL 14:167253f4e170 2165 * a A single precision integer.
wolfSSL 14:167253f4e170 2166 * b A single precision integer.
wolfSSL 14:167253f4e170 2167 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 2168 * respectively.
wolfSSL 14:167253f4e170 2169 */
wolfSSL 14:167253f4e170 2170 static sp_digit sp_2048_cmp_90(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 2171 {
wolfSSL 14:167253f4e170 2172 sp_digit r = 0;
wolfSSL 14:167253f4e170 2173 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2174 int i;
wolfSSL 14:167253f4e170 2175
wolfSSL 14:167253f4e170 2176 for (i=89; i>=0; i--)
wolfSSL 14:167253f4e170 2177 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 2178 #else
wolfSSL 14:167253f4e170 2179 int i;
wolfSSL 14:167253f4e170 2180
wolfSSL 14:167253f4e170 2181 r |= (a[89] - b[89]) & (0 - !r);
wolfSSL 14:167253f4e170 2182 r |= (a[88] - b[88]) & (0 - !r);
wolfSSL 14:167253f4e170 2183 for (i = 80; i >= 0; i -= 8) {
wolfSSL 14:167253f4e170 2184 r |= (a[i + 7] - b[i + 7]) & (0 - !r);
wolfSSL 14:167253f4e170 2185 r |= (a[i + 6] - b[i + 6]) & (0 - !r);
wolfSSL 14:167253f4e170 2186 r |= (a[i + 5] - b[i + 5]) & (0 - !r);
wolfSSL 14:167253f4e170 2187 r |= (a[i + 4] - b[i + 4]) & (0 - !r);
wolfSSL 14:167253f4e170 2188 r |= (a[i + 3] - b[i + 3]) & (0 - !r);
wolfSSL 14:167253f4e170 2189 r |= (a[i + 2] - b[i + 2]) & (0 - !r);
wolfSSL 14:167253f4e170 2190 r |= (a[i + 1] - b[i + 1]) & (0 - !r);
wolfSSL 14:167253f4e170 2191 r |= (a[i + 0] - b[i + 0]) & (0 - !r);
wolfSSL 14:167253f4e170 2192 }
wolfSSL 14:167253f4e170 2193 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 2194
wolfSSL 14:167253f4e170 2195 return r;
wolfSSL 14:167253f4e170 2196 }
wolfSSL 14:167253f4e170 2197
wolfSSL 14:167253f4e170 2198 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 2199 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 2200 *
wolfSSL 14:167253f4e170 2201 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 2202 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 2203 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 2204 * m Mask value to apply.
wolfSSL 14:167253f4e170 2205 */
wolfSSL 14:167253f4e170 2206 static void sp_2048_cond_sub_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 2207 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 2208 {
wolfSSL 14:167253f4e170 2209 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2210 int i;
wolfSSL 14:167253f4e170 2211
wolfSSL 14:167253f4e170 2212 for (i = 0; i < 90; i++)
wolfSSL 14:167253f4e170 2213 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 2214 #else
wolfSSL 14:167253f4e170 2215 int i;
wolfSSL 14:167253f4e170 2216
wolfSSL 14:167253f4e170 2217 for (i = 0; i < 88; i += 8) {
wolfSSL 14:167253f4e170 2218 r[i + 0] = a[i + 0] - (b[i + 0] & m);
wolfSSL 14:167253f4e170 2219 r[i + 1] = a[i + 1] - (b[i + 1] & m);
wolfSSL 14:167253f4e170 2220 r[i + 2] = a[i + 2] - (b[i + 2] & m);
wolfSSL 14:167253f4e170 2221 r[i + 3] = a[i + 3] - (b[i + 3] & m);
wolfSSL 14:167253f4e170 2222 r[i + 4] = a[i + 4] - (b[i + 4] & m);
wolfSSL 14:167253f4e170 2223 r[i + 5] = a[i + 5] - (b[i + 5] & m);
wolfSSL 14:167253f4e170 2224 r[i + 6] = a[i + 6] - (b[i + 6] & m);
wolfSSL 14:167253f4e170 2225 r[i + 7] = a[i + 7] - (b[i + 7] & m);
wolfSSL 14:167253f4e170 2226 }
wolfSSL 14:167253f4e170 2227 r[88] = a[88] - (b[88] & m);
wolfSSL 14:167253f4e170 2228 r[89] = a[89] - (b[89] & m);
wolfSSL 14:167253f4e170 2229 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 2230 }
wolfSSL 14:167253f4e170 2231
wolfSSL 14:167253f4e170 2232 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 2233 *
wolfSSL 14:167253f4e170 2234 * r A single precision integer.
wolfSSL 14:167253f4e170 2235 * a A single precision integer.
wolfSSL 14:167253f4e170 2236 * b A scalar.
wolfSSL 14:167253f4e170 2237 */
wolfSSL 14:167253f4e170 2238 SP_NOINLINE static void sp_2048_mul_add_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 2239 const sp_digit b)
wolfSSL 14:167253f4e170 2240 {
wolfSSL 14:167253f4e170 2241 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2242 int64_t tb = b;
wolfSSL 14:167253f4e170 2243 int64_t t = 0;
wolfSSL 14:167253f4e170 2244 int i;
wolfSSL 14:167253f4e170 2245
wolfSSL 14:167253f4e170 2246 for (i = 0; i < 90; i++) {
wolfSSL 14:167253f4e170 2247 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 2248 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 2249 t >>= 23;
wolfSSL 14:167253f4e170 2250 }
wolfSSL 14:167253f4e170 2251 r[90] += t;
wolfSSL 14:167253f4e170 2252 #else
wolfSSL 14:167253f4e170 2253 int64_t tb = b;
wolfSSL 14:167253f4e170 2254 int64_t t[8];
wolfSSL 14:167253f4e170 2255 int i;
wolfSSL 14:167253f4e170 2256
wolfSSL 14:167253f4e170 2257 t[0] = tb * a[0]; r[0] += t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 2258 for (i = 0; i < 88; i += 8) {
wolfSSL 14:167253f4e170 2259 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 2260 r[i+1] += (t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 2261 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 2262 r[i+2] += (t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 2263 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 2264 r[i+3] += (t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 2265 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 2266 r[i+4] += (t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 2267 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 2268 r[i+5] += (t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 2269 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 2270 r[i+6] += (t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 2271 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 2272 r[i+7] += (t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 2273 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 2274 r[i+8] += (t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 2275 }
wolfSSL 14:167253f4e170 2276 t[1] = tb * a[89]; r[89] += (t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 2277 r[90] += t[1] >> 23;
wolfSSL 14:167253f4e170 2278 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 2279 }
wolfSSL 14:167253f4e170 2280
wolfSSL 14:167253f4e170 2281 /* Normalize the values in each word to 23.
wolfSSL 14:167253f4e170 2282 *
wolfSSL 14:167253f4e170 2283 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 2284 */
wolfSSL 14:167253f4e170 2285 static void sp_2048_norm_90(sp_digit* a)
wolfSSL 14:167253f4e170 2286 {
wolfSSL 14:167253f4e170 2287 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2288 int i;
wolfSSL 14:167253f4e170 2289 for (i = 0; i < 89; i++) {
wolfSSL 14:167253f4e170 2290 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 2291 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 2292 }
wolfSSL 14:167253f4e170 2293 #else
wolfSSL 14:167253f4e170 2294 int i;
wolfSSL 14:167253f4e170 2295 for (i = 0; i < 88; i += 8) {
wolfSSL 14:167253f4e170 2296 a[i+1] += a[i+0] >> 23; a[i+0] &= 0x7fffff;
wolfSSL 14:167253f4e170 2297 a[i+2] += a[i+1] >> 23; a[i+1] &= 0x7fffff;
wolfSSL 14:167253f4e170 2298 a[i+3] += a[i+2] >> 23; a[i+2] &= 0x7fffff;
wolfSSL 14:167253f4e170 2299 a[i+4] += a[i+3] >> 23; a[i+3] &= 0x7fffff;
wolfSSL 14:167253f4e170 2300 a[i+5] += a[i+4] >> 23; a[i+4] &= 0x7fffff;
wolfSSL 14:167253f4e170 2301 a[i+6] += a[i+5] >> 23; a[i+5] &= 0x7fffff;
wolfSSL 14:167253f4e170 2302 a[i+7] += a[i+6] >> 23; a[i+6] &= 0x7fffff;
wolfSSL 14:167253f4e170 2303 a[i+8] += a[i+7] >> 23; a[i+7] &= 0x7fffff;
wolfSSL 14:167253f4e170 2304 a[i+9] += a[i+8] >> 23; a[i+8] &= 0x7fffff;
wolfSSL 14:167253f4e170 2305 }
wolfSSL 14:167253f4e170 2306 a[88+1] += a[88] >> 23;
wolfSSL 14:167253f4e170 2307 a[88] &= 0x7fffff;
wolfSSL 14:167253f4e170 2308 #endif
wolfSSL 14:167253f4e170 2309 }
wolfSSL 14:167253f4e170 2310
wolfSSL 14:167253f4e170 2311 /* Shift the result in the high 2048 bits down to the bottom.
wolfSSL 14:167253f4e170 2312 *
wolfSSL 14:167253f4e170 2313 * r A single precision number.
wolfSSL 14:167253f4e170 2314 * a A single precision number.
wolfSSL 14:167253f4e170 2315 */
wolfSSL 14:167253f4e170 2316 static void sp_2048_mont_shift_90(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 2317 {
wolfSSL 14:167253f4e170 2318 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2319 int i;
wolfSSL 14:167253f4e170 2320 int64_t n = a[89] >> 1;
wolfSSL 14:167253f4e170 2321 n += ((int64_t)a[90]) << 22;
wolfSSL 14:167253f4e170 2322
wolfSSL 14:167253f4e170 2323 for (i = 0; i < 89; i++) {
wolfSSL 14:167253f4e170 2324 r[i] = n & 0x7fffff;
wolfSSL 14:167253f4e170 2325 n >>= 23;
wolfSSL 14:167253f4e170 2326 n += ((int64_t)a[91 + i]) << 22;
wolfSSL 14:167253f4e170 2327 }
wolfSSL 14:167253f4e170 2328 r[89] = (sp_digit)n;
wolfSSL 14:167253f4e170 2329 #else
wolfSSL 14:167253f4e170 2330 int i;
wolfSSL 14:167253f4e170 2331 int64_t n = a[89] >> 1;
wolfSSL 14:167253f4e170 2332 n += ((int64_t)a[90]) << 22;
wolfSSL 14:167253f4e170 2333 for (i = 0; i < 88; i += 8) {
wolfSSL 14:167253f4e170 2334 r[i + 0] = n & 0x7fffff;
wolfSSL 14:167253f4e170 2335 n >>= 23; n += ((int64_t)a[i + 91]) << 22;
wolfSSL 14:167253f4e170 2336 r[i + 1] = n & 0x7fffff;
wolfSSL 14:167253f4e170 2337 n >>= 23; n += ((int64_t)a[i + 92]) << 22;
wolfSSL 14:167253f4e170 2338 r[i + 2] = n & 0x7fffff;
wolfSSL 14:167253f4e170 2339 n >>= 23; n += ((int64_t)a[i + 93]) << 22;
wolfSSL 14:167253f4e170 2340 r[i + 3] = n & 0x7fffff;
wolfSSL 14:167253f4e170 2341 n >>= 23; n += ((int64_t)a[i + 94]) << 22;
wolfSSL 14:167253f4e170 2342 r[i + 4] = n & 0x7fffff;
wolfSSL 14:167253f4e170 2343 n >>= 23; n += ((int64_t)a[i + 95]) << 22;
wolfSSL 14:167253f4e170 2344 r[i + 5] = n & 0x7fffff;
wolfSSL 14:167253f4e170 2345 n >>= 23; n += ((int64_t)a[i + 96]) << 22;
wolfSSL 14:167253f4e170 2346 r[i + 6] = n & 0x7fffff;
wolfSSL 14:167253f4e170 2347 n >>= 23; n += ((int64_t)a[i + 97]) << 22;
wolfSSL 14:167253f4e170 2348 r[i + 7] = n & 0x7fffff;
wolfSSL 14:167253f4e170 2349 n >>= 23; n += ((int64_t)a[i + 98]) << 22;
wolfSSL 14:167253f4e170 2350 }
wolfSSL 14:167253f4e170 2351 r[88] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[179]) << 22;
wolfSSL 14:167253f4e170 2352 r[89] = (sp_digit)n;
wolfSSL 14:167253f4e170 2353 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 2354 XMEMSET(&r[90], 0, sizeof(*r) * 90);
wolfSSL 14:167253f4e170 2355 }
wolfSSL 14:167253f4e170 2356
wolfSSL 14:167253f4e170 2357 /* Reduce the number back to 2048 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 2358 *
wolfSSL 14:167253f4e170 2359 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 2360 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 2361 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 2362 */
wolfSSL 14:167253f4e170 2363 static void sp_2048_mont_reduce_90(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 2364 {
wolfSSL 14:167253f4e170 2365 int i;
wolfSSL 14:167253f4e170 2366 sp_digit mu;
wolfSSL 14:167253f4e170 2367
wolfSSL 14:167253f4e170 2368 if (mp != 1) {
wolfSSL 14:167253f4e170 2369 for (i=0; i<89; i++) {
wolfSSL 14:167253f4e170 2370 mu = (a[i] * mp) & 0x7fffff;
wolfSSL 14:167253f4e170 2371 sp_2048_mul_add_90(a+i, m, mu);
wolfSSL 14:167253f4e170 2372 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 2373 }
wolfSSL 14:167253f4e170 2374 mu = (a[i] * mp) & 0x1l;
wolfSSL 14:167253f4e170 2375 sp_2048_mul_add_90(a+i, m, mu);
wolfSSL 14:167253f4e170 2376 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 2377 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 2378 }
wolfSSL 14:167253f4e170 2379 else {
wolfSSL 14:167253f4e170 2380 for (i=0; i<89; i++) {
wolfSSL 14:167253f4e170 2381 mu = a[i] & 0x7fffff;
wolfSSL 14:167253f4e170 2382 sp_2048_mul_add_90(a+i, m, mu);
wolfSSL 14:167253f4e170 2383 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 2384 }
wolfSSL 14:167253f4e170 2385 mu = a[i] & 0x1l;
wolfSSL 14:167253f4e170 2386 sp_2048_mul_add_90(a+i, m, mu);
wolfSSL 14:167253f4e170 2387 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 2388 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 2389 }
wolfSSL 14:167253f4e170 2390
wolfSSL 14:167253f4e170 2391 sp_2048_mont_shift_90(a, a);
wolfSSL 14:167253f4e170 2392 sp_2048_cond_sub_90(a, a, m, 0 - ((a[89] >> 1) > 0));
wolfSSL 14:167253f4e170 2393 sp_2048_norm_90(a);
wolfSSL 14:167253f4e170 2394 }
wolfSSL 14:167253f4e170 2395
wolfSSL 14:167253f4e170 2396 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 2397 * (r = a * b mod m)
wolfSSL 14:167253f4e170 2398 *
wolfSSL 14:167253f4e170 2399 * r Result of multiplication.
wolfSSL 14:167253f4e170 2400 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 2401 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 2402 * m Modulus (prime).
wolfSSL 14:167253f4e170 2403 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 2404 */
wolfSSL 14:167253f4e170 2405 static void sp_2048_mont_mul_90(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 2406 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 2407 {
wolfSSL 14:167253f4e170 2408 sp_2048_mul_90(r, a, b);
wolfSSL 14:167253f4e170 2409 sp_2048_mont_reduce_90(r, m, mp);
wolfSSL 14:167253f4e170 2410 }
wolfSSL 14:167253f4e170 2411
wolfSSL 14:167253f4e170 2412 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 2413 *
wolfSSL 14:167253f4e170 2414 * r Result of squaring.
wolfSSL 14:167253f4e170 2415 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 2416 * m Modulus (prime).
wolfSSL 14:167253f4e170 2417 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 2418 */
wolfSSL 14:167253f4e170 2419 static void sp_2048_mont_sqr_90(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 2420 sp_digit mp)
wolfSSL 14:167253f4e170 2421 {
wolfSSL 14:167253f4e170 2422 sp_2048_sqr_90(r, a);
wolfSSL 14:167253f4e170 2423 sp_2048_mont_reduce_90(r, m, mp);
wolfSSL 14:167253f4e170 2424 }
wolfSSL 14:167253f4e170 2425
wolfSSL 14:167253f4e170 2426 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 2427 *
wolfSSL 14:167253f4e170 2428 * r A single precision integer.
wolfSSL 14:167253f4e170 2429 * a A single precision integer.
wolfSSL 14:167253f4e170 2430 * b A scalar.
wolfSSL 14:167253f4e170 2431 */
wolfSSL 14:167253f4e170 2432 SP_NOINLINE static void sp_2048_mul_d_180(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 2433 const sp_digit b)
wolfSSL 14:167253f4e170 2434 {
wolfSSL 14:167253f4e170 2435 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2436 int64_t tb = b;
wolfSSL 14:167253f4e170 2437 int64_t t = 0;
wolfSSL 14:167253f4e170 2438 int i;
wolfSSL 14:167253f4e170 2439
wolfSSL 14:167253f4e170 2440 for (i = 0; i < 180; i++) {
wolfSSL 14:167253f4e170 2441 t += tb * a[i];
wolfSSL 14:167253f4e170 2442 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 2443 t >>= 23;
wolfSSL 14:167253f4e170 2444 }
wolfSSL 14:167253f4e170 2445 r[180] = (sp_digit)t;
wolfSSL 14:167253f4e170 2446 #else
wolfSSL 14:167253f4e170 2447 int64_t tb = b;
wolfSSL 14:167253f4e170 2448 int64_t t[8];
wolfSSL 14:167253f4e170 2449 int i;
wolfSSL 14:167253f4e170 2450
wolfSSL 14:167253f4e170 2451 t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 2452 for (i = 0; i < 176; i += 8) {
wolfSSL 14:167253f4e170 2453 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 2454 r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 2455 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 2456 r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 2457 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 2458 r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 2459 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 2460 r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 2461 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 2462 r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 2463 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 2464 r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 2465 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 2466 r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 2467 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 2468 r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 2469 }
wolfSSL 14:167253f4e170 2470 t[1] = tb * a[177];
wolfSSL 14:167253f4e170 2471 r[177] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 2472 t[2] = tb * a[178];
wolfSSL 14:167253f4e170 2473 r[178] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 2474 t[3] = tb * a[179];
wolfSSL 14:167253f4e170 2475 r[179] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 2476 r[180] = (sp_digit)(t[3] >> 23);
wolfSSL 14:167253f4e170 2477 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 2478 }
wolfSSL 14:167253f4e170 2479
wolfSSL 14:167253f4e170 2480 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 2481 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 2482 *
wolfSSL 14:167253f4e170 2483 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 2484 * a A single precision number to add with.
wolfSSL 14:167253f4e170 2485 * b A single precision number to add.
wolfSSL 14:167253f4e170 2486 * m Mask value to apply.
wolfSSL 14:167253f4e170 2487 */
wolfSSL 14:167253f4e170 2488 static void sp_2048_cond_add_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 2489 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 2490 {
wolfSSL 14:167253f4e170 2491 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2492 int i;
wolfSSL 14:167253f4e170 2493
wolfSSL 14:167253f4e170 2494 for (i = 0; i < 90; i++)
wolfSSL 14:167253f4e170 2495 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 2496 #else
wolfSSL 14:167253f4e170 2497 int i;
wolfSSL 14:167253f4e170 2498
wolfSSL 14:167253f4e170 2499 for (i = 0; i < 88; i += 8) {
wolfSSL 14:167253f4e170 2500 r[i + 0] = a[i + 0] + (b[i + 0] & m);
wolfSSL 14:167253f4e170 2501 r[i + 1] = a[i + 1] + (b[i + 1] & m);
wolfSSL 14:167253f4e170 2502 r[i + 2] = a[i + 2] + (b[i + 2] & m);
wolfSSL 14:167253f4e170 2503 r[i + 3] = a[i + 3] + (b[i + 3] & m);
wolfSSL 14:167253f4e170 2504 r[i + 4] = a[i + 4] + (b[i + 4] & m);
wolfSSL 14:167253f4e170 2505 r[i + 5] = a[i + 5] + (b[i + 5] & m);
wolfSSL 14:167253f4e170 2506 r[i + 6] = a[i + 6] + (b[i + 6] & m);
wolfSSL 14:167253f4e170 2507 r[i + 7] = a[i + 7] + (b[i + 7] & m);
wolfSSL 14:167253f4e170 2508 }
wolfSSL 14:167253f4e170 2509 r[88] = a[88] + (b[88] & m);
wolfSSL 14:167253f4e170 2510 r[89] = a[89] + (b[89] & m);
wolfSSL 14:167253f4e170 2511 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 2512 }
wolfSSL 14:167253f4e170 2513
wolfSSL 14:167253f4e170 2514 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 2515 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 2516 *
wolfSSL 14:167253f4e170 2517 * r A single precision integer.
wolfSSL 14:167253f4e170 2518 * a A single precision integer.
wolfSSL 14:167253f4e170 2519 * b A single precision integer.
wolfSSL 14:167253f4e170 2520 */
wolfSSL 14:167253f4e170 2521 SP_NOINLINE static int sp_2048_sub_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 2522 const sp_digit* b)
wolfSSL 14:167253f4e170 2523 {
wolfSSL 14:167253f4e170 2524 int i;
wolfSSL 14:167253f4e170 2525
wolfSSL 14:167253f4e170 2526 for (i = 0; i < 90; i++)
wolfSSL 14:167253f4e170 2527 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 2528
wolfSSL 14:167253f4e170 2529 return 0;
wolfSSL 14:167253f4e170 2530 }
wolfSSL 14:167253f4e170 2531
wolfSSL 14:167253f4e170 2532 #endif
wolfSSL 14:167253f4e170 2533 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 2534 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 2535 *
wolfSSL 14:167253f4e170 2536 * r A single precision integer.
wolfSSL 14:167253f4e170 2537 * a A single precision integer.
wolfSSL 14:167253f4e170 2538 * b A single precision integer.
wolfSSL 14:167253f4e170 2539 */
wolfSSL 14:167253f4e170 2540 SP_NOINLINE static int sp_2048_add_90(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 2541 const sp_digit* b)
wolfSSL 14:167253f4e170 2542 {
wolfSSL 14:167253f4e170 2543 int i;
wolfSSL 14:167253f4e170 2544
wolfSSL 14:167253f4e170 2545 for (i = 0; i < 90; i++)
wolfSSL 14:167253f4e170 2546 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 2547
wolfSSL 14:167253f4e170 2548 return 0;
wolfSSL 14:167253f4e170 2549 }
wolfSSL 14:167253f4e170 2550 #endif
wolfSSL 14:167253f4e170 2551 SP_NOINLINE static void sp_2048_rshift_90(sp_digit* r, sp_digit* a, byte n)
wolfSSL 14:167253f4e170 2552 {
wolfSSL 14:167253f4e170 2553 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2554 int i;
wolfSSL 14:167253f4e170 2555
wolfSSL 14:167253f4e170 2556 for (i=0; i<89; i++)
wolfSSL 14:167253f4e170 2557 r[i] = ((a[i] >> n) | (a[i + 1] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2558 #else
wolfSSL 14:167253f4e170 2559 r[0] = ((a[0] >> n) | (a[1] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2560 r[1] = ((a[1] >> n) | (a[2] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2561 r[2] = ((a[2] >> n) | (a[3] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2562 r[3] = ((a[3] >> n) | (a[4] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2563 r[4] = ((a[4] >> n) | (a[5] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2564 r[5] = ((a[5] >> n) | (a[6] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2565 r[6] = ((a[6] >> n) | (a[7] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2566 r[7] = ((a[7] >> n) | (a[8] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2567 r[8] = ((a[8] >> n) | (a[9] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2568 r[9] = ((a[9] >> n) | (a[10] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2569 r[10] = ((a[10] >> n) | (a[11] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2570 r[11] = ((a[11] >> n) | (a[12] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2571 r[12] = ((a[12] >> n) | (a[13] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2572 r[13] = ((a[13] >> n) | (a[14] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2573 r[14] = ((a[14] >> n) | (a[15] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2574 r[15] = ((a[15] >> n) | (a[16] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2575 r[16] = ((a[16] >> n) | (a[17] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2576 r[17] = ((a[17] >> n) | (a[18] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2577 r[18] = ((a[18] >> n) | (a[19] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2578 r[19] = ((a[19] >> n) | (a[20] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2579 r[20] = ((a[20] >> n) | (a[21] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2580 r[21] = ((a[21] >> n) | (a[22] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2581 r[22] = ((a[22] >> n) | (a[23] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2582 r[23] = ((a[23] >> n) | (a[24] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2583 r[24] = ((a[24] >> n) | (a[25] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2584 r[25] = ((a[25] >> n) | (a[26] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2585 r[26] = ((a[26] >> n) | (a[27] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2586 r[27] = ((a[27] >> n) | (a[28] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2587 r[28] = ((a[28] >> n) | (a[29] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2588 r[29] = ((a[29] >> n) | (a[30] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2589 r[30] = ((a[30] >> n) | (a[31] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2590 r[31] = ((a[31] >> n) | (a[32] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2591 r[32] = ((a[32] >> n) | (a[33] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2592 r[33] = ((a[33] >> n) | (a[34] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2593 r[34] = ((a[34] >> n) | (a[35] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2594 r[35] = ((a[35] >> n) | (a[36] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2595 r[36] = ((a[36] >> n) | (a[37] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2596 r[37] = ((a[37] >> n) | (a[38] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2597 r[38] = ((a[38] >> n) | (a[39] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2598 r[39] = ((a[39] >> n) | (a[40] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2599 r[40] = ((a[40] >> n) | (a[41] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2600 r[41] = ((a[41] >> n) | (a[42] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2601 r[42] = ((a[42] >> n) | (a[43] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2602 r[43] = ((a[43] >> n) | (a[44] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2603 r[44] = ((a[44] >> n) | (a[45] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2604 r[45] = ((a[45] >> n) | (a[46] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2605 r[46] = ((a[46] >> n) | (a[47] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2606 r[47] = ((a[47] >> n) | (a[48] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2607 r[48] = ((a[48] >> n) | (a[49] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2608 r[49] = ((a[49] >> n) | (a[50] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2609 r[50] = ((a[50] >> n) | (a[51] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2610 r[51] = ((a[51] >> n) | (a[52] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2611 r[52] = ((a[52] >> n) | (a[53] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2612 r[53] = ((a[53] >> n) | (a[54] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2613 r[54] = ((a[54] >> n) | (a[55] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2614 r[55] = ((a[55] >> n) | (a[56] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2615 r[56] = ((a[56] >> n) | (a[57] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2616 r[57] = ((a[57] >> n) | (a[58] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2617 r[58] = ((a[58] >> n) | (a[59] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2618 r[59] = ((a[59] >> n) | (a[60] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2619 r[60] = ((a[60] >> n) | (a[61] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2620 r[61] = ((a[61] >> n) | (a[62] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2621 r[62] = ((a[62] >> n) | (a[63] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2622 r[63] = ((a[63] >> n) | (a[64] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2623 r[64] = ((a[64] >> n) | (a[65] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2624 r[65] = ((a[65] >> n) | (a[66] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2625 r[66] = ((a[66] >> n) | (a[67] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2626 r[67] = ((a[67] >> n) | (a[68] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2627 r[68] = ((a[68] >> n) | (a[69] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2628 r[69] = ((a[69] >> n) | (a[70] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2629 r[70] = ((a[70] >> n) | (a[71] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2630 r[71] = ((a[71] >> n) | (a[72] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2631 r[72] = ((a[72] >> n) | (a[73] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2632 r[73] = ((a[73] >> n) | (a[74] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2633 r[74] = ((a[74] >> n) | (a[75] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2634 r[75] = ((a[75] >> n) | (a[76] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2635 r[76] = ((a[76] >> n) | (a[77] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2636 r[77] = ((a[77] >> n) | (a[78] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2637 r[78] = ((a[78] >> n) | (a[79] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2638 r[79] = ((a[79] >> n) | (a[80] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2639 r[80] = ((a[80] >> n) | (a[81] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2640 r[81] = ((a[81] >> n) | (a[82] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2641 r[82] = ((a[82] >> n) | (a[83] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2642 r[83] = ((a[83] >> n) | (a[84] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2643 r[84] = ((a[84] >> n) | (a[85] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2644 r[85] = ((a[85] >> n) | (a[86] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2645 r[86] = ((a[86] >> n) | (a[87] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2646 r[87] = ((a[87] >> n) | (a[88] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2647 r[88] = ((a[88] >> n) | (a[89] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 2648 #endif
wolfSSL 14:167253f4e170 2649 r[89] = a[89] >> n;
wolfSSL 14:167253f4e170 2650 }
wolfSSL 14:167253f4e170 2651
wolfSSL 14:167253f4e170 2652 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 2653 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 2654 *
wolfSSL 14:167253f4e170 2655 * a Nmber to be divided.
wolfSSL 14:167253f4e170 2656 * d Number to divide with.
wolfSSL 14:167253f4e170 2657 * m Multiplier result.
wolfSSL 14:167253f4e170 2658 * r Remainder from the division.
wolfSSL 14:167253f4e170 2659 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 2660 */
wolfSSL 14:167253f4e170 2661 static int sp_2048_div_90(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 2662 sp_digit* r)
wolfSSL 14:167253f4e170 2663 {
wolfSSL 14:167253f4e170 2664 int i;
wolfSSL 14:167253f4e170 2665 int64_t d1;
wolfSSL 14:167253f4e170 2666 sp_digit div, r1;
wolfSSL 14:167253f4e170 2667 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2668 sp_digit* td;
wolfSSL 14:167253f4e170 2669 #else
wolfSSL 14:167253f4e170 2670 sp_digit t1d[180 + 1], t2d[90 + 1], sdd[90 + 1];
wolfSSL 14:167253f4e170 2671 #endif
wolfSSL 14:167253f4e170 2672 sp_digit* t1;
wolfSSL 14:167253f4e170 2673 sp_digit* t2;
wolfSSL 14:167253f4e170 2674 sp_digit* sd;
wolfSSL 14:167253f4e170 2675 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2676
wolfSSL 14:167253f4e170 2677 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2678 td = XMALLOC(sizeof(sp_digit) * (4 * 90 + 3), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2679 if (td != NULL) {
wolfSSL 14:167253f4e170 2680 t1 = td;
wolfSSL 14:167253f4e170 2681 t2 = td + 180 + 1;
wolfSSL 14:167253f4e170 2682 sd = t2 + 90 + 1;
wolfSSL 14:167253f4e170 2683 }
wolfSSL 14:167253f4e170 2684 else
wolfSSL 14:167253f4e170 2685 err = MEMORY_E;
wolfSSL 14:167253f4e170 2686 #else
wolfSSL 14:167253f4e170 2687 t1 = t1d;
wolfSSL 14:167253f4e170 2688 t2 = t2d;
wolfSSL 14:167253f4e170 2689 sd = sdd;
wolfSSL 14:167253f4e170 2690 #endif
wolfSSL 14:167253f4e170 2691
wolfSSL 14:167253f4e170 2692 (void)m;
wolfSSL 14:167253f4e170 2693
wolfSSL 14:167253f4e170 2694 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2695 sp_2048_mul_d_90(sd, d, 1 << 22);
wolfSSL 14:167253f4e170 2696 sp_2048_mul_d_180(t1, a, 1 << 22);
wolfSSL 14:167253f4e170 2697 div = sd[89];
wolfSSL 14:167253f4e170 2698 for (i=90; i>=0; i--) {
wolfSSL 14:167253f4e170 2699 t1[90 + i] += t1[90 + i - 1] >> 23;
wolfSSL 14:167253f4e170 2700 t1[90 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 2701 d1 = t1[90 + i];
wolfSSL 14:167253f4e170 2702 d1 <<= 23;
wolfSSL 14:167253f4e170 2703 d1 += t1[90 + i - 1];
wolfSSL 14:167253f4e170 2704 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 2705
wolfSSL 14:167253f4e170 2706 sp_2048_mul_d_90(t2, sd, r1);
wolfSSL 14:167253f4e170 2707 sp_2048_sub_90(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 2708 t1[90 + i] -= t2[90];
wolfSSL 14:167253f4e170 2709 t1[90 + i] += t1[90 + i - 1] >> 23;
wolfSSL 14:167253f4e170 2710 t1[90 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 2711 r1 = (((-t1[90 + i]) << 23) - t1[90 + i - 1]) / div;
wolfSSL 14:167253f4e170 2712 r1 -= t1[90 + i];
wolfSSL 14:167253f4e170 2713 sp_2048_mul_d_90(t2, sd, r1);
wolfSSL 14:167253f4e170 2714 sp_2048_add_90(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 2715 t1[90 + i] += t1[90 + i - 1] >> 23;
wolfSSL 14:167253f4e170 2716 t1[90 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 2717 }
wolfSSL 14:167253f4e170 2718 t1[90 - 1] += t1[90 - 2] >> 23;
wolfSSL 14:167253f4e170 2719 t1[90 - 2] &= 0x7fffff;
wolfSSL 14:167253f4e170 2720 d1 = t1[90 - 1];
wolfSSL 14:167253f4e170 2721 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 2722
wolfSSL 14:167253f4e170 2723 sp_2048_mul_d_90(t2, sd, r1);
wolfSSL 14:167253f4e170 2724 sp_2048_sub_90(t1, t1, t2);
wolfSSL 14:167253f4e170 2725 XMEMCPY(r, t1, sizeof(*r) * 2 * 90);
wolfSSL 14:167253f4e170 2726 for (i=0; i<88; i++) {
wolfSSL 14:167253f4e170 2727 r[i+1] += r[i] >> 23;
wolfSSL 14:167253f4e170 2728 r[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 2729 }
wolfSSL 14:167253f4e170 2730 sp_2048_cond_add_90(r, r, sd, 0 - (r[89] < 0));
wolfSSL 14:167253f4e170 2731 }
wolfSSL 14:167253f4e170 2732
wolfSSL 14:167253f4e170 2733 sp_2048_rshift_90(r, r, 22);
wolfSSL 14:167253f4e170 2734
wolfSSL 14:167253f4e170 2735 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2736 if (td != NULL)
wolfSSL 14:167253f4e170 2737 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2738 #endif
wolfSSL 14:167253f4e170 2739
wolfSSL 14:167253f4e170 2740 return err;
wolfSSL 14:167253f4e170 2741 }
wolfSSL 14:167253f4e170 2742
wolfSSL 14:167253f4e170 2743 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 2744 *
wolfSSL 14:167253f4e170 2745 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 2746 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 2747 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 2748 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 2749 */
wolfSSL 14:167253f4e170 2750 static int sp_2048_mod_90(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 2751 {
wolfSSL 14:167253f4e170 2752 return sp_2048_div_90(a, m, NULL, r);
wolfSSL 14:167253f4e170 2753 }
wolfSSL 14:167253f4e170 2754
wolfSSL 14:167253f4e170 2755 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 14:167253f4e170 2756 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 14:167253f4e170 2757 *
wolfSSL 14:167253f4e170 2758 * r A single precision number that is the result of the operation.
wolfSSL 14:167253f4e170 2759 * a A single precision number being exponentiated.
wolfSSL 14:167253f4e170 2760 * e A single precision number that is the exponent.
wolfSSL 14:167253f4e170 2761 * bits The number of bits in the exponent.
wolfSSL 14:167253f4e170 2762 * m A single precision number that is the modulus.
wolfSSL 14:167253f4e170 2763 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 14:167253f4e170 2764 */
wolfSSL 14:167253f4e170 2765 static int sp_2048_mod_exp_90(sp_digit* r, sp_digit* a, sp_digit* e, int bits,
wolfSSL 14:167253f4e170 2766 sp_digit* m, int reduceA)
wolfSSL 14:167253f4e170 2767 {
wolfSSL 14:167253f4e170 2768 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2769 sp_digit* td;
wolfSSL 14:167253f4e170 2770 sp_digit* t[3];
wolfSSL 14:167253f4e170 2771 sp_digit* norm;
wolfSSL 14:167253f4e170 2772 sp_digit mp = 1;
wolfSSL 14:167253f4e170 2773 sp_digit n;
wolfSSL 14:167253f4e170 2774 int i;
wolfSSL 14:167253f4e170 2775 int c, y;
wolfSSL 14:167253f4e170 2776 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2777
wolfSSL 14:167253f4e170 2778 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 90 * 2, NULL,
wolfSSL 14:167253f4e170 2779 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2780 if (td == NULL)
wolfSSL 14:167253f4e170 2781 err = MEMORY_E;
wolfSSL 14:167253f4e170 2782
wolfSSL 14:167253f4e170 2783 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2784 XMEMSET(td, 0, sizeof(*td) * 3 * 90 * 2);
wolfSSL 14:167253f4e170 2785
wolfSSL 14:167253f4e170 2786 norm = t[0] = td;
wolfSSL 14:167253f4e170 2787 t[1] = &td[90 * 2];
wolfSSL 14:167253f4e170 2788 t[2] = &td[2 * 90 * 2];
wolfSSL 14:167253f4e170 2789
wolfSSL 14:167253f4e170 2790 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 2791 sp_2048_mont_norm_90(norm, m);
wolfSSL 14:167253f4e170 2792
wolfSSL 14:167253f4e170 2793 if (reduceA)
wolfSSL 14:167253f4e170 2794 err = sp_2048_mod_90(t[1], a, m);
wolfSSL 14:167253f4e170 2795 else
wolfSSL 14:167253f4e170 2796 XMEMCPY(t[1], a, sizeof(sp_digit) * 90);
wolfSSL 14:167253f4e170 2797 }
wolfSSL 14:167253f4e170 2798 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2799 sp_2048_mul_90(t[1], t[1], norm);
wolfSSL 14:167253f4e170 2800 err = sp_2048_mod_90(t[1], t[1], m);
wolfSSL 14:167253f4e170 2801 }
wolfSSL 14:167253f4e170 2802
wolfSSL 14:167253f4e170 2803 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2804 i = bits / 23;
wolfSSL 14:167253f4e170 2805 c = bits % 23;
wolfSSL 14:167253f4e170 2806 n = e[i--] << (23 - c);
wolfSSL 14:167253f4e170 2807 for (; ; c--) {
wolfSSL 14:167253f4e170 2808 if (c == 0) {
wolfSSL 14:167253f4e170 2809 if (i == -1)
wolfSSL 14:167253f4e170 2810 break;
wolfSSL 14:167253f4e170 2811
wolfSSL 14:167253f4e170 2812 n = e[i--];
wolfSSL 14:167253f4e170 2813 c = 23;
wolfSSL 14:167253f4e170 2814 }
wolfSSL 14:167253f4e170 2815
wolfSSL 14:167253f4e170 2816 y = (n >> 22) & 1;
wolfSSL 14:167253f4e170 2817 n <<= 1;
wolfSSL 14:167253f4e170 2818
wolfSSL 14:167253f4e170 2819 sp_2048_mont_mul_90(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 2820
wolfSSL 14:167253f4e170 2821 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 2822 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 2823 sizeof(*t[2]) * 90 * 2);
wolfSSL 14:167253f4e170 2824 sp_2048_mont_sqr_90(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 2825 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 2826 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 2827 sizeof(*t[2]) * 90 * 2);
wolfSSL 14:167253f4e170 2828 }
wolfSSL 14:167253f4e170 2829
wolfSSL 14:167253f4e170 2830 sp_2048_mont_reduce_90(t[0], m, mp);
wolfSSL 14:167253f4e170 2831 n = sp_2048_cmp_90(t[0], m);
wolfSSL 14:167253f4e170 2832 sp_2048_cond_sub_90(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 2833 XMEMCPY(r, t[0], sizeof(*r) * 90 * 2);
wolfSSL 14:167253f4e170 2834
wolfSSL 14:167253f4e170 2835 }
wolfSSL 14:167253f4e170 2836
wolfSSL 14:167253f4e170 2837 if (td != NULL)
wolfSSL 14:167253f4e170 2838 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2839
wolfSSL 14:167253f4e170 2840 return err;
wolfSSL 14:167253f4e170 2841 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 2842 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2843 sp_digit t[3][180];
wolfSSL 14:167253f4e170 2844 #else
wolfSSL 14:167253f4e170 2845 sp_digit* td;
wolfSSL 14:167253f4e170 2846 sp_digit* t[3];
wolfSSL 14:167253f4e170 2847 #endif
wolfSSL 14:167253f4e170 2848 sp_digit* norm;
wolfSSL 14:167253f4e170 2849 sp_digit mp = 1;
wolfSSL 14:167253f4e170 2850 sp_digit n;
wolfSSL 14:167253f4e170 2851 int i;
wolfSSL 14:167253f4e170 2852 int c, y;
wolfSSL 14:167253f4e170 2853 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2854
wolfSSL 14:167253f4e170 2855 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2856 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 90 * 2, NULL,
wolfSSL 14:167253f4e170 2857 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2858 if (td == NULL)
wolfSSL 14:167253f4e170 2859 err = MEMORY_E;
wolfSSL 14:167253f4e170 2860
wolfSSL 14:167253f4e170 2861 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2862 t[0] = td;
wolfSSL 14:167253f4e170 2863 t[1] = &td[90 * 2];
wolfSSL 14:167253f4e170 2864 t[2] = &td[2 * 90 * 2];
wolfSSL 14:167253f4e170 2865 norm = t[0];
wolfSSL 14:167253f4e170 2866 }
wolfSSL 14:167253f4e170 2867 #else
wolfSSL 14:167253f4e170 2868 norm = t[0];
wolfSSL 14:167253f4e170 2869 #endif
wolfSSL 14:167253f4e170 2870
wolfSSL 14:167253f4e170 2871 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2872 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 2873 sp_2048_mont_norm_90(norm, m);
wolfSSL 14:167253f4e170 2874
wolfSSL 14:167253f4e170 2875 if (reduceA) {
wolfSSL 14:167253f4e170 2876 err = sp_2048_mod_90(t[1], a, m);
wolfSSL 14:167253f4e170 2877 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2878 sp_2048_mul_90(t[1], t[1], norm);
wolfSSL 14:167253f4e170 2879 err = sp_2048_mod_90(t[1], t[1], m);
wolfSSL 14:167253f4e170 2880 }
wolfSSL 14:167253f4e170 2881 }
wolfSSL 14:167253f4e170 2882 else {
wolfSSL 14:167253f4e170 2883 sp_2048_mul_90(t[1], a, norm);
wolfSSL 14:167253f4e170 2884 err = sp_2048_mod_90(t[1], t[1], m);
wolfSSL 14:167253f4e170 2885 }
wolfSSL 14:167253f4e170 2886 }
wolfSSL 14:167253f4e170 2887
wolfSSL 14:167253f4e170 2888 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2889 i = bits / 23;
wolfSSL 14:167253f4e170 2890 c = bits % 23;
wolfSSL 14:167253f4e170 2891 n = e[i--] << (23 - c);
wolfSSL 14:167253f4e170 2892 for (; ; c--) {
wolfSSL 14:167253f4e170 2893 if (c == 0) {
wolfSSL 14:167253f4e170 2894 if (i == -1)
wolfSSL 14:167253f4e170 2895 break;
wolfSSL 14:167253f4e170 2896
wolfSSL 14:167253f4e170 2897 n = e[i--];
wolfSSL 14:167253f4e170 2898 c = 23;
wolfSSL 14:167253f4e170 2899 }
wolfSSL 14:167253f4e170 2900
wolfSSL 14:167253f4e170 2901 y = (n >> 22) & 1;
wolfSSL 14:167253f4e170 2902 n <<= 1;
wolfSSL 14:167253f4e170 2903
wolfSSL 14:167253f4e170 2904 sp_2048_mont_mul_90(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 2905
wolfSSL 14:167253f4e170 2906 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 2907 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 2908 sp_2048_mont_sqr_90(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 2909 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 2910 ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 2911 }
wolfSSL 14:167253f4e170 2912
wolfSSL 14:167253f4e170 2913 sp_2048_mont_reduce_90(t[0], m, mp);
wolfSSL 14:167253f4e170 2914 n = sp_2048_cmp_90(t[0], m);
wolfSSL 14:167253f4e170 2915 sp_2048_cond_sub_90(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 2916 XMEMCPY(r, t[0], sizeof(t[0]));
wolfSSL 14:167253f4e170 2917 }
wolfSSL 14:167253f4e170 2918
wolfSSL 14:167253f4e170 2919 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2920 if (td != NULL)
wolfSSL 14:167253f4e170 2921 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2922 #endif
wolfSSL 14:167253f4e170 2923
wolfSSL 14:167253f4e170 2924 return err;
wolfSSL 14:167253f4e170 2925 #else
wolfSSL 14:167253f4e170 2926 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2927 sp_digit t[32][180];
wolfSSL 14:167253f4e170 2928 #else
wolfSSL 14:167253f4e170 2929 sp_digit* t[32];
wolfSSL 14:167253f4e170 2930 sp_digit* td;
wolfSSL 14:167253f4e170 2931 #endif
wolfSSL 14:167253f4e170 2932 sp_digit* norm;
wolfSSL 14:167253f4e170 2933 sp_digit rt[180];
wolfSSL 14:167253f4e170 2934 sp_digit mp = 1;
wolfSSL 14:167253f4e170 2935 sp_digit n;
wolfSSL 14:167253f4e170 2936 int i;
wolfSSL 14:167253f4e170 2937 int c, y;
wolfSSL 14:167253f4e170 2938 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2939
wolfSSL 14:167253f4e170 2940 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2941 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 180, NULL,
wolfSSL 14:167253f4e170 2942 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2943 if (td == NULL)
wolfSSL 14:167253f4e170 2944 err = MEMORY_E;
wolfSSL 14:167253f4e170 2945
wolfSSL 14:167253f4e170 2946 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2947 for (i=0; i<32; i++)
wolfSSL 14:167253f4e170 2948 t[i] = td + i * 180;
wolfSSL 14:167253f4e170 2949 norm = t[0];
wolfSSL 14:167253f4e170 2950 }
wolfSSL 14:167253f4e170 2951 #else
wolfSSL 14:167253f4e170 2952 norm = t[0];
wolfSSL 14:167253f4e170 2953 #endif
wolfSSL 14:167253f4e170 2954
wolfSSL 14:167253f4e170 2955 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2956 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 2957 sp_2048_mont_norm_90(norm, m);
wolfSSL 14:167253f4e170 2958
wolfSSL 14:167253f4e170 2959 if (reduceA) {
wolfSSL 14:167253f4e170 2960 err = sp_2048_mod_90(t[1], a, m);
wolfSSL 14:167253f4e170 2961 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2962 sp_2048_mul_90(t[1], t[1], norm);
wolfSSL 14:167253f4e170 2963 err = sp_2048_mod_90(t[1], t[1], m);
wolfSSL 14:167253f4e170 2964 }
wolfSSL 14:167253f4e170 2965 }
wolfSSL 14:167253f4e170 2966 else {
wolfSSL 14:167253f4e170 2967 sp_2048_mul_90(t[1], a, norm);
wolfSSL 14:167253f4e170 2968 err = sp_2048_mod_90(t[1], t[1], m);
wolfSSL 14:167253f4e170 2969 }
wolfSSL 14:167253f4e170 2970 }
wolfSSL 14:167253f4e170 2971
wolfSSL 14:167253f4e170 2972 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2973 sp_2048_mont_sqr_90(t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 2974 sp_2048_mont_mul_90(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 2975 sp_2048_mont_sqr_90(t[ 4], t[ 2], m, mp);
wolfSSL 14:167253f4e170 2976 sp_2048_mont_mul_90(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 14:167253f4e170 2977 sp_2048_mont_sqr_90(t[ 6], t[ 3], m, mp);
wolfSSL 14:167253f4e170 2978 sp_2048_mont_mul_90(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 14:167253f4e170 2979 sp_2048_mont_sqr_90(t[ 8], t[ 4], m, mp);
wolfSSL 14:167253f4e170 2980 sp_2048_mont_mul_90(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 14:167253f4e170 2981 sp_2048_mont_sqr_90(t[10], t[ 5], m, mp);
wolfSSL 14:167253f4e170 2982 sp_2048_mont_mul_90(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 14:167253f4e170 2983 sp_2048_mont_sqr_90(t[12], t[ 6], m, mp);
wolfSSL 14:167253f4e170 2984 sp_2048_mont_mul_90(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 14:167253f4e170 2985 sp_2048_mont_sqr_90(t[14], t[ 7], m, mp);
wolfSSL 14:167253f4e170 2986 sp_2048_mont_mul_90(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 14:167253f4e170 2987 sp_2048_mont_sqr_90(t[16], t[ 8], m, mp);
wolfSSL 14:167253f4e170 2988 sp_2048_mont_mul_90(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 14:167253f4e170 2989 sp_2048_mont_sqr_90(t[18], t[ 9], m, mp);
wolfSSL 14:167253f4e170 2990 sp_2048_mont_mul_90(t[19], t[10], t[ 9], m, mp);
wolfSSL 14:167253f4e170 2991 sp_2048_mont_sqr_90(t[20], t[10], m, mp);
wolfSSL 14:167253f4e170 2992 sp_2048_mont_mul_90(t[21], t[11], t[10], m, mp);
wolfSSL 14:167253f4e170 2993 sp_2048_mont_sqr_90(t[22], t[11], m, mp);
wolfSSL 14:167253f4e170 2994 sp_2048_mont_mul_90(t[23], t[12], t[11], m, mp);
wolfSSL 14:167253f4e170 2995 sp_2048_mont_sqr_90(t[24], t[12], m, mp);
wolfSSL 14:167253f4e170 2996 sp_2048_mont_mul_90(t[25], t[13], t[12], m, mp);
wolfSSL 14:167253f4e170 2997 sp_2048_mont_sqr_90(t[26], t[13], m, mp);
wolfSSL 14:167253f4e170 2998 sp_2048_mont_mul_90(t[27], t[14], t[13], m, mp);
wolfSSL 14:167253f4e170 2999 sp_2048_mont_sqr_90(t[28], t[14], m, mp);
wolfSSL 14:167253f4e170 3000 sp_2048_mont_mul_90(t[29], t[15], t[14], m, mp);
wolfSSL 14:167253f4e170 3001 sp_2048_mont_sqr_90(t[30], t[15], m, mp);
wolfSSL 14:167253f4e170 3002 sp_2048_mont_mul_90(t[31], t[16], t[15], m, mp);
wolfSSL 14:167253f4e170 3003
wolfSSL 14:167253f4e170 3004 bits = ((bits + 4) / 5) * 5;
wolfSSL 14:167253f4e170 3005 i = ((bits + 22) / 23) - 1;
wolfSSL 14:167253f4e170 3006 c = bits % 23;
wolfSSL 14:167253f4e170 3007 if (c == 0)
wolfSSL 14:167253f4e170 3008 c = 23;
wolfSSL 14:167253f4e170 3009 if (i < 90)
wolfSSL 14:167253f4e170 3010 n = e[i--] << (32 - c);
wolfSSL 14:167253f4e170 3011 else {
wolfSSL 14:167253f4e170 3012 n = 0;
wolfSSL 14:167253f4e170 3013 i--;
wolfSSL 14:167253f4e170 3014 }
wolfSSL 14:167253f4e170 3015 if (c < 5) {
wolfSSL 14:167253f4e170 3016 n |= e[i--] << (9 - c);
wolfSSL 14:167253f4e170 3017 c += 23;
wolfSSL 14:167253f4e170 3018 }
wolfSSL 14:167253f4e170 3019 y = n >> 27;
wolfSSL 14:167253f4e170 3020 n <<= 5;
wolfSSL 14:167253f4e170 3021 c -= 5;
wolfSSL 14:167253f4e170 3022 XMEMCPY(rt, t[y], sizeof(rt));
wolfSSL 14:167253f4e170 3023 for (; i>=0 || c>=5; ) {
wolfSSL 14:167253f4e170 3024 if (c < 5) {
wolfSSL 14:167253f4e170 3025 n |= e[i--] << (9 - c);
wolfSSL 14:167253f4e170 3026 c += 23;
wolfSSL 14:167253f4e170 3027 }
wolfSSL 14:167253f4e170 3028 y = (n >> 27) & 0x1f;
wolfSSL 14:167253f4e170 3029 n <<= 5;
wolfSSL 14:167253f4e170 3030 c -= 5;
wolfSSL 14:167253f4e170 3031
wolfSSL 14:167253f4e170 3032 sp_2048_mont_sqr_90(rt, rt, m, mp);
wolfSSL 14:167253f4e170 3033 sp_2048_mont_sqr_90(rt, rt, m, mp);
wolfSSL 14:167253f4e170 3034 sp_2048_mont_sqr_90(rt, rt, m, mp);
wolfSSL 14:167253f4e170 3035 sp_2048_mont_sqr_90(rt, rt, m, mp);
wolfSSL 14:167253f4e170 3036 sp_2048_mont_sqr_90(rt, rt, m, mp);
wolfSSL 14:167253f4e170 3037
wolfSSL 14:167253f4e170 3038 sp_2048_mont_mul_90(rt, rt, t[y], m, mp);
wolfSSL 14:167253f4e170 3039 }
wolfSSL 14:167253f4e170 3040
wolfSSL 14:167253f4e170 3041 sp_2048_mont_reduce_90(rt, m, mp);
wolfSSL 14:167253f4e170 3042 n = sp_2048_cmp_90(rt, m);
wolfSSL 14:167253f4e170 3043 sp_2048_cond_sub_90(rt, rt, m, (n < 0) - 1);
wolfSSL 14:167253f4e170 3044 XMEMCPY(r, rt, sizeof(rt));
wolfSSL 14:167253f4e170 3045 }
wolfSSL 14:167253f4e170 3046
wolfSSL 14:167253f4e170 3047 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3048 if (td != NULL)
wolfSSL 14:167253f4e170 3049 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3050 #endif
wolfSSL 14:167253f4e170 3051
wolfSSL 14:167253f4e170 3052 return err;
wolfSSL 14:167253f4e170 3053 #endif
wolfSSL 14:167253f4e170 3054 }
wolfSSL 14:167253f4e170 3055 #endif /* SP_RSA_PRIVATE_EXP_D || WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 3056
wolfSSL 14:167253f4e170 3057 #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \
wolfSSL 14:167253f4e170 3058 !defined(RSA_LOW_MEM)
wolfSSL 14:167253f4e170 3059 /* AND m into each word of a and store in r.
wolfSSL 14:167253f4e170 3060 *
wolfSSL 14:167253f4e170 3061 * r A single precision integer.
wolfSSL 14:167253f4e170 3062 * a A single precision integer.
wolfSSL 14:167253f4e170 3063 * m Mask to AND against each digit.
wolfSSL 14:167253f4e170 3064 */
wolfSSL 14:167253f4e170 3065 static void sp_2048_mask_45(sp_digit* r, sp_digit* a, sp_digit m)
wolfSSL 14:167253f4e170 3066 {
wolfSSL 14:167253f4e170 3067 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3068 int i;
wolfSSL 14:167253f4e170 3069
wolfSSL 14:167253f4e170 3070 for (i=0; i<45; i++)
wolfSSL 14:167253f4e170 3071 r[i] = a[i] & m;
wolfSSL 14:167253f4e170 3072 #else
wolfSSL 14:167253f4e170 3073 int i;
wolfSSL 14:167253f4e170 3074
wolfSSL 14:167253f4e170 3075 for (i = 0; i < 40; i += 8) {
wolfSSL 14:167253f4e170 3076 r[i+0] = a[i+0] & m;
wolfSSL 14:167253f4e170 3077 r[i+1] = a[i+1] & m;
wolfSSL 14:167253f4e170 3078 r[i+2] = a[i+2] & m;
wolfSSL 14:167253f4e170 3079 r[i+3] = a[i+3] & m;
wolfSSL 14:167253f4e170 3080 r[i+4] = a[i+4] & m;
wolfSSL 14:167253f4e170 3081 r[i+5] = a[i+5] & m;
wolfSSL 14:167253f4e170 3082 r[i+6] = a[i+6] & m;
wolfSSL 14:167253f4e170 3083 r[i+7] = a[i+7] & m;
wolfSSL 14:167253f4e170 3084 }
wolfSSL 14:167253f4e170 3085 r[40] = a[40] & m;
wolfSSL 14:167253f4e170 3086 r[41] = a[41] & m;
wolfSSL 14:167253f4e170 3087 r[42] = a[42] & m;
wolfSSL 14:167253f4e170 3088 r[43] = a[43] & m;
wolfSSL 14:167253f4e170 3089 r[44] = a[44] & m;
wolfSSL 14:167253f4e170 3090 #endif
wolfSSL 14:167253f4e170 3091 }
wolfSSL 14:167253f4e170 3092
wolfSSL 14:167253f4e170 3093 #endif
wolfSSL 14:167253f4e170 3094 #ifdef WOLFSSL_HAVE_SP_RSA
wolfSSL 14:167253f4e170 3095 /* RSA public key operation.
wolfSSL 14:167253f4e170 3096 *
wolfSSL 14:167253f4e170 3097 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 14:167253f4e170 3098 * inLen Number of bytes in base.
wolfSSL 14:167253f4e170 3099 * em Public exponent.
wolfSSL 14:167253f4e170 3100 * mm Modulus.
wolfSSL 14:167253f4e170 3101 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 3102 * Must be at least 256 bytes long.
wolfSSL 14:167253f4e170 3103 * outLen Number of bytes in result.
wolfSSL 14:167253f4e170 3104 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 14:167253f4e170 3105 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 14:167253f4e170 3106 */
wolfSSL 14:167253f4e170 3107 int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,
wolfSSL 14:167253f4e170 3108 byte* out, word32* outLen)
wolfSSL 14:167253f4e170 3109 {
wolfSSL 14:167253f4e170 3110 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3111 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3112 sp_digit* a;
wolfSSL 14:167253f4e170 3113 sp_digit* m;
wolfSSL 14:167253f4e170 3114 sp_digit* r;
wolfSSL 14:167253f4e170 3115 sp_digit* norm;
wolfSSL 14:167253f4e170 3116 sp_digit e[1];
wolfSSL 14:167253f4e170 3117 sp_digit mp;
wolfSSL 14:167253f4e170 3118 int i;
wolfSSL 14:167253f4e170 3119 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3120
wolfSSL 14:167253f4e170 3121 if (*outLen < 256)
wolfSSL 14:167253f4e170 3122 err = MP_TO_E;
wolfSSL 14:167253f4e170 3123 if (err == MP_OKAY && (mp_count_bits(em) > 23 || inLen > 256 ||
wolfSSL 14:167253f4e170 3124 mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 3125 err = MP_READ_E;
wolfSSL 14:167253f4e170 3126
wolfSSL 14:167253f4e170 3127 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3128 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 90 * 5, NULL,
wolfSSL 14:167253f4e170 3129 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3130 if (d == NULL)
wolfSSL 14:167253f4e170 3131 err = MEMORY_E;
wolfSSL 14:167253f4e170 3132 }
wolfSSL 14:167253f4e170 3133
wolfSSL 14:167253f4e170 3134 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3135 a = d;
wolfSSL 14:167253f4e170 3136 r = a + 90 * 2;
wolfSSL 14:167253f4e170 3137 m = r + 90 * 2;
wolfSSL 14:167253f4e170 3138 norm = r;
wolfSSL 14:167253f4e170 3139
wolfSSL 14:167253f4e170 3140 sp_2048_from_bin(a, 90, in, inLen);
wolfSSL 14:167253f4e170 3141 #if DIGIT_BIT >= 23
wolfSSL 14:167253f4e170 3142 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 3143 #else
wolfSSL 14:167253f4e170 3144 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 3145 if (em->used > 1)
wolfSSL 14:167253f4e170 3146 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 14:167253f4e170 3147 #endif
wolfSSL 14:167253f4e170 3148 if (e[0] == 0)
wolfSSL 14:167253f4e170 3149 err = MP_EXPTMOD_E;
wolfSSL 14:167253f4e170 3150 }
wolfSSL 14:167253f4e170 3151
wolfSSL 14:167253f4e170 3152 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3153 sp_2048_from_mp(m, 90, mm);
wolfSSL 14:167253f4e170 3154
wolfSSL 14:167253f4e170 3155 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 3156 sp_2048_mont_norm_90(norm, m);
wolfSSL 14:167253f4e170 3157 }
wolfSSL 14:167253f4e170 3158 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3159 sp_2048_mul_90(a, a, norm);
wolfSSL 14:167253f4e170 3160 err = sp_2048_mod_90(a, a, m);
wolfSSL 14:167253f4e170 3161 }
wolfSSL 14:167253f4e170 3162 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3163 for (i=22; i>=0; i--)
wolfSSL 14:167253f4e170 3164 if (e[0] >> i)
wolfSSL 14:167253f4e170 3165 break;
wolfSSL 14:167253f4e170 3166
wolfSSL 14:167253f4e170 3167 XMEMCPY(r, a, sizeof(sp_digit) * 90 * 2);
wolfSSL 14:167253f4e170 3168 for (i--; i>=0; i--) {
wolfSSL 14:167253f4e170 3169 sp_2048_mont_sqr_90(r, r, m, mp);
wolfSSL 14:167253f4e170 3170
wolfSSL 14:167253f4e170 3171 if (((e[0] >> i) & 1) == 1)
wolfSSL 14:167253f4e170 3172 sp_2048_mont_mul_90(r, r, a, m, mp);
wolfSSL 14:167253f4e170 3173 }
wolfSSL 14:167253f4e170 3174 sp_2048_mont_reduce_90(r, m, mp);
wolfSSL 14:167253f4e170 3175 mp = sp_2048_cmp_90(r, m);
wolfSSL 14:167253f4e170 3176 sp_2048_cond_sub_90(r, r, m, (mp < 0) - 1);
wolfSSL 14:167253f4e170 3177
wolfSSL 14:167253f4e170 3178 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3179 *outLen = 256;
wolfSSL 14:167253f4e170 3180 }
wolfSSL 14:167253f4e170 3181
wolfSSL 14:167253f4e170 3182 if (d != NULL)
wolfSSL 14:167253f4e170 3183 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3184
wolfSSL 14:167253f4e170 3185 return err;
wolfSSL 14:167253f4e170 3186 #else
wolfSSL 14:167253f4e170 3187 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 3188 sp_digit ad[180], md[90], rd[180];
wolfSSL 14:167253f4e170 3189 #else
wolfSSL 14:167253f4e170 3190 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3191 #endif
wolfSSL 14:167253f4e170 3192 sp_digit* a;
wolfSSL 14:167253f4e170 3193 sp_digit* m;
wolfSSL 14:167253f4e170 3194 sp_digit* r;
wolfSSL 14:167253f4e170 3195 sp_digit e[1];
wolfSSL 14:167253f4e170 3196 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3197
wolfSSL 14:167253f4e170 3198 if (*outLen < 256)
wolfSSL 14:167253f4e170 3199 err = MP_TO_E;
wolfSSL 14:167253f4e170 3200 if (err == MP_OKAY && (mp_count_bits(em) > 23 || inLen > 256 ||
wolfSSL 14:167253f4e170 3201 mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 3202 err = MP_READ_E;
wolfSSL 14:167253f4e170 3203
wolfSSL 14:167253f4e170 3204 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 3205 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3206 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 90 * 5, NULL,
wolfSSL 14:167253f4e170 3207 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3208 if (d == NULL)
wolfSSL 14:167253f4e170 3209 err = MEMORY_E;
wolfSSL 14:167253f4e170 3210 }
wolfSSL 14:167253f4e170 3211
wolfSSL 14:167253f4e170 3212 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3213 a = d;
wolfSSL 14:167253f4e170 3214 r = a + 90 * 2;
wolfSSL 14:167253f4e170 3215 m = r + 90 * 2;
wolfSSL 14:167253f4e170 3216 }
wolfSSL 14:167253f4e170 3217 #else
wolfSSL 14:167253f4e170 3218 a = ad;
wolfSSL 14:167253f4e170 3219 m = md;
wolfSSL 14:167253f4e170 3220 r = rd;
wolfSSL 14:167253f4e170 3221 #endif
wolfSSL 14:167253f4e170 3222
wolfSSL 14:167253f4e170 3223 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3224 sp_2048_from_bin(a, 90, in, inLen);
wolfSSL 14:167253f4e170 3225 #if DIGIT_BIT >= 23
wolfSSL 14:167253f4e170 3226 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 3227 #else
wolfSSL 14:167253f4e170 3228 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 3229 if (em->used > 1)
wolfSSL 14:167253f4e170 3230 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 14:167253f4e170 3231 #endif
wolfSSL 14:167253f4e170 3232 if (e[0] == 0)
wolfSSL 14:167253f4e170 3233 err = MP_EXPTMOD_E;
wolfSSL 14:167253f4e170 3234 }
wolfSSL 14:167253f4e170 3235 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3236 sp_2048_from_mp(m, 90, mm);
wolfSSL 14:167253f4e170 3237
wolfSSL 14:167253f4e170 3238 if (e[0] == 0x3) {
wolfSSL 14:167253f4e170 3239 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3240 sp_2048_sqr_90(r, a);
wolfSSL 14:167253f4e170 3241 err = sp_2048_mod_90(r, r, m);
wolfSSL 14:167253f4e170 3242 }
wolfSSL 14:167253f4e170 3243 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3244 sp_2048_mul_90(r, a, r);
wolfSSL 14:167253f4e170 3245 err = sp_2048_mod_90(r, r, m);
wolfSSL 14:167253f4e170 3246 }
wolfSSL 14:167253f4e170 3247 }
wolfSSL 14:167253f4e170 3248 else {
wolfSSL 14:167253f4e170 3249 sp_digit* norm = r;
wolfSSL 14:167253f4e170 3250 int i;
wolfSSL 14:167253f4e170 3251 sp_digit mp;
wolfSSL 14:167253f4e170 3252
wolfSSL 14:167253f4e170 3253 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 3254 sp_2048_mont_norm_90(norm, m);
wolfSSL 14:167253f4e170 3255
wolfSSL 14:167253f4e170 3256 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3257 sp_2048_mul_90(a, a, norm);
wolfSSL 14:167253f4e170 3258 err = sp_2048_mod_90(a, a, m);
wolfSSL 14:167253f4e170 3259 }
wolfSSL 14:167253f4e170 3260
wolfSSL 14:167253f4e170 3261 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3262 for (i=22; i>=0; i--)
wolfSSL 14:167253f4e170 3263 if (e[0] >> i)
wolfSSL 14:167253f4e170 3264 break;
wolfSSL 14:167253f4e170 3265
wolfSSL 14:167253f4e170 3266 XMEMCPY(r, a, sizeof(sp_digit) * 180);
wolfSSL 14:167253f4e170 3267 for (i--; i>=0; i--) {
wolfSSL 14:167253f4e170 3268 sp_2048_mont_sqr_90(r, r, m, mp);
wolfSSL 14:167253f4e170 3269
wolfSSL 14:167253f4e170 3270 if (((e[0] >> i) & 1) == 1)
wolfSSL 14:167253f4e170 3271 sp_2048_mont_mul_90(r, r, a, m, mp);
wolfSSL 14:167253f4e170 3272 }
wolfSSL 14:167253f4e170 3273 sp_2048_mont_reduce_90(r, m, mp);
wolfSSL 14:167253f4e170 3274 mp = sp_2048_cmp_90(r, m);
wolfSSL 14:167253f4e170 3275 sp_2048_cond_sub_90(r, r, m, (mp < 0) - 1);
wolfSSL 14:167253f4e170 3276 }
wolfSSL 14:167253f4e170 3277 }
wolfSSL 14:167253f4e170 3278 }
wolfSSL 14:167253f4e170 3279
wolfSSL 14:167253f4e170 3280 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3281 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3282 *outLen = 256;
wolfSSL 14:167253f4e170 3283 }
wolfSSL 14:167253f4e170 3284
wolfSSL 14:167253f4e170 3285 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 3286 if (d != NULL)
wolfSSL 14:167253f4e170 3287 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3288 #endif
wolfSSL 14:167253f4e170 3289
wolfSSL 14:167253f4e170 3290 return err;
wolfSSL 14:167253f4e170 3291 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 3292 }
wolfSSL 14:167253f4e170 3293
wolfSSL 14:167253f4e170 3294 /* RSA private key operation.
wolfSSL 14:167253f4e170 3295 *
wolfSSL 14:167253f4e170 3296 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 14:167253f4e170 3297 * inLen Number of bytes in base.
wolfSSL 14:167253f4e170 3298 * dm Private exponent.
wolfSSL 14:167253f4e170 3299 * pm First prime.
wolfSSL 14:167253f4e170 3300 * qm Second prime.
wolfSSL 14:167253f4e170 3301 * dpm First prime's CRT exponent.
wolfSSL 14:167253f4e170 3302 * dqm Second prime's CRT exponent.
wolfSSL 14:167253f4e170 3303 * qim Inverse of second prime mod p.
wolfSSL 14:167253f4e170 3304 * mm Modulus.
wolfSSL 14:167253f4e170 3305 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 3306 * Must be at least 256 bytes long.
wolfSSL 14:167253f4e170 3307 * outLen Number of bytes in result.
wolfSSL 14:167253f4e170 3308 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 14:167253f4e170 3309 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 14:167253f4e170 3310 */
wolfSSL 14:167253f4e170 3311 int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,
wolfSSL 14:167253f4e170 3312 mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,
wolfSSL 14:167253f4e170 3313 byte* out, word32* outLen)
wolfSSL 14:167253f4e170 3314 {
wolfSSL 14:167253f4e170 3315 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
wolfSSL 14:167253f4e170 3316 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 3317 sp_digit* a;
wolfSSL 14:167253f4e170 3318 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3319 sp_digit* m;
wolfSSL 14:167253f4e170 3320 sp_digit* r;
wolfSSL 14:167253f4e170 3321 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3322
wolfSSL 14:167253f4e170 3323 (void)pm;
wolfSSL 14:167253f4e170 3324 (void)qm;
wolfSSL 14:167253f4e170 3325 (void)dpm;
wolfSSL 14:167253f4e170 3326 (void)dqm;
wolfSSL 14:167253f4e170 3327 (void)qim;
wolfSSL 14:167253f4e170 3328
wolfSSL 14:167253f4e170 3329 if (*outLen < 256)
wolfSSL 14:167253f4e170 3330 err = MP_TO_E;
wolfSSL 14:167253f4e170 3331 if (err == MP_OKAY && (mp_count_bits(dm) > 2048 || inLen > 256 ||
wolfSSL 14:167253f4e170 3332 mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 3333 err = MP_READ_E;
wolfSSL 14:167253f4e170 3334
wolfSSL 14:167253f4e170 3335 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3336 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 90 * 4, NULL,
wolfSSL 14:167253f4e170 3337 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3338 if (d == NULL)
wolfSSL 14:167253f4e170 3339 err = MEMORY_E;
wolfSSL 14:167253f4e170 3340 }
wolfSSL 14:167253f4e170 3341 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3342 a = d + 90;
wolfSSL 14:167253f4e170 3343 m = a + 90;
wolfSSL 14:167253f4e170 3344 r = a;
wolfSSL 14:167253f4e170 3345
wolfSSL 14:167253f4e170 3346 sp_2048_from_bin(a, 90, in, inLen);
wolfSSL 14:167253f4e170 3347 sp_2048_from_mp(d, 90, dm);
wolfSSL 14:167253f4e170 3348 sp_2048_from_mp(m, 90, mm);
wolfSSL 14:167253f4e170 3349 err = sp_2048_mod_exp_90(r, a, d, 2048, m, 0);
wolfSSL 14:167253f4e170 3350 }
wolfSSL 14:167253f4e170 3351 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3352 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3353 *outLen = 256;
wolfSSL 14:167253f4e170 3354 }
wolfSSL 14:167253f4e170 3355
wolfSSL 14:167253f4e170 3356 if (d != NULL) {
wolfSSL 14:167253f4e170 3357 XMEMSET(d, 0, sizeof(sp_digit) * 90);
wolfSSL 14:167253f4e170 3358 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3359 }
wolfSSL 14:167253f4e170 3360
wolfSSL 14:167253f4e170 3361 return err;
wolfSSL 14:167253f4e170 3362 #else
wolfSSL 14:167253f4e170 3363 sp_digit a[180], d[90], m[90];
wolfSSL 14:167253f4e170 3364 sp_digit* r = a;
wolfSSL 14:167253f4e170 3365 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3366
wolfSSL 14:167253f4e170 3367 (void)pm;
wolfSSL 14:167253f4e170 3368 (void)qm;
wolfSSL 14:167253f4e170 3369 (void)dpm;
wolfSSL 14:167253f4e170 3370 (void)dqm;
wolfSSL 14:167253f4e170 3371 (void)qim;
wolfSSL 14:167253f4e170 3372
wolfSSL 14:167253f4e170 3373 if (*outLen < 256)
wolfSSL 14:167253f4e170 3374 err = MP_TO_E;
wolfSSL 14:167253f4e170 3375 if (err == MP_OKAY && (mp_count_bits(dm) > 2048 || inLen > 256 ||
wolfSSL 14:167253f4e170 3376 mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 3377 err = MP_READ_E;
wolfSSL 14:167253f4e170 3378
wolfSSL 14:167253f4e170 3379 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3380 sp_2048_from_bin(a, 90, in, inLen);
wolfSSL 14:167253f4e170 3381 sp_2048_from_mp(d, 90, dm);
wolfSSL 14:167253f4e170 3382 sp_2048_from_mp(m, 90, mm);
wolfSSL 14:167253f4e170 3383 err = sp_2048_mod_exp_90(r, a, d, 2048, m, 0);
wolfSSL 14:167253f4e170 3384 }
wolfSSL 14:167253f4e170 3385
wolfSSL 14:167253f4e170 3386 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3387 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3388 *outLen = 256;
wolfSSL 14:167253f4e170 3389 }
wolfSSL 14:167253f4e170 3390
wolfSSL 14:167253f4e170 3391 XMEMSET(d, 0, sizeof(sp_digit) * 90);
wolfSSL 14:167253f4e170 3392
wolfSSL 14:167253f4e170 3393 return err;
wolfSSL 14:167253f4e170 3394 #endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */
wolfSSL 14:167253f4e170 3395 #else
wolfSSL 14:167253f4e170 3396 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 3397 sp_digit* t = NULL;
wolfSSL 14:167253f4e170 3398 sp_digit* a;
wolfSSL 14:167253f4e170 3399 sp_digit* p;
wolfSSL 14:167253f4e170 3400 sp_digit* q;
wolfSSL 14:167253f4e170 3401 sp_digit* dp;
wolfSSL 14:167253f4e170 3402 sp_digit* dq;
wolfSSL 14:167253f4e170 3403 sp_digit* qi;
wolfSSL 14:167253f4e170 3404 sp_digit* tmp;
wolfSSL 14:167253f4e170 3405 sp_digit* tmpa;
wolfSSL 14:167253f4e170 3406 sp_digit* tmpb;
wolfSSL 14:167253f4e170 3407 sp_digit* r;
wolfSSL 14:167253f4e170 3408 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3409
wolfSSL 14:167253f4e170 3410 (void)dm;
wolfSSL 14:167253f4e170 3411 (void)mm;
wolfSSL 14:167253f4e170 3412
wolfSSL 14:167253f4e170 3413 if (*outLen < 256)
wolfSSL 14:167253f4e170 3414 err = MP_TO_E;
wolfSSL 14:167253f4e170 3415 if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 3416 err = MP_READ_E;
wolfSSL 14:167253f4e170 3417
wolfSSL 14:167253f4e170 3418 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3419 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 45 * 11, NULL,
wolfSSL 14:167253f4e170 3420 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3421 if (t == NULL)
wolfSSL 14:167253f4e170 3422 err = MEMORY_E;
wolfSSL 14:167253f4e170 3423 }
wolfSSL 14:167253f4e170 3424 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3425 a = t;
wolfSSL 14:167253f4e170 3426 p = a + 90 * 2;
wolfSSL 14:167253f4e170 3427 q = p + 45;
wolfSSL 14:167253f4e170 3428 qi = dq = dp = q + 45;
wolfSSL 14:167253f4e170 3429 tmpa = qi + 45;
wolfSSL 14:167253f4e170 3430 tmpb = tmpa + 90;
wolfSSL 14:167253f4e170 3431
wolfSSL 14:167253f4e170 3432 tmp = t;
wolfSSL 14:167253f4e170 3433 r = tmp + 90;
wolfSSL 14:167253f4e170 3434
wolfSSL 14:167253f4e170 3435 sp_2048_from_bin(a, 90, in, inLen);
wolfSSL 14:167253f4e170 3436 sp_2048_from_mp(p, 45, pm);
wolfSSL 14:167253f4e170 3437 sp_2048_from_mp(q, 45, qm);
wolfSSL 14:167253f4e170 3438 sp_2048_from_mp(dp, 45, dpm);
wolfSSL 14:167253f4e170 3439 err = sp_2048_mod_exp_45(tmpa, a, dp, 1024, p, 1);
wolfSSL 14:167253f4e170 3440 }
wolfSSL 14:167253f4e170 3441 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3442 sp_2048_from_mp(dq, 45, dqm);
wolfSSL 14:167253f4e170 3443 err = sp_2048_mod_exp_45(tmpb, a, dq, 1024, q, 1);
wolfSSL 14:167253f4e170 3444 }
wolfSSL 14:167253f4e170 3445 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3446 sp_2048_sub_45(tmpa, tmpa, tmpb);
wolfSSL 14:167253f4e170 3447 sp_2048_mask_45(tmp, p, tmpa[44] >> 31);
wolfSSL 14:167253f4e170 3448 sp_2048_add_45(tmpa, tmpa, tmp);
wolfSSL 14:167253f4e170 3449
wolfSSL 14:167253f4e170 3450 sp_2048_from_mp(qi, 45, qim);
wolfSSL 14:167253f4e170 3451 sp_2048_mul_45(tmpa, tmpa, qi);
wolfSSL 14:167253f4e170 3452 err = sp_2048_mod_45(tmpa, tmpa, p);
wolfSSL 14:167253f4e170 3453 }
wolfSSL 14:167253f4e170 3454
wolfSSL 14:167253f4e170 3455 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3456 sp_2048_mul_45(tmpa, q, tmpa);
wolfSSL 14:167253f4e170 3457 sp_2048_add_90(r, tmpb, tmpa);
wolfSSL 14:167253f4e170 3458 sp_2048_norm_90(r);
wolfSSL 14:167253f4e170 3459
wolfSSL 14:167253f4e170 3460 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3461 *outLen = 256;
wolfSSL 14:167253f4e170 3462 }
wolfSSL 14:167253f4e170 3463
wolfSSL 14:167253f4e170 3464 if (t != NULL) {
wolfSSL 14:167253f4e170 3465 XMEMSET(t, 0, sizeof(sp_digit) * 45 * 11);
wolfSSL 14:167253f4e170 3466 XFREE(t, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3467 }
wolfSSL 14:167253f4e170 3468
wolfSSL 14:167253f4e170 3469 return err;
wolfSSL 14:167253f4e170 3470 #else
wolfSSL 14:167253f4e170 3471 sp_digit a[90 * 2];
wolfSSL 14:167253f4e170 3472 sp_digit p[45], q[45], dp[45], dq[45], qi[45];
wolfSSL 14:167253f4e170 3473 sp_digit tmp[90], tmpa[90], tmpb[90];
wolfSSL 14:167253f4e170 3474 sp_digit* r = a;
wolfSSL 14:167253f4e170 3475 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3476
wolfSSL 14:167253f4e170 3477 (void)dm;
wolfSSL 14:167253f4e170 3478 (void)mm;
wolfSSL 14:167253f4e170 3479
wolfSSL 14:167253f4e170 3480 if (*outLen < 256)
wolfSSL 14:167253f4e170 3481 err = MP_TO_E;
wolfSSL 14:167253f4e170 3482 if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 3483 err = MP_READ_E;
wolfSSL 14:167253f4e170 3484
wolfSSL 14:167253f4e170 3485 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3486 sp_2048_from_bin(a, 90, in, inLen);
wolfSSL 14:167253f4e170 3487 sp_2048_from_mp(p, 45, pm);
wolfSSL 14:167253f4e170 3488 sp_2048_from_mp(q, 45, qm);
wolfSSL 14:167253f4e170 3489 sp_2048_from_mp(dp, 45, dpm);
wolfSSL 14:167253f4e170 3490 sp_2048_from_mp(dq, 45, dqm);
wolfSSL 14:167253f4e170 3491 sp_2048_from_mp(qi, 45, qim);
wolfSSL 14:167253f4e170 3492
wolfSSL 14:167253f4e170 3493 err = sp_2048_mod_exp_45(tmpa, a, dp, 1024, p, 1);
wolfSSL 14:167253f4e170 3494 }
wolfSSL 14:167253f4e170 3495 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 3496 err = sp_2048_mod_exp_45(tmpb, a, dq, 1024, q, 1);
wolfSSL 14:167253f4e170 3497
wolfSSL 14:167253f4e170 3498 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3499 sp_2048_sub_45(tmpa, tmpa, tmpb);
wolfSSL 14:167253f4e170 3500 sp_2048_mask_45(tmp, p, tmpa[44] >> 31);
wolfSSL 14:167253f4e170 3501 sp_2048_add_45(tmpa, tmpa, tmp);
wolfSSL 14:167253f4e170 3502 sp_2048_mul_45(tmpa, tmpa, qi);
wolfSSL 14:167253f4e170 3503 err = sp_2048_mod_45(tmpa, tmpa, p);
wolfSSL 14:167253f4e170 3504 }
wolfSSL 14:167253f4e170 3505
wolfSSL 14:167253f4e170 3506 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3507 sp_2048_mul_45(tmpa, tmpa, q);
wolfSSL 14:167253f4e170 3508 sp_2048_add_90(r, tmpb, tmpa);
wolfSSL 14:167253f4e170 3509 sp_2048_norm_90(r);
wolfSSL 14:167253f4e170 3510
wolfSSL 14:167253f4e170 3511 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3512 *outLen = 256;
wolfSSL 14:167253f4e170 3513 }
wolfSSL 14:167253f4e170 3514
wolfSSL 14:167253f4e170 3515 XMEMSET(tmpa, 0, sizeof(tmpa));
wolfSSL 14:167253f4e170 3516 XMEMSET(tmpb, 0, sizeof(tmpb));
wolfSSL 14:167253f4e170 3517 XMEMSET(p, 0, sizeof(p));
wolfSSL 14:167253f4e170 3518 XMEMSET(q, 0, sizeof(q));
wolfSSL 14:167253f4e170 3519 XMEMSET(dp, 0, sizeof(dp));
wolfSSL 14:167253f4e170 3520 XMEMSET(dq, 0, sizeof(dq));
wolfSSL 14:167253f4e170 3521 XMEMSET(qi, 0, sizeof(qi));
wolfSSL 14:167253f4e170 3522
wolfSSL 14:167253f4e170 3523 return err;
wolfSSL 14:167253f4e170 3524 #endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */
wolfSSL 14:167253f4e170 3525 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
wolfSSL 14:167253f4e170 3526 }
wolfSSL 14:167253f4e170 3527
wolfSSL 14:167253f4e170 3528 #endif /* WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 3529 #ifdef WOLFSSL_HAVE_SP_DH
wolfSSL 14:167253f4e170 3530 /* Convert an array of sp_digit to an mp_int.
wolfSSL 14:167253f4e170 3531 *
wolfSSL 14:167253f4e170 3532 * a A single precision integer.
wolfSSL 14:167253f4e170 3533 * r A multi-precision integer.
wolfSSL 14:167253f4e170 3534 */
wolfSSL 14:167253f4e170 3535 static int sp_2048_to_mp(sp_digit* a, mp_int* r)
wolfSSL 14:167253f4e170 3536 {
wolfSSL 14:167253f4e170 3537 int err;
wolfSSL 14:167253f4e170 3538
wolfSSL 14:167253f4e170 3539 err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 14:167253f4e170 3540 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3541 #if DIGIT_BIT == 23
wolfSSL 14:167253f4e170 3542 XMEMCPY(r->dp, a, sizeof(sp_digit) * 90);
wolfSSL 14:167253f4e170 3543 r->used = 90;
wolfSSL 14:167253f4e170 3544 mp_clamp(r);
wolfSSL 14:167253f4e170 3545 #elif DIGIT_BIT < 23
wolfSSL 14:167253f4e170 3546 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 3547
wolfSSL 14:167253f4e170 3548 r->dp[0] = 0;
wolfSSL 14:167253f4e170 3549 for (i = 0; i < 90; i++) {
wolfSSL 14:167253f4e170 3550 r->dp[j] |= a[i] << s;
wolfSSL 14:167253f4e170 3551 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 3552 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 3553 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 3554 while (s + DIGIT_BIT <= 23) {
wolfSSL 14:167253f4e170 3555 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 3556 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 3557 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 3558 }
wolfSSL 14:167253f4e170 3559 s = 23 - s;
wolfSSL 14:167253f4e170 3560 }
wolfSSL 14:167253f4e170 3561 r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 3562 mp_clamp(r);
wolfSSL 14:167253f4e170 3563 #else
wolfSSL 14:167253f4e170 3564 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 3565
wolfSSL 14:167253f4e170 3566 r->dp[0] = 0;
wolfSSL 14:167253f4e170 3567 for (i = 0; i < 90; i++) {
wolfSSL 14:167253f4e170 3568 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 3569 if (s + 23 >= DIGIT_BIT) {
wolfSSL 14:167253f4e170 3570 #if DIGIT_BIT < 32
wolfSSL 14:167253f4e170 3571 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 3572 #endif
wolfSSL 14:167253f4e170 3573 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 3574 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 3575 s = 23 - s;
wolfSSL 14:167253f4e170 3576 }
wolfSSL 14:167253f4e170 3577 else
wolfSSL 14:167253f4e170 3578 s += 23;
wolfSSL 14:167253f4e170 3579 }
wolfSSL 14:167253f4e170 3580 r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 3581 mp_clamp(r);
wolfSSL 14:167253f4e170 3582 #endif
wolfSSL 14:167253f4e170 3583 }
wolfSSL 14:167253f4e170 3584
wolfSSL 14:167253f4e170 3585 return err;
wolfSSL 14:167253f4e170 3586 }
wolfSSL 14:167253f4e170 3587
wolfSSL 14:167253f4e170 3588 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 14:167253f4e170 3589 *
wolfSSL 14:167253f4e170 3590 * base Base. MP integer.
wolfSSL 14:167253f4e170 3591 * exp Exponent. MP integer.
wolfSSL 14:167253f4e170 3592 * mod Modulus. MP integer.
wolfSSL 14:167253f4e170 3593 * res Result. MP integer.
wolfSSL 14:167253f4e170 3594 * returs 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 14:167253f4e170 3595 * and MEMORY_E if memory allocation fails.
wolfSSL 14:167253f4e170 3596 */
wolfSSL 14:167253f4e170 3597 int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)
wolfSSL 14:167253f4e170 3598 {
wolfSSL 14:167253f4e170 3599 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3600 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3601 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3602 sp_digit* b;
wolfSSL 14:167253f4e170 3603 sp_digit* e;
wolfSSL 14:167253f4e170 3604 sp_digit* m;
wolfSSL 14:167253f4e170 3605 sp_digit* r;
wolfSSL 14:167253f4e170 3606 int expBits = mp_count_bits(exp);
wolfSSL 14:167253f4e170 3607
wolfSSL 14:167253f4e170 3608 if (mp_count_bits(base) > 2048 || expBits > 2048 ||
wolfSSL 14:167253f4e170 3609 mp_count_bits(mod) != 2048) {
wolfSSL 14:167253f4e170 3610 err = MP_READ_E;
wolfSSL 14:167253f4e170 3611 }
wolfSSL 14:167253f4e170 3612
wolfSSL 14:167253f4e170 3613 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3614 d = (sp_digit*)XMALLOC(sizeof(*d) * 90 * 4, NULL,
wolfSSL 14:167253f4e170 3615 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3616 if (d == NULL)
wolfSSL 14:167253f4e170 3617 err = MEMORY_E;
wolfSSL 14:167253f4e170 3618 }
wolfSSL 14:167253f4e170 3619
wolfSSL 14:167253f4e170 3620 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3621 b = d;
wolfSSL 14:167253f4e170 3622 e = b + 90 * 2;
wolfSSL 14:167253f4e170 3623 m = e + 90;
wolfSSL 14:167253f4e170 3624 r = b;
wolfSSL 14:167253f4e170 3625
wolfSSL 14:167253f4e170 3626 sp_2048_from_mp(b, 90, base);
wolfSSL 14:167253f4e170 3627 sp_2048_from_mp(e, 90, exp);
wolfSSL 14:167253f4e170 3628 sp_2048_from_mp(m, 90, mod);
wolfSSL 14:167253f4e170 3629
wolfSSL 14:167253f4e170 3630 err = sp_2048_mod_exp_90(r, b, e, mp_count_bits(exp), m, 0);
wolfSSL 14:167253f4e170 3631 }
wolfSSL 14:167253f4e170 3632
wolfSSL 14:167253f4e170 3633 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3634 err = sp_2048_to_mp(r, res);
wolfSSL 14:167253f4e170 3635 }
wolfSSL 14:167253f4e170 3636
wolfSSL 14:167253f4e170 3637 if (d != NULL) {
wolfSSL 14:167253f4e170 3638 XMEMSET(e, 0, sizeof(sp_digit) * 90);
wolfSSL 14:167253f4e170 3639 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3640 }
wolfSSL 14:167253f4e170 3641 return err;
wolfSSL 14:167253f4e170 3642 #else
wolfSSL 14:167253f4e170 3643 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3644 sp_digit bd[180], ed[90], md[90];
wolfSSL 14:167253f4e170 3645 #else
wolfSSL 14:167253f4e170 3646 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3647 #endif
wolfSSL 14:167253f4e170 3648 sp_digit* b;
wolfSSL 14:167253f4e170 3649 sp_digit* e;
wolfSSL 14:167253f4e170 3650 sp_digit* m;
wolfSSL 14:167253f4e170 3651 sp_digit* r;
wolfSSL 14:167253f4e170 3652 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3653 int expBits = mp_count_bits(exp);
wolfSSL 14:167253f4e170 3654
wolfSSL 14:167253f4e170 3655 if (mp_count_bits(base) > 2048 || expBits > 2048 ||
wolfSSL 14:167253f4e170 3656 mp_count_bits(mod) != 2048) {
wolfSSL 14:167253f4e170 3657 err = MP_READ_E;
wolfSSL 14:167253f4e170 3658 }
wolfSSL 14:167253f4e170 3659
wolfSSL 14:167253f4e170 3660 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3661 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3662 d = (sp_digit*)XMALLOC(sizeof(*d) * 90 * 4, NULL,
wolfSSL 14:167253f4e170 3663 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3664 if (d == NULL)
wolfSSL 14:167253f4e170 3665 err = MEMORY_E;
wolfSSL 14:167253f4e170 3666 }
wolfSSL 14:167253f4e170 3667
wolfSSL 14:167253f4e170 3668 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3669 b = d;
wolfSSL 14:167253f4e170 3670 e = b + 90 * 2;
wolfSSL 14:167253f4e170 3671 m = e + 90;
wolfSSL 14:167253f4e170 3672 r = b;
wolfSSL 14:167253f4e170 3673 }
wolfSSL 14:167253f4e170 3674 #else
wolfSSL 14:167253f4e170 3675 r = b = bd;
wolfSSL 14:167253f4e170 3676 e = ed;
wolfSSL 14:167253f4e170 3677 m = md;
wolfSSL 14:167253f4e170 3678 #endif
wolfSSL 14:167253f4e170 3679
wolfSSL 14:167253f4e170 3680 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3681 sp_2048_from_mp(b, 90, base);
wolfSSL 14:167253f4e170 3682 sp_2048_from_mp(e, 90, exp);
wolfSSL 14:167253f4e170 3683 sp_2048_from_mp(m, 90, mod);
wolfSSL 14:167253f4e170 3684
wolfSSL 14:167253f4e170 3685 err = sp_2048_mod_exp_90(r, b, e, expBits, m, 0);
wolfSSL 14:167253f4e170 3686 }
wolfSSL 14:167253f4e170 3687
wolfSSL 14:167253f4e170 3688 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3689 err = sp_2048_to_mp(r, res);
wolfSSL 14:167253f4e170 3690 }
wolfSSL 14:167253f4e170 3691
wolfSSL 14:167253f4e170 3692 XMEMSET(e, 0, sizeof(sp_digit) * 90);
wolfSSL 14:167253f4e170 3693
wolfSSL 14:167253f4e170 3694 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3695 if (d != NULL)
wolfSSL 14:167253f4e170 3696 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3697 #endif
wolfSSL 14:167253f4e170 3698
wolfSSL 14:167253f4e170 3699 return err;
wolfSSL 14:167253f4e170 3700 #endif
wolfSSL 14:167253f4e170 3701 }
wolfSSL 14:167253f4e170 3702
wolfSSL 14:167253f4e170 3703 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 14:167253f4e170 3704 *
wolfSSL 14:167253f4e170 3705 * base Base.
wolfSSL 14:167253f4e170 3706 * exp Array of bytes that is the exponent.
wolfSSL 14:167253f4e170 3707 * expLen Length of data, in bytes, in exponent.
wolfSSL 14:167253f4e170 3708 * mod Modulus.
wolfSSL 14:167253f4e170 3709 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 3710 * Must be at least 256 bytes long.
wolfSSL 14:167253f4e170 3711 * outLen Length, in bytes, of exponentiation result.
wolfSSL 14:167253f4e170 3712 * returs 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 14:167253f4e170 3713 * and MEMORY_E if memory allocation fails.
wolfSSL 14:167253f4e170 3714 */
wolfSSL 14:167253f4e170 3715 int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,
wolfSSL 14:167253f4e170 3716 mp_int* mod, byte* out, word32* outLen)
wolfSSL 14:167253f4e170 3717 {
wolfSSL 14:167253f4e170 3718 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3719 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3720 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3721 sp_digit* b;
wolfSSL 14:167253f4e170 3722 sp_digit* e;
wolfSSL 14:167253f4e170 3723 sp_digit* m;
wolfSSL 14:167253f4e170 3724 sp_digit* r;
wolfSSL 14:167253f4e170 3725 word32 i;
wolfSSL 14:167253f4e170 3726
wolfSSL 14:167253f4e170 3727 if (mp_count_bits(base) > 2048 || expLen > 256 ||
wolfSSL 14:167253f4e170 3728 mp_count_bits(mod) != 2048) {
wolfSSL 14:167253f4e170 3729 err = MP_READ_E;
wolfSSL 14:167253f4e170 3730 }
wolfSSL 14:167253f4e170 3731
wolfSSL 14:167253f4e170 3732 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3733 d = (sp_digit*)XMALLOC(sizeof(*d) * 90 * 4, NULL,
wolfSSL 14:167253f4e170 3734 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3735 if (d == NULL)
wolfSSL 14:167253f4e170 3736 err = MEMORY_E;
wolfSSL 14:167253f4e170 3737 }
wolfSSL 14:167253f4e170 3738
wolfSSL 14:167253f4e170 3739 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3740 b = d;
wolfSSL 14:167253f4e170 3741 e = b + 90 * 2;
wolfSSL 14:167253f4e170 3742 m = e + 90;
wolfSSL 14:167253f4e170 3743 r = b;
wolfSSL 14:167253f4e170 3744
wolfSSL 14:167253f4e170 3745 sp_2048_from_mp(b, 90, base);
wolfSSL 14:167253f4e170 3746 sp_2048_from_bin(e, 90, exp, expLen);
wolfSSL 14:167253f4e170 3747 sp_2048_from_mp(m, 90, mod);
wolfSSL 14:167253f4e170 3748
wolfSSL 14:167253f4e170 3749 err = sp_2048_mod_exp_90(r, b, e, expLen * 8, m, 0);
wolfSSL 14:167253f4e170 3750 }
wolfSSL 14:167253f4e170 3751
wolfSSL 14:167253f4e170 3752 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3753 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3754 *outLen = 256;
wolfSSL 14:167253f4e170 3755 for (i=0; i<256 && out[i] == 0; i++) {
wolfSSL 14:167253f4e170 3756 }
wolfSSL 14:167253f4e170 3757 *outLen -= i;
wolfSSL 14:167253f4e170 3758 XMEMMOVE(out, out + i, *outLen);
wolfSSL 14:167253f4e170 3759 }
wolfSSL 14:167253f4e170 3760
wolfSSL 14:167253f4e170 3761 if (d != NULL) {
wolfSSL 14:167253f4e170 3762 XMEMSET(e, 0, sizeof(sp_digit) * 90);
wolfSSL 14:167253f4e170 3763 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3764 }
wolfSSL 14:167253f4e170 3765 return err;
wolfSSL 14:167253f4e170 3766 #else
wolfSSL 14:167253f4e170 3767 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3768 sp_digit bd[180], ed[90], md[90];
wolfSSL 14:167253f4e170 3769 #else
wolfSSL 14:167253f4e170 3770 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3771 #endif
wolfSSL 14:167253f4e170 3772 sp_digit* b;
wolfSSL 14:167253f4e170 3773 sp_digit* e;
wolfSSL 14:167253f4e170 3774 sp_digit* m;
wolfSSL 14:167253f4e170 3775 sp_digit* r;
wolfSSL 14:167253f4e170 3776 word32 i;
wolfSSL 14:167253f4e170 3777 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3778
wolfSSL 14:167253f4e170 3779 if (mp_count_bits(base) > 2048 || expLen > 256 ||
wolfSSL 14:167253f4e170 3780 mp_count_bits(mod) != 2048) {
wolfSSL 14:167253f4e170 3781 err = MP_READ_E;
wolfSSL 14:167253f4e170 3782 }
wolfSSL 14:167253f4e170 3783
wolfSSL 14:167253f4e170 3784 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3785 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3786 d = (sp_digit*)XMALLOC(sizeof(*d) * 90 * 4, NULL,
wolfSSL 14:167253f4e170 3787 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3788 if (d == NULL)
wolfSSL 14:167253f4e170 3789 err = MEMORY_E;
wolfSSL 14:167253f4e170 3790 }
wolfSSL 14:167253f4e170 3791
wolfSSL 14:167253f4e170 3792 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3793 b = d;
wolfSSL 14:167253f4e170 3794 e = b + 90 * 2;
wolfSSL 14:167253f4e170 3795 m = e + 90;
wolfSSL 14:167253f4e170 3796 r = b;
wolfSSL 14:167253f4e170 3797 }
wolfSSL 14:167253f4e170 3798 #else
wolfSSL 14:167253f4e170 3799 r = b = bd;
wolfSSL 14:167253f4e170 3800 e = ed;
wolfSSL 14:167253f4e170 3801 m = md;
wolfSSL 14:167253f4e170 3802 #endif
wolfSSL 14:167253f4e170 3803
wolfSSL 14:167253f4e170 3804 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3805 sp_2048_from_mp(b, 90, base);
wolfSSL 14:167253f4e170 3806 sp_2048_from_bin(e, 90, exp, expLen);
wolfSSL 14:167253f4e170 3807 sp_2048_from_mp(m, 90, mod);
wolfSSL 14:167253f4e170 3808
wolfSSL 14:167253f4e170 3809 err = sp_2048_mod_exp_90(r, b, e, expLen * 8, m, 0);
wolfSSL 14:167253f4e170 3810 }
wolfSSL 14:167253f4e170 3811
wolfSSL 14:167253f4e170 3812 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3813 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3814 *outLen = 256;
wolfSSL 14:167253f4e170 3815 for (i=0; i<256 && out[i] == 0; i++) {
wolfSSL 14:167253f4e170 3816 }
wolfSSL 14:167253f4e170 3817 *outLen -= i;
wolfSSL 14:167253f4e170 3818 XMEMMOVE(out, out + i, *outLen);
wolfSSL 14:167253f4e170 3819 }
wolfSSL 14:167253f4e170 3820
wolfSSL 14:167253f4e170 3821 XMEMSET(e, 0, sizeof(sp_digit) * 90);
wolfSSL 14:167253f4e170 3822
wolfSSL 14:167253f4e170 3823 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3824 if (d != NULL)
wolfSSL 14:167253f4e170 3825 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3826 #endif
wolfSSL 14:167253f4e170 3827
wolfSSL 14:167253f4e170 3828 return err;
wolfSSL 14:167253f4e170 3829 #endif
wolfSSL 14:167253f4e170 3830 }
wolfSSL 14:167253f4e170 3831
wolfSSL 14:167253f4e170 3832 #endif /* WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 3833
wolfSSL 14:167253f4e170 3834 #endif /* WOLFSSL_SP_NO_2048 */
wolfSSL 14:167253f4e170 3835
wolfSSL 14:167253f4e170 3836 #ifndef WOLFSSL_SP_NO_3072
wolfSSL 14:167253f4e170 3837 /* Read big endian unsigned byte aray into r.
wolfSSL 14:167253f4e170 3838 *
wolfSSL 14:167253f4e170 3839 * r A single precision integer.
wolfSSL 14:167253f4e170 3840 * a Byte array.
wolfSSL 14:167253f4e170 3841 * n Number of bytes in array to read.
wolfSSL 14:167253f4e170 3842 */
wolfSSL 14:167253f4e170 3843 static void sp_3072_from_bin(sp_digit* r, int max, const byte* a, int n)
wolfSSL 14:167253f4e170 3844 {
wolfSSL 14:167253f4e170 3845 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 3846
wolfSSL 14:167253f4e170 3847 r[0] = 0;
wolfSSL 14:167253f4e170 3848 for (i = n-1; i >= 0; i--) {
wolfSSL 14:167253f4e170 3849 r[j] |= ((sp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 3850 if (s >= 15) {
wolfSSL 14:167253f4e170 3851 r[j] &= 0x7fffff;
wolfSSL 14:167253f4e170 3852 s = 23 - s;
wolfSSL 14:167253f4e170 3853 if (j + 1 >= max)
wolfSSL 14:167253f4e170 3854 break;
wolfSSL 14:167253f4e170 3855 r[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 3856 s = 8 - s;
wolfSSL 14:167253f4e170 3857 }
wolfSSL 14:167253f4e170 3858 else
wolfSSL 14:167253f4e170 3859 s += 8;
wolfSSL 14:167253f4e170 3860 }
wolfSSL 14:167253f4e170 3861
wolfSSL 14:167253f4e170 3862 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 3863 r[j] = 0;
wolfSSL 14:167253f4e170 3864 }
wolfSSL 14:167253f4e170 3865
wolfSSL 14:167253f4e170 3866 /* Convert an mp_int to an array of sp_digit.
wolfSSL 14:167253f4e170 3867 *
wolfSSL 14:167253f4e170 3868 * r A single precision integer.
wolfSSL 14:167253f4e170 3869 * a A multi-precision integer.
wolfSSL 14:167253f4e170 3870 */
wolfSSL 14:167253f4e170 3871 static void sp_3072_from_mp(sp_digit* r, int max, mp_int* a)
wolfSSL 14:167253f4e170 3872 {
wolfSSL 14:167253f4e170 3873 #if DIGIT_BIT == 23
wolfSSL 14:167253f4e170 3874 int j;
wolfSSL 14:167253f4e170 3875
wolfSSL 14:167253f4e170 3876 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 14:167253f4e170 3877
wolfSSL 14:167253f4e170 3878 for (j = a->used; j < max; j++)
wolfSSL 14:167253f4e170 3879 r[j] = 0;
wolfSSL 14:167253f4e170 3880 #elif DIGIT_BIT > 23
wolfSSL 14:167253f4e170 3881 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 3882
wolfSSL 14:167253f4e170 3883 r[0] = 0;
wolfSSL 14:167253f4e170 3884 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 3885 r[j] |= a->dp[i] << s;
wolfSSL 14:167253f4e170 3886 r[j] &= 0x7fffff;
wolfSSL 14:167253f4e170 3887 s = 23 - s;
wolfSSL 14:167253f4e170 3888 if (j + 1 >= max)
wolfSSL 14:167253f4e170 3889 break;
wolfSSL 14:167253f4e170 3890 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 3891 while (s + 23 <= DIGIT_BIT) {
wolfSSL 14:167253f4e170 3892 s += 23;
wolfSSL 14:167253f4e170 3893 r[j] &= 0x7fffff;
wolfSSL 14:167253f4e170 3894 if (j + 1 >= max)
wolfSSL 14:167253f4e170 3895 break;
wolfSSL 14:167253f4e170 3896 if (s < DIGIT_BIT)
wolfSSL 14:167253f4e170 3897 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 3898 else
wolfSSL 14:167253f4e170 3899 r[++j] = 0;
wolfSSL 14:167253f4e170 3900 }
wolfSSL 14:167253f4e170 3901 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 3902 }
wolfSSL 14:167253f4e170 3903
wolfSSL 14:167253f4e170 3904 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 3905 r[j] = 0;
wolfSSL 14:167253f4e170 3906 #else
wolfSSL 14:167253f4e170 3907 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 3908
wolfSSL 14:167253f4e170 3909 r[0] = 0;
wolfSSL 14:167253f4e170 3910 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 3911 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 14:167253f4e170 3912 if (s + DIGIT_BIT >= 23) {
wolfSSL 14:167253f4e170 3913 r[j] &= 0x7fffff;
wolfSSL 14:167253f4e170 3914 if (j + 1 >= max)
wolfSSL 14:167253f4e170 3915 break;
wolfSSL 14:167253f4e170 3916 s = 23 - s;
wolfSSL 14:167253f4e170 3917 if (s == DIGIT_BIT) {
wolfSSL 14:167253f4e170 3918 r[++j] = 0;
wolfSSL 14:167253f4e170 3919 s = 0;
wolfSSL 14:167253f4e170 3920 }
wolfSSL 14:167253f4e170 3921 else {
wolfSSL 14:167253f4e170 3922 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 3923 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 3924 }
wolfSSL 14:167253f4e170 3925 }
wolfSSL 14:167253f4e170 3926 else
wolfSSL 14:167253f4e170 3927 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 3928 }
wolfSSL 14:167253f4e170 3929
wolfSSL 14:167253f4e170 3930 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 3931 r[j] = 0;
wolfSSL 14:167253f4e170 3932 #endif
wolfSSL 14:167253f4e170 3933 }
wolfSSL 14:167253f4e170 3934
wolfSSL 14:167253f4e170 3935 /* Write r as big endian to byte aray.
wolfSSL 14:167253f4e170 3936 * Fixed length number of bytes written: 384
wolfSSL 14:167253f4e170 3937 *
wolfSSL 14:167253f4e170 3938 * r A single precision integer.
wolfSSL 14:167253f4e170 3939 * a Byte array.
wolfSSL 14:167253f4e170 3940 */
wolfSSL 14:167253f4e170 3941 static void sp_3072_to_bin(sp_digit* r, byte* a)
wolfSSL 14:167253f4e170 3942 {
wolfSSL 14:167253f4e170 3943 int i, j, s = 0, b;
wolfSSL 14:167253f4e170 3944
wolfSSL 14:167253f4e170 3945 for (i=0; i<135; i++) {
wolfSSL 14:167253f4e170 3946 r[i+1] += r[i] >> 23;
wolfSSL 14:167253f4e170 3947 r[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 3948 }
wolfSSL 14:167253f4e170 3949 j = 3072 / 8 - 1;
wolfSSL 14:167253f4e170 3950 a[j] = 0;
wolfSSL 14:167253f4e170 3951 for (i=0; i<136 && j>=0; i++) {
wolfSSL 14:167253f4e170 3952 b = 0;
wolfSSL 14:167253f4e170 3953 a[j--] |= r[i] << s; b += 8 - s;
wolfSSL 14:167253f4e170 3954 if (j < 0)
wolfSSL 14:167253f4e170 3955 break;
wolfSSL 14:167253f4e170 3956 while (b < 23) {
wolfSSL 14:167253f4e170 3957 a[j--] = r[i] >> b; b += 8;
wolfSSL 14:167253f4e170 3958 if (j < 0)
wolfSSL 14:167253f4e170 3959 break;
wolfSSL 14:167253f4e170 3960 }
wolfSSL 14:167253f4e170 3961 s = 8 - (b - 23);
wolfSSL 14:167253f4e170 3962 if (j >= 0)
wolfSSL 14:167253f4e170 3963 a[j] = 0;
wolfSSL 14:167253f4e170 3964 if (s != 0)
wolfSSL 14:167253f4e170 3965 j++;
wolfSSL 14:167253f4e170 3966 }
wolfSSL 14:167253f4e170 3967 }
wolfSSL 14:167253f4e170 3968
wolfSSL 14:167253f4e170 3969 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3970 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 3971 *
wolfSSL 14:167253f4e170 3972 * r A single precision integer.
wolfSSL 14:167253f4e170 3973 * a A single precision integer.
wolfSSL 14:167253f4e170 3974 * b A single precision integer.
wolfSSL 14:167253f4e170 3975 */
wolfSSL 14:167253f4e170 3976 SP_NOINLINE static void sp_3072_mul_17(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3977 const sp_digit* b)
wolfSSL 14:167253f4e170 3978 {
wolfSSL 14:167253f4e170 3979 int i, j;
wolfSSL 14:167253f4e170 3980 int64_t t[34];
wolfSSL 14:167253f4e170 3981
wolfSSL 14:167253f4e170 3982 XMEMSET(t, 0, sizeof(t));
wolfSSL 14:167253f4e170 3983 for (i=0; i<17; i++) {
wolfSSL 14:167253f4e170 3984 for (j=0; j<17; j++)
wolfSSL 14:167253f4e170 3985 t[i+j] += ((int64_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 3986 }
wolfSSL 14:167253f4e170 3987 for (i=0; i<33; i++) {
wolfSSL 14:167253f4e170 3988 r[i] = t[i] & 0x7fffff;
wolfSSL 14:167253f4e170 3989 t[i+1] += t[i] >> 23;
wolfSSL 14:167253f4e170 3990 }
wolfSSL 14:167253f4e170 3991 r[33] = (sp_digit)t[33];
wolfSSL 14:167253f4e170 3992 }
wolfSSL 14:167253f4e170 3993
wolfSSL 14:167253f4e170 3994 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 3995 *
wolfSSL 14:167253f4e170 3996 * r A single precision integer.
wolfSSL 14:167253f4e170 3997 * a A single precision integer.
wolfSSL 14:167253f4e170 3998 */
wolfSSL 14:167253f4e170 3999 SP_NOINLINE static void sp_3072_sqr_17(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4000 {
wolfSSL 14:167253f4e170 4001 int i, j;
wolfSSL 14:167253f4e170 4002 int64_t t[34];
wolfSSL 14:167253f4e170 4003
wolfSSL 14:167253f4e170 4004 XMEMSET(t, 0, sizeof(t));
wolfSSL 14:167253f4e170 4005 for (i=0; i<17; i++) {
wolfSSL 14:167253f4e170 4006 for (j=0; j<i; j++)
wolfSSL 14:167253f4e170 4007 t[i+j] += (((int64_t)a[i]) * a[j]) * 2;
wolfSSL 14:167253f4e170 4008 t[i+i] += ((int64_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 4009 }
wolfSSL 14:167253f4e170 4010 for (i=0; i<33; i++) {
wolfSSL 14:167253f4e170 4011 r[i] = t[i] & 0x7fffff;
wolfSSL 14:167253f4e170 4012 t[i+1] += t[i] >> 23;
wolfSSL 14:167253f4e170 4013 }
wolfSSL 14:167253f4e170 4014 r[33] = (sp_digit)t[33];
wolfSSL 14:167253f4e170 4015 }
wolfSSL 14:167253f4e170 4016
wolfSSL 14:167253f4e170 4017 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 4018 *
wolfSSL 14:167253f4e170 4019 * r A single precision integer.
wolfSSL 14:167253f4e170 4020 * a A single precision integer.
wolfSSL 14:167253f4e170 4021 * b A single precision integer.
wolfSSL 14:167253f4e170 4022 */
wolfSSL 14:167253f4e170 4023 SP_NOINLINE static int sp_3072_add_17(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4024 const sp_digit* b)
wolfSSL 14:167253f4e170 4025 {
wolfSSL 14:167253f4e170 4026 int i;
wolfSSL 14:167253f4e170 4027
wolfSSL 14:167253f4e170 4028 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 4029 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 4030 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 4031 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 4032 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 4033 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 4034 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 4035 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 4036 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 4037 }
wolfSSL 14:167253f4e170 4038 r[16] = a[16] + b[16];
wolfSSL 14:167253f4e170 4039
wolfSSL 14:167253f4e170 4040 return 0;
wolfSSL 14:167253f4e170 4041 }
wolfSSL 14:167253f4e170 4042
wolfSSL 14:167253f4e170 4043 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 4044 *
wolfSSL 14:167253f4e170 4045 * r A single precision integer.
wolfSSL 14:167253f4e170 4046 * a A single precision integer.
wolfSSL 14:167253f4e170 4047 * b A single precision integer.
wolfSSL 14:167253f4e170 4048 */
wolfSSL 14:167253f4e170 4049 SP_NOINLINE static int sp_3072_add_34(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4050 const sp_digit* b)
wolfSSL 14:167253f4e170 4051 {
wolfSSL 14:167253f4e170 4052 int i;
wolfSSL 14:167253f4e170 4053
wolfSSL 14:167253f4e170 4054 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 4055 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 4056 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 4057 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 4058 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 4059 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 4060 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 4061 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 4062 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 4063 }
wolfSSL 14:167253f4e170 4064 r[32] = a[32] + b[32];
wolfSSL 14:167253f4e170 4065 r[33] = a[33] + b[33];
wolfSSL 14:167253f4e170 4066
wolfSSL 14:167253f4e170 4067 return 0;
wolfSSL 14:167253f4e170 4068 }
wolfSSL 14:167253f4e170 4069
wolfSSL 14:167253f4e170 4070 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 4071 *
wolfSSL 14:167253f4e170 4072 * r A single precision integer.
wolfSSL 14:167253f4e170 4073 * a A single precision integer.
wolfSSL 14:167253f4e170 4074 * b A single precision integer.
wolfSSL 14:167253f4e170 4075 */
wolfSSL 14:167253f4e170 4076 SP_NOINLINE static int sp_3072_sub_34(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4077 const sp_digit* b)
wolfSSL 14:167253f4e170 4078 {
wolfSSL 14:167253f4e170 4079 int i;
wolfSSL 14:167253f4e170 4080
wolfSSL 14:167253f4e170 4081 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 4082 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 4083 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 4084 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 4085 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 4086 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 4087 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 4088 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 4089 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 4090 }
wolfSSL 14:167253f4e170 4091 r[32] = a[32] - b[32];
wolfSSL 14:167253f4e170 4092 r[33] = a[33] - b[33];
wolfSSL 14:167253f4e170 4093
wolfSSL 14:167253f4e170 4094 return 0;
wolfSSL 14:167253f4e170 4095 }
wolfSSL 14:167253f4e170 4096
wolfSSL 14:167253f4e170 4097 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 4098 *
wolfSSL 14:167253f4e170 4099 * r A single precision integer.
wolfSSL 14:167253f4e170 4100 * a A single precision integer.
wolfSSL 14:167253f4e170 4101 * b A single precision integer.
wolfSSL 14:167253f4e170 4102 */
wolfSSL 14:167253f4e170 4103 SP_NOINLINE static void sp_3072_mul_34(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4104 const sp_digit* b)
wolfSSL 14:167253f4e170 4105 {
wolfSSL 14:167253f4e170 4106 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 4107 sp_digit z1[34];
wolfSSL 14:167253f4e170 4108 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 4109 sp_digit b1[17];
wolfSSL 14:167253f4e170 4110 sp_digit* z2 = r + 34;
wolfSSL 14:167253f4e170 4111 sp_3072_add_17(a1, a, &a[17]);
wolfSSL 14:167253f4e170 4112 sp_3072_add_17(b1, b, &b[17]);
wolfSSL 14:167253f4e170 4113 sp_3072_mul_17(z2, &a[17], &b[17]);
wolfSSL 14:167253f4e170 4114 sp_3072_mul_17(z0, a, b);
wolfSSL 14:167253f4e170 4115 sp_3072_mul_17(z1, a1, b1);
wolfSSL 14:167253f4e170 4116 sp_3072_sub_34(z1, z1, z2);
wolfSSL 14:167253f4e170 4117 sp_3072_sub_34(z1, z1, z0);
wolfSSL 14:167253f4e170 4118 sp_3072_add_34(r + 17, r + 17, z1);
wolfSSL 14:167253f4e170 4119 }
wolfSSL 14:167253f4e170 4120
wolfSSL 14:167253f4e170 4121 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 4122 *
wolfSSL 14:167253f4e170 4123 * r A single precision integer.
wolfSSL 14:167253f4e170 4124 * a A single precision integer.
wolfSSL 14:167253f4e170 4125 */
wolfSSL 14:167253f4e170 4126 SP_NOINLINE static void sp_3072_sqr_34(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4127 {
wolfSSL 14:167253f4e170 4128 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 4129 sp_digit z1[34];
wolfSSL 14:167253f4e170 4130 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 4131 sp_digit* z2 = r + 34;
wolfSSL 14:167253f4e170 4132 sp_3072_add_17(a1, a, &a[17]);
wolfSSL 14:167253f4e170 4133 sp_3072_sqr_17(z2, &a[17]);
wolfSSL 14:167253f4e170 4134 sp_3072_sqr_17(z0, a);
wolfSSL 14:167253f4e170 4135 sp_3072_sqr_17(z1, a1);
wolfSSL 14:167253f4e170 4136 sp_3072_sub_34(z1, z1, z2);
wolfSSL 14:167253f4e170 4137 sp_3072_sub_34(z1, z1, z0);
wolfSSL 14:167253f4e170 4138 sp_3072_add_34(r + 17, r + 17, z1);
wolfSSL 14:167253f4e170 4139 }
wolfSSL 14:167253f4e170 4140
wolfSSL 14:167253f4e170 4141 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 4142 *
wolfSSL 14:167253f4e170 4143 * r A single precision integer.
wolfSSL 14:167253f4e170 4144 * a A single precision integer.
wolfSSL 14:167253f4e170 4145 * b A single precision integer.
wolfSSL 14:167253f4e170 4146 */
wolfSSL 14:167253f4e170 4147 SP_NOINLINE static int sp_3072_add_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4148 const sp_digit* b)
wolfSSL 14:167253f4e170 4149 {
wolfSSL 14:167253f4e170 4150 int i;
wolfSSL 14:167253f4e170 4151
wolfSSL 14:167253f4e170 4152 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 4153 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 4154 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 4155 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 4156 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 4157 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 4158 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 4159 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 4160 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 4161 }
wolfSSL 14:167253f4e170 4162 r[64] = a[64] + b[64];
wolfSSL 14:167253f4e170 4163 r[65] = a[65] + b[65];
wolfSSL 14:167253f4e170 4164 r[66] = a[66] + b[66];
wolfSSL 14:167253f4e170 4165 r[67] = a[67] + b[67];
wolfSSL 14:167253f4e170 4166
wolfSSL 14:167253f4e170 4167 return 0;
wolfSSL 14:167253f4e170 4168 }
wolfSSL 14:167253f4e170 4169
wolfSSL 14:167253f4e170 4170 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 4171 *
wolfSSL 14:167253f4e170 4172 * r A single precision integer.
wolfSSL 14:167253f4e170 4173 * a A single precision integer.
wolfSSL 14:167253f4e170 4174 * b A single precision integer.
wolfSSL 14:167253f4e170 4175 */
wolfSSL 14:167253f4e170 4176 SP_NOINLINE static int sp_3072_sub_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4177 const sp_digit* b)
wolfSSL 14:167253f4e170 4178 {
wolfSSL 14:167253f4e170 4179 int i;
wolfSSL 14:167253f4e170 4180
wolfSSL 14:167253f4e170 4181 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 4182 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 4183 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 4184 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 4185 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 4186 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 4187 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 4188 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 4189 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 4190 }
wolfSSL 14:167253f4e170 4191 r[64] = a[64] - b[64];
wolfSSL 14:167253f4e170 4192 r[65] = a[65] - b[65];
wolfSSL 14:167253f4e170 4193 r[66] = a[66] - b[66];
wolfSSL 14:167253f4e170 4194 r[67] = a[67] - b[67];
wolfSSL 14:167253f4e170 4195
wolfSSL 14:167253f4e170 4196 return 0;
wolfSSL 14:167253f4e170 4197 }
wolfSSL 14:167253f4e170 4198
wolfSSL 14:167253f4e170 4199 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 4200 *
wolfSSL 14:167253f4e170 4201 * r A single precision integer.
wolfSSL 14:167253f4e170 4202 * a A single precision integer.
wolfSSL 14:167253f4e170 4203 * b A single precision integer.
wolfSSL 14:167253f4e170 4204 */
wolfSSL 14:167253f4e170 4205 SP_NOINLINE static void sp_3072_mul_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4206 const sp_digit* b)
wolfSSL 14:167253f4e170 4207 {
wolfSSL 14:167253f4e170 4208 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 4209 sp_digit z1[68];
wolfSSL 14:167253f4e170 4210 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 4211 sp_digit b1[34];
wolfSSL 14:167253f4e170 4212 sp_digit* z2 = r + 68;
wolfSSL 14:167253f4e170 4213 sp_3072_add_34(a1, a, &a[34]);
wolfSSL 14:167253f4e170 4214 sp_3072_add_34(b1, b, &b[34]);
wolfSSL 14:167253f4e170 4215 sp_3072_mul_34(z2, &a[34], &b[34]);
wolfSSL 14:167253f4e170 4216 sp_3072_mul_34(z0, a, b);
wolfSSL 14:167253f4e170 4217 sp_3072_mul_34(z1, a1, b1);
wolfSSL 14:167253f4e170 4218 sp_3072_sub_68(z1, z1, z2);
wolfSSL 14:167253f4e170 4219 sp_3072_sub_68(z1, z1, z0);
wolfSSL 14:167253f4e170 4220 sp_3072_add_68(r + 34, r + 34, z1);
wolfSSL 14:167253f4e170 4221 }
wolfSSL 14:167253f4e170 4222
wolfSSL 14:167253f4e170 4223 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 4224 *
wolfSSL 14:167253f4e170 4225 * r A single precision integer.
wolfSSL 14:167253f4e170 4226 * a A single precision integer.
wolfSSL 14:167253f4e170 4227 */
wolfSSL 14:167253f4e170 4228 SP_NOINLINE static void sp_3072_sqr_68(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4229 {
wolfSSL 14:167253f4e170 4230 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 4231 sp_digit z1[68];
wolfSSL 14:167253f4e170 4232 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 4233 sp_digit* z2 = r + 68;
wolfSSL 14:167253f4e170 4234 sp_3072_add_34(a1, a, &a[34]);
wolfSSL 14:167253f4e170 4235 sp_3072_sqr_34(z2, &a[34]);
wolfSSL 14:167253f4e170 4236 sp_3072_sqr_34(z0, a);
wolfSSL 14:167253f4e170 4237 sp_3072_sqr_34(z1, a1);
wolfSSL 14:167253f4e170 4238 sp_3072_sub_68(z1, z1, z2);
wolfSSL 14:167253f4e170 4239 sp_3072_sub_68(z1, z1, z0);
wolfSSL 14:167253f4e170 4240 sp_3072_add_68(r + 34, r + 34, z1);
wolfSSL 14:167253f4e170 4241 }
wolfSSL 14:167253f4e170 4242
wolfSSL 14:167253f4e170 4243 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 4244 *
wolfSSL 14:167253f4e170 4245 * r A single precision integer.
wolfSSL 14:167253f4e170 4246 * a A single precision integer.
wolfSSL 14:167253f4e170 4247 * b A single precision integer.
wolfSSL 14:167253f4e170 4248 */
wolfSSL 14:167253f4e170 4249 SP_NOINLINE static int sp_3072_add_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4250 const sp_digit* b)
wolfSSL 14:167253f4e170 4251 {
wolfSSL 14:167253f4e170 4252 int i;
wolfSSL 14:167253f4e170 4253
wolfSSL 14:167253f4e170 4254 for (i = 0; i < 136; i += 8) {
wolfSSL 14:167253f4e170 4255 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 4256 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 4257 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 4258 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 4259 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 4260 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 4261 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 4262 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 4263 }
wolfSSL 14:167253f4e170 4264
wolfSSL 14:167253f4e170 4265 return 0;
wolfSSL 14:167253f4e170 4266 }
wolfSSL 14:167253f4e170 4267
wolfSSL 14:167253f4e170 4268 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 4269 *
wolfSSL 14:167253f4e170 4270 * r A single precision integer.
wolfSSL 14:167253f4e170 4271 * a A single precision integer.
wolfSSL 14:167253f4e170 4272 * b A single precision integer.
wolfSSL 14:167253f4e170 4273 */
wolfSSL 14:167253f4e170 4274 SP_NOINLINE static int sp_3072_sub_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4275 const sp_digit* b)
wolfSSL 14:167253f4e170 4276 {
wolfSSL 14:167253f4e170 4277 int i;
wolfSSL 14:167253f4e170 4278
wolfSSL 14:167253f4e170 4279 for (i = 0; i < 136; i += 8) {
wolfSSL 14:167253f4e170 4280 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 4281 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 4282 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 4283 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 4284 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 4285 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 4286 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 4287 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 4288 }
wolfSSL 14:167253f4e170 4289
wolfSSL 14:167253f4e170 4290 return 0;
wolfSSL 14:167253f4e170 4291 }
wolfSSL 14:167253f4e170 4292
wolfSSL 14:167253f4e170 4293 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 4294 *
wolfSSL 14:167253f4e170 4295 * r A single precision integer.
wolfSSL 14:167253f4e170 4296 * a A single precision integer.
wolfSSL 14:167253f4e170 4297 * b A single precision integer.
wolfSSL 14:167253f4e170 4298 */
wolfSSL 14:167253f4e170 4299 SP_NOINLINE static void sp_3072_mul_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4300 const sp_digit* b)
wolfSSL 14:167253f4e170 4301 {
wolfSSL 14:167253f4e170 4302 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 4303 sp_digit z1[136];
wolfSSL 14:167253f4e170 4304 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 4305 sp_digit b1[68];
wolfSSL 14:167253f4e170 4306 sp_digit* z2 = r + 136;
wolfSSL 14:167253f4e170 4307 sp_3072_add_68(a1, a, &a[68]);
wolfSSL 14:167253f4e170 4308 sp_3072_add_68(b1, b, &b[68]);
wolfSSL 14:167253f4e170 4309 sp_3072_mul_68(z2, &a[68], &b[68]);
wolfSSL 14:167253f4e170 4310 sp_3072_mul_68(z0, a, b);
wolfSSL 14:167253f4e170 4311 sp_3072_mul_68(z1, a1, b1);
wolfSSL 14:167253f4e170 4312 sp_3072_sub_136(z1, z1, z2);
wolfSSL 14:167253f4e170 4313 sp_3072_sub_136(z1, z1, z0);
wolfSSL 14:167253f4e170 4314 sp_3072_add_136(r + 68, r + 68, z1);
wolfSSL 14:167253f4e170 4315 }
wolfSSL 14:167253f4e170 4316
wolfSSL 14:167253f4e170 4317 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 4318 *
wolfSSL 14:167253f4e170 4319 * r A single precision integer.
wolfSSL 14:167253f4e170 4320 * a A single precision integer.
wolfSSL 14:167253f4e170 4321 */
wolfSSL 14:167253f4e170 4322 SP_NOINLINE static void sp_3072_sqr_136(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4323 {
wolfSSL 14:167253f4e170 4324 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 4325 sp_digit z1[136];
wolfSSL 14:167253f4e170 4326 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 4327 sp_digit* z2 = r + 136;
wolfSSL 14:167253f4e170 4328 sp_3072_add_68(a1, a, &a[68]);
wolfSSL 14:167253f4e170 4329 sp_3072_sqr_68(z2, &a[68]);
wolfSSL 14:167253f4e170 4330 sp_3072_sqr_68(z0, a);
wolfSSL 14:167253f4e170 4331 sp_3072_sqr_68(z1, a1);
wolfSSL 14:167253f4e170 4332 sp_3072_sub_136(z1, z1, z2);
wolfSSL 14:167253f4e170 4333 sp_3072_sub_136(z1, z1, z0);
wolfSSL 14:167253f4e170 4334 sp_3072_add_136(r + 68, r + 68, z1);
wolfSSL 14:167253f4e170 4335 }
wolfSSL 14:167253f4e170 4336
wolfSSL 14:167253f4e170 4337 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4338 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4339 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 4340 *
wolfSSL 14:167253f4e170 4341 * r A single precision integer.
wolfSSL 14:167253f4e170 4342 * a A single precision integer.
wolfSSL 14:167253f4e170 4343 * b A single precision integer.
wolfSSL 14:167253f4e170 4344 */
wolfSSL 14:167253f4e170 4345 SP_NOINLINE static int sp_3072_add_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4346 const sp_digit* b)
wolfSSL 14:167253f4e170 4347 {
wolfSSL 14:167253f4e170 4348 int i;
wolfSSL 14:167253f4e170 4349
wolfSSL 14:167253f4e170 4350 for (i = 0; i < 136; i++)
wolfSSL 14:167253f4e170 4351 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 4352
wolfSSL 14:167253f4e170 4353 return 0;
wolfSSL 14:167253f4e170 4354 }
wolfSSL 14:167253f4e170 4355 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4356 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4357 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 4358 *
wolfSSL 14:167253f4e170 4359 * r A single precision integer.
wolfSSL 14:167253f4e170 4360 * a A single precision integer.
wolfSSL 14:167253f4e170 4361 * b A single precision integer.
wolfSSL 14:167253f4e170 4362 */
wolfSSL 14:167253f4e170 4363 SP_NOINLINE static int sp_3072_sub_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4364 const sp_digit* b)
wolfSSL 14:167253f4e170 4365 {
wolfSSL 14:167253f4e170 4366 int i;
wolfSSL 14:167253f4e170 4367
wolfSSL 14:167253f4e170 4368 for (i = 0; i < 136; i++)
wolfSSL 14:167253f4e170 4369 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 4370
wolfSSL 14:167253f4e170 4371 return 0;
wolfSSL 14:167253f4e170 4372 }
wolfSSL 14:167253f4e170 4373
wolfSSL 14:167253f4e170 4374 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4375 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4376 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 4377 *
wolfSSL 14:167253f4e170 4378 * r A single precision integer.
wolfSSL 14:167253f4e170 4379 * a A single precision integer.
wolfSSL 14:167253f4e170 4380 * b A single precision integer.
wolfSSL 14:167253f4e170 4381 */
wolfSSL 14:167253f4e170 4382 SP_NOINLINE static void sp_3072_mul_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4383 const sp_digit* b)
wolfSSL 14:167253f4e170 4384 {
wolfSSL 14:167253f4e170 4385 int i, j, k;
wolfSSL 14:167253f4e170 4386 int64_t c;
wolfSSL 14:167253f4e170 4387
wolfSSL 14:167253f4e170 4388 c = ((int64_t)a[135]) * b[135];
wolfSSL 14:167253f4e170 4389 r[271] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 4390 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 4391 for (k = 269; k >= 0; k--) {
wolfSSL 14:167253f4e170 4392 for (i = 135; i >= 0; i--) {
wolfSSL 14:167253f4e170 4393 j = k - i;
wolfSSL 14:167253f4e170 4394 if (j >= 136)
wolfSSL 14:167253f4e170 4395 break;
wolfSSL 14:167253f4e170 4396 if (j < 0)
wolfSSL 14:167253f4e170 4397 continue;
wolfSSL 14:167253f4e170 4398
wolfSSL 14:167253f4e170 4399 c += ((int64_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 4400 }
wolfSSL 14:167253f4e170 4401 r[k + 2] += c >> 46;
wolfSSL 14:167253f4e170 4402 r[k + 1] = (c >> 23) & 0x7fffff;
wolfSSL 14:167253f4e170 4403 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 4404 }
wolfSSL 14:167253f4e170 4405 r[0] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 4406 }
wolfSSL 14:167253f4e170 4407
wolfSSL 14:167253f4e170 4408 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 4409 *
wolfSSL 14:167253f4e170 4410 * r A single precision integer.
wolfSSL 14:167253f4e170 4411 * a A single precision integer.
wolfSSL 14:167253f4e170 4412 */
wolfSSL 14:167253f4e170 4413 SP_NOINLINE static void sp_3072_sqr_136(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4414 {
wolfSSL 14:167253f4e170 4415 int i, j, k;
wolfSSL 14:167253f4e170 4416 int64_t c;
wolfSSL 14:167253f4e170 4417
wolfSSL 14:167253f4e170 4418 c = ((int64_t)a[135]) * a[135];
wolfSSL 14:167253f4e170 4419 r[271] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 4420 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 4421 for (k = 269; k >= 0; k--) {
wolfSSL 14:167253f4e170 4422 for (i = 135; i >= 0; i--) {
wolfSSL 14:167253f4e170 4423 j = k - i;
wolfSSL 14:167253f4e170 4424 if (j >= 136 || i <= j)
wolfSSL 14:167253f4e170 4425 break;
wolfSSL 14:167253f4e170 4426 if (j < 0)
wolfSSL 14:167253f4e170 4427 continue;
wolfSSL 14:167253f4e170 4428
wolfSSL 14:167253f4e170 4429 c += ((int64_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 4430 }
wolfSSL 14:167253f4e170 4431 if (i == j)
wolfSSL 14:167253f4e170 4432 c += ((int64_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 4433
wolfSSL 14:167253f4e170 4434 r[k + 2] += c >> 46;
wolfSSL 14:167253f4e170 4435 r[k + 1] = (c >> 23) & 0x7fffff;
wolfSSL 14:167253f4e170 4436 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 4437 }
wolfSSL 14:167253f4e170 4438 r[0] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 4439 }
wolfSSL 14:167253f4e170 4440
wolfSSL 14:167253f4e170 4441 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4442 #if !defined(SP_RSA_PRIVATE_EXP_D) && defined(WOLFSSL_HAVE_SP_RSA)
wolfSSL 14:167253f4e170 4443 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4444 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 4445 *
wolfSSL 14:167253f4e170 4446 * r A single precision integer.
wolfSSL 14:167253f4e170 4447 * a A single precision integer.
wolfSSL 14:167253f4e170 4448 * b A single precision integer.
wolfSSL 14:167253f4e170 4449 */
wolfSSL 14:167253f4e170 4450 SP_NOINLINE static int sp_3072_add_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4451 const sp_digit* b)
wolfSSL 14:167253f4e170 4452 {
wolfSSL 14:167253f4e170 4453 int i;
wolfSSL 14:167253f4e170 4454
wolfSSL 14:167253f4e170 4455 for (i = 0; i < 68; i++)
wolfSSL 14:167253f4e170 4456 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 4457
wolfSSL 14:167253f4e170 4458 return 0;
wolfSSL 14:167253f4e170 4459 }
wolfSSL 14:167253f4e170 4460 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4461 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4462 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 4463 *
wolfSSL 14:167253f4e170 4464 * r A single precision integer.
wolfSSL 14:167253f4e170 4465 * a A single precision integer.
wolfSSL 14:167253f4e170 4466 * b A single precision integer.
wolfSSL 14:167253f4e170 4467 */
wolfSSL 14:167253f4e170 4468 SP_NOINLINE static int sp_3072_sub_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4469 const sp_digit* b)
wolfSSL 14:167253f4e170 4470 {
wolfSSL 14:167253f4e170 4471 int i;
wolfSSL 14:167253f4e170 4472
wolfSSL 14:167253f4e170 4473 for (i = 0; i < 68; i++)
wolfSSL 14:167253f4e170 4474 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 4475
wolfSSL 14:167253f4e170 4476 return 0;
wolfSSL 14:167253f4e170 4477 }
wolfSSL 14:167253f4e170 4478
wolfSSL 14:167253f4e170 4479 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4480 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4481 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 4482 *
wolfSSL 14:167253f4e170 4483 * r A single precision integer.
wolfSSL 14:167253f4e170 4484 * a A single precision integer.
wolfSSL 14:167253f4e170 4485 * b A single precision integer.
wolfSSL 14:167253f4e170 4486 */
wolfSSL 14:167253f4e170 4487 SP_NOINLINE static void sp_3072_mul_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4488 const sp_digit* b)
wolfSSL 14:167253f4e170 4489 {
wolfSSL 14:167253f4e170 4490 int i, j, k;
wolfSSL 14:167253f4e170 4491 int64_t c;
wolfSSL 14:167253f4e170 4492
wolfSSL 14:167253f4e170 4493 c = ((int64_t)a[67]) * b[67];
wolfSSL 14:167253f4e170 4494 r[135] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 4495 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 4496 for (k = 133; k >= 0; k--) {
wolfSSL 14:167253f4e170 4497 for (i = 67; i >= 0; i--) {
wolfSSL 14:167253f4e170 4498 j = k - i;
wolfSSL 14:167253f4e170 4499 if (j >= 68)
wolfSSL 14:167253f4e170 4500 break;
wolfSSL 14:167253f4e170 4501 if (j < 0)
wolfSSL 14:167253f4e170 4502 continue;
wolfSSL 14:167253f4e170 4503
wolfSSL 14:167253f4e170 4504 c += ((int64_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 4505 }
wolfSSL 14:167253f4e170 4506 r[k + 2] += c >> 46;
wolfSSL 14:167253f4e170 4507 r[k + 1] = (c >> 23) & 0x7fffff;
wolfSSL 14:167253f4e170 4508 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 4509 }
wolfSSL 14:167253f4e170 4510 r[0] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 4511 }
wolfSSL 14:167253f4e170 4512
wolfSSL 14:167253f4e170 4513 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 4514 *
wolfSSL 14:167253f4e170 4515 * r A single precision integer.
wolfSSL 14:167253f4e170 4516 * a A single precision integer.
wolfSSL 14:167253f4e170 4517 */
wolfSSL 14:167253f4e170 4518 SP_NOINLINE static void sp_3072_sqr_68(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4519 {
wolfSSL 14:167253f4e170 4520 int i, j, k;
wolfSSL 14:167253f4e170 4521 int64_t c;
wolfSSL 14:167253f4e170 4522
wolfSSL 14:167253f4e170 4523 c = ((int64_t)a[67]) * a[67];
wolfSSL 14:167253f4e170 4524 r[135] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 4525 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 4526 for (k = 133; k >= 0; k--) {
wolfSSL 14:167253f4e170 4527 for (i = 67; i >= 0; i--) {
wolfSSL 14:167253f4e170 4528 j = k - i;
wolfSSL 14:167253f4e170 4529 if (j >= 68 || i <= j)
wolfSSL 14:167253f4e170 4530 break;
wolfSSL 14:167253f4e170 4531 if (j < 0)
wolfSSL 14:167253f4e170 4532 continue;
wolfSSL 14:167253f4e170 4533
wolfSSL 14:167253f4e170 4534 c += ((int64_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 4535 }
wolfSSL 14:167253f4e170 4536 if (i == j)
wolfSSL 14:167253f4e170 4537 c += ((int64_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 4538
wolfSSL 14:167253f4e170 4539 r[k + 2] += c >> 46;
wolfSSL 14:167253f4e170 4540 r[k + 1] = (c >> 23) & 0x7fffff;
wolfSSL 14:167253f4e170 4541 c = (c & 0x7fffff) << 23;
wolfSSL 14:167253f4e170 4542 }
wolfSSL 14:167253f4e170 4543 r[0] = (sp_digit)(c >> 23);
wolfSSL 14:167253f4e170 4544 }
wolfSSL 14:167253f4e170 4545
wolfSSL 14:167253f4e170 4546 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4547 #endif /* !SP_RSA_PRIVATE_EXP_D && WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 4548
wolfSSL 14:167253f4e170 4549 /* Caclulate the bottom digit of -1/a mod 2^n.
wolfSSL 14:167253f4e170 4550 *
wolfSSL 14:167253f4e170 4551 * a A single precision number.
wolfSSL 14:167253f4e170 4552 * rho Bottom word of inverse.
wolfSSL 14:167253f4e170 4553 */
wolfSSL 14:167253f4e170 4554 static void sp_3072_mont_setup(sp_digit* a, sp_digit* rho)
wolfSSL 14:167253f4e170 4555 {
wolfSSL 14:167253f4e170 4556 sp_digit x, b;
wolfSSL 14:167253f4e170 4557
wolfSSL 14:167253f4e170 4558 b = a[0];
wolfSSL 14:167253f4e170 4559 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
wolfSSL 14:167253f4e170 4560 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
wolfSSL 14:167253f4e170 4561 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
wolfSSL 14:167253f4e170 4562 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
wolfSSL 14:167253f4e170 4563 x &= 0x7fffff;
wolfSSL 14:167253f4e170 4564
wolfSSL 14:167253f4e170 4565 /* rho = -1/m mod b */
wolfSSL 14:167253f4e170 4566 *rho = (1L << 23) - x;
wolfSSL 14:167253f4e170 4567 }
wolfSSL 14:167253f4e170 4568
wolfSSL 14:167253f4e170 4569 #if !defined(SP_RSA_PRIVATE_EXP_D) && defined(WOLFSSL_HAVE_SP_RSA)
wolfSSL 14:167253f4e170 4570 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 14:167253f4e170 4571 * Given m must be 3072 bits, just need to subtract.
wolfSSL 14:167253f4e170 4572 *
wolfSSL 14:167253f4e170 4573 * r A single precision number.
wolfSSL 14:167253f4e170 4574 * m A signle precision number.
wolfSSL 14:167253f4e170 4575 */
wolfSSL 14:167253f4e170 4576 static void sp_3072_mont_norm_68(sp_digit* r, sp_digit* m)
wolfSSL 14:167253f4e170 4577 {
wolfSSL 14:167253f4e170 4578 /* Set r = 2^n - 1. */
wolfSSL 14:167253f4e170 4579 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4580 int i;
wolfSSL 14:167253f4e170 4581
wolfSSL 14:167253f4e170 4582 for (i=0; i<67; i++)
wolfSSL 14:167253f4e170 4583 r[i] = 0x7fffff;
wolfSSL 14:167253f4e170 4584 #else
wolfSSL 14:167253f4e170 4585 int i;
wolfSSL 14:167253f4e170 4586
wolfSSL 14:167253f4e170 4587 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 4588 r[i + 0] = 0x7fffff;
wolfSSL 14:167253f4e170 4589 r[i + 1] = 0x7fffff;
wolfSSL 14:167253f4e170 4590 r[i + 2] = 0x7fffff;
wolfSSL 14:167253f4e170 4591 r[i + 3] = 0x7fffff;
wolfSSL 14:167253f4e170 4592 r[i + 4] = 0x7fffff;
wolfSSL 14:167253f4e170 4593 r[i + 5] = 0x7fffff;
wolfSSL 14:167253f4e170 4594 r[i + 6] = 0x7fffff;
wolfSSL 14:167253f4e170 4595 r[i + 7] = 0x7fffff;
wolfSSL 14:167253f4e170 4596 }
wolfSSL 14:167253f4e170 4597 r[64] = 0x7fffff;
wolfSSL 14:167253f4e170 4598 r[65] = 0x7fffff;
wolfSSL 14:167253f4e170 4599 r[66] = 0x7fffff;
wolfSSL 14:167253f4e170 4600 #endif
wolfSSL 14:167253f4e170 4601 r[67] = 0x3ffffl;
wolfSSL 14:167253f4e170 4602
wolfSSL 14:167253f4e170 4603 /* r = (2^n - 1) mod n */
wolfSSL 14:167253f4e170 4604 sp_3072_sub_68(r, r, m);
wolfSSL 14:167253f4e170 4605
wolfSSL 14:167253f4e170 4606 /* Add one so r = 2^n mod m */
wolfSSL 14:167253f4e170 4607 r[0] += 1;
wolfSSL 14:167253f4e170 4608 }
wolfSSL 14:167253f4e170 4609
wolfSSL 14:167253f4e170 4610 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 4611 *
wolfSSL 14:167253f4e170 4612 * a A single precision integer.
wolfSSL 14:167253f4e170 4613 * b A single precision integer.
wolfSSL 14:167253f4e170 4614 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 4615 * respectively.
wolfSSL 14:167253f4e170 4616 */
wolfSSL 14:167253f4e170 4617 static sp_digit sp_3072_cmp_68(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 4618 {
wolfSSL 14:167253f4e170 4619 sp_digit r = 0;
wolfSSL 14:167253f4e170 4620 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4621 int i;
wolfSSL 14:167253f4e170 4622
wolfSSL 14:167253f4e170 4623 for (i=67; i>=0; i--)
wolfSSL 14:167253f4e170 4624 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 4625 #else
wolfSSL 14:167253f4e170 4626 int i;
wolfSSL 14:167253f4e170 4627
wolfSSL 14:167253f4e170 4628 r |= (a[67] - b[67]) & (0 - !r);
wolfSSL 14:167253f4e170 4629 r |= (a[66] - b[66]) & (0 - !r);
wolfSSL 14:167253f4e170 4630 r |= (a[65] - b[65]) & (0 - !r);
wolfSSL 14:167253f4e170 4631 r |= (a[64] - b[64]) & (0 - !r);
wolfSSL 14:167253f4e170 4632 for (i = 56; i >= 0; i -= 8) {
wolfSSL 14:167253f4e170 4633 r |= (a[i + 7] - b[i + 7]) & (0 - !r);
wolfSSL 14:167253f4e170 4634 r |= (a[i + 6] - b[i + 6]) & (0 - !r);
wolfSSL 14:167253f4e170 4635 r |= (a[i + 5] - b[i + 5]) & (0 - !r);
wolfSSL 14:167253f4e170 4636 r |= (a[i + 4] - b[i + 4]) & (0 - !r);
wolfSSL 14:167253f4e170 4637 r |= (a[i + 3] - b[i + 3]) & (0 - !r);
wolfSSL 14:167253f4e170 4638 r |= (a[i + 2] - b[i + 2]) & (0 - !r);
wolfSSL 14:167253f4e170 4639 r |= (a[i + 1] - b[i + 1]) & (0 - !r);
wolfSSL 14:167253f4e170 4640 r |= (a[i + 0] - b[i + 0]) & (0 - !r);
wolfSSL 14:167253f4e170 4641 }
wolfSSL 14:167253f4e170 4642 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4643
wolfSSL 14:167253f4e170 4644 return r;
wolfSSL 14:167253f4e170 4645 }
wolfSSL 14:167253f4e170 4646
wolfSSL 14:167253f4e170 4647 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 4648 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 4649 *
wolfSSL 14:167253f4e170 4650 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 4651 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 4652 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 4653 * m Mask value to apply.
wolfSSL 14:167253f4e170 4654 */
wolfSSL 14:167253f4e170 4655 static void sp_3072_cond_sub_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4656 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 4657 {
wolfSSL 14:167253f4e170 4658 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4659 int i;
wolfSSL 14:167253f4e170 4660
wolfSSL 14:167253f4e170 4661 for (i = 0; i < 68; i++)
wolfSSL 14:167253f4e170 4662 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 4663 #else
wolfSSL 14:167253f4e170 4664 int i;
wolfSSL 14:167253f4e170 4665
wolfSSL 14:167253f4e170 4666 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 4667 r[i + 0] = a[i + 0] - (b[i + 0] & m);
wolfSSL 14:167253f4e170 4668 r[i + 1] = a[i + 1] - (b[i + 1] & m);
wolfSSL 14:167253f4e170 4669 r[i + 2] = a[i + 2] - (b[i + 2] & m);
wolfSSL 14:167253f4e170 4670 r[i + 3] = a[i + 3] - (b[i + 3] & m);
wolfSSL 14:167253f4e170 4671 r[i + 4] = a[i + 4] - (b[i + 4] & m);
wolfSSL 14:167253f4e170 4672 r[i + 5] = a[i + 5] - (b[i + 5] & m);
wolfSSL 14:167253f4e170 4673 r[i + 6] = a[i + 6] - (b[i + 6] & m);
wolfSSL 14:167253f4e170 4674 r[i + 7] = a[i + 7] - (b[i + 7] & m);
wolfSSL 14:167253f4e170 4675 }
wolfSSL 14:167253f4e170 4676 r[64] = a[64] - (b[64] & m);
wolfSSL 14:167253f4e170 4677 r[65] = a[65] - (b[65] & m);
wolfSSL 14:167253f4e170 4678 r[66] = a[66] - (b[66] & m);
wolfSSL 14:167253f4e170 4679 r[67] = a[67] - (b[67] & m);
wolfSSL 14:167253f4e170 4680 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4681 }
wolfSSL 14:167253f4e170 4682
wolfSSL 14:167253f4e170 4683 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 4684 *
wolfSSL 14:167253f4e170 4685 * r A single precision integer.
wolfSSL 14:167253f4e170 4686 * a A single precision integer.
wolfSSL 14:167253f4e170 4687 * b A scalar.
wolfSSL 14:167253f4e170 4688 */
wolfSSL 14:167253f4e170 4689 SP_NOINLINE static void sp_3072_mul_add_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4690 const sp_digit b)
wolfSSL 14:167253f4e170 4691 {
wolfSSL 14:167253f4e170 4692 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4693 int64_t tb = b;
wolfSSL 14:167253f4e170 4694 int64_t t = 0;
wolfSSL 14:167253f4e170 4695 int i;
wolfSSL 14:167253f4e170 4696
wolfSSL 14:167253f4e170 4697 for (i = 0; i < 68; i++) {
wolfSSL 14:167253f4e170 4698 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 4699 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 4700 t >>= 23;
wolfSSL 14:167253f4e170 4701 }
wolfSSL 14:167253f4e170 4702 r[68] += t;
wolfSSL 14:167253f4e170 4703 #else
wolfSSL 14:167253f4e170 4704 int64_t tb = b;
wolfSSL 14:167253f4e170 4705 int64_t t[8];
wolfSSL 14:167253f4e170 4706 int i;
wolfSSL 14:167253f4e170 4707
wolfSSL 14:167253f4e170 4708 t[0] = tb * a[0]; r[0] += t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 4709 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 4710 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 4711 r[i+1] += (t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 4712 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 4713 r[i+2] += (t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 4714 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 4715 r[i+3] += (t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 4716 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 4717 r[i+4] += (t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 4718 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 4719 r[i+5] += (t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 4720 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 4721 r[i+6] += (t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 4722 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 4723 r[i+7] += (t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 4724 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 4725 r[i+8] += (t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 4726 }
wolfSSL 14:167253f4e170 4727 t[1] = tb * a[65]; r[65] += (t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 4728 t[2] = tb * a[66]; r[66] += (t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 4729 t[3] = tb * a[67]; r[67] += (t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 4730 r[68] += t[3] >> 23;
wolfSSL 14:167253f4e170 4731 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4732 }
wolfSSL 14:167253f4e170 4733
wolfSSL 14:167253f4e170 4734 /* Normalize the values in each word to 23.
wolfSSL 14:167253f4e170 4735 *
wolfSSL 14:167253f4e170 4736 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 4737 */
wolfSSL 14:167253f4e170 4738 static void sp_3072_norm_68(sp_digit* a)
wolfSSL 14:167253f4e170 4739 {
wolfSSL 14:167253f4e170 4740 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4741 int i;
wolfSSL 14:167253f4e170 4742 for (i = 0; i < 67; i++) {
wolfSSL 14:167253f4e170 4743 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 4744 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 4745 }
wolfSSL 14:167253f4e170 4746 #else
wolfSSL 14:167253f4e170 4747 int i;
wolfSSL 14:167253f4e170 4748 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 4749 a[i+1] += a[i+0] >> 23; a[i+0] &= 0x7fffff;
wolfSSL 14:167253f4e170 4750 a[i+2] += a[i+1] >> 23; a[i+1] &= 0x7fffff;
wolfSSL 14:167253f4e170 4751 a[i+3] += a[i+2] >> 23; a[i+2] &= 0x7fffff;
wolfSSL 14:167253f4e170 4752 a[i+4] += a[i+3] >> 23; a[i+3] &= 0x7fffff;
wolfSSL 14:167253f4e170 4753 a[i+5] += a[i+4] >> 23; a[i+4] &= 0x7fffff;
wolfSSL 14:167253f4e170 4754 a[i+6] += a[i+5] >> 23; a[i+5] &= 0x7fffff;
wolfSSL 14:167253f4e170 4755 a[i+7] += a[i+6] >> 23; a[i+6] &= 0x7fffff;
wolfSSL 14:167253f4e170 4756 a[i+8] += a[i+7] >> 23; a[i+7] &= 0x7fffff;
wolfSSL 14:167253f4e170 4757 a[i+9] += a[i+8] >> 23; a[i+8] &= 0x7fffff;
wolfSSL 14:167253f4e170 4758 }
wolfSSL 14:167253f4e170 4759 a[64+1] += a[64] >> 23;
wolfSSL 14:167253f4e170 4760 a[64] &= 0x7fffff;
wolfSSL 14:167253f4e170 4761 a[65+1] += a[65] >> 23;
wolfSSL 14:167253f4e170 4762 a[65] &= 0x7fffff;
wolfSSL 14:167253f4e170 4763 a[66+1] += a[66] >> 23;
wolfSSL 14:167253f4e170 4764 a[66] &= 0x7fffff;
wolfSSL 14:167253f4e170 4765 #endif
wolfSSL 14:167253f4e170 4766 }
wolfSSL 14:167253f4e170 4767
wolfSSL 14:167253f4e170 4768 /* Shift the result in the high 1536 bits down to the bottom.
wolfSSL 14:167253f4e170 4769 *
wolfSSL 14:167253f4e170 4770 * r A single precision number.
wolfSSL 14:167253f4e170 4771 * a A single precision number.
wolfSSL 14:167253f4e170 4772 */
wolfSSL 14:167253f4e170 4773 static void sp_3072_mont_shift_68(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4774 {
wolfSSL 14:167253f4e170 4775 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4776 int i;
wolfSSL 14:167253f4e170 4777 sp_digit n, s;
wolfSSL 14:167253f4e170 4778
wolfSSL 14:167253f4e170 4779 s = a[68];
wolfSSL 14:167253f4e170 4780 n = a[67] >> 18;
wolfSSL 14:167253f4e170 4781 for (i = 0; i < 67; i++) {
wolfSSL 14:167253f4e170 4782 n += (s & 0x7fffff) << 5;
wolfSSL 14:167253f4e170 4783 r[i] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4784 n >>= 23;
wolfSSL 14:167253f4e170 4785 s = a[69 + i] + (s >> 23);
wolfSSL 14:167253f4e170 4786 }
wolfSSL 14:167253f4e170 4787 n += s << 5;
wolfSSL 14:167253f4e170 4788 r[67] = n;
wolfSSL 14:167253f4e170 4789 #else
wolfSSL 14:167253f4e170 4790 sp_digit n, s;
wolfSSL 14:167253f4e170 4791 int i;
wolfSSL 14:167253f4e170 4792
wolfSSL 14:167253f4e170 4793 s = a[68]; n = a[67] >> 18;
wolfSSL 14:167253f4e170 4794 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 4795 n += (s & 0x7fffff) << 5; r[i+0] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4796 n >>= 23; s = a[i+69] + (s >> 23);
wolfSSL 14:167253f4e170 4797 n += (s & 0x7fffff) << 5; r[i+1] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4798 n >>= 23; s = a[i+70] + (s >> 23);
wolfSSL 14:167253f4e170 4799 n += (s & 0x7fffff) << 5; r[i+2] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4800 n >>= 23; s = a[i+71] + (s >> 23);
wolfSSL 14:167253f4e170 4801 n += (s & 0x7fffff) << 5; r[i+3] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4802 n >>= 23; s = a[i+72] + (s >> 23);
wolfSSL 14:167253f4e170 4803 n += (s & 0x7fffff) << 5; r[i+4] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4804 n >>= 23; s = a[i+73] + (s >> 23);
wolfSSL 14:167253f4e170 4805 n += (s & 0x7fffff) << 5; r[i+5] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4806 n >>= 23; s = a[i+74] + (s >> 23);
wolfSSL 14:167253f4e170 4807 n += (s & 0x7fffff) << 5; r[i+6] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4808 n >>= 23; s = a[i+75] + (s >> 23);
wolfSSL 14:167253f4e170 4809 n += (s & 0x7fffff) << 5; r[i+7] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4810 n >>= 23; s = a[i+76] + (s >> 23);
wolfSSL 14:167253f4e170 4811 }
wolfSSL 14:167253f4e170 4812 n += (s & 0x7fffff) << 5; r[64] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4813 n >>= 23; s = a[133] + (s >> 23);
wolfSSL 14:167253f4e170 4814 n += (s & 0x7fffff) << 5; r[65] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4815 n >>= 23; s = a[134] + (s >> 23);
wolfSSL 14:167253f4e170 4816 n += (s & 0x7fffff) << 5; r[66] = n & 0x7fffff;
wolfSSL 14:167253f4e170 4817 n >>= 23; s = a[135] + (s >> 23);
wolfSSL 14:167253f4e170 4818 n += s << 5; r[67] = n;
wolfSSL 14:167253f4e170 4819 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4820 XMEMSET(&r[68], 0, sizeof(*r) * 68);
wolfSSL 14:167253f4e170 4821 }
wolfSSL 14:167253f4e170 4822
wolfSSL 14:167253f4e170 4823 /* Reduce the number back to 3072 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 4824 *
wolfSSL 14:167253f4e170 4825 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 4826 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 4827 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 4828 */
wolfSSL 14:167253f4e170 4829 static void sp_3072_mont_reduce_68(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 4830 {
wolfSSL 14:167253f4e170 4831 int i;
wolfSSL 14:167253f4e170 4832 sp_digit mu;
wolfSSL 14:167253f4e170 4833
wolfSSL 14:167253f4e170 4834 for (i=0; i<67; i++) {
wolfSSL 14:167253f4e170 4835 mu = (a[i] * mp) & 0x7fffff;
wolfSSL 14:167253f4e170 4836 sp_3072_mul_add_68(a+i, m, mu);
wolfSSL 14:167253f4e170 4837 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 4838 }
wolfSSL 14:167253f4e170 4839 mu = (a[i] * mp) & 0x3ffffl;
wolfSSL 14:167253f4e170 4840 sp_3072_mul_add_68(a+i, m, mu);
wolfSSL 14:167253f4e170 4841 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 4842 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 4843
wolfSSL 14:167253f4e170 4844 sp_3072_mont_shift_68(a, a);
wolfSSL 14:167253f4e170 4845 sp_3072_cond_sub_68(a, a, m, 0 - ((a[67] >> 18) > 0));
wolfSSL 14:167253f4e170 4846 sp_3072_norm_68(a);
wolfSSL 14:167253f4e170 4847 }
wolfSSL 14:167253f4e170 4848
wolfSSL 14:167253f4e170 4849 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 4850 * (r = a * b mod m)
wolfSSL 14:167253f4e170 4851 *
wolfSSL 14:167253f4e170 4852 * r Result of multiplication.
wolfSSL 14:167253f4e170 4853 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 4854 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 4855 * m Modulus (prime).
wolfSSL 14:167253f4e170 4856 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 4857 */
wolfSSL 14:167253f4e170 4858 static void sp_3072_mont_mul_68(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 4859 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 4860 {
wolfSSL 14:167253f4e170 4861 sp_3072_mul_68(r, a, b);
wolfSSL 14:167253f4e170 4862 sp_3072_mont_reduce_68(r, m, mp);
wolfSSL 14:167253f4e170 4863 }
wolfSSL 14:167253f4e170 4864
wolfSSL 14:167253f4e170 4865 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 4866 *
wolfSSL 14:167253f4e170 4867 * r Result of squaring.
wolfSSL 14:167253f4e170 4868 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 4869 * m Modulus (prime).
wolfSSL 14:167253f4e170 4870 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 4871 */
wolfSSL 14:167253f4e170 4872 static void sp_3072_mont_sqr_68(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 4873 sp_digit mp)
wolfSSL 14:167253f4e170 4874 {
wolfSSL 14:167253f4e170 4875 sp_3072_sqr_68(r, a);
wolfSSL 14:167253f4e170 4876 sp_3072_mont_reduce_68(r, m, mp);
wolfSSL 14:167253f4e170 4877 }
wolfSSL 14:167253f4e170 4878
wolfSSL 14:167253f4e170 4879 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 4880 *
wolfSSL 14:167253f4e170 4881 * r A single precision integer.
wolfSSL 14:167253f4e170 4882 * a A single precision integer.
wolfSSL 14:167253f4e170 4883 * b A scalar.
wolfSSL 14:167253f4e170 4884 */
wolfSSL 14:167253f4e170 4885 SP_NOINLINE static void sp_3072_mul_d_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4886 const sp_digit b)
wolfSSL 14:167253f4e170 4887 {
wolfSSL 14:167253f4e170 4888 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4889 int64_t tb = b;
wolfSSL 14:167253f4e170 4890 int64_t t = 0;
wolfSSL 14:167253f4e170 4891 int i;
wolfSSL 14:167253f4e170 4892
wolfSSL 14:167253f4e170 4893 for (i = 0; i < 68; i++) {
wolfSSL 14:167253f4e170 4894 t += tb * a[i];
wolfSSL 14:167253f4e170 4895 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 4896 t >>= 23;
wolfSSL 14:167253f4e170 4897 }
wolfSSL 14:167253f4e170 4898 r[68] = (sp_digit)t;
wolfSSL 14:167253f4e170 4899 #else
wolfSSL 14:167253f4e170 4900 int64_t tb = b;
wolfSSL 14:167253f4e170 4901 int64_t t[8];
wolfSSL 14:167253f4e170 4902 int i;
wolfSSL 14:167253f4e170 4903
wolfSSL 14:167253f4e170 4904 t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 4905 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 4906 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 4907 r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 4908 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 4909 r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 4910 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 4911 r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 4912 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 4913 r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 4914 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 4915 r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 4916 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 4917 r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 4918 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 4919 r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 4920 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 4921 r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 4922 }
wolfSSL 14:167253f4e170 4923 t[1] = tb * a[65];
wolfSSL 14:167253f4e170 4924 r[65] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 4925 t[2] = tb * a[66];
wolfSSL 14:167253f4e170 4926 r[66] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 4927 t[3] = tb * a[67];
wolfSSL 14:167253f4e170 4928 r[67] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 4929 r[68] = (sp_digit)(t[3] >> 23);
wolfSSL 14:167253f4e170 4930 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4931 }
wolfSSL 14:167253f4e170 4932
wolfSSL 14:167253f4e170 4933 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 4934 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 4935 *
wolfSSL 14:167253f4e170 4936 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 4937 * a A single precision number to add with.
wolfSSL 14:167253f4e170 4938 * b A single precision number to add.
wolfSSL 14:167253f4e170 4939 * m Mask value to apply.
wolfSSL 14:167253f4e170 4940 */
wolfSSL 14:167253f4e170 4941 static void sp_3072_cond_add_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4942 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 4943 {
wolfSSL 14:167253f4e170 4944 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4945 int i;
wolfSSL 14:167253f4e170 4946
wolfSSL 14:167253f4e170 4947 for (i = 0; i < 68; i++)
wolfSSL 14:167253f4e170 4948 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 4949 #else
wolfSSL 14:167253f4e170 4950 int i;
wolfSSL 14:167253f4e170 4951
wolfSSL 14:167253f4e170 4952 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 4953 r[i + 0] = a[i + 0] + (b[i + 0] & m);
wolfSSL 14:167253f4e170 4954 r[i + 1] = a[i + 1] + (b[i + 1] & m);
wolfSSL 14:167253f4e170 4955 r[i + 2] = a[i + 2] + (b[i + 2] & m);
wolfSSL 14:167253f4e170 4956 r[i + 3] = a[i + 3] + (b[i + 3] & m);
wolfSSL 14:167253f4e170 4957 r[i + 4] = a[i + 4] + (b[i + 4] & m);
wolfSSL 14:167253f4e170 4958 r[i + 5] = a[i + 5] + (b[i + 5] & m);
wolfSSL 14:167253f4e170 4959 r[i + 6] = a[i + 6] + (b[i + 6] & m);
wolfSSL 14:167253f4e170 4960 r[i + 7] = a[i + 7] + (b[i + 7] & m);
wolfSSL 14:167253f4e170 4961 }
wolfSSL 14:167253f4e170 4962 r[64] = a[64] + (b[64] & m);
wolfSSL 14:167253f4e170 4963 r[65] = a[65] + (b[65] & m);
wolfSSL 14:167253f4e170 4964 r[66] = a[66] + (b[66] & m);
wolfSSL 14:167253f4e170 4965 r[67] = a[67] + (b[67] & m);
wolfSSL 14:167253f4e170 4966 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4967 }
wolfSSL 14:167253f4e170 4968
wolfSSL 14:167253f4e170 4969 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 4970 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 4971 *
wolfSSL 14:167253f4e170 4972 * r A single precision integer.
wolfSSL 14:167253f4e170 4973 * a A single precision integer.
wolfSSL 14:167253f4e170 4974 * b A single precision integer.
wolfSSL 14:167253f4e170 4975 */
wolfSSL 14:167253f4e170 4976 SP_NOINLINE static int sp_3072_sub_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4977 const sp_digit* b)
wolfSSL 14:167253f4e170 4978 {
wolfSSL 14:167253f4e170 4979 int i;
wolfSSL 14:167253f4e170 4980
wolfSSL 14:167253f4e170 4981 for (i = 0; i < 68; i++)
wolfSSL 14:167253f4e170 4982 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 4983
wolfSSL 14:167253f4e170 4984 return 0;
wolfSSL 14:167253f4e170 4985 }
wolfSSL 14:167253f4e170 4986
wolfSSL 14:167253f4e170 4987 #endif
wolfSSL 14:167253f4e170 4988 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 4989 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 4990 *
wolfSSL 14:167253f4e170 4991 * r A single precision integer.
wolfSSL 14:167253f4e170 4992 * a A single precision integer.
wolfSSL 14:167253f4e170 4993 * b A single precision integer.
wolfSSL 14:167253f4e170 4994 */
wolfSSL 14:167253f4e170 4995 SP_NOINLINE static int sp_3072_add_68(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4996 const sp_digit* b)
wolfSSL 14:167253f4e170 4997 {
wolfSSL 14:167253f4e170 4998 int i;
wolfSSL 14:167253f4e170 4999
wolfSSL 14:167253f4e170 5000 for (i = 0; i < 68; i++)
wolfSSL 14:167253f4e170 5001 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 5002
wolfSSL 14:167253f4e170 5003 return 0;
wolfSSL 14:167253f4e170 5004 }
wolfSSL 14:167253f4e170 5005 #endif
wolfSSL 14:167253f4e170 5006 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 5007 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 5008 *
wolfSSL 14:167253f4e170 5009 * a Nmber to be divided.
wolfSSL 14:167253f4e170 5010 * d Number to divide with.
wolfSSL 14:167253f4e170 5011 * m Multiplier result.
wolfSSL 14:167253f4e170 5012 * r Remainder from the division.
wolfSSL 14:167253f4e170 5013 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 5014 */
wolfSSL 14:167253f4e170 5015 static int sp_3072_div_68(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 5016 sp_digit* r)
wolfSSL 14:167253f4e170 5017 {
wolfSSL 14:167253f4e170 5018 int i;
wolfSSL 14:167253f4e170 5019 int64_t d1;
wolfSSL 14:167253f4e170 5020 sp_digit div, r1;
wolfSSL 14:167253f4e170 5021 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 5022 sp_digit* td;
wolfSSL 14:167253f4e170 5023 #else
wolfSSL 14:167253f4e170 5024 sp_digit t1d[136], t2d[68 + 1];
wolfSSL 14:167253f4e170 5025 #endif
wolfSSL 14:167253f4e170 5026 sp_digit* t1;
wolfSSL 14:167253f4e170 5027 sp_digit* t2;
wolfSSL 14:167253f4e170 5028 int err = MP_OKAY;
wolfSSL 14:167253f4e170 5029
wolfSSL 14:167253f4e170 5030 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 5031 td = XMALLOC(sizeof(sp_digit) * (3 * 68 + 1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5032 if (td != NULL) {
wolfSSL 14:167253f4e170 5033 t1 = td;
wolfSSL 14:167253f4e170 5034 t2 = td + 2 * 68;
wolfSSL 14:167253f4e170 5035 }
wolfSSL 14:167253f4e170 5036 else
wolfSSL 14:167253f4e170 5037 err = MEMORY_E;
wolfSSL 14:167253f4e170 5038 #else
wolfSSL 14:167253f4e170 5039 t1 = t1d;
wolfSSL 14:167253f4e170 5040 t2 = t2d;
wolfSSL 14:167253f4e170 5041 #endif
wolfSSL 14:167253f4e170 5042
wolfSSL 14:167253f4e170 5043 (void)m;
wolfSSL 14:167253f4e170 5044
wolfSSL 14:167253f4e170 5045 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5046 div = d[67];
wolfSSL 14:167253f4e170 5047 XMEMCPY(t1, a, sizeof(*t1) * 2 * 68);
wolfSSL 14:167253f4e170 5048 for (i=67; i>=0; i--) {
wolfSSL 14:167253f4e170 5049 t1[68 + i] += t1[68 + i - 1] >> 23;
wolfSSL 14:167253f4e170 5050 t1[68 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 5051 d1 = t1[68 + i];
wolfSSL 14:167253f4e170 5052 d1 <<= 23;
wolfSSL 14:167253f4e170 5053 d1 += t1[68 + i - 1];
wolfSSL 14:167253f4e170 5054 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 5055
wolfSSL 14:167253f4e170 5056 sp_3072_mul_d_68(t2, d, r1);
wolfSSL 14:167253f4e170 5057 sp_3072_sub_68(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 5058 t1[68 + i] -= t2[68];
wolfSSL 14:167253f4e170 5059 t1[68 + i] += t1[68 + i - 1] >> 23;
wolfSSL 14:167253f4e170 5060 t1[68 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 5061 r1 = (((-t1[68 + i]) << 23) - t1[68 + i - 1]) / div;
wolfSSL 14:167253f4e170 5062 r1++;
wolfSSL 14:167253f4e170 5063 sp_3072_mul_d_68(t2, d, r1);
wolfSSL 14:167253f4e170 5064 sp_3072_add_68(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 5065 t1[68 + i] += t1[68 + i - 1] >> 23;
wolfSSL 14:167253f4e170 5066 t1[68 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 5067 }
wolfSSL 14:167253f4e170 5068 t1[68 - 1] += t1[68 - 2] >> 23;
wolfSSL 14:167253f4e170 5069 t1[68 - 2] &= 0x7fffff;
wolfSSL 14:167253f4e170 5070 d1 = t1[68 - 1];
wolfSSL 14:167253f4e170 5071 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 5072
wolfSSL 14:167253f4e170 5073 sp_3072_mul_d_68(t2, d, r1);
wolfSSL 14:167253f4e170 5074 sp_3072_sub_68(t1, t1, t2);
wolfSSL 14:167253f4e170 5075 XMEMCPY(r, t1, sizeof(*r) * 2 * 68);
wolfSSL 14:167253f4e170 5076 for (i=0; i<66; i++) {
wolfSSL 14:167253f4e170 5077 r[i+1] += r[i] >> 23;
wolfSSL 14:167253f4e170 5078 r[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 5079 }
wolfSSL 14:167253f4e170 5080 sp_3072_cond_add_68(r, r, d, 0 - (r[67] < 0));
wolfSSL 14:167253f4e170 5081 }
wolfSSL 14:167253f4e170 5082
wolfSSL 14:167253f4e170 5083 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 5084 if (td != NULL)
wolfSSL 14:167253f4e170 5085 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5086 #endif
wolfSSL 14:167253f4e170 5087
wolfSSL 14:167253f4e170 5088 return err;
wolfSSL 14:167253f4e170 5089 }
wolfSSL 14:167253f4e170 5090
wolfSSL 14:167253f4e170 5091 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 5092 *
wolfSSL 14:167253f4e170 5093 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 5094 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 5095 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 5096 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 5097 */
wolfSSL 14:167253f4e170 5098 static int sp_3072_mod_68(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 5099 {
wolfSSL 14:167253f4e170 5100 return sp_3072_div_68(a, m, NULL, r);
wolfSSL 14:167253f4e170 5101 }
wolfSSL 14:167253f4e170 5102
wolfSSL 14:167253f4e170 5103 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 14:167253f4e170 5104 *
wolfSSL 14:167253f4e170 5105 * r A single precision number that is the result of the operation.
wolfSSL 14:167253f4e170 5106 * a A single precision number being exponentiated.
wolfSSL 14:167253f4e170 5107 * e A single precision number that is the exponent.
wolfSSL 14:167253f4e170 5108 * bits The number of bits in the exponent.
wolfSSL 14:167253f4e170 5109 * m A single precision number that is the modulus.
wolfSSL 14:167253f4e170 5110 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 14:167253f4e170 5111 */
wolfSSL 14:167253f4e170 5112 static int sp_3072_mod_exp_68(sp_digit* r, sp_digit* a, sp_digit* e, int bits,
wolfSSL 14:167253f4e170 5113 sp_digit* m, int reduceA)
wolfSSL 14:167253f4e170 5114 {
wolfSSL 14:167253f4e170 5115 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5116 sp_digit* td;
wolfSSL 14:167253f4e170 5117 sp_digit* t[3];
wolfSSL 14:167253f4e170 5118 sp_digit* norm;
wolfSSL 14:167253f4e170 5119 sp_digit mp = 1;
wolfSSL 14:167253f4e170 5120 sp_digit n;
wolfSSL 14:167253f4e170 5121 int i;
wolfSSL 14:167253f4e170 5122 int c, y;
wolfSSL 14:167253f4e170 5123 int err = MP_OKAY;
wolfSSL 14:167253f4e170 5124
wolfSSL 14:167253f4e170 5125 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 68 * 2, NULL,
wolfSSL 14:167253f4e170 5126 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5127 if (td == NULL)
wolfSSL 14:167253f4e170 5128 err = MEMORY_E;
wolfSSL 14:167253f4e170 5129
wolfSSL 14:167253f4e170 5130 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5131 XMEMSET(td, 0, sizeof(*td) * 3 * 68 * 2);
wolfSSL 14:167253f4e170 5132
wolfSSL 14:167253f4e170 5133 norm = t[0] = td;
wolfSSL 14:167253f4e170 5134 t[1] = &td[68 * 2];
wolfSSL 14:167253f4e170 5135 t[2] = &td[2 * 68 * 2];
wolfSSL 14:167253f4e170 5136
wolfSSL 14:167253f4e170 5137 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 5138 sp_3072_mont_norm_68(norm, m);
wolfSSL 14:167253f4e170 5139
wolfSSL 14:167253f4e170 5140 if (reduceA)
wolfSSL 14:167253f4e170 5141 err = sp_3072_mod_68(t[1], a, m);
wolfSSL 14:167253f4e170 5142 else
wolfSSL 14:167253f4e170 5143 XMEMCPY(t[1], a, sizeof(sp_digit) * 68);
wolfSSL 14:167253f4e170 5144 }
wolfSSL 14:167253f4e170 5145 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5146 sp_3072_mul_68(t[1], t[1], norm);
wolfSSL 14:167253f4e170 5147 err = sp_3072_mod_68(t[1], t[1], m);
wolfSSL 14:167253f4e170 5148 }
wolfSSL 14:167253f4e170 5149
wolfSSL 14:167253f4e170 5150 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5151 i = bits / 23;
wolfSSL 14:167253f4e170 5152 c = bits % 23;
wolfSSL 14:167253f4e170 5153 n = e[i--] << (23 - c);
wolfSSL 14:167253f4e170 5154 for (; ; c--) {
wolfSSL 14:167253f4e170 5155 if (c == 0) {
wolfSSL 14:167253f4e170 5156 if (i == -1)
wolfSSL 14:167253f4e170 5157 break;
wolfSSL 14:167253f4e170 5158
wolfSSL 14:167253f4e170 5159 n = e[i--];
wolfSSL 14:167253f4e170 5160 c = 23;
wolfSSL 14:167253f4e170 5161 }
wolfSSL 14:167253f4e170 5162
wolfSSL 14:167253f4e170 5163 y = (n >> 22) & 1;
wolfSSL 14:167253f4e170 5164 n <<= 1;
wolfSSL 14:167253f4e170 5165
wolfSSL 14:167253f4e170 5166 sp_3072_mont_mul_68(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 5167
wolfSSL 14:167253f4e170 5168 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 5169 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 5170 sizeof(*t[2]) * 68 * 2);
wolfSSL 14:167253f4e170 5171 sp_3072_mont_sqr_68(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 5172 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 5173 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 5174 sizeof(*t[2]) * 68 * 2);
wolfSSL 14:167253f4e170 5175 }
wolfSSL 14:167253f4e170 5176
wolfSSL 14:167253f4e170 5177 sp_3072_mont_reduce_68(t[0], m, mp);
wolfSSL 14:167253f4e170 5178 n = sp_3072_cmp_68(t[0], m);
wolfSSL 14:167253f4e170 5179 sp_3072_cond_sub_68(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 5180 XMEMCPY(r, t[0], sizeof(*r) * 68 * 2);
wolfSSL 14:167253f4e170 5181
wolfSSL 14:167253f4e170 5182 }
wolfSSL 14:167253f4e170 5183
wolfSSL 14:167253f4e170 5184 if (td != NULL)
wolfSSL 14:167253f4e170 5185 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5186
wolfSSL 14:167253f4e170 5187 return err;
wolfSSL 14:167253f4e170 5188 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 5189 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5190 sp_digit t[3][136];
wolfSSL 14:167253f4e170 5191 #else
wolfSSL 14:167253f4e170 5192 sp_digit* td;
wolfSSL 14:167253f4e170 5193 sp_digit* t[3];
wolfSSL 14:167253f4e170 5194 #endif
wolfSSL 14:167253f4e170 5195 sp_digit* norm;
wolfSSL 14:167253f4e170 5196 sp_digit mp = 1;
wolfSSL 14:167253f4e170 5197 sp_digit n;
wolfSSL 14:167253f4e170 5198 int i;
wolfSSL 14:167253f4e170 5199 int c, y;
wolfSSL 14:167253f4e170 5200 int err = MP_OKAY;
wolfSSL 14:167253f4e170 5201
wolfSSL 14:167253f4e170 5202 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5203 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 68 * 2, NULL,
wolfSSL 14:167253f4e170 5204 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5205 if (td == NULL)
wolfSSL 14:167253f4e170 5206 err = MEMORY_E;
wolfSSL 14:167253f4e170 5207
wolfSSL 14:167253f4e170 5208 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5209 t[0] = td;
wolfSSL 14:167253f4e170 5210 t[1] = &td[68 * 2];
wolfSSL 14:167253f4e170 5211 t[2] = &td[2 * 68 * 2];
wolfSSL 14:167253f4e170 5212 norm = t[0];
wolfSSL 14:167253f4e170 5213 }
wolfSSL 14:167253f4e170 5214 #else
wolfSSL 14:167253f4e170 5215 norm = t[0];
wolfSSL 14:167253f4e170 5216 #endif
wolfSSL 14:167253f4e170 5217
wolfSSL 14:167253f4e170 5218 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5219 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 5220 sp_3072_mont_norm_68(norm, m);
wolfSSL 14:167253f4e170 5221
wolfSSL 14:167253f4e170 5222 if (reduceA) {
wolfSSL 14:167253f4e170 5223 err = sp_3072_mod_68(t[1], a, m);
wolfSSL 14:167253f4e170 5224 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5225 sp_3072_mul_68(t[1], t[1], norm);
wolfSSL 14:167253f4e170 5226 err = sp_3072_mod_68(t[1], t[1], m);
wolfSSL 14:167253f4e170 5227 }
wolfSSL 14:167253f4e170 5228 }
wolfSSL 14:167253f4e170 5229 else {
wolfSSL 14:167253f4e170 5230 sp_3072_mul_68(t[1], a, norm);
wolfSSL 14:167253f4e170 5231 err = sp_3072_mod_68(t[1], t[1], m);
wolfSSL 14:167253f4e170 5232 }
wolfSSL 14:167253f4e170 5233 }
wolfSSL 14:167253f4e170 5234
wolfSSL 14:167253f4e170 5235 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5236 i = bits / 23;
wolfSSL 14:167253f4e170 5237 c = bits % 23;
wolfSSL 14:167253f4e170 5238 n = e[i--] << (23 - c);
wolfSSL 14:167253f4e170 5239 for (; ; c--) {
wolfSSL 14:167253f4e170 5240 if (c == 0) {
wolfSSL 14:167253f4e170 5241 if (i == -1)
wolfSSL 14:167253f4e170 5242 break;
wolfSSL 14:167253f4e170 5243
wolfSSL 14:167253f4e170 5244 n = e[i--];
wolfSSL 14:167253f4e170 5245 c = 23;
wolfSSL 14:167253f4e170 5246 }
wolfSSL 14:167253f4e170 5247
wolfSSL 14:167253f4e170 5248 y = (n >> 22) & 1;
wolfSSL 14:167253f4e170 5249 n <<= 1;
wolfSSL 14:167253f4e170 5250
wolfSSL 14:167253f4e170 5251 sp_3072_mont_mul_68(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 5252
wolfSSL 14:167253f4e170 5253 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 5254 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 5255 sp_3072_mont_sqr_68(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 5256 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 5257 ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 5258 }
wolfSSL 14:167253f4e170 5259
wolfSSL 14:167253f4e170 5260 sp_3072_mont_reduce_68(t[0], m, mp);
wolfSSL 14:167253f4e170 5261 n = sp_3072_cmp_68(t[0], m);
wolfSSL 14:167253f4e170 5262 sp_3072_cond_sub_68(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 5263 XMEMCPY(r, t[0], sizeof(t[0]));
wolfSSL 14:167253f4e170 5264 }
wolfSSL 14:167253f4e170 5265
wolfSSL 14:167253f4e170 5266 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5267 if (td != NULL)
wolfSSL 14:167253f4e170 5268 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5269 #endif
wolfSSL 14:167253f4e170 5270
wolfSSL 14:167253f4e170 5271 return err;
wolfSSL 14:167253f4e170 5272 #else
wolfSSL 14:167253f4e170 5273 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5274 sp_digit t[32][136];
wolfSSL 14:167253f4e170 5275 #else
wolfSSL 14:167253f4e170 5276 sp_digit* t[32];
wolfSSL 14:167253f4e170 5277 sp_digit* td;
wolfSSL 14:167253f4e170 5278 #endif
wolfSSL 14:167253f4e170 5279 sp_digit* norm;
wolfSSL 14:167253f4e170 5280 sp_digit rt[136];
wolfSSL 14:167253f4e170 5281 sp_digit mp = 1;
wolfSSL 14:167253f4e170 5282 sp_digit n;
wolfSSL 14:167253f4e170 5283 int i;
wolfSSL 14:167253f4e170 5284 int c, y;
wolfSSL 14:167253f4e170 5285 int err = MP_OKAY;
wolfSSL 14:167253f4e170 5286
wolfSSL 14:167253f4e170 5287 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5288 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 136, NULL,
wolfSSL 14:167253f4e170 5289 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5290 if (td == NULL)
wolfSSL 14:167253f4e170 5291 err = MEMORY_E;
wolfSSL 14:167253f4e170 5292
wolfSSL 14:167253f4e170 5293 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5294 for (i=0; i<32; i++)
wolfSSL 14:167253f4e170 5295 t[i] = td + i * 136;
wolfSSL 14:167253f4e170 5296 norm = t[0];
wolfSSL 14:167253f4e170 5297 }
wolfSSL 14:167253f4e170 5298 #else
wolfSSL 14:167253f4e170 5299 norm = t[0];
wolfSSL 14:167253f4e170 5300 #endif
wolfSSL 14:167253f4e170 5301
wolfSSL 14:167253f4e170 5302 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5303 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 5304 sp_3072_mont_norm_68(norm, m);
wolfSSL 14:167253f4e170 5305
wolfSSL 14:167253f4e170 5306 if (reduceA) {
wolfSSL 14:167253f4e170 5307 err = sp_3072_mod_68(t[1], a, m);
wolfSSL 14:167253f4e170 5308 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5309 sp_3072_mul_68(t[1], t[1], norm);
wolfSSL 14:167253f4e170 5310 err = sp_3072_mod_68(t[1], t[1], m);
wolfSSL 14:167253f4e170 5311 }
wolfSSL 14:167253f4e170 5312 }
wolfSSL 14:167253f4e170 5313 else {
wolfSSL 14:167253f4e170 5314 sp_3072_mul_68(t[1], a, norm);
wolfSSL 14:167253f4e170 5315 err = sp_3072_mod_68(t[1], t[1], m);
wolfSSL 14:167253f4e170 5316 }
wolfSSL 14:167253f4e170 5317 }
wolfSSL 14:167253f4e170 5318
wolfSSL 14:167253f4e170 5319 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5320 sp_3072_mont_sqr_68(t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 5321 sp_3072_mont_mul_68(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 5322 sp_3072_mont_sqr_68(t[ 4], t[ 2], m, mp);
wolfSSL 14:167253f4e170 5323 sp_3072_mont_mul_68(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 14:167253f4e170 5324 sp_3072_mont_sqr_68(t[ 6], t[ 3], m, mp);
wolfSSL 14:167253f4e170 5325 sp_3072_mont_mul_68(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 14:167253f4e170 5326 sp_3072_mont_sqr_68(t[ 8], t[ 4], m, mp);
wolfSSL 14:167253f4e170 5327 sp_3072_mont_mul_68(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 14:167253f4e170 5328 sp_3072_mont_sqr_68(t[10], t[ 5], m, mp);
wolfSSL 14:167253f4e170 5329 sp_3072_mont_mul_68(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 14:167253f4e170 5330 sp_3072_mont_sqr_68(t[12], t[ 6], m, mp);
wolfSSL 14:167253f4e170 5331 sp_3072_mont_mul_68(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 14:167253f4e170 5332 sp_3072_mont_sqr_68(t[14], t[ 7], m, mp);
wolfSSL 14:167253f4e170 5333 sp_3072_mont_mul_68(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 14:167253f4e170 5334 sp_3072_mont_sqr_68(t[16], t[ 8], m, mp);
wolfSSL 14:167253f4e170 5335 sp_3072_mont_mul_68(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 14:167253f4e170 5336 sp_3072_mont_sqr_68(t[18], t[ 9], m, mp);
wolfSSL 14:167253f4e170 5337 sp_3072_mont_mul_68(t[19], t[10], t[ 9], m, mp);
wolfSSL 14:167253f4e170 5338 sp_3072_mont_sqr_68(t[20], t[10], m, mp);
wolfSSL 14:167253f4e170 5339 sp_3072_mont_mul_68(t[21], t[11], t[10], m, mp);
wolfSSL 14:167253f4e170 5340 sp_3072_mont_sqr_68(t[22], t[11], m, mp);
wolfSSL 14:167253f4e170 5341 sp_3072_mont_mul_68(t[23], t[12], t[11], m, mp);
wolfSSL 14:167253f4e170 5342 sp_3072_mont_sqr_68(t[24], t[12], m, mp);
wolfSSL 14:167253f4e170 5343 sp_3072_mont_mul_68(t[25], t[13], t[12], m, mp);
wolfSSL 14:167253f4e170 5344 sp_3072_mont_sqr_68(t[26], t[13], m, mp);
wolfSSL 14:167253f4e170 5345 sp_3072_mont_mul_68(t[27], t[14], t[13], m, mp);
wolfSSL 14:167253f4e170 5346 sp_3072_mont_sqr_68(t[28], t[14], m, mp);
wolfSSL 14:167253f4e170 5347 sp_3072_mont_mul_68(t[29], t[15], t[14], m, mp);
wolfSSL 14:167253f4e170 5348 sp_3072_mont_sqr_68(t[30], t[15], m, mp);
wolfSSL 14:167253f4e170 5349 sp_3072_mont_mul_68(t[31], t[16], t[15], m, mp);
wolfSSL 14:167253f4e170 5350
wolfSSL 14:167253f4e170 5351 bits = ((bits + 4) / 5) * 5;
wolfSSL 14:167253f4e170 5352 i = ((bits + 22) / 23) - 1;
wolfSSL 14:167253f4e170 5353 c = bits % 23;
wolfSSL 14:167253f4e170 5354 if (c == 0)
wolfSSL 14:167253f4e170 5355 c = 23;
wolfSSL 14:167253f4e170 5356 if (i < 68)
wolfSSL 14:167253f4e170 5357 n = e[i--] << (32 - c);
wolfSSL 14:167253f4e170 5358 else {
wolfSSL 14:167253f4e170 5359 n = 0;
wolfSSL 14:167253f4e170 5360 i--;
wolfSSL 14:167253f4e170 5361 }
wolfSSL 14:167253f4e170 5362 if (c < 5) {
wolfSSL 14:167253f4e170 5363 n |= e[i--] << (9 - c);
wolfSSL 14:167253f4e170 5364 c += 23;
wolfSSL 14:167253f4e170 5365 }
wolfSSL 14:167253f4e170 5366 y = n >> 27;
wolfSSL 14:167253f4e170 5367 n <<= 5;
wolfSSL 14:167253f4e170 5368 c -= 5;
wolfSSL 14:167253f4e170 5369 XMEMCPY(rt, t[y], sizeof(rt));
wolfSSL 14:167253f4e170 5370 for (; i>=0 || c>=5; ) {
wolfSSL 14:167253f4e170 5371 if (c < 5) {
wolfSSL 14:167253f4e170 5372 n |= e[i--] << (9 - c);
wolfSSL 14:167253f4e170 5373 c += 23;
wolfSSL 14:167253f4e170 5374 }
wolfSSL 14:167253f4e170 5375 y = (n >> 27) & 0x1f;
wolfSSL 14:167253f4e170 5376 n <<= 5;
wolfSSL 14:167253f4e170 5377 c -= 5;
wolfSSL 14:167253f4e170 5378
wolfSSL 14:167253f4e170 5379 sp_3072_mont_sqr_68(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5380 sp_3072_mont_sqr_68(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5381 sp_3072_mont_sqr_68(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5382 sp_3072_mont_sqr_68(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5383 sp_3072_mont_sqr_68(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5384
wolfSSL 14:167253f4e170 5385 sp_3072_mont_mul_68(rt, rt, t[y], m, mp);
wolfSSL 14:167253f4e170 5386 }
wolfSSL 14:167253f4e170 5387
wolfSSL 14:167253f4e170 5388 sp_3072_mont_reduce_68(rt, m, mp);
wolfSSL 14:167253f4e170 5389 n = sp_3072_cmp_68(rt, m);
wolfSSL 14:167253f4e170 5390 sp_3072_cond_sub_68(rt, rt, m, (n < 0) - 1);
wolfSSL 14:167253f4e170 5391 XMEMCPY(r, rt, sizeof(rt));
wolfSSL 14:167253f4e170 5392 }
wolfSSL 14:167253f4e170 5393
wolfSSL 14:167253f4e170 5394 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5395 if (td != NULL)
wolfSSL 14:167253f4e170 5396 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5397 #endif
wolfSSL 14:167253f4e170 5398
wolfSSL 14:167253f4e170 5399 return err;
wolfSSL 14:167253f4e170 5400 #endif
wolfSSL 14:167253f4e170 5401 }
wolfSSL 14:167253f4e170 5402
wolfSSL 14:167253f4e170 5403 #endif /* !SP_RSA_PRIVATE_EXP_D && WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 5404
wolfSSL 14:167253f4e170 5405 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 14:167253f4e170 5406 * Given m must be 3072 bits, just need to subtract.
wolfSSL 14:167253f4e170 5407 *
wolfSSL 14:167253f4e170 5408 * r A single precision number.
wolfSSL 14:167253f4e170 5409 * m A signle precision number.
wolfSSL 14:167253f4e170 5410 */
wolfSSL 14:167253f4e170 5411 static void sp_3072_mont_norm_136(sp_digit* r, sp_digit* m)
wolfSSL 14:167253f4e170 5412 {
wolfSSL 14:167253f4e170 5413 /* Set r = 2^n - 1. */
wolfSSL 14:167253f4e170 5414 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5415 int i;
wolfSSL 14:167253f4e170 5416
wolfSSL 14:167253f4e170 5417 for (i=0; i<135; i++)
wolfSSL 14:167253f4e170 5418 r[i] = 0x7fffff;
wolfSSL 14:167253f4e170 5419 #else
wolfSSL 14:167253f4e170 5420 int i;
wolfSSL 14:167253f4e170 5421
wolfSSL 14:167253f4e170 5422 for (i = 0; i < 136; i += 8) {
wolfSSL 14:167253f4e170 5423 r[i + 0] = 0x7fffff;
wolfSSL 14:167253f4e170 5424 r[i + 1] = 0x7fffff;
wolfSSL 14:167253f4e170 5425 r[i + 2] = 0x7fffff;
wolfSSL 14:167253f4e170 5426 r[i + 3] = 0x7fffff;
wolfSSL 14:167253f4e170 5427 r[i + 4] = 0x7fffff;
wolfSSL 14:167253f4e170 5428 r[i + 5] = 0x7fffff;
wolfSSL 14:167253f4e170 5429 r[i + 6] = 0x7fffff;
wolfSSL 14:167253f4e170 5430 r[i + 7] = 0x7fffff;
wolfSSL 14:167253f4e170 5431 }
wolfSSL 14:167253f4e170 5432 #endif
wolfSSL 14:167253f4e170 5433 r[135] = 0x1fffl;
wolfSSL 14:167253f4e170 5434
wolfSSL 14:167253f4e170 5435 /* r = (2^n - 1) mod n */
wolfSSL 14:167253f4e170 5436 sp_3072_sub_136(r, r, m);
wolfSSL 14:167253f4e170 5437
wolfSSL 14:167253f4e170 5438 /* Add one so r = 2^n mod m */
wolfSSL 14:167253f4e170 5439 r[0] += 1;
wolfSSL 14:167253f4e170 5440 }
wolfSSL 14:167253f4e170 5441
wolfSSL 14:167253f4e170 5442 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 5443 *
wolfSSL 14:167253f4e170 5444 * a A single precision integer.
wolfSSL 14:167253f4e170 5445 * b A single precision integer.
wolfSSL 14:167253f4e170 5446 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 5447 * respectively.
wolfSSL 14:167253f4e170 5448 */
wolfSSL 14:167253f4e170 5449 static sp_digit sp_3072_cmp_136(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 5450 {
wolfSSL 14:167253f4e170 5451 sp_digit r = 0;
wolfSSL 14:167253f4e170 5452 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5453 int i;
wolfSSL 14:167253f4e170 5454
wolfSSL 14:167253f4e170 5455 for (i=135; i>=0; i--)
wolfSSL 14:167253f4e170 5456 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 5457 #else
wolfSSL 14:167253f4e170 5458 int i;
wolfSSL 14:167253f4e170 5459
wolfSSL 14:167253f4e170 5460 for (i = 128; i >= 0; i -= 8) {
wolfSSL 14:167253f4e170 5461 r |= (a[i + 7] - b[i + 7]) & (0 - !r);
wolfSSL 14:167253f4e170 5462 r |= (a[i + 6] - b[i + 6]) & (0 - !r);
wolfSSL 14:167253f4e170 5463 r |= (a[i + 5] - b[i + 5]) & (0 - !r);
wolfSSL 14:167253f4e170 5464 r |= (a[i + 4] - b[i + 4]) & (0 - !r);
wolfSSL 14:167253f4e170 5465 r |= (a[i + 3] - b[i + 3]) & (0 - !r);
wolfSSL 14:167253f4e170 5466 r |= (a[i + 2] - b[i + 2]) & (0 - !r);
wolfSSL 14:167253f4e170 5467 r |= (a[i + 1] - b[i + 1]) & (0 - !r);
wolfSSL 14:167253f4e170 5468 r |= (a[i + 0] - b[i + 0]) & (0 - !r);
wolfSSL 14:167253f4e170 5469 }
wolfSSL 14:167253f4e170 5470 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5471
wolfSSL 14:167253f4e170 5472 return r;
wolfSSL 14:167253f4e170 5473 }
wolfSSL 14:167253f4e170 5474
wolfSSL 14:167253f4e170 5475 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 5476 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 5477 *
wolfSSL 14:167253f4e170 5478 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 5479 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 5480 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 5481 * m Mask value to apply.
wolfSSL 14:167253f4e170 5482 */
wolfSSL 14:167253f4e170 5483 static void sp_3072_cond_sub_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5484 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 5485 {
wolfSSL 14:167253f4e170 5486 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5487 int i;
wolfSSL 14:167253f4e170 5488
wolfSSL 14:167253f4e170 5489 for (i = 0; i < 136; i++)
wolfSSL 14:167253f4e170 5490 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 5491 #else
wolfSSL 14:167253f4e170 5492 int i;
wolfSSL 14:167253f4e170 5493
wolfSSL 14:167253f4e170 5494 for (i = 0; i < 136; i += 8) {
wolfSSL 14:167253f4e170 5495 r[i + 0] = a[i + 0] - (b[i + 0] & m);
wolfSSL 14:167253f4e170 5496 r[i + 1] = a[i + 1] - (b[i + 1] & m);
wolfSSL 14:167253f4e170 5497 r[i + 2] = a[i + 2] - (b[i + 2] & m);
wolfSSL 14:167253f4e170 5498 r[i + 3] = a[i + 3] - (b[i + 3] & m);
wolfSSL 14:167253f4e170 5499 r[i + 4] = a[i + 4] - (b[i + 4] & m);
wolfSSL 14:167253f4e170 5500 r[i + 5] = a[i + 5] - (b[i + 5] & m);
wolfSSL 14:167253f4e170 5501 r[i + 6] = a[i + 6] - (b[i + 6] & m);
wolfSSL 14:167253f4e170 5502 r[i + 7] = a[i + 7] - (b[i + 7] & m);
wolfSSL 14:167253f4e170 5503 }
wolfSSL 14:167253f4e170 5504 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5505 }
wolfSSL 14:167253f4e170 5506
wolfSSL 14:167253f4e170 5507 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 5508 *
wolfSSL 14:167253f4e170 5509 * r A single precision integer.
wolfSSL 14:167253f4e170 5510 * a A single precision integer.
wolfSSL 14:167253f4e170 5511 * b A scalar.
wolfSSL 14:167253f4e170 5512 */
wolfSSL 14:167253f4e170 5513 SP_NOINLINE static void sp_3072_mul_add_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5514 const sp_digit b)
wolfSSL 14:167253f4e170 5515 {
wolfSSL 14:167253f4e170 5516 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5517 int64_t tb = b;
wolfSSL 14:167253f4e170 5518 int64_t t = 0;
wolfSSL 14:167253f4e170 5519 int i;
wolfSSL 14:167253f4e170 5520
wolfSSL 14:167253f4e170 5521 for (i = 0; i < 136; i++) {
wolfSSL 14:167253f4e170 5522 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 5523 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 5524 t >>= 23;
wolfSSL 14:167253f4e170 5525 }
wolfSSL 14:167253f4e170 5526 r[136] += t;
wolfSSL 14:167253f4e170 5527 #else
wolfSSL 14:167253f4e170 5528 int64_t tb = b;
wolfSSL 14:167253f4e170 5529 int64_t t[8];
wolfSSL 14:167253f4e170 5530 int i;
wolfSSL 14:167253f4e170 5531
wolfSSL 14:167253f4e170 5532 t[0] = tb * a[0]; r[0] += t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 5533 for (i = 0; i < 136; i += 8) {
wolfSSL 14:167253f4e170 5534 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 5535 r[i+1] += (t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 5536 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 5537 r[i+2] += (t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 5538 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 5539 r[i+3] += (t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 5540 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 5541 r[i+4] += (t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 5542 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 5543 r[i+5] += (t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 5544 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 5545 r[i+6] += (t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 5546 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 5547 r[i+7] += (t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 5548 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 5549 r[i+8] += (t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 5550 }
wolfSSL 14:167253f4e170 5551 r[136] += t[7] >> 23;
wolfSSL 14:167253f4e170 5552 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5553 }
wolfSSL 14:167253f4e170 5554
wolfSSL 14:167253f4e170 5555 /* Normalize the values in each word to 23.
wolfSSL 14:167253f4e170 5556 *
wolfSSL 14:167253f4e170 5557 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 5558 */
wolfSSL 14:167253f4e170 5559 static void sp_3072_norm_136(sp_digit* a)
wolfSSL 14:167253f4e170 5560 {
wolfSSL 14:167253f4e170 5561 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5562 int i;
wolfSSL 14:167253f4e170 5563 for (i = 0; i < 135; i++) {
wolfSSL 14:167253f4e170 5564 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 5565 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 5566 }
wolfSSL 14:167253f4e170 5567 #else
wolfSSL 14:167253f4e170 5568 int i;
wolfSSL 14:167253f4e170 5569 for (i = 0; i < 128; i += 8) {
wolfSSL 14:167253f4e170 5570 a[i+1] += a[i+0] >> 23; a[i+0] &= 0x7fffff;
wolfSSL 14:167253f4e170 5571 a[i+2] += a[i+1] >> 23; a[i+1] &= 0x7fffff;
wolfSSL 14:167253f4e170 5572 a[i+3] += a[i+2] >> 23; a[i+2] &= 0x7fffff;
wolfSSL 14:167253f4e170 5573 a[i+4] += a[i+3] >> 23; a[i+3] &= 0x7fffff;
wolfSSL 14:167253f4e170 5574 a[i+5] += a[i+4] >> 23; a[i+4] &= 0x7fffff;
wolfSSL 14:167253f4e170 5575 a[i+6] += a[i+5] >> 23; a[i+5] &= 0x7fffff;
wolfSSL 14:167253f4e170 5576 a[i+7] += a[i+6] >> 23; a[i+6] &= 0x7fffff;
wolfSSL 14:167253f4e170 5577 a[i+8] += a[i+7] >> 23; a[i+7] &= 0x7fffff;
wolfSSL 14:167253f4e170 5578 a[i+9] += a[i+8] >> 23; a[i+8] &= 0x7fffff;
wolfSSL 14:167253f4e170 5579 }
wolfSSL 14:167253f4e170 5580 a[128+1] += a[128] >> 23;
wolfSSL 14:167253f4e170 5581 a[128] &= 0x7fffff;
wolfSSL 14:167253f4e170 5582 a[129+1] += a[129] >> 23;
wolfSSL 14:167253f4e170 5583 a[129] &= 0x7fffff;
wolfSSL 14:167253f4e170 5584 a[130+1] += a[130] >> 23;
wolfSSL 14:167253f4e170 5585 a[130] &= 0x7fffff;
wolfSSL 14:167253f4e170 5586 a[131+1] += a[131] >> 23;
wolfSSL 14:167253f4e170 5587 a[131] &= 0x7fffff;
wolfSSL 14:167253f4e170 5588 a[132+1] += a[132] >> 23;
wolfSSL 14:167253f4e170 5589 a[132] &= 0x7fffff;
wolfSSL 14:167253f4e170 5590 a[133+1] += a[133] >> 23;
wolfSSL 14:167253f4e170 5591 a[133] &= 0x7fffff;
wolfSSL 14:167253f4e170 5592 a[134+1] += a[134] >> 23;
wolfSSL 14:167253f4e170 5593 a[134] &= 0x7fffff;
wolfSSL 14:167253f4e170 5594 #endif
wolfSSL 14:167253f4e170 5595 }
wolfSSL 14:167253f4e170 5596
wolfSSL 14:167253f4e170 5597 /* Shift the result in the high 3072 bits down to the bottom.
wolfSSL 14:167253f4e170 5598 *
wolfSSL 14:167253f4e170 5599 * r A single precision number.
wolfSSL 14:167253f4e170 5600 * a A single precision number.
wolfSSL 14:167253f4e170 5601 */
wolfSSL 14:167253f4e170 5602 static void sp_3072_mont_shift_136(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 5603 {
wolfSSL 14:167253f4e170 5604 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5605 int i;
wolfSSL 14:167253f4e170 5606 int64_t n = a[135] >> 13;
wolfSSL 14:167253f4e170 5607 n += ((int64_t)a[136]) << 10;
wolfSSL 14:167253f4e170 5608
wolfSSL 14:167253f4e170 5609 for (i = 0; i < 135; i++) {
wolfSSL 14:167253f4e170 5610 r[i] = n & 0x7fffff;
wolfSSL 14:167253f4e170 5611 n >>= 23;
wolfSSL 14:167253f4e170 5612 n += ((int64_t)a[137 + i]) << 10;
wolfSSL 14:167253f4e170 5613 }
wolfSSL 14:167253f4e170 5614 r[135] = (sp_digit)n;
wolfSSL 14:167253f4e170 5615 #else
wolfSSL 14:167253f4e170 5616 int i;
wolfSSL 14:167253f4e170 5617 int64_t n = a[135] >> 13;
wolfSSL 14:167253f4e170 5618 n += ((int64_t)a[136]) << 10;
wolfSSL 14:167253f4e170 5619 for (i = 0; i < 136; i += 8) {
wolfSSL 14:167253f4e170 5620 r[i + 0] = n & 0x7fffff;
wolfSSL 14:167253f4e170 5621 n >>= 23; n += ((int64_t)a[i + 137]) << 10;
wolfSSL 14:167253f4e170 5622 r[i + 1] = n & 0x7fffff;
wolfSSL 14:167253f4e170 5623 n >>= 23; n += ((int64_t)a[i + 138]) << 10;
wolfSSL 14:167253f4e170 5624 r[i + 2] = n & 0x7fffff;
wolfSSL 14:167253f4e170 5625 n >>= 23; n += ((int64_t)a[i + 139]) << 10;
wolfSSL 14:167253f4e170 5626 r[i + 3] = n & 0x7fffff;
wolfSSL 14:167253f4e170 5627 n >>= 23; n += ((int64_t)a[i + 140]) << 10;
wolfSSL 14:167253f4e170 5628 r[i + 4] = n & 0x7fffff;
wolfSSL 14:167253f4e170 5629 n >>= 23; n += ((int64_t)a[i + 141]) << 10;
wolfSSL 14:167253f4e170 5630 r[i + 5] = n & 0x7fffff;
wolfSSL 14:167253f4e170 5631 n >>= 23; n += ((int64_t)a[i + 142]) << 10;
wolfSSL 14:167253f4e170 5632 r[i + 6] = n & 0x7fffff;
wolfSSL 14:167253f4e170 5633 n >>= 23; n += ((int64_t)a[i + 143]) << 10;
wolfSSL 14:167253f4e170 5634 r[i + 7] = n & 0x7fffff;
wolfSSL 14:167253f4e170 5635 n >>= 23; n += ((int64_t)a[i + 144]) << 10;
wolfSSL 14:167253f4e170 5636 }
wolfSSL 14:167253f4e170 5637 r[135] = (sp_digit)n;
wolfSSL 14:167253f4e170 5638 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5639 XMEMSET(&r[136], 0, sizeof(*r) * 136);
wolfSSL 14:167253f4e170 5640 }
wolfSSL 14:167253f4e170 5641
wolfSSL 14:167253f4e170 5642 /* Reduce the number back to 3072 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 5643 *
wolfSSL 14:167253f4e170 5644 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 5645 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 5646 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 5647 */
wolfSSL 14:167253f4e170 5648 static void sp_3072_mont_reduce_136(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 5649 {
wolfSSL 14:167253f4e170 5650 int i;
wolfSSL 14:167253f4e170 5651 sp_digit mu;
wolfSSL 14:167253f4e170 5652
wolfSSL 14:167253f4e170 5653 if (mp != 1) {
wolfSSL 14:167253f4e170 5654 for (i=0; i<135; i++) {
wolfSSL 14:167253f4e170 5655 mu = (a[i] * mp) & 0x7fffff;
wolfSSL 14:167253f4e170 5656 sp_3072_mul_add_136(a+i, m, mu);
wolfSSL 14:167253f4e170 5657 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 5658 }
wolfSSL 14:167253f4e170 5659 mu = (a[i] * mp) & 0x1fffl;
wolfSSL 14:167253f4e170 5660 sp_3072_mul_add_136(a+i, m, mu);
wolfSSL 14:167253f4e170 5661 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 5662 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 5663 }
wolfSSL 14:167253f4e170 5664 else {
wolfSSL 14:167253f4e170 5665 for (i=0; i<135; i++) {
wolfSSL 14:167253f4e170 5666 mu = a[i] & 0x7fffff;
wolfSSL 14:167253f4e170 5667 sp_3072_mul_add_136(a+i, m, mu);
wolfSSL 14:167253f4e170 5668 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 5669 }
wolfSSL 14:167253f4e170 5670 mu = a[i] & 0x1fffl;
wolfSSL 14:167253f4e170 5671 sp_3072_mul_add_136(a+i, m, mu);
wolfSSL 14:167253f4e170 5672 a[i+1] += a[i] >> 23;
wolfSSL 14:167253f4e170 5673 a[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 5674 }
wolfSSL 14:167253f4e170 5675
wolfSSL 14:167253f4e170 5676 sp_3072_mont_shift_136(a, a);
wolfSSL 14:167253f4e170 5677 sp_3072_cond_sub_136(a, a, m, 0 - ((a[135] >> 13) > 0));
wolfSSL 14:167253f4e170 5678 sp_3072_norm_136(a);
wolfSSL 14:167253f4e170 5679 }
wolfSSL 14:167253f4e170 5680
wolfSSL 14:167253f4e170 5681 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 5682 * (r = a * b mod m)
wolfSSL 14:167253f4e170 5683 *
wolfSSL 14:167253f4e170 5684 * r Result of multiplication.
wolfSSL 14:167253f4e170 5685 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 5686 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 5687 * m Modulus (prime).
wolfSSL 14:167253f4e170 5688 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 5689 */
wolfSSL 14:167253f4e170 5690 static void sp_3072_mont_mul_136(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 5691 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 5692 {
wolfSSL 14:167253f4e170 5693 sp_3072_mul_136(r, a, b);
wolfSSL 14:167253f4e170 5694 sp_3072_mont_reduce_136(r, m, mp);
wolfSSL 14:167253f4e170 5695 }
wolfSSL 14:167253f4e170 5696
wolfSSL 14:167253f4e170 5697 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 5698 *
wolfSSL 14:167253f4e170 5699 * r Result of squaring.
wolfSSL 14:167253f4e170 5700 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 5701 * m Modulus (prime).
wolfSSL 14:167253f4e170 5702 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 5703 */
wolfSSL 14:167253f4e170 5704 static void sp_3072_mont_sqr_136(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 5705 sp_digit mp)
wolfSSL 14:167253f4e170 5706 {
wolfSSL 14:167253f4e170 5707 sp_3072_sqr_136(r, a);
wolfSSL 14:167253f4e170 5708 sp_3072_mont_reduce_136(r, m, mp);
wolfSSL 14:167253f4e170 5709 }
wolfSSL 14:167253f4e170 5710
wolfSSL 14:167253f4e170 5711 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 5712 *
wolfSSL 14:167253f4e170 5713 * r A single precision integer.
wolfSSL 14:167253f4e170 5714 * a A single precision integer.
wolfSSL 14:167253f4e170 5715 * b A scalar.
wolfSSL 14:167253f4e170 5716 */
wolfSSL 14:167253f4e170 5717 SP_NOINLINE static void sp_3072_mul_d_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5718 const sp_digit b)
wolfSSL 14:167253f4e170 5719 {
wolfSSL 14:167253f4e170 5720 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5721 int64_t tb = b;
wolfSSL 14:167253f4e170 5722 int64_t t = 0;
wolfSSL 14:167253f4e170 5723 int i;
wolfSSL 14:167253f4e170 5724
wolfSSL 14:167253f4e170 5725 for (i = 0; i < 136; i++) {
wolfSSL 14:167253f4e170 5726 t += tb * a[i];
wolfSSL 14:167253f4e170 5727 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 5728 t >>= 23;
wolfSSL 14:167253f4e170 5729 }
wolfSSL 14:167253f4e170 5730 r[136] = (sp_digit)t;
wolfSSL 14:167253f4e170 5731 #else
wolfSSL 14:167253f4e170 5732 int64_t tb = b;
wolfSSL 14:167253f4e170 5733 int64_t t[8];
wolfSSL 14:167253f4e170 5734 int i;
wolfSSL 14:167253f4e170 5735
wolfSSL 14:167253f4e170 5736 t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 5737 for (i = 0; i < 136; i += 8) {
wolfSSL 14:167253f4e170 5738 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 5739 r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 5740 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 5741 r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 5742 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 5743 r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 5744 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 5745 r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 5746 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 5747 r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 5748 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 5749 r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 5750 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 5751 r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 5752 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 5753 r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 5754 }
wolfSSL 14:167253f4e170 5755 r[136] = (sp_digit)(t[7] >> 23);
wolfSSL 14:167253f4e170 5756 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5757 }
wolfSSL 14:167253f4e170 5758
wolfSSL 14:167253f4e170 5759 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 5760 *
wolfSSL 14:167253f4e170 5761 * r A single precision integer.
wolfSSL 14:167253f4e170 5762 * a A single precision integer.
wolfSSL 14:167253f4e170 5763 * b A scalar.
wolfSSL 14:167253f4e170 5764 */
wolfSSL 14:167253f4e170 5765 SP_NOINLINE static void sp_3072_mul_d_272(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5766 const sp_digit b)
wolfSSL 14:167253f4e170 5767 {
wolfSSL 14:167253f4e170 5768 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5769 int64_t tb = b;
wolfSSL 14:167253f4e170 5770 int64_t t = 0;
wolfSSL 14:167253f4e170 5771 int i;
wolfSSL 14:167253f4e170 5772
wolfSSL 14:167253f4e170 5773 for (i = 0; i < 272; i++) {
wolfSSL 14:167253f4e170 5774 t += tb * a[i];
wolfSSL 14:167253f4e170 5775 r[i] = t & 0x7fffff;
wolfSSL 14:167253f4e170 5776 t >>= 23;
wolfSSL 14:167253f4e170 5777 }
wolfSSL 14:167253f4e170 5778 r[272] = (sp_digit)t;
wolfSSL 14:167253f4e170 5779 #else
wolfSSL 14:167253f4e170 5780 int64_t tb = b;
wolfSSL 14:167253f4e170 5781 int64_t t[8];
wolfSSL 14:167253f4e170 5782 int i;
wolfSSL 14:167253f4e170 5783
wolfSSL 14:167253f4e170 5784 t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;
wolfSSL 14:167253f4e170 5785 for (i = 0; i < 272; i += 8) {
wolfSSL 14:167253f4e170 5786 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 5787 r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);
wolfSSL 14:167253f4e170 5788 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 5789 r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);
wolfSSL 14:167253f4e170 5790 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 5791 r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);
wolfSSL 14:167253f4e170 5792 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 5793 r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);
wolfSSL 14:167253f4e170 5794 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 5795 r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);
wolfSSL 14:167253f4e170 5796 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 5797 r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);
wolfSSL 14:167253f4e170 5798 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 5799 r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);
wolfSSL 14:167253f4e170 5800 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 5801 r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);
wolfSSL 14:167253f4e170 5802 }
wolfSSL 14:167253f4e170 5803 r[272] = (sp_digit)(t[7] >> 23);
wolfSSL 14:167253f4e170 5804 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5805 }
wolfSSL 14:167253f4e170 5806
wolfSSL 14:167253f4e170 5807 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 5808 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 5809 *
wolfSSL 14:167253f4e170 5810 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 5811 * a A single precision number to add with.
wolfSSL 14:167253f4e170 5812 * b A single precision number to add.
wolfSSL 14:167253f4e170 5813 * m Mask value to apply.
wolfSSL 14:167253f4e170 5814 */
wolfSSL 14:167253f4e170 5815 static void sp_3072_cond_add_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5816 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 5817 {
wolfSSL 14:167253f4e170 5818 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5819 int i;
wolfSSL 14:167253f4e170 5820
wolfSSL 14:167253f4e170 5821 for (i = 0; i < 136; i++)
wolfSSL 14:167253f4e170 5822 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 5823 #else
wolfSSL 14:167253f4e170 5824 int i;
wolfSSL 14:167253f4e170 5825
wolfSSL 14:167253f4e170 5826 for (i = 0; i < 136; i += 8) {
wolfSSL 14:167253f4e170 5827 r[i + 0] = a[i + 0] + (b[i + 0] & m);
wolfSSL 14:167253f4e170 5828 r[i + 1] = a[i + 1] + (b[i + 1] & m);
wolfSSL 14:167253f4e170 5829 r[i + 2] = a[i + 2] + (b[i + 2] & m);
wolfSSL 14:167253f4e170 5830 r[i + 3] = a[i + 3] + (b[i + 3] & m);
wolfSSL 14:167253f4e170 5831 r[i + 4] = a[i + 4] + (b[i + 4] & m);
wolfSSL 14:167253f4e170 5832 r[i + 5] = a[i + 5] + (b[i + 5] & m);
wolfSSL 14:167253f4e170 5833 r[i + 6] = a[i + 6] + (b[i + 6] & m);
wolfSSL 14:167253f4e170 5834 r[i + 7] = a[i + 7] + (b[i + 7] & m);
wolfSSL 14:167253f4e170 5835 }
wolfSSL 14:167253f4e170 5836 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5837 }
wolfSSL 14:167253f4e170 5838
wolfSSL 14:167253f4e170 5839 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 5840 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 5841 *
wolfSSL 14:167253f4e170 5842 * r A single precision integer.
wolfSSL 14:167253f4e170 5843 * a A single precision integer.
wolfSSL 14:167253f4e170 5844 * b A single precision integer.
wolfSSL 14:167253f4e170 5845 */
wolfSSL 14:167253f4e170 5846 SP_NOINLINE static int sp_3072_sub_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5847 const sp_digit* b)
wolfSSL 14:167253f4e170 5848 {
wolfSSL 14:167253f4e170 5849 int i;
wolfSSL 14:167253f4e170 5850
wolfSSL 14:167253f4e170 5851 for (i = 0; i < 136; i++)
wolfSSL 14:167253f4e170 5852 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 5853
wolfSSL 14:167253f4e170 5854 return 0;
wolfSSL 14:167253f4e170 5855 }
wolfSSL 14:167253f4e170 5856
wolfSSL 14:167253f4e170 5857 #endif
wolfSSL 14:167253f4e170 5858 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 5859 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 5860 *
wolfSSL 14:167253f4e170 5861 * r A single precision integer.
wolfSSL 14:167253f4e170 5862 * a A single precision integer.
wolfSSL 14:167253f4e170 5863 * b A single precision integer.
wolfSSL 14:167253f4e170 5864 */
wolfSSL 14:167253f4e170 5865 SP_NOINLINE static int sp_3072_add_136(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5866 const sp_digit* b)
wolfSSL 14:167253f4e170 5867 {
wolfSSL 14:167253f4e170 5868 int i;
wolfSSL 14:167253f4e170 5869
wolfSSL 14:167253f4e170 5870 for (i = 0; i < 136; i++)
wolfSSL 14:167253f4e170 5871 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 5872
wolfSSL 14:167253f4e170 5873 return 0;
wolfSSL 14:167253f4e170 5874 }
wolfSSL 14:167253f4e170 5875 #endif
wolfSSL 14:167253f4e170 5876 SP_NOINLINE static void sp_3072_rshift_136(sp_digit* r, sp_digit* a, byte n)
wolfSSL 14:167253f4e170 5877 {
wolfSSL 14:167253f4e170 5878 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5879 int i;
wolfSSL 14:167253f4e170 5880
wolfSSL 14:167253f4e170 5881 for (i=0; i<135; i++)
wolfSSL 14:167253f4e170 5882 r[i] = ((a[i] >> n) | (a[i + 1] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5883 #else
wolfSSL 14:167253f4e170 5884 r[0] = ((a[0] >> n) | (a[1] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5885 r[1] = ((a[1] >> n) | (a[2] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5886 r[2] = ((a[2] >> n) | (a[3] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5887 r[3] = ((a[3] >> n) | (a[4] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5888 r[4] = ((a[4] >> n) | (a[5] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5889 r[5] = ((a[5] >> n) | (a[6] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5890 r[6] = ((a[6] >> n) | (a[7] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5891 r[7] = ((a[7] >> n) | (a[8] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5892 r[8] = ((a[8] >> n) | (a[9] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5893 r[9] = ((a[9] >> n) | (a[10] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5894 r[10] = ((a[10] >> n) | (a[11] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5895 r[11] = ((a[11] >> n) | (a[12] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5896 r[12] = ((a[12] >> n) | (a[13] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5897 r[13] = ((a[13] >> n) | (a[14] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5898 r[14] = ((a[14] >> n) | (a[15] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5899 r[15] = ((a[15] >> n) | (a[16] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5900 r[16] = ((a[16] >> n) | (a[17] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5901 r[17] = ((a[17] >> n) | (a[18] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5902 r[18] = ((a[18] >> n) | (a[19] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5903 r[19] = ((a[19] >> n) | (a[20] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5904 r[20] = ((a[20] >> n) | (a[21] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5905 r[21] = ((a[21] >> n) | (a[22] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5906 r[22] = ((a[22] >> n) | (a[23] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5907 r[23] = ((a[23] >> n) | (a[24] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5908 r[24] = ((a[24] >> n) | (a[25] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5909 r[25] = ((a[25] >> n) | (a[26] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5910 r[26] = ((a[26] >> n) | (a[27] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5911 r[27] = ((a[27] >> n) | (a[28] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5912 r[28] = ((a[28] >> n) | (a[29] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5913 r[29] = ((a[29] >> n) | (a[30] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5914 r[30] = ((a[30] >> n) | (a[31] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5915 r[31] = ((a[31] >> n) | (a[32] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5916 r[32] = ((a[32] >> n) | (a[33] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5917 r[33] = ((a[33] >> n) | (a[34] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5918 r[34] = ((a[34] >> n) | (a[35] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5919 r[35] = ((a[35] >> n) | (a[36] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5920 r[36] = ((a[36] >> n) | (a[37] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5921 r[37] = ((a[37] >> n) | (a[38] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5922 r[38] = ((a[38] >> n) | (a[39] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5923 r[39] = ((a[39] >> n) | (a[40] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5924 r[40] = ((a[40] >> n) | (a[41] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5925 r[41] = ((a[41] >> n) | (a[42] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5926 r[42] = ((a[42] >> n) | (a[43] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5927 r[43] = ((a[43] >> n) | (a[44] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5928 r[44] = ((a[44] >> n) | (a[45] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5929 r[45] = ((a[45] >> n) | (a[46] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5930 r[46] = ((a[46] >> n) | (a[47] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5931 r[47] = ((a[47] >> n) | (a[48] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5932 r[48] = ((a[48] >> n) | (a[49] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5933 r[49] = ((a[49] >> n) | (a[50] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5934 r[50] = ((a[50] >> n) | (a[51] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5935 r[51] = ((a[51] >> n) | (a[52] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5936 r[52] = ((a[52] >> n) | (a[53] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5937 r[53] = ((a[53] >> n) | (a[54] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5938 r[54] = ((a[54] >> n) | (a[55] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5939 r[55] = ((a[55] >> n) | (a[56] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5940 r[56] = ((a[56] >> n) | (a[57] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5941 r[57] = ((a[57] >> n) | (a[58] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5942 r[58] = ((a[58] >> n) | (a[59] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5943 r[59] = ((a[59] >> n) | (a[60] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5944 r[60] = ((a[60] >> n) | (a[61] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5945 r[61] = ((a[61] >> n) | (a[62] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5946 r[62] = ((a[62] >> n) | (a[63] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5947 r[63] = ((a[63] >> n) | (a[64] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5948 r[64] = ((a[64] >> n) | (a[65] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5949 r[65] = ((a[65] >> n) | (a[66] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5950 r[66] = ((a[66] >> n) | (a[67] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5951 r[67] = ((a[67] >> n) | (a[68] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5952 r[68] = ((a[68] >> n) | (a[69] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5953 r[69] = ((a[69] >> n) | (a[70] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5954 r[70] = ((a[70] >> n) | (a[71] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5955 r[71] = ((a[71] >> n) | (a[72] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5956 r[72] = ((a[72] >> n) | (a[73] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5957 r[73] = ((a[73] >> n) | (a[74] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5958 r[74] = ((a[74] >> n) | (a[75] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5959 r[75] = ((a[75] >> n) | (a[76] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5960 r[76] = ((a[76] >> n) | (a[77] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5961 r[77] = ((a[77] >> n) | (a[78] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5962 r[78] = ((a[78] >> n) | (a[79] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5963 r[79] = ((a[79] >> n) | (a[80] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5964 r[80] = ((a[80] >> n) | (a[81] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5965 r[81] = ((a[81] >> n) | (a[82] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5966 r[82] = ((a[82] >> n) | (a[83] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5967 r[83] = ((a[83] >> n) | (a[84] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5968 r[84] = ((a[84] >> n) | (a[85] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5969 r[85] = ((a[85] >> n) | (a[86] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5970 r[86] = ((a[86] >> n) | (a[87] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5971 r[87] = ((a[87] >> n) | (a[88] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5972 r[88] = ((a[88] >> n) | (a[89] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5973 r[89] = ((a[89] >> n) | (a[90] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5974 r[90] = ((a[90] >> n) | (a[91] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5975 r[91] = ((a[91] >> n) | (a[92] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5976 r[92] = ((a[92] >> n) | (a[93] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5977 r[93] = ((a[93] >> n) | (a[94] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5978 r[94] = ((a[94] >> n) | (a[95] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5979 r[95] = ((a[95] >> n) | (a[96] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5980 r[96] = ((a[96] >> n) | (a[97] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5981 r[97] = ((a[97] >> n) | (a[98] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5982 r[98] = ((a[98] >> n) | (a[99] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5983 r[99] = ((a[99] >> n) | (a[100] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5984 r[100] = ((a[100] >> n) | (a[101] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5985 r[101] = ((a[101] >> n) | (a[102] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5986 r[102] = ((a[102] >> n) | (a[103] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5987 r[103] = ((a[103] >> n) | (a[104] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5988 r[104] = ((a[104] >> n) | (a[105] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5989 r[105] = ((a[105] >> n) | (a[106] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5990 r[106] = ((a[106] >> n) | (a[107] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5991 r[107] = ((a[107] >> n) | (a[108] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5992 r[108] = ((a[108] >> n) | (a[109] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5993 r[109] = ((a[109] >> n) | (a[110] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5994 r[110] = ((a[110] >> n) | (a[111] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5995 r[111] = ((a[111] >> n) | (a[112] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5996 r[112] = ((a[112] >> n) | (a[113] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5997 r[113] = ((a[113] >> n) | (a[114] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5998 r[114] = ((a[114] >> n) | (a[115] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 5999 r[115] = ((a[115] >> n) | (a[116] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6000 r[116] = ((a[116] >> n) | (a[117] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6001 r[117] = ((a[117] >> n) | (a[118] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6002 r[118] = ((a[118] >> n) | (a[119] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6003 r[119] = ((a[119] >> n) | (a[120] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6004 r[120] = ((a[120] >> n) | (a[121] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6005 r[121] = ((a[121] >> n) | (a[122] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6006 r[122] = ((a[122] >> n) | (a[123] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6007 r[123] = ((a[123] >> n) | (a[124] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6008 r[124] = ((a[124] >> n) | (a[125] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6009 r[125] = ((a[125] >> n) | (a[126] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6010 r[126] = ((a[126] >> n) | (a[127] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6011 r[127] = ((a[127] >> n) | (a[128] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6012 r[128] = ((a[128] >> n) | (a[129] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6013 r[129] = ((a[129] >> n) | (a[130] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6014 r[130] = ((a[130] >> n) | (a[131] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6015 r[131] = ((a[131] >> n) | (a[132] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6016 r[132] = ((a[132] >> n) | (a[133] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6017 r[133] = ((a[133] >> n) | (a[134] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6018 r[134] = ((a[134] >> n) | (a[135] << (23 - n))) & 0x7fffff;
wolfSSL 14:167253f4e170 6019 #endif
wolfSSL 14:167253f4e170 6020 r[135] = a[135] >> n;
wolfSSL 14:167253f4e170 6021 }
wolfSSL 14:167253f4e170 6022
wolfSSL 14:167253f4e170 6023 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 6024 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 6025 *
wolfSSL 14:167253f4e170 6026 * a Nmber to be divided.
wolfSSL 14:167253f4e170 6027 * d Number to divide with.
wolfSSL 14:167253f4e170 6028 * m Multiplier result.
wolfSSL 14:167253f4e170 6029 * r Remainder from the division.
wolfSSL 14:167253f4e170 6030 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 6031 */
wolfSSL 14:167253f4e170 6032 static int sp_3072_div_136(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 6033 sp_digit* r)
wolfSSL 14:167253f4e170 6034 {
wolfSSL 14:167253f4e170 6035 int i;
wolfSSL 14:167253f4e170 6036 int64_t d1;
wolfSSL 14:167253f4e170 6037 sp_digit div, r1;
wolfSSL 14:167253f4e170 6038 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6039 sp_digit* td;
wolfSSL 14:167253f4e170 6040 #else
wolfSSL 14:167253f4e170 6041 sp_digit t1d[272 + 1], t2d[136 + 1], sdd[136 + 1];
wolfSSL 14:167253f4e170 6042 #endif
wolfSSL 14:167253f4e170 6043 sp_digit* t1;
wolfSSL 14:167253f4e170 6044 sp_digit* t2;
wolfSSL 14:167253f4e170 6045 sp_digit* sd;
wolfSSL 14:167253f4e170 6046 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6047
wolfSSL 14:167253f4e170 6048 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6049 td = XMALLOC(sizeof(sp_digit) * (4 * 136 + 3), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6050 if (td != NULL) {
wolfSSL 14:167253f4e170 6051 t1 = td;
wolfSSL 14:167253f4e170 6052 t2 = td + 272 + 1;
wolfSSL 14:167253f4e170 6053 sd = t2 + 136 + 1;
wolfSSL 14:167253f4e170 6054 }
wolfSSL 14:167253f4e170 6055 else
wolfSSL 14:167253f4e170 6056 err = MEMORY_E;
wolfSSL 14:167253f4e170 6057 #else
wolfSSL 14:167253f4e170 6058 t1 = t1d;
wolfSSL 14:167253f4e170 6059 t2 = t2d;
wolfSSL 14:167253f4e170 6060 sd = sdd;
wolfSSL 14:167253f4e170 6061 #endif
wolfSSL 14:167253f4e170 6062
wolfSSL 14:167253f4e170 6063 (void)m;
wolfSSL 14:167253f4e170 6064
wolfSSL 14:167253f4e170 6065 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6066 sp_3072_mul_d_136(sd, d, 1 << 10);
wolfSSL 14:167253f4e170 6067 sp_3072_mul_d_272(t1, a, 1 << 10);
wolfSSL 14:167253f4e170 6068 div = sd[135];
wolfSSL 14:167253f4e170 6069 for (i=136; i>=0; i--) {
wolfSSL 14:167253f4e170 6070 t1[136 + i] += t1[136 + i - 1] >> 23;
wolfSSL 14:167253f4e170 6071 t1[136 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 6072 d1 = t1[136 + i];
wolfSSL 14:167253f4e170 6073 d1 <<= 23;
wolfSSL 14:167253f4e170 6074 d1 += t1[136 + i - 1];
wolfSSL 14:167253f4e170 6075 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 6076
wolfSSL 14:167253f4e170 6077 sp_3072_mul_d_136(t2, sd, r1);
wolfSSL 14:167253f4e170 6078 sp_3072_sub_136(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 6079 t1[136 + i] -= t2[136];
wolfSSL 14:167253f4e170 6080 t1[136 + i] += t1[136 + i - 1] >> 23;
wolfSSL 14:167253f4e170 6081 t1[136 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 6082 r1 = (((-t1[136 + i]) << 23) - t1[136 + i - 1]) / div;
wolfSSL 14:167253f4e170 6083 r1 -= t1[136 + i];
wolfSSL 14:167253f4e170 6084 sp_3072_mul_d_136(t2, sd, r1);
wolfSSL 14:167253f4e170 6085 sp_3072_add_136(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 6086 t1[136 + i] += t1[136 + i - 1] >> 23;
wolfSSL 14:167253f4e170 6087 t1[136 + i - 1] &= 0x7fffff;
wolfSSL 14:167253f4e170 6088 }
wolfSSL 14:167253f4e170 6089 t1[136 - 1] += t1[136 - 2] >> 23;
wolfSSL 14:167253f4e170 6090 t1[136 - 2] &= 0x7fffff;
wolfSSL 14:167253f4e170 6091 d1 = t1[136 - 1];
wolfSSL 14:167253f4e170 6092 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 6093
wolfSSL 14:167253f4e170 6094 sp_3072_mul_d_136(t2, sd, r1);
wolfSSL 14:167253f4e170 6095 sp_3072_sub_136(t1, t1, t2);
wolfSSL 14:167253f4e170 6096 XMEMCPY(r, t1, sizeof(*r) * 2 * 136);
wolfSSL 14:167253f4e170 6097 for (i=0; i<134; i++) {
wolfSSL 14:167253f4e170 6098 r[i+1] += r[i] >> 23;
wolfSSL 14:167253f4e170 6099 r[i] &= 0x7fffff;
wolfSSL 14:167253f4e170 6100 }
wolfSSL 14:167253f4e170 6101 sp_3072_cond_add_136(r, r, sd, 0 - (r[135] < 0));
wolfSSL 14:167253f4e170 6102 }
wolfSSL 14:167253f4e170 6103
wolfSSL 14:167253f4e170 6104 sp_3072_rshift_136(r, r, 10);
wolfSSL 14:167253f4e170 6105
wolfSSL 14:167253f4e170 6106 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6107 if (td != NULL)
wolfSSL 14:167253f4e170 6108 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6109 #endif
wolfSSL 14:167253f4e170 6110
wolfSSL 14:167253f4e170 6111 return err;
wolfSSL 14:167253f4e170 6112 }
wolfSSL 14:167253f4e170 6113
wolfSSL 14:167253f4e170 6114 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 6115 *
wolfSSL 14:167253f4e170 6116 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 6117 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 6118 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 6119 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 6120 */
wolfSSL 14:167253f4e170 6121 static int sp_3072_mod_136(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 6122 {
wolfSSL 14:167253f4e170 6123 return sp_3072_div_136(a, m, NULL, r);
wolfSSL 14:167253f4e170 6124 }
wolfSSL 14:167253f4e170 6125
wolfSSL 14:167253f4e170 6126 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 14:167253f4e170 6127 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 14:167253f4e170 6128 *
wolfSSL 14:167253f4e170 6129 * r A single precision number that is the result of the operation.
wolfSSL 14:167253f4e170 6130 * a A single precision number being exponentiated.
wolfSSL 14:167253f4e170 6131 * e A single precision number that is the exponent.
wolfSSL 14:167253f4e170 6132 * bits The number of bits in the exponent.
wolfSSL 14:167253f4e170 6133 * m A single precision number that is the modulus.
wolfSSL 14:167253f4e170 6134 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 14:167253f4e170 6135 */
wolfSSL 14:167253f4e170 6136 static int sp_3072_mod_exp_136(sp_digit* r, sp_digit* a, sp_digit* e, int bits,
wolfSSL 14:167253f4e170 6137 sp_digit* m, int reduceA)
wolfSSL 14:167253f4e170 6138 {
wolfSSL 14:167253f4e170 6139 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 6140 sp_digit* td;
wolfSSL 14:167253f4e170 6141 sp_digit* t[3];
wolfSSL 14:167253f4e170 6142 sp_digit* norm;
wolfSSL 14:167253f4e170 6143 sp_digit mp = 1;
wolfSSL 14:167253f4e170 6144 sp_digit n;
wolfSSL 14:167253f4e170 6145 int i;
wolfSSL 14:167253f4e170 6146 int c, y;
wolfSSL 14:167253f4e170 6147 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6148
wolfSSL 14:167253f4e170 6149 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 136 * 2, NULL,
wolfSSL 14:167253f4e170 6150 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6151 if (td == NULL)
wolfSSL 14:167253f4e170 6152 err = MEMORY_E;
wolfSSL 14:167253f4e170 6153
wolfSSL 14:167253f4e170 6154 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6155 XMEMSET(td, 0, sizeof(*td) * 3 * 136 * 2);
wolfSSL 14:167253f4e170 6156
wolfSSL 14:167253f4e170 6157 norm = t[0] = td;
wolfSSL 14:167253f4e170 6158 t[1] = &td[136 * 2];
wolfSSL 14:167253f4e170 6159 t[2] = &td[2 * 136 * 2];
wolfSSL 14:167253f4e170 6160
wolfSSL 14:167253f4e170 6161 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 6162 sp_3072_mont_norm_136(norm, m);
wolfSSL 14:167253f4e170 6163
wolfSSL 14:167253f4e170 6164 if (reduceA)
wolfSSL 14:167253f4e170 6165 err = sp_3072_mod_136(t[1], a, m);
wolfSSL 14:167253f4e170 6166 else
wolfSSL 14:167253f4e170 6167 XMEMCPY(t[1], a, sizeof(sp_digit) * 136);
wolfSSL 14:167253f4e170 6168 }
wolfSSL 14:167253f4e170 6169 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6170 sp_3072_mul_136(t[1], t[1], norm);
wolfSSL 14:167253f4e170 6171 err = sp_3072_mod_136(t[1], t[1], m);
wolfSSL 14:167253f4e170 6172 }
wolfSSL 14:167253f4e170 6173
wolfSSL 14:167253f4e170 6174 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6175 i = bits / 23;
wolfSSL 14:167253f4e170 6176 c = bits % 23;
wolfSSL 14:167253f4e170 6177 n = e[i--] << (23 - c);
wolfSSL 14:167253f4e170 6178 for (; ; c--) {
wolfSSL 14:167253f4e170 6179 if (c == 0) {
wolfSSL 14:167253f4e170 6180 if (i == -1)
wolfSSL 14:167253f4e170 6181 break;
wolfSSL 14:167253f4e170 6182
wolfSSL 14:167253f4e170 6183 n = e[i--];
wolfSSL 14:167253f4e170 6184 c = 23;
wolfSSL 14:167253f4e170 6185 }
wolfSSL 14:167253f4e170 6186
wolfSSL 14:167253f4e170 6187 y = (n >> 22) & 1;
wolfSSL 14:167253f4e170 6188 n <<= 1;
wolfSSL 14:167253f4e170 6189
wolfSSL 14:167253f4e170 6190 sp_3072_mont_mul_136(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 6191
wolfSSL 14:167253f4e170 6192 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 6193 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 6194 sizeof(*t[2]) * 136 * 2);
wolfSSL 14:167253f4e170 6195 sp_3072_mont_sqr_136(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 6196 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 6197 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 6198 sizeof(*t[2]) * 136 * 2);
wolfSSL 14:167253f4e170 6199 }
wolfSSL 14:167253f4e170 6200
wolfSSL 14:167253f4e170 6201 sp_3072_mont_reduce_136(t[0], m, mp);
wolfSSL 14:167253f4e170 6202 n = sp_3072_cmp_136(t[0], m);
wolfSSL 14:167253f4e170 6203 sp_3072_cond_sub_136(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 6204 XMEMCPY(r, t[0], sizeof(*r) * 136 * 2);
wolfSSL 14:167253f4e170 6205
wolfSSL 14:167253f4e170 6206 }
wolfSSL 14:167253f4e170 6207
wolfSSL 14:167253f4e170 6208 if (td != NULL)
wolfSSL 14:167253f4e170 6209 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6210
wolfSSL 14:167253f4e170 6211 return err;
wolfSSL 14:167253f4e170 6212 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 6213 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6214 sp_digit t[3][272];
wolfSSL 14:167253f4e170 6215 #else
wolfSSL 14:167253f4e170 6216 sp_digit* td;
wolfSSL 14:167253f4e170 6217 sp_digit* t[3];
wolfSSL 14:167253f4e170 6218 #endif
wolfSSL 14:167253f4e170 6219 sp_digit* norm;
wolfSSL 14:167253f4e170 6220 sp_digit mp = 1;
wolfSSL 14:167253f4e170 6221 sp_digit n;
wolfSSL 14:167253f4e170 6222 int i;
wolfSSL 14:167253f4e170 6223 int c, y;
wolfSSL 14:167253f4e170 6224 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6225
wolfSSL 14:167253f4e170 6226 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6227 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 136 * 2, NULL,
wolfSSL 14:167253f4e170 6228 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6229 if (td == NULL)
wolfSSL 14:167253f4e170 6230 err = MEMORY_E;
wolfSSL 14:167253f4e170 6231
wolfSSL 14:167253f4e170 6232 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6233 t[0] = td;
wolfSSL 14:167253f4e170 6234 t[1] = &td[136 * 2];
wolfSSL 14:167253f4e170 6235 t[2] = &td[2 * 136 * 2];
wolfSSL 14:167253f4e170 6236 norm = t[0];
wolfSSL 14:167253f4e170 6237 }
wolfSSL 14:167253f4e170 6238 #else
wolfSSL 14:167253f4e170 6239 norm = t[0];
wolfSSL 14:167253f4e170 6240 #endif
wolfSSL 14:167253f4e170 6241
wolfSSL 14:167253f4e170 6242 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6243 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 6244 sp_3072_mont_norm_136(norm, m);
wolfSSL 14:167253f4e170 6245
wolfSSL 14:167253f4e170 6246 if (reduceA) {
wolfSSL 14:167253f4e170 6247 err = sp_3072_mod_136(t[1], a, m);
wolfSSL 14:167253f4e170 6248 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6249 sp_3072_mul_136(t[1], t[1], norm);
wolfSSL 14:167253f4e170 6250 err = sp_3072_mod_136(t[1], t[1], m);
wolfSSL 14:167253f4e170 6251 }
wolfSSL 14:167253f4e170 6252 }
wolfSSL 14:167253f4e170 6253 else {
wolfSSL 14:167253f4e170 6254 sp_3072_mul_136(t[1], a, norm);
wolfSSL 14:167253f4e170 6255 err = sp_3072_mod_136(t[1], t[1], m);
wolfSSL 14:167253f4e170 6256 }
wolfSSL 14:167253f4e170 6257 }
wolfSSL 14:167253f4e170 6258
wolfSSL 14:167253f4e170 6259 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6260 i = bits / 23;
wolfSSL 14:167253f4e170 6261 c = bits % 23;
wolfSSL 14:167253f4e170 6262 n = e[i--] << (23 - c);
wolfSSL 14:167253f4e170 6263 for (; ; c--) {
wolfSSL 14:167253f4e170 6264 if (c == 0) {
wolfSSL 14:167253f4e170 6265 if (i == -1)
wolfSSL 14:167253f4e170 6266 break;
wolfSSL 14:167253f4e170 6267
wolfSSL 14:167253f4e170 6268 n = e[i--];
wolfSSL 14:167253f4e170 6269 c = 23;
wolfSSL 14:167253f4e170 6270 }
wolfSSL 14:167253f4e170 6271
wolfSSL 14:167253f4e170 6272 y = (n >> 22) & 1;
wolfSSL 14:167253f4e170 6273 n <<= 1;
wolfSSL 14:167253f4e170 6274
wolfSSL 14:167253f4e170 6275 sp_3072_mont_mul_136(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 6276
wolfSSL 14:167253f4e170 6277 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 6278 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 6279 sp_3072_mont_sqr_136(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 6280 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 6281 ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 6282 }
wolfSSL 14:167253f4e170 6283
wolfSSL 14:167253f4e170 6284 sp_3072_mont_reduce_136(t[0], m, mp);
wolfSSL 14:167253f4e170 6285 n = sp_3072_cmp_136(t[0], m);
wolfSSL 14:167253f4e170 6286 sp_3072_cond_sub_136(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 6287 XMEMCPY(r, t[0], sizeof(t[0]));
wolfSSL 14:167253f4e170 6288 }
wolfSSL 14:167253f4e170 6289
wolfSSL 14:167253f4e170 6290 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6291 if (td != NULL)
wolfSSL 14:167253f4e170 6292 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6293 #endif
wolfSSL 14:167253f4e170 6294
wolfSSL 14:167253f4e170 6295 return err;
wolfSSL 14:167253f4e170 6296 #else
wolfSSL 14:167253f4e170 6297 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6298 sp_digit t[32][272];
wolfSSL 14:167253f4e170 6299 #else
wolfSSL 14:167253f4e170 6300 sp_digit* t[32];
wolfSSL 14:167253f4e170 6301 sp_digit* td;
wolfSSL 14:167253f4e170 6302 #endif
wolfSSL 14:167253f4e170 6303 sp_digit* norm;
wolfSSL 14:167253f4e170 6304 sp_digit rt[272];
wolfSSL 14:167253f4e170 6305 sp_digit mp = 1;
wolfSSL 14:167253f4e170 6306 sp_digit n;
wolfSSL 14:167253f4e170 6307 int i;
wolfSSL 14:167253f4e170 6308 int c, y;
wolfSSL 14:167253f4e170 6309 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6310
wolfSSL 14:167253f4e170 6311 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6312 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 272, NULL,
wolfSSL 14:167253f4e170 6313 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6314 if (td == NULL)
wolfSSL 14:167253f4e170 6315 err = MEMORY_E;
wolfSSL 14:167253f4e170 6316
wolfSSL 14:167253f4e170 6317 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6318 for (i=0; i<32; i++)
wolfSSL 14:167253f4e170 6319 t[i] = td + i * 272;
wolfSSL 14:167253f4e170 6320 norm = t[0];
wolfSSL 14:167253f4e170 6321 }
wolfSSL 14:167253f4e170 6322 #else
wolfSSL 14:167253f4e170 6323 norm = t[0];
wolfSSL 14:167253f4e170 6324 #endif
wolfSSL 14:167253f4e170 6325
wolfSSL 14:167253f4e170 6326 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6327 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 6328 sp_3072_mont_norm_136(norm, m);
wolfSSL 14:167253f4e170 6329
wolfSSL 14:167253f4e170 6330 if (reduceA) {
wolfSSL 14:167253f4e170 6331 err = sp_3072_mod_136(t[1], a, m);
wolfSSL 14:167253f4e170 6332 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6333 sp_3072_mul_136(t[1], t[1], norm);
wolfSSL 14:167253f4e170 6334 err = sp_3072_mod_136(t[1], t[1], m);
wolfSSL 14:167253f4e170 6335 }
wolfSSL 14:167253f4e170 6336 }
wolfSSL 14:167253f4e170 6337 else {
wolfSSL 14:167253f4e170 6338 sp_3072_mul_136(t[1], a, norm);
wolfSSL 14:167253f4e170 6339 err = sp_3072_mod_136(t[1], t[1], m);
wolfSSL 14:167253f4e170 6340 }
wolfSSL 14:167253f4e170 6341 }
wolfSSL 14:167253f4e170 6342
wolfSSL 14:167253f4e170 6343 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6344 sp_3072_mont_sqr_136(t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 6345 sp_3072_mont_mul_136(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 6346 sp_3072_mont_sqr_136(t[ 4], t[ 2], m, mp);
wolfSSL 14:167253f4e170 6347 sp_3072_mont_mul_136(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 14:167253f4e170 6348 sp_3072_mont_sqr_136(t[ 6], t[ 3], m, mp);
wolfSSL 14:167253f4e170 6349 sp_3072_mont_mul_136(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 14:167253f4e170 6350 sp_3072_mont_sqr_136(t[ 8], t[ 4], m, mp);
wolfSSL 14:167253f4e170 6351 sp_3072_mont_mul_136(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 14:167253f4e170 6352 sp_3072_mont_sqr_136(t[10], t[ 5], m, mp);
wolfSSL 14:167253f4e170 6353 sp_3072_mont_mul_136(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 14:167253f4e170 6354 sp_3072_mont_sqr_136(t[12], t[ 6], m, mp);
wolfSSL 14:167253f4e170 6355 sp_3072_mont_mul_136(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 14:167253f4e170 6356 sp_3072_mont_sqr_136(t[14], t[ 7], m, mp);
wolfSSL 14:167253f4e170 6357 sp_3072_mont_mul_136(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 14:167253f4e170 6358 sp_3072_mont_sqr_136(t[16], t[ 8], m, mp);
wolfSSL 14:167253f4e170 6359 sp_3072_mont_mul_136(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 14:167253f4e170 6360 sp_3072_mont_sqr_136(t[18], t[ 9], m, mp);
wolfSSL 14:167253f4e170 6361 sp_3072_mont_mul_136(t[19], t[10], t[ 9], m, mp);
wolfSSL 14:167253f4e170 6362 sp_3072_mont_sqr_136(t[20], t[10], m, mp);
wolfSSL 14:167253f4e170 6363 sp_3072_mont_mul_136(t[21], t[11], t[10], m, mp);
wolfSSL 14:167253f4e170 6364 sp_3072_mont_sqr_136(t[22], t[11], m, mp);
wolfSSL 14:167253f4e170 6365 sp_3072_mont_mul_136(t[23], t[12], t[11], m, mp);
wolfSSL 14:167253f4e170 6366 sp_3072_mont_sqr_136(t[24], t[12], m, mp);
wolfSSL 14:167253f4e170 6367 sp_3072_mont_mul_136(t[25], t[13], t[12], m, mp);
wolfSSL 14:167253f4e170 6368 sp_3072_mont_sqr_136(t[26], t[13], m, mp);
wolfSSL 14:167253f4e170 6369 sp_3072_mont_mul_136(t[27], t[14], t[13], m, mp);
wolfSSL 14:167253f4e170 6370 sp_3072_mont_sqr_136(t[28], t[14], m, mp);
wolfSSL 14:167253f4e170 6371 sp_3072_mont_mul_136(t[29], t[15], t[14], m, mp);
wolfSSL 14:167253f4e170 6372 sp_3072_mont_sqr_136(t[30], t[15], m, mp);
wolfSSL 14:167253f4e170 6373 sp_3072_mont_mul_136(t[31], t[16], t[15], m, mp);
wolfSSL 14:167253f4e170 6374
wolfSSL 14:167253f4e170 6375 bits = ((bits + 4) / 5) * 5;
wolfSSL 14:167253f4e170 6376 i = ((bits + 22) / 23) - 1;
wolfSSL 14:167253f4e170 6377 c = bits % 23;
wolfSSL 14:167253f4e170 6378 if (c == 0)
wolfSSL 14:167253f4e170 6379 c = 23;
wolfSSL 14:167253f4e170 6380 if (i < 136)
wolfSSL 14:167253f4e170 6381 n = e[i--] << (32 - c);
wolfSSL 14:167253f4e170 6382 else {
wolfSSL 14:167253f4e170 6383 n = 0;
wolfSSL 14:167253f4e170 6384 i--;
wolfSSL 14:167253f4e170 6385 }
wolfSSL 14:167253f4e170 6386 if (c < 5) {
wolfSSL 14:167253f4e170 6387 n |= e[i--] << (9 - c);
wolfSSL 14:167253f4e170 6388 c += 23;
wolfSSL 14:167253f4e170 6389 }
wolfSSL 14:167253f4e170 6390 y = n >> 27;
wolfSSL 14:167253f4e170 6391 n <<= 5;
wolfSSL 14:167253f4e170 6392 c -= 5;
wolfSSL 14:167253f4e170 6393 XMEMCPY(rt, t[y], sizeof(rt));
wolfSSL 14:167253f4e170 6394 for (; i>=0 || c>=5; ) {
wolfSSL 14:167253f4e170 6395 if (c < 5) {
wolfSSL 14:167253f4e170 6396 n |= e[i--] << (9 - c);
wolfSSL 14:167253f4e170 6397 c += 23;
wolfSSL 14:167253f4e170 6398 }
wolfSSL 14:167253f4e170 6399 y = (n >> 27) & 0x1f;
wolfSSL 14:167253f4e170 6400 n <<= 5;
wolfSSL 14:167253f4e170 6401 c -= 5;
wolfSSL 14:167253f4e170 6402
wolfSSL 14:167253f4e170 6403 sp_3072_mont_sqr_136(rt, rt, m, mp);
wolfSSL 14:167253f4e170 6404 sp_3072_mont_sqr_136(rt, rt, m, mp);
wolfSSL 14:167253f4e170 6405 sp_3072_mont_sqr_136(rt, rt, m, mp);
wolfSSL 14:167253f4e170 6406 sp_3072_mont_sqr_136(rt, rt, m, mp);
wolfSSL 14:167253f4e170 6407 sp_3072_mont_sqr_136(rt, rt, m, mp);
wolfSSL 14:167253f4e170 6408
wolfSSL 14:167253f4e170 6409 sp_3072_mont_mul_136(rt, rt, t[y], m, mp);
wolfSSL 14:167253f4e170 6410 }
wolfSSL 14:167253f4e170 6411
wolfSSL 14:167253f4e170 6412 sp_3072_mont_reduce_136(rt, m, mp);
wolfSSL 14:167253f4e170 6413 n = sp_3072_cmp_136(rt, m);
wolfSSL 14:167253f4e170 6414 sp_3072_cond_sub_136(rt, rt, m, (n < 0) - 1);
wolfSSL 14:167253f4e170 6415 XMEMCPY(r, rt, sizeof(rt));
wolfSSL 14:167253f4e170 6416 }
wolfSSL 14:167253f4e170 6417
wolfSSL 14:167253f4e170 6418 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6419 if (td != NULL)
wolfSSL 14:167253f4e170 6420 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6421 #endif
wolfSSL 14:167253f4e170 6422
wolfSSL 14:167253f4e170 6423 return err;
wolfSSL 14:167253f4e170 6424 #endif
wolfSSL 14:167253f4e170 6425 }
wolfSSL 14:167253f4e170 6426 #endif /* SP_RSA_PRIVATE_EXP_D || WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 6427
wolfSSL 14:167253f4e170 6428 #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \
wolfSSL 14:167253f4e170 6429 !defined(RSA_LOW_MEM)
wolfSSL 14:167253f4e170 6430 /* AND m into each word of a and store in r.
wolfSSL 14:167253f4e170 6431 *
wolfSSL 14:167253f4e170 6432 * r A single precision integer.
wolfSSL 14:167253f4e170 6433 * a A single precision integer.
wolfSSL 14:167253f4e170 6434 * m Mask to AND against each digit.
wolfSSL 14:167253f4e170 6435 */
wolfSSL 14:167253f4e170 6436 static void sp_3072_mask_68(sp_digit* r, sp_digit* a, sp_digit m)
wolfSSL 14:167253f4e170 6437 {
wolfSSL 14:167253f4e170 6438 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 6439 int i;
wolfSSL 14:167253f4e170 6440
wolfSSL 14:167253f4e170 6441 for (i=0; i<68; i++)
wolfSSL 14:167253f4e170 6442 r[i] = a[i] & m;
wolfSSL 14:167253f4e170 6443 #else
wolfSSL 14:167253f4e170 6444 int i;
wolfSSL 14:167253f4e170 6445
wolfSSL 14:167253f4e170 6446 for (i = 0; i < 64; i += 8) {
wolfSSL 14:167253f4e170 6447 r[i+0] = a[i+0] & m;
wolfSSL 14:167253f4e170 6448 r[i+1] = a[i+1] & m;
wolfSSL 14:167253f4e170 6449 r[i+2] = a[i+2] & m;
wolfSSL 14:167253f4e170 6450 r[i+3] = a[i+3] & m;
wolfSSL 14:167253f4e170 6451 r[i+4] = a[i+4] & m;
wolfSSL 14:167253f4e170 6452 r[i+5] = a[i+5] & m;
wolfSSL 14:167253f4e170 6453 r[i+6] = a[i+6] & m;
wolfSSL 14:167253f4e170 6454 r[i+7] = a[i+7] & m;
wolfSSL 14:167253f4e170 6455 }
wolfSSL 14:167253f4e170 6456 r[64] = a[64] & m;
wolfSSL 14:167253f4e170 6457 r[65] = a[65] & m;
wolfSSL 14:167253f4e170 6458 r[66] = a[66] & m;
wolfSSL 14:167253f4e170 6459 r[67] = a[67] & m;
wolfSSL 14:167253f4e170 6460 #endif
wolfSSL 14:167253f4e170 6461 }
wolfSSL 14:167253f4e170 6462
wolfSSL 14:167253f4e170 6463 #endif
wolfSSL 14:167253f4e170 6464 #ifdef WOLFSSL_HAVE_SP_RSA
wolfSSL 14:167253f4e170 6465 /* RSA public key operation.
wolfSSL 14:167253f4e170 6466 *
wolfSSL 14:167253f4e170 6467 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 14:167253f4e170 6468 * inLen Number of bytes in base.
wolfSSL 14:167253f4e170 6469 * em Public exponent.
wolfSSL 14:167253f4e170 6470 * mm Modulus.
wolfSSL 14:167253f4e170 6471 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 6472 * Must be at least 384 bytes long.
wolfSSL 14:167253f4e170 6473 * outLen Number of bytes in result.
wolfSSL 14:167253f4e170 6474 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 14:167253f4e170 6475 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 14:167253f4e170 6476 */
wolfSSL 14:167253f4e170 6477 int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,
wolfSSL 14:167253f4e170 6478 byte* out, word32* outLen)
wolfSSL 14:167253f4e170 6479 {
wolfSSL 14:167253f4e170 6480 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 6481 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 6482 sp_digit* a;
wolfSSL 14:167253f4e170 6483 sp_digit* m;
wolfSSL 14:167253f4e170 6484 sp_digit* r;
wolfSSL 14:167253f4e170 6485 sp_digit* norm;
wolfSSL 14:167253f4e170 6486 sp_digit e[1];
wolfSSL 14:167253f4e170 6487 sp_digit mp;
wolfSSL 14:167253f4e170 6488 int i;
wolfSSL 14:167253f4e170 6489 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6490
wolfSSL 14:167253f4e170 6491 if (*outLen < 384)
wolfSSL 14:167253f4e170 6492 err = MP_TO_E;
wolfSSL 14:167253f4e170 6493 if (err == MP_OKAY && (mp_count_bits(em) > 23 || inLen > 384 ||
wolfSSL 14:167253f4e170 6494 mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6495 err = MP_READ_E;
wolfSSL 14:167253f4e170 6496
wolfSSL 14:167253f4e170 6497 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6498 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 136 * 5, NULL,
wolfSSL 14:167253f4e170 6499 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6500 if (d == NULL)
wolfSSL 14:167253f4e170 6501 err = MEMORY_E;
wolfSSL 14:167253f4e170 6502 }
wolfSSL 14:167253f4e170 6503
wolfSSL 14:167253f4e170 6504 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6505 a = d;
wolfSSL 14:167253f4e170 6506 r = a + 136 * 2;
wolfSSL 14:167253f4e170 6507 m = r + 136 * 2;
wolfSSL 14:167253f4e170 6508 norm = r;
wolfSSL 14:167253f4e170 6509
wolfSSL 14:167253f4e170 6510 sp_3072_from_bin(a, 136, in, inLen);
wolfSSL 14:167253f4e170 6511 #if DIGIT_BIT >= 23
wolfSSL 14:167253f4e170 6512 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 6513 #else
wolfSSL 14:167253f4e170 6514 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 6515 if (em->used > 1)
wolfSSL 14:167253f4e170 6516 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 14:167253f4e170 6517 #endif
wolfSSL 14:167253f4e170 6518 if (e[0] == 0)
wolfSSL 14:167253f4e170 6519 err = MP_EXPTMOD_E;
wolfSSL 14:167253f4e170 6520 }
wolfSSL 14:167253f4e170 6521
wolfSSL 14:167253f4e170 6522 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6523 sp_3072_from_mp(m, 136, mm);
wolfSSL 14:167253f4e170 6524
wolfSSL 14:167253f4e170 6525 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 6526 sp_3072_mont_norm_136(norm, m);
wolfSSL 14:167253f4e170 6527 }
wolfSSL 14:167253f4e170 6528 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6529 sp_3072_mul_136(a, a, norm);
wolfSSL 14:167253f4e170 6530 err = sp_3072_mod_136(a, a, m);
wolfSSL 14:167253f4e170 6531 }
wolfSSL 14:167253f4e170 6532 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6533 for (i=22; i>=0; i--)
wolfSSL 14:167253f4e170 6534 if (e[0] >> i)
wolfSSL 14:167253f4e170 6535 break;
wolfSSL 14:167253f4e170 6536
wolfSSL 14:167253f4e170 6537 XMEMCPY(r, a, sizeof(sp_digit) * 136 * 2);
wolfSSL 14:167253f4e170 6538 for (i--; i>=0; i--) {
wolfSSL 14:167253f4e170 6539 sp_3072_mont_sqr_136(r, r, m, mp);
wolfSSL 14:167253f4e170 6540
wolfSSL 14:167253f4e170 6541 if (((e[0] >> i) & 1) == 1)
wolfSSL 14:167253f4e170 6542 sp_3072_mont_mul_136(r, r, a, m, mp);
wolfSSL 14:167253f4e170 6543 }
wolfSSL 14:167253f4e170 6544 sp_3072_mont_reduce_136(r, m, mp);
wolfSSL 14:167253f4e170 6545 mp = sp_3072_cmp_136(r, m);
wolfSSL 14:167253f4e170 6546 sp_3072_cond_sub_136(r, r, m, (mp < 0) - 1);
wolfSSL 14:167253f4e170 6547
wolfSSL 14:167253f4e170 6548 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6549 *outLen = 384;
wolfSSL 14:167253f4e170 6550 }
wolfSSL 14:167253f4e170 6551
wolfSSL 14:167253f4e170 6552 if (d != NULL)
wolfSSL 14:167253f4e170 6553 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6554
wolfSSL 14:167253f4e170 6555 return err;
wolfSSL 14:167253f4e170 6556 #else
wolfSSL 14:167253f4e170 6557 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6558 sp_digit ad[272], md[136], rd[272];
wolfSSL 14:167253f4e170 6559 #else
wolfSSL 14:167253f4e170 6560 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 6561 #endif
wolfSSL 14:167253f4e170 6562 sp_digit* a;
wolfSSL 14:167253f4e170 6563 sp_digit* m;
wolfSSL 14:167253f4e170 6564 sp_digit* r;
wolfSSL 14:167253f4e170 6565 sp_digit e[1];
wolfSSL 14:167253f4e170 6566 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6567
wolfSSL 14:167253f4e170 6568 if (*outLen < 384)
wolfSSL 14:167253f4e170 6569 err = MP_TO_E;
wolfSSL 14:167253f4e170 6570 if (err == MP_OKAY && (mp_count_bits(em) > 23 || inLen > 384 ||
wolfSSL 14:167253f4e170 6571 mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6572 err = MP_READ_E;
wolfSSL 14:167253f4e170 6573
wolfSSL 14:167253f4e170 6574 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6575 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6576 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 136 * 5, NULL,
wolfSSL 14:167253f4e170 6577 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6578 if (d == NULL)
wolfSSL 14:167253f4e170 6579 err = MEMORY_E;
wolfSSL 14:167253f4e170 6580 }
wolfSSL 14:167253f4e170 6581
wolfSSL 14:167253f4e170 6582 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6583 a = d;
wolfSSL 14:167253f4e170 6584 r = a + 136 * 2;
wolfSSL 14:167253f4e170 6585 m = r + 136 * 2;
wolfSSL 14:167253f4e170 6586 }
wolfSSL 14:167253f4e170 6587 #else
wolfSSL 14:167253f4e170 6588 a = ad;
wolfSSL 14:167253f4e170 6589 m = md;
wolfSSL 14:167253f4e170 6590 r = rd;
wolfSSL 14:167253f4e170 6591 #endif
wolfSSL 14:167253f4e170 6592
wolfSSL 14:167253f4e170 6593 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6594 sp_3072_from_bin(a, 136, in, inLen);
wolfSSL 14:167253f4e170 6595 #if DIGIT_BIT >= 23
wolfSSL 14:167253f4e170 6596 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 6597 #else
wolfSSL 14:167253f4e170 6598 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 6599 if (em->used > 1)
wolfSSL 14:167253f4e170 6600 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 14:167253f4e170 6601 #endif
wolfSSL 14:167253f4e170 6602 if (e[0] == 0)
wolfSSL 14:167253f4e170 6603 err = MP_EXPTMOD_E;
wolfSSL 14:167253f4e170 6604 }
wolfSSL 14:167253f4e170 6605 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6606 sp_3072_from_mp(m, 136, mm);
wolfSSL 14:167253f4e170 6607
wolfSSL 14:167253f4e170 6608 if (e[0] == 0x3) {
wolfSSL 14:167253f4e170 6609 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6610 sp_3072_sqr_136(r, a);
wolfSSL 14:167253f4e170 6611 err = sp_3072_mod_136(r, r, m);
wolfSSL 14:167253f4e170 6612 }
wolfSSL 14:167253f4e170 6613 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6614 sp_3072_mul_136(r, a, r);
wolfSSL 14:167253f4e170 6615 err = sp_3072_mod_136(r, r, m);
wolfSSL 14:167253f4e170 6616 }
wolfSSL 14:167253f4e170 6617 }
wolfSSL 14:167253f4e170 6618 else {
wolfSSL 14:167253f4e170 6619 sp_digit* norm = r;
wolfSSL 14:167253f4e170 6620 int i;
wolfSSL 14:167253f4e170 6621 sp_digit mp;
wolfSSL 14:167253f4e170 6622
wolfSSL 14:167253f4e170 6623 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 6624 sp_3072_mont_norm_136(norm, m);
wolfSSL 14:167253f4e170 6625
wolfSSL 14:167253f4e170 6626 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6627 sp_3072_mul_136(a, a, norm);
wolfSSL 14:167253f4e170 6628 err = sp_3072_mod_136(a, a, m);
wolfSSL 14:167253f4e170 6629 }
wolfSSL 14:167253f4e170 6630
wolfSSL 14:167253f4e170 6631 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6632 for (i=22; i>=0; i--)
wolfSSL 14:167253f4e170 6633 if (e[0] >> i)
wolfSSL 14:167253f4e170 6634 break;
wolfSSL 14:167253f4e170 6635
wolfSSL 14:167253f4e170 6636 XMEMCPY(r, a, sizeof(sp_digit) * 272);
wolfSSL 14:167253f4e170 6637 for (i--; i>=0; i--) {
wolfSSL 14:167253f4e170 6638 sp_3072_mont_sqr_136(r, r, m, mp);
wolfSSL 14:167253f4e170 6639
wolfSSL 14:167253f4e170 6640 if (((e[0] >> i) & 1) == 1)
wolfSSL 14:167253f4e170 6641 sp_3072_mont_mul_136(r, r, a, m, mp);
wolfSSL 14:167253f4e170 6642 }
wolfSSL 14:167253f4e170 6643 sp_3072_mont_reduce_136(r, m, mp);
wolfSSL 14:167253f4e170 6644 mp = sp_3072_cmp_136(r, m);
wolfSSL 14:167253f4e170 6645 sp_3072_cond_sub_136(r, r, m, (mp < 0) - 1);
wolfSSL 14:167253f4e170 6646 }
wolfSSL 14:167253f4e170 6647 }
wolfSSL 14:167253f4e170 6648 }
wolfSSL 14:167253f4e170 6649
wolfSSL 14:167253f4e170 6650 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6651 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6652 *outLen = 384;
wolfSSL 14:167253f4e170 6653 }
wolfSSL 14:167253f4e170 6654
wolfSSL 14:167253f4e170 6655 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6656 if (d != NULL)
wolfSSL 14:167253f4e170 6657 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6658 #endif
wolfSSL 14:167253f4e170 6659
wolfSSL 14:167253f4e170 6660 return err;
wolfSSL 14:167253f4e170 6661 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 6662 }
wolfSSL 14:167253f4e170 6663
wolfSSL 14:167253f4e170 6664 /* RSA private key operation.
wolfSSL 14:167253f4e170 6665 *
wolfSSL 14:167253f4e170 6666 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 14:167253f4e170 6667 * inLen Number of bytes in base.
wolfSSL 14:167253f4e170 6668 * dm Private exponent.
wolfSSL 14:167253f4e170 6669 * pm First prime.
wolfSSL 14:167253f4e170 6670 * qm Second prime.
wolfSSL 14:167253f4e170 6671 * dpm First prime's CRT exponent.
wolfSSL 14:167253f4e170 6672 * dqm Second prime's CRT exponent.
wolfSSL 14:167253f4e170 6673 * qim Inverse of second prime mod p.
wolfSSL 14:167253f4e170 6674 * mm Modulus.
wolfSSL 14:167253f4e170 6675 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 6676 * Must be at least 384 bytes long.
wolfSSL 14:167253f4e170 6677 * outLen Number of bytes in result.
wolfSSL 14:167253f4e170 6678 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 14:167253f4e170 6679 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 14:167253f4e170 6680 */
wolfSSL 14:167253f4e170 6681 int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,
wolfSSL 14:167253f4e170 6682 mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,
wolfSSL 14:167253f4e170 6683 byte* out, word32* outLen)
wolfSSL 14:167253f4e170 6684 {
wolfSSL 14:167253f4e170 6685 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
wolfSSL 14:167253f4e170 6686 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6687 sp_digit* a;
wolfSSL 14:167253f4e170 6688 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 6689 sp_digit* m;
wolfSSL 14:167253f4e170 6690 sp_digit* r;
wolfSSL 14:167253f4e170 6691 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6692
wolfSSL 14:167253f4e170 6693 (void)pm;
wolfSSL 14:167253f4e170 6694 (void)qm;
wolfSSL 14:167253f4e170 6695 (void)dpm;
wolfSSL 14:167253f4e170 6696 (void)dqm;
wolfSSL 14:167253f4e170 6697 (void)qim;
wolfSSL 14:167253f4e170 6698
wolfSSL 14:167253f4e170 6699 if (*outLen < 384)
wolfSSL 14:167253f4e170 6700 err = MP_TO_E;
wolfSSL 14:167253f4e170 6701 if (err == MP_OKAY && (mp_count_bits(dm) > 3072 || inLen > 384 ||
wolfSSL 14:167253f4e170 6702 mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6703 err = MP_READ_E;
wolfSSL 14:167253f4e170 6704
wolfSSL 14:167253f4e170 6705 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6706 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 136 * 4, NULL,
wolfSSL 14:167253f4e170 6707 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6708 if (d == NULL)
wolfSSL 14:167253f4e170 6709 err = MEMORY_E;
wolfSSL 14:167253f4e170 6710 }
wolfSSL 14:167253f4e170 6711 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6712 a = d + 136;
wolfSSL 14:167253f4e170 6713 m = a + 136;
wolfSSL 14:167253f4e170 6714 r = a;
wolfSSL 14:167253f4e170 6715
wolfSSL 14:167253f4e170 6716 sp_3072_from_bin(a, 136, in, inLen);
wolfSSL 14:167253f4e170 6717 sp_3072_from_mp(d, 136, dm);
wolfSSL 14:167253f4e170 6718 sp_3072_from_mp(m, 136, mm);
wolfSSL 14:167253f4e170 6719 err = sp_3072_mod_exp_136(r, a, d, 3072, m, 0);
wolfSSL 14:167253f4e170 6720 }
wolfSSL 14:167253f4e170 6721 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6722 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6723 *outLen = 384;
wolfSSL 14:167253f4e170 6724 }
wolfSSL 14:167253f4e170 6725
wolfSSL 14:167253f4e170 6726 if (d != NULL) {
wolfSSL 14:167253f4e170 6727 XMEMSET(d, 0, sizeof(sp_digit) * 136);
wolfSSL 14:167253f4e170 6728 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6729 }
wolfSSL 14:167253f4e170 6730
wolfSSL 14:167253f4e170 6731 return err;
wolfSSL 14:167253f4e170 6732 #else
wolfSSL 14:167253f4e170 6733 sp_digit a[272], d[136], m[136];
wolfSSL 14:167253f4e170 6734 sp_digit* r = a;
wolfSSL 14:167253f4e170 6735 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6736
wolfSSL 14:167253f4e170 6737 (void)pm;
wolfSSL 14:167253f4e170 6738 (void)qm;
wolfSSL 14:167253f4e170 6739 (void)dpm;
wolfSSL 14:167253f4e170 6740 (void)dqm;
wolfSSL 14:167253f4e170 6741 (void)qim;
wolfSSL 14:167253f4e170 6742
wolfSSL 14:167253f4e170 6743 if (*outLen < 384)
wolfSSL 14:167253f4e170 6744 err = MP_TO_E;
wolfSSL 14:167253f4e170 6745 if (err == MP_OKAY && (mp_count_bits(dm) > 3072 || inLen > 384 ||
wolfSSL 14:167253f4e170 6746 mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6747 err = MP_READ_E;
wolfSSL 14:167253f4e170 6748
wolfSSL 14:167253f4e170 6749 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6750 sp_3072_from_bin(a, 136, in, inLen);
wolfSSL 14:167253f4e170 6751 sp_3072_from_mp(d, 136, dm);
wolfSSL 14:167253f4e170 6752 sp_3072_from_mp(m, 136, mm);
wolfSSL 14:167253f4e170 6753 err = sp_3072_mod_exp_136(r, a, d, 3072, m, 0);
wolfSSL 14:167253f4e170 6754 }
wolfSSL 14:167253f4e170 6755
wolfSSL 14:167253f4e170 6756 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6757 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6758 *outLen = 384;
wolfSSL 14:167253f4e170 6759 }
wolfSSL 14:167253f4e170 6760
wolfSSL 14:167253f4e170 6761 XMEMSET(d, 0, sizeof(sp_digit) * 136);
wolfSSL 14:167253f4e170 6762
wolfSSL 14:167253f4e170 6763 return err;
wolfSSL 14:167253f4e170 6764 #endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */
wolfSSL 14:167253f4e170 6765 #else
wolfSSL 14:167253f4e170 6766 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6767 sp_digit* t = NULL;
wolfSSL 14:167253f4e170 6768 sp_digit* a;
wolfSSL 14:167253f4e170 6769 sp_digit* p;
wolfSSL 14:167253f4e170 6770 sp_digit* q;
wolfSSL 14:167253f4e170 6771 sp_digit* dp;
wolfSSL 14:167253f4e170 6772 sp_digit* dq;
wolfSSL 14:167253f4e170 6773 sp_digit* qi;
wolfSSL 14:167253f4e170 6774 sp_digit* tmp;
wolfSSL 14:167253f4e170 6775 sp_digit* tmpa;
wolfSSL 14:167253f4e170 6776 sp_digit* tmpb;
wolfSSL 14:167253f4e170 6777 sp_digit* r;
wolfSSL 14:167253f4e170 6778 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6779
wolfSSL 14:167253f4e170 6780 (void)dm;
wolfSSL 14:167253f4e170 6781 (void)mm;
wolfSSL 14:167253f4e170 6782
wolfSSL 14:167253f4e170 6783 if (*outLen < 384)
wolfSSL 14:167253f4e170 6784 err = MP_TO_E;
wolfSSL 14:167253f4e170 6785 if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6786 err = MP_READ_E;
wolfSSL 14:167253f4e170 6787
wolfSSL 14:167253f4e170 6788 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6789 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 68 * 11, NULL,
wolfSSL 14:167253f4e170 6790 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6791 if (t == NULL)
wolfSSL 14:167253f4e170 6792 err = MEMORY_E;
wolfSSL 14:167253f4e170 6793 }
wolfSSL 14:167253f4e170 6794 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6795 a = t;
wolfSSL 14:167253f4e170 6796 p = a + 136 * 2;
wolfSSL 14:167253f4e170 6797 q = p + 68;
wolfSSL 14:167253f4e170 6798 qi = dq = dp = q + 68;
wolfSSL 14:167253f4e170 6799 tmpa = qi + 68;
wolfSSL 14:167253f4e170 6800 tmpb = tmpa + 136;
wolfSSL 14:167253f4e170 6801
wolfSSL 14:167253f4e170 6802 tmp = t;
wolfSSL 14:167253f4e170 6803 r = tmp + 136;
wolfSSL 14:167253f4e170 6804
wolfSSL 14:167253f4e170 6805 sp_3072_from_bin(a, 136, in, inLen);
wolfSSL 14:167253f4e170 6806 sp_3072_from_mp(p, 68, pm);
wolfSSL 14:167253f4e170 6807 sp_3072_from_mp(q, 68, qm);
wolfSSL 14:167253f4e170 6808 sp_3072_from_mp(dp, 68, dpm);
wolfSSL 14:167253f4e170 6809 err = sp_3072_mod_exp_68(tmpa, a, dp, 1536, p, 1);
wolfSSL 14:167253f4e170 6810 }
wolfSSL 14:167253f4e170 6811 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6812 sp_3072_from_mp(dq, 68, dqm);
wolfSSL 14:167253f4e170 6813 err = sp_3072_mod_exp_68(tmpb, a, dq, 1536, q, 1);
wolfSSL 14:167253f4e170 6814 }
wolfSSL 14:167253f4e170 6815 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6816 sp_3072_sub_68(tmpa, tmpa, tmpb);
wolfSSL 14:167253f4e170 6817 sp_3072_mask_68(tmp, p, tmpa[67] >> 31);
wolfSSL 14:167253f4e170 6818 sp_3072_add_68(tmpa, tmpa, tmp);
wolfSSL 14:167253f4e170 6819
wolfSSL 14:167253f4e170 6820 sp_3072_from_mp(qi, 68, qim);
wolfSSL 14:167253f4e170 6821 sp_3072_mul_68(tmpa, tmpa, qi);
wolfSSL 14:167253f4e170 6822 err = sp_3072_mod_68(tmpa, tmpa, p);
wolfSSL 14:167253f4e170 6823 }
wolfSSL 14:167253f4e170 6824
wolfSSL 14:167253f4e170 6825 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6826 sp_3072_mul_68(tmpa, q, tmpa);
wolfSSL 14:167253f4e170 6827 sp_3072_add_136(r, tmpb, tmpa);
wolfSSL 14:167253f4e170 6828 sp_3072_norm_136(r);
wolfSSL 14:167253f4e170 6829
wolfSSL 14:167253f4e170 6830 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6831 *outLen = 384;
wolfSSL 14:167253f4e170 6832 }
wolfSSL 14:167253f4e170 6833
wolfSSL 14:167253f4e170 6834 if (t != NULL) {
wolfSSL 14:167253f4e170 6835 XMEMSET(t, 0, sizeof(sp_digit) * 68 * 11);
wolfSSL 14:167253f4e170 6836 XFREE(t, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6837 }
wolfSSL 14:167253f4e170 6838
wolfSSL 14:167253f4e170 6839 return err;
wolfSSL 14:167253f4e170 6840 #else
wolfSSL 14:167253f4e170 6841 sp_digit a[136 * 2];
wolfSSL 14:167253f4e170 6842 sp_digit p[68], q[68], dp[68], dq[68], qi[68];
wolfSSL 14:167253f4e170 6843 sp_digit tmp[136], tmpa[136], tmpb[136];
wolfSSL 14:167253f4e170 6844 sp_digit* r = a;
wolfSSL 14:167253f4e170 6845 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6846
wolfSSL 14:167253f4e170 6847 (void)dm;
wolfSSL 14:167253f4e170 6848 (void)mm;
wolfSSL 14:167253f4e170 6849
wolfSSL 14:167253f4e170 6850 if (*outLen < 384)
wolfSSL 14:167253f4e170 6851 err = MP_TO_E;
wolfSSL 14:167253f4e170 6852 if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6853 err = MP_READ_E;
wolfSSL 14:167253f4e170 6854
wolfSSL 14:167253f4e170 6855 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6856 sp_3072_from_bin(a, 136, in, inLen);
wolfSSL 14:167253f4e170 6857 sp_3072_from_mp(p, 68, pm);
wolfSSL 14:167253f4e170 6858 sp_3072_from_mp(q, 68, qm);
wolfSSL 14:167253f4e170 6859 sp_3072_from_mp(dp, 68, dpm);
wolfSSL 14:167253f4e170 6860 sp_3072_from_mp(dq, 68, dqm);
wolfSSL 14:167253f4e170 6861 sp_3072_from_mp(qi, 68, qim);
wolfSSL 14:167253f4e170 6862
wolfSSL 14:167253f4e170 6863 err = sp_3072_mod_exp_68(tmpa, a, dp, 1536, p, 1);
wolfSSL 14:167253f4e170 6864 }
wolfSSL 14:167253f4e170 6865 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 6866 err = sp_3072_mod_exp_68(tmpb, a, dq, 1536, q, 1);
wolfSSL 14:167253f4e170 6867
wolfSSL 14:167253f4e170 6868 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6869 sp_3072_sub_68(tmpa, tmpa, tmpb);
wolfSSL 14:167253f4e170 6870 sp_3072_mask_68(tmp, p, tmpa[67] >> 31);
wolfSSL 14:167253f4e170 6871 sp_3072_add_68(tmpa, tmpa, tmp);
wolfSSL 14:167253f4e170 6872 sp_3072_mul_68(tmpa, tmpa, qi);
wolfSSL 14:167253f4e170 6873 err = sp_3072_mod_68(tmpa, tmpa, p);
wolfSSL 14:167253f4e170 6874 }
wolfSSL 14:167253f4e170 6875
wolfSSL 14:167253f4e170 6876 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6877 sp_3072_mul_68(tmpa, tmpa, q);
wolfSSL 14:167253f4e170 6878 sp_3072_add_136(r, tmpb, tmpa);
wolfSSL 14:167253f4e170 6879 sp_3072_norm_136(r);
wolfSSL 14:167253f4e170 6880
wolfSSL 14:167253f4e170 6881 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6882 *outLen = 384;
wolfSSL 14:167253f4e170 6883 }
wolfSSL 14:167253f4e170 6884
wolfSSL 14:167253f4e170 6885 XMEMSET(tmpa, 0, sizeof(tmpa));
wolfSSL 14:167253f4e170 6886 XMEMSET(tmpb, 0, sizeof(tmpb));
wolfSSL 14:167253f4e170 6887 XMEMSET(p, 0, sizeof(p));
wolfSSL 14:167253f4e170 6888 XMEMSET(q, 0, sizeof(q));
wolfSSL 14:167253f4e170 6889 XMEMSET(dp, 0, sizeof(dp));
wolfSSL 14:167253f4e170 6890 XMEMSET(dq, 0, sizeof(dq));
wolfSSL 14:167253f4e170 6891 XMEMSET(qi, 0, sizeof(qi));
wolfSSL 14:167253f4e170 6892
wolfSSL 14:167253f4e170 6893 return err;
wolfSSL 14:167253f4e170 6894 #endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */
wolfSSL 14:167253f4e170 6895 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
wolfSSL 14:167253f4e170 6896 }
wolfSSL 14:167253f4e170 6897
wolfSSL 14:167253f4e170 6898 #endif /* WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 6899 #ifdef WOLFSSL_HAVE_SP_DH
wolfSSL 14:167253f4e170 6900 /* Convert an array of sp_digit to an mp_int.
wolfSSL 14:167253f4e170 6901 *
wolfSSL 14:167253f4e170 6902 * a A single precision integer.
wolfSSL 14:167253f4e170 6903 * r A multi-precision integer.
wolfSSL 14:167253f4e170 6904 */
wolfSSL 14:167253f4e170 6905 static int sp_3072_to_mp(sp_digit* a, mp_int* r)
wolfSSL 14:167253f4e170 6906 {
wolfSSL 14:167253f4e170 6907 int err;
wolfSSL 14:167253f4e170 6908
wolfSSL 14:167253f4e170 6909 err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 14:167253f4e170 6910 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6911 #if DIGIT_BIT == 23
wolfSSL 14:167253f4e170 6912 XMEMCPY(r->dp, a, sizeof(sp_digit) * 136);
wolfSSL 14:167253f4e170 6913 r->used = 136;
wolfSSL 14:167253f4e170 6914 mp_clamp(r);
wolfSSL 14:167253f4e170 6915 #elif DIGIT_BIT < 23
wolfSSL 14:167253f4e170 6916 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 6917
wolfSSL 14:167253f4e170 6918 r->dp[0] = 0;
wolfSSL 14:167253f4e170 6919 for (i = 0; i < 136; i++) {
wolfSSL 14:167253f4e170 6920 r->dp[j] |= a[i] << s;
wolfSSL 14:167253f4e170 6921 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 6922 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 6923 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 6924 while (s + DIGIT_BIT <= 23) {
wolfSSL 14:167253f4e170 6925 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 6926 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 6927 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 6928 }
wolfSSL 14:167253f4e170 6929 s = 23 - s;
wolfSSL 14:167253f4e170 6930 }
wolfSSL 14:167253f4e170 6931 r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 6932 mp_clamp(r);
wolfSSL 14:167253f4e170 6933 #else
wolfSSL 14:167253f4e170 6934 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 6935
wolfSSL 14:167253f4e170 6936 r->dp[0] = 0;
wolfSSL 14:167253f4e170 6937 for (i = 0; i < 136; i++) {
wolfSSL 14:167253f4e170 6938 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 6939 if (s + 23 >= DIGIT_BIT) {
wolfSSL 14:167253f4e170 6940 #if DIGIT_BIT < 32
wolfSSL 14:167253f4e170 6941 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 6942 #endif
wolfSSL 14:167253f4e170 6943 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 6944 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 6945 s = 23 - s;
wolfSSL 14:167253f4e170 6946 }
wolfSSL 14:167253f4e170 6947 else
wolfSSL 14:167253f4e170 6948 s += 23;
wolfSSL 14:167253f4e170 6949 }
wolfSSL 14:167253f4e170 6950 r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 6951 mp_clamp(r);
wolfSSL 14:167253f4e170 6952 #endif
wolfSSL 14:167253f4e170 6953 }
wolfSSL 14:167253f4e170 6954
wolfSSL 14:167253f4e170 6955 return err;
wolfSSL 14:167253f4e170 6956 }
wolfSSL 14:167253f4e170 6957
wolfSSL 14:167253f4e170 6958 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 14:167253f4e170 6959 *
wolfSSL 14:167253f4e170 6960 * base Base. MP integer.
wolfSSL 14:167253f4e170 6961 * exp Exponent. MP integer.
wolfSSL 14:167253f4e170 6962 * mod Modulus. MP integer.
wolfSSL 14:167253f4e170 6963 * res Result. MP integer.
wolfSSL 14:167253f4e170 6964 * returs 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 14:167253f4e170 6965 * and MEMORY_E if memory allocation fails.
wolfSSL 14:167253f4e170 6966 */
wolfSSL 14:167253f4e170 6967 int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)
wolfSSL 14:167253f4e170 6968 {
wolfSSL 14:167253f4e170 6969 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 6970 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6971 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 6972 sp_digit* b;
wolfSSL 14:167253f4e170 6973 sp_digit* e;
wolfSSL 14:167253f4e170 6974 sp_digit* m;
wolfSSL 14:167253f4e170 6975 sp_digit* r;
wolfSSL 14:167253f4e170 6976 int expBits = mp_count_bits(exp);
wolfSSL 14:167253f4e170 6977
wolfSSL 14:167253f4e170 6978 if (mp_count_bits(base) > 3072 || expBits > 3072 ||
wolfSSL 14:167253f4e170 6979 mp_count_bits(mod) != 3072) {
wolfSSL 14:167253f4e170 6980 err = MP_READ_E;
wolfSSL 14:167253f4e170 6981 }
wolfSSL 14:167253f4e170 6982
wolfSSL 14:167253f4e170 6983 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6984 d = (sp_digit*)XMALLOC(sizeof(*d) * 136 * 4, NULL,
wolfSSL 14:167253f4e170 6985 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6986 if (d == NULL)
wolfSSL 14:167253f4e170 6987 err = MEMORY_E;
wolfSSL 14:167253f4e170 6988 }
wolfSSL 14:167253f4e170 6989
wolfSSL 14:167253f4e170 6990 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6991 b = d;
wolfSSL 14:167253f4e170 6992 e = b + 136 * 2;
wolfSSL 14:167253f4e170 6993 m = e + 136;
wolfSSL 14:167253f4e170 6994 r = b;
wolfSSL 14:167253f4e170 6995
wolfSSL 14:167253f4e170 6996 sp_3072_from_mp(b, 136, base);
wolfSSL 14:167253f4e170 6997 sp_3072_from_mp(e, 136, exp);
wolfSSL 14:167253f4e170 6998 sp_3072_from_mp(m, 136, mod);
wolfSSL 14:167253f4e170 6999
wolfSSL 14:167253f4e170 7000 err = sp_3072_mod_exp_136(r, b, e, mp_count_bits(exp), m, 0);
wolfSSL 14:167253f4e170 7001 }
wolfSSL 14:167253f4e170 7002
wolfSSL 14:167253f4e170 7003 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7004 err = sp_3072_to_mp(r, res);
wolfSSL 14:167253f4e170 7005 }
wolfSSL 14:167253f4e170 7006
wolfSSL 14:167253f4e170 7007 if (d != NULL) {
wolfSSL 14:167253f4e170 7008 XMEMSET(e, 0, sizeof(sp_digit) * 136);
wolfSSL 14:167253f4e170 7009 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 7010 }
wolfSSL 14:167253f4e170 7011 return err;
wolfSSL 14:167253f4e170 7012 #else
wolfSSL 14:167253f4e170 7013 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 7014 sp_digit bd[272], ed[136], md[136];
wolfSSL 14:167253f4e170 7015 #else
wolfSSL 14:167253f4e170 7016 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 7017 #endif
wolfSSL 14:167253f4e170 7018 sp_digit* b;
wolfSSL 14:167253f4e170 7019 sp_digit* e;
wolfSSL 14:167253f4e170 7020 sp_digit* m;
wolfSSL 14:167253f4e170 7021 sp_digit* r;
wolfSSL 14:167253f4e170 7022 int err = MP_OKAY;
wolfSSL 14:167253f4e170 7023 int expBits = mp_count_bits(exp);
wolfSSL 14:167253f4e170 7024
wolfSSL 14:167253f4e170 7025 if (mp_count_bits(base) > 3072 || expBits > 3072 ||
wolfSSL 14:167253f4e170 7026 mp_count_bits(mod) != 3072) {
wolfSSL 14:167253f4e170 7027 err = MP_READ_E;
wolfSSL 14:167253f4e170 7028 }
wolfSSL 14:167253f4e170 7029
wolfSSL 14:167253f4e170 7030 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 7031 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7032 d = (sp_digit*)XMALLOC(sizeof(*d) * 136 * 4, NULL,
wolfSSL 14:167253f4e170 7033 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 7034 if (d == NULL)
wolfSSL 14:167253f4e170 7035 err = MEMORY_E;
wolfSSL 14:167253f4e170 7036 }
wolfSSL 14:167253f4e170 7037
wolfSSL 14:167253f4e170 7038 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7039 b = d;
wolfSSL 14:167253f4e170 7040 e = b + 136 * 2;
wolfSSL 14:167253f4e170 7041 m = e + 136;
wolfSSL 14:167253f4e170 7042 r = b;
wolfSSL 14:167253f4e170 7043 }
wolfSSL 14:167253f4e170 7044 #else
wolfSSL 14:167253f4e170 7045 r = b = bd;
wolfSSL 14:167253f4e170 7046 e = ed;
wolfSSL 14:167253f4e170 7047 m = md;
wolfSSL 14:167253f4e170 7048 #endif
wolfSSL 14:167253f4e170 7049
wolfSSL 14:167253f4e170 7050 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7051 sp_3072_from_mp(b, 136, base);
wolfSSL 14:167253f4e170 7052 sp_3072_from_mp(e, 136, exp);
wolfSSL 14:167253f4e170 7053 sp_3072_from_mp(m, 136, mod);
wolfSSL 14:167253f4e170 7054
wolfSSL 14:167253f4e170 7055 err = sp_3072_mod_exp_136(r, b, e, expBits, m, 0);
wolfSSL 14:167253f4e170 7056 }
wolfSSL 14:167253f4e170 7057
wolfSSL 14:167253f4e170 7058 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7059 err = sp_3072_to_mp(r, res);
wolfSSL 14:167253f4e170 7060 }
wolfSSL 14:167253f4e170 7061
wolfSSL 14:167253f4e170 7062 XMEMSET(e, 0, sizeof(sp_digit) * 136);
wolfSSL 14:167253f4e170 7063
wolfSSL 14:167253f4e170 7064 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 7065 if (d != NULL)
wolfSSL 14:167253f4e170 7066 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 7067 #endif
wolfSSL 14:167253f4e170 7068
wolfSSL 14:167253f4e170 7069 return err;
wolfSSL 14:167253f4e170 7070 #endif
wolfSSL 14:167253f4e170 7071 }
wolfSSL 14:167253f4e170 7072
wolfSSL 14:167253f4e170 7073 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 14:167253f4e170 7074 *
wolfSSL 14:167253f4e170 7075 * base Base.
wolfSSL 14:167253f4e170 7076 * exp Array of bytes that is the exponent.
wolfSSL 14:167253f4e170 7077 * expLen Length of data, in bytes, in exponent.
wolfSSL 14:167253f4e170 7078 * mod Modulus.
wolfSSL 14:167253f4e170 7079 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 7080 * Must be at least 384 bytes long.
wolfSSL 14:167253f4e170 7081 * outLen Length, in bytes, of exponentiation result.
wolfSSL 14:167253f4e170 7082 * returs 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 14:167253f4e170 7083 * and MEMORY_E if memory allocation fails.
wolfSSL 14:167253f4e170 7084 */
wolfSSL 14:167253f4e170 7085 int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,
wolfSSL 14:167253f4e170 7086 mp_int* mod, byte* out, word32* outLen)
wolfSSL 14:167253f4e170 7087 {
wolfSSL 14:167253f4e170 7088 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7089 int err = MP_OKAY;
wolfSSL 14:167253f4e170 7090 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 7091 sp_digit* b;
wolfSSL 14:167253f4e170 7092 sp_digit* e;
wolfSSL 14:167253f4e170 7093 sp_digit* m;
wolfSSL 14:167253f4e170 7094 sp_digit* r;
wolfSSL 14:167253f4e170 7095 word32 i;
wolfSSL 14:167253f4e170 7096
wolfSSL 14:167253f4e170 7097 if (mp_count_bits(base) > 3072 || expLen > 384 ||
wolfSSL 14:167253f4e170 7098 mp_count_bits(mod) != 3072) {
wolfSSL 14:167253f4e170 7099 err = MP_READ_E;
wolfSSL 14:167253f4e170 7100 }
wolfSSL 14:167253f4e170 7101
wolfSSL 14:167253f4e170 7102 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7103 d = (sp_digit*)XMALLOC(sizeof(*d) * 136 * 4, NULL,
wolfSSL 14:167253f4e170 7104 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 7105 if (d == NULL)
wolfSSL 14:167253f4e170 7106 err = MEMORY_E;
wolfSSL 14:167253f4e170 7107 }
wolfSSL 14:167253f4e170 7108
wolfSSL 14:167253f4e170 7109 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7110 b = d;
wolfSSL 14:167253f4e170 7111 e = b + 136 * 2;
wolfSSL 14:167253f4e170 7112 m = e + 136;
wolfSSL 14:167253f4e170 7113 r = b;
wolfSSL 14:167253f4e170 7114
wolfSSL 14:167253f4e170 7115 sp_3072_from_mp(b, 136, base);
wolfSSL 14:167253f4e170 7116 sp_3072_from_bin(e, 136, exp, expLen);
wolfSSL 14:167253f4e170 7117 sp_3072_from_mp(m, 136, mod);
wolfSSL 14:167253f4e170 7118
wolfSSL 14:167253f4e170 7119 err = sp_3072_mod_exp_136(r, b, e, expLen * 8, m, 0);
wolfSSL 14:167253f4e170 7120 }
wolfSSL 14:167253f4e170 7121
wolfSSL 14:167253f4e170 7122 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7123 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 7124 *outLen = 384;
wolfSSL 14:167253f4e170 7125 for (i=0; i<384 && out[i] == 0; i++) {
wolfSSL 14:167253f4e170 7126 }
wolfSSL 14:167253f4e170 7127 *outLen -= i;
wolfSSL 14:167253f4e170 7128 XMEMMOVE(out, out + i, *outLen);
wolfSSL 14:167253f4e170 7129 }
wolfSSL 14:167253f4e170 7130
wolfSSL 14:167253f4e170 7131 if (d != NULL) {
wolfSSL 14:167253f4e170 7132 XMEMSET(e, 0, sizeof(sp_digit) * 136);
wolfSSL 14:167253f4e170 7133 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 7134 }
wolfSSL 14:167253f4e170 7135 return err;
wolfSSL 14:167253f4e170 7136 #else
wolfSSL 14:167253f4e170 7137 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 7138 sp_digit bd[272], ed[136], md[136];
wolfSSL 14:167253f4e170 7139 #else
wolfSSL 14:167253f4e170 7140 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 7141 #endif
wolfSSL 14:167253f4e170 7142 sp_digit* b;
wolfSSL 14:167253f4e170 7143 sp_digit* e;
wolfSSL 14:167253f4e170 7144 sp_digit* m;
wolfSSL 14:167253f4e170 7145 sp_digit* r;
wolfSSL 14:167253f4e170 7146 word32 i;
wolfSSL 14:167253f4e170 7147 int err = MP_OKAY;
wolfSSL 14:167253f4e170 7148
wolfSSL 14:167253f4e170 7149 if (mp_count_bits(base) > 3072 || expLen > 384 ||
wolfSSL 14:167253f4e170 7150 mp_count_bits(mod) != 3072) {
wolfSSL 14:167253f4e170 7151 err = MP_READ_E;
wolfSSL 14:167253f4e170 7152 }
wolfSSL 14:167253f4e170 7153
wolfSSL 14:167253f4e170 7154 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 7155 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7156 d = (sp_digit*)XMALLOC(sizeof(*d) * 136 * 4, NULL,
wolfSSL 14:167253f4e170 7157 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 7158 if (d == NULL)
wolfSSL 14:167253f4e170 7159 err = MEMORY_E;
wolfSSL 14:167253f4e170 7160 }
wolfSSL 14:167253f4e170 7161
wolfSSL 14:167253f4e170 7162 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7163 b = d;
wolfSSL 14:167253f4e170 7164 e = b + 136 * 2;
wolfSSL 14:167253f4e170 7165 m = e + 136;
wolfSSL 14:167253f4e170 7166 r = b;
wolfSSL 14:167253f4e170 7167 }
wolfSSL 14:167253f4e170 7168 #else
wolfSSL 14:167253f4e170 7169 r = b = bd;
wolfSSL 14:167253f4e170 7170 e = ed;
wolfSSL 14:167253f4e170 7171 m = md;
wolfSSL 14:167253f4e170 7172 #endif
wolfSSL 14:167253f4e170 7173
wolfSSL 14:167253f4e170 7174 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7175 sp_3072_from_mp(b, 136, base);
wolfSSL 14:167253f4e170 7176 sp_3072_from_bin(e, 136, exp, expLen);
wolfSSL 14:167253f4e170 7177 sp_3072_from_mp(m, 136, mod);
wolfSSL 14:167253f4e170 7178
wolfSSL 14:167253f4e170 7179 err = sp_3072_mod_exp_136(r, b, e, expLen * 8, m, 0);
wolfSSL 14:167253f4e170 7180 }
wolfSSL 14:167253f4e170 7181
wolfSSL 14:167253f4e170 7182 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7183 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 7184 *outLen = 384;
wolfSSL 14:167253f4e170 7185 for (i=0; i<384 && out[i] == 0; i++) {
wolfSSL 14:167253f4e170 7186 }
wolfSSL 14:167253f4e170 7187 *outLen -= i;
wolfSSL 14:167253f4e170 7188 XMEMMOVE(out, out + i, *outLen);
wolfSSL 14:167253f4e170 7189 }
wolfSSL 14:167253f4e170 7190
wolfSSL 14:167253f4e170 7191 XMEMSET(e, 0, sizeof(sp_digit) * 136);
wolfSSL 14:167253f4e170 7192
wolfSSL 14:167253f4e170 7193 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 7194 if (d != NULL)
wolfSSL 14:167253f4e170 7195 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 7196 #endif
wolfSSL 14:167253f4e170 7197
wolfSSL 14:167253f4e170 7198 return err;
wolfSSL 14:167253f4e170 7199 #endif
wolfSSL 14:167253f4e170 7200 }
wolfSSL 14:167253f4e170 7201
wolfSSL 14:167253f4e170 7202 #endif /* WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 7203
wolfSSL 14:167253f4e170 7204 #endif /* WOLFSSL_SP_NO_3072 */
wolfSSL 14:167253f4e170 7205
wolfSSL 14:167253f4e170 7206 #endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 7207 #ifdef WOLFSSL_HAVE_SP_ECC
wolfSSL 14:167253f4e170 7208 #ifndef WOLFSSL_SP_NO_256
wolfSSL 14:167253f4e170 7209
wolfSSL 14:167253f4e170 7210 /* Point structure to use. */
wolfSSL 14:167253f4e170 7211 typedef struct sp_point {
wolfSSL 14:167253f4e170 7212 sp_digit x[2 * 10];
wolfSSL 14:167253f4e170 7213 sp_digit y[2 * 10];
wolfSSL 14:167253f4e170 7214 sp_digit z[2 * 10];
wolfSSL 14:167253f4e170 7215 int infinity;
wolfSSL 14:167253f4e170 7216 } sp_point;
wolfSSL 14:167253f4e170 7217
wolfSSL 14:167253f4e170 7218 /* The modulus (prime) of the curve P256. */
wolfSSL 14:167253f4e170 7219 static sp_digit p256_mod[10] = {
wolfSSL 14:167253f4e170 7220 0x3ffffff,0x3ffffff,0x3ffffff,0x003ffff,0x0000000,0x0000000,0x0000000,
wolfSSL 14:167253f4e170 7221 0x0000400,0x3ff0000,0x03fffff
wolfSSL 14:167253f4e170 7222 };
wolfSSL 14:167253f4e170 7223 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7224 /* The Montogmery normalizer for modulus of the curve P256. */
wolfSSL 14:167253f4e170 7225 static sp_digit p256_norm_mod[10] = {
wolfSSL 14:167253f4e170 7226 0x0000001,0x0000000,0x0000000,0x3fc0000,0x3ffffff,0x3ffffff,0x3ffffff,
wolfSSL 14:167253f4e170 7227 0x3fffbff,0x000ffff,0x0000000
wolfSSL 14:167253f4e170 7228 };
wolfSSL 14:167253f4e170 7229 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7230 /* The Montogmery multiplier for modulus of the curve P256. */
wolfSSL 14:167253f4e170 7231 static sp_digit p256_mp_mod = 0x000001;
wolfSSL 14:167253f4e170 7232 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
wolfSSL 14:167253f4e170 7233 defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 7234 /* The order of the curve P256. */
wolfSSL 14:167253f4e170 7235 static sp_digit p256_order[10] = {
wolfSSL 14:167253f4e170 7236 0x0632551,0x272b0bf,0x1e84f3b,0x2b69c5e,0x3bce6fa,0x3ffffff,0x3ffffff,
wolfSSL 14:167253f4e170 7237 0x00003ff,0x3ff0000,0x03fffff
wolfSSL 14:167253f4e170 7238 };
wolfSSL 14:167253f4e170 7239 #endif
wolfSSL 14:167253f4e170 7240 /* The order of the curve P256 minus 2. */
wolfSSL 14:167253f4e170 7241 static sp_digit p256_order2[10] = {
wolfSSL 14:167253f4e170 7242 0x063254f,0x272b0bf,0x1e84f3b,0x2b69c5e,0x3bce6fa,0x3ffffff,0x3ffffff,
wolfSSL 14:167253f4e170 7243 0x00003ff,0x3ff0000,0x03fffff
wolfSSL 14:167253f4e170 7244 };
wolfSSL 14:167253f4e170 7245 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 7246 /* The Montogmery normalizer for order of the curve P256. */
wolfSSL 14:167253f4e170 7247 static sp_digit p256_norm_order[10] = {
wolfSSL 14:167253f4e170 7248 0x39cdaaf,0x18d4f40,0x217b0c4,0x14963a1,0x0431905,0x0000000,0x0000000,
wolfSSL 14:167253f4e170 7249 0x3fffc00,0x000ffff,0x0000000
wolfSSL 14:167253f4e170 7250 };
wolfSSL 14:167253f4e170 7251 #endif
wolfSSL 14:167253f4e170 7252 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 7253 /* The Montogmery multiplier for order of the curve P256. */
wolfSSL 14:167253f4e170 7254 static sp_digit p256_mp_order = 0x200bc4f;
wolfSSL 14:167253f4e170 7255 #endif
wolfSSL 14:167253f4e170 7256 /* The base point of curve P256. */
wolfSSL 14:167253f4e170 7257 static sp_point p256_base = {
wolfSSL 14:167253f4e170 7258 /* X ordinate */
wolfSSL 14:167253f4e170 7259 {
wolfSSL 14:167253f4e170 7260 0x098c296,0x04e5176,0x33a0f4a,0x204b7ac,0x277037d,0x0e9103c,0x3ce6e56,
wolfSSL 14:167253f4e170 7261 0x1091fe2,0x1f2e12c,0x01ac5f4
wolfSSL 14:167253f4e170 7262 },
wolfSSL 14:167253f4e170 7263 /* Y ordinate */
wolfSSL 14:167253f4e170 7264 {
wolfSSL 14:167253f4e170 7265 0x3bf51f5,0x1901a0d,0x1ececbb,0x15dacc5,0x22bce33,0x303e785,0x27eb4a7,
wolfSSL 14:167253f4e170 7266 0x1fe6e3b,0x2e2fe1a,0x013f8d0
wolfSSL 14:167253f4e170 7267 },
wolfSSL 14:167253f4e170 7268 /* Z ordinate */
wolfSSL 14:167253f4e170 7269 {
wolfSSL 14:167253f4e170 7270 0x0000001,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,
wolfSSL 14:167253f4e170 7271 0x0000000,0x0000000,0x0000000
wolfSSL 14:167253f4e170 7272 },
wolfSSL 14:167253f4e170 7273 /* infinity */
wolfSSL 14:167253f4e170 7274 0
wolfSSL 14:167253f4e170 7275 };
wolfSSL 14:167253f4e170 7276 #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)
wolfSSL 14:167253f4e170 7277 static sp_digit p256_b[10] = {
wolfSSL 14:167253f4e170 7278 0x3d2604b,0x38f0f89,0x30f63bc,0x2c3314e,0x0651d06,0x1a621af,0x2bbd557,
wolfSSL 14:167253f4e170 7279 0x24f9ecf,0x1d8aa3a,0x016b18d
wolfSSL 14:167253f4e170 7280 };
wolfSSL 14:167253f4e170 7281 #endif
wolfSSL 14:167253f4e170 7282
wolfSSL 14:167253f4e170 7283 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 7284 /* Allocate memory for point and return error. */
wolfSSL 14:167253f4e170 7285 #define sp_ecc_point_new(heap, sp, p) \
wolfSSL 14:167253f4e170 7286 ((p = XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC)) == NULL) ? \
wolfSSL 14:167253f4e170 7287 MEMORY_E : MP_OKAY
wolfSSL 14:167253f4e170 7288 #else
wolfSSL 14:167253f4e170 7289 /* Set pointer to data and return no error. */
wolfSSL 14:167253f4e170 7290 #define sp_ecc_point_new(heap, sp, p) ((p = &sp) == NULL) ? MEMORY_E : MP_OKAY
wolfSSL 14:167253f4e170 7291 #endif
wolfSSL 14:167253f4e170 7292
wolfSSL 14:167253f4e170 7293 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 7294 /* If valid pointer then clear point data if requested and free data. */
wolfSSL 14:167253f4e170 7295 #define sp_ecc_point_free(p, clear, heap) \
wolfSSL 14:167253f4e170 7296 do { \
wolfSSL 14:167253f4e170 7297 if (p != NULL) { \
wolfSSL 14:167253f4e170 7298 if (clear) \
wolfSSL 14:167253f4e170 7299 XMEMSET(p, 0, sizeof(*p)); \
wolfSSL 14:167253f4e170 7300 XFREE(p, heap, DYNAMIC_TYPE_ECC); \
wolfSSL 14:167253f4e170 7301 } \
wolfSSL 14:167253f4e170 7302 } \
wolfSSL 14:167253f4e170 7303 while (0)
wolfSSL 14:167253f4e170 7304 #else
wolfSSL 14:167253f4e170 7305 /* Clear point data if requested. */
wolfSSL 14:167253f4e170 7306 #define sp_ecc_point_free(p, clear, heap) \
wolfSSL 14:167253f4e170 7307 do { \
wolfSSL 14:167253f4e170 7308 if (clear) \
wolfSSL 14:167253f4e170 7309 XMEMSET(p, 0, sizeof(*p)); \
wolfSSL 14:167253f4e170 7310 } \
wolfSSL 14:167253f4e170 7311 while (0)
wolfSSL 14:167253f4e170 7312 #endif
wolfSSL 14:167253f4e170 7313
wolfSSL 14:167253f4e170 7314 /* Multiply a number by Montogmery normalizer mod modulus (prime).
wolfSSL 14:167253f4e170 7315 *
wolfSSL 14:167253f4e170 7316 * r The resulting Montgomery form number.
wolfSSL 14:167253f4e170 7317 * a The number to convert.
wolfSSL 14:167253f4e170 7318 * m The modulus (prime).
wolfSSL 14:167253f4e170 7319 * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 7320 */
wolfSSL 14:167253f4e170 7321 static int sp_256_mod_mul_norm_10(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 7322 {
wolfSSL 14:167253f4e170 7323 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 7324 int64_t* td;
wolfSSL 14:167253f4e170 7325 #else
wolfSSL 14:167253f4e170 7326 int64_t td[8];
wolfSSL 14:167253f4e170 7327 int64_t a32d[8];
wolfSSL 14:167253f4e170 7328 #endif
wolfSSL 14:167253f4e170 7329 int64_t* t;
wolfSSL 14:167253f4e170 7330 int64_t* a32;
wolfSSL 14:167253f4e170 7331 int64_t o;
wolfSSL 14:167253f4e170 7332 int err = MP_OKAY;
wolfSSL 14:167253f4e170 7333
wolfSSL 14:167253f4e170 7334 (void)m;
wolfSSL 14:167253f4e170 7335
wolfSSL 14:167253f4e170 7336 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 7337 td = XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 7338 if (td != NULL) {
wolfSSL 14:167253f4e170 7339 t = td;
wolfSSL 14:167253f4e170 7340 a32 = td + 8;
wolfSSL 14:167253f4e170 7341 }
wolfSSL 14:167253f4e170 7342 else
wolfSSL 14:167253f4e170 7343 err = MEMORY_E;
wolfSSL 14:167253f4e170 7344 #else
wolfSSL 14:167253f4e170 7345 t = td;
wolfSSL 14:167253f4e170 7346 a32 = a32d;
wolfSSL 14:167253f4e170 7347 #endif
wolfSSL 14:167253f4e170 7348
wolfSSL 14:167253f4e170 7349 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7350 a32[0] = a[0];
wolfSSL 14:167253f4e170 7351 a32[0] |= a[1] << 26;
wolfSSL 14:167253f4e170 7352 a32[0] &= 0xffffffff;
wolfSSL 14:167253f4e170 7353 a32[1] = (sp_digit)(a[1] >> 6);
wolfSSL 14:167253f4e170 7354 a32[1] |= a[2] << 20;
wolfSSL 14:167253f4e170 7355 a32[1] &= 0xffffffff;
wolfSSL 14:167253f4e170 7356 a32[2] = (sp_digit)(a[2] >> 12);
wolfSSL 14:167253f4e170 7357 a32[2] |= a[3] << 14;
wolfSSL 14:167253f4e170 7358 a32[2] &= 0xffffffff;
wolfSSL 14:167253f4e170 7359 a32[3] = (sp_digit)(a[3] >> 18);
wolfSSL 14:167253f4e170 7360 a32[3] |= a[4] << 8;
wolfSSL 14:167253f4e170 7361 a32[3] &= 0xffffffff;
wolfSSL 14:167253f4e170 7362 a32[4] = (sp_digit)(a[4] >> 24);
wolfSSL 14:167253f4e170 7363 a32[4] |= a[5] << 2;
wolfSSL 14:167253f4e170 7364 a32[4] |= a[6] << 28;
wolfSSL 14:167253f4e170 7365 a32[4] &= 0xffffffff;
wolfSSL 14:167253f4e170 7366 a32[5] = (sp_digit)(a[6] >> 4);
wolfSSL 14:167253f4e170 7367 a32[5] |= a[7] << 22;
wolfSSL 14:167253f4e170 7368 a32[5] &= 0xffffffff;
wolfSSL 14:167253f4e170 7369 a32[6] = (sp_digit)(a[7] >> 10);
wolfSSL 14:167253f4e170 7370 a32[6] |= a[8] << 16;
wolfSSL 14:167253f4e170 7371 a32[6] &= 0xffffffff;
wolfSSL 14:167253f4e170 7372 a32[7] = (sp_digit)(a[8] >> 16);
wolfSSL 14:167253f4e170 7373 a32[7] |= a[9] << 10;
wolfSSL 14:167253f4e170 7374 a32[7] &= 0xffffffff;
wolfSSL 14:167253f4e170 7375
wolfSSL 14:167253f4e170 7376 /* 1 1 0 -1 -1 -1 -1 0 */
wolfSSL 14:167253f4e170 7377 t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6];
wolfSSL 14:167253f4e170 7378 /* 0 1 1 0 -1 -1 -1 -1 */
wolfSSL 14:167253f4e170 7379 t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7];
wolfSSL 14:167253f4e170 7380 /* 0 0 1 1 0 -1 -1 -1 */
wolfSSL 14:167253f4e170 7381 t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7];
wolfSSL 14:167253f4e170 7382 /* -1 -1 0 2 2 1 0 -1 */
wolfSSL 14:167253f4e170 7383 t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7];
wolfSSL 14:167253f4e170 7384 /* 0 -1 -1 0 2 2 1 0 */
wolfSSL 14:167253f4e170 7385 t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6];
wolfSSL 14:167253f4e170 7386 /* 0 0 -1 -1 0 2 2 1 */
wolfSSL 14:167253f4e170 7387 t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7];
wolfSSL 14:167253f4e170 7388 /* -1 -1 0 0 0 1 3 2 */
wolfSSL 14:167253f4e170 7389 t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7];
wolfSSL 14:167253f4e170 7390 /* 1 0 -1 -1 -1 -1 0 3 */
wolfSSL 14:167253f4e170 7391 t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7];
wolfSSL 14:167253f4e170 7392
wolfSSL 14:167253f4e170 7393 t[1] += t[0] >> 32; t[0] &= 0xffffffff;
wolfSSL 14:167253f4e170 7394 t[2] += t[1] >> 32; t[1] &= 0xffffffff;
wolfSSL 14:167253f4e170 7395 t[3] += t[2] >> 32; t[2] &= 0xffffffff;
wolfSSL 14:167253f4e170 7396 t[4] += t[3] >> 32; t[3] &= 0xffffffff;
wolfSSL 14:167253f4e170 7397 t[5] += t[4] >> 32; t[4] &= 0xffffffff;
wolfSSL 14:167253f4e170 7398 t[6] += t[5] >> 32; t[5] &= 0xffffffff;
wolfSSL 14:167253f4e170 7399 t[7] += t[6] >> 32; t[6] &= 0xffffffff;
wolfSSL 14:167253f4e170 7400 o = t[7] >> 32; t[7] &= 0xffffffff;
wolfSSL 14:167253f4e170 7401 t[0] += o;
wolfSSL 14:167253f4e170 7402 t[3] -= o;
wolfSSL 14:167253f4e170 7403 t[6] -= o;
wolfSSL 14:167253f4e170 7404 t[7] += o;
wolfSSL 14:167253f4e170 7405 t[1] += t[0] >> 32; t[0] &= 0xffffffff;
wolfSSL 14:167253f4e170 7406 t[2] += t[1] >> 32; t[1] &= 0xffffffff;
wolfSSL 14:167253f4e170 7407 t[3] += t[2] >> 32; t[2] &= 0xffffffff;
wolfSSL 14:167253f4e170 7408 t[4] += t[3] >> 32; t[3] &= 0xffffffff;
wolfSSL 14:167253f4e170 7409 t[5] += t[4] >> 32; t[4] &= 0xffffffff;
wolfSSL 14:167253f4e170 7410 t[6] += t[5] >> 32; t[5] &= 0xffffffff;
wolfSSL 14:167253f4e170 7411 t[7] += t[6] >> 32; t[6] &= 0xffffffff;
wolfSSL 14:167253f4e170 7412
wolfSSL 14:167253f4e170 7413 r[0] = (sp_digit)(t[0]) & 0x3ffffff;
wolfSSL 14:167253f4e170 7414 r[1] = (sp_digit)(t[0] >> 26);
wolfSSL 14:167253f4e170 7415 r[1] |= t[1] << 6;
wolfSSL 14:167253f4e170 7416 r[1] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7417 r[2] = (sp_digit)(t[1] >> 20);
wolfSSL 14:167253f4e170 7418 r[2] |= t[2] << 12;
wolfSSL 14:167253f4e170 7419 r[2] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7420 r[3] = (sp_digit)(t[2] >> 14);
wolfSSL 14:167253f4e170 7421 r[3] |= t[3] << 18;
wolfSSL 14:167253f4e170 7422 r[3] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7423 r[4] = (sp_digit)(t[3] >> 8);
wolfSSL 14:167253f4e170 7424 r[4] |= t[4] << 24;
wolfSSL 14:167253f4e170 7425 r[4] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7426 r[5] = (sp_digit)(t[4] >> 2) & 0x3ffffff;
wolfSSL 14:167253f4e170 7427 r[6] = (sp_digit)(t[4] >> 28);
wolfSSL 14:167253f4e170 7428 r[6] |= t[5] << 4;
wolfSSL 14:167253f4e170 7429 r[6] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7430 r[7] = (sp_digit)(t[5] >> 22);
wolfSSL 14:167253f4e170 7431 r[7] |= t[6] << 10;
wolfSSL 14:167253f4e170 7432 r[7] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7433 r[8] = (sp_digit)(t[6] >> 16);
wolfSSL 14:167253f4e170 7434 r[8] |= t[7] << 16;
wolfSSL 14:167253f4e170 7435 r[8] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7436 r[9] = (sp_digit)(t[7] >> 10);
wolfSSL 14:167253f4e170 7437 }
wolfSSL 14:167253f4e170 7438
wolfSSL 14:167253f4e170 7439 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 7440 if (td != NULL)
wolfSSL 14:167253f4e170 7441 XFREE(td, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 7442 #endif
wolfSSL 14:167253f4e170 7443
wolfSSL 14:167253f4e170 7444 return err;
wolfSSL 14:167253f4e170 7445 }
wolfSSL 14:167253f4e170 7446
wolfSSL 14:167253f4e170 7447 /* Convert an mp_int to an array of sp_digit.
wolfSSL 14:167253f4e170 7448 *
wolfSSL 14:167253f4e170 7449 * r A single precision integer.
wolfSSL 14:167253f4e170 7450 * a A multi-precision integer.
wolfSSL 14:167253f4e170 7451 */
wolfSSL 14:167253f4e170 7452 static void sp_256_from_mp(sp_digit* r, int max, mp_int* a)
wolfSSL 14:167253f4e170 7453 {
wolfSSL 14:167253f4e170 7454 #if DIGIT_BIT == 26
wolfSSL 14:167253f4e170 7455 int j;
wolfSSL 14:167253f4e170 7456
wolfSSL 14:167253f4e170 7457 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 14:167253f4e170 7458
wolfSSL 14:167253f4e170 7459 for (j = a->used; j < max; j++)
wolfSSL 14:167253f4e170 7460 r[j] = 0;
wolfSSL 14:167253f4e170 7461 #elif DIGIT_BIT > 26
wolfSSL 14:167253f4e170 7462 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 7463
wolfSSL 14:167253f4e170 7464 r[0] = 0;
wolfSSL 14:167253f4e170 7465 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 7466 r[j] |= a->dp[i] << s;
wolfSSL 14:167253f4e170 7467 r[j] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7468 s = 26 - s;
wolfSSL 14:167253f4e170 7469 if (j + 1 >= max)
wolfSSL 14:167253f4e170 7470 break;
wolfSSL 14:167253f4e170 7471 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 7472 while (s + 26 <= DIGIT_BIT) {
wolfSSL 14:167253f4e170 7473 s += 26;
wolfSSL 14:167253f4e170 7474 r[j] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7475 if (j + 1 >= max)
wolfSSL 14:167253f4e170 7476 break;
wolfSSL 14:167253f4e170 7477 if (s < DIGIT_BIT)
wolfSSL 14:167253f4e170 7478 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 7479 else
wolfSSL 14:167253f4e170 7480 r[++j] = 0;
wolfSSL 14:167253f4e170 7481 }
wolfSSL 14:167253f4e170 7482 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 7483 }
wolfSSL 14:167253f4e170 7484
wolfSSL 14:167253f4e170 7485 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 7486 r[j] = 0;
wolfSSL 14:167253f4e170 7487 #else
wolfSSL 14:167253f4e170 7488 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 7489
wolfSSL 14:167253f4e170 7490 r[0] = 0;
wolfSSL 14:167253f4e170 7491 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 7492 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 14:167253f4e170 7493 if (s + DIGIT_BIT >= 26) {
wolfSSL 14:167253f4e170 7494 r[j] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7495 if (j + 1 >= max)
wolfSSL 14:167253f4e170 7496 break;
wolfSSL 14:167253f4e170 7497 s = 26 - s;
wolfSSL 14:167253f4e170 7498 if (s == DIGIT_BIT) {
wolfSSL 14:167253f4e170 7499 r[++j] = 0;
wolfSSL 14:167253f4e170 7500 s = 0;
wolfSSL 14:167253f4e170 7501 }
wolfSSL 14:167253f4e170 7502 else {
wolfSSL 14:167253f4e170 7503 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 7504 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 7505 }
wolfSSL 14:167253f4e170 7506 }
wolfSSL 14:167253f4e170 7507 else
wolfSSL 14:167253f4e170 7508 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 7509 }
wolfSSL 14:167253f4e170 7510
wolfSSL 14:167253f4e170 7511 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 7512 r[j] = 0;
wolfSSL 14:167253f4e170 7513 #endif
wolfSSL 14:167253f4e170 7514 }
wolfSSL 14:167253f4e170 7515
wolfSSL 14:167253f4e170 7516 /* Convert a point of type ecc_point to type sp_point.
wolfSSL 14:167253f4e170 7517 *
wolfSSL 14:167253f4e170 7518 * p Point of type sp_point (result).
wolfSSL 14:167253f4e170 7519 * pm Point of type ecc_point.
wolfSSL 14:167253f4e170 7520 */
wolfSSL 14:167253f4e170 7521 static void sp_256_point_from_ecc_point_10(sp_point* p, ecc_point* pm)
wolfSSL 14:167253f4e170 7522 {
wolfSSL 14:167253f4e170 7523 XMEMSET(p->x, 0, sizeof(p->x));
wolfSSL 14:167253f4e170 7524 XMEMSET(p->y, 0, sizeof(p->y));
wolfSSL 14:167253f4e170 7525 XMEMSET(p->z, 0, sizeof(p->z));
wolfSSL 14:167253f4e170 7526 sp_256_from_mp(p->x, 10, pm->x);
wolfSSL 14:167253f4e170 7527 sp_256_from_mp(p->y, 10, pm->y);
wolfSSL 14:167253f4e170 7528 sp_256_from_mp(p->z, 10, pm->z);
wolfSSL 14:167253f4e170 7529 p->infinity = 0;
wolfSSL 14:167253f4e170 7530 }
wolfSSL 14:167253f4e170 7531
wolfSSL 14:167253f4e170 7532 /* Convert an array of sp_digit to an mp_int.
wolfSSL 14:167253f4e170 7533 *
wolfSSL 14:167253f4e170 7534 * a A single precision integer.
wolfSSL 14:167253f4e170 7535 * r A multi-precision integer.
wolfSSL 14:167253f4e170 7536 */
wolfSSL 14:167253f4e170 7537 static int sp_256_to_mp(sp_digit* a, mp_int* r)
wolfSSL 14:167253f4e170 7538 {
wolfSSL 14:167253f4e170 7539 int err;
wolfSSL 14:167253f4e170 7540
wolfSSL 14:167253f4e170 7541 err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 14:167253f4e170 7542 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7543 #if DIGIT_BIT == 26
wolfSSL 14:167253f4e170 7544 XMEMCPY(r->dp, a, sizeof(sp_digit) * 10);
wolfSSL 14:167253f4e170 7545 r->used = 10;
wolfSSL 14:167253f4e170 7546 mp_clamp(r);
wolfSSL 14:167253f4e170 7547 #elif DIGIT_BIT < 26
wolfSSL 14:167253f4e170 7548 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 7549
wolfSSL 14:167253f4e170 7550 r->dp[0] = 0;
wolfSSL 14:167253f4e170 7551 for (i = 0; i < 10; i++) {
wolfSSL 14:167253f4e170 7552 r->dp[j] |= a[i] << s;
wolfSSL 14:167253f4e170 7553 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 7554 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 7555 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 7556 while (s + DIGIT_BIT <= 26) {
wolfSSL 14:167253f4e170 7557 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 7558 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 7559 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 7560 }
wolfSSL 14:167253f4e170 7561 s = 26 - s;
wolfSSL 14:167253f4e170 7562 }
wolfSSL 14:167253f4e170 7563 r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 7564 mp_clamp(r);
wolfSSL 14:167253f4e170 7565 #else
wolfSSL 14:167253f4e170 7566 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 7567
wolfSSL 14:167253f4e170 7568 r->dp[0] = 0;
wolfSSL 14:167253f4e170 7569 for (i = 0; i < 10; i++) {
wolfSSL 14:167253f4e170 7570 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 7571 if (s + 26 >= DIGIT_BIT) {
wolfSSL 14:167253f4e170 7572 #if DIGIT_BIT < 32
wolfSSL 14:167253f4e170 7573 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 7574 #endif
wolfSSL 14:167253f4e170 7575 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 7576 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 7577 s = 26 - s;
wolfSSL 14:167253f4e170 7578 }
wolfSSL 14:167253f4e170 7579 else
wolfSSL 14:167253f4e170 7580 s += 26;
wolfSSL 14:167253f4e170 7581 }
wolfSSL 14:167253f4e170 7582 r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 7583 mp_clamp(r);
wolfSSL 14:167253f4e170 7584 #endif
wolfSSL 14:167253f4e170 7585 }
wolfSSL 14:167253f4e170 7586
wolfSSL 14:167253f4e170 7587 return err;
wolfSSL 14:167253f4e170 7588 }
wolfSSL 14:167253f4e170 7589
wolfSSL 14:167253f4e170 7590 /* Convert a point of type sp_point to type ecc_point.
wolfSSL 14:167253f4e170 7591 *
wolfSSL 14:167253f4e170 7592 * p Point of type sp_point.
wolfSSL 14:167253f4e170 7593 * pm Point of type ecc_point (result).
wolfSSL 14:167253f4e170 7594 * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
wolfSSL 14:167253f4e170 7595 * MP_OKAY.
wolfSSL 14:167253f4e170 7596 */
wolfSSL 14:167253f4e170 7597 static int sp_256_point_to_ecc_point_10(sp_point* p, ecc_point* pm)
wolfSSL 14:167253f4e170 7598 {
wolfSSL 14:167253f4e170 7599 int err;
wolfSSL 14:167253f4e170 7600
wolfSSL 14:167253f4e170 7601 err = sp_256_to_mp(p->x, pm->x);
wolfSSL 14:167253f4e170 7602 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 7603 err = sp_256_to_mp(p->y, pm->y);
wolfSSL 14:167253f4e170 7604 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 7605 err = sp_256_to_mp(p->z, pm->z);
wolfSSL 14:167253f4e170 7606
wolfSSL 14:167253f4e170 7607 return err;
wolfSSL 14:167253f4e170 7608 }
wolfSSL 14:167253f4e170 7609
wolfSSL 14:167253f4e170 7610 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 7611 *
wolfSSL 14:167253f4e170 7612 * a A single precision integer.
wolfSSL 14:167253f4e170 7613 * b A single precision integer.
wolfSSL 14:167253f4e170 7614 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 7615 * respectively.
wolfSSL 14:167253f4e170 7616 */
wolfSSL 14:167253f4e170 7617 static sp_digit sp_256_cmp_10(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 7618 {
wolfSSL 14:167253f4e170 7619 sp_digit r = 0;
wolfSSL 14:167253f4e170 7620 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7621 int i;
wolfSSL 14:167253f4e170 7622
wolfSSL 14:167253f4e170 7623 for (i=9; i>=0; i--)
wolfSSL 14:167253f4e170 7624 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 7625 #else
wolfSSL 14:167253f4e170 7626 r |= (a[ 9] - b[ 9]) & (0 - !r);
wolfSSL 14:167253f4e170 7627 r |= (a[ 8] - b[ 8]) & (0 - !r);
wolfSSL 14:167253f4e170 7628 r |= (a[ 7] - b[ 7]) & (0 - !r);
wolfSSL 14:167253f4e170 7629 r |= (a[ 6] - b[ 6]) & (0 - !r);
wolfSSL 14:167253f4e170 7630 r |= (a[ 5] - b[ 5]) & (0 - !r);
wolfSSL 14:167253f4e170 7631 r |= (a[ 4] - b[ 4]) & (0 - !r);
wolfSSL 14:167253f4e170 7632 r |= (a[ 3] - b[ 3]) & (0 - !r);
wolfSSL 14:167253f4e170 7633 r |= (a[ 2] - b[ 2]) & (0 - !r);
wolfSSL 14:167253f4e170 7634 r |= (a[ 1] - b[ 1]) & (0 - !r);
wolfSSL 14:167253f4e170 7635 r |= (a[ 0] - b[ 0]) & (0 - !r);
wolfSSL 14:167253f4e170 7636 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7637
wolfSSL 14:167253f4e170 7638 return r;
wolfSSL 14:167253f4e170 7639 }
wolfSSL 14:167253f4e170 7640
wolfSSL 14:167253f4e170 7641 /* Normalize the values in each word to 26.
wolfSSL 14:167253f4e170 7642 *
wolfSSL 14:167253f4e170 7643 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 7644 */
wolfSSL 14:167253f4e170 7645 static void sp_256_norm_10(sp_digit* a)
wolfSSL 14:167253f4e170 7646 {
wolfSSL 14:167253f4e170 7647 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7648 int i;
wolfSSL 14:167253f4e170 7649 for (i = 0; i < 9; i++) {
wolfSSL 14:167253f4e170 7650 a[i+1] += a[i] >> 26;
wolfSSL 14:167253f4e170 7651 a[i] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7652 }
wolfSSL 14:167253f4e170 7653 #else
wolfSSL 14:167253f4e170 7654 a[1] += a[0] >> 26; a[0] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7655 a[2] += a[1] >> 26; a[1] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7656 a[3] += a[2] >> 26; a[2] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7657 a[4] += a[3] >> 26; a[3] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7658 a[5] += a[4] >> 26; a[4] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7659 a[6] += a[5] >> 26; a[5] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7660 a[7] += a[6] >> 26; a[6] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7661 a[8] += a[7] >> 26; a[7] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7662 a[9] += a[8] >> 26; a[8] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7663 #endif
wolfSSL 14:167253f4e170 7664 }
wolfSSL 14:167253f4e170 7665
wolfSSL 14:167253f4e170 7666 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 7667 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 7668 *
wolfSSL 14:167253f4e170 7669 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 7670 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 7671 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 7672 * m Mask value to apply.
wolfSSL 14:167253f4e170 7673 */
wolfSSL 14:167253f4e170 7674 static void sp_256_cond_sub_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7675 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 7676 {
wolfSSL 14:167253f4e170 7677 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7678 int i;
wolfSSL 14:167253f4e170 7679
wolfSSL 14:167253f4e170 7680 for (i = 0; i < 10; i++)
wolfSSL 14:167253f4e170 7681 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 7682 #else
wolfSSL 14:167253f4e170 7683 r[ 0] = a[ 0] - (b[ 0] & m);
wolfSSL 14:167253f4e170 7684 r[ 1] = a[ 1] - (b[ 1] & m);
wolfSSL 14:167253f4e170 7685 r[ 2] = a[ 2] - (b[ 2] & m);
wolfSSL 14:167253f4e170 7686 r[ 3] = a[ 3] - (b[ 3] & m);
wolfSSL 14:167253f4e170 7687 r[ 4] = a[ 4] - (b[ 4] & m);
wolfSSL 14:167253f4e170 7688 r[ 5] = a[ 5] - (b[ 5] & m);
wolfSSL 14:167253f4e170 7689 r[ 6] = a[ 6] - (b[ 6] & m);
wolfSSL 14:167253f4e170 7690 r[ 7] = a[ 7] - (b[ 7] & m);
wolfSSL 14:167253f4e170 7691 r[ 8] = a[ 8] - (b[ 8] & m);
wolfSSL 14:167253f4e170 7692 r[ 9] = a[ 9] - (b[ 9] & m);
wolfSSL 14:167253f4e170 7693 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7694 }
wolfSSL 14:167253f4e170 7695
wolfSSL 14:167253f4e170 7696 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 7697 *
wolfSSL 14:167253f4e170 7698 * r A single precision integer.
wolfSSL 14:167253f4e170 7699 * a A single precision integer.
wolfSSL 14:167253f4e170 7700 * b A scalar.
wolfSSL 14:167253f4e170 7701 */
wolfSSL 14:167253f4e170 7702 SP_NOINLINE static void sp_256_mul_add_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7703 const sp_digit b)
wolfSSL 14:167253f4e170 7704 {
wolfSSL 14:167253f4e170 7705 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7706 int64_t tb = b;
wolfSSL 14:167253f4e170 7707 int64_t t = 0;
wolfSSL 14:167253f4e170 7708 int i;
wolfSSL 14:167253f4e170 7709
wolfSSL 14:167253f4e170 7710 for (i = 0; i < 10; i++) {
wolfSSL 14:167253f4e170 7711 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 7712 r[i] = t & 0x3ffffff;
wolfSSL 14:167253f4e170 7713 t >>= 26;
wolfSSL 14:167253f4e170 7714 }
wolfSSL 14:167253f4e170 7715 r[10] += t;
wolfSSL 14:167253f4e170 7716 #else
wolfSSL 14:167253f4e170 7717 int64_t tb = b;
wolfSSL 14:167253f4e170 7718 int64_t t[10];
wolfSSL 14:167253f4e170 7719
wolfSSL 14:167253f4e170 7720 t[ 0] = tb * a[ 0];
wolfSSL 14:167253f4e170 7721 t[ 1] = tb * a[ 1];
wolfSSL 14:167253f4e170 7722 t[ 2] = tb * a[ 2];
wolfSSL 14:167253f4e170 7723 t[ 3] = tb * a[ 3];
wolfSSL 14:167253f4e170 7724 t[ 4] = tb * a[ 4];
wolfSSL 14:167253f4e170 7725 t[ 5] = tb * a[ 5];
wolfSSL 14:167253f4e170 7726 t[ 6] = tb * a[ 6];
wolfSSL 14:167253f4e170 7727 t[ 7] = tb * a[ 7];
wolfSSL 14:167253f4e170 7728 t[ 8] = tb * a[ 8];
wolfSSL 14:167253f4e170 7729 t[ 9] = tb * a[ 9];
wolfSSL 14:167253f4e170 7730 r[ 0] += (t[ 0] & 0x3ffffff);
wolfSSL 14:167253f4e170 7731 r[ 1] += (t[ 0] >> 26) + (t[ 1] & 0x3ffffff);
wolfSSL 14:167253f4e170 7732 r[ 2] += (t[ 1] >> 26) + (t[ 2] & 0x3ffffff);
wolfSSL 14:167253f4e170 7733 r[ 3] += (t[ 2] >> 26) + (t[ 3] & 0x3ffffff);
wolfSSL 14:167253f4e170 7734 r[ 4] += (t[ 3] >> 26) + (t[ 4] & 0x3ffffff);
wolfSSL 14:167253f4e170 7735 r[ 5] += (t[ 4] >> 26) + (t[ 5] & 0x3ffffff);
wolfSSL 14:167253f4e170 7736 r[ 6] += (t[ 5] >> 26) + (t[ 6] & 0x3ffffff);
wolfSSL 14:167253f4e170 7737 r[ 7] += (t[ 6] >> 26) + (t[ 7] & 0x3ffffff);
wolfSSL 14:167253f4e170 7738 r[ 8] += (t[ 7] >> 26) + (t[ 8] & 0x3ffffff);
wolfSSL 14:167253f4e170 7739 r[ 9] += (t[ 8] >> 26) + (t[ 9] & 0x3ffffff);
wolfSSL 14:167253f4e170 7740 r[10] += t[ 9] >> 26;
wolfSSL 14:167253f4e170 7741 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7742 }
wolfSSL 14:167253f4e170 7743
wolfSSL 14:167253f4e170 7744 /* Shift the result in the high 256 bits down to the bottom.
wolfSSL 14:167253f4e170 7745 *
wolfSSL 14:167253f4e170 7746 * r A single precision number.
wolfSSL 14:167253f4e170 7747 * a A single precision number.
wolfSSL 14:167253f4e170 7748 */
wolfSSL 14:167253f4e170 7749 static void sp_256_mont_shift_10(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 7750 {
wolfSSL 14:167253f4e170 7751 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7752 int i;
wolfSSL 14:167253f4e170 7753 sp_digit n, s;
wolfSSL 14:167253f4e170 7754
wolfSSL 14:167253f4e170 7755 s = a[10];
wolfSSL 14:167253f4e170 7756 n = a[9] >> 22;
wolfSSL 14:167253f4e170 7757 for (i = 0; i < 9; i++) {
wolfSSL 14:167253f4e170 7758 n += (s & 0x3ffffff) << 4;
wolfSSL 14:167253f4e170 7759 r[i] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7760 n >>= 26;
wolfSSL 14:167253f4e170 7761 s = a[11 + i] + (s >> 26);
wolfSSL 14:167253f4e170 7762 }
wolfSSL 14:167253f4e170 7763 n += s << 4;
wolfSSL 14:167253f4e170 7764 r[9] = n;
wolfSSL 14:167253f4e170 7765 #else
wolfSSL 14:167253f4e170 7766 sp_digit n, s;
wolfSSL 14:167253f4e170 7767
wolfSSL 14:167253f4e170 7768 s = a[10]; n = a[9] >> 22;
wolfSSL 14:167253f4e170 7769 n += (s & 0x3ffffff) << 4; r[ 0] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7770 n >>= 26; s = a[11] + (s >> 26);
wolfSSL 14:167253f4e170 7771 n += (s & 0x3ffffff) << 4; r[ 1] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7772 n >>= 26; s = a[12] + (s >> 26);
wolfSSL 14:167253f4e170 7773 n += (s & 0x3ffffff) << 4; r[ 2] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7774 n >>= 26; s = a[13] + (s >> 26);
wolfSSL 14:167253f4e170 7775 n += (s & 0x3ffffff) << 4; r[ 3] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7776 n >>= 26; s = a[14] + (s >> 26);
wolfSSL 14:167253f4e170 7777 n += (s & 0x3ffffff) << 4; r[ 4] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7778 n >>= 26; s = a[15] + (s >> 26);
wolfSSL 14:167253f4e170 7779 n += (s & 0x3ffffff) << 4; r[ 5] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7780 n >>= 26; s = a[16] + (s >> 26);
wolfSSL 14:167253f4e170 7781 n += (s & 0x3ffffff) << 4; r[ 6] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7782 n >>= 26; s = a[17] + (s >> 26);
wolfSSL 14:167253f4e170 7783 n += (s & 0x3ffffff) << 4; r[ 7] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7784 n >>= 26; s = a[18] + (s >> 26);
wolfSSL 14:167253f4e170 7785 n += (s & 0x3ffffff) << 4; r[ 8] = n & 0x3ffffff;
wolfSSL 14:167253f4e170 7786 n >>= 26; s = a[19] + (s >> 26);
wolfSSL 14:167253f4e170 7787 n += s << 4; r[ 9] = n;
wolfSSL 14:167253f4e170 7788 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7789 XMEMSET(&r[10], 0, sizeof(*r) * 10);
wolfSSL 14:167253f4e170 7790 }
wolfSSL 14:167253f4e170 7791
wolfSSL 14:167253f4e170 7792 /* Reduce the number back to 256 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 7793 *
wolfSSL 14:167253f4e170 7794 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 7795 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 7796 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 7797 */
wolfSSL 14:167253f4e170 7798 static void sp_256_mont_reduce_10(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 7799 {
wolfSSL 14:167253f4e170 7800 int i;
wolfSSL 14:167253f4e170 7801 sp_digit mu;
wolfSSL 14:167253f4e170 7802
wolfSSL 14:167253f4e170 7803 if (mp != 1) {
wolfSSL 14:167253f4e170 7804 for (i=0; i<9; i++) {
wolfSSL 14:167253f4e170 7805 mu = (a[i] * mp) & 0x3ffffff;
wolfSSL 14:167253f4e170 7806 sp_256_mul_add_10(a+i, m, mu);
wolfSSL 14:167253f4e170 7807 a[i+1] += a[i] >> 26;
wolfSSL 14:167253f4e170 7808 }
wolfSSL 14:167253f4e170 7809 mu = (a[i] * mp) & 0x3fffffl;
wolfSSL 14:167253f4e170 7810 sp_256_mul_add_10(a+i, m, mu);
wolfSSL 14:167253f4e170 7811 a[i+1] += a[i] >> 26;
wolfSSL 14:167253f4e170 7812 a[i] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7813 }
wolfSSL 14:167253f4e170 7814 else {
wolfSSL 14:167253f4e170 7815 for (i=0; i<9; i++) {
wolfSSL 14:167253f4e170 7816 mu = a[i] & 0x3ffffff;
wolfSSL 14:167253f4e170 7817 sp_256_mul_add_10(a+i, p256_mod, mu);
wolfSSL 14:167253f4e170 7818 a[i+1] += a[i] >> 26;
wolfSSL 14:167253f4e170 7819 }
wolfSSL 14:167253f4e170 7820 mu = a[i] & 0x3fffffl;
wolfSSL 14:167253f4e170 7821 sp_256_mul_add_10(a+i, p256_mod, mu);
wolfSSL 14:167253f4e170 7822 a[i+1] += a[i] >> 26;
wolfSSL 14:167253f4e170 7823 a[i] &= 0x3ffffff;
wolfSSL 14:167253f4e170 7824 }
wolfSSL 14:167253f4e170 7825
wolfSSL 14:167253f4e170 7826 sp_256_mont_shift_10(a, a);
wolfSSL 14:167253f4e170 7827 sp_256_cond_sub_10(a, a, m, 0 - ((a[9] >> 22) > 0));
wolfSSL 14:167253f4e170 7828 sp_256_norm_10(a);
wolfSSL 14:167253f4e170 7829 }
wolfSSL 14:167253f4e170 7830
wolfSSL 14:167253f4e170 7831 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7832 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 7833 *
wolfSSL 14:167253f4e170 7834 * r A single precision integer.
wolfSSL 14:167253f4e170 7835 * a A single precision integer.
wolfSSL 14:167253f4e170 7836 * b A single precision integer.
wolfSSL 14:167253f4e170 7837 */
wolfSSL 14:167253f4e170 7838 SP_NOINLINE static void sp_256_mul_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7839 const sp_digit* b)
wolfSSL 14:167253f4e170 7840 {
wolfSSL 14:167253f4e170 7841 int i, j, k;
wolfSSL 14:167253f4e170 7842 int64_t c;
wolfSSL 14:167253f4e170 7843
wolfSSL 14:167253f4e170 7844 c = ((int64_t)a[9]) * b[9];
wolfSSL 14:167253f4e170 7845 r[19] = (sp_digit)(c >> 26);
wolfSSL 14:167253f4e170 7846 c = (c & 0x3ffffff) << 26;
wolfSSL 14:167253f4e170 7847 for (k = 17; k >= 0; k--) {
wolfSSL 14:167253f4e170 7848 for (i = 9; i >= 0; i--) {
wolfSSL 14:167253f4e170 7849 j = k - i;
wolfSSL 14:167253f4e170 7850 if (j >= 10)
wolfSSL 14:167253f4e170 7851 break;
wolfSSL 14:167253f4e170 7852 if (j < 0)
wolfSSL 14:167253f4e170 7853 continue;
wolfSSL 14:167253f4e170 7854
wolfSSL 14:167253f4e170 7855 c += ((int64_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 7856 }
wolfSSL 14:167253f4e170 7857 r[k + 2] += c >> 52;
wolfSSL 14:167253f4e170 7858 r[k + 1] = (c >> 26) & 0x3ffffff;
wolfSSL 14:167253f4e170 7859 c = (c & 0x3ffffff) << 26;
wolfSSL 14:167253f4e170 7860 }
wolfSSL 14:167253f4e170 7861 r[0] = (sp_digit)(c >> 26);
wolfSSL 14:167253f4e170 7862 }
wolfSSL 14:167253f4e170 7863
wolfSSL 14:167253f4e170 7864 #else
wolfSSL 14:167253f4e170 7865 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 7866 *
wolfSSL 14:167253f4e170 7867 * r A single precision integer.
wolfSSL 14:167253f4e170 7868 * a A single precision integer.
wolfSSL 14:167253f4e170 7869 * b A single precision integer.
wolfSSL 14:167253f4e170 7870 */
wolfSSL 14:167253f4e170 7871 SP_NOINLINE static void sp_256_mul_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7872 const sp_digit* b)
wolfSSL 14:167253f4e170 7873 {
wolfSSL 14:167253f4e170 7874 int64_t t0 = ((int64_t)a[ 0]) * b[ 0];
wolfSSL 14:167253f4e170 7875 int64_t t1 = ((int64_t)a[ 0]) * b[ 1]
wolfSSL 14:167253f4e170 7876 + ((int64_t)a[ 1]) * b[ 0];
wolfSSL 14:167253f4e170 7877 int64_t t2 = ((int64_t)a[ 0]) * b[ 2]
wolfSSL 14:167253f4e170 7878 + ((int64_t)a[ 1]) * b[ 1]
wolfSSL 14:167253f4e170 7879 + ((int64_t)a[ 2]) * b[ 0];
wolfSSL 14:167253f4e170 7880 int64_t t3 = ((int64_t)a[ 0]) * b[ 3]
wolfSSL 14:167253f4e170 7881 + ((int64_t)a[ 1]) * b[ 2]
wolfSSL 14:167253f4e170 7882 + ((int64_t)a[ 2]) * b[ 1]
wolfSSL 14:167253f4e170 7883 + ((int64_t)a[ 3]) * b[ 0];
wolfSSL 14:167253f4e170 7884 int64_t t4 = ((int64_t)a[ 0]) * b[ 4]
wolfSSL 14:167253f4e170 7885 + ((int64_t)a[ 1]) * b[ 3]
wolfSSL 14:167253f4e170 7886 + ((int64_t)a[ 2]) * b[ 2]
wolfSSL 14:167253f4e170 7887 + ((int64_t)a[ 3]) * b[ 1]
wolfSSL 14:167253f4e170 7888 + ((int64_t)a[ 4]) * b[ 0];
wolfSSL 14:167253f4e170 7889 int64_t t5 = ((int64_t)a[ 0]) * b[ 5]
wolfSSL 14:167253f4e170 7890 + ((int64_t)a[ 1]) * b[ 4]
wolfSSL 14:167253f4e170 7891 + ((int64_t)a[ 2]) * b[ 3]
wolfSSL 14:167253f4e170 7892 + ((int64_t)a[ 3]) * b[ 2]
wolfSSL 14:167253f4e170 7893 + ((int64_t)a[ 4]) * b[ 1]
wolfSSL 14:167253f4e170 7894 + ((int64_t)a[ 5]) * b[ 0];
wolfSSL 14:167253f4e170 7895 int64_t t6 = ((int64_t)a[ 0]) * b[ 6]
wolfSSL 14:167253f4e170 7896 + ((int64_t)a[ 1]) * b[ 5]
wolfSSL 14:167253f4e170 7897 + ((int64_t)a[ 2]) * b[ 4]
wolfSSL 14:167253f4e170 7898 + ((int64_t)a[ 3]) * b[ 3]
wolfSSL 14:167253f4e170 7899 + ((int64_t)a[ 4]) * b[ 2]
wolfSSL 14:167253f4e170 7900 + ((int64_t)a[ 5]) * b[ 1]
wolfSSL 14:167253f4e170 7901 + ((int64_t)a[ 6]) * b[ 0];
wolfSSL 14:167253f4e170 7902 int64_t t7 = ((int64_t)a[ 0]) * b[ 7]
wolfSSL 14:167253f4e170 7903 + ((int64_t)a[ 1]) * b[ 6]
wolfSSL 14:167253f4e170 7904 + ((int64_t)a[ 2]) * b[ 5]
wolfSSL 14:167253f4e170 7905 + ((int64_t)a[ 3]) * b[ 4]
wolfSSL 14:167253f4e170 7906 + ((int64_t)a[ 4]) * b[ 3]
wolfSSL 14:167253f4e170 7907 + ((int64_t)a[ 5]) * b[ 2]
wolfSSL 14:167253f4e170 7908 + ((int64_t)a[ 6]) * b[ 1]
wolfSSL 14:167253f4e170 7909 + ((int64_t)a[ 7]) * b[ 0];
wolfSSL 14:167253f4e170 7910 int64_t t8 = ((int64_t)a[ 0]) * b[ 8]
wolfSSL 14:167253f4e170 7911 + ((int64_t)a[ 1]) * b[ 7]
wolfSSL 14:167253f4e170 7912 + ((int64_t)a[ 2]) * b[ 6]
wolfSSL 14:167253f4e170 7913 + ((int64_t)a[ 3]) * b[ 5]
wolfSSL 14:167253f4e170 7914 + ((int64_t)a[ 4]) * b[ 4]
wolfSSL 14:167253f4e170 7915 + ((int64_t)a[ 5]) * b[ 3]
wolfSSL 14:167253f4e170 7916 + ((int64_t)a[ 6]) * b[ 2]
wolfSSL 14:167253f4e170 7917 + ((int64_t)a[ 7]) * b[ 1]
wolfSSL 14:167253f4e170 7918 + ((int64_t)a[ 8]) * b[ 0];
wolfSSL 14:167253f4e170 7919 int64_t t9 = ((int64_t)a[ 0]) * b[ 9]
wolfSSL 14:167253f4e170 7920 + ((int64_t)a[ 1]) * b[ 8]
wolfSSL 14:167253f4e170 7921 + ((int64_t)a[ 2]) * b[ 7]
wolfSSL 14:167253f4e170 7922 + ((int64_t)a[ 3]) * b[ 6]
wolfSSL 14:167253f4e170 7923 + ((int64_t)a[ 4]) * b[ 5]
wolfSSL 14:167253f4e170 7924 + ((int64_t)a[ 5]) * b[ 4]
wolfSSL 14:167253f4e170 7925 + ((int64_t)a[ 6]) * b[ 3]
wolfSSL 14:167253f4e170 7926 + ((int64_t)a[ 7]) * b[ 2]
wolfSSL 14:167253f4e170 7927 + ((int64_t)a[ 8]) * b[ 1]
wolfSSL 14:167253f4e170 7928 + ((int64_t)a[ 9]) * b[ 0];
wolfSSL 14:167253f4e170 7929 int64_t t10 = ((int64_t)a[ 1]) * b[ 9]
wolfSSL 14:167253f4e170 7930 + ((int64_t)a[ 2]) * b[ 8]
wolfSSL 14:167253f4e170 7931 + ((int64_t)a[ 3]) * b[ 7]
wolfSSL 14:167253f4e170 7932 + ((int64_t)a[ 4]) * b[ 6]
wolfSSL 14:167253f4e170 7933 + ((int64_t)a[ 5]) * b[ 5]
wolfSSL 14:167253f4e170 7934 + ((int64_t)a[ 6]) * b[ 4]
wolfSSL 14:167253f4e170 7935 + ((int64_t)a[ 7]) * b[ 3]
wolfSSL 14:167253f4e170 7936 + ((int64_t)a[ 8]) * b[ 2]
wolfSSL 14:167253f4e170 7937 + ((int64_t)a[ 9]) * b[ 1];
wolfSSL 14:167253f4e170 7938 int64_t t11 = ((int64_t)a[ 2]) * b[ 9]
wolfSSL 14:167253f4e170 7939 + ((int64_t)a[ 3]) * b[ 8]
wolfSSL 14:167253f4e170 7940 + ((int64_t)a[ 4]) * b[ 7]
wolfSSL 14:167253f4e170 7941 + ((int64_t)a[ 5]) * b[ 6]
wolfSSL 14:167253f4e170 7942 + ((int64_t)a[ 6]) * b[ 5]
wolfSSL 14:167253f4e170 7943 + ((int64_t)a[ 7]) * b[ 4]
wolfSSL 14:167253f4e170 7944 + ((int64_t)a[ 8]) * b[ 3]
wolfSSL 14:167253f4e170 7945 + ((int64_t)a[ 9]) * b[ 2];
wolfSSL 14:167253f4e170 7946 int64_t t12 = ((int64_t)a[ 3]) * b[ 9]
wolfSSL 14:167253f4e170 7947 + ((int64_t)a[ 4]) * b[ 8]
wolfSSL 14:167253f4e170 7948 + ((int64_t)a[ 5]) * b[ 7]
wolfSSL 14:167253f4e170 7949 + ((int64_t)a[ 6]) * b[ 6]
wolfSSL 14:167253f4e170 7950 + ((int64_t)a[ 7]) * b[ 5]
wolfSSL 14:167253f4e170 7951 + ((int64_t)a[ 8]) * b[ 4]
wolfSSL 14:167253f4e170 7952 + ((int64_t)a[ 9]) * b[ 3];
wolfSSL 14:167253f4e170 7953 int64_t t13 = ((int64_t)a[ 4]) * b[ 9]
wolfSSL 14:167253f4e170 7954 + ((int64_t)a[ 5]) * b[ 8]
wolfSSL 14:167253f4e170 7955 + ((int64_t)a[ 6]) * b[ 7]
wolfSSL 14:167253f4e170 7956 + ((int64_t)a[ 7]) * b[ 6]
wolfSSL 14:167253f4e170 7957 + ((int64_t)a[ 8]) * b[ 5]
wolfSSL 14:167253f4e170 7958 + ((int64_t)a[ 9]) * b[ 4];
wolfSSL 14:167253f4e170 7959 int64_t t14 = ((int64_t)a[ 5]) * b[ 9]
wolfSSL 14:167253f4e170 7960 + ((int64_t)a[ 6]) * b[ 8]
wolfSSL 14:167253f4e170 7961 + ((int64_t)a[ 7]) * b[ 7]
wolfSSL 14:167253f4e170 7962 + ((int64_t)a[ 8]) * b[ 6]
wolfSSL 14:167253f4e170 7963 + ((int64_t)a[ 9]) * b[ 5];
wolfSSL 14:167253f4e170 7964 int64_t t15 = ((int64_t)a[ 6]) * b[ 9]
wolfSSL 14:167253f4e170 7965 + ((int64_t)a[ 7]) * b[ 8]
wolfSSL 14:167253f4e170 7966 + ((int64_t)a[ 8]) * b[ 7]
wolfSSL 14:167253f4e170 7967 + ((int64_t)a[ 9]) * b[ 6];
wolfSSL 14:167253f4e170 7968 int64_t t16 = ((int64_t)a[ 7]) * b[ 9]
wolfSSL 14:167253f4e170 7969 + ((int64_t)a[ 8]) * b[ 8]
wolfSSL 14:167253f4e170 7970 + ((int64_t)a[ 9]) * b[ 7];
wolfSSL 14:167253f4e170 7971 int64_t t17 = ((int64_t)a[ 8]) * b[ 9]
wolfSSL 14:167253f4e170 7972 + ((int64_t)a[ 9]) * b[ 8];
wolfSSL 14:167253f4e170 7973 int64_t t18 = ((int64_t)a[ 9]) * b[ 9];
wolfSSL 14:167253f4e170 7974
wolfSSL 14:167253f4e170 7975 t1 += t0 >> 26; r[ 0] = t0 & 0x3ffffff;
wolfSSL 14:167253f4e170 7976 t2 += t1 >> 26; r[ 1] = t1 & 0x3ffffff;
wolfSSL 14:167253f4e170 7977 t3 += t2 >> 26; r[ 2] = t2 & 0x3ffffff;
wolfSSL 14:167253f4e170 7978 t4 += t3 >> 26; r[ 3] = t3 & 0x3ffffff;
wolfSSL 14:167253f4e170 7979 t5 += t4 >> 26; r[ 4] = t4 & 0x3ffffff;
wolfSSL 14:167253f4e170 7980 t6 += t5 >> 26; r[ 5] = t5 & 0x3ffffff;
wolfSSL 14:167253f4e170 7981 t7 += t6 >> 26; r[ 6] = t6 & 0x3ffffff;
wolfSSL 14:167253f4e170 7982 t8 += t7 >> 26; r[ 7] = t7 & 0x3ffffff;
wolfSSL 14:167253f4e170 7983 t9 += t8 >> 26; r[ 8] = t8 & 0x3ffffff;
wolfSSL 14:167253f4e170 7984 t10 += t9 >> 26; r[ 9] = t9 & 0x3ffffff;
wolfSSL 14:167253f4e170 7985 t11 += t10 >> 26; r[10] = t10 & 0x3ffffff;
wolfSSL 14:167253f4e170 7986 t12 += t11 >> 26; r[11] = t11 & 0x3ffffff;
wolfSSL 14:167253f4e170 7987 t13 += t12 >> 26; r[12] = t12 & 0x3ffffff;
wolfSSL 14:167253f4e170 7988 t14 += t13 >> 26; r[13] = t13 & 0x3ffffff;
wolfSSL 14:167253f4e170 7989 t15 += t14 >> 26; r[14] = t14 & 0x3ffffff;
wolfSSL 14:167253f4e170 7990 t16 += t15 >> 26; r[15] = t15 & 0x3ffffff;
wolfSSL 14:167253f4e170 7991 t17 += t16 >> 26; r[16] = t16 & 0x3ffffff;
wolfSSL 14:167253f4e170 7992 t18 += t17 >> 26; r[17] = t17 & 0x3ffffff;
wolfSSL 14:167253f4e170 7993 r[19] = (sp_digit)(t18 >> 26);
wolfSSL 14:167253f4e170 7994 r[18] = t18 & 0x3ffffff;
wolfSSL 14:167253f4e170 7995 }
wolfSSL 14:167253f4e170 7996
wolfSSL 14:167253f4e170 7997 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7998 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 7999 * (r = a * b mod m)
wolfSSL 14:167253f4e170 8000 *
wolfSSL 14:167253f4e170 8001 * r Result of multiplication.
wolfSSL 14:167253f4e170 8002 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 8003 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 8004 * m Modulus (prime).
wolfSSL 14:167253f4e170 8005 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 8006 */
wolfSSL 14:167253f4e170 8007 static void sp_256_mont_mul_10(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 8008 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 8009 {
wolfSSL 14:167253f4e170 8010 sp_256_mul_10(r, a, b);
wolfSSL 14:167253f4e170 8011 sp_256_mont_reduce_10(r, m, mp);
wolfSSL 14:167253f4e170 8012 }
wolfSSL 14:167253f4e170 8013
wolfSSL 14:167253f4e170 8014 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 8015 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 8016 *
wolfSSL 14:167253f4e170 8017 * r A single precision integer.
wolfSSL 14:167253f4e170 8018 * a A single precision integer.
wolfSSL 14:167253f4e170 8019 */
wolfSSL 14:167253f4e170 8020 SP_NOINLINE static void sp_256_sqr_10(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 8021 {
wolfSSL 14:167253f4e170 8022 int i, j, k;
wolfSSL 14:167253f4e170 8023 int64_t c;
wolfSSL 14:167253f4e170 8024
wolfSSL 14:167253f4e170 8025 c = ((int64_t)a[9]) * a[9];
wolfSSL 14:167253f4e170 8026 r[19] = (sp_digit)(c >> 26);
wolfSSL 14:167253f4e170 8027 c = (c & 0x3ffffff) << 26;
wolfSSL 14:167253f4e170 8028 for (k = 17; k >= 0; k--) {
wolfSSL 14:167253f4e170 8029 for (i = 9; i >= 0; i--) {
wolfSSL 14:167253f4e170 8030 j = k - i;
wolfSSL 14:167253f4e170 8031 if (j >= 10 || i <= j)
wolfSSL 14:167253f4e170 8032 break;
wolfSSL 14:167253f4e170 8033 if (j < 0)
wolfSSL 14:167253f4e170 8034 continue;
wolfSSL 14:167253f4e170 8035
wolfSSL 14:167253f4e170 8036 c += ((int64_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 8037 }
wolfSSL 14:167253f4e170 8038 if (i == j)
wolfSSL 14:167253f4e170 8039 c += ((int64_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 8040
wolfSSL 14:167253f4e170 8041 r[k + 2] += c >> 52;
wolfSSL 14:167253f4e170 8042 r[k + 1] = (c >> 26) & 0x3ffffff;
wolfSSL 14:167253f4e170 8043 c = (c & 0x3ffffff) << 26;
wolfSSL 14:167253f4e170 8044 }
wolfSSL 14:167253f4e170 8045 r[0] = (sp_digit)(c >> 26);
wolfSSL 14:167253f4e170 8046 }
wolfSSL 14:167253f4e170 8047
wolfSSL 14:167253f4e170 8048 #else
wolfSSL 14:167253f4e170 8049 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 8050 *
wolfSSL 14:167253f4e170 8051 * r A single precision integer.
wolfSSL 14:167253f4e170 8052 * a A single precision integer.
wolfSSL 14:167253f4e170 8053 */
wolfSSL 14:167253f4e170 8054 SP_NOINLINE static void sp_256_sqr_10(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 8055 {
wolfSSL 14:167253f4e170 8056 int64_t t0 = ((int64_t)a[ 0]) * a[ 0];
wolfSSL 14:167253f4e170 8057 int64_t t1 = (((int64_t)a[ 0]) * a[ 1]) * 2;
wolfSSL 14:167253f4e170 8058 int64_t t2 = (((int64_t)a[ 0]) * a[ 2]) * 2
wolfSSL 14:167253f4e170 8059 + ((int64_t)a[ 1]) * a[ 1];
wolfSSL 14:167253f4e170 8060 int64_t t3 = (((int64_t)a[ 0]) * a[ 3]
wolfSSL 14:167253f4e170 8061 + ((int64_t)a[ 1]) * a[ 2]) * 2;
wolfSSL 14:167253f4e170 8062 int64_t t4 = (((int64_t)a[ 0]) * a[ 4]
wolfSSL 14:167253f4e170 8063 + ((int64_t)a[ 1]) * a[ 3]) * 2
wolfSSL 14:167253f4e170 8064 + ((int64_t)a[ 2]) * a[ 2];
wolfSSL 14:167253f4e170 8065 int64_t t5 = (((int64_t)a[ 0]) * a[ 5]
wolfSSL 14:167253f4e170 8066 + ((int64_t)a[ 1]) * a[ 4]
wolfSSL 14:167253f4e170 8067 + ((int64_t)a[ 2]) * a[ 3]) * 2;
wolfSSL 14:167253f4e170 8068 int64_t t6 = (((int64_t)a[ 0]) * a[ 6]
wolfSSL 14:167253f4e170 8069 + ((int64_t)a[ 1]) * a[ 5]
wolfSSL 14:167253f4e170 8070 + ((int64_t)a[ 2]) * a[ 4]) * 2
wolfSSL 14:167253f4e170 8071 + ((int64_t)a[ 3]) * a[ 3];
wolfSSL 14:167253f4e170 8072 int64_t t7 = (((int64_t)a[ 0]) * a[ 7]
wolfSSL 14:167253f4e170 8073 + ((int64_t)a[ 1]) * a[ 6]
wolfSSL 14:167253f4e170 8074 + ((int64_t)a[ 2]) * a[ 5]
wolfSSL 14:167253f4e170 8075 + ((int64_t)a[ 3]) * a[ 4]) * 2;
wolfSSL 14:167253f4e170 8076 int64_t t8 = (((int64_t)a[ 0]) * a[ 8]
wolfSSL 14:167253f4e170 8077 + ((int64_t)a[ 1]) * a[ 7]
wolfSSL 14:167253f4e170 8078 + ((int64_t)a[ 2]) * a[ 6]
wolfSSL 14:167253f4e170 8079 + ((int64_t)a[ 3]) * a[ 5]) * 2
wolfSSL 14:167253f4e170 8080 + ((int64_t)a[ 4]) * a[ 4];
wolfSSL 14:167253f4e170 8081 int64_t t9 = (((int64_t)a[ 0]) * a[ 9]
wolfSSL 14:167253f4e170 8082 + ((int64_t)a[ 1]) * a[ 8]
wolfSSL 14:167253f4e170 8083 + ((int64_t)a[ 2]) * a[ 7]
wolfSSL 14:167253f4e170 8084 + ((int64_t)a[ 3]) * a[ 6]
wolfSSL 14:167253f4e170 8085 + ((int64_t)a[ 4]) * a[ 5]) * 2;
wolfSSL 14:167253f4e170 8086 int64_t t10 = (((int64_t)a[ 1]) * a[ 9]
wolfSSL 14:167253f4e170 8087 + ((int64_t)a[ 2]) * a[ 8]
wolfSSL 14:167253f4e170 8088 + ((int64_t)a[ 3]) * a[ 7]
wolfSSL 14:167253f4e170 8089 + ((int64_t)a[ 4]) * a[ 6]) * 2
wolfSSL 14:167253f4e170 8090 + ((int64_t)a[ 5]) * a[ 5];
wolfSSL 14:167253f4e170 8091 int64_t t11 = (((int64_t)a[ 2]) * a[ 9]
wolfSSL 14:167253f4e170 8092 + ((int64_t)a[ 3]) * a[ 8]
wolfSSL 14:167253f4e170 8093 + ((int64_t)a[ 4]) * a[ 7]
wolfSSL 14:167253f4e170 8094 + ((int64_t)a[ 5]) * a[ 6]) * 2;
wolfSSL 14:167253f4e170 8095 int64_t t12 = (((int64_t)a[ 3]) * a[ 9]
wolfSSL 14:167253f4e170 8096 + ((int64_t)a[ 4]) * a[ 8]
wolfSSL 14:167253f4e170 8097 + ((int64_t)a[ 5]) * a[ 7]) * 2
wolfSSL 14:167253f4e170 8098 + ((int64_t)a[ 6]) * a[ 6];
wolfSSL 14:167253f4e170 8099 int64_t t13 = (((int64_t)a[ 4]) * a[ 9]
wolfSSL 14:167253f4e170 8100 + ((int64_t)a[ 5]) * a[ 8]
wolfSSL 14:167253f4e170 8101 + ((int64_t)a[ 6]) * a[ 7]) * 2;
wolfSSL 14:167253f4e170 8102 int64_t t14 = (((int64_t)a[ 5]) * a[ 9]
wolfSSL 14:167253f4e170 8103 + ((int64_t)a[ 6]) * a[ 8]) * 2
wolfSSL 14:167253f4e170 8104 + ((int64_t)a[ 7]) * a[ 7];
wolfSSL 14:167253f4e170 8105 int64_t t15 = (((int64_t)a[ 6]) * a[ 9]
wolfSSL 14:167253f4e170 8106 + ((int64_t)a[ 7]) * a[ 8]) * 2;
wolfSSL 14:167253f4e170 8107 int64_t t16 = (((int64_t)a[ 7]) * a[ 9]) * 2
wolfSSL 14:167253f4e170 8108 + ((int64_t)a[ 8]) * a[ 8];
wolfSSL 14:167253f4e170 8109 int64_t t17 = (((int64_t)a[ 8]) * a[ 9]) * 2;
wolfSSL 14:167253f4e170 8110 int64_t t18 = ((int64_t)a[ 9]) * a[ 9];
wolfSSL 14:167253f4e170 8111
wolfSSL 14:167253f4e170 8112 t1 += t0 >> 26; r[ 0] = t0 & 0x3ffffff;
wolfSSL 14:167253f4e170 8113 t2 += t1 >> 26; r[ 1] = t1 & 0x3ffffff;
wolfSSL 14:167253f4e170 8114 t3 += t2 >> 26; r[ 2] = t2 & 0x3ffffff;
wolfSSL 14:167253f4e170 8115 t4 += t3 >> 26; r[ 3] = t3 & 0x3ffffff;
wolfSSL 14:167253f4e170 8116 t5 += t4 >> 26; r[ 4] = t4 & 0x3ffffff;
wolfSSL 14:167253f4e170 8117 t6 += t5 >> 26; r[ 5] = t5 & 0x3ffffff;
wolfSSL 14:167253f4e170 8118 t7 += t6 >> 26; r[ 6] = t6 & 0x3ffffff;
wolfSSL 14:167253f4e170 8119 t8 += t7 >> 26; r[ 7] = t7 & 0x3ffffff;
wolfSSL 14:167253f4e170 8120 t9 += t8 >> 26; r[ 8] = t8 & 0x3ffffff;
wolfSSL 14:167253f4e170 8121 t10 += t9 >> 26; r[ 9] = t9 & 0x3ffffff;
wolfSSL 14:167253f4e170 8122 t11 += t10 >> 26; r[10] = t10 & 0x3ffffff;
wolfSSL 14:167253f4e170 8123 t12 += t11 >> 26; r[11] = t11 & 0x3ffffff;
wolfSSL 14:167253f4e170 8124 t13 += t12 >> 26; r[12] = t12 & 0x3ffffff;
wolfSSL 14:167253f4e170 8125 t14 += t13 >> 26; r[13] = t13 & 0x3ffffff;
wolfSSL 14:167253f4e170 8126 t15 += t14 >> 26; r[14] = t14 & 0x3ffffff;
wolfSSL 14:167253f4e170 8127 t16 += t15 >> 26; r[15] = t15 & 0x3ffffff;
wolfSSL 14:167253f4e170 8128 t17 += t16 >> 26; r[16] = t16 & 0x3ffffff;
wolfSSL 14:167253f4e170 8129 t18 += t17 >> 26; r[17] = t17 & 0x3ffffff;
wolfSSL 14:167253f4e170 8130 r[19] = (sp_digit)(t18 >> 26);
wolfSSL 14:167253f4e170 8131 r[18] = t18 & 0x3ffffff;
wolfSSL 14:167253f4e170 8132 }
wolfSSL 14:167253f4e170 8133
wolfSSL 14:167253f4e170 8134 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 8135 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 8136 *
wolfSSL 14:167253f4e170 8137 * r Result of squaring.
wolfSSL 14:167253f4e170 8138 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 8139 * m Modulus (prime).
wolfSSL 14:167253f4e170 8140 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 8141 */
wolfSSL 14:167253f4e170 8142 static void sp_256_mont_sqr_10(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 8143 sp_digit mp)
wolfSSL 14:167253f4e170 8144 {
wolfSSL 14:167253f4e170 8145 sp_256_sqr_10(r, a);
wolfSSL 14:167253f4e170 8146 sp_256_mont_reduce_10(r, m, mp);
wolfSSL 14:167253f4e170 8147 }
wolfSSL 14:167253f4e170 8148
wolfSSL 14:167253f4e170 8149 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 8150 /* Square the Montgomery form number a number of times. (r = a ^ n mod m)
wolfSSL 14:167253f4e170 8151 *
wolfSSL 14:167253f4e170 8152 * r Result of squaring.
wolfSSL 14:167253f4e170 8153 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 8154 * n Number of times to square.
wolfSSL 14:167253f4e170 8155 * m Modulus (prime).
wolfSSL 14:167253f4e170 8156 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 8157 */
wolfSSL 14:167253f4e170 8158 static void sp_256_mont_sqr_n_10(sp_digit* r, sp_digit* a, int n,
wolfSSL 14:167253f4e170 8159 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 8160 {
wolfSSL 14:167253f4e170 8161 sp_256_mont_sqr_10(r, a, m, mp);
wolfSSL 14:167253f4e170 8162 for (; n > 1; n--)
wolfSSL 14:167253f4e170 8163 sp_256_mont_sqr_10(r, r, m, mp);
wolfSSL 14:167253f4e170 8164 }
wolfSSL 14:167253f4e170 8165
wolfSSL 14:167253f4e170 8166 #else
wolfSSL 14:167253f4e170 8167 /* Mod-2 for the P256 curve. */
wolfSSL 14:167253f4e170 8168 static const uint32_t p256_mod_2[8] = {
wolfSSL 14:167253f4e170 8169 0xfffffffd,0xffffffff,0xffffffff,0x00000000,0x00000000,0x00000000,
wolfSSL 14:167253f4e170 8170 0x00000001,0xffffffff
wolfSSL 14:167253f4e170 8171 };
wolfSSL 14:167253f4e170 8172 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 8173
wolfSSL 14:167253f4e170 8174 /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
wolfSSL 14:167253f4e170 8175 * P256 curve. (r = 1 / a mod m)
wolfSSL 14:167253f4e170 8176 *
wolfSSL 14:167253f4e170 8177 * r Inverse result.
wolfSSL 14:167253f4e170 8178 * a Number to invert.
wolfSSL 14:167253f4e170 8179 * td Temporary data.
wolfSSL 14:167253f4e170 8180 */
wolfSSL 14:167253f4e170 8181 static void sp_256_mont_inv_10(sp_digit* r, sp_digit* a, sp_digit* td)
wolfSSL 14:167253f4e170 8182 {
wolfSSL 14:167253f4e170 8183 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 8184 sp_digit* t = td;
wolfSSL 14:167253f4e170 8185 int i;
wolfSSL 14:167253f4e170 8186
wolfSSL 14:167253f4e170 8187 XMEMCPY(t, a, sizeof(sp_digit) * 10);
wolfSSL 14:167253f4e170 8188 for (i=254; i>=0; i--) {
wolfSSL 14:167253f4e170 8189 sp_256_mont_sqr_10(t, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8190 if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 8191 sp_256_mont_mul_10(t, t, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8192 }
wolfSSL 14:167253f4e170 8193 XMEMCPY(r, t, sizeof(sp_digit) * 10);
wolfSSL 14:167253f4e170 8194 #else
wolfSSL 14:167253f4e170 8195 sp_digit* t = td;
wolfSSL 14:167253f4e170 8196 sp_digit* t2 = td + 2 * 10;
wolfSSL 14:167253f4e170 8197 sp_digit* t3 = td + 4 * 10;
wolfSSL 14:167253f4e170 8198
wolfSSL 14:167253f4e170 8199 /* t = a^2 */
wolfSSL 14:167253f4e170 8200 sp_256_mont_sqr_10(t, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8201 /* t = a^3 = t * a */
wolfSSL 14:167253f4e170 8202 sp_256_mont_mul_10(t, t, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8203 /* t2= a^c = t ^ 2 ^ 2 */
wolfSSL 14:167253f4e170 8204 sp_256_mont_sqr_n_10(t2, t, 2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8205 /* t3= a^d = t2 * a */
wolfSSL 14:167253f4e170 8206 sp_256_mont_mul_10(t3, t2, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8207 /* t = a^f = t2 * t */
wolfSSL 14:167253f4e170 8208 sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8209 /* t2= a^f0 = t ^ 2 ^ 4 */
wolfSSL 14:167253f4e170 8210 sp_256_mont_sqr_n_10(t2, t, 4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8211 /* t3= a^fd = t2 * t3 */
wolfSSL 14:167253f4e170 8212 sp_256_mont_mul_10(t3, t2, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8213 /* t = a^ff = t2 * t */
wolfSSL 14:167253f4e170 8214 sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8215 /* t2= a^ff00 = t ^ 2 ^ 8 */
wolfSSL 14:167253f4e170 8216 sp_256_mont_sqr_n_10(t2, t, 8, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8217 /* t3= a^fffd = t2 * t3 */
wolfSSL 14:167253f4e170 8218 sp_256_mont_mul_10(t3, t2, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8219 /* t = a^ffff = t2 * t */
wolfSSL 14:167253f4e170 8220 sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8221 /* t2= a^ffff0000 = t ^ 2 ^ 16 */
wolfSSL 14:167253f4e170 8222 sp_256_mont_sqr_n_10(t2, t, 16, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8223 /* t3= a^fffffffd = t2 * t3 */
wolfSSL 14:167253f4e170 8224 sp_256_mont_mul_10(t3, t2, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8225 /* t = a^ffffffff = t2 * t */
wolfSSL 14:167253f4e170 8226 sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8227 /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */
wolfSSL 14:167253f4e170 8228 sp_256_mont_sqr_n_10(t2, t, 32, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8229 /* t2= a^ffffffffffffffff = t2 * t */
wolfSSL 14:167253f4e170 8230 sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8231 /* t2= a^ffffffff00000001 = t2 * a */
wolfSSL 14:167253f4e170 8232 sp_256_mont_mul_10(t2, t2, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8233 /* t2= a^ffffffff000000010000000000000000000000000000000000000000
wolfSSL 14:167253f4e170 8234 * = t2 ^ 2 ^ 160 */
wolfSSL 14:167253f4e170 8235 sp_256_mont_sqr_n_10(t2, t2, 160, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8236 /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff
wolfSSL 14:167253f4e170 8237 * = t2 * t */
wolfSSL 14:167253f4e170 8238 sp_256_mont_mul_10(t2, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8239 /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000
wolfSSL 14:167253f4e170 8240 * = t2 ^ 2 ^ 32 */
wolfSSL 14:167253f4e170 8241 sp_256_mont_sqr_n_10(t2, t2, 32, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8242 /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd
wolfSSL 14:167253f4e170 8243 * = t2 * t3 */
wolfSSL 14:167253f4e170 8244 sp_256_mont_mul_10(r, t2, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8245 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 8246 }
wolfSSL 14:167253f4e170 8247
wolfSSL 14:167253f4e170 8248 /* Map the Montgomery form projective co-ordinate point to an affine point.
wolfSSL 14:167253f4e170 8249 *
wolfSSL 14:167253f4e170 8250 * r Resulting affine co-ordinate point.
wolfSSL 14:167253f4e170 8251 * p Montgomery form projective co-ordinate point.
wolfSSL 14:167253f4e170 8252 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 8253 */
wolfSSL 14:167253f4e170 8254 static void sp_256_map_10(sp_point* r, sp_point* p, sp_digit* t)
wolfSSL 14:167253f4e170 8255 {
wolfSSL 14:167253f4e170 8256 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 8257 sp_digit* t2 = t + 2*10;
wolfSSL 14:167253f4e170 8258 int32_t n;
wolfSSL 14:167253f4e170 8259
wolfSSL 14:167253f4e170 8260 sp_256_mont_inv_10(t1, p->z, t + 2*10);
wolfSSL 14:167253f4e170 8261
wolfSSL 14:167253f4e170 8262 sp_256_mont_sqr_10(t2, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8263 sp_256_mont_mul_10(t1, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8264
wolfSSL 14:167253f4e170 8265 /* x /= z^2 */
wolfSSL 14:167253f4e170 8266 sp_256_mont_mul_10(r->x, p->x, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8267 XMEMSET(r->x + 10, 0, sizeof(r->x) / 2);
wolfSSL 14:167253f4e170 8268 sp_256_mont_reduce_10(r->x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8269 /* Reduce x to less than modulus */
wolfSSL 14:167253f4e170 8270 n = sp_256_cmp_10(r->x, p256_mod);
wolfSSL 14:167253f4e170 8271 sp_256_cond_sub_10(r->x, r->x, p256_mod, 0 - (n >= 0));
wolfSSL 14:167253f4e170 8272 sp_256_norm_10(r->x);
wolfSSL 14:167253f4e170 8273
wolfSSL 14:167253f4e170 8274 /* y /= z^3 */
wolfSSL 14:167253f4e170 8275 sp_256_mont_mul_10(r->y, p->y, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8276 XMEMSET(r->y + 10, 0, sizeof(r->y) / 2);
wolfSSL 14:167253f4e170 8277 sp_256_mont_reduce_10(r->y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8278 /* Reduce y to less than modulus */
wolfSSL 14:167253f4e170 8279 n = sp_256_cmp_10(r->y, p256_mod);
wolfSSL 14:167253f4e170 8280 sp_256_cond_sub_10(r->y, r->y, p256_mod, 0 - (n >= 0));
wolfSSL 14:167253f4e170 8281 sp_256_norm_10(r->y);
wolfSSL 14:167253f4e170 8282
wolfSSL 14:167253f4e170 8283 XMEMSET(r->z, 0, sizeof(r->z));
wolfSSL 14:167253f4e170 8284 r->z[0] = 1;
wolfSSL 14:167253f4e170 8285
wolfSSL 14:167253f4e170 8286 }
wolfSSL 14:167253f4e170 8287
wolfSSL 14:167253f4e170 8288 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 8289 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 8290 *
wolfSSL 14:167253f4e170 8291 * r A single precision integer.
wolfSSL 14:167253f4e170 8292 * a A single precision integer.
wolfSSL 14:167253f4e170 8293 * b A single precision integer.
wolfSSL 14:167253f4e170 8294 */
wolfSSL 14:167253f4e170 8295 SP_NOINLINE static int sp_256_add_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 8296 const sp_digit* b)
wolfSSL 14:167253f4e170 8297 {
wolfSSL 14:167253f4e170 8298 int i;
wolfSSL 14:167253f4e170 8299
wolfSSL 14:167253f4e170 8300 for (i = 0; i < 10; i++)
wolfSSL 14:167253f4e170 8301 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 8302
wolfSSL 14:167253f4e170 8303 return 0;
wolfSSL 14:167253f4e170 8304 }
wolfSSL 14:167253f4e170 8305 #else
wolfSSL 14:167253f4e170 8306 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 8307 *
wolfSSL 14:167253f4e170 8308 * r A single precision integer.
wolfSSL 14:167253f4e170 8309 * a A single precision integer.
wolfSSL 14:167253f4e170 8310 * b A single precision integer.
wolfSSL 14:167253f4e170 8311 */
wolfSSL 14:167253f4e170 8312 SP_NOINLINE static int sp_256_add_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 8313 const sp_digit* b)
wolfSSL 14:167253f4e170 8314 {
wolfSSL 14:167253f4e170 8315 r[ 0] = a[ 0] + b[ 0];
wolfSSL 14:167253f4e170 8316 r[ 1] = a[ 1] + b[ 1];
wolfSSL 14:167253f4e170 8317 r[ 2] = a[ 2] + b[ 2];
wolfSSL 14:167253f4e170 8318 r[ 3] = a[ 3] + b[ 3];
wolfSSL 14:167253f4e170 8319 r[ 4] = a[ 4] + b[ 4];
wolfSSL 14:167253f4e170 8320 r[ 5] = a[ 5] + b[ 5];
wolfSSL 14:167253f4e170 8321 r[ 6] = a[ 6] + b[ 6];
wolfSSL 14:167253f4e170 8322 r[ 7] = a[ 7] + b[ 7];
wolfSSL 14:167253f4e170 8323 r[ 8] = a[ 8] + b[ 8];
wolfSSL 14:167253f4e170 8324 r[ 9] = a[ 9] + b[ 9];
wolfSSL 14:167253f4e170 8325
wolfSSL 14:167253f4e170 8326 return 0;
wolfSSL 14:167253f4e170 8327 }
wolfSSL 14:167253f4e170 8328
wolfSSL 14:167253f4e170 8329 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 8330 /* Add two Montgomery form numbers (r = a + b % m).
wolfSSL 14:167253f4e170 8331 *
wolfSSL 14:167253f4e170 8332 * r Result of addition.
wolfSSL 14:167253f4e170 8333 * a First number to add in Montogmery form.
wolfSSL 14:167253f4e170 8334 * b Second number to add in Montogmery form.
wolfSSL 14:167253f4e170 8335 * m Modulus (prime).
wolfSSL 14:167253f4e170 8336 */
wolfSSL 14:167253f4e170 8337 static void sp_256_mont_add_10(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 8338 sp_digit* m)
wolfSSL 14:167253f4e170 8339 {
wolfSSL 14:167253f4e170 8340 sp_256_add_10(r, a, b);
wolfSSL 14:167253f4e170 8341 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8342 sp_256_cond_sub_10(r, r, m, 0 - ((r[9] >> 22) > 0));
wolfSSL 14:167253f4e170 8343 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8344 }
wolfSSL 14:167253f4e170 8345
wolfSSL 14:167253f4e170 8346 /* Double a Montgomery form number (r = a + a % m).
wolfSSL 14:167253f4e170 8347 *
wolfSSL 14:167253f4e170 8348 * r Result of doubling.
wolfSSL 14:167253f4e170 8349 * a Number to double in Montogmery form.
wolfSSL 14:167253f4e170 8350 * m Modulus (prime).
wolfSSL 14:167253f4e170 8351 */
wolfSSL 14:167253f4e170 8352 static void sp_256_mont_dbl_10(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 8353 {
wolfSSL 14:167253f4e170 8354 sp_256_add_10(r, a, a);
wolfSSL 14:167253f4e170 8355 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8356 sp_256_cond_sub_10(r, r, m, 0 - ((r[9] >> 22) > 0));
wolfSSL 14:167253f4e170 8357 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8358 }
wolfSSL 14:167253f4e170 8359
wolfSSL 14:167253f4e170 8360 /* Triple a Montgomery form number (r = a + a + a % m).
wolfSSL 14:167253f4e170 8361 *
wolfSSL 14:167253f4e170 8362 * r Result of Tripling.
wolfSSL 14:167253f4e170 8363 * a Number to triple in Montogmery form.
wolfSSL 14:167253f4e170 8364 * m Modulus (prime).
wolfSSL 14:167253f4e170 8365 */
wolfSSL 14:167253f4e170 8366 static void sp_256_mont_tpl_10(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 8367 {
wolfSSL 14:167253f4e170 8368 sp_256_add_10(r, a, a);
wolfSSL 14:167253f4e170 8369 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8370 sp_256_cond_sub_10(r, r, m, 0 - ((r[9] >> 22) > 0));
wolfSSL 14:167253f4e170 8371 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8372 sp_256_add_10(r, r, a);
wolfSSL 14:167253f4e170 8373 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8374 sp_256_cond_sub_10(r, r, m, 0 - ((r[9] >> 22) > 0));
wolfSSL 14:167253f4e170 8375 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8376 }
wolfSSL 14:167253f4e170 8377
wolfSSL 14:167253f4e170 8378 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 8379 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 8380 *
wolfSSL 14:167253f4e170 8381 * r A single precision integer.
wolfSSL 14:167253f4e170 8382 * a A single precision integer.
wolfSSL 14:167253f4e170 8383 * b A single precision integer.
wolfSSL 14:167253f4e170 8384 */
wolfSSL 14:167253f4e170 8385 SP_NOINLINE static int sp_256_sub_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 8386 const sp_digit* b)
wolfSSL 14:167253f4e170 8387 {
wolfSSL 14:167253f4e170 8388 int i;
wolfSSL 14:167253f4e170 8389
wolfSSL 14:167253f4e170 8390 for (i = 0; i < 10; i++)
wolfSSL 14:167253f4e170 8391 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 8392
wolfSSL 14:167253f4e170 8393 return 0;
wolfSSL 14:167253f4e170 8394 }
wolfSSL 14:167253f4e170 8395
wolfSSL 14:167253f4e170 8396 #else
wolfSSL 14:167253f4e170 8397 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 8398 *
wolfSSL 14:167253f4e170 8399 * r A single precision integer.
wolfSSL 14:167253f4e170 8400 * a A single precision integer.
wolfSSL 14:167253f4e170 8401 * b A single precision integer.
wolfSSL 14:167253f4e170 8402 */
wolfSSL 14:167253f4e170 8403 SP_NOINLINE static int sp_256_sub_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 8404 const sp_digit* b)
wolfSSL 14:167253f4e170 8405 {
wolfSSL 14:167253f4e170 8406 r[ 0] = a[ 0] - b[ 0];
wolfSSL 14:167253f4e170 8407 r[ 1] = a[ 1] - b[ 1];
wolfSSL 14:167253f4e170 8408 r[ 2] = a[ 2] - b[ 2];
wolfSSL 14:167253f4e170 8409 r[ 3] = a[ 3] - b[ 3];
wolfSSL 14:167253f4e170 8410 r[ 4] = a[ 4] - b[ 4];
wolfSSL 14:167253f4e170 8411 r[ 5] = a[ 5] - b[ 5];
wolfSSL 14:167253f4e170 8412 r[ 6] = a[ 6] - b[ 6];
wolfSSL 14:167253f4e170 8413 r[ 7] = a[ 7] - b[ 7];
wolfSSL 14:167253f4e170 8414 r[ 8] = a[ 8] - b[ 8];
wolfSSL 14:167253f4e170 8415 r[ 9] = a[ 9] - b[ 9];
wolfSSL 14:167253f4e170 8416
wolfSSL 14:167253f4e170 8417 return 0;
wolfSSL 14:167253f4e170 8418 }
wolfSSL 14:167253f4e170 8419
wolfSSL 14:167253f4e170 8420 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 8421 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 8422 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 8423 *
wolfSSL 14:167253f4e170 8424 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 8425 * a A single precision number to add with.
wolfSSL 14:167253f4e170 8426 * b A single precision number to add.
wolfSSL 14:167253f4e170 8427 * m Mask value to apply.
wolfSSL 14:167253f4e170 8428 */
wolfSSL 14:167253f4e170 8429 static void sp_256_cond_add_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 8430 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 8431 {
wolfSSL 14:167253f4e170 8432 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 8433 int i;
wolfSSL 14:167253f4e170 8434
wolfSSL 14:167253f4e170 8435 for (i = 0; i < 10; i++)
wolfSSL 14:167253f4e170 8436 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 8437 #else
wolfSSL 14:167253f4e170 8438 r[ 0] = a[ 0] + (b[ 0] & m);
wolfSSL 14:167253f4e170 8439 r[ 1] = a[ 1] + (b[ 1] & m);
wolfSSL 14:167253f4e170 8440 r[ 2] = a[ 2] + (b[ 2] & m);
wolfSSL 14:167253f4e170 8441 r[ 3] = a[ 3] + (b[ 3] & m);
wolfSSL 14:167253f4e170 8442 r[ 4] = a[ 4] + (b[ 4] & m);
wolfSSL 14:167253f4e170 8443 r[ 5] = a[ 5] + (b[ 5] & m);
wolfSSL 14:167253f4e170 8444 r[ 6] = a[ 6] + (b[ 6] & m);
wolfSSL 14:167253f4e170 8445 r[ 7] = a[ 7] + (b[ 7] & m);
wolfSSL 14:167253f4e170 8446 r[ 8] = a[ 8] + (b[ 8] & m);
wolfSSL 14:167253f4e170 8447 r[ 9] = a[ 9] + (b[ 9] & m);
wolfSSL 14:167253f4e170 8448 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 8449 }
wolfSSL 14:167253f4e170 8450
wolfSSL 14:167253f4e170 8451 /* Subtract two Montgomery form numbers (r = a - b % m).
wolfSSL 14:167253f4e170 8452 *
wolfSSL 14:167253f4e170 8453 * r Result of subtration.
wolfSSL 14:167253f4e170 8454 * a Number to subtract from in Montogmery form.
wolfSSL 14:167253f4e170 8455 * b Number to subtract with in Montogmery form.
wolfSSL 14:167253f4e170 8456 * m Modulus (prime).
wolfSSL 14:167253f4e170 8457 */
wolfSSL 14:167253f4e170 8458 static void sp_256_mont_sub_10(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 8459 sp_digit* m)
wolfSSL 14:167253f4e170 8460 {
wolfSSL 14:167253f4e170 8461 sp_256_sub_10(r, a, b);
wolfSSL 14:167253f4e170 8462 sp_256_cond_add_10(r, r, m, r[9] >> 22);
wolfSSL 14:167253f4e170 8463 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8464 }
wolfSSL 14:167253f4e170 8465
wolfSSL 14:167253f4e170 8466 /* Shift number left one bit.
wolfSSL 14:167253f4e170 8467 * Bottom bit is lost.
wolfSSL 14:167253f4e170 8468 *
wolfSSL 14:167253f4e170 8469 * r Result of shift.
wolfSSL 14:167253f4e170 8470 * a Number to shift.
wolfSSL 14:167253f4e170 8471 */
wolfSSL 14:167253f4e170 8472 SP_NOINLINE static void sp_256_rshift1_10(sp_digit* r, sp_digit* a)
wolfSSL 14:167253f4e170 8473 {
wolfSSL 14:167253f4e170 8474 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 8475 int i;
wolfSSL 14:167253f4e170 8476
wolfSSL 14:167253f4e170 8477 for (i=0; i<9; i++)
wolfSSL 14:167253f4e170 8478 r[i] = ((a[i] >> 1) | (a[i + 1] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8479 #else
wolfSSL 14:167253f4e170 8480 r[0] = ((a[0] >> 1) | (a[1] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8481 r[1] = ((a[1] >> 1) | (a[2] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8482 r[2] = ((a[2] >> 1) | (a[3] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8483 r[3] = ((a[3] >> 1) | (a[4] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8484 r[4] = ((a[4] >> 1) | (a[5] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8485 r[5] = ((a[5] >> 1) | (a[6] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8486 r[6] = ((a[6] >> 1) | (a[7] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8487 r[7] = ((a[7] >> 1) | (a[8] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8488 r[8] = ((a[8] >> 1) | (a[9] << 25)) & 0x3ffffff;
wolfSSL 14:167253f4e170 8489 #endif
wolfSSL 14:167253f4e170 8490 r[9] = a[9] >> 1;
wolfSSL 14:167253f4e170 8491 }
wolfSSL 14:167253f4e170 8492
wolfSSL 14:167253f4e170 8493 /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
wolfSSL 14:167253f4e170 8494 *
wolfSSL 14:167253f4e170 8495 * r Result of division by 2.
wolfSSL 14:167253f4e170 8496 * a Number to divide.
wolfSSL 14:167253f4e170 8497 * m Modulus (prime).
wolfSSL 14:167253f4e170 8498 */
wolfSSL 14:167253f4e170 8499 static void sp_256_div2_10(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 8500 {
wolfSSL 14:167253f4e170 8501 sp_256_cond_add_10(r, a, m, 0 - (a[0] & 1));
wolfSSL 14:167253f4e170 8502 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 8503 sp_256_rshift1_10(r, r);
wolfSSL 14:167253f4e170 8504 }
wolfSSL 14:167253f4e170 8505
wolfSSL 14:167253f4e170 8506 /* Double the Montgomery form projective point p.
wolfSSL 14:167253f4e170 8507 *
wolfSSL 14:167253f4e170 8508 * r Result of doubling point.
wolfSSL 14:167253f4e170 8509 * p Point to double.
wolfSSL 14:167253f4e170 8510 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 8511 */
wolfSSL 14:167253f4e170 8512 static void sp_256_proj_point_dbl_10(sp_point* r, sp_point* p, sp_digit* t)
wolfSSL 14:167253f4e170 8513 {
wolfSSL 14:167253f4e170 8514 sp_point *rp[2];
wolfSSL 14:167253f4e170 8515 sp_point tp;
wolfSSL 14:167253f4e170 8516 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 8517 sp_digit* t2 = t + 2*10;
wolfSSL 14:167253f4e170 8518 sp_digit* x;
wolfSSL 14:167253f4e170 8519 sp_digit* y;
wolfSSL 14:167253f4e170 8520 sp_digit* z;
wolfSSL 14:167253f4e170 8521 int i;
wolfSSL 14:167253f4e170 8522
wolfSSL 14:167253f4e170 8523 /* When infinity don't double point passed in - constant time. */
wolfSSL 14:167253f4e170 8524 rp[0] = r;
wolfSSL 14:167253f4e170 8525 rp[1] = &tp;
wolfSSL 14:167253f4e170 8526 x = rp[p->infinity]->x;
wolfSSL 14:167253f4e170 8527 y = rp[p->infinity]->y;
wolfSSL 14:167253f4e170 8528 z = rp[p->infinity]->z;
wolfSSL 14:167253f4e170 8529 /* Put point to double into result - good for infinty. */
wolfSSL 14:167253f4e170 8530 if (r != p) {
wolfSSL 14:167253f4e170 8531 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 8532 r->x[i] = p->x[i];
wolfSSL 14:167253f4e170 8533 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 8534 r->y[i] = p->y[i];
wolfSSL 14:167253f4e170 8535 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 8536 r->z[i] = p->z[i];
wolfSSL 14:167253f4e170 8537 r->infinity = p->infinity;
wolfSSL 14:167253f4e170 8538 }
wolfSSL 14:167253f4e170 8539
wolfSSL 14:167253f4e170 8540 /* T1 = Z * Z */
wolfSSL 14:167253f4e170 8541 sp_256_mont_sqr_10(t1, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8542 /* Z = Y * Z */
wolfSSL 14:167253f4e170 8543 sp_256_mont_mul_10(z, y, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8544 /* Z = 2Z */
wolfSSL 14:167253f4e170 8545 sp_256_mont_dbl_10(z, z, p256_mod);
wolfSSL 14:167253f4e170 8546 /* T2 = X - T1 */
wolfSSL 14:167253f4e170 8547 sp_256_mont_sub_10(t2, x, t1, p256_mod);
wolfSSL 14:167253f4e170 8548 /* T1 = X + T1 */
wolfSSL 14:167253f4e170 8549 sp_256_mont_add_10(t1, x, t1, p256_mod);
wolfSSL 14:167253f4e170 8550 /* T2 = T1 * T2 */
wolfSSL 14:167253f4e170 8551 sp_256_mont_mul_10(t2, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8552 /* T1 = 3T2 */
wolfSSL 14:167253f4e170 8553 sp_256_mont_tpl_10(t1, t2, p256_mod);
wolfSSL 14:167253f4e170 8554 /* Y = 2Y */
wolfSSL 14:167253f4e170 8555 sp_256_mont_dbl_10(y, y, p256_mod);
wolfSSL 14:167253f4e170 8556 /* Y = Y * Y */
wolfSSL 14:167253f4e170 8557 sp_256_mont_sqr_10(y, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8558 /* T2 = Y * Y */
wolfSSL 14:167253f4e170 8559 sp_256_mont_sqr_10(t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8560 /* T2 = T2/2 */
wolfSSL 14:167253f4e170 8561 sp_256_div2_10(t2, t2, p256_mod);
wolfSSL 14:167253f4e170 8562 /* Y = Y * X */
wolfSSL 14:167253f4e170 8563 sp_256_mont_mul_10(y, y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8564 /* X = T1 * T1 */
wolfSSL 14:167253f4e170 8565 sp_256_mont_mul_10(x, t1, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8566 /* X = X - Y */
wolfSSL 14:167253f4e170 8567 sp_256_mont_sub_10(x, x, y, p256_mod);
wolfSSL 14:167253f4e170 8568 /* X = X - Y */
wolfSSL 14:167253f4e170 8569 sp_256_mont_sub_10(x, x, y, p256_mod);
wolfSSL 14:167253f4e170 8570 /* Y = Y - X */
wolfSSL 14:167253f4e170 8571 sp_256_mont_sub_10(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 8572 /* Y = Y * T1 */
wolfSSL 14:167253f4e170 8573 sp_256_mont_mul_10(y, y, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8574 /* Y = Y - T2 */
wolfSSL 14:167253f4e170 8575 sp_256_mont_sub_10(y, y, t2, p256_mod);
wolfSSL 14:167253f4e170 8576
wolfSSL 14:167253f4e170 8577 }
wolfSSL 14:167253f4e170 8578
wolfSSL 14:167253f4e170 8579 /* Compare two numbers to determine if they are equal.
wolfSSL 14:167253f4e170 8580 * Constant time implementation.
wolfSSL 14:167253f4e170 8581 *
wolfSSL 14:167253f4e170 8582 * a First number to compare.
wolfSSL 14:167253f4e170 8583 * b Second number to compare.
wolfSSL 14:167253f4e170 8584 * returns 1 when equal and 0 otherwise.
wolfSSL 14:167253f4e170 8585 */
wolfSSL 14:167253f4e170 8586 static int sp_256_cmp_equal_10(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 8587 {
wolfSSL 14:167253f4e170 8588 return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |
wolfSSL 14:167253f4e170 8589 (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) |
wolfSSL 14:167253f4e170 8590 (a[8] ^ b[8]) | (a[9] ^ b[9])) == 0;
wolfSSL 14:167253f4e170 8591 }
wolfSSL 14:167253f4e170 8592
wolfSSL 14:167253f4e170 8593 /* Add two Montgomery form projective points.
wolfSSL 14:167253f4e170 8594 *
wolfSSL 14:167253f4e170 8595 * r Result of addition.
wolfSSL 14:167253f4e170 8596 * p Frist point to add.
wolfSSL 14:167253f4e170 8597 * q Second point to add.
wolfSSL 14:167253f4e170 8598 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 8599 */
wolfSSL 14:167253f4e170 8600 static void sp_256_proj_point_add_10(sp_point* r, sp_point* p, sp_point* q,
wolfSSL 14:167253f4e170 8601 sp_digit* t)
wolfSSL 14:167253f4e170 8602 {
wolfSSL 14:167253f4e170 8603 sp_point *ap[2];
wolfSSL 14:167253f4e170 8604 sp_point *rp[2];
wolfSSL 14:167253f4e170 8605 sp_point tp;
wolfSSL 14:167253f4e170 8606 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 8607 sp_digit* t2 = t + 2*10;
wolfSSL 14:167253f4e170 8608 sp_digit* t3 = t + 4*10;
wolfSSL 14:167253f4e170 8609 sp_digit* t4 = t + 6*10;
wolfSSL 14:167253f4e170 8610 sp_digit* t5 = t + 8*10;
wolfSSL 14:167253f4e170 8611 sp_digit* x;
wolfSSL 14:167253f4e170 8612 sp_digit* y;
wolfSSL 14:167253f4e170 8613 sp_digit* z;
wolfSSL 14:167253f4e170 8614 int i;
wolfSSL 14:167253f4e170 8615
wolfSSL 14:167253f4e170 8616 /* Ensure only the first point is the same as the result. */
wolfSSL 14:167253f4e170 8617 if (q == r) {
wolfSSL 14:167253f4e170 8618 sp_point* a = p;
wolfSSL 14:167253f4e170 8619 p = q;
wolfSSL 14:167253f4e170 8620 q = a;
wolfSSL 14:167253f4e170 8621 }
wolfSSL 14:167253f4e170 8622
wolfSSL 14:167253f4e170 8623 /* Check double */
wolfSSL 14:167253f4e170 8624 sp_256_sub_10(t1, p256_mod, q->y);
wolfSSL 14:167253f4e170 8625 sp_256_norm_10(t1);
wolfSSL 14:167253f4e170 8626 if (sp_256_cmp_equal_10(p->x, q->x) & sp_256_cmp_equal_10(p->z, q->z) &
wolfSSL 14:167253f4e170 8627 (sp_256_cmp_equal_10(p->y, q->y) | sp_256_cmp_equal_10(p->y, t1))) {
wolfSSL 14:167253f4e170 8628 sp_256_proj_point_dbl_10(r, p, t);
wolfSSL 14:167253f4e170 8629 }
wolfSSL 14:167253f4e170 8630 else {
wolfSSL 14:167253f4e170 8631 rp[0] = r;
wolfSSL 14:167253f4e170 8632 rp[1] = &tp;
wolfSSL 14:167253f4e170 8633 XMEMSET(&tp, 0, sizeof(tp));
wolfSSL 14:167253f4e170 8634 x = rp[p->infinity | q->infinity]->x;
wolfSSL 14:167253f4e170 8635 y = rp[p->infinity | q->infinity]->y;
wolfSSL 14:167253f4e170 8636 z = rp[p->infinity | q->infinity]->z;
wolfSSL 14:167253f4e170 8637
wolfSSL 14:167253f4e170 8638 ap[0] = p;
wolfSSL 14:167253f4e170 8639 ap[1] = q;
wolfSSL 14:167253f4e170 8640 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 8641 r->x[i] = ap[p->infinity]->x[i];
wolfSSL 14:167253f4e170 8642 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 8643 r->y[i] = ap[p->infinity]->y[i];
wolfSSL 14:167253f4e170 8644 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 8645 r->z[i] = ap[p->infinity]->z[i];
wolfSSL 14:167253f4e170 8646 r->infinity = ap[p->infinity]->infinity;
wolfSSL 14:167253f4e170 8647
wolfSSL 14:167253f4e170 8648 /* U1 = X1*Z2^2 */
wolfSSL 14:167253f4e170 8649 sp_256_mont_sqr_10(t1, q->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8650 sp_256_mont_mul_10(t3, t1, q->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8651 sp_256_mont_mul_10(t1, t1, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8652 /* U2 = X2*Z1^2 */
wolfSSL 14:167253f4e170 8653 sp_256_mont_sqr_10(t2, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8654 sp_256_mont_mul_10(t4, t2, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8655 sp_256_mont_mul_10(t2, t2, q->x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8656 /* S1 = Y1*Z2^3 */
wolfSSL 14:167253f4e170 8657 sp_256_mont_mul_10(t3, t3, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8658 /* S2 = Y2*Z1^3 */
wolfSSL 14:167253f4e170 8659 sp_256_mont_mul_10(t4, t4, q->y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8660 /* H = U2 - U1 */
wolfSSL 14:167253f4e170 8661 sp_256_mont_sub_10(t2, t2, t1, p256_mod);
wolfSSL 14:167253f4e170 8662 /* R = S2 - S1 */
wolfSSL 14:167253f4e170 8663 sp_256_mont_sub_10(t4, t4, t3, p256_mod);
wolfSSL 14:167253f4e170 8664 /* Z3 = H*Z1*Z2 */
wolfSSL 14:167253f4e170 8665 sp_256_mont_mul_10(z, z, q->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8666 sp_256_mont_mul_10(z, z, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8667 /* X3 = R^2 - H^3 - 2*U1*H^2 */
wolfSSL 14:167253f4e170 8668 sp_256_mont_sqr_10(x, t4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8669 sp_256_mont_sqr_10(t5, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8670 sp_256_mont_mul_10(y, t1, t5, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8671 sp_256_mont_mul_10(t5, t5, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8672 sp_256_mont_sub_10(x, x, t5, p256_mod);
wolfSSL 14:167253f4e170 8673 sp_256_mont_dbl_10(t1, y, p256_mod);
wolfSSL 14:167253f4e170 8674 sp_256_mont_sub_10(x, x, t1, p256_mod);
wolfSSL 14:167253f4e170 8675 /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
wolfSSL 14:167253f4e170 8676 sp_256_mont_sub_10(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 8677 sp_256_mont_mul_10(y, y, t4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8678 sp_256_mont_mul_10(t5, t5, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8679 sp_256_mont_sub_10(y, y, t5, p256_mod);
wolfSSL 14:167253f4e170 8680 }
wolfSSL 14:167253f4e170 8681 }
wolfSSL 14:167253f4e170 8682
wolfSSL 14:167253f4e170 8683 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 8684 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 8685 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 8686 *
wolfSSL 14:167253f4e170 8687 * r Resulting point.
wolfSSL 14:167253f4e170 8688 * g Point to multiply.
wolfSSL 14:167253f4e170 8689 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 8690 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 8691 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8692 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 8693 */
wolfSSL 14:167253f4e170 8694 static int sp_256_ecc_mulmod_10(sp_point* r, sp_point* g, sp_digit* k,
wolfSSL 14:167253f4e170 8695 int map, void* heap)
wolfSSL 14:167253f4e170 8696 {
wolfSSL 14:167253f4e170 8697 sp_point* td;
wolfSSL 14:167253f4e170 8698 sp_point* t[3];
wolfSSL 14:167253f4e170 8699 sp_digit* tmp;
wolfSSL 14:167253f4e170 8700 sp_digit n;
wolfSSL 14:167253f4e170 8701 int i;
wolfSSL 14:167253f4e170 8702 int c, y;
wolfSSL 14:167253f4e170 8703 int err = MP_OKAY;
wolfSSL 14:167253f4e170 8704
wolfSSL 14:167253f4e170 8705 (void)heap;
wolfSSL 14:167253f4e170 8706
wolfSSL 14:167253f4e170 8707 td = (sp_point*)XMALLOC(sizeof(sp_point) * 3, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8708 if (td == NULL)
wolfSSL 14:167253f4e170 8709 err = MEMORY_E;
wolfSSL 14:167253f4e170 8710 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap,
wolfSSL 14:167253f4e170 8711 DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8712 if (tmp == NULL)
wolfSSL 14:167253f4e170 8713 err = MEMORY_E;
wolfSSL 14:167253f4e170 8714
wolfSSL 14:167253f4e170 8715 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8716 XMEMSET(td, 0, sizeof(*td) * 3);
wolfSSL 14:167253f4e170 8717
wolfSSL 14:167253f4e170 8718 t[0] = &td[0];
wolfSSL 14:167253f4e170 8719 t[1] = &td[1];
wolfSSL 14:167253f4e170 8720 t[2] = &td[2];
wolfSSL 14:167253f4e170 8721
wolfSSL 14:167253f4e170 8722 /* t[0] = {0, 0, 1} * norm */
wolfSSL 14:167253f4e170 8723 t[0]->infinity = 1;
wolfSSL 14:167253f4e170 8724 /* t[1] = {g->x, g->y, g->z} * norm */
wolfSSL 14:167253f4e170 8725 err = sp_256_mod_mul_norm_10(t[1]->x, g->x, p256_mod);
wolfSSL 14:167253f4e170 8726 }
wolfSSL 14:167253f4e170 8727 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8728 err = sp_256_mod_mul_norm_10(t[1]->y, g->y, p256_mod);
wolfSSL 14:167253f4e170 8729 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8730 err = sp_256_mod_mul_norm_10(t[1]->z, g->z, p256_mod);
wolfSSL 14:167253f4e170 8731
wolfSSL 14:167253f4e170 8732 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8733 i = 9;
wolfSSL 14:167253f4e170 8734 c = 22;
wolfSSL 14:167253f4e170 8735 n = k[i--] << (26 - c);
wolfSSL 14:167253f4e170 8736 for (; ; c--) {
wolfSSL 14:167253f4e170 8737 if (c == 0) {
wolfSSL 14:167253f4e170 8738 if (i == -1)
wolfSSL 14:167253f4e170 8739 break;
wolfSSL 14:167253f4e170 8740
wolfSSL 14:167253f4e170 8741 n = k[i--];
wolfSSL 14:167253f4e170 8742 c = 26;
wolfSSL 14:167253f4e170 8743 }
wolfSSL 14:167253f4e170 8744
wolfSSL 14:167253f4e170 8745 y = (n >> 25) & 1;
wolfSSL 14:167253f4e170 8746 n <<= 1;
wolfSSL 14:167253f4e170 8747
wolfSSL 14:167253f4e170 8748 sp_256_proj_point_add_10(t[y^1], t[0], t[1], tmp);
wolfSSL 14:167253f4e170 8749
wolfSSL 14:167253f4e170 8750 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 8751 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 8752 sizeof(sp_point));
wolfSSL 14:167253f4e170 8753 sp_256_proj_point_dbl_10(t[2], t[2], tmp);
wolfSSL 14:167253f4e170 8754 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 8755 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 8756 sizeof(sp_point));
wolfSSL 14:167253f4e170 8757 }
wolfSSL 14:167253f4e170 8758
wolfSSL 14:167253f4e170 8759 if (map)
wolfSSL 14:167253f4e170 8760 sp_256_map_10(r, t[0], tmp);
wolfSSL 14:167253f4e170 8761 else
wolfSSL 14:167253f4e170 8762 XMEMCPY(r, t[0], sizeof(sp_point));
wolfSSL 14:167253f4e170 8763 }
wolfSSL 14:167253f4e170 8764
wolfSSL 14:167253f4e170 8765 if (tmp != NULL) {
wolfSSL 14:167253f4e170 8766 XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 10 * 5);
wolfSSL 14:167253f4e170 8767 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 8768 }
wolfSSL 14:167253f4e170 8769 if (td != NULL) {
wolfSSL 14:167253f4e170 8770 XMEMSET(td, 0, sizeof(sp_point) * 3);
wolfSSL 14:167253f4e170 8771 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 8772 }
wolfSSL 14:167253f4e170 8773
wolfSSL 14:167253f4e170 8774 return err;
wolfSSL 14:167253f4e170 8775 }
wolfSSL 14:167253f4e170 8776
wolfSSL 14:167253f4e170 8777 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 8778 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 8779 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 8780 *
wolfSSL 14:167253f4e170 8781 * r Resulting point.
wolfSSL 14:167253f4e170 8782 * g Point to multiply.
wolfSSL 14:167253f4e170 8783 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 8784 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 8785 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8786 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 8787 */
wolfSSL 14:167253f4e170 8788 static int sp_256_ecc_mulmod_10(sp_point* r, sp_point* g, sp_digit* k,
wolfSSL 14:167253f4e170 8789 int map, void* heap)
wolfSSL 14:167253f4e170 8790 {
wolfSSL 14:167253f4e170 8791 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8792 sp_point td[3];
wolfSSL 14:167253f4e170 8793 sp_digit tmpd[2 * 10 * 5];
wolfSSL 14:167253f4e170 8794 #endif
wolfSSL 14:167253f4e170 8795 sp_point* t;
wolfSSL 14:167253f4e170 8796 sp_digit* tmp;
wolfSSL 14:167253f4e170 8797 sp_digit n;
wolfSSL 14:167253f4e170 8798 int i;
wolfSSL 14:167253f4e170 8799 int c, y;
wolfSSL 14:167253f4e170 8800 int err = MP_OKAY;
wolfSSL 14:167253f4e170 8801
wolfSSL 14:167253f4e170 8802 (void)heap;
wolfSSL 14:167253f4e170 8803
wolfSSL 14:167253f4e170 8804 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8805 sp_point td[3];
wolfSSL 14:167253f4e170 8806 t = (sp_point*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8807 if (t == NULL)
wolfSSL 14:167253f4e170 8808 err = MEMORY_E;
wolfSSL 14:167253f4e170 8809 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap,
wolfSSL 14:167253f4e170 8810 DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8811 if (tmp == NULL)
wolfSSL 14:167253f4e170 8812 err = MEMORY_E;
wolfSSL 14:167253f4e170 8813 #else
wolfSSL 14:167253f4e170 8814 t = td;
wolfSSL 14:167253f4e170 8815 tmp = tmpd;
wolfSSL 14:167253f4e170 8816 #endif
wolfSSL 14:167253f4e170 8817
wolfSSL 14:167253f4e170 8818 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8819 t[0] = &td[0];
wolfSSL 14:167253f4e170 8820 t[1] = &td[1];
wolfSSL 14:167253f4e170 8821 t[2] = &td[2];
wolfSSL 14:167253f4e170 8822
wolfSSL 14:167253f4e170 8823 /* t[0] = {0, 0, 1} * norm */
wolfSSL 14:167253f4e170 8824 XMEMSET(&t[0], 0, sizeof(t[0]));
wolfSSL 14:167253f4e170 8825 t[0].infinity = 1;
wolfSSL 14:167253f4e170 8826 /* t[1] = {g->x, g->y, g->z} * norm */
wolfSSL 14:167253f4e170 8827 err = sp_256_mod_mul_norm_10(t[1].x, g->x, p256_mod);
wolfSSL 14:167253f4e170 8828 }
wolfSSL 14:167253f4e170 8829 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8830 err = sp_256_mod_mul_norm_10(t[1].y, g->y, p256_mod);
wolfSSL 14:167253f4e170 8831 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8832 err = sp_256_mod_mul_norm_10(t[1].z, g->z, p256_mod);
wolfSSL 14:167253f4e170 8833
wolfSSL 14:167253f4e170 8834 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8835 i = 9;
wolfSSL 14:167253f4e170 8836 c = 22;
wolfSSL 14:167253f4e170 8837 n = k[i--] << (26 - c);
wolfSSL 14:167253f4e170 8838 for (; ; c--) {
wolfSSL 14:167253f4e170 8839 if (c == 0) {
wolfSSL 14:167253f4e170 8840 if (i == -1)
wolfSSL 14:167253f4e170 8841 break;
wolfSSL 14:167253f4e170 8842
wolfSSL 14:167253f4e170 8843 n = k[i--];
wolfSSL 14:167253f4e170 8844 c = 26;
wolfSSL 14:167253f4e170 8845 }
wolfSSL 14:167253f4e170 8846
wolfSSL 14:167253f4e170 8847 y = (n >> 25) & 1;
wolfSSL 14:167253f4e170 8848 n <<= 1;
wolfSSL 14:167253f4e170 8849
wolfSSL 14:167253f4e170 8850 sp_256_proj_point_add_10(&t[y^1], &t[0], &t[1], tmp);
wolfSSL 14:167253f4e170 8851
wolfSSL 14:167253f4e170 8852 XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 8853 ((size_t)&t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 8854 sp_256_proj_point_dbl_10(&t[2], &t[2], tmp);
wolfSSL 14:167253f4e170 8855 XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 8856 ((size_t)&t[1] & addr_mask[y])), &t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 8857 }
wolfSSL 14:167253f4e170 8858
wolfSSL 14:167253f4e170 8859 if (map)
wolfSSL 14:167253f4e170 8860 sp_256_map_10(r, &t[0], tmp);
wolfSSL 14:167253f4e170 8861 else
wolfSSL 14:167253f4e170 8862 XMEMCPY(r, &t[0], sizeof(sp_point));
wolfSSL 14:167253f4e170 8863 }
wolfSSL 14:167253f4e170 8864
wolfSSL 14:167253f4e170 8865 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8866 if (tmp != NULL) {
wolfSSL 14:167253f4e170 8867 XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 10 * 5);
wolfSSL 14:167253f4e170 8868 XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8869 }
wolfSSL 14:167253f4e170 8870 if (t != NULL) {
wolfSSL 14:167253f4e170 8871 XMEMSET(t, 0, sizeof(sp_point) * 3);
wolfSSL 14:167253f4e170 8872 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8873 }
wolfSSL 14:167253f4e170 8874 #else
wolfSSL 14:167253f4e170 8875 ForceZero(tmpd, sizeof(tmpd));
wolfSSL 14:167253f4e170 8876 ForceZero(td, sizeof(td));
wolfSSL 14:167253f4e170 8877 #endif
wolfSSL 14:167253f4e170 8878
wolfSSL 14:167253f4e170 8879 return err;
wolfSSL 14:167253f4e170 8880 }
wolfSSL 14:167253f4e170 8881
wolfSSL 14:167253f4e170 8882 #else
wolfSSL 14:167253f4e170 8883 /* A table entry for pre-computed points. */
wolfSSL 14:167253f4e170 8884 typedef struct sp_table_entry {
wolfSSL 14:167253f4e170 8885 sp_digit x[10];
wolfSSL 14:167253f4e170 8886 sp_digit y[10];
wolfSSL 14:167253f4e170 8887 byte infinity;
wolfSSL 14:167253f4e170 8888 } sp_table_entry;
wolfSSL 14:167253f4e170 8889
wolfSSL 14:167253f4e170 8890 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 8891 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 8892 *
wolfSSL 14:167253f4e170 8893 * r Resulting point.
wolfSSL 14:167253f4e170 8894 * g Point to multiply.
wolfSSL 14:167253f4e170 8895 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 8896 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 8897 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8898 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 8899 */
wolfSSL 14:167253f4e170 8900 static int sp_256_ecc_mulmod_fast_10(sp_point* r, sp_point* g, sp_digit* k,
wolfSSL 14:167253f4e170 8901 int map, void* heap)
wolfSSL 14:167253f4e170 8902 {
wolfSSL 14:167253f4e170 8903 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8904 sp_point td[16];
wolfSSL 14:167253f4e170 8905 sp_point rtd;
wolfSSL 14:167253f4e170 8906 sp_digit tmpd[2 * 10 * 5];
wolfSSL 14:167253f4e170 8907 #endif
wolfSSL 14:167253f4e170 8908 sp_point* t;
wolfSSL 14:167253f4e170 8909 sp_point* rt;
wolfSSL 14:167253f4e170 8910 sp_digit* tmp;
wolfSSL 14:167253f4e170 8911 sp_digit n;
wolfSSL 14:167253f4e170 8912 int i;
wolfSSL 14:167253f4e170 8913 int c, y;
wolfSSL 14:167253f4e170 8914 int err;
wolfSSL 14:167253f4e170 8915
wolfSSL 14:167253f4e170 8916 (void)heap;
wolfSSL 14:167253f4e170 8917
wolfSSL 14:167253f4e170 8918 err = sp_ecc_point_new(heap, rtd, rt);
wolfSSL 14:167253f4e170 8919 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8920 t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8921 if (t == NULL)
wolfSSL 14:167253f4e170 8922 err = MEMORY_E;
wolfSSL 14:167253f4e170 8923 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap,
wolfSSL 14:167253f4e170 8924 DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8925 if (tmp == NULL)
wolfSSL 14:167253f4e170 8926 err = MEMORY_E;
wolfSSL 14:167253f4e170 8927 #else
wolfSSL 14:167253f4e170 8928 t = td;
wolfSSL 14:167253f4e170 8929 tmp = tmpd;
wolfSSL 14:167253f4e170 8930 #endif
wolfSSL 14:167253f4e170 8931
wolfSSL 14:167253f4e170 8932 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8933 /* t[0] = {0, 0, 1} * norm */
wolfSSL 14:167253f4e170 8934 XMEMSET(&t[0], 0, sizeof(t[0]));
wolfSSL 14:167253f4e170 8935 t[0].infinity = 1;
wolfSSL 14:167253f4e170 8936 /* t[1] = {g->x, g->y, g->z} * norm */
wolfSSL 14:167253f4e170 8937 sp_256_mod_mul_norm_10(t[1].x, g->x, p256_mod);
wolfSSL 14:167253f4e170 8938 sp_256_mod_mul_norm_10(t[1].y, g->y, p256_mod);
wolfSSL 14:167253f4e170 8939 sp_256_mod_mul_norm_10(t[1].z, g->z, p256_mod);
wolfSSL 14:167253f4e170 8940 t[1].infinity = 0;
wolfSSL 14:167253f4e170 8941 sp_256_proj_point_dbl_10(&t[ 2], &t[ 1], tmp);
wolfSSL 14:167253f4e170 8942 t[ 2].infinity = 0;
wolfSSL 14:167253f4e170 8943 sp_256_proj_point_add_10(&t[ 3], &t[ 2], &t[ 1], tmp);
wolfSSL 14:167253f4e170 8944 t[ 3].infinity = 0;
wolfSSL 14:167253f4e170 8945 sp_256_proj_point_dbl_10(&t[ 4], &t[ 2], tmp);
wolfSSL 14:167253f4e170 8946 t[ 4].infinity = 0;
wolfSSL 14:167253f4e170 8947 sp_256_proj_point_add_10(&t[ 5], &t[ 3], &t[ 2], tmp);
wolfSSL 14:167253f4e170 8948 t[ 5].infinity = 0;
wolfSSL 14:167253f4e170 8949 sp_256_proj_point_dbl_10(&t[ 6], &t[ 3], tmp);
wolfSSL 14:167253f4e170 8950 t[ 6].infinity = 0;
wolfSSL 14:167253f4e170 8951 sp_256_proj_point_add_10(&t[ 7], &t[ 4], &t[ 3], tmp);
wolfSSL 14:167253f4e170 8952 t[ 7].infinity = 0;
wolfSSL 14:167253f4e170 8953 sp_256_proj_point_dbl_10(&t[ 8], &t[ 4], tmp);
wolfSSL 14:167253f4e170 8954 t[ 8].infinity = 0;
wolfSSL 14:167253f4e170 8955 sp_256_proj_point_add_10(&t[ 9], &t[ 5], &t[ 4], tmp);
wolfSSL 14:167253f4e170 8956 t[ 9].infinity = 0;
wolfSSL 14:167253f4e170 8957 sp_256_proj_point_dbl_10(&t[10], &t[ 5], tmp);
wolfSSL 14:167253f4e170 8958 t[10].infinity = 0;
wolfSSL 14:167253f4e170 8959 sp_256_proj_point_add_10(&t[11], &t[ 6], &t[ 5], tmp);
wolfSSL 14:167253f4e170 8960 t[11].infinity = 0;
wolfSSL 14:167253f4e170 8961 sp_256_proj_point_dbl_10(&t[12], &t[ 6], tmp);
wolfSSL 14:167253f4e170 8962 t[12].infinity = 0;
wolfSSL 14:167253f4e170 8963 sp_256_proj_point_add_10(&t[13], &t[ 7], &t[ 6], tmp);
wolfSSL 14:167253f4e170 8964 t[13].infinity = 0;
wolfSSL 14:167253f4e170 8965 sp_256_proj_point_dbl_10(&t[14], &t[ 7], tmp);
wolfSSL 14:167253f4e170 8966 t[14].infinity = 0;
wolfSSL 14:167253f4e170 8967 sp_256_proj_point_add_10(&t[15], &t[ 8], &t[ 7], tmp);
wolfSSL 14:167253f4e170 8968 t[15].infinity = 0;
wolfSSL 14:167253f4e170 8969
wolfSSL 14:167253f4e170 8970 i = 8;
wolfSSL 14:167253f4e170 8971 n = k[i+1] << 6;
wolfSSL 14:167253f4e170 8972 c = 18;
wolfSSL 14:167253f4e170 8973 y = n >> 24;
wolfSSL 14:167253f4e170 8974 XMEMCPY(rt, &t[y], sizeof(sp_point));
wolfSSL 14:167253f4e170 8975 n <<= 8;
wolfSSL 14:167253f4e170 8976 for (; i>=0 || c>=4; ) {
wolfSSL 14:167253f4e170 8977 if (c < 4) {
wolfSSL 14:167253f4e170 8978 n |= k[i--] << (6 - c);
wolfSSL 14:167253f4e170 8979 c += 26;
wolfSSL 14:167253f4e170 8980 }
wolfSSL 14:167253f4e170 8981 y = (n >> 28) & 0xf;
wolfSSL 14:167253f4e170 8982 n <<= 4;
wolfSSL 14:167253f4e170 8983 c -= 4;
wolfSSL 14:167253f4e170 8984
wolfSSL 14:167253f4e170 8985 sp_256_proj_point_dbl_10(rt, rt, tmp);
wolfSSL 14:167253f4e170 8986 sp_256_proj_point_dbl_10(rt, rt, tmp);
wolfSSL 14:167253f4e170 8987 sp_256_proj_point_dbl_10(rt, rt, tmp);
wolfSSL 14:167253f4e170 8988 sp_256_proj_point_dbl_10(rt, rt, tmp);
wolfSSL 14:167253f4e170 8989
wolfSSL 14:167253f4e170 8990 sp_256_proj_point_add_10(rt, rt, &t[y], tmp);
wolfSSL 14:167253f4e170 8991 }
wolfSSL 14:167253f4e170 8992
wolfSSL 14:167253f4e170 8993 if (map)
wolfSSL 14:167253f4e170 8994 sp_256_map_10(r, rt, tmp);
wolfSSL 14:167253f4e170 8995 else
wolfSSL 14:167253f4e170 8996 XMEMCPY(r, rt, sizeof(sp_point));
wolfSSL 14:167253f4e170 8997 }
wolfSSL 14:167253f4e170 8998
wolfSSL 14:167253f4e170 8999 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 9000 if (tmp != NULL) {
wolfSSL 14:167253f4e170 9001 XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 10 * 5);
wolfSSL 14:167253f4e170 9002 XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 9003 }
wolfSSL 14:167253f4e170 9004 if (t != NULL) {
wolfSSL 14:167253f4e170 9005 XMEMSET(t, 0, sizeof(sp_point) * 16);
wolfSSL 14:167253f4e170 9006 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 9007 }
wolfSSL 14:167253f4e170 9008 #else
wolfSSL 14:167253f4e170 9009 ForceZero(tmpd, sizeof(tmpd));
wolfSSL 14:167253f4e170 9010 ForceZero(td, sizeof(td));
wolfSSL 14:167253f4e170 9011 #endif
wolfSSL 14:167253f4e170 9012 sp_ecc_point_free(rt, 1, heap);
wolfSSL 14:167253f4e170 9013
wolfSSL 14:167253f4e170 9014 return err;
wolfSSL 14:167253f4e170 9015 }
wolfSSL 14:167253f4e170 9016
wolfSSL 14:167253f4e170 9017 #ifdef FP_ECC
wolfSSL 14:167253f4e170 9018 /* Double the Montgomery form projective point p a number of times.
wolfSSL 14:167253f4e170 9019 *
wolfSSL 14:167253f4e170 9020 * r Result of repeated doubling of point.
wolfSSL 14:167253f4e170 9021 * p Point to double.
wolfSSL 14:167253f4e170 9022 * n Number of times to double
wolfSSL 14:167253f4e170 9023 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 9024 */
wolfSSL 14:167253f4e170 9025 static void sp_256_proj_point_dbl_n_10(sp_point* r, sp_point* p, int n,
wolfSSL 14:167253f4e170 9026 sp_digit* t)
wolfSSL 14:167253f4e170 9027 {
wolfSSL 14:167253f4e170 9028 sp_point *rp[2];
wolfSSL 14:167253f4e170 9029 sp_point tp;
wolfSSL 14:167253f4e170 9030 sp_digit* w = t;
wolfSSL 14:167253f4e170 9031 sp_digit* a = t + 2*10;
wolfSSL 14:167253f4e170 9032 sp_digit* b = t + 4*10;
wolfSSL 14:167253f4e170 9033 sp_digit* t1 = t + 6*10;
wolfSSL 14:167253f4e170 9034 sp_digit* t2 = t + 8*10;
wolfSSL 14:167253f4e170 9035 sp_digit* x;
wolfSSL 14:167253f4e170 9036 sp_digit* y;
wolfSSL 14:167253f4e170 9037 sp_digit* z;
wolfSSL 14:167253f4e170 9038 int i;
wolfSSL 14:167253f4e170 9039
wolfSSL 14:167253f4e170 9040 rp[0] = r;
wolfSSL 14:167253f4e170 9041 rp[1] = &tp;
wolfSSL 14:167253f4e170 9042 x = rp[p->infinity]->x;
wolfSSL 14:167253f4e170 9043 y = rp[p->infinity]->y;
wolfSSL 14:167253f4e170 9044 z = rp[p->infinity]->z;
wolfSSL 14:167253f4e170 9045 if (r != p) {
wolfSSL 14:167253f4e170 9046 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 9047 r->x[i] = p->x[i];
wolfSSL 14:167253f4e170 9048 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 9049 r->y[i] = p->y[i];
wolfSSL 14:167253f4e170 9050 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 9051 r->z[i] = p->z[i];
wolfSSL 14:167253f4e170 9052 r->infinity = p->infinity;
wolfSSL 14:167253f4e170 9053 }
wolfSSL 14:167253f4e170 9054
wolfSSL 14:167253f4e170 9055 /* Y = 2*Y */
wolfSSL 14:167253f4e170 9056 sp_256_mont_dbl_10(y, y, p256_mod);
wolfSSL 14:167253f4e170 9057 /* W = Z^4 */
wolfSSL 14:167253f4e170 9058 sp_256_mont_sqr_10(w, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9059 sp_256_mont_sqr_10(w, w, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9060 while (n--) {
wolfSSL 14:167253f4e170 9061 /* A = 3*(X^2 - W) */
wolfSSL 14:167253f4e170 9062 sp_256_mont_sqr_10(t1, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9063 sp_256_mont_sub_10(t1, t1, w, p256_mod);
wolfSSL 14:167253f4e170 9064 sp_256_mont_tpl_10(a, t1, p256_mod);
wolfSSL 14:167253f4e170 9065 /* B = X*Y^2 */
wolfSSL 14:167253f4e170 9066 sp_256_mont_sqr_10(t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9067 sp_256_mont_mul_10(b, t2, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9068 /* X = A^2 - 2B */
wolfSSL 14:167253f4e170 9069 sp_256_mont_sqr_10(x, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9070 sp_256_mont_dbl_10(t1, b, p256_mod);
wolfSSL 14:167253f4e170 9071 sp_256_mont_sub_10(x, x, t1, p256_mod);
wolfSSL 14:167253f4e170 9072 /* Z = Z*Y */
wolfSSL 14:167253f4e170 9073 sp_256_mont_mul_10(z, z, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9074 /* t2 = Y^4 */
wolfSSL 14:167253f4e170 9075 sp_256_mont_sqr_10(t2, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9076 if (n) {
wolfSSL 14:167253f4e170 9077 /* W = W*Y^4 */
wolfSSL 14:167253f4e170 9078 sp_256_mont_mul_10(w, w, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9079 }
wolfSSL 14:167253f4e170 9080 /* y = 2*A*(B - X) - Y^4 */
wolfSSL 14:167253f4e170 9081 sp_256_mont_sub_10(y, b, x, p256_mod);
wolfSSL 14:167253f4e170 9082 sp_256_mont_mul_10(y, y, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9083 sp_256_mont_dbl_10(y, y, p256_mod);
wolfSSL 14:167253f4e170 9084 sp_256_mont_sub_10(y, y, t2, p256_mod);
wolfSSL 14:167253f4e170 9085 }
wolfSSL 14:167253f4e170 9086 /* Y = Y/2 */
wolfSSL 14:167253f4e170 9087 sp_256_div2_10(y, y, p256_mod);
wolfSSL 14:167253f4e170 9088 }
wolfSSL 14:167253f4e170 9089
wolfSSL 14:167253f4e170 9090 #endif /* FP_ECC */
wolfSSL 14:167253f4e170 9091 /* Add two Montgomery form projective points. The second point has a q value of
wolfSSL 14:167253f4e170 9092 * one.
wolfSSL 14:167253f4e170 9093 * Only the first point can be the same pointer as the result point.
wolfSSL 14:167253f4e170 9094 *
wolfSSL 14:167253f4e170 9095 * r Result of addition.
wolfSSL 14:167253f4e170 9096 * p Frist point to add.
wolfSSL 14:167253f4e170 9097 * q Second point to add.
wolfSSL 14:167253f4e170 9098 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 9099 */
wolfSSL 14:167253f4e170 9100 static void sp_256_proj_point_add_qz1_10(sp_point* r, sp_point* p,
wolfSSL 14:167253f4e170 9101 sp_point* q, sp_digit* t)
wolfSSL 14:167253f4e170 9102 {
wolfSSL 14:167253f4e170 9103 sp_point *ap[2];
wolfSSL 14:167253f4e170 9104 sp_point *rp[2];
wolfSSL 14:167253f4e170 9105 sp_point tp;
wolfSSL 14:167253f4e170 9106 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 9107 sp_digit* t2 = t + 2*10;
wolfSSL 14:167253f4e170 9108 sp_digit* t3 = t + 4*10;
wolfSSL 14:167253f4e170 9109 sp_digit* t4 = t + 6*10;
wolfSSL 14:167253f4e170 9110 sp_digit* t5 = t + 8*10;
wolfSSL 14:167253f4e170 9111 sp_digit* x;
wolfSSL 14:167253f4e170 9112 sp_digit* y;
wolfSSL 14:167253f4e170 9113 sp_digit* z;
wolfSSL 14:167253f4e170 9114 int i;
wolfSSL 14:167253f4e170 9115
wolfSSL 14:167253f4e170 9116 /* Check double */
wolfSSL 14:167253f4e170 9117 sp_256_sub_10(t1, p256_mod, q->y);
wolfSSL 14:167253f4e170 9118 sp_256_norm_10(t1);
wolfSSL 14:167253f4e170 9119 if (sp_256_cmp_equal_10(p->x, q->x) & sp_256_cmp_equal_10(p->z, q->z) &
wolfSSL 14:167253f4e170 9120 (sp_256_cmp_equal_10(p->y, q->y) | sp_256_cmp_equal_10(p->y, t1))) {
wolfSSL 14:167253f4e170 9121 sp_256_proj_point_dbl_10(r, p, t);
wolfSSL 14:167253f4e170 9122 }
wolfSSL 14:167253f4e170 9123 else {
wolfSSL 14:167253f4e170 9124 rp[0] = r;
wolfSSL 14:167253f4e170 9125 rp[1] = &tp;
wolfSSL 14:167253f4e170 9126 XMEMSET(&tp, 0, sizeof(tp));
wolfSSL 14:167253f4e170 9127 x = rp[p->infinity | q->infinity]->x;
wolfSSL 14:167253f4e170 9128 y = rp[p->infinity | q->infinity]->y;
wolfSSL 14:167253f4e170 9129 z = rp[p->infinity | q->infinity]->z;
wolfSSL 14:167253f4e170 9130
wolfSSL 14:167253f4e170 9131 ap[0] = p;
wolfSSL 14:167253f4e170 9132 ap[1] = q;
wolfSSL 14:167253f4e170 9133 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 9134 r->x[i] = ap[p->infinity]->x[i];
wolfSSL 14:167253f4e170 9135 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 9136 r->y[i] = ap[p->infinity]->y[i];
wolfSSL 14:167253f4e170 9137 for (i=0; i<10; i++)
wolfSSL 14:167253f4e170 9138 r->z[i] = ap[p->infinity]->z[i];
wolfSSL 14:167253f4e170 9139 r->infinity = ap[p->infinity]->infinity;
wolfSSL 14:167253f4e170 9140
wolfSSL 14:167253f4e170 9141 /* U2 = X2*Z1^2 */
wolfSSL 14:167253f4e170 9142 sp_256_mont_sqr_10(t2, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9143 sp_256_mont_mul_10(t4, t2, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9144 sp_256_mont_mul_10(t2, t2, q->x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9145 /* S2 = Y2*Z1^3 */
wolfSSL 14:167253f4e170 9146 sp_256_mont_mul_10(t4, t4, q->y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9147 /* H = U2 - X1 */
wolfSSL 14:167253f4e170 9148 sp_256_mont_sub_10(t2, t2, x, p256_mod);
wolfSSL 14:167253f4e170 9149 /* R = S2 - Y1 */
wolfSSL 14:167253f4e170 9150 sp_256_mont_sub_10(t4, t4, y, p256_mod);
wolfSSL 14:167253f4e170 9151 /* Z3 = H*Z1 */
wolfSSL 14:167253f4e170 9152 sp_256_mont_mul_10(z, z, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9153 /* X3 = R^2 - H^3 - 2*X1*H^2 */
wolfSSL 14:167253f4e170 9154 sp_256_mont_sqr_10(t1, t4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9155 sp_256_mont_sqr_10(t5, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9156 sp_256_mont_mul_10(t3, x, t5, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9157 sp_256_mont_mul_10(t5, t5, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9158 sp_256_mont_sub_10(x, t1, t5, p256_mod);
wolfSSL 14:167253f4e170 9159 sp_256_mont_dbl_10(t1, t3, p256_mod);
wolfSSL 14:167253f4e170 9160 sp_256_mont_sub_10(x, x, t1, p256_mod);
wolfSSL 14:167253f4e170 9161 /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
wolfSSL 14:167253f4e170 9162 sp_256_mont_sub_10(t3, t3, x, p256_mod);
wolfSSL 14:167253f4e170 9163 sp_256_mont_mul_10(t3, t3, t4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9164 sp_256_mont_mul_10(t5, t5, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9165 sp_256_mont_sub_10(y, t3, t5, p256_mod);
wolfSSL 14:167253f4e170 9166 }
wolfSSL 14:167253f4e170 9167 }
wolfSSL 14:167253f4e170 9168
wolfSSL 14:167253f4e170 9169 #ifdef FP_ECC
wolfSSL 14:167253f4e170 9170 /* Convert the projective point to affine.
wolfSSL 14:167253f4e170 9171 * Ordinates are in Montgomery form.
wolfSSL 14:167253f4e170 9172 *
wolfSSL 14:167253f4e170 9173 * a Point to convert.
wolfSSL 14:167253f4e170 9174 * t Temprorary data.
wolfSSL 14:167253f4e170 9175 */
wolfSSL 14:167253f4e170 9176 static void sp_256_proj_to_affine_10(sp_point* a, sp_digit* t)
wolfSSL 14:167253f4e170 9177 {
wolfSSL 14:167253f4e170 9178 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 9179 sp_digit* t2 = t + 2 * 10;
wolfSSL 14:167253f4e170 9180 sp_digit* tmp = t + 4 * 10;
wolfSSL 14:167253f4e170 9181
wolfSSL 14:167253f4e170 9182 sp_256_mont_inv_10(t1, a->z, tmp);
wolfSSL 14:167253f4e170 9183
wolfSSL 14:167253f4e170 9184 sp_256_mont_sqr_10(t2, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9185 sp_256_mont_mul_10(t1, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9186
wolfSSL 14:167253f4e170 9187 sp_256_mont_mul_10(a->x, a->x, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9188 sp_256_mont_mul_10(a->y, a->y, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 9189 XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 9190 }
wolfSSL 14:167253f4e170 9191
wolfSSL 14:167253f4e170 9192 /* Generate the pre-computed table of points for the base point.
wolfSSL 14:167253f4e170 9193 *
wolfSSL 14:167253f4e170 9194 * a The base point.
wolfSSL 14:167253f4e170 9195 * table Place to store generated point data.
wolfSSL 14:167253f4e170 9196 * tmp Temprorary data.
wolfSSL 14:167253f4e170 9197 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 9198 */
wolfSSL 14:167253f4e170 9199 static int sp_256_gen_stripe_table_10(sp_point* a,
wolfSSL 14:167253f4e170 9200 sp_table_entry* table, sp_digit* tmp, void* heap)
wolfSSL 14:167253f4e170 9201 {
wolfSSL 14:167253f4e170 9202 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 9203 sp_point td, s1d, s2d;
wolfSSL 14:167253f4e170 9204 #endif
wolfSSL 14:167253f4e170 9205 sp_point* t;
wolfSSL 14:167253f4e170 9206 sp_point* s1 = NULL;
wolfSSL 14:167253f4e170 9207 sp_point* s2 = NULL;
wolfSSL 14:167253f4e170 9208 int i, j;
wolfSSL 14:167253f4e170 9209 int err;
wolfSSL 14:167253f4e170 9210
wolfSSL 14:167253f4e170 9211 (void)heap;
wolfSSL 14:167253f4e170 9212
wolfSSL 14:167253f4e170 9213 err = sp_ecc_point_new(heap, td, t);
wolfSSL 14:167253f4e170 9214 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 9215 err = sp_ecc_point_new(heap, s1d, s1);
wolfSSL 14:167253f4e170 9216 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 9217 err = sp_ecc_point_new(heap, s2d, s2);
wolfSSL 14:167253f4e170 9218
wolfSSL 14:167253f4e170 9219 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 9220 err = sp_256_mod_mul_norm_10(t->x, a->x, p256_mod);
wolfSSL 14:167253f4e170 9221 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 9222 err = sp_256_mod_mul_norm_10(t->y, a->y, p256_mod);
wolfSSL 14:167253f4e170 9223 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 9224 err = sp_256_mod_mul_norm_10(t->z, a->z, p256_mod);
wolfSSL 14:167253f4e170 9225 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 9226 t->infinity = 0;
wolfSSL 14:167253f4e170 9227 sp_256_proj_to_affine_10(t, tmp);
wolfSSL 14:167253f4e170 9228
wolfSSL 14:167253f4e170 9229 XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 9230 s1->infinity = 0;
wolfSSL 14:167253f4e170 9231 XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 9232 s2->infinity = 0;
wolfSSL 14:167253f4e170 9233
wolfSSL 14:167253f4e170 9234 /* table[0] = {0, 0, infinity} */
wolfSSL 14:167253f4e170 9235 XMEMSET(&table[0], 0, sizeof(sp_table_entry));
wolfSSL 14:167253f4e170 9236 table[0].infinity = 1;
wolfSSL 14:167253f4e170 9237 /* table[1] = Affine version of 'a' in Montgomery form */
wolfSSL 14:167253f4e170 9238 XMEMCPY(table[1].x, t->x, sizeof(table->x));
wolfSSL 14:167253f4e170 9239 XMEMCPY(table[1].y, t->y, sizeof(table->y));
wolfSSL 14:167253f4e170 9240 table[1].infinity = 0;
wolfSSL 14:167253f4e170 9241
wolfSSL 14:167253f4e170 9242 for (i=1; i<8; i++) {
wolfSSL 14:167253f4e170 9243 sp_256_proj_point_dbl_n_10(t, t, 32, tmp);
wolfSSL 14:167253f4e170 9244 sp_256_proj_to_affine_10(t, tmp);
wolfSSL 14:167253f4e170 9245 XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
wolfSSL 14:167253f4e170 9246 XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
wolfSSL 14:167253f4e170 9247 table[1<<i].infinity = 0;
wolfSSL 14:167253f4e170 9248 }
wolfSSL 14:167253f4e170 9249
wolfSSL 14:167253f4e170 9250 for (i=1; i<8; i++) {
wolfSSL 14:167253f4e170 9251 XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
wolfSSL 14:167253f4e170 9252 XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
wolfSSL 14:167253f4e170 9253 for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
wolfSSL 14:167253f4e170 9254 XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
wolfSSL 14:167253f4e170 9255 XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
wolfSSL 14:167253f4e170 9256 sp_256_proj_point_add_qz1_10(t, s1, s2, tmp);
wolfSSL 14:167253f4e170 9257 sp_256_proj_to_affine_10(t, tmp);
wolfSSL 14:167253f4e170 9258 XMEMCPY(table[j].x, t->x, sizeof(table->x));
wolfSSL 14:167253f4e170 9259 XMEMCPY(table[j].y, t->y, sizeof(table->y));
wolfSSL 14:167253f4e170 9260 table[j].infinity = 0;
wolfSSL 14:167253f4e170 9261 }
wolfSSL 14:167253f4e170 9262 }
wolfSSL 14:167253f4e170 9263 }
wolfSSL 14:167253f4e170 9264
wolfSSL 14:167253f4e170 9265 sp_ecc_point_free(s2, 0, heap);
wolfSSL 14:167253f4e170 9266 sp_ecc_point_free(s1, 0, heap);
wolfSSL 14:167253f4e170 9267 sp_ecc_point_free( t, 0, heap);
wolfSSL 14:167253f4e170 9268
wolfSSL 14:167253f4e170 9269 return err;
wolfSSL 14:167253f4e170 9270 }
wolfSSL 14:167253f4e170 9271
wolfSSL 14:167253f4e170 9272 #endif /* FP_ECC */
wolfSSL 14:167253f4e170 9273 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 9274 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 9275 *
wolfSSL 14:167253f4e170 9276 * r Resulting point.
wolfSSL 14:167253f4e170 9277 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 9278 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 9279 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 9280 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 9281 */
wolfSSL 14:167253f4e170 9282 static int sp_256_ecc_mulmod_stripe_10(sp_point* r, sp_point* g,
wolfSSL 14:167253f4e170 9283 sp_table_entry* table, sp_digit* k, int map, void* heap)
wolfSSL 14:167253f4e170 9284 {
wolfSSL 14:167253f4e170 9285 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 9286 sp_point rtd;
wolfSSL 14:167253f4e170 9287 sp_point pd;
wolfSSL 14:167253f4e170 9288 sp_digit td[2 * 10 * 5];
wolfSSL 14:167253f4e170 9289 #endif
wolfSSL 14:167253f4e170 9290 sp_point* rt;
wolfSSL 14:167253f4e170 9291 sp_point* p = NULL;
wolfSSL 14:167253f4e170 9292 sp_digit* t;
wolfSSL 14:167253f4e170 9293 int i, j;
wolfSSL 14:167253f4e170 9294 int y, x;
wolfSSL 14:167253f4e170 9295 int err;
wolfSSL 14:167253f4e170 9296
wolfSSL 14:167253f4e170 9297 (void)g;
wolfSSL 14:167253f4e170 9298 (void)heap;
wolfSSL 14:167253f4e170 9299
wolfSSL 14:167253f4e170 9300 err = sp_ecc_point_new(heap, rtd, rt);
wolfSSL 14:167253f4e170 9301 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 9302 err = sp_ecc_point_new(heap, pd, p);
wolfSSL 14:167253f4e170 9303 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 9304 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap,
wolfSSL 14:167253f4e170 9305 DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 9306 if (t == NULL)
wolfSSL 14:167253f4e170 9307 err = MEMORY_E;
wolfSSL 14:167253f4e170 9308 #else
wolfSSL 14:167253f4e170 9309 t = td;
wolfSSL 14:167253f4e170 9310 #endif
wolfSSL 14:167253f4e170 9311
wolfSSL 14:167253f4e170 9312 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 9313 XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 9314 XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 9315
wolfSSL 14:167253f4e170 9316 y = 0;
wolfSSL 14:167253f4e170 9317 for (j=0,x=31; j<8; j++,x+=32)
wolfSSL 14:167253f4e170 9318 y |= ((k[x / 26] >> (x % 26)) & 1) << j;
wolfSSL 14:167253f4e170 9319 XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
wolfSSL 14:167253f4e170 9320 XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
wolfSSL 14:167253f4e170 9321 rt->infinity = table[y].infinity;
wolfSSL 14:167253f4e170 9322 for (i=30; i>=0; i--) {
wolfSSL 14:167253f4e170 9323 y = 0;
wolfSSL 14:167253f4e170 9324 for (j=0,x=i; j<8; j++,x+=32)
wolfSSL 14:167253f4e170 9325 y |= ((k[x / 26] >> (x % 26)) & 1) << j;
wolfSSL 14:167253f4e170 9326
wolfSSL 14:167253f4e170 9327 sp_256_proj_point_dbl_10(rt, rt, t);
wolfSSL 14:167253f4e170 9328 XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
wolfSSL 14:167253f4e170 9329 XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
wolfSSL 14:167253f4e170 9330 p->infinity = table[y].infinity;
wolfSSL 14:167253f4e170 9331 sp_256_proj_point_add_qz1_10(rt, rt, p, t);
wolfSSL 14:167253f4e170 9332 }
wolfSSL 14:167253f4e170 9333
wolfSSL 14:167253f4e170 9334 if (map)
wolfSSL 14:167253f4e170 9335 sp_256_map_10(r, rt, t);
wolfSSL 14:167253f4e170 9336 else
wolfSSL 14:167253f4e170 9337 XMEMCPY(r, rt, sizeof(sp_point));
wolfSSL 14:167253f4e170 9338 }
wolfSSL 14:167253f4e170 9339
wolfSSL 14:167253f4e170 9340 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 9341 if (t != NULL)
wolfSSL 14:167253f4e170 9342 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 9343 #endif
wolfSSL 14:167253f4e170 9344 sp_ecc_point_free(p, 0, heap);
wolfSSL 14:167253f4e170 9345 sp_ecc_point_free(rt, 0, heap);
wolfSSL 14:167253f4e170 9346
wolfSSL 14:167253f4e170 9347 return err;
wolfSSL 14:167253f4e170 9348 }
wolfSSL 14:167253f4e170 9349
wolfSSL 14:167253f4e170 9350 #ifdef FP_ECC
wolfSSL 14:167253f4e170 9351 #ifndef FP_ENTRIES
wolfSSL 14:167253f4e170 9352 #define FP_ENTRIES 16
wolfSSL 14:167253f4e170 9353 #endif
wolfSSL 14:167253f4e170 9354
wolfSSL 14:167253f4e170 9355 typedef struct sp_cache_t {
wolfSSL 14:167253f4e170 9356 sp_digit x[10];
wolfSSL 14:167253f4e170 9357 sp_digit y[10];
wolfSSL 14:167253f4e170 9358 sp_table_entry table[256];
wolfSSL 14:167253f4e170 9359 uint32_t cnt;
wolfSSL 14:167253f4e170 9360 int set;
wolfSSL 14:167253f4e170 9361 } sp_cache_t;
wolfSSL 14:167253f4e170 9362
wolfSSL 14:167253f4e170 9363 static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];
wolfSSL 14:167253f4e170 9364 static THREAD_LS_T int sp_cache_last = -1;
wolfSSL 14:167253f4e170 9365 static THREAD_LS_T int sp_cache_inited = 0;
wolfSSL 14:167253f4e170 9366
wolfSSL 14:167253f4e170 9367 #ifndef HAVE_THREAD_LS
wolfSSL 14:167253f4e170 9368 static volatile int initCacheMutex = 0;
wolfSSL 14:167253f4e170 9369 static wolfSSL_Mutex sp_cache_lock;
wolfSSL 14:167253f4e170 9370 #endif
wolfSSL 14:167253f4e170 9371
wolfSSL 14:167253f4e170 9372 static void sp_ecc_get_cache(sp_point* g, sp_cache_t** cache)
wolfSSL 14:167253f4e170 9373 {
wolfSSL 14:167253f4e170 9374 int i, j;
wolfSSL 14:167253f4e170 9375 uint32_t least;
wolfSSL 14:167253f4e170 9376
wolfSSL 14:167253f4e170 9377 if (sp_cache_inited == 0) {
wolfSSL 14:167253f4e170 9378 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 14:167253f4e170 9379 sp_cache[i].set = 0;
wolfSSL 14:167253f4e170 9380 }
wolfSSL 14:167253f4e170 9381 sp_cache_inited = 1;
wolfSSL 14:167253f4e170 9382 }
wolfSSL 14:167253f4e170 9383
wolfSSL 14:167253f4e170 9384 /* Compare point with those in cache. */
wolfSSL 14:167253f4e170 9385 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 14:167253f4e170 9386 if (!sp_cache[i].set)
wolfSSL 14:167253f4e170 9387 continue;
wolfSSL 14:167253f4e170 9388
wolfSSL 14:167253f4e170 9389 if (sp_256_cmp_equal_10(g->x, sp_cache[i].x) &
wolfSSL 14:167253f4e170 9390 sp_256_cmp_equal_10(g->y, sp_cache[i].y)) {
wolfSSL 14:167253f4e170 9391 sp_cache[i].cnt++;
wolfSSL 14:167253f4e170 9392 break;
wolfSSL 14:167253f4e170 9393 }
wolfSSL 14:167253f4e170 9394 }
wolfSSL 14:167253f4e170 9395
wolfSSL 14:167253f4e170 9396 /* No match. */
wolfSSL 14:167253f4e170 9397 if (i == FP_ENTRIES) {
wolfSSL 14:167253f4e170 9398 /* Find empty entry. */
wolfSSL 14:167253f4e170 9399 i = (sp_cache_last + 1) % FP_ENTRIES;
wolfSSL 14:167253f4e170 9400 for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {
wolfSSL 14:167253f4e170 9401 if (!sp_cache[i].set) {
wolfSSL 14:167253f4e170 9402 break;
wolfSSL 14:167253f4e170 9403 }
wolfSSL 14:167253f4e170 9404 }
wolfSSL 14:167253f4e170 9405
wolfSSL 14:167253f4e170 9406 /* Evict least used. */
wolfSSL 14:167253f4e170 9407 if (i == sp_cache_last) {
wolfSSL 14:167253f4e170 9408 least = sp_cache[0].cnt;
wolfSSL 14:167253f4e170 9409 for (j=1; j<FP_ENTRIES; j++) {
wolfSSL 14:167253f4e170 9410 if (sp_cache[j].cnt < least) {
wolfSSL 14:167253f4e170 9411 i = j;
wolfSSL 14:167253f4e170 9412 least = sp_cache[i].cnt;
wolfSSL 14:167253f4e170 9413 }
wolfSSL 14:167253f4e170 9414 }
wolfSSL 14:167253f4e170 9415 }
wolfSSL 14:167253f4e170 9416
wolfSSL 14:167253f4e170 9417 XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));
wolfSSL 14:167253f4e170 9418 XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));
wolfSSL 14:167253f4e170 9419 sp_cache[i].set = 1;
wolfSSL 14:167253f4e170 9420 sp_cache[i].cnt = 1;
wolfSSL 14:167253f4e170 9421 }
wolfSSL 14:167253f4e170 9422
wolfSSL 14:167253f4e170 9423 *cache = &sp_cache[i];
wolfSSL 14:167253f4e170 9424 sp_cache_last = i;
wolfSSL 14:167253f4e170 9425 }
wolfSSL 14:167253f4e170 9426 #endif /* FP_ECC */
wolfSSL 14:167253f4e170 9427
wolfSSL 14:167253f4e170 9428 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 14:167253f4e170 9429 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 9430 *
wolfSSL 14:167253f4e170 9431 * r Resulting point.
wolfSSL 14:167253f4e170 9432 * g Point to multiply.
wolfSSL 14:167253f4e170 9433 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 9434 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 9435 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 9436 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 9437 */
wolfSSL 14:167253f4e170 9438 static int sp_256_ecc_mulmod_10(sp_point* r, sp_point* g, sp_digit* k,
wolfSSL 14:167253f4e170 9439 int map, void* heap)
wolfSSL 14:167253f4e170 9440 {
wolfSSL 14:167253f4e170 9441 #ifndef FP_ECC
wolfSSL 14:167253f4e170 9442 return sp_256_ecc_mulmod_fast_10(r, g, k, map, heap);
wolfSSL 14:167253f4e170 9443 #else
wolfSSL 14:167253f4e170 9444 sp_digit tmp[2 * 10 * 5];
wolfSSL 14:167253f4e170 9445 sp_cache_t* cache;
wolfSSL 14:167253f4e170 9446 int err = MP_OKAY;
wolfSSL 14:167253f4e170 9447
wolfSSL 14:167253f4e170 9448 #ifndef HAVE_THREAD_LS
wolfSSL 14:167253f4e170 9449 if (initCacheMutex == 0) {
wolfSSL 14:167253f4e170 9450 wc_InitMutex(&sp_cache_lock);
wolfSSL 14:167253f4e170 9451 initCacheMutex = 1;
wolfSSL 14:167253f4e170 9452 }
wolfSSL 14:167253f4e170 9453 if (wc_LockMutex(&sp_cache_lock) != 0)
wolfSSL 14:167253f4e170 9454 err = BAD_MUTEX_E;
wolfSSL 14:167253f4e170 9455 #endif /* HAVE_THREAD_LS */
wolfSSL 14:167253f4e170 9456
wolfSSL 14:167253f4e170 9457 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 9458 sp_ecc_get_cache(g, &cache);
wolfSSL 14:167253f4e170 9459 if (cache->cnt == 2)
wolfSSL 14:167253f4e170 9460 sp_256_gen_stripe_table_10(g, cache->table, tmp, heap);
wolfSSL 14:167253f4e170 9461
wolfSSL 14:167253f4e170 9462 #ifndef HAVE_THREAD_LS
wolfSSL 14:167253f4e170 9463 wc_UnLockMutex(&sp_cache_lock);
wolfSSL 14:167253f4e170 9464 #endif /* HAVE_THREAD_LS */
wolfSSL 14:167253f4e170 9465
wolfSSL 14:167253f4e170 9466 if (cache->cnt < 2) {
wolfSSL 14:167253f4e170 9467 err = sp_256_ecc_mulmod_fast_10(r, g, k, map, heap);
wolfSSL 14:167253f4e170 9468 }
wolfSSL 14:167253f4e170 9469 else {
wolfSSL 14:167253f4e170 9470 err = sp_256_ecc_mulmod_stripe_10(r, g, cache->table, k,
wolfSSL 14:167253f4e170 9471 map, heap);
wolfSSL 14:167253f4e170 9472 }
wolfSSL 14:167253f4e170 9473 }
wolfSSL 14:167253f4e170 9474
wolfSSL 14:167253f4e170 9475 return err;
wolfSSL 14:167253f4e170 9476 #endif
wolfSSL 14:167253f4e170 9477 }
wolfSSL 14:167253f4e170 9478
wolfSSL 14:167253f4e170 9479 #endif
wolfSSL 14:167253f4e170 9480 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 9481 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 9482 *
wolfSSL 14:167253f4e170 9483 * km Scalar to multiply by.
wolfSSL 14:167253f4e170 9484 * p Point to multiply.
wolfSSL 14:167253f4e170 9485 * r Resulting point.
wolfSSL 14:167253f4e170 9486 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 9487 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 9488 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 9489 */
wolfSSL 14:167253f4e170 9490 int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,
wolfSSL 14:167253f4e170 9491 void* heap)
wolfSSL 14:167253f4e170 9492 {
wolfSSL 14:167253f4e170 9493 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 9494 sp_point p;
wolfSSL 14:167253f4e170 9495 sp_digit kd[10];
wolfSSL 14:167253f4e170 9496 #endif
wolfSSL 14:167253f4e170 9497 sp_point* point;
wolfSSL 14:167253f4e170 9498 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 9499 int err = MP_OKAY;
wolfSSL 14:167253f4e170 9500 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 9501 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 9502 #endif
wolfSSL 14:167253f4e170 9503
wolfSSL 14:167253f4e170 9504 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 9505 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 9506 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 9507 k = XMALLOC(sizeof(sp_digit) * 10, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 9508 if (k == NULL)
wolfSSL 14:167253f4e170 9509 err = MEMORY_E;
wolfSSL 14:167253f4e170 9510 }
wolfSSL 14:167253f4e170 9511 #else
wolfSSL 14:167253f4e170 9512 k = kd;
wolfSSL 14:167253f4e170 9513 #endif
wolfSSL 14:167253f4e170 9514 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 9515 sp_256_from_mp(k, 10, km);
wolfSSL 14:167253f4e170 9516 sp_256_point_from_ecc_point_10(point, gm);
wolfSSL 14:167253f4e170 9517
wolfSSL 14:167253f4e170 9518 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 9519 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 9520 err = sp_256_ecc_mulmod_avx2_10(point, point, k, map, heap);
wolfSSL 14:167253f4e170 9521 else
wolfSSL 14:167253f4e170 9522 #endif
wolfSSL 14:167253f4e170 9523 err = sp_256_ecc_mulmod_10(point, point, k, map, heap);
wolfSSL 14:167253f4e170 9524 }
wolfSSL 14:167253f4e170 9525 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 9526 err = sp_256_point_to_ecc_point_10(point, r);
wolfSSL 14:167253f4e170 9527
wolfSSL 14:167253f4e170 9528 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 9529 if (k != NULL)
wolfSSL 14:167253f4e170 9530 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 9531 #endif
wolfSSL 14:167253f4e170 9532 sp_ecc_point_free(point, 0, heap);
wolfSSL 14:167253f4e170 9533
wolfSSL 14:167253f4e170 9534 return err;
wolfSSL 14:167253f4e170 9535 }
wolfSSL 14:167253f4e170 9536
wolfSSL 14:167253f4e170 9537 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 9538 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 14:167253f4e170 9539 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 9540 *
wolfSSL 14:167253f4e170 9541 * r Resulting point.
wolfSSL 14:167253f4e170 9542 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 9543 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 9544 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 9545 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 9546 */
wolfSSL 14:167253f4e170 9547 static int sp_256_ecc_mulmod_base_10(sp_point* r, sp_digit* k,
wolfSSL 14:167253f4e170 9548 int map, void* heap)
wolfSSL 14:167253f4e170 9549 {
wolfSSL 14:167253f4e170 9550 /* No pre-computed values. */
wolfSSL 14:167253f4e170 9551 return sp_256_ecc_mulmod_10(r, &p256_base, k, map, heap);
wolfSSL 14:167253f4e170 9552 }
wolfSSL 14:167253f4e170 9553
wolfSSL 14:167253f4e170 9554 #else
wolfSSL 14:167253f4e170 9555 static sp_table_entry p256_table[256] = {
wolfSSL 14:167253f4e170 9556 /* 0 */
wolfSSL 14:167253f4e170 9557 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
wolfSSL 14:167253f4e170 9558 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
wolfSSL 14:167253f4e170 9559 1 },
wolfSSL 14:167253f4e170 9560 /* 1 */
wolfSSL 14:167253f4e170 9561 { { 0x0a9143c,0x1cc3506,0x360179e,0x3f17fb6,0x075ba95,0x1d88944,
wolfSSL 14:167253f4e170 9562 0x3b732b7,0x15719e7,0x376a537,0x0062417 },
wolfSSL 14:167253f4e170 9563 { 0x295560a,0x094d5f3,0x245cddf,0x392e867,0x18b4ab8,0x3487cc9,
wolfSSL 14:167253f4e170 9564 0x288688d,0x176174b,0x3182588,0x0215c7f },
wolfSSL 14:167253f4e170 9565 0 },
wolfSSL 14:167253f4e170 9566 /* 2 */
wolfSSL 14:167253f4e170 9567 { { 0x147519a,0x2218090,0x32f0202,0x2b09acd,0x0d0981e,0x1e17af2,
wolfSSL 14:167253f4e170 9568 0x14a7caa,0x163a6a7,0x10ddbdf,0x03654f1 },
wolfSSL 14:167253f4e170 9569 { 0x1590f8f,0x0d8733f,0x09179d6,0x1ad139b,0x372e962,0x0bad933,
wolfSSL 14:167253f4e170 9570 0x1961102,0x223cdff,0x37e9eb2,0x0218fae },
wolfSSL 14:167253f4e170 9571 0 },
wolfSSL 14:167253f4e170 9572 /* 3 */
wolfSSL 14:167253f4e170 9573 { { 0x0db6485,0x1ad88d7,0x2f97785,0x288bc28,0x3808f0e,0x3df8c02,
wolfSSL 14:167253f4e170 9574 0x28d9544,0x20280f9,0x055b5ff,0x00001d8 },
wolfSSL 14:167253f4e170 9575 { 0x38d2010,0x13ae6e0,0x308a763,0x2ecc90d,0x254014f,0x10a9981,
wolfSSL 14:167253f4e170 9576 0x247d398,0x0fb8383,0x3613437,0x020c21d },
wolfSSL 14:167253f4e170 9577 0 },
wolfSSL 14:167253f4e170 9578 /* 4 */
wolfSSL 14:167253f4e170 9579 { { 0x2a0d2bb,0x08bf145,0x34994f9,0x1b06988,0x30d5cc1,0x1f18b22,
wolfSSL 14:167253f4e170 9580 0x01cf3a5,0x199fe49,0x161fd1b,0x00bd79a },
wolfSSL 14:167253f4e170 9581 { 0x1a01797,0x171c2fd,0x21925c1,0x1358255,0x23d20b4,0x1c7f6d4,
wolfSSL 14:167253f4e170 9582 0x111b370,0x03dec12,0x1168d6f,0x03d923e },
wolfSSL 14:167253f4e170 9583 0 },
wolfSSL 14:167253f4e170 9584 /* 5 */
wolfSSL 14:167253f4e170 9585 { { 0x137bbbc,0x19a11f8,0x0bec9e5,0x27a29a8,0x3e43446,0x275cd18,
wolfSSL 14:167253f4e170 9586 0x0427617,0x00056c7,0x285133d,0x016af80 },
wolfSSL 14:167253f4e170 9587 { 0x04c7dab,0x2a0df30,0x0c0792a,0x1310c98,0x3573d9f,0x239b30d,
wolfSSL 14:167253f4e170 9588 0x1315627,0x1ce0c32,0x25b6b6f,0x0252edc },
wolfSSL 14:167253f4e170 9589 0 },
wolfSSL 14:167253f4e170 9590 /* 6 */
wolfSSL 14:167253f4e170 9591 { { 0x20f141c,0x26d23dc,0x3c74bbf,0x334b7d6,0x06199b3,0x0441171,
wolfSSL 14:167253f4e170 9592 0x3f61294,0x313bf70,0x3cb2f7d,0x03375ae },
wolfSSL 14:167253f4e170 9593 { 0x2f436fd,0x19c02fa,0x26becca,0x1b6e64c,0x26f647f,0x053c948,
wolfSSL 14:167253f4e170 9594 0x0fa7920,0x397d830,0x2bd4bda,0x028d86f },
wolfSSL 14:167253f4e170 9595 0 },
wolfSSL 14:167253f4e170 9596 /* 7 */
wolfSSL 14:167253f4e170 9597 { { 0x17c13c7,0x2895616,0x03e128a,0x17d42df,0x1c38d63,0x0f02747,
wolfSSL 14:167253f4e170 9598 0x039aecf,0x0a4b01c,0x209c4b5,0x02e84b2 },
wolfSSL 14:167253f4e170 9599 { 0x1f91dfd,0x023e916,0x07fb9e4,0x19b3ba8,0x13af43b,0x35e02ca,
wolfSSL 14:167253f4e170 9600 0x0eb0899,0x3bd2c7b,0x19d701f,0x014faee },
wolfSSL 14:167253f4e170 9601 0 },
wolfSSL 14:167253f4e170 9602 /* 8 */
wolfSSL 14:167253f4e170 9603 { { 0x0e63d34,0x1fb8c6c,0x0fab4fe,0x1caa795,0x0f46005,0x179ed69,
wolfSSL 14:167253f4e170 9604 0x093334d,0x120c701,0x39206d5,0x021627e },
wolfSSL 14:167253f4e170 9605 { 0x183553a,0x03d7319,0x09e5aa7,0x12b8959,0x2087909,0x0011194,
wolfSSL 14:167253f4e170 9606 0x1045071,0x0713f32,0x16d0254,0x03aec1a },
wolfSSL 14:167253f4e170 9607 0 },
wolfSSL 14:167253f4e170 9608 /* 9 */
wolfSSL 14:167253f4e170 9609 { { 0x01647c5,0x1b2856b,0x1799461,0x11f133d,0x0b8127d,0x1937eeb,
wolfSSL 14:167253f4e170 9610 0x266aa37,0x1f68f71,0x0cbd1b2,0x03aca08 },
wolfSSL 14:167253f4e170 9611 { 0x287e008,0x1be361a,0x38f3940,0x276488d,0x2d87dfa,0x0333b2c,
wolfSSL 14:167253f4e170 9612 0x2d2e428,0x368755b,0x09b55a7,0x007ca0a },
wolfSSL 14:167253f4e170 9613 0 },
wolfSSL 14:167253f4e170 9614 /* 10 */
wolfSSL 14:167253f4e170 9615 { { 0x389da99,0x2a8300e,0x0022abb,0x27ae0a1,0x0a6f2d7,0x207017a,
wolfSSL 14:167253f4e170 9616 0x047862b,0x1358c9e,0x35905e5,0x00cde92 },
wolfSSL 14:167253f4e170 9617 { 0x1f7794a,0x1d40348,0x3f613c6,0x2ddf5b5,0x0207005,0x133f5ba,
wolfSSL 14:167253f4e170 9618 0x1a37810,0x3ef5829,0x0d5f4c2,0x0035978 },
wolfSSL 14:167253f4e170 9619 0 },
wolfSSL 14:167253f4e170 9620 /* 11 */
wolfSSL 14:167253f4e170 9621 { { 0x1275d38,0x026efad,0x2358d9d,0x1142f82,0x14268a7,0x1cfac99,
wolfSSL 14:167253f4e170 9622 0x362ff49,0x288cbc1,0x24252f4,0x0308f68 },
wolfSSL 14:167253f4e170 9623 { 0x394520c,0x06e13c2,0x178e5da,0x18ec16f,0x1096667,0x134a7a8,
wolfSSL 14:167253f4e170 9624 0x0dcb869,0x33fc4e9,0x38cc790,0x006778e },
wolfSSL 14:167253f4e170 9625 0 },
wolfSSL 14:167253f4e170 9626 /* 12 */
wolfSSL 14:167253f4e170 9627 { { 0x2c5fe04,0x29c5b09,0x1bdb183,0x02ceee8,0x03b28de,0x132dc4b,
wolfSSL 14:167253f4e170 9628 0x32c586a,0x32ff5d0,0x3d491fc,0x038d372 },
wolfSSL 14:167253f4e170 9629 { 0x2a58403,0x2351aea,0x3a53b40,0x21a0ba5,0x39a6974,0x1aaaa2b,
wolfSSL 14:167253f4e170 9630 0x3901273,0x03dfe78,0x3447b4e,0x039d907 },
wolfSSL 14:167253f4e170 9631 0 },
wolfSSL 14:167253f4e170 9632 /* 13 */
wolfSSL 14:167253f4e170 9633 { { 0x364ba59,0x14e5077,0x02fc7d7,0x3b02c09,0x1d33f10,0x0560616,
wolfSSL 14:167253f4e170 9634 0x06dfc6a,0x15efd3c,0x357052a,0x01284b7 },
wolfSSL 14:167253f4e170 9635 { 0x039dbd0,0x18ce3e5,0x3e1fbfa,0x352f794,0x0d3c24b,0x07c6cc5,
wolfSSL 14:167253f4e170 9636 0x1e4ffa2,0x3a91bf5,0x293bb5b,0x01abd6a },
wolfSSL 14:167253f4e170 9637 0 },
wolfSSL 14:167253f4e170 9638 /* 14 */
wolfSSL 14:167253f4e170 9639 { { 0x0c91999,0x02da644,0x0491da1,0x100a960,0x00a24b4,0x2330824,
wolfSSL 14:167253f4e170 9640 0x0094b4b,0x1004cf8,0x35a66a4,0x017f8d1 },
wolfSSL 14:167253f4e170 9641 { 0x13e7b4b,0x232af7e,0x391ab0f,0x069f08f,0x3292b50,0x3479898,
wolfSSL 14:167253f4e170 9642 0x2889aec,0x2a4590b,0x308ecfe,0x02d5138 },
wolfSSL 14:167253f4e170 9643 0 },
wolfSSL 14:167253f4e170 9644 /* 15 */
wolfSSL 14:167253f4e170 9645 { { 0x2ddfdce,0x231ba45,0x39e6647,0x19be245,0x12c3291,0x35399f8,
wolfSSL 14:167253f4e170 9646 0x0d6e764,0x3082d3a,0x2bda6b0,0x0382dac },
wolfSSL 14:167253f4e170 9647 { 0x37efb57,0x04b7cae,0x00070d3,0x379e431,0x01aac0d,0x1e6f251,
wolfSSL 14:167253f4e170 9648 0x0336ad6,0x0ddd3e4,0x3de25a6,0x01c7008 },
wolfSSL 14:167253f4e170 9649 0 },
wolfSSL 14:167253f4e170 9650 /* 16 */
wolfSSL 14:167253f4e170 9651 { { 0x3e20925,0x230912f,0x286762a,0x30e3f73,0x391c19a,0x34e1c18,
wolfSSL 14:167253f4e170 9652 0x16a5d5d,0x093d96a,0x3d421d3,0x0187561 },
wolfSSL 14:167253f4e170 9653 { 0x37173ea,0x19ce8a8,0x0b65e87,0x0214dde,0x2238480,0x16ead0f,
wolfSSL 14:167253f4e170 9654 0x38441e0,0x3bef843,0x2124621,0x03e847f },
wolfSSL 14:167253f4e170 9655 0 },
wolfSSL 14:167253f4e170 9656 /* 17 */
wolfSSL 14:167253f4e170 9657 { { 0x0b19ffd,0x247cacb,0x3c231c8,0x16ec648,0x201ba8d,0x2b172a3,
wolfSSL 14:167253f4e170 9658 0x103d678,0x2fb72db,0x04c1f13,0x0161bac },
wolfSSL 14:167253f4e170 9659 { 0x3e8ed09,0x171b949,0x2de20c3,0x0f06067,0x21e81a3,0x1b194be,
wolfSSL 14:167253f4e170 9660 0x0fd6c05,0x13c449e,0x0087086,0x006756b },
wolfSSL 14:167253f4e170 9661 0 },
wolfSSL 14:167253f4e170 9662 /* 18 */
wolfSSL 14:167253f4e170 9663 { { 0x09a4e1f,0x27d604c,0x00741e9,0x06fa49c,0x0ab7de7,0x3f4a348,
wolfSSL 14:167253f4e170 9664 0x25ef0be,0x158fc9a,0x33f7f9c,0x039f001 },
wolfSSL 14:167253f4e170 9665 { 0x2f59f76,0x3598e83,0x30501f6,0x15083f2,0x0669b3b,0x29980b5,
wolfSSL 14:167253f4e170 9666 0x0c1f7a7,0x0f02b02,0x0fec65b,0x0382141 },
wolfSSL 14:167253f4e170 9667 0 },
wolfSSL 14:167253f4e170 9668 /* 19 */
wolfSSL 14:167253f4e170 9669 { { 0x031b3ca,0x23da368,0x2d66f09,0x27b9b69,0x06d1cab,0x13c91ba,
wolfSSL 14:167253f4e170 9670 0x3d81fa9,0x25ad16f,0x0825b09,0x01e3c06 },
wolfSSL 14:167253f4e170 9671 { 0x225787f,0x3bf790e,0x2c9bb7e,0x0347732,0x28016f8,0x0d6ff0d,
wolfSSL 14:167253f4e170 9672 0x2a4877b,0x1d1e833,0x3b87e94,0x010e9dc },
wolfSSL 14:167253f4e170 9673 0 },
wolfSSL 14:167253f4e170 9674 /* 20 */
wolfSSL 14:167253f4e170 9675 { { 0x2b533d5,0x1ddcd34,0x1dc0625,0x3da86f7,0x3673b8a,0x1e7b0a4,
wolfSSL 14:167253f4e170 9676 0x3e7c9aa,0x19ac55d,0x251c3b2,0x02edb79 },
wolfSSL 14:167253f4e170 9677 { 0x25259b3,0x24c0ead,0x3480e7e,0x34f40e9,0x3d6a0af,0x2cf3f09,
wolfSSL 14:167253f4e170 9678 0x2c83d19,0x2e66f16,0x19a5d18,0x0182d18 },
wolfSSL 14:167253f4e170 9679 0 },
wolfSSL 14:167253f4e170 9680 /* 21 */
wolfSSL 14:167253f4e170 9681 { { 0x2e5aa1c,0x28e3846,0x3658bd6,0x0ad279c,0x1b8b765,0x397e1fb,
wolfSSL 14:167253f4e170 9682 0x130014e,0x3ff342c,0x3b2aeeb,0x02743c9 },
wolfSSL 14:167253f4e170 9683 { 0x2730a55,0x0918c5e,0x083aca9,0x0bf76ef,0x19c955b,0x300669c,
wolfSSL 14:167253f4e170 9684 0x01dfe0a,0x312341f,0x26d356e,0x0091295 },
wolfSSL 14:167253f4e170 9685 0 },
wolfSSL 14:167253f4e170 9686 /* 22 */
wolfSSL 14:167253f4e170 9687 { { 0x2cf1f96,0x00e52ba,0x271c6db,0x2a40930,0x19f2122,0x0b2f4ee,
wolfSSL 14:167253f4e170 9688 0x26ac1b8,0x3bda498,0x0873581,0x0117963 },
wolfSSL 14:167253f4e170 9689 { 0x38f9dbc,0x3d1e768,0x2040d3f,0x11ba222,0x3a8aaf1,0x1b82fb5,
wolfSSL 14:167253f4e170 9690 0x1adfb24,0x2de9251,0x21cc1e4,0x0301038 },
wolfSSL 14:167253f4e170 9691 0 },
wolfSSL 14:167253f4e170 9692 /* 23 */
wolfSSL 14:167253f4e170 9693 { { 0x38117b6,0x2bc001b,0x1433847,0x3fdce8d,0x3651969,0x3651d7a,
wolfSSL 14:167253f4e170 9694 0x2b35761,0x1bb1d20,0x097682c,0x00737d7 },
wolfSSL 14:167253f4e170 9695 { 0x1f04839,0x1dd6d04,0x16987db,0x3d12378,0x17dbeac,0x1c2cc86,
wolfSSL 14:167253f4e170 9696 0x121dd1b,0x3fcf6ca,0x1f8a92d,0x00119d5 },
wolfSSL 14:167253f4e170 9697 0 },
wolfSSL 14:167253f4e170 9698 /* 24 */
wolfSSL 14:167253f4e170 9699 { { 0x0e8ffcd,0x2b174af,0x1a82cc8,0x22cbf98,0x30d53c4,0x080b5b1,
wolfSSL 14:167253f4e170 9700 0x3161727,0x297cfdb,0x2113b83,0x0011b97 },
wolfSSL 14:167253f4e170 9701 { 0x0007f01,0x23fd936,0x3183e7b,0x0496bd0,0x07fb1ef,0x178680f,
wolfSSL 14:167253f4e170 9702 0x1c5ea63,0x0016c11,0x2c3303d,0x01b8041 },
wolfSSL 14:167253f4e170 9703 0 },
wolfSSL 14:167253f4e170 9704 /* 25 */
wolfSSL 14:167253f4e170 9705 { { 0x0dd73b1,0x1cd6122,0x10d948c,0x23e657b,0x3767070,0x15a8aad,
wolfSSL 14:167253f4e170 9706 0x385ea8c,0x33c7ce0,0x0ede901,0x0110965 },
wolfSSL 14:167253f4e170 9707 { 0x2d4b65b,0x2a8b244,0x0c37f8f,0x0ee5b24,0x394c234,0x3a5e347,
wolfSSL 14:167253f4e170 9708 0x26e4a15,0x39a3b4c,0x2514c2e,0x029e5be },
wolfSSL 14:167253f4e170 9709 0 },
wolfSSL 14:167253f4e170 9710 /* 26 */
wolfSSL 14:167253f4e170 9711 { { 0x23addd7,0x3ed8120,0x13b3359,0x20f959a,0x09e2a61,0x32fcf20,
wolfSSL 14:167253f4e170 9712 0x05b78e3,0x19ba7e2,0x1a9c697,0x0392b4b },
wolfSSL 14:167253f4e170 9713 { 0x2048a61,0x3dfd0a3,0x19a0357,0x233024b,0x3082d19,0x00fb63b,
wolfSSL 14:167253f4e170 9714 0x3a1af4c,0x1450ff0,0x046c37b,0x0317a50 },
wolfSSL 14:167253f4e170 9715 0 },
wolfSSL 14:167253f4e170 9716 /* 27 */
wolfSSL 14:167253f4e170 9717 { { 0x3e75f9e,0x294e30a,0x3a78476,0x3a32c48,0x36fd1a9,0x0427012,
wolfSSL 14:167253f4e170 9718 0x1e4df0b,0x11d1f61,0x1afdb46,0x018ca0f },
wolfSSL 14:167253f4e170 9719 { 0x2f2df15,0x0a33dee,0x27f4ce7,0x1542b66,0x3e592c4,0x20d2f30,
wolfSSL 14:167253f4e170 9720 0x3226ade,0x2a4e3ea,0x1ab1981,0x01a2f46 },
wolfSSL 14:167253f4e170 9721 0 },
wolfSSL 14:167253f4e170 9722 /* 28 */
wolfSSL 14:167253f4e170 9723 { { 0x087d659,0x3ab5446,0x305ac08,0x3d2cd64,0x33374d5,0x3f9d3f8,
wolfSSL 14:167253f4e170 9724 0x186981c,0x37f5a5a,0x2f53c6f,0x01254a4 },
wolfSSL 14:167253f4e170 9725 { 0x2cec896,0x1e32786,0x04844a8,0x043b16d,0x3d964b2,0x1935829,
wolfSSL 14:167253f4e170 9726 0x16f7e26,0x1a0dd9a,0x30d2603,0x003b1d4 },
wolfSSL 14:167253f4e170 9727 0 },
wolfSSL 14:167253f4e170 9728 /* 29 */
wolfSSL 14:167253f4e170 9729 { { 0x12687bb,0x04e816b,0x21fa2da,0x1abccb8,0x3a1f83b,0x375181e,
wolfSSL 14:167253f4e170 9730 0x0f5ef51,0x0fc2ce4,0x3a66486,0x003d881 },
wolfSSL 14:167253f4e170 9731 { 0x3138233,0x1f8eec3,0x2718bd6,0x1b09caa,0x2dd66b9,0x1bb222b,
wolfSSL 14:167253f4e170 9732 0x1004072,0x1b73e3b,0x07208ed,0x03fc36c },
wolfSSL 14:167253f4e170 9733 0 },
wolfSSL 14:167253f4e170 9734 /* 30 */
wolfSSL 14:167253f4e170 9735 { { 0x095d553,0x3e84053,0x0a8a749,0x3f575a0,0x3a44052,0x3ced59b,
wolfSSL 14:167253f4e170 9736 0x3b4317f,0x03a8c60,0x13c8874,0x00c4ed4 },
wolfSSL 14:167253f4e170 9737 { 0x0d11549,0x0b8ab02,0x221cb40,0x02ed37b,0x2071ee1,0x1fc8c83,
wolfSSL 14:167253f4e170 9738 0x3987dd4,0x27e049a,0x0f986f1,0x00b4eaf },
wolfSSL 14:167253f4e170 9739 0 },
wolfSSL 14:167253f4e170 9740 /* 31 */
wolfSSL 14:167253f4e170 9741 { { 0x15581a2,0x2214060,0x11af4c2,0x1598c88,0x19a0a6d,0x32acba6,
wolfSSL 14:167253f4e170 9742 0x3a7a0f0,0x2337c66,0x210ded9,0x0300dbe },
wolfSSL 14:167253f4e170 9743 { 0x1fbd009,0x3822eb0,0x181629a,0x2401b45,0x30b68b1,0x2e78363,
wolfSSL 14:167253f4e170 9744 0x2b32779,0x006530b,0x2c4b6d4,0x029aca8 },
wolfSSL 14:167253f4e170 9745 0 },
wolfSSL 14:167253f4e170 9746 /* 32 */
wolfSSL 14:167253f4e170 9747 { { 0x13549cf,0x0f943db,0x265ed43,0x1bfeb35,0x06f3369,0x3847f2d,
wolfSSL 14:167253f4e170 9748 0x1bfdacc,0x26181a5,0x252af7c,0x02043b8 },
wolfSSL 14:167253f4e170 9749 { 0x159bb2c,0x143f85c,0x357b654,0x2f9d62c,0x2f7dfbe,0x1a7fa9c,
wolfSSL 14:167253f4e170 9750 0x057e74d,0x05d14ac,0x17a9273,0x035215c },
wolfSSL 14:167253f4e170 9751 0 },
wolfSSL 14:167253f4e170 9752 /* 33 */
wolfSSL 14:167253f4e170 9753 { { 0x0cb5a98,0x106a2bc,0x10bf117,0x24c7cc4,0x3d3da8f,0x2ce0ab7,
wolfSSL 14:167253f4e170 9754 0x14e2cba,0x1813866,0x1a72f9a,0x01a9811 },
wolfSSL 14:167253f4e170 9755 { 0x2b2411d,0x3034fe8,0x16e0170,0x0f9443a,0x0be0eb8,0x2196cf3,
wolfSSL 14:167253f4e170 9756 0x0c9f738,0x15e40ef,0x0faf9e1,0x034f917 },
wolfSSL 14:167253f4e170 9757 0 },
wolfSSL 14:167253f4e170 9758 /* 34 */
wolfSSL 14:167253f4e170 9759 { { 0x03f7669,0x3da6efa,0x3d6bce1,0x209ca1d,0x109f8ae,0x09109e3,
wolfSSL 14:167253f4e170 9760 0x08ae543,0x3067255,0x1dee3c2,0x0081dd5 },
wolfSSL 14:167253f4e170 9761 { 0x3ef1945,0x358765b,0x28c387b,0x3bec4b4,0x218813c,0x0b7d92a,
wolfSSL 14:167253f4e170 9762 0x3cd1d67,0x2c0367e,0x2e57154,0x0123717 },
wolfSSL 14:167253f4e170 9763 0 },
wolfSSL 14:167253f4e170 9764 /* 35 */
wolfSSL 14:167253f4e170 9765 { { 0x3e5a199,0x1e42ffd,0x0bb7123,0x33e6273,0x1e0efb8,0x294671e,
wolfSSL 14:167253f4e170 9766 0x3a2bfe0,0x3d11709,0x2eddff6,0x03cbec2 },
wolfSSL 14:167253f4e170 9767 { 0x0b5025f,0x0255d7c,0x1f2241c,0x35d03ea,0x0550543,0x202fef4,
wolfSSL 14:167253f4e170 9768 0x23c8ad3,0x354963e,0x015db28,0x0284fa4 },
wolfSSL 14:167253f4e170 9769 0 },
wolfSSL 14:167253f4e170 9770 /* 36 */
wolfSSL 14:167253f4e170 9771 { { 0x2b65cbc,0x1e8d428,0x0226f9f,0x1c8a919,0x10b04b9,0x08fc1e8,
wolfSSL 14:167253f4e170 9772 0x1ce241e,0x149bc99,0x2b01497,0x00afc35 },
wolfSSL 14:167253f4e170 9773 { 0x3216fb7,0x1374fd2,0x226ad3d,0x19fef76,0x0f7d7b8,0x1c21417,
wolfSSL 14:167253f4e170 9774 0x37b83f6,0x3a27eba,0x25a162f,0x010aa52 },
wolfSSL 14:167253f4e170 9775 0 },
wolfSSL 14:167253f4e170 9776 /* 37 */
wolfSSL 14:167253f4e170 9777 { { 0x2adf191,0x1ab42fa,0x28d7584,0x2409689,0x20f8a48,0x253707d,
wolfSSL 14:167253f4e170 9778 0x2030504,0x378f7a1,0x169c65e,0x00b0b76 },
wolfSSL 14:167253f4e170 9779 { 0x3849c17,0x085c764,0x10dd6d0,0x2e87689,0x1460488,0x30e9521,
wolfSSL 14:167253f4e170 9780 0x10c7063,0x1b6f120,0x21f42c5,0x03d0dfe },
wolfSSL 14:167253f4e170 9781 0 },
wolfSSL 14:167253f4e170 9782 /* 38 */
wolfSSL 14:167253f4e170 9783 { { 0x20f7dab,0x035c512,0x29ac6aa,0x24c5ddb,0x20f0497,0x17ce5e1,
wolfSSL 14:167253f4e170 9784 0x00a050f,0x1eaa14b,0x3335470,0x02abd16 },
wolfSSL 14:167253f4e170 9785 { 0x18d364a,0x0df0cf0,0x316585e,0x018f925,0x0d40b9b,0x17b1511,
wolfSSL 14:167253f4e170 9786 0x1716811,0x1caf3d0,0x10df4f2,0x0337d8c },
wolfSSL 14:167253f4e170 9787 0 },
wolfSSL 14:167253f4e170 9788 /* 39 */
wolfSSL 14:167253f4e170 9789 { { 0x2a8b7ef,0x0f188e3,0x2287747,0x06216f0,0x008e935,0x2f6a38d,
wolfSSL 14:167253f4e170 9790 0x1567722,0x0bfc906,0x0bada9e,0x03c3402 },
wolfSSL 14:167253f4e170 9791 { 0x014d3b1,0x099c749,0x2a76291,0x216c067,0x3b37549,0x14ef2f6,
wolfSSL 14:167253f4e170 9792 0x21b96d4,0x1ee2d71,0x2f5ca88,0x016f570 },
wolfSSL 14:167253f4e170 9793 0 },
wolfSSL 14:167253f4e170 9794 /* 40 */
wolfSSL 14:167253f4e170 9795 { { 0x09a3154,0x3d1a7bd,0x2e9aef0,0x255b8ac,0x03e85a5,0x2a492a7,
wolfSSL 14:167253f4e170 9796 0x2aec1ea,0x11c6516,0x3c8a09e,0x02a84b7 },
wolfSSL 14:167253f4e170 9797 { 0x1f69f1d,0x09c89d3,0x1e7326f,0x0b28bfd,0x0e0e4c8,0x1ea7751,
wolfSSL 14:167253f4e170 9798 0x18ce73b,0x2a406e7,0x273e48c,0x01b00db },
wolfSSL 14:167253f4e170 9799 0 },
wolfSSL 14:167253f4e170 9800 /* 41 */
wolfSSL 14:167253f4e170 9801 { { 0x36e3138,0x2b84a83,0x345a5cf,0x00096b4,0x16966ef,0x159caf1,
wolfSSL 14:167253f4e170 9802 0x13c64b4,0x2f89226,0x25896af,0x00a4bfd },
wolfSSL 14:167253f4e170 9803 { 0x2213402,0x1435117,0x09fed52,0x09d0e4b,0x0f6580e,0x2871cba,
wolfSSL 14:167253f4e170 9804 0x3b397fd,0x1c9d825,0x090311b,0x0191383 },
wolfSSL 14:167253f4e170 9805 0 },
wolfSSL 14:167253f4e170 9806 /* 42 */
wolfSSL 14:167253f4e170 9807 { { 0x07153f0,0x1087869,0x18c9e1e,0x1e64810,0x2b86c3b,0x0175d9c,
wolfSSL 14:167253f4e170 9808 0x3dce877,0x269de4e,0x393cab7,0x03c96b9 },
wolfSSL 14:167253f4e170 9809 { 0x1869d0c,0x06528db,0x02641f3,0x209261b,0x29d55c8,0x25ba517,
wolfSSL 14:167253f4e170 9810 0x3b5ea30,0x028f927,0x25313db,0x00e6e39 },
wolfSSL 14:167253f4e170 9811 0 },
wolfSSL 14:167253f4e170 9812 /* 43 */
wolfSSL 14:167253f4e170 9813 { { 0x2fd2e59,0x150802d,0x098f377,0x19a4957,0x135e2c0,0x38a95ce,
wolfSSL 14:167253f4e170 9814 0x1ab21a0,0x36c1b67,0x32f0f19,0x00e448b },
wolfSSL 14:167253f4e170 9815 { 0x3cad53c,0x3387800,0x17e3cfb,0x03f9970,0x3225b2c,0x2a84e1d,
wolfSSL 14:167253f4e170 9816 0x3af1d29,0x3fe35ca,0x2f8ce80,0x0237a02 },
wolfSSL 14:167253f4e170 9817 0 },
wolfSSL 14:167253f4e170 9818 /* 44 */
wolfSSL 14:167253f4e170 9819 { { 0x07bbb76,0x3aa3648,0x2758afb,0x1f085e0,0x1921c7e,0x3010dac,
wolfSSL 14:167253f4e170 9820 0x22b74b1,0x230137e,0x1062e36,0x021c652 },
wolfSSL 14:167253f4e170 9821 { 0x3993df5,0x24a2ee8,0x126ab5f,0x2d7cecf,0x0639d75,0x16d5414,
wolfSSL 14:167253f4e170 9822 0x1aa78a8,0x3f78404,0x26a5b74,0x03f0c57 },
wolfSSL 14:167253f4e170 9823 0 },
wolfSSL 14:167253f4e170 9824 /* 45 */
wolfSSL 14:167253f4e170 9825 { { 0x0d6ecfa,0x3f506ba,0x3f86561,0x3d86bb1,0x15f8c44,0x2491d07,
wolfSSL 14:167253f4e170 9826 0x052a7b4,0x2422261,0x3adee38,0x039b529 },
wolfSSL 14:167253f4e170 9827 { 0x193c75d,0x14bb451,0x1162605,0x293749c,0x370a70d,0x2e8b1f6,
wolfSSL 14:167253f4e170 9828 0x2ede937,0x2b95f4a,0x39a9be2,0x00d77eb },
wolfSSL 14:167253f4e170 9829 0 },
wolfSSL 14:167253f4e170 9830 /* 46 */
wolfSSL 14:167253f4e170 9831 { { 0x2736636,0x15bf36a,0x2b7e6b9,0x25eb8b2,0x209f51d,0x3cd2659,
wolfSSL 14:167253f4e170 9832 0x10bf410,0x034afec,0x3d71c83,0x0076971 },
wolfSSL 14:167253f4e170 9833 { 0x0ce6825,0x07920cf,0x3c3b5c4,0x23fe55c,0x015ad11,0x08c0dae,
wolfSSL 14:167253f4e170 9834 0x0552c7f,0x2e75a8a,0x0fddbf4,0x01c1df0 },
wolfSSL 14:167253f4e170 9835 0 },
wolfSSL 14:167253f4e170 9836 /* 47 */
wolfSSL 14:167253f4e170 9837 { { 0x2b9661c,0x0ffe351,0x3d71bf6,0x1ac34b3,0x3a1dfd3,0x211fe3d,
wolfSSL 14:167253f4e170 9838 0x33e140a,0x3f9100d,0x32ee50e,0x014ea18 },
wolfSSL 14:167253f4e170 9839 { 0x16d8051,0x1bfda1a,0x068a097,0x2571d3d,0x1daec0c,0x39389af,
wolfSSL 14:167253f4e170 9840 0x194dc35,0x3f3058a,0x36d34e1,0x000a329 },
wolfSSL 14:167253f4e170 9841 0 },
wolfSSL 14:167253f4e170 9842 /* 48 */
wolfSSL 14:167253f4e170 9843 { { 0x09877ee,0x351f73f,0x0002d11,0x0420074,0x2c8b362,0x130982d,
wolfSSL 14:167253f4e170 9844 0x02c1175,0x3c11b40,0x0d86962,0x001305f },
wolfSSL 14:167253f4e170 9845 { 0x0daddf5,0x2f4252c,0x15c06d9,0x1d49339,0x1bea235,0x0b680ed,
wolfSSL 14:167253f4e170 9846 0x3356e67,0x1d1d198,0x1e9fed9,0x03dee93 },
wolfSSL 14:167253f4e170 9847 0 },
wolfSSL 14:167253f4e170 9848 /* 49 */
wolfSSL 14:167253f4e170 9849 { { 0x3e1263f,0x2fe8d3a,0x3ce6d0d,0x0d5c6b9,0x3557637,0x0a9bd48,
wolfSSL 14:167253f4e170 9850 0x0405538,0x0710749,0x2005213,0x038c7e5 },
wolfSSL 14:167253f4e170 9851 { 0x26b6ec6,0x2e485ba,0x3c44d1b,0x0b9cf0b,0x037a1d1,0x27428a5,
wolfSSL 14:167253f4e170 9852 0x0e7eac8,0x351ef04,0x259ce34,0x02a8e98 },
wolfSSL 14:167253f4e170 9853 0 },
wolfSSL 14:167253f4e170 9854 /* 50 */
wolfSSL 14:167253f4e170 9855 { { 0x2f3dcd3,0x3e77d4d,0x3360fbc,0x1434afd,0x36ceded,0x3d413d6,
wolfSSL 14:167253f4e170 9856 0x1710fad,0x36bb924,0x1627e79,0x008e637 },
wolfSSL 14:167253f4e170 9857 { 0x109569e,0x1c168db,0x3769cf4,0x2ed4527,0x0ea0619,0x17d80d3,
wolfSSL 14:167253f4e170 9858 0x1c03773,0x18843fe,0x1b21c04,0x015c5fd },
wolfSSL 14:167253f4e170 9859 0 },
wolfSSL 14:167253f4e170 9860 /* 51 */
wolfSSL 14:167253f4e170 9861 { { 0x1dd895e,0x08a7248,0x04519fe,0x001030a,0x18e5185,0x358dfb3,
wolfSSL 14:167253f4e170 9862 0x13d2391,0x0a37be8,0x0560e3c,0x019828b },
wolfSSL 14:167253f4e170 9863 { 0x27fcbd0,0x2a22bb5,0x30969cc,0x1e03aa7,0x1c84724,0x0ba4ad3,
wolfSSL 14:167253f4e170 9864 0x32f4817,0x0914cca,0x14c4f52,0x01893b9 },
wolfSSL 14:167253f4e170 9865 0 },
wolfSSL 14:167253f4e170 9866 /* 52 */
wolfSSL 14:167253f4e170 9867 { { 0x097eccc,0x1273936,0x00aa095,0x364fe62,0x04d49d1,0x10e9f08,
wolfSSL 14:167253f4e170 9868 0x3c24230,0x3ef01c8,0x2fb92bd,0x013ce4a },
wolfSSL 14:167253f4e170 9869 { 0x1e44fd9,0x27e3e9f,0x2156696,0x3915ecc,0x0b66cfb,0x1a3af0f,
wolfSSL 14:167253f4e170 9870 0x2fa8033,0x0e6736c,0x177ccdb,0x0228f9e },
wolfSSL 14:167253f4e170 9871 0 },
wolfSSL 14:167253f4e170 9872 /* 53 */
wolfSSL 14:167253f4e170 9873 { { 0x2c4b125,0x06207c1,0x0a8cdde,0x003db8f,0x1ae34e3,0x31e84fa,
wolfSSL 14:167253f4e170 9874 0x2999de5,0x11013bd,0x02370c2,0x00e2234 },
wolfSSL 14:167253f4e170 9875 { 0x0f91081,0x200d591,0x1504762,0x1857c05,0x23d9fcf,0x0cb34db,
wolfSSL 14:167253f4e170 9876 0x27edc86,0x08cd860,0x2471810,0x029798b },
wolfSSL 14:167253f4e170 9877 0 },
wolfSSL 14:167253f4e170 9878 /* 54 */
wolfSSL 14:167253f4e170 9879 { { 0x3acd6c8,0x097b8cb,0x3c661a8,0x15152f2,0x1699c63,0x237e64c,
wolfSSL 14:167253f4e170 9880 0x23edf79,0x16b7033,0x0e6466a,0x00b11da },
wolfSSL 14:167253f4e170 9881 { 0x0a64bc9,0x1bfe324,0x1f5cb34,0x08391de,0x0630a60,0x3017a21,
wolfSSL 14:167253f4e170 9882 0x09d064b,0x14a8365,0x041f9e6,0x01ed799 },
wolfSSL 14:167253f4e170 9883 0 },
wolfSSL 14:167253f4e170 9884 /* 55 */
wolfSSL 14:167253f4e170 9885 { { 0x128444a,0x2508b07,0x2a39216,0x362f84d,0x2e996c5,0x2c31ff3,
wolfSSL 14:167253f4e170 9886 0x07afe5f,0x1d1288e,0x3cb0c8d,0x02e2bdc },
wolfSSL 14:167253f4e170 9887 { 0x38b86fd,0x3a0ea8c,0x1cff5fd,0x1629629,0x3fee3f1,0x02b250c,
wolfSSL 14:167253f4e170 9888 0x2e8f6f2,0x0225727,0x15f7f3f,0x0280d8e },
wolfSSL 14:167253f4e170 9889 0 },
wolfSSL 14:167253f4e170 9890 /* 56 */
wolfSSL 14:167253f4e170 9891 { { 0x10f7770,0x0f1aee8,0x0e248c7,0x20684a8,0x3a6f16d,0x06f0ae7,
wolfSSL 14:167253f4e170 9892 0x0df6825,0x2d4cc40,0x301875f,0x012f8da },
wolfSSL 14:167253f4e170 9893 { 0x3b56dbb,0x1821ba7,0x24f8922,0x22c1f9e,0x0306fef,0x1b54bc8,
wolfSSL 14:167253f4e170 9894 0x2ccc056,0x00303ba,0x2871bdc,0x0232f26 },
wolfSSL 14:167253f4e170 9895 0 },
wolfSSL 14:167253f4e170 9896 /* 57 */
wolfSSL 14:167253f4e170 9897 { { 0x0dac4ab,0x0625730,0x3112e13,0x101c4bf,0x3a874a4,0x2873b95,
wolfSSL 14:167253f4e170 9898 0x32ae7c6,0x0d7e18c,0x13e0c08,0x01139d5 },
wolfSSL 14:167253f4e170 9899 { 0x334002d,0x00fffdd,0x025c6d5,0x22c2cd1,0x19d35cb,0x3a1ce2d,
wolfSSL 14:167253f4e170 9900 0x3702760,0x3f06257,0x03a5eb8,0x011c29a },
wolfSSL 14:167253f4e170 9901 0 },
wolfSSL 14:167253f4e170 9902 /* 58 */
wolfSSL 14:167253f4e170 9903 { { 0x0513482,0x1d87724,0x276a81b,0x0a807a4,0x3028720,0x339cc20,
wolfSSL 14:167253f4e170 9904 0x2441ee0,0x31bbf36,0x290c63d,0x0059041 },
wolfSSL 14:167253f4e170 9905 { 0x106a2ed,0x0d2819b,0x100bf50,0x114626c,0x1dd4d77,0x2e08632,
wolfSSL 14:167253f4e170 9906 0x14ae72a,0x2ed3f64,0x1fd7abc,0x035cd1e },
wolfSSL 14:167253f4e170 9907 0 },
wolfSSL 14:167253f4e170 9908 /* 59 */
wolfSSL 14:167253f4e170 9909 { { 0x2d4c6e5,0x3bec596,0x104d7ed,0x23d6c1b,0x0262cf0,0x15d72c5,
wolfSSL 14:167253f4e170 9910 0x2d5bb18,0x199ac4b,0x1e30771,0x020591a },
wolfSSL 14:167253f4e170 9911 { 0x21e291e,0x2e75e55,0x1661d7a,0x08b0778,0x3eb9daf,0x0d78144,
wolfSSL 14:167253f4e170 9912 0x1827eb1,0x0fe73d2,0x123f0dd,0x0028db7 },
wolfSSL 14:167253f4e170 9913 0 },
wolfSSL 14:167253f4e170 9914 /* 60 */
wolfSSL 14:167253f4e170 9915 { { 0x1d5533c,0x34cb1d0,0x228f098,0x27a1a11,0x17c5f5a,0x0d26f44,
wolfSSL 14:167253f4e170 9916 0x2228ade,0x2c460e6,0x3d6fdba,0x038cc77 },
wolfSSL 14:167253f4e170 9917 { 0x3cc6ed8,0x02ada1a,0x260e510,0x2f7bde8,0x37160c3,0x33a1435,
wolfSSL 14:167253f4e170 9918 0x23d9a7b,0x0ce2641,0x02a492e,0x034ed1e },
wolfSSL 14:167253f4e170 9919 0 },
wolfSSL 14:167253f4e170 9920 /* 61 */
wolfSSL 14:167253f4e170 9921 { { 0x3821f90,0x26dba3c,0x3aada14,0x3b59bad,0x292edd9,0x2804c45,
wolfSSL 14:167253f4e170 9922 0x3669531,0x296f42e,0x35a4c86,0x01ca049 },
wolfSSL 14:167253f4e170 9923 { 0x3ff47e5,0x2163df4,0x2441503,0x2f18405,0x15e1616,0x37f66ec,
wolfSSL 14:167253f4e170 9924 0x30f11a7,0x141658a,0x27ece14,0x00b018b },
wolfSSL 14:167253f4e170 9925 0 },
wolfSSL 14:167253f4e170 9926 /* 62 */
wolfSSL 14:167253f4e170 9927 { { 0x159ac2e,0x3e65bc0,0x2713a76,0x0db2f6c,0x3281e77,0x2391811,
wolfSSL 14:167253f4e170 9928 0x16d2880,0x1fbc4ab,0x1f92c4e,0x00a0a8d },
wolfSSL 14:167253f4e170 9929 { 0x0ce5cd2,0x152c7b0,0x02299c3,0x3244de7,0x2cf99ef,0x3a0b047,
wolfSSL 14:167253f4e170 9930 0x2caf383,0x0aaf664,0x113554d,0x031c735 },
wolfSSL 14:167253f4e170 9931 0 },
wolfSSL 14:167253f4e170 9932 /* 63 */
wolfSSL 14:167253f4e170 9933 { { 0x1b578f4,0x177a702,0x3a7a488,0x1638ebf,0x31884e2,0x2460bc7,
wolfSSL 14:167253f4e170 9934 0x36b1b75,0x3ce8e3d,0x340cf47,0x03143d9 },
wolfSSL 14:167253f4e170 9935 { 0x34b68ea,0x12b7ccd,0x1fe2a9c,0x08da659,0x0a406f3,0x1694c14,
wolfSSL 14:167253f4e170 9936 0x06a2228,0x16370be,0x3a72129,0x02e7b2c },
wolfSSL 14:167253f4e170 9937 0 },
wolfSSL 14:167253f4e170 9938 /* 64 */
wolfSSL 14:167253f4e170 9939 { { 0x0f8b16a,0x21043bd,0x266a56f,0x3fb11ec,0x197241a,0x36721f0,
wolfSSL 14:167253f4e170 9940 0x006b8e6,0x2ac6c29,0x202cd42,0x0200fcf },
wolfSSL 14:167253f4e170 9941 { 0x0dbec69,0x0c26a01,0x105f7f0,0x3dceeeb,0x3a83b85,0x363865f,
wolfSSL 14:167253f4e170 9942 0x097273a,0x2b70718,0x00e5067,0x03025d1 },
wolfSSL 14:167253f4e170 9943 0 },
wolfSSL 14:167253f4e170 9944 /* 65 */
wolfSSL 14:167253f4e170 9945 { { 0x379ab34,0x295bcb0,0x38d1846,0x22e1077,0x3a8ee06,0x1db1a3b,
wolfSSL 14:167253f4e170 9946 0x3144591,0x07cc080,0x2d5915f,0x03c6bcc },
wolfSSL 14:167253f4e170 9947 { 0x175bd50,0x0dd4c57,0x27bc99c,0x2ebdcbd,0x3837cff,0x235dc8f,
wolfSSL 14:167253f4e170 9948 0x13a4184,0x0722c18,0x130e2d4,0x008f43c },
wolfSSL 14:167253f4e170 9949 0 },
wolfSSL 14:167253f4e170 9950 /* 66 */
wolfSSL 14:167253f4e170 9951 { { 0x01500d9,0x2adbb7d,0x2da8857,0x397f2fa,0x10d890a,0x25c9654,
wolfSSL 14:167253f4e170 9952 0x3e86488,0x3eb754b,0x1d6c0a3,0x02c0a23 },
wolfSSL 14:167253f4e170 9953 { 0x10bcb08,0x083cc19,0x2e16853,0x04da575,0x271af63,0x2626a9d,
wolfSSL 14:167253f4e170 9954 0x3520a7b,0x32348c7,0x24ff408,0x03ff4dc },
wolfSSL 14:167253f4e170 9955 0 },
wolfSSL 14:167253f4e170 9956 /* 67 */
wolfSSL 14:167253f4e170 9957 { { 0x058e6cb,0x1a3992d,0x1d28539,0x080c5e9,0x2992dad,0x2a9d7d5,
wolfSSL 14:167253f4e170 9958 0x14ae0b7,0x09b7ce0,0x34ad78c,0x03d5643 },
wolfSSL 14:167253f4e170 9959 { 0x30ba55a,0x092f4f3,0x0bae0fc,0x12831de,0x20fc472,0x20ed9d2,
wolfSSL 14:167253f4e170 9960 0x29864f6,0x1288073,0x254f6f7,0x00635b6 },
wolfSSL 14:167253f4e170 9961 0 },
wolfSSL 14:167253f4e170 9962 /* 68 */
wolfSSL 14:167253f4e170 9963 { { 0x1be5a2b,0x0f88975,0x33c6ed9,0x20d64d3,0x06fe799,0x0989bff,
wolfSSL 14:167253f4e170 9964 0x1409262,0x085a90c,0x0d97990,0x0142eed },
wolfSSL 14:167253f4e170 9965 { 0x17ec63e,0x06471b9,0x0db2378,0x1006077,0x265422c,0x08db83d,
wolfSSL 14:167253f4e170 9966 0x28099b0,0x1270d06,0x11801fe,0x00ac400 },
wolfSSL 14:167253f4e170 9967 0 },
wolfSSL 14:167253f4e170 9968 /* 69 */
wolfSSL 14:167253f4e170 9969 { { 0x3391593,0x22d7166,0x30fcfc6,0x2896609,0x3c385f5,0x066b72e,
wolfSSL 14:167253f4e170 9970 0x04f3aad,0x2b831c5,0x19983fb,0x0375562 },
wolfSSL 14:167253f4e170 9971 { 0x0b82ff4,0x222e39d,0x34c993b,0x101c79c,0x2d2e03c,0x0f00c8a,
wolfSSL 14:167253f4e170 9972 0x3a9eaf4,0x1810669,0x151149d,0x039b931 },
wolfSSL 14:167253f4e170 9973 0 },
wolfSSL 14:167253f4e170 9974 /* 70 */
wolfSSL 14:167253f4e170 9975 { { 0x29af288,0x1956ec7,0x293155f,0x193deb6,0x1647e1a,0x2ca0839,
wolfSSL 14:167253f4e170 9976 0x297e4bc,0x15bfd0d,0x1b107ed,0x0147803 },
wolfSSL 14:167253f4e170 9977 { 0x31c327e,0x05a6e1d,0x02ad43d,0x02d2a5b,0x129cdb2,0x37ad1de,
wolfSSL 14:167253f4e170 9978 0x3d51f53,0x245df01,0x2414982,0x0388bd0 },
wolfSSL 14:167253f4e170 9979 0 },
wolfSSL 14:167253f4e170 9980 /* 71 */
wolfSSL 14:167253f4e170 9981 { { 0x35f1abb,0x17a3d18,0x0874cd4,0x2d5a14e,0x17edc0c,0x16a00d3,
wolfSSL 14:167253f4e170 9982 0x072c1fb,0x1232725,0x33d52dc,0x03dc24d },
wolfSSL 14:167253f4e170 9983 { 0x0af30d6,0x259aeea,0x369c401,0x12bc4de,0x295bf5f,0x0d8711f,
wolfSSL 14:167253f4e170 9984 0x26162a9,0x16c44e5,0x288e727,0x02f54b4 },
wolfSSL 14:167253f4e170 9985 0 },
wolfSSL 14:167253f4e170 9986 /* 72 */
wolfSSL 14:167253f4e170 9987 { { 0x05fa877,0x1571ea7,0x3d48ab1,0x1c9f4e8,0x017dad6,0x0f46276,
wolfSSL 14:167253f4e170 9988 0x343f9e7,0x1de990f,0x0e4c8aa,0x028343e },
wolfSSL 14:167253f4e170 9989 { 0x094f92d,0x3abf633,0x1b3a0bb,0x2f83137,0x0d818c8,0x20bae85,
wolfSSL 14:167253f4e170 9990 0x0c65f8b,0x1a8008b,0x0c7946d,0x0295b1e },
wolfSSL 14:167253f4e170 9991 0 },
wolfSSL 14:167253f4e170 9992 /* 73 */
wolfSSL 14:167253f4e170 9993 { { 0x1d09529,0x08e46c3,0x1fcf296,0x298f6b7,0x1803e0e,0x2d6fd20,
wolfSSL 14:167253f4e170 9994 0x37351f5,0x0d9e8b1,0x1f8731a,0x0362fbf },
wolfSSL 14:167253f4e170 9995 { 0x00157f4,0x06750bf,0x2650ab9,0x35ffb23,0x2f51cae,0x0b522c2,
wolfSSL 14:167253f4e170 9996 0x39cb400,0x191e337,0x0a5ce9f,0x021529a },
wolfSSL 14:167253f4e170 9997 0 },
wolfSSL 14:167253f4e170 9998 /* 74 */
wolfSSL 14:167253f4e170 9999 { { 0x3506ea5,0x17d9ed8,0x0d66dc3,0x22693f8,0x19286c4,0x3a57353,
wolfSSL 14:167253f4e170 10000 0x101d3bf,0x1aa54fc,0x20b9884,0x0172b3a },
wolfSSL 14:167253f4e170 10001 { 0x0eac44d,0x37d8327,0x1c3aa90,0x3d0d534,0x23db29a,0x3576eaf,
wolfSSL 14:167253f4e170 10002 0x1d3de8a,0x3bea423,0x11235e4,0x039260b },
wolfSSL 14:167253f4e170 10003 0 },
wolfSSL 14:167253f4e170 10004 /* 75 */
wolfSSL 14:167253f4e170 10005 { { 0x34cd55e,0x01288b0,0x1132231,0x2cc9a03,0x358695b,0x3e87650,
wolfSSL 14:167253f4e170 10006 0x345afa1,0x01267ec,0x3f616b2,0x02011ad },
wolfSSL 14:167253f4e170 10007 { 0x0e7d098,0x0d6078e,0x0b70b53,0x237d1bc,0x0d7f61e,0x132de31,
wolfSSL 14:167253f4e170 10008 0x1ea9ea4,0x2bd54c3,0x27b9082,0x03ac5f2 },
wolfSSL 14:167253f4e170 10009 0 },
wolfSSL 14:167253f4e170 10010 /* 76 */
wolfSSL 14:167253f4e170 10011 { { 0x2a145b9,0x06d661d,0x31ec175,0x03f06f1,0x3a5cf6b,0x249c56e,
wolfSSL 14:167253f4e170 10012 0x2035653,0x384c74f,0x0bafab5,0x0025ec0 },
wolfSSL 14:167253f4e170 10013 { 0x25f69e1,0x1b23a55,0x1199aa6,0x16ad6f9,0x077e8f7,0x293f661,
wolfSSL 14:167253f4e170 10014 0x33ba11d,0x3327980,0x07bafdb,0x03e571d },
wolfSSL 14:167253f4e170 10015 0 },
wolfSSL 14:167253f4e170 10016 /* 77 */
wolfSSL 14:167253f4e170 10017 { { 0x2bae45e,0x3c074ef,0x2955558,0x3c312f1,0x2a8ebe9,0x2f193f1,
wolfSSL 14:167253f4e170 10018 0x3705b1d,0x360deba,0x01e566e,0x00d4498 },
wolfSSL 14:167253f4e170 10019 { 0x21161cd,0x1bc787e,0x2f87933,0x3553197,0x1328ab8,0x093c879,
wolfSSL 14:167253f4e170 10020 0x17eee27,0x2adad1d,0x1236068,0x003be5c },
wolfSSL 14:167253f4e170 10021 0 },
wolfSSL 14:167253f4e170 10022 /* 78 */
wolfSSL 14:167253f4e170 10023 { { 0x0ca4226,0x2633dd5,0x2c8e025,0x0e3e190,0x05eede1,0x1a385e4,
wolfSSL 14:167253f4e170 10024 0x163f744,0x2f25522,0x1333b4f,0x03f05b6 },
wolfSSL 14:167253f4e170 10025 { 0x3c800ca,0x1becc79,0x2daabe9,0x0c499e2,0x1138063,0x3fcfa2d,
wolfSSL 14:167253f4e170 10026 0x2244976,0x1e85cf5,0x2f1b95d,0x0053292 },
wolfSSL 14:167253f4e170 10027 0 },
wolfSSL 14:167253f4e170 10028 /* 79 */
wolfSSL 14:167253f4e170 10029 { { 0x12f81d5,0x1dc6eaf,0x11967a4,0x1a407df,0x31a5f9d,0x2b67241,
wolfSSL 14:167253f4e170 10030 0x18bef7c,0x08c7762,0x063f59c,0x01015ec },
wolfSSL 14:167253f4e170 10031 { 0x1c05c0a,0x360bfa2,0x1f85bff,0x1bc7703,0x3e4911c,0x0d685b6,
wolfSSL 14:167253f4e170 10032 0x2fccaea,0x02c4cef,0x164f133,0x0070ed7 },
wolfSSL 14:167253f4e170 10033 0 },
wolfSSL 14:167253f4e170 10034 /* 80 */
wolfSSL 14:167253f4e170 10035 { { 0x0ec21fe,0x052ffa0,0x3e825fe,0x1ab0956,0x3f6ce11,0x3d29759,
wolfSSL 14:167253f4e170 10036 0x3c5a072,0x18ebe62,0x148db7e,0x03eb49c },
wolfSSL 14:167253f4e170 10037 { 0x1ab05b3,0x02dab0a,0x1ae690c,0x0f13894,0x137a9a8,0x0aab79f,
wolfSSL 14:167253f4e170 10038 0x3dc875c,0x06a1029,0x1e39f0e,0x01dce1f },
wolfSSL 14:167253f4e170 10039 0 },
wolfSSL 14:167253f4e170 10040 /* 81 */
wolfSSL 14:167253f4e170 10041 { { 0x16c0dd7,0x3b31269,0x2c741e9,0x3611821,0x2a5cffc,0x1416bb3,
wolfSSL 14:167253f4e170 10042 0x3a1408f,0x311fa3d,0x1c0bef0,0x02cdee1 },
wolfSSL 14:167253f4e170 10043 { 0x00e6a8f,0x1adb933,0x0f23359,0x2fdace2,0x2fd6d4b,0x0e73bd3,
wolfSSL 14:167253f4e170 10044 0x2453fac,0x0a356ae,0x2c8f9f6,0x02704d6 },
wolfSSL 14:167253f4e170 10045 0 },
wolfSSL 14:167253f4e170 10046 /* 82 */
wolfSSL 14:167253f4e170 10047 { { 0x0e35743,0x28c80a1,0x0def32a,0x2c6168f,0x1320d6a,0x37c6606,
wolfSSL 14:167253f4e170 10048 0x21b1761,0x2147ee0,0x21fc433,0x015c84d },
wolfSSL 14:167253f4e170 10049 { 0x1fc9168,0x36cda9c,0x003c1f0,0x1cd7971,0x15f98ba,0x1ef363d,
wolfSSL 14:167253f4e170 10050 0x0ca87e3,0x046f7d9,0x3c9e6bb,0x0372eb0 },
wolfSSL 14:167253f4e170 10051 0 },
wolfSSL 14:167253f4e170 10052 /* 83 */
wolfSSL 14:167253f4e170 10053 { { 0x118cbe2,0x3665a11,0x304ef01,0x062727a,0x3d242fc,0x11ffbaf,
wolfSSL 14:167253f4e170 10054 0x3663c7e,0x1a189c9,0x09e2d62,0x02e3072 },
wolfSSL 14:167253f4e170 10055 { 0x0e1d569,0x162f772,0x0cd051a,0x322df62,0x3563809,0x047cc7a,
wolfSSL 14:167253f4e170 10056 0x027fd9f,0x08b509b,0x3da2f94,0x01748ee },
wolfSSL 14:167253f4e170 10057 0 },
wolfSSL 14:167253f4e170 10058 /* 84 */
wolfSSL 14:167253f4e170 10059 { { 0x1c8f8be,0x31ca525,0x22bf0a1,0x200efcd,0x02961c4,0x3d8f52b,
wolfSSL 14:167253f4e170 10060 0x018403d,0x3a40279,0x1cb91ec,0x030427e },
wolfSSL 14:167253f4e170 10061 { 0x0945705,0x0257416,0x05c0c2d,0x25b77ae,0x3b9083d,0x2901126,
wolfSSL 14:167253f4e170 10062 0x292b8d7,0x07b8611,0x04f2eee,0x026f0cd },
wolfSSL 14:167253f4e170 10063 0 },
wolfSSL 14:167253f4e170 10064 /* 85 */
wolfSSL 14:167253f4e170 10065 { { 0x2913074,0x2b8d590,0x02b10d5,0x09d2295,0x255491b,0x0c41cca,
wolfSSL 14:167253f4e170 10066 0x1ca665b,0x133051a,0x1525f1a,0x00a5647 },
wolfSSL 14:167253f4e170 10067 { 0x04f983f,0x3d6daee,0x04e1e76,0x1067d7e,0x1be7eef,0x02ea862,
wolfSSL 14:167253f4e170 10068 0x00d4968,0x0ccb048,0x11f18ef,0x018dd95 },
wolfSSL 14:167253f4e170 10069 0 },
wolfSSL 14:167253f4e170 10070 /* 86 */
wolfSSL 14:167253f4e170 10071 { { 0x22976cc,0x17c5395,0x2c38bda,0x3983bc4,0x222bca3,0x332a614,
wolfSSL 14:167253f4e170 10072 0x3a30646,0x261eaef,0x1c808e2,0x02f6de7 },
wolfSSL 14:167253f4e170 10073 { 0x306a772,0x32d7272,0x2dcefd2,0x2abf94d,0x038f475,0x30ad76e,
wolfSSL 14:167253f4e170 10074 0x23e0227,0x3052b0a,0x001add3,0x023ba18 },
wolfSSL 14:167253f4e170 10075 0 },
wolfSSL 14:167253f4e170 10076 /* 87 */
wolfSSL 14:167253f4e170 10077 { { 0x0ade873,0x25a6069,0x248ccbe,0x13713ee,0x17ee9aa,0x28152e9,
wolfSSL 14:167253f4e170 10078 0x2e28995,0x2a92cb3,0x17a6f77,0x024b947 },
wolfSSL 14:167253f4e170 10079 { 0x190a34d,0x2ebea1c,0x1ed1948,0x16fdaf4,0x0d698f7,0x32bc451,
wolfSSL 14:167253f4e170 10080 0x0ee6e30,0x2aaab40,0x06f0a56,0x01460be },
wolfSSL 14:167253f4e170 10081 0 },
wolfSSL 14:167253f4e170 10082 /* 88 */
wolfSSL 14:167253f4e170 10083 { { 0x24cc99c,0x1884b1e,0x1ca1fba,0x1a0f9b6,0x2ff609b,0x2b26316,
wolfSSL 14:167253f4e170 10084 0x3b27cb5,0x29bc976,0x35d4073,0x024772a },
wolfSSL 14:167253f4e170 10085 { 0x3575a70,0x1b30f57,0x07fa01b,0x0e5be36,0x20cb361,0x26605cd,
wolfSSL 14:167253f4e170 10086 0x1d4e8c8,0x13cac59,0x2db9797,0x005e833 },
wolfSSL 14:167253f4e170 10087 0 },
wolfSSL 14:167253f4e170 10088 /* 89 */
wolfSSL 14:167253f4e170 10089 { { 0x36c8d3a,0x1878a81,0x124b388,0x0e4843e,0x1701aad,0x0ea0d76,
wolfSSL 14:167253f4e170 10090 0x10eae41,0x37d0653,0x36c7f4c,0x00ba338 },
wolfSSL 14:167253f4e170 10091 { 0x37a862b,0x1cf6ac0,0x08fa912,0x2dd8393,0x101ba9b,0x0eebcb7,
wolfSSL 14:167253f4e170 10092 0x2453883,0x1a3cfe5,0x2cb34f6,0x03d3331 },
wolfSSL 14:167253f4e170 10093 0 },
wolfSSL 14:167253f4e170 10094 /* 90 */
wolfSSL 14:167253f4e170 10095 { { 0x1f79687,0x3d4973c,0x281544e,0x2564bbe,0x17c5954,0x171e34a,
wolfSSL 14:167253f4e170 10096 0x231741a,0x3cf2784,0x0889a0d,0x02b036d },
wolfSSL 14:167253f4e170 10097 { 0x301747f,0x3f1c477,0x1f1386b,0x163bc5f,0x1592b93,0x332daed,
wolfSSL 14:167253f4e170 10098 0x080e4f5,0x1d28b96,0x26194c9,0x0256992 },
wolfSSL 14:167253f4e170 10099 0 },
wolfSSL 14:167253f4e170 10100 /* 91 */
wolfSSL 14:167253f4e170 10101 { { 0x15a4c93,0x07bf6b0,0x114172c,0x1ce0961,0x140269b,0x1b2c2eb,
wolfSSL 14:167253f4e170 10102 0x0dfb1c1,0x019ddaa,0x0ba2921,0x008c795 },
wolfSSL 14:167253f4e170 10103 { 0x2e6d2dc,0x37e45e2,0x2918a70,0x0fce444,0x34d6aa6,0x396dc88,
wolfSSL 14:167253f4e170 10104 0x27726b5,0x0c787d8,0x032d8a7,0x02ac2f8 },
wolfSSL 14:167253f4e170 10105 0 },
wolfSSL 14:167253f4e170 10106 /* 92 */
wolfSSL 14:167253f4e170 10107 { { 0x1131f2d,0x2b43a63,0x3101097,0x38cec13,0x0637f09,0x17a69d2,
wolfSSL 14:167253f4e170 10108 0x086196d,0x299e46b,0x0802cf6,0x03c6f32 },
wolfSSL 14:167253f4e170 10109 { 0x0daacb4,0x1a4503a,0x100925c,0x15583d9,0x23c4e40,0x1de4de9,
wolfSSL 14:167253f4e170 10110 0x1cc8fc4,0x2c9c564,0x0695aeb,0x02145a5 },
wolfSSL 14:167253f4e170 10111 0 },
wolfSSL 14:167253f4e170 10112 /* 93 */
wolfSSL 14:167253f4e170 10113 { { 0x1dcf593,0x17050fc,0x3e3bde3,0x0a6c062,0x178202b,0x2f7674f,
wolfSSL 14:167253f4e170 10114 0x0dadc29,0x15763a7,0x1d2daad,0x023d9f6 },
wolfSSL 14:167253f4e170 10115 { 0x081ea5f,0x045959d,0x190c841,0x3a78d31,0x0e7d2dd,0x1414fea,
wolfSSL 14:167253f4e170 10116 0x1d43f40,0x22d77ff,0x2b9c072,0x03e115c },
wolfSSL 14:167253f4e170 10117 0 },
wolfSSL 14:167253f4e170 10118 /* 94 */
wolfSSL 14:167253f4e170 10119 { { 0x3af71c9,0x29e9c65,0x25655e1,0x111e9cd,0x3a14494,0x3875418,
wolfSSL 14:167253f4e170 10120 0x34ae070,0x0b06686,0x310616b,0x03b7b89 },
wolfSSL 14:167253f4e170 10121 { 0x1734121,0x00d3d44,0x29f0b2f,0x1552897,0x31cac6e,0x1030bb3,
wolfSSL 14:167253f4e170 10122 0x0148f3a,0x35fd237,0x29b44eb,0x027f49f },
wolfSSL 14:167253f4e170 10123 0 },
wolfSSL 14:167253f4e170 10124 /* 95 */
wolfSSL 14:167253f4e170 10125 { { 0x2e2cb16,0x1d962bd,0x19b63cc,0x0b3f964,0x3e3eb7d,0x1a35560,
wolfSSL 14:167253f4e170 10126 0x0c58161,0x3ce1d6a,0x3b6958f,0x029030b },
wolfSSL 14:167253f4e170 10127 { 0x2dcc158,0x3b1583f,0x30568c9,0x31957c8,0x27ad804,0x28c1f84,
wolfSSL 14:167253f4e170 10128 0x3967049,0x37b3f64,0x3b87dc6,0x0266f26 },
wolfSSL 14:167253f4e170 10129 0 },
wolfSSL 14:167253f4e170 10130 /* 96 */
wolfSSL 14:167253f4e170 10131 { { 0x27dafc6,0x2548764,0x0d1984a,0x1a57027,0x252c1fb,0x24d9b77,
wolfSSL 14:167253f4e170 10132 0x1581a0f,0x1f99276,0x10ba16d,0x026af88 },
wolfSSL 14:167253f4e170 10133 { 0x0915220,0x2be1292,0x16c6480,0x1a93760,0x2fa7317,0x1a07296,
wolfSSL 14:167253f4e170 10134 0x1539871,0x112c31f,0x25787f3,0x01e2070 },
wolfSSL 14:167253f4e170 10135 0 },
wolfSSL 14:167253f4e170 10136 /* 97 */
wolfSSL 14:167253f4e170 10137 { { 0x0bcf3ff,0x266d478,0x34f6933,0x31449fd,0x00d02cb,0x340765a,
wolfSSL 14:167253f4e170 10138 0x3465a2d,0x225023e,0x319a30e,0x00579b8 },
wolfSSL 14:167253f4e170 10139 { 0x20e05f4,0x35b834f,0x0404646,0x3710d62,0x3fad7bd,0x13e1434,
wolfSSL 14:167253f4e170 10140 0x21c7d1c,0x1cb3af9,0x2cf1911,0x003957e },
wolfSSL 14:167253f4e170 10141 0 },
wolfSSL 14:167253f4e170 10142 /* 98 */
wolfSSL 14:167253f4e170 10143 { { 0x0787564,0x36601be,0x1ce67e9,0x084c7a1,0x21a3317,0x2067a35,
wolfSSL 14:167253f4e170 10144 0x0158cab,0x195ddac,0x1766fe9,0x035cf42 },
wolfSSL 14:167253f4e170 10145 { 0x2b7206e,0x20d0947,0x3b42424,0x03f1862,0x0a51929,0x38c2948,
wolfSSL 14:167253f4e170 10146 0x0bb8595,0x2942d77,0x3748f15,0x0249428 },
wolfSSL 14:167253f4e170 10147 0 },
wolfSSL 14:167253f4e170 10148 /* 99 */
wolfSSL 14:167253f4e170 10149 { { 0x2577410,0x3c23e2f,0x28c6caf,0x00d41de,0x0fd408a,0x30298e9,
wolfSSL 14:167253f4e170 10150 0x363289e,0x2302fc7,0x082c1cc,0x01dd050 },
wolfSSL 14:167253f4e170 10151 { 0x30991cd,0x103e9ba,0x029605a,0x19927f7,0x0c1ca08,0x0c93f50,
wolfSSL 14:167253f4e170 10152 0x28a3c7b,0x082e4e9,0x34d12eb,0x0232c13 },
wolfSSL 14:167253f4e170 10153 0 },
wolfSSL 14:167253f4e170 10154 /* 100 */
wolfSSL 14:167253f4e170 10155 { { 0x106171c,0x0b4155a,0x0c3fb1c,0x336c090,0x19073e9,0x2241a10,
wolfSSL 14:167253f4e170 10156 0x0e6b4fd,0x0ed476e,0x1ef4712,0x039390a },
wolfSSL 14:167253f4e170 10157 { 0x0ec36f4,0x3754f0e,0x2a270b8,0x007fd2d,0x0f9d2dc,0x1e6a692,
wolfSSL 14:167253f4e170 10158 0x066e078,0x1954974,0x2ff3c6e,0x00def28 },
wolfSSL 14:167253f4e170 10159 0 },
wolfSSL 14:167253f4e170 10160 /* 101 */
wolfSSL 14:167253f4e170 10161 { { 0x3562470,0x0b8f1f7,0x0ac94cd,0x28b0259,0x244f272,0x031e4ef,
wolfSSL 14:167253f4e170 10162 0x2d5df98,0x2c8a9f1,0x2dc3002,0x016644f },
wolfSSL 14:167253f4e170 10163 { 0x350592a,0x0e6a0d5,0x1e027a1,0x2039e0f,0x399e01d,0x2817593,
wolfSSL 14:167253f4e170 10164 0x0c0375e,0x3889b3e,0x24ab013,0x010de1b },
wolfSSL 14:167253f4e170 10165 0 },
wolfSSL 14:167253f4e170 10166 /* 102 */
wolfSSL 14:167253f4e170 10167 { { 0x256b5a6,0x0ac3b67,0x28f9ff3,0x29b67f1,0x30750d9,0x25e11a9,
wolfSSL 14:167253f4e170 10168 0x15e8455,0x279ebb0,0x298b7e7,0x0218e32 },
wolfSSL 14:167253f4e170 10169 { 0x2fc24b2,0x2b82582,0x28f22f5,0x2bd36b3,0x305398e,0x3b2e9e3,
wolfSSL 14:167253f4e170 10170 0x365dd0a,0x29bc0ed,0x36a7b3a,0x007b374 },
wolfSSL 14:167253f4e170 10171 0 },
wolfSSL 14:167253f4e170 10172 /* 103 */
wolfSSL 14:167253f4e170 10173 { { 0x05ff2f3,0x2b3589b,0x29785d3,0x300a1ce,0x0a2d516,0x0844355,
wolfSSL 14:167253f4e170 10174 0x14c9fad,0x3ccb6b6,0x385d459,0x0361743 },
wolfSSL 14:167253f4e170 10175 { 0x0b11da3,0x002e344,0x18c49f7,0x0c29e0c,0x1d2c22c,0x08237b3,
wolfSSL 14:167253f4e170 10176 0x2988f49,0x0f18955,0x1c3b4ed,0x02813c6 },
wolfSSL 14:167253f4e170 10177 0 },
wolfSSL 14:167253f4e170 10178 /* 104 */
wolfSSL 14:167253f4e170 10179 { { 0x17f93bd,0x249323b,0x11f6087,0x174e4bd,0x3cb64ac,0x086dc6b,
wolfSSL 14:167253f4e170 10180 0x2e330a8,0x142c1f2,0x2ea5c09,0x024acbb },
wolfSSL 14:167253f4e170 10181 { 0x1b6e235,0x3132521,0x00f085a,0x2a4a4db,0x1ab2ca4,0x0142224,
wolfSSL 14:167253f4e170 10182 0x3aa6b3e,0x09db203,0x2215834,0x007b9e0 },
wolfSSL 14:167253f4e170 10183 0 },
wolfSSL 14:167253f4e170 10184 /* 105 */
wolfSSL 14:167253f4e170 10185 { { 0x23e79f7,0x28b8039,0x1906a60,0x2cbce67,0x1f590e7,0x181f027,
wolfSSL 14:167253f4e170 10186 0x21054a6,0x3854240,0x2d857a6,0x03cfcb3 },
wolfSSL 14:167253f4e170 10187 { 0x10d9b55,0x1443cfc,0x2648200,0x2b36190,0x09d2fcf,0x22f439f,
wolfSSL 14:167253f4e170 10188 0x231aa7e,0x3884395,0x0543da3,0x003d5a9 },
wolfSSL 14:167253f4e170 10189 0 },
wolfSSL 14:167253f4e170 10190 /* 106 */
wolfSSL 14:167253f4e170 10191 { { 0x043e0df,0x06ffe84,0x3e6d5b2,0x3327001,0x26c74b6,0x12a145e,
wolfSSL 14:167253f4e170 10192 0x256ec0d,0x3898c69,0x3411969,0x02f63c5 },
wolfSSL 14:167253f4e170 10193 { 0x2b7494a,0x2eee1af,0x38388a9,0x1bd17ce,0x21567d4,0x13969e6,
wolfSSL 14:167253f4e170 10194 0x3a12a7a,0x3e8277d,0x03530cc,0x00b4687 },
wolfSSL 14:167253f4e170 10195 0 },
wolfSSL 14:167253f4e170 10196 /* 107 */
wolfSSL 14:167253f4e170 10197 { { 0x06508da,0x38e04d4,0x15a7192,0x312875e,0x3336180,0x2a6512c,
wolfSSL 14:167253f4e170 10198 0x1b59497,0x2e91b37,0x25eb91f,0x02841e9 },
wolfSSL 14:167253f4e170 10199 { 0x394d639,0x0747143,0x37d7e6d,0x1d62962,0x08b4af3,0x34df287,
wolfSSL 14:167253f4e170 10200 0x3c5584b,0x26bc869,0x20af87a,0x0060f5d },
wolfSSL 14:167253f4e170 10201 0 },
wolfSSL 14:167253f4e170 10202 /* 108 */
wolfSSL 14:167253f4e170 10203 { { 0x1de59a4,0x1a5c443,0x2f8729d,0x01c3a2f,0x0f1ad8d,0x3cbaf9e,
wolfSSL 14:167253f4e170 10204 0x1b49634,0x35d508a,0x39dc269,0x0075105 },
wolfSSL 14:167253f4e170 10205 { 0x390d30e,0x37033e0,0x110cb32,0x14c37a0,0x20a3b27,0x2f00ce6,
wolfSSL 14:167253f4e170 10206 0x2f1dc52,0x34988c6,0x0c29606,0x01dc7e7 },
wolfSSL 14:167253f4e170 10207 0 },
wolfSSL 14:167253f4e170 10208 /* 109 */
wolfSSL 14:167253f4e170 10209 { { 0x1040739,0x24f9de1,0x2939999,0x2e6009a,0x244539d,0x17e3f09,
wolfSSL 14:167253f4e170 10210 0x00f6f2f,0x1c63b3d,0x2310362,0x019109e },
wolfSSL 14:167253f4e170 10211 { 0x1428aa8,0x3cb61e1,0x09a84f4,0x0ffafed,0x07b7adc,0x08f406b,
wolfSSL 14:167253f4e170 10212 0x1b2c6df,0x035b480,0x3496ae9,0x012766d },
wolfSSL 14:167253f4e170 10213 0 },
wolfSSL 14:167253f4e170 10214 /* 110 */
wolfSSL 14:167253f4e170 10215 { { 0x35d1099,0x2362f10,0x1a08cc7,0x13a3a34,0x12adbcd,0x32da290,
wolfSSL 14:167253f4e170 10216 0x02e2a02,0x151140b,0x01b3f60,0x0240df6 },
wolfSSL 14:167253f4e170 10217 { 0x34c7b61,0x2eb09c1,0x172e7cd,0x2ad5eff,0x2fe2031,0x25b54d4,
wolfSSL 14:167253f4e170 10218 0x0cec965,0x18e7187,0x26a7cc0,0x00230f7 },
wolfSSL 14:167253f4e170 10219 0 },
wolfSSL 14:167253f4e170 10220 /* 111 */
wolfSSL 14:167253f4e170 10221 { { 0x2d552ab,0x374083d,0x01f120f,0x2601736,0x156baff,0x04d44a4,
wolfSSL 14:167253f4e170 10222 0x3b7c3e9,0x1acbc1b,0x0424579,0x031a425 },
wolfSSL 14:167253f4e170 10223 { 0x1231bd1,0x0eba710,0x020517b,0x21d7316,0x21eac6e,0x275a848,
wolfSSL 14:167253f4e170 10224 0x0837abf,0x0eb0082,0x302cafe,0x00fe8f6 },
wolfSSL 14:167253f4e170 10225 0 },
wolfSSL 14:167253f4e170 10226 /* 112 */
wolfSSL 14:167253f4e170 10227 { { 0x1058880,0x28f9941,0x03f2d75,0x3bd90e5,0x17da365,0x2ac9249,
wolfSSL 14:167253f4e170 10228 0x07861cf,0x023fd05,0x1b0fdb8,0x031712f },
wolfSSL 14:167253f4e170 10229 { 0x272b56b,0x04f8d2c,0x043a735,0x25446e4,0x1c8327e,0x221125a,
wolfSSL 14:167253f4e170 10230 0x0ce37df,0x2dad7f6,0x39446c2,0x00b55b6 },
wolfSSL 14:167253f4e170 10231 0 },
wolfSSL 14:167253f4e170 10232 /* 113 */
wolfSSL 14:167253f4e170 10233 { { 0x346ac6b,0x05e0bff,0x2425246,0x0981e8b,0x1d19f79,0x2692378,
wolfSSL 14:167253f4e170 10234 0x3ea3c40,0x2e90beb,0x19de503,0x003d5af },
wolfSSL 14:167253f4e170 10235 { 0x05cda49,0x353b44d,0x299d137,0x3f205bc,0x2821158,0x3ad0d00,
wolfSSL 14:167253f4e170 10236 0x06a54aa,0x2d7c79f,0x39d1173,0x01000ee },
wolfSSL 14:167253f4e170 10237 0 },
wolfSSL 14:167253f4e170 10238 /* 114 */
wolfSSL 14:167253f4e170 10239 { { 0x0803387,0x3a06268,0x14043b8,0x3d4e72f,0x1ece115,0x0a1dfc8,
wolfSSL 14:167253f4e170 10240 0x17208dd,0x0be790a,0x122a07f,0x014dd95 },
wolfSSL 14:167253f4e170 10241 { 0x0a4182d,0x202886a,0x1f79a49,0x1e8c867,0x0a2bbd0,0x28668b5,
wolfSSL 14:167253f4e170 10242 0x0d0a2e1,0x115259d,0x3586c5d,0x01e815b },
wolfSSL 14:167253f4e170 10243 0 },
wolfSSL 14:167253f4e170 10244 /* 115 */
wolfSSL 14:167253f4e170 10245 { { 0x18a2a47,0x2c95627,0x2773646,0x1230f7c,0x15b5829,0x2fc354e,
wolfSSL 14:167253f4e170 10246 0x2c000ea,0x099d547,0x2f17a1a,0x01df520 },
wolfSSL 14:167253f4e170 10247 { 0x3853948,0x06f6561,0x3feeb8a,0x2f5b3ef,0x3a6f817,0x01a0791,
wolfSSL 14:167253f4e170 10248 0x2ec0578,0x2c392ad,0x12b2b38,0x0104540 },
wolfSSL 14:167253f4e170 10249 0 },
wolfSSL 14:167253f4e170 10250 /* 116 */
wolfSSL 14:167253f4e170 10251 { { 0x1e28ced,0x0fc3d1b,0x2c473c7,0x1826c4f,0x21d5da7,0x39718e4,
wolfSSL 14:167253f4e170 10252 0x38ce9e6,0x0251986,0x172fbea,0x0337c11 },
wolfSSL 14:167253f4e170 10253 { 0x053c3b0,0x0f162db,0x043c1cb,0x04111ee,0x297fe3c,0x32e5e03,
wolfSSL 14:167253f4e170 10254 0x2b8ae12,0x0c427ec,0x1da9738,0x03b9c0f },
wolfSSL 14:167253f4e170 10255 0 },
wolfSSL 14:167253f4e170 10256 /* 117 */
wolfSSL 14:167253f4e170 10257 { { 0x357e43a,0x054503f,0x11b8345,0x34ec6e0,0x2d44660,0x3d0ae61,
wolfSSL 14:167253f4e170 10258 0x3b5dff8,0x33884ac,0x09da162,0x00a82b6 },
wolfSSL 14:167253f4e170 10259 { 0x3c277ba,0x129a51a,0x027664e,0x1530507,0x0c788c9,0x2afd89d,
wolfSSL 14:167253f4e170 10260 0x1aa64cc,0x1196450,0x367ac2b,0x0358b42 },
wolfSSL 14:167253f4e170 10261 0 },
wolfSSL 14:167253f4e170 10262 /* 118 */
wolfSSL 14:167253f4e170 10263 { { 0x0054ac4,0x1761ecb,0x378839c,0x167c9f7,0x2570058,0x0604a35,
wolfSSL 14:167253f4e170 10264 0x37cbf3b,0x0909bb7,0x3f2991c,0x02ce688 },
wolfSSL 14:167253f4e170 10265 { 0x0b16ae5,0x212857c,0x351b952,0x2c684db,0x30c6a05,0x09c01e0,
wolfSSL 14:167253f4e170 10266 0x23c137f,0x1331475,0x092c067,0x0013b40 },
wolfSSL 14:167253f4e170 10267 0 },
wolfSSL 14:167253f4e170 10268 /* 119 */
wolfSSL 14:167253f4e170 10269 { { 0x2e90393,0x0617466,0x24e61f4,0x0a528f5,0x03047b4,0x2153f05,
wolfSSL 14:167253f4e170 10270 0x0001a69,0x30e1eb8,0x3c10177,0x0282a47 },
wolfSSL 14:167253f4e170 10271 { 0x22c831e,0x28fc06b,0x3e16ff0,0x208adc9,0x0bb76ae,0x28c1d6d,
wolfSSL 14:167253f4e170 10272 0x12c8a15,0x031063c,0x1889ed2,0x002133e },
wolfSSL 14:167253f4e170 10273 0 },
wolfSSL 14:167253f4e170 10274 /* 120 */
wolfSSL 14:167253f4e170 10275 { { 0x0a6becf,0x14277bf,0x3328d98,0x201f7fe,0x12fceae,0x1de3a2e,
wolfSSL 14:167253f4e170 10276 0x0a15c44,0x3ddf976,0x1b273ab,0x0355e55 },
wolfSSL 14:167253f4e170 10277 { 0x1b5d4f1,0x369e78c,0x3a1c210,0x12cf3e9,0x3aa52f0,0x309f082,
wolfSSL 14:167253f4e170 10278 0x112089d,0x107c753,0x24202d1,0x023853a },
wolfSSL 14:167253f4e170 10279 0 },
wolfSSL 14:167253f4e170 10280 /* 121 */
wolfSSL 14:167253f4e170 10281 { { 0x2897042,0x140d17c,0x2c4aeed,0x07d0d00,0x18d0533,0x22f7ec8,
wolfSSL 14:167253f4e170 10282 0x19c194c,0x3456323,0x2372aa4,0x0165f86 },
wolfSSL 14:167253f4e170 10283 { 0x30bd68c,0x1fb06b3,0x0945032,0x372ac09,0x06d4be0,0x27f8fa1,
wolfSSL 14:167253f4e170 10284 0x1c8d7ac,0x137a96e,0x236199b,0x0328fc0 },
wolfSSL 14:167253f4e170 10285 0 },
wolfSSL 14:167253f4e170 10286 /* 122 */
wolfSSL 14:167253f4e170 10287 { { 0x170bd20,0x2842d58,0x1de7592,0x3c5b4fd,0x20ea897,0x12cab78,
wolfSSL 14:167253f4e170 10288 0x363ff14,0x01f928c,0x17e309c,0x02f79ff },
wolfSSL 14:167253f4e170 10289 { 0x0f5432c,0x2edb4ae,0x044b516,0x32f810d,0x2210dc1,0x23e56d6,
wolfSSL 14:167253f4e170 10290 0x301e6ff,0x34660f6,0x10e0a7d,0x02d88eb },
wolfSSL 14:167253f4e170 10291 0 },
wolfSSL 14:167253f4e170 10292 /* 123 */
wolfSSL 14:167253f4e170 10293 { { 0x0c7b65b,0x2f59d58,0x2289a75,0x2408e92,0x1ab8c55,0x1ec99e5,
wolfSSL 14:167253f4e170 10294 0x220fd0d,0x04defe0,0x24658ec,0x035aa8b },
wolfSSL 14:167253f4e170 10295 { 0x138bb85,0x2f002d4,0x295c10a,0x08760ce,0x28c31d1,0x1c0a8cb,
wolfSSL 14:167253f4e170 10296 0x0ff00b1,0x144eac9,0x2e02dcc,0x0044598 },
wolfSSL 14:167253f4e170 10297 0 },
wolfSSL 14:167253f4e170 10298 /* 124 */
wolfSSL 14:167253f4e170 10299 { { 0x3b42b87,0x050057b,0x0dff781,0x1c06db1,0x1bd9f5d,0x1f5f04a,
wolfSSL 14:167253f4e170 10300 0x2cccd7a,0x143e19b,0x1cb94b7,0x036cfb8 },
wolfSSL 14:167253f4e170 10301 { 0x34837cf,0x3cf6c3c,0x0d4fb26,0x22ee55e,0x1e7eed1,0x315995f,
wolfSSL 14:167253f4e170 10302 0x2cdf937,0x1a96574,0x0425220,0x0221a99 },
wolfSSL 14:167253f4e170 10303 0 },
wolfSSL 14:167253f4e170 10304 /* 125 */
wolfSSL 14:167253f4e170 10305 { { 0x1b569ea,0x0d33ed9,0x19c13c2,0x107dc84,0x2200111,0x0569867,
wolfSSL 14:167253f4e170 10306 0x2dc85da,0x05ef22e,0x0eb018a,0x029c33d },
wolfSSL 14:167253f4e170 10307 { 0x04a6a65,0x3e5eba3,0x378f224,0x09c04d0,0x036e5cf,0x3df8258,
wolfSSL 14:167253f4e170 10308 0x3a609e4,0x1eddef8,0x2abd174,0x02a91dc },
wolfSSL 14:167253f4e170 10309 0 },
wolfSSL 14:167253f4e170 10310 /* 126 */
wolfSSL 14:167253f4e170 10311 { { 0x2a60cc0,0x1d84c5e,0x115f676,0x1840da0,0x2c79163,0x2f06ed6,
wolfSSL 14:167253f4e170 10312 0x198bb4b,0x3e5d37b,0x1dc30fa,0x018469b },
wolfSSL 14:167253f4e170 10313 { 0x15ee47a,0x1e32f30,0x16a530e,0x2093836,0x02e8962,0x3767b62,
wolfSSL 14:167253f4e170 10314 0x335adf3,0x27220db,0x2f81642,0x0173ffe },
wolfSSL 14:167253f4e170 10315 0 },
wolfSSL 14:167253f4e170 10316 /* 127 */
wolfSSL 14:167253f4e170 10317 { { 0x37a99cd,0x1533fe6,0x05a1c0d,0x27610f1,0x17bf3b9,0x0b1ce78,
wolfSSL 14:167253f4e170 10318 0x0a908f6,0x265300e,0x3237dc1,0x01b969a },
wolfSSL 14:167253f4e170 10319 { 0x3a5db77,0x2d15382,0x0d63ef8,0x1feb3d8,0x0b7b880,0x19820de,
wolfSSL 14:167253f4e170 10320 0x11c0c67,0x2af3396,0x38d242d,0x0120688 },
wolfSSL 14:167253f4e170 10321 0 },
wolfSSL 14:167253f4e170 10322 /* 128 */
wolfSSL 14:167253f4e170 10323 { { 0x1d0b34a,0x05ef00d,0x00a7e34,0x1ae0c9f,0x1440b38,0x300d8b4,
wolfSSL 14:167253f4e170 10324 0x37262da,0x3e50e3e,0x14ce0cd,0x00b1044 },
wolfSSL 14:167253f4e170 10325 { 0x195a0b1,0x173bc6b,0x03622ba,0x2a19f55,0x1c09b37,0x07921b2,
wolfSSL 14:167253f4e170 10326 0x16cdd20,0x24a5c9b,0x2bf42ff,0x00811de },
wolfSSL 14:167253f4e170 10327 0 },
wolfSSL 14:167253f4e170 10328 /* 129 */
wolfSSL 14:167253f4e170 10329 { { 0x0d65dbf,0x145cf06,0x1ad82f7,0x038ce7b,0x077bf94,0x33c4007,
wolfSSL 14:167253f4e170 10330 0x22d26bd,0x25ad9c0,0x09ac773,0x02b1990 },
wolfSSL 14:167253f4e170 10331 { 0x2261cc3,0x2ecdbf1,0x3e908b0,0x3246439,0x0213f7b,0x1179b04,
wolfSSL 14:167253f4e170 10332 0x01cebaa,0x0be1595,0x175cc12,0x033a39a },
wolfSSL 14:167253f4e170 10333 0 },
wolfSSL 14:167253f4e170 10334 /* 130 */
wolfSSL 14:167253f4e170 10335 { { 0x00a67d2,0x086d06f,0x248a0f1,0x0291134,0x362d476,0x166d1cd,
wolfSSL 14:167253f4e170 10336 0x044f1d6,0x2d2a038,0x365250b,0x0023f78 },
wolfSSL 14:167253f4e170 10337 { 0x08bf287,0x3b0f6a1,0x1d6eace,0x20b4cda,0x2c2a621,0x0912520,
wolfSSL 14:167253f4e170 10338 0x02dfdc9,0x1b35cd6,0x3d2565d,0x00bdf8b },
wolfSSL 14:167253f4e170 10339 0 },
wolfSSL 14:167253f4e170 10340 /* 131 */
wolfSSL 14:167253f4e170 10341 { { 0x3770fa7,0x2e4b6f0,0x03f9ae4,0x170de41,0x1095e8d,0x1dd845c,
wolfSSL 14:167253f4e170 10342 0x334e9d1,0x00ab953,0x12e9077,0x03196fa },
wolfSSL 14:167253f4e170 10343 { 0x2fd0a40,0x228c0fd,0x384b275,0x38ef339,0x3e7d822,0x3e5d9ef,
wolfSSL 14:167253f4e170 10344 0x24f5854,0x0ece9eb,0x247d119,0x012ffe3 },
wolfSSL 14:167253f4e170 10345 0 },
wolfSSL 14:167253f4e170 10346 /* 132 */
wolfSSL 14:167253f4e170 10347 { { 0x0ff1480,0x07487c0,0x1b16cd4,0x1f41d53,0x22ab8fb,0x2f83cfa,
wolfSSL 14:167253f4e170 10348 0x01d2efb,0x259f6b2,0x2e65772,0x00f9392 },
wolfSSL 14:167253f4e170 10349 { 0x05303e6,0x23cdb4f,0x23977e1,0x12e4898,0x03bd999,0x0c930f0,
wolfSSL 14:167253f4e170 10350 0x170e261,0x180a27b,0x2fd58ec,0x014e22b },
wolfSSL 14:167253f4e170 10351 0 },
wolfSSL 14:167253f4e170 10352 /* 133 */
wolfSSL 14:167253f4e170 10353 { { 0x25d7713,0x0c5fad7,0x09daad1,0x3b9d779,0x109b985,0x1d3ec98,
wolfSSL 14:167253f4e170 10354 0x35bc4fc,0x2f838cb,0x0d14f75,0x0173e42 },
wolfSSL 14:167253f4e170 10355 { 0x2657b12,0x10d4423,0x19e6760,0x296e5bb,0x2bfd421,0x25c3330,
wolfSSL 14:167253f4e170 10356 0x29f51f8,0x0338838,0x24060f0,0x029a62e },
wolfSSL 14:167253f4e170 10357 0 },
wolfSSL 14:167253f4e170 10358 /* 134 */
wolfSSL 14:167253f4e170 10359 { { 0x3748fec,0x2c5a1bb,0x2cf973d,0x289fa74,0x3e6e755,0x38997bf,
wolfSSL 14:167253f4e170 10360 0x0b6544c,0x2b6358c,0x38a7aeb,0x02c50bb },
wolfSSL 14:167253f4e170 10361 { 0x3d5770a,0x06be7c5,0x012fad3,0x19cb2cd,0x266af3b,0x3ccd677,
wolfSSL 14:167253f4e170 10362 0x160d1bd,0x141d5af,0x2965851,0x034625a },
wolfSSL 14:167253f4e170 10363 0 },
wolfSSL 14:167253f4e170 10364 /* 135 */
wolfSSL 14:167253f4e170 10365 { { 0x3c41c08,0x255eacc,0x22e1ec5,0x2b151a3,0x087de94,0x311cbdb,
wolfSSL 14:167253f4e170 10366 0x016b73a,0x368e462,0x20b7981,0x0099ec3 },
wolfSSL 14:167253f4e170 10367 { 0x262b988,0x1539763,0x21e76e5,0x15445b4,0x1d8ddc7,0x34a9be6,
wolfSSL 14:167253f4e170 10368 0x10faf03,0x24e4d18,0x07aa111,0x02d538a },
wolfSSL 14:167253f4e170 10369 0 },
wolfSSL 14:167253f4e170 10370 /* 136 */
wolfSSL 14:167253f4e170 10371 { { 0x38a876b,0x048ad45,0x04b40a0,0x3fc2144,0x251ff96,0x13ca7dd,
wolfSSL 14:167253f4e170 10372 0x0b31ab1,0x3539814,0x28b5f87,0x0212aec },
wolfSSL 14:167253f4e170 10373 { 0x270790a,0x350e7e0,0x346bd5e,0x276178f,0x22d6cb5,0x3078884,
wolfSSL 14:167253f4e170 10374 0x355c1b6,0x15901d7,0x3671765,0x03950db },
wolfSSL 14:167253f4e170 10375 0 },
wolfSSL 14:167253f4e170 10376 /* 137 */
wolfSSL 14:167253f4e170 10377 { { 0x286e8d5,0x2409788,0x13be53f,0x2d21911,0x0353c95,0x10238e8,
wolfSSL 14:167253f4e170 10378 0x32f5bde,0x3a67b60,0x28b5b9c,0x001013d },
wolfSSL 14:167253f4e170 10379 { 0x381e8e5,0x0cef7a9,0x2f5bcad,0x06058f0,0x33cdf50,0x04672a8,
wolfSSL 14:167253f4e170 10380 0x1769600,0x31c055d,0x3df0ac1,0x00e9098 },
wolfSSL 14:167253f4e170 10381 0 },
wolfSSL 14:167253f4e170 10382 /* 138 */
wolfSSL 14:167253f4e170 10383 { { 0x2eb596d,0x197b326,0x12b4c29,0x39c08f2,0x101ea03,0x3804e58,
wolfSSL 14:167253f4e170 10384 0x04b4b62,0x28d9d1c,0x13f905e,0x0032a3f },
wolfSSL 14:167253f4e170 10385 { 0x11b2b61,0x08e9095,0x0d06925,0x270e43f,0x21eb7a8,0x0e4a98f,
wolfSSL 14:167253f4e170 10386 0x31d2be0,0x030cf9f,0x2644ddb,0x025b728 },
wolfSSL 14:167253f4e170 10387 0 },
wolfSSL 14:167253f4e170 10388 /* 139 */
wolfSSL 14:167253f4e170 10389 { { 0x07510af,0x2ed0e8e,0x2a01203,0x2a2a68d,0x0846fea,0x3e540de,
wolfSSL 14:167253f4e170 10390 0x3a57702,0x1677348,0x2123aad,0x010d8f8 },
wolfSSL 14:167253f4e170 10391 { 0x0246a47,0x0e871d0,0x124dca4,0x34b9577,0x2b362b8,0x363ebe5,
wolfSSL 14:167253f4e170 10392 0x3086045,0x26313e6,0x15cd8bb,0x0210384 },
wolfSSL 14:167253f4e170 10393 0 },
wolfSSL 14:167253f4e170 10394 /* 140 */
wolfSSL 14:167253f4e170 10395 { { 0x023e8a7,0x0817884,0x3a0bf12,0x3376371,0x3c808a8,0x18e9777,
wolfSSL 14:167253f4e170 10396 0x12a2721,0x35b538a,0x2bd30de,0x017835a },
wolfSSL 14:167253f4e170 10397 { 0x0fc0f64,0x1c8709f,0x2d8807a,0x0743957,0x242eec0,0x347e76c,
wolfSSL 14:167253f4e170 10398 0x27bef91,0x289689a,0x0f42945,0x01f7a92 },
wolfSSL 14:167253f4e170 10399 0 },
wolfSSL 14:167253f4e170 10400 /* 141 */
wolfSSL 14:167253f4e170 10401 { { 0x1060a81,0x3dbc739,0x1615abd,0x1cbe3e5,0x3e79f9c,0x1ab09a2,
wolfSSL 14:167253f4e170 10402 0x136c540,0x05b473f,0x2beebfd,0x02af0a8 },
wolfSSL 14:167253f4e170 10403 { 0x3e2eac7,0x19be474,0x04668ac,0x18f4b74,0x36f10ba,0x0a0b4c6,
wolfSSL 14:167253f4e170 10404 0x10e3770,0x3bf059e,0x3946c7e,0x013a8d4 },
wolfSSL 14:167253f4e170 10405 0 },
wolfSSL 14:167253f4e170 10406 /* 142 */
wolfSSL 14:167253f4e170 10407 { { 0x266309d,0x28be354,0x1a3eed8,0x3020651,0x10a51c6,0x1e31770,
wolfSSL 14:167253f4e170 10408 0x0af45a5,0x3ff0f3b,0x2891c94,0x00e9db9 },
wolfSSL 14:167253f4e170 10409 { 0x17b0d0f,0x33a291f,0x0a5f9aa,0x25a3d61,0x2963ace,0x39a5fef,
wolfSSL 14:167253f4e170 10410 0x230c724,0x1919146,0x10a465e,0x02084a8 },
wolfSSL 14:167253f4e170 10411 0 },
wolfSSL 14:167253f4e170 10412 /* 143 */
wolfSSL 14:167253f4e170 10413 { { 0x3ab8caa,0x31870f3,0x2390ef7,0x2103850,0x218eb8e,0x3a5ccf2,
wolfSSL 14:167253f4e170 10414 0x1dff677,0x2c59334,0x371599c,0x02a9f2a },
wolfSSL 14:167253f4e170 10415 { 0x0837bd1,0x3249cef,0x35d702f,0x3430dab,0x1c06407,0x108f692,
wolfSSL 14:167253f4e170 10416 0x221292f,0x05f0c5d,0x073fe06,0x01038e0 },
wolfSSL 14:167253f4e170 10417 0 },
wolfSSL 14:167253f4e170 10418 /* 144 */
wolfSSL 14:167253f4e170 10419 { { 0x3bf9b7c,0x2020929,0x30d0f4f,0x080fef8,0x3365d23,0x1f3e738,
wolfSSL 14:167253f4e170 10420 0x3e53209,0x1549afe,0x300b305,0x038d811 },
wolfSSL 14:167253f4e170 10421 { 0x0c6c2c7,0x2e6445b,0x3ee64dc,0x022e932,0x0726837,0x0deb67b,
wolfSSL 14:167253f4e170 10422 0x1ed4346,0x3857f73,0x277a3de,0x01950b5 },
wolfSSL 14:167253f4e170 10423 0 },
wolfSSL 14:167253f4e170 10424 /* 145 */
wolfSSL 14:167253f4e170 10425 { { 0x36c377a,0x0adb41e,0x08be3f3,0x11e40d1,0x36cb038,0x036a2bd,
wolfSSL 14:167253f4e170 10426 0x3dd3a82,0x1bc875b,0x2ee09bb,0x02994d2 },
wolfSSL 14:167253f4e170 10427 { 0x035facf,0x05e0344,0x07e630a,0x0ce772d,0x335e55a,0x111fce4,
wolfSSL 14:167253f4e170 10428 0x250fe1c,0x3bc89ba,0x32fdc9a,0x03cf2d9 },
wolfSSL 14:167253f4e170 10429 0 },
wolfSSL 14:167253f4e170 10430 /* 146 */
wolfSSL 14:167253f4e170 10431 { { 0x355fd83,0x1c67f8e,0x1d10eb3,0x1b21d77,0x0e0d7a4,0x173a9e1,
wolfSSL 14:167253f4e170 10432 0x2c9fa90,0x1c39cce,0x22eaae8,0x01f2bea },
wolfSSL 14:167253f4e170 10433 { 0x153b338,0x0534107,0x26c69b8,0x283be1f,0x3e0acc0,0x059cac3,
wolfSSL 14:167253f4e170 10434 0x13d1081,0x148bbee,0x3c1b9bd,0x002aac4 },
wolfSSL 14:167253f4e170 10435 0 },
wolfSSL 14:167253f4e170 10436 /* 147 */
wolfSSL 14:167253f4e170 10437 { { 0x2681297,0x3389e34,0x146addc,0x2c6d425,0x2cb350e,0x1986abc,
wolfSSL 14:167253f4e170 10438 0x0431737,0x04ba4b7,0x2028470,0x012e469 },
wolfSSL 14:167253f4e170 10439 { 0x2f8ddcf,0x3c4255c,0x1af4dcf,0x07a6a44,0x208ebf6,0x0dc90c3,
wolfSSL 14:167253f4e170 10440 0x34360ac,0x072ad23,0x0537232,0x01254d3 },
wolfSSL 14:167253f4e170 10441 0 },
wolfSSL 14:167253f4e170 10442 /* 148 */
wolfSSL 14:167253f4e170 10443 { { 0x07b7e9d,0x3df5c7c,0x116f83d,0x28c4f35,0x3a478ef,0x3011fb8,
wolfSSL 14:167253f4e170 10444 0x2f264b6,0x317b9e3,0x04fd65a,0x032bd1b },
wolfSSL 14:167253f4e170 10445 { 0x2aa8266,0x3431de4,0x04bba04,0x19a44da,0x0edf454,0x392c5ac,
wolfSSL 14:167253f4e170 10446 0x265168a,0x1dc3d5b,0x25704c6,0x00533a7 },
wolfSSL 14:167253f4e170 10447 0 },
wolfSSL 14:167253f4e170 10448 /* 149 */
wolfSSL 14:167253f4e170 10449 { { 0x25e8f91,0x1178fa5,0x2492994,0x2eb2c3c,0x0d3aca1,0x0322828,
wolfSSL 14:167253f4e170 10450 0x1cc70f9,0x269c74c,0x0a53e4c,0x006edc2 },
wolfSSL 14:167253f4e170 10451 { 0x18bdd7a,0x2a79a55,0x26b1d5c,0x0200628,0x0734a05,0x3273c7b,
wolfSSL 14:167253f4e170 10452 0x13aa714,0x0040ac2,0x2f2da30,0x03e7449 },
wolfSSL 14:167253f4e170 10453 0 },
wolfSSL 14:167253f4e170 10454 /* 150 */
wolfSSL 14:167253f4e170 10455 { { 0x3f9563e,0x2f29eab,0x14a0749,0x3fad264,0x1dd077a,0x3d7c59c,
wolfSSL 14:167253f4e170 10456 0x3a0311b,0x331a789,0x0b9729e,0x0201ebf },
wolfSSL 14:167253f4e170 10457 { 0x1b08b77,0x2a4cdf2,0x3e387f8,0x21510f1,0x286c3a7,0x1dbf62e,
wolfSSL 14:167253f4e170 10458 0x3afa594,0x3363217,0x0d16568,0x01d46b7 },
wolfSSL 14:167253f4e170 10459 0 },
wolfSSL 14:167253f4e170 10460 /* 151 */
wolfSSL 14:167253f4e170 10461 { { 0x0715c0d,0x28e2d04,0x17f78ae,0x1c63dda,0x1d113ea,0x0fefc1b,
wolfSSL 14:167253f4e170 10462 0x1eab149,0x1d0fd99,0x0682537,0x00a7b11 },
wolfSSL 14:167253f4e170 10463 { 0x10bebbc,0x11c672d,0x14223d9,0x2ff9141,0x1399ee5,0x34b7b6c,
wolfSSL 14:167253f4e170 10464 0x0d5b3a8,0x01df643,0x0e392a4,0x03fe4dc },
wolfSSL 14:167253f4e170 10465 0 },
wolfSSL 14:167253f4e170 10466 /* 152 */
wolfSSL 14:167253f4e170 10467 { { 0x2b75b65,0x0b5a6f1,0x11c559a,0x3549999,0x24188f8,0x37a75f4,
wolfSSL 14:167253f4e170 10468 0x29f33e3,0x34068a2,0x38ba2a9,0x025dd91 },
wolfSSL 14:167253f4e170 10469 { 0x29af2c7,0x0988b64,0x0923885,0x1b539a4,0x1334f5d,0x226947a,
wolfSSL 14:167253f4e170 10470 0x2cc7e5a,0x20beb39,0x13fac2f,0x01d298c },
wolfSSL 14:167253f4e170 10471 0 },
wolfSSL 14:167253f4e170 10472 /* 153 */
wolfSSL 14:167253f4e170 10473 { { 0x35f079c,0x137f76d,0x2fbbb2f,0x254638d,0x185b07c,0x1f34db7,
wolfSSL 14:167253f4e170 10474 0x2cfcf0e,0x218f46d,0x2150ff4,0x02add6f },
wolfSSL 14:167253f4e170 10475 { 0x33fc9b7,0x0d9f005,0x0fd081b,0x0834965,0x2b90a74,0x102448d,
wolfSSL 14:167253f4e170 10476 0x3dbf03c,0x167d857,0x02e0b44,0x013afab },
wolfSSL 14:167253f4e170 10477 0 },
wolfSSL 14:167253f4e170 10478 /* 154 */
wolfSSL 14:167253f4e170 10479 { { 0x09f2c53,0x317f9d7,0x1411eb6,0x0463aba,0x0d25220,0x256b176,
wolfSSL 14:167253f4e170 10480 0x087633f,0x2bff322,0x07b2c1b,0x037e662 },
wolfSSL 14:167253f4e170 10481 { 0x10aaecb,0x23bb4a1,0x2272bb7,0x06c075a,0x09d4918,0x0736f2b,
wolfSSL 14:167253f4e170 10482 0x0dd511b,0x101625e,0x0a7779f,0x009ec10 },
wolfSSL 14:167253f4e170 10483 0 },
wolfSSL 14:167253f4e170 10484 /* 155 */
wolfSSL 14:167253f4e170 10485 { { 0x33b2eb2,0x0176dfd,0x2118904,0x022386c,0x2e0df85,0x2588c9f,
wolfSSL 14:167253f4e170 10486 0x1b71525,0x28fd540,0x137e4cf,0x02ce4f7 },
wolfSSL 14:167253f4e170 10487 { 0x3d75165,0x0c39ecf,0x3554a12,0x30af34c,0x2d66344,0x3ded408,
wolfSSL 14:167253f4e170 10488 0x36f1be0,0x0d065b0,0x012d046,0x0025623 },
wolfSSL 14:167253f4e170 10489 0 },
wolfSSL 14:167253f4e170 10490 /* 156 */
wolfSSL 14:167253f4e170 10491 { { 0x2601c3b,0x1824fc0,0x335fe08,0x3e33d70,0x0fb0252,0x252bfca,
wolfSSL 14:167253f4e170 10492 0x1cf2808,0x1922e55,0x1a9db9f,0x020721e },
wolfSSL 14:167253f4e170 10493 { 0x2f56c51,0x39a1f31,0x218c040,0x1a4fc5d,0x3fed471,0x0164d4e,
wolfSSL 14:167253f4e170 10494 0x388a419,0x06f1113,0x0f55fc1,0x03e8352 },
wolfSSL 14:167253f4e170 10495 0 },
wolfSSL 14:167253f4e170 10496 /* 157 */
wolfSSL 14:167253f4e170 10497 { { 0x1608e4d,0x3872778,0x022cbc6,0x044d60a,0x3010dda,0x15fb0b5,
wolfSSL 14:167253f4e170 10498 0x37ddc11,0x19f5bda,0x156b6a3,0x023a838 },
wolfSSL 14:167253f4e170 10499 { 0x383b3b4,0x1380bc8,0x353ca35,0x250fc07,0x169966b,0x3780f29,
wolfSSL 14:167253f4e170 10500 0x36632b2,0x2d6b13f,0x124fa00,0x00fd6ae },
wolfSSL 14:167253f4e170 10501 0 },
wolfSSL 14:167253f4e170 10502 /* 158 */
wolfSSL 14:167253f4e170 10503 { { 0x1739efb,0x2ec3656,0x2c0d337,0x3d39faf,0x1c751b0,0x04699f4,
wolfSSL 14:167253f4e170 10504 0x252dd64,0x095b8b6,0x0872b74,0x022f1da },
wolfSSL 14:167253f4e170 10505 { 0x2d3d253,0x38edca0,0x379fa5b,0x287d635,0x3a9f679,0x059d9ee,
wolfSSL 14:167253f4e170 10506 0x0ac168e,0x3cd3e87,0x19060fc,0x02ce1bc },
wolfSSL 14:167253f4e170 10507 0 },
wolfSSL 14:167253f4e170 10508 /* 159 */
wolfSSL 14:167253f4e170 10509 { { 0x3edcfc2,0x0f04d4b,0x2f0d31f,0x1898be2,0x25396bf,0x15ca230,
wolfSSL 14:167253f4e170 10510 0x02b4eae,0x2713668,0x0f71b06,0x0132d18 },
wolfSSL 14:167253f4e170 10511 { 0x38095ea,0x1ed34d6,0x3603ae6,0x165bf01,0x192bbf8,0x1852859,
wolfSSL 14:167253f4e170 10512 0x075f66b,0x1488f85,0x10895ef,0x014b035 },
wolfSSL 14:167253f4e170 10513 0 },
wolfSSL 14:167253f4e170 10514 /* 160 */
wolfSSL 14:167253f4e170 10515 { { 0x1339848,0x3084385,0x0c8d231,0x3a1c1de,0x0e87a28,0x255b85c,
wolfSSL 14:167253f4e170 10516 0x1de6616,0x2702e74,0x1382bb0,0x012b0f2 },
wolfSSL 14:167253f4e170 10517 { 0x198987d,0x381545a,0x34d619b,0x312b827,0x18b2376,0x28fe4cf,
wolfSSL 14:167253f4e170 10518 0x20b7651,0x017d077,0x0c7e397,0x00e0365 },
wolfSSL 14:167253f4e170 10519 0 },
wolfSSL 14:167253f4e170 10520 /* 161 */
wolfSSL 14:167253f4e170 10521 { { 0x1542e75,0x0d56aa0,0x39b701a,0x287b806,0x396c724,0x0935c21,
wolfSSL 14:167253f4e170 10522 0x3a29776,0x0debdac,0x171de26,0x00b38f8 },
wolfSSL 14:167253f4e170 10523 { 0x1d5bc1a,0x3fad27d,0x22b5cfe,0x1f89ddf,0x0a65560,0x144dd5b,
wolfSSL 14:167253f4e170 10524 0x2aac2f9,0x139353f,0x0520b62,0x00b9b36 },
wolfSSL 14:167253f4e170 10525 0 },
wolfSSL 14:167253f4e170 10526 /* 162 */
wolfSSL 14:167253f4e170 10527 { { 0x031c31d,0x16552e3,0x1a0c368,0x0016fc8,0x168533d,0x171e7b2,
wolfSSL 14:167253f4e170 10528 0x17626e7,0x275502f,0x14742c6,0x03285dd },
wolfSSL 14:167253f4e170 10529 { 0x2d2dbb2,0x3b6bffd,0x1d18cc6,0x2f45d2a,0x0fd0d8c,0x2915e3a,
wolfSSL 14:167253f4e170 10530 0x1e8793a,0x0b39a1d,0x3139cab,0x02a5da9 },
wolfSSL 14:167253f4e170 10531 0 },
wolfSSL 14:167253f4e170 10532 /* 163 */
wolfSSL 14:167253f4e170 10533 { { 0x3fb353d,0x147c6e4,0x3a720a6,0x22d5ff3,0x1d75cab,0x06c54a0,
wolfSSL 14:167253f4e170 10534 0x08cfa73,0x12666aa,0x3170a1f,0x021c829 },
wolfSSL 14:167253f4e170 10535 { 0x13e1b90,0x3a34dda,0x1fc38c3,0x02c5bdb,0x2d345dc,0x14aa1d0,
wolfSSL 14:167253f4e170 10536 0x28d00ab,0x224f23a,0x329c769,0x025c67b },
wolfSSL 14:167253f4e170 10537 0 },
wolfSSL 14:167253f4e170 10538 /* 164 */
wolfSSL 14:167253f4e170 10539 { { 0x0e35909,0x3bb6356,0x0116820,0x370cf77,0x29366d8,0x3881409,
wolfSSL 14:167253f4e170 10540 0x3999d06,0x013075f,0x176e157,0x02941ca },
wolfSSL 14:167253f4e170 10541 { 0x0e70b2e,0x28dfab1,0x2a8a002,0x15da242,0x084dcf6,0x116ca97,
wolfSSL 14:167253f4e170 10542 0x31bf186,0x1dc9735,0x09df7b7,0x0264e27 },
wolfSSL 14:167253f4e170 10543 0 },
wolfSSL 14:167253f4e170 10544 /* 165 */
wolfSSL 14:167253f4e170 10545 { { 0x2da7a4b,0x3023c9e,0x1366238,0x00ff4e2,0x03abe9d,0x19bd44b,
wolfSSL 14:167253f4e170 10546 0x272e897,0x20b91ad,0x2aa202c,0x02a2201 },
wolfSSL 14:167253f4e170 10547 { 0x380184e,0x08112b4,0x0b85660,0x31049aa,0x3a8cb78,0x36113c5,
wolfSSL 14:167253f4e170 10548 0x1670c0a,0x373f9e7,0x3fb4738,0x00010ef },
wolfSSL 14:167253f4e170 10549 0 },
wolfSSL 14:167253f4e170 10550 /* 166 */
wolfSSL 14:167253f4e170 10551 { { 0x2d5192e,0x26d770d,0x32af8d5,0x34d1642,0x1acf885,0x05805e0,
wolfSSL 14:167253f4e170 10552 0x166d0a1,0x1219a0d,0x301ba6c,0x014bcfb },
wolfSSL 14:167253f4e170 10553 { 0x2dcb64d,0x19cca83,0x379f398,0x08e01a0,0x10a482c,0x0103cc2,
wolfSSL 14:167253f4e170 10554 0x0be5fa7,0x1f9d45b,0x1899ef2,0x00ca5af },
wolfSSL 14:167253f4e170 10555 0 },
wolfSSL 14:167253f4e170 10556 /* 167 */
wolfSSL 14:167253f4e170 10557 { { 0x14d81d7,0x2aea251,0x1b3c476,0x3bd47ae,0x29eade7,0x0715e61,
wolfSSL 14:167253f4e170 10558 0x1a21cd8,0x1c7a586,0x2bfaee5,0x00ee43f },
wolfSSL 14:167253f4e170 10559 { 0x096f7cb,0x0c08f95,0x1bc4939,0x361fed4,0x255be41,0x26fad73,
wolfSSL 14:167253f4e170 10560 0x31dd489,0x02c600f,0x29d9f81,0x01ba201 },
wolfSSL 14:167253f4e170 10561 0 },
wolfSSL 14:167253f4e170 10562 /* 168 */
wolfSSL 14:167253f4e170 10563 { { 0x03ea1db,0x1eac46d,0x1292ce3,0x2a54967,0x20a7ff1,0x3e13c61,
wolfSSL 14:167253f4e170 10564 0x1b02218,0x2b44e14,0x3eadefa,0x029c88a },
wolfSSL 14:167253f4e170 10565 { 0x30a9144,0x31e3b0a,0x19c5a2a,0x147cbe9,0x05a0240,0x051f38e,
wolfSSL 14:167253f4e170 10566 0x11eca56,0x31a4247,0x123bc2a,0x02fa535 },
wolfSSL 14:167253f4e170 10567 0 },
wolfSSL 14:167253f4e170 10568 /* 169 */
wolfSSL 14:167253f4e170 10569 { { 0x3226ce7,0x1251782,0x0b7072f,0x11e59fa,0x2b8afd7,0x169b18f,
wolfSSL 14:167253f4e170 10570 0x2a46f18,0x31d9bb7,0x2fe9be8,0x01de0b7 },
wolfSSL 14:167253f4e170 10571 { 0x1b38626,0x34aa90f,0x3ad1760,0x21ddbd9,0x3460ae7,0x1126736,
wolfSSL 14:167253f4e170 10572 0x1b86fc5,0x0b92cd0,0x167a289,0x000e0e1 },
wolfSSL 14:167253f4e170 10573 0 },
wolfSSL 14:167253f4e170 10574 /* 170 */
wolfSSL 14:167253f4e170 10575 { { 0x1ec1a0f,0x36bbf5e,0x1c972d8,0x3f73ace,0x13bbcd6,0x23d86a5,
wolfSSL 14:167253f4e170 10576 0x175ffc5,0x2d083d5,0x2c4adf7,0x036f661 },
wolfSSL 14:167253f4e170 10577 { 0x1f39eb7,0x2a20505,0x176c81a,0x3d6e636,0x16ee2fc,0x3cbdc5f,
wolfSSL 14:167253f4e170 10578 0x25475dc,0x2ef4151,0x3c46860,0x0238934 },
wolfSSL 14:167253f4e170 10579 0 },
wolfSSL 14:167253f4e170 10580 /* 171 */
wolfSSL 14:167253f4e170 10581 { { 0x2587390,0x3639526,0x0588749,0x13c32fb,0x212bb19,0x09660f1,
wolfSSL 14:167253f4e170 10582 0x207da4b,0x2bf211b,0x1c4407b,0x01506a6 },
wolfSSL 14:167253f4e170 10583 { 0x24c8842,0x105a498,0x05ffdb2,0x0ab61b0,0x26044c1,0x3dff3d8,
wolfSSL 14:167253f4e170 10584 0x1d14b44,0x0d74716,0x049f57d,0x030024b },
wolfSSL 14:167253f4e170 10585 0 },
wolfSSL 14:167253f4e170 10586 /* 172 */
wolfSSL 14:167253f4e170 10587 { { 0x32e61ef,0x31d70f7,0x35cad3c,0x320b86c,0x07e8841,0x027ca7d,
wolfSSL 14:167253f4e170 10588 0x2d30d19,0x2513718,0x2347286,0x01d7901 },
wolfSSL 14:167253f4e170 10589 { 0x3c237d0,0x107f16e,0x01c9e7d,0x3c3b13c,0x0c9537b,0x20af54d,
wolfSSL 14:167253f4e170 10590 0x051a162,0x2161a47,0x258c784,0x016df2d },
wolfSSL 14:167253f4e170 10591 0 },
wolfSSL 14:167253f4e170 10592 /* 173 */
wolfSSL 14:167253f4e170 10593 { { 0x228ead1,0x29c2122,0x07f6964,0x023f4ed,0x1802dc5,0x19f96ce,
wolfSSL 14:167253f4e170 10594 0x24bfd17,0x25e866b,0x2ba8df0,0x01eb84f },
wolfSSL 14:167253f4e170 10595 { 0x2dd384e,0x05bbe3a,0x3f06fd2,0x366dacb,0x30361a2,0x2f36d7c,
wolfSSL 14:167253f4e170 10596 0x0b98784,0x38ff481,0x074e2a8,0x01e1f60 },
wolfSSL 14:167253f4e170 10597 0 },
wolfSSL 14:167253f4e170 10598 /* 174 */
wolfSSL 14:167253f4e170 10599 { { 0x17fbb1c,0x0975add,0x1debc5e,0x2cb2880,0x3e47bdd,0x3488cff,
wolfSSL 14:167253f4e170 10600 0x15e9a36,0x2121129,0x0199ef2,0x017088a },
wolfSSL 14:167253f4e170 10601 { 0x0315250,0x352a162,0x17c1773,0x0ae09c2,0x321b21a,0x3bd74cf,
wolfSSL 14:167253f4e170 10602 0x3c4ea1d,0x3cac2ad,0x3abbaf0,0x039174d },
wolfSSL 14:167253f4e170 10603 0 },
wolfSSL 14:167253f4e170 10604 /* 175 */
wolfSSL 14:167253f4e170 10605 { { 0x0511c8a,0x3c78d0a,0x2cd3d2d,0x322f729,0x3ebb229,0x09f0e69,
wolfSSL 14:167253f4e170 10606 0x0a71a76,0x2e74d5e,0x12284df,0x03b5ef0 },
wolfSSL 14:167253f4e170 10607 { 0x3dea561,0x0a9b7e4,0x0ed1cf2,0x237523c,0x05443f1,0x2eb48fa,
wolfSSL 14:167253f4e170 10608 0x3861405,0x1b49f62,0x0c945ca,0x02ab25f },
wolfSSL 14:167253f4e170 10609 0 },
wolfSSL 14:167253f4e170 10610 /* 176 */
wolfSSL 14:167253f4e170 10611 { { 0x16bd00a,0x13a9d28,0x3cc1eb5,0x2b7d702,0x2d839e9,0x3e6ff01,
wolfSSL 14:167253f4e170 10612 0x2bb7f11,0x3713824,0x3b31163,0x00c63e5 },
wolfSSL 14:167253f4e170 10613 { 0x30d7138,0x0316fb0,0x0220ecc,0x08eaf0c,0x244e8df,0x0088d81,
wolfSSL 14:167253f4e170 10614 0x37972fb,0x3fd34ae,0x2a19a84,0x03e907e },
wolfSSL 14:167253f4e170 10615 0 },
wolfSSL 14:167253f4e170 10616 /* 177 */
wolfSSL 14:167253f4e170 10617 { { 0x2642269,0x0b65d29,0x03bd440,0x33a6ede,0x3c81814,0x2507982,
wolfSSL 14:167253f4e170 10618 0x0d38e47,0x3a788e6,0x32c1d26,0x00e2eda },
wolfSSL 14:167253f4e170 10619 { 0x2577f87,0x392895a,0x3e1cc64,0x14f7047,0x08b52d2,0x08a01ca,
wolfSSL 14:167253f4e170 10620 0x336abf6,0x00697fc,0x105ce76,0x0253742 },
wolfSSL 14:167253f4e170 10621 0 },
wolfSSL 14:167253f4e170 10622 /* 178 */
wolfSSL 14:167253f4e170 10623 { { 0x293f92a,0x33df737,0x3315156,0x32e26d7,0x0a01333,0x26579d4,
wolfSSL 14:167253f4e170 10624 0x004df9c,0x0aba409,0x067d25c,0x02481de },
wolfSSL 14:167253f4e170 10625 { 0x3f39d44,0x1c78042,0x13d7e24,0x0825aed,0x35f2c90,0x3270f63,
wolfSSL 14:167253f4e170 10626 0x04b7b35,0x3ad4531,0x28bd29b,0x0207a10 },
wolfSSL 14:167253f4e170 10627 0 },
wolfSSL 14:167253f4e170 10628 /* 179 */
wolfSSL 14:167253f4e170 10629 { { 0x077199f,0x270aeb1,0x0dd96dd,0x3b9ad7b,0x28cb8ee,0x3903f43,
wolfSSL 14:167253f4e170 10630 0x37db3fe,0x292c62b,0x362dbbf,0x006e52a },
wolfSSL 14:167253f4e170 10631 { 0x247f143,0x0362cf3,0x216344f,0x3f18fd1,0x351e623,0x31664e0,
wolfSSL 14:167253f4e170 10632 0x0f270fc,0x243bbc6,0x2280555,0x001a8e3 },
wolfSSL 14:167253f4e170 10633 0 },
wolfSSL 14:167253f4e170 10634 /* 180 */
wolfSSL 14:167253f4e170 10635 { { 0x3355b49,0x2c04e6c,0x399b2e5,0x182d3af,0x020e265,0x09a7cf7,
wolfSSL 14:167253f4e170 10636 0x0ffa6bd,0x353e302,0x02083d9,0x029ecdb },
wolfSSL 14:167253f4e170 10637 { 0x33e8830,0x0570e86,0x1c0b64d,0x386a27e,0x0d5fcea,0x0b45a4c,
wolfSSL 14:167253f4e170 10638 0x2ee4a2e,0x0a8833f,0x2b4a282,0x02f9531 },
wolfSSL 14:167253f4e170 10639 0 },
wolfSSL 14:167253f4e170 10640 /* 181 */
wolfSSL 14:167253f4e170 10641 { { 0x191167c,0x36cf7e3,0x225ed6c,0x1e79e99,0x0517c3f,0x11ab1fd,
wolfSSL 14:167253f4e170 10642 0x05648f3,0x08aedc4,0x1abeae0,0x02fcc29 },
wolfSSL 14:167253f4e170 10643 { 0x3828a68,0x1e16fa4,0x30368e7,0x0c9fcfb,0x25161c3,0x24851ac,
wolfSSL 14:167253f4e170 10644 0x1b5feb5,0x344eb84,0x0de2732,0x0347208 },
wolfSSL 14:167253f4e170 10645 0 },
wolfSSL 14:167253f4e170 10646 /* 182 */
wolfSSL 14:167253f4e170 10647 { { 0x038b363,0x384d1e4,0x2519043,0x151ac17,0x158c11f,0x009b2b4,
wolfSSL 14:167253f4e170 10648 0x257abe6,0x2368d3f,0x3ed68a1,0x02df45e },
wolfSSL 14:167253f4e170 10649 { 0x29c2559,0x2962478,0x3d8444c,0x1d96fff,0x04f7a03,0x1391a52,
wolfSSL 14:167253f4e170 10650 0x0de4af7,0x3319126,0x15e6412,0x00e65ff },
wolfSSL 14:167253f4e170 10651 0 },
wolfSSL 14:167253f4e170 10652 /* 183 */
wolfSSL 14:167253f4e170 10653 { { 0x3d61507,0x1d1a0a2,0x0d2af20,0x354d299,0x329e132,0x2a28578,
wolfSSL 14:167253f4e170 10654 0x2ddfb08,0x04fa3ff,0x1293c6c,0x003bae2 },
wolfSSL 14:167253f4e170 10655 { 0x3e259f8,0x1a68fa9,0x3e67e9b,0x39b44f9,0x1ce1db7,0x347e9a1,
wolfSSL 14:167253f4e170 10656 0x3318f6a,0x2dbbc9d,0x2f8c922,0x008a245 },
wolfSSL 14:167253f4e170 10657 0 },
wolfSSL 14:167253f4e170 10658 /* 184 */
wolfSSL 14:167253f4e170 10659 { { 0x212ab5b,0x2b896c2,0x0136959,0x07e55ef,0x0cc1117,0x05b8ac3,
wolfSSL 14:167253f4e170 10660 0x18429ed,0x025fa01,0x11d6e93,0x03b016b },
wolfSSL 14:167253f4e170 10661 { 0x03f3708,0x2e96fab,0x1d77157,0x0d4c2d6,0x131baf9,0x0608d39,
wolfSSL 14:167253f4e170 10662 0x3552371,0x06cdd1e,0x1567ff1,0x01f4c50 },
wolfSSL 14:167253f4e170 10663 0 },
wolfSSL 14:167253f4e170 10664 /* 185 */
wolfSSL 14:167253f4e170 10665 { { 0x2dfefab,0x270173d,0x37077bd,0x1a372cd,0x1be2f22,0x28e2ee5,
wolfSSL 14:167253f4e170 10666 0x3ead973,0x35e8f94,0x2fc9bc1,0x03a7399 },
wolfSSL 14:167253f4e170 10667 { 0x36a02a1,0x2855d9b,0x00ed75a,0x37d8398,0x138c087,0x233706e,
wolfSSL 14:167253f4e170 10668 0x147f346,0x01947e2,0x3017228,0x0365942 },
wolfSSL 14:167253f4e170 10669 0 },
wolfSSL 14:167253f4e170 10670 /* 186 */
wolfSSL 14:167253f4e170 10671 { { 0x2057e60,0x2d31296,0x25e4504,0x2fa37bc,0x1cbccc3,0x1f0732f,
wolfSSL 14:167253f4e170 10672 0x3532081,0x2de8a98,0x19a804e,0x005359a },
wolfSSL 14:167253f4e170 10673 { 0x31f411a,0x2a10576,0x369c2c8,0x02fe035,0x109fbaf,0x30bddeb,
wolfSSL 14:167253f4e170 10674 0x1eef901,0x1662ad3,0x0410d43,0x01bd31a },
wolfSSL 14:167253f4e170 10675 0 },
wolfSSL 14:167253f4e170 10676 /* 187 */
wolfSSL 14:167253f4e170 10677 { { 0x2c24a96,0x1b7d3a5,0x19a3872,0x217f2f6,0x2534dbc,0x2cab8c2,
wolfSSL 14:167253f4e170 10678 0x066ef28,0x26aecf1,0x0fd6118,0x01310d4 },
wolfSSL 14:167253f4e170 10679 { 0x055b8da,0x1fdc5be,0x38a1296,0x25118f0,0x341a423,0x2ba4cd0,
wolfSSL 14:167253f4e170 10680 0x3e1413e,0x062d70d,0x2425a31,0x029c9b4 },
wolfSSL 14:167253f4e170 10681 0 },
wolfSSL 14:167253f4e170 10682 /* 188 */
wolfSSL 14:167253f4e170 10683 { { 0x08c1086,0x1acfba5,0x22e1dae,0x0f72f4e,0x3f1de50,0x0f408bc,
wolfSSL 14:167253f4e170 10684 0x35ed3f0,0x3ce48fc,0x282cc6c,0x004d8e7 },
wolfSSL 14:167253f4e170 10685 { 0x1afaa86,0x24e3ef3,0x22589ac,0x3ec9952,0x1f45bc5,0x14144ca,
wolfSSL 14:167253f4e170 10686 0x23b26e4,0x0d68c65,0x1e1c1a3,0x032a4d9 },
wolfSSL 14:167253f4e170 10687 0 },
wolfSSL 14:167253f4e170 10688 /* 189 */
wolfSSL 14:167253f4e170 10689 { { 0x03b2d20,0x16b1d53,0x241b361,0x05e4138,0x1742a54,0x32741c7,
wolfSSL 14:167253f4e170 10690 0x0521c4c,0x1ca96c2,0x034970b,0x02738a7 },
wolfSSL 14:167253f4e170 10691 { 0x13e0ad6,0x207dcdb,0x034c8cc,0x27bcbe1,0x18060da,0x33a18b6,
wolfSSL 14:167253f4e170 10692 0x2d1d1a6,0x2be60d7,0x3d7ab42,0x012312a },
wolfSSL 14:167253f4e170 10693 0 },
wolfSSL 14:167253f4e170 10694 /* 190 */
wolfSSL 14:167253f4e170 10695 { { 0x0c7485a,0x06c3310,0x0dbfd22,0x2ef949d,0x0ead455,0x098f4ba,
wolfSSL 14:167253f4e170 10696 0x3c76989,0x0cf2d24,0x032f67b,0x01e005f },
wolfSSL 14:167253f4e170 10697 { 0x30cb5ee,0x0d5da64,0x0ed2b9d,0x2503102,0x1c0d14e,0x1cbc693,
wolfSSL 14:167253f4e170 10698 0x37bf552,0x07013e2,0x054de5c,0x014f341 },
wolfSSL 14:167253f4e170 10699 0 },
wolfSSL 14:167253f4e170 10700 /* 191 */
wolfSSL 14:167253f4e170 10701 { { 0x128ccac,0x1617e97,0x346ebcd,0x158016d,0x25f823e,0x34048ea,
wolfSSL 14:167253f4e170 10702 0x39f0a1c,0x3ea3df1,0x1c1d3d7,0x03ba919 },
wolfSSL 14:167253f4e170 10703 { 0x151803b,0x01967c1,0x2f70781,0x27df39a,0x06c0b59,0x24a239c,
wolfSSL 14:167253f4e170 10704 0x15a7702,0x2464d06,0x2a47ae6,0x006db90 },
wolfSSL 14:167253f4e170 10705 0 },
wolfSSL 14:167253f4e170 10706 /* 192 */
wolfSSL 14:167253f4e170 10707 { { 0x27d04c3,0x024df3d,0x38112e8,0x38a27ba,0x01e312b,0x0965358,
wolfSSL 14:167253f4e170 10708 0x35d8879,0x2f4f55a,0x214187f,0x0008936 },
wolfSSL 14:167253f4e170 10709 { 0x05fe36f,0x2ee18c3,0x1f5f87a,0x1813bd4,0x0580f3c,0x0ed0a7b,
wolfSSL 14:167253f4e170 10710 0x0fb1bfb,0x3fcce59,0x2f042bf,0x01820e3 },
wolfSSL 14:167253f4e170 10711 0 },
wolfSSL 14:167253f4e170 10712 /* 193 */
wolfSSL 14:167253f4e170 10713 { { 0x20bbe99,0x32cbc9f,0x39ee432,0x3cc12a8,0x37bda44,0x3ea4e40,
wolfSSL 14:167253f4e170 10714 0x097c7a9,0x0590d7d,0x2022d33,0x018dbac },
wolfSSL 14:167253f4e170 10715 { 0x3ae00aa,0x3439864,0x2d2ffcf,0x3f8c6b9,0x0875a00,0x3e4e407,
wolfSSL 14:167253f4e170 10716 0x3658a29,0x22eb3d0,0x2b63921,0x022113b },
wolfSSL 14:167253f4e170 10717 0 },
wolfSSL 14:167253f4e170 10718 /* 194 */
wolfSSL 14:167253f4e170 10719 { { 0x33bae58,0x05c749a,0x1f3e114,0x1c45f8e,0x27db3df,0x06a3ab6,
wolfSSL 14:167253f4e170 10720 0x37bc7f8,0x1e27b34,0x3dc51fb,0x009eea0 },
wolfSSL 14:167253f4e170 10721 { 0x3f54de5,0x3d0e7fe,0x1a71a7d,0x02ed7f8,0x0727703,0x2ca5e92,
wolfSSL 14:167253f4e170 10722 0x2e8e35d,0x292ad0b,0x13487f3,0x02b6d8b },
wolfSSL 14:167253f4e170 10723 0 },
wolfSSL 14:167253f4e170 10724 /* 195 */
wolfSSL 14:167253f4e170 10725 { { 0x175df2a,0x05a28a8,0x32e99b1,0x13d8630,0x2082aa0,0x11ac245,
wolfSSL 14:167253f4e170 10726 0x24f2e71,0x322cb27,0x17675e7,0x02e643f },
wolfSSL 14:167253f4e170 10727 { 0x1f37313,0x2765ad3,0x0789082,0x1e742d0,0x11c2055,0x2021dc4,
wolfSSL 14:167253f4e170 10728 0x09ae4a7,0x346359b,0x2f94d10,0x0205c1f },
wolfSSL 14:167253f4e170 10729 0 },
wolfSSL 14:167253f4e170 10730 /* 196 */
wolfSSL 14:167253f4e170 10731 { { 0x3d6ff96,0x1f2ac80,0x336097d,0x3f03610,0x35b851b,0x010b6d2,
wolfSSL 14:167253f4e170 10732 0x0823c4d,0x2a9709a,0x2ead5a8,0x00de4b6 },
wolfSSL 14:167253f4e170 10733 { 0x01afa0b,0x0621965,0x3671528,0x1050b60,0x3f3e9e7,0x2f93829,
wolfSSL 14:167253f4e170 10734 0x0825275,0x006e85f,0x35e94b0,0x016af58 },
wolfSSL 14:167253f4e170 10735 0 },
wolfSSL 14:167253f4e170 10736 /* 197 */
wolfSSL 14:167253f4e170 10737 { { 0x2c4927c,0x3ea1382,0x0f23727,0x0d69f23,0x3e38860,0x2b72837,
wolfSSL 14:167253f4e170 10738 0x3cd5ea4,0x2d84292,0x321846a,0x016656f },
wolfSSL 14:167253f4e170 10739 { 0x29dfa33,0x3e182e0,0x018be90,0x2ba563f,0x2caafe2,0x218c0d9,
wolfSSL 14:167253f4e170 10740 0x3baf447,0x1047a6c,0x0a2d483,0x01130cb },
wolfSSL 14:167253f4e170 10741 0 },
wolfSSL 14:167253f4e170 10742 /* 198 */
wolfSSL 14:167253f4e170 10743 { { 0x00ed80c,0x2a5fc79,0x0a82a74,0x2c4c74b,0x15f938c,0x30b5ab6,
wolfSSL 14:167253f4e170 10744 0x32124b7,0x295314f,0x2fb8082,0x007c858 },
wolfSSL 14:167253f4e170 10745 { 0x20b173e,0x19f315c,0x12f97e4,0x198217c,0x040e8a6,0x3275977,
wolfSSL 14:167253f4e170 10746 0x2bc20e4,0x01f2633,0x02bc3e9,0x023c750 },
wolfSSL 14:167253f4e170 10747 0 },
wolfSSL 14:167253f4e170 10748 /* 199 */
wolfSSL 14:167253f4e170 10749 { { 0x3c4058a,0x24be73e,0x16704f5,0x2d8a4bd,0x3b15e14,0x3076315,
wolfSSL 14:167253f4e170 10750 0x1cfe37b,0x36fe715,0x343926e,0x02c6603 },
wolfSSL 14:167253f4e170 10751 { 0x2c76b09,0x0cf824c,0x3f7898c,0x274cec1,0x11df527,0x18eed18,
wolfSSL 14:167253f4e170 10752 0x08ead48,0x23915bc,0x19b3744,0x00a0a2b },
wolfSSL 14:167253f4e170 10753 0 },
wolfSSL 14:167253f4e170 10754 /* 200 */
wolfSSL 14:167253f4e170 10755 { { 0x0cf4ac5,0x1c8b131,0x0afb696,0x0ff7799,0x2f5ac1a,0x022420c,
wolfSSL 14:167253f4e170 10756 0x11baa2e,0x2ce4015,0x1275a14,0x0125cfc },
wolfSSL 14:167253f4e170 10757 { 0x22eac5d,0x360cd4c,0x3568e59,0x3d42f66,0x35e07ee,0x09620e4,
wolfSSL 14:167253f4e170 10758 0x36720fa,0x22b1eac,0x2d0db16,0x01b6b23 },
wolfSSL 14:167253f4e170 10759 0 },
wolfSSL 14:167253f4e170 10760 /* 201 */
wolfSSL 14:167253f4e170 10761 { { 0x1a835ef,0x1516bbb,0x2d51f7b,0x3487443,0x14aa113,0x0dd06c2,
wolfSSL 14:167253f4e170 10762 0x1a65e01,0x379300d,0x35920b9,0x012c8fb },
wolfSSL 14:167253f4e170 10763 { 0x04c7341,0x2eda00f,0x3c37e82,0x1b4fd62,0x0d45770,0x1478fba,
wolfSSL 14:167253f4e170 10764 0x127863a,0x26939cd,0x134ddf4,0x01375c5 },
wolfSSL 14:167253f4e170 10765 0 },
wolfSSL 14:167253f4e170 10766 /* 202 */
wolfSSL 14:167253f4e170 10767 { { 0x1476cd9,0x1119ca5,0x325bbf9,0x0bf8c69,0x0648d07,0x312d9f8,
wolfSSL 14:167253f4e170 10768 0x01c8b8f,0x136ec51,0x0002f4a,0x03f4c5c },
wolfSSL 14:167253f4e170 10769 { 0x195d0e1,0x10ffd22,0x29aa1cb,0x3443bdc,0x276e695,0x05e6260,
wolfSSL 14:167253f4e170 10770 0x15f9764,0x3cd9783,0x18c9569,0x0053eb1 },
wolfSSL 14:167253f4e170 10771 0 },
wolfSSL 14:167253f4e170 10772 /* 203 */
wolfSSL 14:167253f4e170 10773 { { 0x312ae18,0x280197c,0x3fc9ad9,0x303f324,0x251958d,0x29f4a11,
wolfSSL 14:167253f4e170 10774 0x2142408,0x3694366,0x25136ab,0x03b5f1d },
wolfSSL 14:167253f4e170 10775 { 0x1d4abbc,0x1c3c689,0x13ea462,0x3cfc684,0x39b5dd8,0x2d4654b,
wolfSSL 14:167253f4e170 10776 0x09b0755,0x27d4f18,0x3f74d2e,0x03fbf2d },
wolfSSL 14:167253f4e170 10777 0 },
wolfSSL 14:167253f4e170 10778 /* 204 */
wolfSSL 14:167253f4e170 10779 { { 0x2119185,0x2525eae,0x1ba4bd0,0x0c2ab11,0x1d54e8c,0x294845e,
wolfSSL 14:167253f4e170 10780 0x2479dea,0x3602d24,0x17e87e0,0x0060069 },
wolfSSL 14:167253f4e170 10781 { 0x0afffb0,0x34fe37f,0x1240073,0x02eb895,0x06cf33c,0x2d7f7ef,
wolfSSL 14:167253f4e170 10782 0x1d763b5,0x04191e0,0x11e1ead,0x027e3f0 },
wolfSSL 14:167253f4e170 10783 0 },
wolfSSL 14:167253f4e170 10784 /* 205 */
wolfSSL 14:167253f4e170 10785 { { 0x269544c,0x0e85c57,0x3813158,0x19fc12d,0x20eaf85,0x1e2930c,
wolfSSL 14:167253f4e170 10786 0x22a8fd2,0x1a6a478,0x09d3d3a,0x02a74e0 },
wolfSSL 14:167253f4e170 10787 { 0x1a2da3b,0x30b0b16,0x0847936,0x3d86257,0x138ccbc,0x0f5421a,
wolfSSL 14:167253f4e170 10788 0x25244e6,0x23bdd79,0x1aee117,0x00c01ae },
wolfSSL 14:167253f4e170 10789 0 },
wolfSSL 14:167253f4e170 10790 /* 206 */
wolfSSL 14:167253f4e170 10791 { { 0x1eead28,0x07cac32,0x1fbc0bb,0x17627d3,0x17eef63,0x0b3a24e,
wolfSSL 14:167253f4e170 10792 0x0757fdb,0x3dd841d,0x3d745f8,0x002ae17 },
wolfSSL 14:167253f4e170 10793 { 0x25b4549,0x29f24cf,0x2f21ecd,0x1725e48,0x04be2bb,0x10ee010,
wolfSSL 14:167253f4e170 10794 0x1a1274b,0x10b0898,0x27511e9,0x02c48b5 },
wolfSSL 14:167253f4e170 10795 0 },
wolfSSL 14:167253f4e170 10796 /* 207 */
wolfSSL 14:167253f4e170 10797 { { 0x2a5ae7a,0x181ef99,0x0be33be,0x3e9dab7,0x101e703,0x3adb971,
wolfSSL 14:167253f4e170 10798 0x1043014,0x2ebb2be,0x1c1097d,0x027d667 },
wolfSSL 14:167253f4e170 10799 { 0x3f250ed,0x16dc603,0x20dc6d7,0x1d0d268,0x38eb915,0x02c89e8,
wolfSSL 14:167253f4e170 10800 0x1605a41,0x12de109,0x0e08a29,0x01f554a },
wolfSSL 14:167253f4e170 10801 0 },
wolfSSL 14:167253f4e170 10802 /* 208 */
wolfSSL 14:167253f4e170 10803 { { 0x0c26def,0x163d988,0x2d1ef0f,0x3a960ac,0x1025585,0x0738e20,
wolfSSL 14:167253f4e170 10804 0x27d79b0,0x05cc3ef,0x201303f,0x00a333a },
wolfSSL 14:167253f4e170 10805 { 0x1644ba5,0x2af345e,0x30b8d1d,0x3a01bff,0x31fc643,0x1acf85e,
wolfSSL 14:167253f4e170 10806 0x0a76fc6,0x04efe98,0x348a1d0,0x03062eb },
wolfSSL 14:167253f4e170 10807 0 },
wolfSSL 14:167253f4e170 10808 /* 209 */
wolfSSL 14:167253f4e170 10809 { { 0x1c4216d,0x18e3217,0x02ac34e,0x19c8185,0x200c010,0x17d4192,
wolfSSL 14:167253f4e170 10810 0x13a1719,0x165af51,0x09db7a9,0x0277be0 },
wolfSSL 14:167253f4e170 10811 { 0x3ab8d2c,0x2190b99,0x22b641e,0x0cd88de,0x3b42404,0x1310862,
wolfSSL 14:167253f4e170 10812 0x106a6d6,0x23395f5,0x0b06880,0x000d5fe },
wolfSSL 14:167253f4e170 10813 0 },
wolfSSL 14:167253f4e170 10814 /* 210 */
wolfSSL 14:167253f4e170 10815 { { 0x0d2cc88,0x36f9913,0x339d8e9,0x237c2e3,0x0cc61c2,0x34c2832,
wolfSSL 14:167253f4e170 10816 0x309874c,0x2621d28,0x2dd1b48,0x0392806 },
wolfSSL 14:167253f4e170 10817 { 0x17cd8f9,0x07bab3d,0x0c482ed,0x0faf565,0x31b767d,0x2f4bde1,
wolfSSL 14:167253f4e170 10818 0x295c717,0x330c29c,0x179ce10,0x0119b5f },
wolfSSL 14:167253f4e170 10819 0 },
wolfSSL 14:167253f4e170 10820 /* 211 */
wolfSSL 14:167253f4e170 10821 { { 0x1ada2c7,0x0c624a7,0x227d47d,0x30e3e6a,0x14fa0a6,0x0829678,
wolfSSL 14:167253f4e170 10822 0x24fd288,0x2b46a43,0x122451e,0x0319ca9 },
wolfSSL 14:167253f4e170 10823 { 0x186b655,0x01f3217,0x0af1306,0x0efe6b5,0x2f0235d,0x1c45ca9,
wolfSSL 14:167253f4e170 10824 0x2086805,0x1d44e66,0x0faf2a6,0x0178f59 },
wolfSSL 14:167253f4e170 10825 0 },
wolfSSL 14:167253f4e170 10826 /* 212 */
wolfSSL 14:167253f4e170 10827 { { 0x33b4416,0x10431e6,0x2d99aa6,0x217aac9,0x0cd8fcf,0x2d95a9d,
wolfSSL 14:167253f4e170 10828 0x3ff74ad,0x10bf17a,0x295eb8e,0x01b229e },
wolfSSL 14:167253f4e170 10829 { 0x02a63bd,0x182e9ec,0x004710c,0x00e2e3c,0x06b2f23,0x04b642c,
wolfSSL 14:167253f4e170 10830 0x2c37383,0x32a4631,0x022ad82,0x00d22b9 },
wolfSSL 14:167253f4e170 10831 0 },
wolfSSL 14:167253f4e170 10832 /* 213 */
wolfSSL 14:167253f4e170 10833 { { 0x0cda2fb,0x1d198d7,0x26d27f4,0x286381c,0x022acca,0x24ac7c8,
wolfSSL 14:167253f4e170 10834 0x2df7824,0x0b4ba16,0x1e0d9ef,0x03041d3 },
wolfSSL 14:167253f4e170 10835 { 0x29a65b3,0x0f3912b,0x151bfcf,0x2b0175c,0x0fd71e4,0x39aa5e2,
wolfSSL 14:167253f4e170 10836 0x311f50c,0x13ff351,0x3dbc9e5,0x03eeb7e },
wolfSSL 14:167253f4e170 10837 0 },
wolfSSL 14:167253f4e170 10838 /* 214 */
wolfSSL 14:167253f4e170 10839 { { 0x0a99363,0x0fc7348,0x2775171,0x23db3c8,0x2b91565,0x134d66c,
wolfSSL 14:167253f4e170 10840 0x0175cd2,0x1bf365a,0x2b48371,0x02dfe5d },
wolfSSL 14:167253f4e170 10841 { 0x16dbf74,0x2389357,0x2f36575,0x3f5c70e,0x38d23ba,0x090f7f8,
wolfSSL 14:167253f4e170 10842 0x3477600,0x3201523,0x32ecafc,0x03d3506 },
wolfSSL 14:167253f4e170 10843 0 },
wolfSSL 14:167253f4e170 10844 /* 215 */
wolfSSL 14:167253f4e170 10845 { { 0x1abd48d,0x073ca3f,0x38a451f,0x0d8cb01,0x1ce81be,0x05c51ba,
wolfSSL 14:167253f4e170 10846 0x0e29741,0x03c41ab,0x0eae016,0x0060209 },
wolfSSL 14:167253f4e170 10847 { 0x2e58358,0x1da62d9,0x2358038,0x14b39b2,0x1635687,0x39079b1,
wolfSSL 14:167253f4e170 10848 0x380e345,0x1b49608,0x23983cf,0x019f97d },
wolfSSL 14:167253f4e170 10849 0 },
wolfSSL 14:167253f4e170 10850 /* 216 */
wolfSSL 14:167253f4e170 10851 { { 0x34899ef,0x332e373,0x04c0f89,0x3c27aed,0x1949015,0x09663b2,
wolfSSL 14:167253f4e170 10852 0x2f9276b,0x07f1951,0x09a04c1,0x027fbde },
wolfSSL 14:167253f4e170 10853 { 0x3d2a071,0x19fb3d4,0x1b096d3,0x1fe9146,0x3b10e1a,0x0478bbb,
wolfSSL 14:167253f4e170 10854 0x2b3fb06,0x1388329,0x181a99c,0x02f2030 },
wolfSSL 14:167253f4e170 10855 0 },
wolfSSL 14:167253f4e170 10856 /* 217 */
wolfSSL 14:167253f4e170 10857 { { 0x1eb82e6,0x14dbe39,0x3920972,0x31fd5b2,0x21a484f,0x02d7697,
wolfSSL 14:167253f4e170 10858 0x0e21715,0x37c431e,0x2629f8c,0x01249c3 },
wolfSSL 14:167253f4e170 10859 { 0x26b50ad,0x26deefa,0x0ffc1a3,0x30688e2,0x39a0284,0x041c65e,
wolfSSL 14:167253f4e170 10860 0x03eb178,0x0bdfd50,0x2f96137,0x034bb94 },
wolfSSL 14:167253f4e170 10861 0 },
wolfSSL 14:167253f4e170 10862 /* 218 */
wolfSSL 14:167253f4e170 10863 { { 0x0e0362a,0x334a162,0x194dd37,0x29e3e97,0x2442fa8,0x10d2949,
wolfSSL 14:167253f4e170 10864 0x3836e5a,0x2dccebf,0x0bee5ab,0x037ed1e },
wolfSSL 14:167253f4e170 10865 { 0x33eede6,0x3c739d9,0x2f04a91,0x350ad6c,0x3a5390a,0x14c368b,
wolfSSL 14:167253f4e170 10866 0x26f7bf5,0x11ce979,0x0b408df,0x0366850 },
wolfSSL 14:167253f4e170 10867 0 },
wolfSSL 14:167253f4e170 10868 /* 219 */
wolfSSL 14:167253f4e170 10869 { { 0x28ea498,0x0886d5b,0x2e090e0,0x0a4d58f,0x2623478,0x0d74ab7,
wolfSSL 14:167253f4e170 10870 0x2b83913,0x12c6b81,0x18d623f,0x01d8301 },
wolfSSL 14:167253f4e170 10871 { 0x198aa79,0x26d6330,0x3a7f0b8,0x34bc1ea,0x2f74890,0x378955a,
wolfSSL 14:167253f4e170 10872 0x204110f,0x0102538,0x02d8f19,0x01c5066 },
wolfSSL 14:167253f4e170 10873 0 },
wolfSSL 14:167253f4e170 10874 /* 220 */
wolfSSL 14:167253f4e170 10875 { { 0x14b0f45,0x2838cd3,0x14e16f0,0x0e0e4aa,0x2d9280b,0x0f18757,
wolfSSL 14:167253f4e170 10876 0x3324c6b,0x1391ceb,0x1ce89d5,0x00ebe74 },
wolfSSL 14:167253f4e170 10877 { 0x0930371,0x3de6048,0x3097fd8,0x1308705,0x3eda266,0x3108c26,
wolfSSL 14:167253f4e170 10878 0x1545dcd,0x1f7583a,0x1c37395,0x02c7e05 },
wolfSSL 14:167253f4e170 10879 0 },
wolfSSL 14:167253f4e170 10880 /* 221 */
wolfSSL 14:167253f4e170 10881 { { 0x1fec44a,0x2a9e3a2,0x0caf84f,0x11cf2a9,0x0c8c2ae,0x06da989,
wolfSSL 14:167253f4e170 10882 0x1c807dc,0x3c149a4,0x1141543,0x02906bb },
wolfSSL 14:167253f4e170 10883 { 0x15ffe04,0x0d4e65f,0x2e20424,0x37d896d,0x18bacb2,0x1e05ddd,
wolfSSL 14:167253f4e170 10884 0x1660be8,0x183be17,0x1dd86fb,0x035ba70 },
wolfSSL 14:167253f4e170 10885 0 },
wolfSSL 14:167253f4e170 10886 /* 222 */
wolfSSL 14:167253f4e170 10887 { { 0x2853264,0x0ba5fb1,0x0a0b3aa,0x2df88c1,0x2771533,0x23aba6f,
wolfSSL 14:167253f4e170 10888 0x112bb7b,0x3e3086e,0x210ae9b,0x027271b },
wolfSSL 14:167253f4e170 10889 { 0x030b74c,0x0269678,0x1e90a23,0x135a98c,0x24ed749,0x126de7c,
wolfSSL 14:167253f4e170 10890 0x344b23a,0x186da27,0x19640fa,0x0159af5 },
wolfSSL 14:167253f4e170 10891 0 },
wolfSSL 14:167253f4e170 10892 /* 223 */
wolfSSL 14:167253f4e170 10893 { { 0x18061f3,0x3004630,0x3c70066,0x34df20f,0x1190b25,0x1c9cc91,
wolfSSL 14:167253f4e170 10894 0x1fc8e02,0x0d17bc1,0x390f525,0x033cb1c },
wolfSSL 14:167253f4e170 10895 { 0x0eb30cf,0x2f3ad04,0x303aa09,0x2e835dd,0x1cfd2eb,0x143fc95,
wolfSSL 14:167253f4e170 10896 0x02c43a1,0x025e7a1,0x3558aa2,0x000bd45 },
wolfSSL 14:167253f4e170 10897 0 },
wolfSSL 14:167253f4e170 10898 /* 224 */
wolfSSL 14:167253f4e170 10899 { { 0x1db7d07,0x3bde52b,0x1500396,0x1089115,0x20b4fc7,0x1e2a8f3,
wolfSSL 14:167253f4e170 10900 0x3f8eacc,0x365f7eb,0x1a5e8d4,0x0053a6b },
wolfSSL 14:167253f4e170 10901 { 0x37079e2,0x120284b,0x000edaa,0x33792c2,0x145baa3,0x20e055f,
wolfSSL 14:167253f4e170 10902 0x365e2d7,0x26ba005,0x3ab8e9d,0x0282b53 },
wolfSSL 14:167253f4e170 10903 0 },
wolfSSL 14:167253f4e170 10904 /* 225 */
wolfSSL 14:167253f4e170 10905 { { 0x2653618,0x2dd8852,0x2a5f0bf,0x0f0c7aa,0x2187281,0x1252757,
wolfSSL 14:167253f4e170 10906 0x13e7374,0x3b47855,0x0b86e56,0x02f354c },
wolfSSL 14:167253f4e170 10907 { 0x2e9c47b,0x2fa14cc,0x19ab169,0x3fad401,0x0dc2776,0x24afeed,
wolfSSL 14:167253f4e170 10908 0x3a97611,0x0d07736,0x3cf6979,0x02424a0 },
wolfSSL 14:167253f4e170 10909 0 },
wolfSSL 14:167253f4e170 10910 /* 226 */
wolfSSL 14:167253f4e170 10911 { { 0x2e81a13,0x000c91d,0x123967b,0x265885c,0x29bee1a,0x0cb8675,
wolfSSL 14:167253f4e170 10912 0x2d361bd,0x1526823,0x3c9ace1,0x00d7bad },
wolfSSL 14:167253f4e170 10913 { 0x24e5bdc,0x02b969f,0x2c6e128,0x34edb3b,0x12dcd2c,0x3899af0,
wolfSSL 14:167253f4e170 10914 0x24224c6,0x3a1914b,0x0f4448a,0x026a2cb },
wolfSSL 14:167253f4e170 10915 0 },
wolfSSL 14:167253f4e170 10916 /* 227 */
wolfSSL 14:167253f4e170 10917 { { 0x1d03b59,0x1c6fc82,0x32abf64,0x28ed96b,0x1c90e62,0x2f57bb2,
wolfSSL 14:167253f4e170 10918 0x3ff168e,0x04de7fd,0x0f4d449,0x01af6d8 },
wolfSSL 14:167253f4e170 10919 { 0x255bc30,0x2bfaf22,0x3fe0dad,0x0584025,0x1c79ead,0x3078ef7,
wolfSSL 14:167253f4e170 10920 0x2197414,0x022a50b,0x0fd94ba,0x0007b0f },
wolfSSL 14:167253f4e170 10921 0 },
wolfSSL 14:167253f4e170 10922 /* 228 */
wolfSSL 14:167253f4e170 10923 { { 0x09485c2,0x09dfaf7,0x10c7ba6,0x1e48bec,0x248cc9a,0x028a362,
wolfSSL 14:167253f4e170 10924 0x21d60f7,0x193d93d,0x1c04754,0x0346b2c },
wolfSSL 14:167253f4e170 10925 { 0x2f36612,0x240ac49,0x0d8bd26,0x13b8186,0x259c3a4,0x020d5fb,
wolfSSL 14:167253f4e170 10926 0x38a8133,0x09b0937,0x39d4056,0x01f7341 },
wolfSSL 14:167253f4e170 10927 0 },
wolfSSL 14:167253f4e170 10928 /* 229 */
wolfSSL 14:167253f4e170 10929 { { 0x05a4b48,0x1f534fc,0x07725ce,0x148dc8c,0x2adcd29,0x04aa456,
wolfSSL 14:167253f4e170 10930 0x0f79718,0x066e346,0x189377d,0x002fd4d },
wolfSSL 14:167253f4e170 10931 { 0x068ea73,0x336569b,0x184d35e,0x32a08e9,0x3c7f3bb,0x11ce9c8,
wolfSSL 14:167253f4e170 10932 0x3674c6f,0x21bf27e,0x0d9e166,0x034a2f9 },
wolfSSL 14:167253f4e170 10933 0 },
wolfSSL 14:167253f4e170 10934 /* 230 */
wolfSSL 14:167253f4e170 10935 { { 0x0fa8e4b,0x2e6418e,0x18fc5d2,0x1ba24ff,0x0559f18,0x0dbedbf,
wolfSSL 14:167253f4e170 10936 0x2de2aa4,0x22338e9,0x3aa510f,0x035d801 },
wolfSSL 14:167253f4e170 10937 { 0x23a4988,0x02aad94,0x02732d1,0x111d374,0x0b455cf,0x0d01c9e,
wolfSSL 14:167253f4e170 10938 0x067082a,0x2ec05fd,0x368b303,0x03cad4b },
wolfSSL 14:167253f4e170 10939 0 },
wolfSSL 14:167253f4e170 10940 /* 231 */
wolfSSL 14:167253f4e170 10941 { { 0x035b4ca,0x1fabea6,0x1cbc0d5,0x3f2ed9a,0x02d2232,0x1990c66,
wolfSSL 14:167253f4e170 10942 0x2eb680c,0x3b4ea3b,0x18ecc5a,0x03636fa },
wolfSSL 14:167253f4e170 10943 { 0x1a02709,0x26f8ff1,0x1fa8cba,0x397d6e8,0x230be68,0x043aa14,
wolfSSL 14:167253f4e170 10944 0x3d43cdf,0x25c17fa,0x3a3ee55,0x0380564 },
wolfSSL 14:167253f4e170 10945 0 },
wolfSSL 14:167253f4e170 10946 /* 232 */
wolfSSL 14:167253f4e170 10947 { { 0x275a0a6,0x16bd43a,0x0033d3e,0x2b15e16,0x2512226,0x005d901,
wolfSSL 14:167253f4e170 10948 0x26d50fd,0x3bc19bf,0x3b1aeb8,0x02bfb01 },
wolfSSL 14:167253f4e170 10949 { 0x0bb0a31,0x26559e0,0x1aae7fb,0x330dcc2,0x16f1af3,0x06afce2,
wolfSSL 14:167253f4e170 10950 0x13a15a0,0x2ff7645,0x3546e2d,0x029c6e4 },
wolfSSL 14:167253f4e170 10951 0 },
wolfSSL 14:167253f4e170 10952 /* 233 */
wolfSSL 14:167253f4e170 10953 { { 0x0f593d2,0x384b806,0x122bbf8,0x0a281e0,0x1d1a904,0x2e93cab,
wolfSSL 14:167253f4e170 10954 0x0505db0,0x08f6454,0x05c6285,0x014e880 },
wolfSSL 14:167253f4e170 10955 { 0x3f2b935,0x22d8e79,0x161a07c,0x16b060a,0x02bff97,0x146328b,
wolfSSL 14:167253f4e170 10956 0x3ceea77,0x238f61a,0x19b3d58,0x02fd1f4 },
wolfSSL 14:167253f4e170 10957 0 },
wolfSSL 14:167253f4e170 10958 /* 234 */
wolfSSL 14:167253f4e170 10959 { { 0x17665d5,0x259e9f7,0x0de5672,0x15cbcbd,0x34e3030,0x035240f,
wolfSSL 14:167253f4e170 10960 0x0005ae8,0x286d851,0x07f39c9,0x000070b },
wolfSSL 14:167253f4e170 10961 { 0x1efc6d6,0x2a0051a,0x2724143,0x2a9ef1e,0x0c810bd,0x1e05429,
wolfSSL 14:167253f4e170 10962 0x25670ba,0x2e66d7d,0x0e786ff,0x03f6b7e },
wolfSSL 14:167253f4e170 10963 0 },
wolfSSL 14:167253f4e170 10964 /* 235 */
wolfSSL 14:167253f4e170 10965 { { 0x3c00785,0x232e23f,0x2b67fd3,0x244ed23,0x077fa75,0x3cda3ef,
wolfSSL 14:167253f4e170 10966 0x14d055b,0x0f25011,0x24d5aa4,0x00ea0e3 },
wolfSSL 14:167253f4e170 10967 { 0x297bb9a,0x198ca4f,0x14d9561,0x18d1076,0x39eb933,0x2b6caa0,
wolfSSL 14:167253f4e170 10968 0x1591a60,0x0768d45,0x257873e,0x00f36e0 },
wolfSSL 14:167253f4e170 10969 0 },
wolfSSL 14:167253f4e170 10970 /* 236 */
wolfSSL 14:167253f4e170 10971 { { 0x1e77eab,0x0502a5f,0x0109137,0x0350592,0x3f7e1c5,0x3ac7437,
wolfSSL 14:167253f4e170 10972 0x2dcad2c,0x1fee9d8,0x089f1f5,0x0169833 },
wolfSSL 14:167253f4e170 10973 { 0x0d45673,0x0d8e090,0x065580b,0x065644f,0x11b82be,0x3592dd0,
wolfSSL 14:167253f4e170 10974 0x3284b8d,0x23f0015,0x16fdbfd,0x0248bfd },
wolfSSL 14:167253f4e170 10975 0 },
wolfSSL 14:167253f4e170 10976 /* 237 */
wolfSSL 14:167253f4e170 10977 { { 0x1a129a1,0x1977bb2,0x0e041b2,0x15f30a1,0x0a5b1ce,0x3afef8f,
wolfSSL 14:167253f4e170 10978 0x380c46c,0x3358810,0x27df6c5,0x01ca466 },
wolfSSL 14:167253f4e170 10979 { 0x3b90f9a,0x3d14ea3,0x031b298,0x02e2390,0x2d719c0,0x25bc615,
wolfSSL 14:167253f4e170 10980 0x2c0e777,0x0226b8c,0x3803624,0x0179e45 },
wolfSSL 14:167253f4e170 10981 0 },
wolfSSL 14:167253f4e170 10982 /* 238 */
wolfSSL 14:167253f4e170 10983 { { 0x363cdfb,0x1bb155f,0x24fd5c1,0x1c7c72b,0x28e6a35,0x18165f2,
wolfSSL 14:167253f4e170 10984 0x226bea5,0x0beaff3,0x371e24c,0x0138294 },
wolfSSL 14:167253f4e170 10985 { 0x1765357,0x29034e9,0x22b4276,0x11035ce,0x23c89af,0x074468c,
wolfSSL 14:167253f4e170 10986 0x3370ae4,0x013bae3,0x018d566,0x03d7fde },
wolfSSL 14:167253f4e170 10987 0 },
wolfSSL 14:167253f4e170 10988 /* 239 */
wolfSSL 14:167253f4e170 10989 { { 0x209df21,0x0f8ff86,0x0e47fbf,0x23b99ba,0x126d5d2,0x2722405,
wolfSSL 14:167253f4e170 10990 0x16bd0a2,0x1799082,0x0e9533f,0x039077c },
wolfSSL 14:167253f4e170 10991 { 0x3ba9e3f,0x3f6902c,0x1895305,0x3ac9813,0x3f2340c,0x3c0d9f1,
wolfSSL 14:167253f4e170 10992 0x26e1927,0x0557c21,0x16eac4f,0x023b75f },
wolfSSL 14:167253f4e170 10993 0 },
wolfSSL 14:167253f4e170 10994 /* 240 */
wolfSSL 14:167253f4e170 10995 { { 0x3fc8ff3,0x0770382,0x342fc9a,0x0afa4db,0x314efd8,0x328e07b,
wolfSSL 14:167253f4e170 10996 0x016f7cc,0x3ba599c,0x1caed8a,0x0050cb0 },
wolfSSL 14:167253f4e170 10997 { 0x0b23c26,0x2120a5c,0x3273ec6,0x1cc1cd6,0x2a64fe8,0x2bbc3d6,
wolfSSL 14:167253f4e170 10998 0x09f6e5e,0x34b1b8e,0x00b5ac8,0x032bbd2 },
wolfSSL 14:167253f4e170 10999 0 },
wolfSSL 14:167253f4e170 11000 /* 241 */
wolfSSL 14:167253f4e170 11001 { { 0x1315922,0x1725e1d,0x0ca5524,0x1c4c18f,0x3d82951,0x193bcb2,
wolfSSL 14:167253f4e170 11002 0x0e60d0b,0x388dbcf,0x37e8efa,0x0342e85 },
wolfSSL 14:167253f4e170 11003 { 0x1b3af60,0x26ba3ec,0x220e53a,0x394f4b6,0x01a796a,0x3e7bbca,
wolfSSL 14:167253f4e170 11004 0x163605d,0x2b85807,0x17c1c54,0x03cc725 },
wolfSSL 14:167253f4e170 11005 0 },
wolfSSL 14:167253f4e170 11006 /* 242 */
wolfSSL 14:167253f4e170 11007 { { 0x1cc4597,0x1635492,0x2028c0f,0x2c2eb82,0x2dc5015,0x0d2a052,
wolfSSL 14:167253f4e170 11008 0x05fc557,0x1f0ebbf,0x0cb96e1,0x0004d01 },
wolfSSL 14:167253f4e170 11009 { 0x1a824bf,0x3896172,0x2ed7b29,0x178007a,0x0d59318,0x07bda2b,
wolfSSL 14:167253f4e170 11010 0x2ee6826,0x0f9b235,0x04b9193,0x01bcddf },
wolfSSL 14:167253f4e170 11011 0 },
wolfSSL 14:167253f4e170 11012 /* 243 */
wolfSSL 14:167253f4e170 11013 { { 0x0333fd2,0x0eeb46a,0x15b89f9,0x00968aa,0x2a89302,0x2bdd6b3,
wolfSSL 14:167253f4e170 11014 0x1e5037e,0x2541884,0x24ed2d0,0x01b6e8f },
wolfSSL 14:167253f4e170 11015 { 0x04399cd,0x3be6334,0x3adea48,0x1bb9adc,0x31811c6,0x05fb2bc,
wolfSSL 14:167253f4e170 11016 0x360752c,0x3d29dcb,0x3423bec,0x03c4f3c },
wolfSSL 14:167253f4e170 11017 0 },
wolfSSL 14:167253f4e170 11018 /* 244 */
wolfSSL 14:167253f4e170 11019 { { 0x119e2eb,0x2e7b02a,0x0f68cee,0x257d8b0,0x183a9a1,0x2ae88a6,
wolfSSL 14:167253f4e170 11020 0x3a3bb67,0x2eb4f3e,0x1a9274b,0x0320fea },
wolfSSL 14:167253f4e170 11021 { 0x2fa1ce0,0x346c2d8,0x2fbf0d7,0x3d4d063,0x0e58b60,0x09c1bc1,
wolfSSL 14:167253f4e170 11022 0x28ef9e5,0x09a0efe,0x0f45d70,0x02d275c },
wolfSSL 14:167253f4e170 11023 0 },
wolfSSL 14:167253f4e170 11024 /* 245 */
wolfSSL 14:167253f4e170 11025 { { 0x2d5513b,0x31d443e,0x1e2d914,0x3b2c5d4,0x105f32e,0x27ee756,
wolfSSL 14:167253f4e170 11026 0x050418d,0x3c73db6,0x1bb0c30,0x01673eb },
wolfSSL 14:167253f4e170 11027 { 0x1cb7fd6,0x1eb08d5,0x26a3e16,0x2e20810,0x0249367,0x029e219,
wolfSSL 14:167253f4e170 11028 0x2ec58c9,0x12d9fab,0x362354a,0x016eafc },
wolfSSL 14:167253f4e170 11029 0 },
wolfSSL 14:167253f4e170 11030 /* 246 */
wolfSSL 14:167253f4e170 11031 { { 0x2424865,0x260747b,0x177f37c,0x1e3cb95,0x08b0028,0x2783016,
wolfSSL 14:167253f4e170 11032 0x2970f1b,0x323c1c0,0x2a79026,0x0186231 },
wolfSSL 14:167253f4e170 11033 { 0x0f244da,0x26866f4,0x087306f,0x173ec20,0x31ecced,0x3c84d8d,
wolfSSL 14:167253f4e170 11034 0x070f9b9,0x2e764d5,0x075df50,0x0264ff9 },
wolfSSL 14:167253f4e170 11035 0 },
wolfSSL 14:167253f4e170 11036 /* 247 */
wolfSSL 14:167253f4e170 11037 { { 0x32c3609,0x0c737e6,0x14ea68e,0x300b11b,0x184eb19,0x29dd440,
wolfSSL 14:167253f4e170 11038 0x09ec1a9,0x185adeb,0x0664c80,0x0207dd9 },
wolfSSL 14:167253f4e170 11039 { 0x1fbe978,0x30a969d,0x33561d7,0x34fc60e,0x36743fe,0x00774af,
wolfSSL 14:167253f4e170 11040 0x0d1f045,0x018360e,0x12a5fe9,0x01592a0 },
wolfSSL 14:167253f4e170 11041 0 },
wolfSSL 14:167253f4e170 11042 /* 248 */
wolfSSL 14:167253f4e170 11043 { { 0x2817d1d,0x2993d3e,0x2e0f7a5,0x112faa0,0x255f968,0x355fe6a,
wolfSSL 14:167253f4e170 11044 0x3f5a0fc,0x075b2d7,0x3cf00e5,0x0089afc },
wolfSSL 14:167253f4e170 11045 { 0x32833cf,0x06a7e4b,0x09a8d6d,0x1693d3e,0x320a0a3,0x3cfdfdd,
wolfSSL 14:167253f4e170 11046 0x136c498,0x1e0d845,0x347ff25,0x01a1de7 },
wolfSSL 14:167253f4e170 11047 0 },
wolfSSL 14:167253f4e170 11048 /* 249 */
wolfSSL 14:167253f4e170 11049 { { 0x3043d08,0x030705c,0x20fa79b,0x1d07f00,0x0a54467,0x29b49b4,
wolfSSL 14:167253f4e170 11050 0x367e289,0x0b82f4d,0x0d1eb09,0x025ef2c },
wolfSSL 14:167253f4e170 11051 { 0x32ed3c3,0x1baaa3c,0x3c482ab,0x146ca06,0x3c8a4f1,0x3e85e3c,
wolfSSL 14:167253f4e170 11052 0x1bf4f3b,0x1195534,0x3e80a78,0x02a1cbf },
wolfSSL 14:167253f4e170 11053 0 },
wolfSSL 14:167253f4e170 11054 /* 250 */
wolfSSL 14:167253f4e170 11055 { { 0x32b2086,0x2de4d68,0x3486b1a,0x03a0583,0x2e1eb71,0x2dab9af,
wolfSSL 14:167253f4e170 11056 0x10cd913,0x28daa6f,0x3fcb732,0x000a04a },
wolfSSL 14:167253f4e170 11057 { 0x3605318,0x3f5f2b3,0x2d1da63,0x143f7f5,0x1646e5d,0x040b586,
wolfSSL 14:167253f4e170 11058 0x1683982,0x25abe87,0x0c9fe53,0x001ce47 },
wolfSSL 14:167253f4e170 11059 0 },
wolfSSL 14:167253f4e170 11060 /* 251 */
wolfSSL 14:167253f4e170 11061 { { 0x380d02b,0x055fc22,0x3f7fc50,0x3458a1d,0x26b8333,0x23550ab,
wolfSSL 14:167253f4e170 11062 0x0a1af87,0x0a821eb,0x2dc7e6d,0x00d574a },
wolfSSL 14:167253f4e170 11063 { 0x07386e1,0x3ccd68a,0x3275b41,0x253e390,0x2fd272a,0x1e6627a,
wolfSSL 14:167253f4e170 11064 0x2ca2cde,0x0e9e4a1,0x1e37c2a,0x00f70ac },
wolfSSL 14:167253f4e170 11065 0 },
wolfSSL 14:167253f4e170 11066 /* 252 */
wolfSSL 14:167253f4e170 11067 { { 0x0581352,0x2748701,0x02bed68,0x094dd9e,0x30a00c8,0x3fb5c07,
wolfSSL 14:167253f4e170 11068 0x3bd5909,0x211ac80,0x1103ccd,0x0311e1a },
wolfSSL 14:167253f4e170 11069 { 0x0c768ed,0x29dc209,0x36575db,0x009a107,0x272feea,0x2b33383,
wolfSSL 14:167253f4e170 11070 0x313ed56,0x134c9cc,0x168d5bb,0x033310a },
wolfSSL 14:167253f4e170 11071 0 },
wolfSSL 14:167253f4e170 11072 /* 253 */
wolfSSL 14:167253f4e170 11073 { { 0x17620b9,0x143784f,0x256a94e,0x229664a,0x1d89a5c,0x1d521f2,
wolfSSL 14:167253f4e170 11074 0x0076406,0x1c73f70,0x342aa48,0x03851fa },
wolfSSL 14:167253f4e170 11075 { 0x0f3ae46,0x2ad3bab,0x0fbe274,0x3ed40d4,0x2fd4936,0x232103a,
wolfSSL 14:167253f4e170 11076 0x2afe474,0x25b8f7c,0x047080e,0x008e6b0 },
wolfSSL 14:167253f4e170 11077 0 },
wolfSSL 14:167253f4e170 11078 /* 254 */
wolfSSL 14:167253f4e170 11079 { { 0x3fee8d4,0x347cd4a,0x0fec481,0x33fe9ec,0x0ce80b5,0x33a6bcf,
wolfSSL 14:167253f4e170 11080 0x1c4c9e2,0x3967441,0x1a3f5f7,0x03157e8 },
wolfSSL 14:167253f4e170 11081 { 0x257c227,0x1bc53a0,0x200b318,0x0fcd0af,0x2c5b165,0x2a413ec,
wolfSSL 14:167253f4e170 11082 0x2fc998a,0x2da6426,0x19cd4f4,0x0025336 },
wolfSSL 14:167253f4e170 11083 0 },
wolfSSL 14:167253f4e170 11084 /* 255 */
wolfSSL 14:167253f4e170 11085 { { 0x303beba,0x2072135,0x32918a9,0x140cb3a,0x08631d1,0x0ef527b,
wolfSSL 14:167253f4e170 11086 0x05f2c9e,0x2b4ce91,0x0b642ab,0x02e428c },
wolfSSL 14:167253f4e170 11087 { 0x0a5abf9,0x15013ed,0x3603b46,0x30dd76d,0x3004750,0x28d7627,
wolfSSL 14:167253f4e170 11088 0x1a42ccc,0x093ddbe,0x39a1b79,0x00067e2 },
wolfSSL 14:167253f4e170 11089 0 },
wolfSSL 14:167253f4e170 11090 };
wolfSSL 14:167253f4e170 11091
wolfSSL 14:167253f4e170 11092 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 14:167253f4e170 11093 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 11094 *
wolfSSL 14:167253f4e170 11095 * r Resulting point.
wolfSSL 14:167253f4e170 11096 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 11097 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 11098 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 11099 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 11100 */
wolfSSL 14:167253f4e170 11101 static int sp_256_ecc_mulmod_base_10(sp_point* r, sp_digit* k,
wolfSSL 14:167253f4e170 11102 int map, void* heap)
wolfSSL 14:167253f4e170 11103 {
wolfSSL 14:167253f4e170 11104 return sp_256_ecc_mulmod_stripe_10(r, &p256_base, p256_table,
wolfSSL 14:167253f4e170 11105 k, map, heap);
wolfSSL 14:167253f4e170 11106 }
wolfSSL 14:167253f4e170 11107
wolfSSL 14:167253f4e170 11108 #endif
wolfSSL 14:167253f4e170 11109
wolfSSL 14:167253f4e170 11110 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 14:167253f4e170 11111 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 11112 *
wolfSSL 14:167253f4e170 11113 * km Scalar to multiply by.
wolfSSL 14:167253f4e170 11114 * r Resulting point.
wolfSSL 14:167253f4e170 11115 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 11116 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 11117 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 11118 */
wolfSSL 14:167253f4e170 11119 int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)
wolfSSL 14:167253f4e170 11120 {
wolfSSL 14:167253f4e170 11121 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11122 sp_point p;
wolfSSL 14:167253f4e170 11123 sp_digit kd[10];
wolfSSL 14:167253f4e170 11124 #endif
wolfSSL 14:167253f4e170 11125 sp_point* point;
wolfSSL 14:167253f4e170 11126 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 11127 int err = MP_OKAY;
wolfSSL 14:167253f4e170 11128 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11129 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11130 #endif
wolfSSL 14:167253f4e170 11131
wolfSSL 14:167253f4e170 11132 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 11133 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11134 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11135 k = XMALLOC(sizeof(sp_digit) * 10, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11136 if (k == NULL)
wolfSSL 14:167253f4e170 11137 err = MEMORY_E;
wolfSSL 14:167253f4e170 11138 }
wolfSSL 14:167253f4e170 11139 #else
wolfSSL 14:167253f4e170 11140 k = kd;
wolfSSL 14:167253f4e170 11141 #endif
wolfSSL 14:167253f4e170 11142 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11143 sp_256_from_mp(k, 10, km);
wolfSSL 14:167253f4e170 11144
wolfSSL 14:167253f4e170 11145 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11146 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11147 err = sp_256_ecc_mulmod_base_avx2_10(point, k, map, heap);
wolfSSL 14:167253f4e170 11148 else
wolfSSL 14:167253f4e170 11149 #endif
wolfSSL 14:167253f4e170 11150 err = sp_256_ecc_mulmod_base_10(point, k, map, heap);
wolfSSL 14:167253f4e170 11151 }
wolfSSL 14:167253f4e170 11152 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11153 err = sp_256_point_to_ecc_point_10(point, r);
wolfSSL 14:167253f4e170 11154
wolfSSL 14:167253f4e170 11155 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11156 if (k != NULL)
wolfSSL 14:167253f4e170 11157 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11158 #endif
wolfSSL 14:167253f4e170 11159 sp_ecc_point_free(point, 0, heap);
wolfSSL 14:167253f4e170 11160
wolfSSL 14:167253f4e170 11161 return err;
wolfSSL 14:167253f4e170 11162 }
wolfSSL 14:167253f4e170 11163
wolfSSL 14:167253f4e170 11164 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN)
wolfSSL 14:167253f4e170 11165 /* Returns 1 if the number of zero.
wolfSSL 14:167253f4e170 11166 * Implementation is constant time.
wolfSSL 14:167253f4e170 11167 *
wolfSSL 14:167253f4e170 11168 * a Number to check.
wolfSSL 14:167253f4e170 11169 * returns 1 if the number is zero and 0 otherwise.
wolfSSL 14:167253f4e170 11170 */
wolfSSL 14:167253f4e170 11171 static int sp_256_iszero_10(const sp_digit* a)
wolfSSL 14:167253f4e170 11172 {
wolfSSL 14:167253f4e170 11173 return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] |
wolfSSL 14:167253f4e170 11174 a[8] | a[9]) == 0;
wolfSSL 14:167253f4e170 11175 }
wolfSSL 14:167253f4e170 11176
wolfSSL 14:167253f4e170 11177 #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN */
wolfSSL 14:167253f4e170 11178 /* Add 1 to a. (a = a + 1)
wolfSSL 14:167253f4e170 11179 *
wolfSSL 14:167253f4e170 11180 * r A single precision integer.
wolfSSL 14:167253f4e170 11181 * a A single precision integer.
wolfSSL 14:167253f4e170 11182 */
wolfSSL 14:167253f4e170 11183 SP_NOINLINE static void sp_256_add_one_10(sp_digit* a)
wolfSSL 14:167253f4e170 11184 {
wolfSSL 14:167253f4e170 11185 a[0]++;
wolfSSL 14:167253f4e170 11186 sp_256_norm_10(a);
wolfSSL 14:167253f4e170 11187 }
wolfSSL 14:167253f4e170 11188
wolfSSL 14:167253f4e170 11189 /* Read big endian unsigned byte aray into r.
wolfSSL 14:167253f4e170 11190 *
wolfSSL 14:167253f4e170 11191 * r A single precision integer.
wolfSSL 14:167253f4e170 11192 * a Byte array.
wolfSSL 14:167253f4e170 11193 * n Number of bytes in array to read.
wolfSSL 14:167253f4e170 11194 */
wolfSSL 14:167253f4e170 11195 static void sp_256_from_bin(sp_digit* r, int max, const byte* a, int n)
wolfSSL 14:167253f4e170 11196 {
wolfSSL 14:167253f4e170 11197 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 11198
wolfSSL 14:167253f4e170 11199 r[0] = 0;
wolfSSL 14:167253f4e170 11200 for (i = n-1; i >= 0; i--) {
wolfSSL 14:167253f4e170 11201 r[j] |= ((sp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 11202 if (s >= 18) {
wolfSSL 14:167253f4e170 11203 r[j] &= 0x3ffffff;
wolfSSL 14:167253f4e170 11204 s = 26 - s;
wolfSSL 14:167253f4e170 11205 if (j + 1 >= max)
wolfSSL 14:167253f4e170 11206 break;
wolfSSL 14:167253f4e170 11207 r[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 11208 s = 8 - s;
wolfSSL 14:167253f4e170 11209 }
wolfSSL 14:167253f4e170 11210 else
wolfSSL 14:167253f4e170 11211 s += 8;
wolfSSL 14:167253f4e170 11212 }
wolfSSL 14:167253f4e170 11213
wolfSSL 14:167253f4e170 11214 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 11215 r[j] = 0;
wolfSSL 14:167253f4e170 11216 }
wolfSSL 14:167253f4e170 11217
wolfSSL 14:167253f4e170 11218 /* Generates a scalar that is in the range 1..order-1.
wolfSSL 14:167253f4e170 11219 *
wolfSSL 14:167253f4e170 11220 * rng Random number generator.
wolfSSL 14:167253f4e170 11221 * k Scalar value.
wolfSSL 14:167253f4e170 11222 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 14:167253f4e170 11223 * MP_OKAY on success.
wolfSSL 14:167253f4e170 11224 */
wolfSSL 14:167253f4e170 11225 static int sp_256_ecc_gen_k_10(WC_RNG* rng, sp_digit* k)
wolfSSL 14:167253f4e170 11226 {
wolfSSL 14:167253f4e170 11227 int err;
wolfSSL 14:167253f4e170 11228 byte buf[32];
wolfSSL 14:167253f4e170 11229
wolfSSL 14:167253f4e170 11230 do {
wolfSSL 14:167253f4e170 11231 err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));
wolfSSL 14:167253f4e170 11232 if (err == 0) {
wolfSSL 14:167253f4e170 11233 sp_256_from_bin(k, 10, buf, sizeof(buf));
wolfSSL 14:167253f4e170 11234 if (sp_256_cmp_10(k, p256_order2) < 0) {
wolfSSL 14:167253f4e170 11235 sp_256_add_one_10(k);
wolfSSL 14:167253f4e170 11236 break;
wolfSSL 14:167253f4e170 11237 }
wolfSSL 14:167253f4e170 11238 }
wolfSSL 14:167253f4e170 11239 }
wolfSSL 14:167253f4e170 11240 while (err == 0);
wolfSSL 14:167253f4e170 11241
wolfSSL 14:167253f4e170 11242 return err;
wolfSSL 14:167253f4e170 11243 }
wolfSSL 14:167253f4e170 11244
wolfSSL 14:167253f4e170 11245 /* Makes a random EC key pair.
wolfSSL 14:167253f4e170 11246 *
wolfSSL 14:167253f4e170 11247 * rng Random number generator.
wolfSSL 14:167253f4e170 11248 * priv Generated private value.
wolfSSL 14:167253f4e170 11249 * pub Generated public point.
wolfSSL 14:167253f4e170 11250 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 11251 * returns ECC_INF_E when the point does not have the correct order, RNG
wolfSSL 14:167253f4e170 11252 * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 11253 */
wolfSSL 14:167253f4e170 11254 int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)
wolfSSL 14:167253f4e170 11255 {
wolfSSL 14:167253f4e170 11256 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11257 sp_point p;
wolfSSL 14:167253f4e170 11258 sp_digit kd[10];
wolfSSL 14:167253f4e170 11259 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 11260 sp_point inf;
wolfSSL 14:167253f4e170 11261 #endif
wolfSSL 14:167253f4e170 11262 #endif
wolfSSL 14:167253f4e170 11263 sp_point* point;
wolfSSL 14:167253f4e170 11264 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 11265 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 11266 sp_point* infinity;
wolfSSL 14:167253f4e170 11267 #endif
wolfSSL 14:167253f4e170 11268 int err;
wolfSSL 14:167253f4e170 11269 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11270 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11271 #endif
wolfSSL 14:167253f4e170 11272
wolfSSL 14:167253f4e170 11273 (void)heap;
wolfSSL 14:167253f4e170 11274
wolfSSL 14:167253f4e170 11275 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 11276 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 11277 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11278 err = sp_ecc_point_new(heap, inf, infinity);
wolfSSL 14:167253f4e170 11279 #endif
wolfSSL 14:167253f4e170 11280 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11281 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11282 k = XMALLOC(sizeof(sp_digit) * 10, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11283 if (k == NULL)
wolfSSL 14:167253f4e170 11284 err = MEMORY_E;
wolfSSL 14:167253f4e170 11285 }
wolfSSL 14:167253f4e170 11286 #else
wolfSSL 14:167253f4e170 11287 k = kd;
wolfSSL 14:167253f4e170 11288 #endif
wolfSSL 14:167253f4e170 11289
wolfSSL 14:167253f4e170 11290 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11291 err = sp_256_ecc_gen_k_10(rng, k);
wolfSSL 14:167253f4e170 11292 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11293 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11294 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11295 err = sp_256_ecc_mulmod_base_avx2_10(point, k, 1, NULL);
wolfSSL 14:167253f4e170 11296 else
wolfSSL 14:167253f4e170 11297 #endif
wolfSSL 14:167253f4e170 11298 err = sp_256_ecc_mulmod_base_10(point, k, 1, NULL);
wolfSSL 14:167253f4e170 11299 }
wolfSSL 14:167253f4e170 11300
wolfSSL 14:167253f4e170 11301 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 11302 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11303 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11304 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {
wolfSSL 14:167253f4e170 11305 err = sp_256_ecc_mulmod_avx2_10(infinity, point, p256_order, 1,
wolfSSL 14:167253f4e170 11306 NULL);
wolfSSL 14:167253f4e170 11307 }
wolfSSL 14:167253f4e170 11308 else
wolfSSL 14:167253f4e170 11309 #endif
wolfSSL 14:167253f4e170 11310 err = sp_256_ecc_mulmod_10(infinity, point, p256_order, 1, NULL);
wolfSSL 14:167253f4e170 11311 }
wolfSSL 14:167253f4e170 11312 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11313 if (!sp_256_iszero_10(point->x) || !sp_256_iszero_10(point->y))
wolfSSL 14:167253f4e170 11314 err = ECC_INF_E;
wolfSSL 14:167253f4e170 11315 }
wolfSSL 14:167253f4e170 11316 #endif
wolfSSL 14:167253f4e170 11317
wolfSSL 14:167253f4e170 11318 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11319 err = sp_256_to_mp(k, priv);
wolfSSL 14:167253f4e170 11320 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11321 err = sp_256_point_to_ecc_point_10(point, pub);
wolfSSL 14:167253f4e170 11322
wolfSSL 14:167253f4e170 11323 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11324 if (k != NULL)
wolfSSL 14:167253f4e170 11325 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11326 #endif
wolfSSL 14:167253f4e170 11327 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 11328 sp_ecc_point_free(infinity, 1, heap);
wolfSSL 14:167253f4e170 11329 #endif
wolfSSL 14:167253f4e170 11330 sp_ecc_point_free(point, 1, heap);
wolfSSL 14:167253f4e170 11331
wolfSSL 14:167253f4e170 11332 return err;
wolfSSL 14:167253f4e170 11333 }
wolfSSL 14:167253f4e170 11334
wolfSSL 14:167253f4e170 11335 #ifdef HAVE_ECC_DHE
wolfSSL 14:167253f4e170 11336 /* Write r as big endian to byte aray.
wolfSSL 14:167253f4e170 11337 * Fixed length number of bytes written: 32
wolfSSL 14:167253f4e170 11338 *
wolfSSL 14:167253f4e170 11339 * r A single precision integer.
wolfSSL 14:167253f4e170 11340 * a Byte array.
wolfSSL 14:167253f4e170 11341 */
wolfSSL 14:167253f4e170 11342 static void sp_256_to_bin(sp_digit* r, byte* a)
wolfSSL 14:167253f4e170 11343 {
wolfSSL 14:167253f4e170 11344 int i, j, s = 0, b;
wolfSSL 14:167253f4e170 11345
wolfSSL 14:167253f4e170 11346 for (i=0; i<9; i++) {
wolfSSL 14:167253f4e170 11347 r[i+1] += r[i] >> 26;
wolfSSL 14:167253f4e170 11348 r[i] &= 0x3ffffff;
wolfSSL 14:167253f4e170 11349 }
wolfSSL 14:167253f4e170 11350 j = 256 / 8 - 1;
wolfSSL 14:167253f4e170 11351 a[j] = 0;
wolfSSL 14:167253f4e170 11352 for (i=0; i<10 && j>=0; i++) {
wolfSSL 14:167253f4e170 11353 b = 0;
wolfSSL 14:167253f4e170 11354 a[j--] |= r[i] << s; b += 8 - s;
wolfSSL 14:167253f4e170 11355 if (j < 0)
wolfSSL 14:167253f4e170 11356 break;
wolfSSL 14:167253f4e170 11357 while (b < 26) {
wolfSSL 14:167253f4e170 11358 a[j--] = r[i] >> b; b += 8;
wolfSSL 14:167253f4e170 11359 if (j < 0)
wolfSSL 14:167253f4e170 11360 break;
wolfSSL 14:167253f4e170 11361 }
wolfSSL 14:167253f4e170 11362 s = 8 - (b - 26);
wolfSSL 14:167253f4e170 11363 if (j >= 0)
wolfSSL 14:167253f4e170 11364 a[j] = 0;
wolfSSL 14:167253f4e170 11365 if (s != 0)
wolfSSL 14:167253f4e170 11366 j++;
wolfSSL 14:167253f4e170 11367 }
wolfSSL 14:167253f4e170 11368 }
wolfSSL 14:167253f4e170 11369
wolfSSL 14:167253f4e170 11370 /* Multiply the point by the scalar and serialize the X ordinate.
wolfSSL 14:167253f4e170 11371 * The number is 0 padded to maximum size on output.
wolfSSL 14:167253f4e170 11372 *
wolfSSL 14:167253f4e170 11373 * priv Scalar to multiply the point by.
wolfSSL 14:167253f4e170 11374 * pub Point to multiply.
wolfSSL 14:167253f4e170 11375 * out Buffer to hold X ordinate.
wolfSSL 14:167253f4e170 11376 * outLen On entry, size of the buffer in bytes.
wolfSSL 14:167253f4e170 11377 * On exit, length of data in buffer in bytes.
wolfSSL 14:167253f4e170 11378 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 11379 * returns BUFFER_E if the buffer is to small for output size,
wolfSSL 14:167253f4e170 11380 * MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 11381 */
wolfSSL 14:167253f4e170 11382 int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,
wolfSSL 14:167253f4e170 11383 word32* outLen, void* heap)
wolfSSL 14:167253f4e170 11384 {
wolfSSL 14:167253f4e170 11385 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11386 sp_point p;
wolfSSL 14:167253f4e170 11387 sp_digit kd[10];
wolfSSL 14:167253f4e170 11388 #endif
wolfSSL 14:167253f4e170 11389 sp_point* point = NULL;
wolfSSL 14:167253f4e170 11390 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 11391 int err = MP_OKAY;
wolfSSL 14:167253f4e170 11392 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11393 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11394 #endif
wolfSSL 14:167253f4e170 11395
wolfSSL 14:167253f4e170 11396 if (*outLen < 32)
wolfSSL 14:167253f4e170 11397 err = BUFFER_E;
wolfSSL 14:167253f4e170 11398
wolfSSL 14:167253f4e170 11399 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11400 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 11401 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11402 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11403 k = XMALLOC(sizeof(sp_digit) * 10, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11404 if (k == NULL)
wolfSSL 14:167253f4e170 11405 err = MEMORY_E;
wolfSSL 14:167253f4e170 11406 }
wolfSSL 14:167253f4e170 11407 #else
wolfSSL 14:167253f4e170 11408 k = kd;
wolfSSL 14:167253f4e170 11409 #endif
wolfSSL 14:167253f4e170 11410
wolfSSL 14:167253f4e170 11411 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11412 sp_256_from_mp(k, 10, priv);
wolfSSL 14:167253f4e170 11413 sp_256_point_from_ecc_point_10(point, pub);
wolfSSL 14:167253f4e170 11414 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11415 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11416 err = sp_256_ecc_mulmod_avx2_10(point, point, k, 1, heap);
wolfSSL 14:167253f4e170 11417 else
wolfSSL 14:167253f4e170 11418 #endif
wolfSSL 14:167253f4e170 11419 err = sp_256_ecc_mulmod_10(point, point, k, 1, heap);
wolfSSL 14:167253f4e170 11420 }
wolfSSL 14:167253f4e170 11421 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11422 sp_256_to_bin(point->x, out);
wolfSSL 14:167253f4e170 11423 *outLen = 32;
wolfSSL 14:167253f4e170 11424 }
wolfSSL 14:167253f4e170 11425
wolfSSL 14:167253f4e170 11426 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11427 if (k != NULL)
wolfSSL 14:167253f4e170 11428 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11429 #endif
wolfSSL 14:167253f4e170 11430 sp_ecc_point_free(point, 0, heap);
wolfSSL 14:167253f4e170 11431
wolfSSL 14:167253f4e170 11432 return err;
wolfSSL 14:167253f4e170 11433 }
wolfSSL 14:167253f4e170 11434 #endif /* HAVE_ECC_DHE */
wolfSSL 14:167253f4e170 11435
wolfSSL 14:167253f4e170 11436 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 11437 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11438 #endif /* HAVE_INTEL_AVX2 */
wolfSSL 14:167253f4e170 11439 #endif
wolfSSL 14:167253f4e170 11440 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 11441 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 11442 *
wolfSSL 14:167253f4e170 11443 * r A single precision integer.
wolfSSL 14:167253f4e170 11444 * a A single precision integer.
wolfSSL 14:167253f4e170 11445 * b A scalar.
wolfSSL 14:167253f4e170 11446 */
wolfSSL 14:167253f4e170 11447 SP_NOINLINE static void sp_256_mul_d_10(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 11448 const sp_digit b)
wolfSSL 14:167253f4e170 11449 {
wolfSSL 14:167253f4e170 11450 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 11451 int64_t tb = b;
wolfSSL 14:167253f4e170 11452 int64_t t = 0;
wolfSSL 14:167253f4e170 11453 int i;
wolfSSL 14:167253f4e170 11454
wolfSSL 14:167253f4e170 11455 for (i = 0; i < 10; i++) {
wolfSSL 14:167253f4e170 11456 t += tb * a[i];
wolfSSL 14:167253f4e170 11457 r[i] = t & 0x3ffffff;
wolfSSL 14:167253f4e170 11458 t >>= 26;
wolfSSL 14:167253f4e170 11459 }
wolfSSL 14:167253f4e170 11460 r[10] = (sp_digit)t;
wolfSSL 14:167253f4e170 11461 #else
wolfSSL 14:167253f4e170 11462 int64_t tb = b;
wolfSSL 14:167253f4e170 11463 int64_t t[10];
wolfSSL 14:167253f4e170 11464
wolfSSL 14:167253f4e170 11465 t[ 0] = tb * a[ 0];
wolfSSL 14:167253f4e170 11466 t[ 1] = tb * a[ 1];
wolfSSL 14:167253f4e170 11467 t[ 2] = tb * a[ 2];
wolfSSL 14:167253f4e170 11468 t[ 3] = tb * a[ 3];
wolfSSL 14:167253f4e170 11469 t[ 4] = tb * a[ 4];
wolfSSL 14:167253f4e170 11470 t[ 5] = tb * a[ 5];
wolfSSL 14:167253f4e170 11471 t[ 6] = tb * a[ 6];
wolfSSL 14:167253f4e170 11472 t[ 7] = tb * a[ 7];
wolfSSL 14:167253f4e170 11473 t[ 8] = tb * a[ 8];
wolfSSL 14:167253f4e170 11474 t[ 9] = tb * a[ 9];
wolfSSL 14:167253f4e170 11475 r[ 0] = (t[ 0] & 0x3ffffff);
wolfSSL 14:167253f4e170 11476 r[ 1] = (sp_digit)(t[ 0] >> 26) + (t[ 1] & 0x3ffffff);
wolfSSL 14:167253f4e170 11477 r[ 2] = (sp_digit)(t[ 1] >> 26) + (t[ 2] & 0x3ffffff);
wolfSSL 14:167253f4e170 11478 r[ 3] = (sp_digit)(t[ 2] >> 26) + (t[ 3] & 0x3ffffff);
wolfSSL 14:167253f4e170 11479 r[ 4] = (sp_digit)(t[ 3] >> 26) + (t[ 4] & 0x3ffffff);
wolfSSL 14:167253f4e170 11480 r[ 5] = (sp_digit)(t[ 4] >> 26) + (t[ 5] & 0x3ffffff);
wolfSSL 14:167253f4e170 11481 r[ 6] = (sp_digit)(t[ 5] >> 26) + (t[ 6] & 0x3ffffff);
wolfSSL 14:167253f4e170 11482 r[ 7] = (sp_digit)(t[ 6] >> 26) + (t[ 7] & 0x3ffffff);
wolfSSL 14:167253f4e170 11483 r[ 8] = (sp_digit)(t[ 7] >> 26) + (t[ 8] & 0x3ffffff);
wolfSSL 14:167253f4e170 11484 r[ 9] = (sp_digit)(t[ 8] >> 26) + (t[ 9] & 0x3ffffff);
wolfSSL 14:167253f4e170 11485 r[10] = (sp_digit)(t[ 9] >> 26);
wolfSSL 14:167253f4e170 11486 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 11487 }
wolfSSL 14:167253f4e170 11488
wolfSSL 14:167253f4e170 11489 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 11490 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 11491 *
wolfSSL 14:167253f4e170 11492 * a Nmber to be divided.
wolfSSL 14:167253f4e170 11493 * d Number to divide with.
wolfSSL 14:167253f4e170 11494 * m Multiplier result.
wolfSSL 14:167253f4e170 11495 * r Remainder from the division.
wolfSSL 14:167253f4e170 11496 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11497 */
wolfSSL 14:167253f4e170 11498 static int sp_256_div_10(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 11499 sp_digit* r)
wolfSSL 14:167253f4e170 11500 {
wolfSSL 14:167253f4e170 11501 int i;
wolfSSL 14:167253f4e170 11502 int64_t d1;
wolfSSL 14:167253f4e170 11503 sp_digit div, r1;
wolfSSL 14:167253f4e170 11504 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11505 sp_digit* td;
wolfSSL 14:167253f4e170 11506 #else
wolfSSL 14:167253f4e170 11507 sp_digit t1d[20], t2d[10 + 1];
wolfSSL 14:167253f4e170 11508 #endif
wolfSSL 14:167253f4e170 11509 sp_digit* t1;
wolfSSL 14:167253f4e170 11510 sp_digit* t2;
wolfSSL 14:167253f4e170 11511 int err = MP_OKAY;
wolfSSL 14:167253f4e170 11512
wolfSSL 14:167253f4e170 11513 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11514 td = XMALLOC(sizeof(sp_digit) * (3 * 10 + 1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 11515 if (td != NULL) {
wolfSSL 14:167253f4e170 11516 t1 = td;
wolfSSL 14:167253f4e170 11517 t2 = td + 2 * 10;
wolfSSL 14:167253f4e170 11518 }
wolfSSL 14:167253f4e170 11519 else
wolfSSL 14:167253f4e170 11520 err = MEMORY_E;
wolfSSL 14:167253f4e170 11521 #else
wolfSSL 14:167253f4e170 11522 t1 = t1d;
wolfSSL 14:167253f4e170 11523 t2 = t2d;
wolfSSL 14:167253f4e170 11524 #endif
wolfSSL 14:167253f4e170 11525
wolfSSL 14:167253f4e170 11526 (void)m;
wolfSSL 14:167253f4e170 11527
wolfSSL 14:167253f4e170 11528 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11529 div = d[9];
wolfSSL 14:167253f4e170 11530 XMEMCPY(t1, a, sizeof(*t1) * 2 * 10);
wolfSSL 14:167253f4e170 11531 for (i=9; i>=0; i--) {
wolfSSL 14:167253f4e170 11532 t1[10 + i] += t1[10 + i - 1] >> 26;
wolfSSL 14:167253f4e170 11533 t1[10 + i - 1] &= 0x3ffffff;
wolfSSL 14:167253f4e170 11534 d1 = t1[10 + i];
wolfSSL 14:167253f4e170 11535 d1 <<= 26;
wolfSSL 14:167253f4e170 11536 d1 += t1[10 + i - 1];
wolfSSL 14:167253f4e170 11537 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 11538
wolfSSL 14:167253f4e170 11539 sp_256_mul_d_10(t2, d, r1);
wolfSSL 14:167253f4e170 11540 sp_256_sub_10(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 11541 t1[10 + i] -= t2[10];
wolfSSL 14:167253f4e170 11542 t1[10 + i] += t1[10 + i - 1] >> 26;
wolfSSL 14:167253f4e170 11543 t1[10 + i - 1] &= 0x3ffffff;
wolfSSL 14:167253f4e170 11544 r1 = (((-t1[10 + i]) << 26) - t1[10 + i - 1]) / div;
wolfSSL 14:167253f4e170 11545 r1++;
wolfSSL 14:167253f4e170 11546 sp_256_mul_d_10(t2, d, r1);
wolfSSL 14:167253f4e170 11547 sp_256_add_10(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 11548 t1[10 + i] += t1[10 + i - 1] >> 26;
wolfSSL 14:167253f4e170 11549 t1[10 + i - 1] &= 0x3ffffff;
wolfSSL 14:167253f4e170 11550 }
wolfSSL 14:167253f4e170 11551 t1[10 - 1] += t1[10 - 2] >> 26;
wolfSSL 14:167253f4e170 11552 t1[10 - 2] &= 0x3ffffff;
wolfSSL 14:167253f4e170 11553 d1 = t1[10 - 1];
wolfSSL 14:167253f4e170 11554 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 11555
wolfSSL 14:167253f4e170 11556 sp_256_mul_d_10(t2, d, r1);
wolfSSL 14:167253f4e170 11557 sp_256_sub_10(t1, t1, t2);
wolfSSL 14:167253f4e170 11558 XMEMCPY(r, t1, sizeof(*r) * 2 * 10);
wolfSSL 14:167253f4e170 11559 for (i=0; i<8; i++) {
wolfSSL 14:167253f4e170 11560 r[i+1] += r[i] >> 26;
wolfSSL 14:167253f4e170 11561 r[i] &= 0x3ffffff;
wolfSSL 14:167253f4e170 11562 }
wolfSSL 14:167253f4e170 11563 sp_256_cond_add_10(r, r, d, 0 - (r[9] < 0));
wolfSSL 14:167253f4e170 11564 }
wolfSSL 14:167253f4e170 11565
wolfSSL 14:167253f4e170 11566 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11567 if (td != NULL)
wolfSSL 14:167253f4e170 11568 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 11569 #endif
wolfSSL 14:167253f4e170 11570
wolfSSL 14:167253f4e170 11571 return err;
wolfSSL 14:167253f4e170 11572 }
wolfSSL 14:167253f4e170 11573
wolfSSL 14:167253f4e170 11574 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 11575 *
wolfSSL 14:167253f4e170 11576 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 11577 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 11578 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 11579 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11580 */
wolfSSL 14:167253f4e170 11581 static int sp_256_mod_10(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 11582 {
wolfSSL 14:167253f4e170 11583 return sp_256_div_10(a, m, NULL, r);
wolfSSL 14:167253f4e170 11584 }
wolfSSL 14:167253f4e170 11585
wolfSSL 14:167253f4e170 11586 #endif
wolfSSL 14:167253f4e170 11587 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 11588 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 11589 /* Order-2 for the P256 curve. */
wolfSSL 14:167253f4e170 11590 static const uint32_t p256_order_2[8] = {
wolfSSL 14:167253f4e170 11591 0xfc63254f,0xf3b9cac2,0xa7179e84,0xbce6faad,0xffffffff,0xffffffff,
wolfSSL 14:167253f4e170 11592 0x00000000,0xffffffff
wolfSSL 14:167253f4e170 11593 };
wolfSSL 14:167253f4e170 11594 #else
wolfSSL 14:167253f4e170 11595 /* The low half of the order-2 of the P256 curve. */
wolfSSL 14:167253f4e170 11596 static const uint32_t p256_order_low[4] = {
wolfSSL 14:167253f4e170 11597 0xfc63254f,0xf3b9cac2,0xa7179e84,0xbce6faad
wolfSSL 14:167253f4e170 11598 };
wolfSSL 14:167253f4e170 11599 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 11600
wolfSSL 14:167253f4e170 11601 /* Multiply two number mod the order of P256 curve. (r = a * b mod order)
wolfSSL 14:167253f4e170 11602 *
wolfSSL 14:167253f4e170 11603 * r Result of the multiplication.
wolfSSL 14:167253f4e170 11604 * a First operand of the multiplication.
wolfSSL 14:167253f4e170 11605 * b Second operand of the multiplication.
wolfSSL 14:167253f4e170 11606 */
wolfSSL 14:167253f4e170 11607 static void sp_256_mont_mul_order_10(sp_digit* r, sp_digit* a, sp_digit* b)
wolfSSL 14:167253f4e170 11608 {
wolfSSL 14:167253f4e170 11609 sp_256_mul_10(r, a, b);
wolfSSL 14:167253f4e170 11610 sp_256_mont_reduce_10(r, p256_order, p256_mp_order);
wolfSSL 14:167253f4e170 11611 }
wolfSSL 14:167253f4e170 11612
wolfSSL 14:167253f4e170 11613 /* Square number mod the order of P256 curve. (r = a * a mod order)
wolfSSL 14:167253f4e170 11614 *
wolfSSL 14:167253f4e170 11615 * r Result of the squaring.
wolfSSL 14:167253f4e170 11616 * a Number to square.
wolfSSL 14:167253f4e170 11617 */
wolfSSL 14:167253f4e170 11618 static void sp_256_mont_sqr_order_10(sp_digit* r, sp_digit* a)
wolfSSL 14:167253f4e170 11619 {
wolfSSL 14:167253f4e170 11620 sp_256_sqr_10(r, a);
wolfSSL 14:167253f4e170 11621 sp_256_mont_reduce_10(r, p256_order, p256_mp_order);
wolfSSL 14:167253f4e170 11622 }
wolfSSL 14:167253f4e170 11623
wolfSSL 14:167253f4e170 11624 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 11625 /* Square number mod the order of P256 curve a number of times.
wolfSSL 14:167253f4e170 11626 * (r = a ^ n mod order)
wolfSSL 14:167253f4e170 11627 *
wolfSSL 14:167253f4e170 11628 * r Result of the squaring.
wolfSSL 14:167253f4e170 11629 * a Number to square.
wolfSSL 14:167253f4e170 11630 */
wolfSSL 14:167253f4e170 11631 static void sp_256_mont_sqr_n_order_10(sp_digit* r, sp_digit* a, int n)
wolfSSL 14:167253f4e170 11632 {
wolfSSL 14:167253f4e170 11633 int i;
wolfSSL 14:167253f4e170 11634
wolfSSL 14:167253f4e170 11635 sp_256_mont_sqr_order_10(r, a);
wolfSSL 14:167253f4e170 11636 for (i=1; i<n; i++)
wolfSSL 14:167253f4e170 11637 sp_256_mont_sqr_order_10(r, r);
wolfSSL 14:167253f4e170 11638 }
wolfSSL 14:167253f4e170 11639 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 11640
wolfSSL 14:167253f4e170 11641 /* Invert the number, in Montgomery form, modulo the order of the P256 curve.
wolfSSL 14:167253f4e170 11642 * (r = 1 / a mod order)
wolfSSL 14:167253f4e170 11643 *
wolfSSL 14:167253f4e170 11644 * r Inverse result.
wolfSSL 14:167253f4e170 11645 * a Number to invert.
wolfSSL 14:167253f4e170 11646 * td Temporary data.
wolfSSL 14:167253f4e170 11647 */
wolfSSL 14:167253f4e170 11648 static void sp_256_mont_inv_order_10(sp_digit* r, sp_digit* a,
wolfSSL 14:167253f4e170 11649 sp_digit* td)
wolfSSL 14:167253f4e170 11650 {
wolfSSL 14:167253f4e170 11651 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 11652 sp_digit* t = td;
wolfSSL 14:167253f4e170 11653 int i;
wolfSSL 14:167253f4e170 11654
wolfSSL 14:167253f4e170 11655 XMEMCPY(t, a, sizeof(sp_digit) * 10);
wolfSSL 14:167253f4e170 11656 for (i=254; i>=0; i--) {
wolfSSL 14:167253f4e170 11657 sp_256_mont_sqr_order_10(t, t);
wolfSSL 14:167253f4e170 11658 if (p256_order_2[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11659 sp_256_mont_mul_order_10(t, t, a);
wolfSSL 14:167253f4e170 11660 }
wolfSSL 14:167253f4e170 11661 XMEMCPY(r, t, sizeof(sp_digit) * 10);
wolfSSL 14:167253f4e170 11662 #else
wolfSSL 14:167253f4e170 11663 sp_digit* t = td;
wolfSSL 14:167253f4e170 11664 sp_digit* t2 = td + 2 * 10;
wolfSSL 14:167253f4e170 11665 sp_digit* t3 = td + 4 * 10;
wolfSSL 14:167253f4e170 11666 int i;
wolfSSL 14:167253f4e170 11667
wolfSSL 14:167253f4e170 11668 /* t = a^2 */
wolfSSL 14:167253f4e170 11669 sp_256_mont_sqr_order_10(t, a);
wolfSSL 14:167253f4e170 11670 /* t = a^3 = t * a */
wolfSSL 14:167253f4e170 11671 sp_256_mont_mul_order_10(t, t, a);
wolfSSL 14:167253f4e170 11672 /* t2= a^c = t ^ 2 ^ 2 */
wolfSSL 14:167253f4e170 11673 sp_256_mont_sqr_n_order_10(t2, t, 2);
wolfSSL 14:167253f4e170 11674 /* t3= a^f = t2 * t */
wolfSSL 14:167253f4e170 11675 sp_256_mont_mul_order_10(t3, t2, t);
wolfSSL 14:167253f4e170 11676 /* t2= a^f0 = t3 ^ 2 ^ 4 */
wolfSSL 14:167253f4e170 11677 sp_256_mont_sqr_n_order_10(t2, t3, 4);
wolfSSL 14:167253f4e170 11678 /* t = a^ff = t2 * t3 */
wolfSSL 14:167253f4e170 11679 sp_256_mont_mul_order_10(t, t2, t3);
wolfSSL 14:167253f4e170 11680 /* t3= a^ff00 = t ^ 2 ^ 8 */
wolfSSL 14:167253f4e170 11681 sp_256_mont_sqr_n_order_10(t2, t, 8);
wolfSSL 14:167253f4e170 11682 /* t = a^ffff = t2 * t */
wolfSSL 14:167253f4e170 11683 sp_256_mont_mul_order_10(t, t2, t);
wolfSSL 14:167253f4e170 11684 /* t2= a^ffff0000 = t ^ 2 ^ 16 */
wolfSSL 14:167253f4e170 11685 sp_256_mont_sqr_n_order_10(t2, t, 16);
wolfSSL 14:167253f4e170 11686 /* t = a^ffffffff = t2 * t */
wolfSSL 14:167253f4e170 11687 sp_256_mont_mul_order_10(t, t2, t);
wolfSSL 14:167253f4e170 11688 /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64 */
wolfSSL 14:167253f4e170 11689 sp_256_mont_sqr_n_order_10(t2, t, 64);
wolfSSL 14:167253f4e170 11690 /* t2= a^ffffffff00000000ffffffff = t2 * t */
wolfSSL 14:167253f4e170 11691 sp_256_mont_mul_order_10(t2, t2, t);
wolfSSL 14:167253f4e170 11692 /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32 */
wolfSSL 14:167253f4e170 11693 sp_256_mont_sqr_n_order_10(t2, t2, 32);
wolfSSL 14:167253f4e170 11694 /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */
wolfSSL 14:167253f4e170 11695 sp_256_mont_mul_order_10(t2, t2, t);
wolfSSL 14:167253f4e170 11696 /* t2= a^ffffffff00000000ffffffffffffffffbce6 */
wolfSSL 14:167253f4e170 11697 for (i=127; i>=112; i--) {
wolfSSL 14:167253f4e170 11698 sp_256_mont_sqr_order_10(t2, t2);
wolfSSL 14:167253f4e170 11699 if (p256_order_low[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11700 sp_256_mont_mul_order_10(t2, t2, a);
wolfSSL 14:167253f4e170 11701 }
wolfSSL 14:167253f4e170 11702 /* t2= a^ffffffff00000000ffffffffffffffffbce6f */
wolfSSL 14:167253f4e170 11703 sp_256_mont_sqr_n_order_10(t2, t2, 4);
wolfSSL 14:167253f4e170 11704 sp_256_mont_mul_order_10(t2, t2, t3);
wolfSSL 14:167253f4e170 11705 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */
wolfSSL 14:167253f4e170 11706 for (i=107; i>=64; i--) {
wolfSSL 14:167253f4e170 11707 sp_256_mont_sqr_order_10(t2, t2);
wolfSSL 14:167253f4e170 11708 if (p256_order_low[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11709 sp_256_mont_mul_order_10(t2, t2, a);
wolfSSL 14:167253f4e170 11710 }
wolfSSL 14:167253f4e170 11711 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */
wolfSSL 14:167253f4e170 11712 sp_256_mont_sqr_n_order_10(t2, t2, 4);
wolfSSL 14:167253f4e170 11713 sp_256_mont_mul_order_10(t2, t2, t3);
wolfSSL 14:167253f4e170 11714 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */
wolfSSL 14:167253f4e170 11715 for (i=59; i>=32; i--) {
wolfSSL 14:167253f4e170 11716 sp_256_mont_sqr_order_10(t2, t2);
wolfSSL 14:167253f4e170 11717 if (p256_order_low[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11718 sp_256_mont_mul_order_10(t2, t2, a);
wolfSSL 14:167253f4e170 11719 }
wolfSSL 14:167253f4e170 11720 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */
wolfSSL 14:167253f4e170 11721 sp_256_mont_sqr_n_order_10(t2, t2, 4);
wolfSSL 14:167253f4e170 11722 sp_256_mont_mul_order_10(t2, t2, t3);
wolfSSL 14:167253f4e170 11723 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */
wolfSSL 14:167253f4e170 11724 for (i=27; i>=0; i--) {
wolfSSL 14:167253f4e170 11725 sp_256_mont_sqr_order_10(t2, t2);
wolfSSL 14:167253f4e170 11726 if (p256_order_low[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11727 sp_256_mont_mul_order_10(t2, t2, a);
wolfSSL 14:167253f4e170 11728 }
wolfSSL 14:167253f4e170 11729 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */
wolfSSL 14:167253f4e170 11730 sp_256_mont_sqr_n_order_10(t2, t2, 4);
wolfSSL 14:167253f4e170 11731 /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */
wolfSSL 14:167253f4e170 11732 sp_256_mont_mul_order_10(r, t2, t3);
wolfSSL 14:167253f4e170 11733 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 11734 }
wolfSSL 14:167253f4e170 11735
wolfSSL 14:167253f4e170 11736 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11737 /* Multiply two number mod the order of P256 curve. (r = a * b mod order)
wolfSSL 14:167253f4e170 11738 *
wolfSSL 14:167253f4e170 11739 * r Result of the multiplication.
wolfSSL 14:167253f4e170 11740 * a First operand of the multiplication.
wolfSSL 14:167253f4e170 11741 * b Second operand of the multiplication.
wolfSSL 14:167253f4e170 11742 */
wolfSSL 14:167253f4e170 11743 static void sp_256_mont_mul_order_avx2_10(sp_digit* r, sp_digit* a, sp_digit* b)
wolfSSL 14:167253f4e170 11744 {
wolfSSL 14:167253f4e170 11745 sp_256_mul_avx2_10(r, a, b);
wolfSSL 14:167253f4e170 11746 sp_256_mont_reduce_avx2_10(r, p256_order, p256_mp_order);
wolfSSL 14:167253f4e170 11747 }
wolfSSL 14:167253f4e170 11748
wolfSSL 14:167253f4e170 11749 /* Square number mod the order of P256 curve. (r = a * a mod order)
wolfSSL 14:167253f4e170 11750 *
wolfSSL 14:167253f4e170 11751 * r Result of the squaring.
wolfSSL 14:167253f4e170 11752 * a Number to square.
wolfSSL 14:167253f4e170 11753 */
wolfSSL 14:167253f4e170 11754 static void sp_256_mont_sqr_order_avx2_10(sp_digit* r, sp_digit* a)
wolfSSL 14:167253f4e170 11755 {
wolfSSL 14:167253f4e170 11756 sp_256_sqr_avx2_10(r, a);
wolfSSL 14:167253f4e170 11757 sp_256_mont_reduce_avx2_10(r, p256_order, p256_mp_order);
wolfSSL 14:167253f4e170 11758 }
wolfSSL 14:167253f4e170 11759
wolfSSL 14:167253f4e170 11760 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 11761 /* Square number mod the order of P256 curve a number of times.
wolfSSL 14:167253f4e170 11762 * (r = a ^ n mod order)
wolfSSL 14:167253f4e170 11763 *
wolfSSL 14:167253f4e170 11764 * r Result of the squaring.
wolfSSL 14:167253f4e170 11765 * a Number to square.
wolfSSL 14:167253f4e170 11766 */
wolfSSL 14:167253f4e170 11767 static void sp_256_mont_sqr_n_order_avx2_10(sp_digit* r, sp_digit* a, int n)
wolfSSL 14:167253f4e170 11768 {
wolfSSL 14:167253f4e170 11769 int i;
wolfSSL 14:167253f4e170 11770
wolfSSL 14:167253f4e170 11771 sp_256_mont_sqr_order_avx2_10(r, a);
wolfSSL 14:167253f4e170 11772 for (i=1; i<n; i++)
wolfSSL 14:167253f4e170 11773 sp_256_mont_sqr_order_avx2_10(r, r);
wolfSSL 14:167253f4e170 11774 }
wolfSSL 14:167253f4e170 11775 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 11776
wolfSSL 14:167253f4e170 11777 /* Invert the number, in Montgomery form, modulo the order of the P256 curve.
wolfSSL 14:167253f4e170 11778 * (r = 1 / a mod order)
wolfSSL 14:167253f4e170 11779 *
wolfSSL 14:167253f4e170 11780 * r Inverse result.
wolfSSL 14:167253f4e170 11781 * a Number to invert.
wolfSSL 14:167253f4e170 11782 * td Temporary data.
wolfSSL 14:167253f4e170 11783 */
wolfSSL 14:167253f4e170 11784 static void sp_256_mont_inv_order_avx2_10(sp_digit* r, sp_digit* a,
wolfSSL 14:167253f4e170 11785 sp_digit* td)
wolfSSL 14:167253f4e170 11786 {
wolfSSL 14:167253f4e170 11787 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 11788 sp_digit* t = td;
wolfSSL 14:167253f4e170 11789 int i;
wolfSSL 14:167253f4e170 11790
wolfSSL 14:167253f4e170 11791 XMEMCPY(t, a, sizeof(sp_digit) * 10);
wolfSSL 14:167253f4e170 11792 for (i=254; i>=0; i--) {
wolfSSL 14:167253f4e170 11793 sp_256_mont_sqr_order_avx2_10(t, t);
wolfSSL 14:167253f4e170 11794 if (p256_order_2[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11795 sp_256_mont_mul_order_avx2_10(t, t, a);
wolfSSL 14:167253f4e170 11796 }
wolfSSL 14:167253f4e170 11797 XMEMCPY(r, t, sizeof(sp_digit) * 10);
wolfSSL 14:167253f4e170 11798 #else
wolfSSL 14:167253f4e170 11799 sp_digit* t = td;
wolfSSL 14:167253f4e170 11800 sp_digit* t2 = td + 2 * 10;
wolfSSL 14:167253f4e170 11801 sp_digit* t3 = td + 4 * 10;
wolfSSL 14:167253f4e170 11802 int i;
wolfSSL 14:167253f4e170 11803
wolfSSL 14:167253f4e170 11804 /* t = a^2 */
wolfSSL 14:167253f4e170 11805 sp_256_mont_sqr_order_avx2_10(t, a);
wolfSSL 14:167253f4e170 11806 /* t = a^3 = t * a */
wolfSSL 14:167253f4e170 11807 sp_256_mont_mul_order_avx2_10(t, t, a);
wolfSSL 14:167253f4e170 11808 /* t2= a^c = t ^ 2 ^ 2 */
wolfSSL 14:167253f4e170 11809 sp_256_mont_sqr_n_order_avx2_10(t2, t, 2);
wolfSSL 14:167253f4e170 11810 /* t3= a^f = t2 * t */
wolfSSL 14:167253f4e170 11811 sp_256_mont_mul_order_avx2_10(t3, t2, t);
wolfSSL 14:167253f4e170 11812 /* t2= a^f0 = t3 ^ 2 ^ 4 */
wolfSSL 14:167253f4e170 11813 sp_256_mont_sqr_n_order_avx2_10(t2, t3, 4);
wolfSSL 14:167253f4e170 11814 /* t = a^ff = t2 * t3 */
wolfSSL 14:167253f4e170 11815 sp_256_mont_mul_order_avx2_10(t, t2, t3);
wolfSSL 14:167253f4e170 11816 /* t3= a^ff00 = t ^ 2 ^ 8 */
wolfSSL 14:167253f4e170 11817 sp_256_mont_sqr_n_order_avx2_10(t2, t, 8);
wolfSSL 14:167253f4e170 11818 /* t = a^ffff = t2 * t */
wolfSSL 14:167253f4e170 11819 sp_256_mont_mul_order_avx2_10(t, t2, t);
wolfSSL 14:167253f4e170 11820 /* t2= a^ffff0000 = t ^ 2 ^ 16 */
wolfSSL 14:167253f4e170 11821 sp_256_mont_sqr_n_order_avx2_10(t2, t, 16);
wolfSSL 14:167253f4e170 11822 /* t = a^ffffffff = t2 * t */
wolfSSL 14:167253f4e170 11823 sp_256_mont_mul_order_avx2_10(t, t2, t);
wolfSSL 14:167253f4e170 11824 /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64 */
wolfSSL 14:167253f4e170 11825 sp_256_mont_sqr_n_order_avx2_10(t2, t, 64);
wolfSSL 14:167253f4e170 11826 /* t2= a^ffffffff00000000ffffffff = t2 * t */
wolfSSL 14:167253f4e170 11827 sp_256_mont_mul_order_avx2_10(t2, t2, t);
wolfSSL 14:167253f4e170 11828 /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32 */
wolfSSL 14:167253f4e170 11829 sp_256_mont_sqr_n_order_avx2_10(t2, t2, 32);
wolfSSL 14:167253f4e170 11830 /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */
wolfSSL 14:167253f4e170 11831 sp_256_mont_mul_order_avx2_10(t2, t2, t);
wolfSSL 14:167253f4e170 11832 /* t2= a^ffffffff00000000ffffffffffffffffbce6 */
wolfSSL 14:167253f4e170 11833 for (i=127; i>=112; i--) {
wolfSSL 14:167253f4e170 11834 sp_256_mont_sqr_order_avx2_10(t2, t2);
wolfSSL 14:167253f4e170 11835 if (p256_order_low[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11836 sp_256_mont_mul_order_avx2_10(t2, t2, a);
wolfSSL 14:167253f4e170 11837 }
wolfSSL 14:167253f4e170 11838 /* t2= a^ffffffff00000000ffffffffffffffffbce6f */
wolfSSL 14:167253f4e170 11839 sp_256_mont_sqr_n_order_avx2_10(t2, t2, 4);
wolfSSL 14:167253f4e170 11840 sp_256_mont_mul_order_avx2_10(t2, t2, t3);
wolfSSL 14:167253f4e170 11841 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */
wolfSSL 14:167253f4e170 11842 for (i=107; i>=64; i--) {
wolfSSL 14:167253f4e170 11843 sp_256_mont_sqr_order_avx2_10(t2, t2);
wolfSSL 14:167253f4e170 11844 if (p256_order_low[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11845 sp_256_mont_mul_order_avx2_10(t2, t2, a);
wolfSSL 14:167253f4e170 11846 }
wolfSSL 14:167253f4e170 11847 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */
wolfSSL 14:167253f4e170 11848 sp_256_mont_sqr_n_order_avx2_10(t2, t2, 4);
wolfSSL 14:167253f4e170 11849 sp_256_mont_mul_order_avx2_10(t2, t2, t3);
wolfSSL 14:167253f4e170 11850 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */
wolfSSL 14:167253f4e170 11851 for (i=59; i>=32; i--) {
wolfSSL 14:167253f4e170 11852 sp_256_mont_sqr_order_avx2_10(t2, t2);
wolfSSL 14:167253f4e170 11853 if (p256_order_low[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11854 sp_256_mont_mul_order_avx2_10(t2, t2, a);
wolfSSL 14:167253f4e170 11855 }
wolfSSL 14:167253f4e170 11856 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */
wolfSSL 14:167253f4e170 11857 sp_256_mont_sqr_n_order_avx2_10(t2, t2, 4);
wolfSSL 14:167253f4e170 11858 sp_256_mont_mul_order_avx2_10(t2, t2, t3);
wolfSSL 14:167253f4e170 11859 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */
wolfSSL 14:167253f4e170 11860 for (i=27; i>=0; i--) {
wolfSSL 14:167253f4e170 11861 sp_256_mont_sqr_order_avx2_10(t2, t2);
wolfSSL 14:167253f4e170 11862 if (p256_order_low[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 14:167253f4e170 11863 sp_256_mont_mul_order_avx2_10(t2, t2, a);
wolfSSL 14:167253f4e170 11864 }
wolfSSL 14:167253f4e170 11865 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */
wolfSSL 14:167253f4e170 11866 sp_256_mont_sqr_n_order_avx2_10(t2, t2, 4);
wolfSSL 14:167253f4e170 11867 /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */
wolfSSL 14:167253f4e170 11868 sp_256_mont_mul_order_avx2_10(r, t2, t3);
wolfSSL 14:167253f4e170 11869 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 11870 }
wolfSSL 14:167253f4e170 11871
wolfSSL 14:167253f4e170 11872 #endif /* HAVE_INTEL_AVX2 */
wolfSSL 14:167253f4e170 11873 #endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */
wolfSSL 14:167253f4e170 11874 #ifdef HAVE_ECC_SIGN
wolfSSL 14:167253f4e170 11875 #ifndef SP_ECC_MAX_SIG_GEN
wolfSSL 14:167253f4e170 11876 #define SP_ECC_MAX_SIG_GEN 64
wolfSSL 14:167253f4e170 11877 #endif
wolfSSL 14:167253f4e170 11878
wolfSSL 14:167253f4e170 11879 /* Sign the hash using the private key.
wolfSSL 14:167253f4e170 11880 * e = [hash, 256 bits] from binary
wolfSSL 14:167253f4e170 11881 * r = (k.G)->x mod order
wolfSSL 14:167253f4e170 11882 * s = (r * x + e) / k mod order
wolfSSL 14:167253f4e170 11883 * The hash is truncated to the first 256 bits.
wolfSSL 14:167253f4e170 11884 *
wolfSSL 14:167253f4e170 11885 * hash Hash to sign.
wolfSSL 14:167253f4e170 11886 * hashLen Length of the hash data.
wolfSSL 14:167253f4e170 11887 * rng Random number generator.
wolfSSL 14:167253f4e170 11888 * priv Private part of key - scalar.
wolfSSL 14:167253f4e170 11889 * rm First part of result as an mp_int.
wolfSSL 14:167253f4e170 11890 * sm Sirst part of result as an mp_int.
wolfSSL 14:167253f4e170 11891 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 11892 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 14:167253f4e170 11893 * MP_OKAY on success.
wolfSSL 14:167253f4e170 11894 */
wolfSSL 14:167253f4e170 11895 int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
wolfSSL 14:167253f4e170 11896 mp_int* rm, mp_int* sm, void* heap)
wolfSSL 14:167253f4e170 11897 {
wolfSSL 14:167253f4e170 11898 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11899 sp_digit* d;
wolfSSL 14:167253f4e170 11900 #else
wolfSSL 14:167253f4e170 11901 sp_digit ed[2*10];
wolfSSL 14:167253f4e170 11902 sp_digit xd[2*10];
wolfSSL 14:167253f4e170 11903 sp_digit kd[2*10];
wolfSSL 14:167253f4e170 11904 sp_digit rd[2*10];
wolfSSL 14:167253f4e170 11905 sp_digit td[3 * 2*10];
wolfSSL 14:167253f4e170 11906 sp_point p;
wolfSSL 14:167253f4e170 11907 #endif
wolfSSL 14:167253f4e170 11908 sp_digit* e = NULL;
wolfSSL 14:167253f4e170 11909 sp_digit* x = NULL;
wolfSSL 14:167253f4e170 11910 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 11911 sp_digit* r = NULL;
wolfSSL 14:167253f4e170 11912 sp_digit* tmp = NULL;
wolfSSL 14:167253f4e170 11913 sp_point* point = NULL;
wolfSSL 14:167253f4e170 11914 sp_digit carry;
wolfSSL 14:167253f4e170 11915 sp_digit* s;
wolfSSL 14:167253f4e170 11916 sp_digit* kInv;
wolfSSL 14:167253f4e170 11917 int err = MP_OKAY;
wolfSSL 14:167253f4e170 11918 int32_t c;
wolfSSL 14:167253f4e170 11919 int i;
wolfSSL 14:167253f4e170 11920 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11921 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11922 #endif
wolfSSL 14:167253f4e170 11923
wolfSSL 14:167253f4e170 11924 (void)heap;
wolfSSL 14:167253f4e170 11925
wolfSSL 14:167253f4e170 11926 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 11927 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11928 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11929 d = XMALLOC(sizeof(sp_digit) * 7 * 2 * 10, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11930 if (d != NULL) {
wolfSSL 14:167253f4e170 11931 e = d + 0 * 10;
wolfSSL 14:167253f4e170 11932 x = d + 2 * 10;
wolfSSL 14:167253f4e170 11933 k = d + 4 * 10;
wolfSSL 14:167253f4e170 11934 r = d + 6 * 10;
wolfSSL 14:167253f4e170 11935 tmp = d + 8 * 10;
wolfSSL 14:167253f4e170 11936 }
wolfSSL 14:167253f4e170 11937 else
wolfSSL 14:167253f4e170 11938 err = MEMORY_E;
wolfSSL 14:167253f4e170 11939 }
wolfSSL 14:167253f4e170 11940 #else
wolfSSL 14:167253f4e170 11941 e = ed;
wolfSSL 14:167253f4e170 11942 x = xd;
wolfSSL 14:167253f4e170 11943 k = kd;
wolfSSL 14:167253f4e170 11944 r = rd;
wolfSSL 14:167253f4e170 11945 tmp = td;
wolfSSL 14:167253f4e170 11946 #endif
wolfSSL 14:167253f4e170 11947 s = e;
wolfSSL 14:167253f4e170 11948 kInv = k;
wolfSSL 14:167253f4e170 11949
wolfSSL 14:167253f4e170 11950 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11951 if (hashLen > 32)
wolfSSL 14:167253f4e170 11952 hashLen = 32;
wolfSSL 14:167253f4e170 11953
wolfSSL 14:167253f4e170 11954 sp_256_from_bin(e, 10, hash, hashLen);
wolfSSL 14:167253f4e170 11955 sp_256_from_mp(x, 10, priv);
wolfSSL 14:167253f4e170 11956 }
wolfSSL 14:167253f4e170 11957
wolfSSL 14:167253f4e170 11958 for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {
wolfSSL 14:167253f4e170 11959 /* New random point. */
wolfSSL 14:167253f4e170 11960 err = sp_256_ecc_gen_k_10(rng, k);
wolfSSL 14:167253f4e170 11961 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11962 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11963 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11964 err = sp_256_ecc_mulmod_base_avx2_10(point, k, 1, heap);
wolfSSL 14:167253f4e170 11965 else
wolfSSL 14:167253f4e170 11966 #endif
wolfSSL 14:167253f4e170 11967 err = sp_256_ecc_mulmod_base_10(point, k, 1, NULL);
wolfSSL 14:167253f4e170 11968 }
wolfSSL 14:167253f4e170 11969
wolfSSL 14:167253f4e170 11970 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11971 /* r = point->x mod order */
wolfSSL 14:167253f4e170 11972 XMEMCPY(r, point->x, sizeof(sp_digit) * 10);
wolfSSL 14:167253f4e170 11973 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 11974 c = sp_256_cmp_10(r, p256_order);
wolfSSL 14:167253f4e170 11975 sp_256_cond_sub_10(r, r, p256_order, 0 - (c >= 0));
wolfSSL 14:167253f4e170 11976 sp_256_norm_10(r);
wolfSSL 14:167253f4e170 11977
wolfSSL 14:167253f4e170 11978 /* Conv k to Montgomery form (mod order) */
wolfSSL 14:167253f4e170 11979 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11980 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11981 sp_256_mul_avx2_10(k, k, p256_norm_order);
wolfSSL 14:167253f4e170 11982 else
wolfSSL 14:167253f4e170 11983 #endif
wolfSSL 14:167253f4e170 11984 sp_256_mul_10(k, k, p256_norm_order);
wolfSSL 14:167253f4e170 11985 err = sp_256_mod_10(k, k, p256_order);
wolfSSL 14:167253f4e170 11986 }
wolfSSL 14:167253f4e170 11987 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11988 sp_256_norm_10(k);
wolfSSL 14:167253f4e170 11989 /* kInv = 1/k mod order */
wolfSSL 14:167253f4e170 11990 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11991 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11992 sp_256_mont_inv_order_avx2_10(kInv, k, tmp);
wolfSSL 14:167253f4e170 11993 else
wolfSSL 14:167253f4e170 11994 #endif
wolfSSL 14:167253f4e170 11995 sp_256_mont_inv_order_10(kInv, k, tmp);
wolfSSL 14:167253f4e170 11996 sp_256_norm_10(kInv);
wolfSSL 14:167253f4e170 11997
wolfSSL 14:167253f4e170 11998 /* s = r * x + e */
wolfSSL 14:167253f4e170 11999 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12000 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12001 sp_256_mul_avx2_10(x, x, r);
wolfSSL 14:167253f4e170 12002 else
wolfSSL 14:167253f4e170 12003 #endif
wolfSSL 14:167253f4e170 12004 sp_256_mul_10(x, x, r);
wolfSSL 14:167253f4e170 12005 err = sp_256_mod_10(x, x, p256_order);
wolfSSL 14:167253f4e170 12006 }
wolfSSL 14:167253f4e170 12007 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12008 sp_256_norm_10(x);
wolfSSL 14:167253f4e170 12009 carry = sp_256_add_10(s, e, x);
wolfSSL 14:167253f4e170 12010 sp_256_cond_sub_10(s, s, p256_order, 0 - carry);
wolfSSL 14:167253f4e170 12011 sp_256_norm_10(s);
wolfSSL 14:167253f4e170 12012 c = sp_256_cmp_10(s, p256_order);
wolfSSL 14:167253f4e170 12013 sp_256_cond_sub_10(s, s, p256_order, 0 - (c >= 0));
wolfSSL 14:167253f4e170 12014 sp_256_norm_10(s);
wolfSSL 14:167253f4e170 12015
wolfSSL 14:167253f4e170 12016 /* s = s * k^-1 mod order */
wolfSSL 14:167253f4e170 12017 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12018 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12019 sp_256_mont_mul_order_avx2_10(s, s, kInv);
wolfSSL 14:167253f4e170 12020 else
wolfSSL 14:167253f4e170 12021 #endif
wolfSSL 14:167253f4e170 12022 sp_256_mont_mul_order_10(s, s, kInv);
wolfSSL 14:167253f4e170 12023 sp_256_norm_10(s);
wolfSSL 14:167253f4e170 12024
wolfSSL 14:167253f4e170 12025 /* Check that signature is usable. */
wolfSSL 14:167253f4e170 12026 if (!sp_256_iszero_10(s))
wolfSSL 14:167253f4e170 12027 break;
wolfSSL 14:167253f4e170 12028 }
wolfSSL 14:167253f4e170 12029 }
wolfSSL 14:167253f4e170 12030
wolfSSL 14:167253f4e170 12031 if (i == 0)
wolfSSL 14:167253f4e170 12032 err = RNG_FAILURE_E;
wolfSSL 14:167253f4e170 12033
wolfSSL 14:167253f4e170 12034 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12035 err = sp_256_to_mp(r, rm);
wolfSSL 14:167253f4e170 12036 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12037 err = sp_256_to_mp(s, sm);
wolfSSL 14:167253f4e170 12038
wolfSSL 14:167253f4e170 12039 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12040 if (d != NULL) {
wolfSSL 14:167253f4e170 12041 XMEMSET(d, 0, sizeof(sp_digit) * 8 * 10);
wolfSSL 14:167253f4e170 12042 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12043 }
wolfSSL 14:167253f4e170 12044 #else
wolfSSL 14:167253f4e170 12045 XMEMSET(e, 0, sizeof(sp_digit) * 2 * 10);
wolfSSL 14:167253f4e170 12046 XMEMSET(x, 0, sizeof(sp_digit) * 2 * 10);
wolfSSL 14:167253f4e170 12047 XMEMSET(k, 0, sizeof(sp_digit) * 2 * 10);
wolfSSL 14:167253f4e170 12048 XMEMSET(r, 0, sizeof(sp_digit) * 2 * 10);
wolfSSL 14:167253f4e170 12049 XMEMSET(r, 0, sizeof(sp_digit) * 2 * 10);
wolfSSL 14:167253f4e170 12050 XMEMSET(tmp, 0, sizeof(sp_digit) * 3 * 2*10);
wolfSSL 14:167253f4e170 12051 #endif
wolfSSL 14:167253f4e170 12052 sp_ecc_point_free(point, 1, heap);
wolfSSL 14:167253f4e170 12053
wolfSSL 14:167253f4e170 12054 return err;
wolfSSL 14:167253f4e170 12055 }
wolfSSL 14:167253f4e170 12056 #endif /* HAVE_ECC_SIGN */
wolfSSL 14:167253f4e170 12057
wolfSSL 14:167253f4e170 12058 #ifdef HAVE_ECC_VERIFY
wolfSSL 14:167253f4e170 12059 /* Verify the signature values with the hash and public key.
wolfSSL 14:167253f4e170 12060 * e = Truncate(hash, 256)
wolfSSL 14:167253f4e170 12061 * u1 = e/s mod order
wolfSSL 14:167253f4e170 12062 * u2 = r/s mod order
wolfSSL 14:167253f4e170 12063 * r == (u1.G + u2.Q)->x mod order
wolfSSL 14:167253f4e170 12064 * Optimization: Leave point in projective form.
wolfSSL 14:167253f4e170 12065 * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
wolfSSL 14:167253f4e170 12066 * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
wolfSSL 14:167253f4e170 12067 * The hash is truncated to the first 256 bits.
wolfSSL 14:167253f4e170 12068 *
wolfSSL 14:167253f4e170 12069 * hash Hash to sign.
wolfSSL 14:167253f4e170 12070 * hashLen Length of the hash data.
wolfSSL 14:167253f4e170 12071 * rng Random number generator.
wolfSSL 14:167253f4e170 12072 * priv Private part of key - scalar.
wolfSSL 14:167253f4e170 12073 * rm First part of result as an mp_int.
wolfSSL 14:167253f4e170 12074 * sm Sirst part of result as an mp_int.
wolfSSL 14:167253f4e170 12075 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 12076 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 14:167253f4e170 12077 * MP_OKAY on success.
wolfSSL 14:167253f4e170 12078 */
wolfSSL 14:167253f4e170 12079 int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
wolfSSL 14:167253f4e170 12080 mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)
wolfSSL 14:167253f4e170 12081 {
wolfSSL 14:167253f4e170 12082 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12083 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 12084 #else
wolfSSL 14:167253f4e170 12085 sp_digit u1d[2*10];
wolfSSL 14:167253f4e170 12086 sp_digit u2d[2*10];
wolfSSL 14:167253f4e170 12087 sp_digit sd[2*10];
wolfSSL 14:167253f4e170 12088 sp_digit tmpd[2*10 * 5];
wolfSSL 14:167253f4e170 12089 sp_point p1d;
wolfSSL 14:167253f4e170 12090 sp_point p2d;
wolfSSL 14:167253f4e170 12091 #endif
wolfSSL 14:167253f4e170 12092 sp_digit* u1;
wolfSSL 14:167253f4e170 12093 sp_digit* u2;
wolfSSL 14:167253f4e170 12094 sp_digit* s;
wolfSSL 14:167253f4e170 12095 sp_digit* tmp;
wolfSSL 14:167253f4e170 12096 sp_point* p1;
wolfSSL 14:167253f4e170 12097 sp_point* p2 = NULL;
wolfSSL 14:167253f4e170 12098 sp_digit carry;
wolfSSL 14:167253f4e170 12099 int32_t c;
wolfSSL 14:167253f4e170 12100 int err;
wolfSSL 14:167253f4e170 12101 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12102 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 12103 #endif
wolfSSL 14:167253f4e170 12104
wolfSSL 14:167253f4e170 12105 err = sp_ecc_point_new(heap, p1d, p1);
wolfSSL 14:167253f4e170 12106 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12107 err = sp_ecc_point_new(heap, p2d, p2);
wolfSSL 14:167253f4e170 12108 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12109 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12110 d = XMALLOC(sizeof(sp_digit) * 16 * 10, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12111 if (d != NULL) {
wolfSSL 14:167253f4e170 12112 u1 = d + 0 * 10;
wolfSSL 14:167253f4e170 12113 u2 = d + 2 * 10;
wolfSSL 14:167253f4e170 12114 s = d + 4 * 10;
wolfSSL 14:167253f4e170 12115 tmp = d + 6 * 10;
wolfSSL 14:167253f4e170 12116 }
wolfSSL 14:167253f4e170 12117 else
wolfSSL 14:167253f4e170 12118 err = MEMORY_E;
wolfSSL 14:167253f4e170 12119 }
wolfSSL 14:167253f4e170 12120 #else
wolfSSL 14:167253f4e170 12121 u1 = u1d;
wolfSSL 14:167253f4e170 12122 u2 = u2d;
wolfSSL 14:167253f4e170 12123 s = sd;
wolfSSL 14:167253f4e170 12124 tmp = tmpd;
wolfSSL 14:167253f4e170 12125 #endif
wolfSSL 14:167253f4e170 12126
wolfSSL 14:167253f4e170 12127 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12128 if (hashLen > 32)
wolfSSL 14:167253f4e170 12129 hashLen = 32;
wolfSSL 14:167253f4e170 12130
wolfSSL 14:167253f4e170 12131 sp_256_from_bin(u1, 10, hash, hashLen);
wolfSSL 14:167253f4e170 12132 sp_256_from_mp(u2, 10, r);
wolfSSL 14:167253f4e170 12133 sp_256_from_mp(s, 10, sm);
wolfSSL 14:167253f4e170 12134 sp_256_from_mp(p2->x, 10, pX);
wolfSSL 14:167253f4e170 12135 sp_256_from_mp(p2->y, 10, pY);
wolfSSL 14:167253f4e170 12136 sp_256_from_mp(p2->z, 10, pZ);
wolfSSL 14:167253f4e170 12137
wolfSSL 14:167253f4e170 12138 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12139 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12140 sp_256_mul_avx2_10(s, s, p256_norm_order);
wolfSSL 14:167253f4e170 12141 else
wolfSSL 14:167253f4e170 12142 #endif
wolfSSL 14:167253f4e170 12143 sp_256_mul_10(s, s, p256_norm_order);
wolfSSL 14:167253f4e170 12144 err = sp_256_mod_10(s, s, p256_order);
wolfSSL 14:167253f4e170 12145 }
wolfSSL 14:167253f4e170 12146 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12147 sp_256_norm_10(s);
wolfSSL 14:167253f4e170 12148 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12149 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {
wolfSSL 14:167253f4e170 12150 sp_256_mont_inv_order_avx2_10(s, s, tmp);
wolfSSL 14:167253f4e170 12151 sp_256_mont_mul_order_avx2_10(u1, u1, s);
wolfSSL 14:167253f4e170 12152 sp_256_mont_mul_order_avx2_10(u2, u2, s);
wolfSSL 14:167253f4e170 12153 }
wolfSSL 14:167253f4e170 12154 else
wolfSSL 14:167253f4e170 12155 #endif
wolfSSL 14:167253f4e170 12156 {
wolfSSL 14:167253f4e170 12157 sp_256_mont_inv_order_10(s, s, tmp);
wolfSSL 14:167253f4e170 12158 sp_256_mont_mul_order_10(u1, u1, s);
wolfSSL 14:167253f4e170 12159 sp_256_mont_mul_order_10(u2, u2, s);
wolfSSL 14:167253f4e170 12160 }
wolfSSL 14:167253f4e170 12161
wolfSSL 14:167253f4e170 12162 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12163 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12164 err = sp_256_ecc_mulmod_base_avx2_10(p1, u1, 0, heap);
wolfSSL 14:167253f4e170 12165 else
wolfSSL 14:167253f4e170 12166 #endif
wolfSSL 14:167253f4e170 12167 err = sp_256_ecc_mulmod_base_10(p1, u1, 0, heap);
wolfSSL 14:167253f4e170 12168 }
wolfSSL 14:167253f4e170 12169 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12170 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12171 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12172 err = sp_256_ecc_mulmod_avx2_10(p2, p2, u2, 0, heap);
wolfSSL 14:167253f4e170 12173 else
wolfSSL 14:167253f4e170 12174 #endif
wolfSSL 14:167253f4e170 12175 err = sp_256_ecc_mulmod_10(p2, p2, u2, 0, heap);
wolfSSL 14:167253f4e170 12176 }
wolfSSL 14:167253f4e170 12177
wolfSSL 14:167253f4e170 12178 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12179 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12180 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12181 sp_256_proj_point_add_avx2_10(p1, p1, p2, tmp);
wolfSSL 14:167253f4e170 12182 else
wolfSSL 14:167253f4e170 12183 #endif
wolfSSL 14:167253f4e170 12184 sp_256_proj_point_add_10(p1, p1, p2, tmp);
wolfSSL 14:167253f4e170 12185
wolfSSL 14:167253f4e170 12186 /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
wolfSSL 14:167253f4e170 12187 /* Reload r and convert to Montgomery form. */
wolfSSL 14:167253f4e170 12188 sp_256_from_mp(u2, 10, r);
wolfSSL 14:167253f4e170 12189 err = sp_256_mod_mul_norm_10(u2, u2, p256_mod);
wolfSSL 14:167253f4e170 12190 }
wolfSSL 14:167253f4e170 12191
wolfSSL 14:167253f4e170 12192 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12193 /* u1 = r.z'.z' mod prime */
wolfSSL 14:167253f4e170 12194 sp_256_mont_sqr_10(p1->z, p1->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12195 sp_256_mont_mul_10(u1, u2, p1->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12196 *res = sp_256_cmp_10(p1->x, u1) == 0;
wolfSSL 14:167253f4e170 12197 if (*res == 0) {
wolfSSL 14:167253f4e170 12198 /* Reload r and add order. */
wolfSSL 14:167253f4e170 12199 sp_256_from_mp(u2, 10, r);
wolfSSL 14:167253f4e170 12200 carry = sp_256_add_10(u2, u2, p256_order);
wolfSSL 14:167253f4e170 12201 /* Carry means result is greater than mod and is not valid. */
wolfSSL 14:167253f4e170 12202 if (!carry) {
wolfSSL 14:167253f4e170 12203 sp_256_norm_10(u2);
wolfSSL 14:167253f4e170 12204
wolfSSL 14:167253f4e170 12205 /* Compare with mod and if greater or equal then not valid. */
wolfSSL 14:167253f4e170 12206 c = sp_256_cmp_10(u2, p256_mod);
wolfSSL 14:167253f4e170 12207 if (c < 0) {
wolfSSL 14:167253f4e170 12208 /* Convert to Montogomery form */
wolfSSL 14:167253f4e170 12209 err = sp_256_mod_mul_norm_10(u2, u2, p256_mod);
wolfSSL 14:167253f4e170 12210 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12211 /* u1 = (r + 1*order).z'.z' mod prime */
wolfSSL 14:167253f4e170 12212 sp_256_mont_mul_10(u1, u2, p1->z, p256_mod,
wolfSSL 14:167253f4e170 12213 p256_mp_mod);
wolfSSL 14:167253f4e170 12214 *res = sp_256_cmp_10(p1->x, u2) == 0;
wolfSSL 14:167253f4e170 12215 }
wolfSSL 14:167253f4e170 12216 }
wolfSSL 14:167253f4e170 12217 }
wolfSSL 14:167253f4e170 12218 }
wolfSSL 14:167253f4e170 12219 }
wolfSSL 14:167253f4e170 12220
wolfSSL 14:167253f4e170 12221 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12222 if (d != NULL)
wolfSSL 14:167253f4e170 12223 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12224 #endif
wolfSSL 14:167253f4e170 12225 sp_ecc_point_free(p1, 0, heap);
wolfSSL 14:167253f4e170 12226 sp_ecc_point_free(p2, 0, heap);
wolfSSL 14:167253f4e170 12227
wolfSSL 14:167253f4e170 12228 return err;
wolfSSL 14:167253f4e170 12229 }
wolfSSL 14:167253f4e170 12230 #endif /* HAVE_ECC_VERIFY */
wolfSSL 14:167253f4e170 12231
wolfSSL 14:167253f4e170 12232 #ifdef HAVE_ECC_CHECK_KEY
wolfSSL 14:167253f4e170 12233 /* Check that the x and y oridinates are a valid point on the curve.
wolfSSL 14:167253f4e170 12234 *
wolfSSL 14:167253f4e170 12235 * point EC point.
wolfSSL 14:167253f4e170 12236 * heap Heap to use if dynamically allocating.
wolfSSL 14:167253f4e170 12237 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 14:167253f4e170 12238 * not on the curve and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 12239 */
wolfSSL 14:167253f4e170 12240 static int sp_256_ecc_is_point_10(sp_point* point, void* heap)
wolfSSL 14:167253f4e170 12241 {
wolfSSL 14:167253f4e170 12242 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12243 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 12244 #else
wolfSSL 14:167253f4e170 12245 sp_digit t1d[2*10];
wolfSSL 14:167253f4e170 12246 sp_digit t2d[2*10];
wolfSSL 14:167253f4e170 12247 #endif
wolfSSL 14:167253f4e170 12248 sp_digit* t1;
wolfSSL 14:167253f4e170 12249 sp_digit* t2;
wolfSSL 14:167253f4e170 12250 int err = MP_OKAY;
wolfSSL 14:167253f4e170 12251
wolfSSL 14:167253f4e170 12252 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12253 d = XMALLOC(sizeof(sp_digit) * 10 * 4, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12254 if (d != NULL) {
wolfSSL 14:167253f4e170 12255 t1 = d + 0 * 10;
wolfSSL 14:167253f4e170 12256 t2 = d + 2 * 10;
wolfSSL 14:167253f4e170 12257 }
wolfSSL 14:167253f4e170 12258 else
wolfSSL 14:167253f4e170 12259 err = MEMORY_E;
wolfSSL 14:167253f4e170 12260 #else
wolfSSL 14:167253f4e170 12261 (void)heap;
wolfSSL 14:167253f4e170 12262
wolfSSL 14:167253f4e170 12263 t1 = t1d;
wolfSSL 14:167253f4e170 12264 t2 = t2d;
wolfSSL 14:167253f4e170 12265 #endif
wolfSSL 14:167253f4e170 12266
wolfSSL 14:167253f4e170 12267 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12268 sp_256_sqr_10(t1, point->y);
wolfSSL 14:167253f4e170 12269 sp_256_mod_10(t1, t1, p256_mod);
wolfSSL 14:167253f4e170 12270 sp_256_sqr_10(t2, point->x);
wolfSSL 14:167253f4e170 12271 sp_256_mod_10(t2, t2, p256_mod);
wolfSSL 14:167253f4e170 12272 sp_256_mul_10(t2, t2, point->x);
wolfSSL 14:167253f4e170 12273 sp_256_mod_10(t2, t2, p256_mod);
wolfSSL 14:167253f4e170 12274 sp_256_sub_10(t2, p256_mod, t2);
wolfSSL 14:167253f4e170 12275 sp_256_mont_add_10(t1, t1, t2, p256_mod);
wolfSSL 14:167253f4e170 12276
wolfSSL 14:167253f4e170 12277 sp_256_mont_add_10(t1, t1, point->x, p256_mod);
wolfSSL 14:167253f4e170 12278 sp_256_mont_add_10(t1, t1, point->x, p256_mod);
wolfSSL 14:167253f4e170 12279 sp_256_mont_add_10(t1, t1, point->x, p256_mod);
wolfSSL 14:167253f4e170 12280
wolfSSL 14:167253f4e170 12281 if (sp_256_cmp_10(t1, p256_b) != 0)
wolfSSL 14:167253f4e170 12282 err = MP_VAL;
wolfSSL 14:167253f4e170 12283 }
wolfSSL 14:167253f4e170 12284
wolfSSL 14:167253f4e170 12285 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12286 if (d != NULL)
wolfSSL 14:167253f4e170 12287 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12288 #endif
wolfSSL 14:167253f4e170 12289
wolfSSL 14:167253f4e170 12290 return err;
wolfSSL 14:167253f4e170 12291 }
wolfSSL 14:167253f4e170 12292
wolfSSL 14:167253f4e170 12293 /* Check that the x and y oridinates are a valid point on the curve.
wolfSSL 14:167253f4e170 12294 *
wolfSSL 14:167253f4e170 12295 * pX X ordinate of EC point.
wolfSSL 14:167253f4e170 12296 * pY Y ordinate of EC point.
wolfSSL 14:167253f4e170 12297 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 14:167253f4e170 12298 * not on the curve and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 12299 */
wolfSSL 14:167253f4e170 12300 int sp_ecc_is_point_256(mp_int* pX, mp_int* pY)
wolfSSL 14:167253f4e170 12301 {
wolfSSL 14:167253f4e170 12302 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12303 sp_point pubd;
wolfSSL 14:167253f4e170 12304 #endif
wolfSSL 14:167253f4e170 12305 sp_point* pub;
wolfSSL 14:167253f4e170 12306 byte one[1] = { 1 };
wolfSSL 14:167253f4e170 12307 int err;
wolfSSL 14:167253f4e170 12308
wolfSSL 14:167253f4e170 12309 err = sp_ecc_point_new(NULL, pubd, pub);
wolfSSL 14:167253f4e170 12310 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12311 sp_256_from_mp(pub->x, 10, pX);
wolfSSL 14:167253f4e170 12312 sp_256_from_mp(pub->y, 10, pY);
wolfSSL 14:167253f4e170 12313 sp_256_from_bin(pub->z, 10, one, sizeof(one));
wolfSSL 14:167253f4e170 12314
wolfSSL 14:167253f4e170 12315 err = sp_256_ecc_is_point_10(pub, NULL);
wolfSSL 14:167253f4e170 12316 }
wolfSSL 14:167253f4e170 12317
wolfSSL 14:167253f4e170 12318 sp_ecc_point_free(pub, 0, NULL);
wolfSSL 14:167253f4e170 12319
wolfSSL 14:167253f4e170 12320 return err;
wolfSSL 14:167253f4e170 12321 }
wolfSSL 14:167253f4e170 12322
wolfSSL 14:167253f4e170 12323 /* Check that the private scalar generates the EC point (px, py), the point is
wolfSSL 14:167253f4e170 12324 * on the curve and the point has the correct order.
wolfSSL 14:167253f4e170 12325 *
wolfSSL 14:167253f4e170 12326 * pX X ordinate of EC point.
wolfSSL 14:167253f4e170 12327 * pY Y ordinate of EC point.
wolfSSL 14:167253f4e170 12328 * privm Private scalar that generates EC point.
wolfSSL 14:167253f4e170 12329 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 14:167253f4e170 12330 * not on the curve, ECC_INF_E if the point does not have the correct order,
wolfSSL 14:167253f4e170 12331 * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
wolfSSL 14:167253f4e170 12332 * MP_OKAY otherwise.
wolfSSL 14:167253f4e170 12333 */
wolfSSL 14:167253f4e170 12334 int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)
wolfSSL 14:167253f4e170 12335 {
wolfSSL 14:167253f4e170 12336 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12337 sp_digit privd[10];
wolfSSL 14:167253f4e170 12338 sp_point pubd;
wolfSSL 14:167253f4e170 12339 sp_point pd;
wolfSSL 14:167253f4e170 12340 #endif
wolfSSL 14:167253f4e170 12341 sp_digit* priv = NULL;
wolfSSL 14:167253f4e170 12342 sp_point* pub;
wolfSSL 14:167253f4e170 12343 sp_point* p = NULL;
wolfSSL 14:167253f4e170 12344 byte one[1] = { 1 };
wolfSSL 14:167253f4e170 12345 int err;
wolfSSL 14:167253f4e170 12346 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12347 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 12348 #endif
wolfSSL 14:167253f4e170 12349
wolfSSL 14:167253f4e170 12350 err = sp_ecc_point_new(heap, pubd, pub);
wolfSSL 14:167253f4e170 12351 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12352 err = sp_ecc_point_new(heap, pd, p);
wolfSSL 14:167253f4e170 12353 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12354 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12355 priv = XMALLOC(sizeof(sp_digit) * 10, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12356 if (priv == NULL)
wolfSSL 14:167253f4e170 12357 err = MEMORY_E;
wolfSSL 14:167253f4e170 12358 }
wolfSSL 14:167253f4e170 12359 #else
wolfSSL 14:167253f4e170 12360 priv = privd;
wolfSSL 14:167253f4e170 12361 #endif
wolfSSL 14:167253f4e170 12362
wolfSSL 14:167253f4e170 12363 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12364 sp_256_from_mp(pub->x, 10, pX);
wolfSSL 14:167253f4e170 12365 sp_256_from_mp(pub->y, 10, pY);
wolfSSL 14:167253f4e170 12366 sp_256_from_bin(pub->z, 10, one, sizeof(one));
wolfSSL 14:167253f4e170 12367 sp_256_from_mp(priv, 10, privm);
wolfSSL 14:167253f4e170 12368
wolfSSL 14:167253f4e170 12369 /* Check point at infinitiy. */
wolfSSL 14:167253f4e170 12370 if (sp_256_iszero_10(pub->x) &&
wolfSSL 14:167253f4e170 12371 sp_256_iszero_10(pub->y))
wolfSSL 14:167253f4e170 12372 err = ECC_INF_E;
wolfSSL 14:167253f4e170 12373 }
wolfSSL 14:167253f4e170 12374
wolfSSL 14:167253f4e170 12375 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12376 /* Check range of X and Y */
wolfSSL 14:167253f4e170 12377 if (sp_256_cmp_10(pub->x, p256_mod) >= 0 ||
wolfSSL 14:167253f4e170 12378 sp_256_cmp_10(pub->y, p256_mod) >= 0)
wolfSSL 14:167253f4e170 12379 err = ECC_OUT_OF_RANGE_E;
wolfSSL 14:167253f4e170 12380 }
wolfSSL 14:167253f4e170 12381
wolfSSL 14:167253f4e170 12382 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12383 /* Check point is on curve */
wolfSSL 14:167253f4e170 12384 err = sp_256_ecc_is_point_10(pub, heap);
wolfSSL 14:167253f4e170 12385 }
wolfSSL 14:167253f4e170 12386
wolfSSL 14:167253f4e170 12387 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12388 /* Point * order = infinity */
wolfSSL 14:167253f4e170 12389 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12390 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12391 err = sp_256_ecc_mulmod_avx2_10(p, pub, p256_order, 1, heap);
wolfSSL 14:167253f4e170 12392 else
wolfSSL 14:167253f4e170 12393 #endif
wolfSSL 14:167253f4e170 12394 err = sp_256_ecc_mulmod_10(p, pub, p256_order, 1, heap);
wolfSSL 14:167253f4e170 12395 }
wolfSSL 14:167253f4e170 12396 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12397 /* Check result is infinity */
wolfSSL 14:167253f4e170 12398 if (!sp_256_iszero_10(p->x) ||
wolfSSL 14:167253f4e170 12399 !sp_256_iszero_10(p->y)) {
wolfSSL 14:167253f4e170 12400 err = ECC_INF_E;
wolfSSL 14:167253f4e170 12401 }
wolfSSL 14:167253f4e170 12402 }
wolfSSL 14:167253f4e170 12403
wolfSSL 14:167253f4e170 12404 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12405 /* Base * private = point */
wolfSSL 14:167253f4e170 12406 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12407 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12408 err = sp_256_ecc_mulmod_base_avx2_10(p, priv, 1, heap);
wolfSSL 14:167253f4e170 12409 else
wolfSSL 14:167253f4e170 12410 #endif
wolfSSL 14:167253f4e170 12411 err = sp_256_ecc_mulmod_base_10(p, priv, 1, heap);
wolfSSL 14:167253f4e170 12412 }
wolfSSL 14:167253f4e170 12413 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12414 /* Check result is public key */
wolfSSL 14:167253f4e170 12415 if (sp_256_cmp_10(p->x, pub->x) != 0 ||
wolfSSL 14:167253f4e170 12416 sp_256_cmp_10(p->y, pub->y) != 0) {
wolfSSL 14:167253f4e170 12417 err = ECC_PRIV_KEY_E;
wolfSSL 14:167253f4e170 12418 }
wolfSSL 14:167253f4e170 12419 }
wolfSSL 14:167253f4e170 12420
wolfSSL 14:167253f4e170 12421 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12422 if (priv != NULL)
wolfSSL 14:167253f4e170 12423 XFREE(priv, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12424 #endif
wolfSSL 14:167253f4e170 12425 sp_ecc_point_free(p, 0, heap);
wolfSSL 14:167253f4e170 12426 sp_ecc_point_free(pub, 0, heap);
wolfSSL 14:167253f4e170 12427
wolfSSL 14:167253f4e170 12428 return err;
wolfSSL 14:167253f4e170 12429 }
wolfSSL 14:167253f4e170 12430 #endif
wolfSSL 14:167253f4e170 12431 #ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
wolfSSL 14:167253f4e170 12432 /* Add two projective EC points together.
wolfSSL 14:167253f4e170 12433 * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)
wolfSSL 14:167253f4e170 12434 *
wolfSSL 14:167253f4e170 12435 * pX First EC point's X ordinate.
wolfSSL 14:167253f4e170 12436 * pY First EC point's Y ordinate.
wolfSSL 14:167253f4e170 12437 * pZ First EC point's Z ordinate.
wolfSSL 14:167253f4e170 12438 * qX Second EC point's X ordinate.
wolfSSL 14:167253f4e170 12439 * qY Second EC point's Y ordinate.
wolfSSL 14:167253f4e170 12440 * qZ Second EC point's Z ordinate.
wolfSSL 14:167253f4e170 12441 * rX Resultant EC point's X ordinate.
wolfSSL 14:167253f4e170 12442 * rY Resultant EC point's Y ordinate.
wolfSSL 14:167253f4e170 12443 * rZ Resultant EC point's Z ordinate.
wolfSSL 14:167253f4e170 12444 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 12445 */
wolfSSL 14:167253f4e170 12446 int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
wolfSSL 14:167253f4e170 12447 mp_int* qX, mp_int* qY, mp_int* qZ,
wolfSSL 14:167253f4e170 12448 mp_int* rX, mp_int* rY, mp_int* rZ)
wolfSSL 14:167253f4e170 12449 {
wolfSSL 14:167253f4e170 12450 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12451 sp_digit tmpd[2 * 10 * 5];
wolfSSL 14:167253f4e170 12452 sp_point pd;
wolfSSL 14:167253f4e170 12453 sp_point qd;
wolfSSL 14:167253f4e170 12454 #endif
wolfSSL 14:167253f4e170 12455 sp_digit* tmp;
wolfSSL 14:167253f4e170 12456 sp_point* p;
wolfSSL 14:167253f4e170 12457 sp_point* q = NULL;
wolfSSL 14:167253f4e170 12458 int err;
wolfSSL 14:167253f4e170 12459 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12460 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 12461 #endif
wolfSSL 14:167253f4e170 12462
wolfSSL 14:167253f4e170 12463 err = sp_ecc_point_new(NULL, pd, p);
wolfSSL 14:167253f4e170 12464 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12465 err = sp_ecc_point_new(NULL, qd, q);
wolfSSL 14:167253f4e170 12466 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12467 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12468 tmp = XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12469 if (tmp == NULL)
wolfSSL 14:167253f4e170 12470 err = MEMORY_E;
wolfSSL 14:167253f4e170 12471 }
wolfSSL 14:167253f4e170 12472 #else
wolfSSL 14:167253f4e170 12473 tmp = tmpd;
wolfSSL 14:167253f4e170 12474 #endif
wolfSSL 14:167253f4e170 12475
wolfSSL 14:167253f4e170 12476 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12477 sp_256_from_mp(p->x, 10, pX);
wolfSSL 14:167253f4e170 12478 sp_256_from_mp(p->y, 10, pY);
wolfSSL 14:167253f4e170 12479 sp_256_from_mp(p->z, 10, pZ);
wolfSSL 14:167253f4e170 12480 sp_256_from_mp(q->x, 10, qX);
wolfSSL 14:167253f4e170 12481 sp_256_from_mp(q->y, 10, qY);
wolfSSL 14:167253f4e170 12482 sp_256_from_mp(q->z, 10, qZ);
wolfSSL 14:167253f4e170 12483
wolfSSL 14:167253f4e170 12484 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12485 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12486 sp_256_proj_point_add_avx2_10(p, p, q, tmp);
wolfSSL 14:167253f4e170 12487 else
wolfSSL 14:167253f4e170 12488 #endif
wolfSSL 14:167253f4e170 12489 sp_256_proj_point_add_10(p, p, q, tmp);
wolfSSL 14:167253f4e170 12490 }
wolfSSL 14:167253f4e170 12491
wolfSSL 14:167253f4e170 12492 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12493 err = sp_256_to_mp(p->x, rX);
wolfSSL 14:167253f4e170 12494 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12495 err = sp_256_to_mp(p->y, rY);
wolfSSL 14:167253f4e170 12496 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12497 err = sp_256_to_mp(p->z, rZ);
wolfSSL 14:167253f4e170 12498
wolfSSL 14:167253f4e170 12499 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12500 if (tmp != NULL)
wolfSSL 14:167253f4e170 12501 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12502 #endif
wolfSSL 14:167253f4e170 12503 sp_ecc_point_free(q, 0, NULL);
wolfSSL 14:167253f4e170 12504 sp_ecc_point_free(p, 0, NULL);
wolfSSL 14:167253f4e170 12505
wolfSSL 14:167253f4e170 12506 return err;
wolfSSL 14:167253f4e170 12507 }
wolfSSL 14:167253f4e170 12508
wolfSSL 14:167253f4e170 12509 /* Double a projective EC point.
wolfSSL 14:167253f4e170 12510 * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)
wolfSSL 14:167253f4e170 12511 *
wolfSSL 14:167253f4e170 12512 * pX EC point's X ordinate.
wolfSSL 14:167253f4e170 12513 * pY EC point's Y ordinate.
wolfSSL 14:167253f4e170 12514 * pZ EC point's Z ordinate.
wolfSSL 14:167253f4e170 12515 * rX Resultant EC point's X ordinate.
wolfSSL 14:167253f4e170 12516 * rY Resultant EC point's Y ordinate.
wolfSSL 14:167253f4e170 12517 * rZ Resultant EC point's Z ordinate.
wolfSSL 14:167253f4e170 12518 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 12519 */
wolfSSL 14:167253f4e170 12520 int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
wolfSSL 14:167253f4e170 12521 mp_int* rX, mp_int* rY, mp_int* rZ)
wolfSSL 14:167253f4e170 12522 {
wolfSSL 14:167253f4e170 12523 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12524 sp_digit tmpd[2 * 10 * 2];
wolfSSL 14:167253f4e170 12525 sp_point pd;
wolfSSL 14:167253f4e170 12526 #endif
wolfSSL 14:167253f4e170 12527 sp_digit* tmp;
wolfSSL 14:167253f4e170 12528 sp_point* p;
wolfSSL 14:167253f4e170 12529 int err;
wolfSSL 14:167253f4e170 12530 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12531 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 12532 #endif
wolfSSL 14:167253f4e170 12533
wolfSSL 14:167253f4e170 12534 err = sp_ecc_point_new(NULL, pd, p);
wolfSSL 14:167253f4e170 12535 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12536 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12537 tmp = XMALLOC(sizeof(sp_digit) * 2 * 10 * 2, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12538 if (tmp == NULL)
wolfSSL 14:167253f4e170 12539 err = MEMORY_E;
wolfSSL 14:167253f4e170 12540 }
wolfSSL 14:167253f4e170 12541 #else
wolfSSL 14:167253f4e170 12542 tmp = tmpd;
wolfSSL 14:167253f4e170 12543 #endif
wolfSSL 14:167253f4e170 12544
wolfSSL 14:167253f4e170 12545 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12546 sp_256_from_mp(p->x, 10, pX);
wolfSSL 14:167253f4e170 12547 sp_256_from_mp(p->y, 10, pY);
wolfSSL 14:167253f4e170 12548 sp_256_from_mp(p->z, 10, pZ);
wolfSSL 14:167253f4e170 12549
wolfSSL 14:167253f4e170 12550 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12551 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 12552 sp_256_proj_point_dbl_avx2_10(p, p, tmp);
wolfSSL 14:167253f4e170 12553 else
wolfSSL 14:167253f4e170 12554 #endif
wolfSSL 14:167253f4e170 12555 sp_256_proj_point_dbl_10(p, p, tmp);
wolfSSL 14:167253f4e170 12556 }
wolfSSL 14:167253f4e170 12557
wolfSSL 14:167253f4e170 12558 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12559 err = sp_256_to_mp(p->x, rX);
wolfSSL 14:167253f4e170 12560 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12561 err = sp_256_to_mp(p->y, rY);
wolfSSL 14:167253f4e170 12562 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12563 err = sp_256_to_mp(p->z, rZ);
wolfSSL 14:167253f4e170 12564
wolfSSL 14:167253f4e170 12565 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12566 if (tmp != NULL)
wolfSSL 14:167253f4e170 12567 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12568 #endif
wolfSSL 14:167253f4e170 12569 sp_ecc_point_free(p, 0, NULL);
wolfSSL 14:167253f4e170 12570
wolfSSL 14:167253f4e170 12571 return err;
wolfSSL 14:167253f4e170 12572 }
wolfSSL 14:167253f4e170 12573
wolfSSL 14:167253f4e170 12574 /* Map a projective EC point to affine in place.
wolfSSL 14:167253f4e170 12575 * pZ will be one.
wolfSSL 14:167253f4e170 12576 *
wolfSSL 14:167253f4e170 12577 * pX EC point's X ordinate.
wolfSSL 14:167253f4e170 12578 * pY EC point's Y ordinate.
wolfSSL 14:167253f4e170 12579 * pZ EC point's Z ordinate.
wolfSSL 14:167253f4e170 12580 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 12581 */
wolfSSL 14:167253f4e170 12582 int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)
wolfSSL 14:167253f4e170 12583 {
wolfSSL 14:167253f4e170 12584 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12585 sp_digit tmpd[2 * 10 * 4];
wolfSSL 14:167253f4e170 12586 sp_point pd;
wolfSSL 14:167253f4e170 12587 #endif
wolfSSL 14:167253f4e170 12588 sp_digit* tmp;
wolfSSL 14:167253f4e170 12589 sp_point* p;
wolfSSL 14:167253f4e170 12590 int err;
wolfSSL 14:167253f4e170 12591
wolfSSL 14:167253f4e170 12592 err = sp_ecc_point_new(NULL, pd, p);
wolfSSL 14:167253f4e170 12593 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12594 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12595 tmp = XMALLOC(sizeof(sp_digit) * 2 * 10 * 4, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12596 if (tmp == NULL)
wolfSSL 14:167253f4e170 12597 err = MEMORY_E;
wolfSSL 14:167253f4e170 12598 }
wolfSSL 14:167253f4e170 12599 #else
wolfSSL 14:167253f4e170 12600 tmp = tmpd;
wolfSSL 14:167253f4e170 12601 #endif
wolfSSL 14:167253f4e170 12602 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12603 sp_256_from_mp(p->x, 10, pX);
wolfSSL 14:167253f4e170 12604 sp_256_from_mp(p->y, 10, pY);
wolfSSL 14:167253f4e170 12605 sp_256_from_mp(p->z, 10, pZ);
wolfSSL 14:167253f4e170 12606
wolfSSL 14:167253f4e170 12607 sp_256_map_10(p, p, tmp);
wolfSSL 14:167253f4e170 12608 }
wolfSSL 14:167253f4e170 12609
wolfSSL 14:167253f4e170 12610 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12611 err = sp_256_to_mp(p->x, pX);
wolfSSL 14:167253f4e170 12612 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12613 err = sp_256_to_mp(p->y, pY);
wolfSSL 14:167253f4e170 12614 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 12615 err = sp_256_to_mp(p->z, pZ);
wolfSSL 14:167253f4e170 12616
wolfSSL 14:167253f4e170 12617 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12618 if (tmp != NULL)
wolfSSL 14:167253f4e170 12619 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12620 #endif
wolfSSL 14:167253f4e170 12621 sp_ecc_point_free(p, 0, NULL);
wolfSSL 14:167253f4e170 12622
wolfSSL 14:167253f4e170 12623 return err;
wolfSSL 14:167253f4e170 12624 }
wolfSSL 14:167253f4e170 12625 #endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */
wolfSSL 14:167253f4e170 12626 #ifdef HAVE_COMP_KEY
wolfSSL 14:167253f4e170 12627 /* Find the square root of a number mod the prime of the curve.
wolfSSL 14:167253f4e170 12628 *
wolfSSL 14:167253f4e170 12629 * y The number to operate on and the result.
wolfSSL 14:167253f4e170 12630 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 12631 */
wolfSSL 14:167253f4e170 12632 static int sp_256_mont_sqrt_10(sp_digit* y)
wolfSSL 14:167253f4e170 12633 {
wolfSSL 14:167253f4e170 12634 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12635 sp_digit* d;
wolfSSL 14:167253f4e170 12636 #else
wolfSSL 14:167253f4e170 12637 sp_digit t1d[2 * 10];
wolfSSL 14:167253f4e170 12638 sp_digit t2d[2 * 10];
wolfSSL 14:167253f4e170 12639 #endif
wolfSSL 14:167253f4e170 12640 sp_digit* t1;
wolfSSL 14:167253f4e170 12641 sp_digit* t2;
wolfSSL 14:167253f4e170 12642 int err = MP_OKAY;
wolfSSL 14:167253f4e170 12643 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12644 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 12645 #endif
wolfSSL 14:167253f4e170 12646
wolfSSL 14:167253f4e170 12647 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12648 d = XMALLOC(sizeof(sp_digit) * 4 * 10, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12649 if (d != NULL) {
wolfSSL 14:167253f4e170 12650 t1 = d + 0 * 10;
wolfSSL 14:167253f4e170 12651 t2 = d + 2 * 10;
wolfSSL 14:167253f4e170 12652 }
wolfSSL 14:167253f4e170 12653 else
wolfSSL 14:167253f4e170 12654 err = MEMORY_E;
wolfSSL 14:167253f4e170 12655 #else
wolfSSL 14:167253f4e170 12656 t1 = t1d;
wolfSSL 14:167253f4e170 12657 t2 = t2d;
wolfSSL 14:167253f4e170 12658 #endif
wolfSSL 14:167253f4e170 12659
wolfSSL 14:167253f4e170 12660 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12661 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12662 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {
wolfSSL 14:167253f4e170 12663 /* t2 = y ^ 0x2 */
wolfSSL 14:167253f4e170 12664 sp_256_mont_sqr_avx2_10(t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12665 /* t1 = y ^ 0x3 */
wolfSSL 14:167253f4e170 12666 sp_256_mont_mul_avx2_10(t1, t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12667 /* t2 = y ^ 0xc */
wolfSSL 14:167253f4e170 12668 sp_256_mont_sqr_n_avx2_10(t2, t1, 2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12669 /* t1 = y ^ 0xf */
wolfSSL 14:167253f4e170 12670 sp_256_mont_mul_avx2_10(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12671 /* t2 = y ^ 0xf0 */
wolfSSL 14:167253f4e170 12672 sp_256_mont_sqr_n_avx2_10(t2, t1, 4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12673 /* t1 = y ^ 0xff */
wolfSSL 14:167253f4e170 12674 sp_256_mont_mul_avx2_10(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12675 /* t2 = y ^ 0xff00 */
wolfSSL 14:167253f4e170 12676 sp_256_mont_sqr_n_avx2_10(t2, t1, 8, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12677 /* t1 = y ^ 0xffff */
wolfSSL 14:167253f4e170 12678 sp_256_mont_mul_avx2_10(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12679 /* t2 = y ^ 0xffff0000 */
wolfSSL 14:167253f4e170 12680 sp_256_mont_sqr_n_avx2_10(t2, t1, 16, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12681 /* t1 = y ^ 0xffffffff */
wolfSSL 14:167253f4e170 12682 sp_256_mont_mul_avx2_10(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12683 /* t1 = y ^ 0xffffffff00000000 */
wolfSSL 14:167253f4e170 12684 sp_256_mont_sqr_n_avx2_10(t1, t1, 32, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12685 /* t1 = y ^ 0xffffffff00000001 */
wolfSSL 14:167253f4e170 12686 sp_256_mont_mul_avx2_10(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12687 /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */
wolfSSL 14:167253f4e170 12688 sp_256_mont_sqr_n_avx2_10(t1, t1, 96, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12689 /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */
wolfSSL 14:167253f4e170 12690 sp_256_mont_mul_avx2_10(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12691 sp_256_mont_sqr_n_avx2_10(y, t1, 94, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12692 }
wolfSSL 14:167253f4e170 12693 else
wolfSSL 14:167253f4e170 12694 #endif
wolfSSL 14:167253f4e170 12695 {
wolfSSL 14:167253f4e170 12696 /* t2 = y ^ 0x2 */
wolfSSL 14:167253f4e170 12697 sp_256_mont_sqr_10(t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12698 /* t1 = y ^ 0x3 */
wolfSSL 14:167253f4e170 12699 sp_256_mont_mul_10(t1, t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12700 /* t2 = y ^ 0xc */
wolfSSL 14:167253f4e170 12701 sp_256_mont_sqr_n_10(t2, t1, 2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12702 /* t1 = y ^ 0xf */
wolfSSL 14:167253f4e170 12703 sp_256_mont_mul_10(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12704 /* t2 = y ^ 0xf0 */
wolfSSL 14:167253f4e170 12705 sp_256_mont_sqr_n_10(t2, t1, 4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12706 /* t1 = y ^ 0xff */
wolfSSL 14:167253f4e170 12707 sp_256_mont_mul_10(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12708 /* t2 = y ^ 0xff00 */
wolfSSL 14:167253f4e170 12709 sp_256_mont_sqr_n_10(t2, t1, 8, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12710 /* t1 = y ^ 0xffff */
wolfSSL 14:167253f4e170 12711 sp_256_mont_mul_10(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12712 /* t2 = y ^ 0xffff0000 */
wolfSSL 14:167253f4e170 12713 sp_256_mont_sqr_n_10(t2, t1, 16, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12714 /* t1 = y ^ 0xffffffff */
wolfSSL 14:167253f4e170 12715 sp_256_mont_mul_10(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12716 /* t1 = y ^ 0xffffffff00000000 */
wolfSSL 14:167253f4e170 12717 sp_256_mont_sqr_n_10(t1, t1, 32, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12718 /* t1 = y ^ 0xffffffff00000001 */
wolfSSL 14:167253f4e170 12719 sp_256_mont_mul_10(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12720 /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */
wolfSSL 14:167253f4e170 12721 sp_256_mont_sqr_n_10(t1, t1, 96, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12722 /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */
wolfSSL 14:167253f4e170 12723 sp_256_mont_mul_10(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12724 sp_256_mont_sqr_n_10(y, t1, 94, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12725 }
wolfSSL 14:167253f4e170 12726 }
wolfSSL 14:167253f4e170 12727
wolfSSL 14:167253f4e170 12728 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12729 if (d != NULL)
wolfSSL 14:167253f4e170 12730 XFREE(d, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12731 #endif
wolfSSL 14:167253f4e170 12732
wolfSSL 14:167253f4e170 12733 return err;
wolfSSL 14:167253f4e170 12734 }
wolfSSL 14:167253f4e170 12735
wolfSSL 14:167253f4e170 12736 /* Uncompress the point given the X ordinate.
wolfSSL 14:167253f4e170 12737 *
wolfSSL 14:167253f4e170 12738 * xm X ordinate.
wolfSSL 14:167253f4e170 12739 * odd Whether the Y ordinate is odd.
wolfSSL 14:167253f4e170 12740 * ym Calculated Y ordinate.
wolfSSL 14:167253f4e170 12741 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 12742 */
wolfSSL 14:167253f4e170 12743 int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)
wolfSSL 14:167253f4e170 12744 {
wolfSSL 14:167253f4e170 12745 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12746 sp_digit* d;
wolfSSL 14:167253f4e170 12747 #else
wolfSSL 14:167253f4e170 12748 sp_digit xd[2 * 10];
wolfSSL 14:167253f4e170 12749 sp_digit yd[2 * 10];
wolfSSL 14:167253f4e170 12750 #endif
wolfSSL 14:167253f4e170 12751 sp_digit* x;
wolfSSL 14:167253f4e170 12752 sp_digit* y;
wolfSSL 14:167253f4e170 12753 int err = MP_OKAY;
wolfSSL 14:167253f4e170 12754 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12755 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 12756 #endif
wolfSSL 14:167253f4e170 12757
wolfSSL 14:167253f4e170 12758 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12759 d = XMALLOC(sizeof(sp_digit) * 4 * 10, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12760 if (d != NULL) {
wolfSSL 14:167253f4e170 12761 x = d + 0 * 10;
wolfSSL 14:167253f4e170 12762 y = d + 2 * 10;
wolfSSL 14:167253f4e170 12763 }
wolfSSL 14:167253f4e170 12764 else
wolfSSL 14:167253f4e170 12765 err = MEMORY_E;
wolfSSL 14:167253f4e170 12766 #else
wolfSSL 14:167253f4e170 12767 x = xd;
wolfSSL 14:167253f4e170 12768 y = yd;
wolfSSL 14:167253f4e170 12769 #endif
wolfSSL 14:167253f4e170 12770
wolfSSL 14:167253f4e170 12771 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12772 sp_256_from_mp(x, 10, xm);
wolfSSL 14:167253f4e170 12773
wolfSSL 14:167253f4e170 12774 err = sp_256_mod_mul_norm_10(x, x, p256_mod);
wolfSSL 14:167253f4e170 12775 }
wolfSSL 14:167253f4e170 12776
wolfSSL 14:167253f4e170 12777 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12778 /* y = x^3 */
wolfSSL 14:167253f4e170 12779 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 12780 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {
wolfSSL 14:167253f4e170 12781 sp_256_mont_sqr_avx2_10(y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12782 sp_256_mont_mul_avx2_10(y, y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12783 }
wolfSSL 14:167253f4e170 12784 else
wolfSSL 14:167253f4e170 12785 #endif
wolfSSL 14:167253f4e170 12786 {
wolfSSL 14:167253f4e170 12787 sp_256_mont_sqr_10(y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12788 sp_256_mont_mul_10(y, y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12789 }
wolfSSL 14:167253f4e170 12790 /* y = x^3 - 3x */
wolfSSL 14:167253f4e170 12791 sp_256_mont_sub_10(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 12792 sp_256_mont_sub_10(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 12793 sp_256_mont_sub_10(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 12794 /* y = x^3 - 3x + b */
wolfSSL 14:167253f4e170 12795 err = sp_256_mod_mul_norm_10(x, p256_b, p256_mod);
wolfSSL 14:167253f4e170 12796 }
wolfSSL 14:167253f4e170 12797 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12798 sp_256_mont_add_10(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 12799 /* y = sqrt(x^3 - 3x + b) */
wolfSSL 14:167253f4e170 12800 err = sp_256_mont_sqrt_10(y);
wolfSSL 14:167253f4e170 12801 }
wolfSSL 14:167253f4e170 12802 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12803 XMEMSET(y + 10, 0, 10 * sizeof(sp_digit));
wolfSSL 14:167253f4e170 12804 sp_256_mont_reduce_10(y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12805 if (((y[0] ^ odd) & 1) != 0)
wolfSSL 14:167253f4e170 12806 sp_256_mont_sub_10(y, p256_mod, y, p256_mod);
wolfSSL 14:167253f4e170 12807
wolfSSL 14:167253f4e170 12808 err = sp_256_to_mp(y, ym);
wolfSSL 14:167253f4e170 12809 }
wolfSSL 14:167253f4e170 12810
wolfSSL 14:167253f4e170 12811 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12812 if (d != NULL)
wolfSSL 14:167253f4e170 12813 XFREE(d, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12814 #endif
wolfSSL 14:167253f4e170 12815
wolfSSL 14:167253f4e170 12816 return err;
wolfSSL 14:167253f4e170 12817 }
wolfSSL 14:167253f4e170 12818 #endif
wolfSSL 14:167253f4e170 12819 #endif /* WOLFSSL_SP_NO_256 */
wolfSSL 14:167253f4e170 12820 #endif /* SP_WORD_SIZE == 32 */
wolfSSL 14:167253f4e170 12821 #endif /* !WOLFSSL_SP_ASM */
wolfSSL 14:167253f4e170 12822 #endif /* WOLFSSL_HAVE_SP_ECC */
wolfSSL 14:167253f4e170 12823 #endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */
wolfSSL 14:167253f4e170 12824