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 == 64
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 >= 49) {
wolfSSL 14:167253f4e170 74 r[j] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 75 s = 57 - 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 == 57
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 > 57
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] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 110 s = 57 - 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 + 57 <= DIGIT_BIT) {
wolfSSL 14:167253f4e170 115 s += 57;
wolfSSL 14:167253f4e170 116 r[j] &= 0x1ffffffffffffffl;
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 >= 57) {
wolfSSL 14:167253f4e170 136 r[j] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 137 if (j + 1 >= max)
wolfSSL 14:167253f4e170 138 break;
wolfSSL 14:167253f4e170 139 s = 57 - 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<35; i++) {
wolfSSL 14:167253f4e170 169 r[i+1] += r[i] >> 57;
wolfSSL 14:167253f4e170 170 r[i] &= 0x1ffffffffffffffl;
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<36 && 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 < 57) {
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 - 57);
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_9(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 200 const sp_digit* b)
wolfSSL 14:167253f4e170 201 {
wolfSSL 14:167253f4e170 202 int128_t t0 = ((int128_t)a[ 0]) * b[ 0];
wolfSSL 14:167253f4e170 203 int128_t t1 = ((int128_t)a[ 0]) * b[ 1]
wolfSSL 14:167253f4e170 204 + ((int128_t)a[ 1]) * b[ 0];
wolfSSL 14:167253f4e170 205 int128_t t2 = ((int128_t)a[ 0]) * b[ 2]
wolfSSL 14:167253f4e170 206 + ((int128_t)a[ 1]) * b[ 1]
wolfSSL 14:167253f4e170 207 + ((int128_t)a[ 2]) * b[ 0];
wolfSSL 14:167253f4e170 208 int128_t t3 = ((int128_t)a[ 0]) * b[ 3]
wolfSSL 14:167253f4e170 209 + ((int128_t)a[ 1]) * b[ 2]
wolfSSL 14:167253f4e170 210 + ((int128_t)a[ 2]) * b[ 1]
wolfSSL 14:167253f4e170 211 + ((int128_t)a[ 3]) * b[ 0];
wolfSSL 14:167253f4e170 212 int128_t t4 = ((int128_t)a[ 0]) * b[ 4]
wolfSSL 14:167253f4e170 213 + ((int128_t)a[ 1]) * b[ 3]
wolfSSL 14:167253f4e170 214 + ((int128_t)a[ 2]) * b[ 2]
wolfSSL 14:167253f4e170 215 + ((int128_t)a[ 3]) * b[ 1]
wolfSSL 14:167253f4e170 216 + ((int128_t)a[ 4]) * b[ 0];
wolfSSL 14:167253f4e170 217 int128_t t5 = ((int128_t)a[ 0]) * b[ 5]
wolfSSL 14:167253f4e170 218 + ((int128_t)a[ 1]) * b[ 4]
wolfSSL 14:167253f4e170 219 + ((int128_t)a[ 2]) * b[ 3]
wolfSSL 14:167253f4e170 220 + ((int128_t)a[ 3]) * b[ 2]
wolfSSL 14:167253f4e170 221 + ((int128_t)a[ 4]) * b[ 1]
wolfSSL 14:167253f4e170 222 + ((int128_t)a[ 5]) * b[ 0];
wolfSSL 14:167253f4e170 223 int128_t t6 = ((int128_t)a[ 0]) * b[ 6]
wolfSSL 14:167253f4e170 224 + ((int128_t)a[ 1]) * b[ 5]
wolfSSL 14:167253f4e170 225 + ((int128_t)a[ 2]) * b[ 4]
wolfSSL 14:167253f4e170 226 + ((int128_t)a[ 3]) * b[ 3]
wolfSSL 14:167253f4e170 227 + ((int128_t)a[ 4]) * b[ 2]
wolfSSL 14:167253f4e170 228 + ((int128_t)a[ 5]) * b[ 1]
wolfSSL 14:167253f4e170 229 + ((int128_t)a[ 6]) * b[ 0];
wolfSSL 14:167253f4e170 230 int128_t t7 = ((int128_t)a[ 0]) * b[ 7]
wolfSSL 14:167253f4e170 231 + ((int128_t)a[ 1]) * b[ 6]
wolfSSL 14:167253f4e170 232 + ((int128_t)a[ 2]) * b[ 5]
wolfSSL 14:167253f4e170 233 + ((int128_t)a[ 3]) * b[ 4]
wolfSSL 14:167253f4e170 234 + ((int128_t)a[ 4]) * b[ 3]
wolfSSL 14:167253f4e170 235 + ((int128_t)a[ 5]) * b[ 2]
wolfSSL 14:167253f4e170 236 + ((int128_t)a[ 6]) * b[ 1]
wolfSSL 14:167253f4e170 237 + ((int128_t)a[ 7]) * b[ 0];
wolfSSL 14:167253f4e170 238 int128_t t8 = ((int128_t)a[ 0]) * b[ 8]
wolfSSL 14:167253f4e170 239 + ((int128_t)a[ 1]) * b[ 7]
wolfSSL 14:167253f4e170 240 + ((int128_t)a[ 2]) * b[ 6]
wolfSSL 14:167253f4e170 241 + ((int128_t)a[ 3]) * b[ 5]
wolfSSL 14:167253f4e170 242 + ((int128_t)a[ 4]) * b[ 4]
wolfSSL 14:167253f4e170 243 + ((int128_t)a[ 5]) * b[ 3]
wolfSSL 14:167253f4e170 244 + ((int128_t)a[ 6]) * b[ 2]
wolfSSL 14:167253f4e170 245 + ((int128_t)a[ 7]) * b[ 1]
wolfSSL 14:167253f4e170 246 + ((int128_t)a[ 8]) * b[ 0];
wolfSSL 14:167253f4e170 247 int128_t t9 = ((int128_t)a[ 1]) * b[ 8]
wolfSSL 14:167253f4e170 248 + ((int128_t)a[ 2]) * b[ 7]
wolfSSL 14:167253f4e170 249 + ((int128_t)a[ 3]) * b[ 6]
wolfSSL 14:167253f4e170 250 + ((int128_t)a[ 4]) * b[ 5]
wolfSSL 14:167253f4e170 251 + ((int128_t)a[ 5]) * b[ 4]
wolfSSL 14:167253f4e170 252 + ((int128_t)a[ 6]) * b[ 3]
wolfSSL 14:167253f4e170 253 + ((int128_t)a[ 7]) * b[ 2]
wolfSSL 14:167253f4e170 254 + ((int128_t)a[ 8]) * b[ 1];
wolfSSL 14:167253f4e170 255 int128_t t10 = ((int128_t)a[ 2]) * b[ 8]
wolfSSL 14:167253f4e170 256 + ((int128_t)a[ 3]) * b[ 7]
wolfSSL 14:167253f4e170 257 + ((int128_t)a[ 4]) * b[ 6]
wolfSSL 14:167253f4e170 258 + ((int128_t)a[ 5]) * b[ 5]
wolfSSL 14:167253f4e170 259 + ((int128_t)a[ 6]) * b[ 4]
wolfSSL 14:167253f4e170 260 + ((int128_t)a[ 7]) * b[ 3]
wolfSSL 14:167253f4e170 261 + ((int128_t)a[ 8]) * b[ 2];
wolfSSL 14:167253f4e170 262 int128_t t11 = ((int128_t)a[ 3]) * b[ 8]
wolfSSL 14:167253f4e170 263 + ((int128_t)a[ 4]) * b[ 7]
wolfSSL 14:167253f4e170 264 + ((int128_t)a[ 5]) * b[ 6]
wolfSSL 14:167253f4e170 265 + ((int128_t)a[ 6]) * b[ 5]
wolfSSL 14:167253f4e170 266 + ((int128_t)a[ 7]) * b[ 4]
wolfSSL 14:167253f4e170 267 + ((int128_t)a[ 8]) * b[ 3];
wolfSSL 14:167253f4e170 268 int128_t t12 = ((int128_t)a[ 4]) * b[ 8]
wolfSSL 14:167253f4e170 269 + ((int128_t)a[ 5]) * b[ 7]
wolfSSL 14:167253f4e170 270 + ((int128_t)a[ 6]) * b[ 6]
wolfSSL 14:167253f4e170 271 + ((int128_t)a[ 7]) * b[ 5]
wolfSSL 14:167253f4e170 272 + ((int128_t)a[ 8]) * b[ 4];
wolfSSL 14:167253f4e170 273 int128_t t13 = ((int128_t)a[ 5]) * b[ 8]
wolfSSL 14:167253f4e170 274 + ((int128_t)a[ 6]) * b[ 7]
wolfSSL 14:167253f4e170 275 + ((int128_t)a[ 7]) * b[ 6]
wolfSSL 14:167253f4e170 276 + ((int128_t)a[ 8]) * b[ 5];
wolfSSL 14:167253f4e170 277 int128_t t14 = ((int128_t)a[ 6]) * b[ 8]
wolfSSL 14:167253f4e170 278 + ((int128_t)a[ 7]) * b[ 7]
wolfSSL 14:167253f4e170 279 + ((int128_t)a[ 8]) * b[ 6];
wolfSSL 14:167253f4e170 280 int128_t t15 = ((int128_t)a[ 7]) * b[ 8]
wolfSSL 14:167253f4e170 281 + ((int128_t)a[ 8]) * b[ 7];
wolfSSL 14:167253f4e170 282 int128_t t16 = ((int128_t)a[ 8]) * b[ 8];
wolfSSL 14:167253f4e170 283
wolfSSL 14:167253f4e170 284 t1 += t0 >> 57; r[ 0] = t0 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 285 t2 += t1 >> 57; r[ 1] = t1 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 286 t3 += t2 >> 57; r[ 2] = t2 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 287 t4 += t3 >> 57; r[ 3] = t3 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 288 t5 += t4 >> 57; r[ 4] = t4 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 289 t6 += t5 >> 57; r[ 5] = t5 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 290 t7 += t6 >> 57; r[ 6] = t6 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 291 t8 += t7 >> 57; r[ 7] = t7 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 292 t9 += t8 >> 57; r[ 8] = t8 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 293 t10 += t9 >> 57; r[ 9] = t9 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 294 t11 += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 295 t12 += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 296 t13 += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 297 t14 += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 298 t15 += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 299 t16 += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 300 r[17] = (sp_digit)(t16 >> 57);
wolfSSL 14:167253f4e170 301 r[16] = t16 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 302 }
wolfSSL 14:167253f4e170 303
wolfSSL 14:167253f4e170 304 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 305 *
wolfSSL 14:167253f4e170 306 * r A single precision integer.
wolfSSL 14:167253f4e170 307 * a A single precision integer.
wolfSSL 14:167253f4e170 308 */
wolfSSL 14:167253f4e170 309 SP_NOINLINE static void sp_2048_sqr_9(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 310 {
wolfSSL 14:167253f4e170 311 int128_t t0 = ((int128_t)a[ 0]) * a[ 0];
wolfSSL 14:167253f4e170 312 int128_t t1 = (((int128_t)a[ 0]) * a[ 1]) * 2;
wolfSSL 14:167253f4e170 313 int128_t t2 = (((int128_t)a[ 0]) * a[ 2]) * 2
wolfSSL 14:167253f4e170 314 + ((int128_t)a[ 1]) * a[ 1];
wolfSSL 14:167253f4e170 315 int128_t t3 = (((int128_t)a[ 0]) * a[ 3]
wolfSSL 14:167253f4e170 316 + ((int128_t)a[ 1]) * a[ 2]) * 2;
wolfSSL 14:167253f4e170 317 int128_t t4 = (((int128_t)a[ 0]) * a[ 4]
wolfSSL 14:167253f4e170 318 + ((int128_t)a[ 1]) * a[ 3]) * 2
wolfSSL 14:167253f4e170 319 + ((int128_t)a[ 2]) * a[ 2];
wolfSSL 14:167253f4e170 320 int128_t t5 = (((int128_t)a[ 0]) * a[ 5]
wolfSSL 14:167253f4e170 321 + ((int128_t)a[ 1]) * a[ 4]
wolfSSL 14:167253f4e170 322 + ((int128_t)a[ 2]) * a[ 3]) * 2;
wolfSSL 14:167253f4e170 323 int128_t t6 = (((int128_t)a[ 0]) * a[ 6]
wolfSSL 14:167253f4e170 324 + ((int128_t)a[ 1]) * a[ 5]
wolfSSL 14:167253f4e170 325 + ((int128_t)a[ 2]) * a[ 4]) * 2
wolfSSL 14:167253f4e170 326 + ((int128_t)a[ 3]) * a[ 3];
wolfSSL 14:167253f4e170 327 int128_t t7 = (((int128_t)a[ 0]) * a[ 7]
wolfSSL 14:167253f4e170 328 + ((int128_t)a[ 1]) * a[ 6]
wolfSSL 14:167253f4e170 329 + ((int128_t)a[ 2]) * a[ 5]
wolfSSL 14:167253f4e170 330 + ((int128_t)a[ 3]) * a[ 4]) * 2;
wolfSSL 14:167253f4e170 331 int128_t t8 = (((int128_t)a[ 0]) * a[ 8]
wolfSSL 14:167253f4e170 332 + ((int128_t)a[ 1]) * a[ 7]
wolfSSL 14:167253f4e170 333 + ((int128_t)a[ 2]) * a[ 6]
wolfSSL 14:167253f4e170 334 + ((int128_t)a[ 3]) * a[ 5]) * 2
wolfSSL 14:167253f4e170 335 + ((int128_t)a[ 4]) * a[ 4];
wolfSSL 14:167253f4e170 336 int128_t t9 = (((int128_t)a[ 1]) * a[ 8]
wolfSSL 14:167253f4e170 337 + ((int128_t)a[ 2]) * a[ 7]
wolfSSL 14:167253f4e170 338 + ((int128_t)a[ 3]) * a[ 6]
wolfSSL 14:167253f4e170 339 + ((int128_t)a[ 4]) * a[ 5]) * 2;
wolfSSL 14:167253f4e170 340 int128_t t10 = (((int128_t)a[ 2]) * a[ 8]
wolfSSL 14:167253f4e170 341 + ((int128_t)a[ 3]) * a[ 7]
wolfSSL 14:167253f4e170 342 + ((int128_t)a[ 4]) * a[ 6]) * 2
wolfSSL 14:167253f4e170 343 + ((int128_t)a[ 5]) * a[ 5];
wolfSSL 14:167253f4e170 344 int128_t t11 = (((int128_t)a[ 3]) * a[ 8]
wolfSSL 14:167253f4e170 345 + ((int128_t)a[ 4]) * a[ 7]
wolfSSL 14:167253f4e170 346 + ((int128_t)a[ 5]) * a[ 6]) * 2;
wolfSSL 14:167253f4e170 347 int128_t t12 = (((int128_t)a[ 4]) * a[ 8]
wolfSSL 14:167253f4e170 348 + ((int128_t)a[ 5]) * a[ 7]) * 2
wolfSSL 14:167253f4e170 349 + ((int128_t)a[ 6]) * a[ 6];
wolfSSL 14:167253f4e170 350 int128_t t13 = (((int128_t)a[ 5]) * a[ 8]
wolfSSL 14:167253f4e170 351 + ((int128_t)a[ 6]) * a[ 7]) * 2;
wolfSSL 14:167253f4e170 352 int128_t t14 = (((int128_t)a[ 6]) * a[ 8]) * 2
wolfSSL 14:167253f4e170 353 + ((int128_t)a[ 7]) * a[ 7];
wolfSSL 14:167253f4e170 354 int128_t t15 = (((int128_t)a[ 7]) * a[ 8]) * 2;
wolfSSL 14:167253f4e170 355 int128_t t16 = ((int128_t)a[ 8]) * a[ 8];
wolfSSL 14:167253f4e170 356
wolfSSL 14:167253f4e170 357 t1 += t0 >> 57; r[ 0] = t0 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 358 t2 += t1 >> 57; r[ 1] = t1 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 359 t3 += t2 >> 57; r[ 2] = t2 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 360 t4 += t3 >> 57; r[ 3] = t3 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 361 t5 += t4 >> 57; r[ 4] = t4 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 362 t6 += t5 >> 57; r[ 5] = t5 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 363 t7 += t6 >> 57; r[ 6] = t6 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 364 t8 += t7 >> 57; r[ 7] = t7 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 365 t9 += t8 >> 57; r[ 8] = t8 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 366 t10 += t9 >> 57; r[ 9] = t9 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 367 t11 += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 368 t12 += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 369 t13 += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 370 t14 += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 371 t15 += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 372 t16 += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 373 r[17] = (sp_digit)(t16 >> 57);
wolfSSL 14:167253f4e170 374 r[16] = t16 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 375 }
wolfSSL 14:167253f4e170 376
wolfSSL 14:167253f4e170 377 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 378 *
wolfSSL 14:167253f4e170 379 * r A single precision integer.
wolfSSL 14:167253f4e170 380 * a A single precision integer.
wolfSSL 14:167253f4e170 381 * b A single precision integer.
wolfSSL 14:167253f4e170 382 */
wolfSSL 14:167253f4e170 383 SP_NOINLINE static int sp_2048_add_9(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 384 const sp_digit* b)
wolfSSL 14:167253f4e170 385 {
wolfSSL 14:167253f4e170 386 r[ 0] = a[ 0] + b[ 0];
wolfSSL 14:167253f4e170 387 r[ 1] = a[ 1] + b[ 1];
wolfSSL 14:167253f4e170 388 r[ 2] = a[ 2] + b[ 2];
wolfSSL 14:167253f4e170 389 r[ 3] = a[ 3] + b[ 3];
wolfSSL 14:167253f4e170 390 r[ 4] = a[ 4] + b[ 4];
wolfSSL 14:167253f4e170 391 r[ 5] = a[ 5] + b[ 5];
wolfSSL 14:167253f4e170 392 r[ 6] = a[ 6] + b[ 6];
wolfSSL 14:167253f4e170 393 r[ 7] = a[ 7] + b[ 7];
wolfSSL 14:167253f4e170 394 r[ 8] = a[ 8] + b[ 8];
wolfSSL 14:167253f4e170 395
wolfSSL 14:167253f4e170 396 return 0;
wolfSSL 14:167253f4e170 397 }
wolfSSL 14:167253f4e170 398
wolfSSL 14:167253f4e170 399 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 400 *
wolfSSL 14:167253f4e170 401 * r A single precision integer.
wolfSSL 14:167253f4e170 402 * a A single precision integer.
wolfSSL 14:167253f4e170 403 * b A single precision integer.
wolfSSL 14:167253f4e170 404 */
wolfSSL 14:167253f4e170 405 SP_NOINLINE static int sp_2048_add_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 406 const sp_digit* b)
wolfSSL 14:167253f4e170 407 {
wolfSSL 14:167253f4e170 408 int i;
wolfSSL 14:167253f4e170 409
wolfSSL 14:167253f4e170 410 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 411 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 412 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 413 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 414 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 415 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 416 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 417 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 418 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 419 }
wolfSSL 14:167253f4e170 420 r[16] = a[16] + b[16];
wolfSSL 14:167253f4e170 421 r[17] = a[17] + b[17];
wolfSSL 14:167253f4e170 422
wolfSSL 14:167253f4e170 423 return 0;
wolfSSL 14:167253f4e170 424 }
wolfSSL 14:167253f4e170 425
wolfSSL 14:167253f4e170 426 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 427 *
wolfSSL 14:167253f4e170 428 * r A single precision integer.
wolfSSL 14:167253f4e170 429 * a A single precision integer.
wolfSSL 14:167253f4e170 430 * b A single precision integer.
wolfSSL 14:167253f4e170 431 */
wolfSSL 14:167253f4e170 432 SP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 433 const sp_digit* b)
wolfSSL 14:167253f4e170 434 {
wolfSSL 14:167253f4e170 435 int i;
wolfSSL 14:167253f4e170 436
wolfSSL 14:167253f4e170 437 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 438 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 439 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 440 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 441 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 442 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 443 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 444 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 445 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 446 }
wolfSSL 14:167253f4e170 447 r[16] = a[16] - b[16];
wolfSSL 14:167253f4e170 448 r[17] = a[17] - b[17];
wolfSSL 14:167253f4e170 449
wolfSSL 14:167253f4e170 450 return 0;
wolfSSL 14:167253f4e170 451 }
wolfSSL 14:167253f4e170 452
wolfSSL 14:167253f4e170 453 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 454 *
wolfSSL 14:167253f4e170 455 * r A single precision integer.
wolfSSL 14:167253f4e170 456 * a A single precision integer.
wolfSSL 14:167253f4e170 457 * b A single precision integer.
wolfSSL 14:167253f4e170 458 */
wolfSSL 14:167253f4e170 459 SP_NOINLINE static void sp_2048_mul_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 460 const sp_digit* b)
wolfSSL 14:167253f4e170 461 {
wolfSSL 14:167253f4e170 462 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 463 sp_digit z1[18];
wolfSSL 14:167253f4e170 464 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 465 sp_digit b1[9];
wolfSSL 14:167253f4e170 466 sp_digit* z2 = r + 18;
wolfSSL 14:167253f4e170 467 sp_2048_add_9(a1, a, &a[9]);
wolfSSL 14:167253f4e170 468 sp_2048_add_9(b1, b, &b[9]);
wolfSSL 14:167253f4e170 469 sp_2048_mul_9(z2, &a[9], &b[9]);
wolfSSL 14:167253f4e170 470 sp_2048_mul_9(z0, a, b);
wolfSSL 14:167253f4e170 471 sp_2048_mul_9(z1, a1, b1);
wolfSSL 14:167253f4e170 472 sp_2048_sub_18(z1, z1, z2);
wolfSSL 14:167253f4e170 473 sp_2048_sub_18(z1, z1, z0);
wolfSSL 14:167253f4e170 474 sp_2048_add_18(r + 9, r + 9, z1);
wolfSSL 14:167253f4e170 475 }
wolfSSL 14:167253f4e170 476
wolfSSL 14:167253f4e170 477 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 478 *
wolfSSL 14:167253f4e170 479 * r A single precision integer.
wolfSSL 14:167253f4e170 480 * a A single precision integer.
wolfSSL 14:167253f4e170 481 */
wolfSSL 14:167253f4e170 482 SP_NOINLINE static void sp_2048_sqr_18(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 483 {
wolfSSL 14:167253f4e170 484 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 485 sp_digit z1[18];
wolfSSL 14:167253f4e170 486 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 487 sp_digit* z2 = r + 18;
wolfSSL 14:167253f4e170 488 sp_2048_add_9(a1, a, &a[9]);
wolfSSL 14:167253f4e170 489 sp_2048_sqr_9(z2, &a[9]);
wolfSSL 14:167253f4e170 490 sp_2048_sqr_9(z0, a);
wolfSSL 14:167253f4e170 491 sp_2048_sqr_9(z1, a1);
wolfSSL 14:167253f4e170 492 sp_2048_sub_18(z1, z1, z2);
wolfSSL 14:167253f4e170 493 sp_2048_sub_18(z1, z1, z0);
wolfSSL 14:167253f4e170 494 sp_2048_add_18(r + 9, r + 9, z1);
wolfSSL 14:167253f4e170 495 }
wolfSSL 14:167253f4e170 496
wolfSSL 14:167253f4e170 497 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 498 *
wolfSSL 14:167253f4e170 499 * r A single precision integer.
wolfSSL 14:167253f4e170 500 * a A single precision integer.
wolfSSL 14:167253f4e170 501 * b A single precision integer.
wolfSSL 14:167253f4e170 502 */
wolfSSL 14:167253f4e170 503 SP_NOINLINE static int sp_2048_add_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 504 const sp_digit* b)
wolfSSL 14:167253f4e170 505 {
wolfSSL 14:167253f4e170 506 int i;
wolfSSL 14:167253f4e170 507
wolfSSL 14:167253f4e170 508 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 509 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 510 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 511 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 512 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 513 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 514 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 515 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 516 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 517 }
wolfSSL 14:167253f4e170 518 r[32] = a[32] + b[32];
wolfSSL 14:167253f4e170 519 r[33] = a[33] + b[33];
wolfSSL 14:167253f4e170 520 r[34] = a[34] + b[34];
wolfSSL 14:167253f4e170 521 r[35] = a[35] + b[35];
wolfSSL 14:167253f4e170 522
wolfSSL 14:167253f4e170 523 return 0;
wolfSSL 14:167253f4e170 524 }
wolfSSL 14:167253f4e170 525
wolfSSL 14:167253f4e170 526 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 527 *
wolfSSL 14:167253f4e170 528 * r A single precision integer.
wolfSSL 14:167253f4e170 529 * a A single precision integer.
wolfSSL 14:167253f4e170 530 * b A single precision integer.
wolfSSL 14:167253f4e170 531 */
wolfSSL 14:167253f4e170 532 SP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 533 const sp_digit* b)
wolfSSL 14:167253f4e170 534 {
wolfSSL 14:167253f4e170 535 int i;
wolfSSL 14:167253f4e170 536
wolfSSL 14:167253f4e170 537 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 538 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 539 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 540 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 541 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 542 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 543 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 544 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 545 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 546 }
wolfSSL 14:167253f4e170 547 r[32] = a[32] - b[32];
wolfSSL 14:167253f4e170 548 r[33] = a[33] - b[33];
wolfSSL 14:167253f4e170 549 r[34] = a[34] - b[34];
wolfSSL 14:167253f4e170 550 r[35] = a[35] - b[35];
wolfSSL 14:167253f4e170 551
wolfSSL 14:167253f4e170 552 return 0;
wolfSSL 14:167253f4e170 553 }
wolfSSL 14:167253f4e170 554
wolfSSL 14:167253f4e170 555 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 556 *
wolfSSL 14:167253f4e170 557 * r A single precision integer.
wolfSSL 14:167253f4e170 558 * a A single precision integer.
wolfSSL 14:167253f4e170 559 * b A single precision integer.
wolfSSL 14:167253f4e170 560 */
wolfSSL 14:167253f4e170 561 SP_NOINLINE static void sp_2048_mul_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 562 const sp_digit* b)
wolfSSL 14:167253f4e170 563 {
wolfSSL 14:167253f4e170 564 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 565 sp_digit z1[36];
wolfSSL 14:167253f4e170 566 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 567 sp_digit b1[18];
wolfSSL 14:167253f4e170 568 sp_digit* z2 = r + 36;
wolfSSL 14:167253f4e170 569 sp_2048_add_18(a1, a, &a[18]);
wolfSSL 14:167253f4e170 570 sp_2048_add_18(b1, b, &b[18]);
wolfSSL 14:167253f4e170 571 sp_2048_mul_18(z2, &a[18], &b[18]);
wolfSSL 14:167253f4e170 572 sp_2048_mul_18(z0, a, b);
wolfSSL 14:167253f4e170 573 sp_2048_mul_18(z1, a1, b1);
wolfSSL 14:167253f4e170 574 sp_2048_sub_36(z1, z1, z2);
wolfSSL 14:167253f4e170 575 sp_2048_sub_36(z1, z1, z0);
wolfSSL 14:167253f4e170 576 sp_2048_add_36(r + 18, r + 18, z1);
wolfSSL 14:167253f4e170 577 }
wolfSSL 14:167253f4e170 578
wolfSSL 14:167253f4e170 579 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 580 *
wolfSSL 14:167253f4e170 581 * r A single precision integer.
wolfSSL 14:167253f4e170 582 * a A single precision integer.
wolfSSL 14:167253f4e170 583 */
wolfSSL 14:167253f4e170 584 SP_NOINLINE static void sp_2048_sqr_36(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 585 {
wolfSSL 14:167253f4e170 586 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 587 sp_digit z1[36];
wolfSSL 14:167253f4e170 588 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 589 sp_digit* z2 = r + 36;
wolfSSL 14:167253f4e170 590 sp_2048_add_18(a1, a, &a[18]);
wolfSSL 14:167253f4e170 591 sp_2048_sqr_18(z2, &a[18]);
wolfSSL 14:167253f4e170 592 sp_2048_sqr_18(z0, a);
wolfSSL 14:167253f4e170 593 sp_2048_sqr_18(z1, a1);
wolfSSL 14:167253f4e170 594 sp_2048_sub_36(z1, z1, z2);
wolfSSL 14:167253f4e170 595 sp_2048_sub_36(z1, z1, z0);
wolfSSL 14:167253f4e170 596 sp_2048_add_36(r + 18, r + 18, z1);
wolfSSL 14:167253f4e170 597 }
wolfSSL 14:167253f4e170 598
wolfSSL 14:167253f4e170 599 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 600 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 601 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 602 *
wolfSSL 14:167253f4e170 603 * r A single precision integer.
wolfSSL 14:167253f4e170 604 * a A single precision integer.
wolfSSL 14:167253f4e170 605 * b A single precision integer.
wolfSSL 14:167253f4e170 606 */
wolfSSL 14:167253f4e170 607 SP_NOINLINE static int sp_2048_add_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 608 const sp_digit* b)
wolfSSL 14:167253f4e170 609 {
wolfSSL 14:167253f4e170 610 int i;
wolfSSL 14:167253f4e170 611
wolfSSL 14:167253f4e170 612 for (i = 0; i < 36; i++)
wolfSSL 14:167253f4e170 613 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 614
wolfSSL 14:167253f4e170 615 return 0;
wolfSSL 14:167253f4e170 616 }
wolfSSL 14:167253f4e170 617 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 618 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 619 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 620 *
wolfSSL 14:167253f4e170 621 * r A single precision integer.
wolfSSL 14:167253f4e170 622 * a A single precision integer.
wolfSSL 14:167253f4e170 623 * b A single precision integer.
wolfSSL 14:167253f4e170 624 */
wolfSSL 14:167253f4e170 625 SP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 626 const sp_digit* b)
wolfSSL 14:167253f4e170 627 {
wolfSSL 14:167253f4e170 628 int i;
wolfSSL 14:167253f4e170 629
wolfSSL 14:167253f4e170 630 for (i = 0; i < 36; i++)
wolfSSL 14:167253f4e170 631 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 632
wolfSSL 14:167253f4e170 633 return 0;
wolfSSL 14:167253f4e170 634 }
wolfSSL 14:167253f4e170 635
wolfSSL 14:167253f4e170 636 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 637 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 638 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 639 *
wolfSSL 14:167253f4e170 640 * r A single precision integer.
wolfSSL 14:167253f4e170 641 * a A single precision integer.
wolfSSL 14:167253f4e170 642 * b A single precision integer.
wolfSSL 14:167253f4e170 643 */
wolfSSL 14:167253f4e170 644 SP_NOINLINE static void sp_2048_mul_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 645 const sp_digit* b)
wolfSSL 14:167253f4e170 646 {
wolfSSL 14:167253f4e170 647 int i, j, k;
wolfSSL 14:167253f4e170 648 int128_t c;
wolfSSL 14:167253f4e170 649
wolfSSL 14:167253f4e170 650 c = ((int128_t)a[35]) * b[35];
wolfSSL 14:167253f4e170 651 r[71] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 652 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 653 for (k = 69; k >= 0; k--) {
wolfSSL 14:167253f4e170 654 for (i = 35; i >= 0; i--) {
wolfSSL 14:167253f4e170 655 j = k - i;
wolfSSL 14:167253f4e170 656 if (j >= 36)
wolfSSL 14:167253f4e170 657 break;
wolfSSL 14:167253f4e170 658 if (j < 0)
wolfSSL 14:167253f4e170 659 continue;
wolfSSL 14:167253f4e170 660
wolfSSL 14:167253f4e170 661 c += ((int128_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 662 }
wolfSSL 14:167253f4e170 663 r[k + 2] += c >> 114;
wolfSSL 14:167253f4e170 664 r[k + 1] = (c >> 57) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 665 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 666 }
wolfSSL 14:167253f4e170 667 r[0] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 668 }
wolfSSL 14:167253f4e170 669
wolfSSL 14:167253f4e170 670 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 671 *
wolfSSL 14:167253f4e170 672 * r A single precision integer.
wolfSSL 14:167253f4e170 673 * a A single precision integer.
wolfSSL 14:167253f4e170 674 */
wolfSSL 14:167253f4e170 675 SP_NOINLINE static void sp_2048_sqr_36(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 676 {
wolfSSL 14:167253f4e170 677 int i, j, k;
wolfSSL 14:167253f4e170 678 int128_t c;
wolfSSL 14:167253f4e170 679
wolfSSL 14:167253f4e170 680 c = ((int128_t)a[35]) * a[35];
wolfSSL 14:167253f4e170 681 r[71] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 682 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 683 for (k = 69; k >= 0; k--) {
wolfSSL 14:167253f4e170 684 for (i = 35; i >= 0; i--) {
wolfSSL 14:167253f4e170 685 j = k - i;
wolfSSL 14:167253f4e170 686 if (j >= 36 || i <= j)
wolfSSL 14:167253f4e170 687 break;
wolfSSL 14:167253f4e170 688 if (j < 0)
wolfSSL 14:167253f4e170 689 continue;
wolfSSL 14:167253f4e170 690
wolfSSL 14:167253f4e170 691 c += ((int128_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 692 }
wolfSSL 14:167253f4e170 693 if (i == j)
wolfSSL 14:167253f4e170 694 c += ((int128_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 695
wolfSSL 14:167253f4e170 696 r[k + 2] += c >> 114;
wolfSSL 14:167253f4e170 697 r[k + 1] = (c >> 57) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 698 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 699 }
wolfSSL 14:167253f4e170 700 r[0] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 701 }
wolfSSL 14:167253f4e170 702
wolfSSL 14:167253f4e170 703 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 704 #if !defined(SP_RSA_PRIVATE_EXP_D) && defined(WOLFSSL_HAVE_SP_RSA)
wolfSSL 14:167253f4e170 705 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 706 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 707 *
wolfSSL 14:167253f4e170 708 * r A single precision integer.
wolfSSL 14:167253f4e170 709 * a A single precision integer.
wolfSSL 14:167253f4e170 710 * b A single precision integer.
wolfSSL 14:167253f4e170 711 */
wolfSSL 14:167253f4e170 712 SP_NOINLINE static int sp_2048_add_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 713 const sp_digit* b)
wolfSSL 14:167253f4e170 714 {
wolfSSL 14:167253f4e170 715 int i;
wolfSSL 14:167253f4e170 716
wolfSSL 14:167253f4e170 717 for (i = 0; i < 18; i++)
wolfSSL 14:167253f4e170 718 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 719
wolfSSL 14:167253f4e170 720 return 0;
wolfSSL 14:167253f4e170 721 }
wolfSSL 14:167253f4e170 722 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 723 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 724 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 725 *
wolfSSL 14:167253f4e170 726 * r A single precision integer.
wolfSSL 14:167253f4e170 727 * a A single precision integer.
wolfSSL 14:167253f4e170 728 * b A single precision integer.
wolfSSL 14:167253f4e170 729 */
wolfSSL 14:167253f4e170 730 SP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 731 const sp_digit* b)
wolfSSL 14:167253f4e170 732 {
wolfSSL 14:167253f4e170 733 int i;
wolfSSL 14:167253f4e170 734
wolfSSL 14:167253f4e170 735 for (i = 0; i < 18; i++)
wolfSSL 14:167253f4e170 736 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 737
wolfSSL 14:167253f4e170 738 return 0;
wolfSSL 14:167253f4e170 739 }
wolfSSL 14:167253f4e170 740
wolfSSL 14:167253f4e170 741 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 742 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 743 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 744 *
wolfSSL 14:167253f4e170 745 * r A single precision integer.
wolfSSL 14:167253f4e170 746 * a A single precision integer.
wolfSSL 14:167253f4e170 747 * b A single precision integer.
wolfSSL 14:167253f4e170 748 */
wolfSSL 14:167253f4e170 749 SP_NOINLINE static void sp_2048_mul_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 750 const sp_digit* b)
wolfSSL 14:167253f4e170 751 {
wolfSSL 14:167253f4e170 752 int i, j, k;
wolfSSL 14:167253f4e170 753 int128_t c;
wolfSSL 14:167253f4e170 754
wolfSSL 14:167253f4e170 755 c = ((int128_t)a[17]) * b[17];
wolfSSL 14:167253f4e170 756 r[35] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 757 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 758 for (k = 33; k >= 0; k--) {
wolfSSL 14:167253f4e170 759 for (i = 17; i >= 0; i--) {
wolfSSL 14:167253f4e170 760 j = k - i;
wolfSSL 14:167253f4e170 761 if (j >= 18)
wolfSSL 14:167253f4e170 762 break;
wolfSSL 14:167253f4e170 763 if (j < 0)
wolfSSL 14:167253f4e170 764 continue;
wolfSSL 14:167253f4e170 765
wolfSSL 14:167253f4e170 766 c += ((int128_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 767 }
wolfSSL 14:167253f4e170 768 r[k + 2] += c >> 114;
wolfSSL 14:167253f4e170 769 r[k + 1] = (c >> 57) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 770 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 771 }
wolfSSL 14:167253f4e170 772 r[0] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 773 }
wolfSSL 14:167253f4e170 774
wolfSSL 14:167253f4e170 775 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 776 *
wolfSSL 14:167253f4e170 777 * r A single precision integer.
wolfSSL 14:167253f4e170 778 * a A single precision integer.
wolfSSL 14:167253f4e170 779 */
wolfSSL 14:167253f4e170 780 SP_NOINLINE static void sp_2048_sqr_18(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 781 {
wolfSSL 14:167253f4e170 782 int i, j, k;
wolfSSL 14:167253f4e170 783 int128_t c;
wolfSSL 14:167253f4e170 784
wolfSSL 14:167253f4e170 785 c = ((int128_t)a[17]) * a[17];
wolfSSL 14:167253f4e170 786 r[35] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 787 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 788 for (k = 33; k >= 0; k--) {
wolfSSL 14:167253f4e170 789 for (i = 17; i >= 0; i--) {
wolfSSL 14:167253f4e170 790 j = k - i;
wolfSSL 14:167253f4e170 791 if (j >= 18 || i <= j)
wolfSSL 14:167253f4e170 792 break;
wolfSSL 14:167253f4e170 793 if (j < 0)
wolfSSL 14:167253f4e170 794 continue;
wolfSSL 14:167253f4e170 795
wolfSSL 14:167253f4e170 796 c += ((int128_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 797 }
wolfSSL 14:167253f4e170 798 if (i == j)
wolfSSL 14:167253f4e170 799 c += ((int128_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 800
wolfSSL 14:167253f4e170 801 r[k + 2] += c >> 114;
wolfSSL 14:167253f4e170 802 r[k + 1] = (c >> 57) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 803 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 804 }
wolfSSL 14:167253f4e170 805 r[0] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 806 }
wolfSSL 14:167253f4e170 807
wolfSSL 14:167253f4e170 808 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 809 #endif /* !SP_RSA_PRIVATE_EXP_D && WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 810
wolfSSL 14:167253f4e170 811 /* Caclulate the bottom digit of -1/a mod 2^n.
wolfSSL 14:167253f4e170 812 *
wolfSSL 14:167253f4e170 813 * a A single precision number.
wolfSSL 14:167253f4e170 814 * rho Bottom word of inverse.
wolfSSL 14:167253f4e170 815 */
wolfSSL 14:167253f4e170 816 static void sp_2048_mont_setup(sp_digit* a, sp_digit* rho)
wolfSSL 14:167253f4e170 817 {
wolfSSL 14:167253f4e170 818 sp_digit x, b;
wolfSSL 14:167253f4e170 819
wolfSSL 14:167253f4e170 820 b = a[0];
wolfSSL 14:167253f4e170 821 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
wolfSSL 14:167253f4e170 822 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
wolfSSL 14:167253f4e170 823 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
wolfSSL 14:167253f4e170 824 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
wolfSSL 14:167253f4e170 825 x *= 2 - b * x; /* here x*a==1 mod 2**64 */
wolfSSL 14:167253f4e170 826 x &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 827
wolfSSL 14:167253f4e170 828 /* rho = -1/m mod b */
wolfSSL 14:167253f4e170 829 *rho = (1L << 57) - x;
wolfSSL 14:167253f4e170 830 }
wolfSSL 14:167253f4e170 831
wolfSSL 14:167253f4e170 832 #if !defined(SP_RSA_PRIVATE_EXP_D) && defined(WOLFSSL_HAVE_SP_RSA)
wolfSSL 14:167253f4e170 833 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 14:167253f4e170 834 * Given m must be 2048 bits, just need to subtract.
wolfSSL 14:167253f4e170 835 *
wolfSSL 14:167253f4e170 836 * r A single precision number.
wolfSSL 14:167253f4e170 837 * m A signle precision number.
wolfSSL 14:167253f4e170 838 */
wolfSSL 14:167253f4e170 839 static void sp_2048_mont_norm_18(sp_digit* r, sp_digit* m)
wolfSSL 14:167253f4e170 840 {
wolfSSL 14:167253f4e170 841 /* Set r = 2^n - 1. */
wolfSSL 14:167253f4e170 842 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 843 int i;
wolfSSL 14:167253f4e170 844
wolfSSL 14:167253f4e170 845 for (i=0; i<17; i++)
wolfSSL 14:167253f4e170 846 r[i] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 847 #else
wolfSSL 14:167253f4e170 848 int i;
wolfSSL 14:167253f4e170 849
wolfSSL 14:167253f4e170 850 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 851 r[i + 0] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 852 r[i + 1] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 853 r[i + 2] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 854 r[i + 3] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 855 r[i + 4] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 856 r[i + 5] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 857 r[i + 6] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 858 r[i + 7] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 859 }
wolfSSL 14:167253f4e170 860 r[16] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 861 #endif
wolfSSL 14:167253f4e170 862 r[17] = 0x7fffffffffffffl;
wolfSSL 14:167253f4e170 863
wolfSSL 14:167253f4e170 864 /* r = (2^n - 1) mod n */
wolfSSL 14:167253f4e170 865 sp_2048_sub_18(r, r, m);
wolfSSL 14:167253f4e170 866
wolfSSL 14:167253f4e170 867 /* Add one so r = 2^n mod m */
wolfSSL 14:167253f4e170 868 r[0] += 1;
wolfSSL 14:167253f4e170 869 }
wolfSSL 14:167253f4e170 870
wolfSSL 14:167253f4e170 871 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 872 *
wolfSSL 14:167253f4e170 873 * a A single precision integer.
wolfSSL 14:167253f4e170 874 * b A single precision integer.
wolfSSL 14:167253f4e170 875 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 876 * respectively.
wolfSSL 14:167253f4e170 877 */
wolfSSL 14:167253f4e170 878 static sp_digit sp_2048_cmp_18(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 879 {
wolfSSL 14:167253f4e170 880 sp_digit r = 0;
wolfSSL 14:167253f4e170 881 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 882 int i;
wolfSSL 14:167253f4e170 883
wolfSSL 14:167253f4e170 884 for (i=17; i>=0; i--)
wolfSSL 14:167253f4e170 885 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 886 #else
wolfSSL 14:167253f4e170 887 int i;
wolfSSL 14:167253f4e170 888
wolfSSL 14:167253f4e170 889 r |= (a[17] - b[17]) & (0 - !r);
wolfSSL 14:167253f4e170 890 r |= (a[16] - b[16]) & (0 - !r);
wolfSSL 14:167253f4e170 891 for (i = 8; i >= 0; i -= 8) {
wolfSSL 14:167253f4e170 892 r |= (a[i + 7] - b[i + 7]) & (0 - !r);
wolfSSL 14:167253f4e170 893 r |= (a[i + 6] - b[i + 6]) & (0 - !r);
wolfSSL 14:167253f4e170 894 r |= (a[i + 5] - b[i + 5]) & (0 - !r);
wolfSSL 14:167253f4e170 895 r |= (a[i + 4] - b[i + 4]) & (0 - !r);
wolfSSL 14:167253f4e170 896 r |= (a[i + 3] - b[i + 3]) & (0 - !r);
wolfSSL 14:167253f4e170 897 r |= (a[i + 2] - b[i + 2]) & (0 - !r);
wolfSSL 14:167253f4e170 898 r |= (a[i + 1] - b[i + 1]) & (0 - !r);
wolfSSL 14:167253f4e170 899 r |= (a[i + 0] - b[i + 0]) & (0 - !r);
wolfSSL 14:167253f4e170 900 }
wolfSSL 14:167253f4e170 901 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 902
wolfSSL 14:167253f4e170 903 return r;
wolfSSL 14:167253f4e170 904 }
wolfSSL 14:167253f4e170 905
wolfSSL 14:167253f4e170 906 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 907 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 908 *
wolfSSL 14:167253f4e170 909 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 910 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 911 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 912 * m Mask value to apply.
wolfSSL 14:167253f4e170 913 */
wolfSSL 14:167253f4e170 914 static void sp_2048_cond_sub_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 915 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 916 {
wolfSSL 14:167253f4e170 917 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 918 int i;
wolfSSL 14:167253f4e170 919
wolfSSL 14:167253f4e170 920 for (i = 0; i < 18; i++)
wolfSSL 14:167253f4e170 921 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 922 #else
wolfSSL 14:167253f4e170 923 int i;
wolfSSL 14:167253f4e170 924
wolfSSL 14:167253f4e170 925 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 926 r[i + 0] = a[i + 0] - (b[i + 0] & m);
wolfSSL 14:167253f4e170 927 r[i + 1] = a[i + 1] - (b[i + 1] & m);
wolfSSL 14:167253f4e170 928 r[i + 2] = a[i + 2] - (b[i + 2] & m);
wolfSSL 14:167253f4e170 929 r[i + 3] = a[i + 3] - (b[i + 3] & m);
wolfSSL 14:167253f4e170 930 r[i + 4] = a[i + 4] - (b[i + 4] & m);
wolfSSL 14:167253f4e170 931 r[i + 5] = a[i + 5] - (b[i + 5] & m);
wolfSSL 14:167253f4e170 932 r[i + 6] = a[i + 6] - (b[i + 6] & m);
wolfSSL 14:167253f4e170 933 r[i + 7] = a[i + 7] - (b[i + 7] & m);
wolfSSL 14:167253f4e170 934 }
wolfSSL 14:167253f4e170 935 r[16] = a[16] - (b[16] & m);
wolfSSL 14:167253f4e170 936 r[17] = a[17] - (b[17] & m);
wolfSSL 14:167253f4e170 937 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 938 }
wolfSSL 14:167253f4e170 939
wolfSSL 14:167253f4e170 940 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 941 *
wolfSSL 14:167253f4e170 942 * r A single precision integer.
wolfSSL 14:167253f4e170 943 * a A single precision integer.
wolfSSL 14:167253f4e170 944 * b A scalar.
wolfSSL 14:167253f4e170 945 */
wolfSSL 14:167253f4e170 946 SP_NOINLINE static void sp_2048_mul_add_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 947 const sp_digit b)
wolfSSL 14:167253f4e170 948 {
wolfSSL 14:167253f4e170 949 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 950 int128_t tb = b;
wolfSSL 14:167253f4e170 951 int128_t t = 0;
wolfSSL 14:167253f4e170 952 int i;
wolfSSL 14:167253f4e170 953
wolfSSL 14:167253f4e170 954 for (i = 0; i < 18; i++) {
wolfSSL 14:167253f4e170 955 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 956 r[i] = t & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 957 t >>= 57;
wolfSSL 14:167253f4e170 958 }
wolfSSL 14:167253f4e170 959 r[18] += t;
wolfSSL 14:167253f4e170 960 #else
wolfSSL 14:167253f4e170 961 int128_t tb = b;
wolfSSL 14:167253f4e170 962 int128_t t[8];
wolfSSL 14:167253f4e170 963 int i;
wolfSSL 14:167253f4e170 964
wolfSSL 14:167253f4e170 965 t[0] = tb * a[0]; r[0] += t[0] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 966 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 967 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 968 r[i+1] += (t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 969 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 970 r[i+2] += (t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 971 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 972 r[i+3] += (t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 973 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 974 r[i+4] += (t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 975 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 976 r[i+5] += (t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 977 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 978 r[i+6] += (t[5] >> 57) + (t[6] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 979 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 980 r[i+7] += (t[6] >> 57) + (t[7] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 981 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 982 r[i+8] += (t[7] >> 57) + (t[0] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 983 }
wolfSSL 14:167253f4e170 984 t[1] = tb * a[17]; r[17] += (t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 985 r[18] += t[1] >> 57;
wolfSSL 14:167253f4e170 986 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 987 }
wolfSSL 14:167253f4e170 988
wolfSSL 14:167253f4e170 989 /* Normalize the values in each word to 57.
wolfSSL 14:167253f4e170 990 *
wolfSSL 14:167253f4e170 991 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 992 */
wolfSSL 14:167253f4e170 993 static void sp_2048_norm_18(sp_digit* a)
wolfSSL 14:167253f4e170 994 {
wolfSSL 14:167253f4e170 995 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 996 int i;
wolfSSL 14:167253f4e170 997 for (i = 0; i < 17; i++) {
wolfSSL 14:167253f4e170 998 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 999 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1000 }
wolfSSL 14:167253f4e170 1001 #else
wolfSSL 14:167253f4e170 1002 int i;
wolfSSL 14:167253f4e170 1003 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 1004 a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1005 a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1006 a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1007 a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1008 a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1009 a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1010 a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1011 a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1012 a[i+9] += a[i+8] >> 57; a[i+8] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1013 }
wolfSSL 14:167253f4e170 1014 a[16+1] += a[16] >> 57;
wolfSSL 14:167253f4e170 1015 a[16] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1016 #endif
wolfSSL 14:167253f4e170 1017 }
wolfSSL 14:167253f4e170 1018
wolfSSL 14:167253f4e170 1019 /* Shift the result in the high 1024 bits down to the bottom.
wolfSSL 14:167253f4e170 1020 *
wolfSSL 14:167253f4e170 1021 * r A single precision number.
wolfSSL 14:167253f4e170 1022 * a A single precision number.
wolfSSL 14:167253f4e170 1023 */
wolfSSL 14:167253f4e170 1024 static void sp_2048_mont_shift_18(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 1025 {
wolfSSL 14:167253f4e170 1026 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1027 int i;
wolfSSL 14:167253f4e170 1028 word64 n;
wolfSSL 14:167253f4e170 1029
wolfSSL 14:167253f4e170 1030 n = a[17] >> 55;
wolfSSL 14:167253f4e170 1031 for (i = 0; i < 17; i++) {
wolfSSL 14:167253f4e170 1032 n += a[18 + i] << 2;
wolfSSL 14:167253f4e170 1033 r[i] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1034 n >>= 57;
wolfSSL 14:167253f4e170 1035 }
wolfSSL 14:167253f4e170 1036 n += a[35] << 2;
wolfSSL 14:167253f4e170 1037 r[17] = n;
wolfSSL 14:167253f4e170 1038 #else
wolfSSL 14:167253f4e170 1039 word64 n;
wolfSSL 14:167253f4e170 1040 int i;
wolfSSL 14:167253f4e170 1041
wolfSSL 14:167253f4e170 1042 n = a[17] >> 55;
wolfSSL 14:167253f4e170 1043 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 1044 n += a[i+18] << 2; r[i+0] = n & 0x1ffffffffffffffl; n >>= 57;
wolfSSL 14:167253f4e170 1045 n += a[i+19] << 2; r[i+1] = n & 0x1ffffffffffffffl; n >>= 57;
wolfSSL 14:167253f4e170 1046 n += a[i+20] << 2; r[i+2] = n & 0x1ffffffffffffffl; n >>= 57;
wolfSSL 14:167253f4e170 1047 n += a[i+21] << 2; r[i+3] = n & 0x1ffffffffffffffl; n >>= 57;
wolfSSL 14:167253f4e170 1048 n += a[i+22] << 2; r[i+4] = n & 0x1ffffffffffffffl; n >>= 57;
wolfSSL 14:167253f4e170 1049 n += a[i+23] << 2; r[i+5] = n & 0x1ffffffffffffffl; n >>= 57;
wolfSSL 14:167253f4e170 1050 n += a[i+24] << 2; r[i+6] = n & 0x1ffffffffffffffl; n >>= 57;
wolfSSL 14:167253f4e170 1051 n += a[i+25] << 2; r[i+7] = n & 0x1ffffffffffffffl; n >>= 57;
wolfSSL 14:167253f4e170 1052 }
wolfSSL 14:167253f4e170 1053 n += a[34] << 2; r[16] = n & 0x1ffffffffffffffl; n >>= 57;
wolfSSL 14:167253f4e170 1054 n += a[35] << 2; r[17] = n;
wolfSSL 14:167253f4e170 1055 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1056 XMEMSET(&r[18], 0, sizeof(*r) * 18);
wolfSSL 14:167253f4e170 1057 }
wolfSSL 14:167253f4e170 1058
wolfSSL 14:167253f4e170 1059 /* Reduce the number back to 2048 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 1060 *
wolfSSL 14:167253f4e170 1061 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 1062 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 1063 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 1064 */
wolfSSL 14:167253f4e170 1065 static void sp_2048_mont_reduce_18(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 1066 {
wolfSSL 14:167253f4e170 1067 int i;
wolfSSL 14:167253f4e170 1068 sp_digit mu;
wolfSSL 14:167253f4e170 1069
wolfSSL 14:167253f4e170 1070 for (i=0; i<17; i++) {
wolfSSL 14:167253f4e170 1071 mu = (a[i] * mp) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1072 sp_2048_mul_add_18(a+i, m, mu);
wolfSSL 14:167253f4e170 1073 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 1074 }
wolfSSL 14:167253f4e170 1075 mu = (a[i] * mp) & 0x7fffffffffffffl;
wolfSSL 14:167253f4e170 1076 sp_2048_mul_add_18(a+i, m, mu);
wolfSSL 14:167253f4e170 1077 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 1078 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1079
wolfSSL 14:167253f4e170 1080 sp_2048_mont_shift_18(a, a);
wolfSSL 14:167253f4e170 1081 sp_2048_cond_sub_18(a, a, m, 0 - ((a[17] >> 55) > 0));
wolfSSL 14:167253f4e170 1082 sp_2048_norm_18(a);
wolfSSL 14:167253f4e170 1083 }
wolfSSL 14:167253f4e170 1084
wolfSSL 14:167253f4e170 1085 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 1086 * (r = a * b mod m)
wolfSSL 14:167253f4e170 1087 *
wolfSSL 14:167253f4e170 1088 * r Result of multiplication.
wolfSSL 14:167253f4e170 1089 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 1090 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 1091 * m Modulus (prime).
wolfSSL 14:167253f4e170 1092 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 1093 */
wolfSSL 14:167253f4e170 1094 static void sp_2048_mont_mul_18(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 1095 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 1096 {
wolfSSL 14:167253f4e170 1097 sp_2048_mul_18(r, a, b);
wolfSSL 14:167253f4e170 1098 sp_2048_mont_reduce_18(r, m, mp);
wolfSSL 14:167253f4e170 1099 }
wolfSSL 14:167253f4e170 1100
wolfSSL 14:167253f4e170 1101 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 1102 *
wolfSSL 14:167253f4e170 1103 * r Result of squaring.
wolfSSL 14:167253f4e170 1104 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 1105 * m Modulus (prime).
wolfSSL 14:167253f4e170 1106 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 1107 */
wolfSSL 14:167253f4e170 1108 static void sp_2048_mont_sqr_18(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 1109 sp_digit mp)
wolfSSL 14:167253f4e170 1110 {
wolfSSL 14:167253f4e170 1111 sp_2048_sqr_18(r, a);
wolfSSL 14:167253f4e170 1112 sp_2048_mont_reduce_18(r, m, mp);
wolfSSL 14:167253f4e170 1113 }
wolfSSL 14:167253f4e170 1114
wolfSSL 14:167253f4e170 1115 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 1116 *
wolfSSL 14:167253f4e170 1117 * r A single precision integer.
wolfSSL 14:167253f4e170 1118 * a A single precision integer.
wolfSSL 14:167253f4e170 1119 * b A scalar.
wolfSSL 14:167253f4e170 1120 */
wolfSSL 14:167253f4e170 1121 SP_NOINLINE static void sp_2048_mul_d_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1122 const sp_digit b)
wolfSSL 14:167253f4e170 1123 {
wolfSSL 14:167253f4e170 1124 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1125 int128_t tb = b;
wolfSSL 14:167253f4e170 1126 int128_t t = 0;
wolfSSL 14:167253f4e170 1127 int i;
wolfSSL 14:167253f4e170 1128
wolfSSL 14:167253f4e170 1129 for (i = 0; i < 18; i++) {
wolfSSL 14:167253f4e170 1130 t += tb * a[i];
wolfSSL 14:167253f4e170 1131 r[i] = t & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1132 t >>= 57;
wolfSSL 14:167253f4e170 1133 }
wolfSSL 14:167253f4e170 1134 r[18] = (sp_digit)t;
wolfSSL 14:167253f4e170 1135 #else
wolfSSL 14:167253f4e170 1136 int128_t tb = b;
wolfSSL 14:167253f4e170 1137 int128_t t[8];
wolfSSL 14:167253f4e170 1138 int i;
wolfSSL 14:167253f4e170 1139
wolfSSL 14:167253f4e170 1140 t[0] = tb * a[0]; r[0] = t[0] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1141 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 1142 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 1143 r[i+1] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1144 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 1145 r[i+2] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1146 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 1147 r[i+3] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1148 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 1149 r[i+4] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1150 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 1151 r[i+5] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1152 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 1153 r[i+6] = (sp_digit)(t[5] >> 57) + (t[6] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1154 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 1155 r[i+7] = (sp_digit)(t[6] >> 57) + (t[7] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1156 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 1157 r[i+8] = (sp_digit)(t[7] >> 57) + (t[0] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1158 }
wolfSSL 14:167253f4e170 1159 t[1] = tb * a[17];
wolfSSL 14:167253f4e170 1160 r[17] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1161 r[18] = (sp_digit)(t[1] >> 57);
wolfSSL 14:167253f4e170 1162 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1163 }
wolfSSL 14:167253f4e170 1164
wolfSSL 14:167253f4e170 1165 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 1166 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 1167 *
wolfSSL 14:167253f4e170 1168 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 1169 * a A single precision number to add with.
wolfSSL 14:167253f4e170 1170 * b A single precision number to add.
wolfSSL 14:167253f4e170 1171 * m Mask value to apply.
wolfSSL 14:167253f4e170 1172 */
wolfSSL 14:167253f4e170 1173 static void sp_2048_cond_add_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1174 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 1175 {
wolfSSL 14:167253f4e170 1176 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1177 int i;
wolfSSL 14:167253f4e170 1178
wolfSSL 14:167253f4e170 1179 for (i = 0; i < 18; i++)
wolfSSL 14:167253f4e170 1180 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 1181 #else
wolfSSL 14:167253f4e170 1182 int i;
wolfSSL 14:167253f4e170 1183
wolfSSL 14:167253f4e170 1184 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 1185 r[i + 0] = a[i + 0] + (b[i + 0] & m);
wolfSSL 14:167253f4e170 1186 r[i + 1] = a[i + 1] + (b[i + 1] & m);
wolfSSL 14:167253f4e170 1187 r[i + 2] = a[i + 2] + (b[i + 2] & m);
wolfSSL 14:167253f4e170 1188 r[i + 3] = a[i + 3] + (b[i + 3] & m);
wolfSSL 14:167253f4e170 1189 r[i + 4] = a[i + 4] + (b[i + 4] & m);
wolfSSL 14:167253f4e170 1190 r[i + 5] = a[i + 5] + (b[i + 5] & m);
wolfSSL 14:167253f4e170 1191 r[i + 6] = a[i + 6] + (b[i + 6] & m);
wolfSSL 14:167253f4e170 1192 r[i + 7] = a[i + 7] + (b[i + 7] & m);
wolfSSL 14:167253f4e170 1193 }
wolfSSL 14:167253f4e170 1194 r[16] = a[16] + (b[16] & m);
wolfSSL 14:167253f4e170 1195 r[17] = a[17] + (b[17] & m);
wolfSSL 14:167253f4e170 1196 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1197 }
wolfSSL 14:167253f4e170 1198
wolfSSL 14:167253f4e170 1199 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 1200 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 1201 *
wolfSSL 14:167253f4e170 1202 * r A single precision integer.
wolfSSL 14:167253f4e170 1203 * a A single precision integer.
wolfSSL 14:167253f4e170 1204 * b A single precision integer.
wolfSSL 14:167253f4e170 1205 */
wolfSSL 14:167253f4e170 1206 SP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1207 const sp_digit* b)
wolfSSL 14:167253f4e170 1208 {
wolfSSL 14:167253f4e170 1209 int i;
wolfSSL 14:167253f4e170 1210
wolfSSL 14:167253f4e170 1211 for (i = 0; i < 18; i++)
wolfSSL 14:167253f4e170 1212 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 1213
wolfSSL 14:167253f4e170 1214 return 0;
wolfSSL 14:167253f4e170 1215 }
wolfSSL 14:167253f4e170 1216
wolfSSL 14:167253f4e170 1217 #endif
wolfSSL 14:167253f4e170 1218 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 1219 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 1220 *
wolfSSL 14:167253f4e170 1221 * r A single precision integer.
wolfSSL 14:167253f4e170 1222 * a A single precision integer.
wolfSSL 14:167253f4e170 1223 * b A single precision integer.
wolfSSL 14:167253f4e170 1224 */
wolfSSL 14:167253f4e170 1225 SP_NOINLINE static int sp_2048_add_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1226 const sp_digit* b)
wolfSSL 14:167253f4e170 1227 {
wolfSSL 14:167253f4e170 1228 int i;
wolfSSL 14:167253f4e170 1229
wolfSSL 14:167253f4e170 1230 for (i = 0; i < 18; i++)
wolfSSL 14:167253f4e170 1231 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 1232
wolfSSL 14:167253f4e170 1233 return 0;
wolfSSL 14:167253f4e170 1234 }
wolfSSL 14:167253f4e170 1235 #endif
wolfSSL 14:167253f4e170 1236 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 1237 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 1238 *
wolfSSL 14:167253f4e170 1239 * a Nmber to be divided.
wolfSSL 14:167253f4e170 1240 * d Number to divide with.
wolfSSL 14:167253f4e170 1241 * m Multiplier result.
wolfSSL 14:167253f4e170 1242 * r Remainder from the division.
wolfSSL 14:167253f4e170 1243 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 1244 */
wolfSSL 14:167253f4e170 1245 static int sp_2048_div_18(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 1246 sp_digit* r)
wolfSSL 14:167253f4e170 1247 {
wolfSSL 14:167253f4e170 1248 int i;
wolfSSL 14:167253f4e170 1249 int128_t d1;
wolfSSL 14:167253f4e170 1250 sp_digit div, r1;
wolfSSL 14:167253f4e170 1251 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 1252 sp_digit* td;
wolfSSL 14:167253f4e170 1253 #else
wolfSSL 14:167253f4e170 1254 sp_digit t1d[36], t2d[18 + 1];
wolfSSL 14:167253f4e170 1255 #endif
wolfSSL 14:167253f4e170 1256 sp_digit* t1;
wolfSSL 14:167253f4e170 1257 sp_digit* t2;
wolfSSL 14:167253f4e170 1258 int err = MP_OKAY;
wolfSSL 14:167253f4e170 1259
wolfSSL 14:167253f4e170 1260 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 1261 td = XMALLOC(sizeof(sp_digit) * (3 * 18 + 1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1262 if (td != NULL) {
wolfSSL 14:167253f4e170 1263 t1 = td;
wolfSSL 14:167253f4e170 1264 t2 = td + 2 * 18;
wolfSSL 14:167253f4e170 1265 }
wolfSSL 14:167253f4e170 1266 else
wolfSSL 14:167253f4e170 1267 err = MEMORY_E;
wolfSSL 14:167253f4e170 1268 #else
wolfSSL 14:167253f4e170 1269 t1 = t1d;
wolfSSL 14:167253f4e170 1270 t2 = t2d;
wolfSSL 14:167253f4e170 1271 #endif
wolfSSL 14:167253f4e170 1272
wolfSSL 14:167253f4e170 1273 (void)m;
wolfSSL 14:167253f4e170 1274
wolfSSL 14:167253f4e170 1275 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1276 div = d[17];
wolfSSL 14:167253f4e170 1277 XMEMCPY(t1, a, sizeof(*t1) * 2 * 18);
wolfSSL 14:167253f4e170 1278 for (i=17; i>=0; i--) {
wolfSSL 14:167253f4e170 1279 t1[18 + i] += t1[18 + i - 1] >> 57;
wolfSSL 14:167253f4e170 1280 t1[18 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1281 d1 = t1[18 + i];
wolfSSL 14:167253f4e170 1282 d1 <<= 57;
wolfSSL 14:167253f4e170 1283 d1 += t1[18 + i - 1];
wolfSSL 14:167253f4e170 1284 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 1285
wolfSSL 14:167253f4e170 1286 sp_2048_mul_d_18(t2, d, r1);
wolfSSL 14:167253f4e170 1287 sp_2048_sub_18(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 1288 t1[18 + i] -= t2[18];
wolfSSL 14:167253f4e170 1289 t1[18 + i] += t1[18 + i - 1] >> 57;
wolfSSL 14:167253f4e170 1290 t1[18 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1291 r1 = (((-t1[18 + i]) << 57) - t1[18 + i - 1]) / div;
wolfSSL 14:167253f4e170 1292 r1++;
wolfSSL 14:167253f4e170 1293 sp_2048_mul_d_18(t2, d, r1);
wolfSSL 14:167253f4e170 1294 sp_2048_add_18(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 1295 t1[18 + i] += t1[18 + i - 1] >> 57;
wolfSSL 14:167253f4e170 1296 t1[18 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1297 }
wolfSSL 14:167253f4e170 1298 t1[18 - 1] += t1[18 - 2] >> 57;
wolfSSL 14:167253f4e170 1299 t1[18 - 2] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1300 d1 = t1[18 - 1];
wolfSSL 14:167253f4e170 1301 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 1302
wolfSSL 14:167253f4e170 1303 sp_2048_mul_d_18(t2, d, r1);
wolfSSL 14:167253f4e170 1304 sp_2048_sub_18(t1, t1, t2);
wolfSSL 14:167253f4e170 1305 XMEMCPY(r, t1, sizeof(*r) * 2 * 18);
wolfSSL 14:167253f4e170 1306 for (i=0; i<16; i++) {
wolfSSL 14:167253f4e170 1307 r[i+1] += r[i] >> 57;
wolfSSL 14:167253f4e170 1308 r[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1309 }
wolfSSL 14:167253f4e170 1310 sp_2048_cond_add_18(r, r, d, 0 - (r[17] < 0));
wolfSSL 14:167253f4e170 1311 }
wolfSSL 14:167253f4e170 1312
wolfSSL 14:167253f4e170 1313 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 1314 if (td != NULL)
wolfSSL 14:167253f4e170 1315 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1316 #endif
wolfSSL 14:167253f4e170 1317
wolfSSL 14:167253f4e170 1318 return err;
wolfSSL 14:167253f4e170 1319 }
wolfSSL 14:167253f4e170 1320
wolfSSL 14:167253f4e170 1321 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 1322 *
wolfSSL 14:167253f4e170 1323 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 1324 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 1325 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 1326 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 1327 */
wolfSSL 14:167253f4e170 1328 static int sp_2048_mod_18(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 1329 {
wolfSSL 14:167253f4e170 1330 return sp_2048_div_18(a, m, NULL, r);
wolfSSL 14:167253f4e170 1331 }
wolfSSL 14:167253f4e170 1332
wolfSSL 14:167253f4e170 1333 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 14:167253f4e170 1334 *
wolfSSL 14:167253f4e170 1335 * r A single precision number that is the result of the operation.
wolfSSL 14:167253f4e170 1336 * a A single precision number being exponentiated.
wolfSSL 14:167253f4e170 1337 * e A single precision number that is the exponent.
wolfSSL 14:167253f4e170 1338 * bits The number of bits in the exponent.
wolfSSL 14:167253f4e170 1339 * m A single precision number that is the modulus.
wolfSSL 14:167253f4e170 1340 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 14:167253f4e170 1341 */
wolfSSL 14:167253f4e170 1342 static int sp_2048_mod_exp_18(sp_digit* r, sp_digit* a, sp_digit* e, int bits,
wolfSSL 14:167253f4e170 1343 sp_digit* m, int reduceA)
wolfSSL 14:167253f4e170 1344 {
wolfSSL 14:167253f4e170 1345 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1346 sp_digit* td;
wolfSSL 14:167253f4e170 1347 sp_digit* t[3];
wolfSSL 14:167253f4e170 1348 sp_digit* norm;
wolfSSL 14:167253f4e170 1349 sp_digit mp = 1;
wolfSSL 14:167253f4e170 1350 sp_digit n;
wolfSSL 14:167253f4e170 1351 int i;
wolfSSL 14:167253f4e170 1352 int c, y;
wolfSSL 14:167253f4e170 1353 int err = MP_OKAY;
wolfSSL 14:167253f4e170 1354
wolfSSL 14:167253f4e170 1355 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 18 * 2, NULL,
wolfSSL 14:167253f4e170 1356 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1357 if (td == NULL)
wolfSSL 14:167253f4e170 1358 err = MEMORY_E;
wolfSSL 14:167253f4e170 1359
wolfSSL 14:167253f4e170 1360 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1361 XMEMSET(td, 0, sizeof(*td) * 3 * 18 * 2);
wolfSSL 14:167253f4e170 1362
wolfSSL 14:167253f4e170 1363 norm = t[0] = td;
wolfSSL 14:167253f4e170 1364 t[1] = &td[18 * 2];
wolfSSL 14:167253f4e170 1365 t[2] = &td[2 * 18 * 2];
wolfSSL 14:167253f4e170 1366
wolfSSL 14:167253f4e170 1367 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 1368 sp_2048_mont_norm_18(norm, m);
wolfSSL 14:167253f4e170 1369
wolfSSL 14:167253f4e170 1370 if (reduceA)
wolfSSL 14:167253f4e170 1371 err = sp_2048_mod_18(t[1], a, m);
wolfSSL 14:167253f4e170 1372 else
wolfSSL 14:167253f4e170 1373 XMEMCPY(t[1], a, sizeof(sp_digit) * 18);
wolfSSL 14:167253f4e170 1374 }
wolfSSL 14:167253f4e170 1375 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1376 sp_2048_mul_18(t[1], t[1], norm);
wolfSSL 14:167253f4e170 1377 err = sp_2048_mod_18(t[1], t[1], m);
wolfSSL 14:167253f4e170 1378 }
wolfSSL 14:167253f4e170 1379
wolfSSL 14:167253f4e170 1380 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1381 i = bits / 57;
wolfSSL 14:167253f4e170 1382 c = bits % 57;
wolfSSL 14:167253f4e170 1383 n = e[i--] << (57 - c);
wolfSSL 14:167253f4e170 1384 for (; ; c--) {
wolfSSL 14:167253f4e170 1385 if (c == 0) {
wolfSSL 14:167253f4e170 1386 if (i == -1)
wolfSSL 14:167253f4e170 1387 break;
wolfSSL 14:167253f4e170 1388
wolfSSL 14:167253f4e170 1389 n = e[i--];
wolfSSL 14:167253f4e170 1390 c = 57;
wolfSSL 14:167253f4e170 1391 }
wolfSSL 14:167253f4e170 1392
wolfSSL 14:167253f4e170 1393 y = (n >> 56) & 1;
wolfSSL 14:167253f4e170 1394 n <<= 1;
wolfSSL 14:167253f4e170 1395
wolfSSL 14:167253f4e170 1396 sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 1397
wolfSSL 14:167253f4e170 1398 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 1399 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 1400 sizeof(*t[2]) * 18 * 2);
wolfSSL 14:167253f4e170 1401 sp_2048_mont_sqr_18(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 1402 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 1403 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 1404 sizeof(*t[2]) * 18 * 2);
wolfSSL 14:167253f4e170 1405 }
wolfSSL 14:167253f4e170 1406
wolfSSL 14:167253f4e170 1407 sp_2048_mont_reduce_18(t[0], m, mp);
wolfSSL 14:167253f4e170 1408 n = sp_2048_cmp_18(t[0], m);
wolfSSL 14:167253f4e170 1409 sp_2048_cond_sub_18(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 1410 XMEMCPY(r, t[0], sizeof(*r) * 18 * 2);
wolfSSL 14:167253f4e170 1411
wolfSSL 14:167253f4e170 1412 }
wolfSSL 14:167253f4e170 1413
wolfSSL 14:167253f4e170 1414 if (td != NULL)
wolfSSL 14:167253f4e170 1415 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1416
wolfSSL 14:167253f4e170 1417 return err;
wolfSSL 14:167253f4e170 1418 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 1419 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1420 sp_digit t[3][36];
wolfSSL 14:167253f4e170 1421 #else
wolfSSL 14:167253f4e170 1422 sp_digit* td;
wolfSSL 14:167253f4e170 1423 sp_digit* t[3];
wolfSSL 14:167253f4e170 1424 #endif
wolfSSL 14:167253f4e170 1425 sp_digit* norm;
wolfSSL 14:167253f4e170 1426 sp_digit mp = 1;
wolfSSL 14:167253f4e170 1427 sp_digit n;
wolfSSL 14:167253f4e170 1428 int i;
wolfSSL 14:167253f4e170 1429 int c, y;
wolfSSL 14:167253f4e170 1430 int err = MP_OKAY;
wolfSSL 14:167253f4e170 1431
wolfSSL 14:167253f4e170 1432 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1433 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 18 * 2, NULL,
wolfSSL 14:167253f4e170 1434 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1435 if (td == NULL)
wolfSSL 14:167253f4e170 1436 err = MEMORY_E;
wolfSSL 14:167253f4e170 1437
wolfSSL 14:167253f4e170 1438 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1439 t[0] = td;
wolfSSL 14:167253f4e170 1440 t[1] = &td[18 * 2];
wolfSSL 14:167253f4e170 1441 t[2] = &td[2 * 18 * 2];
wolfSSL 14:167253f4e170 1442 norm = t[0];
wolfSSL 14:167253f4e170 1443 }
wolfSSL 14:167253f4e170 1444 #else
wolfSSL 14:167253f4e170 1445 norm = t[0];
wolfSSL 14:167253f4e170 1446 #endif
wolfSSL 14:167253f4e170 1447
wolfSSL 14:167253f4e170 1448 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1449 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 1450 sp_2048_mont_norm_18(norm, m);
wolfSSL 14:167253f4e170 1451
wolfSSL 14:167253f4e170 1452 if (reduceA) {
wolfSSL 14:167253f4e170 1453 err = sp_2048_mod_18(t[1], a, m);
wolfSSL 14:167253f4e170 1454 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1455 sp_2048_mul_18(t[1], t[1], norm);
wolfSSL 14:167253f4e170 1456 err = sp_2048_mod_18(t[1], t[1], m);
wolfSSL 14:167253f4e170 1457 }
wolfSSL 14:167253f4e170 1458 }
wolfSSL 14:167253f4e170 1459 else {
wolfSSL 14:167253f4e170 1460 sp_2048_mul_18(t[1], a, norm);
wolfSSL 14:167253f4e170 1461 err = sp_2048_mod_18(t[1], t[1], m);
wolfSSL 14:167253f4e170 1462 }
wolfSSL 14:167253f4e170 1463 }
wolfSSL 14:167253f4e170 1464
wolfSSL 14:167253f4e170 1465 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1466 i = bits / 57;
wolfSSL 14:167253f4e170 1467 c = bits % 57;
wolfSSL 14:167253f4e170 1468 n = e[i--] << (57 - c);
wolfSSL 14:167253f4e170 1469 for (; ; c--) {
wolfSSL 14:167253f4e170 1470 if (c == 0) {
wolfSSL 14:167253f4e170 1471 if (i == -1)
wolfSSL 14:167253f4e170 1472 break;
wolfSSL 14:167253f4e170 1473
wolfSSL 14:167253f4e170 1474 n = e[i--];
wolfSSL 14:167253f4e170 1475 c = 57;
wolfSSL 14:167253f4e170 1476 }
wolfSSL 14:167253f4e170 1477
wolfSSL 14:167253f4e170 1478 y = (n >> 56) & 1;
wolfSSL 14:167253f4e170 1479 n <<= 1;
wolfSSL 14:167253f4e170 1480
wolfSSL 14:167253f4e170 1481 sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 1482
wolfSSL 14:167253f4e170 1483 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 1484 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 1485 sp_2048_mont_sqr_18(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 1486 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 1487 ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 1488 }
wolfSSL 14:167253f4e170 1489
wolfSSL 14:167253f4e170 1490 sp_2048_mont_reduce_18(t[0], m, mp);
wolfSSL 14:167253f4e170 1491 n = sp_2048_cmp_18(t[0], m);
wolfSSL 14:167253f4e170 1492 sp_2048_cond_sub_18(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 1493 XMEMCPY(r, t[0], sizeof(t[0]));
wolfSSL 14:167253f4e170 1494 }
wolfSSL 14:167253f4e170 1495
wolfSSL 14:167253f4e170 1496 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1497 if (td != NULL)
wolfSSL 14:167253f4e170 1498 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1499 #endif
wolfSSL 14:167253f4e170 1500
wolfSSL 14:167253f4e170 1501 return err;
wolfSSL 14:167253f4e170 1502 #else
wolfSSL 14:167253f4e170 1503 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1504 sp_digit t[32][36];
wolfSSL 14:167253f4e170 1505 #else
wolfSSL 14:167253f4e170 1506 sp_digit* t[32];
wolfSSL 14:167253f4e170 1507 sp_digit* td;
wolfSSL 14:167253f4e170 1508 #endif
wolfSSL 14:167253f4e170 1509 sp_digit* norm;
wolfSSL 14:167253f4e170 1510 sp_digit rt[36];
wolfSSL 14:167253f4e170 1511 sp_digit mp = 1;
wolfSSL 14:167253f4e170 1512 sp_digit n;
wolfSSL 14:167253f4e170 1513 int i;
wolfSSL 14:167253f4e170 1514 int c, y;
wolfSSL 14:167253f4e170 1515 int err = MP_OKAY;
wolfSSL 14:167253f4e170 1516
wolfSSL 14:167253f4e170 1517 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1518 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 36, NULL,
wolfSSL 14:167253f4e170 1519 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1520 if (td == NULL)
wolfSSL 14:167253f4e170 1521 err = MEMORY_E;
wolfSSL 14:167253f4e170 1522
wolfSSL 14:167253f4e170 1523 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1524 for (i=0; i<32; i++)
wolfSSL 14:167253f4e170 1525 t[i] = td + i * 36;
wolfSSL 14:167253f4e170 1526 norm = t[0];
wolfSSL 14:167253f4e170 1527 }
wolfSSL 14:167253f4e170 1528 #else
wolfSSL 14:167253f4e170 1529 norm = t[0];
wolfSSL 14:167253f4e170 1530 #endif
wolfSSL 14:167253f4e170 1531
wolfSSL 14:167253f4e170 1532 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1533 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 1534 sp_2048_mont_norm_18(norm, m);
wolfSSL 14:167253f4e170 1535
wolfSSL 14:167253f4e170 1536 if (reduceA) {
wolfSSL 14:167253f4e170 1537 err = sp_2048_mod_18(t[1], a, m);
wolfSSL 14:167253f4e170 1538 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1539 sp_2048_mul_18(t[1], t[1], norm);
wolfSSL 14:167253f4e170 1540 err = sp_2048_mod_18(t[1], t[1], m);
wolfSSL 14:167253f4e170 1541 }
wolfSSL 14:167253f4e170 1542 }
wolfSSL 14:167253f4e170 1543 else {
wolfSSL 14:167253f4e170 1544 sp_2048_mul_18(t[1], a, norm);
wolfSSL 14:167253f4e170 1545 err = sp_2048_mod_18(t[1], t[1], m);
wolfSSL 14:167253f4e170 1546 }
wolfSSL 14:167253f4e170 1547 }
wolfSSL 14:167253f4e170 1548
wolfSSL 14:167253f4e170 1549 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 1550 sp_2048_mont_sqr_18(t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 1551 sp_2048_mont_mul_18(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 1552 sp_2048_mont_sqr_18(t[ 4], t[ 2], m, mp);
wolfSSL 14:167253f4e170 1553 sp_2048_mont_mul_18(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 14:167253f4e170 1554 sp_2048_mont_sqr_18(t[ 6], t[ 3], m, mp);
wolfSSL 14:167253f4e170 1555 sp_2048_mont_mul_18(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 14:167253f4e170 1556 sp_2048_mont_sqr_18(t[ 8], t[ 4], m, mp);
wolfSSL 14:167253f4e170 1557 sp_2048_mont_mul_18(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 14:167253f4e170 1558 sp_2048_mont_sqr_18(t[10], t[ 5], m, mp);
wolfSSL 14:167253f4e170 1559 sp_2048_mont_mul_18(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 14:167253f4e170 1560 sp_2048_mont_sqr_18(t[12], t[ 6], m, mp);
wolfSSL 14:167253f4e170 1561 sp_2048_mont_mul_18(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 14:167253f4e170 1562 sp_2048_mont_sqr_18(t[14], t[ 7], m, mp);
wolfSSL 14:167253f4e170 1563 sp_2048_mont_mul_18(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 14:167253f4e170 1564 sp_2048_mont_sqr_18(t[16], t[ 8], m, mp);
wolfSSL 14:167253f4e170 1565 sp_2048_mont_mul_18(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 14:167253f4e170 1566 sp_2048_mont_sqr_18(t[18], t[ 9], m, mp);
wolfSSL 14:167253f4e170 1567 sp_2048_mont_mul_18(t[19], t[10], t[ 9], m, mp);
wolfSSL 14:167253f4e170 1568 sp_2048_mont_sqr_18(t[20], t[10], m, mp);
wolfSSL 14:167253f4e170 1569 sp_2048_mont_mul_18(t[21], t[11], t[10], m, mp);
wolfSSL 14:167253f4e170 1570 sp_2048_mont_sqr_18(t[22], t[11], m, mp);
wolfSSL 14:167253f4e170 1571 sp_2048_mont_mul_18(t[23], t[12], t[11], m, mp);
wolfSSL 14:167253f4e170 1572 sp_2048_mont_sqr_18(t[24], t[12], m, mp);
wolfSSL 14:167253f4e170 1573 sp_2048_mont_mul_18(t[25], t[13], t[12], m, mp);
wolfSSL 14:167253f4e170 1574 sp_2048_mont_sqr_18(t[26], t[13], m, mp);
wolfSSL 14:167253f4e170 1575 sp_2048_mont_mul_18(t[27], t[14], t[13], m, mp);
wolfSSL 14:167253f4e170 1576 sp_2048_mont_sqr_18(t[28], t[14], m, mp);
wolfSSL 14:167253f4e170 1577 sp_2048_mont_mul_18(t[29], t[15], t[14], m, mp);
wolfSSL 14:167253f4e170 1578 sp_2048_mont_sqr_18(t[30], t[15], m, mp);
wolfSSL 14:167253f4e170 1579 sp_2048_mont_mul_18(t[31], t[16], t[15], m, mp);
wolfSSL 14:167253f4e170 1580
wolfSSL 14:167253f4e170 1581 bits = ((bits + 4) / 5) * 5;
wolfSSL 14:167253f4e170 1582 i = ((bits + 56) / 57) - 1;
wolfSSL 14:167253f4e170 1583 c = bits % 57;
wolfSSL 14:167253f4e170 1584 if (c == 0)
wolfSSL 14:167253f4e170 1585 c = 57;
wolfSSL 14:167253f4e170 1586 if (i < 18)
wolfSSL 14:167253f4e170 1587 n = e[i--] << (64 - c);
wolfSSL 14:167253f4e170 1588 else {
wolfSSL 14:167253f4e170 1589 n = 0;
wolfSSL 14:167253f4e170 1590 i--;
wolfSSL 14:167253f4e170 1591 }
wolfSSL 14:167253f4e170 1592 if (c < 5) {
wolfSSL 14:167253f4e170 1593 n |= e[i--] << (7 - c);
wolfSSL 14:167253f4e170 1594 c += 57;
wolfSSL 14:167253f4e170 1595 }
wolfSSL 14:167253f4e170 1596 y = n >> 59;
wolfSSL 14:167253f4e170 1597 n <<= 5;
wolfSSL 14:167253f4e170 1598 c -= 5;
wolfSSL 14:167253f4e170 1599 XMEMCPY(rt, t[y], sizeof(rt));
wolfSSL 14:167253f4e170 1600 for (; i>=0 || c>=5; ) {
wolfSSL 14:167253f4e170 1601 if (c < 5) {
wolfSSL 14:167253f4e170 1602 n |= e[i--] << (7 - c);
wolfSSL 14:167253f4e170 1603 c += 57;
wolfSSL 14:167253f4e170 1604 }
wolfSSL 14:167253f4e170 1605 y = (n >> 59) & 0x1f;
wolfSSL 14:167253f4e170 1606 n <<= 5;
wolfSSL 14:167253f4e170 1607 c -= 5;
wolfSSL 14:167253f4e170 1608
wolfSSL 14:167253f4e170 1609 sp_2048_mont_sqr_18(rt, rt, m, mp);
wolfSSL 14:167253f4e170 1610 sp_2048_mont_sqr_18(rt, rt, m, mp);
wolfSSL 14:167253f4e170 1611 sp_2048_mont_sqr_18(rt, rt, m, mp);
wolfSSL 14:167253f4e170 1612 sp_2048_mont_sqr_18(rt, rt, m, mp);
wolfSSL 14:167253f4e170 1613 sp_2048_mont_sqr_18(rt, rt, m, mp);
wolfSSL 14:167253f4e170 1614
wolfSSL 14:167253f4e170 1615 sp_2048_mont_mul_18(rt, rt, t[y], m, mp);
wolfSSL 14:167253f4e170 1616 }
wolfSSL 14:167253f4e170 1617
wolfSSL 14:167253f4e170 1618 sp_2048_mont_reduce_18(rt, m, mp);
wolfSSL 14:167253f4e170 1619 n = sp_2048_cmp_18(rt, m);
wolfSSL 14:167253f4e170 1620 sp_2048_cond_sub_18(rt, rt, m, (n < 0) - 1);
wolfSSL 14:167253f4e170 1621 XMEMCPY(r, rt, sizeof(rt));
wolfSSL 14:167253f4e170 1622 }
wolfSSL 14:167253f4e170 1623
wolfSSL 14:167253f4e170 1624 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 1625 if (td != NULL)
wolfSSL 14:167253f4e170 1626 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 1627 #endif
wolfSSL 14:167253f4e170 1628
wolfSSL 14:167253f4e170 1629 return err;
wolfSSL 14:167253f4e170 1630 #endif
wolfSSL 14:167253f4e170 1631 }
wolfSSL 14:167253f4e170 1632
wolfSSL 14:167253f4e170 1633 #endif /* !SP_RSA_PRIVATE_EXP_D && WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 1634
wolfSSL 14:167253f4e170 1635 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 14:167253f4e170 1636 * Given m must be 2048 bits, just need to subtract.
wolfSSL 14:167253f4e170 1637 *
wolfSSL 14:167253f4e170 1638 * r A single precision number.
wolfSSL 14:167253f4e170 1639 * m A signle precision number.
wolfSSL 14:167253f4e170 1640 */
wolfSSL 14:167253f4e170 1641 static void sp_2048_mont_norm_36(sp_digit* r, sp_digit* m)
wolfSSL 14:167253f4e170 1642 {
wolfSSL 14:167253f4e170 1643 /* Set r = 2^n - 1. */
wolfSSL 14:167253f4e170 1644 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1645 int i;
wolfSSL 14:167253f4e170 1646
wolfSSL 14:167253f4e170 1647 for (i=0; i<35; i++)
wolfSSL 14:167253f4e170 1648 r[i] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1649 #else
wolfSSL 14:167253f4e170 1650 int i;
wolfSSL 14:167253f4e170 1651
wolfSSL 14:167253f4e170 1652 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 1653 r[i + 0] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1654 r[i + 1] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1655 r[i + 2] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1656 r[i + 3] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1657 r[i + 4] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1658 r[i + 5] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1659 r[i + 6] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1660 r[i + 7] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1661 }
wolfSSL 14:167253f4e170 1662 r[32] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1663 r[33] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1664 r[34] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1665 #endif
wolfSSL 14:167253f4e170 1666 r[35] = 0x1fffffffffffffl;
wolfSSL 14:167253f4e170 1667
wolfSSL 14:167253f4e170 1668 /* r = (2^n - 1) mod n */
wolfSSL 14:167253f4e170 1669 sp_2048_sub_36(r, r, m);
wolfSSL 14:167253f4e170 1670
wolfSSL 14:167253f4e170 1671 /* Add one so r = 2^n mod m */
wolfSSL 14:167253f4e170 1672 r[0] += 1;
wolfSSL 14:167253f4e170 1673 }
wolfSSL 14:167253f4e170 1674
wolfSSL 14:167253f4e170 1675 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 1676 *
wolfSSL 14:167253f4e170 1677 * a A single precision integer.
wolfSSL 14:167253f4e170 1678 * b A single precision integer.
wolfSSL 14:167253f4e170 1679 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 1680 * respectively.
wolfSSL 14:167253f4e170 1681 */
wolfSSL 14:167253f4e170 1682 static sp_digit sp_2048_cmp_36(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 1683 {
wolfSSL 14:167253f4e170 1684 sp_digit r = 0;
wolfSSL 14:167253f4e170 1685 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1686 int i;
wolfSSL 14:167253f4e170 1687
wolfSSL 14:167253f4e170 1688 for (i=35; i>=0; i--)
wolfSSL 14:167253f4e170 1689 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 1690 #else
wolfSSL 14:167253f4e170 1691 int i;
wolfSSL 14:167253f4e170 1692
wolfSSL 14:167253f4e170 1693 r |= (a[35] - b[35]) & (0 - !r);
wolfSSL 14:167253f4e170 1694 r |= (a[34] - b[34]) & (0 - !r);
wolfSSL 14:167253f4e170 1695 r |= (a[33] - b[33]) & (0 - !r);
wolfSSL 14:167253f4e170 1696 r |= (a[32] - b[32]) & (0 - !r);
wolfSSL 14:167253f4e170 1697 for (i = 24; i >= 0; i -= 8) {
wolfSSL 14:167253f4e170 1698 r |= (a[i + 7] - b[i + 7]) & (0 - !r);
wolfSSL 14:167253f4e170 1699 r |= (a[i + 6] - b[i + 6]) & (0 - !r);
wolfSSL 14:167253f4e170 1700 r |= (a[i + 5] - b[i + 5]) & (0 - !r);
wolfSSL 14:167253f4e170 1701 r |= (a[i + 4] - b[i + 4]) & (0 - !r);
wolfSSL 14:167253f4e170 1702 r |= (a[i + 3] - b[i + 3]) & (0 - !r);
wolfSSL 14:167253f4e170 1703 r |= (a[i + 2] - b[i + 2]) & (0 - !r);
wolfSSL 14:167253f4e170 1704 r |= (a[i + 1] - b[i + 1]) & (0 - !r);
wolfSSL 14:167253f4e170 1705 r |= (a[i + 0] - b[i + 0]) & (0 - !r);
wolfSSL 14:167253f4e170 1706 }
wolfSSL 14:167253f4e170 1707 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1708
wolfSSL 14:167253f4e170 1709 return r;
wolfSSL 14:167253f4e170 1710 }
wolfSSL 14:167253f4e170 1711
wolfSSL 14:167253f4e170 1712 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 1713 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 1714 *
wolfSSL 14:167253f4e170 1715 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 1716 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 1717 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 1718 * m Mask value to apply.
wolfSSL 14:167253f4e170 1719 */
wolfSSL 14:167253f4e170 1720 static void sp_2048_cond_sub_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1721 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 1722 {
wolfSSL 14:167253f4e170 1723 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1724 int i;
wolfSSL 14:167253f4e170 1725
wolfSSL 14:167253f4e170 1726 for (i = 0; i < 36; i++)
wolfSSL 14:167253f4e170 1727 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 1728 #else
wolfSSL 14:167253f4e170 1729 int i;
wolfSSL 14:167253f4e170 1730
wolfSSL 14:167253f4e170 1731 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 1732 r[i + 0] = a[i + 0] - (b[i + 0] & m);
wolfSSL 14:167253f4e170 1733 r[i + 1] = a[i + 1] - (b[i + 1] & m);
wolfSSL 14:167253f4e170 1734 r[i + 2] = a[i + 2] - (b[i + 2] & m);
wolfSSL 14:167253f4e170 1735 r[i + 3] = a[i + 3] - (b[i + 3] & m);
wolfSSL 14:167253f4e170 1736 r[i + 4] = a[i + 4] - (b[i + 4] & m);
wolfSSL 14:167253f4e170 1737 r[i + 5] = a[i + 5] - (b[i + 5] & m);
wolfSSL 14:167253f4e170 1738 r[i + 6] = a[i + 6] - (b[i + 6] & m);
wolfSSL 14:167253f4e170 1739 r[i + 7] = a[i + 7] - (b[i + 7] & m);
wolfSSL 14:167253f4e170 1740 }
wolfSSL 14:167253f4e170 1741 r[32] = a[32] - (b[32] & m);
wolfSSL 14:167253f4e170 1742 r[33] = a[33] - (b[33] & m);
wolfSSL 14:167253f4e170 1743 r[34] = a[34] - (b[34] & m);
wolfSSL 14:167253f4e170 1744 r[35] = a[35] - (b[35] & m);
wolfSSL 14:167253f4e170 1745 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1746 }
wolfSSL 14:167253f4e170 1747
wolfSSL 14:167253f4e170 1748 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 1749 *
wolfSSL 14:167253f4e170 1750 * r A single precision integer.
wolfSSL 14:167253f4e170 1751 * a A single precision integer.
wolfSSL 14:167253f4e170 1752 * b A scalar.
wolfSSL 14:167253f4e170 1753 */
wolfSSL 14:167253f4e170 1754 SP_NOINLINE static void sp_2048_mul_add_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1755 const sp_digit b)
wolfSSL 14:167253f4e170 1756 {
wolfSSL 14:167253f4e170 1757 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1758 int128_t tb = b;
wolfSSL 14:167253f4e170 1759 int128_t t = 0;
wolfSSL 14:167253f4e170 1760 int i;
wolfSSL 14:167253f4e170 1761
wolfSSL 14:167253f4e170 1762 for (i = 0; i < 36; i++) {
wolfSSL 14:167253f4e170 1763 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 1764 r[i] = t & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1765 t >>= 57;
wolfSSL 14:167253f4e170 1766 }
wolfSSL 14:167253f4e170 1767 r[36] += t;
wolfSSL 14:167253f4e170 1768 #else
wolfSSL 14:167253f4e170 1769 int128_t tb = b;
wolfSSL 14:167253f4e170 1770 int128_t t[8];
wolfSSL 14:167253f4e170 1771 int i;
wolfSSL 14:167253f4e170 1772
wolfSSL 14:167253f4e170 1773 t[0] = tb * a[0]; r[0] += t[0] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1774 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 1775 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 1776 r[i+1] += (t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1777 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 1778 r[i+2] += (t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1779 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 1780 r[i+3] += (t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1781 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 1782 r[i+4] += (t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1783 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 1784 r[i+5] += (t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1785 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 1786 r[i+6] += (t[5] >> 57) + (t[6] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1787 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 1788 r[i+7] += (t[6] >> 57) + (t[7] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1789 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 1790 r[i+8] += (t[7] >> 57) + (t[0] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1791 }
wolfSSL 14:167253f4e170 1792 t[1] = tb * a[33]; r[33] += (t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1793 t[2] = tb * a[34]; r[34] += (t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1794 t[3] = tb * a[35]; r[35] += (t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1795 r[36] += t[3] >> 57;
wolfSSL 14:167253f4e170 1796 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1797 }
wolfSSL 14:167253f4e170 1798
wolfSSL 14:167253f4e170 1799 /* Normalize the values in each word to 57.
wolfSSL 14:167253f4e170 1800 *
wolfSSL 14:167253f4e170 1801 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 1802 */
wolfSSL 14:167253f4e170 1803 static void sp_2048_norm_36(sp_digit* a)
wolfSSL 14:167253f4e170 1804 {
wolfSSL 14:167253f4e170 1805 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1806 int i;
wolfSSL 14:167253f4e170 1807 for (i = 0; i < 35; i++) {
wolfSSL 14:167253f4e170 1808 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 1809 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1810 }
wolfSSL 14:167253f4e170 1811 #else
wolfSSL 14:167253f4e170 1812 int i;
wolfSSL 14:167253f4e170 1813 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 1814 a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1815 a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1816 a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1817 a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1818 a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1819 a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1820 a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1821 a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1822 a[i+9] += a[i+8] >> 57; a[i+8] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1823 }
wolfSSL 14:167253f4e170 1824 a[32+1] += a[32] >> 57;
wolfSSL 14:167253f4e170 1825 a[32] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1826 a[33+1] += a[33] >> 57;
wolfSSL 14:167253f4e170 1827 a[33] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1828 a[34+1] += a[34] >> 57;
wolfSSL 14:167253f4e170 1829 a[34] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1830 #endif
wolfSSL 14:167253f4e170 1831 }
wolfSSL 14:167253f4e170 1832
wolfSSL 14:167253f4e170 1833 /* Shift the result in the high 2048 bits down to the bottom.
wolfSSL 14:167253f4e170 1834 *
wolfSSL 14:167253f4e170 1835 * r A single precision number.
wolfSSL 14:167253f4e170 1836 * a A single precision number.
wolfSSL 14:167253f4e170 1837 */
wolfSSL 14:167253f4e170 1838 static void sp_2048_mont_shift_36(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 1839 {
wolfSSL 14:167253f4e170 1840 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1841 int i;
wolfSSL 14:167253f4e170 1842 sp_digit n, s;
wolfSSL 14:167253f4e170 1843
wolfSSL 14:167253f4e170 1844 s = a[36];
wolfSSL 14:167253f4e170 1845 n = a[35] >> 53;
wolfSSL 14:167253f4e170 1846 for (i = 0; i < 35; i++) {
wolfSSL 14:167253f4e170 1847 n += (s & 0x1ffffffffffffffl) << 4;
wolfSSL 14:167253f4e170 1848 r[i] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1849 n >>= 57;
wolfSSL 14:167253f4e170 1850 s = a[37 + i] + (s >> 57);
wolfSSL 14:167253f4e170 1851 }
wolfSSL 14:167253f4e170 1852 n += s << 4;
wolfSSL 14:167253f4e170 1853 r[35] = n;
wolfSSL 14:167253f4e170 1854 #else
wolfSSL 14:167253f4e170 1855 sp_digit n, s;
wolfSSL 14:167253f4e170 1856 int i;
wolfSSL 14:167253f4e170 1857
wolfSSL 14:167253f4e170 1858 s = a[36]; n = a[35] >> 53;
wolfSSL 14:167253f4e170 1859 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 1860 n += (s & 0x1ffffffffffffffl) << 4; r[i+0] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1861 n >>= 57; s = a[i+37] + (s >> 57);
wolfSSL 14:167253f4e170 1862 n += (s & 0x1ffffffffffffffl) << 4; r[i+1] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1863 n >>= 57; s = a[i+38] + (s >> 57);
wolfSSL 14:167253f4e170 1864 n += (s & 0x1ffffffffffffffl) << 4; r[i+2] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1865 n >>= 57; s = a[i+39] + (s >> 57);
wolfSSL 14:167253f4e170 1866 n += (s & 0x1ffffffffffffffl) << 4; r[i+3] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1867 n >>= 57; s = a[i+40] + (s >> 57);
wolfSSL 14:167253f4e170 1868 n += (s & 0x1ffffffffffffffl) << 4; r[i+4] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1869 n >>= 57; s = a[i+41] + (s >> 57);
wolfSSL 14:167253f4e170 1870 n += (s & 0x1ffffffffffffffl) << 4; r[i+5] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1871 n >>= 57; s = a[i+42] + (s >> 57);
wolfSSL 14:167253f4e170 1872 n += (s & 0x1ffffffffffffffl) << 4; r[i+6] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1873 n >>= 57; s = a[i+43] + (s >> 57);
wolfSSL 14:167253f4e170 1874 n += (s & 0x1ffffffffffffffl) << 4; r[i+7] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1875 n >>= 57; s = a[i+44] + (s >> 57);
wolfSSL 14:167253f4e170 1876 }
wolfSSL 14:167253f4e170 1877 n += (s & 0x1ffffffffffffffl) << 4; r[32] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1878 n >>= 57; s = a[69] + (s >> 57);
wolfSSL 14:167253f4e170 1879 n += (s & 0x1ffffffffffffffl) << 4; r[33] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1880 n >>= 57; s = a[70] + (s >> 57);
wolfSSL 14:167253f4e170 1881 n += (s & 0x1ffffffffffffffl) << 4; r[34] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1882 n >>= 57; s = a[71] + (s >> 57);
wolfSSL 14:167253f4e170 1883 n += s << 4; r[35] = n;
wolfSSL 14:167253f4e170 1884 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 1885 XMEMSET(&r[36], 0, sizeof(*r) * 36);
wolfSSL 14:167253f4e170 1886 }
wolfSSL 14:167253f4e170 1887
wolfSSL 14:167253f4e170 1888 /* Reduce the number back to 2048 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 1889 *
wolfSSL 14:167253f4e170 1890 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 1891 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 1892 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 1893 */
wolfSSL 14:167253f4e170 1894 static void sp_2048_mont_reduce_36(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 1895 {
wolfSSL 14:167253f4e170 1896 int i;
wolfSSL 14:167253f4e170 1897 sp_digit mu;
wolfSSL 14:167253f4e170 1898
wolfSSL 14:167253f4e170 1899 if (mp != 1) {
wolfSSL 14:167253f4e170 1900 for (i=0; i<35; i++) {
wolfSSL 14:167253f4e170 1901 mu = (a[i] * mp) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1902 sp_2048_mul_add_36(a+i, m, mu);
wolfSSL 14:167253f4e170 1903 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 1904 }
wolfSSL 14:167253f4e170 1905 mu = (a[i] * mp) & 0x1fffffffffffffl;
wolfSSL 14:167253f4e170 1906 sp_2048_mul_add_36(a+i, m, mu);
wolfSSL 14:167253f4e170 1907 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 1908 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1909 }
wolfSSL 14:167253f4e170 1910 else {
wolfSSL 14:167253f4e170 1911 for (i=0; i<35; i++) {
wolfSSL 14:167253f4e170 1912 mu = a[i] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1913 sp_2048_mul_add_36(a+i, m, mu);
wolfSSL 14:167253f4e170 1914 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 1915 }
wolfSSL 14:167253f4e170 1916 mu = a[i] & 0x1fffffffffffffl;
wolfSSL 14:167253f4e170 1917 sp_2048_mul_add_36(a+i, m, mu);
wolfSSL 14:167253f4e170 1918 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 1919 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1920 }
wolfSSL 14:167253f4e170 1921
wolfSSL 14:167253f4e170 1922 sp_2048_mont_shift_36(a, a);
wolfSSL 14:167253f4e170 1923 sp_2048_cond_sub_36(a, a, m, 0 - ((a[35] >> 53) > 0));
wolfSSL 14:167253f4e170 1924 sp_2048_norm_36(a);
wolfSSL 14:167253f4e170 1925 }
wolfSSL 14:167253f4e170 1926
wolfSSL 14:167253f4e170 1927 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 1928 * (r = a * b mod m)
wolfSSL 14:167253f4e170 1929 *
wolfSSL 14:167253f4e170 1930 * r Result of multiplication.
wolfSSL 14:167253f4e170 1931 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 1932 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 1933 * m Modulus (prime).
wolfSSL 14:167253f4e170 1934 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 1935 */
wolfSSL 14:167253f4e170 1936 static void sp_2048_mont_mul_36(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 1937 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 1938 {
wolfSSL 14:167253f4e170 1939 sp_2048_mul_36(r, a, b);
wolfSSL 14:167253f4e170 1940 sp_2048_mont_reduce_36(r, m, mp);
wolfSSL 14:167253f4e170 1941 }
wolfSSL 14:167253f4e170 1942
wolfSSL 14:167253f4e170 1943 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 1944 *
wolfSSL 14:167253f4e170 1945 * r Result of squaring.
wolfSSL 14:167253f4e170 1946 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 1947 * m Modulus (prime).
wolfSSL 14:167253f4e170 1948 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 1949 */
wolfSSL 14:167253f4e170 1950 static void sp_2048_mont_sqr_36(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 1951 sp_digit mp)
wolfSSL 14:167253f4e170 1952 {
wolfSSL 14:167253f4e170 1953 sp_2048_sqr_36(r, a);
wolfSSL 14:167253f4e170 1954 sp_2048_mont_reduce_36(r, m, mp);
wolfSSL 14:167253f4e170 1955 }
wolfSSL 14:167253f4e170 1956
wolfSSL 14:167253f4e170 1957 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 1958 *
wolfSSL 14:167253f4e170 1959 * r A single precision integer.
wolfSSL 14:167253f4e170 1960 * a A single precision integer.
wolfSSL 14:167253f4e170 1961 * b A scalar.
wolfSSL 14:167253f4e170 1962 */
wolfSSL 14:167253f4e170 1963 SP_NOINLINE static void sp_2048_mul_d_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 1964 const sp_digit b)
wolfSSL 14:167253f4e170 1965 {
wolfSSL 14:167253f4e170 1966 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 1967 int128_t tb = b;
wolfSSL 14:167253f4e170 1968 int128_t t = 0;
wolfSSL 14:167253f4e170 1969 int i;
wolfSSL 14:167253f4e170 1970
wolfSSL 14:167253f4e170 1971 for (i = 0; i < 36; i++) {
wolfSSL 14:167253f4e170 1972 t += tb * a[i];
wolfSSL 14:167253f4e170 1973 r[i] = t & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1974 t >>= 57;
wolfSSL 14:167253f4e170 1975 }
wolfSSL 14:167253f4e170 1976 r[36] = (sp_digit)t;
wolfSSL 14:167253f4e170 1977 #else
wolfSSL 14:167253f4e170 1978 int128_t tb = b;
wolfSSL 14:167253f4e170 1979 int128_t t[8];
wolfSSL 14:167253f4e170 1980 int i;
wolfSSL 14:167253f4e170 1981
wolfSSL 14:167253f4e170 1982 t[0] = tb * a[0]; r[0] = t[0] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 1983 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 1984 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 1985 r[i+1] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1986 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 1987 r[i+2] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1988 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 1989 r[i+3] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1990 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 1991 r[i+4] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1992 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 1993 r[i+5] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1994 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 1995 r[i+6] = (sp_digit)(t[5] >> 57) + (t[6] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1996 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 1997 r[i+7] = (sp_digit)(t[6] >> 57) + (t[7] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 1998 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 1999 r[i+8] = (sp_digit)(t[7] >> 57) + (t[0] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 2000 }
wolfSSL 14:167253f4e170 2001 t[1] = tb * a[33];
wolfSSL 14:167253f4e170 2002 r[33] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 2003 t[2] = tb * a[34];
wolfSSL 14:167253f4e170 2004 r[34] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 2005 t[3] = tb * a[35];
wolfSSL 14:167253f4e170 2006 r[35] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 2007 r[36] = (sp_digit)(t[3] >> 57);
wolfSSL 14:167253f4e170 2008 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 2009 }
wolfSSL 14:167253f4e170 2010
wolfSSL 14:167253f4e170 2011 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 2012 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 2013 *
wolfSSL 14:167253f4e170 2014 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 2015 * a A single precision number to add with.
wolfSSL 14:167253f4e170 2016 * b A single precision number to add.
wolfSSL 14:167253f4e170 2017 * m Mask value to apply.
wolfSSL 14:167253f4e170 2018 */
wolfSSL 14:167253f4e170 2019 static void sp_2048_cond_add_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 2020 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 2021 {
wolfSSL 14:167253f4e170 2022 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2023 int i;
wolfSSL 14:167253f4e170 2024
wolfSSL 14:167253f4e170 2025 for (i = 0; i < 36; i++)
wolfSSL 14:167253f4e170 2026 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 2027 #else
wolfSSL 14:167253f4e170 2028 int i;
wolfSSL 14:167253f4e170 2029
wolfSSL 14:167253f4e170 2030 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 2031 r[i + 0] = a[i + 0] + (b[i + 0] & m);
wolfSSL 14:167253f4e170 2032 r[i + 1] = a[i + 1] + (b[i + 1] & m);
wolfSSL 14:167253f4e170 2033 r[i + 2] = a[i + 2] + (b[i + 2] & m);
wolfSSL 14:167253f4e170 2034 r[i + 3] = a[i + 3] + (b[i + 3] & m);
wolfSSL 14:167253f4e170 2035 r[i + 4] = a[i + 4] + (b[i + 4] & m);
wolfSSL 14:167253f4e170 2036 r[i + 5] = a[i + 5] + (b[i + 5] & m);
wolfSSL 14:167253f4e170 2037 r[i + 6] = a[i + 6] + (b[i + 6] & m);
wolfSSL 14:167253f4e170 2038 r[i + 7] = a[i + 7] + (b[i + 7] & m);
wolfSSL 14:167253f4e170 2039 }
wolfSSL 14:167253f4e170 2040 r[32] = a[32] + (b[32] & m);
wolfSSL 14:167253f4e170 2041 r[33] = a[33] + (b[33] & m);
wolfSSL 14:167253f4e170 2042 r[34] = a[34] + (b[34] & m);
wolfSSL 14:167253f4e170 2043 r[35] = a[35] + (b[35] & m);
wolfSSL 14:167253f4e170 2044 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 2045 }
wolfSSL 14:167253f4e170 2046
wolfSSL 14:167253f4e170 2047 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 2048 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 2049 *
wolfSSL 14:167253f4e170 2050 * r A single precision integer.
wolfSSL 14:167253f4e170 2051 * a A single precision integer.
wolfSSL 14:167253f4e170 2052 * b A single precision integer.
wolfSSL 14:167253f4e170 2053 */
wolfSSL 14:167253f4e170 2054 SP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 2055 const sp_digit* b)
wolfSSL 14:167253f4e170 2056 {
wolfSSL 14:167253f4e170 2057 int i;
wolfSSL 14:167253f4e170 2058
wolfSSL 14:167253f4e170 2059 for (i = 0; i < 36; i++)
wolfSSL 14:167253f4e170 2060 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 2061
wolfSSL 14:167253f4e170 2062 return 0;
wolfSSL 14:167253f4e170 2063 }
wolfSSL 14:167253f4e170 2064
wolfSSL 14:167253f4e170 2065 #endif
wolfSSL 14:167253f4e170 2066 #ifdef WOLFSSL_SMALL
wolfSSL 14:167253f4e170 2067 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 2068 *
wolfSSL 14:167253f4e170 2069 * r A single precision integer.
wolfSSL 14:167253f4e170 2070 * a A single precision integer.
wolfSSL 14:167253f4e170 2071 * b A single precision integer.
wolfSSL 14:167253f4e170 2072 */
wolfSSL 14:167253f4e170 2073 SP_NOINLINE static int sp_2048_add_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 2074 const sp_digit* b)
wolfSSL 14:167253f4e170 2075 {
wolfSSL 14:167253f4e170 2076 int i;
wolfSSL 14:167253f4e170 2077
wolfSSL 14:167253f4e170 2078 for (i = 0; i < 36; i++)
wolfSSL 14:167253f4e170 2079 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 2080
wolfSSL 14:167253f4e170 2081 return 0;
wolfSSL 14:167253f4e170 2082 }
wolfSSL 14:167253f4e170 2083 #endif
wolfSSL 14:167253f4e170 2084 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 2085 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 2086 *
wolfSSL 14:167253f4e170 2087 * a Nmber to be divided.
wolfSSL 14:167253f4e170 2088 * d Number to divide with.
wolfSSL 14:167253f4e170 2089 * m Multiplier result.
wolfSSL 14:167253f4e170 2090 * r Remainder from the division.
wolfSSL 14:167253f4e170 2091 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 2092 */
wolfSSL 14:167253f4e170 2093 static int sp_2048_div_36(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 2094 sp_digit* r)
wolfSSL 14:167253f4e170 2095 {
wolfSSL 14:167253f4e170 2096 int i;
wolfSSL 14:167253f4e170 2097 int128_t d1;
wolfSSL 14:167253f4e170 2098 sp_digit div, r1;
wolfSSL 14:167253f4e170 2099 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2100 sp_digit* td;
wolfSSL 14:167253f4e170 2101 #else
wolfSSL 14:167253f4e170 2102 sp_digit t1d[72], t2d[36 + 1];
wolfSSL 14:167253f4e170 2103 #endif
wolfSSL 14:167253f4e170 2104 sp_digit* t1;
wolfSSL 14:167253f4e170 2105 sp_digit* t2;
wolfSSL 14:167253f4e170 2106 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2107
wolfSSL 14:167253f4e170 2108 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2109 td = XMALLOC(sizeof(sp_digit) * (3 * 36 + 1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2110 if (td != NULL) {
wolfSSL 14:167253f4e170 2111 t1 = td;
wolfSSL 14:167253f4e170 2112 t2 = td + 2 * 36;
wolfSSL 14:167253f4e170 2113 }
wolfSSL 14:167253f4e170 2114 else
wolfSSL 14:167253f4e170 2115 err = MEMORY_E;
wolfSSL 14:167253f4e170 2116 #else
wolfSSL 14:167253f4e170 2117 t1 = t1d;
wolfSSL 14:167253f4e170 2118 t2 = t2d;
wolfSSL 14:167253f4e170 2119 #endif
wolfSSL 14:167253f4e170 2120
wolfSSL 14:167253f4e170 2121 (void)m;
wolfSSL 14:167253f4e170 2122
wolfSSL 14:167253f4e170 2123 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2124 div = d[35];
wolfSSL 14:167253f4e170 2125 XMEMCPY(t1, a, sizeof(*t1) * 2 * 36);
wolfSSL 14:167253f4e170 2126 for (i=35; i>=0; i--) {
wolfSSL 14:167253f4e170 2127 t1[36 + i] += t1[36 + i - 1] >> 57;
wolfSSL 14:167253f4e170 2128 t1[36 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 2129 d1 = t1[36 + i];
wolfSSL 14:167253f4e170 2130 d1 <<= 57;
wolfSSL 14:167253f4e170 2131 d1 += t1[36 + i - 1];
wolfSSL 14:167253f4e170 2132 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 2133
wolfSSL 14:167253f4e170 2134 sp_2048_mul_d_36(t2, d, r1);
wolfSSL 14:167253f4e170 2135 sp_2048_sub_36(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 2136 t1[36 + i] -= t2[36];
wolfSSL 14:167253f4e170 2137 t1[36 + i] += t1[36 + i - 1] >> 57;
wolfSSL 14:167253f4e170 2138 t1[36 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 2139 r1 = (((-t1[36 + i]) << 57) - t1[36 + i - 1]) / div;
wolfSSL 14:167253f4e170 2140 r1++;
wolfSSL 14:167253f4e170 2141 sp_2048_mul_d_36(t2, d, r1);
wolfSSL 14:167253f4e170 2142 sp_2048_add_36(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 2143 t1[36 + i] += t1[36 + i - 1] >> 57;
wolfSSL 14:167253f4e170 2144 t1[36 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 2145 }
wolfSSL 14:167253f4e170 2146 t1[36 - 1] += t1[36 - 2] >> 57;
wolfSSL 14:167253f4e170 2147 t1[36 - 2] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 2148 d1 = t1[36 - 1];
wolfSSL 14:167253f4e170 2149 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 2150
wolfSSL 14:167253f4e170 2151 sp_2048_mul_d_36(t2, d, r1);
wolfSSL 14:167253f4e170 2152 sp_2048_sub_36(t1, t1, t2);
wolfSSL 14:167253f4e170 2153 XMEMCPY(r, t1, sizeof(*r) * 2 * 36);
wolfSSL 14:167253f4e170 2154 for (i=0; i<34; i++) {
wolfSSL 14:167253f4e170 2155 r[i+1] += r[i] >> 57;
wolfSSL 14:167253f4e170 2156 r[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 2157 }
wolfSSL 14:167253f4e170 2158 sp_2048_cond_add_36(r, r, d, 0 - (r[35] < 0));
wolfSSL 14:167253f4e170 2159 }
wolfSSL 14:167253f4e170 2160
wolfSSL 14:167253f4e170 2161 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2162 if (td != NULL)
wolfSSL 14:167253f4e170 2163 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2164 #endif
wolfSSL 14:167253f4e170 2165
wolfSSL 14:167253f4e170 2166 return err;
wolfSSL 14:167253f4e170 2167 }
wolfSSL 14:167253f4e170 2168
wolfSSL 14:167253f4e170 2169 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 2170 *
wolfSSL 14:167253f4e170 2171 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 2172 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 2173 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 2174 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 2175 */
wolfSSL 14:167253f4e170 2176 static int sp_2048_mod_36(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 2177 {
wolfSSL 14:167253f4e170 2178 return sp_2048_div_36(a, m, NULL, r);
wolfSSL 14:167253f4e170 2179 }
wolfSSL 14:167253f4e170 2180
wolfSSL 14:167253f4e170 2181 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 14:167253f4e170 2182 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 14:167253f4e170 2183 *
wolfSSL 14:167253f4e170 2184 * r A single precision number that is the result of the operation.
wolfSSL 14:167253f4e170 2185 * a A single precision number being exponentiated.
wolfSSL 14:167253f4e170 2186 * e A single precision number that is the exponent.
wolfSSL 14:167253f4e170 2187 * bits The number of bits in the exponent.
wolfSSL 14:167253f4e170 2188 * m A single precision number that is the modulus.
wolfSSL 14:167253f4e170 2189 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 14:167253f4e170 2190 */
wolfSSL 14:167253f4e170 2191 static int sp_2048_mod_exp_36(sp_digit* r, sp_digit* a, sp_digit* e, int bits,
wolfSSL 14:167253f4e170 2192 sp_digit* m, int reduceA)
wolfSSL 14:167253f4e170 2193 {
wolfSSL 14:167253f4e170 2194 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2195 sp_digit* td;
wolfSSL 14:167253f4e170 2196 sp_digit* t[3];
wolfSSL 14:167253f4e170 2197 sp_digit* norm;
wolfSSL 14:167253f4e170 2198 sp_digit mp = 1;
wolfSSL 14:167253f4e170 2199 sp_digit n;
wolfSSL 14:167253f4e170 2200 int i;
wolfSSL 14:167253f4e170 2201 int c, y;
wolfSSL 14:167253f4e170 2202 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2203
wolfSSL 14:167253f4e170 2204 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 36 * 2, NULL,
wolfSSL 14:167253f4e170 2205 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2206 if (td == NULL)
wolfSSL 14:167253f4e170 2207 err = MEMORY_E;
wolfSSL 14:167253f4e170 2208
wolfSSL 14:167253f4e170 2209 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2210 XMEMSET(td, 0, sizeof(*td) * 3 * 36 * 2);
wolfSSL 14:167253f4e170 2211
wolfSSL 14:167253f4e170 2212 norm = t[0] = td;
wolfSSL 14:167253f4e170 2213 t[1] = &td[36 * 2];
wolfSSL 14:167253f4e170 2214 t[2] = &td[2 * 36 * 2];
wolfSSL 14:167253f4e170 2215
wolfSSL 14:167253f4e170 2216 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 2217 sp_2048_mont_norm_36(norm, m);
wolfSSL 14:167253f4e170 2218
wolfSSL 14:167253f4e170 2219 if (reduceA)
wolfSSL 14:167253f4e170 2220 err = sp_2048_mod_36(t[1], a, m);
wolfSSL 14:167253f4e170 2221 else
wolfSSL 14:167253f4e170 2222 XMEMCPY(t[1], a, sizeof(sp_digit) * 36);
wolfSSL 14:167253f4e170 2223 }
wolfSSL 14:167253f4e170 2224 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2225 sp_2048_mul_36(t[1], t[1], norm);
wolfSSL 14:167253f4e170 2226 err = sp_2048_mod_36(t[1], t[1], m);
wolfSSL 14:167253f4e170 2227 }
wolfSSL 14:167253f4e170 2228
wolfSSL 14:167253f4e170 2229 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2230 i = bits / 57;
wolfSSL 14:167253f4e170 2231 c = bits % 57;
wolfSSL 14:167253f4e170 2232 n = e[i--] << (57 - c);
wolfSSL 14:167253f4e170 2233 for (; ; c--) {
wolfSSL 14:167253f4e170 2234 if (c == 0) {
wolfSSL 14:167253f4e170 2235 if (i == -1)
wolfSSL 14:167253f4e170 2236 break;
wolfSSL 14:167253f4e170 2237
wolfSSL 14:167253f4e170 2238 n = e[i--];
wolfSSL 14:167253f4e170 2239 c = 57;
wolfSSL 14:167253f4e170 2240 }
wolfSSL 14:167253f4e170 2241
wolfSSL 14:167253f4e170 2242 y = (n >> 56) & 1;
wolfSSL 14:167253f4e170 2243 n <<= 1;
wolfSSL 14:167253f4e170 2244
wolfSSL 14:167253f4e170 2245 sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 2246
wolfSSL 14:167253f4e170 2247 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 2248 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 2249 sizeof(*t[2]) * 36 * 2);
wolfSSL 14:167253f4e170 2250 sp_2048_mont_sqr_36(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 2251 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 2252 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 2253 sizeof(*t[2]) * 36 * 2);
wolfSSL 14:167253f4e170 2254 }
wolfSSL 14:167253f4e170 2255
wolfSSL 14:167253f4e170 2256 sp_2048_mont_reduce_36(t[0], m, mp);
wolfSSL 14:167253f4e170 2257 n = sp_2048_cmp_36(t[0], m);
wolfSSL 14:167253f4e170 2258 sp_2048_cond_sub_36(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 2259 XMEMCPY(r, t[0], sizeof(*r) * 36 * 2);
wolfSSL 14:167253f4e170 2260
wolfSSL 14:167253f4e170 2261 }
wolfSSL 14:167253f4e170 2262
wolfSSL 14:167253f4e170 2263 if (td != NULL)
wolfSSL 14:167253f4e170 2264 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2265
wolfSSL 14:167253f4e170 2266 return err;
wolfSSL 14:167253f4e170 2267 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 2268 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2269 sp_digit t[3][72];
wolfSSL 14:167253f4e170 2270 #else
wolfSSL 14:167253f4e170 2271 sp_digit* td;
wolfSSL 14:167253f4e170 2272 sp_digit* t[3];
wolfSSL 14:167253f4e170 2273 #endif
wolfSSL 14:167253f4e170 2274 sp_digit* norm;
wolfSSL 14:167253f4e170 2275 sp_digit mp = 1;
wolfSSL 14:167253f4e170 2276 sp_digit n;
wolfSSL 14:167253f4e170 2277 int i;
wolfSSL 14:167253f4e170 2278 int c, y;
wolfSSL 14:167253f4e170 2279 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2280
wolfSSL 14:167253f4e170 2281 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2282 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 36 * 2, NULL,
wolfSSL 14:167253f4e170 2283 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2284 if (td == NULL)
wolfSSL 14:167253f4e170 2285 err = MEMORY_E;
wolfSSL 14:167253f4e170 2286
wolfSSL 14:167253f4e170 2287 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2288 t[0] = td;
wolfSSL 14:167253f4e170 2289 t[1] = &td[36 * 2];
wolfSSL 14:167253f4e170 2290 t[2] = &td[2 * 36 * 2];
wolfSSL 14:167253f4e170 2291 norm = t[0];
wolfSSL 14:167253f4e170 2292 }
wolfSSL 14:167253f4e170 2293 #else
wolfSSL 14:167253f4e170 2294 norm = t[0];
wolfSSL 14:167253f4e170 2295 #endif
wolfSSL 14:167253f4e170 2296
wolfSSL 14:167253f4e170 2297 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2298 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 2299 sp_2048_mont_norm_36(norm, m);
wolfSSL 14:167253f4e170 2300
wolfSSL 14:167253f4e170 2301 if (reduceA) {
wolfSSL 14:167253f4e170 2302 err = sp_2048_mod_36(t[1], a, m);
wolfSSL 14:167253f4e170 2303 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2304 sp_2048_mul_36(t[1], t[1], norm);
wolfSSL 14:167253f4e170 2305 err = sp_2048_mod_36(t[1], t[1], m);
wolfSSL 14:167253f4e170 2306 }
wolfSSL 14:167253f4e170 2307 }
wolfSSL 14:167253f4e170 2308 else {
wolfSSL 14:167253f4e170 2309 sp_2048_mul_36(t[1], a, norm);
wolfSSL 14:167253f4e170 2310 err = sp_2048_mod_36(t[1], t[1], m);
wolfSSL 14:167253f4e170 2311 }
wolfSSL 14:167253f4e170 2312 }
wolfSSL 14:167253f4e170 2313
wolfSSL 14:167253f4e170 2314 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2315 i = bits / 57;
wolfSSL 14:167253f4e170 2316 c = bits % 57;
wolfSSL 14:167253f4e170 2317 n = e[i--] << (57 - c);
wolfSSL 14:167253f4e170 2318 for (; ; c--) {
wolfSSL 14:167253f4e170 2319 if (c == 0) {
wolfSSL 14:167253f4e170 2320 if (i == -1)
wolfSSL 14:167253f4e170 2321 break;
wolfSSL 14:167253f4e170 2322
wolfSSL 14:167253f4e170 2323 n = e[i--];
wolfSSL 14:167253f4e170 2324 c = 57;
wolfSSL 14:167253f4e170 2325 }
wolfSSL 14:167253f4e170 2326
wolfSSL 14:167253f4e170 2327 y = (n >> 56) & 1;
wolfSSL 14:167253f4e170 2328 n <<= 1;
wolfSSL 14:167253f4e170 2329
wolfSSL 14:167253f4e170 2330 sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 2331
wolfSSL 14:167253f4e170 2332 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 2333 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 2334 sp_2048_mont_sqr_36(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 2335 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 2336 ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 2337 }
wolfSSL 14:167253f4e170 2338
wolfSSL 14:167253f4e170 2339 sp_2048_mont_reduce_36(t[0], m, mp);
wolfSSL 14:167253f4e170 2340 n = sp_2048_cmp_36(t[0], m);
wolfSSL 14:167253f4e170 2341 sp_2048_cond_sub_36(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 2342 XMEMCPY(r, t[0], sizeof(t[0]));
wolfSSL 14:167253f4e170 2343 }
wolfSSL 14:167253f4e170 2344
wolfSSL 14:167253f4e170 2345 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2346 if (td != NULL)
wolfSSL 14:167253f4e170 2347 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2348 #endif
wolfSSL 14:167253f4e170 2349
wolfSSL 14:167253f4e170 2350 return err;
wolfSSL 14:167253f4e170 2351 #else
wolfSSL 14:167253f4e170 2352 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2353 sp_digit t[32][72];
wolfSSL 14:167253f4e170 2354 #else
wolfSSL 14:167253f4e170 2355 sp_digit* t[32];
wolfSSL 14:167253f4e170 2356 sp_digit* td;
wolfSSL 14:167253f4e170 2357 #endif
wolfSSL 14:167253f4e170 2358 sp_digit* norm;
wolfSSL 14:167253f4e170 2359 sp_digit rt[72];
wolfSSL 14:167253f4e170 2360 sp_digit mp = 1;
wolfSSL 14:167253f4e170 2361 sp_digit n;
wolfSSL 14:167253f4e170 2362 int i;
wolfSSL 14:167253f4e170 2363 int c, y;
wolfSSL 14:167253f4e170 2364 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2365
wolfSSL 14:167253f4e170 2366 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2367 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 72, NULL,
wolfSSL 14:167253f4e170 2368 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2369 if (td == NULL)
wolfSSL 14:167253f4e170 2370 err = MEMORY_E;
wolfSSL 14:167253f4e170 2371
wolfSSL 14:167253f4e170 2372 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2373 for (i=0; i<32; i++)
wolfSSL 14:167253f4e170 2374 t[i] = td + i * 72;
wolfSSL 14:167253f4e170 2375 norm = t[0];
wolfSSL 14:167253f4e170 2376 }
wolfSSL 14:167253f4e170 2377 #else
wolfSSL 14:167253f4e170 2378 norm = t[0];
wolfSSL 14:167253f4e170 2379 #endif
wolfSSL 14:167253f4e170 2380
wolfSSL 14:167253f4e170 2381 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2382 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 2383 sp_2048_mont_norm_36(norm, m);
wolfSSL 14:167253f4e170 2384
wolfSSL 14:167253f4e170 2385 if (reduceA) {
wolfSSL 14:167253f4e170 2386 err = sp_2048_mod_36(t[1], a, m);
wolfSSL 14:167253f4e170 2387 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2388 sp_2048_mul_36(t[1], t[1], norm);
wolfSSL 14:167253f4e170 2389 err = sp_2048_mod_36(t[1], t[1], m);
wolfSSL 14:167253f4e170 2390 }
wolfSSL 14:167253f4e170 2391 }
wolfSSL 14:167253f4e170 2392 else {
wolfSSL 14:167253f4e170 2393 sp_2048_mul_36(t[1], a, norm);
wolfSSL 14:167253f4e170 2394 err = sp_2048_mod_36(t[1], t[1], m);
wolfSSL 14:167253f4e170 2395 }
wolfSSL 14:167253f4e170 2396 }
wolfSSL 14:167253f4e170 2397
wolfSSL 14:167253f4e170 2398 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2399 sp_2048_mont_sqr_36(t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 2400 sp_2048_mont_mul_36(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 2401 sp_2048_mont_sqr_36(t[ 4], t[ 2], m, mp);
wolfSSL 14:167253f4e170 2402 sp_2048_mont_mul_36(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 14:167253f4e170 2403 sp_2048_mont_sqr_36(t[ 6], t[ 3], m, mp);
wolfSSL 14:167253f4e170 2404 sp_2048_mont_mul_36(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 14:167253f4e170 2405 sp_2048_mont_sqr_36(t[ 8], t[ 4], m, mp);
wolfSSL 14:167253f4e170 2406 sp_2048_mont_mul_36(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 14:167253f4e170 2407 sp_2048_mont_sqr_36(t[10], t[ 5], m, mp);
wolfSSL 14:167253f4e170 2408 sp_2048_mont_mul_36(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 14:167253f4e170 2409 sp_2048_mont_sqr_36(t[12], t[ 6], m, mp);
wolfSSL 14:167253f4e170 2410 sp_2048_mont_mul_36(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 14:167253f4e170 2411 sp_2048_mont_sqr_36(t[14], t[ 7], m, mp);
wolfSSL 14:167253f4e170 2412 sp_2048_mont_mul_36(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 14:167253f4e170 2413 sp_2048_mont_sqr_36(t[16], t[ 8], m, mp);
wolfSSL 14:167253f4e170 2414 sp_2048_mont_mul_36(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 14:167253f4e170 2415 sp_2048_mont_sqr_36(t[18], t[ 9], m, mp);
wolfSSL 14:167253f4e170 2416 sp_2048_mont_mul_36(t[19], t[10], t[ 9], m, mp);
wolfSSL 14:167253f4e170 2417 sp_2048_mont_sqr_36(t[20], t[10], m, mp);
wolfSSL 14:167253f4e170 2418 sp_2048_mont_mul_36(t[21], t[11], t[10], m, mp);
wolfSSL 14:167253f4e170 2419 sp_2048_mont_sqr_36(t[22], t[11], m, mp);
wolfSSL 14:167253f4e170 2420 sp_2048_mont_mul_36(t[23], t[12], t[11], m, mp);
wolfSSL 14:167253f4e170 2421 sp_2048_mont_sqr_36(t[24], t[12], m, mp);
wolfSSL 14:167253f4e170 2422 sp_2048_mont_mul_36(t[25], t[13], t[12], m, mp);
wolfSSL 14:167253f4e170 2423 sp_2048_mont_sqr_36(t[26], t[13], m, mp);
wolfSSL 14:167253f4e170 2424 sp_2048_mont_mul_36(t[27], t[14], t[13], m, mp);
wolfSSL 14:167253f4e170 2425 sp_2048_mont_sqr_36(t[28], t[14], m, mp);
wolfSSL 14:167253f4e170 2426 sp_2048_mont_mul_36(t[29], t[15], t[14], m, mp);
wolfSSL 14:167253f4e170 2427 sp_2048_mont_sqr_36(t[30], t[15], m, mp);
wolfSSL 14:167253f4e170 2428 sp_2048_mont_mul_36(t[31], t[16], t[15], m, mp);
wolfSSL 14:167253f4e170 2429
wolfSSL 14:167253f4e170 2430 bits = ((bits + 4) / 5) * 5;
wolfSSL 14:167253f4e170 2431 i = ((bits + 56) / 57) - 1;
wolfSSL 14:167253f4e170 2432 c = bits % 57;
wolfSSL 14:167253f4e170 2433 if (c == 0)
wolfSSL 14:167253f4e170 2434 c = 57;
wolfSSL 14:167253f4e170 2435 if (i < 36)
wolfSSL 14:167253f4e170 2436 n = e[i--] << (64 - c);
wolfSSL 14:167253f4e170 2437 else {
wolfSSL 14:167253f4e170 2438 n = 0;
wolfSSL 14:167253f4e170 2439 i--;
wolfSSL 14:167253f4e170 2440 }
wolfSSL 14:167253f4e170 2441 if (c < 5) {
wolfSSL 14:167253f4e170 2442 n |= e[i--] << (7 - c);
wolfSSL 14:167253f4e170 2443 c += 57;
wolfSSL 14:167253f4e170 2444 }
wolfSSL 14:167253f4e170 2445 y = n >> 59;
wolfSSL 14:167253f4e170 2446 n <<= 5;
wolfSSL 14:167253f4e170 2447 c -= 5;
wolfSSL 14:167253f4e170 2448 XMEMCPY(rt, t[y], sizeof(rt));
wolfSSL 14:167253f4e170 2449 for (; i>=0 || c>=5; ) {
wolfSSL 14:167253f4e170 2450 if (c < 5) {
wolfSSL 14:167253f4e170 2451 n |= e[i--] << (7 - c);
wolfSSL 14:167253f4e170 2452 c += 57;
wolfSSL 14:167253f4e170 2453 }
wolfSSL 14:167253f4e170 2454 y = (n >> 59) & 0x1f;
wolfSSL 14:167253f4e170 2455 n <<= 5;
wolfSSL 14:167253f4e170 2456 c -= 5;
wolfSSL 14:167253f4e170 2457
wolfSSL 14:167253f4e170 2458 sp_2048_mont_sqr_36(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2459 sp_2048_mont_sqr_36(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2460 sp_2048_mont_sqr_36(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2461 sp_2048_mont_sqr_36(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2462 sp_2048_mont_sqr_36(rt, rt, m, mp);
wolfSSL 14:167253f4e170 2463
wolfSSL 14:167253f4e170 2464 sp_2048_mont_mul_36(rt, rt, t[y], m, mp);
wolfSSL 14:167253f4e170 2465 }
wolfSSL 14:167253f4e170 2466
wolfSSL 14:167253f4e170 2467 sp_2048_mont_reduce_36(rt, m, mp);
wolfSSL 14:167253f4e170 2468 n = sp_2048_cmp_36(rt, m);
wolfSSL 14:167253f4e170 2469 sp_2048_cond_sub_36(rt, rt, m, (n < 0) - 1);
wolfSSL 14:167253f4e170 2470 XMEMCPY(r, rt, sizeof(rt));
wolfSSL 14:167253f4e170 2471 }
wolfSSL 14:167253f4e170 2472
wolfSSL 14:167253f4e170 2473 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 2474 if (td != NULL)
wolfSSL 14:167253f4e170 2475 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2476 #endif
wolfSSL 14:167253f4e170 2477
wolfSSL 14:167253f4e170 2478 return err;
wolfSSL 14:167253f4e170 2479 #endif
wolfSSL 14:167253f4e170 2480 }
wolfSSL 14:167253f4e170 2481 #endif /* SP_RSA_PRIVATE_EXP_D || WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 2482
wolfSSL 14:167253f4e170 2483 #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \
wolfSSL 14:167253f4e170 2484 !defined(RSA_LOW_MEM)
wolfSSL 14:167253f4e170 2485 /* AND m into each word of a and store in r.
wolfSSL 14:167253f4e170 2486 *
wolfSSL 14:167253f4e170 2487 * r A single precision integer.
wolfSSL 14:167253f4e170 2488 * a A single precision integer.
wolfSSL 14:167253f4e170 2489 * m Mask to AND against each digit.
wolfSSL 14:167253f4e170 2490 */
wolfSSL 14:167253f4e170 2491 static void sp_2048_mask_18(sp_digit* r, sp_digit* a, sp_digit m)
wolfSSL 14:167253f4e170 2492 {
wolfSSL 14:167253f4e170 2493 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2494 int i;
wolfSSL 14:167253f4e170 2495
wolfSSL 14:167253f4e170 2496 for (i=0; i<18; i++)
wolfSSL 14:167253f4e170 2497 r[i] = a[i] & m;
wolfSSL 14:167253f4e170 2498 #else
wolfSSL 14:167253f4e170 2499 int i;
wolfSSL 14:167253f4e170 2500
wolfSSL 14:167253f4e170 2501 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 2502 r[i+0] = a[i+0] & m;
wolfSSL 14:167253f4e170 2503 r[i+1] = a[i+1] & m;
wolfSSL 14:167253f4e170 2504 r[i+2] = a[i+2] & m;
wolfSSL 14:167253f4e170 2505 r[i+3] = a[i+3] & m;
wolfSSL 14:167253f4e170 2506 r[i+4] = a[i+4] & m;
wolfSSL 14:167253f4e170 2507 r[i+5] = a[i+5] & m;
wolfSSL 14:167253f4e170 2508 r[i+6] = a[i+6] & m;
wolfSSL 14:167253f4e170 2509 r[i+7] = a[i+7] & m;
wolfSSL 14:167253f4e170 2510 }
wolfSSL 14:167253f4e170 2511 r[16] = a[16] & m;
wolfSSL 14:167253f4e170 2512 r[17] = a[17] & m;
wolfSSL 14:167253f4e170 2513 #endif
wolfSSL 14:167253f4e170 2514 }
wolfSSL 14:167253f4e170 2515
wolfSSL 14:167253f4e170 2516 #endif
wolfSSL 14:167253f4e170 2517 #ifdef WOLFSSL_HAVE_SP_RSA
wolfSSL 14:167253f4e170 2518 /* RSA public key operation.
wolfSSL 14:167253f4e170 2519 *
wolfSSL 14:167253f4e170 2520 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 14:167253f4e170 2521 * inLen Number of bytes in base.
wolfSSL 14:167253f4e170 2522 * em Public exponent.
wolfSSL 14:167253f4e170 2523 * mm Modulus.
wolfSSL 14:167253f4e170 2524 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 2525 * Must be at least 256 bytes long.
wolfSSL 14:167253f4e170 2526 * outLen Number of bytes in result.
wolfSSL 14:167253f4e170 2527 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 14:167253f4e170 2528 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 14:167253f4e170 2529 */
wolfSSL 14:167253f4e170 2530 int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,
wolfSSL 14:167253f4e170 2531 byte* out, word32* outLen)
wolfSSL 14:167253f4e170 2532 {
wolfSSL 14:167253f4e170 2533 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 2534 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 2535 sp_digit* a;
wolfSSL 14:167253f4e170 2536 sp_digit* m;
wolfSSL 14:167253f4e170 2537 sp_digit* r;
wolfSSL 14:167253f4e170 2538 sp_digit* norm;
wolfSSL 14:167253f4e170 2539 sp_digit e[1];
wolfSSL 14:167253f4e170 2540 sp_digit mp;
wolfSSL 14:167253f4e170 2541 int i;
wolfSSL 14:167253f4e170 2542 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2543
wolfSSL 14:167253f4e170 2544 if (*outLen < 256)
wolfSSL 14:167253f4e170 2545 err = MP_TO_E;
wolfSSL 14:167253f4e170 2546 if (err == MP_OKAY && (mp_count_bits(em) > 57 || inLen > 256 ||
wolfSSL 14:167253f4e170 2547 mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 2548 err = MP_READ_E;
wolfSSL 14:167253f4e170 2549
wolfSSL 14:167253f4e170 2550 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2551 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 5, NULL,
wolfSSL 14:167253f4e170 2552 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2553 if (d == NULL)
wolfSSL 14:167253f4e170 2554 err = MEMORY_E;
wolfSSL 14:167253f4e170 2555 }
wolfSSL 14:167253f4e170 2556
wolfSSL 14:167253f4e170 2557 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2558 a = d;
wolfSSL 14:167253f4e170 2559 r = a + 36 * 2;
wolfSSL 14:167253f4e170 2560 m = r + 36 * 2;
wolfSSL 14:167253f4e170 2561 norm = r;
wolfSSL 14:167253f4e170 2562
wolfSSL 14:167253f4e170 2563 sp_2048_from_bin(a, 36, in, inLen);
wolfSSL 14:167253f4e170 2564 #if DIGIT_BIT >= 57
wolfSSL 14:167253f4e170 2565 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 2566 #else
wolfSSL 14:167253f4e170 2567 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 2568 if (em->used > 1)
wolfSSL 14:167253f4e170 2569 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 14:167253f4e170 2570 #endif
wolfSSL 14:167253f4e170 2571 if (e[0] == 0)
wolfSSL 14:167253f4e170 2572 err = MP_EXPTMOD_E;
wolfSSL 14:167253f4e170 2573 }
wolfSSL 14:167253f4e170 2574
wolfSSL 14:167253f4e170 2575 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2576 sp_2048_from_mp(m, 36, mm);
wolfSSL 14:167253f4e170 2577
wolfSSL 14:167253f4e170 2578 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 2579 sp_2048_mont_norm_36(norm, m);
wolfSSL 14:167253f4e170 2580 }
wolfSSL 14:167253f4e170 2581 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2582 sp_2048_mul_36(a, a, norm);
wolfSSL 14:167253f4e170 2583 err = sp_2048_mod_36(a, a, m);
wolfSSL 14:167253f4e170 2584 }
wolfSSL 14:167253f4e170 2585 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2586 for (i=56; i>=0; i--)
wolfSSL 14:167253f4e170 2587 if (e[0] >> i)
wolfSSL 14:167253f4e170 2588 break;
wolfSSL 14:167253f4e170 2589
wolfSSL 14:167253f4e170 2590 XMEMCPY(r, a, sizeof(sp_digit) * 36 * 2);
wolfSSL 14:167253f4e170 2591 for (i--; i>=0; i--) {
wolfSSL 14:167253f4e170 2592 sp_2048_mont_sqr_36(r, r, m, mp);
wolfSSL 14:167253f4e170 2593
wolfSSL 14:167253f4e170 2594 if (((e[0] >> i) & 1) == 1)
wolfSSL 14:167253f4e170 2595 sp_2048_mont_mul_36(r, r, a, m, mp);
wolfSSL 14:167253f4e170 2596 }
wolfSSL 14:167253f4e170 2597 sp_2048_mont_reduce_36(r, m, mp);
wolfSSL 14:167253f4e170 2598 mp = sp_2048_cmp_36(r, m);
wolfSSL 14:167253f4e170 2599 sp_2048_cond_sub_36(r, r, m, (mp < 0) - 1);
wolfSSL 14:167253f4e170 2600
wolfSSL 14:167253f4e170 2601 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 2602 *outLen = 256;
wolfSSL 14:167253f4e170 2603 }
wolfSSL 14:167253f4e170 2604
wolfSSL 14:167253f4e170 2605 if (d != NULL)
wolfSSL 14:167253f4e170 2606 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2607
wolfSSL 14:167253f4e170 2608 return err;
wolfSSL 14:167253f4e170 2609 #else
wolfSSL 14:167253f4e170 2610 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2611 sp_digit ad[72], md[36], rd[72];
wolfSSL 14:167253f4e170 2612 #else
wolfSSL 14:167253f4e170 2613 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 2614 #endif
wolfSSL 14:167253f4e170 2615 sp_digit* a;
wolfSSL 14:167253f4e170 2616 sp_digit* m;
wolfSSL 14:167253f4e170 2617 sp_digit* r;
wolfSSL 14:167253f4e170 2618 sp_digit e[1];
wolfSSL 14:167253f4e170 2619 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2620
wolfSSL 14:167253f4e170 2621 if (*outLen < 256)
wolfSSL 14:167253f4e170 2622 err = MP_TO_E;
wolfSSL 14:167253f4e170 2623 if (err == MP_OKAY && (mp_count_bits(em) > 57 || inLen > 256 ||
wolfSSL 14:167253f4e170 2624 mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 2625 err = MP_READ_E;
wolfSSL 14:167253f4e170 2626
wolfSSL 14:167253f4e170 2627 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2628 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2629 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 5, NULL,
wolfSSL 14:167253f4e170 2630 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2631 if (d == NULL)
wolfSSL 14:167253f4e170 2632 err = MEMORY_E;
wolfSSL 14:167253f4e170 2633 }
wolfSSL 14:167253f4e170 2634
wolfSSL 14:167253f4e170 2635 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2636 a = d;
wolfSSL 14:167253f4e170 2637 r = a + 36 * 2;
wolfSSL 14:167253f4e170 2638 m = r + 36 * 2;
wolfSSL 14:167253f4e170 2639 }
wolfSSL 14:167253f4e170 2640 #else
wolfSSL 14:167253f4e170 2641 a = ad;
wolfSSL 14:167253f4e170 2642 m = md;
wolfSSL 14:167253f4e170 2643 r = rd;
wolfSSL 14:167253f4e170 2644 #endif
wolfSSL 14:167253f4e170 2645
wolfSSL 14:167253f4e170 2646 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2647 sp_2048_from_bin(a, 36, in, inLen);
wolfSSL 14:167253f4e170 2648 #if DIGIT_BIT >= 57
wolfSSL 14:167253f4e170 2649 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 2650 #else
wolfSSL 14:167253f4e170 2651 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 2652 if (em->used > 1)
wolfSSL 14:167253f4e170 2653 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 14:167253f4e170 2654 #endif
wolfSSL 14:167253f4e170 2655 if (e[0] == 0)
wolfSSL 14:167253f4e170 2656 err = MP_EXPTMOD_E;
wolfSSL 14:167253f4e170 2657 }
wolfSSL 14:167253f4e170 2658 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2659 sp_2048_from_mp(m, 36, mm);
wolfSSL 14:167253f4e170 2660
wolfSSL 14:167253f4e170 2661 if (e[0] == 0x3) {
wolfSSL 14:167253f4e170 2662 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2663 sp_2048_sqr_36(r, a);
wolfSSL 14:167253f4e170 2664 err = sp_2048_mod_36(r, r, m);
wolfSSL 14:167253f4e170 2665 }
wolfSSL 14:167253f4e170 2666 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2667 sp_2048_mul_36(r, a, r);
wolfSSL 14:167253f4e170 2668 err = sp_2048_mod_36(r, r, m);
wolfSSL 14:167253f4e170 2669 }
wolfSSL 14:167253f4e170 2670 }
wolfSSL 14:167253f4e170 2671 else {
wolfSSL 14:167253f4e170 2672 sp_digit* norm = r;
wolfSSL 14:167253f4e170 2673 int i;
wolfSSL 14:167253f4e170 2674 sp_digit mp;
wolfSSL 14:167253f4e170 2675
wolfSSL 14:167253f4e170 2676 sp_2048_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 2677 sp_2048_mont_norm_36(norm, m);
wolfSSL 14:167253f4e170 2678
wolfSSL 14:167253f4e170 2679 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2680 sp_2048_mul_36(a, a, norm);
wolfSSL 14:167253f4e170 2681 err = sp_2048_mod_36(a, a, m);
wolfSSL 14:167253f4e170 2682 }
wolfSSL 14:167253f4e170 2683
wolfSSL 14:167253f4e170 2684 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2685 for (i=56; i>=0; i--)
wolfSSL 14:167253f4e170 2686 if (e[0] >> i)
wolfSSL 14:167253f4e170 2687 break;
wolfSSL 14:167253f4e170 2688
wolfSSL 14:167253f4e170 2689 XMEMCPY(r, a, sizeof(sp_digit) * 72);
wolfSSL 14:167253f4e170 2690 for (i--; i>=0; i--) {
wolfSSL 14:167253f4e170 2691 sp_2048_mont_sqr_36(r, r, m, mp);
wolfSSL 14:167253f4e170 2692
wolfSSL 14:167253f4e170 2693 if (((e[0] >> i) & 1) == 1)
wolfSSL 14:167253f4e170 2694 sp_2048_mont_mul_36(r, r, a, m, mp);
wolfSSL 14:167253f4e170 2695 }
wolfSSL 14:167253f4e170 2696 sp_2048_mont_reduce_36(r, m, mp);
wolfSSL 14:167253f4e170 2697 mp = sp_2048_cmp_36(r, m);
wolfSSL 14:167253f4e170 2698 sp_2048_cond_sub_36(r, r, m, (mp < 0) - 1);
wolfSSL 14:167253f4e170 2699 }
wolfSSL 14:167253f4e170 2700 }
wolfSSL 14:167253f4e170 2701 }
wolfSSL 14:167253f4e170 2702
wolfSSL 14:167253f4e170 2703 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2704 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 2705 *outLen = 256;
wolfSSL 14:167253f4e170 2706 }
wolfSSL 14:167253f4e170 2707
wolfSSL 14:167253f4e170 2708 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2709 if (d != NULL)
wolfSSL 14:167253f4e170 2710 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2711 #endif
wolfSSL 14:167253f4e170 2712
wolfSSL 14:167253f4e170 2713 return err;
wolfSSL 14:167253f4e170 2714 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 2715 }
wolfSSL 14:167253f4e170 2716
wolfSSL 14:167253f4e170 2717 /* RSA private key operation.
wolfSSL 14:167253f4e170 2718 *
wolfSSL 14:167253f4e170 2719 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 14:167253f4e170 2720 * inLen Number of bytes in base.
wolfSSL 14:167253f4e170 2721 * dm Private exponent.
wolfSSL 14:167253f4e170 2722 * pm First prime.
wolfSSL 14:167253f4e170 2723 * qm Second prime.
wolfSSL 14:167253f4e170 2724 * dpm First prime's CRT exponent.
wolfSSL 14:167253f4e170 2725 * dqm Second prime's CRT exponent.
wolfSSL 14:167253f4e170 2726 * qim Inverse of second prime mod p.
wolfSSL 14:167253f4e170 2727 * mm Modulus.
wolfSSL 14:167253f4e170 2728 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 2729 * Must be at least 256 bytes long.
wolfSSL 14:167253f4e170 2730 * outLen Number of bytes in result.
wolfSSL 14:167253f4e170 2731 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 14:167253f4e170 2732 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 14:167253f4e170 2733 */
wolfSSL 14:167253f4e170 2734 int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,
wolfSSL 14:167253f4e170 2735 mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,
wolfSSL 14:167253f4e170 2736 byte* out, word32* outLen)
wolfSSL 14:167253f4e170 2737 {
wolfSSL 14:167253f4e170 2738 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
wolfSSL 14:167253f4e170 2739 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2740 sp_digit* a;
wolfSSL 14:167253f4e170 2741 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 2742 sp_digit* m;
wolfSSL 14:167253f4e170 2743 sp_digit* r;
wolfSSL 14:167253f4e170 2744 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2745
wolfSSL 14:167253f4e170 2746 (void)pm;
wolfSSL 14:167253f4e170 2747 (void)qm;
wolfSSL 14:167253f4e170 2748 (void)dpm;
wolfSSL 14:167253f4e170 2749 (void)dqm;
wolfSSL 14:167253f4e170 2750 (void)qim;
wolfSSL 14:167253f4e170 2751
wolfSSL 14:167253f4e170 2752 if (*outLen < 256)
wolfSSL 14:167253f4e170 2753 err = MP_TO_E;
wolfSSL 14:167253f4e170 2754 if (err == MP_OKAY && (mp_count_bits(dm) > 2048 || inLen > 256 ||
wolfSSL 14:167253f4e170 2755 mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 2756 err = MP_READ_E;
wolfSSL 14:167253f4e170 2757
wolfSSL 14:167253f4e170 2758 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2759 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,
wolfSSL 14:167253f4e170 2760 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2761 if (d == NULL)
wolfSSL 14:167253f4e170 2762 err = MEMORY_E;
wolfSSL 14:167253f4e170 2763 }
wolfSSL 14:167253f4e170 2764 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2765 a = d + 36;
wolfSSL 14:167253f4e170 2766 m = a + 36;
wolfSSL 14:167253f4e170 2767 r = a;
wolfSSL 14:167253f4e170 2768
wolfSSL 14:167253f4e170 2769 sp_2048_from_bin(a, 36, in, inLen);
wolfSSL 14:167253f4e170 2770 sp_2048_from_mp(d, 36, dm);
wolfSSL 14:167253f4e170 2771 sp_2048_from_mp(m, 36, mm);
wolfSSL 14:167253f4e170 2772 err = sp_2048_mod_exp_36(r, a, d, 2048, m, 0);
wolfSSL 14:167253f4e170 2773 }
wolfSSL 14:167253f4e170 2774 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2775 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 2776 *outLen = 256;
wolfSSL 14:167253f4e170 2777 }
wolfSSL 14:167253f4e170 2778
wolfSSL 14:167253f4e170 2779 if (d != NULL) {
wolfSSL 14:167253f4e170 2780 XMEMSET(d, 0, sizeof(sp_digit) * 36);
wolfSSL 14:167253f4e170 2781 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2782 }
wolfSSL 14:167253f4e170 2783
wolfSSL 14:167253f4e170 2784 return err;
wolfSSL 14:167253f4e170 2785 #else
wolfSSL 14:167253f4e170 2786 sp_digit a[72], d[36], m[36];
wolfSSL 14:167253f4e170 2787 sp_digit* r = a;
wolfSSL 14:167253f4e170 2788 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2789
wolfSSL 14:167253f4e170 2790 (void)pm;
wolfSSL 14:167253f4e170 2791 (void)qm;
wolfSSL 14:167253f4e170 2792 (void)dpm;
wolfSSL 14:167253f4e170 2793 (void)dqm;
wolfSSL 14:167253f4e170 2794 (void)qim;
wolfSSL 14:167253f4e170 2795
wolfSSL 14:167253f4e170 2796 if (*outLen < 256)
wolfSSL 14:167253f4e170 2797 err = MP_TO_E;
wolfSSL 14:167253f4e170 2798 if (err == MP_OKAY && (mp_count_bits(dm) > 2048 || inLen > 256 ||
wolfSSL 14:167253f4e170 2799 mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 2800 err = MP_READ_E;
wolfSSL 14:167253f4e170 2801
wolfSSL 14:167253f4e170 2802 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2803 sp_2048_from_bin(a, 36, in, inLen);
wolfSSL 14:167253f4e170 2804 sp_2048_from_mp(d, 36, dm);
wolfSSL 14:167253f4e170 2805 sp_2048_from_mp(m, 36, mm);
wolfSSL 14:167253f4e170 2806 err = sp_2048_mod_exp_36(r, a, d, 2048, m, 0);
wolfSSL 14:167253f4e170 2807 }
wolfSSL 14:167253f4e170 2808
wolfSSL 14:167253f4e170 2809 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2810 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 2811 *outLen = 256;
wolfSSL 14:167253f4e170 2812 }
wolfSSL 14:167253f4e170 2813
wolfSSL 14:167253f4e170 2814 XMEMSET(d, 0, sizeof(sp_digit) * 36);
wolfSSL 14:167253f4e170 2815
wolfSSL 14:167253f4e170 2816 return err;
wolfSSL 14:167253f4e170 2817 #endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */
wolfSSL 14:167253f4e170 2818 #else
wolfSSL 14:167253f4e170 2819 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 2820 sp_digit* t = NULL;
wolfSSL 14:167253f4e170 2821 sp_digit* a;
wolfSSL 14:167253f4e170 2822 sp_digit* p;
wolfSSL 14:167253f4e170 2823 sp_digit* q;
wolfSSL 14:167253f4e170 2824 sp_digit* dp;
wolfSSL 14:167253f4e170 2825 sp_digit* dq;
wolfSSL 14:167253f4e170 2826 sp_digit* qi;
wolfSSL 14:167253f4e170 2827 sp_digit* tmp;
wolfSSL 14:167253f4e170 2828 sp_digit* tmpa;
wolfSSL 14:167253f4e170 2829 sp_digit* tmpb;
wolfSSL 14:167253f4e170 2830 sp_digit* r;
wolfSSL 14:167253f4e170 2831 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2832
wolfSSL 14:167253f4e170 2833 (void)dm;
wolfSSL 14:167253f4e170 2834 (void)mm;
wolfSSL 14:167253f4e170 2835
wolfSSL 14:167253f4e170 2836 if (*outLen < 256)
wolfSSL 14:167253f4e170 2837 err = MP_TO_E;
wolfSSL 14:167253f4e170 2838 if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 2839 err = MP_READ_E;
wolfSSL 14:167253f4e170 2840
wolfSSL 14:167253f4e170 2841 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2842 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 11, NULL,
wolfSSL 14:167253f4e170 2843 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2844 if (t == NULL)
wolfSSL 14:167253f4e170 2845 err = MEMORY_E;
wolfSSL 14:167253f4e170 2846 }
wolfSSL 14:167253f4e170 2847 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2848 a = t;
wolfSSL 14:167253f4e170 2849 p = a + 36 * 2;
wolfSSL 14:167253f4e170 2850 q = p + 18;
wolfSSL 14:167253f4e170 2851 qi = dq = dp = q + 18;
wolfSSL 14:167253f4e170 2852 tmpa = qi + 18;
wolfSSL 14:167253f4e170 2853 tmpb = tmpa + 36;
wolfSSL 14:167253f4e170 2854
wolfSSL 14:167253f4e170 2855 tmp = t;
wolfSSL 14:167253f4e170 2856 r = tmp + 36;
wolfSSL 14:167253f4e170 2857
wolfSSL 14:167253f4e170 2858 sp_2048_from_bin(a, 36, in, inLen);
wolfSSL 14:167253f4e170 2859 sp_2048_from_mp(p, 18, pm);
wolfSSL 14:167253f4e170 2860 sp_2048_from_mp(q, 18, qm);
wolfSSL 14:167253f4e170 2861 sp_2048_from_mp(dp, 18, dpm);
wolfSSL 14:167253f4e170 2862 err = sp_2048_mod_exp_18(tmpa, a, dp, 1024, p, 1);
wolfSSL 14:167253f4e170 2863 }
wolfSSL 14:167253f4e170 2864 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2865 sp_2048_from_mp(dq, 18, dqm);
wolfSSL 14:167253f4e170 2866 err = sp_2048_mod_exp_18(tmpb, a, dq, 1024, q, 1);
wolfSSL 14:167253f4e170 2867 }
wolfSSL 14:167253f4e170 2868 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2869 sp_2048_sub_18(tmpa, tmpa, tmpb);
wolfSSL 14:167253f4e170 2870 sp_2048_mask_18(tmp, p, tmpa[17] >> 63);
wolfSSL 14:167253f4e170 2871 sp_2048_add_18(tmpa, tmpa, tmp);
wolfSSL 14:167253f4e170 2872
wolfSSL 14:167253f4e170 2873 sp_2048_from_mp(qi, 18, qim);
wolfSSL 14:167253f4e170 2874 sp_2048_mul_18(tmpa, tmpa, qi);
wolfSSL 14:167253f4e170 2875 err = sp_2048_mod_18(tmpa, tmpa, p);
wolfSSL 14:167253f4e170 2876 }
wolfSSL 14:167253f4e170 2877
wolfSSL 14:167253f4e170 2878 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2879 sp_2048_mul_18(tmpa, q, tmpa);
wolfSSL 14:167253f4e170 2880 sp_2048_add_36(r, tmpb, tmpa);
wolfSSL 14:167253f4e170 2881 sp_2048_norm_36(r);
wolfSSL 14:167253f4e170 2882
wolfSSL 14:167253f4e170 2883 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 2884 *outLen = 256;
wolfSSL 14:167253f4e170 2885 }
wolfSSL 14:167253f4e170 2886
wolfSSL 14:167253f4e170 2887 if (t != NULL) {
wolfSSL 14:167253f4e170 2888 XMEMSET(t, 0, sizeof(sp_digit) * 18 * 11);
wolfSSL 14:167253f4e170 2889 XFREE(t, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 2890 }
wolfSSL 14:167253f4e170 2891
wolfSSL 14:167253f4e170 2892 return err;
wolfSSL 14:167253f4e170 2893 #else
wolfSSL 14:167253f4e170 2894 sp_digit a[36 * 2];
wolfSSL 14:167253f4e170 2895 sp_digit p[18], q[18], dp[18], dq[18], qi[18];
wolfSSL 14:167253f4e170 2896 sp_digit tmp[36], tmpa[36], tmpb[36];
wolfSSL 14:167253f4e170 2897 sp_digit* r = a;
wolfSSL 14:167253f4e170 2898 int err = MP_OKAY;
wolfSSL 14:167253f4e170 2899
wolfSSL 14:167253f4e170 2900 (void)dm;
wolfSSL 14:167253f4e170 2901 (void)mm;
wolfSSL 14:167253f4e170 2902
wolfSSL 14:167253f4e170 2903 if (*outLen < 256)
wolfSSL 14:167253f4e170 2904 err = MP_TO_E;
wolfSSL 14:167253f4e170 2905 if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))
wolfSSL 14:167253f4e170 2906 err = MP_READ_E;
wolfSSL 14:167253f4e170 2907
wolfSSL 14:167253f4e170 2908 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2909 sp_2048_from_bin(a, 36, in, inLen);
wolfSSL 14:167253f4e170 2910 sp_2048_from_mp(p, 18, pm);
wolfSSL 14:167253f4e170 2911 sp_2048_from_mp(q, 18, qm);
wolfSSL 14:167253f4e170 2912 sp_2048_from_mp(dp, 18, dpm);
wolfSSL 14:167253f4e170 2913 sp_2048_from_mp(dq, 18, dqm);
wolfSSL 14:167253f4e170 2914 sp_2048_from_mp(qi, 18, qim);
wolfSSL 14:167253f4e170 2915
wolfSSL 14:167253f4e170 2916 err = sp_2048_mod_exp_18(tmpa, a, dp, 1024, p, 1);
wolfSSL 14:167253f4e170 2917 }
wolfSSL 14:167253f4e170 2918 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 2919 err = sp_2048_mod_exp_18(tmpb, a, dq, 1024, q, 1);
wolfSSL 14:167253f4e170 2920
wolfSSL 14:167253f4e170 2921 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2922 sp_2048_sub_18(tmpa, tmpa, tmpb);
wolfSSL 14:167253f4e170 2923 sp_2048_mask_18(tmp, p, tmpa[17] >> 63);
wolfSSL 14:167253f4e170 2924 sp_2048_add_18(tmpa, tmpa, tmp);
wolfSSL 14:167253f4e170 2925 sp_2048_mul_18(tmpa, tmpa, qi);
wolfSSL 14:167253f4e170 2926 err = sp_2048_mod_18(tmpa, tmpa, p);
wolfSSL 14:167253f4e170 2927 }
wolfSSL 14:167253f4e170 2928
wolfSSL 14:167253f4e170 2929 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2930 sp_2048_mul_18(tmpa, tmpa, q);
wolfSSL 14:167253f4e170 2931 sp_2048_add_36(r, tmpb, tmpa);
wolfSSL 14:167253f4e170 2932 sp_2048_norm_36(r);
wolfSSL 14:167253f4e170 2933
wolfSSL 14:167253f4e170 2934 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 2935 *outLen = 256;
wolfSSL 14:167253f4e170 2936 }
wolfSSL 14:167253f4e170 2937
wolfSSL 14:167253f4e170 2938 XMEMSET(tmpa, 0, sizeof(tmpa));
wolfSSL 14:167253f4e170 2939 XMEMSET(tmpb, 0, sizeof(tmpb));
wolfSSL 14:167253f4e170 2940 XMEMSET(p, 0, sizeof(p));
wolfSSL 14:167253f4e170 2941 XMEMSET(q, 0, sizeof(q));
wolfSSL 14:167253f4e170 2942 XMEMSET(dp, 0, sizeof(dp));
wolfSSL 14:167253f4e170 2943 XMEMSET(dq, 0, sizeof(dq));
wolfSSL 14:167253f4e170 2944 XMEMSET(qi, 0, sizeof(qi));
wolfSSL 14:167253f4e170 2945
wolfSSL 14:167253f4e170 2946 return err;
wolfSSL 14:167253f4e170 2947 #endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */
wolfSSL 14:167253f4e170 2948 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
wolfSSL 14:167253f4e170 2949 }
wolfSSL 14:167253f4e170 2950
wolfSSL 14:167253f4e170 2951 #endif /* WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 2952 #ifdef WOLFSSL_HAVE_SP_DH
wolfSSL 14:167253f4e170 2953 /* Convert an array of sp_digit to an mp_int.
wolfSSL 14:167253f4e170 2954 *
wolfSSL 14:167253f4e170 2955 * a A single precision integer.
wolfSSL 14:167253f4e170 2956 * r A multi-precision integer.
wolfSSL 14:167253f4e170 2957 */
wolfSSL 14:167253f4e170 2958 static int sp_2048_to_mp(sp_digit* a, mp_int* r)
wolfSSL 14:167253f4e170 2959 {
wolfSSL 14:167253f4e170 2960 int err;
wolfSSL 14:167253f4e170 2961
wolfSSL 14:167253f4e170 2962 err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 14:167253f4e170 2963 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 2964 #if DIGIT_BIT == 57
wolfSSL 14:167253f4e170 2965 XMEMCPY(r->dp, a, sizeof(sp_digit) * 36);
wolfSSL 14:167253f4e170 2966 r->used = 36;
wolfSSL 14:167253f4e170 2967 mp_clamp(r);
wolfSSL 14:167253f4e170 2968 #elif DIGIT_BIT < 57
wolfSSL 14:167253f4e170 2969 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 2970
wolfSSL 14:167253f4e170 2971 r->dp[0] = 0;
wolfSSL 14:167253f4e170 2972 for (i = 0; i < 36; i++) {
wolfSSL 14:167253f4e170 2973 r->dp[j] |= a[i] << s;
wolfSSL 14:167253f4e170 2974 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 2975 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 2976 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 2977 while (s + DIGIT_BIT <= 57) {
wolfSSL 14:167253f4e170 2978 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 2979 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 2980 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 2981 }
wolfSSL 14:167253f4e170 2982 s = 57 - s;
wolfSSL 14:167253f4e170 2983 }
wolfSSL 14:167253f4e170 2984 r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 2985 mp_clamp(r);
wolfSSL 14:167253f4e170 2986 #else
wolfSSL 14:167253f4e170 2987 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 2988
wolfSSL 14:167253f4e170 2989 r->dp[0] = 0;
wolfSSL 14:167253f4e170 2990 for (i = 0; i < 36; i++) {
wolfSSL 14:167253f4e170 2991 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 2992 if (s + 57 >= DIGIT_BIT) {
wolfSSL 14:167253f4e170 2993 #if DIGIT_BIT < 64
wolfSSL 14:167253f4e170 2994 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 2995 #endif
wolfSSL 14:167253f4e170 2996 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 2997 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 2998 s = 57 - s;
wolfSSL 14:167253f4e170 2999 }
wolfSSL 14:167253f4e170 3000 else
wolfSSL 14:167253f4e170 3001 s += 57;
wolfSSL 14:167253f4e170 3002 }
wolfSSL 14:167253f4e170 3003 r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 3004 mp_clamp(r);
wolfSSL 14:167253f4e170 3005 #endif
wolfSSL 14:167253f4e170 3006 }
wolfSSL 14:167253f4e170 3007
wolfSSL 14:167253f4e170 3008 return err;
wolfSSL 14:167253f4e170 3009 }
wolfSSL 14:167253f4e170 3010
wolfSSL 14:167253f4e170 3011 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 14:167253f4e170 3012 *
wolfSSL 14:167253f4e170 3013 * base Base. MP integer.
wolfSSL 14:167253f4e170 3014 * exp Exponent. MP integer.
wolfSSL 14:167253f4e170 3015 * mod Modulus. MP integer.
wolfSSL 14:167253f4e170 3016 * res Result. MP integer.
wolfSSL 14:167253f4e170 3017 * returs 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 14:167253f4e170 3018 * and MEMORY_E if memory allocation fails.
wolfSSL 14:167253f4e170 3019 */
wolfSSL 14:167253f4e170 3020 int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)
wolfSSL 14:167253f4e170 3021 {
wolfSSL 14:167253f4e170 3022 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3023 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3024 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3025 sp_digit* b;
wolfSSL 14:167253f4e170 3026 sp_digit* e;
wolfSSL 14:167253f4e170 3027 sp_digit* m;
wolfSSL 14:167253f4e170 3028 sp_digit* r;
wolfSSL 14:167253f4e170 3029 int expBits = mp_count_bits(exp);
wolfSSL 14:167253f4e170 3030
wolfSSL 14:167253f4e170 3031 if (mp_count_bits(base) > 2048 || expBits > 2048 ||
wolfSSL 14:167253f4e170 3032 mp_count_bits(mod) != 2048) {
wolfSSL 14:167253f4e170 3033 err = MP_READ_E;
wolfSSL 14:167253f4e170 3034 }
wolfSSL 14:167253f4e170 3035
wolfSSL 14:167253f4e170 3036 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3037 d = (sp_digit*)XMALLOC(sizeof(*d) * 36 * 4, NULL,
wolfSSL 14:167253f4e170 3038 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3039 if (d == NULL)
wolfSSL 14:167253f4e170 3040 err = MEMORY_E;
wolfSSL 14:167253f4e170 3041 }
wolfSSL 14:167253f4e170 3042
wolfSSL 14:167253f4e170 3043 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3044 b = d;
wolfSSL 14:167253f4e170 3045 e = b + 36 * 2;
wolfSSL 14:167253f4e170 3046 m = e + 36;
wolfSSL 14:167253f4e170 3047 r = b;
wolfSSL 14:167253f4e170 3048
wolfSSL 14:167253f4e170 3049 sp_2048_from_mp(b, 36, base);
wolfSSL 14:167253f4e170 3050 sp_2048_from_mp(e, 36, exp);
wolfSSL 14:167253f4e170 3051 sp_2048_from_mp(m, 36, mod);
wolfSSL 14:167253f4e170 3052
wolfSSL 14:167253f4e170 3053 err = sp_2048_mod_exp_36(r, b, e, mp_count_bits(exp), m, 0);
wolfSSL 14:167253f4e170 3054 }
wolfSSL 14:167253f4e170 3055
wolfSSL 14:167253f4e170 3056 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3057 err = sp_2048_to_mp(r, res);
wolfSSL 14:167253f4e170 3058 }
wolfSSL 14:167253f4e170 3059
wolfSSL 14:167253f4e170 3060 if (d != NULL) {
wolfSSL 14:167253f4e170 3061 XMEMSET(e, 0, sizeof(sp_digit) * 36);
wolfSSL 14:167253f4e170 3062 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3063 }
wolfSSL 14:167253f4e170 3064 return err;
wolfSSL 14:167253f4e170 3065 #else
wolfSSL 14:167253f4e170 3066 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3067 sp_digit bd[72], ed[36], md[36];
wolfSSL 14:167253f4e170 3068 #else
wolfSSL 14:167253f4e170 3069 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3070 #endif
wolfSSL 14:167253f4e170 3071 sp_digit* b;
wolfSSL 14:167253f4e170 3072 sp_digit* e;
wolfSSL 14:167253f4e170 3073 sp_digit* m;
wolfSSL 14:167253f4e170 3074 sp_digit* r;
wolfSSL 14:167253f4e170 3075 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3076 int expBits = mp_count_bits(exp);
wolfSSL 14:167253f4e170 3077
wolfSSL 14:167253f4e170 3078 if (mp_count_bits(base) > 2048 || expBits > 2048 ||
wolfSSL 14:167253f4e170 3079 mp_count_bits(mod) != 2048) {
wolfSSL 14:167253f4e170 3080 err = MP_READ_E;
wolfSSL 14:167253f4e170 3081 }
wolfSSL 14:167253f4e170 3082
wolfSSL 14:167253f4e170 3083 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3084 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3085 d = (sp_digit*)XMALLOC(sizeof(*d) * 36 * 4, NULL,
wolfSSL 14:167253f4e170 3086 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3087 if (d == NULL)
wolfSSL 14:167253f4e170 3088 err = MEMORY_E;
wolfSSL 14:167253f4e170 3089 }
wolfSSL 14:167253f4e170 3090
wolfSSL 14:167253f4e170 3091 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3092 b = d;
wolfSSL 14:167253f4e170 3093 e = b + 36 * 2;
wolfSSL 14:167253f4e170 3094 m = e + 36;
wolfSSL 14:167253f4e170 3095 r = b;
wolfSSL 14:167253f4e170 3096 }
wolfSSL 14:167253f4e170 3097 #else
wolfSSL 14:167253f4e170 3098 r = b = bd;
wolfSSL 14:167253f4e170 3099 e = ed;
wolfSSL 14:167253f4e170 3100 m = md;
wolfSSL 14:167253f4e170 3101 #endif
wolfSSL 14:167253f4e170 3102
wolfSSL 14:167253f4e170 3103 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3104 sp_2048_from_mp(b, 36, base);
wolfSSL 14:167253f4e170 3105 sp_2048_from_mp(e, 36, exp);
wolfSSL 14:167253f4e170 3106 sp_2048_from_mp(m, 36, mod);
wolfSSL 14:167253f4e170 3107
wolfSSL 14:167253f4e170 3108 err = sp_2048_mod_exp_36(r, b, e, expBits, m, 0);
wolfSSL 14:167253f4e170 3109 }
wolfSSL 14:167253f4e170 3110
wolfSSL 14:167253f4e170 3111 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3112 err = sp_2048_to_mp(r, res);
wolfSSL 14:167253f4e170 3113 }
wolfSSL 14:167253f4e170 3114
wolfSSL 14:167253f4e170 3115 XMEMSET(e, 0, sizeof(sp_digit) * 36);
wolfSSL 14:167253f4e170 3116
wolfSSL 14:167253f4e170 3117 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3118 if (d != NULL)
wolfSSL 14:167253f4e170 3119 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3120 #endif
wolfSSL 14:167253f4e170 3121
wolfSSL 14:167253f4e170 3122 return err;
wolfSSL 14:167253f4e170 3123 #endif
wolfSSL 14:167253f4e170 3124 }
wolfSSL 14:167253f4e170 3125
wolfSSL 14:167253f4e170 3126 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 14:167253f4e170 3127 *
wolfSSL 14:167253f4e170 3128 * base Base.
wolfSSL 14:167253f4e170 3129 * exp Array of bytes that is the exponent.
wolfSSL 14:167253f4e170 3130 * expLen Length of data, in bytes, in exponent.
wolfSSL 14:167253f4e170 3131 * mod Modulus.
wolfSSL 14:167253f4e170 3132 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 3133 * Must be at least 256 bytes long.
wolfSSL 14:167253f4e170 3134 * outLen Length, in bytes, of exponentiation result.
wolfSSL 14:167253f4e170 3135 * returs 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 14:167253f4e170 3136 * and MEMORY_E if memory allocation fails.
wolfSSL 14:167253f4e170 3137 */
wolfSSL 14:167253f4e170 3138 int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,
wolfSSL 14:167253f4e170 3139 mp_int* mod, byte* out, word32* outLen)
wolfSSL 14:167253f4e170 3140 {
wolfSSL 14:167253f4e170 3141 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3142 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3143 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3144 sp_digit* b;
wolfSSL 14:167253f4e170 3145 sp_digit* e;
wolfSSL 14:167253f4e170 3146 sp_digit* m;
wolfSSL 14:167253f4e170 3147 sp_digit* r;
wolfSSL 14:167253f4e170 3148 word32 i;
wolfSSL 14:167253f4e170 3149
wolfSSL 14:167253f4e170 3150 if (mp_count_bits(base) > 2048 || expLen > 256 ||
wolfSSL 14:167253f4e170 3151 mp_count_bits(mod) != 2048) {
wolfSSL 14:167253f4e170 3152 err = MP_READ_E;
wolfSSL 14:167253f4e170 3153 }
wolfSSL 14:167253f4e170 3154
wolfSSL 14:167253f4e170 3155 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3156 d = (sp_digit*)XMALLOC(sizeof(*d) * 36 * 4, NULL,
wolfSSL 14:167253f4e170 3157 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3158 if (d == NULL)
wolfSSL 14:167253f4e170 3159 err = MEMORY_E;
wolfSSL 14:167253f4e170 3160 }
wolfSSL 14:167253f4e170 3161
wolfSSL 14:167253f4e170 3162 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3163 b = d;
wolfSSL 14:167253f4e170 3164 e = b + 36 * 2;
wolfSSL 14:167253f4e170 3165 m = e + 36;
wolfSSL 14:167253f4e170 3166 r = b;
wolfSSL 14:167253f4e170 3167
wolfSSL 14:167253f4e170 3168 sp_2048_from_mp(b, 36, base);
wolfSSL 14:167253f4e170 3169 sp_2048_from_bin(e, 36, exp, expLen);
wolfSSL 14:167253f4e170 3170 sp_2048_from_mp(m, 36, mod);
wolfSSL 14:167253f4e170 3171
wolfSSL 14:167253f4e170 3172 err = sp_2048_mod_exp_36(r, b, e, expLen * 8, m, 0);
wolfSSL 14:167253f4e170 3173 }
wolfSSL 14:167253f4e170 3174
wolfSSL 14:167253f4e170 3175 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3176 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3177 *outLen = 256;
wolfSSL 14:167253f4e170 3178 for (i=0; i<256 && out[i] == 0; i++) {
wolfSSL 14:167253f4e170 3179 }
wolfSSL 14:167253f4e170 3180 *outLen -= i;
wolfSSL 14:167253f4e170 3181 XMEMMOVE(out, out + i, *outLen);
wolfSSL 14:167253f4e170 3182 }
wolfSSL 14:167253f4e170 3183
wolfSSL 14:167253f4e170 3184 if (d != NULL) {
wolfSSL 14:167253f4e170 3185 XMEMSET(e, 0, sizeof(sp_digit) * 36);
wolfSSL 14:167253f4e170 3186 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3187 }
wolfSSL 14:167253f4e170 3188 return err;
wolfSSL 14:167253f4e170 3189 #else
wolfSSL 14:167253f4e170 3190 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3191 sp_digit bd[72], ed[36], md[36];
wolfSSL 14:167253f4e170 3192 #else
wolfSSL 14:167253f4e170 3193 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 3194 #endif
wolfSSL 14:167253f4e170 3195 sp_digit* b;
wolfSSL 14:167253f4e170 3196 sp_digit* e;
wolfSSL 14:167253f4e170 3197 sp_digit* m;
wolfSSL 14:167253f4e170 3198 sp_digit* r;
wolfSSL 14:167253f4e170 3199 word32 i;
wolfSSL 14:167253f4e170 3200 int err = MP_OKAY;
wolfSSL 14:167253f4e170 3201
wolfSSL 14:167253f4e170 3202 if (mp_count_bits(base) > 2048 || expLen > 256 ||
wolfSSL 14:167253f4e170 3203 mp_count_bits(mod) != 2048) {
wolfSSL 14:167253f4e170 3204 err = MP_READ_E;
wolfSSL 14:167253f4e170 3205 }
wolfSSL 14:167253f4e170 3206
wolfSSL 14:167253f4e170 3207 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3208 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3209 d = (sp_digit*)XMALLOC(sizeof(*d) * 36 * 4, NULL,
wolfSSL 14:167253f4e170 3210 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3211 if (d == NULL)
wolfSSL 14:167253f4e170 3212 err = MEMORY_E;
wolfSSL 14:167253f4e170 3213 }
wolfSSL 14:167253f4e170 3214
wolfSSL 14:167253f4e170 3215 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3216 b = d;
wolfSSL 14:167253f4e170 3217 e = b + 36 * 2;
wolfSSL 14:167253f4e170 3218 m = e + 36;
wolfSSL 14:167253f4e170 3219 r = b;
wolfSSL 14:167253f4e170 3220 }
wolfSSL 14:167253f4e170 3221 #else
wolfSSL 14:167253f4e170 3222 r = b = bd;
wolfSSL 14:167253f4e170 3223 e = ed;
wolfSSL 14:167253f4e170 3224 m = md;
wolfSSL 14:167253f4e170 3225 #endif
wolfSSL 14:167253f4e170 3226
wolfSSL 14:167253f4e170 3227 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3228 sp_2048_from_mp(b, 36, base);
wolfSSL 14:167253f4e170 3229 sp_2048_from_bin(e, 36, exp, expLen);
wolfSSL 14:167253f4e170 3230 sp_2048_from_mp(m, 36, mod);
wolfSSL 14:167253f4e170 3231
wolfSSL 14:167253f4e170 3232 err = sp_2048_mod_exp_36(r, b, e, expLen * 8, m, 0);
wolfSSL 14:167253f4e170 3233 }
wolfSSL 14:167253f4e170 3234
wolfSSL 14:167253f4e170 3235 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 3236 sp_2048_to_bin(r, out);
wolfSSL 14:167253f4e170 3237 *outLen = 256;
wolfSSL 14:167253f4e170 3238 for (i=0; i<256 && out[i] == 0; i++) {
wolfSSL 14:167253f4e170 3239 }
wolfSSL 14:167253f4e170 3240 *outLen -= i;
wolfSSL 14:167253f4e170 3241 XMEMMOVE(out, out + i, *outLen);
wolfSSL 14:167253f4e170 3242 }
wolfSSL 14:167253f4e170 3243
wolfSSL 14:167253f4e170 3244 XMEMSET(e, 0, sizeof(sp_digit) * 36);
wolfSSL 14:167253f4e170 3245
wolfSSL 14:167253f4e170 3246 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 3247 if (d != NULL)
wolfSSL 14:167253f4e170 3248 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 3249 #endif
wolfSSL 14:167253f4e170 3250
wolfSSL 14:167253f4e170 3251 return err;
wolfSSL 14:167253f4e170 3252 #endif
wolfSSL 14:167253f4e170 3253 }
wolfSSL 14:167253f4e170 3254
wolfSSL 14:167253f4e170 3255 #endif /* WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 3256
wolfSSL 14:167253f4e170 3257 #endif /* WOLFSSL_SP_NO_2048 */
wolfSSL 14:167253f4e170 3258
wolfSSL 14:167253f4e170 3259 #ifndef WOLFSSL_SP_NO_3072
wolfSSL 14:167253f4e170 3260 /* Read big endian unsigned byte aray into r.
wolfSSL 14:167253f4e170 3261 *
wolfSSL 14:167253f4e170 3262 * r A single precision integer.
wolfSSL 14:167253f4e170 3263 * a Byte array.
wolfSSL 14:167253f4e170 3264 * n Number of bytes in array to read.
wolfSSL 14:167253f4e170 3265 */
wolfSSL 14:167253f4e170 3266 static void sp_3072_from_bin(sp_digit* r, int max, const byte* a, int n)
wolfSSL 14:167253f4e170 3267 {
wolfSSL 14:167253f4e170 3268 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 3269
wolfSSL 14:167253f4e170 3270 r[0] = 0;
wolfSSL 14:167253f4e170 3271 for (i = n-1; i >= 0; i--) {
wolfSSL 14:167253f4e170 3272 r[j] |= ((sp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 3273 if (s >= 49) {
wolfSSL 14:167253f4e170 3274 r[j] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3275 s = 57 - s;
wolfSSL 14:167253f4e170 3276 if (j + 1 >= max)
wolfSSL 14:167253f4e170 3277 break;
wolfSSL 14:167253f4e170 3278 r[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 3279 s = 8 - s;
wolfSSL 14:167253f4e170 3280 }
wolfSSL 14:167253f4e170 3281 else
wolfSSL 14:167253f4e170 3282 s += 8;
wolfSSL 14:167253f4e170 3283 }
wolfSSL 14:167253f4e170 3284
wolfSSL 14:167253f4e170 3285 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 3286 r[j] = 0;
wolfSSL 14:167253f4e170 3287 }
wolfSSL 14:167253f4e170 3288
wolfSSL 14:167253f4e170 3289 /* Convert an mp_int to an array of sp_digit.
wolfSSL 14:167253f4e170 3290 *
wolfSSL 14:167253f4e170 3291 * r A single precision integer.
wolfSSL 14:167253f4e170 3292 * a A multi-precision integer.
wolfSSL 14:167253f4e170 3293 */
wolfSSL 14:167253f4e170 3294 static void sp_3072_from_mp(sp_digit* r, int max, mp_int* a)
wolfSSL 14:167253f4e170 3295 {
wolfSSL 14:167253f4e170 3296 #if DIGIT_BIT == 57
wolfSSL 14:167253f4e170 3297 int j;
wolfSSL 14:167253f4e170 3298
wolfSSL 14:167253f4e170 3299 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 14:167253f4e170 3300
wolfSSL 14:167253f4e170 3301 for (j = a->used; j < max; j++)
wolfSSL 14:167253f4e170 3302 r[j] = 0;
wolfSSL 14:167253f4e170 3303 #elif DIGIT_BIT > 57
wolfSSL 14:167253f4e170 3304 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 3305
wolfSSL 14:167253f4e170 3306 r[0] = 0;
wolfSSL 14:167253f4e170 3307 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 3308 r[j] |= a->dp[i] << s;
wolfSSL 14:167253f4e170 3309 r[j] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3310 s = 57 - s;
wolfSSL 14:167253f4e170 3311 if (j + 1 >= max)
wolfSSL 14:167253f4e170 3312 break;
wolfSSL 14:167253f4e170 3313 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 3314 while (s + 57 <= DIGIT_BIT) {
wolfSSL 14:167253f4e170 3315 s += 57;
wolfSSL 14:167253f4e170 3316 r[j] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3317 if (j + 1 >= max)
wolfSSL 14:167253f4e170 3318 break;
wolfSSL 14:167253f4e170 3319 if (s < DIGIT_BIT)
wolfSSL 14:167253f4e170 3320 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 3321 else
wolfSSL 14:167253f4e170 3322 r[++j] = 0;
wolfSSL 14:167253f4e170 3323 }
wolfSSL 14:167253f4e170 3324 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 3325 }
wolfSSL 14:167253f4e170 3326
wolfSSL 14:167253f4e170 3327 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 3328 r[j] = 0;
wolfSSL 14:167253f4e170 3329 #else
wolfSSL 14:167253f4e170 3330 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 3331
wolfSSL 14:167253f4e170 3332 r[0] = 0;
wolfSSL 14:167253f4e170 3333 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 3334 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 14:167253f4e170 3335 if (s + DIGIT_BIT >= 57) {
wolfSSL 14:167253f4e170 3336 r[j] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3337 if (j + 1 >= max)
wolfSSL 14:167253f4e170 3338 break;
wolfSSL 14:167253f4e170 3339 s = 57 - s;
wolfSSL 14:167253f4e170 3340 if (s == DIGIT_BIT) {
wolfSSL 14:167253f4e170 3341 r[++j] = 0;
wolfSSL 14:167253f4e170 3342 s = 0;
wolfSSL 14:167253f4e170 3343 }
wolfSSL 14:167253f4e170 3344 else {
wolfSSL 14:167253f4e170 3345 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 3346 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 3347 }
wolfSSL 14:167253f4e170 3348 }
wolfSSL 14:167253f4e170 3349 else
wolfSSL 14:167253f4e170 3350 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 3351 }
wolfSSL 14:167253f4e170 3352
wolfSSL 14:167253f4e170 3353 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 3354 r[j] = 0;
wolfSSL 14:167253f4e170 3355 #endif
wolfSSL 14:167253f4e170 3356 }
wolfSSL 14:167253f4e170 3357
wolfSSL 14:167253f4e170 3358 /* Write r as big endian to byte aray.
wolfSSL 14:167253f4e170 3359 * Fixed length number of bytes written: 384
wolfSSL 14:167253f4e170 3360 *
wolfSSL 14:167253f4e170 3361 * r A single precision integer.
wolfSSL 14:167253f4e170 3362 * a Byte array.
wolfSSL 14:167253f4e170 3363 */
wolfSSL 14:167253f4e170 3364 static void sp_3072_to_bin(sp_digit* r, byte* a)
wolfSSL 14:167253f4e170 3365 {
wolfSSL 14:167253f4e170 3366 int i, j, s = 0, b;
wolfSSL 14:167253f4e170 3367
wolfSSL 14:167253f4e170 3368 for (i=0; i<53; i++) {
wolfSSL 14:167253f4e170 3369 r[i+1] += r[i] >> 57;
wolfSSL 14:167253f4e170 3370 r[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3371 }
wolfSSL 14:167253f4e170 3372 j = 3072 / 8 - 1;
wolfSSL 14:167253f4e170 3373 a[j] = 0;
wolfSSL 14:167253f4e170 3374 for (i=0; i<54 && j>=0; i++) {
wolfSSL 14:167253f4e170 3375 b = 0;
wolfSSL 14:167253f4e170 3376 a[j--] |= r[i] << s; b += 8 - s;
wolfSSL 14:167253f4e170 3377 if (j < 0)
wolfSSL 14:167253f4e170 3378 break;
wolfSSL 14:167253f4e170 3379 while (b < 57) {
wolfSSL 14:167253f4e170 3380 a[j--] = r[i] >> b; b += 8;
wolfSSL 14:167253f4e170 3381 if (j < 0)
wolfSSL 14:167253f4e170 3382 break;
wolfSSL 14:167253f4e170 3383 }
wolfSSL 14:167253f4e170 3384 s = 8 - (b - 57);
wolfSSL 14:167253f4e170 3385 if (j >= 0)
wolfSSL 14:167253f4e170 3386 a[j] = 0;
wolfSSL 14:167253f4e170 3387 if (s != 0)
wolfSSL 14:167253f4e170 3388 j++;
wolfSSL 14:167253f4e170 3389 }
wolfSSL 14:167253f4e170 3390 }
wolfSSL 14:167253f4e170 3391
wolfSSL 14:167253f4e170 3392 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3393 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 3394 *
wolfSSL 14:167253f4e170 3395 * r A single precision integer.
wolfSSL 14:167253f4e170 3396 * a A single precision integer.
wolfSSL 14:167253f4e170 3397 * b A single precision integer.
wolfSSL 14:167253f4e170 3398 */
wolfSSL 14:167253f4e170 3399 SP_NOINLINE static void sp_3072_mul_9(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3400 const sp_digit* b)
wolfSSL 14:167253f4e170 3401 {
wolfSSL 14:167253f4e170 3402 int128_t t0 = ((int128_t)a[ 0]) * b[ 0];
wolfSSL 14:167253f4e170 3403 int128_t t1 = ((int128_t)a[ 0]) * b[ 1]
wolfSSL 14:167253f4e170 3404 + ((int128_t)a[ 1]) * b[ 0];
wolfSSL 14:167253f4e170 3405 int128_t t2 = ((int128_t)a[ 0]) * b[ 2]
wolfSSL 14:167253f4e170 3406 + ((int128_t)a[ 1]) * b[ 1]
wolfSSL 14:167253f4e170 3407 + ((int128_t)a[ 2]) * b[ 0];
wolfSSL 14:167253f4e170 3408 int128_t t3 = ((int128_t)a[ 0]) * b[ 3]
wolfSSL 14:167253f4e170 3409 + ((int128_t)a[ 1]) * b[ 2]
wolfSSL 14:167253f4e170 3410 + ((int128_t)a[ 2]) * b[ 1]
wolfSSL 14:167253f4e170 3411 + ((int128_t)a[ 3]) * b[ 0];
wolfSSL 14:167253f4e170 3412 int128_t t4 = ((int128_t)a[ 0]) * b[ 4]
wolfSSL 14:167253f4e170 3413 + ((int128_t)a[ 1]) * b[ 3]
wolfSSL 14:167253f4e170 3414 + ((int128_t)a[ 2]) * b[ 2]
wolfSSL 14:167253f4e170 3415 + ((int128_t)a[ 3]) * b[ 1]
wolfSSL 14:167253f4e170 3416 + ((int128_t)a[ 4]) * b[ 0];
wolfSSL 14:167253f4e170 3417 int128_t t5 = ((int128_t)a[ 0]) * b[ 5]
wolfSSL 14:167253f4e170 3418 + ((int128_t)a[ 1]) * b[ 4]
wolfSSL 14:167253f4e170 3419 + ((int128_t)a[ 2]) * b[ 3]
wolfSSL 14:167253f4e170 3420 + ((int128_t)a[ 3]) * b[ 2]
wolfSSL 14:167253f4e170 3421 + ((int128_t)a[ 4]) * b[ 1]
wolfSSL 14:167253f4e170 3422 + ((int128_t)a[ 5]) * b[ 0];
wolfSSL 14:167253f4e170 3423 int128_t t6 = ((int128_t)a[ 0]) * b[ 6]
wolfSSL 14:167253f4e170 3424 + ((int128_t)a[ 1]) * b[ 5]
wolfSSL 14:167253f4e170 3425 + ((int128_t)a[ 2]) * b[ 4]
wolfSSL 14:167253f4e170 3426 + ((int128_t)a[ 3]) * b[ 3]
wolfSSL 14:167253f4e170 3427 + ((int128_t)a[ 4]) * b[ 2]
wolfSSL 14:167253f4e170 3428 + ((int128_t)a[ 5]) * b[ 1]
wolfSSL 14:167253f4e170 3429 + ((int128_t)a[ 6]) * b[ 0];
wolfSSL 14:167253f4e170 3430 int128_t t7 = ((int128_t)a[ 0]) * b[ 7]
wolfSSL 14:167253f4e170 3431 + ((int128_t)a[ 1]) * b[ 6]
wolfSSL 14:167253f4e170 3432 + ((int128_t)a[ 2]) * b[ 5]
wolfSSL 14:167253f4e170 3433 + ((int128_t)a[ 3]) * b[ 4]
wolfSSL 14:167253f4e170 3434 + ((int128_t)a[ 4]) * b[ 3]
wolfSSL 14:167253f4e170 3435 + ((int128_t)a[ 5]) * b[ 2]
wolfSSL 14:167253f4e170 3436 + ((int128_t)a[ 6]) * b[ 1]
wolfSSL 14:167253f4e170 3437 + ((int128_t)a[ 7]) * b[ 0];
wolfSSL 14:167253f4e170 3438 int128_t t8 = ((int128_t)a[ 0]) * b[ 8]
wolfSSL 14:167253f4e170 3439 + ((int128_t)a[ 1]) * b[ 7]
wolfSSL 14:167253f4e170 3440 + ((int128_t)a[ 2]) * b[ 6]
wolfSSL 14:167253f4e170 3441 + ((int128_t)a[ 3]) * b[ 5]
wolfSSL 14:167253f4e170 3442 + ((int128_t)a[ 4]) * b[ 4]
wolfSSL 14:167253f4e170 3443 + ((int128_t)a[ 5]) * b[ 3]
wolfSSL 14:167253f4e170 3444 + ((int128_t)a[ 6]) * b[ 2]
wolfSSL 14:167253f4e170 3445 + ((int128_t)a[ 7]) * b[ 1]
wolfSSL 14:167253f4e170 3446 + ((int128_t)a[ 8]) * b[ 0];
wolfSSL 14:167253f4e170 3447 int128_t t9 = ((int128_t)a[ 1]) * b[ 8]
wolfSSL 14:167253f4e170 3448 + ((int128_t)a[ 2]) * b[ 7]
wolfSSL 14:167253f4e170 3449 + ((int128_t)a[ 3]) * b[ 6]
wolfSSL 14:167253f4e170 3450 + ((int128_t)a[ 4]) * b[ 5]
wolfSSL 14:167253f4e170 3451 + ((int128_t)a[ 5]) * b[ 4]
wolfSSL 14:167253f4e170 3452 + ((int128_t)a[ 6]) * b[ 3]
wolfSSL 14:167253f4e170 3453 + ((int128_t)a[ 7]) * b[ 2]
wolfSSL 14:167253f4e170 3454 + ((int128_t)a[ 8]) * b[ 1];
wolfSSL 14:167253f4e170 3455 int128_t t10 = ((int128_t)a[ 2]) * b[ 8]
wolfSSL 14:167253f4e170 3456 + ((int128_t)a[ 3]) * b[ 7]
wolfSSL 14:167253f4e170 3457 + ((int128_t)a[ 4]) * b[ 6]
wolfSSL 14:167253f4e170 3458 + ((int128_t)a[ 5]) * b[ 5]
wolfSSL 14:167253f4e170 3459 + ((int128_t)a[ 6]) * b[ 4]
wolfSSL 14:167253f4e170 3460 + ((int128_t)a[ 7]) * b[ 3]
wolfSSL 14:167253f4e170 3461 + ((int128_t)a[ 8]) * b[ 2];
wolfSSL 14:167253f4e170 3462 int128_t t11 = ((int128_t)a[ 3]) * b[ 8]
wolfSSL 14:167253f4e170 3463 + ((int128_t)a[ 4]) * b[ 7]
wolfSSL 14:167253f4e170 3464 + ((int128_t)a[ 5]) * b[ 6]
wolfSSL 14:167253f4e170 3465 + ((int128_t)a[ 6]) * b[ 5]
wolfSSL 14:167253f4e170 3466 + ((int128_t)a[ 7]) * b[ 4]
wolfSSL 14:167253f4e170 3467 + ((int128_t)a[ 8]) * b[ 3];
wolfSSL 14:167253f4e170 3468 int128_t t12 = ((int128_t)a[ 4]) * b[ 8]
wolfSSL 14:167253f4e170 3469 + ((int128_t)a[ 5]) * b[ 7]
wolfSSL 14:167253f4e170 3470 + ((int128_t)a[ 6]) * b[ 6]
wolfSSL 14:167253f4e170 3471 + ((int128_t)a[ 7]) * b[ 5]
wolfSSL 14:167253f4e170 3472 + ((int128_t)a[ 8]) * b[ 4];
wolfSSL 14:167253f4e170 3473 int128_t t13 = ((int128_t)a[ 5]) * b[ 8]
wolfSSL 14:167253f4e170 3474 + ((int128_t)a[ 6]) * b[ 7]
wolfSSL 14:167253f4e170 3475 + ((int128_t)a[ 7]) * b[ 6]
wolfSSL 14:167253f4e170 3476 + ((int128_t)a[ 8]) * b[ 5];
wolfSSL 14:167253f4e170 3477 int128_t t14 = ((int128_t)a[ 6]) * b[ 8]
wolfSSL 14:167253f4e170 3478 + ((int128_t)a[ 7]) * b[ 7]
wolfSSL 14:167253f4e170 3479 + ((int128_t)a[ 8]) * b[ 6];
wolfSSL 14:167253f4e170 3480 int128_t t15 = ((int128_t)a[ 7]) * b[ 8]
wolfSSL 14:167253f4e170 3481 + ((int128_t)a[ 8]) * b[ 7];
wolfSSL 14:167253f4e170 3482 int128_t t16 = ((int128_t)a[ 8]) * b[ 8];
wolfSSL 14:167253f4e170 3483
wolfSSL 14:167253f4e170 3484 t1 += t0 >> 57; r[ 0] = t0 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3485 t2 += t1 >> 57; r[ 1] = t1 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3486 t3 += t2 >> 57; r[ 2] = t2 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3487 t4 += t3 >> 57; r[ 3] = t3 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3488 t5 += t4 >> 57; r[ 4] = t4 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3489 t6 += t5 >> 57; r[ 5] = t5 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3490 t7 += t6 >> 57; r[ 6] = t6 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3491 t8 += t7 >> 57; r[ 7] = t7 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3492 t9 += t8 >> 57; r[ 8] = t8 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3493 t10 += t9 >> 57; r[ 9] = t9 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3494 t11 += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3495 t12 += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3496 t13 += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3497 t14 += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3498 t15 += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3499 t16 += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3500 r[17] = (sp_digit)(t16 >> 57);
wolfSSL 14:167253f4e170 3501 r[16] = t16 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3502 }
wolfSSL 14:167253f4e170 3503
wolfSSL 14:167253f4e170 3504 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 3505 *
wolfSSL 14:167253f4e170 3506 * r A single precision integer.
wolfSSL 14:167253f4e170 3507 * a A single precision integer.
wolfSSL 14:167253f4e170 3508 */
wolfSSL 14:167253f4e170 3509 SP_NOINLINE static void sp_3072_sqr_9(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 3510 {
wolfSSL 14:167253f4e170 3511 int128_t t0 = ((int128_t)a[ 0]) * a[ 0];
wolfSSL 14:167253f4e170 3512 int128_t t1 = (((int128_t)a[ 0]) * a[ 1]) * 2;
wolfSSL 14:167253f4e170 3513 int128_t t2 = (((int128_t)a[ 0]) * a[ 2]) * 2
wolfSSL 14:167253f4e170 3514 + ((int128_t)a[ 1]) * a[ 1];
wolfSSL 14:167253f4e170 3515 int128_t t3 = (((int128_t)a[ 0]) * a[ 3]
wolfSSL 14:167253f4e170 3516 + ((int128_t)a[ 1]) * a[ 2]) * 2;
wolfSSL 14:167253f4e170 3517 int128_t t4 = (((int128_t)a[ 0]) * a[ 4]
wolfSSL 14:167253f4e170 3518 + ((int128_t)a[ 1]) * a[ 3]) * 2
wolfSSL 14:167253f4e170 3519 + ((int128_t)a[ 2]) * a[ 2];
wolfSSL 14:167253f4e170 3520 int128_t t5 = (((int128_t)a[ 0]) * a[ 5]
wolfSSL 14:167253f4e170 3521 + ((int128_t)a[ 1]) * a[ 4]
wolfSSL 14:167253f4e170 3522 + ((int128_t)a[ 2]) * a[ 3]) * 2;
wolfSSL 14:167253f4e170 3523 int128_t t6 = (((int128_t)a[ 0]) * a[ 6]
wolfSSL 14:167253f4e170 3524 + ((int128_t)a[ 1]) * a[ 5]
wolfSSL 14:167253f4e170 3525 + ((int128_t)a[ 2]) * a[ 4]) * 2
wolfSSL 14:167253f4e170 3526 + ((int128_t)a[ 3]) * a[ 3];
wolfSSL 14:167253f4e170 3527 int128_t t7 = (((int128_t)a[ 0]) * a[ 7]
wolfSSL 14:167253f4e170 3528 + ((int128_t)a[ 1]) * a[ 6]
wolfSSL 14:167253f4e170 3529 + ((int128_t)a[ 2]) * a[ 5]
wolfSSL 14:167253f4e170 3530 + ((int128_t)a[ 3]) * a[ 4]) * 2;
wolfSSL 14:167253f4e170 3531 int128_t t8 = (((int128_t)a[ 0]) * a[ 8]
wolfSSL 14:167253f4e170 3532 + ((int128_t)a[ 1]) * a[ 7]
wolfSSL 14:167253f4e170 3533 + ((int128_t)a[ 2]) * a[ 6]
wolfSSL 14:167253f4e170 3534 + ((int128_t)a[ 3]) * a[ 5]) * 2
wolfSSL 14:167253f4e170 3535 + ((int128_t)a[ 4]) * a[ 4];
wolfSSL 14:167253f4e170 3536 int128_t t9 = (((int128_t)a[ 1]) * a[ 8]
wolfSSL 14:167253f4e170 3537 + ((int128_t)a[ 2]) * a[ 7]
wolfSSL 14:167253f4e170 3538 + ((int128_t)a[ 3]) * a[ 6]
wolfSSL 14:167253f4e170 3539 + ((int128_t)a[ 4]) * a[ 5]) * 2;
wolfSSL 14:167253f4e170 3540 int128_t t10 = (((int128_t)a[ 2]) * a[ 8]
wolfSSL 14:167253f4e170 3541 + ((int128_t)a[ 3]) * a[ 7]
wolfSSL 14:167253f4e170 3542 + ((int128_t)a[ 4]) * a[ 6]) * 2
wolfSSL 14:167253f4e170 3543 + ((int128_t)a[ 5]) * a[ 5];
wolfSSL 14:167253f4e170 3544 int128_t t11 = (((int128_t)a[ 3]) * a[ 8]
wolfSSL 14:167253f4e170 3545 + ((int128_t)a[ 4]) * a[ 7]
wolfSSL 14:167253f4e170 3546 + ((int128_t)a[ 5]) * a[ 6]) * 2;
wolfSSL 14:167253f4e170 3547 int128_t t12 = (((int128_t)a[ 4]) * a[ 8]
wolfSSL 14:167253f4e170 3548 + ((int128_t)a[ 5]) * a[ 7]) * 2
wolfSSL 14:167253f4e170 3549 + ((int128_t)a[ 6]) * a[ 6];
wolfSSL 14:167253f4e170 3550 int128_t t13 = (((int128_t)a[ 5]) * a[ 8]
wolfSSL 14:167253f4e170 3551 + ((int128_t)a[ 6]) * a[ 7]) * 2;
wolfSSL 14:167253f4e170 3552 int128_t t14 = (((int128_t)a[ 6]) * a[ 8]) * 2
wolfSSL 14:167253f4e170 3553 + ((int128_t)a[ 7]) * a[ 7];
wolfSSL 14:167253f4e170 3554 int128_t t15 = (((int128_t)a[ 7]) * a[ 8]) * 2;
wolfSSL 14:167253f4e170 3555 int128_t t16 = ((int128_t)a[ 8]) * a[ 8];
wolfSSL 14:167253f4e170 3556
wolfSSL 14:167253f4e170 3557 t1 += t0 >> 57; r[ 0] = t0 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3558 t2 += t1 >> 57; r[ 1] = t1 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3559 t3 += t2 >> 57; r[ 2] = t2 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3560 t4 += t3 >> 57; r[ 3] = t3 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3561 t5 += t4 >> 57; r[ 4] = t4 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3562 t6 += t5 >> 57; r[ 5] = t5 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3563 t7 += t6 >> 57; r[ 6] = t6 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3564 t8 += t7 >> 57; r[ 7] = t7 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3565 t9 += t8 >> 57; r[ 8] = t8 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3566 t10 += t9 >> 57; r[ 9] = t9 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3567 t11 += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3568 t12 += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3569 t13 += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3570 t14 += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3571 t15 += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3572 t16 += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3573 r[17] = (sp_digit)(t16 >> 57);
wolfSSL 14:167253f4e170 3574 r[16] = t16 & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3575 }
wolfSSL 14:167253f4e170 3576
wolfSSL 14:167253f4e170 3577 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 3578 *
wolfSSL 14:167253f4e170 3579 * r A single precision integer.
wolfSSL 14:167253f4e170 3580 * a A single precision integer.
wolfSSL 14:167253f4e170 3581 * b A single precision integer.
wolfSSL 14:167253f4e170 3582 */
wolfSSL 14:167253f4e170 3583 SP_NOINLINE static int sp_3072_add_9(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3584 const sp_digit* b)
wolfSSL 14:167253f4e170 3585 {
wolfSSL 14:167253f4e170 3586 r[ 0] = a[ 0] + b[ 0];
wolfSSL 14:167253f4e170 3587 r[ 1] = a[ 1] + b[ 1];
wolfSSL 14:167253f4e170 3588 r[ 2] = a[ 2] + b[ 2];
wolfSSL 14:167253f4e170 3589 r[ 3] = a[ 3] + b[ 3];
wolfSSL 14:167253f4e170 3590 r[ 4] = a[ 4] + b[ 4];
wolfSSL 14:167253f4e170 3591 r[ 5] = a[ 5] + b[ 5];
wolfSSL 14:167253f4e170 3592 r[ 6] = a[ 6] + b[ 6];
wolfSSL 14:167253f4e170 3593 r[ 7] = a[ 7] + b[ 7];
wolfSSL 14:167253f4e170 3594 r[ 8] = a[ 8] + b[ 8];
wolfSSL 14:167253f4e170 3595
wolfSSL 14:167253f4e170 3596 return 0;
wolfSSL 14:167253f4e170 3597 }
wolfSSL 14:167253f4e170 3598
wolfSSL 14:167253f4e170 3599 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 3600 *
wolfSSL 14:167253f4e170 3601 * r A single precision integer.
wolfSSL 14:167253f4e170 3602 * a A single precision integer.
wolfSSL 14:167253f4e170 3603 * b A single precision integer.
wolfSSL 14:167253f4e170 3604 */
wolfSSL 14:167253f4e170 3605 SP_NOINLINE static int sp_3072_add_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3606 const sp_digit* b)
wolfSSL 14:167253f4e170 3607 {
wolfSSL 14:167253f4e170 3608 int i;
wolfSSL 14:167253f4e170 3609
wolfSSL 14:167253f4e170 3610 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 3611 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 3612 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 3613 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 3614 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 3615 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 3616 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 3617 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 3618 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 3619 }
wolfSSL 14:167253f4e170 3620 r[16] = a[16] + b[16];
wolfSSL 14:167253f4e170 3621 r[17] = a[17] + b[17];
wolfSSL 14:167253f4e170 3622
wolfSSL 14:167253f4e170 3623 return 0;
wolfSSL 14:167253f4e170 3624 }
wolfSSL 14:167253f4e170 3625
wolfSSL 14:167253f4e170 3626 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 3627 *
wolfSSL 14:167253f4e170 3628 * r A single precision integer.
wolfSSL 14:167253f4e170 3629 * a A single precision integer.
wolfSSL 14:167253f4e170 3630 * b A single precision integer.
wolfSSL 14:167253f4e170 3631 */
wolfSSL 14:167253f4e170 3632 SP_NOINLINE static int sp_3072_sub_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3633 const sp_digit* b)
wolfSSL 14:167253f4e170 3634 {
wolfSSL 14:167253f4e170 3635 int i;
wolfSSL 14:167253f4e170 3636
wolfSSL 14:167253f4e170 3637 for (i = 0; i < 16; i += 8) {
wolfSSL 14:167253f4e170 3638 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 3639 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 3640 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 3641 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 3642 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 3643 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 3644 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 3645 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 3646 }
wolfSSL 14:167253f4e170 3647 r[16] = a[16] - b[16];
wolfSSL 14:167253f4e170 3648 r[17] = a[17] - b[17];
wolfSSL 14:167253f4e170 3649
wolfSSL 14:167253f4e170 3650 return 0;
wolfSSL 14:167253f4e170 3651 }
wolfSSL 14:167253f4e170 3652
wolfSSL 14:167253f4e170 3653 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 3654 *
wolfSSL 14:167253f4e170 3655 * r A single precision integer.
wolfSSL 14:167253f4e170 3656 * a A single precision integer.
wolfSSL 14:167253f4e170 3657 * b A single precision integer.
wolfSSL 14:167253f4e170 3658 */
wolfSSL 14:167253f4e170 3659 SP_NOINLINE static void sp_3072_mul_18(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3660 const sp_digit* b)
wolfSSL 14:167253f4e170 3661 {
wolfSSL 14:167253f4e170 3662 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 3663 sp_digit z1[18];
wolfSSL 14:167253f4e170 3664 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 3665 sp_digit b1[9];
wolfSSL 14:167253f4e170 3666 sp_digit* z2 = r + 18;
wolfSSL 14:167253f4e170 3667 sp_3072_add_9(a1, a, &a[9]);
wolfSSL 14:167253f4e170 3668 sp_3072_add_9(b1, b, &b[9]);
wolfSSL 14:167253f4e170 3669 sp_3072_mul_9(z2, &a[9], &b[9]);
wolfSSL 14:167253f4e170 3670 sp_3072_mul_9(z0, a, b);
wolfSSL 14:167253f4e170 3671 sp_3072_mul_9(z1, a1, b1);
wolfSSL 14:167253f4e170 3672 sp_3072_sub_18(z1, z1, z2);
wolfSSL 14:167253f4e170 3673 sp_3072_sub_18(z1, z1, z0);
wolfSSL 14:167253f4e170 3674 sp_3072_add_18(r + 9, r + 9, z1);
wolfSSL 14:167253f4e170 3675 }
wolfSSL 14:167253f4e170 3676
wolfSSL 14:167253f4e170 3677 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 3678 *
wolfSSL 14:167253f4e170 3679 * r A single precision integer.
wolfSSL 14:167253f4e170 3680 * a A single precision integer.
wolfSSL 14:167253f4e170 3681 */
wolfSSL 14:167253f4e170 3682 SP_NOINLINE static void sp_3072_sqr_18(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 3683 {
wolfSSL 14:167253f4e170 3684 sp_digit* z0 = r;
wolfSSL 14:167253f4e170 3685 sp_digit z1[18];
wolfSSL 14:167253f4e170 3686 sp_digit* a1 = z1;
wolfSSL 14:167253f4e170 3687 sp_digit* z2 = r + 18;
wolfSSL 14:167253f4e170 3688 sp_3072_add_9(a1, a, &a[9]);
wolfSSL 14:167253f4e170 3689 sp_3072_sqr_9(z2, &a[9]);
wolfSSL 14:167253f4e170 3690 sp_3072_sqr_9(z0, a);
wolfSSL 14:167253f4e170 3691 sp_3072_sqr_9(z1, a1);
wolfSSL 14:167253f4e170 3692 sp_3072_sub_18(z1, z1, z2);
wolfSSL 14:167253f4e170 3693 sp_3072_sub_18(z1, z1, z0);
wolfSSL 14:167253f4e170 3694 sp_3072_add_18(r + 9, r + 9, z1);
wolfSSL 14:167253f4e170 3695 }
wolfSSL 14:167253f4e170 3696
wolfSSL 14:167253f4e170 3697 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 3698 *
wolfSSL 14:167253f4e170 3699 * r A single precision integer.
wolfSSL 14:167253f4e170 3700 * a A single precision integer.
wolfSSL 14:167253f4e170 3701 * b A single precision integer.
wolfSSL 14:167253f4e170 3702 */
wolfSSL 14:167253f4e170 3703 SP_NOINLINE static int sp_3072_sub_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3704 const sp_digit* b)
wolfSSL 14:167253f4e170 3705 {
wolfSSL 14:167253f4e170 3706 int i;
wolfSSL 14:167253f4e170 3707
wolfSSL 14:167253f4e170 3708 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 3709 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 3710 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 3711 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 3712 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 3713 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 3714 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 3715 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 3716 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 3717 }
wolfSSL 14:167253f4e170 3718 r[32] = a[32] - b[32];
wolfSSL 14:167253f4e170 3719 r[33] = a[33] - b[33];
wolfSSL 14:167253f4e170 3720 r[34] = a[34] - b[34];
wolfSSL 14:167253f4e170 3721 r[35] = a[35] - b[35];
wolfSSL 14:167253f4e170 3722
wolfSSL 14:167253f4e170 3723 return 0;
wolfSSL 14:167253f4e170 3724 }
wolfSSL 14:167253f4e170 3725
wolfSSL 14:167253f4e170 3726 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 3727 *
wolfSSL 14:167253f4e170 3728 * r A single precision integer.
wolfSSL 14:167253f4e170 3729 * a A single precision integer.
wolfSSL 14:167253f4e170 3730 * b A single precision integer.
wolfSSL 14:167253f4e170 3731 */
wolfSSL 14:167253f4e170 3732 SP_NOINLINE static int sp_3072_add_36(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3733 const sp_digit* b)
wolfSSL 14:167253f4e170 3734 {
wolfSSL 14:167253f4e170 3735 int i;
wolfSSL 14:167253f4e170 3736
wolfSSL 14:167253f4e170 3737 for (i = 0; i < 32; i += 8) {
wolfSSL 14:167253f4e170 3738 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 3739 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 3740 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 3741 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 3742 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 3743 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 3744 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 3745 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 3746 }
wolfSSL 14:167253f4e170 3747 r[32] = a[32] + b[32];
wolfSSL 14:167253f4e170 3748 r[33] = a[33] + b[33];
wolfSSL 14:167253f4e170 3749 r[34] = a[34] + b[34];
wolfSSL 14:167253f4e170 3750 r[35] = a[35] + b[35];
wolfSSL 14:167253f4e170 3751
wolfSSL 14:167253f4e170 3752 return 0;
wolfSSL 14:167253f4e170 3753 }
wolfSSL 14:167253f4e170 3754
wolfSSL 14:167253f4e170 3755 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 3756 *
wolfSSL 14:167253f4e170 3757 * r A single precision integer.
wolfSSL 14:167253f4e170 3758 * a A single precision integer.
wolfSSL 14:167253f4e170 3759 * b A single precision integer.
wolfSSL 14:167253f4e170 3760 */
wolfSSL 14:167253f4e170 3761 SP_NOINLINE static void sp_3072_mul_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3762 const sp_digit* b)
wolfSSL 14:167253f4e170 3763 {
wolfSSL 14:167253f4e170 3764 sp_digit p0[36];
wolfSSL 14:167253f4e170 3765 sp_digit p1[36];
wolfSSL 14:167253f4e170 3766 sp_digit p2[36];
wolfSSL 14:167253f4e170 3767 sp_digit p3[36];
wolfSSL 14:167253f4e170 3768 sp_digit p4[36];
wolfSSL 14:167253f4e170 3769 sp_digit p5[36];
wolfSSL 14:167253f4e170 3770 sp_digit t0[36];
wolfSSL 14:167253f4e170 3771 sp_digit t1[36];
wolfSSL 14:167253f4e170 3772 sp_digit t2[36];
wolfSSL 14:167253f4e170 3773 sp_digit a0[18];
wolfSSL 14:167253f4e170 3774 sp_digit a1[18];
wolfSSL 14:167253f4e170 3775 sp_digit a2[18];
wolfSSL 14:167253f4e170 3776 sp_digit b0[18];
wolfSSL 14:167253f4e170 3777 sp_digit b1[18];
wolfSSL 14:167253f4e170 3778 sp_digit b2[18];
wolfSSL 14:167253f4e170 3779 sp_3072_add_18(a0, a, &a[18]);
wolfSSL 14:167253f4e170 3780 sp_3072_add_18(b0, b, &b[18]);
wolfSSL 14:167253f4e170 3781 sp_3072_add_18(a1, &a[18], &a[36]);
wolfSSL 14:167253f4e170 3782 sp_3072_add_18(b1, &b[18], &b[36]);
wolfSSL 14:167253f4e170 3783 sp_3072_add_18(a2, a0, &a[36]);
wolfSSL 14:167253f4e170 3784 sp_3072_add_18(b2, b0, &b[36]);
wolfSSL 14:167253f4e170 3785 sp_3072_mul_18(p0, a, b);
wolfSSL 14:167253f4e170 3786 sp_3072_mul_18(p2, &a[18], &b[18]);
wolfSSL 14:167253f4e170 3787 sp_3072_mul_18(p4, &a[36], &b[36]);
wolfSSL 14:167253f4e170 3788 sp_3072_mul_18(p1, a0, b0);
wolfSSL 14:167253f4e170 3789 sp_3072_mul_18(p3, a1, b1);
wolfSSL 14:167253f4e170 3790 sp_3072_mul_18(p5, a2, b2);
wolfSSL 14:167253f4e170 3791 XMEMSET(r, 0, sizeof(*r)*2*54);
wolfSSL 14:167253f4e170 3792 sp_3072_sub_36(t0, p3, p2);
wolfSSL 14:167253f4e170 3793 sp_3072_sub_36(t1, p1, p2);
wolfSSL 14:167253f4e170 3794 sp_3072_sub_36(t2, p5, t0);
wolfSSL 14:167253f4e170 3795 sp_3072_sub_36(t2, t2, t1);
wolfSSL 14:167253f4e170 3796 sp_3072_sub_36(t0, t0, p4);
wolfSSL 14:167253f4e170 3797 sp_3072_sub_36(t1, t1, p0);
wolfSSL 14:167253f4e170 3798 sp_3072_add_36(r, r, p0);
wolfSSL 14:167253f4e170 3799 sp_3072_add_36(&r[18], &r[18], t1);
wolfSSL 14:167253f4e170 3800 sp_3072_add_36(&r[36], &r[36], t2);
wolfSSL 14:167253f4e170 3801 sp_3072_add_36(&r[54], &r[54], t0);
wolfSSL 14:167253f4e170 3802 sp_3072_add_36(&r[72], &r[72], p4);
wolfSSL 14:167253f4e170 3803 }
wolfSSL 14:167253f4e170 3804
wolfSSL 14:167253f4e170 3805 /* Square a into r. (r = a * a)
wolfSSL 14:167253f4e170 3806 *
wolfSSL 14:167253f4e170 3807 * r A single precision integer.
wolfSSL 14:167253f4e170 3808 * a A single precision integer.
wolfSSL 14:167253f4e170 3809 */
wolfSSL 14:167253f4e170 3810 SP_NOINLINE static void sp_3072_sqr_54(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 3811 {
wolfSSL 14:167253f4e170 3812 sp_digit p0[36];
wolfSSL 14:167253f4e170 3813 sp_digit p1[36];
wolfSSL 14:167253f4e170 3814 sp_digit p2[36];
wolfSSL 14:167253f4e170 3815 sp_digit p3[36];
wolfSSL 14:167253f4e170 3816 sp_digit p4[36];
wolfSSL 14:167253f4e170 3817 sp_digit p5[36];
wolfSSL 14:167253f4e170 3818 sp_digit t0[36];
wolfSSL 14:167253f4e170 3819 sp_digit t1[36];
wolfSSL 14:167253f4e170 3820 sp_digit t2[36];
wolfSSL 14:167253f4e170 3821 sp_digit a0[18];
wolfSSL 14:167253f4e170 3822 sp_digit a1[18];
wolfSSL 14:167253f4e170 3823 sp_digit a2[18];
wolfSSL 14:167253f4e170 3824 sp_3072_add_18(a0, a, &a[18]);
wolfSSL 14:167253f4e170 3825 sp_3072_add_18(a1, &a[18], &a[36]);
wolfSSL 14:167253f4e170 3826 sp_3072_add_18(a2, a0, &a[36]);
wolfSSL 14:167253f4e170 3827 sp_3072_sqr_18(p0, a);
wolfSSL 14:167253f4e170 3828 sp_3072_sqr_18(p2, &a[18]);
wolfSSL 14:167253f4e170 3829 sp_3072_sqr_18(p4, &a[36]);
wolfSSL 14:167253f4e170 3830 sp_3072_sqr_18(p1, a0);
wolfSSL 14:167253f4e170 3831 sp_3072_sqr_18(p3, a1);
wolfSSL 14:167253f4e170 3832 sp_3072_sqr_18(p5, a2);
wolfSSL 14:167253f4e170 3833 XMEMSET(r, 0, sizeof(*r)*2*54);
wolfSSL 14:167253f4e170 3834 sp_3072_sub_36(t0, p3, p2);
wolfSSL 14:167253f4e170 3835 sp_3072_sub_36(t1, p1, p2);
wolfSSL 14:167253f4e170 3836 sp_3072_sub_36(t2, p5, t0);
wolfSSL 14:167253f4e170 3837 sp_3072_sub_36(t2, t2, t1);
wolfSSL 14:167253f4e170 3838 sp_3072_sub_36(t0, t0, p4);
wolfSSL 14:167253f4e170 3839 sp_3072_sub_36(t1, t1, p0);
wolfSSL 14:167253f4e170 3840 sp_3072_add_36(r, r, p0);
wolfSSL 14:167253f4e170 3841 sp_3072_add_36(&r[18], &r[18], t1);
wolfSSL 14:167253f4e170 3842 sp_3072_add_36(&r[36], &r[36], t2);
wolfSSL 14:167253f4e170 3843 sp_3072_add_36(&r[54], &r[54], t0);
wolfSSL 14:167253f4e170 3844 sp_3072_add_36(&r[72], &r[72], p4);
wolfSSL 14:167253f4e170 3845 }
wolfSSL 14:167253f4e170 3846
wolfSSL 14:167253f4e170 3847 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 3848 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3849 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 3850 *
wolfSSL 14:167253f4e170 3851 * r A single precision integer.
wolfSSL 14:167253f4e170 3852 * a A single precision integer.
wolfSSL 14:167253f4e170 3853 * b A single precision integer.
wolfSSL 14:167253f4e170 3854 */
wolfSSL 14:167253f4e170 3855 SP_NOINLINE static int sp_3072_add_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3856 const sp_digit* b)
wolfSSL 14:167253f4e170 3857 {
wolfSSL 14:167253f4e170 3858 int i;
wolfSSL 14:167253f4e170 3859
wolfSSL 14:167253f4e170 3860 for (i = 0; i < 54; i++)
wolfSSL 14:167253f4e170 3861 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 3862
wolfSSL 14:167253f4e170 3863 return 0;
wolfSSL 14:167253f4e170 3864 }
wolfSSL 14:167253f4e170 3865 #else
wolfSSL 14:167253f4e170 3866 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 3867 *
wolfSSL 14:167253f4e170 3868 * r A single precision integer.
wolfSSL 14:167253f4e170 3869 * a A single precision integer.
wolfSSL 14:167253f4e170 3870 * b A single precision integer.
wolfSSL 14:167253f4e170 3871 */
wolfSSL 14:167253f4e170 3872 SP_NOINLINE static int sp_3072_add_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3873 const sp_digit* b)
wolfSSL 14:167253f4e170 3874 {
wolfSSL 14:167253f4e170 3875 int i;
wolfSSL 14:167253f4e170 3876
wolfSSL 14:167253f4e170 3877 for (i = 0; i < 48; i += 8) {
wolfSSL 14:167253f4e170 3878 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 3879 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 3880 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 3881 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 3882 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 3883 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 3884 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 3885 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 3886 }
wolfSSL 14:167253f4e170 3887 r[48] = a[48] + b[48];
wolfSSL 14:167253f4e170 3888 r[49] = a[49] + b[49];
wolfSSL 14:167253f4e170 3889 r[50] = a[50] + b[50];
wolfSSL 14:167253f4e170 3890 r[51] = a[51] + b[51];
wolfSSL 14:167253f4e170 3891 r[52] = a[52] + b[52];
wolfSSL 14:167253f4e170 3892 r[53] = a[53] + b[53];
wolfSSL 14:167253f4e170 3893
wolfSSL 14:167253f4e170 3894 return 0;
wolfSSL 14:167253f4e170 3895 }
wolfSSL 14:167253f4e170 3896
wolfSSL 14:167253f4e170 3897 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 3898 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3899 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 3900 *
wolfSSL 14:167253f4e170 3901 * r A single precision integer.
wolfSSL 14:167253f4e170 3902 * a A single precision integer.
wolfSSL 14:167253f4e170 3903 * b A single precision integer.
wolfSSL 14:167253f4e170 3904 */
wolfSSL 14:167253f4e170 3905 SP_NOINLINE static int sp_3072_sub_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3906 const sp_digit* b)
wolfSSL 14:167253f4e170 3907 {
wolfSSL 14:167253f4e170 3908 int i;
wolfSSL 14:167253f4e170 3909
wolfSSL 14:167253f4e170 3910 for (i = 0; i < 54; i++)
wolfSSL 14:167253f4e170 3911 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 3912
wolfSSL 14:167253f4e170 3913 return 0;
wolfSSL 14:167253f4e170 3914 }
wolfSSL 14:167253f4e170 3915
wolfSSL 14:167253f4e170 3916 #else
wolfSSL 14:167253f4e170 3917 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 3918 *
wolfSSL 14:167253f4e170 3919 * r A single precision integer.
wolfSSL 14:167253f4e170 3920 * a A single precision integer.
wolfSSL 14:167253f4e170 3921 * b A single precision integer.
wolfSSL 14:167253f4e170 3922 */
wolfSSL 14:167253f4e170 3923 SP_NOINLINE static int sp_3072_sub_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3924 const sp_digit* b)
wolfSSL 14:167253f4e170 3925 {
wolfSSL 14:167253f4e170 3926 int i;
wolfSSL 14:167253f4e170 3927
wolfSSL 14:167253f4e170 3928 for (i = 0; i < 48; i += 8) {
wolfSSL 14:167253f4e170 3929 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 3930 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 3931 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 3932 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 3933 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 3934 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 3935 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 3936 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 3937 }
wolfSSL 14:167253f4e170 3938 r[48] = a[48] - b[48];
wolfSSL 14:167253f4e170 3939 r[49] = a[49] - b[49];
wolfSSL 14:167253f4e170 3940 r[50] = a[50] - b[50];
wolfSSL 14:167253f4e170 3941 r[51] = a[51] - b[51];
wolfSSL 14:167253f4e170 3942 r[52] = a[52] - b[52];
wolfSSL 14:167253f4e170 3943 r[53] = a[53] - b[53];
wolfSSL 14:167253f4e170 3944
wolfSSL 14:167253f4e170 3945 return 0;
wolfSSL 14:167253f4e170 3946 }
wolfSSL 14:167253f4e170 3947
wolfSSL 14:167253f4e170 3948 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 3949 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 3950 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 3951 *
wolfSSL 14:167253f4e170 3952 * r A single precision integer.
wolfSSL 14:167253f4e170 3953 * a A single precision integer.
wolfSSL 14:167253f4e170 3954 * b A single precision integer.
wolfSSL 14:167253f4e170 3955 */
wolfSSL 14:167253f4e170 3956 SP_NOINLINE static void sp_3072_mul_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 3957 const sp_digit* b)
wolfSSL 14:167253f4e170 3958 {
wolfSSL 14:167253f4e170 3959 int i, j, k;
wolfSSL 14:167253f4e170 3960 int128_t c;
wolfSSL 14:167253f4e170 3961
wolfSSL 14:167253f4e170 3962 c = ((int128_t)a[53]) * b[53];
wolfSSL 14:167253f4e170 3963 r[107] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 3964 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 3965 for (k = 105; k >= 0; k--) {
wolfSSL 14:167253f4e170 3966 for (i = 53; i >= 0; i--) {
wolfSSL 14:167253f4e170 3967 j = k - i;
wolfSSL 14:167253f4e170 3968 if (j >= 54)
wolfSSL 14:167253f4e170 3969 break;
wolfSSL 14:167253f4e170 3970 if (j < 0)
wolfSSL 14:167253f4e170 3971 continue;
wolfSSL 14:167253f4e170 3972
wolfSSL 14:167253f4e170 3973 c += ((int128_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 3974 }
wolfSSL 14:167253f4e170 3975 r[k + 2] += c >> 114;
wolfSSL 14:167253f4e170 3976 r[k + 1] = (c >> 57) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 3977 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 3978 }
wolfSSL 14:167253f4e170 3979 r[0] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 3980 }
wolfSSL 14:167253f4e170 3981
wolfSSL 14:167253f4e170 3982 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 3983 *
wolfSSL 14:167253f4e170 3984 * r A single precision integer.
wolfSSL 14:167253f4e170 3985 * a A single precision integer.
wolfSSL 14:167253f4e170 3986 */
wolfSSL 14:167253f4e170 3987 SP_NOINLINE static void sp_3072_sqr_54(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 3988 {
wolfSSL 14:167253f4e170 3989 int i, j, k;
wolfSSL 14:167253f4e170 3990 int128_t c;
wolfSSL 14:167253f4e170 3991
wolfSSL 14:167253f4e170 3992 c = ((int128_t)a[53]) * a[53];
wolfSSL 14:167253f4e170 3993 r[107] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 3994 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 3995 for (k = 105; k >= 0; k--) {
wolfSSL 14:167253f4e170 3996 for (i = 53; i >= 0; i--) {
wolfSSL 14:167253f4e170 3997 j = k - i;
wolfSSL 14:167253f4e170 3998 if (j >= 54 || i <= j)
wolfSSL 14:167253f4e170 3999 break;
wolfSSL 14:167253f4e170 4000 if (j < 0)
wolfSSL 14:167253f4e170 4001 continue;
wolfSSL 14:167253f4e170 4002
wolfSSL 14:167253f4e170 4003 c += ((int128_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 4004 }
wolfSSL 14:167253f4e170 4005 if (i == j)
wolfSSL 14:167253f4e170 4006 c += ((int128_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 4007
wolfSSL 14:167253f4e170 4008 r[k + 2] += c >> 114;
wolfSSL 14:167253f4e170 4009 r[k + 1] = (c >> 57) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4010 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 4011 }
wolfSSL 14:167253f4e170 4012 r[0] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 4013 }
wolfSSL 14:167253f4e170 4014
wolfSSL 14:167253f4e170 4015 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4016 #if !defined(SP_RSA_PRIVATE_EXP_D) && defined(WOLFSSL_HAVE_SP_RSA)
wolfSSL 14:167253f4e170 4017 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4018 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 4019 *
wolfSSL 14:167253f4e170 4020 * r A single precision integer.
wolfSSL 14:167253f4e170 4021 * a A single precision integer.
wolfSSL 14:167253f4e170 4022 * b A single precision integer.
wolfSSL 14:167253f4e170 4023 */
wolfSSL 14:167253f4e170 4024 SP_NOINLINE static int sp_3072_add_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4025 const sp_digit* b)
wolfSSL 14:167253f4e170 4026 {
wolfSSL 14:167253f4e170 4027 int i;
wolfSSL 14:167253f4e170 4028
wolfSSL 14:167253f4e170 4029 for (i = 0; i < 27; i++)
wolfSSL 14:167253f4e170 4030 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 4031
wolfSSL 14:167253f4e170 4032 return 0;
wolfSSL 14:167253f4e170 4033 }
wolfSSL 14:167253f4e170 4034 #else
wolfSSL 14:167253f4e170 4035 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 4036 *
wolfSSL 14:167253f4e170 4037 * r A single precision integer.
wolfSSL 14:167253f4e170 4038 * a A single precision integer.
wolfSSL 14:167253f4e170 4039 * b A single precision integer.
wolfSSL 14:167253f4e170 4040 */
wolfSSL 14:167253f4e170 4041 SP_NOINLINE static int sp_3072_add_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4042 const sp_digit* b)
wolfSSL 14:167253f4e170 4043 {
wolfSSL 14:167253f4e170 4044 int i;
wolfSSL 14:167253f4e170 4045
wolfSSL 14:167253f4e170 4046 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 4047 r[i + 0] = a[i + 0] + b[i + 0];
wolfSSL 14:167253f4e170 4048 r[i + 1] = a[i + 1] + b[i + 1];
wolfSSL 14:167253f4e170 4049 r[i + 2] = a[i + 2] + b[i + 2];
wolfSSL 14:167253f4e170 4050 r[i + 3] = a[i + 3] + b[i + 3];
wolfSSL 14:167253f4e170 4051 r[i + 4] = a[i + 4] + b[i + 4];
wolfSSL 14:167253f4e170 4052 r[i + 5] = a[i + 5] + b[i + 5];
wolfSSL 14:167253f4e170 4053 r[i + 6] = a[i + 6] + b[i + 6];
wolfSSL 14:167253f4e170 4054 r[i + 7] = a[i + 7] + b[i + 7];
wolfSSL 14:167253f4e170 4055 }
wolfSSL 14:167253f4e170 4056 r[24] = a[24] + b[24];
wolfSSL 14:167253f4e170 4057 r[25] = a[25] + b[25];
wolfSSL 14:167253f4e170 4058 r[26] = a[26] + b[26];
wolfSSL 14:167253f4e170 4059
wolfSSL 14:167253f4e170 4060 return 0;
wolfSSL 14:167253f4e170 4061 }
wolfSSL 14:167253f4e170 4062
wolfSSL 14:167253f4e170 4063 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4064 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4065 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 4066 *
wolfSSL 14:167253f4e170 4067 * r A single precision integer.
wolfSSL 14:167253f4e170 4068 * a A single precision integer.
wolfSSL 14:167253f4e170 4069 * b A single precision integer.
wolfSSL 14:167253f4e170 4070 */
wolfSSL 14:167253f4e170 4071 SP_NOINLINE static int sp_3072_sub_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4072 const sp_digit* b)
wolfSSL 14:167253f4e170 4073 {
wolfSSL 14:167253f4e170 4074 int i;
wolfSSL 14:167253f4e170 4075
wolfSSL 14:167253f4e170 4076 for (i = 0; i < 27; i++)
wolfSSL 14:167253f4e170 4077 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 4078
wolfSSL 14:167253f4e170 4079 return 0;
wolfSSL 14:167253f4e170 4080 }
wolfSSL 14:167253f4e170 4081
wolfSSL 14:167253f4e170 4082 #else
wolfSSL 14:167253f4e170 4083 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 4084 *
wolfSSL 14:167253f4e170 4085 * r A single precision integer.
wolfSSL 14:167253f4e170 4086 * a A single precision integer.
wolfSSL 14:167253f4e170 4087 * b A single precision integer.
wolfSSL 14:167253f4e170 4088 */
wolfSSL 14:167253f4e170 4089 SP_NOINLINE static int sp_3072_sub_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4090 const sp_digit* b)
wolfSSL 14:167253f4e170 4091 {
wolfSSL 14:167253f4e170 4092 int i;
wolfSSL 14:167253f4e170 4093
wolfSSL 14:167253f4e170 4094 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 4095 r[i + 0] = a[i + 0] - b[i + 0];
wolfSSL 14:167253f4e170 4096 r[i + 1] = a[i + 1] - b[i + 1];
wolfSSL 14:167253f4e170 4097 r[i + 2] = a[i + 2] - b[i + 2];
wolfSSL 14:167253f4e170 4098 r[i + 3] = a[i + 3] - b[i + 3];
wolfSSL 14:167253f4e170 4099 r[i + 4] = a[i + 4] - b[i + 4];
wolfSSL 14:167253f4e170 4100 r[i + 5] = a[i + 5] - b[i + 5];
wolfSSL 14:167253f4e170 4101 r[i + 6] = a[i + 6] - b[i + 6];
wolfSSL 14:167253f4e170 4102 r[i + 7] = a[i + 7] - b[i + 7];
wolfSSL 14:167253f4e170 4103 }
wolfSSL 14:167253f4e170 4104 r[24] = a[24] - b[24];
wolfSSL 14:167253f4e170 4105 r[25] = a[25] - b[25];
wolfSSL 14:167253f4e170 4106 r[26] = a[26] - b[26];
wolfSSL 14:167253f4e170 4107
wolfSSL 14:167253f4e170 4108 return 0;
wolfSSL 14:167253f4e170 4109 }
wolfSSL 14:167253f4e170 4110
wolfSSL 14:167253f4e170 4111 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4112 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4113 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 4114 *
wolfSSL 14:167253f4e170 4115 * r A single precision integer.
wolfSSL 14:167253f4e170 4116 * a A single precision integer.
wolfSSL 14:167253f4e170 4117 * b A single precision integer.
wolfSSL 14:167253f4e170 4118 */
wolfSSL 14:167253f4e170 4119 SP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4120 const sp_digit* b)
wolfSSL 14:167253f4e170 4121 {
wolfSSL 14:167253f4e170 4122 int i, j, k;
wolfSSL 14:167253f4e170 4123 int128_t c;
wolfSSL 14:167253f4e170 4124
wolfSSL 14:167253f4e170 4125 c = ((int128_t)a[26]) * b[26];
wolfSSL 14:167253f4e170 4126 r[53] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 4127 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 4128 for (k = 51; k >= 0; k--) {
wolfSSL 14:167253f4e170 4129 for (i = 26; i >= 0; i--) {
wolfSSL 14:167253f4e170 4130 j = k - i;
wolfSSL 14:167253f4e170 4131 if (j >= 27)
wolfSSL 14:167253f4e170 4132 break;
wolfSSL 14:167253f4e170 4133 if (j < 0)
wolfSSL 14:167253f4e170 4134 continue;
wolfSSL 14:167253f4e170 4135
wolfSSL 14:167253f4e170 4136 c += ((int128_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 4137 }
wolfSSL 14:167253f4e170 4138 r[k + 2] += c >> 114;
wolfSSL 14:167253f4e170 4139 r[k + 1] = (c >> 57) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4140 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 4141 }
wolfSSL 14:167253f4e170 4142 r[0] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 4143 }
wolfSSL 14:167253f4e170 4144
wolfSSL 14:167253f4e170 4145 #else
wolfSSL 14:167253f4e170 4146 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 4147 *
wolfSSL 14:167253f4e170 4148 * r A single precision integer.
wolfSSL 14:167253f4e170 4149 * a A single precision integer.
wolfSSL 14:167253f4e170 4150 * b A single precision integer.
wolfSSL 14:167253f4e170 4151 */
wolfSSL 14:167253f4e170 4152 SP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4153 const sp_digit* b)
wolfSSL 14:167253f4e170 4154 {
wolfSSL 14:167253f4e170 4155 int i, j;
wolfSSL 14:167253f4e170 4156 int128_t t[54];
wolfSSL 14:167253f4e170 4157
wolfSSL 14:167253f4e170 4158 XMEMSET(t, 0, sizeof(t));
wolfSSL 14:167253f4e170 4159 for (i=0; i<27; i++) {
wolfSSL 14:167253f4e170 4160 for (j=0; j<27; j++)
wolfSSL 14:167253f4e170 4161 t[i+j] += ((int128_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 4162 }
wolfSSL 14:167253f4e170 4163 for (i=0; i<53; i++) {
wolfSSL 14:167253f4e170 4164 r[i] = t[i] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4165 t[i+1] += t[i] >> 57;
wolfSSL 14:167253f4e170 4166 }
wolfSSL 14:167253f4e170 4167 r[53] = (sp_digit)t[53];
wolfSSL 14:167253f4e170 4168 }
wolfSSL 14:167253f4e170 4169
wolfSSL 14:167253f4e170 4170 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4171 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4172 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 4173 *
wolfSSL 14:167253f4e170 4174 * r A single precision integer.
wolfSSL 14:167253f4e170 4175 * a A single precision integer.
wolfSSL 14:167253f4e170 4176 */
wolfSSL 14:167253f4e170 4177 SP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4178 {
wolfSSL 14:167253f4e170 4179 int i, j, k;
wolfSSL 14:167253f4e170 4180 int128_t c;
wolfSSL 14:167253f4e170 4181
wolfSSL 14:167253f4e170 4182 c = ((int128_t)a[26]) * a[26];
wolfSSL 14:167253f4e170 4183 r[53] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 4184 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 4185 for (k = 51; k >= 0; k--) {
wolfSSL 14:167253f4e170 4186 for (i = 26; i >= 0; i--) {
wolfSSL 14:167253f4e170 4187 j = k - i;
wolfSSL 14:167253f4e170 4188 if (j >= 27 || i <= j)
wolfSSL 14:167253f4e170 4189 break;
wolfSSL 14:167253f4e170 4190 if (j < 0)
wolfSSL 14:167253f4e170 4191 continue;
wolfSSL 14:167253f4e170 4192
wolfSSL 14:167253f4e170 4193 c += ((int128_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 4194 }
wolfSSL 14:167253f4e170 4195 if (i == j)
wolfSSL 14:167253f4e170 4196 c += ((int128_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 4197
wolfSSL 14:167253f4e170 4198 r[k + 2] += c >> 114;
wolfSSL 14:167253f4e170 4199 r[k + 1] = (c >> 57) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4200 c = (c & 0x1ffffffffffffffl) << 57;
wolfSSL 14:167253f4e170 4201 }
wolfSSL 14:167253f4e170 4202 r[0] = (sp_digit)(c >> 57);
wolfSSL 14:167253f4e170 4203 }
wolfSSL 14:167253f4e170 4204
wolfSSL 14:167253f4e170 4205 #else
wolfSSL 14:167253f4e170 4206 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 4207 *
wolfSSL 14:167253f4e170 4208 * r A single precision integer.
wolfSSL 14:167253f4e170 4209 * a A single precision integer.
wolfSSL 14:167253f4e170 4210 */
wolfSSL 14:167253f4e170 4211 SP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4212 {
wolfSSL 14:167253f4e170 4213 int i, j;
wolfSSL 14:167253f4e170 4214 int128_t t[54];
wolfSSL 14:167253f4e170 4215
wolfSSL 14:167253f4e170 4216 XMEMSET(t, 0, sizeof(t));
wolfSSL 14:167253f4e170 4217 for (i=0; i<27; i++) {
wolfSSL 14:167253f4e170 4218 for (j=0; j<i; j++)
wolfSSL 14:167253f4e170 4219 t[i+j] += (((int128_t)a[i]) * a[j]) * 2;
wolfSSL 14:167253f4e170 4220 t[i+i] += ((int128_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 4221 }
wolfSSL 14:167253f4e170 4222 for (i=0; i<53; i++) {
wolfSSL 14:167253f4e170 4223 r[i] = t[i] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4224 t[i+1] += t[i] >> 57;
wolfSSL 14:167253f4e170 4225 }
wolfSSL 14:167253f4e170 4226 r[53] = (sp_digit)t[53];
wolfSSL 14:167253f4e170 4227 }
wolfSSL 14:167253f4e170 4228
wolfSSL 14:167253f4e170 4229 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4230 #endif /* !SP_RSA_PRIVATE_EXP_D && WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 4231
wolfSSL 14:167253f4e170 4232 /* Caclulate the bottom digit of -1/a mod 2^n.
wolfSSL 14:167253f4e170 4233 *
wolfSSL 14:167253f4e170 4234 * a A single precision number.
wolfSSL 14:167253f4e170 4235 * rho Bottom word of inverse.
wolfSSL 14:167253f4e170 4236 */
wolfSSL 14:167253f4e170 4237 static void sp_3072_mont_setup(sp_digit* a, sp_digit* rho)
wolfSSL 14:167253f4e170 4238 {
wolfSSL 14:167253f4e170 4239 sp_digit x, b;
wolfSSL 14:167253f4e170 4240
wolfSSL 14:167253f4e170 4241 b = a[0];
wolfSSL 14:167253f4e170 4242 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
wolfSSL 14:167253f4e170 4243 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
wolfSSL 14:167253f4e170 4244 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
wolfSSL 14:167253f4e170 4245 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
wolfSSL 14:167253f4e170 4246 x *= 2 - b * x; /* here x*a==1 mod 2**64 */
wolfSSL 14:167253f4e170 4247 x &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4248
wolfSSL 14:167253f4e170 4249 /* rho = -1/m mod b */
wolfSSL 14:167253f4e170 4250 *rho = (1L << 57) - x;
wolfSSL 14:167253f4e170 4251 }
wolfSSL 14:167253f4e170 4252
wolfSSL 14:167253f4e170 4253 #if !defined(SP_RSA_PRIVATE_EXP_D) && defined(WOLFSSL_HAVE_SP_RSA)
wolfSSL 14:167253f4e170 4254 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 14:167253f4e170 4255 * Given m must be 3072 bits, just need to subtract.
wolfSSL 14:167253f4e170 4256 *
wolfSSL 14:167253f4e170 4257 * r A single precision number.
wolfSSL 14:167253f4e170 4258 * m A signle precision number.
wolfSSL 14:167253f4e170 4259 */
wolfSSL 14:167253f4e170 4260 static void sp_3072_mont_norm_27(sp_digit* r, sp_digit* m)
wolfSSL 14:167253f4e170 4261 {
wolfSSL 14:167253f4e170 4262 /* Set r = 2^n - 1. */
wolfSSL 14:167253f4e170 4263 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4264 int i;
wolfSSL 14:167253f4e170 4265
wolfSSL 14:167253f4e170 4266 for (i=0; i<26; i++)
wolfSSL 14:167253f4e170 4267 r[i] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4268 #else
wolfSSL 14:167253f4e170 4269 int i;
wolfSSL 14:167253f4e170 4270
wolfSSL 14:167253f4e170 4271 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 4272 r[i + 0] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4273 r[i + 1] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4274 r[i + 2] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4275 r[i + 3] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4276 r[i + 4] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4277 r[i + 5] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4278 r[i + 6] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4279 r[i + 7] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4280 }
wolfSSL 14:167253f4e170 4281 r[24] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4282 r[25] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4283 #endif
wolfSSL 14:167253f4e170 4284 r[26] = 0x3fffffffffffffl;
wolfSSL 14:167253f4e170 4285
wolfSSL 14:167253f4e170 4286 /* r = (2^n - 1) mod n */
wolfSSL 14:167253f4e170 4287 sp_3072_sub_27(r, r, m);
wolfSSL 14:167253f4e170 4288
wolfSSL 14:167253f4e170 4289 /* Add one so r = 2^n mod m */
wolfSSL 14:167253f4e170 4290 r[0] += 1;
wolfSSL 14:167253f4e170 4291 }
wolfSSL 14:167253f4e170 4292
wolfSSL 14:167253f4e170 4293 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 4294 *
wolfSSL 14:167253f4e170 4295 * a A single precision integer.
wolfSSL 14:167253f4e170 4296 * b A single precision integer.
wolfSSL 14:167253f4e170 4297 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 4298 * respectively.
wolfSSL 14:167253f4e170 4299 */
wolfSSL 14:167253f4e170 4300 static sp_digit sp_3072_cmp_27(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 4301 {
wolfSSL 14:167253f4e170 4302 sp_digit r = 0;
wolfSSL 14:167253f4e170 4303 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4304 int i;
wolfSSL 14:167253f4e170 4305
wolfSSL 14:167253f4e170 4306 for (i=26; i>=0; i--)
wolfSSL 14:167253f4e170 4307 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 4308 #else
wolfSSL 14:167253f4e170 4309 int i;
wolfSSL 14:167253f4e170 4310
wolfSSL 14:167253f4e170 4311 r |= (a[26] - b[26]) & (0 - !r);
wolfSSL 14:167253f4e170 4312 r |= (a[25] - b[25]) & (0 - !r);
wolfSSL 14:167253f4e170 4313 r |= (a[24] - b[24]) & (0 - !r);
wolfSSL 14:167253f4e170 4314 for (i = 16; i >= 0; i -= 8) {
wolfSSL 14:167253f4e170 4315 r |= (a[i + 7] - b[i + 7]) & (0 - !r);
wolfSSL 14:167253f4e170 4316 r |= (a[i + 6] - b[i + 6]) & (0 - !r);
wolfSSL 14:167253f4e170 4317 r |= (a[i + 5] - b[i + 5]) & (0 - !r);
wolfSSL 14:167253f4e170 4318 r |= (a[i + 4] - b[i + 4]) & (0 - !r);
wolfSSL 14:167253f4e170 4319 r |= (a[i + 3] - b[i + 3]) & (0 - !r);
wolfSSL 14:167253f4e170 4320 r |= (a[i + 2] - b[i + 2]) & (0 - !r);
wolfSSL 14:167253f4e170 4321 r |= (a[i + 1] - b[i + 1]) & (0 - !r);
wolfSSL 14:167253f4e170 4322 r |= (a[i + 0] - b[i + 0]) & (0 - !r);
wolfSSL 14:167253f4e170 4323 }
wolfSSL 14:167253f4e170 4324 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4325
wolfSSL 14:167253f4e170 4326 return r;
wolfSSL 14:167253f4e170 4327 }
wolfSSL 14:167253f4e170 4328
wolfSSL 14:167253f4e170 4329 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 4330 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 4331 *
wolfSSL 14:167253f4e170 4332 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 4333 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 4334 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 4335 * m Mask value to apply.
wolfSSL 14:167253f4e170 4336 */
wolfSSL 14:167253f4e170 4337 static void sp_3072_cond_sub_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4338 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 4339 {
wolfSSL 14:167253f4e170 4340 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4341 int i;
wolfSSL 14:167253f4e170 4342
wolfSSL 14:167253f4e170 4343 for (i = 0; i < 27; i++)
wolfSSL 14:167253f4e170 4344 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 4345 #else
wolfSSL 14:167253f4e170 4346 int i;
wolfSSL 14:167253f4e170 4347
wolfSSL 14:167253f4e170 4348 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 4349 r[i + 0] = a[i + 0] - (b[i + 0] & m);
wolfSSL 14:167253f4e170 4350 r[i + 1] = a[i + 1] - (b[i + 1] & m);
wolfSSL 14:167253f4e170 4351 r[i + 2] = a[i + 2] - (b[i + 2] & m);
wolfSSL 14:167253f4e170 4352 r[i + 3] = a[i + 3] - (b[i + 3] & m);
wolfSSL 14:167253f4e170 4353 r[i + 4] = a[i + 4] - (b[i + 4] & m);
wolfSSL 14:167253f4e170 4354 r[i + 5] = a[i + 5] - (b[i + 5] & m);
wolfSSL 14:167253f4e170 4355 r[i + 6] = a[i + 6] - (b[i + 6] & m);
wolfSSL 14:167253f4e170 4356 r[i + 7] = a[i + 7] - (b[i + 7] & m);
wolfSSL 14:167253f4e170 4357 }
wolfSSL 14:167253f4e170 4358 r[24] = a[24] - (b[24] & m);
wolfSSL 14:167253f4e170 4359 r[25] = a[25] - (b[25] & m);
wolfSSL 14:167253f4e170 4360 r[26] = a[26] - (b[26] & m);
wolfSSL 14:167253f4e170 4361 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4362 }
wolfSSL 14:167253f4e170 4363
wolfSSL 14:167253f4e170 4364 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 4365 *
wolfSSL 14:167253f4e170 4366 * r A single precision integer.
wolfSSL 14:167253f4e170 4367 * a A single precision integer.
wolfSSL 14:167253f4e170 4368 * b A scalar.
wolfSSL 14:167253f4e170 4369 */
wolfSSL 14:167253f4e170 4370 SP_NOINLINE static void sp_3072_mul_add_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4371 const sp_digit b)
wolfSSL 14:167253f4e170 4372 {
wolfSSL 14:167253f4e170 4373 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4374 int128_t tb = b;
wolfSSL 14:167253f4e170 4375 int128_t t = 0;
wolfSSL 14:167253f4e170 4376 int i;
wolfSSL 14:167253f4e170 4377
wolfSSL 14:167253f4e170 4378 for (i = 0; i < 27; i++) {
wolfSSL 14:167253f4e170 4379 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 4380 r[i] = t & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4381 t >>= 57;
wolfSSL 14:167253f4e170 4382 }
wolfSSL 14:167253f4e170 4383 r[27] += t;
wolfSSL 14:167253f4e170 4384 #else
wolfSSL 14:167253f4e170 4385 int128_t tb = b;
wolfSSL 14:167253f4e170 4386 int128_t t[8];
wolfSSL 14:167253f4e170 4387 int i;
wolfSSL 14:167253f4e170 4388
wolfSSL 14:167253f4e170 4389 t[0] = tb * a[0]; r[0] += t[0] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4390 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 4391 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 4392 r[i+1] += (t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4393 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 4394 r[i+2] += (t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4395 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 4396 r[i+3] += (t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4397 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 4398 r[i+4] += (t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4399 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 4400 r[i+5] += (t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4401 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 4402 r[i+6] += (t[5] >> 57) + (t[6] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4403 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 4404 r[i+7] += (t[6] >> 57) + (t[7] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4405 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 4406 r[i+8] += (t[7] >> 57) + (t[0] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4407 }
wolfSSL 14:167253f4e170 4408 t[1] = tb * a[25]; r[25] += (t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4409 t[2] = tb * a[26]; r[26] += (t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4410 r[27] += t[2] >> 57;
wolfSSL 14:167253f4e170 4411 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4412 }
wolfSSL 14:167253f4e170 4413
wolfSSL 14:167253f4e170 4414 /* Normalize the values in each word to 57.
wolfSSL 14:167253f4e170 4415 *
wolfSSL 14:167253f4e170 4416 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 4417 */
wolfSSL 14:167253f4e170 4418 static void sp_3072_norm_27(sp_digit* a)
wolfSSL 14:167253f4e170 4419 {
wolfSSL 14:167253f4e170 4420 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4421 int i;
wolfSSL 14:167253f4e170 4422 for (i = 0; i < 26; i++) {
wolfSSL 14:167253f4e170 4423 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 4424 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4425 }
wolfSSL 14:167253f4e170 4426 #else
wolfSSL 14:167253f4e170 4427 int i;
wolfSSL 14:167253f4e170 4428 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 4429 a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4430 a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4431 a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4432 a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4433 a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4434 a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4435 a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4436 a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4437 a[i+9] += a[i+8] >> 57; a[i+8] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4438 }
wolfSSL 14:167253f4e170 4439 a[24+1] += a[24] >> 57;
wolfSSL 14:167253f4e170 4440 a[24] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4441 a[25+1] += a[25] >> 57;
wolfSSL 14:167253f4e170 4442 a[25] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4443 #endif
wolfSSL 14:167253f4e170 4444 }
wolfSSL 14:167253f4e170 4445
wolfSSL 14:167253f4e170 4446 /* Shift the result in the high 1536 bits down to the bottom.
wolfSSL 14:167253f4e170 4447 *
wolfSSL 14:167253f4e170 4448 * r A single precision number.
wolfSSL 14:167253f4e170 4449 * a A single precision number.
wolfSSL 14:167253f4e170 4450 */
wolfSSL 14:167253f4e170 4451 static void sp_3072_mont_shift_27(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 4452 {
wolfSSL 14:167253f4e170 4453 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4454 int i;
wolfSSL 14:167253f4e170 4455 sp_digit n, s;
wolfSSL 14:167253f4e170 4456
wolfSSL 14:167253f4e170 4457 s = a[27];
wolfSSL 14:167253f4e170 4458 n = a[26] >> 54;
wolfSSL 14:167253f4e170 4459 for (i = 0; i < 26; i++) {
wolfSSL 14:167253f4e170 4460 n += (s & 0x1ffffffffffffffl) << 3;
wolfSSL 14:167253f4e170 4461 r[i] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4462 n >>= 57;
wolfSSL 14:167253f4e170 4463 s = a[28 + i] + (s >> 57);
wolfSSL 14:167253f4e170 4464 }
wolfSSL 14:167253f4e170 4465 n += s << 3;
wolfSSL 14:167253f4e170 4466 r[26] = n;
wolfSSL 14:167253f4e170 4467 #else
wolfSSL 14:167253f4e170 4468 sp_digit n, s;
wolfSSL 14:167253f4e170 4469 int i;
wolfSSL 14:167253f4e170 4470
wolfSSL 14:167253f4e170 4471 s = a[27]; n = a[26] >> 54;
wolfSSL 14:167253f4e170 4472 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 4473 n += (s & 0x1ffffffffffffffl) << 3; r[i+0] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4474 n >>= 57; s = a[i+28] + (s >> 57);
wolfSSL 14:167253f4e170 4475 n += (s & 0x1ffffffffffffffl) << 3; r[i+1] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4476 n >>= 57; s = a[i+29] + (s >> 57);
wolfSSL 14:167253f4e170 4477 n += (s & 0x1ffffffffffffffl) << 3; r[i+2] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4478 n >>= 57; s = a[i+30] + (s >> 57);
wolfSSL 14:167253f4e170 4479 n += (s & 0x1ffffffffffffffl) << 3; r[i+3] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4480 n >>= 57; s = a[i+31] + (s >> 57);
wolfSSL 14:167253f4e170 4481 n += (s & 0x1ffffffffffffffl) << 3; r[i+4] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4482 n >>= 57; s = a[i+32] + (s >> 57);
wolfSSL 14:167253f4e170 4483 n += (s & 0x1ffffffffffffffl) << 3; r[i+5] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4484 n >>= 57; s = a[i+33] + (s >> 57);
wolfSSL 14:167253f4e170 4485 n += (s & 0x1ffffffffffffffl) << 3; r[i+6] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4486 n >>= 57; s = a[i+34] + (s >> 57);
wolfSSL 14:167253f4e170 4487 n += (s & 0x1ffffffffffffffl) << 3; r[i+7] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4488 n >>= 57; s = a[i+35] + (s >> 57);
wolfSSL 14:167253f4e170 4489 }
wolfSSL 14:167253f4e170 4490 n += (s & 0x1ffffffffffffffl) << 3; r[24] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4491 n >>= 57; s = a[52] + (s >> 57);
wolfSSL 14:167253f4e170 4492 n += (s & 0x1ffffffffffffffl) << 3; r[25] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4493 n >>= 57; s = a[53] + (s >> 57);
wolfSSL 14:167253f4e170 4494 n += s << 3; r[26] = n;
wolfSSL 14:167253f4e170 4495 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4496 XMEMSET(&r[27], 0, sizeof(*r) * 27);
wolfSSL 14:167253f4e170 4497 }
wolfSSL 14:167253f4e170 4498
wolfSSL 14:167253f4e170 4499 /* Reduce the number back to 3072 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 4500 *
wolfSSL 14:167253f4e170 4501 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 4502 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 4503 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 4504 */
wolfSSL 14:167253f4e170 4505 static void sp_3072_mont_reduce_27(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 4506 {
wolfSSL 14:167253f4e170 4507 int i;
wolfSSL 14:167253f4e170 4508 sp_digit mu;
wolfSSL 14:167253f4e170 4509
wolfSSL 14:167253f4e170 4510 for (i=0; i<26; i++) {
wolfSSL 14:167253f4e170 4511 mu = (a[i] * mp) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4512 sp_3072_mul_add_27(a+i, m, mu);
wolfSSL 14:167253f4e170 4513 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 4514 }
wolfSSL 14:167253f4e170 4515 mu = (a[i] * mp) & 0x3fffffffffffffl;
wolfSSL 14:167253f4e170 4516 sp_3072_mul_add_27(a+i, m, mu);
wolfSSL 14:167253f4e170 4517 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 4518 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4519
wolfSSL 14:167253f4e170 4520 sp_3072_mont_shift_27(a, a);
wolfSSL 14:167253f4e170 4521 sp_3072_cond_sub_27(a, a, m, 0 - ((a[26] >> 54) > 0));
wolfSSL 14:167253f4e170 4522 sp_3072_norm_27(a);
wolfSSL 14:167253f4e170 4523 }
wolfSSL 14:167253f4e170 4524
wolfSSL 14:167253f4e170 4525 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 4526 * (r = a * b mod m)
wolfSSL 14:167253f4e170 4527 *
wolfSSL 14:167253f4e170 4528 * r Result of multiplication.
wolfSSL 14:167253f4e170 4529 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 4530 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 4531 * m Modulus (prime).
wolfSSL 14:167253f4e170 4532 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 4533 */
wolfSSL 14:167253f4e170 4534 static void sp_3072_mont_mul_27(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 4535 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 4536 {
wolfSSL 14:167253f4e170 4537 sp_3072_mul_27(r, a, b);
wolfSSL 14:167253f4e170 4538 sp_3072_mont_reduce_27(r, m, mp);
wolfSSL 14:167253f4e170 4539 }
wolfSSL 14:167253f4e170 4540
wolfSSL 14:167253f4e170 4541 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 4542 *
wolfSSL 14:167253f4e170 4543 * r Result of squaring.
wolfSSL 14:167253f4e170 4544 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 4545 * m Modulus (prime).
wolfSSL 14:167253f4e170 4546 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 4547 */
wolfSSL 14:167253f4e170 4548 static void sp_3072_mont_sqr_27(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 4549 sp_digit mp)
wolfSSL 14:167253f4e170 4550 {
wolfSSL 14:167253f4e170 4551 sp_3072_sqr_27(r, a);
wolfSSL 14:167253f4e170 4552 sp_3072_mont_reduce_27(r, m, mp);
wolfSSL 14:167253f4e170 4553 }
wolfSSL 14:167253f4e170 4554
wolfSSL 14:167253f4e170 4555 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 4556 *
wolfSSL 14:167253f4e170 4557 * r A single precision integer.
wolfSSL 14:167253f4e170 4558 * a A single precision integer.
wolfSSL 14:167253f4e170 4559 * b A scalar.
wolfSSL 14:167253f4e170 4560 */
wolfSSL 14:167253f4e170 4561 SP_NOINLINE static void sp_3072_mul_d_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4562 const sp_digit b)
wolfSSL 14:167253f4e170 4563 {
wolfSSL 14:167253f4e170 4564 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4565 int128_t tb = b;
wolfSSL 14:167253f4e170 4566 int128_t t = 0;
wolfSSL 14:167253f4e170 4567 int i;
wolfSSL 14:167253f4e170 4568
wolfSSL 14:167253f4e170 4569 for (i = 0; i < 27; i++) {
wolfSSL 14:167253f4e170 4570 t += tb * a[i];
wolfSSL 14:167253f4e170 4571 r[i] = t & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4572 t >>= 57;
wolfSSL 14:167253f4e170 4573 }
wolfSSL 14:167253f4e170 4574 r[27] = (sp_digit)t;
wolfSSL 14:167253f4e170 4575 #else
wolfSSL 14:167253f4e170 4576 int128_t tb = b;
wolfSSL 14:167253f4e170 4577 int128_t t[8];
wolfSSL 14:167253f4e170 4578 int i;
wolfSSL 14:167253f4e170 4579
wolfSSL 14:167253f4e170 4580 t[0] = tb * a[0]; r[0] = t[0] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4581 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 4582 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 4583 r[i+1] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4584 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 4585 r[i+2] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4586 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 4587 r[i+3] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4588 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 4589 r[i+4] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4590 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 4591 r[i+5] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4592 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 4593 r[i+6] = (sp_digit)(t[5] >> 57) + (t[6] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4594 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 4595 r[i+7] = (sp_digit)(t[6] >> 57) + (t[7] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4596 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 4597 r[i+8] = (sp_digit)(t[7] >> 57) + (t[0] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4598 }
wolfSSL 14:167253f4e170 4599 t[1] = tb * a[25];
wolfSSL 14:167253f4e170 4600 r[25] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4601 t[2] = tb * a[26];
wolfSSL 14:167253f4e170 4602 r[26] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 4603 r[27] = (sp_digit)(t[2] >> 57);
wolfSSL 14:167253f4e170 4604 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4605 }
wolfSSL 14:167253f4e170 4606
wolfSSL 14:167253f4e170 4607 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 4608 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 4609 *
wolfSSL 14:167253f4e170 4610 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 4611 * a A single precision number to add with.
wolfSSL 14:167253f4e170 4612 * b A single precision number to add.
wolfSSL 14:167253f4e170 4613 * m Mask value to apply.
wolfSSL 14:167253f4e170 4614 */
wolfSSL 14:167253f4e170 4615 static void sp_3072_cond_add_27(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 4616 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 4617 {
wolfSSL 14:167253f4e170 4618 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4619 int i;
wolfSSL 14:167253f4e170 4620
wolfSSL 14:167253f4e170 4621 for (i = 0; i < 27; i++)
wolfSSL 14:167253f4e170 4622 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 4623 #else
wolfSSL 14:167253f4e170 4624 int i;
wolfSSL 14:167253f4e170 4625
wolfSSL 14:167253f4e170 4626 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 4627 r[i + 0] = a[i + 0] + (b[i + 0] & m);
wolfSSL 14:167253f4e170 4628 r[i + 1] = a[i + 1] + (b[i + 1] & m);
wolfSSL 14:167253f4e170 4629 r[i + 2] = a[i + 2] + (b[i + 2] & m);
wolfSSL 14:167253f4e170 4630 r[i + 3] = a[i + 3] + (b[i + 3] & m);
wolfSSL 14:167253f4e170 4631 r[i + 4] = a[i + 4] + (b[i + 4] & m);
wolfSSL 14:167253f4e170 4632 r[i + 5] = a[i + 5] + (b[i + 5] & m);
wolfSSL 14:167253f4e170 4633 r[i + 6] = a[i + 6] + (b[i + 6] & m);
wolfSSL 14:167253f4e170 4634 r[i + 7] = a[i + 7] + (b[i + 7] & m);
wolfSSL 14:167253f4e170 4635 }
wolfSSL 14:167253f4e170 4636 r[24] = a[24] + (b[24] & m);
wolfSSL 14:167253f4e170 4637 r[25] = a[25] + (b[25] & m);
wolfSSL 14:167253f4e170 4638 r[26] = a[26] + (b[26] & m);
wolfSSL 14:167253f4e170 4639 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 4640 }
wolfSSL 14:167253f4e170 4641
wolfSSL 14:167253f4e170 4642 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 4643 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 4644 *
wolfSSL 14:167253f4e170 4645 * a Nmber to be divided.
wolfSSL 14:167253f4e170 4646 * d Number to divide with.
wolfSSL 14:167253f4e170 4647 * m Multiplier result.
wolfSSL 14:167253f4e170 4648 * r Remainder from the division.
wolfSSL 14:167253f4e170 4649 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 4650 */
wolfSSL 14:167253f4e170 4651 static int sp_3072_div_27(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 4652 sp_digit* r)
wolfSSL 14:167253f4e170 4653 {
wolfSSL 14:167253f4e170 4654 int i;
wolfSSL 14:167253f4e170 4655 int128_t d1;
wolfSSL 14:167253f4e170 4656 sp_digit div, r1;
wolfSSL 14:167253f4e170 4657 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 4658 sp_digit* td;
wolfSSL 14:167253f4e170 4659 #else
wolfSSL 14:167253f4e170 4660 sp_digit t1d[54], t2d[27 + 1];
wolfSSL 14:167253f4e170 4661 #endif
wolfSSL 14:167253f4e170 4662 sp_digit* t1;
wolfSSL 14:167253f4e170 4663 sp_digit* t2;
wolfSSL 14:167253f4e170 4664 int err = MP_OKAY;
wolfSSL 14:167253f4e170 4665
wolfSSL 14:167253f4e170 4666 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 4667 td = XMALLOC(sizeof(sp_digit) * (3 * 27 + 1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 4668 if (td != NULL) {
wolfSSL 14:167253f4e170 4669 t1 = td;
wolfSSL 14:167253f4e170 4670 t2 = td + 2 * 27;
wolfSSL 14:167253f4e170 4671 }
wolfSSL 14:167253f4e170 4672 else
wolfSSL 14:167253f4e170 4673 err = MEMORY_E;
wolfSSL 14:167253f4e170 4674 #else
wolfSSL 14:167253f4e170 4675 t1 = t1d;
wolfSSL 14:167253f4e170 4676 t2 = t2d;
wolfSSL 14:167253f4e170 4677 #endif
wolfSSL 14:167253f4e170 4678
wolfSSL 14:167253f4e170 4679 (void)m;
wolfSSL 14:167253f4e170 4680
wolfSSL 14:167253f4e170 4681 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4682 div = d[26];
wolfSSL 14:167253f4e170 4683 XMEMCPY(t1, a, sizeof(*t1) * 2 * 27);
wolfSSL 14:167253f4e170 4684 for (i=26; i>=0; i--) {
wolfSSL 14:167253f4e170 4685 t1[27 + i] += t1[27 + i - 1] >> 57;
wolfSSL 14:167253f4e170 4686 t1[27 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4687 d1 = t1[27 + i];
wolfSSL 14:167253f4e170 4688 d1 <<= 57;
wolfSSL 14:167253f4e170 4689 d1 += t1[27 + i - 1];
wolfSSL 14:167253f4e170 4690 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 4691
wolfSSL 14:167253f4e170 4692 sp_3072_mul_d_27(t2, d, r1);
wolfSSL 14:167253f4e170 4693 sp_3072_sub_27(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 4694 t1[27 + i] -= t2[27];
wolfSSL 14:167253f4e170 4695 t1[27 + i] += t1[27 + i - 1] >> 57;
wolfSSL 14:167253f4e170 4696 t1[27 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4697 r1 = (((-t1[27 + i]) << 57) - t1[27 + i - 1]) / div;
wolfSSL 14:167253f4e170 4698 r1++;
wolfSSL 14:167253f4e170 4699 sp_3072_mul_d_27(t2, d, r1);
wolfSSL 14:167253f4e170 4700 sp_3072_add_27(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 4701 t1[27 + i] += t1[27 + i - 1] >> 57;
wolfSSL 14:167253f4e170 4702 t1[27 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4703 }
wolfSSL 14:167253f4e170 4704 t1[27 - 1] += t1[27 - 2] >> 57;
wolfSSL 14:167253f4e170 4705 t1[27 - 2] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4706 d1 = t1[27 - 1];
wolfSSL 14:167253f4e170 4707 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 4708
wolfSSL 14:167253f4e170 4709 sp_3072_mul_d_27(t2, d, r1);
wolfSSL 14:167253f4e170 4710 sp_3072_sub_27(t1, t1, t2);
wolfSSL 14:167253f4e170 4711 XMEMCPY(r, t1, sizeof(*r) * 2 * 27);
wolfSSL 14:167253f4e170 4712 for (i=0; i<25; i++) {
wolfSSL 14:167253f4e170 4713 r[i+1] += r[i] >> 57;
wolfSSL 14:167253f4e170 4714 r[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 4715 }
wolfSSL 14:167253f4e170 4716 sp_3072_cond_add_27(r, r, d, 0 - (r[26] < 0));
wolfSSL 14:167253f4e170 4717 }
wolfSSL 14:167253f4e170 4718
wolfSSL 14:167253f4e170 4719 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 4720 if (td != NULL)
wolfSSL 14:167253f4e170 4721 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 4722 #endif
wolfSSL 14:167253f4e170 4723
wolfSSL 14:167253f4e170 4724 return err;
wolfSSL 14:167253f4e170 4725 }
wolfSSL 14:167253f4e170 4726
wolfSSL 14:167253f4e170 4727 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 4728 *
wolfSSL 14:167253f4e170 4729 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 4730 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 4731 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 4732 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 4733 */
wolfSSL 14:167253f4e170 4734 static int sp_3072_mod_27(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 4735 {
wolfSSL 14:167253f4e170 4736 return sp_3072_div_27(a, m, NULL, r);
wolfSSL 14:167253f4e170 4737 }
wolfSSL 14:167253f4e170 4738
wolfSSL 14:167253f4e170 4739 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 14:167253f4e170 4740 *
wolfSSL 14:167253f4e170 4741 * r A single precision number that is the result of the operation.
wolfSSL 14:167253f4e170 4742 * a A single precision number being exponentiated.
wolfSSL 14:167253f4e170 4743 * e A single precision number that is the exponent.
wolfSSL 14:167253f4e170 4744 * bits The number of bits in the exponent.
wolfSSL 14:167253f4e170 4745 * m A single precision number that is the modulus.
wolfSSL 14:167253f4e170 4746 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 14:167253f4e170 4747 */
wolfSSL 14:167253f4e170 4748 static int sp_3072_mod_exp_27(sp_digit* r, sp_digit* a, sp_digit* e, int bits,
wolfSSL 14:167253f4e170 4749 sp_digit* m, int reduceA)
wolfSSL 14:167253f4e170 4750 {
wolfSSL 14:167253f4e170 4751 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 4752 sp_digit* td;
wolfSSL 14:167253f4e170 4753 sp_digit* t[3];
wolfSSL 14:167253f4e170 4754 sp_digit* norm;
wolfSSL 14:167253f4e170 4755 sp_digit mp = 1;
wolfSSL 14:167253f4e170 4756 sp_digit n;
wolfSSL 14:167253f4e170 4757 int i;
wolfSSL 14:167253f4e170 4758 int c, y;
wolfSSL 14:167253f4e170 4759 int err = MP_OKAY;
wolfSSL 14:167253f4e170 4760
wolfSSL 14:167253f4e170 4761 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 27 * 2, NULL,
wolfSSL 14:167253f4e170 4762 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 4763 if (td == NULL)
wolfSSL 14:167253f4e170 4764 err = MEMORY_E;
wolfSSL 14:167253f4e170 4765
wolfSSL 14:167253f4e170 4766 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4767 XMEMSET(td, 0, sizeof(*td) * 3 * 27 * 2);
wolfSSL 14:167253f4e170 4768
wolfSSL 14:167253f4e170 4769 norm = t[0] = td;
wolfSSL 14:167253f4e170 4770 t[1] = &td[27 * 2];
wolfSSL 14:167253f4e170 4771 t[2] = &td[2 * 27 * 2];
wolfSSL 14:167253f4e170 4772
wolfSSL 14:167253f4e170 4773 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 4774 sp_3072_mont_norm_27(norm, m);
wolfSSL 14:167253f4e170 4775
wolfSSL 14:167253f4e170 4776 if (reduceA)
wolfSSL 14:167253f4e170 4777 err = sp_3072_mod_27(t[1], a, m);
wolfSSL 14:167253f4e170 4778 else
wolfSSL 14:167253f4e170 4779 XMEMCPY(t[1], a, sizeof(sp_digit) * 27);
wolfSSL 14:167253f4e170 4780 }
wolfSSL 14:167253f4e170 4781 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4782 sp_3072_mul_27(t[1], t[1], norm);
wolfSSL 14:167253f4e170 4783 err = sp_3072_mod_27(t[1], t[1], m);
wolfSSL 14:167253f4e170 4784 }
wolfSSL 14:167253f4e170 4785
wolfSSL 14:167253f4e170 4786 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4787 i = bits / 57;
wolfSSL 14:167253f4e170 4788 c = bits % 57;
wolfSSL 14:167253f4e170 4789 n = e[i--] << (57 - c);
wolfSSL 14:167253f4e170 4790 for (; ; c--) {
wolfSSL 14:167253f4e170 4791 if (c == 0) {
wolfSSL 14:167253f4e170 4792 if (i == -1)
wolfSSL 14:167253f4e170 4793 break;
wolfSSL 14:167253f4e170 4794
wolfSSL 14:167253f4e170 4795 n = e[i--];
wolfSSL 14:167253f4e170 4796 c = 57;
wolfSSL 14:167253f4e170 4797 }
wolfSSL 14:167253f4e170 4798
wolfSSL 14:167253f4e170 4799 y = (n >> 56) & 1;
wolfSSL 14:167253f4e170 4800 n <<= 1;
wolfSSL 14:167253f4e170 4801
wolfSSL 14:167253f4e170 4802 sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 4803
wolfSSL 14:167253f4e170 4804 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 4805 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 4806 sizeof(*t[2]) * 27 * 2);
wolfSSL 14:167253f4e170 4807 sp_3072_mont_sqr_27(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 4808 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 4809 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 4810 sizeof(*t[2]) * 27 * 2);
wolfSSL 14:167253f4e170 4811 }
wolfSSL 14:167253f4e170 4812
wolfSSL 14:167253f4e170 4813 sp_3072_mont_reduce_27(t[0], m, mp);
wolfSSL 14:167253f4e170 4814 n = sp_3072_cmp_27(t[0], m);
wolfSSL 14:167253f4e170 4815 sp_3072_cond_sub_27(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 4816 XMEMCPY(r, t[0], sizeof(*r) * 27 * 2);
wolfSSL 14:167253f4e170 4817
wolfSSL 14:167253f4e170 4818 }
wolfSSL 14:167253f4e170 4819
wolfSSL 14:167253f4e170 4820 if (td != NULL)
wolfSSL 14:167253f4e170 4821 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 4822
wolfSSL 14:167253f4e170 4823 return err;
wolfSSL 14:167253f4e170 4824 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 4825 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 4826 sp_digit t[3][54];
wolfSSL 14:167253f4e170 4827 #else
wolfSSL 14:167253f4e170 4828 sp_digit* td;
wolfSSL 14:167253f4e170 4829 sp_digit* t[3];
wolfSSL 14:167253f4e170 4830 #endif
wolfSSL 14:167253f4e170 4831 sp_digit* norm;
wolfSSL 14:167253f4e170 4832 sp_digit mp = 1;
wolfSSL 14:167253f4e170 4833 sp_digit n;
wolfSSL 14:167253f4e170 4834 int i;
wolfSSL 14:167253f4e170 4835 int c, y;
wolfSSL 14:167253f4e170 4836 int err = MP_OKAY;
wolfSSL 14:167253f4e170 4837
wolfSSL 14:167253f4e170 4838 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 4839 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 27 * 2, NULL,
wolfSSL 14:167253f4e170 4840 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 4841 if (td == NULL)
wolfSSL 14:167253f4e170 4842 err = MEMORY_E;
wolfSSL 14:167253f4e170 4843
wolfSSL 14:167253f4e170 4844 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4845 t[0] = td;
wolfSSL 14:167253f4e170 4846 t[1] = &td[27 * 2];
wolfSSL 14:167253f4e170 4847 t[2] = &td[2 * 27 * 2];
wolfSSL 14:167253f4e170 4848 norm = t[0];
wolfSSL 14:167253f4e170 4849 }
wolfSSL 14:167253f4e170 4850 #else
wolfSSL 14:167253f4e170 4851 norm = t[0];
wolfSSL 14:167253f4e170 4852 #endif
wolfSSL 14:167253f4e170 4853
wolfSSL 14:167253f4e170 4854 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4855 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 4856 sp_3072_mont_norm_27(norm, m);
wolfSSL 14:167253f4e170 4857
wolfSSL 14:167253f4e170 4858 if (reduceA) {
wolfSSL 14:167253f4e170 4859 err = sp_3072_mod_27(t[1], a, m);
wolfSSL 14:167253f4e170 4860 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4861 sp_3072_mul_27(t[1], t[1], norm);
wolfSSL 14:167253f4e170 4862 err = sp_3072_mod_27(t[1], t[1], m);
wolfSSL 14:167253f4e170 4863 }
wolfSSL 14:167253f4e170 4864 }
wolfSSL 14:167253f4e170 4865 else {
wolfSSL 14:167253f4e170 4866 sp_3072_mul_27(t[1], a, norm);
wolfSSL 14:167253f4e170 4867 err = sp_3072_mod_27(t[1], t[1], m);
wolfSSL 14:167253f4e170 4868 }
wolfSSL 14:167253f4e170 4869 }
wolfSSL 14:167253f4e170 4870
wolfSSL 14:167253f4e170 4871 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4872 i = bits / 57;
wolfSSL 14:167253f4e170 4873 c = bits % 57;
wolfSSL 14:167253f4e170 4874 n = e[i--] << (57 - c);
wolfSSL 14:167253f4e170 4875 for (; ; c--) {
wolfSSL 14:167253f4e170 4876 if (c == 0) {
wolfSSL 14:167253f4e170 4877 if (i == -1)
wolfSSL 14:167253f4e170 4878 break;
wolfSSL 14:167253f4e170 4879
wolfSSL 14:167253f4e170 4880 n = e[i--];
wolfSSL 14:167253f4e170 4881 c = 57;
wolfSSL 14:167253f4e170 4882 }
wolfSSL 14:167253f4e170 4883
wolfSSL 14:167253f4e170 4884 y = (n >> 56) & 1;
wolfSSL 14:167253f4e170 4885 n <<= 1;
wolfSSL 14:167253f4e170 4886
wolfSSL 14:167253f4e170 4887 sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 4888
wolfSSL 14:167253f4e170 4889 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 4890 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 4891 sp_3072_mont_sqr_27(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 4892 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 4893 ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 4894 }
wolfSSL 14:167253f4e170 4895
wolfSSL 14:167253f4e170 4896 sp_3072_mont_reduce_27(t[0], m, mp);
wolfSSL 14:167253f4e170 4897 n = sp_3072_cmp_27(t[0], m);
wolfSSL 14:167253f4e170 4898 sp_3072_cond_sub_27(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 4899 XMEMCPY(r, t[0], sizeof(t[0]));
wolfSSL 14:167253f4e170 4900 }
wolfSSL 14:167253f4e170 4901
wolfSSL 14:167253f4e170 4902 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 4903 if (td != NULL)
wolfSSL 14:167253f4e170 4904 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 4905 #endif
wolfSSL 14:167253f4e170 4906
wolfSSL 14:167253f4e170 4907 return err;
wolfSSL 14:167253f4e170 4908 #else
wolfSSL 14:167253f4e170 4909 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 4910 sp_digit t[32][54];
wolfSSL 14:167253f4e170 4911 #else
wolfSSL 14:167253f4e170 4912 sp_digit* t[32];
wolfSSL 14:167253f4e170 4913 sp_digit* td;
wolfSSL 14:167253f4e170 4914 #endif
wolfSSL 14:167253f4e170 4915 sp_digit* norm;
wolfSSL 14:167253f4e170 4916 sp_digit rt[54];
wolfSSL 14:167253f4e170 4917 sp_digit mp = 1;
wolfSSL 14:167253f4e170 4918 sp_digit n;
wolfSSL 14:167253f4e170 4919 int i;
wolfSSL 14:167253f4e170 4920 int c, y;
wolfSSL 14:167253f4e170 4921 int err = MP_OKAY;
wolfSSL 14:167253f4e170 4922
wolfSSL 14:167253f4e170 4923 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 4924 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 54, NULL,
wolfSSL 14:167253f4e170 4925 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 4926 if (td == NULL)
wolfSSL 14:167253f4e170 4927 err = MEMORY_E;
wolfSSL 14:167253f4e170 4928
wolfSSL 14:167253f4e170 4929 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4930 for (i=0; i<32; i++)
wolfSSL 14:167253f4e170 4931 t[i] = td + i * 54;
wolfSSL 14:167253f4e170 4932 norm = t[0];
wolfSSL 14:167253f4e170 4933 }
wolfSSL 14:167253f4e170 4934 #else
wolfSSL 14:167253f4e170 4935 norm = t[0];
wolfSSL 14:167253f4e170 4936 #endif
wolfSSL 14:167253f4e170 4937
wolfSSL 14:167253f4e170 4938 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4939 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 4940 sp_3072_mont_norm_27(norm, m);
wolfSSL 14:167253f4e170 4941
wolfSSL 14:167253f4e170 4942 if (reduceA) {
wolfSSL 14:167253f4e170 4943 err = sp_3072_mod_27(t[1], a, m);
wolfSSL 14:167253f4e170 4944 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4945 sp_3072_mul_27(t[1], t[1], norm);
wolfSSL 14:167253f4e170 4946 err = sp_3072_mod_27(t[1], t[1], m);
wolfSSL 14:167253f4e170 4947 }
wolfSSL 14:167253f4e170 4948 }
wolfSSL 14:167253f4e170 4949 else {
wolfSSL 14:167253f4e170 4950 sp_3072_mul_27(t[1], a, norm);
wolfSSL 14:167253f4e170 4951 err = sp_3072_mod_27(t[1], t[1], m);
wolfSSL 14:167253f4e170 4952 }
wolfSSL 14:167253f4e170 4953 }
wolfSSL 14:167253f4e170 4954
wolfSSL 14:167253f4e170 4955 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 4956 sp_3072_mont_sqr_27(t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 4957 sp_3072_mont_mul_27(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 4958 sp_3072_mont_sqr_27(t[ 4], t[ 2], m, mp);
wolfSSL 14:167253f4e170 4959 sp_3072_mont_mul_27(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 14:167253f4e170 4960 sp_3072_mont_sqr_27(t[ 6], t[ 3], m, mp);
wolfSSL 14:167253f4e170 4961 sp_3072_mont_mul_27(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 14:167253f4e170 4962 sp_3072_mont_sqr_27(t[ 8], t[ 4], m, mp);
wolfSSL 14:167253f4e170 4963 sp_3072_mont_mul_27(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 14:167253f4e170 4964 sp_3072_mont_sqr_27(t[10], t[ 5], m, mp);
wolfSSL 14:167253f4e170 4965 sp_3072_mont_mul_27(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 14:167253f4e170 4966 sp_3072_mont_sqr_27(t[12], t[ 6], m, mp);
wolfSSL 14:167253f4e170 4967 sp_3072_mont_mul_27(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 14:167253f4e170 4968 sp_3072_mont_sqr_27(t[14], t[ 7], m, mp);
wolfSSL 14:167253f4e170 4969 sp_3072_mont_mul_27(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 14:167253f4e170 4970 sp_3072_mont_sqr_27(t[16], t[ 8], m, mp);
wolfSSL 14:167253f4e170 4971 sp_3072_mont_mul_27(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 14:167253f4e170 4972 sp_3072_mont_sqr_27(t[18], t[ 9], m, mp);
wolfSSL 14:167253f4e170 4973 sp_3072_mont_mul_27(t[19], t[10], t[ 9], m, mp);
wolfSSL 14:167253f4e170 4974 sp_3072_mont_sqr_27(t[20], t[10], m, mp);
wolfSSL 14:167253f4e170 4975 sp_3072_mont_mul_27(t[21], t[11], t[10], m, mp);
wolfSSL 14:167253f4e170 4976 sp_3072_mont_sqr_27(t[22], t[11], m, mp);
wolfSSL 14:167253f4e170 4977 sp_3072_mont_mul_27(t[23], t[12], t[11], m, mp);
wolfSSL 14:167253f4e170 4978 sp_3072_mont_sqr_27(t[24], t[12], m, mp);
wolfSSL 14:167253f4e170 4979 sp_3072_mont_mul_27(t[25], t[13], t[12], m, mp);
wolfSSL 14:167253f4e170 4980 sp_3072_mont_sqr_27(t[26], t[13], m, mp);
wolfSSL 14:167253f4e170 4981 sp_3072_mont_mul_27(t[27], t[14], t[13], m, mp);
wolfSSL 14:167253f4e170 4982 sp_3072_mont_sqr_27(t[28], t[14], m, mp);
wolfSSL 14:167253f4e170 4983 sp_3072_mont_mul_27(t[29], t[15], t[14], m, mp);
wolfSSL 14:167253f4e170 4984 sp_3072_mont_sqr_27(t[30], t[15], m, mp);
wolfSSL 14:167253f4e170 4985 sp_3072_mont_mul_27(t[31], t[16], t[15], m, mp);
wolfSSL 14:167253f4e170 4986
wolfSSL 14:167253f4e170 4987 bits = ((bits + 4) / 5) * 5;
wolfSSL 14:167253f4e170 4988 i = ((bits + 56) / 57) - 1;
wolfSSL 14:167253f4e170 4989 c = bits % 57;
wolfSSL 14:167253f4e170 4990 if (c == 0)
wolfSSL 14:167253f4e170 4991 c = 57;
wolfSSL 14:167253f4e170 4992 if (i < 27)
wolfSSL 14:167253f4e170 4993 n = e[i--] << (64 - c);
wolfSSL 14:167253f4e170 4994 else {
wolfSSL 14:167253f4e170 4995 n = 0;
wolfSSL 14:167253f4e170 4996 i--;
wolfSSL 14:167253f4e170 4997 }
wolfSSL 14:167253f4e170 4998 if (c < 5) {
wolfSSL 14:167253f4e170 4999 n |= e[i--] << (7 - c);
wolfSSL 14:167253f4e170 5000 c += 57;
wolfSSL 14:167253f4e170 5001 }
wolfSSL 14:167253f4e170 5002 y = n >> 59;
wolfSSL 14:167253f4e170 5003 n <<= 5;
wolfSSL 14:167253f4e170 5004 c -= 5;
wolfSSL 14:167253f4e170 5005 XMEMCPY(rt, t[y], sizeof(rt));
wolfSSL 14:167253f4e170 5006 for (; i>=0 || c>=5; ) {
wolfSSL 14:167253f4e170 5007 if (c < 5) {
wolfSSL 14:167253f4e170 5008 n |= e[i--] << (7 - c);
wolfSSL 14:167253f4e170 5009 c += 57;
wolfSSL 14:167253f4e170 5010 }
wolfSSL 14:167253f4e170 5011 y = (n >> 59) & 0x1f;
wolfSSL 14:167253f4e170 5012 n <<= 5;
wolfSSL 14:167253f4e170 5013 c -= 5;
wolfSSL 14:167253f4e170 5014
wolfSSL 14:167253f4e170 5015 sp_3072_mont_sqr_27(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5016 sp_3072_mont_sqr_27(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5017 sp_3072_mont_sqr_27(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5018 sp_3072_mont_sqr_27(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5019 sp_3072_mont_sqr_27(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5020
wolfSSL 14:167253f4e170 5021 sp_3072_mont_mul_27(rt, rt, t[y], m, mp);
wolfSSL 14:167253f4e170 5022 }
wolfSSL 14:167253f4e170 5023
wolfSSL 14:167253f4e170 5024 sp_3072_mont_reduce_27(rt, m, mp);
wolfSSL 14:167253f4e170 5025 n = sp_3072_cmp_27(rt, m);
wolfSSL 14:167253f4e170 5026 sp_3072_cond_sub_27(rt, rt, m, (n < 0) - 1);
wolfSSL 14:167253f4e170 5027 XMEMCPY(r, rt, sizeof(rt));
wolfSSL 14:167253f4e170 5028 }
wolfSSL 14:167253f4e170 5029
wolfSSL 14:167253f4e170 5030 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5031 if (td != NULL)
wolfSSL 14:167253f4e170 5032 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5033 #endif
wolfSSL 14:167253f4e170 5034
wolfSSL 14:167253f4e170 5035 return err;
wolfSSL 14:167253f4e170 5036 #endif
wolfSSL 14:167253f4e170 5037 }
wolfSSL 14:167253f4e170 5038
wolfSSL 14:167253f4e170 5039 #endif /* !SP_RSA_PRIVATE_EXP_D && WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 5040
wolfSSL 14:167253f4e170 5041 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 14:167253f4e170 5042 * Given m must be 3072 bits, just need to subtract.
wolfSSL 14:167253f4e170 5043 *
wolfSSL 14:167253f4e170 5044 * r A single precision number.
wolfSSL 14:167253f4e170 5045 * m A signle precision number.
wolfSSL 14:167253f4e170 5046 */
wolfSSL 14:167253f4e170 5047 static void sp_3072_mont_norm_54(sp_digit* r, sp_digit* m)
wolfSSL 14:167253f4e170 5048 {
wolfSSL 14:167253f4e170 5049 /* Set r = 2^n - 1. */
wolfSSL 14:167253f4e170 5050 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5051 int i;
wolfSSL 14:167253f4e170 5052
wolfSSL 14:167253f4e170 5053 for (i=0; i<53; i++)
wolfSSL 14:167253f4e170 5054 r[i] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5055 #else
wolfSSL 14:167253f4e170 5056 int i;
wolfSSL 14:167253f4e170 5057
wolfSSL 14:167253f4e170 5058 for (i = 0; i < 48; i += 8) {
wolfSSL 14:167253f4e170 5059 r[i + 0] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5060 r[i + 1] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5061 r[i + 2] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5062 r[i + 3] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5063 r[i + 4] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5064 r[i + 5] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5065 r[i + 6] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5066 r[i + 7] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5067 }
wolfSSL 14:167253f4e170 5068 r[48] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5069 r[49] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5070 r[50] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5071 r[51] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5072 r[52] = 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5073 #endif
wolfSSL 14:167253f4e170 5074 r[53] = 0x7ffffffffffffl;
wolfSSL 14:167253f4e170 5075
wolfSSL 14:167253f4e170 5076 /* r = (2^n - 1) mod n */
wolfSSL 14:167253f4e170 5077 sp_3072_sub_54(r, r, m);
wolfSSL 14:167253f4e170 5078
wolfSSL 14:167253f4e170 5079 /* Add one so r = 2^n mod m */
wolfSSL 14:167253f4e170 5080 r[0] += 1;
wolfSSL 14:167253f4e170 5081 }
wolfSSL 14:167253f4e170 5082
wolfSSL 14:167253f4e170 5083 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 5084 *
wolfSSL 14:167253f4e170 5085 * a A single precision integer.
wolfSSL 14:167253f4e170 5086 * b A single precision integer.
wolfSSL 14:167253f4e170 5087 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 5088 * respectively.
wolfSSL 14:167253f4e170 5089 */
wolfSSL 14:167253f4e170 5090 static sp_digit sp_3072_cmp_54(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 5091 {
wolfSSL 14:167253f4e170 5092 sp_digit r = 0;
wolfSSL 14:167253f4e170 5093 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5094 int i;
wolfSSL 14:167253f4e170 5095
wolfSSL 14:167253f4e170 5096 for (i=53; i>=0; i--)
wolfSSL 14:167253f4e170 5097 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 5098 #else
wolfSSL 14:167253f4e170 5099 int i;
wolfSSL 14:167253f4e170 5100
wolfSSL 14:167253f4e170 5101 r |= (a[53] - b[53]) & (0 - !r);
wolfSSL 14:167253f4e170 5102 r |= (a[52] - b[52]) & (0 - !r);
wolfSSL 14:167253f4e170 5103 r |= (a[51] - b[51]) & (0 - !r);
wolfSSL 14:167253f4e170 5104 r |= (a[50] - b[50]) & (0 - !r);
wolfSSL 14:167253f4e170 5105 r |= (a[49] - b[49]) & (0 - !r);
wolfSSL 14:167253f4e170 5106 r |= (a[48] - b[48]) & (0 - !r);
wolfSSL 14:167253f4e170 5107 for (i = 40; i >= 0; i -= 8) {
wolfSSL 14:167253f4e170 5108 r |= (a[i + 7] - b[i + 7]) & (0 - !r);
wolfSSL 14:167253f4e170 5109 r |= (a[i + 6] - b[i + 6]) & (0 - !r);
wolfSSL 14:167253f4e170 5110 r |= (a[i + 5] - b[i + 5]) & (0 - !r);
wolfSSL 14:167253f4e170 5111 r |= (a[i + 4] - b[i + 4]) & (0 - !r);
wolfSSL 14:167253f4e170 5112 r |= (a[i + 3] - b[i + 3]) & (0 - !r);
wolfSSL 14:167253f4e170 5113 r |= (a[i + 2] - b[i + 2]) & (0 - !r);
wolfSSL 14:167253f4e170 5114 r |= (a[i + 1] - b[i + 1]) & (0 - !r);
wolfSSL 14:167253f4e170 5115 r |= (a[i + 0] - b[i + 0]) & (0 - !r);
wolfSSL 14:167253f4e170 5116 }
wolfSSL 14:167253f4e170 5117 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5118
wolfSSL 14:167253f4e170 5119 return r;
wolfSSL 14:167253f4e170 5120 }
wolfSSL 14:167253f4e170 5121
wolfSSL 14:167253f4e170 5122 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 5123 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 5124 *
wolfSSL 14:167253f4e170 5125 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 5126 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 5127 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 5128 * m Mask value to apply.
wolfSSL 14:167253f4e170 5129 */
wolfSSL 14:167253f4e170 5130 static void sp_3072_cond_sub_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5131 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 5132 {
wolfSSL 14:167253f4e170 5133 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5134 int i;
wolfSSL 14:167253f4e170 5135
wolfSSL 14:167253f4e170 5136 for (i = 0; i < 54; i++)
wolfSSL 14:167253f4e170 5137 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 5138 #else
wolfSSL 14:167253f4e170 5139 int i;
wolfSSL 14:167253f4e170 5140
wolfSSL 14:167253f4e170 5141 for (i = 0; i < 48; i += 8) {
wolfSSL 14:167253f4e170 5142 r[i + 0] = a[i + 0] - (b[i + 0] & m);
wolfSSL 14:167253f4e170 5143 r[i + 1] = a[i + 1] - (b[i + 1] & m);
wolfSSL 14:167253f4e170 5144 r[i + 2] = a[i + 2] - (b[i + 2] & m);
wolfSSL 14:167253f4e170 5145 r[i + 3] = a[i + 3] - (b[i + 3] & m);
wolfSSL 14:167253f4e170 5146 r[i + 4] = a[i + 4] - (b[i + 4] & m);
wolfSSL 14:167253f4e170 5147 r[i + 5] = a[i + 5] - (b[i + 5] & m);
wolfSSL 14:167253f4e170 5148 r[i + 6] = a[i + 6] - (b[i + 6] & m);
wolfSSL 14:167253f4e170 5149 r[i + 7] = a[i + 7] - (b[i + 7] & m);
wolfSSL 14:167253f4e170 5150 }
wolfSSL 14:167253f4e170 5151 r[48] = a[48] - (b[48] & m);
wolfSSL 14:167253f4e170 5152 r[49] = a[49] - (b[49] & m);
wolfSSL 14:167253f4e170 5153 r[50] = a[50] - (b[50] & m);
wolfSSL 14:167253f4e170 5154 r[51] = a[51] - (b[51] & m);
wolfSSL 14:167253f4e170 5155 r[52] = a[52] - (b[52] & m);
wolfSSL 14:167253f4e170 5156 r[53] = a[53] - (b[53] & m);
wolfSSL 14:167253f4e170 5157 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5158 }
wolfSSL 14:167253f4e170 5159
wolfSSL 14:167253f4e170 5160 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 5161 *
wolfSSL 14:167253f4e170 5162 * r A single precision integer.
wolfSSL 14:167253f4e170 5163 * a A single precision integer.
wolfSSL 14:167253f4e170 5164 * b A scalar.
wolfSSL 14:167253f4e170 5165 */
wolfSSL 14:167253f4e170 5166 SP_NOINLINE static void sp_3072_mul_add_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5167 const sp_digit b)
wolfSSL 14:167253f4e170 5168 {
wolfSSL 14:167253f4e170 5169 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5170 int128_t tb = b;
wolfSSL 14:167253f4e170 5171 int128_t t = 0;
wolfSSL 14:167253f4e170 5172 int i;
wolfSSL 14:167253f4e170 5173
wolfSSL 14:167253f4e170 5174 for (i = 0; i < 54; i++) {
wolfSSL 14:167253f4e170 5175 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 5176 r[i] = t & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5177 t >>= 57;
wolfSSL 14:167253f4e170 5178 }
wolfSSL 14:167253f4e170 5179 r[54] += t;
wolfSSL 14:167253f4e170 5180 #else
wolfSSL 14:167253f4e170 5181 int128_t tb = b;
wolfSSL 14:167253f4e170 5182 int128_t t[8];
wolfSSL 14:167253f4e170 5183 int i;
wolfSSL 14:167253f4e170 5184
wolfSSL 14:167253f4e170 5185 t[0] = tb * a[0]; r[0] += t[0] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5186 for (i = 0; i < 48; i += 8) {
wolfSSL 14:167253f4e170 5187 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 5188 r[i+1] += (t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5189 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 5190 r[i+2] += (t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5191 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 5192 r[i+3] += (t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5193 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 5194 r[i+4] += (t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5195 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 5196 r[i+5] += (t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5197 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 5198 r[i+6] += (t[5] >> 57) + (t[6] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5199 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 5200 r[i+7] += (t[6] >> 57) + (t[7] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5201 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 5202 r[i+8] += (t[7] >> 57) + (t[0] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5203 }
wolfSSL 14:167253f4e170 5204 t[1] = tb * a[49]; r[49] += (t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5205 t[2] = tb * a[50]; r[50] += (t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5206 t[3] = tb * a[51]; r[51] += (t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5207 t[4] = tb * a[52]; r[52] += (t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5208 t[5] = tb * a[53]; r[53] += (t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5209 r[54] += t[5] >> 57;
wolfSSL 14:167253f4e170 5210 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5211 }
wolfSSL 14:167253f4e170 5212
wolfSSL 14:167253f4e170 5213 /* Normalize the values in each word to 57.
wolfSSL 14:167253f4e170 5214 *
wolfSSL 14:167253f4e170 5215 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 5216 */
wolfSSL 14:167253f4e170 5217 static void sp_3072_norm_54(sp_digit* a)
wolfSSL 14:167253f4e170 5218 {
wolfSSL 14:167253f4e170 5219 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5220 int i;
wolfSSL 14:167253f4e170 5221 for (i = 0; i < 53; i++) {
wolfSSL 14:167253f4e170 5222 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 5223 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5224 }
wolfSSL 14:167253f4e170 5225 #else
wolfSSL 14:167253f4e170 5226 int i;
wolfSSL 14:167253f4e170 5227 for (i = 0; i < 48; i += 8) {
wolfSSL 14:167253f4e170 5228 a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5229 a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5230 a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5231 a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5232 a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5233 a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5234 a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5235 a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5236 a[i+9] += a[i+8] >> 57; a[i+8] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5237 }
wolfSSL 14:167253f4e170 5238 a[48+1] += a[48] >> 57;
wolfSSL 14:167253f4e170 5239 a[48] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5240 a[49+1] += a[49] >> 57;
wolfSSL 14:167253f4e170 5241 a[49] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5242 a[50+1] += a[50] >> 57;
wolfSSL 14:167253f4e170 5243 a[50] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5244 a[51+1] += a[51] >> 57;
wolfSSL 14:167253f4e170 5245 a[51] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5246 a[52+1] += a[52] >> 57;
wolfSSL 14:167253f4e170 5247 a[52] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5248 #endif
wolfSSL 14:167253f4e170 5249 }
wolfSSL 14:167253f4e170 5250
wolfSSL 14:167253f4e170 5251 /* Shift the result in the high 3072 bits down to the bottom.
wolfSSL 14:167253f4e170 5252 *
wolfSSL 14:167253f4e170 5253 * r A single precision number.
wolfSSL 14:167253f4e170 5254 * a A single precision number.
wolfSSL 14:167253f4e170 5255 */
wolfSSL 14:167253f4e170 5256 static void sp_3072_mont_shift_54(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 5257 {
wolfSSL 14:167253f4e170 5258 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5259 int i;
wolfSSL 14:167253f4e170 5260 int128_t n = a[53] >> 51;
wolfSSL 14:167253f4e170 5261 n += ((int128_t)a[54]) << 6;
wolfSSL 14:167253f4e170 5262
wolfSSL 14:167253f4e170 5263 for (i = 0; i < 53; i++) {
wolfSSL 14:167253f4e170 5264 r[i] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5265 n >>= 57;
wolfSSL 14:167253f4e170 5266 n += ((int128_t)a[55 + i]) << 6;
wolfSSL 14:167253f4e170 5267 }
wolfSSL 14:167253f4e170 5268 r[53] = (sp_digit)n;
wolfSSL 14:167253f4e170 5269 #else
wolfSSL 14:167253f4e170 5270 int i;
wolfSSL 14:167253f4e170 5271 int128_t n = a[53] >> 51;
wolfSSL 14:167253f4e170 5272 n += ((int128_t)a[54]) << 6;
wolfSSL 14:167253f4e170 5273 for (i = 0; i < 48; i += 8) {
wolfSSL 14:167253f4e170 5274 r[i + 0] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5275 n >>= 57; n += ((int128_t)a[i + 55]) << 6;
wolfSSL 14:167253f4e170 5276 r[i + 1] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5277 n >>= 57; n += ((int128_t)a[i + 56]) << 6;
wolfSSL 14:167253f4e170 5278 r[i + 2] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5279 n >>= 57; n += ((int128_t)a[i + 57]) << 6;
wolfSSL 14:167253f4e170 5280 r[i + 3] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5281 n >>= 57; n += ((int128_t)a[i + 58]) << 6;
wolfSSL 14:167253f4e170 5282 r[i + 4] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5283 n >>= 57; n += ((int128_t)a[i + 59]) << 6;
wolfSSL 14:167253f4e170 5284 r[i + 5] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5285 n >>= 57; n += ((int128_t)a[i + 60]) << 6;
wolfSSL 14:167253f4e170 5286 r[i + 6] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5287 n >>= 57; n += ((int128_t)a[i + 61]) << 6;
wolfSSL 14:167253f4e170 5288 r[i + 7] = n & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5289 n >>= 57; n += ((int128_t)a[i + 62]) << 6;
wolfSSL 14:167253f4e170 5290 }
wolfSSL 14:167253f4e170 5291 r[48] = n & 0x1ffffffffffffffl; n >>= 57; n += ((int128_t)a[103]) << 6;
wolfSSL 14:167253f4e170 5292 r[49] = n & 0x1ffffffffffffffl; n >>= 57; n += ((int128_t)a[104]) << 6;
wolfSSL 14:167253f4e170 5293 r[50] = n & 0x1ffffffffffffffl; n >>= 57; n += ((int128_t)a[105]) << 6;
wolfSSL 14:167253f4e170 5294 r[51] = n & 0x1ffffffffffffffl; n >>= 57; n += ((int128_t)a[106]) << 6;
wolfSSL 14:167253f4e170 5295 r[52] = n & 0x1ffffffffffffffl; n >>= 57; n += ((int128_t)a[107]) << 6;
wolfSSL 14:167253f4e170 5296 r[53] = (sp_digit)n;
wolfSSL 14:167253f4e170 5297 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5298 XMEMSET(&r[54], 0, sizeof(*r) * 54);
wolfSSL 14:167253f4e170 5299 }
wolfSSL 14:167253f4e170 5300
wolfSSL 14:167253f4e170 5301 /* Reduce the number back to 3072 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 5302 *
wolfSSL 14:167253f4e170 5303 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 5304 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 5305 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 5306 */
wolfSSL 14:167253f4e170 5307 static void sp_3072_mont_reduce_54(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 5308 {
wolfSSL 14:167253f4e170 5309 int i;
wolfSSL 14:167253f4e170 5310 sp_digit mu;
wolfSSL 14:167253f4e170 5311
wolfSSL 14:167253f4e170 5312 if (mp != 1) {
wolfSSL 14:167253f4e170 5313 for (i=0; i<53; i++) {
wolfSSL 14:167253f4e170 5314 mu = (a[i] * mp) & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5315 sp_3072_mul_add_54(a+i, m, mu);
wolfSSL 14:167253f4e170 5316 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 5317 }
wolfSSL 14:167253f4e170 5318 mu = (a[i] * mp) & 0x7ffffffffffffl;
wolfSSL 14:167253f4e170 5319 sp_3072_mul_add_54(a+i, m, mu);
wolfSSL 14:167253f4e170 5320 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 5321 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5322 }
wolfSSL 14:167253f4e170 5323 else {
wolfSSL 14:167253f4e170 5324 for (i=0; i<53; i++) {
wolfSSL 14:167253f4e170 5325 mu = a[i] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5326 sp_3072_mul_add_54(a+i, m, mu);
wolfSSL 14:167253f4e170 5327 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 5328 }
wolfSSL 14:167253f4e170 5329 mu = a[i] & 0x7ffffffffffffl;
wolfSSL 14:167253f4e170 5330 sp_3072_mul_add_54(a+i, m, mu);
wolfSSL 14:167253f4e170 5331 a[i+1] += a[i] >> 57;
wolfSSL 14:167253f4e170 5332 a[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5333 }
wolfSSL 14:167253f4e170 5334
wolfSSL 14:167253f4e170 5335 sp_3072_mont_shift_54(a, a);
wolfSSL 14:167253f4e170 5336 sp_3072_cond_sub_54(a, a, m, 0 - ((a[53] >> 51) > 0));
wolfSSL 14:167253f4e170 5337 sp_3072_norm_54(a);
wolfSSL 14:167253f4e170 5338 }
wolfSSL 14:167253f4e170 5339
wolfSSL 14:167253f4e170 5340 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 5341 * (r = a * b mod m)
wolfSSL 14:167253f4e170 5342 *
wolfSSL 14:167253f4e170 5343 * r Result of multiplication.
wolfSSL 14:167253f4e170 5344 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 5345 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 5346 * m Modulus (prime).
wolfSSL 14:167253f4e170 5347 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 5348 */
wolfSSL 14:167253f4e170 5349 static void sp_3072_mont_mul_54(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 5350 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 5351 {
wolfSSL 14:167253f4e170 5352 sp_3072_mul_54(r, a, b);
wolfSSL 14:167253f4e170 5353 sp_3072_mont_reduce_54(r, m, mp);
wolfSSL 14:167253f4e170 5354 }
wolfSSL 14:167253f4e170 5355
wolfSSL 14:167253f4e170 5356 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 5357 *
wolfSSL 14:167253f4e170 5358 * r Result of squaring.
wolfSSL 14:167253f4e170 5359 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 5360 * m Modulus (prime).
wolfSSL 14:167253f4e170 5361 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 5362 */
wolfSSL 14:167253f4e170 5363 static void sp_3072_mont_sqr_54(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 5364 sp_digit mp)
wolfSSL 14:167253f4e170 5365 {
wolfSSL 14:167253f4e170 5366 sp_3072_sqr_54(r, a);
wolfSSL 14:167253f4e170 5367 sp_3072_mont_reduce_54(r, m, mp);
wolfSSL 14:167253f4e170 5368 }
wolfSSL 14:167253f4e170 5369
wolfSSL 14:167253f4e170 5370 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 5371 *
wolfSSL 14:167253f4e170 5372 * r A single precision integer.
wolfSSL 14:167253f4e170 5373 * a A single precision integer.
wolfSSL 14:167253f4e170 5374 * b A scalar.
wolfSSL 14:167253f4e170 5375 */
wolfSSL 14:167253f4e170 5376 SP_NOINLINE static void sp_3072_mul_d_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5377 const sp_digit b)
wolfSSL 14:167253f4e170 5378 {
wolfSSL 14:167253f4e170 5379 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5380 int128_t tb = b;
wolfSSL 14:167253f4e170 5381 int128_t t = 0;
wolfSSL 14:167253f4e170 5382 int i;
wolfSSL 14:167253f4e170 5383
wolfSSL 14:167253f4e170 5384 for (i = 0; i < 54; i++) {
wolfSSL 14:167253f4e170 5385 t += tb * a[i];
wolfSSL 14:167253f4e170 5386 r[i] = t & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5387 t >>= 57;
wolfSSL 14:167253f4e170 5388 }
wolfSSL 14:167253f4e170 5389 r[54] = (sp_digit)t;
wolfSSL 14:167253f4e170 5390 #else
wolfSSL 14:167253f4e170 5391 int128_t tb = b;
wolfSSL 14:167253f4e170 5392 int128_t t[8];
wolfSSL 14:167253f4e170 5393 int i;
wolfSSL 14:167253f4e170 5394
wolfSSL 14:167253f4e170 5395 t[0] = tb * a[0]; r[0] = t[0] & 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5396 for (i = 0; i < 48; i += 8) {
wolfSSL 14:167253f4e170 5397 t[1] = tb * a[i+1];
wolfSSL 14:167253f4e170 5398 r[i+1] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5399 t[2] = tb * a[i+2];
wolfSSL 14:167253f4e170 5400 r[i+2] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5401 t[3] = tb * a[i+3];
wolfSSL 14:167253f4e170 5402 r[i+3] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5403 t[4] = tb * a[i+4];
wolfSSL 14:167253f4e170 5404 r[i+4] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5405 t[5] = tb * a[i+5];
wolfSSL 14:167253f4e170 5406 r[i+5] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5407 t[6] = tb * a[i+6];
wolfSSL 14:167253f4e170 5408 r[i+6] = (sp_digit)(t[5] >> 57) + (t[6] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5409 t[7] = tb * a[i+7];
wolfSSL 14:167253f4e170 5410 r[i+7] = (sp_digit)(t[6] >> 57) + (t[7] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5411 t[0] = tb * a[i+8];
wolfSSL 14:167253f4e170 5412 r[i+8] = (sp_digit)(t[7] >> 57) + (t[0] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5413 }
wolfSSL 14:167253f4e170 5414 t[1] = tb * a[49];
wolfSSL 14:167253f4e170 5415 r[49] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5416 t[2] = tb * a[50];
wolfSSL 14:167253f4e170 5417 r[50] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5418 t[3] = tb * a[51];
wolfSSL 14:167253f4e170 5419 r[51] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5420 t[4] = tb * a[52];
wolfSSL 14:167253f4e170 5421 r[52] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5422 t[5] = tb * a[53];
wolfSSL 14:167253f4e170 5423 r[53] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffl);
wolfSSL 14:167253f4e170 5424 r[54] = (sp_digit)(t[5] >> 57);
wolfSSL 14:167253f4e170 5425 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5426 }
wolfSSL 14:167253f4e170 5427
wolfSSL 14:167253f4e170 5428 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 5429 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 5430 *
wolfSSL 14:167253f4e170 5431 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 5432 * a A single precision number to add with.
wolfSSL 14:167253f4e170 5433 * b A single precision number to add.
wolfSSL 14:167253f4e170 5434 * m Mask value to apply.
wolfSSL 14:167253f4e170 5435 */
wolfSSL 14:167253f4e170 5436 static void sp_3072_cond_add_54(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 5437 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 5438 {
wolfSSL 14:167253f4e170 5439 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5440 int i;
wolfSSL 14:167253f4e170 5441
wolfSSL 14:167253f4e170 5442 for (i = 0; i < 54; i++)
wolfSSL 14:167253f4e170 5443 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 5444 #else
wolfSSL 14:167253f4e170 5445 int i;
wolfSSL 14:167253f4e170 5446
wolfSSL 14:167253f4e170 5447 for (i = 0; i < 48; i += 8) {
wolfSSL 14:167253f4e170 5448 r[i + 0] = a[i + 0] + (b[i + 0] & m);
wolfSSL 14:167253f4e170 5449 r[i + 1] = a[i + 1] + (b[i + 1] & m);
wolfSSL 14:167253f4e170 5450 r[i + 2] = a[i + 2] + (b[i + 2] & m);
wolfSSL 14:167253f4e170 5451 r[i + 3] = a[i + 3] + (b[i + 3] & m);
wolfSSL 14:167253f4e170 5452 r[i + 4] = a[i + 4] + (b[i + 4] & m);
wolfSSL 14:167253f4e170 5453 r[i + 5] = a[i + 5] + (b[i + 5] & m);
wolfSSL 14:167253f4e170 5454 r[i + 6] = a[i + 6] + (b[i + 6] & m);
wolfSSL 14:167253f4e170 5455 r[i + 7] = a[i + 7] + (b[i + 7] & m);
wolfSSL 14:167253f4e170 5456 }
wolfSSL 14:167253f4e170 5457 r[48] = a[48] + (b[48] & m);
wolfSSL 14:167253f4e170 5458 r[49] = a[49] + (b[49] & m);
wolfSSL 14:167253f4e170 5459 r[50] = a[50] + (b[50] & m);
wolfSSL 14:167253f4e170 5460 r[51] = a[51] + (b[51] & m);
wolfSSL 14:167253f4e170 5461 r[52] = a[52] + (b[52] & m);
wolfSSL 14:167253f4e170 5462 r[53] = a[53] + (b[53] & m);
wolfSSL 14:167253f4e170 5463 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 5464 }
wolfSSL 14:167253f4e170 5465
wolfSSL 14:167253f4e170 5466 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 5467 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 5468 *
wolfSSL 14:167253f4e170 5469 * a Nmber to be divided.
wolfSSL 14:167253f4e170 5470 * d Number to divide with.
wolfSSL 14:167253f4e170 5471 * m Multiplier result.
wolfSSL 14:167253f4e170 5472 * r Remainder from the division.
wolfSSL 14:167253f4e170 5473 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 5474 */
wolfSSL 14:167253f4e170 5475 static int sp_3072_div_54(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 5476 sp_digit* r)
wolfSSL 14:167253f4e170 5477 {
wolfSSL 14:167253f4e170 5478 int i;
wolfSSL 14:167253f4e170 5479 int128_t d1;
wolfSSL 14:167253f4e170 5480 sp_digit div, r1;
wolfSSL 14:167253f4e170 5481 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 5482 sp_digit* td;
wolfSSL 14:167253f4e170 5483 #else
wolfSSL 14:167253f4e170 5484 sp_digit t1d[108], t2d[54 + 1];
wolfSSL 14:167253f4e170 5485 #endif
wolfSSL 14:167253f4e170 5486 sp_digit* t1;
wolfSSL 14:167253f4e170 5487 sp_digit* t2;
wolfSSL 14:167253f4e170 5488 int err = MP_OKAY;
wolfSSL 14:167253f4e170 5489
wolfSSL 14:167253f4e170 5490 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 5491 td = XMALLOC(sizeof(sp_digit) * (3 * 54 + 1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5492 if (td != NULL) {
wolfSSL 14:167253f4e170 5493 t1 = td;
wolfSSL 14:167253f4e170 5494 t2 = td + 2 * 54;
wolfSSL 14:167253f4e170 5495 }
wolfSSL 14:167253f4e170 5496 else
wolfSSL 14:167253f4e170 5497 err = MEMORY_E;
wolfSSL 14:167253f4e170 5498 #else
wolfSSL 14:167253f4e170 5499 t1 = t1d;
wolfSSL 14:167253f4e170 5500 t2 = t2d;
wolfSSL 14:167253f4e170 5501 #endif
wolfSSL 14:167253f4e170 5502
wolfSSL 14:167253f4e170 5503 (void)m;
wolfSSL 14:167253f4e170 5504
wolfSSL 14:167253f4e170 5505 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5506 div = d[53];
wolfSSL 14:167253f4e170 5507 XMEMCPY(t1, a, sizeof(*t1) * 2 * 54);
wolfSSL 14:167253f4e170 5508 for (i=53; i>=0; i--) {
wolfSSL 14:167253f4e170 5509 t1[54 + i] += t1[54 + i - 1] >> 57;
wolfSSL 14:167253f4e170 5510 t1[54 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5511 d1 = t1[54 + i];
wolfSSL 14:167253f4e170 5512 d1 <<= 57;
wolfSSL 14:167253f4e170 5513 d1 += t1[54 + i - 1];
wolfSSL 14:167253f4e170 5514 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 5515
wolfSSL 14:167253f4e170 5516 sp_3072_mul_d_54(t2, d, r1);
wolfSSL 14:167253f4e170 5517 sp_3072_sub_54(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 5518 t1[54 + i] -= t2[54];
wolfSSL 14:167253f4e170 5519 t1[54 + i] += t1[54 + i - 1] >> 57;
wolfSSL 14:167253f4e170 5520 t1[54 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5521 r1 = (((-t1[54 + i]) << 57) - t1[54 + i - 1]) / div;
wolfSSL 14:167253f4e170 5522 r1++;
wolfSSL 14:167253f4e170 5523 sp_3072_mul_d_54(t2, d, r1);
wolfSSL 14:167253f4e170 5524 sp_3072_add_54(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 5525 t1[54 + i] += t1[54 + i - 1] >> 57;
wolfSSL 14:167253f4e170 5526 t1[54 + i - 1] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5527 }
wolfSSL 14:167253f4e170 5528 t1[54 - 1] += t1[54 - 2] >> 57;
wolfSSL 14:167253f4e170 5529 t1[54 - 2] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5530 d1 = t1[54 - 1];
wolfSSL 14:167253f4e170 5531 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 5532
wolfSSL 14:167253f4e170 5533 sp_3072_mul_d_54(t2, d, r1);
wolfSSL 14:167253f4e170 5534 sp_3072_sub_54(t1, t1, t2);
wolfSSL 14:167253f4e170 5535 XMEMCPY(r, t1, sizeof(*r) * 2 * 54);
wolfSSL 14:167253f4e170 5536 for (i=0; i<52; i++) {
wolfSSL 14:167253f4e170 5537 r[i+1] += r[i] >> 57;
wolfSSL 14:167253f4e170 5538 r[i] &= 0x1ffffffffffffffl;
wolfSSL 14:167253f4e170 5539 }
wolfSSL 14:167253f4e170 5540 sp_3072_cond_add_54(r, r, d, 0 - (r[53] < 0));
wolfSSL 14:167253f4e170 5541 }
wolfSSL 14:167253f4e170 5542
wolfSSL 14:167253f4e170 5543 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 5544 if (td != NULL)
wolfSSL 14:167253f4e170 5545 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5546 #endif
wolfSSL 14:167253f4e170 5547
wolfSSL 14:167253f4e170 5548 return err;
wolfSSL 14:167253f4e170 5549 }
wolfSSL 14:167253f4e170 5550
wolfSSL 14:167253f4e170 5551 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 5552 *
wolfSSL 14:167253f4e170 5553 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 5554 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 5555 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 5556 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 5557 */
wolfSSL 14:167253f4e170 5558 static int sp_3072_mod_54(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 5559 {
wolfSSL 14:167253f4e170 5560 return sp_3072_div_54(a, m, NULL, r);
wolfSSL 14:167253f4e170 5561 }
wolfSSL 14:167253f4e170 5562
wolfSSL 14:167253f4e170 5563 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 14:167253f4e170 5564 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 14:167253f4e170 5565 *
wolfSSL 14:167253f4e170 5566 * r A single precision number that is the result of the operation.
wolfSSL 14:167253f4e170 5567 * a A single precision number being exponentiated.
wolfSSL 14:167253f4e170 5568 * e A single precision number that is the exponent.
wolfSSL 14:167253f4e170 5569 * bits The number of bits in the exponent.
wolfSSL 14:167253f4e170 5570 * m A single precision number that is the modulus.
wolfSSL 14:167253f4e170 5571 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 14:167253f4e170 5572 */
wolfSSL 14:167253f4e170 5573 static int sp_3072_mod_exp_54(sp_digit* r, sp_digit* a, sp_digit* e, int bits,
wolfSSL 14:167253f4e170 5574 sp_digit* m, int reduceA)
wolfSSL 14:167253f4e170 5575 {
wolfSSL 14:167253f4e170 5576 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5577 sp_digit* td;
wolfSSL 14:167253f4e170 5578 sp_digit* t[3];
wolfSSL 14:167253f4e170 5579 sp_digit* norm;
wolfSSL 14:167253f4e170 5580 sp_digit mp = 1;
wolfSSL 14:167253f4e170 5581 sp_digit n;
wolfSSL 14:167253f4e170 5582 int i;
wolfSSL 14:167253f4e170 5583 int c, y;
wolfSSL 14:167253f4e170 5584 int err = MP_OKAY;
wolfSSL 14:167253f4e170 5585
wolfSSL 14:167253f4e170 5586 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 54 * 2, NULL,
wolfSSL 14:167253f4e170 5587 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5588 if (td == NULL)
wolfSSL 14:167253f4e170 5589 err = MEMORY_E;
wolfSSL 14:167253f4e170 5590
wolfSSL 14:167253f4e170 5591 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5592 XMEMSET(td, 0, sizeof(*td) * 3 * 54 * 2);
wolfSSL 14:167253f4e170 5593
wolfSSL 14:167253f4e170 5594 norm = t[0] = td;
wolfSSL 14:167253f4e170 5595 t[1] = &td[54 * 2];
wolfSSL 14:167253f4e170 5596 t[2] = &td[2 * 54 * 2];
wolfSSL 14:167253f4e170 5597
wolfSSL 14:167253f4e170 5598 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 5599 sp_3072_mont_norm_54(norm, m);
wolfSSL 14:167253f4e170 5600
wolfSSL 14:167253f4e170 5601 if (reduceA)
wolfSSL 14:167253f4e170 5602 err = sp_3072_mod_54(t[1], a, m);
wolfSSL 14:167253f4e170 5603 else
wolfSSL 14:167253f4e170 5604 XMEMCPY(t[1], a, sizeof(sp_digit) * 54);
wolfSSL 14:167253f4e170 5605 }
wolfSSL 14:167253f4e170 5606 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5607 sp_3072_mul_54(t[1], t[1], norm);
wolfSSL 14:167253f4e170 5608 err = sp_3072_mod_54(t[1], t[1], m);
wolfSSL 14:167253f4e170 5609 }
wolfSSL 14:167253f4e170 5610
wolfSSL 14:167253f4e170 5611 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5612 i = bits / 57;
wolfSSL 14:167253f4e170 5613 c = bits % 57;
wolfSSL 14:167253f4e170 5614 n = e[i--] << (57 - c);
wolfSSL 14:167253f4e170 5615 for (; ; c--) {
wolfSSL 14:167253f4e170 5616 if (c == 0) {
wolfSSL 14:167253f4e170 5617 if (i == -1)
wolfSSL 14:167253f4e170 5618 break;
wolfSSL 14:167253f4e170 5619
wolfSSL 14:167253f4e170 5620 n = e[i--];
wolfSSL 14:167253f4e170 5621 c = 57;
wolfSSL 14:167253f4e170 5622 }
wolfSSL 14:167253f4e170 5623
wolfSSL 14:167253f4e170 5624 y = (n >> 56) & 1;
wolfSSL 14:167253f4e170 5625 n <<= 1;
wolfSSL 14:167253f4e170 5626
wolfSSL 14:167253f4e170 5627 sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 5628
wolfSSL 14:167253f4e170 5629 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 5630 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 5631 sizeof(*t[2]) * 54 * 2);
wolfSSL 14:167253f4e170 5632 sp_3072_mont_sqr_54(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 5633 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 5634 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 5635 sizeof(*t[2]) * 54 * 2);
wolfSSL 14:167253f4e170 5636 }
wolfSSL 14:167253f4e170 5637
wolfSSL 14:167253f4e170 5638 sp_3072_mont_reduce_54(t[0], m, mp);
wolfSSL 14:167253f4e170 5639 n = sp_3072_cmp_54(t[0], m);
wolfSSL 14:167253f4e170 5640 sp_3072_cond_sub_54(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 5641 XMEMCPY(r, t[0], sizeof(*r) * 54 * 2);
wolfSSL 14:167253f4e170 5642
wolfSSL 14:167253f4e170 5643 }
wolfSSL 14:167253f4e170 5644
wolfSSL 14:167253f4e170 5645 if (td != NULL)
wolfSSL 14:167253f4e170 5646 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5647
wolfSSL 14:167253f4e170 5648 return err;
wolfSSL 14:167253f4e170 5649 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 5650 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5651 sp_digit t[3][108];
wolfSSL 14:167253f4e170 5652 #else
wolfSSL 14:167253f4e170 5653 sp_digit* td;
wolfSSL 14:167253f4e170 5654 sp_digit* t[3];
wolfSSL 14:167253f4e170 5655 #endif
wolfSSL 14:167253f4e170 5656 sp_digit* norm;
wolfSSL 14:167253f4e170 5657 sp_digit mp = 1;
wolfSSL 14:167253f4e170 5658 sp_digit n;
wolfSSL 14:167253f4e170 5659 int i;
wolfSSL 14:167253f4e170 5660 int c, y;
wolfSSL 14:167253f4e170 5661 int err = MP_OKAY;
wolfSSL 14:167253f4e170 5662
wolfSSL 14:167253f4e170 5663 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5664 td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 54 * 2, NULL,
wolfSSL 14:167253f4e170 5665 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5666 if (td == NULL)
wolfSSL 14:167253f4e170 5667 err = MEMORY_E;
wolfSSL 14:167253f4e170 5668
wolfSSL 14:167253f4e170 5669 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5670 t[0] = td;
wolfSSL 14:167253f4e170 5671 t[1] = &td[54 * 2];
wolfSSL 14:167253f4e170 5672 t[2] = &td[2 * 54 * 2];
wolfSSL 14:167253f4e170 5673 norm = t[0];
wolfSSL 14:167253f4e170 5674 }
wolfSSL 14:167253f4e170 5675 #else
wolfSSL 14:167253f4e170 5676 norm = t[0];
wolfSSL 14:167253f4e170 5677 #endif
wolfSSL 14:167253f4e170 5678
wolfSSL 14:167253f4e170 5679 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5680 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 5681 sp_3072_mont_norm_54(norm, m);
wolfSSL 14:167253f4e170 5682
wolfSSL 14:167253f4e170 5683 if (reduceA) {
wolfSSL 14:167253f4e170 5684 err = sp_3072_mod_54(t[1], a, m);
wolfSSL 14:167253f4e170 5685 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5686 sp_3072_mul_54(t[1], t[1], norm);
wolfSSL 14:167253f4e170 5687 err = sp_3072_mod_54(t[1], t[1], m);
wolfSSL 14:167253f4e170 5688 }
wolfSSL 14:167253f4e170 5689 }
wolfSSL 14:167253f4e170 5690 else {
wolfSSL 14:167253f4e170 5691 sp_3072_mul_54(t[1], a, norm);
wolfSSL 14:167253f4e170 5692 err = sp_3072_mod_54(t[1], t[1], m);
wolfSSL 14:167253f4e170 5693 }
wolfSSL 14:167253f4e170 5694 }
wolfSSL 14:167253f4e170 5695
wolfSSL 14:167253f4e170 5696 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5697 i = bits / 57;
wolfSSL 14:167253f4e170 5698 c = bits % 57;
wolfSSL 14:167253f4e170 5699 n = e[i--] << (57 - c);
wolfSSL 14:167253f4e170 5700 for (; ; c--) {
wolfSSL 14:167253f4e170 5701 if (c == 0) {
wolfSSL 14:167253f4e170 5702 if (i == -1)
wolfSSL 14:167253f4e170 5703 break;
wolfSSL 14:167253f4e170 5704
wolfSSL 14:167253f4e170 5705 n = e[i--];
wolfSSL 14:167253f4e170 5706 c = 57;
wolfSSL 14:167253f4e170 5707 }
wolfSSL 14:167253f4e170 5708
wolfSSL 14:167253f4e170 5709 y = (n >> 56) & 1;
wolfSSL 14:167253f4e170 5710 n <<= 1;
wolfSSL 14:167253f4e170 5711
wolfSSL 14:167253f4e170 5712 sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp);
wolfSSL 14:167253f4e170 5713
wolfSSL 14:167253f4e170 5714 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 5715 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 5716 sp_3072_mont_sqr_54(t[2], t[2], m, mp);
wolfSSL 14:167253f4e170 5717 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 5718 ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 5719 }
wolfSSL 14:167253f4e170 5720
wolfSSL 14:167253f4e170 5721 sp_3072_mont_reduce_54(t[0], m, mp);
wolfSSL 14:167253f4e170 5722 n = sp_3072_cmp_54(t[0], m);
wolfSSL 14:167253f4e170 5723 sp_3072_cond_sub_54(t[0], t[0], m, (n < 0) - 1);
wolfSSL 14:167253f4e170 5724 XMEMCPY(r, t[0], sizeof(t[0]));
wolfSSL 14:167253f4e170 5725 }
wolfSSL 14:167253f4e170 5726
wolfSSL 14:167253f4e170 5727 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5728 if (td != NULL)
wolfSSL 14:167253f4e170 5729 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5730 #endif
wolfSSL 14:167253f4e170 5731
wolfSSL 14:167253f4e170 5732 return err;
wolfSSL 14:167253f4e170 5733 #else
wolfSSL 14:167253f4e170 5734 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5735 sp_digit t[32][108];
wolfSSL 14:167253f4e170 5736 #else
wolfSSL 14:167253f4e170 5737 sp_digit* t[32];
wolfSSL 14:167253f4e170 5738 sp_digit* td;
wolfSSL 14:167253f4e170 5739 #endif
wolfSSL 14:167253f4e170 5740 sp_digit* norm;
wolfSSL 14:167253f4e170 5741 sp_digit rt[108];
wolfSSL 14:167253f4e170 5742 sp_digit mp = 1;
wolfSSL 14:167253f4e170 5743 sp_digit n;
wolfSSL 14:167253f4e170 5744 int i;
wolfSSL 14:167253f4e170 5745 int c, y;
wolfSSL 14:167253f4e170 5746 int err = MP_OKAY;
wolfSSL 14:167253f4e170 5747
wolfSSL 14:167253f4e170 5748 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5749 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 108, NULL,
wolfSSL 14:167253f4e170 5750 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5751 if (td == NULL)
wolfSSL 14:167253f4e170 5752 err = MEMORY_E;
wolfSSL 14:167253f4e170 5753
wolfSSL 14:167253f4e170 5754 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5755 for (i=0; i<32; i++)
wolfSSL 14:167253f4e170 5756 t[i] = td + i * 108;
wolfSSL 14:167253f4e170 5757 norm = t[0];
wolfSSL 14:167253f4e170 5758 }
wolfSSL 14:167253f4e170 5759 #else
wolfSSL 14:167253f4e170 5760 norm = t[0];
wolfSSL 14:167253f4e170 5761 #endif
wolfSSL 14:167253f4e170 5762
wolfSSL 14:167253f4e170 5763 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5764 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 5765 sp_3072_mont_norm_54(norm, m);
wolfSSL 14:167253f4e170 5766
wolfSSL 14:167253f4e170 5767 if (reduceA) {
wolfSSL 14:167253f4e170 5768 err = sp_3072_mod_54(t[1], a, m);
wolfSSL 14:167253f4e170 5769 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5770 sp_3072_mul_54(t[1], t[1], norm);
wolfSSL 14:167253f4e170 5771 err = sp_3072_mod_54(t[1], t[1], m);
wolfSSL 14:167253f4e170 5772 }
wolfSSL 14:167253f4e170 5773 }
wolfSSL 14:167253f4e170 5774 else {
wolfSSL 14:167253f4e170 5775 sp_3072_mul_54(t[1], a, norm);
wolfSSL 14:167253f4e170 5776 err = sp_3072_mod_54(t[1], t[1], m);
wolfSSL 14:167253f4e170 5777 }
wolfSSL 14:167253f4e170 5778 }
wolfSSL 14:167253f4e170 5779
wolfSSL 14:167253f4e170 5780 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5781 sp_3072_mont_sqr_54(t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 5782 sp_3072_mont_mul_54(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 14:167253f4e170 5783 sp_3072_mont_sqr_54(t[ 4], t[ 2], m, mp);
wolfSSL 14:167253f4e170 5784 sp_3072_mont_mul_54(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 14:167253f4e170 5785 sp_3072_mont_sqr_54(t[ 6], t[ 3], m, mp);
wolfSSL 14:167253f4e170 5786 sp_3072_mont_mul_54(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 14:167253f4e170 5787 sp_3072_mont_sqr_54(t[ 8], t[ 4], m, mp);
wolfSSL 14:167253f4e170 5788 sp_3072_mont_mul_54(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 14:167253f4e170 5789 sp_3072_mont_sqr_54(t[10], t[ 5], m, mp);
wolfSSL 14:167253f4e170 5790 sp_3072_mont_mul_54(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 14:167253f4e170 5791 sp_3072_mont_sqr_54(t[12], t[ 6], m, mp);
wolfSSL 14:167253f4e170 5792 sp_3072_mont_mul_54(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 14:167253f4e170 5793 sp_3072_mont_sqr_54(t[14], t[ 7], m, mp);
wolfSSL 14:167253f4e170 5794 sp_3072_mont_mul_54(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 14:167253f4e170 5795 sp_3072_mont_sqr_54(t[16], t[ 8], m, mp);
wolfSSL 14:167253f4e170 5796 sp_3072_mont_mul_54(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 14:167253f4e170 5797 sp_3072_mont_sqr_54(t[18], t[ 9], m, mp);
wolfSSL 14:167253f4e170 5798 sp_3072_mont_mul_54(t[19], t[10], t[ 9], m, mp);
wolfSSL 14:167253f4e170 5799 sp_3072_mont_sqr_54(t[20], t[10], m, mp);
wolfSSL 14:167253f4e170 5800 sp_3072_mont_mul_54(t[21], t[11], t[10], m, mp);
wolfSSL 14:167253f4e170 5801 sp_3072_mont_sqr_54(t[22], t[11], m, mp);
wolfSSL 14:167253f4e170 5802 sp_3072_mont_mul_54(t[23], t[12], t[11], m, mp);
wolfSSL 14:167253f4e170 5803 sp_3072_mont_sqr_54(t[24], t[12], m, mp);
wolfSSL 14:167253f4e170 5804 sp_3072_mont_mul_54(t[25], t[13], t[12], m, mp);
wolfSSL 14:167253f4e170 5805 sp_3072_mont_sqr_54(t[26], t[13], m, mp);
wolfSSL 14:167253f4e170 5806 sp_3072_mont_mul_54(t[27], t[14], t[13], m, mp);
wolfSSL 14:167253f4e170 5807 sp_3072_mont_sqr_54(t[28], t[14], m, mp);
wolfSSL 14:167253f4e170 5808 sp_3072_mont_mul_54(t[29], t[15], t[14], m, mp);
wolfSSL 14:167253f4e170 5809 sp_3072_mont_sqr_54(t[30], t[15], m, mp);
wolfSSL 14:167253f4e170 5810 sp_3072_mont_mul_54(t[31], t[16], t[15], m, mp);
wolfSSL 14:167253f4e170 5811
wolfSSL 14:167253f4e170 5812 bits = ((bits + 4) / 5) * 5;
wolfSSL 14:167253f4e170 5813 i = ((bits + 56) / 57) - 1;
wolfSSL 14:167253f4e170 5814 c = bits % 57;
wolfSSL 14:167253f4e170 5815 if (c == 0)
wolfSSL 14:167253f4e170 5816 c = 57;
wolfSSL 14:167253f4e170 5817 if (i < 54)
wolfSSL 14:167253f4e170 5818 n = e[i--] << (64 - c);
wolfSSL 14:167253f4e170 5819 else {
wolfSSL 14:167253f4e170 5820 n = 0;
wolfSSL 14:167253f4e170 5821 i--;
wolfSSL 14:167253f4e170 5822 }
wolfSSL 14:167253f4e170 5823 if (c < 5) {
wolfSSL 14:167253f4e170 5824 n |= e[i--] << (7 - c);
wolfSSL 14:167253f4e170 5825 c += 57;
wolfSSL 14:167253f4e170 5826 }
wolfSSL 14:167253f4e170 5827 y = n >> 59;
wolfSSL 14:167253f4e170 5828 n <<= 5;
wolfSSL 14:167253f4e170 5829 c -= 5;
wolfSSL 14:167253f4e170 5830 XMEMCPY(rt, t[y], sizeof(rt));
wolfSSL 14:167253f4e170 5831 for (; i>=0 || c>=5; ) {
wolfSSL 14:167253f4e170 5832 if (c < 5) {
wolfSSL 14:167253f4e170 5833 n |= e[i--] << (7 - c);
wolfSSL 14:167253f4e170 5834 c += 57;
wolfSSL 14:167253f4e170 5835 }
wolfSSL 14:167253f4e170 5836 y = (n >> 59) & 0x1f;
wolfSSL 14:167253f4e170 5837 n <<= 5;
wolfSSL 14:167253f4e170 5838 c -= 5;
wolfSSL 14:167253f4e170 5839
wolfSSL 14:167253f4e170 5840 sp_3072_mont_sqr_54(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5841 sp_3072_mont_sqr_54(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5842 sp_3072_mont_sqr_54(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5843 sp_3072_mont_sqr_54(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5844 sp_3072_mont_sqr_54(rt, rt, m, mp);
wolfSSL 14:167253f4e170 5845
wolfSSL 14:167253f4e170 5846 sp_3072_mont_mul_54(rt, rt, t[y], m, mp);
wolfSSL 14:167253f4e170 5847 }
wolfSSL 14:167253f4e170 5848
wolfSSL 14:167253f4e170 5849 sp_3072_mont_reduce_54(rt, m, mp);
wolfSSL 14:167253f4e170 5850 n = sp_3072_cmp_54(rt, m);
wolfSSL 14:167253f4e170 5851 sp_3072_cond_sub_54(rt, rt, m, (n < 0) - 1);
wolfSSL 14:167253f4e170 5852 XMEMCPY(r, rt, sizeof(rt));
wolfSSL 14:167253f4e170 5853 }
wolfSSL 14:167253f4e170 5854
wolfSSL 14:167253f4e170 5855 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 5856 if (td != NULL)
wolfSSL 14:167253f4e170 5857 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5858 #endif
wolfSSL 14:167253f4e170 5859
wolfSSL 14:167253f4e170 5860 return err;
wolfSSL 14:167253f4e170 5861 #endif
wolfSSL 14:167253f4e170 5862 }
wolfSSL 14:167253f4e170 5863 #endif /* SP_RSA_PRIVATE_EXP_D || WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 5864
wolfSSL 14:167253f4e170 5865 #if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \
wolfSSL 14:167253f4e170 5866 !defined(RSA_LOW_MEM)
wolfSSL 14:167253f4e170 5867 /* AND m into each word of a and store in r.
wolfSSL 14:167253f4e170 5868 *
wolfSSL 14:167253f4e170 5869 * r A single precision integer.
wolfSSL 14:167253f4e170 5870 * a A single precision integer.
wolfSSL 14:167253f4e170 5871 * m Mask to AND against each digit.
wolfSSL 14:167253f4e170 5872 */
wolfSSL 14:167253f4e170 5873 static void sp_3072_mask_27(sp_digit* r, sp_digit* a, sp_digit m)
wolfSSL 14:167253f4e170 5874 {
wolfSSL 14:167253f4e170 5875 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5876 int i;
wolfSSL 14:167253f4e170 5877
wolfSSL 14:167253f4e170 5878 for (i=0; i<27; i++)
wolfSSL 14:167253f4e170 5879 r[i] = a[i] & m;
wolfSSL 14:167253f4e170 5880 #else
wolfSSL 14:167253f4e170 5881 int i;
wolfSSL 14:167253f4e170 5882
wolfSSL 14:167253f4e170 5883 for (i = 0; i < 24; i += 8) {
wolfSSL 14:167253f4e170 5884 r[i+0] = a[i+0] & m;
wolfSSL 14:167253f4e170 5885 r[i+1] = a[i+1] & m;
wolfSSL 14:167253f4e170 5886 r[i+2] = a[i+2] & m;
wolfSSL 14:167253f4e170 5887 r[i+3] = a[i+3] & m;
wolfSSL 14:167253f4e170 5888 r[i+4] = a[i+4] & m;
wolfSSL 14:167253f4e170 5889 r[i+5] = a[i+5] & m;
wolfSSL 14:167253f4e170 5890 r[i+6] = a[i+6] & m;
wolfSSL 14:167253f4e170 5891 r[i+7] = a[i+7] & m;
wolfSSL 14:167253f4e170 5892 }
wolfSSL 14:167253f4e170 5893 r[24] = a[24] & m;
wolfSSL 14:167253f4e170 5894 r[25] = a[25] & m;
wolfSSL 14:167253f4e170 5895 r[26] = a[26] & m;
wolfSSL 14:167253f4e170 5896 #endif
wolfSSL 14:167253f4e170 5897 }
wolfSSL 14:167253f4e170 5898
wolfSSL 14:167253f4e170 5899 #endif
wolfSSL 14:167253f4e170 5900 #ifdef WOLFSSL_HAVE_SP_RSA
wolfSSL 14:167253f4e170 5901 /* RSA public key operation.
wolfSSL 14:167253f4e170 5902 *
wolfSSL 14:167253f4e170 5903 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 14:167253f4e170 5904 * inLen Number of bytes in base.
wolfSSL 14:167253f4e170 5905 * em Public exponent.
wolfSSL 14:167253f4e170 5906 * mm Modulus.
wolfSSL 14:167253f4e170 5907 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 5908 * Must be at least 384 bytes long.
wolfSSL 14:167253f4e170 5909 * outLen Number of bytes in result.
wolfSSL 14:167253f4e170 5910 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 14:167253f4e170 5911 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 14:167253f4e170 5912 */
wolfSSL 14:167253f4e170 5913 int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,
wolfSSL 14:167253f4e170 5914 byte* out, word32* outLen)
wolfSSL 14:167253f4e170 5915 {
wolfSSL 14:167253f4e170 5916 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 5917 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 5918 sp_digit* a;
wolfSSL 14:167253f4e170 5919 sp_digit* m;
wolfSSL 14:167253f4e170 5920 sp_digit* r;
wolfSSL 14:167253f4e170 5921 sp_digit* norm;
wolfSSL 14:167253f4e170 5922 sp_digit e[1];
wolfSSL 14:167253f4e170 5923 sp_digit mp;
wolfSSL 14:167253f4e170 5924 int i;
wolfSSL 14:167253f4e170 5925 int err = MP_OKAY;
wolfSSL 14:167253f4e170 5926
wolfSSL 14:167253f4e170 5927 if (*outLen < 384)
wolfSSL 14:167253f4e170 5928 err = MP_TO_E;
wolfSSL 14:167253f4e170 5929 if (err == MP_OKAY && (mp_count_bits(em) > 57 || inLen > 384 ||
wolfSSL 14:167253f4e170 5930 mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 5931 err = MP_READ_E;
wolfSSL 14:167253f4e170 5932
wolfSSL 14:167253f4e170 5933 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5934 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 5, NULL,
wolfSSL 14:167253f4e170 5935 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5936 if (d == NULL)
wolfSSL 14:167253f4e170 5937 err = MEMORY_E;
wolfSSL 14:167253f4e170 5938 }
wolfSSL 14:167253f4e170 5939
wolfSSL 14:167253f4e170 5940 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5941 a = d;
wolfSSL 14:167253f4e170 5942 r = a + 54 * 2;
wolfSSL 14:167253f4e170 5943 m = r + 54 * 2;
wolfSSL 14:167253f4e170 5944 norm = r;
wolfSSL 14:167253f4e170 5945
wolfSSL 14:167253f4e170 5946 sp_3072_from_bin(a, 54, in, inLen);
wolfSSL 14:167253f4e170 5947 #if DIGIT_BIT >= 57
wolfSSL 14:167253f4e170 5948 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 5949 #else
wolfSSL 14:167253f4e170 5950 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 5951 if (em->used > 1)
wolfSSL 14:167253f4e170 5952 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 14:167253f4e170 5953 #endif
wolfSSL 14:167253f4e170 5954 if (e[0] == 0)
wolfSSL 14:167253f4e170 5955 err = MP_EXPTMOD_E;
wolfSSL 14:167253f4e170 5956 }
wolfSSL 14:167253f4e170 5957
wolfSSL 14:167253f4e170 5958 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5959 sp_3072_from_mp(m, 54, mm);
wolfSSL 14:167253f4e170 5960
wolfSSL 14:167253f4e170 5961 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 5962 sp_3072_mont_norm_54(norm, m);
wolfSSL 14:167253f4e170 5963 }
wolfSSL 14:167253f4e170 5964 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5965 sp_3072_mul_54(a, a, norm);
wolfSSL 14:167253f4e170 5966 err = sp_3072_mod_54(a, a, m);
wolfSSL 14:167253f4e170 5967 }
wolfSSL 14:167253f4e170 5968 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 5969 for (i=56; i>=0; i--)
wolfSSL 14:167253f4e170 5970 if (e[0] >> i)
wolfSSL 14:167253f4e170 5971 break;
wolfSSL 14:167253f4e170 5972
wolfSSL 14:167253f4e170 5973 XMEMCPY(r, a, sizeof(sp_digit) * 54 * 2);
wolfSSL 14:167253f4e170 5974 for (i--; i>=0; i--) {
wolfSSL 14:167253f4e170 5975 sp_3072_mont_sqr_54(r, r, m, mp);
wolfSSL 14:167253f4e170 5976
wolfSSL 14:167253f4e170 5977 if (((e[0] >> i) & 1) == 1)
wolfSSL 14:167253f4e170 5978 sp_3072_mont_mul_54(r, r, a, m, mp);
wolfSSL 14:167253f4e170 5979 }
wolfSSL 14:167253f4e170 5980 sp_3072_mont_reduce_54(r, m, mp);
wolfSSL 14:167253f4e170 5981 mp = sp_3072_cmp_54(r, m);
wolfSSL 14:167253f4e170 5982 sp_3072_cond_sub_54(r, r, m, (mp < 0) - 1);
wolfSSL 14:167253f4e170 5983
wolfSSL 14:167253f4e170 5984 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 5985 *outLen = 384;
wolfSSL 14:167253f4e170 5986 }
wolfSSL 14:167253f4e170 5987
wolfSSL 14:167253f4e170 5988 if (d != NULL)
wolfSSL 14:167253f4e170 5989 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 5990
wolfSSL 14:167253f4e170 5991 return err;
wolfSSL 14:167253f4e170 5992 #else
wolfSSL 14:167253f4e170 5993 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 5994 sp_digit ad[108], md[54], rd[108];
wolfSSL 14:167253f4e170 5995 #else
wolfSSL 14:167253f4e170 5996 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 5997 #endif
wolfSSL 14:167253f4e170 5998 sp_digit* a;
wolfSSL 14:167253f4e170 5999 sp_digit* m;
wolfSSL 14:167253f4e170 6000 sp_digit* r;
wolfSSL 14:167253f4e170 6001 sp_digit e[1];
wolfSSL 14:167253f4e170 6002 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6003
wolfSSL 14:167253f4e170 6004 if (*outLen < 384)
wolfSSL 14:167253f4e170 6005 err = MP_TO_E;
wolfSSL 14:167253f4e170 6006 if (err == MP_OKAY && (mp_count_bits(em) > 57 || inLen > 384 ||
wolfSSL 14:167253f4e170 6007 mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6008 err = MP_READ_E;
wolfSSL 14:167253f4e170 6009
wolfSSL 14:167253f4e170 6010 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6011 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6012 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 5, NULL,
wolfSSL 14:167253f4e170 6013 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6014 if (d == NULL)
wolfSSL 14:167253f4e170 6015 err = MEMORY_E;
wolfSSL 14:167253f4e170 6016 }
wolfSSL 14:167253f4e170 6017
wolfSSL 14:167253f4e170 6018 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6019 a = d;
wolfSSL 14:167253f4e170 6020 r = a + 54 * 2;
wolfSSL 14:167253f4e170 6021 m = r + 54 * 2;
wolfSSL 14:167253f4e170 6022 }
wolfSSL 14:167253f4e170 6023 #else
wolfSSL 14:167253f4e170 6024 a = ad;
wolfSSL 14:167253f4e170 6025 m = md;
wolfSSL 14:167253f4e170 6026 r = rd;
wolfSSL 14:167253f4e170 6027 #endif
wolfSSL 14:167253f4e170 6028
wolfSSL 14:167253f4e170 6029 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6030 sp_3072_from_bin(a, 54, in, inLen);
wolfSSL 14:167253f4e170 6031 #if DIGIT_BIT >= 57
wolfSSL 14:167253f4e170 6032 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 6033 #else
wolfSSL 14:167253f4e170 6034 e[0] = em->dp[0];
wolfSSL 14:167253f4e170 6035 if (em->used > 1)
wolfSSL 14:167253f4e170 6036 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 14:167253f4e170 6037 #endif
wolfSSL 14:167253f4e170 6038 if (e[0] == 0)
wolfSSL 14:167253f4e170 6039 err = MP_EXPTMOD_E;
wolfSSL 14:167253f4e170 6040 }
wolfSSL 14:167253f4e170 6041 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6042 sp_3072_from_mp(m, 54, mm);
wolfSSL 14:167253f4e170 6043
wolfSSL 14:167253f4e170 6044 if (e[0] == 0x3) {
wolfSSL 14:167253f4e170 6045 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6046 sp_3072_sqr_54(r, a);
wolfSSL 14:167253f4e170 6047 err = sp_3072_mod_54(r, r, m);
wolfSSL 14:167253f4e170 6048 }
wolfSSL 14:167253f4e170 6049 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6050 sp_3072_mul_54(r, a, r);
wolfSSL 14:167253f4e170 6051 err = sp_3072_mod_54(r, r, m);
wolfSSL 14:167253f4e170 6052 }
wolfSSL 14:167253f4e170 6053 }
wolfSSL 14:167253f4e170 6054 else {
wolfSSL 14:167253f4e170 6055 sp_digit* norm = r;
wolfSSL 14:167253f4e170 6056 int i;
wolfSSL 14:167253f4e170 6057 sp_digit mp;
wolfSSL 14:167253f4e170 6058
wolfSSL 14:167253f4e170 6059 sp_3072_mont_setup(m, &mp);
wolfSSL 14:167253f4e170 6060 sp_3072_mont_norm_54(norm, m);
wolfSSL 14:167253f4e170 6061
wolfSSL 14:167253f4e170 6062 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6063 sp_3072_mul_54(a, a, norm);
wolfSSL 14:167253f4e170 6064 err = sp_3072_mod_54(a, a, m);
wolfSSL 14:167253f4e170 6065 }
wolfSSL 14:167253f4e170 6066
wolfSSL 14:167253f4e170 6067 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6068 for (i=56; i>=0; i--)
wolfSSL 14:167253f4e170 6069 if (e[0] >> i)
wolfSSL 14:167253f4e170 6070 break;
wolfSSL 14:167253f4e170 6071
wolfSSL 14:167253f4e170 6072 XMEMCPY(r, a, sizeof(sp_digit) * 108);
wolfSSL 14:167253f4e170 6073 for (i--; i>=0; i--) {
wolfSSL 14:167253f4e170 6074 sp_3072_mont_sqr_54(r, r, m, mp);
wolfSSL 14:167253f4e170 6075
wolfSSL 14:167253f4e170 6076 if (((e[0] >> i) & 1) == 1)
wolfSSL 14:167253f4e170 6077 sp_3072_mont_mul_54(r, r, a, m, mp);
wolfSSL 14:167253f4e170 6078 }
wolfSSL 14:167253f4e170 6079 sp_3072_mont_reduce_54(r, m, mp);
wolfSSL 14:167253f4e170 6080 mp = sp_3072_cmp_54(r, m);
wolfSSL 14:167253f4e170 6081 sp_3072_cond_sub_54(r, r, m, (mp < 0) - 1);
wolfSSL 14:167253f4e170 6082 }
wolfSSL 14:167253f4e170 6083 }
wolfSSL 14:167253f4e170 6084 }
wolfSSL 14:167253f4e170 6085
wolfSSL 14:167253f4e170 6086 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6087 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6088 *outLen = 384;
wolfSSL 14:167253f4e170 6089 }
wolfSSL 14:167253f4e170 6090
wolfSSL 14:167253f4e170 6091 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6092 if (d != NULL)
wolfSSL 14:167253f4e170 6093 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6094 #endif
wolfSSL 14:167253f4e170 6095
wolfSSL 14:167253f4e170 6096 return err;
wolfSSL 14:167253f4e170 6097 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 6098 }
wolfSSL 14:167253f4e170 6099
wolfSSL 14:167253f4e170 6100 /* RSA private key operation.
wolfSSL 14:167253f4e170 6101 *
wolfSSL 14:167253f4e170 6102 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 14:167253f4e170 6103 * inLen Number of bytes in base.
wolfSSL 14:167253f4e170 6104 * dm Private exponent.
wolfSSL 14:167253f4e170 6105 * pm First prime.
wolfSSL 14:167253f4e170 6106 * qm Second prime.
wolfSSL 14:167253f4e170 6107 * dpm First prime's CRT exponent.
wolfSSL 14:167253f4e170 6108 * dqm Second prime's CRT exponent.
wolfSSL 14:167253f4e170 6109 * qim Inverse of second prime mod p.
wolfSSL 14:167253f4e170 6110 * mm Modulus.
wolfSSL 14:167253f4e170 6111 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 6112 * Must be at least 384 bytes long.
wolfSSL 14:167253f4e170 6113 * outLen Number of bytes in result.
wolfSSL 14:167253f4e170 6114 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 14:167253f4e170 6115 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 14:167253f4e170 6116 */
wolfSSL 14:167253f4e170 6117 int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,
wolfSSL 14:167253f4e170 6118 mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,
wolfSSL 14:167253f4e170 6119 byte* out, word32* outLen)
wolfSSL 14:167253f4e170 6120 {
wolfSSL 14:167253f4e170 6121 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
wolfSSL 14:167253f4e170 6122 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6123 sp_digit* a;
wolfSSL 14:167253f4e170 6124 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 6125 sp_digit* m;
wolfSSL 14:167253f4e170 6126 sp_digit* r;
wolfSSL 14:167253f4e170 6127 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6128
wolfSSL 14:167253f4e170 6129 (void)pm;
wolfSSL 14:167253f4e170 6130 (void)qm;
wolfSSL 14:167253f4e170 6131 (void)dpm;
wolfSSL 14:167253f4e170 6132 (void)dqm;
wolfSSL 14:167253f4e170 6133 (void)qim;
wolfSSL 14:167253f4e170 6134
wolfSSL 14:167253f4e170 6135 if (*outLen < 384)
wolfSSL 14:167253f4e170 6136 err = MP_TO_E;
wolfSSL 14:167253f4e170 6137 if (err == MP_OKAY && (mp_count_bits(dm) > 3072 || inLen > 384 ||
wolfSSL 14:167253f4e170 6138 mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6139 err = MP_READ_E;
wolfSSL 14:167253f4e170 6140
wolfSSL 14:167253f4e170 6141 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6142 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,
wolfSSL 14:167253f4e170 6143 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6144 if (d == NULL)
wolfSSL 14:167253f4e170 6145 err = MEMORY_E;
wolfSSL 14:167253f4e170 6146 }
wolfSSL 14:167253f4e170 6147 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6148 a = d + 54;
wolfSSL 14:167253f4e170 6149 m = a + 54;
wolfSSL 14:167253f4e170 6150 r = a;
wolfSSL 14:167253f4e170 6151
wolfSSL 14:167253f4e170 6152 sp_3072_from_bin(a, 54, in, inLen);
wolfSSL 14:167253f4e170 6153 sp_3072_from_mp(d, 54, dm);
wolfSSL 14:167253f4e170 6154 sp_3072_from_mp(m, 54, mm);
wolfSSL 14:167253f4e170 6155 err = sp_3072_mod_exp_54(r, a, d, 3072, m, 0);
wolfSSL 14:167253f4e170 6156 }
wolfSSL 14:167253f4e170 6157 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6158 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6159 *outLen = 384;
wolfSSL 14:167253f4e170 6160 }
wolfSSL 14:167253f4e170 6161
wolfSSL 14:167253f4e170 6162 if (d != NULL) {
wolfSSL 14:167253f4e170 6163 XMEMSET(d, 0, sizeof(sp_digit) * 54);
wolfSSL 14:167253f4e170 6164 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6165 }
wolfSSL 14:167253f4e170 6166
wolfSSL 14:167253f4e170 6167 return err;
wolfSSL 14:167253f4e170 6168 #else
wolfSSL 14:167253f4e170 6169 sp_digit a[108], d[54], m[54];
wolfSSL 14:167253f4e170 6170 sp_digit* r = a;
wolfSSL 14:167253f4e170 6171 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6172
wolfSSL 14:167253f4e170 6173 (void)pm;
wolfSSL 14:167253f4e170 6174 (void)qm;
wolfSSL 14:167253f4e170 6175 (void)dpm;
wolfSSL 14:167253f4e170 6176 (void)dqm;
wolfSSL 14:167253f4e170 6177 (void)qim;
wolfSSL 14:167253f4e170 6178
wolfSSL 14:167253f4e170 6179 if (*outLen < 384)
wolfSSL 14:167253f4e170 6180 err = MP_TO_E;
wolfSSL 14:167253f4e170 6181 if (err == MP_OKAY && (mp_count_bits(dm) > 3072 || inLen > 384 ||
wolfSSL 14:167253f4e170 6182 mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6183 err = MP_READ_E;
wolfSSL 14:167253f4e170 6184
wolfSSL 14:167253f4e170 6185 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6186 sp_3072_from_bin(a, 54, in, inLen);
wolfSSL 14:167253f4e170 6187 sp_3072_from_mp(d, 54, dm);
wolfSSL 14:167253f4e170 6188 sp_3072_from_mp(m, 54, mm);
wolfSSL 14:167253f4e170 6189 err = sp_3072_mod_exp_54(r, a, d, 3072, m, 0);
wolfSSL 14:167253f4e170 6190 }
wolfSSL 14:167253f4e170 6191
wolfSSL 14:167253f4e170 6192 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6193 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6194 *outLen = 384;
wolfSSL 14:167253f4e170 6195 }
wolfSSL 14:167253f4e170 6196
wolfSSL 14:167253f4e170 6197 XMEMSET(d, 0, sizeof(sp_digit) * 54);
wolfSSL 14:167253f4e170 6198
wolfSSL 14:167253f4e170 6199 return err;
wolfSSL 14:167253f4e170 6200 #endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */
wolfSSL 14:167253f4e170 6201 #else
wolfSSL 14:167253f4e170 6202 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6203 sp_digit* t = NULL;
wolfSSL 14:167253f4e170 6204 sp_digit* a;
wolfSSL 14:167253f4e170 6205 sp_digit* p;
wolfSSL 14:167253f4e170 6206 sp_digit* q;
wolfSSL 14:167253f4e170 6207 sp_digit* dp;
wolfSSL 14:167253f4e170 6208 sp_digit* dq;
wolfSSL 14:167253f4e170 6209 sp_digit* qi;
wolfSSL 14:167253f4e170 6210 sp_digit* tmp;
wolfSSL 14:167253f4e170 6211 sp_digit* tmpa;
wolfSSL 14:167253f4e170 6212 sp_digit* tmpb;
wolfSSL 14:167253f4e170 6213 sp_digit* r;
wolfSSL 14:167253f4e170 6214 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6215
wolfSSL 14:167253f4e170 6216 (void)dm;
wolfSSL 14:167253f4e170 6217 (void)mm;
wolfSSL 14:167253f4e170 6218
wolfSSL 14:167253f4e170 6219 if (*outLen < 384)
wolfSSL 14:167253f4e170 6220 err = MP_TO_E;
wolfSSL 14:167253f4e170 6221 if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6222 err = MP_READ_E;
wolfSSL 14:167253f4e170 6223
wolfSSL 14:167253f4e170 6224 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6225 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 11, NULL,
wolfSSL 14:167253f4e170 6226 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6227 if (t == NULL)
wolfSSL 14:167253f4e170 6228 err = MEMORY_E;
wolfSSL 14:167253f4e170 6229 }
wolfSSL 14:167253f4e170 6230 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6231 a = t;
wolfSSL 14:167253f4e170 6232 p = a + 54 * 2;
wolfSSL 14:167253f4e170 6233 q = p + 27;
wolfSSL 14:167253f4e170 6234 qi = dq = dp = q + 27;
wolfSSL 14:167253f4e170 6235 tmpa = qi + 27;
wolfSSL 14:167253f4e170 6236 tmpb = tmpa + 54;
wolfSSL 14:167253f4e170 6237
wolfSSL 14:167253f4e170 6238 tmp = t;
wolfSSL 14:167253f4e170 6239 r = tmp + 54;
wolfSSL 14:167253f4e170 6240
wolfSSL 14:167253f4e170 6241 sp_3072_from_bin(a, 54, in, inLen);
wolfSSL 14:167253f4e170 6242 sp_3072_from_mp(p, 27, pm);
wolfSSL 14:167253f4e170 6243 sp_3072_from_mp(q, 27, qm);
wolfSSL 14:167253f4e170 6244 sp_3072_from_mp(dp, 27, dpm);
wolfSSL 14:167253f4e170 6245 err = sp_3072_mod_exp_27(tmpa, a, dp, 1536, p, 1);
wolfSSL 14:167253f4e170 6246 }
wolfSSL 14:167253f4e170 6247 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6248 sp_3072_from_mp(dq, 27, dqm);
wolfSSL 14:167253f4e170 6249 err = sp_3072_mod_exp_27(tmpb, a, dq, 1536, q, 1);
wolfSSL 14:167253f4e170 6250 }
wolfSSL 14:167253f4e170 6251 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6252 sp_3072_sub_27(tmpa, tmpa, tmpb);
wolfSSL 14:167253f4e170 6253 sp_3072_mask_27(tmp, p, tmpa[26] >> 63);
wolfSSL 14:167253f4e170 6254 sp_3072_add_27(tmpa, tmpa, tmp);
wolfSSL 14:167253f4e170 6255
wolfSSL 14:167253f4e170 6256 sp_3072_from_mp(qi, 27, qim);
wolfSSL 14:167253f4e170 6257 sp_3072_mul_27(tmpa, tmpa, qi);
wolfSSL 14:167253f4e170 6258 err = sp_3072_mod_27(tmpa, tmpa, p);
wolfSSL 14:167253f4e170 6259 }
wolfSSL 14:167253f4e170 6260
wolfSSL 14:167253f4e170 6261 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6262 sp_3072_mul_27(tmpa, q, tmpa);
wolfSSL 14:167253f4e170 6263 sp_3072_add_54(r, tmpb, tmpa);
wolfSSL 14:167253f4e170 6264 sp_3072_norm_54(r);
wolfSSL 14:167253f4e170 6265
wolfSSL 14:167253f4e170 6266 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6267 *outLen = 384;
wolfSSL 14:167253f4e170 6268 }
wolfSSL 14:167253f4e170 6269
wolfSSL 14:167253f4e170 6270 if (t != NULL) {
wolfSSL 14:167253f4e170 6271 XMEMSET(t, 0, sizeof(sp_digit) * 27 * 11);
wolfSSL 14:167253f4e170 6272 XFREE(t, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6273 }
wolfSSL 14:167253f4e170 6274
wolfSSL 14:167253f4e170 6275 return err;
wolfSSL 14:167253f4e170 6276 #else
wolfSSL 14:167253f4e170 6277 sp_digit a[54 * 2];
wolfSSL 14:167253f4e170 6278 sp_digit p[27], q[27], dp[27], dq[27], qi[27];
wolfSSL 14:167253f4e170 6279 sp_digit tmp[54], tmpa[54], tmpb[54];
wolfSSL 14:167253f4e170 6280 sp_digit* r = a;
wolfSSL 14:167253f4e170 6281 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6282
wolfSSL 14:167253f4e170 6283 (void)dm;
wolfSSL 14:167253f4e170 6284 (void)mm;
wolfSSL 14:167253f4e170 6285
wolfSSL 14:167253f4e170 6286 if (*outLen < 384)
wolfSSL 14:167253f4e170 6287 err = MP_TO_E;
wolfSSL 14:167253f4e170 6288 if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))
wolfSSL 14:167253f4e170 6289 err = MP_READ_E;
wolfSSL 14:167253f4e170 6290
wolfSSL 14:167253f4e170 6291 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6292 sp_3072_from_bin(a, 54, in, inLen);
wolfSSL 14:167253f4e170 6293 sp_3072_from_mp(p, 27, pm);
wolfSSL 14:167253f4e170 6294 sp_3072_from_mp(q, 27, qm);
wolfSSL 14:167253f4e170 6295 sp_3072_from_mp(dp, 27, dpm);
wolfSSL 14:167253f4e170 6296 sp_3072_from_mp(dq, 27, dqm);
wolfSSL 14:167253f4e170 6297 sp_3072_from_mp(qi, 27, qim);
wolfSSL 14:167253f4e170 6298
wolfSSL 14:167253f4e170 6299 err = sp_3072_mod_exp_27(tmpa, a, dp, 1536, p, 1);
wolfSSL 14:167253f4e170 6300 }
wolfSSL 14:167253f4e170 6301 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 6302 err = sp_3072_mod_exp_27(tmpb, a, dq, 1536, q, 1);
wolfSSL 14:167253f4e170 6303
wolfSSL 14:167253f4e170 6304 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6305 sp_3072_sub_27(tmpa, tmpa, tmpb);
wolfSSL 14:167253f4e170 6306 sp_3072_mask_27(tmp, p, tmpa[26] >> 63);
wolfSSL 14:167253f4e170 6307 sp_3072_add_27(tmpa, tmpa, tmp);
wolfSSL 14:167253f4e170 6308 sp_3072_mul_27(tmpa, tmpa, qi);
wolfSSL 14:167253f4e170 6309 err = sp_3072_mod_27(tmpa, tmpa, p);
wolfSSL 14:167253f4e170 6310 }
wolfSSL 14:167253f4e170 6311
wolfSSL 14:167253f4e170 6312 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6313 sp_3072_mul_27(tmpa, tmpa, q);
wolfSSL 14:167253f4e170 6314 sp_3072_add_54(r, tmpb, tmpa);
wolfSSL 14:167253f4e170 6315 sp_3072_norm_54(r);
wolfSSL 14:167253f4e170 6316
wolfSSL 14:167253f4e170 6317 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6318 *outLen = 384;
wolfSSL 14:167253f4e170 6319 }
wolfSSL 14:167253f4e170 6320
wolfSSL 14:167253f4e170 6321 XMEMSET(tmpa, 0, sizeof(tmpa));
wolfSSL 14:167253f4e170 6322 XMEMSET(tmpb, 0, sizeof(tmpb));
wolfSSL 14:167253f4e170 6323 XMEMSET(p, 0, sizeof(p));
wolfSSL 14:167253f4e170 6324 XMEMSET(q, 0, sizeof(q));
wolfSSL 14:167253f4e170 6325 XMEMSET(dp, 0, sizeof(dp));
wolfSSL 14:167253f4e170 6326 XMEMSET(dq, 0, sizeof(dq));
wolfSSL 14:167253f4e170 6327 XMEMSET(qi, 0, sizeof(qi));
wolfSSL 14:167253f4e170 6328
wolfSSL 14:167253f4e170 6329 return err;
wolfSSL 14:167253f4e170 6330 #endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */
wolfSSL 14:167253f4e170 6331 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
wolfSSL 14:167253f4e170 6332 }
wolfSSL 14:167253f4e170 6333
wolfSSL 14:167253f4e170 6334 #endif /* WOLFSSL_HAVE_SP_RSA */
wolfSSL 14:167253f4e170 6335 #ifdef WOLFSSL_HAVE_SP_DH
wolfSSL 14:167253f4e170 6336 /* Convert an array of sp_digit to an mp_int.
wolfSSL 14:167253f4e170 6337 *
wolfSSL 14:167253f4e170 6338 * a A single precision integer.
wolfSSL 14:167253f4e170 6339 * r A multi-precision integer.
wolfSSL 14:167253f4e170 6340 */
wolfSSL 14:167253f4e170 6341 static int sp_3072_to_mp(sp_digit* a, mp_int* r)
wolfSSL 14:167253f4e170 6342 {
wolfSSL 14:167253f4e170 6343 int err;
wolfSSL 14:167253f4e170 6344
wolfSSL 14:167253f4e170 6345 err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 14:167253f4e170 6346 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6347 #if DIGIT_BIT == 57
wolfSSL 14:167253f4e170 6348 XMEMCPY(r->dp, a, sizeof(sp_digit) * 54);
wolfSSL 14:167253f4e170 6349 r->used = 54;
wolfSSL 14:167253f4e170 6350 mp_clamp(r);
wolfSSL 14:167253f4e170 6351 #elif DIGIT_BIT < 57
wolfSSL 14:167253f4e170 6352 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 6353
wolfSSL 14:167253f4e170 6354 r->dp[0] = 0;
wolfSSL 14:167253f4e170 6355 for (i = 0; i < 54; i++) {
wolfSSL 14:167253f4e170 6356 r->dp[j] |= a[i] << s;
wolfSSL 14:167253f4e170 6357 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 6358 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 6359 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 6360 while (s + DIGIT_BIT <= 57) {
wolfSSL 14:167253f4e170 6361 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 6362 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 6363 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 6364 }
wolfSSL 14:167253f4e170 6365 s = 57 - s;
wolfSSL 14:167253f4e170 6366 }
wolfSSL 14:167253f4e170 6367 r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 6368 mp_clamp(r);
wolfSSL 14:167253f4e170 6369 #else
wolfSSL 14:167253f4e170 6370 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 6371
wolfSSL 14:167253f4e170 6372 r->dp[0] = 0;
wolfSSL 14:167253f4e170 6373 for (i = 0; i < 54; i++) {
wolfSSL 14:167253f4e170 6374 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 6375 if (s + 57 >= DIGIT_BIT) {
wolfSSL 14:167253f4e170 6376 #if DIGIT_BIT < 64
wolfSSL 14:167253f4e170 6377 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 6378 #endif
wolfSSL 14:167253f4e170 6379 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 6380 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 6381 s = 57 - s;
wolfSSL 14:167253f4e170 6382 }
wolfSSL 14:167253f4e170 6383 else
wolfSSL 14:167253f4e170 6384 s += 57;
wolfSSL 14:167253f4e170 6385 }
wolfSSL 14:167253f4e170 6386 r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 6387 mp_clamp(r);
wolfSSL 14:167253f4e170 6388 #endif
wolfSSL 14:167253f4e170 6389 }
wolfSSL 14:167253f4e170 6390
wolfSSL 14:167253f4e170 6391 return err;
wolfSSL 14:167253f4e170 6392 }
wolfSSL 14:167253f4e170 6393
wolfSSL 14:167253f4e170 6394 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 14:167253f4e170 6395 *
wolfSSL 14:167253f4e170 6396 * base Base. MP integer.
wolfSSL 14:167253f4e170 6397 * exp Exponent. MP integer.
wolfSSL 14:167253f4e170 6398 * mod Modulus. MP integer.
wolfSSL 14:167253f4e170 6399 * res Result. MP integer.
wolfSSL 14:167253f4e170 6400 * returs 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 14:167253f4e170 6401 * and MEMORY_E if memory allocation fails.
wolfSSL 14:167253f4e170 6402 */
wolfSSL 14:167253f4e170 6403 int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)
wolfSSL 14:167253f4e170 6404 {
wolfSSL 14:167253f4e170 6405 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 6406 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6407 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 6408 sp_digit* b;
wolfSSL 14:167253f4e170 6409 sp_digit* e;
wolfSSL 14:167253f4e170 6410 sp_digit* m;
wolfSSL 14:167253f4e170 6411 sp_digit* r;
wolfSSL 14:167253f4e170 6412 int expBits = mp_count_bits(exp);
wolfSSL 14:167253f4e170 6413
wolfSSL 14:167253f4e170 6414 if (mp_count_bits(base) > 3072 || expBits > 3072 ||
wolfSSL 14:167253f4e170 6415 mp_count_bits(mod) != 3072) {
wolfSSL 14:167253f4e170 6416 err = MP_READ_E;
wolfSSL 14:167253f4e170 6417 }
wolfSSL 14:167253f4e170 6418
wolfSSL 14:167253f4e170 6419 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6420 d = (sp_digit*)XMALLOC(sizeof(*d) * 54 * 4, NULL,
wolfSSL 14:167253f4e170 6421 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6422 if (d == NULL)
wolfSSL 14:167253f4e170 6423 err = MEMORY_E;
wolfSSL 14:167253f4e170 6424 }
wolfSSL 14:167253f4e170 6425
wolfSSL 14:167253f4e170 6426 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6427 b = d;
wolfSSL 14:167253f4e170 6428 e = b + 54 * 2;
wolfSSL 14:167253f4e170 6429 m = e + 54;
wolfSSL 14:167253f4e170 6430 r = b;
wolfSSL 14:167253f4e170 6431
wolfSSL 14:167253f4e170 6432 sp_3072_from_mp(b, 54, base);
wolfSSL 14:167253f4e170 6433 sp_3072_from_mp(e, 54, exp);
wolfSSL 14:167253f4e170 6434 sp_3072_from_mp(m, 54, mod);
wolfSSL 14:167253f4e170 6435
wolfSSL 14:167253f4e170 6436 err = sp_3072_mod_exp_54(r, b, e, mp_count_bits(exp), m, 0);
wolfSSL 14:167253f4e170 6437 }
wolfSSL 14:167253f4e170 6438
wolfSSL 14:167253f4e170 6439 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6440 err = sp_3072_to_mp(r, res);
wolfSSL 14:167253f4e170 6441 }
wolfSSL 14:167253f4e170 6442
wolfSSL 14:167253f4e170 6443 if (d != NULL) {
wolfSSL 14:167253f4e170 6444 XMEMSET(e, 0, sizeof(sp_digit) * 54);
wolfSSL 14:167253f4e170 6445 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6446 }
wolfSSL 14:167253f4e170 6447 return err;
wolfSSL 14:167253f4e170 6448 #else
wolfSSL 14:167253f4e170 6449 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6450 sp_digit bd[108], ed[54], md[54];
wolfSSL 14:167253f4e170 6451 #else
wolfSSL 14:167253f4e170 6452 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 6453 #endif
wolfSSL 14:167253f4e170 6454 sp_digit* b;
wolfSSL 14:167253f4e170 6455 sp_digit* e;
wolfSSL 14:167253f4e170 6456 sp_digit* m;
wolfSSL 14:167253f4e170 6457 sp_digit* r;
wolfSSL 14:167253f4e170 6458 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6459 int expBits = mp_count_bits(exp);
wolfSSL 14:167253f4e170 6460
wolfSSL 14:167253f4e170 6461 if (mp_count_bits(base) > 3072 || expBits > 3072 ||
wolfSSL 14:167253f4e170 6462 mp_count_bits(mod) != 3072) {
wolfSSL 14:167253f4e170 6463 err = MP_READ_E;
wolfSSL 14:167253f4e170 6464 }
wolfSSL 14:167253f4e170 6465
wolfSSL 14:167253f4e170 6466 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6467 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6468 d = (sp_digit*)XMALLOC(sizeof(*d) * 54 * 4, NULL,
wolfSSL 14:167253f4e170 6469 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6470 if (d == NULL)
wolfSSL 14:167253f4e170 6471 err = MEMORY_E;
wolfSSL 14:167253f4e170 6472 }
wolfSSL 14:167253f4e170 6473
wolfSSL 14:167253f4e170 6474 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6475 b = d;
wolfSSL 14:167253f4e170 6476 e = b + 54 * 2;
wolfSSL 14:167253f4e170 6477 m = e + 54;
wolfSSL 14:167253f4e170 6478 r = b;
wolfSSL 14:167253f4e170 6479 }
wolfSSL 14:167253f4e170 6480 #else
wolfSSL 14:167253f4e170 6481 r = b = bd;
wolfSSL 14:167253f4e170 6482 e = ed;
wolfSSL 14:167253f4e170 6483 m = md;
wolfSSL 14:167253f4e170 6484 #endif
wolfSSL 14:167253f4e170 6485
wolfSSL 14:167253f4e170 6486 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6487 sp_3072_from_mp(b, 54, base);
wolfSSL 14:167253f4e170 6488 sp_3072_from_mp(e, 54, exp);
wolfSSL 14:167253f4e170 6489 sp_3072_from_mp(m, 54, mod);
wolfSSL 14:167253f4e170 6490
wolfSSL 14:167253f4e170 6491 err = sp_3072_mod_exp_54(r, b, e, expBits, m, 0);
wolfSSL 14:167253f4e170 6492 }
wolfSSL 14:167253f4e170 6493
wolfSSL 14:167253f4e170 6494 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6495 err = sp_3072_to_mp(r, res);
wolfSSL 14:167253f4e170 6496 }
wolfSSL 14:167253f4e170 6497
wolfSSL 14:167253f4e170 6498 XMEMSET(e, 0, sizeof(sp_digit) * 54);
wolfSSL 14:167253f4e170 6499
wolfSSL 14:167253f4e170 6500 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6501 if (d != NULL)
wolfSSL 14:167253f4e170 6502 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6503 #endif
wolfSSL 14:167253f4e170 6504
wolfSSL 14:167253f4e170 6505 return err;
wolfSSL 14:167253f4e170 6506 #endif
wolfSSL 14:167253f4e170 6507 }
wolfSSL 14:167253f4e170 6508
wolfSSL 14:167253f4e170 6509 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 14:167253f4e170 6510 *
wolfSSL 14:167253f4e170 6511 * base Base.
wolfSSL 14:167253f4e170 6512 * exp Array of bytes that is the exponent.
wolfSSL 14:167253f4e170 6513 * expLen Length of data, in bytes, in exponent.
wolfSSL 14:167253f4e170 6514 * mod Modulus.
wolfSSL 14:167253f4e170 6515 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 14:167253f4e170 6516 * Must be at least 384 bytes long.
wolfSSL 14:167253f4e170 6517 * outLen Length, in bytes, of exponentiation result.
wolfSSL 14:167253f4e170 6518 * returs 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 14:167253f4e170 6519 * and MEMORY_E if memory allocation fails.
wolfSSL 14:167253f4e170 6520 */
wolfSSL 14:167253f4e170 6521 int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,
wolfSSL 14:167253f4e170 6522 mp_int* mod, byte* out, word32* outLen)
wolfSSL 14:167253f4e170 6523 {
wolfSSL 14:167253f4e170 6524 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 6525 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6526 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 6527 sp_digit* b;
wolfSSL 14:167253f4e170 6528 sp_digit* e;
wolfSSL 14:167253f4e170 6529 sp_digit* m;
wolfSSL 14:167253f4e170 6530 sp_digit* r;
wolfSSL 14:167253f4e170 6531 word32 i;
wolfSSL 14:167253f4e170 6532
wolfSSL 14:167253f4e170 6533 if (mp_count_bits(base) > 3072 || expLen > 384 ||
wolfSSL 14:167253f4e170 6534 mp_count_bits(mod) != 3072) {
wolfSSL 14:167253f4e170 6535 err = MP_READ_E;
wolfSSL 14:167253f4e170 6536 }
wolfSSL 14:167253f4e170 6537
wolfSSL 14:167253f4e170 6538 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6539 d = (sp_digit*)XMALLOC(sizeof(*d) * 54 * 4, NULL,
wolfSSL 14:167253f4e170 6540 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6541 if (d == NULL)
wolfSSL 14:167253f4e170 6542 err = MEMORY_E;
wolfSSL 14:167253f4e170 6543 }
wolfSSL 14:167253f4e170 6544
wolfSSL 14:167253f4e170 6545 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6546 b = d;
wolfSSL 14:167253f4e170 6547 e = b + 54 * 2;
wolfSSL 14:167253f4e170 6548 m = e + 54;
wolfSSL 14:167253f4e170 6549 r = b;
wolfSSL 14:167253f4e170 6550
wolfSSL 14:167253f4e170 6551 sp_3072_from_mp(b, 54, base);
wolfSSL 14:167253f4e170 6552 sp_3072_from_bin(e, 54, exp, expLen);
wolfSSL 14:167253f4e170 6553 sp_3072_from_mp(m, 54, mod);
wolfSSL 14:167253f4e170 6554
wolfSSL 14:167253f4e170 6555 err = sp_3072_mod_exp_54(r, b, e, expLen * 8, m, 0);
wolfSSL 14:167253f4e170 6556 }
wolfSSL 14:167253f4e170 6557
wolfSSL 14:167253f4e170 6558 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6559 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6560 *outLen = 384;
wolfSSL 14:167253f4e170 6561 for (i=0; i<384 && out[i] == 0; i++) {
wolfSSL 14:167253f4e170 6562 }
wolfSSL 14:167253f4e170 6563 *outLen -= i;
wolfSSL 14:167253f4e170 6564 XMEMMOVE(out, out + i, *outLen);
wolfSSL 14:167253f4e170 6565 }
wolfSSL 14:167253f4e170 6566
wolfSSL 14:167253f4e170 6567 if (d != NULL) {
wolfSSL 14:167253f4e170 6568 XMEMSET(e, 0, sizeof(sp_digit) * 54);
wolfSSL 14:167253f4e170 6569 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6570 }
wolfSSL 14:167253f4e170 6571 return err;
wolfSSL 14:167253f4e170 6572 #else
wolfSSL 14:167253f4e170 6573 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6574 sp_digit bd[108], ed[54], md[54];
wolfSSL 14:167253f4e170 6575 #else
wolfSSL 14:167253f4e170 6576 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 6577 #endif
wolfSSL 14:167253f4e170 6578 sp_digit* b;
wolfSSL 14:167253f4e170 6579 sp_digit* e;
wolfSSL 14:167253f4e170 6580 sp_digit* m;
wolfSSL 14:167253f4e170 6581 sp_digit* r;
wolfSSL 14:167253f4e170 6582 word32 i;
wolfSSL 14:167253f4e170 6583 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6584
wolfSSL 14:167253f4e170 6585 if (mp_count_bits(base) > 3072 || expLen > 384 ||
wolfSSL 14:167253f4e170 6586 mp_count_bits(mod) != 3072) {
wolfSSL 14:167253f4e170 6587 err = MP_READ_E;
wolfSSL 14:167253f4e170 6588 }
wolfSSL 14:167253f4e170 6589
wolfSSL 14:167253f4e170 6590 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6591 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6592 d = (sp_digit*)XMALLOC(sizeof(*d) * 54 * 4, NULL,
wolfSSL 14:167253f4e170 6593 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6594 if (d == NULL)
wolfSSL 14:167253f4e170 6595 err = MEMORY_E;
wolfSSL 14:167253f4e170 6596 }
wolfSSL 14:167253f4e170 6597
wolfSSL 14:167253f4e170 6598 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6599 b = d;
wolfSSL 14:167253f4e170 6600 e = b + 54 * 2;
wolfSSL 14:167253f4e170 6601 m = e + 54;
wolfSSL 14:167253f4e170 6602 r = b;
wolfSSL 14:167253f4e170 6603 }
wolfSSL 14:167253f4e170 6604 #else
wolfSSL 14:167253f4e170 6605 r = b = bd;
wolfSSL 14:167253f4e170 6606 e = ed;
wolfSSL 14:167253f4e170 6607 m = md;
wolfSSL 14:167253f4e170 6608 #endif
wolfSSL 14:167253f4e170 6609
wolfSSL 14:167253f4e170 6610 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6611 sp_3072_from_mp(b, 54, base);
wolfSSL 14:167253f4e170 6612 sp_3072_from_bin(e, 54, exp, expLen);
wolfSSL 14:167253f4e170 6613 sp_3072_from_mp(m, 54, mod);
wolfSSL 14:167253f4e170 6614
wolfSSL 14:167253f4e170 6615 err = sp_3072_mod_exp_54(r, b, e, expLen * 8, m, 0);
wolfSSL 14:167253f4e170 6616 }
wolfSSL 14:167253f4e170 6617
wolfSSL 14:167253f4e170 6618 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6619 sp_3072_to_bin(r, out);
wolfSSL 14:167253f4e170 6620 *outLen = 384;
wolfSSL 14:167253f4e170 6621 for (i=0; i<384 && out[i] == 0; i++) {
wolfSSL 14:167253f4e170 6622 }
wolfSSL 14:167253f4e170 6623 *outLen -= i;
wolfSSL 14:167253f4e170 6624 XMEMMOVE(out, out + i, *outLen);
wolfSSL 14:167253f4e170 6625 }
wolfSSL 14:167253f4e170 6626
wolfSSL 14:167253f4e170 6627 XMEMSET(e, 0, sizeof(sp_digit) * 54);
wolfSSL 14:167253f4e170 6628
wolfSSL 14:167253f4e170 6629 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 14:167253f4e170 6630 if (d != NULL)
wolfSSL 14:167253f4e170 6631 XFREE(d, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 6632 #endif
wolfSSL 14:167253f4e170 6633
wolfSSL 14:167253f4e170 6634 return err;
wolfSSL 14:167253f4e170 6635 #endif
wolfSSL 14:167253f4e170 6636 }
wolfSSL 14:167253f4e170 6637
wolfSSL 14:167253f4e170 6638 #endif /* WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 6639
wolfSSL 14:167253f4e170 6640 #endif /* WOLFSSL_SP_NO_3072 */
wolfSSL 14:167253f4e170 6641
wolfSSL 14:167253f4e170 6642 #endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */
wolfSSL 14:167253f4e170 6643 #ifdef WOLFSSL_HAVE_SP_ECC
wolfSSL 14:167253f4e170 6644 #ifndef WOLFSSL_SP_NO_256
wolfSSL 14:167253f4e170 6645
wolfSSL 14:167253f4e170 6646 /* Point structure to use. */
wolfSSL 14:167253f4e170 6647 typedef struct sp_point {
wolfSSL 14:167253f4e170 6648 sp_digit x[2 * 5];
wolfSSL 14:167253f4e170 6649 sp_digit y[2 * 5];
wolfSSL 14:167253f4e170 6650 sp_digit z[2 * 5];
wolfSSL 14:167253f4e170 6651 int infinity;
wolfSSL 14:167253f4e170 6652 } sp_point;
wolfSSL 14:167253f4e170 6653
wolfSSL 14:167253f4e170 6654 /* The modulus (prime) of the curve P256. */
wolfSSL 14:167253f4e170 6655 static sp_digit p256_mod[5] = {
wolfSSL 14:167253f4e170 6656 0xfffffffffffffl,0x00fffffffffffl,0x0000000000000l,0x0001000000000l,
wolfSSL 14:167253f4e170 6657 0x0ffffffff0000l
wolfSSL 14:167253f4e170 6658 };
wolfSSL 14:167253f4e170 6659 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 6660 /* The Montogmery normalizer for modulus of the curve P256. */
wolfSSL 14:167253f4e170 6661 static sp_digit p256_norm_mod[5] = {
wolfSSL 14:167253f4e170 6662 0x0000000000001l,0xff00000000000l,0xfffffffffffffl,0xfffefffffffffl,
wolfSSL 14:167253f4e170 6663 0x000000000ffffl
wolfSSL 14:167253f4e170 6664 };
wolfSSL 14:167253f4e170 6665 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 6666 /* The Montogmery multiplier for modulus of the curve P256. */
wolfSSL 14:167253f4e170 6667 static sp_digit p256_mp_mod = 0x0000000000001;
wolfSSL 14:167253f4e170 6668 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
wolfSSL 14:167253f4e170 6669 defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 6670 /* The order of the curve P256. */
wolfSSL 14:167253f4e170 6671 static sp_digit p256_order[5] = {
wolfSSL 14:167253f4e170 6672 0x9cac2fc632551l,0xada7179e84f3bl,0xfffffffbce6fal,0x0000fffffffffl,
wolfSSL 14:167253f4e170 6673 0x0ffffffff0000l
wolfSSL 14:167253f4e170 6674 };
wolfSSL 14:167253f4e170 6675 #endif
wolfSSL 14:167253f4e170 6676 /* The order of the curve P256 minus 2. */
wolfSSL 14:167253f4e170 6677 static sp_digit p256_order2[5] = {
wolfSSL 14:167253f4e170 6678 0x9cac2fc63254fl,0xada7179e84f3bl,0xfffffffbce6fal,0x0000fffffffffl,
wolfSSL 14:167253f4e170 6679 0x0ffffffff0000l
wolfSSL 14:167253f4e170 6680 };
wolfSSL 14:167253f4e170 6681 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 6682 /* The Montogmery normalizer for order of the curve P256. */
wolfSSL 14:167253f4e170 6683 static sp_digit p256_norm_order[5] = {
wolfSSL 14:167253f4e170 6684 0x6353d039cdaafl,0x5258e8617b0c4l,0x0000000431905l,0xffff000000000l,
wolfSSL 14:167253f4e170 6685 0x000000000ffffl
wolfSSL 14:167253f4e170 6686 };
wolfSSL 14:167253f4e170 6687 #endif
wolfSSL 14:167253f4e170 6688 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 6689 /* The Montogmery multiplier for order of the curve P256. */
wolfSSL 14:167253f4e170 6690 static sp_digit p256_mp_order = 0x1c8aaee00bc4fl;
wolfSSL 14:167253f4e170 6691 #endif
wolfSSL 14:167253f4e170 6692 /* The base point of curve P256. */
wolfSSL 14:167253f4e170 6693 static sp_point p256_base = {
wolfSSL 14:167253f4e170 6694 /* X ordinate */
wolfSSL 14:167253f4e170 6695 {
wolfSSL 14:167253f4e170 6696 0x13945d898c296l,0x812deb33a0f4al,0x3a440f277037dl,0x4247f8bce6e56l,
wolfSSL 14:167253f4e170 6697 0x06b17d1f2e12cl
wolfSSL 14:167253f4e170 6698 },
wolfSSL 14:167253f4e170 6699 /* Y ordinate */
wolfSSL 14:167253f4e170 6700 {
wolfSSL 14:167253f4e170 6701 0x6406837bf51f5l,0x576b315ececbbl,0xc0f9e162bce33l,0x7f9b8ee7eb4a7l,
wolfSSL 14:167253f4e170 6702 0x04fe342e2fe1al
wolfSSL 14:167253f4e170 6703 },
wolfSSL 14:167253f4e170 6704 /* Z ordinate */
wolfSSL 14:167253f4e170 6705 {
wolfSSL 14:167253f4e170 6706 0x0000000000001l,0x0000000000000l,0x0000000000000l,0x0000000000000l,
wolfSSL 14:167253f4e170 6707 0x0000000000000l
wolfSSL 14:167253f4e170 6708 },
wolfSSL 14:167253f4e170 6709 /* infinity */
wolfSSL 14:167253f4e170 6710 0
wolfSSL 14:167253f4e170 6711 };
wolfSSL 14:167253f4e170 6712 #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)
wolfSSL 14:167253f4e170 6713 static sp_digit p256_b[5] = {
wolfSSL 14:167253f4e170 6714 0xe3c3e27d2604bl,0xb0cc53b0f63bcl,0x69886bc651d06l,0x93e7b3ebbd557l,
wolfSSL 14:167253f4e170 6715 0x05ac635d8aa3al
wolfSSL 14:167253f4e170 6716 };
wolfSSL 14:167253f4e170 6717 #endif
wolfSSL 14:167253f4e170 6718
wolfSSL 14:167253f4e170 6719 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6720 /* Allocate memory for point and return error. */
wolfSSL 14:167253f4e170 6721 #define sp_ecc_point_new(heap, sp, p) \
wolfSSL 14:167253f4e170 6722 ((p = XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC)) == NULL) ? \
wolfSSL 14:167253f4e170 6723 MEMORY_E : MP_OKAY
wolfSSL 14:167253f4e170 6724 #else
wolfSSL 14:167253f4e170 6725 /* Set pointer to data and return no error. */
wolfSSL 14:167253f4e170 6726 #define sp_ecc_point_new(heap, sp, p) ((p = &sp) == NULL) ? MEMORY_E : MP_OKAY
wolfSSL 14:167253f4e170 6727 #endif
wolfSSL 14:167253f4e170 6728
wolfSSL 14:167253f4e170 6729 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6730 /* If valid pointer then clear point data if requested and free data. */
wolfSSL 14:167253f4e170 6731 #define sp_ecc_point_free(p, clear, heap) \
wolfSSL 14:167253f4e170 6732 do { \
wolfSSL 14:167253f4e170 6733 if (p != NULL) { \
wolfSSL 14:167253f4e170 6734 if (clear) \
wolfSSL 14:167253f4e170 6735 XMEMSET(p, 0, sizeof(*p)); \
wolfSSL 14:167253f4e170 6736 XFREE(p, heap, DYNAMIC_TYPE_ECC); \
wolfSSL 14:167253f4e170 6737 } \
wolfSSL 14:167253f4e170 6738 } \
wolfSSL 14:167253f4e170 6739 while (0)
wolfSSL 14:167253f4e170 6740 #else
wolfSSL 14:167253f4e170 6741 /* Clear point data if requested. */
wolfSSL 14:167253f4e170 6742 #define sp_ecc_point_free(p, clear, heap) \
wolfSSL 14:167253f4e170 6743 do { \
wolfSSL 14:167253f4e170 6744 if (clear) \
wolfSSL 14:167253f4e170 6745 XMEMSET(p, 0, sizeof(*p)); \
wolfSSL 14:167253f4e170 6746 } \
wolfSSL 14:167253f4e170 6747 while (0)
wolfSSL 14:167253f4e170 6748 #endif
wolfSSL 14:167253f4e170 6749
wolfSSL 14:167253f4e170 6750 /* Multiply a number by Montogmery normalizer mod modulus (prime).
wolfSSL 14:167253f4e170 6751 *
wolfSSL 14:167253f4e170 6752 * r The resulting Montgomery form number.
wolfSSL 14:167253f4e170 6753 * a The number to convert.
wolfSSL 14:167253f4e170 6754 * m The modulus (prime).
wolfSSL 14:167253f4e170 6755 * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 6756 */
wolfSSL 14:167253f4e170 6757 static int sp_256_mod_mul_norm_5(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 6758 {
wolfSSL 14:167253f4e170 6759 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6760 int64_t* td;
wolfSSL 14:167253f4e170 6761 #else
wolfSSL 14:167253f4e170 6762 int64_t td[8];
wolfSSL 14:167253f4e170 6763 int64_t a32d[8];
wolfSSL 14:167253f4e170 6764 #endif
wolfSSL 14:167253f4e170 6765 int64_t* t;
wolfSSL 14:167253f4e170 6766 int64_t* a32;
wolfSSL 14:167253f4e170 6767 int64_t o;
wolfSSL 14:167253f4e170 6768 int err = MP_OKAY;
wolfSSL 14:167253f4e170 6769
wolfSSL 14:167253f4e170 6770 (void)m;
wolfSSL 14:167253f4e170 6771
wolfSSL 14:167253f4e170 6772 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6773 td = XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 6774 if (td != NULL) {
wolfSSL 14:167253f4e170 6775 t = td;
wolfSSL 14:167253f4e170 6776 a32 = td + 8;
wolfSSL 14:167253f4e170 6777 }
wolfSSL 14:167253f4e170 6778 else
wolfSSL 14:167253f4e170 6779 err = MEMORY_E;
wolfSSL 14:167253f4e170 6780 #else
wolfSSL 14:167253f4e170 6781 t = td;
wolfSSL 14:167253f4e170 6782 a32 = a32d;
wolfSSL 14:167253f4e170 6783 #endif
wolfSSL 14:167253f4e170 6784
wolfSSL 14:167253f4e170 6785 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6786 a32[0] = (sp_digit)(a[0]) & 0xffffffff;
wolfSSL 14:167253f4e170 6787 a32[1] = (sp_digit)(a[0] >> 32);
wolfSSL 14:167253f4e170 6788 a32[1] |= a[1] << 20;
wolfSSL 14:167253f4e170 6789 a32[1] &= 0xffffffff;
wolfSSL 14:167253f4e170 6790 a32[2] = (sp_digit)(a[1] >> 12) & 0xffffffff;
wolfSSL 14:167253f4e170 6791 a32[3] = (sp_digit)(a[1] >> 44);
wolfSSL 14:167253f4e170 6792 a32[3] |= a[2] << 8;
wolfSSL 14:167253f4e170 6793 a32[3] &= 0xffffffff;
wolfSSL 14:167253f4e170 6794 a32[4] = (sp_digit)(a[2] >> 24);
wolfSSL 14:167253f4e170 6795 a32[4] |= a[3] << 28;
wolfSSL 14:167253f4e170 6796 a32[4] &= 0xffffffff;
wolfSSL 14:167253f4e170 6797 a32[5] = (sp_digit)(a[3] >> 4) & 0xffffffff;
wolfSSL 14:167253f4e170 6798 a32[6] = (sp_digit)(a[3] >> 36);
wolfSSL 14:167253f4e170 6799 a32[6] |= a[4] << 16;
wolfSSL 14:167253f4e170 6800 a32[6] &= 0xffffffff;
wolfSSL 14:167253f4e170 6801 a32[7] = (sp_digit)(a[4] >> 16) & 0xffffffff;
wolfSSL 14:167253f4e170 6802
wolfSSL 14:167253f4e170 6803 /* 1 1 0 -1 -1 -1 -1 0 */
wolfSSL 14:167253f4e170 6804 t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6];
wolfSSL 14:167253f4e170 6805 /* 0 1 1 0 -1 -1 -1 -1 */
wolfSSL 14:167253f4e170 6806 t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7];
wolfSSL 14:167253f4e170 6807 /* 0 0 1 1 0 -1 -1 -1 */
wolfSSL 14:167253f4e170 6808 t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7];
wolfSSL 14:167253f4e170 6809 /* -1 -1 0 2 2 1 0 -1 */
wolfSSL 14:167253f4e170 6810 t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7];
wolfSSL 14:167253f4e170 6811 /* 0 -1 -1 0 2 2 1 0 */
wolfSSL 14:167253f4e170 6812 t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6];
wolfSSL 14:167253f4e170 6813 /* 0 0 -1 -1 0 2 2 1 */
wolfSSL 14:167253f4e170 6814 t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7];
wolfSSL 14:167253f4e170 6815 /* -1 -1 0 0 0 1 3 2 */
wolfSSL 14:167253f4e170 6816 t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7];
wolfSSL 14:167253f4e170 6817 /* 1 0 -1 -1 -1 -1 0 3 */
wolfSSL 14:167253f4e170 6818 t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7];
wolfSSL 14:167253f4e170 6819
wolfSSL 14:167253f4e170 6820 t[1] += t[0] >> 32; t[0] &= 0xffffffff;
wolfSSL 14:167253f4e170 6821 t[2] += t[1] >> 32; t[1] &= 0xffffffff;
wolfSSL 14:167253f4e170 6822 t[3] += t[2] >> 32; t[2] &= 0xffffffff;
wolfSSL 14:167253f4e170 6823 t[4] += t[3] >> 32; t[3] &= 0xffffffff;
wolfSSL 14:167253f4e170 6824 t[5] += t[4] >> 32; t[4] &= 0xffffffff;
wolfSSL 14:167253f4e170 6825 t[6] += t[5] >> 32; t[5] &= 0xffffffff;
wolfSSL 14:167253f4e170 6826 t[7] += t[6] >> 32; t[6] &= 0xffffffff;
wolfSSL 14:167253f4e170 6827 o = t[7] >> 32; t[7] &= 0xffffffff;
wolfSSL 14:167253f4e170 6828 t[0] += o;
wolfSSL 14:167253f4e170 6829 t[3] -= o;
wolfSSL 14:167253f4e170 6830 t[6] -= o;
wolfSSL 14:167253f4e170 6831 t[7] += o;
wolfSSL 14:167253f4e170 6832 t[1] += t[0] >> 32; t[0] &= 0xffffffff;
wolfSSL 14:167253f4e170 6833 t[2] += t[1] >> 32; t[1] &= 0xffffffff;
wolfSSL 14:167253f4e170 6834 t[3] += t[2] >> 32; t[2] &= 0xffffffff;
wolfSSL 14:167253f4e170 6835 t[4] += t[3] >> 32; t[3] &= 0xffffffff;
wolfSSL 14:167253f4e170 6836 t[5] += t[4] >> 32; t[4] &= 0xffffffff;
wolfSSL 14:167253f4e170 6837 t[6] += t[5] >> 32; t[5] &= 0xffffffff;
wolfSSL 14:167253f4e170 6838 t[7] += t[6] >> 32; t[6] &= 0xffffffff;
wolfSSL 14:167253f4e170 6839
wolfSSL 14:167253f4e170 6840 r[0] = t[0];
wolfSSL 14:167253f4e170 6841 r[0] |= t[1] << 32;
wolfSSL 14:167253f4e170 6842 r[0] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 6843 r[1] = (sp_digit)(t[1] >> 20);
wolfSSL 14:167253f4e170 6844 r[1] |= t[2] << 12;
wolfSSL 14:167253f4e170 6845 r[1] |= t[3] << 44;
wolfSSL 14:167253f4e170 6846 r[1] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 6847 r[2] = (sp_digit)(t[3] >> 8);
wolfSSL 14:167253f4e170 6848 r[2] |= t[4] << 24;
wolfSSL 14:167253f4e170 6849 r[2] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 6850 r[3] = (sp_digit)(t[4] >> 28);
wolfSSL 14:167253f4e170 6851 r[3] |= t[5] << 4;
wolfSSL 14:167253f4e170 6852 r[3] |= t[6] << 36;
wolfSSL 14:167253f4e170 6853 r[3] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 6854 r[4] = (sp_digit)(t[6] >> 16);
wolfSSL 14:167253f4e170 6855 r[4] |= t[7] << 16;
wolfSSL 14:167253f4e170 6856 }
wolfSSL 14:167253f4e170 6857
wolfSSL 14:167253f4e170 6858 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 6859 if (td != NULL)
wolfSSL 14:167253f4e170 6860 XFREE(td, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 6861 #endif
wolfSSL 14:167253f4e170 6862
wolfSSL 14:167253f4e170 6863 return err;
wolfSSL 14:167253f4e170 6864 }
wolfSSL 14:167253f4e170 6865
wolfSSL 14:167253f4e170 6866 /* Convert an mp_int to an array of sp_digit.
wolfSSL 14:167253f4e170 6867 *
wolfSSL 14:167253f4e170 6868 * r A single precision integer.
wolfSSL 14:167253f4e170 6869 * a A multi-precision integer.
wolfSSL 14:167253f4e170 6870 */
wolfSSL 14:167253f4e170 6871 static void sp_256_from_mp(sp_digit* r, int max, mp_int* a)
wolfSSL 14:167253f4e170 6872 {
wolfSSL 14:167253f4e170 6873 #if DIGIT_BIT == 52
wolfSSL 14:167253f4e170 6874 int j;
wolfSSL 14:167253f4e170 6875
wolfSSL 14:167253f4e170 6876 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 14:167253f4e170 6877
wolfSSL 14:167253f4e170 6878 for (j = a->used; j < max; j++)
wolfSSL 14:167253f4e170 6879 r[j] = 0;
wolfSSL 14:167253f4e170 6880 #elif DIGIT_BIT > 52
wolfSSL 14:167253f4e170 6881 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 6882
wolfSSL 14:167253f4e170 6883 r[0] = 0;
wolfSSL 14:167253f4e170 6884 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 6885 r[j] |= a->dp[i] << s;
wolfSSL 14:167253f4e170 6886 r[j] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 6887 s = 52 - s;
wolfSSL 14:167253f4e170 6888 if (j + 1 >= max)
wolfSSL 14:167253f4e170 6889 break;
wolfSSL 14:167253f4e170 6890 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 6891 while (s + 52 <= DIGIT_BIT) {
wolfSSL 14:167253f4e170 6892 s += 52;
wolfSSL 14:167253f4e170 6893 r[j] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 6894 if (j + 1 >= max)
wolfSSL 14:167253f4e170 6895 break;
wolfSSL 14:167253f4e170 6896 if (s < DIGIT_BIT)
wolfSSL 14:167253f4e170 6897 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 6898 else
wolfSSL 14:167253f4e170 6899 r[++j] = 0;
wolfSSL 14:167253f4e170 6900 }
wolfSSL 14:167253f4e170 6901 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 6902 }
wolfSSL 14:167253f4e170 6903
wolfSSL 14:167253f4e170 6904 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 6905 r[j] = 0;
wolfSSL 14:167253f4e170 6906 #else
wolfSSL 14:167253f4e170 6907 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 6908
wolfSSL 14:167253f4e170 6909 r[0] = 0;
wolfSSL 14:167253f4e170 6910 for (i = 0; i < a->used && j < max; i++) {
wolfSSL 14:167253f4e170 6911 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 14:167253f4e170 6912 if (s + DIGIT_BIT >= 52) {
wolfSSL 14:167253f4e170 6913 r[j] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 6914 if (j + 1 >= max)
wolfSSL 14:167253f4e170 6915 break;
wolfSSL 14:167253f4e170 6916 s = 52 - s;
wolfSSL 14:167253f4e170 6917 if (s == DIGIT_BIT) {
wolfSSL 14:167253f4e170 6918 r[++j] = 0;
wolfSSL 14:167253f4e170 6919 s = 0;
wolfSSL 14:167253f4e170 6920 }
wolfSSL 14:167253f4e170 6921 else {
wolfSSL 14:167253f4e170 6922 r[++j] = a->dp[i] >> s;
wolfSSL 14:167253f4e170 6923 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 6924 }
wolfSSL 14:167253f4e170 6925 }
wolfSSL 14:167253f4e170 6926 else
wolfSSL 14:167253f4e170 6927 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 6928 }
wolfSSL 14:167253f4e170 6929
wolfSSL 14:167253f4e170 6930 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 6931 r[j] = 0;
wolfSSL 14:167253f4e170 6932 #endif
wolfSSL 14:167253f4e170 6933 }
wolfSSL 14:167253f4e170 6934
wolfSSL 14:167253f4e170 6935 /* Convert a point of type ecc_point to type sp_point.
wolfSSL 14:167253f4e170 6936 *
wolfSSL 14:167253f4e170 6937 * p Point of type sp_point (result).
wolfSSL 14:167253f4e170 6938 * pm Point of type ecc_point.
wolfSSL 14:167253f4e170 6939 */
wolfSSL 14:167253f4e170 6940 static void sp_256_point_from_ecc_point_5(sp_point* p, ecc_point* pm)
wolfSSL 14:167253f4e170 6941 {
wolfSSL 14:167253f4e170 6942 XMEMSET(p->x, 0, sizeof(p->x));
wolfSSL 14:167253f4e170 6943 XMEMSET(p->y, 0, sizeof(p->y));
wolfSSL 14:167253f4e170 6944 XMEMSET(p->z, 0, sizeof(p->z));
wolfSSL 14:167253f4e170 6945 sp_256_from_mp(p->x, 5, pm->x);
wolfSSL 14:167253f4e170 6946 sp_256_from_mp(p->y, 5, pm->y);
wolfSSL 14:167253f4e170 6947 sp_256_from_mp(p->z, 5, pm->z);
wolfSSL 14:167253f4e170 6948 p->infinity = 0;
wolfSSL 14:167253f4e170 6949 }
wolfSSL 14:167253f4e170 6950
wolfSSL 14:167253f4e170 6951 /* Convert an array of sp_digit to an mp_int.
wolfSSL 14:167253f4e170 6952 *
wolfSSL 14:167253f4e170 6953 * a A single precision integer.
wolfSSL 14:167253f4e170 6954 * r A multi-precision integer.
wolfSSL 14:167253f4e170 6955 */
wolfSSL 14:167253f4e170 6956 static int sp_256_to_mp(sp_digit* a, mp_int* r)
wolfSSL 14:167253f4e170 6957 {
wolfSSL 14:167253f4e170 6958 int err;
wolfSSL 14:167253f4e170 6959
wolfSSL 14:167253f4e170 6960 err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 14:167253f4e170 6961 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 6962 #if DIGIT_BIT == 52
wolfSSL 14:167253f4e170 6963 XMEMCPY(r->dp, a, sizeof(sp_digit) * 5);
wolfSSL 14:167253f4e170 6964 r->used = 5;
wolfSSL 14:167253f4e170 6965 mp_clamp(r);
wolfSSL 14:167253f4e170 6966 #elif DIGIT_BIT < 52
wolfSSL 14:167253f4e170 6967 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 6968
wolfSSL 14:167253f4e170 6969 r->dp[0] = 0;
wolfSSL 14:167253f4e170 6970 for (i = 0; i < 5; i++) {
wolfSSL 14:167253f4e170 6971 r->dp[j] |= a[i] << s;
wolfSSL 14:167253f4e170 6972 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 6973 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 6974 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 6975 while (s + DIGIT_BIT <= 52) {
wolfSSL 14:167253f4e170 6976 s += DIGIT_BIT;
wolfSSL 14:167253f4e170 6977 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 6978 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 6979 }
wolfSSL 14:167253f4e170 6980 s = 52 - s;
wolfSSL 14:167253f4e170 6981 }
wolfSSL 14:167253f4e170 6982 r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 6983 mp_clamp(r);
wolfSSL 14:167253f4e170 6984 #else
wolfSSL 14:167253f4e170 6985 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 6986
wolfSSL 14:167253f4e170 6987 r->dp[0] = 0;
wolfSSL 14:167253f4e170 6988 for (i = 0; i < 5; i++) {
wolfSSL 14:167253f4e170 6989 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 6990 if (s + 52 >= DIGIT_BIT) {
wolfSSL 14:167253f4e170 6991 #if DIGIT_BIT < 64
wolfSSL 14:167253f4e170 6992 r->dp[j] &= (1l << DIGIT_BIT) - 1;
wolfSSL 14:167253f4e170 6993 #endif
wolfSSL 14:167253f4e170 6994 s = DIGIT_BIT - s;
wolfSSL 14:167253f4e170 6995 r->dp[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 6996 s = 52 - s;
wolfSSL 14:167253f4e170 6997 }
wolfSSL 14:167253f4e170 6998 else
wolfSSL 14:167253f4e170 6999 s += 52;
wolfSSL 14:167253f4e170 7000 }
wolfSSL 14:167253f4e170 7001 r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 14:167253f4e170 7002 mp_clamp(r);
wolfSSL 14:167253f4e170 7003 #endif
wolfSSL 14:167253f4e170 7004 }
wolfSSL 14:167253f4e170 7005
wolfSSL 14:167253f4e170 7006 return err;
wolfSSL 14:167253f4e170 7007 }
wolfSSL 14:167253f4e170 7008
wolfSSL 14:167253f4e170 7009 /* Convert a point of type sp_point to type ecc_point.
wolfSSL 14:167253f4e170 7010 *
wolfSSL 14:167253f4e170 7011 * p Point of type sp_point.
wolfSSL 14:167253f4e170 7012 * pm Point of type ecc_point (result).
wolfSSL 14:167253f4e170 7013 * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
wolfSSL 14:167253f4e170 7014 * MP_OKAY.
wolfSSL 14:167253f4e170 7015 */
wolfSSL 14:167253f4e170 7016 static int sp_256_point_to_ecc_point_5(sp_point* p, ecc_point* pm)
wolfSSL 14:167253f4e170 7017 {
wolfSSL 14:167253f4e170 7018 int err;
wolfSSL 14:167253f4e170 7019
wolfSSL 14:167253f4e170 7020 err = sp_256_to_mp(p->x, pm->x);
wolfSSL 14:167253f4e170 7021 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 7022 err = sp_256_to_mp(p->y, pm->y);
wolfSSL 14:167253f4e170 7023 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 7024 err = sp_256_to_mp(p->z, pm->z);
wolfSSL 14:167253f4e170 7025
wolfSSL 14:167253f4e170 7026 return err;
wolfSSL 14:167253f4e170 7027 }
wolfSSL 14:167253f4e170 7028
wolfSSL 14:167253f4e170 7029 /* Compare a with b in constant time.
wolfSSL 14:167253f4e170 7030 *
wolfSSL 14:167253f4e170 7031 * a A single precision integer.
wolfSSL 14:167253f4e170 7032 * b A single precision integer.
wolfSSL 14:167253f4e170 7033 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 14:167253f4e170 7034 * respectively.
wolfSSL 14:167253f4e170 7035 */
wolfSSL 14:167253f4e170 7036 static sp_digit sp_256_cmp_5(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 7037 {
wolfSSL 14:167253f4e170 7038 sp_digit r = 0;
wolfSSL 14:167253f4e170 7039 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7040 int i;
wolfSSL 14:167253f4e170 7041
wolfSSL 14:167253f4e170 7042 for (i=4; i>=0; i--)
wolfSSL 14:167253f4e170 7043 r |= (a[i] - b[i]) & (0 - !r);
wolfSSL 14:167253f4e170 7044 #else
wolfSSL 14:167253f4e170 7045 r |= (a[ 4] - b[ 4]) & (0 - !r);
wolfSSL 14:167253f4e170 7046 r |= (a[ 3] - b[ 3]) & (0 - !r);
wolfSSL 14:167253f4e170 7047 r |= (a[ 2] - b[ 2]) & (0 - !r);
wolfSSL 14:167253f4e170 7048 r |= (a[ 1] - b[ 1]) & (0 - !r);
wolfSSL 14:167253f4e170 7049 r |= (a[ 0] - b[ 0]) & (0 - !r);
wolfSSL 14:167253f4e170 7050 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7051
wolfSSL 14:167253f4e170 7052 return r;
wolfSSL 14:167253f4e170 7053 }
wolfSSL 14:167253f4e170 7054
wolfSSL 14:167253f4e170 7055 /* Normalize the values in each word to 52.
wolfSSL 14:167253f4e170 7056 *
wolfSSL 14:167253f4e170 7057 * a Array of sp_digit to normalize.
wolfSSL 14:167253f4e170 7058 */
wolfSSL 14:167253f4e170 7059 static void sp_256_norm_5(sp_digit* a)
wolfSSL 14:167253f4e170 7060 {
wolfSSL 14:167253f4e170 7061 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7062 int i;
wolfSSL 14:167253f4e170 7063 for (i = 0; i < 4; i++) {
wolfSSL 14:167253f4e170 7064 a[i+1] += a[i] >> 52;
wolfSSL 14:167253f4e170 7065 a[i] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7066 }
wolfSSL 14:167253f4e170 7067 #else
wolfSSL 14:167253f4e170 7068 a[1] += a[0] >> 52; a[0] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7069 a[2] += a[1] >> 52; a[1] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7070 a[3] += a[2] >> 52; a[2] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7071 a[4] += a[3] >> 52; a[3] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7072 #endif
wolfSSL 14:167253f4e170 7073 }
wolfSSL 14:167253f4e170 7074
wolfSSL 14:167253f4e170 7075 /* Conditionally subtract b from a using the mask m.
wolfSSL 14:167253f4e170 7076 * m is -1 to subtract and 0 when not.
wolfSSL 14:167253f4e170 7077 *
wolfSSL 14:167253f4e170 7078 * r A single precision number representing condition subtract result.
wolfSSL 14:167253f4e170 7079 * a A single precision number to subtract from.
wolfSSL 14:167253f4e170 7080 * b A single precision number to subtract.
wolfSSL 14:167253f4e170 7081 * m Mask value to apply.
wolfSSL 14:167253f4e170 7082 */
wolfSSL 14:167253f4e170 7083 static void sp_256_cond_sub_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7084 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 7085 {
wolfSSL 14:167253f4e170 7086 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7087 int i;
wolfSSL 14:167253f4e170 7088
wolfSSL 14:167253f4e170 7089 for (i = 0; i < 5; i++)
wolfSSL 14:167253f4e170 7090 r[i] = a[i] - (b[i] & m);
wolfSSL 14:167253f4e170 7091 #else
wolfSSL 14:167253f4e170 7092 r[ 0] = a[ 0] - (b[ 0] & m);
wolfSSL 14:167253f4e170 7093 r[ 1] = a[ 1] - (b[ 1] & m);
wolfSSL 14:167253f4e170 7094 r[ 2] = a[ 2] - (b[ 2] & m);
wolfSSL 14:167253f4e170 7095 r[ 3] = a[ 3] - (b[ 3] & m);
wolfSSL 14:167253f4e170 7096 r[ 4] = a[ 4] - (b[ 4] & m);
wolfSSL 14:167253f4e170 7097 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7098 }
wolfSSL 14:167253f4e170 7099
wolfSSL 14:167253f4e170 7100 /* Mul a by scalar b and add into r. (r += a * b)
wolfSSL 14:167253f4e170 7101 *
wolfSSL 14:167253f4e170 7102 * r A single precision integer.
wolfSSL 14:167253f4e170 7103 * a A single precision integer.
wolfSSL 14:167253f4e170 7104 * b A scalar.
wolfSSL 14:167253f4e170 7105 */
wolfSSL 14:167253f4e170 7106 SP_NOINLINE static void sp_256_mul_add_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7107 const sp_digit b)
wolfSSL 14:167253f4e170 7108 {
wolfSSL 14:167253f4e170 7109 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7110 int128_t tb = b;
wolfSSL 14:167253f4e170 7111 int128_t t = 0;
wolfSSL 14:167253f4e170 7112 int i;
wolfSSL 14:167253f4e170 7113
wolfSSL 14:167253f4e170 7114 for (i = 0; i < 5; i++) {
wolfSSL 14:167253f4e170 7115 t += (tb * a[i]) + r[i];
wolfSSL 14:167253f4e170 7116 r[i] = t & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7117 t >>= 52;
wolfSSL 14:167253f4e170 7118 }
wolfSSL 14:167253f4e170 7119 r[5] += t;
wolfSSL 14:167253f4e170 7120 #else
wolfSSL 14:167253f4e170 7121 int128_t tb = b;
wolfSSL 14:167253f4e170 7122 int128_t t[5];
wolfSSL 14:167253f4e170 7123
wolfSSL 14:167253f4e170 7124 t[ 0] = tb * a[ 0];
wolfSSL 14:167253f4e170 7125 t[ 1] = tb * a[ 1];
wolfSSL 14:167253f4e170 7126 t[ 2] = tb * a[ 2];
wolfSSL 14:167253f4e170 7127 t[ 3] = tb * a[ 3];
wolfSSL 14:167253f4e170 7128 t[ 4] = tb * a[ 4];
wolfSSL 14:167253f4e170 7129 r[ 0] += (t[ 0] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 7130 r[ 1] += (t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 7131 r[ 2] += (t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 7132 r[ 3] += (t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 7133 r[ 4] += (t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 7134 r[ 5] += t[ 4] >> 52;
wolfSSL 14:167253f4e170 7135 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7136 }
wolfSSL 14:167253f4e170 7137
wolfSSL 14:167253f4e170 7138 /* Shift the result in the high 256 bits down to the bottom.
wolfSSL 14:167253f4e170 7139 *
wolfSSL 14:167253f4e170 7140 * r A single precision number.
wolfSSL 14:167253f4e170 7141 * a A single precision number.
wolfSSL 14:167253f4e170 7142 */
wolfSSL 14:167253f4e170 7143 static void sp_256_mont_shift_5(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 7144 {
wolfSSL 14:167253f4e170 7145 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7146 int i;
wolfSSL 14:167253f4e170 7147 word64 n;
wolfSSL 14:167253f4e170 7148
wolfSSL 14:167253f4e170 7149 n = a[4] >> 48;
wolfSSL 14:167253f4e170 7150 for (i = 0; i < 4; i++) {
wolfSSL 14:167253f4e170 7151 n += a[5 + i] << 4;
wolfSSL 14:167253f4e170 7152 r[i] = n & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7153 n >>= 52;
wolfSSL 14:167253f4e170 7154 }
wolfSSL 14:167253f4e170 7155 n += a[9] << 4;
wolfSSL 14:167253f4e170 7156 r[4] = n;
wolfSSL 14:167253f4e170 7157 #else
wolfSSL 14:167253f4e170 7158 word64 n;
wolfSSL 14:167253f4e170 7159
wolfSSL 14:167253f4e170 7160 n = a[4] >> 48;
wolfSSL 14:167253f4e170 7161 n += a[ 5] << 4; r[ 0] = n & 0xfffffffffffffl; n >>= 52;
wolfSSL 14:167253f4e170 7162 n += a[ 6] << 4; r[ 1] = n & 0xfffffffffffffl; n >>= 52;
wolfSSL 14:167253f4e170 7163 n += a[ 7] << 4; r[ 2] = n & 0xfffffffffffffl; n >>= 52;
wolfSSL 14:167253f4e170 7164 n += a[ 8] << 4; r[ 3] = n & 0xfffffffffffffl; n >>= 52;
wolfSSL 14:167253f4e170 7165 n += a[ 9] << 4; r[ 4] = n;
wolfSSL 14:167253f4e170 7166 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7167 XMEMSET(&r[5], 0, sizeof(*r) * 5);
wolfSSL 14:167253f4e170 7168 }
wolfSSL 14:167253f4e170 7169
wolfSSL 14:167253f4e170 7170 /* Reduce the number back to 256 bits using Montgomery reduction.
wolfSSL 14:167253f4e170 7171 *
wolfSSL 14:167253f4e170 7172 * a A single precision number to reduce in place.
wolfSSL 14:167253f4e170 7173 * m The single precision number representing the modulus.
wolfSSL 14:167253f4e170 7174 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 14:167253f4e170 7175 */
wolfSSL 14:167253f4e170 7176 static void sp_256_mont_reduce_5(sp_digit* a, sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 7177 {
wolfSSL 14:167253f4e170 7178 int i;
wolfSSL 14:167253f4e170 7179 sp_digit mu;
wolfSSL 14:167253f4e170 7180
wolfSSL 14:167253f4e170 7181 if (mp != 1) {
wolfSSL 14:167253f4e170 7182 for (i=0; i<4; i++) {
wolfSSL 14:167253f4e170 7183 mu = (a[i] * mp) & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7184 sp_256_mul_add_5(a+i, m, mu);
wolfSSL 14:167253f4e170 7185 a[i+1] += a[i] >> 52;
wolfSSL 14:167253f4e170 7186 }
wolfSSL 14:167253f4e170 7187 mu = (a[i] * mp) & 0xffffffffffffl;
wolfSSL 14:167253f4e170 7188 sp_256_mul_add_5(a+i, m, mu);
wolfSSL 14:167253f4e170 7189 a[i+1] += a[i] >> 52;
wolfSSL 14:167253f4e170 7190 a[i] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7191 }
wolfSSL 14:167253f4e170 7192 else {
wolfSSL 14:167253f4e170 7193 for (i=0; i<4; i++) {
wolfSSL 14:167253f4e170 7194 mu = a[i] & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7195 sp_256_mul_add_5(a+i, p256_mod, mu);
wolfSSL 14:167253f4e170 7196 a[i+1] += a[i] >> 52;
wolfSSL 14:167253f4e170 7197 }
wolfSSL 14:167253f4e170 7198 mu = a[i] & 0xffffffffffffl;
wolfSSL 14:167253f4e170 7199 sp_256_mul_add_5(a+i, p256_mod, mu);
wolfSSL 14:167253f4e170 7200 a[i+1] += a[i] >> 52;
wolfSSL 14:167253f4e170 7201 a[i] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7202 }
wolfSSL 14:167253f4e170 7203
wolfSSL 14:167253f4e170 7204 sp_256_mont_shift_5(a, a);
wolfSSL 14:167253f4e170 7205 sp_256_cond_sub_5(a, a, m, 0 - ((a[4] >> 48) > 0));
wolfSSL 14:167253f4e170 7206 sp_256_norm_5(a);
wolfSSL 14:167253f4e170 7207 }
wolfSSL 14:167253f4e170 7208
wolfSSL 14:167253f4e170 7209 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7210 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 7211 *
wolfSSL 14:167253f4e170 7212 * r A single precision integer.
wolfSSL 14:167253f4e170 7213 * a A single precision integer.
wolfSSL 14:167253f4e170 7214 * b A single precision integer.
wolfSSL 14:167253f4e170 7215 */
wolfSSL 14:167253f4e170 7216 SP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7217 const sp_digit* b)
wolfSSL 14:167253f4e170 7218 {
wolfSSL 14:167253f4e170 7219 int i, j, k;
wolfSSL 14:167253f4e170 7220 int128_t c;
wolfSSL 14:167253f4e170 7221
wolfSSL 14:167253f4e170 7222 c = ((int128_t)a[4]) * b[4];
wolfSSL 14:167253f4e170 7223 r[9] = (sp_digit)(c >> 52);
wolfSSL 14:167253f4e170 7224 c = (c & 0xfffffffffffffl) << 52;
wolfSSL 14:167253f4e170 7225 for (k = 7; k >= 0; k--) {
wolfSSL 14:167253f4e170 7226 for (i = 4; i >= 0; i--) {
wolfSSL 14:167253f4e170 7227 j = k - i;
wolfSSL 14:167253f4e170 7228 if (j >= 5)
wolfSSL 14:167253f4e170 7229 break;
wolfSSL 14:167253f4e170 7230 if (j < 0)
wolfSSL 14:167253f4e170 7231 continue;
wolfSSL 14:167253f4e170 7232
wolfSSL 14:167253f4e170 7233 c += ((int128_t)a[i]) * b[j];
wolfSSL 14:167253f4e170 7234 }
wolfSSL 14:167253f4e170 7235 r[k + 2] += c >> 104;
wolfSSL 14:167253f4e170 7236 r[k + 1] = (c >> 52) & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7237 c = (c & 0xfffffffffffffl) << 52;
wolfSSL 14:167253f4e170 7238 }
wolfSSL 14:167253f4e170 7239 r[0] = (sp_digit)(c >> 52);
wolfSSL 14:167253f4e170 7240 }
wolfSSL 14:167253f4e170 7241
wolfSSL 14:167253f4e170 7242 #else
wolfSSL 14:167253f4e170 7243 /* Multiply a and b into r. (r = a * b)
wolfSSL 14:167253f4e170 7244 *
wolfSSL 14:167253f4e170 7245 * r A single precision integer.
wolfSSL 14:167253f4e170 7246 * a A single precision integer.
wolfSSL 14:167253f4e170 7247 * b A single precision integer.
wolfSSL 14:167253f4e170 7248 */
wolfSSL 14:167253f4e170 7249 SP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7250 const sp_digit* b)
wolfSSL 14:167253f4e170 7251 {
wolfSSL 14:167253f4e170 7252 int128_t t0 = ((int128_t)a[ 0]) * b[ 0];
wolfSSL 14:167253f4e170 7253 int128_t t1 = ((int128_t)a[ 0]) * b[ 1]
wolfSSL 14:167253f4e170 7254 + ((int128_t)a[ 1]) * b[ 0];
wolfSSL 14:167253f4e170 7255 int128_t t2 = ((int128_t)a[ 0]) * b[ 2]
wolfSSL 14:167253f4e170 7256 + ((int128_t)a[ 1]) * b[ 1]
wolfSSL 14:167253f4e170 7257 + ((int128_t)a[ 2]) * b[ 0];
wolfSSL 14:167253f4e170 7258 int128_t t3 = ((int128_t)a[ 0]) * b[ 3]
wolfSSL 14:167253f4e170 7259 + ((int128_t)a[ 1]) * b[ 2]
wolfSSL 14:167253f4e170 7260 + ((int128_t)a[ 2]) * b[ 1]
wolfSSL 14:167253f4e170 7261 + ((int128_t)a[ 3]) * b[ 0];
wolfSSL 14:167253f4e170 7262 int128_t t4 = ((int128_t)a[ 0]) * b[ 4]
wolfSSL 14:167253f4e170 7263 + ((int128_t)a[ 1]) * b[ 3]
wolfSSL 14:167253f4e170 7264 + ((int128_t)a[ 2]) * b[ 2]
wolfSSL 14:167253f4e170 7265 + ((int128_t)a[ 3]) * b[ 1]
wolfSSL 14:167253f4e170 7266 + ((int128_t)a[ 4]) * b[ 0];
wolfSSL 14:167253f4e170 7267 int128_t t5 = ((int128_t)a[ 1]) * b[ 4]
wolfSSL 14:167253f4e170 7268 + ((int128_t)a[ 2]) * b[ 3]
wolfSSL 14:167253f4e170 7269 + ((int128_t)a[ 3]) * b[ 2]
wolfSSL 14:167253f4e170 7270 + ((int128_t)a[ 4]) * b[ 1];
wolfSSL 14:167253f4e170 7271 int128_t t6 = ((int128_t)a[ 2]) * b[ 4]
wolfSSL 14:167253f4e170 7272 + ((int128_t)a[ 3]) * b[ 3]
wolfSSL 14:167253f4e170 7273 + ((int128_t)a[ 4]) * b[ 2];
wolfSSL 14:167253f4e170 7274 int128_t t7 = ((int128_t)a[ 3]) * b[ 4]
wolfSSL 14:167253f4e170 7275 + ((int128_t)a[ 4]) * b[ 3];
wolfSSL 14:167253f4e170 7276 int128_t t8 = ((int128_t)a[ 4]) * b[ 4];
wolfSSL 14:167253f4e170 7277
wolfSSL 14:167253f4e170 7278 t1 += t0 >> 52; r[ 0] = t0 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7279 t2 += t1 >> 52; r[ 1] = t1 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7280 t3 += t2 >> 52; r[ 2] = t2 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7281 t4 += t3 >> 52; r[ 3] = t3 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7282 t5 += t4 >> 52; r[ 4] = t4 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7283 t6 += t5 >> 52; r[ 5] = t5 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7284 t7 += t6 >> 52; r[ 6] = t6 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7285 t8 += t7 >> 52; r[ 7] = t7 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7286 r[9] = (sp_digit)(t8 >> 52);
wolfSSL 14:167253f4e170 7287 r[8] = t8 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7288 }
wolfSSL 14:167253f4e170 7289
wolfSSL 14:167253f4e170 7290 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7291 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 14:167253f4e170 7292 * (r = a * b mod m)
wolfSSL 14:167253f4e170 7293 *
wolfSSL 14:167253f4e170 7294 * r Result of multiplication.
wolfSSL 14:167253f4e170 7295 * a First number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 7296 * b Second number to multiply in Montogmery form.
wolfSSL 14:167253f4e170 7297 * m Modulus (prime).
wolfSSL 14:167253f4e170 7298 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 7299 */
wolfSSL 14:167253f4e170 7300 static void sp_256_mont_mul_5(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 7301 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 7302 {
wolfSSL 14:167253f4e170 7303 sp_256_mul_5(r, a, b);
wolfSSL 14:167253f4e170 7304 sp_256_mont_reduce_5(r, m, mp);
wolfSSL 14:167253f4e170 7305 }
wolfSSL 14:167253f4e170 7306
wolfSSL 14:167253f4e170 7307 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7308 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 7309 *
wolfSSL 14:167253f4e170 7310 * r A single precision integer.
wolfSSL 14:167253f4e170 7311 * a A single precision integer.
wolfSSL 14:167253f4e170 7312 */
wolfSSL 14:167253f4e170 7313 SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 7314 {
wolfSSL 14:167253f4e170 7315 int i, j, k;
wolfSSL 14:167253f4e170 7316 int128_t c;
wolfSSL 14:167253f4e170 7317
wolfSSL 14:167253f4e170 7318 c = ((int128_t)a[4]) * a[4];
wolfSSL 14:167253f4e170 7319 r[9] = (sp_digit)(c >> 52);
wolfSSL 14:167253f4e170 7320 c = (c & 0xfffffffffffffl) << 52;
wolfSSL 14:167253f4e170 7321 for (k = 7; k >= 0; k--) {
wolfSSL 14:167253f4e170 7322 for (i = 4; i >= 0; i--) {
wolfSSL 14:167253f4e170 7323 j = k - i;
wolfSSL 14:167253f4e170 7324 if (j >= 5 || i <= j)
wolfSSL 14:167253f4e170 7325 break;
wolfSSL 14:167253f4e170 7326 if (j < 0)
wolfSSL 14:167253f4e170 7327 continue;
wolfSSL 14:167253f4e170 7328
wolfSSL 14:167253f4e170 7329 c += ((int128_t)a[i]) * a[j] * 2;
wolfSSL 14:167253f4e170 7330 }
wolfSSL 14:167253f4e170 7331 if (i == j)
wolfSSL 14:167253f4e170 7332 c += ((int128_t)a[i]) * a[i];
wolfSSL 14:167253f4e170 7333
wolfSSL 14:167253f4e170 7334 r[k + 2] += c >> 104;
wolfSSL 14:167253f4e170 7335 r[k + 1] = (c >> 52) & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7336 c = (c & 0xfffffffffffffl) << 52;
wolfSSL 14:167253f4e170 7337 }
wolfSSL 14:167253f4e170 7338 r[0] = (sp_digit)(c >> 52);
wolfSSL 14:167253f4e170 7339 }
wolfSSL 14:167253f4e170 7340
wolfSSL 14:167253f4e170 7341 #else
wolfSSL 14:167253f4e170 7342 /* Square a and put result in r. (r = a * a)
wolfSSL 14:167253f4e170 7343 *
wolfSSL 14:167253f4e170 7344 * r A single precision integer.
wolfSSL 14:167253f4e170 7345 * a A single precision integer.
wolfSSL 14:167253f4e170 7346 */
wolfSSL 14:167253f4e170 7347 SP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a)
wolfSSL 14:167253f4e170 7348 {
wolfSSL 14:167253f4e170 7349 int128_t t0 = ((int128_t)a[ 0]) * a[ 0];
wolfSSL 14:167253f4e170 7350 int128_t t1 = (((int128_t)a[ 0]) * a[ 1]) * 2;
wolfSSL 14:167253f4e170 7351 int128_t t2 = (((int128_t)a[ 0]) * a[ 2]) * 2
wolfSSL 14:167253f4e170 7352 + ((int128_t)a[ 1]) * a[ 1];
wolfSSL 14:167253f4e170 7353 int128_t t3 = (((int128_t)a[ 0]) * a[ 3]
wolfSSL 14:167253f4e170 7354 + ((int128_t)a[ 1]) * a[ 2]) * 2;
wolfSSL 14:167253f4e170 7355 int128_t t4 = (((int128_t)a[ 0]) * a[ 4]
wolfSSL 14:167253f4e170 7356 + ((int128_t)a[ 1]) * a[ 3]) * 2
wolfSSL 14:167253f4e170 7357 + ((int128_t)a[ 2]) * a[ 2];
wolfSSL 14:167253f4e170 7358 int128_t t5 = (((int128_t)a[ 1]) * a[ 4]
wolfSSL 14:167253f4e170 7359 + ((int128_t)a[ 2]) * a[ 3]) * 2;
wolfSSL 14:167253f4e170 7360 int128_t t6 = (((int128_t)a[ 2]) * a[ 4]) * 2
wolfSSL 14:167253f4e170 7361 + ((int128_t)a[ 3]) * a[ 3];
wolfSSL 14:167253f4e170 7362 int128_t t7 = (((int128_t)a[ 3]) * a[ 4]) * 2;
wolfSSL 14:167253f4e170 7363 int128_t t8 = ((int128_t)a[ 4]) * a[ 4];
wolfSSL 14:167253f4e170 7364
wolfSSL 14:167253f4e170 7365 t1 += t0 >> 52; r[ 0] = t0 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7366 t2 += t1 >> 52; r[ 1] = t1 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7367 t3 += t2 >> 52; r[ 2] = t2 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7368 t4 += t3 >> 52; r[ 3] = t3 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7369 t5 += t4 >> 52; r[ 4] = t4 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7370 t6 += t5 >> 52; r[ 5] = t5 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7371 t7 += t6 >> 52; r[ 6] = t6 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7372 t8 += t7 >> 52; r[ 7] = t7 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7373 r[9] = (sp_digit)(t8 >> 52);
wolfSSL 14:167253f4e170 7374 r[8] = t8 & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7375 }
wolfSSL 14:167253f4e170 7376
wolfSSL 14:167253f4e170 7377 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7378 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 14:167253f4e170 7379 *
wolfSSL 14:167253f4e170 7380 * r Result of squaring.
wolfSSL 14:167253f4e170 7381 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 7382 * m Modulus (prime).
wolfSSL 14:167253f4e170 7383 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 7384 */
wolfSSL 14:167253f4e170 7385 static void sp_256_mont_sqr_5(sp_digit* r, sp_digit* a, sp_digit* m,
wolfSSL 14:167253f4e170 7386 sp_digit mp)
wolfSSL 14:167253f4e170 7387 {
wolfSSL 14:167253f4e170 7388 sp_256_sqr_5(r, a);
wolfSSL 14:167253f4e170 7389 sp_256_mont_reduce_5(r, m, mp);
wolfSSL 14:167253f4e170 7390 }
wolfSSL 14:167253f4e170 7391
wolfSSL 14:167253f4e170 7392 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7393 /* Square the Montgomery form number a number of times. (r = a ^ n mod m)
wolfSSL 14:167253f4e170 7394 *
wolfSSL 14:167253f4e170 7395 * r Result of squaring.
wolfSSL 14:167253f4e170 7396 * a Number to square in Montogmery form.
wolfSSL 14:167253f4e170 7397 * n Number of times to square.
wolfSSL 14:167253f4e170 7398 * m Modulus (prime).
wolfSSL 14:167253f4e170 7399 * mp Montogmery mulitplier.
wolfSSL 14:167253f4e170 7400 */
wolfSSL 14:167253f4e170 7401 static void sp_256_mont_sqr_n_5(sp_digit* r, sp_digit* a, int n,
wolfSSL 14:167253f4e170 7402 sp_digit* m, sp_digit mp)
wolfSSL 14:167253f4e170 7403 {
wolfSSL 14:167253f4e170 7404 sp_256_mont_sqr_5(r, a, m, mp);
wolfSSL 14:167253f4e170 7405 for (; n > 1; n--)
wolfSSL 14:167253f4e170 7406 sp_256_mont_sqr_5(r, r, m, mp);
wolfSSL 14:167253f4e170 7407 }
wolfSSL 14:167253f4e170 7408
wolfSSL 14:167253f4e170 7409 #else
wolfSSL 14:167253f4e170 7410 /* Mod-2 for the P256 curve. */
wolfSSL 14:167253f4e170 7411 static const uint64_t p256_mod_2[4] = {
wolfSSL 14:167253f4e170 7412 0xfffffffffffffffd,0x00000000ffffffff,0x0000000000000000,
wolfSSL 14:167253f4e170 7413 0xffffffff00000001
wolfSSL 14:167253f4e170 7414 };
wolfSSL 14:167253f4e170 7415 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7416
wolfSSL 14:167253f4e170 7417 /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
wolfSSL 14:167253f4e170 7418 * P256 curve. (r = 1 / a mod m)
wolfSSL 14:167253f4e170 7419 *
wolfSSL 14:167253f4e170 7420 * r Inverse result.
wolfSSL 14:167253f4e170 7421 * a Number to invert.
wolfSSL 14:167253f4e170 7422 * td Temporary data.
wolfSSL 14:167253f4e170 7423 */
wolfSSL 14:167253f4e170 7424 static void sp_256_mont_inv_5(sp_digit* r, sp_digit* a, sp_digit* td)
wolfSSL 14:167253f4e170 7425 {
wolfSSL 14:167253f4e170 7426 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7427 sp_digit* t = td;
wolfSSL 14:167253f4e170 7428 int i;
wolfSSL 14:167253f4e170 7429
wolfSSL 14:167253f4e170 7430 XMEMCPY(t, a, sizeof(sp_digit) * 5);
wolfSSL 14:167253f4e170 7431 for (i=254; i>=0; i--) {
wolfSSL 14:167253f4e170 7432 sp_256_mont_sqr_5(t, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7433 if (p256_mod_2[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 7434 sp_256_mont_mul_5(t, t, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7435 }
wolfSSL 14:167253f4e170 7436 XMEMCPY(r, t, sizeof(sp_digit) * 5);
wolfSSL 14:167253f4e170 7437 #else
wolfSSL 14:167253f4e170 7438 sp_digit* t = td;
wolfSSL 14:167253f4e170 7439 sp_digit* t2 = td + 2 * 5;
wolfSSL 14:167253f4e170 7440 sp_digit* t3 = td + 4 * 5;
wolfSSL 14:167253f4e170 7441
wolfSSL 14:167253f4e170 7442 /* t = a^2 */
wolfSSL 14:167253f4e170 7443 sp_256_mont_sqr_5(t, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7444 /* t = a^3 = t * a */
wolfSSL 14:167253f4e170 7445 sp_256_mont_mul_5(t, t, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7446 /* t2= a^c = t ^ 2 ^ 2 */
wolfSSL 14:167253f4e170 7447 sp_256_mont_sqr_n_5(t2, t, 2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7448 /* t3= a^d = t2 * a */
wolfSSL 14:167253f4e170 7449 sp_256_mont_mul_5(t3, t2, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7450 /* t = a^f = t2 * t */
wolfSSL 14:167253f4e170 7451 sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7452 /* t2= a^f0 = t ^ 2 ^ 4 */
wolfSSL 14:167253f4e170 7453 sp_256_mont_sqr_n_5(t2, t, 4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7454 /* t3= a^fd = t2 * t3 */
wolfSSL 14:167253f4e170 7455 sp_256_mont_mul_5(t3, t2, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7456 /* t = a^ff = t2 * t */
wolfSSL 14:167253f4e170 7457 sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7458 /* t2= a^ff00 = t ^ 2 ^ 8 */
wolfSSL 14:167253f4e170 7459 sp_256_mont_sqr_n_5(t2, t, 8, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7460 /* t3= a^fffd = t2 * t3 */
wolfSSL 14:167253f4e170 7461 sp_256_mont_mul_5(t3, t2, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7462 /* t = a^ffff = t2 * t */
wolfSSL 14:167253f4e170 7463 sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7464 /* t2= a^ffff0000 = t ^ 2 ^ 16 */
wolfSSL 14:167253f4e170 7465 sp_256_mont_sqr_n_5(t2, t, 16, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7466 /* t3= a^fffffffd = t2 * t3 */
wolfSSL 14:167253f4e170 7467 sp_256_mont_mul_5(t3, t2, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7468 /* t = a^ffffffff = t2 * t */
wolfSSL 14:167253f4e170 7469 sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7470 /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */
wolfSSL 14:167253f4e170 7471 sp_256_mont_sqr_n_5(t2, t, 32, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7472 /* t2= a^ffffffffffffffff = t2 * t */
wolfSSL 14:167253f4e170 7473 sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7474 /* t2= a^ffffffff00000001 = t2 * a */
wolfSSL 14:167253f4e170 7475 sp_256_mont_mul_5(t2, t2, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7476 /* t2= a^ffffffff000000010000000000000000000000000000000000000000
wolfSSL 14:167253f4e170 7477 * = t2 ^ 2 ^ 160 */
wolfSSL 14:167253f4e170 7478 sp_256_mont_sqr_n_5(t2, t2, 160, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7479 /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff
wolfSSL 14:167253f4e170 7480 * = t2 * t */
wolfSSL 14:167253f4e170 7481 sp_256_mont_mul_5(t2, t2, t, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7482 /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000
wolfSSL 14:167253f4e170 7483 * = t2 ^ 2 ^ 32 */
wolfSSL 14:167253f4e170 7484 sp_256_mont_sqr_n_5(t2, t2, 32, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7485 /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd
wolfSSL 14:167253f4e170 7486 * = t2 * t3 */
wolfSSL 14:167253f4e170 7487 sp_256_mont_mul_5(r, t2, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7488 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7489 }
wolfSSL 14:167253f4e170 7490
wolfSSL 14:167253f4e170 7491 /* Map the Montgomery form projective co-ordinate point to an affine point.
wolfSSL 14:167253f4e170 7492 *
wolfSSL 14:167253f4e170 7493 * r Resulting affine co-ordinate point.
wolfSSL 14:167253f4e170 7494 * p Montgomery form projective co-ordinate point.
wolfSSL 14:167253f4e170 7495 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 7496 */
wolfSSL 14:167253f4e170 7497 static void sp_256_map_5(sp_point* r, sp_point* p, sp_digit* t)
wolfSSL 14:167253f4e170 7498 {
wolfSSL 14:167253f4e170 7499 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 7500 sp_digit* t2 = t + 2*5;
wolfSSL 14:167253f4e170 7501 int64_t n;
wolfSSL 14:167253f4e170 7502
wolfSSL 14:167253f4e170 7503 sp_256_mont_inv_5(t1, p->z, t + 2*5);
wolfSSL 14:167253f4e170 7504
wolfSSL 14:167253f4e170 7505 sp_256_mont_sqr_5(t2, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7506 sp_256_mont_mul_5(t1, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7507
wolfSSL 14:167253f4e170 7508 /* x /= z^2 */
wolfSSL 14:167253f4e170 7509 sp_256_mont_mul_5(r->x, p->x, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7510 XMEMSET(r->x + 5, 0, sizeof(r->x) / 2);
wolfSSL 14:167253f4e170 7511 sp_256_mont_reduce_5(r->x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7512 /* Reduce x to less than modulus */
wolfSSL 14:167253f4e170 7513 n = sp_256_cmp_5(r->x, p256_mod);
wolfSSL 14:167253f4e170 7514 sp_256_cond_sub_5(r->x, r->x, p256_mod, 0 - (n >= 0));
wolfSSL 14:167253f4e170 7515 sp_256_norm_5(r->x);
wolfSSL 14:167253f4e170 7516
wolfSSL 14:167253f4e170 7517 /* y /= z^3 */
wolfSSL 14:167253f4e170 7518 sp_256_mont_mul_5(r->y, p->y, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7519 XMEMSET(r->y + 5, 0, sizeof(r->y) / 2);
wolfSSL 14:167253f4e170 7520 sp_256_mont_reduce_5(r->y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7521 /* Reduce y to less than modulus */
wolfSSL 14:167253f4e170 7522 n = sp_256_cmp_5(r->y, p256_mod);
wolfSSL 14:167253f4e170 7523 sp_256_cond_sub_5(r->y, r->y, p256_mod, 0 - (n >= 0));
wolfSSL 14:167253f4e170 7524 sp_256_norm_5(r->y);
wolfSSL 14:167253f4e170 7525
wolfSSL 14:167253f4e170 7526 XMEMSET(r->z, 0, sizeof(r->z));
wolfSSL 14:167253f4e170 7527 r->z[0] = 1;
wolfSSL 14:167253f4e170 7528
wolfSSL 14:167253f4e170 7529 }
wolfSSL 14:167253f4e170 7530
wolfSSL 14:167253f4e170 7531 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7532 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 7533 *
wolfSSL 14:167253f4e170 7534 * r A single precision integer.
wolfSSL 14:167253f4e170 7535 * a A single precision integer.
wolfSSL 14:167253f4e170 7536 * b A single precision integer.
wolfSSL 14:167253f4e170 7537 */
wolfSSL 14:167253f4e170 7538 SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7539 const sp_digit* b)
wolfSSL 14:167253f4e170 7540 {
wolfSSL 14:167253f4e170 7541 int i;
wolfSSL 14:167253f4e170 7542
wolfSSL 14:167253f4e170 7543 for (i = 0; i < 5; i++)
wolfSSL 14:167253f4e170 7544 r[i] = a[i] + b[i];
wolfSSL 14:167253f4e170 7545
wolfSSL 14:167253f4e170 7546 return 0;
wolfSSL 14:167253f4e170 7547 }
wolfSSL 14:167253f4e170 7548 #else
wolfSSL 14:167253f4e170 7549 /* Add b to a into r. (r = a + b)
wolfSSL 14:167253f4e170 7550 *
wolfSSL 14:167253f4e170 7551 * r A single precision integer.
wolfSSL 14:167253f4e170 7552 * a A single precision integer.
wolfSSL 14:167253f4e170 7553 * b A single precision integer.
wolfSSL 14:167253f4e170 7554 */
wolfSSL 14:167253f4e170 7555 SP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7556 const sp_digit* b)
wolfSSL 14:167253f4e170 7557 {
wolfSSL 14:167253f4e170 7558 r[ 0] = a[ 0] + b[ 0];
wolfSSL 14:167253f4e170 7559 r[ 1] = a[ 1] + b[ 1];
wolfSSL 14:167253f4e170 7560 r[ 2] = a[ 2] + b[ 2];
wolfSSL 14:167253f4e170 7561 r[ 3] = a[ 3] + b[ 3];
wolfSSL 14:167253f4e170 7562 r[ 4] = a[ 4] + b[ 4];
wolfSSL 14:167253f4e170 7563
wolfSSL 14:167253f4e170 7564 return 0;
wolfSSL 14:167253f4e170 7565 }
wolfSSL 14:167253f4e170 7566
wolfSSL 14:167253f4e170 7567 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7568 /* Add two Montgomery form numbers (r = a + b % m).
wolfSSL 14:167253f4e170 7569 *
wolfSSL 14:167253f4e170 7570 * r Result of addition.
wolfSSL 14:167253f4e170 7571 * a First number to add in Montogmery form.
wolfSSL 14:167253f4e170 7572 * b Second number to add in Montogmery form.
wolfSSL 14:167253f4e170 7573 * m Modulus (prime).
wolfSSL 14:167253f4e170 7574 */
wolfSSL 14:167253f4e170 7575 static void sp_256_mont_add_5(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 7576 sp_digit* m)
wolfSSL 14:167253f4e170 7577 {
wolfSSL 14:167253f4e170 7578 sp_256_add_5(r, a, b);
wolfSSL 14:167253f4e170 7579 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7580 sp_256_cond_sub_5(r, r, m, 0 - ((r[4] >> 48) > 0));
wolfSSL 14:167253f4e170 7581 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7582 }
wolfSSL 14:167253f4e170 7583
wolfSSL 14:167253f4e170 7584 /* Double a Montgomery form number (r = a + a % m).
wolfSSL 14:167253f4e170 7585 *
wolfSSL 14:167253f4e170 7586 * r Result of doubling.
wolfSSL 14:167253f4e170 7587 * a Number to double in Montogmery form.
wolfSSL 14:167253f4e170 7588 * m Modulus (prime).
wolfSSL 14:167253f4e170 7589 */
wolfSSL 14:167253f4e170 7590 static void sp_256_mont_dbl_5(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 7591 {
wolfSSL 14:167253f4e170 7592 sp_256_add_5(r, a, a);
wolfSSL 14:167253f4e170 7593 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7594 sp_256_cond_sub_5(r, r, m, 0 - ((r[4] >> 48) > 0));
wolfSSL 14:167253f4e170 7595 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7596 }
wolfSSL 14:167253f4e170 7597
wolfSSL 14:167253f4e170 7598 /* Triple a Montgomery form number (r = a + a + a % m).
wolfSSL 14:167253f4e170 7599 *
wolfSSL 14:167253f4e170 7600 * r Result of Tripling.
wolfSSL 14:167253f4e170 7601 * a Number to triple in Montogmery form.
wolfSSL 14:167253f4e170 7602 * m Modulus (prime).
wolfSSL 14:167253f4e170 7603 */
wolfSSL 14:167253f4e170 7604 static void sp_256_mont_tpl_5(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 7605 {
wolfSSL 14:167253f4e170 7606 sp_256_add_5(r, a, a);
wolfSSL 14:167253f4e170 7607 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7608 sp_256_cond_sub_5(r, r, m, 0 - ((r[4] >> 48) > 0));
wolfSSL 14:167253f4e170 7609 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7610 sp_256_add_5(r, r, a);
wolfSSL 14:167253f4e170 7611 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7612 sp_256_cond_sub_5(r, r, m, 0 - ((r[4] >> 48) > 0));
wolfSSL 14:167253f4e170 7613 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7614 }
wolfSSL 14:167253f4e170 7615
wolfSSL 14:167253f4e170 7616 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7617 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 7618 *
wolfSSL 14:167253f4e170 7619 * r A single precision integer.
wolfSSL 14:167253f4e170 7620 * a A single precision integer.
wolfSSL 14:167253f4e170 7621 * b A single precision integer.
wolfSSL 14:167253f4e170 7622 */
wolfSSL 14:167253f4e170 7623 SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7624 const sp_digit* b)
wolfSSL 14:167253f4e170 7625 {
wolfSSL 14:167253f4e170 7626 int i;
wolfSSL 14:167253f4e170 7627
wolfSSL 14:167253f4e170 7628 for (i = 0; i < 5; i++)
wolfSSL 14:167253f4e170 7629 r[i] = a[i] - b[i];
wolfSSL 14:167253f4e170 7630
wolfSSL 14:167253f4e170 7631 return 0;
wolfSSL 14:167253f4e170 7632 }
wolfSSL 14:167253f4e170 7633
wolfSSL 14:167253f4e170 7634 #else
wolfSSL 14:167253f4e170 7635 /* Sub b from a into r. (r = a - b)
wolfSSL 14:167253f4e170 7636 *
wolfSSL 14:167253f4e170 7637 * r A single precision integer.
wolfSSL 14:167253f4e170 7638 * a A single precision integer.
wolfSSL 14:167253f4e170 7639 * b A single precision integer.
wolfSSL 14:167253f4e170 7640 */
wolfSSL 14:167253f4e170 7641 SP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7642 const sp_digit* b)
wolfSSL 14:167253f4e170 7643 {
wolfSSL 14:167253f4e170 7644 r[ 0] = a[ 0] - b[ 0];
wolfSSL 14:167253f4e170 7645 r[ 1] = a[ 1] - b[ 1];
wolfSSL 14:167253f4e170 7646 r[ 2] = a[ 2] - b[ 2];
wolfSSL 14:167253f4e170 7647 r[ 3] = a[ 3] - b[ 3];
wolfSSL 14:167253f4e170 7648 r[ 4] = a[ 4] - b[ 4];
wolfSSL 14:167253f4e170 7649
wolfSSL 14:167253f4e170 7650 return 0;
wolfSSL 14:167253f4e170 7651 }
wolfSSL 14:167253f4e170 7652
wolfSSL 14:167253f4e170 7653 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7654 /* Conditionally add a and b using the mask m.
wolfSSL 14:167253f4e170 7655 * m is -1 to add and 0 when not.
wolfSSL 14:167253f4e170 7656 *
wolfSSL 14:167253f4e170 7657 * r A single precision number representing conditional add result.
wolfSSL 14:167253f4e170 7658 * a A single precision number to add with.
wolfSSL 14:167253f4e170 7659 * b A single precision number to add.
wolfSSL 14:167253f4e170 7660 * m Mask value to apply.
wolfSSL 14:167253f4e170 7661 */
wolfSSL 14:167253f4e170 7662 static void sp_256_cond_add_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 7663 const sp_digit* b, const sp_digit m)
wolfSSL 14:167253f4e170 7664 {
wolfSSL 14:167253f4e170 7665 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7666 int i;
wolfSSL 14:167253f4e170 7667
wolfSSL 14:167253f4e170 7668 for (i = 0; i < 5; i++)
wolfSSL 14:167253f4e170 7669 r[i] = a[i] + (b[i] & m);
wolfSSL 14:167253f4e170 7670 #else
wolfSSL 14:167253f4e170 7671 r[ 0] = a[ 0] + (b[ 0] & m);
wolfSSL 14:167253f4e170 7672 r[ 1] = a[ 1] + (b[ 1] & m);
wolfSSL 14:167253f4e170 7673 r[ 2] = a[ 2] + (b[ 2] & m);
wolfSSL 14:167253f4e170 7674 r[ 3] = a[ 3] + (b[ 3] & m);
wolfSSL 14:167253f4e170 7675 r[ 4] = a[ 4] + (b[ 4] & m);
wolfSSL 14:167253f4e170 7676 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 7677 }
wolfSSL 14:167253f4e170 7678
wolfSSL 14:167253f4e170 7679 /* Subtract two Montgomery form numbers (r = a - b % m).
wolfSSL 14:167253f4e170 7680 *
wolfSSL 14:167253f4e170 7681 * r Result of subtration.
wolfSSL 14:167253f4e170 7682 * a Number to subtract from in Montogmery form.
wolfSSL 14:167253f4e170 7683 * b Number to subtract with in Montogmery form.
wolfSSL 14:167253f4e170 7684 * m Modulus (prime).
wolfSSL 14:167253f4e170 7685 */
wolfSSL 14:167253f4e170 7686 static void sp_256_mont_sub_5(sp_digit* r, sp_digit* a, sp_digit* b,
wolfSSL 14:167253f4e170 7687 sp_digit* m)
wolfSSL 14:167253f4e170 7688 {
wolfSSL 14:167253f4e170 7689 sp_256_sub_5(r, a, b);
wolfSSL 14:167253f4e170 7690 sp_256_cond_add_5(r, r, m, r[4] >> 48);
wolfSSL 14:167253f4e170 7691 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7692 }
wolfSSL 14:167253f4e170 7693
wolfSSL 14:167253f4e170 7694 /* Shift number left one bit.
wolfSSL 14:167253f4e170 7695 * Bottom bit is lost.
wolfSSL 14:167253f4e170 7696 *
wolfSSL 14:167253f4e170 7697 * r Result of shift.
wolfSSL 14:167253f4e170 7698 * a Number to shift.
wolfSSL 14:167253f4e170 7699 */
wolfSSL 14:167253f4e170 7700 SP_NOINLINE static void sp_256_rshift1_5(sp_digit* r, sp_digit* a)
wolfSSL 14:167253f4e170 7701 {
wolfSSL 14:167253f4e170 7702 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7703 int i;
wolfSSL 14:167253f4e170 7704
wolfSSL 14:167253f4e170 7705 for (i=0; i<4; i++)
wolfSSL 14:167253f4e170 7706 r[i] = ((a[i] >> 1) | (a[i + 1] << 51)) & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7707 #else
wolfSSL 14:167253f4e170 7708 r[0] = ((a[0] >> 1) | (a[1] << 51)) & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7709 r[1] = ((a[1] >> 1) | (a[2] << 51)) & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7710 r[2] = ((a[2] >> 1) | (a[3] << 51)) & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7711 r[3] = ((a[3] >> 1) | (a[4] << 51)) & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 7712 #endif
wolfSSL 14:167253f4e170 7713 r[4] = a[4] >> 1;
wolfSSL 14:167253f4e170 7714 }
wolfSSL 14:167253f4e170 7715
wolfSSL 14:167253f4e170 7716 /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
wolfSSL 14:167253f4e170 7717 *
wolfSSL 14:167253f4e170 7718 * r Result of division by 2.
wolfSSL 14:167253f4e170 7719 * a Number to divide.
wolfSSL 14:167253f4e170 7720 * m Modulus (prime).
wolfSSL 14:167253f4e170 7721 */
wolfSSL 14:167253f4e170 7722 static void sp_256_div2_5(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 7723 {
wolfSSL 14:167253f4e170 7724 sp_256_cond_add_5(r, a, m, 0 - (a[0] & 1));
wolfSSL 14:167253f4e170 7725 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 7726 sp_256_rshift1_5(r, r);
wolfSSL 14:167253f4e170 7727 }
wolfSSL 14:167253f4e170 7728
wolfSSL 14:167253f4e170 7729 /* Double the Montgomery form projective point p.
wolfSSL 14:167253f4e170 7730 *
wolfSSL 14:167253f4e170 7731 * r Result of doubling point.
wolfSSL 14:167253f4e170 7732 * p Point to double.
wolfSSL 14:167253f4e170 7733 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 7734 */
wolfSSL 14:167253f4e170 7735 static void sp_256_proj_point_dbl_5(sp_point* r, sp_point* p, sp_digit* t)
wolfSSL 14:167253f4e170 7736 {
wolfSSL 14:167253f4e170 7737 sp_point *rp[2];
wolfSSL 14:167253f4e170 7738 sp_point tp;
wolfSSL 14:167253f4e170 7739 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 7740 sp_digit* t2 = t + 2*5;
wolfSSL 14:167253f4e170 7741 sp_digit* x;
wolfSSL 14:167253f4e170 7742 sp_digit* y;
wolfSSL 14:167253f4e170 7743 sp_digit* z;
wolfSSL 14:167253f4e170 7744 int i;
wolfSSL 14:167253f4e170 7745
wolfSSL 14:167253f4e170 7746 /* When infinity don't double point passed in - constant time. */
wolfSSL 14:167253f4e170 7747 rp[0] = r;
wolfSSL 14:167253f4e170 7748 rp[1] = &tp;
wolfSSL 14:167253f4e170 7749 x = rp[p->infinity]->x;
wolfSSL 14:167253f4e170 7750 y = rp[p->infinity]->y;
wolfSSL 14:167253f4e170 7751 z = rp[p->infinity]->z;
wolfSSL 14:167253f4e170 7752 /* Put point to double into result - good for infinty. */
wolfSSL 14:167253f4e170 7753 if (r != p) {
wolfSSL 14:167253f4e170 7754 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 7755 r->x[i] = p->x[i];
wolfSSL 14:167253f4e170 7756 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 7757 r->y[i] = p->y[i];
wolfSSL 14:167253f4e170 7758 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 7759 r->z[i] = p->z[i];
wolfSSL 14:167253f4e170 7760 r->infinity = p->infinity;
wolfSSL 14:167253f4e170 7761 }
wolfSSL 14:167253f4e170 7762
wolfSSL 14:167253f4e170 7763 /* T1 = Z * Z */
wolfSSL 14:167253f4e170 7764 sp_256_mont_sqr_5(t1, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7765 /* Z = Y * Z */
wolfSSL 14:167253f4e170 7766 sp_256_mont_mul_5(z, y, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7767 /* Z = 2Z */
wolfSSL 14:167253f4e170 7768 sp_256_mont_dbl_5(z, z, p256_mod);
wolfSSL 14:167253f4e170 7769 /* T2 = X - T1 */
wolfSSL 14:167253f4e170 7770 sp_256_mont_sub_5(t2, x, t1, p256_mod);
wolfSSL 14:167253f4e170 7771 /* T1 = X + T1 */
wolfSSL 14:167253f4e170 7772 sp_256_mont_add_5(t1, x, t1, p256_mod);
wolfSSL 14:167253f4e170 7773 /* T2 = T1 * T2 */
wolfSSL 14:167253f4e170 7774 sp_256_mont_mul_5(t2, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7775 /* T1 = 3T2 */
wolfSSL 14:167253f4e170 7776 sp_256_mont_tpl_5(t1, t2, p256_mod);
wolfSSL 14:167253f4e170 7777 /* Y = 2Y */
wolfSSL 14:167253f4e170 7778 sp_256_mont_dbl_5(y, y, p256_mod);
wolfSSL 14:167253f4e170 7779 /* Y = Y * Y */
wolfSSL 14:167253f4e170 7780 sp_256_mont_sqr_5(y, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7781 /* T2 = Y * Y */
wolfSSL 14:167253f4e170 7782 sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7783 /* T2 = T2/2 */
wolfSSL 14:167253f4e170 7784 sp_256_div2_5(t2, t2, p256_mod);
wolfSSL 14:167253f4e170 7785 /* Y = Y * X */
wolfSSL 14:167253f4e170 7786 sp_256_mont_mul_5(y, y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7787 /* X = T1 * T1 */
wolfSSL 14:167253f4e170 7788 sp_256_mont_mul_5(x, t1, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7789 /* X = X - Y */
wolfSSL 14:167253f4e170 7790 sp_256_mont_sub_5(x, x, y, p256_mod);
wolfSSL 14:167253f4e170 7791 /* X = X - Y */
wolfSSL 14:167253f4e170 7792 sp_256_mont_sub_5(x, x, y, p256_mod);
wolfSSL 14:167253f4e170 7793 /* Y = Y - X */
wolfSSL 14:167253f4e170 7794 sp_256_mont_sub_5(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 7795 /* Y = Y * T1 */
wolfSSL 14:167253f4e170 7796 sp_256_mont_mul_5(y, y, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7797 /* Y = Y - T2 */
wolfSSL 14:167253f4e170 7798 sp_256_mont_sub_5(y, y, t2, p256_mod);
wolfSSL 14:167253f4e170 7799
wolfSSL 14:167253f4e170 7800 }
wolfSSL 14:167253f4e170 7801
wolfSSL 14:167253f4e170 7802 /* Compare two numbers to determine if they are equal.
wolfSSL 14:167253f4e170 7803 * Constant time implementation.
wolfSSL 14:167253f4e170 7804 *
wolfSSL 14:167253f4e170 7805 * a First number to compare.
wolfSSL 14:167253f4e170 7806 * b Second number to compare.
wolfSSL 14:167253f4e170 7807 * returns 1 when equal and 0 otherwise.
wolfSSL 14:167253f4e170 7808 */
wolfSSL 14:167253f4e170 7809 static int sp_256_cmp_equal_5(const sp_digit* a, const sp_digit* b)
wolfSSL 14:167253f4e170 7810 {
wolfSSL 14:167253f4e170 7811 return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |
wolfSSL 14:167253f4e170 7812 (a[4] ^ b[4])) == 0;
wolfSSL 14:167253f4e170 7813 }
wolfSSL 14:167253f4e170 7814
wolfSSL 14:167253f4e170 7815 /* Add two Montgomery form projective points.
wolfSSL 14:167253f4e170 7816 *
wolfSSL 14:167253f4e170 7817 * r Result of addition.
wolfSSL 14:167253f4e170 7818 * p Frist point to add.
wolfSSL 14:167253f4e170 7819 * q Second point to add.
wolfSSL 14:167253f4e170 7820 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 7821 */
wolfSSL 14:167253f4e170 7822 static void sp_256_proj_point_add_5(sp_point* r, sp_point* p, sp_point* q,
wolfSSL 14:167253f4e170 7823 sp_digit* t)
wolfSSL 14:167253f4e170 7824 {
wolfSSL 14:167253f4e170 7825 sp_point *ap[2];
wolfSSL 14:167253f4e170 7826 sp_point *rp[2];
wolfSSL 14:167253f4e170 7827 sp_point tp;
wolfSSL 14:167253f4e170 7828 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 7829 sp_digit* t2 = t + 2*5;
wolfSSL 14:167253f4e170 7830 sp_digit* t3 = t + 4*5;
wolfSSL 14:167253f4e170 7831 sp_digit* t4 = t + 6*5;
wolfSSL 14:167253f4e170 7832 sp_digit* t5 = t + 8*5;
wolfSSL 14:167253f4e170 7833 sp_digit* x;
wolfSSL 14:167253f4e170 7834 sp_digit* y;
wolfSSL 14:167253f4e170 7835 sp_digit* z;
wolfSSL 14:167253f4e170 7836 int i;
wolfSSL 14:167253f4e170 7837
wolfSSL 14:167253f4e170 7838 /* Ensure only the first point is the same as the result. */
wolfSSL 14:167253f4e170 7839 if (q == r) {
wolfSSL 14:167253f4e170 7840 sp_point* a = p;
wolfSSL 14:167253f4e170 7841 p = q;
wolfSSL 14:167253f4e170 7842 q = a;
wolfSSL 14:167253f4e170 7843 }
wolfSSL 14:167253f4e170 7844
wolfSSL 14:167253f4e170 7845 /* Check double */
wolfSSL 14:167253f4e170 7846 sp_256_sub_5(t1, p256_mod, q->y);
wolfSSL 14:167253f4e170 7847 sp_256_norm_5(t1);
wolfSSL 14:167253f4e170 7848 if (sp_256_cmp_equal_5(p->x, q->x) & sp_256_cmp_equal_5(p->z, q->z) &
wolfSSL 14:167253f4e170 7849 (sp_256_cmp_equal_5(p->y, q->y) | sp_256_cmp_equal_5(p->y, t1))) {
wolfSSL 14:167253f4e170 7850 sp_256_proj_point_dbl_5(r, p, t);
wolfSSL 14:167253f4e170 7851 }
wolfSSL 14:167253f4e170 7852 else {
wolfSSL 14:167253f4e170 7853 rp[0] = r;
wolfSSL 14:167253f4e170 7854 rp[1] = &tp;
wolfSSL 14:167253f4e170 7855 XMEMSET(&tp, 0, sizeof(tp));
wolfSSL 14:167253f4e170 7856 x = rp[p->infinity | q->infinity]->x;
wolfSSL 14:167253f4e170 7857 y = rp[p->infinity | q->infinity]->y;
wolfSSL 14:167253f4e170 7858 z = rp[p->infinity | q->infinity]->z;
wolfSSL 14:167253f4e170 7859
wolfSSL 14:167253f4e170 7860 ap[0] = p;
wolfSSL 14:167253f4e170 7861 ap[1] = q;
wolfSSL 14:167253f4e170 7862 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 7863 r->x[i] = ap[p->infinity]->x[i];
wolfSSL 14:167253f4e170 7864 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 7865 r->y[i] = ap[p->infinity]->y[i];
wolfSSL 14:167253f4e170 7866 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 7867 r->z[i] = ap[p->infinity]->z[i];
wolfSSL 14:167253f4e170 7868 r->infinity = ap[p->infinity]->infinity;
wolfSSL 14:167253f4e170 7869
wolfSSL 14:167253f4e170 7870 /* U1 = X1*Z2^2 */
wolfSSL 14:167253f4e170 7871 sp_256_mont_sqr_5(t1, q->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7872 sp_256_mont_mul_5(t3, t1, q->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7873 sp_256_mont_mul_5(t1, t1, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7874 /* U2 = X2*Z1^2 */
wolfSSL 14:167253f4e170 7875 sp_256_mont_sqr_5(t2, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7876 sp_256_mont_mul_5(t4, t2, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7877 sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7878 /* S1 = Y1*Z2^3 */
wolfSSL 14:167253f4e170 7879 sp_256_mont_mul_5(t3, t3, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7880 /* S2 = Y2*Z1^3 */
wolfSSL 14:167253f4e170 7881 sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7882 /* H = U2 - U1 */
wolfSSL 14:167253f4e170 7883 sp_256_mont_sub_5(t2, t2, t1, p256_mod);
wolfSSL 14:167253f4e170 7884 /* R = S2 - S1 */
wolfSSL 14:167253f4e170 7885 sp_256_mont_sub_5(t4, t4, t3, p256_mod);
wolfSSL 14:167253f4e170 7886 /* Z3 = H*Z1*Z2 */
wolfSSL 14:167253f4e170 7887 sp_256_mont_mul_5(z, z, q->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7888 sp_256_mont_mul_5(z, z, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7889 /* X3 = R^2 - H^3 - 2*U1*H^2 */
wolfSSL 14:167253f4e170 7890 sp_256_mont_sqr_5(x, t4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7891 sp_256_mont_sqr_5(t5, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7892 sp_256_mont_mul_5(y, t1, t5, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7893 sp_256_mont_mul_5(t5, t5, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7894 sp_256_mont_sub_5(x, x, t5, p256_mod);
wolfSSL 14:167253f4e170 7895 sp_256_mont_dbl_5(t1, y, p256_mod);
wolfSSL 14:167253f4e170 7896 sp_256_mont_sub_5(x, x, t1, p256_mod);
wolfSSL 14:167253f4e170 7897 /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
wolfSSL 14:167253f4e170 7898 sp_256_mont_sub_5(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 7899 sp_256_mont_mul_5(y, y, t4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7900 sp_256_mont_mul_5(t5, t5, t3, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 7901 sp_256_mont_sub_5(y, y, t5, p256_mod);
wolfSSL 14:167253f4e170 7902 }
wolfSSL 14:167253f4e170 7903 }
wolfSSL 14:167253f4e170 7904
wolfSSL 14:167253f4e170 7905 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 7906 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 7907 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 7908 *
wolfSSL 14:167253f4e170 7909 * r Resulting point.
wolfSSL 14:167253f4e170 7910 * g Point to multiply.
wolfSSL 14:167253f4e170 7911 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 7912 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 7913 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 7914 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 7915 */
wolfSSL 14:167253f4e170 7916 static int sp_256_ecc_mulmod_5(sp_point* r, sp_point* g, sp_digit* k,
wolfSSL 14:167253f4e170 7917 int map, void* heap)
wolfSSL 14:167253f4e170 7918 {
wolfSSL 14:167253f4e170 7919 sp_point* td;
wolfSSL 14:167253f4e170 7920 sp_point* t[3];
wolfSSL 14:167253f4e170 7921 sp_digit* tmp;
wolfSSL 14:167253f4e170 7922 sp_digit n;
wolfSSL 14:167253f4e170 7923 int i;
wolfSSL 14:167253f4e170 7924 int c, y;
wolfSSL 14:167253f4e170 7925 int err = MP_OKAY;
wolfSSL 14:167253f4e170 7926
wolfSSL 14:167253f4e170 7927 (void)heap;
wolfSSL 14:167253f4e170 7928
wolfSSL 14:167253f4e170 7929 td = (sp_point*)XMALLOC(sizeof(sp_point) * 3, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 7930 if (td == NULL)
wolfSSL 14:167253f4e170 7931 err = MEMORY_E;
wolfSSL 14:167253f4e170 7932 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,
wolfSSL 14:167253f4e170 7933 DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 7934 if (tmp == NULL)
wolfSSL 14:167253f4e170 7935 err = MEMORY_E;
wolfSSL 14:167253f4e170 7936
wolfSSL 14:167253f4e170 7937 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7938 XMEMSET(td, 0, sizeof(*td) * 3);
wolfSSL 14:167253f4e170 7939
wolfSSL 14:167253f4e170 7940 t[0] = &td[0];
wolfSSL 14:167253f4e170 7941 t[1] = &td[1];
wolfSSL 14:167253f4e170 7942 t[2] = &td[2];
wolfSSL 14:167253f4e170 7943
wolfSSL 14:167253f4e170 7944 /* t[0] = {0, 0, 1} * norm */
wolfSSL 14:167253f4e170 7945 t[0]->infinity = 1;
wolfSSL 14:167253f4e170 7946 /* t[1] = {g->x, g->y, g->z} * norm */
wolfSSL 14:167253f4e170 7947 err = sp_256_mod_mul_norm_5(t[1]->x, g->x, p256_mod);
wolfSSL 14:167253f4e170 7948 }
wolfSSL 14:167253f4e170 7949 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 7950 err = sp_256_mod_mul_norm_5(t[1]->y, g->y, p256_mod);
wolfSSL 14:167253f4e170 7951 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 7952 err = sp_256_mod_mul_norm_5(t[1]->z, g->z, p256_mod);
wolfSSL 14:167253f4e170 7953
wolfSSL 14:167253f4e170 7954 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 7955 i = 4;
wolfSSL 14:167253f4e170 7956 c = 48;
wolfSSL 14:167253f4e170 7957 n = k[i--] << (52 - c);
wolfSSL 14:167253f4e170 7958 for (; ; c--) {
wolfSSL 14:167253f4e170 7959 if (c == 0) {
wolfSSL 14:167253f4e170 7960 if (i == -1)
wolfSSL 14:167253f4e170 7961 break;
wolfSSL 14:167253f4e170 7962
wolfSSL 14:167253f4e170 7963 n = k[i--];
wolfSSL 14:167253f4e170 7964 c = 52;
wolfSSL 14:167253f4e170 7965 }
wolfSSL 14:167253f4e170 7966
wolfSSL 14:167253f4e170 7967 y = (n >> 51) & 1;
wolfSSL 14:167253f4e170 7968 n <<= 1;
wolfSSL 14:167253f4e170 7969
wolfSSL 14:167253f4e170 7970 sp_256_proj_point_add_5(t[y^1], t[0], t[1], tmp);
wolfSSL 14:167253f4e170 7971
wolfSSL 14:167253f4e170 7972 XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 7973 ((size_t)t[1] & addr_mask[y])),
wolfSSL 14:167253f4e170 7974 sizeof(sp_point));
wolfSSL 14:167253f4e170 7975 sp_256_proj_point_dbl_5(t[2], t[2], tmp);
wolfSSL 14:167253f4e170 7976 XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 7977 ((size_t)t[1] & addr_mask[y])), t[2],
wolfSSL 14:167253f4e170 7978 sizeof(sp_point));
wolfSSL 14:167253f4e170 7979 }
wolfSSL 14:167253f4e170 7980
wolfSSL 14:167253f4e170 7981 if (map)
wolfSSL 14:167253f4e170 7982 sp_256_map_5(r, t[0], tmp);
wolfSSL 14:167253f4e170 7983 else
wolfSSL 14:167253f4e170 7984 XMEMCPY(r, t[0], sizeof(sp_point));
wolfSSL 14:167253f4e170 7985 }
wolfSSL 14:167253f4e170 7986
wolfSSL 14:167253f4e170 7987 if (tmp != NULL) {
wolfSSL 14:167253f4e170 7988 XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 5 * 5);
wolfSSL 14:167253f4e170 7989 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 7990 }
wolfSSL 14:167253f4e170 7991 if (td != NULL) {
wolfSSL 14:167253f4e170 7992 XMEMSET(td, 0, sizeof(sp_point) * 3);
wolfSSL 14:167253f4e170 7993 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 7994 }
wolfSSL 14:167253f4e170 7995
wolfSSL 14:167253f4e170 7996 return err;
wolfSSL 14:167253f4e170 7997 }
wolfSSL 14:167253f4e170 7998
wolfSSL 14:167253f4e170 7999 #elif defined(WOLFSSL_SP_CACHE_RESISTANT)
wolfSSL 14:167253f4e170 8000 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 8001 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 8002 *
wolfSSL 14:167253f4e170 8003 * r Resulting point.
wolfSSL 14:167253f4e170 8004 * g Point to multiply.
wolfSSL 14:167253f4e170 8005 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 8006 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 8007 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8008 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 8009 */
wolfSSL 14:167253f4e170 8010 static int sp_256_ecc_mulmod_5(sp_point* r, sp_point* g, sp_digit* k,
wolfSSL 14:167253f4e170 8011 int map, void* heap)
wolfSSL 14:167253f4e170 8012 {
wolfSSL 14:167253f4e170 8013 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8014 sp_point td[3];
wolfSSL 14:167253f4e170 8015 sp_digit tmpd[2 * 5 * 5];
wolfSSL 14:167253f4e170 8016 #endif
wolfSSL 14:167253f4e170 8017 sp_point* t;
wolfSSL 14:167253f4e170 8018 sp_digit* tmp;
wolfSSL 14:167253f4e170 8019 sp_digit n;
wolfSSL 14:167253f4e170 8020 int i;
wolfSSL 14:167253f4e170 8021 int c, y;
wolfSSL 14:167253f4e170 8022 int err = MP_OKAY;
wolfSSL 14:167253f4e170 8023
wolfSSL 14:167253f4e170 8024 (void)heap;
wolfSSL 14:167253f4e170 8025
wolfSSL 14:167253f4e170 8026 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8027 sp_point td[3];
wolfSSL 14:167253f4e170 8028 t = (sp_point*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8029 if (t == NULL)
wolfSSL 14:167253f4e170 8030 err = MEMORY_E;
wolfSSL 14:167253f4e170 8031 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,
wolfSSL 14:167253f4e170 8032 DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8033 if (tmp == NULL)
wolfSSL 14:167253f4e170 8034 err = MEMORY_E;
wolfSSL 14:167253f4e170 8035 #else
wolfSSL 14:167253f4e170 8036 t = td;
wolfSSL 14:167253f4e170 8037 tmp = tmpd;
wolfSSL 14:167253f4e170 8038 #endif
wolfSSL 14:167253f4e170 8039
wolfSSL 14:167253f4e170 8040 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8041 t[0] = &td[0];
wolfSSL 14:167253f4e170 8042 t[1] = &td[1];
wolfSSL 14:167253f4e170 8043 t[2] = &td[2];
wolfSSL 14:167253f4e170 8044
wolfSSL 14:167253f4e170 8045 /* t[0] = {0, 0, 1} * norm */
wolfSSL 14:167253f4e170 8046 XMEMSET(&t[0], 0, sizeof(t[0]));
wolfSSL 14:167253f4e170 8047 t[0].infinity = 1;
wolfSSL 14:167253f4e170 8048 /* t[1] = {g->x, g->y, g->z} * norm */
wolfSSL 14:167253f4e170 8049 err = sp_256_mod_mul_norm_5(t[1].x, g->x, p256_mod);
wolfSSL 14:167253f4e170 8050 }
wolfSSL 14:167253f4e170 8051 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8052 err = sp_256_mod_mul_norm_5(t[1].y, g->y, p256_mod);
wolfSSL 14:167253f4e170 8053 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8054 err = sp_256_mod_mul_norm_5(t[1].z, g->z, p256_mod);
wolfSSL 14:167253f4e170 8055
wolfSSL 14:167253f4e170 8056 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8057 i = 4;
wolfSSL 14:167253f4e170 8058 c = 48;
wolfSSL 14:167253f4e170 8059 n = k[i--] << (52 - c);
wolfSSL 14:167253f4e170 8060 for (; ; c--) {
wolfSSL 14:167253f4e170 8061 if (c == 0) {
wolfSSL 14:167253f4e170 8062 if (i == -1)
wolfSSL 14:167253f4e170 8063 break;
wolfSSL 14:167253f4e170 8064
wolfSSL 14:167253f4e170 8065 n = k[i--];
wolfSSL 14:167253f4e170 8066 c = 52;
wolfSSL 14:167253f4e170 8067 }
wolfSSL 14:167253f4e170 8068
wolfSSL 14:167253f4e170 8069 y = (n >> 51) & 1;
wolfSSL 14:167253f4e170 8070 n <<= 1;
wolfSSL 14:167253f4e170 8071
wolfSSL 14:167253f4e170 8072 sp_256_proj_point_add_5(&t[y^1], &t[0], &t[1], tmp);
wolfSSL 14:167253f4e170 8073
wolfSSL 14:167253f4e170 8074 XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 8075 ((size_t)&t[1] & addr_mask[y])), sizeof(t[2]));
wolfSSL 14:167253f4e170 8076 sp_256_proj_point_dbl_5(&t[2], &t[2], tmp);
wolfSSL 14:167253f4e170 8077 XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +
wolfSSL 14:167253f4e170 8078 ((size_t)&t[1] & addr_mask[y])), &t[2], sizeof(t[2]));
wolfSSL 14:167253f4e170 8079 }
wolfSSL 14:167253f4e170 8080
wolfSSL 14:167253f4e170 8081 if (map)
wolfSSL 14:167253f4e170 8082 sp_256_map_5(r, &t[0], tmp);
wolfSSL 14:167253f4e170 8083 else
wolfSSL 14:167253f4e170 8084 XMEMCPY(r, &t[0], sizeof(sp_point));
wolfSSL 14:167253f4e170 8085 }
wolfSSL 14:167253f4e170 8086
wolfSSL 14:167253f4e170 8087 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8088 if (tmp != NULL) {
wolfSSL 14:167253f4e170 8089 XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 5 * 5);
wolfSSL 14:167253f4e170 8090 XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8091 }
wolfSSL 14:167253f4e170 8092 if (t != NULL) {
wolfSSL 14:167253f4e170 8093 XMEMSET(t, 0, sizeof(sp_point) * 3);
wolfSSL 14:167253f4e170 8094 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8095 }
wolfSSL 14:167253f4e170 8096 #else
wolfSSL 14:167253f4e170 8097 ForceZero(tmpd, sizeof(tmpd));
wolfSSL 14:167253f4e170 8098 ForceZero(td, sizeof(td));
wolfSSL 14:167253f4e170 8099 #endif
wolfSSL 14:167253f4e170 8100
wolfSSL 14:167253f4e170 8101 return err;
wolfSSL 14:167253f4e170 8102 }
wolfSSL 14:167253f4e170 8103
wolfSSL 14:167253f4e170 8104 #else
wolfSSL 14:167253f4e170 8105 /* A table entry for pre-computed points. */
wolfSSL 14:167253f4e170 8106 typedef struct sp_table_entry {
wolfSSL 14:167253f4e170 8107 sp_digit x[5];
wolfSSL 14:167253f4e170 8108 sp_digit y[5];
wolfSSL 14:167253f4e170 8109 byte infinity;
wolfSSL 14:167253f4e170 8110 } sp_table_entry;
wolfSSL 14:167253f4e170 8111
wolfSSL 14:167253f4e170 8112 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 8113 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 8114 *
wolfSSL 14:167253f4e170 8115 * r Resulting point.
wolfSSL 14:167253f4e170 8116 * g Point to multiply.
wolfSSL 14:167253f4e170 8117 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 8118 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 8119 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8120 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 8121 */
wolfSSL 14:167253f4e170 8122 static int sp_256_ecc_mulmod_fast_5(sp_point* r, sp_point* g, sp_digit* k,
wolfSSL 14:167253f4e170 8123 int map, void* heap)
wolfSSL 14:167253f4e170 8124 {
wolfSSL 14:167253f4e170 8125 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8126 sp_point td[16];
wolfSSL 14:167253f4e170 8127 sp_point rtd;
wolfSSL 14:167253f4e170 8128 sp_digit tmpd[2 * 5 * 5];
wolfSSL 14:167253f4e170 8129 #endif
wolfSSL 14:167253f4e170 8130 sp_point* t;
wolfSSL 14:167253f4e170 8131 sp_point* rt;
wolfSSL 14:167253f4e170 8132 sp_digit* tmp;
wolfSSL 14:167253f4e170 8133 sp_digit n;
wolfSSL 14:167253f4e170 8134 int i;
wolfSSL 14:167253f4e170 8135 int c, y;
wolfSSL 14:167253f4e170 8136 int err;
wolfSSL 14:167253f4e170 8137
wolfSSL 14:167253f4e170 8138 (void)heap;
wolfSSL 14:167253f4e170 8139
wolfSSL 14:167253f4e170 8140 err = sp_ecc_point_new(heap, rtd, rt);
wolfSSL 14:167253f4e170 8141 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8142 t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8143 if (t == NULL)
wolfSSL 14:167253f4e170 8144 err = MEMORY_E;
wolfSSL 14:167253f4e170 8145 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,
wolfSSL 14:167253f4e170 8146 DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8147 if (tmp == NULL)
wolfSSL 14:167253f4e170 8148 err = MEMORY_E;
wolfSSL 14:167253f4e170 8149 #else
wolfSSL 14:167253f4e170 8150 t = td;
wolfSSL 14:167253f4e170 8151 tmp = tmpd;
wolfSSL 14:167253f4e170 8152 #endif
wolfSSL 14:167253f4e170 8153
wolfSSL 14:167253f4e170 8154 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8155 /* t[0] = {0, 0, 1} * norm */
wolfSSL 14:167253f4e170 8156 XMEMSET(&t[0], 0, sizeof(t[0]));
wolfSSL 14:167253f4e170 8157 t[0].infinity = 1;
wolfSSL 14:167253f4e170 8158 /* t[1] = {g->x, g->y, g->z} * norm */
wolfSSL 14:167253f4e170 8159 sp_256_mod_mul_norm_5(t[1].x, g->x, p256_mod);
wolfSSL 14:167253f4e170 8160 sp_256_mod_mul_norm_5(t[1].y, g->y, p256_mod);
wolfSSL 14:167253f4e170 8161 sp_256_mod_mul_norm_5(t[1].z, g->z, p256_mod);
wolfSSL 14:167253f4e170 8162 t[1].infinity = 0;
wolfSSL 14:167253f4e170 8163 sp_256_proj_point_dbl_5(&t[ 2], &t[ 1], tmp);
wolfSSL 14:167253f4e170 8164 t[ 2].infinity = 0;
wolfSSL 14:167253f4e170 8165 sp_256_proj_point_add_5(&t[ 3], &t[ 2], &t[ 1], tmp);
wolfSSL 14:167253f4e170 8166 t[ 3].infinity = 0;
wolfSSL 14:167253f4e170 8167 sp_256_proj_point_dbl_5(&t[ 4], &t[ 2], tmp);
wolfSSL 14:167253f4e170 8168 t[ 4].infinity = 0;
wolfSSL 14:167253f4e170 8169 sp_256_proj_point_add_5(&t[ 5], &t[ 3], &t[ 2], tmp);
wolfSSL 14:167253f4e170 8170 t[ 5].infinity = 0;
wolfSSL 14:167253f4e170 8171 sp_256_proj_point_dbl_5(&t[ 6], &t[ 3], tmp);
wolfSSL 14:167253f4e170 8172 t[ 6].infinity = 0;
wolfSSL 14:167253f4e170 8173 sp_256_proj_point_add_5(&t[ 7], &t[ 4], &t[ 3], tmp);
wolfSSL 14:167253f4e170 8174 t[ 7].infinity = 0;
wolfSSL 14:167253f4e170 8175 sp_256_proj_point_dbl_5(&t[ 8], &t[ 4], tmp);
wolfSSL 14:167253f4e170 8176 t[ 8].infinity = 0;
wolfSSL 14:167253f4e170 8177 sp_256_proj_point_add_5(&t[ 9], &t[ 5], &t[ 4], tmp);
wolfSSL 14:167253f4e170 8178 t[ 9].infinity = 0;
wolfSSL 14:167253f4e170 8179 sp_256_proj_point_dbl_5(&t[10], &t[ 5], tmp);
wolfSSL 14:167253f4e170 8180 t[10].infinity = 0;
wolfSSL 14:167253f4e170 8181 sp_256_proj_point_add_5(&t[11], &t[ 6], &t[ 5], tmp);
wolfSSL 14:167253f4e170 8182 t[11].infinity = 0;
wolfSSL 14:167253f4e170 8183 sp_256_proj_point_dbl_5(&t[12], &t[ 6], tmp);
wolfSSL 14:167253f4e170 8184 t[12].infinity = 0;
wolfSSL 14:167253f4e170 8185 sp_256_proj_point_add_5(&t[13], &t[ 7], &t[ 6], tmp);
wolfSSL 14:167253f4e170 8186 t[13].infinity = 0;
wolfSSL 14:167253f4e170 8187 sp_256_proj_point_dbl_5(&t[14], &t[ 7], tmp);
wolfSSL 14:167253f4e170 8188 t[14].infinity = 0;
wolfSSL 14:167253f4e170 8189 sp_256_proj_point_add_5(&t[15], &t[ 8], &t[ 7], tmp);
wolfSSL 14:167253f4e170 8190 t[15].infinity = 0;
wolfSSL 14:167253f4e170 8191
wolfSSL 14:167253f4e170 8192 i = 3;
wolfSSL 14:167253f4e170 8193 n = k[i+1] << 12;
wolfSSL 14:167253f4e170 8194 c = 44;
wolfSSL 14:167253f4e170 8195 y = n >> 56;
wolfSSL 14:167253f4e170 8196 XMEMCPY(rt, &t[y], sizeof(sp_point));
wolfSSL 14:167253f4e170 8197 n <<= 8;
wolfSSL 14:167253f4e170 8198 for (; i>=0 || c>=4; ) {
wolfSSL 14:167253f4e170 8199 if (c < 4) {
wolfSSL 14:167253f4e170 8200 n |= k[i--] << (12 - c);
wolfSSL 14:167253f4e170 8201 c += 52;
wolfSSL 14:167253f4e170 8202 }
wolfSSL 14:167253f4e170 8203 y = (n >> 60) & 0xf;
wolfSSL 14:167253f4e170 8204 n <<= 4;
wolfSSL 14:167253f4e170 8205 c -= 4;
wolfSSL 14:167253f4e170 8206
wolfSSL 14:167253f4e170 8207 sp_256_proj_point_dbl_5(rt, rt, tmp);
wolfSSL 14:167253f4e170 8208 sp_256_proj_point_dbl_5(rt, rt, tmp);
wolfSSL 14:167253f4e170 8209 sp_256_proj_point_dbl_5(rt, rt, tmp);
wolfSSL 14:167253f4e170 8210 sp_256_proj_point_dbl_5(rt, rt, tmp);
wolfSSL 14:167253f4e170 8211
wolfSSL 14:167253f4e170 8212 sp_256_proj_point_add_5(rt, rt, &t[y], tmp);
wolfSSL 14:167253f4e170 8213 }
wolfSSL 14:167253f4e170 8214
wolfSSL 14:167253f4e170 8215 if (map)
wolfSSL 14:167253f4e170 8216 sp_256_map_5(r, rt, tmp);
wolfSSL 14:167253f4e170 8217 else
wolfSSL 14:167253f4e170 8218 XMEMCPY(r, rt, sizeof(sp_point));
wolfSSL 14:167253f4e170 8219 }
wolfSSL 14:167253f4e170 8220
wolfSSL 14:167253f4e170 8221 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8222 if (tmp != NULL) {
wolfSSL 14:167253f4e170 8223 XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 5 * 5);
wolfSSL 14:167253f4e170 8224 XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8225 }
wolfSSL 14:167253f4e170 8226 if (t != NULL) {
wolfSSL 14:167253f4e170 8227 XMEMSET(t, 0, sizeof(sp_point) * 16);
wolfSSL 14:167253f4e170 8228 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8229 }
wolfSSL 14:167253f4e170 8230 #else
wolfSSL 14:167253f4e170 8231 ForceZero(tmpd, sizeof(tmpd));
wolfSSL 14:167253f4e170 8232 ForceZero(td, sizeof(td));
wolfSSL 14:167253f4e170 8233 #endif
wolfSSL 14:167253f4e170 8234 sp_ecc_point_free(rt, 1, heap);
wolfSSL 14:167253f4e170 8235
wolfSSL 14:167253f4e170 8236 return err;
wolfSSL 14:167253f4e170 8237 }
wolfSSL 14:167253f4e170 8238
wolfSSL 14:167253f4e170 8239 #ifdef FP_ECC
wolfSSL 14:167253f4e170 8240 /* Double the Montgomery form projective point p a number of times.
wolfSSL 14:167253f4e170 8241 *
wolfSSL 14:167253f4e170 8242 * r Result of repeated doubling of point.
wolfSSL 14:167253f4e170 8243 * p Point to double.
wolfSSL 14:167253f4e170 8244 * n Number of times to double
wolfSSL 14:167253f4e170 8245 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 8246 */
wolfSSL 14:167253f4e170 8247 static void sp_256_proj_point_dbl_n_5(sp_point* r, sp_point* p, int n,
wolfSSL 14:167253f4e170 8248 sp_digit* t)
wolfSSL 14:167253f4e170 8249 {
wolfSSL 14:167253f4e170 8250 sp_point *rp[2];
wolfSSL 14:167253f4e170 8251 sp_point tp;
wolfSSL 14:167253f4e170 8252 sp_digit* w = t;
wolfSSL 14:167253f4e170 8253 sp_digit* a = t + 2*5;
wolfSSL 14:167253f4e170 8254 sp_digit* b = t + 4*5;
wolfSSL 14:167253f4e170 8255 sp_digit* t1 = t + 6*5;
wolfSSL 14:167253f4e170 8256 sp_digit* t2 = t + 8*5;
wolfSSL 14:167253f4e170 8257 sp_digit* x;
wolfSSL 14:167253f4e170 8258 sp_digit* y;
wolfSSL 14:167253f4e170 8259 sp_digit* z;
wolfSSL 14:167253f4e170 8260 int i;
wolfSSL 14:167253f4e170 8261
wolfSSL 14:167253f4e170 8262 rp[0] = r;
wolfSSL 14:167253f4e170 8263 rp[1] = &tp;
wolfSSL 14:167253f4e170 8264 x = rp[p->infinity]->x;
wolfSSL 14:167253f4e170 8265 y = rp[p->infinity]->y;
wolfSSL 14:167253f4e170 8266 z = rp[p->infinity]->z;
wolfSSL 14:167253f4e170 8267 if (r != p) {
wolfSSL 14:167253f4e170 8268 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 8269 r->x[i] = p->x[i];
wolfSSL 14:167253f4e170 8270 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 8271 r->y[i] = p->y[i];
wolfSSL 14:167253f4e170 8272 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 8273 r->z[i] = p->z[i];
wolfSSL 14:167253f4e170 8274 r->infinity = p->infinity;
wolfSSL 14:167253f4e170 8275 }
wolfSSL 14:167253f4e170 8276
wolfSSL 14:167253f4e170 8277 /* Y = 2*Y */
wolfSSL 14:167253f4e170 8278 sp_256_mont_dbl_5(y, y, p256_mod);
wolfSSL 14:167253f4e170 8279 /* W = Z^4 */
wolfSSL 14:167253f4e170 8280 sp_256_mont_sqr_5(w, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8281 sp_256_mont_sqr_5(w, w, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8282 while (n--) {
wolfSSL 14:167253f4e170 8283 /* A = 3*(X^2 - W) */
wolfSSL 14:167253f4e170 8284 sp_256_mont_sqr_5(t1, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8285 sp_256_mont_sub_5(t1, t1, w, p256_mod);
wolfSSL 14:167253f4e170 8286 sp_256_mont_tpl_5(a, t1, p256_mod);
wolfSSL 14:167253f4e170 8287 /* B = X*Y^2 */
wolfSSL 14:167253f4e170 8288 sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8289 sp_256_mont_mul_5(b, t2, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8290 /* X = A^2 - 2B */
wolfSSL 14:167253f4e170 8291 sp_256_mont_sqr_5(x, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8292 sp_256_mont_dbl_5(t1, b, p256_mod);
wolfSSL 14:167253f4e170 8293 sp_256_mont_sub_5(x, x, t1, p256_mod);
wolfSSL 14:167253f4e170 8294 /* Z = Z*Y */
wolfSSL 14:167253f4e170 8295 sp_256_mont_mul_5(z, z, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8296 /* t2 = Y^4 */
wolfSSL 14:167253f4e170 8297 sp_256_mont_sqr_5(t2, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8298 if (n) {
wolfSSL 14:167253f4e170 8299 /* W = W*Y^4 */
wolfSSL 14:167253f4e170 8300 sp_256_mont_mul_5(w, w, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8301 }
wolfSSL 14:167253f4e170 8302 /* y = 2*A*(B - X) - Y^4 */
wolfSSL 14:167253f4e170 8303 sp_256_mont_sub_5(y, b, x, p256_mod);
wolfSSL 14:167253f4e170 8304 sp_256_mont_mul_5(y, y, a, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8305 sp_256_mont_dbl_5(y, y, p256_mod);
wolfSSL 14:167253f4e170 8306 sp_256_mont_sub_5(y, y, t2, p256_mod);
wolfSSL 14:167253f4e170 8307 }
wolfSSL 14:167253f4e170 8308 /* Y = Y/2 */
wolfSSL 14:167253f4e170 8309 sp_256_div2_5(y, y, p256_mod);
wolfSSL 14:167253f4e170 8310 }
wolfSSL 14:167253f4e170 8311
wolfSSL 14:167253f4e170 8312 #endif /* FP_ECC */
wolfSSL 14:167253f4e170 8313 /* Add two Montgomery form projective points. The second point has a q value of
wolfSSL 14:167253f4e170 8314 * one.
wolfSSL 14:167253f4e170 8315 * Only the first point can be the same pointer as the result point.
wolfSSL 14:167253f4e170 8316 *
wolfSSL 14:167253f4e170 8317 * r Result of addition.
wolfSSL 14:167253f4e170 8318 * p Frist point to add.
wolfSSL 14:167253f4e170 8319 * q Second point to add.
wolfSSL 14:167253f4e170 8320 * t Temporary ordinate data.
wolfSSL 14:167253f4e170 8321 */
wolfSSL 14:167253f4e170 8322 static void sp_256_proj_point_add_qz1_5(sp_point* r, sp_point* p,
wolfSSL 14:167253f4e170 8323 sp_point* q, sp_digit* t)
wolfSSL 14:167253f4e170 8324 {
wolfSSL 14:167253f4e170 8325 sp_point *ap[2];
wolfSSL 14:167253f4e170 8326 sp_point *rp[2];
wolfSSL 14:167253f4e170 8327 sp_point tp;
wolfSSL 14:167253f4e170 8328 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 8329 sp_digit* t2 = t + 2*5;
wolfSSL 14:167253f4e170 8330 sp_digit* t3 = t + 4*5;
wolfSSL 14:167253f4e170 8331 sp_digit* t4 = t + 6*5;
wolfSSL 14:167253f4e170 8332 sp_digit* t5 = t + 8*5;
wolfSSL 14:167253f4e170 8333 sp_digit* x;
wolfSSL 14:167253f4e170 8334 sp_digit* y;
wolfSSL 14:167253f4e170 8335 sp_digit* z;
wolfSSL 14:167253f4e170 8336 int i;
wolfSSL 14:167253f4e170 8337
wolfSSL 14:167253f4e170 8338 /* Check double */
wolfSSL 14:167253f4e170 8339 sp_256_sub_5(t1, p256_mod, q->y);
wolfSSL 14:167253f4e170 8340 sp_256_norm_5(t1);
wolfSSL 14:167253f4e170 8341 if (sp_256_cmp_equal_5(p->x, q->x) & sp_256_cmp_equal_5(p->z, q->z) &
wolfSSL 14:167253f4e170 8342 (sp_256_cmp_equal_5(p->y, q->y) | sp_256_cmp_equal_5(p->y, t1))) {
wolfSSL 14:167253f4e170 8343 sp_256_proj_point_dbl_5(r, p, t);
wolfSSL 14:167253f4e170 8344 }
wolfSSL 14:167253f4e170 8345 else {
wolfSSL 14:167253f4e170 8346 rp[0] = r;
wolfSSL 14:167253f4e170 8347 rp[1] = &tp;
wolfSSL 14:167253f4e170 8348 XMEMSET(&tp, 0, sizeof(tp));
wolfSSL 14:167253f4e170 8349 x = rp[p->infinity | q->infinity]->x;
wolfSSL 14:167253f4e170 8350 y = rp[p->infinity | q->infinity]->y;
wolfSSL 14:167253f4e170 8351 z = rp[p->infinity | q->infinity]->z;
wolfSSL 14:167253f4e170 8352
wolfSSL 14:167253f4e170 8353 ap[0] = p;
wolfSSL 14:167253f4e170 8354 ap[1] = q;
wolfSSL 14:167253f4e170 8355 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 8356 r->x[i] = ap[p->infinity]->x[i];
wolfSSL 14:167253f4e170 8357 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 8358 r->y[i] = ap[p->infinity]->y[i];
wolfSSL 14:167253f4e170 8359 for (i=0; i<5; i++)
wolfSSL 14:167253f4e170 8360 r->z[i] = ap[p->infinity]->z[i];
wolfSSL 14:167253f4e170 8361 r->infinity = ap[p->infinity]->infinity;
wolfSSL 14:167253f4e170 8362
wolfSSL 14:167253f4e170 8363 /* U2 = X2*Z1^2 */
wolfSSL 14:167253f4e170 8364 sp_256_mont_sqr_5(t2, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8365 sp_256_mont_mul_5(t4, t2, z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8366 sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8367 /* S2 = Y2*Z1^3 */
wolfSSL 14:167253f4e170 8368 sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8369 /* H = U2 - X1 */
wolfSSL 14:167253f4e170 8370 sp_256_mont_sub_5(t2, t2, x, p256_mod);
wolfSSL 14:167253f4e170 8371 /* R = S2 - Y1 */
wolfSSL 14:167253f4e170 8372 sp_256_mont_sub_5(t4, t4, y, p256_mod);
wolfSSL 14:167253f4e170 8373 /* Z3 = H*Z1 */
wolfSSL 14:167253f4e170 8374 sp_256_mont_mul_5(z, z, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8375 /* X3 = R^2 - H^3 - 2*X1*H^2 */
wolfSSL 14:167253f4e170 8376 sp_256_mont_sqr_5(t1, t4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8377 sp_256_mont_sqr_5(t5, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8378 sp_256_mont_mul_5(t3, x, t5, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8379 sp_256_mont_mul_5(t5, t5, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8380 sp_256_mont_sub_5(x, t1, t5, p256_mod);
wolfSSL 14:167253f4e170 8381 sp_256_mont_dbl_5(t1, t3, p256_mod);
wolfSSL 14:167253f4e170 8382 sp_256_mont_sub_5(x, x, t1, p256_mod);
wolfSSL 14:167253f4e170 8383 /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
wolfSSL 14:167253f4e170 8384 sp_256_mont_sub_5(t3, t3, x, p256_mod);
wolfSSL 14:167253f4e170 8385 sp_256_mont_mul_5(t3, t3, t4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8386 sp_256_mont_mul_5(t5, t5, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8387 sp_256_mont_sub_5(y, t3, t5, p256_mod);
wolfSSL 14:167253f4e170 8388 }
wolfSSL 14:167253f4e170 8389 }
wolfSSL 14:167253f4e170 8390
wolfSSL 14:167253f4e170 8391 #ifdef FP_ECC
wolfSSL 14:167253f4e170 8392 /* Convert the projective point to affine.
wolfSSL 14:167253f4e170 8393 * Ordinates are in Montgomery form.
wolfSSL 14:167253f4e170 8394 *
wolfSSL 14:167253f4e170 8395 * a Point to convert.
wolfSSL 14:167253f4e170 8396 * t Temprorary data.
wolfSSL 14:167253f4e170 8397 */
wolfSSL 14:167253f4e170 8398 static void sp_256_proj_to_affine_5(sp_point* a, sp_digit* t)
wolfSSL 14:167253f4e170 8399 {
wolfSSL 14:167253f4e170 8400 sp_digit* t1 = t;
wolfSSL 14:167253f4e170 8401 sp_digit* t2 = t + 2 * 5;
wolfSSL 14:167253f4e170 8402 sp_digit* tmp = t + 4 * 5;
wolfSSL 14:167253f4e170 8403
wolfSSL 14:167253f4e170 8404 sp_256_mont_inv_5(t1, a->z, tmp);
wolfSSL 14:167253f4e170 8405
wolfSSL 14:167253f4e170 8406 sp_256_mont_sqr_5(t2, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8407 sp_256_mont_mul_5(t1, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8408
wolfSSL 14:167253f4e170 8409 sp_256_mont_mul_5(a->x, a->x, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8410 sp_256_mont_mul_5(a->y, a->y, t1, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 8411 XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 8412 }
wolfSSL 14:167253f4e170 8413
wolfSSL 14:167253f4e170 8414 /* Generate the pre-computed table of points for the base point.
wolfSSL 14:167253f4e170 8415 *
wolfSSL 14:167253f4e170 8416 * a The base point.
wolfSSL 14:167253f4e170 8417 * table Place to store generated point data.
wolfSSL 14:167253f4e170 8418 * tmp Temprorary data.
wolfSSL 14:167253f4e170 8419 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8420 */
wolfSSL 14:167253f4e170 8421 static int sp_256_gen_stripe_table_5(sp_point* a,
wolfSSL 14:167253f4e170 8422 sp_table_entry* table, sp_digit* tmp, void* heap)
wolfSSL 14:167253f4e170 8423 {
wolfSSL 14:167253f4e170 8424 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8425 sp_point td, s1d, s2d;
wolfSSL 14:167253f4e170 8426 #endif
wolfSSL 14:167253f4e170 8427 sp_point* t;
wolfSSL 14:167253f4e170 8428 sp_point* s1 = NULL;
wolfSSL 14:167253f4e170 8429 sp_point* s2 = NULL;
wolfSSL 14:167253f4e170 8430 int i, j;
wolfSSL 14:167253f4e170 8431 int err;
wolfSSL 14:167253f4e170 8432
wolfSSL 14:167253f4e170 8433 (void)heap;
wolfSSL 14:167253f4e170 8434
wolfSSL 14:167253f4e170 8435 err = sp_ecc_point_new(heap, td, t);
wolfSSL 14:167253f4e170 8436 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8437 err = sp_ecc_point_new(heap, s1d, s1);
wolfSSL 14:167253f4e170 8438 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8439 err = sp_ecc_point_new(heap, s2d, s2);
wolfSSL 14:167253f4e170 8440
wolfSSL 14:167253f4e170 8441 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8442 err = sp_256_mod_mul_norm_5(t->x, a->x, p256_mod);
wolfSSL 14:167253f4e170 8443 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8444 err = sp_256_mod_mul_norm_5(t->y, a->y, p256_mod);
wolfSSL 14:167253f4e170 8445 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8446 err = sp_256_mod_mul_norm_5(t->z, a->z, p256_mod);
wolfSSL 14:167253f4e170 8447 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8448 t->infinity = 0;
wolfSSL 14:167253f4e170 8449 sp_256_proj_to_affine_5(t, tmp);
wolfSSL 14:167253f4e170 8450
wolfSSL 14:167253f4e170 8451 XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 8452 s1->infinity = 0;
wolfSSL 14:167253f4e170 8453 XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 8454 s2->infinity = 0;
wolfSSL 14:167253f4e170 8455
wolfSSL 14:167253f4e170 8456 /* table[0] = {0, 0, infinity} */
wolfSSL 14:167253f4e170 8457 XMEMSET(&table[0], 0, sizeof(sp_table_entry));
wolfSSL 14:167253f4e170 8458 table[0].infinity = 1;
wolfSSL 14:167253f4e170 8459 /* table[1] = Affine version of 'a' in Montgomery form */
wolfSSL 14:167253f4e170 8460 XMEMCPY(table[1].x, t->x, sizeof(table->x));
wolfSSL 14:167253f4e170 8461 XMEMCPY(table[1].y, t->y, sizeof(table->y));
wolfSSL 14:167253f4e170 8462 table[1].infinity = 0;
wolfSSL 14:167253f4e170 8463
wolfSSL 14:167253f4e170 8464 for (i=1; i<8; i++) {
wolfSSL 14:167253f4e170 8465 sp_256_proj_point_dbl_n_5(t, t, 32, tmp);
wolfSSL 14:167253f4e170 8466 sp_256_proj_to_affine_5(t, tmp);
wolfSSL 14:167253f4e170 8467 XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
wolfSSL 14:167253f4e170 8468 XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
wolfSSL 14:167253f4e170 8469 table[1<<i].infinity = 0;
wolfSSL 14:167253f4e170 8470 }
wolfSSL 14:167253f4e170 8471
wolfSSL 14:167253f4e170 8472 for (i=1; i<8; i++) {
wolfSSL 14:167253f4e170 8473 XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
wolfSSL 14:167253f4e170 8474 XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
wolfSSL 14:167253f4e170 8475 for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
wolfSSL 14:167253f4e170 8476 XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
wolfSSL 14:167253f4e170 8477 XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
wolfSSL 14:167253f4e170 8478 sp_256_proj_point_add_qz1_5(t, s1, s2, tmp);
wolfSSL 14:167253f4e170 8479 sp_256_proj_to_affine_5(t, tmp);
wolfSSL 14:167253f4e170 8480 XMEMCPY(table[j].x, t->x, sizeof(table->x));
wolfSSL 14:167253f4e170 8481 XMEMCPY(table[j].y, t->y, sizeof(table->y));
wolfSSL 14:167253f4e170 8482 table[j].infinity = 0;
wolfSSL 14:167253f4e170 8483 }
wolfSSL 14:167253f4e170 8484 }
wolfSSL 14:167253f4e170 8485 }
wolfSSL 14:167253f4e170 8486
wolfSSL 14:167253f4e170 8487 sp_ecc_point_free(s2, 0, heap);
wolfSSL 14:167253f4e170 8488 sp_ecc_point_free(s1, 0, heap);
wolfSSL 14:167253f4e170 8489 sp_ecc_point_free( t, 0, heap);
wolfSSL 14:167253f4e170 8490
wolfSSL 14:167253f4e170 8491 return err;
wolfSSL 14:167253f4e170 8492 }
wolfSSL 14:167253f4e170 8493
wolfSSL 14:167253f4e170 8494 #endif /* FP_ECC */
wolfSSL 14:167253f4e170 8495 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 8496 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 8497 *
wolfSSL 14:167253f4e170 8498 * r Resulting point.
wolfSSL 14:167253f4e170 8499 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 8500 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 8501 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8502 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 8503 */
wolfSSL 14:167253f4e170 8504 static int sp_256_ecc_mulmod_stripe_5(sp_point* r, sp_point* g,
wolfSSL 14:167253f4e170 8505 sp_table_entry* table, sp_digit* k, int map, void* heap)
wolfSSL 14:167253f4e170 8506 {
wolfSSL 14:167253f4e170 8507 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8508 sp_point rtd;
wolfSSL 14:167253f4e170 8509 sp_point pd;
wolfSSL 14:167253f4e170 8510 sp_digit td[2 * 5 * 5];
wolfSSL 14:167253f4e170 8511 #endif
wolfSSL 14:167253f4e170 8512 sp_point* rt;
wolfSSL 14:167253f4e170 8513 sp_point* p = NULL;
wolfSSL 14:167253f4e170 8514 sp_digit* t;
wolfSSL 14:167253f4e170 8515 int i, j;
wolfSSL 14:167253f4e170 8516 int y, x;
wolfSSL 14:167253f4e170 8517 int err;
wolfSSL 14:167253f4e170 8518
wolfSSL 14:167253f4e170 8519 (void)g;
wolfSSL 14:167253f4e170 8520 (void)heap;
wolfSSL 14:167253f4e170 8521
wolfSSL 14:167253f4e170 8522 err = sp_ecc_point_new(heap, rtd, rt);
wolfSSL 14:167253f4e170 8523 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8524 err = sp_ecc_point_new(heap, pd, p);
wolfSSL 14:167253f4e170 8525 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8526 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,
wolfSSL 14:167253f4e170 8527 DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8528 if (t == NULL)
wolfSSL 14:167253f4e170 8529 err = MEMORY_E;
wolfSSL 14:167253f4e170 8530 #else
wolfSSL 14:167253f4e170 8531 t = td;
wolfSSL 14:167253f4e170 8532 #endif
wolfSSL 14:167253f4e170 8533
wolfSSL 14:167253f4e170 8534 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8535 XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 8536 XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 14:167253f4e170 8537
wolfSSL 14:167253f4e170 8538 y = 0;
wolfSSL 14:167253f4e170 8539 for (j=0,x=31; j<8; j++,x+=32)
wolfSSL 14:167253f4e170 8540 y |= ((k[x / 52] >> (x % 52)) & 1) << j;
wolfSSL 14:167253f4e170 8541 XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
wolfSSL 14:167253f4e170 8542 XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
wolfSSL 14:167253f4e170 8543 rt->infinity = table[y].infinity;
wolfSSL 14:167253f4e170 8544 for (i=30; i>=0; i--) {
wolfSSL 14:167253f4e170 8545 y = 0;
wolfSSL 14:167253f4e170 8546 for (j=0,x=i; j<8; j++,x+=32)
wolfSSL 14:167253f4e170 8547 y |= ((k[x / 52] >> (x % 52)) & 1) << j;
wolfSSL 14:167253f4e170 8548
wolfSSL 14:167253f4e170 8549 sp_256_proj_point_dbl_5(rt, rt, t);
wolfSSL 14:167253f4e170 8550 XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
wolfSSL 14:167253f4e170 8551 XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
wolfSSL 14:167253f4e170 8552 p->infinity = table[y].infinity;
wolfSSL 14:167253f4e170 8553 sp_256_proj_point_add_qz1_5(rt, rt, p, t);
wolfSSL 14:167253f4e170 8554 }
wolfSSL 14:167253f4e170 8555
wolfSSL 14:167253f4e170 8556 if (map)
wolfSSL 14:167253f4e170 8557 sp_256_map_5(r, rt, t);
wolfSSL 14:167253f4e170 8558 else
wolfSSL 14:167253f4e170 8559 XMEMCPY(r, rt, sizeof(sp_point));
wolfSSL 14:167253f4e170 8560 }
wolfSSL 14:167253f4e170 8561
wolfSSL 14:167253f4e170 8562 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8563 if (t != NULL)
wolfSSL 14:167253f4e170 8564 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8565 #endif
wolfSSL 14:167253f4e170 8566 sp_ecc_point_free(p, 0, heap);
wolfSSL 14:167253f4e170 8567 sp_ecc_point_free(rt, 0, heap);
wolfSSL 14:167253f4e170 8568
wolfSSL 14:167253f4e170 8569 return err;
wolfSSL 14:167253f4e170 8570 }
wolfSSL 14:167253f4e170 8571
wolfSSL 14:167253f4e170 8572 #ifdef FP_ECC
wolfSSL 14:167253f4e170 8573 #ifndef FP_ENTRIES
wolfSSL 14:167253f4e170 8574 #define FP_ENTRIES 16
wolfSSL 14:167253f4e170 8575 #endif
wolfSSL 14:167253f4e170 8576
wolfSSL 14:167253f4e170 8577 typedef struct sp_cache_t {
wolfSSL 14:167253f4e170 8578 sp_digit x[5];
wolfSSL 14:167253f4e170 8579 sp_digit y[5];
wolfSSL 14:167253f4e170 8580 sp_table_entry table[256];
wolfSSL 14:167253f4e170 8581 uint32_t cnt;
wolfSSL 14:167253f4e170 8582 int set;
wolfSSL 14:167253f4e170 8583 } sp_cache_t;
wolfSSL 14:167253f4e170 8584
wolfSSL 14:167253f4e170 8585 static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];
wolfSSL 14:167253f4e170 8586 static THREAD_LS_T int sp_cache_last = -1;
wolfSSL 14:167253f4e170 8587 static THREAD_LS_T int sp_cache_inited = 0;
wolfSSL 14:167253f4e170 8588
wolfSSL 14:167253f4e170 8589 #ifndef HAVE_THREAD_LS
wolfSSL 14:167253f4e170 8590 static volatile int initCacheMutex = 0;
wolfSSL 14:167253f4e170 8591 static wolfSSL_Mutex sp_cache_lock;
wolfSSL 14:167253f4e170 8592 #endif
wolfSSL 14:167253f4e170 8593
wolfSSL 14:167253f4e170 8594 static void sp_ecc_get_cache(sp_point* g, sp_cache_t** cache)
wolfSSL 14:167253f4e170 8595 {
wolfSSL 14:167253f4e170 8596 int i, j;
wolfSSL 14:167253f4e170 8597 uint32_t least;
wolfSSL 14:167253f4e170 8598
wolfSSL 14:167253f4e170 8599 if (sp_cache_inited == 0) {
wolfSSL 14:167253f4e170 8600 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 14:167253f4e170 8601 sp_cache[i].set = 0;
wolfSSL 14:167253f4e170 8602 }
wolfSSL 14:167253f4e170 8603 sp_cache_inited = 1;
wolfSSL 14:167253f4e170 8604 }
wolfSSL 14:167253f4e170 8605
wolfSSL 14:167253f4e170 8606 /* Compare point with those in cache. */
wolfSSL 14:167253f4e170 8607 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 14:167253f4e170 8608 if (!sp_cache[i].set)
wolfSSL 14:167253f4e170 8609 continue;
wolfSSL 14:167253f4e170 8610
wolfSSL 14:167253f4e170 8611 if (sp_256_cmp_equal_5(g->x, sp_cache[i].x) &
wolfSSL 14:167253f4e170 8612 sp_256_cmp_equal_5(g->y, sp_cache[i].y)) {
wolfSSL 14:167253f4e170 8613 sp_cache[i].cnt++;
wolfSSL 14:167253f4e170 8614 break;
wolfSSL 14:167253f4e170 8615 }
wolfSSL 14:167253f4e170 8616 }
wolfSSL 14:167253f4e170 8617
wolfSSL 14:167253f4e170 8618 /* No match. */
wolfSSL 14:167253f4e170 8619 if (i == FP_ENTRIES) {
wolfSSL 14:167253f4e170 8620 /* Find empty entry. */
wolfSSL 14:167253f4e170 8621 i = (sp_cache_last + 1) % FP_ENTRIES;
wolfSSL 14:167253f4e170 8622 for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {
wolfSSL 14:167253f4e170 8623 if (!sp_cache[i].set) {
wolfSSL 14:167253f4e170 8624 break;
wolfSSL 14:167253f4e170 8625 }
wolfSSL 14:167253f4e170 8626 }
wolfSSL 14:167253f4e170 8627
wolfSSL 14:167253f4e170 8628 /* Evict least used. */
wolfSSL 14:167253f4e170 8629 if (i == sp_cache_last) {
wolfSSL 14:167253f4e170 8630 least = sp_cache[0].cnt;
wolfSSL 14:167253f4e170 8631 for (j=1; j<FP_ENTRIES; j++) {
wolfSSL 14:167253f4e170 8632 if (sp_cache[j].cnt < least) {
wolfSSL 14:167253f4e170 8633 i = j;
wolfSSL 14:167253f4e170 8634 least = sp_cache[i].cnt;
wolfSSL 14:167253f4e170 8635 }
wolfSSL 14:167253f4e170 8636 }
wolfSSL 14:167253f4e170 8637 }
wolfSSL 14:167253f4e170 8638
wolfSSL 14:167253f4e170 8639 XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));
wolfSSL 14:167253f4e170 8640 XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));
wolfSSL 14:167253f4e170 8641 sp_cache[i].set = 1;
wolfSSL 14:167253f4e170 8642 sp_cache[i].cnt = 1;
wolfSSL 14:167253f4e170 8643 }
wolfSSL 14:167253f4e170 8644
wolfSSL 14:167253f4e170 8645 *cache = &sp_cache[i];
wolfSSL 14:167253f4e170 8646 sp_cache_last = i;
wolfSSL 14:167253f4e170 8647 }
wolfSSL 14:167253f4e170 8648 #endif /* FP_ECC */
wolfSSL 14:167253f4e170 8649
wolfSSL 14:167253f4e170 8650 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 14:167253f4e170 8651 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 8652 *
wolfSSL 14:167253f4e170 8653 * r Resulting point.
wolfSSL 14:167253f4e170 8654 * g Point to multiply.
wolfSSL 14:167253f4e170 8655 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 8656 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 8657 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8658 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 8659 */
wolfSSL 14:167253f4e170 8660 static int sp_256_ecc_mulmod_5(sp_point* r, sp_point* g, sp_digit* k,
wolfSSL 14:167253f4e170 8661 int map, void* heap)
wolfSSL 14:167253f4e170 8662 {
wolfSSL 14:167253f4e170 8663 #ifndef FP_ECC
wolfSSL 14:167253f4e170 8664 return sp_256_ecc_mulmod_fast_5(r, g, k, map, heap);
wolfSSL 14:167253f4e170 8665 #else
wolfSSL 14:167253f4e170 8666 sp_digit tmp[2 * 5 * 5];
wolfSSL 14:167253f4e170 8667 sp_cache_t* cache;
wolfSSL 14:167253f4e170 8668 int err = MP_OKAY;
wolfSSL 14:167253f4e170 8669
wolfSSL 14:167253f4e170 8670 #ifndef HAVE_THREAD_LS
wolfSSL 14:167253f4e170 8671 if (initCacheMutex == 0) {
wolfSSL 14:167253f4e170 8672 wc_InitMutex(&sp_cache_lock);
wolfSSL 14:167253f4e170 8673 initCacheMutex = 1;
wolfSSL 14:167253f4e170 8674 }
wolfSSL 14:167253f4e170 8675 if (wc_LockMutex(&sp_cache_lock) != 0)
wolfSSL 14:167253f4e170 8676 err = BAD_MUTEX_E;
wolfSSL 14:167253f4e170 8677 #endif /* HAVE_THREAD_LS */
wolfSSL 14:167253f4e170 8678
wolfSSL 14:167253f4e170 8679 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8680 sp_ecc_get_cache(g, &cache);
wolfSSL 14:167253f4e170 8681 if (cache->cnt == 2)
wolfSSL 14:167253f4e170 8682 sp_256_gen_stripe_table_5(g, cache->table, tmp, heap);
wolfSSL 14:167253f4e170 8683
wolfSSL 14:167253f4e170 8684 #ifndef HAVE_THREAD_LS
wolfSSL 14:167253f4e170 8685 wc_UnLockMutex(&sp_cache_lock);
wolfSSL 14:167253f4e170 8686 #endif /* HAVE_THREAD_LS */
wolfSSL 14:167253f4e170 8687
wolfSSL 14:167253f4e170 8688 if (cache->cnt < 2) {
wolfSSL 14:167253f4e170 8689 err = sp_256_ecc_mulmod_fast_5(r, g, k, map, heap);
wolfSSL 14:167253f4e170 8690 }
wolfSSL 14:167253f4e170 8691 else {
wolfSSL 14:167253f4e170 8692 err = sp_256_ecc_mulmod_stripe_5(r, g, cache->table, k,
wolfSSL 14:167253f4e170 8693 map, heap);
wolfSSL 14:167253f4e170 8694 }
wolfSSL 14:167253f4e170 8695 }
wolfSSL 14:167253f4e170 8696
wolfSSL 14:167253f4e170 8697 return err;
wolfSSL 14:167253f4e170 8698 #endif
wolfSSL 14:167253f4e170 8699 }
wolfSSL 14:167253f4e170 8700
wolfSSL 14:167253f4e170 8701 #endif
wolfSSL 14:167253f4e170 8702 /* Multiply the point by the scalar and return the result.
wolfSSL 14:167253f4e170 8703 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 8704 *
wolfSSL 14:167253f4e170 8705 * km Scalar to multiply by.
wolfSSL 14:167253f4e170 8706 * p Point to multiply.
wolfSSL 14:167253f4e170 8707 * r Resulting point.
wolfSSL 14:167253f4e170 8708 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 8709 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8710 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 8711 */
wolfSSL 14:167253f4e170 8712 int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,
wolfSSL 14:167253f4e170 8713 void* heap)
wolfSSL 14:167253f4e170 8714 {
wolfSSL 14:167253f4e170 8715 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8716 sp_point p;
wolfSSL 14:167253f4e170 8717 sp_digit kd[5];
wolfSSL 14:167253f4e170 8718 #endif
wolfSSL 14:167253f4e170 8719 sp_point* point;
wolfSSL 14:167253f4e170 8720 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 8721 int err = MP_OKAY;
wolfSSL 14:167253f4e170 8722 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 8723 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 8724 #endif
wolfSSL 14:167253f4e170 8725
wolfSSL 14:167253f4e170 8726 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 8727 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8728 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8729 k = XMALLOC(sizeof(sp_digit) * 5, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8730 if (k == NULL)
wolfSSL 14:167253f4e170 8731 err = MEMORY_E;
wolfSSL 14:167253f4e170 8732 }
wolfSSL 14:167253f4e170 8733 #else
wolfSSL 14:167253f4e170 8734 k = kd;
wolfSSL 14:167253f4e170 8735 #endif
wolfSSL 14:167253f4e170 8736 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 8737 sp_256_from_mp(k, 5, km);
wolfSSL 14:167253f4e170 8738 sp_256_point_from_ecc_point_5(point, gm);
wolfSSL 14:167253f4e170 8739
wolfSSL 14:167253f4e170 8740 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 8741 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 8742 err = sp_256_ecc_mulmod_avx2_5(point, point, k, map, heap);
wolfSSL 14:167253f4e170 8743 else
wolfSSL 14:167253f4e170 8744 #endif
wolfSSL 14:167253f4e170 8745 err = sp_256_ecc_mulmod_5(point, point, k, map, heap);
wolfSSL 14:167253f4e170 8746 }
wolfSSL 14:167253f4e170 8747 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 8748 err = sp_256_point_to_ecc_point_5(point, r);
wolfSSL 14:167253f4e170 8749
wolfSSL 14:167253f4e170 8750 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 8751 if (k != NULL)
wolfSSL 14:167253f4e170 8752 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 8753 #endif
wolfSSL 14:167253f4e170 8754 sp_ecc_point_free(point, 0, heap);
wolfSSL 14:167253f4e170 8755
wolfSSL 14:167253f4e170 8756 return err;
wolfSSL 14:167253f4e170 8757 }
wolfSSL 14:167253f4e170 8758
wolfSSL 14:167253f4e170 8759 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 8760 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 14:167253f4e170 8761 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 8762 *
wolfSSL 14:167253f4e170 8763 * r Resulting point.
wolfSSL 14:167253f4e170 8764 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 8765 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 8766 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 8767 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 8768 */
wolfSSL 14:167253f4e170 8769 static int sp_256_ecc_mulmod_base_5(sp_point* r, sp_digit* k,
wolfSSL 14:167253f4e170 8770 int map, void* heap)
wolfSSL 14:167253f4e170 8771 {
wolfSSL 14:167253f4e170 8772 /* No pre-computed values. */
wolfSSL 14:167253f4e170 8773 return sp_256_ecc_mulmod_5(r, &p256_base, k, map, heap);
wolfSSL 14:167253f4e170 8774 }
wolfSSL 14:167253f4e170 8775
wolfSSL 14:167253f4e170 8776 #else
wolfSSL 14:167253f4e170 8777 static sp_table_entry p256_table[256] = {
wolfSSL 14:167253f4e170 8778 /* 0 */
wolfSSL 14:167253f4e170 8779 { { 0x00, 0x00, 0x00, 0x00, 0x00 },
wolfSSL 14:167253f4e170 8780 { 0x00, 0x00, 0x00, 0x00, 0x00 },
wolfSSL 14:167253f4e170 8781 1 },
wolfSSL 14:167253f4e170 8782 /* 1 */
wolfSSL 14:167253f4e170 8783 { { 0x730d418a9143cl,0xfc5fedb60179el,0x762251075ba95l,0x55c679fb732b7l,
wolfSSL 14:167253f4e170 8784 0x018905f76a537l },
wolfSSL 14:167253f4e170 8785 { 0x25357ce95560al,0xe4ba19e45cddfl,0xd21f3258b4ab8l,0x5d85d2e88688dl,
wolfSSL 14:167253f4e170 8786 0x08571ff182588l },
wolfSSL 14:167253f4e170 8787 0 },
wolfSSL 14:167253f4e170 8788 /* 2 */
wolfSSL 14:167253f4e170 8789 { { 0x886024147519al,0xac26b372f0202l,0x785ebc8d0981el,0x58e9a9d4a7caal,
wolfSSL 14:167253f4e170 8790 0x0d953c50ddbdfl },
wolfSSL 14:167253f4e170 8791 { 0x361ccfd590f8fl,0x6b44e6c9179d6l,0x2eb64cf72e962l,0x88f37fd961102l,
wolfSSL 14:167253f4e170 8792 0x0863ebb7e9eb2l },
wolfSSL 14:167253f4e170 8793 0 },
wolfSSL 14:167253f4e170 8794 /* 3 */
wolfSSL 14:167253f4e170 8795 { { 0x6b6235cdb6485l,0xa22f0a2f97785l,0xf7e300b808f0el,0x80a03e68d9544l,
wolfSSL 14:167253f4e170 8796 0x000076055b5ffl },
wolfSSL 14:167253f4e170 8797 { 0x4eb9b838d2010l,0xbb3243708a763l,0x42a660654014fl,0x3ee0e0e47d398l,
wolfSSL 14:167253f4e170 8798 0x0830877613437l },
wolfSSL 14:167253f4e170 8799 0 },
wolfSSL 14:167253f4e170 8800 /* 4 */
wolfSSL 14:167253f4e170 8801 { { 0x22fc516a0d2bbl,0x6c1a6234994f9l,0x7c62c8b0d5cc1l,0x667f9241cf3a5l,
wolfSSL 14:167253f4e170 8802 0x02f5e6961fd1bl },
wolfSSL 14:167253f4e170 8803 { 0x5c70bf5a01797l,0x4d609561925c1l,0x71fdb523d20b4l,0x0f7b04911b370l,
wolfSSL 14:167253f4e170 8804 0x0f648f9168d6fl },
wolfSSL 14:167253f4e170 8805 0 },
wolfSSL 14:167253f4e170 8806 /* 5 */
wolfSSL 14:167253f4e170 8807 { { 0x66847e137bbbcl,0x9e8a6a0bec9e5l,0x9d73463e43446l,0x0015b1c427617l,
wolfSSL 14:167253f4e170 8808 0x05abe0285133dl },
wolfSSL 14:167253f4e170 8809 { 0xa837cc04c7dabl,0x4c43260c0792al,0x8e6cc37573d9fl,0x73830c9315627l,
wolfSSL 14:167253f4e170 8810 0x094bb725b6b6fl },
wolfSSL 14:167253f4e170 8811 0 },
wolfSSL 14:167253f4e170 8812 /* 6 */
wolfSSL 14:167253f4e170 8813 { { 0x9b48f720f141cl,0xcd2df5bc74bbfl,0x11045c46199b3l,0xc4efdc3f61294l,
wolfSSL 14:167253f4e170 8814 0x0cdd6bbcb2f7dl },
wolfSSL 14:167253f4e170 8815 { 0x6700beaf436fdl,0x6db99326beccal,0x14f25226f647fl,0xe5f60c0fa7920l,
wolfSSL 14:167253f4e170 8816 0x0a361bebd4bdal },
wolfSSL 14:167253f4e170 8817 0 },
wolfSSL 14:167253f4e170 8818 /* 7 */
wolfSSL 14:167253f4e170 8819 { { 0xa2558597c13c7l,0x5f50b7c3e128al,0x3c09d1dc38d63l,0x292c07039aecfl,
wolfSSL 14:167253f4e170 8820 0x0ba12ca09c4b5l },
wolfSSL 14:167253f4e170 8821 { 0x08fa459f91dfdl,0x66ceea07fb9e4l,0xd780b293af43bl,0xef4b1eceb0899l,
wolfSSL 14:167253f4e170 8822 0x053ebb99d701fl },
wolfSSL 14:167253f4e170 8823 0 },
wolfSSL 14:167253f4e170 8824 /* 8 */
wolfSSL 14:167253f4e170 8825 { { 0x7ee31b0e63d34l,0x72a9e54fab4fel,0x5e7b5a4f46005l,0x4831c0493334dl,
wolfSSL 14:167253f4e170 8826 0x08589fb9206d5l },
wolfSSL 14:167253f4e170 8827 { 0x0f5cc6583553al,0x4ae25649e5aa7l,0x0044652087909l,0x1c4fcc9045071l,
wolfSSL 14:167253f4e170 8828 0x0ebb0696d0254l },
wolfSSL 14:167253f4e170 8829 0 },
wolfSSL 14:167253f4e170 8830 /* 9 */
wolfSSL 14:167253f4e170 8831 { { 0x6ca15ac1647c5l,0x47c4cf5799461l,0x64dfbacb8127dl,0x7da3dc666aa37l,
wolfSSL 14:167253f4e170 8832 0x0eb2820cbd1b2l },
wolfSSL 14:167253f4e170 8833 { 0x6f8d86a87e008l,0x9d922378f3940l,0x0ccecb2d87dfal,0xda1d56ed2e428l,
wolfSSL 14:167253f4e170 8834 0x01f28289b55a7l },
wolfSSL 14:167253f4e170 8835 0 },
wolfSSL 14:167253f4e170 8836 /* 10 */
wolfSSL 14:167253f4e170 8837 { { 0xaa0c03b89da99l,0x9eb8284022abbl,0x81c05e8a6f2d7l,0x4d6327847862bl,
wolfSSL 14:167253f4e170 8838 0x0337a4b5905e5l },
wolfSSL 14:167253f4e170 8839 { 0x7500d21f7794al,0xb77d6d7f613c6l,0x4cfd6e8207005l,0xfbd60a5a37810l,
wolfSSL 14:167253f4e170 8840 0x00d65e0d5f4c2l },
wolfSSL 14:167253f4e170 8841 0 },
wolfSSL 14:167253f4e170 8842 /* 11 */
wolfSSL 14:167253f4e170 8843 { { 0x09bbeb5275d38l,0x450be0a358d9dl,0x73eb2654268a7l,0xa232f0762ff49l,
wolfSSL 14:167253f4e170 8844 0x0c23da24252f4l },
wolfSSL 14:167253f4e170 8845 { 0x1b84f0b94520cl,0x63b05bd78e5dal,0x4d29ea1096667l,0xcff13a4dcb869l,
wolfSSL 14:167253f4e170 8846 0x019de3b8cc790l },
wolfSSL 14:167253f4e170 8847 0 },
wolfSSL 14:167253f4e170 8848 /* 12 */
wolfSSL 14:167253f4e170 8849 { { 0xa716c26c5fe04l,0x0b3bba1bdb183l,0x4cb712c3b28del,0xcbfd7432c586al,
wolfSSL 14:167253f4e170 8850 0x0e34dcbd491fcl },
wolfSSL 14:167253f4e170 8851 { 0x8d46baaa58403l,0x8682e97a53b40l,0x6aaa8af9a6974l,0x0f7f9e3901273l,
wolfSSL 14:167253f4e170 8852 0x0e7641f447b4el },
wolfSSL 14:167253f4e170 8853 0 },
wolfSSL 14:167253f4e170 8854 /* 13 */
wolfSSL 14:167253f4e170 8855 { { 0x53941df64ba59l,0xec0b0242fc7d7l,0x1581859d33f10l,0x57bf4f06dfc6al,
wolfSSL 14:167253f4e170 8856 0x04a12df57052al },
wolfSSL 14:167253f4e170 8857 { 0x6338f9439dbd0l,0xd4bde53e1fbfal,0x1f1b314d3c24bl,0xea46fd5e4ffa2l,
wolfSSL 14:167253f4e170 8858 0x06af5aa93bb5bl },
wolfSSL 14:167253f4e170 8859 0 },
wolfSSL 14:167253f4e170 8860 /* 14 */
wolfSSL 14:167253f4e170 8861 { { 0x0b69910c91999l,0x402a580491da1l,0x8cc20900a24b4l,0x40133e0094b4bl,
wolfSSL 14:167253f4e170 8862 0x05fe3475a66a4l },
wolfSSL 14:167253f4e170 8863 { 0x8cabdf93e7b4bl,0x1a7c23f91ab0fl,0xd1e6263292b50l,0xa91642e889aecl,
wolfSSL 14:167253f4e170 8864 0x0b544e308ecfel },
wolfSSL 14:167253f4e170 8865 0 },
wolfSSL 14:167253f4e170 8866 /* 15 */
wolfSSL 14:167253f4e170 8867 { { 0x8c6e916ddfdcel,0x66f89179e6647l,0xd4e67e12c3291l,0xc20b4e8d6e764l,
wolfSSL 14:167253f4e170 8868 0x0e0b6b2bda6b0l },
wolfSSL 14:167253f4e170 8869 { 0x12df2bb7efb57l,0xde790c40070d3l,0x79bc9441aac0dl,0x3774f90336ad6l,
wolfSSL 14:167253f4e170 8870 0x071c023de25a6l },
wolfSSL 14:167253f4e170 8871 0 },
wolfSSL 14:167253f4e170 8872 /* 16 */
wolfSSL 14:167253f4e170 8873 { { 0x8c244bfe20925l,0xc38fdce86762al,0xd38706391c19al,0x24f65a96a5d5dl,
wolfSSL 14:167253f4e170 8874 0x061d587d421d3l },
wolfSSL 14:167253f4e170 8875 { 0x673a2a37173eal,0x0853778b65e87l,0x5bab43e238480l,0xefbe10f8441e0l,
wolfSSL 14:167253f4e170 8876 0x0fa11fe124621l },
wolfSSL 14:167253f4e170 8877 0 },
wolfSSL 14:167253f4e170 8878 /* 17 */
wolfSSL 14:167253f4e170 8879 { { 0x91f2b2cb19ffdl,0x5bb1923c231c8l,0xac5ca8e01ba8dl,0xbedcb6d03d678l,
wolfSSL 14:167253f4e170 8880 0x0586eb04c1f13l },
wolfSSL 14:167253f4e170 8881 { 0x5c6e527e8ed09l,0x3c1819ede20c3l,0x6c652fa1e81a3l,0x4f11278fd6c05l,
wolfSSL 14:167253f4e170 8882 0x019d5ac087086l },
wolfSSL 14:167253f4e170 8883 0 },
wolfSSL 14:167253f4e170 8884 /* 18 */
wolfSSL 14:167253f4e170 8885 { { 0x9f581309a4e1fl,0x1be92700741e9l,0xfd28d20ab7de7l,0x563f26a5ef0bel,
wolfSSL 14:167253f4e170 8886 0x0e7c0073f7f9cl },
wolfSSL 14:167253f4e170 8887 { 0xd663a0ef59f76l,0x5420fcb0501f6l,0xa6602d4669b3bl,0x3c0ac08c1f7a7l,
wolfSSL 14:167253f4e170 8888 0x0e08504fec65bl },
wolfSSL 14:167253f4e170 8889 0 },
wolfSSL 14:167253f4e170 8890 /* 19 */
wolfSSL 14:167253f4e170 8891 { { 0x8f68da031b3cal,0x9ee6da6d66f09l,0x4f246e86d1cabl,0x96b45bfd81fa9l,
wolfSSL 14:167253f4e170 8892 0x078f018825b09l },
wolfSSL 14:167253f4e170 8893 { 0xefde43a25787fl,0x0d1dccac9bb7el,0x35bfc368016f8l,0x747a0cea4877bl,
wolfSSL 14:167253f4e170 8894 0x043a773b87e94l },
wolfSSL 14:167253f4e170 8895 0 },
wolfSSL 14:167253f4e170 8896 /* 20 */
wolfSSL 14:167253f4e170 8897 { { 0x77734d2b533d5l,0xf6a1bdddc0625l,0x79ec293673b8al,0x66b1577e7c9aal,
wolfSSL 14:167253f4e170 8898 0x0bb6de651c3b2l },
wolfSSL 14:167253f4e170 8899 { 0x9303ab65259b3l,0xd3d03a7480e7el,0xb3cfc27d6a0afl,0xb99bc5ac83d19l,
wolfSSL 14:167253f4e170 8900 0x060b4619a5d18l },
wolfSSL 14:167253f4e170 8901 0 },
wolfSSL 14:167253f4e170 8902 /* 21 */
wolfSSL 14:167253f4e170 8903 { { 0xa38e11ae5aa1cl,0x2b49e73658bd6l,0xe5f87edb8b765l,0xffcd0b130014el,
wolfSSL 14:167253f4e170 8904 0x09d0f27b2aeebl },
wolfSSL 14:167253f4e170 8905 { 0x246317a730a55l,0x2fddbbc83aca9l,0xc019a719c955bl,0xc48d07c1dfe0al,
wolfSSL 14:167253f4e170 8906 0x0244a566d356el },
wolfSSL 14:167253f4e170 8907 0 },
wolfSSL 14:167253f4e170 8908 /* 22 */
wolfSSL 14:167253f4e170 8909 { { 0x0394aeacf1f96l,0xa9024c271c6dbl,0x2cbd3b99f2122l,0xef692626ac1b8l,
wolfSSL 14:167253f4e170 8910 0x045e58c873581l },
wolfSSL 14:167253f4e170 8911 { 0xf479da38f9dbcl,0x46e888a040d3fl,0x6e0bed7a8aaf1l,0xb7a4945adfb24l,
wolfSSL 14:167253f4e170 8912 0x0c040e21cc1e4l },
wolfSSL 14:167253f4e170 8913 0 },
wolfSSL 14:167253f4e170 8914 /* 23 */
wolfSSL 14:167253f4e170 8915 { { 0xaf0006f8117b6l,0xff73a35433847l,0xd9475eb651969l,0x6ec7482b35761l,
wolfSSL 14:167253f4e170 8916 0x01cdf5c97682cl },
wolfSSL 14:167253f4e170 8917 { 0x775b411f04839l,0xf448de16987dbl,0x70b32197dbeacl,0xff3db2921dd1bl,
wolfSSL 14:167253f4e170 8918 0x0046755f8a92dl },
wolfSSL 14:167253f4e170 8919 0 },
wolfSSL 14:167253f4e170 8920 /* 24 */
wolfSSL 14:167253f4e170 8921 { { 0xac5d2bce8ffcdl,0x8b2fe61a82cc8l,0x202d6c70d53c4l,0xa5f3f6f161727l,
wolfSSL 14:167253f4e170 8922 0x0046e5e113b83l },
wolfSSL 14:167253f4e170 8923 { 0x8ff64d8007f01l,0x125af43183e7bl,0x5e1a03c7fb1efl,0x005b045c5ea63l,
wolfSSL 14:167253f4e170 8924 0x06e0106c3303dl },
wolfSSL 14:167253f4e170 8925 0 },
wolfSSL 14:167253f4e170 8926 /* 25 */
wolfSSL 14:167253f4e170 8927 { { 0x7358488dd73b1l,0x8f995ed0d948cl,0x56a2ab7767070l,0xcf1f38385ea8cl,
wolfSSL 14:167253f4e170 8928 0x0442594ede901l },
wolfSSL 14:167253f4e170 8929 { 0xaa2c912d4b65bl,0x3b96c90c37f8fl,0xe978d1f94c234l,0xe68ed326e4a15l,
wolfSSL 14:167253f4e170 8930 0x0a796fa514c2el },
wolfSSL 14:167253f4e170 8931 0 },
wolfSSL 14:167253f4e170 8932 /* 26 */
wolfSSL 14:167253f4e170 8933 { { 0xfb604823addd7l,0x83e56693b3359l,0xcbf3c809e2a61l,0x66e9f885b78e3l,
wolfSSL 14:167253f4e170 8934 0x0e4ad2da9c697l },
wolfSSL 14:167253f4e170 8935 { 0xf7f428e048a61l,0x8cc092d9a0357l,0x03ed8ef082d19l,0x5143fc3a1af4cl,
wolfSSL 14:167253f4e170 8936 0x0c5e94046c37bl },
wolfSSL 14:167253f4e170 8937 0 },
wolfSSL 14:167253f4e170 8938 /* 27 */
wolfSSL 14:167253f4e170 8939 { { 0xa538c2be75f9el,0xe8cb123a78476l,0x109c04b6fd1a9l,0x4747d85e4df0bl,
wolfSSL 14:167253f4e170 8940 0x063283dafdb46l },
wolfSSL 14:167253f4e170 8941 { 0x28cf7baf2df15l,0x550ad9a7f4ce7l,0x834bcc3e592c4l,0xa938fab226adel,
wolfSSL 14:167253f4e170 8942 0x068bd19ab1981l },
wolfSSL 14:167253f4e170 8943 0 },
wolfSSL 14:167253f4e170 8944 /* 28 */
wolfSSL 14:167253f4e170 8945 { { 0xead511887d659l,0xf4b359305ac08l,0xfe74fe33374d5l,0xdfd696986981cl,
wolfSSL 14:167253f4e170 8946 0x0495292f53c6fl },
wolfSSL 14:167253f4e170 8947 { 0x78c9e1acec896l,0x10ec5b44844a8l,0x64d60a7d964b2l,0x68376696f7e26l,
wolfSSL 14:167253f4e170 8948 0x00ec7530d2603l },
wolfSSL 14:167253f4e170 8949 0 },
wolfSSL 14:167253f4e170 8950 /* 29 */
wolfSSL 14:167253f4e170 8951 { { 0x13a05ad2687bbl,0x6af32e21fa2dal,0xdd4607ba1f83bl,0x3f0b390f5ef51l,
wolfSSL 14:167253f4e170 8952 0x00f6207a66486l },
wolfSSL 14:167253f4e170 8953 { 0x7e3bb0f138233l,0x6c272aa718bd6l,0x6ec88aedd66b9l,0x6dcf8ed004072l,
wolfSSL 14:167253f4e170 8954 0x0ff0db07208edl },
wolfSSL 14:167253f4e170 8955 0 },
wolfSSL 14:167253f4e170 8956 /* 30 */
wolfSSL 14:167253f4e170 8957 { { 0xfa1014c95d553l,0xfd5d680a8a749l,0xf3b566fa44052l,0x0ea3183b4317fl,
wolfSSL 14:167253f4e170 8958 0x0313b513c8874l },
wolfSSL 14:167253f4e170 8959 { 0x2e2ac08d11549l,0x0bb4dee21cb40l,0x7f2320e071ee1l,0x9f8126b987dd4l,
wolfSSL 14:167253f4e170 8960 0x02d3abcf986f1l },
wolfSSL 14:167253f4e170 8961 0 },
wolfSSL 14:167253f4e170 8962 /* 31 */
wolfSSL 14:167253f4e170 8963 { { 0x88501815581a2l,0x56632211af4c2l,0xcab2e999a0a6dl,0x8cdf19ba7a0f0l,
wolfSSL 14:167253f4e170 8964 0x0c036fa10ded9l },
wolfSSL 14:167253f4e170 8965 { 0xe08bac1fbd009l,0x9006d1581629al,0xb9e0d8f0b68b1l,0x0194c2eb32779l,
wolfSSL 14:167253f4e170 8966 0x0a6b2a2c4b6d4l },
wolfSSL 14:167253f4e170 8967 0 },
wolfSSL 14:167253f4e170 8968 /* 32 */
wolfSSL 14:167253f4e170 8969 { { 0x3e50f6d3549cfl,0x6ffacd665ed43l,0xe11fcb46f3369l,0x9860695bfdaccl,
wolfSSL 14:167253f4e170 8970 0x0810ee252af7cl },
wolfSSL 14:167253f4e170 8971 { 0x50fe17159bb2cl,0xbe758b357b654l,0x69fea72f7dfbel,0x17452b057e74dl,
wolfSSL 14:167253f4e170 8972 0x0d485717a9273l },
wolfSSL 14:167253f4e170 8973 0 },
wolfSSL 14:167253f4e170 8974 /* 33 */
wolfSSL 14:167253f4e170 8975 { { 0x41a8af0cb5a98l,0x931f3110bf117l,0xb382adfd3da8fl,0x604e1994e2cbal,
wolfSSL 14:167253f4e170 8976 0x06a6045a72f9al },
wolfSSL 14:167253f4e170 8977 { 0xc0d3fa2b2411dl,0x3e510e96e0170l,0x865b3ccbe0eb8l,0x57903bcc9f738l,
wolfSSL 14:167253f4e170 8978 0x0d3e45cfaf9e1l },
wolfSSL 14:167253f4e170 8979 0 },
wolfSSL 14:167253f4e170 8980 /* 34 */
wolfSSL 14:167253f4e170 8981 { { 0xf69bbe83f7669l,0x8272877d6bce1l,0x244278d09f8ael,0xc19c9548ae543l,
wolfSSL 14:167253f4e170 8982 0x0207755dee3c2l },
wolfSSL 14:167253f4e170 8983 { 0xd61d96fef1945l,0xefb12d28c387bl,0x2df64aa18813cl,0xb00d9fbcd1d67l,
wolfSSL 14:167253f4e170 8984 0x048dc5ee57154l },
wolfSSL 14:167253f4e170 8985 0 },
wolfSSL 14:167253f4e170 8986 /* 35 */
wolfSSL 14:167253f4e170 8987 { { 0x790bff7e5a199l,0xcf989ccbb7123l,0xa519c79e0efb8l,0xf445c27a2bfe0l,
wolfSSL 14:167253f4e170 8988 0x0f2fb0aeddff6l },
wolfSSL 14:167253f4e170 8989 { 0x09575f0b5025fl,0xd740fa9f2241cl,0x80bfbd0550543l,0xd5258fa3c8ad3l,
wolfSSL 14:167253f4e170 8990 0x0a13e9015db28l },
wolfSSL 14:167253f4e170 8991 0 },
wolfSSL 14:167253f4e170 8992 /* 36 */
wolfSSL 14:167253f4e170 8993 { { 0x7a350a2b65cbcl,0x722a464226f9fl,0x23f07a10b04b9l,0x526f265ce241el,
wolfSSL 14:167253f4e170 8994 0x02bf0d6b01497l },
wolfSSL 14:167253f4e170 8995 { 0x4dd3f4b216fb7l,0x67fbdda26ad3dl,0x708505cf7d7b8l,0xe89faeb7b83f6l,
wolfSSL 14:167253f4e170 8996 0x042a94a5a162fl },
wolfSSL 14:167253f4e170 8997 0 },
wolfSSL 14:167253f4e170 8998 /* 37 */
wolfSSL 14:167253f4e170 8999 { { 0x6ad0beaadf191l,0x9025a268d7584l,0x94dc1f60f8a48l,0xde3de86030504l,
wolfSSL 14:167253f4e170 9000 0x02c2dd969c65el },
wolfSSL 14:167253f4e170 9001 { 0x2171d93849c17l,0xba1da250dd6d0l,0xc3a5485460488l,0x6dbc4810c7063l,
wolfSSL 14:167253f4e170 9002 0x0f437fa1f42c5l },
wolfSSL 14:167253f4e170 9003 0 },
wolfSSL 14:167253f4e170 9004 /* 38 */
wolfSSL 14:167253f4e170 9005 { { 0x0d7144a0f7dabl,0x931776e9ac6aal,0x5f397860f0497l,0x7aa852c0a050fl,
wolfSSL 14:167253f4e170 9006 0x0aaf45b335470l },
wolfSSL 14:167253f4e170 9007 { 0x37c33c18d364al,0x063e49716585el,0x5ec5444d40b9bl,0x72bcf41716811l,
wolfSSL 14:167253f4e170 9008 0x0cdf6310df4f2l },
wolfSSL 14:167253f4e170 9009 0 },
wolfSSL 14:167253f4e170 9010 /* 39 */
wolfSSL 14:167253f4e170 9011 { { 0x3c6238ea8b7efl,0x1885bc2287747l,0xbda8e3408e935l,0x2ff2419567722l,
wolfSSL 14:167253f4e170 9012 0x0f0d008bada9el },
wolfSSL 14:167253f4e170 9013 { 0x2671d2414d3b1l,0x85b019ea76291l,0x53bcbdbb37549l,0x7b8b5c61b96d4l,
wolfSSL 14:167253f4e170 9014 0x05bd5c2f5ca88l },
wolfSSL 14:167253f4e170 9015 0 },
wolfSSL 14:167253f4e170 9016 /* 40 */
wolfSSL 14:167253f4e170 9017 { { 0xf469ef49a3154l,0x956e2b2e9aef0l,0xa924a9c3e85a5l,0x471945aaec1eal,
wolfSSL 14:167253f4e170 9018 0x0aa12dfc8a09el },
wolfSSL 14:167253f4e170 9019 { 0x272274df69f1dl,0x2ca2ff5e7326fl,0x7a9dd44e0e4c8l,0xa901b9d8ce73bl,
wolfSSL 14:167253f4e170 9020 0x06c036e73e48cl },
wolfSSL 14:167253f4e170 9021 0 },
wolfSSL 14:167253f4e170 9022 /* 41 */
wolfSSL 14:167253f4e170 9023 { { 0xae12a0f6e3138l,0x0025ad345a5cfl,0x5672bc56966efl,0xbe248993c64b4l,
wolfSSL 14:167253f4e170 9024 0x0292ff65896afl },
wolfSSL 14:167253f4e170 9025 { 0x50d445e213402l,0x274392c9fed52l,0xa1c72e8f6580el,0x7276097b397fdl,
wolfSSL 14:167253f4e170 9026 0x0644e0c90311bl },
wolfSSL 14:167253f4e170 9027 0 },
wolfSSL 14:167253f4e170 9028 /* 42 */
wolfSSL 14:167253f4e170 9029 { { 0x421e1a47153f0l,0x79920418c9e1el,0x05d7672b86c3bl,0x9a7793bdce877l,
wolfSSL 14:167253f4e170 9030 0x0f25ae793cab7l },
wolfSSL 14:167253f4e170 9031 { 0x194a36d869d0cl,0x824986c2641f3l,0x96e945e9d55c8l,0x0a3e49fb5ea30l,
wolfSSL 14:167253f4e170 9032 0x039b8e65313dbl },
wolfSSL 14:167253f4e170 9033 0 },
wolfSSL 14:167253f4e170 9034 /* 43 */
wolfSSL 14:167253f4e170 9035 { { 0x54200b6fd2e59l,0x669255c98f377l,0xe2a573935e2c0l,0xdb06d9dab21a0l,
wolfSSL 14:167253f4e170 9036 0x039122f2f0f19l },
wolfSSL 14:167253f4e170 9037 { 0xce1e003cad53cl,0x0fe65c17e3cfbl,0xaa13877225b2cl,0xff8d72baf1d29l,
wolfSSL 14:167253f4e170 9038 0x08de80af8ce80l },
wolfSSL 14:167253f4e170 9039 0 },
wolfSSL 14:167253f4e170 9040 /* 44 */
wolfSSL 14:167253f4e170 9041 { { 0xea8d9207bbb76l,0x7c21782758afbl,0xc0436b1921c7el,0x8c04dfa2b74b1l,
wolfSSL 14:167253f4e170 9042 0x0871949062e36l },
wolfSSL 14:167253f4e170 9043 { 0x928bba3993df5l,0xb5f3b3d26ab5fl,0x5b55050639d75l,0xfde1011aa78a8l,
wolfSSL 14:167253f4e170 9044 0x0fc315e6a5b74l },
wolfSSL 14:167253f4e170 9045 0 },
wolfSSL 14:167253f4e170 9046 /* 45 */
wolfSSL 14:167253f4e170 9047 { { 0xfd41ae8d6ecfal,0xf61aec7f86561l,0x924741d5f8c44l,0x908898452a7b4l,
wolfSSL 14:167253f4e170 9048 0x0e6d4a7adee38l },
wolfSSL 14:167253f4e170 9049 { 0x52ed14593c75dl,0xa4dd271162605l,0xba2c7db70a70dl,0xae57d2aede937l,
wolfSSL 14:167253f4e170 9050 0x035dfaf9a9be2l },
wolfSSL 14:167253f4e170 9051 0 },
wolfSSL 14:167253f4e170 9052 /* 46 */
wolfSSL 14:167253f4e170 9053 { { 0x56fcdaa736636l,0x97ae2cab7e6b9l,0xf34996609f51dl,0x0d2bfb10bf410l,
wolfSSL 14:167253f4e170 9054 0x01da5c7d71c83l },
wolfSSL 14:167253f4e170 9055 { 0x1e4833cce6825l,0x8ff9573c3b5c4l,0x23036b815ad11l,0xb9d6a28552c7fl,
wolfSSL 14:167253f4e170 9056 0x07077c0fddbf4l },
wolfSSL 14:167253f4e170 9057 0 },
wolfSSL 14:167253f4e170 9058 /* 47 */
wolfSSL 14:167253f4e170 9059 { { 0x3ff8d46b9661cl,0x6b0d2cfd71bf6l,0x847f8f7a1dfd3l,0xfe440373e140al,
wolfSSL 14:167253f4e170 9060 0x053a8632ee50el },
wolfSSL 14:167253f4e170 9061 { 0x6ff68696d8051l,0x95c74f468a097l,0xe4e26bddaec0cl,0xfcc162994dc35l,
wolfSSL 14:167253f4e170 9062 0x0028ca76d34e1l },
wolfSSL 14:167253f4e170 9063 0 },
wolfSSL 14:167253f4e170 9064 /* 48 */
wolfSSL 14:167253f4e170 9065 { { 0xd47dcfc9877eel,0x10801d0002d11l,0x4c260b6c8b362l,0xf046d002c1175l,
wolfSSL 14:167253f4e170 9066 0x004c17cd86962l },
wolfSSL 14:167253f4e170 9067 { 0xbd094b0daddf5l,0x7524ce55c06d9l,0x2da03b5bea235l,0x7474663356e67l,
wolfSSL 14:167253f4e170 9068 0x0f7ba4de9fed9l },
wolfSSL 14:167253f4e170 9069 0 },
wolfSSL 14:167253f4e170 9070 /* 49 */
wolfSSL 14:167253f4e170 9071 { { 0xbfa34ebe1263fl,0x3571ae7ce6d0dl,0x2a6f523557637l,0x1c41d24405538l,
wolfSSL 14:167253f4e170 9072 0x0e31f96005213l },
wolfSSL 14:167253f4e170 9073 { 0xb9216ea6b6ec6l,0x2e73c2fc44d1bl,0x9d0a29437a1d1l,0xd47bc10e7eac8l,
wolfSSL 14:167253f4e170 9074 0x0aa3a6259ce34l },
wolfSSL 14:167253f4e170 9075 0 },
wolfSSL 14:167253f4e170 9076 /* 50 */
wolfSSL 14:167253f4e170 9077 { { 0xf9df536f3dcd3l,0x50d2bf7360fbcl,0xf504f5b6cededl,0xdaee491710fadl,
wolfSSL 14:167253f4e170 9078 0x02398dd627e79l },
wolfSSL 14:167253f4e170 9079 { 0x705a36d09569el,0xbb5149f769cf4l,0x5f6034cea0619l,0x6210ff9c03773l,
wolfSSL 14:167253f4e170 9080 0x05717f5b21c04l },
wolfSSL 14:167253f4e170 9081 0 },
wolfSSL 14:167253f4e170 9082 /* 51 */
wolfSSL 14:167253f4e170 9083 { { 0x229c921dd895el,0x0040c284519fel,0xd637ecd8e5185l,0x28defa13d2391l,
wolfSSL 14:167253f4e170 9084 0x0660a2c560e3cl },
wolfSSL 14:167253f4e170 9085 { 0xa88aed67fcbd0l,0x780ea9f0969ccl,0x2e92b4dc84724l,0x245332b2f4817l,
wolfSSL 14:167253f4e170 9086 0x0624ee54c4f52l },
wolfSSL 14:167253f4e170 9087 0 },
wolfSSL 14:167253f4e170 9088 /* 52 */
wolfSSL 14:167253f4e170 9089 { { 0x49ce4d897ecccl,0xd93f9880aa095l,0x43a7c204d49d1l,0xfbc0723c24230l,
wolfSSL 14:167253f4e170 9090 0x04f392afb92bdl },
wolfSSL 14:167253f4e170 9091 { 0x9f8fa7de44fd9l,0xe457b32156696l,0x68ebc3cb66cfbl,0x399cdb2fa8033l,
wolfSSL 14:167253f4e170 9092 0x08a3e7977ccdbl },
wolfSSL 14:167253f4e170 9093 0 },
wolfSSL 14:167253f4e170 9094 /* 53 */
wolfSSL 14:167253f4e170 9095 { { 0x1881f06c4b125l,0x00f6e3ca8cddel,0xc7a13e9ae34e3l,0x4404ef6999de5l,
wolfSSL 14:167253f4e170 9096 0x03888d02370c2l },
wolfSSL 14:167253f4e170 9097 { 0x8035644f91081l,0x615f015504762l,0x32cd36e3d9fcfl,0x23361827edc86l,
wolfSSL 14:167253f4e170 9098 0x0a5e62e471810l },
wolfSSL 14:167253f4e170 9099 0 },
wolfSSL 14:167253f4e170 9100 /* 54 */
wolfSSL 14:167253f4e170 9101 { { 0x25ee32facd6c8l,0x5454bcbc661a8l,0x8df9931699c63l,0x5adc0ce3edf79l,
wolfSSL 14:167253f4e170 9102 0x02c4768e6466al },
wolfSSL 14:167253f4e170 9103 { 0x6ff8c90a64bc9l,0x20e4779f5cb34l,0xc05e884630a60l,0x52a0d949d064bl,
wolfSSL 14:167253f4e170 9104 0x07b5e6441f9e6l },
wolfSSL 14:167253f4e170 9105 0 },
wolfSSL 14:167253f4e170 9106 /* 55 */
wolfSSL 14:167253f4e170 9107 { { 0x9422c1d28444al,0xd8be136a39216l,0xb0c7fcee996c5l,0x744a2387afe5fl,
wolfSSL 14:167253f4e170 9108 0x0b8af73cb0c8dl },
wolfSSL 14:167253f4e170 9109 { 0xe83aa338b86fdl,0x58a58a5cff5fdl,0x0ac9433fee3f1l,0x0895c9ee8f6f2l,
wolfSSL 14:167253f4e170 9110 0x0a036395f7f3fl },
wolfSSL 14:167253f4e170 9111 0 },
wolfSSL 14:167253f4e170 9112 /* 56 */
wolfSSL 14:167253f4e170 9113 { { 0x3c6bba10f7770l,0x81a12a0e248c7l,0x1bc2b9fa6f16dl,0xb533100df6825l,
wolfSSL 14:167253f4e170 9114 0x04be36b01875fl },
wolfSSL 14:167253f4e170 9115 { 0x6086e9fb56dbbl,0x8b07e7a4f8922l,0x6d52f20306fefl,0x00c0eeaccc056l,
wolfSSL 14:167253f4e170 9116 0x08cbc9a871bdcl },
wolfSSL 14:167253f4e170 9117 0 },
wolfSSL 14:167253f4e170 9118 /* 57 */
wolfSSL 14:167253f4e170 9119 { { 0x1895cc0dac4abl,0x40712ff112e13l,0xa1cee57a874a4l,0x35f86332ae7c6l,
wolfSSL 14:167253f4e170 9120 0x044e7553e0c08l },
wolfSSL 14:167253f4e170 9121 { 0x03fff7734002dl,0x8b0b34425c6d5l,0xe8738b59d35cbl,0xfc1895f702760l,
wolfSSL 14:167253f4e170 9122 0x0470a683a5eb8l },
wolfSSL 14:167253f4e170 9123 0 },
wolfSSL 14:167253f4e170 9124 /* 58 */
wolfSSL 14:167253f4e170 9125 { { 0x761dc90513482l,0x2a01e9276a81bl,0xce73083028720l,0xc6efcda441ee0l,
wolfSSL 14:167253f4e170 9126 0x016410690c63dl },
wolfSSL 14:167253f4e170 9127 { 0x34a066d06a2edl,0x45189b100bf50l,0xb8218c9dd4d77l,0xbb4fd914ae72al,
wolfSSL 14:167253f4e170 9128 0x0d73479fd7abcl },
wolfSSL 14:167253f4e170 9129 0 },
wolfSSL 14:167253f4e170 9130 /* 59 */
wolfSSL 14:167253f4e170 9131 { { 0xefb165ad4c6e5l,0x8f5b06d04d7edl,0x575cb14262cf0l,0x666b12ed5bb18l,
wolfSSL 14:167253f4e170 9132 0x0816469e30771l },
wolfSSL 14:167253f4e170 9133 { 0xb9d79561e291el,0x22c1de1661d7al,0x35e0513eb9dafl,0x3f9cf49827eb1l,
wolfSSL 14:167253f4e170 9134 0x00a36dd23f0ddl },
wolfSSL 14:167253f4e170 9135 0 },
wolfSSL 14:167253f4e170 9136 /* 60 */
wolfSSL 14:167253f4e170 9137 { { 0xd32c741d5533cl,0x9e8684628f098l,0x349bd117c5f5al,0xb11839a228adel,
wolfSSL 14:167253f4e170 9138 0x0e331dfd6fdbal },
wolfSSL 14:167253f4e170 9139 { 0x0ab686bcc6ed8l,0xbdef7a260e510l,0xce850d77160c3l,0x33899063d9a7bl,
wolfSSL 14:167253f4e170 9140 0x0d3b4782a492el },
wolfSSL 14:167253f4e170 9141 0 },
wolfSSL 14:167253f4e170 9142 /* 61 */
wolfSSL 14:167253f4e170 9143 { { 0x9b6e8f3821f90l,0xed66eb7aada14l,0xa01311692edd9l,0xa5bd0bb669531l,
wolfSSL 14:167253f4e170 9144 0x07281275a4c86l },
wolfSSL 14:167253f4e170 9145 { 0x858f7d3ff47e5l,0xbc61016441503l,0xdfd9bb15e1616l,0x505962b0f11a7l,
wolfSSL 14:167253f4e170 9146 0x02c062e7ece14l },
wolfSSL 14:167253f4e170 9147 0 },
wolfSSL 14:167253f4e170 9148 /* 62 */
wolfSSL 14:167253f4e170 9149 { { 0xf996f0159ac2el,0x36cbdb2713a76l,0x8e46047281e77l,0x7ef12ad6d2880l,
wolfSSL 14:167253f4e170 9150 0x0282a35f92c4el },
wolfSSL 14:167253f4e170 9151 { 0x54b1ec0ce5cd2l,0xc91379c2299c3l,0xe82c11ecf99efl,0x2abd992caf383l,
wolfSSL 14:167253f4e170 9152 0x0c71cd513554dl },
wolfSSL 14:167253f4e170 9153 0 },
wolfSSL 14:167253f4e170 9154 /* 63 */
wolfSSL 14:167253f4e170 9155 { { 0x5de9c09b578f4l,0x58e3affa7a488l,0x9182f1f1884e2l,0xf3a38f76b1b75l,
wolfSSL 14:167253f4e170 9156 0x0c50f6740cf47l },
wolfSSL 14:167253f4e170 9157 { 0x4adf3374b68eal,0x2369965fe2a9cl,0x5a53050a406f3l,0x58dc2f86a2228l,
wolfSSL 14:167253f4e170 9158 0x0b9ecb3a72129l },
wolfSSL 14:167253f4e170 9159 0 },
wolfSSL 14:167253f4e170 9160 /* 64 */
wolfSSL 14:167253f4e170 9161 { { 0x8410ef4f8b16al,0xfec47b266a56fl,0xd9c87c197241al,0xab1b0a406b8e6l,
wolfSSL 14:167253f4e170 9162 0x0803f3e02cd42l },
wolfSSL 14:167253f4e170 9163 { 0x309a804dbec69l,0xf73bbad05f7f0l,0xd8e197fa83b85l,0xadc1c6097273al,
wolfSSL 14:167253f4e170 9164 0x0c097440e5067l },
wolfSSL 14:167253f4e170 9165 0 },
wolfSSL 14:167253f4e170 9166 /* 65 */
wolfSSL 14:167253f4e170 9167 { { 0xa56f2c379ab34l,0x8b841df8d1846l,0x76c68efa8ee06l,0x1f30203144591l,
wolfSSL 14:167253f4e170 9168 0x0f1af32d5915fl },
wolfSSL 14:167253f4e170 9169 { 0x375315d75bd50l,0xbaf72f67bc99cl,0x8d7723f837cffl,0x1c8b0613a4184l,
wolfSSL 14:167253f4e170 9170 0x023d0f130e2d4l },
wolfSSL 14:167253f4e170 9171 0 },
wolfSSL 14:167253f4e170 9172 /* 66 */
wolfSSL 14:167253f4e170 9173 { { 0xab6edf41500d9l,0xe5fcbeada8857l,0x97259510d890al,0xfadd52fe86488l,
wolfSSL 14:167253f4e170 9174 0x0b0288dd6c0a3l },
wolfSSL 14:167253f4e170 9175 { 0x20f30650bcb08l,0x13695d6e16853l,0x989aa7671af63l,0xc8d231f520a7bl,
wolfSSL 14:167253f4e170 9176 0x0ffd3724ff408l },
wolfSSL 14:167253f4e170 9177 0 },
wolfSSL 14:167253f4e170 9178 /* 67 */
wolfSSL 14:167253f4e170 9179 { { 0x68e64b458e6cbl,0x20317a5d28539l,0xaa75f56992dadl,0x26df3814ae0b7l,
wolfSSL 14:167253f4e170 9180 0x0f5590f4ad78cl },
wolfSSL 14:167253f4e170 9181 { 0x24bd3cf0ba55al,0x4a0c778bae0fcl,0x83b674a0fc472l,0x4a201ce9864f6l,
wolfSSL 14:167253f4e170 9182 0x018d6da54f6f7l },
wolfSSL 14:167253f4e170 9183 0 },
wolfSSL 14:167253f4e170 9184 /* 68 */
wolfSSL 14:167253f4e170 9185 { { 0x3e225d5be5a2bl,0x835934f3c6ed9l,0x2626ffc6fe799l,0x216a431409262l,
wolfSSL 14:167253f4e170 9186 0x050bbb4d97990l },
wolfSSL 14:167253f4e170 9187 { 0x191c6e57ec63el,0x40181dcdb2378l,0x236e0f665422cl,0x49c341a8099b0l,
wolfSSL 14:167253f4e170 9188 0x02b10011801fel },
wolfSSL 14:167253f4e170 9189 0 },
wolfSSL 14:167253f4e170 9190 /* 69 */
wolfSSL 14:167253f4e170 9191 { { 0x8b5c59b391593l,0xa2598270fcfc6l,0x19adcbbc385f5l,0xae0c7144f3aadl,
wolfSSL 14:167253f4e170 9192 0x0dd55899983fbl },
wolfSSL 14:167253f4e170 9193 { 0x88b8e74b82ff4l,0x4071e734c993bl,0x3c0322ad2e03cl,0x60419a7a9eaf4l,
wolfSSL 14:167253f4e170 9194 0x0e6e4c551149dl },
wolfSSL 14:167253f4e170 9195 0 },
wolfSSL 14:167253f4e170 9196 /* 70 */
wolfSSL 14:167253f4e170 9197 { { 0x655bb1e9af288l,0x64f7ada93155fl,0xb2820e5647e1al,0x56ff43697e4bcl,
wolfSSL 14:167253f4e170 9198 0x051e00db107edl },
wolfSSL 14:167253f4e170 9199 { 0x169b8771c327el,0x0b4a96c2ad43dl,0xdeb477929cdb2l,0x9177c07d51f53l,
wolfSSL 14:167253f4e170 9200 0x0e22f42414982l },
wolfSSL 14:167253f4e170 9201 0 },
wolfSSL 14:167253f4e170 9202 /* 71 */
wolfSSL 14:167253f4e170 9203 { { 0x5e8f4635f1abbl,0xb568538874cd4l,0x5a8034d7edc0cl,0x48c9c9472c1fbl,
wolfSSL 14:167253f4e170 9204 0x0f709373d52dcl },
wolfSSL 14:167253f4e170 9205 { 0x966bba8af30d6l,0x4af137b69c401l,0x361c47e95bf5fl,0x5b113966162a9l,
wolfSSL 14:167253f4e170 9206 0x0bd52d288e727l },
wolfSSL 14:167253f4e170 9207 0 },
wolfSSL 14:167253f4e170 9208 /* 72 */
wolfSSL 14:167253f4e170 9209 { { 0x55c7a9c5fa877l,0x727d3a3d48ab1l,0x3d189d817dad6l,0x77a643f43f9e7l,
wolfSSL 14:167253f4e170 9210 0x0a0d0f8e4c8aal },
wolfSSL 14:167253f4e170 9211 { 0xeafd8cc94f92dl,0xbe0c4ddb3a0bbl,0x82eba14d818c8l,0x6a0022cc65f8bl,
wolfSSL 14:167253f4e170 9212 0x0a56c78c7946dl },
wolfSSL 14:167253f4e170 9213 0 },
wolfSSL 14:167253f4e170 9214 /* 73 */
wolfSSL 14:167253f4e170 9215 { { 0x2391b0dd09529l,0xa63daddfcf296l,0xb5bf481803e0el,0x367a2c77351f5l,
wolfSSL 14:167253f4e170 9216 0x0d8befdf8731al },
wolfSSL 14:167253f4e170 9217 { 0x19d42fc0157f4l,0xd7fec8e650ab9l,0x2d48b0af51cael,0x6478cdf9cb400l,
wolfSSL 14:167253f4e170 9218 0x0854a68a5ce9fl },
wolfSSL 14:167253f4e170 9219 0 },
wolfSSL 14:167253f4e170 9220 /* 74 */
wolfSSL 14:167253f4e170 9221 { { 0x5f67b63506ea5l,0x89a4fe0d66dc3l,0xe95cd4d9286c4l,0x6a953f101d3bfl,
wolfSSL 14:167253f4e170 9222 0x05cacea0b9884l },
wolfSSL 14:167253f4e170 9223 { 0xdf60c9ceac44dl,0xf4354d1c3aa90l,0xd5dbabe3db29al,0xefa908dd3de8al,
wolfSSL 14:167253f4e170 9224 0x0e4982d1235e4l },
wolfSSL 14:167253f4e170 9225 0 },
wolfSSL 14:167253f4e170 9226 /* 75 */
wolfSSL 14:167253f4e170 9227 { { 0x04a22c34cd55el,0xb32680d132231l,0xfa1d94358695bl,0x0499fb345afa1l,
wolfSSL 14:167253f4e170 9228 0x08046b7f616b2l },
wolfSSL 14:167253f4e170 9229 { 0x3581e38e7d098l,0x8df46f0b70b53l,0x4cb78c4d7f61el,0xaf5530dea9ea4l,
wolfSSL 14:167253f4e170 9230 0x0eb17ca7b9082l },
wolfSSL 14:167253f4e170 9231 0 },
wolfSSL 14:167253f4e170 9232 /* 76 */
wolfSSL 14:167253f4e170 9233 { { 0x1b59876a145b9l,0x0fc1bc71ec175l,0x92715bba5cf6bl,0xe131d3e035653l,
wolfSSL 14:167253f4e170 9234 0x0097b00bafab5l },
wolfSSL 14:167253f4e170 9235 { 0x6c8e9565f69e1l,0x5ab5be5199aa6l,0xa4fd98477e8f7l,0xcc9e6033ba11dl,
wolfSSL 14:167253f4e170 9236 0x0f95c747bafdbl },
wolfSSL 14:167253f4e170 9237 0 },
wolfSSL 14:167253f4e170 9238 /* 77 */
wolfSSL 14:167253f4e170 9239 { { 0xf01d3bebae45el,0xf0c4bc6955558l,0xbc64fc6a8ebe9l,0xd837aeb705b1dl,
wolfSSL 14:167253f4e170 9240 0x03512601e566el },
wolfSSL 14:167253f4e170 9241 { 0x6f1e1fa1161cdl,0xd54c65ef87933l,0x24f21e5328ab8l,0xab6b4757eee27l,
wolfSSL 14:167253f4e170 9242 0x00ef971236068l },
wolfSSL 14:167253f4e170 9243 0 },
wolfSSL 14:167253f4e170 9244 /* 78 */
wolfSSL 14:167253f4e170 9245 { { 0x98cf754ca4226l,0x38f8642c8e025l,0x68e17905eede1l,0xbc9548963f744l,
wolfSSL 14:167253f4e170 9246 0x0fc16d9333b4fl },
wolfSSL 14:167253f4e170 9247 { 0x6fb31e7c800cal,0x312678adaabe9l,0xff3e8b5138063l,0x7a173d6244976l,
wolfSSL 14:167253f4e170 9248 0x014ca4af1b95dl },
wolfSSL 14:167253f4e170 9249 0 },
wolfSSL 14:167253f4e170 9250 /* 79 */
wolfSSL 14:167253f4e170 9251 { { 0x771babd2f81d5l,0x6901f7d1967a4l,0xad9c9071a5f9dl,0x231dd898bef7cl,
wolfSSL 14:167253f4e170 9252 0x04057b063f59cl },
wolfSSL 14:167253f4e170 9253 { 0xd82fe89c05c0al,0x6f1dc0df85bffl,0x35a16dbe4911cl,0x0b133befccaeal,
wolfSSL 14:167253f4e170 9254 0x01c3b5d64f133l },
wolfSSL 14:167253f4e170 9255 0 },
wolfSSL 14:167253f4e170 9256 /* 80 */
wolfSSL 14:167253f4e170 9257 { { 0x14bfe80ec21fel,0x6ac255be825fel,0xf4a5d67f6ce11l,0x63af98bc5a072l,
wolfSSL 14:167253f4e170 9258 0x0fad27148db7el },
wolfSSL 14:167253f4e170 9259 { 0x0b6ac29ab05b3l,0x3c4e251ae690cl,0x2aade7d37a9a8l,0x1a840a7dc875cl,
wolfSSL 14:167253f4e170 9260 0x077387de39f0el },
wolfSSL 14:167253f4e170 9261 0 },
wolfSSL 14:167253f4e170 9262 /* 81 */
wolfSSL 14:167253f4e170 9263 { { 0xecc49a56c0dd7l,0xd846086c741e9l,0x505aecea5cffcl,0xc47e8f7a1408fl,
wolfSSL 14:167253f4e170 9264 0x0b37b85c0bef0l },
wolfSSL 14:167253f4e170 9265 { 0x6b6e4cc0e6a8fl,0xbf6b388f23359l,0x39cef4efd6d4bl,0x28d5aba453facl,
wolfSSL 14:167253f4e170 9266 0x09c135ac8f9f6l },
wolfSSL 14:167253f4e170 9267 0 },
wolfSSL 14:167253f4e170 9268 /* 82 */
wolfSSL 14:167253f4e170 9269 { { 0xa320284e35743l,0xb185a3cdef32al,0xdf19819320d6al,0x851fb821b1761l,
wolfSSL 14:167253f4e170 9270 0x05721361fc433l },
wolfSSL 14:167253f4e170 9271 { 0xdb36a71fc9168l,0x735e5c403c1f0l,0x7bcd8f55f98bal,0x11bdf64ca87e3l,
wolfSSL 14:167253f4e170 9272 0x0dcbac3c9e6bbl },
wolfSSL 14:167253f4e170 9273 0 },
wolfSSL 14:167253f4e170 9274 /* 83 */
wolfSSL 14:167253f4e170 9275 { { 0xd99684518cbe2l,0x189c9eb04ef01l,0x47feebfd242fcl,0x6862727663c7el,
wolfSSL 14:167253f4e170 9276 0x0b8c1c89e2d62l },
wolfSSL 14:167253f4e170 9277 { 0x58bddc8e1d569l,0xc8b7d88cd051al,0x11f31eb563809l,0x22d426c27fd9fl,
wolfSSL 14:167253f4e170 9278 0x05d23bbda2f94l },
wolfSSL 14:167253f4e170 9279 0 },
wolfSSL 14:167253f4e170 9280 /* 84 */
wolfSSL 14:167253f4e170 9281 { { 0xc729495c8f8bel,0x803bf362bf0a1l,0xf63d4ac2961c4l,0xe9009e418403dl,
wolfSSL 14:167253f4e170 9282 0x0c109f9cb91ecl },
wolfSSL 14:167253f4e170 9283 { 0x095d058945705l,0x96ddeb85c0c2dl,0xa40449bb9083dl,0x1ee184692b8d7l,
wolfSSL 14:167253f4e170 9284 0x09bc3344f2eeel },
wolfSSL 14:167253f4e170 9285 0 },
wolfSSL 14:167253f4e170 9286 /* 85 */
wolfSSL 14:167253f4e170 9287 { { 0xae35642913074l,0x2748a542b10d5l,0x310732a55491bl,0x4cc1469ca665bl,
wolfSSL 14:167253f4e170 9288 0x029591d525f1al },
wolfSSL 14:167253f4e170 9289 { 0xf5b6bb84f983fl,0x419f5f84e1e76l,0x0baa189be7eefl,0x332c1200d4968l,
wolfSSL 14:167253f4e170 9290 0x06376551f18efl },
wolfSSL 14:167253f4e170 9291 0 },
wolfSSL 14:167253f4e170 9292 /* 86 */
wolfSSL 14:167253f4e170 9293 { { 0x5f14e562976ccl,0xe60ef12c38bdal,0xcca985222bca3l,0x987abbfa30646l,
wolfSSL 14:167253f4e170 9294 0x0bdb79dc808e2l },
wolfSSL 14:167253f4e170 9295 { 0xcb5c9cb06a772l,0xaafe536dcefd2l,0xc2b5db838f475l,0xc14ac2a3e0227l,
wolfSSL 14:167253f4e170 9296 0x08ee86001add3l },
wolfSSL 14:167253f4e170 9297 0 },
wolfSSL 14:167253f4e170 9298 /* 87 */
wolfSSL 14:167253f4e170 9299 { { 0x96981a4ade873l,0x4dc4fba48ccbel,0xa054ba57ee9aal,0xaa4b2cee28995l,
wolfSSL 14:167253f4e170 9300 0x092e51d7a6f77l },
wolfSSL 14:167253f4e170 9301 { 0xbafa87190a34dl,0x5bf6bd1ed1948l,0xcaf1144d698f7l,0xaaaad00ee6e30l,
wolfSSL 14:167253f4e170 9302 0x05182f86f0a56l },
wolfSSL 14:167253f4e170 9303 0 },
wolfSSL 14:167253f4e170 9304 /* 88 */
wolfSSL 14:167253f4e170 9305 { { 0x6212c7a4cc99cl,0x683e6d9ca1fbal,0xac98c5aff609bl,0xa6f25dbb27cb5l,
wolfSSL 14:167253f4e170 9306 0x091dcab5d4073l },
wolfSSL 14:167253f4e170 9307 { 0x6cc3d5f575a70l,0x396f8d87fa01bl,0x99817360cb361l,0x4f2b165d4e8c8l,
wolfSSL 14:167253f4e170 9308 0x017a0cedb9797l },
wolfSSL 14:167253f4e170 9309 0 },
wolfSSL 14:167253f4e170 9310 /* 89 */
wolfSSL 14:167253f4e170 9311 { { 0x61e2a076c8d3al,0x39210f924b388l,0x3a835d9701aadl,0xdf4194d0eae41l,
wolfSSL 14:167253f4e170 9312 0x02e8ce36c7f4cl },
wolfSSL 14:167253f4e170 9313 { 0x73dab037a862bl,0xb760e4c8fa912l,0x3baf2dd01ba9bl,0x68f3f96453883l,
wolfSSL 14:167253f4e170 9314 0x0f4ccc6cb34f6l },
wolfSSL 14:167253f4e170 9315 0 },
wolfSSL 14:167253f4e170 9316 /* 90 */
wolfSSL 14:167253f4e170 9317 { { 0xf525cf1f79687l,0x9592efa81544el,0x5c78d297c5954l,0xf3c9e1231741al,
wolfSSL 14:167253f4e170 9318 0x0ac0db4889a0dl },
wolfSSL 14:167253f4e170 9319 { 0xfc711df01747fl,0x58ef17df1386bl,0xccb6bb5592b93l,0x74a2e5880e4f5l,
wolfSSL 14:167253f4e170 9320 0x095a64a6194c9l },
wolfSSL 14:167253f4e170 9321 0 },
wolfSSL 14:167253f4e170 9322 /* 91 */
wolfSSL 14:167253f4e170 9323 { { 0x1efdac15a4c93l,0x738258514172cl,0x6cb0bad40269bl,0x06776a8dfb1c1l,
wolfSSL 14:167253f4e170 9324 0x0231e54ba2921l },
wolfSSL 14:167253f4e170 9325 { 0xdf9178ae6d2dcl,0x3f39112918a70l,0xe5b72234d6aa6l,0x31e1f627726b5l,
wolfSSL 14:167253f4e170 9326 0x0ab0be032d8a7l },
wolfSSL 14:167253f4e170 9327 0 },
wolfSSL 14:167253f4e170 9328 /* 92 */
wolfSSL 14:167253f4e170 9329 { { 0xad0e98d131f2dl,0xe33b04f101097l,0x5e9a748637f09l,0xa6791ac86196dl,
wolfSSL 14:167253f4e170 9330 0x0f1bcc8802cf6l },
wolfSSL 14:167253f4e170 9331 { 0x69140e8daacb4l,0x5560f6500925cl,0x77937a63c4e40l,0xb271591cc8fc4l,
wolfSSL 14:167253f4e170 9332 0x0851694695aebl },
wolfSSL 14:167253f4e170 9333 0 },
wolfSSL 14:167253f4e170 9334 /* 93 */
wolfSSL 14:167253f4e170 9335 { { 0x5c143f1dcf593l,0x29b018be3bde3l,0xbdd9d3d78202bl,0x55d8e9cdadc29l,
wolfSSL 14:167253f4e170 9336 0x08f67d9d2daadl },
wolfSSL 14:167253f4e170 9337 { 0x116567481ea5fl,0xe9e34c590c841l,0x5053fa8e7d2ddl,0x8b5dffdd43f40l,
wolfSSL 14:167253f4e170 9338 0x0f84572b9c072l },
wolfSSL 14:167253f4e170 9339 0 },
wolfSSL 14:167253f4e170 9340 /* 94 */
wolfSSL 14:167253f4e170 9341 { { 0xa7a7197af71c9l,0x447a7365655e1l,0xe1d5063a14494l,0x2c19a1b4ae070l,
wolfSSL 14:167253f4e170 9342 0x0edee2710616bl },
wolfSSL 14:167253f4e170 9343 { 0x034f511734121l,0x554a25e9f0b2fl,0x40c2ecf1cac6el,0xd7f48dc148f3al,
wolfSSL 14:167253f4e170 9344 0x09fd27e9b44ebl },
wolfSSL 14:167253f4e170 9345 0 },
wolfSSL 14:167253f4e170 9346 /* 95 */
wolfSSL 14:167253f4e170 9347 { { 0x7658af6e2cb16l,0x2cfe5919b63ccl,0x68d5583e3eb7dl,0xf3875a8c58161l,
wolfSSL 14:167253f4e170 9348 0x0a40c2fb6958fl },
wolfSSL 14:167253f4e170 9349 { 0xec560fedcc158l,0xc655f230568c9l,0xa307e127ad804l,0xdecfd93967049l,
wolfSSL 14:167253f4e170 9350 0x099bc9bb87dc6l },
wolfSSL 14:167253f4e170 9351 0 },
wolfSSL 14:167253f4e170 9352 /* 96 */
wolfSSL 14:167253f4e170 9353 { { 0x9521d927dafc6l,0x695c09cd1984al,0x9366dde52c1fbl,0x7e649d9581a0fl,
wolfSSL 14:167253f4e170 9354 0x09abe210ba16dl },
wolfSSL 14:167253f4e170 9355 { 0xaf84a48915220l,0x6a4dd816c6480l,0x681ca5afa7317l,0x44b0c7d539871l,
wolfSSL 14:167253f4e170 9356 0x07881c25787f3l },
wolfSSL 14:167253f4e170 9357 0 },
wolfSSL 14:167253f4e170 9358 /* 97 */
wolfSSL 14:167253f4e170 9359 { { 0x99b51e0bcf3ffl,0xc5127f74f6933l,0xd01d9680d02cbl,0x89408fb465a2dl,
wolfSSL 14:167253f4e170 9360 0x015e6e319a30el },
wolfSSL 14:167253f4e170 9361 { 0xd6e0d3e0e05f4l,0xdc43588404646l,0x4f850d3fad7bdl,0x72cebe61c7d1cl,
wolfSSL 14:167253f4e170 9362 0x00e55facf1911l },
wolfSSL 14:167253f4e170 9363 0 },
wolfSSL 14:167253f4e170 9364 /* 98 */
wolfSSL 14:167253f4e170 9365 { { 0xd9806f8787564l,0x2131e85ce67e9l,0x819e8d61a3317l,0x65776b0158cabl,
wolfSSL 14:167253f4e170 9366 0x0d73d09766fe9l },
wolfSSL 14:167253f4e170 9367 { 0x834251eb7206el,0x0fc618bb42424l,0xe30a520a51929l,0xa50b5dcbb8595l,
wolfSSL 14:167253f4e170 9368 0x09250a3748f15l },
wolfSSL 14:167253f4e170 9369 0 },
wolfSSL 14:167253f4e170 9370 /* 99 */
wolfSSL 14:167253f4e170 9371 { { 0xf08f8be577410l,0x035077a8c6cafl,0xc0a63a4fd408al,0x8c0bf1f63289el,
wolfSSL 14:167253f4e170 9372 0x077414082c1ccl },
wolfSSL 14:167253f4e170 9373 { 0x40fa6eb0991cdl,0x6649fdc29605al,0x324fd40c1ca08l,0x20b93a68a3c7bl,
wolfSSL 14:167253f4e170 9374 0x08cb04f4d12ebl },
wolfSSL 14:167253f4e170 9375 0 },
wolfSSL 14:167253f4e170 9376 /* 100 */
wolfSSL 14:167253f4e170 9377 { { 0x2d0556906171cl,0xcdb0240c3fb1cl,0x89068419073e9l,0x3b51db8e6b4fdl,
wolfSSL 14:167253f4e170 9378 0x0e4e429ef4712l },
wolfSSL 14:167253f4e170 9379 { 0xdd53c38ec36f4l,0x01ff4b6a270b8l,0x79a9a48f9d2dcl,0x65525d066e078l,
wolfSSL 14:167253f4e170 9380 0x037bca2ff3c6el },
wolfSSL 14:167253f4e170 9381 0 },
wolfSSL 14:167253f4e170 9382 /* 101 */
wolfSSL 14:167253f4e170 9383 { { 0x2e3c7df562470l,0xa2c0964ac94cdl,0x0c793be44f272l,0xb22a7c6d5df98l,
wolfSSL 14:167253f4e170 9384 0x059913edc3002l },
wolfSSL 14:167253f4e170 9385 { 0x39a835750592al,0x80e783de027a1l,0xa05d64f99e01dl,0xe226cf8c0375el,
wolfSSL 14:167253f4e170 9386 0x043786e4ab013l },
wolfSSL 14:167253f4e170 9387 0 },
wolfSSL 14:167253f4e170 9388 /* 102 */
wolfSSL 14:167253f4e170 9389 { { 0x2b0ed9e56b5a6l,0xa6d9fc68f9ff3l,0x97846a70750d9l,0x9e7aec15e8455l,
wolfSSL 14:167253f4e170 9390 0x08638ca98b7e7l },
wolfSSL 14:167253f4e170 9391 { 0xae0960afc24b2l,0xaf4dace8f22f5l,0xecba78f05398el,0xa6f03b765dd0al,
wolfSSL 14:167253f4e170 9392 0x01ecdd36a7b3al },
wolfSSL 14:167253f4e170 9393 0 },
wolfSSL 14:167253f4e170 9394 /* 103 */
wolfSSL 14:167253f4e170 9395 { { 0xacd626c5ff2f3l,0xc02873a9785d3l,0x2110d54a2d516l,0xf32dad94c9fadl,
wolfSSL 14:167253f4e170 9396 0x0d85d0f85d459l },
wolfSSL 14:167253f4e170 9397 { 0x00b8d10b11da3l,0x30a78318c49f7l,0x208decdd2c22cl,0x3c62556988f49l,
wolfSSL 14:167253f4e170 9398 0x0a04f19c3b4edl },
wolfSSL 14:167253f4e170 9399 0 },
wolfSSL 14:167253f4e170 9400 /* 104 */
wolfSSL 14:167253f4e170 9401 { { 0x924c8ed7f93bdl,0x5d392f51f6087l,0x21b71afcb64acl,0x50b07cae330a8l,
wolfSSL 14:167253f4e170 9402 0x092b2eeea5c09l },
wolfSSL 14:167253f4e170 9403 { 0xc4c9485b6e235l,0xa92936c0f085al,0x0508891ab2ca4l,0x276c80faa6b3el,
wolfSSL 14:167253f4e170 9404 0x01ee782215834l },
wolfSSL 14:167253f4e170 9405 0 },
wolfSSL 14:167253f4e170 9406 /* 105 */
wolfSSL 14:167253f4e170 9407 { { 0xa2e00e63e79f7l,0xb2f399d906a60l,0x607c09df590e7l,0xe1509021054a6l,
wolfSSL 14:167253f4e170 9408 0x0f3f2ced857a6l },
wolfSSL 14:167253f4e170 9409 { 0x510f3f10d9b55l,0xacd8642648200l,0x8bd0e7c9d2fcfl,0xe210e5631aa7el,
wolfSSL 14:167253f4e170 9410 0x00f56a4543da3l },
wolfSSL 14:167253f4e170 9411 0 },
wolfSSL 14:167253f4e170 9412 /* 106 */
wolfSSL 14:167253f4e170 9413 { { 0x1bffa1043e0dfl,0xcc9c007e6d5b2l,0x4a8517a6c74b6l,0xe2631a656ec0dl,
wolfSSL 14:167253f4e170 9414 0x0bd8f17411969l },
wolfSSL 14:167253f4e170 9415 { 0xbbb86beb7494al,0x6f45f3b8388a9l,0x4e5a79a1567d4l,0xfa09df7a12a7al,
wolfSSL 14:167253f4e170 9416 0x02d1a1c3530ccl },
wolfSSL 14:167253f4e170 9417 0 },
wolfSSL 14:167253f4e170 9418 /* 107 */
wolfSSL 14:167253f4e170 9419 { { 0xe3813506508dal,0xc4a1d795a7192l,0xa9944b3336180l,0xba46cddb59497l,
wolfSSL 14:167253f4e170 9420 0x0a107a65eb91fl },
wolfSSL 14:167253f4e170 9421 { 0x1d1c50f94d639l,0x758a58b7d7e6dl,0xd37ca1c8b4af3l,0x9af21a7c5584bl,
wolfSSL 14:167253f4e170 9422 0x0183d760af87al },
wolfSSL 14:167253f4e170 9423 0 },
wolfSSL 14:167253f4e170 9424 /* 108 */
wolfSSL 14:167253f4e170 9425 { { 0x697110dde59a4l,0x070e8bef8729dl,0xf2ebe78f1ad8dl,0xd754229b49634l,
wolfSSL 14:167253f4e170 9426 0x01d44179dc269l },
wolfSSL 14:167253f4e170 9427 { 0xdc0cf8390d30el,0x530de8110cb32l,0xbc0339a0a3b27l,0xd26231af1dc52l,
wolfSSL 14:167253f4e170 9428 0x0771f9cc29606l },
wolfSSL 14:167253f4e170 9429 0 },
wolfSSL 14:167253f4e170 9430 /* 109 */
wolfSSL 14:167253f4e170 9431 { { 0x93e7785040739l,0xb98026a939999l,0x5f8fc2644539dl,0x718ecf40f6f2fl,
wolfSSL 14:167253f4e170 9432 0x064427a310362l },
wolfSSL 14:167253f4e170 9433 { 0xf2d8785428aa8l,0x3febfb49a84f4l,0x23d01ac7b7adcl,0x0d6d201b2c6dfl,
wolfSSL 14:167253f4e170 9434 0x049d9b7496ae9l },
wolfSSL 14:167253f4e170 9435 0 },
wolfSSL 14:167253f4e170 9436 /* 110 */
wolfSSL 14:167253f4e170 9437 { { 0x8d8bc435d1099l,0x4e8e8d1a08cc7l,0xcb68a412adbcdl,0x544502c2e2a02l,
wolfSSL 14:167253f4e170 9438 0x09037d81b3f60l },
wolfSSL 14:167253f4e170 9439 { 0xbac27074c7b61l,0xab57bfd72e7cdl,0x96d5352fe2031l,0x639c61ccec965l,
wolfSSL 14:167253f4e170 9440 0x008c3de6a7cc0l },
wolfSSL 14:167253f4e170 9441 0 },
wolfSSL 14:167253f4e170 9442 /* 111 */
wolfSSL 14:167253f4e170 9443 { { 0xdd020f6d552abl,0x9805cd81f120fl,0x135129156baffl,0x6b2f06fb7c3e9l,
wolfSSL 14:167253f4e170 9444 0x0c69094424579l },
wolfSSL 14:167253f4e170 9445 { 0x3ae9c41231bd1l,0x875cc5820517bl,0x9d6a1221eac6el,0x3ac0208837abfl,
wolfSSL 14:167253f4e170 9446 0x03fa3db02cafel },
wolfSSL 14:167253f4e170 9447 0 },
wolfSSL 14:167253f4e170 9448 /* 112 */
wolfSSL 14:167253f4e170 9449 { { 0xa3e6505058880l,0xef643943f2d75l,0xab249257da365l,0x08ff4147861cfl,
wolfSSL 14:167253f4e170 9450 0x0c5c4bdb0fdb8l },
wolfSSL 14:167253f4e170 9451 { 0x13e34b272b56bl,0x9511b9043a735l,0x8844969c8327el,0xb6b5fd8ce37dfl,
wolfSSL 14:167253f4e170 9452 0x02d56db9446c2l },
wolfSSL 14:167253f4e170 9453 0 },
wolfSSL 14:167253f4e170 9454 /* 113 */
wolfSSL 14:167253f4e170 9455 { { 0x1782fff46ac6bl,0x2607a2e425246l,0x9a48de1d19f79l,0xba42fafea3c40l,
wolfSSL 14:167253f4e170 9456 0x00f56bd9de503l },
wolfSSL 14:167253f4e170 9457 { 0xd4ed1345cda49l,0xfc816f299d137l,0xeb43402821158l,0xb5f1e7c6a54aal,
wolfSSL 14:167253f4e170 9458 0x04003bb9d1173l },
wolfSSL 14:167253f4e170 9459 0 },
wolfSSL 14:167253f4e170 9460 /* 114 */
wolfSSL 14:167253f4e170 9461 { { 0xe8189a0803387l,0xf539cbd4043b8l,0x2877f21ece115l,0x2f9e4297208ddl,
wolfSSL 14:167253f4e170 9462 0x053765522a07fl },
wolfSSL 14:167253f4e170 9463 { 0x80a21a8a4182dl,0x7a3219df79a49l,0xa19a2d4a2bbd0l,0x4549674d0a2e1l,
wolfSSL 14:167253f4e170 9464 0x07a056f586c5dl },
wolfSSL 14:167253f4e170 9465 0 },
wolfSSL 14:167253f4e170 9466 /* 115 */
wolfSSL 14:167253f4e170 9467 { { 0xb25589d8a2a47l,0x48c3df2773646l,0xbf0d5395b5829l,0x267551ec000eal,
wolfSSL 14:167253f4e170 9468 0x077d482f17a1al },
wolfSSL 14:167253f4e170 9469 { 0x1bd9587853948l,0xbd6cfbffeeb8al,0x0681e47a6f817l,0xb0e4ab6ec0578l,
wolfSSL 14:167253f4e170 9470 0x04115012b2b38l },
wolfSSL 14:167253f4e170 9471 0 },
wolfSSL 14:167253f4e170 9472 /* 116 */
wolfSSL 14:167253f4e170 9473 { { 0x3f0f46de28cedl,0x609b13ec473c7l,0xe5c63921d5da7l,0x094661b8ce9e6l,
wolfSSL 14:167253f4e170 9474 0x0cdf04572fbeal },
wolfSSL 14:167253f4e170 9475 { 0x3c58b6c53c3b0l,0x10447b843c1cbl,0xcb9780e97fe3cl,0x3109fb2b8ae12l,
wolfSSL 14:167253f4e170 9476 0x0ee703dda9738l },
wolfSSL 14:167253f4e170 9477 0 },
wolfSSL 14:167253f4e170 9478 /* 117 */
wolfSSL 14:167253f4e170 9479 { { 0x15140ff57e43al,0xd3b1b811b8345l,0xf42b986d44660l,0xce212b3b5dff8l,
wolfSSL 14:167253f4e170 9480 0x02a0ad89da162l },
wolfSSL 14:167253f4e170 9481 { 0x4a6946bc277bal,0x54c141c27664el,0xabf6274c788c9l,0x4659141aa64ccl,
wolfSSL 14:167253f4e170 9482 0x0d62d0b67ac2bl },
wolfSSL 14:167253f4e170 9483 0 },
wolfSSL 14:167253f4e170 9484 /* 118 */
wolfSSL 14:167253f4e170 9485 { { 0x5d87b2c054ac4l,0x59f27df78839cl,0x18128d6570058l,0x2426edf7cbf3bl,
wolfSSL 14:167253f4e170 9486 0x0b39a23f2991cl },
wolfSSL 14:167253f4e170 9487 { 0x84a15f0b16ae5l,0xb1a136f51b952l,0x27007830c6a05l,0x4cc51d63c137fl,
wolfSSL 14:167253f4e170 9488 0x004ed0092c067l },
wolfSSL 14:167253f4e170 9489 0 },
wolfSSL 14:167253f4e170 9490 /* 119 */
wolfSSL 14:167253f4e170 9491 { { 0x185d19ae90393l,0x294a3d64e61f4l,0x854fc143047b4l,0xc387ae0001a69l,
wolfSSL 14:167253f4e170 9492 0x0a0a91fc10177l },
wolfSSL 14:167253f4e170 9493 { 0xa3f01ae2c831el,0x822b727e16ff0l,0xa3075b4bb76ael,0x0c418f12c8a15l,
wolfSSL 14:167253f4e170 9494 0x0084cf9889ed2l },
wolfSSL 14:167253f4e170 9495 0 },
wolfSSL 14:167253f4e170 9496 /* 120 */
wolfSSL 14:167253f4e170 9497 { { 0x509defca6becfl,0x807dffb328d98l,0x778e8b92fceael,0xf77e5d8a15c44l,
wolfSSL 14:167253f4e170 9498 0x0d57955b273abl },
wolfSSL 14:167253f4e170 9499 { 0xda79e31b5d4f1l,0x4b3cfa7a1c210l,0xc27c20baa52f0l,0x41f1d4d12089dl,
wolfSSL 14:167253f4e170 9500 0x08e14ea4202d1l },
wolfSSL 14:167253f4e170 9501 0 },
wolfSSL 14:167253f4e170 9502 /* 121 */
wolfSSL 14:167253f4e170 9503 { { 0x50345f2897042l,0x1f43402c4aeedl,0x8bdfb218d0533l,0xd158c8d9c194cl,
wolfSSL 14:167253f4e170 9504 0x0597e1a372aa4l },
wolfSSL 14:167253f4e170 9505 { 0x7ec1acf0bd68cl,0xdcab024945032l,0x9fe3e846d4be0l,0x4dea5b9c8d7acl,
wolfSSL 14:167253f4e170 9506 0x0ca3f0236199bl },
wolfSSL 14:167253f4e170 9507 0 },
wolfSSL 14:167253f4e170 9508 /* 122 */
wolfSSL 14:167253f4e170 9509 { { 0xa10b56170bd20l,0xf16d3f5de7592l,0x4b2ade20ea897l,0x07e4a3363ff14l,
wolfSSL 14:167253f4e170 9510 0x0bde7fd7e309cl },
wolfSSL 14:167253f4e170 9511 { 0xbb6d2b8f5432cl,0xcbe043444b516l,0x8f95b5a210dc1l,0xd1983db01e6ffl,
wolfSSL 14:167253f4e170 9512 0x0b623ad0e0a7dl },
wolfSSL 14:167253f4e170 9513 0 },
wolfSSL 14:167253f4e170 9514 /* 123 */
wolfSSL 14:167253f4e170 9515 { { 0xbd67560c7b65bl,0x9023a4a289a75l,0x7b26795ab8c55l,0x137bf8220fd0dl,
wolfSSL 14:167253f4e170 9516 0x0d6aa2e4658ecl },
wolfSSL 14:167253f4e170 9517 { 0xbc00b5138bb85l,0x21d833a95c10al,0x702a32e8c31d1l,0x513ab24ff00b1l,
wolfSSL 14:167253f4e170 9518 0x0111662e02dccl },
wolfSSL 14:167253f4e170 9519 0 },
wolfSSL 14:167253f4e170 9520 /* 124 */
wolfSSL 14:167253f4e170 9521 { { 0x14015efb42b87l,0x701b6c4dff781l,0x7d7c129bd9f5dl,0x50f866ecccd7al,
wolfSSL 14:167253f4e170 9522 0x0db3ee1cb94b7l },
wolfSSL 14:167253f4e170 9523 { 0xf3db0f34837cfl,0x8bb9578d4fb26l,0xc56657de7eed1l,0x6a595d2cdf937l,
wolfSSL 14:167253f4e170 9524 0x0886a64425220l },
wolfSSL 14:167253f4e170 9525 0 },
wolfSSL 14:167253f4e170 9526 /* 125 */
wolfSSL 14:167253f4e170 9527 { { 0x34cfb65b569eal,0x41f72119c13c2l,0x15a619e200111l,0x17bc8badc85dal,
wolfSSL 14:167253f4e170 9528 0x0a70cf4eb018al },
wolfSSL 14:167253f4e170 9529 { 0xf97ae8c4a6a65l,0x270134378f224l,0xf7e096036e5cfl,0x7b77be3a609e4l,
wolfSSL 14:167253f4e170 9530 0x0aa4772abd174l },
wolfSSL 14:167253f4e170 9531 0 },
wolfSSL 14:167253f4e170 9532 /* 126 */
wolfSSL 14:167253f4e170 9533 { { 0x761317aa60cc0l,0x610368115f676l,0xbc1bb5ac79163l,0xf974ded98bb4bl,
wolfSSL 14:167253f4e170 9534 0x0611a6ddc30fal },
wolfSSL 14:167253f4e170 9535 { 0x78cbcc15ee47al,0x824e0d96a530el,0xdd9ed882e8962l,0x9c8836f35adf3l,
wolfSSL 14:167253f4e170 9536 0x05cfffaf81642l },
wolfSSL 14:167253f4e170 9537 0 },
wolfSSL 14:167253f4e170 9538 /* 127 */
wolfSSL 14:167253f4e170 9539 { { 0x54cff9b7a99cdl,0x9d843c45a1c0dl,0x2c739e17bf3b9l,0x994c038a908f6l,
wolfSSL 14:167253f4e170 9540 0x06e5a6b237dc1l },
wolfSSL 14:167253f4e170 9541 { 0xb454e0ba5db77l,0x7facf60d63ef8l,0x6608378b7b880l,0xabcce591c0c67l,
wolfSSL 14:167253f4e170 9542 0x0481a238d242dl },
wolfSSL 14:167253f4e170 9543 0 },
wolfSSL 14:167253f4e170 9544 /* 128 */
wolfSSL 14:167253f4e170 9545 { { 0x17bc035d0b34al,0x6b8327c0a7e34l,0xc0362d1440b38l,0xf9438fb7262dal,
wolfSSL 14:167253f4e170 9546 0x02c41114ce0cdl },
wolfSSL 14:167253f4e170 9547 { 0x5cef1ad95a0b1l,0xa867d543622bal,0x1e486c9c09b37l,0x929726d6cdd20l,
wolfSSL 14:167253f4e170 9548 0x020477abf42ffl },
wolfSSL 14:167253f4e170 9549 0 },
wolfSSL 14:167253f4e170 9550 /* 129 */
wolfSSL 14:167253f4e170 9551 { { 0x5173c18d65dbfl,0x0e339edad82f7l,0xcf1001c77bf94l,0x96b67022d26bdl,
wolfSSL 14:167253f4e170 9552 0x0ac66409ac773l },
wolfSSL 14:167253f4e170 9553 { 0xbb36fc6261cc3l,0xc9190e7e908b0l,0x45e6c10213f7bl,0x2f856541cebaal,
wolfSSL 14:167253f4e170 9554 0x0ce8e6975cc12l },
wolfSSL 14:167253f4e170 9555 0 },
wolfSSL 14:167253f4e170 9556 /* 130 */
wolfSSL 14:167253f4e170 9557 { { 0x21b41bc0a67d2l,0x0a444d248a0f1l,0x59b473762d476l,0xb4a80e044f1d6l,
wolfSSL 14:167253f4e170 9558 0x008fde365250bl },
wolfSSL 14:167253f4e170 9559 { 0xec3da848bf287l,0x82d3369d6eacel,0x2449482c2a621l,0x6cd73582dfdc9l,
wolfSSL 14:167253f4e170 9560 0x02f7e2fd2565dl },
wolfSSL 14:167253f4e170 9561 0 },
wolfSSL 14:167253f4e170 9562 /* 131 */
wolfSSL 14:167253f4e170 9563 { { 0xb92dbc3770fa7l,0x5c379043f9ae4l,0x7761171095e8dl,0x02ae54f34e9d1l,
wolfSSL 14:167253f4e170 9564 0x0c65be92e9077l },
wolfSSL 14:167253f4e170 9565 { 0x8a303f6fd0a40l,0xe3bcce784b275l,0xf9767bfe7d822l,0x3b3a7ae4f5854l,
wolfSSL 14:167253f4e170 9566 0x04bff8e47d119l },
wolfSSL 14:167253f4e170 9567 0 },
wolfSSL 14:167253f4e170 9568 /* 132 */
wolfSSL 14:167253f4e170 9569 { { 0x1d21f00ff1480l,0x7d0754db16cd4l,0xbe0f3ea2ab8fbl,0x967dac81d2efbl,
wolfSSL 14:167253f4e170 9570 0x03e4e4ae65772l },
wolfSSL 14:167253f4e170 9571 { 0x8f36d3c5303e6l,0x4b922623977e1l,0x324c3c03bd999l,0x60289ed70e261l,
wolfSSL 14:167253f4e170 9572 0x05388aefd58ecl },
wolfSSL 14:167253f4e170 9573 0 },
wolfSSL 14:167253f4e170 9574 /* 133 */
wolfSSL 14:167253f4e170 9575 { { 0x317eb5e5d7713l,0xee75de49daad1l,0x74fb26109b985l,0xbe0e32f5bc4fcl,
wolfSSL 14:167253f4e170 9576 0x05cf908d14f75l },
wolfSSL 14:167253f4e170 9577 { 0x435108e657b12l,0xa5b96ed9e6760l,0x970ccc2bfd421l,0x0ce20e29f51f8l,
wolfSSL 14:167253f4e170 9578 0x0a698ba4060f0l },
wolfSSL 14:167253f4e170 9579 0 },
wolfSSL 14:167253f4e170 9580 /* 134 */
wolfSSL 14:167253f4e170 9581 { { 0xb1686ef748fecl,0xa27e9d2cf973dl,0xe265effe6e755l,0xad8d630b6544cl,
wolfSSL 14:167253f4e170 9582 0x0b142ef8a7aebl },
wolfSSL 14:167253f4e170 9583 { 0x1af9f17d5770al,0x672cb3412fad3l,0xf3359de66af3bl,0x50756bd60d1bdl,
wolfSSL 14:167253f4e170 9584 0x0d1896a965851l },
wolfSSL 14:167253f4e170 9585 0 },
wolfSSL 14:167253f4e170 9586 /* 135 */
wolfSSL 14:167253f4e170 9587 { { 0x957ab33c41c08l,0xac5468e2e1ec5l,0xc472f6c87de94l,0xda3918816b73al,
wolfSSL 14:167253f4e170 9588 0x0267b0e0b7981l },
wolfSSL 14:167253f4e170 9589 { 0x54e5d8e62b988l,0x55116d21e76e5l,0xd2a6f99d8ddc7l,0x93934610faf03l,
wolfSSL 14:167253f4e170 9590 0x0b54e287aa111l },
wolfSSL 14:167253f4e170 9591 0 },
wolfSSL 14:167253f4e170 9592 /* 136 */
wolfSSL 14:167253f4e170 9593 { { 0x122b5178a876bl,0xff085104b40a0l,0x4f29f7651ff96l,0xd4e6050b31ab1l,
wolfSSL 14:167253f4e170 9594 0x084abb28b5f87l },
wolfSSL 14:167253f4e170 9595 { 0xd439f8270790al,0x9d85e3f46bd5el,0xc1e22122d6cb5l,0x564075f55c1b6l,
wolfSSL 14:167253f4e170 9596 0x0e5436f671765l },
wolfSSL 14:167253f4e170 9597 0 },
wolfSSL 14:167253f4e170 9598 /* 137 */
wolfSSL 14:167253f4e170 9599 { { 0x9025e2286e8d5l,0xb4864453be53fl,0x408e3a0353c95l,0xe99ed832f5bdel,
wolfSSL 14:167253f4e170 9600 0x00404f68b5b9cl },
wolfSSL 14:167253f4e170 9601 { 0x33bdea781e8e5l,0x18163c2f5bcadl,0x119caa33cdf50l,0xc701575769600l,
wolfSSL 14:167253f4e170 9602 0x03a4263df0ac1l },
wolfSSL 14:167253f4e170 9603 0 },
wolfSSL 14:167253f4e170 9604 /* 138 */
wolfSSL 14:167253f4e170 9605 { { 0x65ecc9aeb596dl,0xe7023c92b4c29l,0xe01396101ea03l,0xa3674704b4b62l,
wolfSSL 14:167253f4e170 9606 0x00ca8fd3f905el },
wolfSSL 14:167253f4e170 9607 { 0x23a42551b2b61l,0x9c390fcd06925l,0x392a63e1eb7a8l,0x0c33e7f1d2be0l,
wolfSSL 14:167253f4e170 9608 0x096dca2644ddbl },
wolfSSL 14:167253f4e170 9609 0 },
wolfSSL 14:167253f4e170 9610 /* 139 */
wolfSSL 14:167253f4e170 9611 { { 0xbb43a387510afl,0xa8a9a36a01203l,0xf950378846feal,0x59dcd23a57702l,
wolfSSL 14:167253f4e170 9612 0x04363e2123aadl },
wolfSSL 14:167253f4e170 9613 { 0x3a1c740246a47l,0xd2e55dd24dca4l,0xd8faf96b362b8l,0x98c4f9b086045l,
wolfSSL 14:167253f4e170 9614 0x0840e115cd8bbl },
wolfSSL 14:167253f4e170 9615 0 },
wolfSSL 14:167253f4e170 9616 /* 140 */
wolfSSL 14:167253f4e170 9617 { { 0x205e21023e8a7l,0xcdd8dc7a0bf12l,0x63a5ddfc808a8l,0xd6d4e292a2721l,
wolfSSL 14:167253f4e170 9618 0x05e0d6abd30del },
wolfSSL 14:167253f4e170 9619 { 0x721c27cfc0f64l,0x1d0e55ed8807al,0xd1f9db242eec0l,0xa25a26a7bef91l,
wolfSSL 14:167253f4e170 9620 0x07dea48f42945l },
wolfSSL 14:167253f4e170 9621 0 },
wolfSSL 14:167253f4e170 9622 /* 141 */
wolfSSL 14:167253f4e170 9623 { { 0xf6f1ce5060a81l,0x72f8f95615abdl,0x6ac268be79f9cl,0x16d1cfd36c540l,
wolfSSL 14:167253f4e170 9624 0x0abc2a2beebfdl },
wolfSSL 14:167253f4e170 9625 { 0x66f91d3e2eac7l,0x63d2dd04668acl,0x282d31b6f10bal,0xefc16790e3770l,
wolfSSL 14:167253f4e170 9626 0x04ea353946c7el },
wolfSSL 14:167253f4e170 9627 0 },
wolfSSL 14:167253f4e170 9628 /* 142 */
wolfSSL 14:167253f4e170 9629 { { 0xa2f8d5266309dl,0xc081945a3eed8l,0x78c5dc10a51c6l,0xffc3cecaf45a5l,
wolfSSL 14:167253f4e170 9630 0x03a76e6891c94l },
wolfSSL 14:167253f4e170 9631 { 0xce8a47d7b0d0fl,0x968f584a5f9aal,0xe697fbe963acel,0x646451a30c724l,
wolfSSL 14:167253f4e170 9632 0x08212a10a465el },
wolfSSL 14:167253f4e170 9633 0 },
wolfSSL 14:167253f4e170 9634 /* 143 */
wolfSSL 14:167253f4e170 9635 { { 0xc61c3cfab8caal,0x840e142390ef7l,0xe9733ca18eb8el,0xb164cd1dff677l,
wolfSSL 14:167253f4e170 9636 0x0aa7cab71599cl },
wolfSSL 14:167253f4e170 9637 { 0xc9273bc837bd1l,0xd0c36af5d702fl,0x423da49c06407l,0x17c317621292fl,
wolfSSL 14:167253f4e170 9638 0x040e38073fe06l },
wolfSSL 14:167253f4e170 9639 0 },
wolfSSL 14:167253f4e170 9640 /* 144 */
wolfSSL 14:167253f4e170 9641 { { 0x80824a7bf9b7cl,0x203fbe30d0f4fl,0x7cf9ce3365d23l,0x5526bfbe53209l,
wolfSSL 14:167253f4e170 9642 0x0e3604700b305l },
wolfSSL 14:167253f4e170 9643 { 0xb99116cc6c2c7l,0x08ba4cbee64dcl,0x37ad9ec726837l,0xe15fdcded4346l,
wolfSSL 14:167253f4e170 9644 0x06542d677a3del },
wolfSSL 14:167253f4e170 9645 0 },
wolfSSL 14:167253f4e170 9646 /* 145 */
wolfSSL 14:167253f4e170 9647 { { 0x2b6d07b6c377al,0x47903448be3f3l,0x0da8af76cb038l,0x6f21d6fdd3a82l,
wolfSSL 14:167253f4e170 9648 0x0a6534aee09bbl },
wolfSSL 14:167253f4e170 9649 { 0x1780d1035facfl,0x339dcb47e630al,0x447f39335e55al,0xef226ea50fe1cl,
wolfSSL 14:167253f4e170 9650 0x0f3cb672fdc9al },
wolfSSL 14:167253f4e170 9651 0 },
wolfSSL 14:167253f4e170 9652 /* 146 */
wolfSSL 14:167253f4e170 9653 { { 0x719fe3b55fd83l,0x6c875ddd10eb3l,0x5cea784e0d7a4l,0x70e733ac9fa90l,
wolfSSL 14:167253f4e170 9654 0x07cafaa2eaae8l },
wolfSSL 14:167253f4e170 9655 { 0x14d041d53b338l,0xa0ef87e6c69b8l,0x1672b0fe0acc0l,0x522efb93d1081l,
wolfSSL 14:167253f4e170 9656 0x00aab13c1b9bdl },
wolfSSL 14:167253f4e170 9657 0 },
wolfSSL 14:167253f4e170 9658 /* 147 */
wolfSSL 14:167253f4e170 9659 { { 0xce278d2681297l,0xb1b509546addcl,0x661aaf2cb350el,0x12e92dc431737l,
wolfSSL 14:167253f4e170 9660 0x04b91a6028470l },
wolfSSL 14:167253f4e170 9661 { 0xf109572f8ddcfl,0x1e9a911af4dcfl,0x372430e08ebf6l,0x1cab48f4360acl,
wolfSSL 14:167253f4e170 9662 0x049534c537232l },
wolfSSL 14:167253f4e170 9663 0 },
wolfSSL 14:167253f4e170 9664 /* 148 */
wolfSSL 14:167253f4e170 9665 { { 0xf7d71f07b7e9dl,0xa313cd516f83dl,0xc047ee3a478efl,0xc5ee78ef264b6l,
wolfSSL 14:167253f4e170 9666 0x0caf46c4fd65al },
wolfSSL 14:167253f4e170 9667 { 0xd0c7792aa8266l,0x66913684bba04l,0xe4b16b0edf454l,0x770f56e65168al,
wolfSSL 14:167253f4e170 9668 0x014ce9e5704c6l },
wolfSSL 14:167253f4e170 9669 0 },
wolfSSL 14:167253f4e170 9670 /* 149 */
wolfSSL 14:167253f4e170 9671 { { 0x45e3e965e8f91l,0xbacb0f2492994l,0x0c8a0a0d3aca1l,0x9a71d31cc70f9l,
wolfSSL 14:167253f4e170 9672 0x01bb708a53e4cl },
wolfSSL 14:167253f4e170 9673 { 0xa9e69558bdd7al,0x08018a26b1d5cl,0xc9cf1ec734a05l,0x0102b093aa714l,
wolfSSL 14:167253f4e170 9674 0x0f9d126f2da30l },
wolfSSL 14:167253f4e170 9675 0 },
wolfSSL 14:167253f4e170 9676 /* 150 */
wolfSSL 14:167253f4e170 9677 { { 0xbca7aaff9563el,0xfeb49914a0749l,0xf5f1671dd077al,0xcc69e27a0311bl,
wolfSSL 14:167253f4e170 9678 0x0807afcb9729el },
wolfSSL 14:167253f4e170 9679 { 0xa9337c9b08b77l,0x85443c7e387f8l,0x76fd8ba86c3a7l,0xcd8c85fafa594l,
wolfSSL 14:167253f4e170 9680 0x0751adcd16568l },
wolfSSL 14:167253f4e170 9681 0 },
wolfSSL 14:167253f4e170 9682 /* 151 */
wolfSSL 14:167253f4e170 9683 { { 0xa38b410715c0dl,0x718f7697f78ael,0x3fbf06dd113eal,0x743f665eab149l,
wolfSSL 14:167253f4e170 9684 0x029ec44682537l },
wolfSSL 14:167253f4e170 9685 { 0x4719cb50bebbcl,0xbfe45054223d9l,0xd2dedb1399ee5l,0x077d90cd5b3a8l,
wolfSSL 14:167253f4e170 9686 0x0ff9370e392a4l },
wolfSSL 14:167253f4e170 9687 0 },
wolfSSL 14:167253f4e170 9688 /* 152 */
wolfSSL 14:167253f4e170 9689 { { 0x2d69bc6b75b65l,0xd5266651c559al,0xde9d7d24188f8l,0xd01a28a9f33e3l,
wolfSSL 14:167253f4e170 9690 0x09776478ba2a9l },
wolfSSL 14:167253f4e170 9691 { 0x2622d929af2c7l,0x6d4e690923885l,0x89a51e9334f5dl,0x82face6cc7e5al,
wolfSSL 14:167253f4e170 9692 0x074a6313fac2fl },
wolfSSL 14:167253f4e170 9693 0 },
wolfSSL 14:167253f4e170 9694 /* 153 */
wolfSSL 14:167253f4e170 9695 { { 0x4dfddb75f079cl,0x9518e36fbbb2fl,0x7cd36dd85b07cl,0x863d1b6cfcf0el,
wolfSSL 14:167253f4e170 9696 0x0ab75be150ff4l },
wolfSSL 14:167253f4e170 9697 { 0x367c0173fc9b7l,0x20d2594fd081bl,0x4091236b90a74l,0x59f615fdbf03cl,
wolfSSL 14:167253f4e170 9698 0x04ebeac2e0b44l },
wolfSSL 14:167253f4e170 9699 0 },
wolfSSL 14:167253f4e170 9700 /* 154 */
wolfSSL 14:167253f4e170 9701 { { 0xc5fe75c9f2c53l,0x118eae9411eb6l,0x95ac5d8d25220l,0xaffcc8887633fl,
wolfSSL 14:167253f4e170 9702 0x0df99887b2c1bl },
wolfSSL 14:167253f4e170 9703 { 0x8eed2850aaecbl,0x1b01d6a272bb7l,0x1cdbcac9d4918l,0x4058978dd511bl,
wolfSSL 14:167253f4e170 9704 0x027b040a7779fl },
wolfSSL 14:167253f4e170 9705 0 },
wolfSSL 14:167253f4e170 9706 /* 155 */
wolfSSL 14:167253f4e170 9707 { { 0x05db7f73b2eb2l,0x088e1b2118904l,0x962327ee0df85l,0xa3f5501b71525l,
wolfSSL 14:167253f4e170 9708 0x0b393dd37e4cfl },
wolfSSL 14:167253f4e170 9709 { 0x30e7b3fd75165l,0xc2bcd33554a12l,0xf7b5022d66344l,0x34196c36f1be0l,
wolfSSL 14:167253f4e170 9710 0x009588c12d046l },
wolfSSL 14:167253f4e170 9711 0 },
wolfSSL 14:167253f4e170 9712 /* 156 */
wolfSSL 14:167253f4e170 9713 { { 0x6093f02601c3bl,0xf8cf5c335fe08l,0x94aff28fb0252l,0x648b955cf2808l,
wolfSSL 14:167253f4e170 9714 0x081c879a9db9fl },
wolfSSL 14:167253f4e170 9715 { 0xe687cc6f56c51l,0x693f17618c040l,0x059353bfed471l,0x1bc444f88a419l,
wolfSSL 14:167253f4e170 9716 0x0fa0d48f55fc1l },
wolfSSL 14:167253f4e170 9717 0 },
wolfSSL 14:167253f4e170 9718 /* 157 */
wolfSSL 14:167253f4e170 9719 { { 0xe1c9de1608e4dl,0x113582822cbc6l,0x57ec2d7010ddal,0x67d6f6b7ddc11l,
wolfSSL 14:167253f4e170 9720 0x08ea0e156b6a3l },
wolfSSL 14:167253f4e170 9721 { 0x4e02f2383b3b4l,0x943f01f53ca35l,0xde03ca569966bl,0xb5ac4ff6632b2l,
wolfSSL 14:167253f4e170 9722 0x03f5ab924fa00l },
wolfSSL 14:167253f4e170 9723 0 },
wolfSSL 14:167253f4e170 9724 /* 158 */
wolfSSL 14:167253f4e170 9725 { { 0xbb0d959739efbl,0xf4e7ebec0d337l,0x11a67d1c751b0l,0x256e2da52dd64l,
wolfSSL 14:167253f4e170 9726 0x08bc768872b74l },
wolfSSL 14:167253f4e170 9727 { 0xe3b7282d3d253l,0xa1f58d779fa5bl,0x16767bba9f679l,0xf34fa1cac168el,
wolfSSL 14:167253f4e170 9728 0x0b386f19060fcl },
wolfSSL 14:167253f4e170 9729 0 },
wolfSSL 14:167253f4e170 9730 /* 159 */
wolfSSL 14:167253f4e170 9731 { { 0x3c1352fedcfc2l,0x6262f8af0d31fl,0x57288c25396bfl,0x9c4d9a02b4eael,
wolfSSL 14:167253f4e170 9732 0x04cb460f71b06l },
wolfSSL 14:167253f4e170 9733 { 0x7b4d35b8095eal,0x596fc07603ae6l,0x614a16592bbf8l,0x5223e1475f66bl,
wolfSSL 14:167253f4e170 9734 0x052c0d50895efl },
wolfSSL 14:167253f4e170 9735 0 },
wolfSSL 14:167253f4e170 9736 /* 160 */
wolfSSL 14:167253f4e170 9737 { { 0xc210e15339848l,0xe870778c8d231l,0x956e170e87a28l,0x9c0b9d1de6616l,
wolfSSL 14:167253f4e170 9738 0x04ac3c9382bb0l },
wolfSSL 14:167253f4e170 9739 { 0xe05516998987dl,0xc4ae09f4d619bl,0xa3f933d8b2376l,0x05f41de0b7651l,
wolfSSL 14:167253f4e170 9740 0x0380d94c7e397l },
wolfSSL 14:167253f4e170 9741 0 },
wolfSSL 14:167253f4e170 9742 /* 161 */
wolfSSL 14:167253f4e170 9743 { { 0x355aa81542e75l,0xa1ee01b9b701al,0x24d708796c724l,0x37af6b3a29776l,
wolfSSL 14:167253f4e170 9744 0x02ce3e171de26l },
wolfSSL 14:167253f4e170 9745 { 0xfeb49f5d5bc1al,0x7e2777e2b5cfel,0x513756ca65560l,0x4e4d4feaac2f9l,
wolfSSL 14:167253f4e170 9746 0x02e6cd8520b62l },
wolfSSL 14:167253f4e170 9747 0 },
wolfSSL 14:167253f4e170 9748 /* 162 */
wolfSSL 14:167253f4e170 9749 { { 0x5954b8c31c31dl,0x005bf21a0c368l,0x5c79ec968533dl,0x9d540bd7626e7l,
wolfSSL 14:167253f4e170 9750 0x0ca17754742c6l },
wolfSSL 14:167253f4e170 9751 { 0xedafff6d2dbb2l,0xbd174a9d18cc6l,0xa4578e8fd0d8cl,0x2ce6875e8793al,
wolfSSL 14:167253f4e170 9752 0x0a976a7139cabl },
wolfSSL 14:167253f4e170 9753 0 },
wolfSSL 14:167253f4e170 9754 /* 163 */
wolfSSL 14:167253f4e170 9755 { { 0x51f1b93fb353dl,0x8b57fcfa720a6l,0x1b15281d75cabl,0x4999aa88cfa73l,
wolfSSL 14:167253f4e170 9756 0x08720a7170a1fl },
wolfSSL 14:167253f4e170 9757 { 0xe8d37693e1b90l,0x0b16f6dfc38c3l,0x52a8742d345dcl,0x893c8ea8d00abl,
wolfSSL 14:167253f4e170 9758 0x09719ef29c769l },
wolfSSL 14:167253f4e170 9759 0 },
wolfSSL 14:167253f4e170 9760 /* 164 */
wolfSSL 14:167253f4e170 9761 { { 0xeed8d58e35909l,0xdc33ddc116820l,0xe2050269366d8l,0x04c1d7f999d06l,
wolfSSL 14:167253f4e170 9762 0x0a5072976e157l },
wolfSSL 14:167253f4e170 9763 { 0xa37eac4e70b2el,0x576890aa8a002l,0x45b2a5c84dcf6l,0x7725cd71bf186l,
wolfSSL 14:167253f4e170 9764 0x099389c9df7b7l },
wolfSSL 14:167253f4e170 9765 0 },
wolfSSL 14:167253f4e170 9766 /* 165 */
wolfSSL 14:167253f4e170 9767 { { 0xc08f27ada7a4bl,0x03fd389366238l,0x66f512c3abe9dl,0x82e46b672e897l,
wolfSSL 14:167253f4e170 9768 0x0a88806aa202cl },
wolfSSL 14:167253f4e170 9769 { 0x2044ad380184el,0xc4126a8b85660l,0xd844f17a8cb78l,0xdcfe79d670c0al,
wolfSSL 14:167253f4e170 9770 0x00043bffb4738l },
wolfSSL 14:167253f4e170 9771 0 },
wolfSSL 14:167253f4e170 9772 /* 166 */
wolfSSL 14:167253f4e170 9773 { { 0x9b5dc36d5192el,0xd34590b2af8d5l,0x1601781acf885l,0x486683566d0a1l,
wolfSSL 14:167253f4e170 9774 0x052f3ef01ba6cl },
wolfSSL 14:167253f4e170 9775 { 0x6732a0edcb64dl,0x238068379f398l,0x040f3090a482cl,0x7e7516cbe5fa7l,
wolfSSL 14:167253f4e170 9776 0x03296bd899ef2l },
wolfSSL 14:167253f4e170 9777 0 },
wolfSSL 14:167253f4e170 9778 /* 167 */
wolfSSL 14:167253f4e170 9779 { { 0xaba89454d81d7l,0xef51eb9b3c476l,0x1c579869eade7l,0x71e9619a21cd8l,
wolfSSL 14:167253f4e170 9780 0x03b90febfaee5l },
wolfSSL 14:167253f4e170 9781 { 0x3023e5496f7cbl,0xd87fb51bc4939l,0x9beb5ce55be41l,0x0b1803f1dd489l,
wolfSSL 14:167253f4e170 9782 0x06e88069d9f81l },
wolfSSL 14:167253f4e170 9783 0 },
wolfSSL 14:167253f4e170 9784 /* 168 */
wolfSSL 14:167253f4e170 9785 { { 0x7ab11b43ea1dbl,0xa95259d292ce3l,0xf84f1860a7ff1l,0xad13851b02218l,
wolfSSL 14:167253f4e170 9786 0x0a7222beadefal },
wolfSSL 14:167253f4e170 9787 { 0xc78ec2b0a9144l,0x51f2fa59c5a2al,0x147ce385a0240l,0xc69091d1eca56l,
wolfSSL 14:167253f4e170 9788 0x0be94d523bc2al },
wolfSSL 14:167253f4e170 9789 0 },
wolfSSL 14:167253f4e170 9790 /* 169 */
wolfSSL 14:167253f4e170 9791 { { 0x4945e0b226ce7l,0x47967e8b7072fl,0x5a6c63eb8afd7l,0xc766edea46f18l,
wolfSSL 14:167253f4e170 9792 0x07782defe9be8l },
wolfSSL 14:167253f4e170 9793 { 0xd2aa43db38626l,0x8776f67ad1760l,0x4499cdb460ae7l,0x2e4b341b86fc5l,
wolfSSL 14:167253f4e170 9794 0x003838567a289l },
wolfSSL 14:167253f4e170 9795 0 },
wolfSSL 14:167253f4e170 9796 /* 170 */
wolfSSL 14:167253f4e170 9797 { { 0xdaefd79ec1a0fl,0xfdceb39c972d8l,0x8f61a953bbcd6l,0xb420f5575ffc5l,
wolfSSL 14:167253f4e170 9798 0x0dbd986c4adf7l },
wolfSSL 14:167253f4e170 9799 { 0xa881415f39eb7l,0xf5b98d976c81al,0xf2f717d6ee2fcl,0xbbd05465475dcl,
wolfSSL 14:167253f4e170 9800 0x08e24d3c46860l },
wolfSSL 14:167253f4e170 9801 0 },
wolfSSL 14:167253f4e170 9802 /* 171 */
wolfSSL 14:167253f4e170 9803 { { 0xd8e549a587390l,0x4f0cbec588749l,0x25983c612bb19l,0xafc846e07da4bl,
wolfSSL 14:167253f4e170 9804 0x0541a99c4407bl },
wolfSSL 14:167253f4e170 9805 { 0x41692624c8842l,0x2ad86c05ffdb2l,0xf7fcf626044c1l,0x35d1c59d14b44l,
wolfSSL 14:167253f4e170 9806 0x0c0092c49f57dl },
wolfSSL 14:167253f4e170 9807 0 },
wolfSSL 14:167253f4e170 9808 /* 172 */
wolfSSL 14:167253f4e170 9809 { { 0xc75c3df2e61efl,0xc82e1b35cad3cl,0x09f29f47e8841l,0x944dc62d30d19l,
wolfSSL 14:167253f4e170 9810 0x075e406347286l },
wolfSSL 14:167253f4e170 9811 { 0x41fc5bbc237d0l,0xf0ec4f01c9e7dl,0x82bd534c9537bl,0x858691c51a162l,
wolfSSL 14:167253f4e170 9812 0x05b7cb658c784l },
wolfSSL 14:167253f4e170 9813 0 },
wolfSSL 14:167253f4e170 9814 /* 173 */
wolfSSL 14:167253f4e170 9815 { { 0xa70848a28ead1l,0x08fd3b47f6964l,0x67e5b39802dc5l,0x97a19ae4bfd17l,
wolfSSL 14:167253f4e170 9816 0x07ae13eba8df0l },
wolfSSL 14:167253f4e170 9817 { 0x16ef8eadd384el,0xd9b6b2ff06fd2l,0xbcdb5f30361a2l,0xe3fd204b98784l,
wolfSSL 14:167253f4e170 9818 0x0787d8074e2a8l },
wolfSSL 14:167253f4e170 9819 0 },
wolfSSL 14:167253f4e170 9820 /* 174 */
wolfSSL 14:167253f4e170 9821 { { 0x25d6b757fbb1cl,0xb2ca201debc5el,0xd2233ffe47bddl,0x84844a55e9a36l,
wolfSSL 14:167253f4e170 9822 0x05c2228199ef2l },
wolfSSL 14:167253f4e170 9823 { 0xd4a8588315250l,0x2b827097c1773l,0xef5d33f21b21al,0xf2b0ab7c4ea1dl,
wolfSSL 14:167253f4e170 9824 0x0e45d37abbaf0l },
wolfSSL 14:167253f4e170 9825 0 },
wolfSSL 14:167253f4e170 9826 /* 175 */
wolfSSL 14:167253f4e170 9827 { { 0xf1e3428511c8al,0xc8bdca6cd3d2dl,0x27c39a7ebb229l,0xb9d3578a71a76l,
wolfSSL 14:167253f4e170 9828 0x0ed7bc12284dfl },
wolfSSL 14:167253f4e170 9829 { 0x2a6df93dea561l,0x8dd48f0ed1cf2l,0xbad23e85443f1l,0x6d27d8b861405l,
wolfSSL 14:167253f4e170 9830 0x0aac97cc945cal },
wolfSSL 14:167253f4e170 9831 0 },
wolfSSL 14:167253f4e170 9832 /* 176 */
wolfSSL 14:167253f4e170 9833 { { 0x4ea74a16bd00al,0xadf5c0bcc1eb5l,0xf9bfc06d839e9l,0xdc4e092bb7f11l,
wolfSSL 14:167253f4e170 9834 0x0318f97b31163l },
wolfSSL 14:167253f4e170 9835 { 0x0c5bec30d7138l,0x23abc30220eccl,0x022360644e8dfl,0xff4d2bb7972fbl,
wolfSSL 14:167253f4e170 9836 0x0fa41faa19a84l },
wolfSSL 14:167253f4e170 9837 0 },
wolfSSL 14:167253f4e170 9838 /* 177 */
wolfSSL 14:167253f4e170 9839 { { 0x2d974a6642269l,0xce9bb783bd440l,0x941e60bc81814l,0xe9e2398d38e47l,
wolfSSL 14:167253f4e170 9840 0x038bb6b2c1d26l },
wolfSSL 14:167253f4e170 9841 { 0xe4a256a577f87l,0x53dc11fe1cc64l,0x22807288b52d2l,0x01a5ff336abf6l,
wolfSSL 14:167253f4e170 9842 0x094dd0905ce76l },
wolfSSL 14:167253f4e170 9843 0 },
wolfSSL 14:167253f4e170 9844 /* 178 */
wolfSSL 14:167253f4e170 9845 { { 0xcf7dcde93f92al,0xcb89b5f315156l,0x995e750a01333l,0x2ae902404df9cl,
wolfSSL 14:167253f4e170 9846 0x092077867d25cl },
wolfSSL 14:167253f4e170 9847 { 0x71e010bf39d44l,0x2096bb53d7e24l,0xc9c3d8f5f2c90l,0xeb514c44b7b35l,
wolfSSL 14:167253f4e170 9848 0x081e8428bd29bl },
wolfSSL 14:167253f4e170 9849 0 },
wolfSSL 14:167253f4e170 9850 /* 179 */
wolfSSL 14:167253f4e170 9851 { { 0x9c2bac477199fl,0xee6b5ecdd96ddl,0xe40fd0e8cb8eel,0xa4b18af7db3fel,
wolfSSL 14:167253f4e170 9852 0x01b94ab62dbbfl },
wolfSSL 14:167253f4e170 9853 { 0x0d8b3ce47f143l,0xfc63f4616344fl,0xc59938351e623l,0x90eef18f270fcl,
wolfSSL 14:167253f4e170 9854 0x006a38e280555l },
wolfSSL 14:167253f4e170 9855 0 },
wolfSSL 14:167253f4e170 9856 /* 180 */
wolfSSL 14:167253f4e170 9857 { { 0xb0139b3355b49l,0x60b4ebf99b2e5l,0x269f3dc20e265l,0xd4f8c08ffa6bdl,
wolfSSL 14:167253f4e170 9858 0x0a7b36c2083d9l },
wolfSSL 14:167253f4e170 9859 { 0x15c3a1b3e8830l,0xe1a89f9c0b64dl,0x2d16930d5fceal,0x2a20cfeee4a2el,
wolfSSL 14:167253f4e170 9860 0x0be54c6b4a282l },
wolfSSL 14:167253f4e170 9861 0 },
wolfSSL 14:167253f4e170 9862 /* 181 */
wolfSSL 14:167253f4e170 9863 { { 0xdb3df8d91167cl,0x79e7a6625ed6cl,0x46ac7f4517c3fl,0x22bb7105648f3l,
wolfSSL 14:167253f4e170 9864 0x0bf30a5abeae0l },
wolfSSL 14:167253f4e170 9865 { 0x785be93828a68l,0x327f3ef0368e7l,0x92146b25161c3l,0xd13ae11b5feb5l,
wolfSSL 14:167253f4e170 9866 0x0d1c820de2732l },
wolfSSL 14:167253f4e170 9867 0 },
wolfSSL 14:167253f4e170 9868 /* 182 */
wolfSSL 14:167253f4e170 9869 { { 0xe13479038b363l,0x546b05e519043l,0x026cad158c11fl,0x8da34fe57abe6l,
wolfSSL 14:167253f4e170 9870 0x0b7d17bed68a1l },
wolfSSL 14:167253f4e170 9871 { 0xa5891e29c2559l,0x765bfffd8444cl,0x4e469484f7a03l,0xcc64498de4af7l,
wolfSSL 14:167253f4e170 9872 0x03997fd5e6412l },
wolfSSL 14:167253f4e170 9873 0 },
wolfSSL 14:167253f4e170 9874 /* 183 */
wolfSSL 14:167253f4e170 9875 { { 0x746828bd61507l,0xd534a64d2af20l,0xa8a15e329e132l,0x13e8ffeddfb08l,
wolfSSL 14:167253f4e170 9876 0x00eeb89293c6cl },
wolfSSL 14:167253f4e170 9877 { 0x69a3ea7e259f8l,0xe6d13e7e67e9bl,0xd1fa685ce1db7l,0xb6ef277318f6al,
wolfSSL 14:167253f4e170 9878 0x0228916f8c922l },
wolfSSL 14:167253f4e170 9879 0 },
wolfSSL 14:167253f4e170 9880 /* 184 */
wolfSSL 14:167253f4e170 9881 { { 0xae25b0a12ab5bl,0x1f957bc136959l,0x16e2b0ccc1117l,0x097e8058429edl,
wolfSSL 14:167253f4e170 9882 0x0ec05ad1d6e93l },
wolfSSL 14:167253f4e170 9883 { 0xba5beac3f3708l,0x3530b59d77157l,0x18234e531baf9l,0x1b3747b552371l,
wolfSSL 14:167253f4e170 9884 0x07d3141567ff1l },
wolfSSL 14:167253f4e170 9885 0 },
wolfSSL 14:167253f4e170 9886 /* 185 */
wolfSSL 14:167253f4e170 9887 { { 0x9c05cf6dfefabl,0x68dcb377077bdl,0xa38bb95be2f22l,0xd7a3e53ead973l,
wolfSSL 14:167253f4e170 9888 0x0e9ce66fc9bc1l },
wolfSSL 14:167253f4e170 9889 { 0xa15766f6a02a1l,0xdf60e600ed75al,0x8cdc1b938c087l,0x0651f8947f346l,
wolfSSL 14:167253f4e170 9890 0x0d9650b017228l },
wolfSSL 14:167253f4e170 9891 0 },
wolfSSL 14:167253f4e170 9892 /* 186 */
wolfSSL 14:167253f4e170 9893 { { 0xb4c4a5a057e60l,0xbe8def25e4504l,0x7c1ccbdcbccc3l,0xb7a2a63532081l,
wolfSSL 14:167253f4e170 9894 0x014d6699a804el },
wolfSSL 14:167253f4e170 9895 { 0xa8415db1f411al,0x0bf80d769c2c8l,0xc2f77ad09fbafl,0x598ab4deef901l,
wolfSSL 14:167253f4e170 9896 0x06f4c68410d43l },
wolfSSL 14:167253f4e170 9897 0 },
wolfSSL 14:167253f4e170 9898 /* 187 */
wolfSSL 14:167253f4e170 9899 { { 0x6df4e96c24a96l,0x85fcbd99a3872l,0xb2ae30a534dbcl,0x9abb3c466ef28l,
wolfSSL 14:167253f4e170 9900 0x04c4350fd6118l },
wolfSSL 14:167253f4e170 9901 { 0x7f716f855b8dal,0x94463c38a1296l,0xae9334341a423l,0x18b5c37e1413el,
wolfSSL 14:167253f4e170 9902 0x0a726d2425a31l },
wolfSSL 14:167253f4e170 9903 0 },
wolfSSL 14:167253f4e170 9904 /* 188 */
wolfSSL 14:167253f4e170 9905 { { 0x6b3ee948c1086l,0x3dcbd3a2e1dael,0x3d022f3f1de50l,0xf3923f35ed3f0l,
wolfSSL 14:167253f4e170 9906 0x013639e82cc6cl },
wolfSSL 14:167253f4e170 9907 { 0x938fbcdafaa86l,0xfb2654a2589acl,0x5051329f45bc5l,0x35a31963b26e4l,
wolfSSL 14:167253f4e170 9908 0x0ca9365e1c1a3l },
wolfSSL 14:167253f4e170 9909 0 },
wolfSSL 14:167253f4e170 9910 /* 189 */
wolfSSL 14:167253f4e170 9911 { { 0x5ac754c3b2d20l,0x17904e241b361l,0xc9d071d742a54l,0x72a5b08521c4cl,
wolfSSL 14:167253f4e170 9912 0x09ce29c34970bl },
wolfSSL 14:167253f4e170 9913 { 0x81f736d3e0ad6l,0x9ef2f8434c8ccl,0xce862d98060dal,0xaf9835ed1d1a6l,
wolfSSL 14:167253f4e170 9914 0x048c4abd7ab42l },
wolfSSL 14:167253f4e170 9915 0 },
wolfSSL 14:167253f4e170 9916 /* 190 */
wolfSSL 14:167253f4e170 9917 { { 0x1b0cc40c7485al,0xbbe5274dbfd22l,0x263d2e8ead455l,0x33cb493c76989l,
wolfSSL 14:167253f4e170 9918 0x078017c32f67bl },
wolfSSL 14:167253f4e170 9919 { 0x35769930cb5eel,0x940c408ed2b9dl,0x72f1a4dc0d14el,0x1c04f8b7bf552l,
wolfSSL 14:167253f4e170 9920 0x053cd0454de5cl },
wolfSSL 14:167253f4e170 9921 0 },
wolfSSL 14:167253f4e170 9922 /* 191 */
wolfSSL 14:167253f4e170 9923 { { 0x585fa5d28ccacl,0x56005b746ebcdl,0xd0123aa5f823el,0xfa8f7c79f0a1cl,
wolfSSL 14:167253f4e170 9924 0x0eea465c1d3d7l },
wolfSSL 14:167253f4e170 9925 { 0x0659f0551803bl,0x9f7ce6af70781l,0x9288e706c0b59l,0x91934195a7702l,
wolfSSL 14:167253f4e170 9926 0x01b6e42a47ae6l },
wolfSSL 14:167253f4e170 9927 0 },
wolfSSL 14:167253f4e170 9928 /* 192 */
wolfSSL 14:167253f4e170 9929 { { 0x0937cf67d04c3l,0xe289eeb8112e8l,0x2594d601e312bl,0xbd3d56b5d8879l,
wolfSSL 14:167253f4e170 9930 0x00224da14187fl },
wolfSSL 14:167253f4e170 9931 { 0xbb8630c5fe36fl,0x604ef51f5f87al,0x3b429ec580f3cl,0xff33964fb1bfbl,
wolfSSL 14:167253f4e170 9932 0x060838ef042bfl },
wolfSSL 14:167253f4e170 9933 0 },
wolfSSL 14:167253f4e170 9934 /* 193 */
wolfSSL 14:167253f4e170 9935 { { 0xcb2f27e0bbe99l,0xf304aa39ee432l,0xfa939037bda44l,0x16435f497c7a9l,
wolfSSL 14:167253f4e170 9936 0x0636eb2022d33l },
wolfSSL 14:167253f4e170 9937 { 0xd0e6193ae00aal,0xfe31ae6d2ffcfl,0xf93901c875a00l,0x8bacf43658a29l,
wolfSSL 14:167253f4e170 9938 0x08844eeb63921l },
wolfSSL 14:167253f4e170 9939 0 },
wolfSSL 14:167253f4e170 9940 /* 194 */
wolfSSL 14:167253f4e170 9941 { { 0x171d26b3bae58l,0x7117e39f3e114l,0x1a8eada7db3dfl,0x789ecd37bc7f8l,
wolfSSL 14:167253f4e170 9942 0x027ba83dc51fbl },
wolfSSL 14:167253f4e170 9943 { 0xf439ffbf54de5l,0x0bb5fe1a71a7dl,0xb297a48727703l,0xa4ab42ee8e35dl,
wolfSSL 14:167253f4e170 9944 0x0adb62d3487f3l },
wolfSSL 14:167253f4e170 9945 0 },
wolfSSL 14:167253f4e170 9946 /* 195 */
wolfSSL 14:167253f4e170 9947 { { 0x168a2a175df2al,0x4f618c32e99b1l,0x46b0916082aa0l,0xc8b2c9e4f2e71l,
wolfSSL 14:167253f4e170 9948 0x0b990fd7675e7l },
wolfSSL 14:167253f4e170 9949 { 0x9d96b4df37313l,0x79d0b40789082l,0x80877111c2055l,0xd18d66c9ae4a7l,
wolfSSL 14:167253f4e170 9950 0x081707ef94d10l },
wolfSSL 14:167253f4e170 9951 0 },
wolfSSL 14:167253f4e170 9952 /* 196 */
wolfSSL 14:167253f4e170 9953 { { 0x7cab203d6ff96l,0xfc0d84336097dl,0x042db4b5b851bl,0xaa5c268823c4dl,
wolfSSL 14:167253f4e170 9954 0x03792daead5a8l },
wolfSSL 14:167253f4e170 9955 { 0x18865941afa0bl,0x4142d83671528l,0xbe4e0a7f3e9e7l,0x01ba17c825275l,
wolfSSL 14:167253f4e170 9956 0x05abd635e94b0l },
wolfSSL 14:167253f4e170 9957 0 },
wolfSSL 14:167253f4e170 9958 /* 197 */
wolfSSL 14:167253f4e170 9959 { { 0xfa84e0ac4927cl,0x35a7c8cf23727l,0xadca0dfe38860l,0xb610a4bcd5ea4l,
wolfSSL 14:167253f4e170 9960 0x05995bf21846al },
wolfSSL 14:167253f4e170 9961 { 0xf860b829dfa33l,0xae958fc18be90l,0x8630366caafe2l,0x411e9b3baf447l,
wolfSSL 14:167253f4e170 9962 0x044c32ca2d483l },
wolfSSL 14:167253f4e170 9963 0 },
wolfSSL 14:167253f4e170 9964 /* 198 */
wolfSSL 14:167253f4e170 9965 { { 0xa97f1e40ed80cl,0xb131d2ca82a74l,0xc2d6ad95f938cl,0xa54c53f2124b7l,
wolfSSL 14:167253f4e170 9966 0x01f2162fb8082l },
wolfSSL 14:167253f4e170 9967 { 0x67cc5720b173el,0x66085f12f97e4l,0xc9d65dc40e8a6l,0x07c98cebc20e4l,
wolfSSL 14:167253f4e170 9968 0x08f1d402bc3e9l },
wolfSSL 14:167253f4e170 9969 0 },
wolfSSL 14:167253f4e170 9970 /* 199 */
wolfSSL 14:167253f4e170 9971 { { 0x92f9cfbc4058al,0xb6292f56704f5l,0xc1d8c57b15e14l,0xdbf9c55cfe37bl,
wolfSSL 14:167253f4e170 9972 0x0b1980f43926el },
wolfSSL 14:167253f4e170 9973 { 0x33e0932c76b09l,0x9d33b07f7898cl,0x63bb4611df527l,0x8e456f08ead48l,
wolfSSL 14:167253f4e170 9974 0x02828ad9b3744l },
wolfSSL 14:167253f4e170 9975 0 },
wolfSSL 14:167253f4e170 9976 /* 200 */
wolfSSL 14:167253f4e170 9977 { { 0x722c4c4cf4ac5l,0x3fdde64afb696l,0x0890832f5ac1al,0xb3900551baa2el,
wolfSSL 14:167253f4e170 9978 0x04973f1275a14l },
wolfSSL 14:167253f4e170 9979 { 0xd8335322eac5dl,0xf50bd9b568e59l,0x25883935e07eel,0x8ac7ab36720fal,
wolfSSL 14:167253f4e170 9980 0x06dac8ed0db16l },
wolfSSL 14:167253f4e170 9981 0 },
wolfSSL 14:167253f4e170 9982 /* 201 */
wolfSSL 14:167253f4e170 9983 { { 0x545aeeda835efl,0xd21d10ed51f7bl,0x3741b094aa113l,0xde4c035a65e01l,
wolfSSL 14:167253f4e170 9984 0x04b23ef5920b9l },
wolfSSL 14:167253f4e170 9985 { 0xbb6803c4c7341l,0x6d3f58bc37e82l,0x51e3ee8d45770l,0x9a4e73527863al,
wolfSSL 14:167253f4e170 9986 0x04dd71534ddf4l },
wolfSSL 14:167253f4e170 9987 0 },
wolfSSL 14:167253f4e170 9988 /* 202 */
wolfSSL 14:167253f4e170 9989 { { 0x4467295476cd9l,0x2fe31a725bbf9l,0xc4b67e0648d07l,0x4dbb1441c8b8fl,
wolfSSL 14:167253f4e170 9990 0x0fd3170002f4al },
wolfSSL 14:167253f4e170 9991 { 0x43ff48995d0e1l,0xd10ef729aa1cbl,0x179898276e695l,0xf365e0d5f9764l,
wolfSSL 14:167253f4e170 9992 0x014fac58c9569l },
wolfSSL 14:167253f4e170 9993 0 },
wolfSSL 14:167253f4e170 9994 /* 203 */
wolfSSL 14:167253f4e170 9995 { { 0xa0065f312ae18l,0xc0fcc93fc9ad9l,0xa7d284651958dl,0xda50d9a142408l,
wolfSSL 14:167253f4e170 9996 0x0ed7c765136abl },
wolfSSL 14:167253f4e170 9997 { 0x70f1a25d4abbcl,0xf3f1a113ea462l,0xb51952f9b5dd8l,0x9f53c609b0755l,
wolfSSL 14:167253f4e170 9998 0x0fefcb7f74d2el },
wolfSSL 14:167253f4e170 9999 0 },
wolfSSL 14:167253f4e170 10000 /* 204 */
wolfSSL 14:167253f4e170 10001 { { 0x9497aba119185l,0x30aac45ba4bd0l,0xa521179d54e8cl,0xd80b492479deal,
wolfSSL 14:167253f4e170 10002 0x01801a57e87e0l },
wolfSSL 14:167253f4e170 10003 { 0xd3f8dfcafffb0l,0x0bae255240073l,0xb5fdfbc6cf33cl,0x1064781d763b5l,
wolfSSL 14:167253f4e170 10004 0x09f8fc11e1eadl },
wolfSSL 14:167253f4e170 10005 0 },
wolfSSL 14:167253f4e170 10006 /* 205 */
wolfSSL 14:167253f4e170 10007 { { 0x3a1715e69544cl,0x67f04b7813158l,0x78a4c320eaf85l,0x69a91e22a8fd2l,
wolfSSL 14:167253f4e170 10008 0x0a9d3809d3d3al },
wolfSSL 14:167253f4e170 10009 { 0xc2c2c59a2da3bl,0xf61895c847936l,0x3d5086938ccbcl,0x8ef75e65244e6l,
wolfSSL 14:167253f4e170 10010 0x03006b9aee117l },
wolfSSL 14:167253f4e170 10011 0 },
wolfSSL 14:167253f4e170 10012 /* 206 */
wolfSSL 14:167253f4e170 10013 { { 0x1f2b0c9eead28l,0x5d89f4dfbc0bbl,0x2ce89397eef63l,0xf761074757fdbl,
wolfSSL 14:167253f4e170 10014 0x00ab85fd745f8l },
wolfSSL 14:167253f4e170 10015 { 0xa7c933e5b4549l,0x5c97922f21ecdl,0x43b80404be2bbl,0x42c2261a1274bl,
wolfSSL 14:167253f4e170 10016 0x0b122d67511e9l },
wolfSSL 14:167253f4e170 10017 0 },
wolfSSL 14:167253f4e170 10018 /* 207 */
wolfSSL 14:167253f4e170 10019 { { 0x607be66a5ae7al,0xfa76adcbe33bel,0xeb6e5c501e703l,0xbaecaf9043014l,
wolfSSL 14:167253f4e170 10020 0x09f599dc1097dl },
wolfSSL 14:167253f4e170 10021 { 0x5b7180ff250edl,0x74349a20dc6d7l,0x0b227a38eb915l,0x4b78425605a41l,
wolfSSL 14:167253f4e170 10022 0x07d5528e08a29l },
wolfSSL 14:167253f4e170 10023 0 },
wolfSSL 14:167253f4e170 10024 /* 208 */
wolfSSL 14:167253f4e170 10025 { { 0x58f6620c26defl,0xea582b2d1ef0fl,0x1ce3881025585l,0x1730fbe7d79b0l,
wolfSSL 14:167253f4e170 10026 0x028ccea01303fl },
wolfSSL 14:167253f4e170 10027 { 0xabcd179644ba5l,0xe806fff0b8d1dl,0x6b3e17b1fc643l,0x13bfa60a76fc6l,
wolfSSL 14:167253f4e170 10028 0x0c18baf48a1d0l },
wolfSSL 14:167253f4e170 10029 0 },
wolfSSL 14:167253f4e170 10030 /* 209 */
wolfSSL 14:167253f4e170 10031 { { 0x638c85dc4216dl,0x67206142ac34el,0x5f5064a00c010l,0x596bd453a1719l,
wolfSSL 14:167253f4e170 10032 0x09def809db7a9l },
wolfSSL 14:167253f4e170 10033 { 0x8642e67ab8d2cl,0x336237a2b641el,0x4c4218bb42404l,0x8ce57d506a6d6l,
wolfSSL 14:167253f4e170 10034 0x00357f8b06880l },
wolfSSL 14:167253f4e170 10035 0 },
wolfSSL 14:167253f4e170 10036 /* 210 */
wolfSSL 14:167253f4e170 10037 { { 0xdbe644cd2cc88l,0x8df0b8f39d8e9l,0xd30a0c8cc61c2l,0x98874a309874cl,
wolfSSL 14:167253f4e170 10038 0x0e4a01add1b48l },
wolfSSL 14:167253f4e170 10039 { 0x1eeacf57cd8f9l,0x3ebd594c482edl,0xbd2f7871b767dl,0xcc30a7295c717l,
wolfSSL 14:167253f4e170 10040 0x0466d7d79ce10l },
wolfSSL 14:167253f4e170 10041 0 },
wolfSSL 14:167253f4e170 10042 /* 211 */
wolfSSL 14:167253f4e170 10043 { { 0x318929dada2c7l,0xc38f9aa27d47dl,0x20a59e14fa0a6l,0xad1a90e4fd288l,
wolfSSL 14:167253f4e170 10044 0x0c672a522451el },
wolfSSL 14:167253f4e170 10045 { 0x07cc85d86b655l,0x3bf9ad4af1306l,0x71172a6f0235dl,0x751399a086805l,
wolfSSL 14:167253f4e170 10046 0x05e3d64faf2a6l },
wolfSSL 14:167253f4e170 10047 0 },
wolfSSL 14:167253f4e170 10048 /* 212 */
wolfSSL 14:167253f4e170 10049 { { 0x410c79b3b4416l,0x85eab26d99aa6l,0xb656a74cd8fcfl,0x42fc5ebff74adl,
wolfSSL 14:167253f4e170 10050 0x06c8a7a95eb8el },
wolfSSL 14:167253f4e170 10051 { 0x60ba7b02a63bdl,0x038b8f004710cl,0x12d90b06b2f23l,0xca918c6c37383l,
wolfSSL 14:167253f4e170 10052 0x0348ae422ad82l },
wolfSSL 14:167253f4e170 10053 0 },
wolfSSL 14:167253f4e170 10054 /* 213 */
wolfSSL 14:167253f4e170 10055 { { 0x746635ccda2fbl,0xa18e0726d27f4l,0x92b1f2022accal,0x2d2e85adf7824l,
wolfSSL 14:167253f4e170 10056 0x0c1074de0d9efl },
wolfSSL 14:167253f4e170 10057 { 0x3ce44ae9a65b3l,0xac05d7151bfcfl,0xe6a9788fd71e4l,0x4ffcd4711f50cl,
wolfSSL 14:167253f4e170 10058 0x0fbadfbdbc9e5l },
wolfSSL 14:167253f4e170 10059 0 },
wolfSSL 14:167253f4e170 10060 /* 214 */
wolfSSL 14:167253f4e170 10061 { { 0x3f1cd20a99363l,0x8f6cf22775171l,0x4d359b2b91565l,0x6fcd968175cd2l,
wolfSSL 14:167253f4e170 10062 0x0b7f976b48371l },
wolfSSL 14:167253f4e170 10063 { 0x8e24d5d6dbf74l,0xfd71c3af36575l,0x243dfe38d23bal,0xc80548f477600l,
wolfSSL 14:167253f4e170 10064 0x0f4d41b2ecafcl },
wolfSSL 14:167253f4e170 10065 0 },
wolfSSL 14:167253f4e170 10066 /* 215 */
wolfSSL 14:167253f4e170 10067 { { 0x1cf28fdabd48dl,0x3632c078a451fl,0x17146e9ce81bel,0x0f106ace29741l,
wolfSSL 14:167253f4e170 10068 0x0180824eae016l },
wolfSSL 14:167253f4e170 10069 { 0x7698b66e58358l,0x52ce6ca358038l,0xe41e6c5635687l,0x6d2582380e345l,
wolfSSL 14:167253f4e170 10070 0x067e5f63983cfl },
wolfSSL 14:167253f4e170 10071 0 },
wolfSSL 14:167253f4e170 10072 /* 216 */
wolfSSL 14:167253f4e170 10073 { { 0xccb8dcf4899efl,0xf09ebb44c0f89l,0x2598ec9949015l,0x1fc6546f9276bl,
wolfSSL 14:167253f4e170 10074 0x09fef789a04c1l },
wolfSSL 14:167253f4e170 10075 { 0x67ecf53d2a071l,0x7fa4519b096d3l,0x11e2eefb10e1al,0x4e20ca6b3fb06l,
wolfSSL 14:167253f4e170 10076 0x0bc80c181a99cl },
wolfSSL 14:167253f4e170 10077 0 },
wolfSSL 14:167253f4e170 10078 /* 217 */
wolfSSL 14:167253f4e170 10079 { { 0x536f8e5eb82e6l,0xc7f56cb920972l,0x0b5da5e1a484fl,0xdf10c78e21715l,
wolfSSL 14:167253f4e170 10080 0x049270e629f8cl },
wolfSSL 14:167253f4e170 10081 { 0x9b7bbea6b50adl,0xc1a2388ffc1a3l,0x107197b9a0284l,0x2f7f5403eb178l,
wolfSSL 14:167253f4e170 10082 0x0d2ee52f96137l },
wolfSSL 14:167253f4e170 10083 0 },
wolfSSL 14:167253f4e170 10084 /* 218 */
wolfSSL 14:167253f4e170 10085 { { 0xcd28588e0362al,0xa78fa5d94dd37l,0x434a526442fa8l,0xb733aff836e5al,
wolfSSL 14:167253f4e170 10086 0x0dfb478bee5abl },
wolfSSL 14:167253f4e170 10087 { 0xf1ce7673eede6l,0xd42b5b2f04a91l,0x530da2fa5390al,0x473a5e66f7bf5l,
wolfSSL 14:167253f4e170 10088 0x0d9a140b408dfl },
wolfSSL 14:167253f4e170 10089 0 },
wolfSSL 14:167253f4e170 10090 /* 219 */
wolfSSL 14:167253f4e170 10091 { { 0x221b56e8ea498l,0x293563ee090e0l,0x35d2ade623478l,0x4b1ae06b83913l,
wolfSSL 14:167253f4e170 10092 0x0760c058d623fl },
wolfSSL 14:167253f4e170 10093 { 0x9b58cc198aa79l,0xd2f07aba7f0b8l,0xde2556af74890l,0x04094e204110fl,
wolfSSL 14:167253f4e170 10094 0x07141982d8f19l },
wolfSSL 14:167253f4e170 10095 0 },
wolfSSL 14:167253f4e170 10096 /* 220 */
wolfSSL 14:167253f4e170 10097 { { 0xa0e334d4b0f45l,0x38392a94e16f0l,0x3c61d5ed9280bl,0x4e473af324c6bl,
wolfSSL 14:167253f4e170 10098 0x03af9d1ce89d5l },
wolfSSL 14:167253f4e170 10099 { 0xf798120930371l,0x4c21c17097fd8l,0xc42309beda266l,0x7dd60e9545dcdl,
wolfSSL 14:167253f4e170 10100 0x0b1f815c37395l },
wolfSSL 14:167253f4e170 10101 0 },
wolfSSL 14:167253f4e170 10102 /* 221 */
wolfSSL 14:167253f4e170 10103 { { 0xaa78e89fec44al,0x473caa4caf84fl,0x1b6a624c8c2ael,0xf052691c807dcl,
wolfSSL 14:167253f4e170 10104 0x0a41aed141543l },
wolfSSL 14:167253f4e170 10105 { 0x353997d5ffe04l,0xdf625b6e20424l,0x78177758bacb2l,0x60ef85d660be8l,
wolfSSL 14:167253f4e170 10106 0x0d6e9c1dd86fbl },
wolfSSL 14:167253f4e170 10107 0 },
wolfSSL 14:167253f4e170 10108 /* 222 */
wolfSSL 14:167253f4e170 10109 { { 0x2e97ec6853264l,0xb7e2304a0b3aal,0x8eae9be771533l,0xf8c21b912bb7bl,
wolfSSL 14:167253f4e170 10110 0x09c9c6e10ae9bl },
wolfSSL 14:167253f4e170 10111 { 0x09a59e030b74cl,0x4d6a631e90a23l,0x49b79f24ed749l,0x61b689f44b23al,
wolfSSL 14:167253f4e170 10112 0x0566bd59640fal },
wolfSSL 14:167253f4e170 10113 0 },
wolfSSL 14:167253f4e170 10114 /* 223 */
wolfSSL 14:167253f4e170 10115 { { 0xc0118c18061f3l,0xd37c83fc70066l,0x7273245190b25l,0x345ef05fc8e02l,
wolfSSL 14:167253f4e170 10116 0x0cf2c7390f525l },
wolfSSL 14:167253f4e170 10117 { 0xbceb410eb30cfl,0xba0d77703aa09l,0x50ff255cfd2ebl,0x0979e842c43a1l,
wolfSSL 14:167253f4e170 10118 0x002f517558aa2l },
wolfSSL 14:167253f4e170 10119 0 },
wolfSSL 14:167253f4e170 10120 /* 224 */
wolfSSL 14:167253f4e170 10121 { { 0xef794addb7d07l,0x4224455500396l,0x78aa3ce0b4fc7l,0xd97dfaff8eaccl,
wolfSSL 14:167253f4e170 10122 0x014e9ada5e8d4l },
wolfSSL 14:167253f4e170 10123 { 0x480a12f7079e2l,0xcde4b0800edaal,0x838157d45baa3l,0x9ae801765e2d7l,
wolfSSL 14:167253f4e170 10124 0x0a0ad4fab8e9dl },
wolfSSL 14:167253f4e170 10125 0 },
wolfSSL 14:167253f4e170 10126 /* 225 */
wolfSSL 14:167253f4e170 10127 { { 0xb76214a653618l,0x3c31eaaa5f0bfl,0x4949d5e187281l,0xed1e1553e7374l,
wolfSSL 14:167253f4e170 10128 0x0bcd530b86e56l },
wolfSSL 14:167253f4e170 10129 { 0xbe85332e9c47bl,0xfeb50059ab169l,0x92bfbb4dc2776l,0x341dcdba97611l,
wolfSSL 14:167253f4e170 10130 0x0909283cf6979l },
wolfSSL 14:167253f4e170 10131 0 },
wolfSSL 14:167253f4e170 10132 /* 226 */
wolfSSL 14:167253f4e170 10133 { { 0x0032476e81a13l,0x996217123967bl,0x32e19d69bee1al,0x549a08ed361bdl,
wolfSSL 14:167253f4e170 10134 0x035eeb7c9ace1l },
wolfSSL 14:167253f4e170 10135 { 0x0ae5a7e4e5bdcl,0xd3b6ceec6e128l,0xe266bc12dcd2cl,0xe86452e4224c6l,
wolfSSL 14:167253f4e170 10136 0x09a8b2cf4448al },
wolfSSL 14:167253f4e170 10137 0 },
wolfSSL 14:167253f4e170 10138 /* 227 */
wolfSSL 14:167253f4e170 10139 { { 0x71bf209d03b59l,0xa3b65af2abf64l,0xbd5eec9c90e62l,0x1379ff7ff168el,
wolfSSL 14:167253f4e170 10140 0x06bdb60f4d449l },
wolfSSL 14:167253f4e170 10141 { 0xafebc8a55bc30l,0x1610097fe0dadl,0xc1e3bddc79eadl,0x08a942e197414l,
wolfSSL 14:167253f4e170 10142 0x001ec3cfd94bal },
wolfSSL 14:167253f4e170 10143 0 },
wolfSSL 14:167253f4e170 10144 /* 228 */
wolfSSL 14:167253f4e170 10145 { { 0x277ebdc9485c2l,0x7922fb10c7ba6l,0x0a28d8a48cc9al,0x64f64f61d60f7l,
wolfSSL 14:167253f4e170 10146 0x0d1acb1c04754l },
wolfSSL 14:167253f4e170 10147 { 0x902b126f36612l,0x4ee0618d8bd26l,0x08357ee59c3a4l,0x26c24df8a8133l,
wolfSSL 14:167253f4e170 10148 0x07dcd079d4056l },
wolfSSL 14:167253f4e170 10149 0 },
wolfSSL 14:167253f4e170 10150 /* 229 */
wolfSSL 14:167253f4e170 10151 { { 0x7d4d3f05a4b48l,0x52372307725cel,0x12a915aadcd29l,0x19b8d18f79718l,
wolfSSL 14:167253f4e170 10152 0x00bf53589377dl },
wolfSSL 14:167253f4e170 10153 { 0xcd95a6c68ea73l,0xca823a584d35el,0x473a723c7f3bbl,0x86fc9fb674c6fl,
wolfSSL 14:167253f4e170 10154 0x0d28be4d9e166l },
wolfSSL 14:167253f4e170 10155 0 },
wolfSSL 14:167253f4e170 10156 /* 230 */
wolfSSL 14:167253f4e170 10157 { { 0xb990638fa8e4bl,0x6e893fd8fc5d2l,0x36fb6fc559f18l,0x88ce3a6de2aa4l,
wolfSSL 14:167253f4e170 10158 0x0d76007aa510fl },
wolfSSL 14:167253f4e170 10159 { 0x0aab6523a4988l,0x4474dd02732d1l,0x3407278b455cfl,0xbb017f467082al,
wolfSSL 14:167253f4e170 10160 0x0f2b52f68b303l },
wolfSSL 14:167253f4e170 10161 0 },
wolfSSL 14:167253f4e170 10162 /* 231 */
wolfSSL 14:167253f4e170 10163 { { 0x7eafa9835b4cal,0xfcbb669cbc0d5l,0x66431982d2232l,0xed3a8eeeb680cl,
wolfSSL 14:167253f4e170 10164 0x0d8dbe98ecc5al },
wolfSSL 14:167253f4e170 10165 { 0x9be3fc5a02709l,0xe5f5ba1fa8cbal,0x10ea85230be68l,0x9705febd43cdfl,
wolfSSL 14:167253f4e170 10166 0x0e01593a3ee55l },
wolfSSL 14:167253f4e170 10167 0 },
wolfSSL 14:167253f4e170 10168 /* 232 */
wolfSSL 14:167253f4e170 10169 { { 0x5af50ea75a0a6l,0xac57858033d3el,0x0176406512226l,0xef066fe6d50fdl,
wolfSSL 14:167253f4e170 10170 0x0afec07b1aeb8l },
wolfSSL 14:167253f4e170 10171 { 0x9956780bb0a31l,0xcc37309aae7fbl,0x1abf3896f1af3l,0xbfdd9153a15a0l,
wolfSSL 14:167253f4e170 10172 0x0a71b93546e2dl },
wolfSSL 14:167253f4e170 10173 0 },
wolfSSL 14:167253f4e170 10174 /* 233 */
wolfSSL 14:167253f4e170 10175 { { 0xe12e018f593d2l,0x28a078122bbf8l,0xba4f2add1a904l,0x23d9150505db0l,
wolfSSL 14:167253f4e170 10176 0x053a2005c6285l },
wolfSSL 14:167253f4e170 10177 { 0x8b639e7f2b935l,0x5ac182961a07cl,0x518ca2c2bff97l,0x8e3d86bceea77l,
wolfSSL 14:167253f4e170 10178 0x0bf47d19b3d58l },
wolfSSL 14:167253f4e170 10179 0 },
wolfSSL 14:167253f4e170 10180 /* 234 */
wolfSSL 14:167253f4e170 10181 { { 0x967a7dd7665d5l,0x572f2f4de5672l,0x0d4903f4e3030l,0xa1b6144005ae8l,
wolfSSL 14:167253f4e170 10182 0x0001c2c7f39c9l },
wolfSSL 14:167253f4e170 10183 { 0xa801469efc6d6l,0xaa7bc7a724143l,0x78150a4c810bdl,0xb99b5f65670bal,
wolfSSL 14:167253f4e170 10184 0x0fdadf8e786ffl },
wolfSSL 14:167253f4e170 10185 0 },
wolfSSL 14:167253f4e170 10186 /* 235 */
wolfSSL 14:167253f4e170 10187 { { 0x8cb88ffc00785l,0x913b48eb67fd3l,0xf368fbc77fa75l,0x3c940454d055bl,
wolfSSL 14:167253f4e170 10188 0x03a838e4d5aa4l },
wolfSSL 14:167253f4e170 10189 { 0x663293e97bb9al,0x63441d94d9561l,0xadb2a839eb933l,0x1da3515591a60l,
wolfSSL 14:167253f4e170 10190 0x03cdb8257873el },
wolfSSL 14:167253f4e170 10191 0 },
wolfSSL 14:167253f4e170 10192 /* 236 */
wolfSSL 14:167253f4e170 10193 { { 0x140a97de77eabl,0x0d41648109137l,0xeb1d0dff7e1c5l,0x7fba762dcad2cl,
wolfSSL 14:167253f4e170 10194 0x05a60cc89f1f5l },
wolfSSL 14:167253f4e170 10195 { 0x3638240d45673l,0x195913c65580bl,0xd64b7411b82bel,0x8fc0057284b8dl,
wolfSSL 14:167253f4e170 10196 0x0922ff56fdbfdl },
wolfSSL 14:167253f4e170 10197 0 },
wolfSSL 14:167253f4e170 10198 /* 237 */
wolfSSL 14:167253f4e170 10199 { { 0x65deec9a129a1l,0x57cc284e041b2l,0xebfbe3ca5b1cel,0xcd6204380c46cl,
wolfSSL 14:167253f4e170 10200 0x072919a7df6c5l },
wolfSSL 14:167253f4e170 10201 { 0xf453a8fb90f9al,0x0b88e4031b298l,0x96f1856d719c0l,0x089ae32c0e777l,
wolfSSL 14:167253f4e170 10202 0x05e7917803624l },
wolfSSL 14:167253f4e170 10203 0 },
wolfSSL 14:167253f4e170 10204 /* 238 */
wolfSSL 14:167253f4e170 10205 { { 0x6ec557f63cdfbl,0x71f1cae4fd5c1l,0x60597ca8e6a35l,0x2fabfce26bea5l,
wolfSSL 14:167253f4e170 10206 0x04e0a5371e24cl },
wolfSSL 14:167253f4e170 10207 { 0xa40d3a5765357l,0x440d73a2b4276l,0x1d11a323c89afl,0x04eeb8f370ae4l,
wolfSSL 14:167253f4e170 10208 0x0f5ff7818d566l },
wolfSSL 14:167253f4e170 10209 0 },
wolfSSL 14:167253f4e170 10210 /* 239 */
wolfSSL 14:167253f4e170 10211 { { 0x3e3fe1a09df21l,0x8ee66e8e47fbfl,0x9c8901526d5d2l,0x5e642096bd0a2l,
wolfSSL 14:167253f4e170 10212 0x0e41df0e9533fl },
wolfSSL 14:167253f4e170 10213 { 0xfda40b3ba9e3fl,0xeb2604d895305l,0xf0367c7f2340cl,0x155f0866e1927l,
wolfSSL 14:167253f4e170 10214 0x08edd7d6eac4fl },
wolfSSL 14:167253f4e170 10215 0 },
wolfSSL 14:167253f4e170 10216 /* 240 */
wolfSSL 14:167253f4e170 10217 { { 0x1dc0e0bfc8ff3l,0x2be936f42fc9al,0xca381ef14efd8l,0xee9667016f7ccl,
wolfSSL 14:167253f4e170 10218 0x01432c1caed8al },
wolfSSL 14:167253f4e170 10219 { 0x8482970b23c26l,0x730735b273ec6l,0xaef0f5aa64fe8l,0xd2c6e389f6e5el,
wolfSSL 14:167253f4e170 10220 0x0caef480b5ac8l },
wolfSSL 14:167253f4e170 10221 0 },
wolfSSL 14:167253f4e170 10222 /* 241 */
wolfSSL 14:167253f4e170 10223 { { 0x5c97875315922l,0x713063cca5524l,0x64ef2cbd82951l,0xe236f3ce60d0bl,
wolfSSL 14:167253f4e170 10224 0x0d0ba177e8efal },
wolfSSL 14:167253f4e170 10225 { 0x9ae8fb1b3af60l,0xe53d2da20e53al,0xf9eef281a796al,0xae1601d63605dl,
wolfSSL 14:167253f4e170 10226 0x0f31c957c1c54l },
wolfSSL 14:167253f4e170 10227 0 },
wolfSSL 14:167253f4e170 10228 /* 242 */
wolfSSL 14:167253f4e170 10229 { { 0x58d5249cc4597l,0xb0bae0a028c0fl,0x34a814adc5015l,0x7c3aefc5fc557l,
wolfSSL 14:167253f4e170 10230 0x0013404cb96e1l },
wolfSSL 14:167253f4e170 10231 { 0xe2585c9a824bfl,0x5e001eaed7b29l,0x1ef68acd59318l,0x3e6c8d6ee6826l,
wolfSSL 14:167253f4e170 10232 0x06f377c4b9193l },
wolfSSL 14:167253f4e170 10233 0 },
wolfSSL 14:167253f4e170 10234 /* 243 */
wolfSSL 14:167253f4e170 10235 { { 0x3bad1a8333fd2l,0x025a2a95b89f9l,0xaf75acea89302l,0x9506211e5037el,
wolfSSL 14:167253f4e170 10236 0x06dba3e4ed2d0l },
wolfSSL 14:167253f4e170 10237 { 0xef98cd04399cdl,0x6ee6b73adea48l,0x17ecaf31811c6l,0xf4a772f60752cl,
wolfSSL 14:167253f4e170 10238 0x0f13cf3423becl },
wolfSSL 14:167253f4e170 10239 0 },
wolfSSL 14:167253f4e170 10240 /* 244 */
wolfSSL 14:167253f4e170 10241 { { 0xb9ec0a919e2ebl,0x95f62c0f68ceel,0xaba229983a9a1l,0xbad3cfba3bb67l,
wolfSSL 14:167253f4e170 10242 0x0c83fa9a9274bl },
wolfSSL 14:167253f4e170 10243 { 0xd1b0b62fa1ce0l,0xf53418efbf0d7l,0x2706f04e58b60l,0x2683bfa8ef9e5l,
wolfSSL 14:167253f4e170 10244 0x0b49d70f45d70l },
wolfSSL 14:167253f4e170 10245 0 },
wolfSSL 14:167253f4e170 10246 /* 245 */
wolfSSL 14:167253f4e170 10247 { { 0xc7510fad5513bl,0xecb1751e2d914l,0x9fb9d5905f32el,0xf1cf6d850418dl,
wolfSSL 14:167253f4e170 10248 0x059cfadbb0c30l },
wolfSSL 14:167253f4e170 10249 { 0x7ac2355cb7fd6l,0xb8820426a3e16l,0x0a78864249367l,0x4b67eaeec58c9l,
wolfSSL 14:167253f4e170 10250 0x05babf362354al },
wolfSSL 14:167253f4e170 10251 0 },
wolfSSL 14:167253f4e170 10252 /* 246 */
wolfSSL 14:167253f4e170 10253 { { 0x981d1ee424865l,0x78f2e5577f37cl,0x9e0c0588b0028l,0xc8f0702970f1bl,
wolfSSL 14:167253f4e170 10254 0x06188c6a79026l },
wolfSSL 14:167253f4e170 10255 { 0x9a19bd0f244dal,0x5cfb08087306fl,0xf2136371eccedl,0xb9d935470f9b9l,
wolfSSL 14:167253f4e170 10256 0x0993fe475df50l },
wolfSSL 14:167253f4e170 10257 0 },
wolfSSL 14:167253f4e170 10258 /* 247 */
wolfSSL 14:167253f4e170 10259 { { 0x31cdf9b2c3609l,0xc02c46d4ea68el,0xa77510184eb19l,0x616b7ac9ec1a9l,
wolfSSL 14:167253f4e170 10260 0x081f764664c80l },
wolfSSL 14:167253f4e170 10261 { 0xc2a5a75fbe978l,0xd3f183b3561d7l,0x01dd2bf6743fel,0x060d838d1f045l,
wolfSSL 14:167253f4e170 10262 0x0564a812a5fe9l },
wolfSSL 14:167253f4e170 10263 0 },
wolfSSL 14:167253f4e170 10264 /* 248 */
wolfSSL 14:167253f4e170 10265 { { 0xa64f4fa817d1dl,0x44bea82e0f7a5l,0xd57f9aa55f968l,0x1d6cb5ff5a0fcl,
wolfSSL 14:167253f4e170 10266 0x0226bf3cf00e5l },
wolfSSL 14:167253f4e170 10267 { 0x1a9f92f2833cfl,0x5a4f4f89a8d6dl,0xf3f7f7720a0a3l,0x783611536c498l,
wolfSSL 14:167253f4e170 10268 0x068779f47ff25l },
wolfSSL 14:167253f4e170 10269 0 },
wolfSSL 14:167253f4e170 10270 /* 249 */
wolfSSL 14:167253f4e170 10271 { { 0x0c1c173043d08l,0x741fc020fa79bl,0xa6d26d0a54467l,0x2e0bd3767e289l,
wolfSSL 14:167253f4e170 10272 0x097bcb0d1eb09l },
wolfSSL 14:167253f4e170 10273 { 0x6eaa8f32ed3c3l,0x51b281bc482abl,0xfa178f3c8a4f1l,0x46554d1bf4f3bl,
wolfSSL 14:167253f4e170 10274 0x0a872ffe80a78l },
wolfSSL 14:167253f4e170 10275 0 },
wolfSSL 14:167253f4e170 10276 /* 250 */
wolfSSL 14:167253f4e170 10277 { { 0xb7935a32b2086l,0x0e8160f486b1al,0xb6ae6bee1eb71l,0xa36a9bd0cd913l,
wolfSSL 14:167253f4e170 10278 0x002812bfcb732l },
wolfSSL 14:167253f4e170 10279 { 0xfd7cacf605318l,0x50fdfd6d1da63l,0x102d619646e5dl,0x96afa1d683982l,
wolfSSL 14:167253f4e170 10280 0x007391cc9fe53l },
wolfSSL 14:167253f4e170 10281 0 },
wolfSSL 14:167253f4e170 10282 /* 251 */
wolfSSL 14:167253f4e170 10283 { { 0x157f08b80d02bl,0xd162877f7fc50l,0x8d542ae6b8333l,0x2a087aca1af87l,
wolfSSL 14:167253f4e170 10284 0x0355d2adc7e6dl },
wolfSSL 14:167253f4e170 10285 { 0xf335a287386e1l,0x94f8e43275b41l,0x79989eafd272al,0x3a79286ca2cdel,
wolfSSL 14:167253f4e170 10286 0x03dc2b1e37c2al },
wolfSSL 14:167253f4e170 10287 0 },
wolfSSL 14:167253f4e170 10288 /* 252 */
wolfSSL 14:167253f4e170 10289 { { 0x9d21c04581352l,0x25376782bed68l,0xfed701f0a00c8l,0x846b203bd5909l,
wolfSSL 14:167253f4e170 10290 0x0c47869103ccdl },
wolfSSL 14:167253f4e170 10291 { 0xa770824c768edl,0x026841f6575dbl,0xaccce0e72feeal,0x4d3273313ed56l,
wolfSSL 14:167253f4e170 10292 0x0ccc42968d5bbl },
wolfSSL 14:167253f4e170 10293 0 },
wolfSSL 14:167253f4e170 10294 /* 253 */
wolfSSL 14:167253f4e170 10295 { { 0x50de13d7620b9l,0x8a5992a56a94el,0x75487c9d89a5cl,0x71cfdc0076406l,
wolfSSL 14:167253f4e170 10296 0x0e147eb42aa48l },
wolfSSL 14:167253f4e170 10297 { 0xab4eeacf3ae46l,0xfb50350fbe274l,0x8c840eafd4936l,0x96e3df2afe474l,
wolfSSL 14:167253f4e170 10298 0x0239ac047080el },
wolfSSL 14:167253f4e170 10299 0 },
wolfSSL 14:167253f4e170 10300 /* 254 */
wolfSSL 14:167253f4e170 10301 { { 0xd1f352bfee8d4l,0xcffa7b0fec481l,0xce9af3cce80b5l,0xe59d105c4c9e2l,
wolfSSL 14:167253f4e170 10302 0x0c55fa1a3f5f7l },
wolfSSL 14:167253f4e170 10303 { 0x6f14e8257c227l,0x3f342be00b318l,0xa904fb2c5b165l,0xb69909afc998al,
wolfSSL 14:167253f4e170 10304 0x0094cd99cd4f4l },
wolfSSL 14:167253f4e170 10305 0 },
wolfSSL 14:167253f4e170 10306 /* 255 */
wolfSSL 14:167253f4e170 10307 { { 0x81c84d703bebal,0x5032ceb2918a9l,0x3bd49ec8631d1l,0xad33a445f2c9el,
wolfSSL 14:167253f4e170 10308 0x0b90a30b642abl },
wolfSSL 14:167253f4e170 10309 { 0x5404fb4a5abf9l,0xc375db7603b46l,0xa35d89f004750l,0x24f76f9a42cccl,
wolfSSL 14:167253f4e170 10310 0x0019f8b9a1b79l },
wolfSSL 14:167253f4e170 10311 0 },
wolfSSL 14:167253f4e170 10312 };
wolfSSL 14:167253f4e170 10313
wolfSSL 14:167253f4e170 10314 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 14:167253f4e170 10315 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 10316 *
wolfSSL 14:167253f4e170 10317 * r Resulting point.
wolfSSL 14:167253f4e170 10318 * k Scalar to multiply by.
wolfSSL 14:167253f4e170 10319 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 10320 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 10321 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 10322 */
wolfSSL 14:167253f4e170 10323 static int sp_256_ecc_mulmod_base_5(sp_point* r, sp_digit* k,
wolfSSL 14:167253f4e170 10324 int map, void* heap)
wolfSSL 14:167253f4e170 10325 {
wolfSSL 14:167253f4e170 10326 return sp_256_ecc_mulmod_stripe_5(r, &p256_base, p256_table,
wolfSSL 14:167253f4e170 10327 k, map, heap);
wolfSSL 14:167253f4e170 10328 }
wolfSSL 14:167253f4e170 10329
wolfSSL 14:167253f4e170 10330 #endif
wolfSSL 14:167253f4e170 10331
wolfSSL 14:167253f4e170 10332 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 14:167253f4e170 10333 * If map is true then convert result to affine co-ordinates.
wolfSSL 14:167253f4e170 10334 *
wolfSSL 14:167253f4e170 10335 * km Scalar to multiply by.
wolfSSL 14:167253f4e170 10336 * r Resulting point.
wolfSSL 14:167253f4e170 10337 * map Indicates whether to convert result to affine.
wolfSSL 14:167253f4e170 10338 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 10339 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 10340 */
wolfSSL 14:167253f4e170 10341 int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)
wolfSSL 14:167253f4e170 10342 {
wolfSSL 14:167253f4e170 10343 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10344 sp_point p;
wolfSSL 14:167253f4e170 10345 sp_digit kd[5];
wolfSSL 14:167253f4e170 10346 #endif
wolfSSL 14:167253f4e170 10347 sp_point* point;
wolfSSL 14:167253f4e170 10348 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 10349 int err = MP_OKAY;
wolfSSL 14:167253f4e170 10350 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 10351 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 10352 #endif
wolfSSL 14:167253f4e170 10353
wolfSSL 14:167253f4e170 10354 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 10355 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10356 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10357 k = XMALLOC(sizeof(sp_digit) * 5, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 10358 if (k == NULL)
wolfSSL 14:167253f4e170 10359 err = MEMORY_E;
wolfSSL 14:167253f4e170 10360 }
wolfSSL 14:167253f4e170 10361 #else
wolfSSL 14:167253f4e170 10362 k = kd;
wolfSSL 14:167253f4e170 10363 #endif
wolfSSL 14:167253f4e170 10364 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10365 sp_256_from_mp(k, 5, km);
wolfSSL 14:167253f4e170 10366
wolfSSL 14:167253f4e170 10367 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 10368 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 10369 err = sp_256_ecc_mulmod_base_avx2_5(point, k, map, heap);
wolfSSL 14:167253f4e170 10370 else
wolfSSL 14:167253f4e170 10371 #endif
wolfSSL 14:167253f4e170 10372 err = sp_256_ecc_mulmod_base_5(point, k, map, heap);
wolfSSL 14:167253f4e170 10373 }
wolfSSL 14:167253f4e170 10374 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 10375 err = sp_256_point_to_ecc_point_5(point, r);
wolfSSL 14:167253f4e170 10376
wolfSSL 14:167253f4e170 10377 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10378 if (k != NULL)
wolfSSL 14:167253f4e170 10379 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 10380 #endif
wolfSSL 14:167253f4e170 10381 sp_ecc_point_free(point, 0, heap);
wolfSSL 14:167253f4e170 10382
wolfSSL 14:167253f4e170 10383 return err;
wolfSSL 14:167253f4e170 10384 }
wolfSSL 14:167253f4e170 10385
wolfSSL 14:167253f4e170 10386 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN)
wolfSSL 14:167253f4e170 10387 /* Returns 1 if the number of zero.
wolfSSL 14:167253f4e170 10388 * Implementation is constant time.
wolfSSL 14:167253f4e170 10389 *
wolfSSL 14:167253f4e170 10390 * a Number to check.
wolfSSL 14:167253f4e170 10391 * returns 1 if the number is zero and 0 otherwise.
wolfSSL 14:167253f4e170 10392 */
wolfSSL 14:167253f4e170 10393 static int sp_256_iszero_5(const sp_digit* a)
wolfSSL 14:167253f4e170 10394 {
wolfSSL 14:167253f4e170 10395 return (a[0] | a[1] | a[2] | a[3] | a[4]) == 0;
wolfSSL 14:167253f4e170 10396 }
wolfSSL 14:167253f4e170 10397
wolfSSL 14:167253f4e170 10398 #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN */
wolfSSL 14:167253f4e170 10399 /* Add 1 to a. (a = a + 1)
wolfSSL 14:167253f4e170 10400 *
wolfSSL 14:167253f4e170 10401 * r A single precision integer.
wolfSSL 14:167253f4e170 10402 * a A single precision integer.
wolfSSL 14:167253f4e170 10403 */
wolfSSL 14:167253f4e170 10404 SP_NOINLINE static void sp_256_add_one_5(sp_digit* a)
wolfSSL 14:167253f4e170 10405 {
wolfSSL 14:167253f4e170 10406 a[0]++;
wolfSSL 14:167253f4e170 10407 sp_256_norm_5(a);
wolfSSL 14:167253f4e170 10408 }
wolfSSL 14:167253f4e170 10409
wolfSSL 14:167253f4e170 10410 /* Read big endian unsigned byte aray into r.
wolfSSL 14:167253f4e170 10411 *
wolfSSL 14:167253f4e170 10412 * r A single precision integer.
wolfSSL 14:167253f4e170 10413 * a Byte array.
wolfSSL 14:167253f4e170 10414 * n Number of bytes in array to read.
wolfSSL 14:167253f4e170 10415 */
wolfSSL 14:167253f4e170 10416 static void sp_256_from_bin(sp_digit* r, int max, const byte* a, int n)
wolfSSL 14:167253f4e170 10417 {
wolfSSL 14:167253f4e170 10418 int i, j = 0, s = 0;
wolfSSL 14:167253f4e170 10419
wolfSSL 14:167253f4e170 10420 r[0] = 0;
wolfSSL 14:167253f4e170 10421 for (i = n-1; i >= 0; i--) {
wolfSSL 14:167253f4e170 10422 r[j] |= ((sp_digit)a[i]) << s;
wolfSSL 14:167253f4e170 10423 if (s >= 44) {
wolfSSL 14:167253f4e170 10424 r[j] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 10425 s = 52 - s;
wolfSSL 14:167253f4e170 10426 if (j + 1 >= max)
wolfSSL 14:167253f4e170 10427 break;
wolfSSL 14:167253f4e170 10428 r[++j] = a[i] >> s;
wolfSSL 14:167253f4e170 10429 s = 8 - s;
wolfSSL 14:167253f4e170 10430 }
wolfSSL 14:167253f4e170 10431 else
wolfSSL 14:167253f4e170 10432 s += 8;
wolfSSL 14:167253f4e170 10433 }
wolfSSL 14:167253f4e170 10434
wolfSSL 14:167253f4e170 10435 for (j++; j < max; j++)
wolfSSL 14:167253f4e170 10436 r[j] = 0;
wolfSSL 14:167253f4e170 10437 }
wolfSSL 14:167253f4e170 10438
wolfSSL 14:167253f4e170 10439 /* Generates a scalar that is in the range 1..order-1.
wolfSSL 14:167253f4e170 10440 *
wolfSSL 14:167253f4e170 10441 * rng Random number generator.
wolfSSL 14:167253f4e170 10442 * k Scalar value.
wolfSSL 14:167253f4e170 10443 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 14:167253f4e170 10444 * MP_OKAY on success.
wolfSSL 14:167253f4e170 10445 */
wolfSSL 14:167253f4e170 10446 static int sp_256_ecc_gen_k_5(WC_RNG* rng, sp_digit* k)
wolfSSL 14:167253f4e170 10447 {
wolfSSL 14:167253f4e170 10448 int err;
wolfSSL 14:167253f4e170 10449 byte buf[32];
wolfSSL 14:167253f4e170 10450
wolfSSL 14:167253f4e170 10451 do {
wolfSSL 14:167253f4e170 10452 err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));
wolfSSL 14:167253f4e170 10453 if (err == 0) {
wolfSSL 14:167253f4e170 10454 sp_256_from_bin(k, 5, buf, sizeof(buf));
wolfSSL 14:167253f4e170 10455 if (sp_256_cmp_5(k, p256_order2) < 0) {
wolfSSL 14:167253f4e170 10456 sp_256_add_one_5(k);
wolfSSL 14:167253f4e170 10457 break;
wolfSSL 14:167253f4e170 10458 }
wolfSSL 14:167253f4e170 10459 }
wolfSSL 14:167253f4e170 10460 }
wolfSSL 14:167253f4e170 10461 while (err == 0);
wolfSSL 14:167253f4e170 10462
wolfSSL 14:167253f4e170 10463 return err;
wolfSSL 14:167253f4e170 10464 }
wolfSSL 14:167253f4e170 10465
wolfSSL 14:167253f4e170 10466 /* Makes a random EC key pair.
wolfSSL 14:167253f4e170 10467 *
wolfSSL 14:167253f4e170 10468 * rng Random number generator.
wolfSSL 14:167253f4e170 10469 * priv Generated private value.
wolfSSL 14:167253f4e170 10470 * pub Generated public point.
wolfSSL 14:167253f4e170 10471 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 10472 * returns ECC_INF_E when the point does not have the correct order, RNG
wolfSSL 14:167253f4e170 10473 * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 10474 */
wolfSSL 14:167253f4e170 10475 int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)
wolfSSL 14:167253f4e170 10476 {
wolfSSL 14:167253f4e170 10477 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10478 sp_point p;
wolfSSL 14:167253f4e170 10479 sp_digit kd[5];
wolfSSL 14:167253f4e170 10480 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 10481 sp_point inf;
wolfSSL 14:167253f4e170 10482 #endif
wolfSSL 14:167253f4e170 10483 #endif
wolfSSL 14:167253f4e170 10484 sp_point* point;
wolfSSL 14:167253f4e170 10485 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 10486 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 10487 sp_point* infinity;
wolfSSL 14:167253f4e170 10488 #endif
wolfSSL 14:167253f4e170 10489 int err;
wolfSSL 14:167253f4e170 10490 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 10491 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 10492 #endif
wolfSSL 14:167253f4e170 10493
wolfSSL 14:167253f4e170 10494 (void)heap;
wolfSSL 14:167253f4e170 10495
wolfSSL 14:167253f4e170 10496 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 10497 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 10498 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 10499 err = sp_ecc_point_new(heap, inf, infinity);
wolfSSL 14:167253f4e170 10500 #endif
wolfSSL 14:167253f4e170 10501 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10502 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10503 k = XMALLOC(sizeof(sp_digit) * 5, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 10504 if (k == NULL)
wolfSSL 14:167253f4e170 10505 err = MEMORY_E;
wolfSSL 14:167253f4e170 10506 }
wolfSSL 14:167253f4e170 10507 #else
wolfSSL 14:167253f4e170 10508 k = kd;
wolfSSL 14:167253f4e170 10509 #endif
wolfSSL 14:167253f4e170 10510
wolfSSL 14:167253f4e170 10511 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 10512 err = sp_256_ecc_gen_k_5(rng, k);
wolfSSL 14:167253f4e170 10513 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10514 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 10515 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 10516 err = sp_256_ecc_mulmod_base_avx2_5(point, k, 1, NULL);
wolfSSL 14:167253f4e170 10517 else
wolfSSL 14:167253f4e170 10518 #endif
wolfSSL 14:167253f4e170 10519 err = sp_256_ecc_mulmod_base_5(point, k, 1, NULL);
wolfSSL 14:167253f4e170 10520 }
wolfSSL 14:167253f4e170 10521
wolfSSL 14:167253f4e170 10522 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 10523 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10524 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 10525 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {
wolfSSL 14:167253f4e170 10526 err = sp_256_ecc_mulmod_avx2_5(infinity, point, p256_order, 1,
wolfSSL 14:167253f4e170 10527 NULL);
wolfSSL 14:167253f4e170 10528 }
wolfSSL 14:167253f4e170 10529 else
wolfSSL 14:167253f4e170 10530 #endif
wolfSSL 14:167253f4e170 10531 err = sp_256_ecc_mulmod_5(infinity, point, p256_order, 1, NULL);
wolfSSL 14:167253f4e170 10532 }
wolfSSL 14:167253f4e170 10533 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10534 if (!sp_256_iszero_5(point->x) || !sp_256_iszero_5(point->y))
wolfSSL 14:167253f4e170 10535 err = ECC_INF_E;
wolfSSL 14:167253f4e170 10536 }
wolfSSL 14:167253f4e170 10537 #endif
wolfSSL 14:167253f4e170 10538
wolfSSL 14:167253f4e170 10539 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 10540 err = sp_256_to_mp(k, priv);
wolfSSL 14:167253f4e170 10541 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 10542 err = sp_256_point_to_ecc_point_5(point, pub);
wolfSSL 14:167253f4e170 10543
wolfSSL 14:167253f4e170 10544 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10545 if (k != NULL)
wolfSSL 14:167253f4e170 10546 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 10547 #endif
wolfSSL 14:167253f4e170 10548 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 14:167253f4e170 10549 sp_ecc_point_free(infinity, 1, heap);
wolfSSL 14:167253f4e170 10550 #endif
wolfSSL 14:167253f4e170 10551 sp_ecc_point_free(point, 1, heap);
wolfSSL 14:167253f4e170 10552
wolfSSL 14:167253f4e170 10553 return err;
wolfSSL 14:167253f4e170 10554 }
wolfSSL 14:167253f4e170 10555
wolfSSL 14:167253f4e170 10556 #ifdef HAVE_ECC_DHE
wolfSSL 14:167253f4e170 10557 /* Write r as big endian to byte aray.
wolfSSL 14:167253f4e170 10558 * Fixed length number of bytes written: 32
wolfSSL 14:167253f4e170 10559 *
wolfSSL 14:167253f4e170 10560 * r A single precision integer.
wolfSSL 14:167253f4e170 10561 * a Byte array.
wolfSSL 14:167253f4e170 10562 */
wolfSSL 14:167253f4e170 10563 static void sp_256_to_bin(sp_digit* r, byte* a)
wolfSSL 14:167253f4e170 10564 {
wolfSSL 14:167253f4e170 10565 int i, j, s = 0, b;
wolfSSL 14:167253f4e170 10566
wolfSSL 14:167253f4e170 10567 for (i=0; i<4; i++) {
wolfSSL 14:167253f4e170 10568 r[i+1] += r[i] >> 52;
wolfSSL 14:167253f4e170 10569 r[i] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 10570 }
wolfSSL 14:167253f4e170 10571 j = 256 / 8 - 1;
wolfSSL 14:167253f4e170 10572 a[j] = 0;
wolfSSL 14:167253f4e170 10573 for (i=0; i<5 && j>=0; i++) {
wolfSSL 14:167253f4e170 10574 b = 0;
wolfSSL 14:167253f4e170 10575 a[j--] |= r[i] << s; b += 8 - s;
wolfSSL 14:167253f4e170 10576 if (j < 0)
wolfSSL 14:167253f4e170 10577 break;
wolfSSL 14:167253f4e170 10578 while (b < 52) {
wolfSSL 14:167253f4e170 10579 a[j--] = r[i] >> b; b += 8;
wolfSSL 14:167253f4e170 10580 if (j < 0)
wolfSSL 14:167253f4e170 10581 break;
wolfSSL 14:167253f4e170 10582 }
wolfSSL 14:167253f4e170 10583 s = 8 - (b - 52);
wolfSSL 14:167253f4e170 10584 if (j >= 0)
wolfSSL 14:167253f4e170 10585 a[j] = 0;
wolfSSL 14:167253f4e170 10586 if (s != 0)
wolfSSL 14:167253f4e170 10587 j++;
wolfSSL 14:167253f4e170 10588 }
wolfSSL 14:167253f4e170 10589 }
wolfSSL 14:167253f4e170 10590
wolfSSL 14:167253f4e170 10591 /* Multiply the point by the scalar and serialize the X ordinate.
wolfSSL 14:167253f4e170 10592 * The number is 0 padded to maximum size on output.
wolfSSL 14:167253f4e170 10593 *
wolfSSL 14:167253f4e170 10594 * priv Scalar to multiply the point by.
wolfSSL 14:167253f4e170 10595 * pub Point to multiply.
wolfSSL 14:167253f4e170 10596 * out Buffer to hold X ordinate.
wolfSSL 14:167253f4e170 10597 * outLen On entry, size of the buffer in bytes.
wolfSSL 14:167253f4e170 10598 * On exit, length of data in buffer in bytes.
wolfSSL 14:167253f4e170 10599 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 10600 * returns BUFFER_E if the buffer is to small for output size,
wolfSSL 14:167253f4e170 10601 * MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 14:167253f4e170 10602 */
wolfSSL 14:167253f4e170 10603 int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,
wolfSSL 14:167253f4e170 10604 word32* outLen, void* heap)
wolfSSL 14:167253f4e170 10605 {
wolfSSL 14:167253f4e170 10606 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10607 sp_point p;
wolfSSL 14:167253f4e170 10608 sp_digit kd[5];
wolfSSL 14:167253f4e170 10609 #endif
wolfSSL 14:167253f4e170 10610 sp_point* point = NULL;
wolfSSL 14:167253f4e170 10611 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 10612 int err = MP_OKAY;
wolfSSL 14:167253f4e170 10613 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 10614 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 10615 #endif
wolfSSL 14:167253f4e170 10616
wolfSSL 14:167253f4e170 10617 if (*outLen < 32)
wolfSSL 14:167253f4e170 10618 err = BUFFER_E;
wolfSSL 14:167253f4e170 10619
wolfSSL 14:167253f4e170 10620 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 10621 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 10622 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10623 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10624 k = XMALLOC(sizeof(sp_digit) * 5, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 10625 if (k == NULL)
wolfSSL 14:167253f4e170 10626 err = MEMORY_E;
wolfSSL 14:167253f4e170 10627 }
wolfSSL 14:167253f4e170 10628 #else
wolfSSL 14:167253f4e170 10629 k = kd;
wolfSSL 14:167253f4e170 10630 #endif
wolfSSL 14:167253f4e170 10631
wolfSSL 14:167253f4e170 10632 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10633 sp_256_from_mp(k, 5, priv);
wolfSSL 14:167253f4e170 10634 sp_256_point_from_ecc_point_5(point, pub);
wolfSSL 14:167253f4e170 10635 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 10636 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 10637 err = sp_256_ecc_mulmod_avx2_5(point, point, k, 1, heap);
wolfSSL 14:167253f4e170 10638 else
wolfSSL 14:167253f4e170 10639 #endif
wolfSSL 14:167253f4e170 10640 err = sp_256_ecc_mulmod_5(point, point, k, 1, heap);
wolfSSL 14:167253f4e170 10641 }
wolfSSL 14:167253f4e170 10642 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10643 sp_256_to_bin(point->x, out);
wolfSSL 14:167253f4e170 10644 *outLen = 32;
wolfSSL 14:167253f4e170 10645 }
wolfSSL 14:167253f4e170 10646
wolfSSL 14:167253f4e170 10647 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10648 if (k != NULL)
wolfSSL 14:167253f4e170 10649 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 10650 #endif
wolfSSL 14:167253f4e170 10651 sp_ecc_point_free(point, 0, heap);
wolfSSL 14:167253f4e170 10652
wolfSSL 14:167253f4e170 10653 return err;
wolfSSL 14:167253f4e170 10654 }
wolfSSL 14:167253f4e170 10655 #endif /* HAVE_ECC_DHE */
wolfSSL 14:167253f4e170 10656
wolfSSL 14:167253f4e170 10657 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 10658 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 10659 #endif /* HAVE_INTEL_AVX2 */
wolfSSL 14:167253f4e170 10660 #endif
wolfSSL 14:167253f4e170 10661 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 10662 /* Multiply a by scalar b into r. (r = a * b)
wolfSSL 14:167253f4e170 10663 *
wolfSSL 14:167253f4e170 10664 * r A single precision integer.
wolfSSL 14:167253f4e170 10665 * a A single precision integer.
wolfSSL 14:167253f4e170 10666 * b A scalar.
wolfSSL 14:167253f4e170 10667 */
wolfSSL 14:167253f4e170 10668 SP_NOINLINE static void sp_256_mul_d_5(sp_digit* r, const sp_digit* a,
wolfSSL 14:167253f4e170 10669 const sp_digit b)
wolfSSL 14:167253f4e170 10670 {
wolfSSL 14:167253f4e170 10671 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 10672 int128_t tb = b;
wolfSSL 14:167253f4e170 10673 int128_t t = 0;
wolfSSL 14:167253f4e170 10674 int i;
wolfSSL 14:167253f4e170 10675
wolfSSL 14:167253f4e170 10676 for (i = 0; i < 5; i++) {
wolfSSL 14:167253f4e170 10677 t += tb * a[i];
wolfSSL 14:167253f4e170 10678 r[i] = t & 0xfffffffffffffl;
wolfSSL 14:167253f4e170 10679 t >>= 52;
wolfSSL 14:167253f4e170 10680 }
wolfSSL 14:167253f4e170 10681 r[5] = (sp_digit)t;
wolfSSL 14:167253f4e170 10682 #else
wolfSSL 14:167253f4e170 10683 int128_t tb = b;
wolfSSL 14:167253f4e170 10684 int128_t t[5];
wolfSSL 14:167253f4e170 10685
wolfSSL 14:167253f4e170 10686 t[ 0] = tb * a[ 0];
wolfSSL 14:167253f4e170 10687 t[ 1] = tb * a[ 1];
wolfSSL 14:167253f4e170 10688 t[ 2] = tb * a[ 2];
wolfSSL 14:167253f4e170 10689 t[ 3] = tb * a[ 3];
wolfSSL 14:167253f4e170 10690 t[ 4] = tb * a[ 4];
wolfSSL 14:167253f4e170 10691 r[ 0] = (t[ 0] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 10692 r[ 1] = (sp_digit)(t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 10693 r[ 2] = (sp_digit)(t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 10694 r[ 3] = (sp_digit)(t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 10695 r[ 4] = (sp_digit)(t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffl);
wolfSSL 14:167253f4e170 10696 r[ 5] = (sp_digit)(t[ 4] >> 52);
wolfSSL 14:167253f4e170 10697 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 10698 }
wolfSSL 14:167253f4e170 10699
wolfSSL 14:167253f4e170 10700 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 14:167253f4e170 10701 * m is not calculated as it is not needed at this time.
wolfSSL 14:167253f4e170 10702 *
wolfSSL 14:167253f4e170 10703 * a Nmber to be divided.
wolfSSL 14:167253f4e170 10704 * d Number to divide with.
wolfSSL 14:167253f4e170 10705 * m Multiplier result.
wolfSSL 14:167253f4e170 10706 * r Remainder from the division.
wolfSSL 14:167253f4e170 10707 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 10708 */
wolfSSL 14:167253f4e170 10709 static int sp_256_div_5(sp_digit* a, sp_digit* d, sp_digit* m,
wolfSSL 14:167253f4e170 10710 sp_digit* r)
wolfSSL 14:167253f4e170 10711 {
wolfSSL 14:167253f4e170 10712 int i;
wolfSSL 14:167253f4e170 10713 int128_t d1;
wolfSSL 14:167253f4e170 10714 sp_digit div, r1;
wolfSSL 14:167253f4e170 10715 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10716 sp_digit* td;
wolfSSL 14:167253f4e170 10717 #else
wolfSSL 14:167253f4e170 10718 sp_digit t1d[10], t2d[5 + 1];
wolfSSL 14:167253f4e170 10719 #endif
wolfSSL 14:167253f4e170 10720 sp_digit* t1;
wolfSSL 14:167253f4e170 10721 sp_digit* t2;
wolfSSL 14:167253f4e170 10722 int err = MP_OKAY;
wolfSSL 14:167253f4e170 10723
wolfSSL 14:167253f4e170 10724 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10725 td = XMALLOC(sizeof(sp_digit) * (3 * 5 + 1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 10726 if (td != NULL) {
wolfSSL 14:167253f4e170 10727 t1 = td;
wolfSSL 14:167253f4e170 10728 t2 = td + 2 * 5;
wolfSSL 14:167253f4e170 10729 }
wolfSSL 14:167253f4e170 10730 else
wolfSSL 14:167253f4e170 10731 err = MEMORY_E;
wolfSSL 14:167253f4e170 10732 #else
wolfSSL 14:167253f4e170 10733 t1 = t1d;
wolfSSL 14:167253f4e170 10734 t2 = t2d;
wolfSSL 14:167253f4e170 10735 #endif
wolfSSL 14:167253f4e170 10736
wolfSSL 14:167253f4e170 10737 (void)m;
wolfSSL 14:167253f4e170 10738
wolfSSL 14:167253f4e170 10739 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 10740 div = d[4];
wolfSSL 14:167253f4e170 10741 XMEMCPY(t1, a, sizeof(*t1) * 2 * 5);
wolfSSL 14:167253f4e170 10742 for (i=4; i>=0; i--) {
wolfSSL 14:167253f4e170 10743 t1[5 + i] += t1[5 + i - 1] >> 52;
wolfSSL 14:167253f4e170 10744 t1[5 + i - 1] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 10745 d1 = t1[5 + i];
wolfSSL 14:167253f4e170 10746 d1 <<= 52;
wolfSSL 14:167253f4e170 10747 d1 += t1[5 + i - 1];
wolfSSL 14:167253f4e170 10748 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 10749
wolfSSL 14:167253f4e170 10750 sp_256_mul_d_5(t2, d, r1);
wolfSSL 14:167253f4e170 10751 sp_256_sub_5(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 10752 t1[5 + i] -= t2[5];
wolfSSL 14:167253f4e170 10753 t1[5 + i] += t1[5 + i - 1] >> 52;
wolfSSL 14:167253f4e170 10754 t1[5 + i - 1] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 10755 r1 = (((-t1[5 + i]) << 52) - t1[5 + i - 1]) / div;
wolfSSL 14:167253f4e170 10756 r1++;
wolfSSL 14:167253f4e170 10757 sp_256_mul_d_5(t2, d, r1);
wolfSSL 14:167253f4e170 10758 sp_256_add_5(&t1[i], &t1[i], t2);
wolfSSL 14:167253f4e170 10759 t1[5 + i] += t1[5 + i - 1] >> 52;
wolfSSL 14:167253f4e170 10760 t1[5 + i - 1] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 10761 }
wolfSSL 14:167253f4e170 10762 t1[5 - 1] += t1[5 - 2] >> 52;
wolfSSL 14:167253f4e170 10763 t1[5 - 2] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 10764 d1 = t1[5 - 1];
wolfSSL 14:167253f4e170 10765 r1 = (sp_digit)(d1 / div);
wolfSSL 14:167253f4e170 10766
wolfSSL 14:167253f4e170 10767 sp_256_mul_d_5(t2, d, r1);
wolfSSL 14:167253f4e170 10768 sp_256_sub_5(t1, t1, t2);
wolfSSL 14:167253f4e170 10769 XMEMCPY(r, t1, sizeof(*r) * 2 * 5);
wolfSSL 14:167253f4e170 10770 for (i=0; i<3; i++) {
wolfSSL 14:167253f4e170 10771 r[i+1] += r[i] >> 52;
wolfSSL 14:167253f4e170 10772 r[i] &= 0xfffffffffffffl;
wolfSSL 14:167253f4e170 10773 }
wolfSSL 14:167253f4e170 10774 sp_256_cond_add_5(r, r, d, 0 - (r[4] < 0));
wolfSSL 14:167253f4e170 10775 }
wolfSSL 14:167253f4e170 10776
wolfSSL 14:167253f4e170 10777 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 10778 if (td != NULL)
wolfSSL 14:167253f4e170 10779 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 14:167253f4e170 10780 #endif
wolfSSL 14:167253f4e170 10781
wolfSSL 14:167253f4e170 10782 return err;
wolfSSL 14:167253f4e170 10783 }
wolfSSL 14:167253f4e170 10784
wolfSSL 14:167253f4e170 10785 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 14:167253f4e170 10786 *
wolfSSL 14:167253f4e170 10787 * r A single precision number that is the reduced result.
wolfSSL 14:167253f4e170 10788 * a A single precision number that is to be reduced.
wolfSSL 14:167253f4e170 10789 * m A single precision number that is the modulus to reduce with.
wolfSSL 14:167253f4e170 10790 * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 10791 */
wolfSSL 14:167253f4e170 10792 static int sp_256_mod_5(sp_digit* r, sp_digit* a, sp_digit* m)
wolfSSL 14:167253f4e170 10793 {
wolfSSL 14:167253f4e170 10794 return sp_256_div_5(a, m, NULL, r);
wolfSSL 14:167253f4e170 10795 }
wolfSSL 14:167253f4e170 10796
wolfSSL 14:167253f4e170 10797 #endif
wolfSSL 14:167253f4e170 10798 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 14:167253f4e170 10799 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 10800 /* Order-2 for the P256 curve. */
wolfSSL 14:167253f4e170 10801 static const uint64_t p256_order_2[4] = {
wolfSSL 14:167253f4e170 10802 0xf3b9cac2fc63254f,0xbce6faada7179e84,0xffffffffffffffff,
wolfSSL 14:167253f4e170 10803 0xffffffff00000000
wolfSSL 14:167253f4e170 10804 };
wolfSSL 14:167253f4e170 10805 #else
wolfSSL 14:167253f4e170 10806 /* The low half of the order-2 of the P256 curve. */
wolfSSL 14:167253f4e170 10807 static const uint64_t p256_order_low[2] = {
wolfSSL 14:167253f4e170 10808 0xf3b9cac2fc63254f,0xbce6faada7179e84
wolfSSL 14:167253f4e170 10809 };
wolfSSL 14:167253f4e170 10810 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 10811
wolfSSL 14:167253f4e170 10812 /* Multiply two number mod the order of P256 curve. (r = a * b mod order)
wolfSSL 14:167253f4e170 10813 *
wolfSSL 14:167253f4e170 10814 * r Result of the multiplication.
wolfSSL 14:167253f4e170 10815 * a First operand of the multiplication.
wolfSSL 14:167253f4e170 10816 * b Second operand of the multiplication.
wolfSSL 14:167253f4e170 10817 */
wolfSSL 14:167253f4e170 10818 static void sp_256_mont_mul_order_5(sp_digit* r, sp_digit* a, sp_digit* b)
wolfSSL 14:167253f4e170 10819 {
wolfSSL 14:167253f4e170 10820 sp_256_mul_5(r, a, b);
wolfSSL 14:167253f4e170 10821 sp_256_mont_reduce_5(r, p256_order, p256_mp_order);
wolfSSL 14:167253f4e170 10822 }
wolfSSL 14:167253f4e170 10823
wolfSSL 14:167253f4e170 10824 /* Square number mod the order of P256 curve. (r = a * a mod order)
wolfSSL 14:167253f4e170 10825 *
wolfSSL 14:167253f4e170 10826 * r Result of the squaring.
wolfSSL 14:167253f4e170 10827 * a Number to square.
wolfSSL 14:167253f4e170 10828 */
wolfSSL 14:167253f4e170 10829 static void sp_256_mont_sqr_order_5(sp_digit* r, sp_digit* a)
wolfSSL 14:167253f4e170 10830 {
wolfSSL 14:167253f4e170 10831 sp_256_sqr_5(r, a);
wolfSSL 14:167253f4e170 10832 sp_256_mont_reduce_5(r, p256_order, p256_mp_order);
wolfSSL 14:167253f4e170 10833 }
wolfSSL 14:167253f4e170 10834
wolfSSL 14:167253f4e170 10835 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 10836 /* Square number mod the order of P256 curve a number of times.
wolfSSL 14:167253f4e170 10837 * (r = a ^ n mod order)
wolfSSL 14:167253f4e170 10838 *
wolfSSL 14:167253f4e170 10839 * r Result of the squaring.
wolfSSL 14:167253f4e170 10840 * a Number to square.
wolfSSL 14:167253f4e170 10841 */
wolfSSL 14:167253f4e170 10842 static void sp_256_mont_sqr_n_order_5(sp_digit* r, sp_digit* a, int n)
wolfSSL 14:167253f4e170 10843 {
wolfSSL 14:167253f4e170 10844 int i;
wolfSSL 14:167253f4e170 10845
wolfSSL 14:167253f4e170 10846 sp_256_mont_sqr_order_5(r, a);
wolfSSL 14:167253f4e170 10847 for (i=1; i<n; i++)
wolfSSL 14:167253f4e170 10848 sp_256_mont_sqr_order_5(r, r);
wolfSSL 14:167253f4e170 10849 }
wolfSSL 14:167253f4e170 10850 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 10851
wolfSSL 14:167253f4e170 10852 /* Invert the number, in Montgomery form, modulo the order of the P256 curve.
wolfSSL 14:167253f4e170 10853 * (r = 1 / a mod order)
wolfSSL 14:167253f4e170 10854 *
wolfSSL 14:167253f4e170 10855 * r Inverse result.
wolfSSL 14:167253f4e170 10856 * a Number to invert.
wolfSSL 14:167253f4e170 10857 * td Temporary data.
wolfSSL 14:167253f4e170 10858 */
wolfSSL 14:167253f4e170 10859 static void sp_256_mont_inv_order_5(sp_digit* r, sp_digit* a,
wolfSSL 14:167253f4e170 10860 sp_digit* td)
wolfSSL 14:167253f4e170 10861 {
wolfSSL 14:167253f4e170 10862 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 10863 sp_digit* t = td;
wolfSSL 14:167253f4e170 10864 int i;
wolfSSL 14:167253f4e170 10865
wolfSSL 14:167253f4e170 10866 XMEMCPY(t, a, sizeof(sp_digit) * 5);
wolfSSL 14:167253f4e170 10867 for (i=254; i>=0; i--) {
wolfSSL 14:167253f4e170 10868 sp_256_mont_sqr_order_5(t, t);
wolfSSL 14:167253f4e170 10869 if (p256_order_2[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 10870 sp_256_mont_mul_order_5(t, t, a);
wolfSSL 14:167253f4e170 10871 }
wolfSSL 14:167253f4e170 10872 XMEMCPY(r, t, sizeof(sp_digit) * 5);
wolfSSL 14:167253f4e170 10873 #else
wolfSSL 14:167253f4e170 10874 sp_digit* t = td;
wolfSSL 14:167253f4e170 10875 sp_digit* t2 = td + 2 * 5;
wolfSSL 14:167253f4e170 10876 sp_digit* t3 = td + 4 * 5;
wolfSSL 14:167253f4e170 10877 int i;
wolfSSL 14:167253f4e170 10878
wolfSSL 14:167253f4e170 10879 /* t = a^2 */
wolfSSL 14:167253f4e170 10880 sp_256_mont_sqr_order_5(t, a);
wolfSSL 14:167253f4e170 10881 /* t = a^3 = t * a */
wolfSSL 14:167253f4e170 10882 sp_256_mont_mul_order_5(t, t, a);
wolfSSL 14:167253f4e170 10883 /* t2= a^c = t ^ 2 ^ 2 */
wolfSSL 14:167253f4e170 10884 sp_256_mont_sqr_n_order_5(t2, t, 2);
wolfSSL 14:167253f4e170 10885 /* t3= a^f = t2 * t */
wolfSSL 14:167253f4e170 10886 sp_256_mont_mul_order_5(t3, t2, t);
wolfSSL 14:167253f4e170 10887 /* t2= a^f0 = t3 ^ 2 ^ 4 */
wolfSSL 14:167253f4e170 10888 sp_256_mont_sqr_n_order_5(t2, t3, 4);
wolfSSL 14:167253f4e170 10889 /* t = a^ff = t2 * t3 */
wolfSSL 14:167253f4e170 10890 sp_256_mont_mul_order_5(t, t2, t3);
wolfSSL 14:167253f4e170 10891 /* t3= a^ff00 = t ^ 2 ^ 8 */
wolfSSL 14:167253f4e170 10892 sp_256_mont_sqr_n_order_5(t2, t, 8);
wolfSSL 14:167253f4e170 10893 /* t = a^ffff = t2 * t */
wolfSSL 14:167253f4e170 10894 sp_256_mont_mul_order_5(t, t2, t);
wolfSSL 14:167253f4e170 10895 /* t2= a^ffff0000 = t ^ 2 ^ 16 */
wolfSSL 14:167253f4e170 10896 sp_256_mont_sqr_n_order_5(t2, t, 16);
wolfSSL 14:167253f4e170 10897 /* t = a^ffffffff = t2 * t */
wolfSSL 14:167253f4e170 10898 sp_256_mont_mul_order_5(t, t2, t);
wolfSSL 14:167253f4e170 10899 /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64 */
wolfSSL 14:167253f4e170 10900 sp_256_mont_sqr_n_order_5(t2, t, 64);
wolfSSL 14:167253f4e170 10901 /* t2= a^ffffffff00000000ffffffff = t2 * t */
wolfSSL 14:167253f4e170 10902 sp_256_mont_mul_order_5(t2, t2, t);
wolfSSL 14:167253f4e170 10903 /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32 */
wolfSSL 14:167253f4e170 10904 sp_256_mont_sqr_n_order_5(t2, t2, 32);
wolfSSL 14:167253f4e170 10905 /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */
wolfSSL 14:167253f4e170 10906 sp_256_mont_mul_order_5(t2, t2, t);
wolfSSL 14:167253f4e170 10907 /* t2= a^ffffffff00000000ffffffffffffffffbce6 */
wolfSSL 14:167253f4e170 10908 for (i=127; i>=112; i--) {
wolfSSL 14:167253f4e170 10909 sp_256_mont_sqr_order_5(t2, t2);
wolfSSL 14:167253f4e170 10910 if (p256_order_low[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 10911 sp_256_mont_mul_order_5(t2, t2, a);
wolfSSL 14:167253f4e170 10912 }
wolfSSL 14:167253f4e170 10913 /* t2= a^ffffffff00000000ffffffffffffffffbce6f */
wolfSSL 14:167253f4e170 10914 sp_256_mont_sqr_n_order_5(t2, t2, 4);
wolfSSL 14:167253f4e170 10915 sp_256_mont_mul_order_5(t2, t2, t3);
wolfSSL 14:167253f4e170 10916 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */
wolfSSL 14:167253f4e170 10917 for (i=107; i>=64; i--) {
wolfSSL 14:167253f4e170 10918 sp_256_mont_sqr_order_5(t2, t2);
wolfSSL 14:167253f4e170 10919 if (p256_order_low[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 10920 sp_256_mont_mul_order_5(t2, t2, a);
wolfSSL 14:167253f4e170 10921 }
wolfSSL 14:167253f4e170 10922 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */
wolfSSL 14:167253f4e170 10923 sp_256_mont_sqr_n_order_5(t2, t2, 4);
wolfSSL 14:167253f4e170 10924 sp_256_mont_mul_order_5(t2, t2, t3);
wolfSSL 14:167253f4e170 10925 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */
wolfSSL 14:167253f4e170 10926 for (i=59; i>=32; i--) {
wolfSSL 14:167253f4e170 10927 sp_256_mont_sqr_order_5(t2, t2);
wolfSSL 14:167253f4e170 10928 if (p256_order_low[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 10929 sp_256_mont_mul_order_5(t2, t2, a);
wolfSSL 14:167253f4e170 10930 }
wolfSSL 14:167253f4e170 10931 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */
wolfSSL 14:167253f4e170 10932 sp_256_mont_sqr_n_order_5(t2, t2, 4);
wolfSSL 14:167253f4e170 10933 sp_256_mont_mul_order_5(t2, t2, t3);
wolfSSL 14:167253f4e170 10934 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */
wolfSSL 14:167253f4e170 10935 for (i=27; i>=0; i--) {
wolfSSL 14:167253f4e170 10936 sp_256_mont_sqr_order_5(t2, t2);
wolfSSL 14:167253f4e170 10937 if (p256_order_low[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 10938 sp_256_mont_mul_order_5(t2, t2, a);
wolfSSL 14:167253f4e170 10939 }
wolfSSL 14:167253f4e170 10940 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */
wolfSSL 14:167253f4e170 10941 sp_256_mont_sqr_n_order_5(t2, t2, 4);
wolfSSL 14:167253f4e170 10942 /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */
wolfSSL 14:167253f4e170 10943 sp_256_mont_mul_order_5(r, t2, t3);
wolfSSL 14:167253f4e170 10944 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 10945 }
wolfSSL 14:167253f4e170 10946
wolfSSL 14:167253f4e170 10947 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 10948 /* Multiply two number mod the order of P256 curve. (r = a * b mod order)
wolfSSL 14:167253f4e170 10949 *
wolfSSL 14:167253f4e170 10950 * r Result of the multiplication.
wolfSSL 14:167253f4e170 10951 * a First operand of the multiplication.
wolfSSL 14:167253f4e170 10952 * b Second operand of the multiplication.
wolfSSL 14:167253f4e170 10953 */
wolfSSL 14:167253f4e170 10954 static void sp_256_mont_mul_order_avx2_5(sp_digit* r, sp_digit* a, sp_digit* b)
wolfSSL 14:167253f4e170 10955 {
wolfSSL 14:167253f4e170 10956 sp_256_mul_avx2_5(r, a, b);
wolfSSL 14:167253f4e170 10957 sp_256_mont_reduce_avx2_5(r, p256_order, p256_mp_order);
wolfSSL 14:167253f4e170 10958 }
wolfSSL 14:167253f4e170 10959
wolfSSL 14:167253f4e170 10960 /* Square number mod the order of P256 curve. (r = a * a mod order)
wolfSSL 14:167253f4e170 10961 *
wolfSSL 14:167253f4e170 10962 * r Result of the squaring.
wolfSSL 14:167253f4e170 10963 * a Number to square.
wolfSSL 14:167253f4e170 10964 */
wolfSSL 14:167253f4e170 10965 static void sp_256_mont_sqr_order_avx2_5(sp_digit* r, sp_digit* a)
wolfSSL 14:167253f4e170 10966 {
wolfSSL 14:167253f4e170 10967 sp_256_sqr_avx2_5(r, a);
wolfSSL 14:167253f4e170 10968 sp_256_mont_reduce_avx2_5(r, p256_order, p256_mp_order);
wolfSSL 14:167253f4e170 10969 }
wolfSSL 14:167253f4e170 10970
wolfSSL 14:167253f4e170 10971 #ifndef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 10972 /* Square number mod the order of P256 curve a number of times.
wolfSSL 14:167253f4e170 10973 * (r = a ^ n mod order)
wolfSSL 14:167253f4e170 10974 *
wolfSSL 14:167253f4e170 10975 * r Result of the squaring.
wolfSSL 14:167253f4e170 10976 * a Number to square.
wolfSSL 14:167253f4e170 10977 */
wolfSSL 14:167253f4e170 10978 static void sp_256_mont_sqr_n_order_avx2_5(sp_digit* r, sp_digit* a, int n)
wolfSSL 14:167253f4e170 10979 {
wolfSSL 14:167253f4e170 10980 int i;
wolfSSL 14:167253f4e170 10981
wolfSSL 14:167253f4e170 10982 sp_256_mont_sqr_order_avx2_5(r, a);
wolfSSL 14:167253f4e170 10983 for (i=1; i<n; i++)
wolfSSL 14:167253f4e170 10984 sp_256_mont_sqr_order_avx2_5(r, r);
wolfSSL 14:167253f4e170 10985 }
wolfSSL 14:167253f4e170 10986 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 10987
wolfSSL 14:167253f4e170 10988 /* Invert the number, in Montgomery form, modulo the order of the P256 curve.
wolfSSL 14:167253f4e170 10989 * (r = 1 / a mod order)
wolfSSL 14:167253f4e170 10990 *
wolfSSL 14:167253f4e170 10991 * r Inverse result.
wolfSSL 14:167253f4e170 10992 * a Number to invert.
wolfSSL 14:167253f4e170 10993 * td Temporary data.
wolfSSL 14:167253f4e170 10994 */
wolfSSL 14:167253f4e170 10995 static void sp_256_mont_inv_order_avx2_5(sp_digit* r, sp_digit* a,
wolfSSL 14:167253f4e170 10996 sp_digit* td)
wolfSSL 14:167253f4e170 10997 {
wolfSSL 14:167253f4e170 10998 #ifdef WOLFSSL_SP_SMALL
wolfSSL 14:167253f4e170 10999 sp_digit* t = td;
wolfSSL 14:167253f4e170 11000 int i;
wolfSSL 14:167253f4e170 11001
wolfSSL 14:167253f4e170 11002 XMEMCPY(t, a, sizeof(sp_digit) * 5);
wolfSSL 14:167253f4e170 11003 for (i=254; i>=0; i--) {
wolfSSL 14:167253f4e170 11004 sp_256_mont_sqr_order_avx2_5(t, t);
wolfSSL 14:167253f4e170 11005 if (p256_order_2[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 11006 sp_256_mont_mul_order_avx2_5(t, t, a);
wolfSSL 14:167253f4e170 11007 }
wolfSSL 14:167253f4e170 11008 XMEMCPY(r, t, sizeof(sp_digit) * 5);
wolfSSL 14:167253f4e170 11009 #else
wolfSSL 14:167253f4e170 11010 sp_digit* t = td;
wolfSSL 14:167253f4e170 11011 sp_digit* t2 = td + 2 * 5;
wolfSSL 14:167253f4e170 11012 sp_digit* t3 = td + 4 * 5;
wolfSSL 14:167253f4e170 11013 int i;
wolfSSL 14:167253f4e170 11014
wolfSSL 14:167253f4e170 11015 /* t = a^2 */
wolfSSL 14:167253f4e170 11016 sp_256_mont_sqr_order_avx2_5(t, a);
wolfSSL 14:167253f4e170 11017 /* t = a^3 = t * a */
wolfSSL 14:167253f4e170 11018 sp_256_mont_mul_order_avx2_5(t, t, a);
wolfSSL 14:167253f4e170 11019 /* t2= a^c = t ^ 2 ^ 2 */
wolfSSL 14:167253f4e170 11020 sp_256_mont_sqr_n_order_avx2_5(t2, t, 2);
wolfSSL 14:167253f4e170 11021 /* t3= a^f = t2 * t */
wolfSSL 14:167253f4e170 11022 sp_256_mont_mul_order_avx2_5(t3, t2, t);
wolfSSL 14:167253f4e170 11023 /* t2= a^f0 = t3 ^ 2 ^ 4 */
wolfSSL 14:167253f4e170 11024 sp_256_mont_sqr_n_order_avx2_5(t2, t3, 4);
wolfSSL 14:167253f4e170 11025 /* t = a^ff = t2 * t3 */
wolfSSL 14:167253f4e170 11026 sp_256_mont_mul_order_avx2_5(t, t2, t3);
wolfSSL 14:167253f4e170 11027 /* t3= a^ff00 = t ^ 2 ^ 8 */
wolfSSL 14:167253f4e170 11028 sp_256_mont_sqr_n_order_avx2_5(t2, t, 8);
wolfSSL 14:167253f4e170 11029 /* t = a^ffff = t2 * t */
wolfSSL 14:167253f4e170 11030 sp_256_mont_mul_order_avx2_5(t, t2, t);
wolfSSL 14:167253f4e170 11031 /* t2= a^ffff0000 = t ^ 2 ^ 16 */
wolfSSL 14:167253f4e170 11032 sp_256_mont_sqr_n_order_avx2_5(t2, t, 16);
wolfSSL 14:167253f4e170 11033 /* t = a^ffffffff = t2 * t */
wolfSSL 14:167253f4e170 11034 sp_256_mont_mul_order_avx2_5(t, t2, t);
wolfSSL 14:167253f4e170 11035 /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64 */
wolfSSL 14:167253f4e170 11036 sp_256_mont_sqr_n_order_avx2_5(t2, t, 64);
wolfSSL 14:167253f4e170 11037 /* t2= a^ffffffff00000000ffffffff = t2 * t */
wolfSSL 14:167253f4e170 11038 sp_256_mont_mul_order_avx2_5(t2, t2, t);
wolfSSL 14:167253f4e170 11039 /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32 */
wolfSSL 14:167253f4e170 11040 sp_256_mont_sqr_n_order_avx2_5(t2, t2, 32);
wolfSSL 14:167253f4e170 11041 /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */
wolfSSL 14:167253f4e170 11042 sp_256_mont_mul_order_avx2_5(t2, t2, t);
wolfSSL 14:167253f4e170 11043 /* t2= a^ffffffff00000000ffffffffffffffffbce6 */
wolfSSL 14:167253f4e170 11044 for (i=127; i>=112; i--) {
wolfSSL 14:167253f4e170 11045 sp_256_mont_sqr_order_avx2_5(t2, t2);
wolfSSL 14:167253f4e170 11046 if (p256_order_low[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 11047 sp_256_mont_mul_order_avx2_5(t2, t2, a);
wolfSSL 14:167253f4e170 11048 }
wolfSSL 14:167253f4e170 11049 /* t2= a^ffffffff00000000ffffffffffffffffbce6f */
wolfSSL 14:167253f4e170 11050 sp_256_mont_sqr_n_order_avx2_5(t2, t2, 4);
wolfSSL 14:167253f4e170 11051 sp_256_mont_mul_order_avx2_5(t2, t2, t3);
wolfSSL 14:167253f4e170 11052 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */
wolfSSL 14:167253f4e170 11053 for (i=107; i>=64; i--) {
wolfSSL 14:167253f4e170 11054 sp_256_mont_sqr_order_avx2_5(t2, t2);
wolfSSL 14:167253f4e170 11055 if (p256_order_low[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 11056 sp_256_mont_mul_order_avx2_5(t2, t2, a);
wolfSSL 14:167253f4e170 11057 }
wolfSSL 14:167253f4e170 11058 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */
wolfSSL 14:167253f4e170 11059 sp_256_mont_sqr_n_order_avx2_5(t2, t2, 4);
wolfSSL 14:167253f4e170 11060 sp_256_mont_mul_order_avx2_5(t2, t2, t3);
wolfSSL 14:167253f4e170 11061 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */
wolfSSL 14:167253f4e170 11062 for (i=59; i>=32; i--) {
wolfSSL 14:167253f4e170 11063 sp_256_mont_sqr_order_avx2_5(t2, t2);
wolfSSL 14:167253f4e170 11064 if (p256_order_low[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 11065 sp_256_mont_mul_order_avx2_5(t2, t2, a);
wolfSSL 14:167253f4e170 11066 }
wolfSSL 14:167253f4e170 11067 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */
wolfSSL 14:167253f4e170 11068 sp_256_mont_sqr_n_order_avx2_5(t2, t2, 4);
wolfSSL 14:167253f4e170 11069 sp_256_mont_mul_order_avx2_5(t2, t2, t3);
wolfSSL 14:167253f4e170 11070 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */
wolfSSL 14:167253f4e170 11071 for (i=27; i>=0; i--) {
wolfSSL 14:167253f4e170 11072 sp_256_mont_sqr_order_avx2_5(t2, t2);
wolfSSL 14:167253f4e170 11073 if (p256_order_low[i / 64] & ((sp_digit)1 << (i % 64)))
wolfSSL 14:167253f4e170 11074 sp_256_mont_mul_order_avx2_5(t2, t2, a);
wolfSSL 14:167253f4e170 11075 }
wolfSSL 14:167253f4e170 11076 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */
wolfSSL 14:167253f4e170 11077 sp_256_mont_sqr_n_order_avx2_5(t2, t2, 4);
wolfSSL 14:167253f4e170 11078 /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */
wolfSSL 14:167253f4e170 11079 sp_256_mont_mul_order_avx2_5(r, t2, t3);
wolfSSL 14:167253f4e170 11080 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 14:167253f4e170 11081 }
wolfSSL 14:167253f4e170 11082
wolfSSL 14:167253f4e170 11083 #endif /* HAVE_INTEL_AVX2 */
wolfSSL 14:167253f4e170 11084 #endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */
wolfSSL 14:167253f4e170 11085 #ifdef HAVE_ECC_SIGN
wolfSSL 14:167253f4e170 11086 #ifndef SP_ECC_MAX_SIG_GEN
wolfSSL 14:167253f4e170 11087 #define SP_ECC_MAX_SIG_GEN 64
wolfSSL 14:167253f4e170 11088 #endif
wolfSSL 14:167253f4e170 11089
wolfSSL 14:167253f4e170 11090 /* Sign the hash using the private key.
wolfSSL 14:167253f4e170 11091 * e = [hash, 256 bits] from binary
wolfSSL 14:167253f4e170 11092 * r = (k.G)->x mod order
wolfSSL 14:167253f4e170 11093 * s = (r * x + e) / k mod order
wolfSSL 14:167253f4e170 11094 * The hash is truncated to the first 256 bits.
wolfSSL 14:167253f4e170 11095 *
wolfSSL 14:167253f4e170 11096 * hash Hash to sign.
wolfSSL 14:167253f4e170 11097 * hashLen Length of the hash data.
wolfSSL 14:167253f4e170 11098 * rng Random number generator.
wolfSSL 14:167253f4e170 11099 * priv Private part of key - scalar.
wolfSSL 14:167253f4e170 11100 * rm First part of result as an mp_int.
wolfSSL 14:167253f4e170 11101 * sm Sirst part of result as an mp_int.
wolfSSL 14:167253f4e170 11102 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 11103 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 14:167253f4e170 11104 * MP_OKAY on success.
wolfSSL 14:167253f4e170 11105 */
wolfSSL 14:167253f4e170 11106 int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
wolfSSL 14:167253f4e170 11107 mp_int* rm, mp_int* sm, void* heap)
wolfSSL 14:167253f4e170 11108 {
wolfSSL 14:167253f4e170 11109 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11110 sp_digit* d;
wolfSSL 14:167253f4e170 11111 #else
wolfSSL 14:167253f4e170 11112 sp_digit ed[2*5];
wolfSSL 14:167253f4e170 11113 sp_digit xd[2*5];
wolfSSL 14:167253f4e170 11114 sp_digit kd[2*5];
wolfSSL 14:167253f4e170 11115 sp_digit rd[2*5];
wolfSSL 14:167253f4e170 11116 sp_digit td[3 * 2*5];
wolfSSL 14:167253f4e170 11117 sp_point p;
wolfSSL 14:167253f4e170 11118 #endif
wolfSSL 14:167253f4e170 11119 sp_digit* e = NULL;
wolfSSL 14:167253f4e170 11120 sp_digit* x = NULL;
wolfSSL 14:167253f4e170 11121 sp_digit* k = NULL;
wolfSSL 14:167253f4e170 11122 sp_digit* r = NULL;
wolfSSL 14:167253f4e170 11123 sp_digit* tmp = NULL;
wolfSSL 14:167253f4e170 11124 sp_point* point = NULL;
wolfSSL 14:167253f4e170 11125 sp_digit carry;
wolfSSL 14:167253f4e170 11126 sp_digit* s;
wolfSSL 14:167253f4e170 11127 sp_digit* kInv;
wolfSSL 14:167253f4e170 11128 int err = MP_OKAY;
wolfSSL 14:167253f4e170 11129 int64_t c;
wolfSSL 14:167253f4e170 11130 int i;
wolfSSL 14:167253f4e170 11131 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11132 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11133 #endif
wolfSSL 14:167253f4e170 11134
wolfSSL 14:167253f4e170 11135 (void)heap;
wolfSSL 14:167253f4e170 11136
wolfSSL 14:167253f4e170 11137 err = sp_ecc_point_new(heap, p, point);
wolfSSL 14:167253f4e170 11138 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11139 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11140 d = XMALLOC(sizeof(sp_digit) * 7 * 2 * 5, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11141 if (d != NULL) {
wolfSSL 14:167253f4e170 11142 e = d + 0 * 5;
wolfSSL 14:167253f4e170 11143 x = d + 2 * 5;
wolfSSL 14:167253f4e170 11144 k = d + 4 * 5;
wolfSSL 14:167253f4e170 11145 r = d + 6 * 5;
wolfSSL 14:167253f4e170 11146 tmp = d + 8 * 5;
wolfSSL 14:167253f4e170 11147 }
wolfSSL 14:167253f4e170 11148 else
wolfSSL 14:167253f4e170 11149 err = MEMORY_E;
wolfSSL 14:167253f4e170 11150 }
wolfSSL 14:167253f4e170 11151 #else
wolfSSL 14:167253f4e170 11152 e = ed;
wolfSSL 14:167253f4e170 11153 x = xd;
wolfSSL 14:167253f4e170 11154 k = kd;
wolfSSL 14:167253f4e170 11155 r = rd;
wolfSSL 14:167253f4e170 11156 tmp = td;
wolfSSL 14:167253f4e170 11157 #endif
wolfSSL 14:167253f4e170 11158 s = e;
wolfSSL 14:167253f4e170 11159 kInv = k;
wolfSSL 14:167253f4e170 11160
wolfSSL 14:167253f4e170 11161 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11162 if (hashLen > 32)
wolfSSL 14:167253f4e170 11163 hashLen = 32;
wolfSSL 14:167253f4e170 11164
wolfSSL 14:167253f4e170 11165 sp_256_from_bin(e, 5, hash, hashLen);
wolfSSL 14:167253f4e170 11166 sp_256_from_mp(x, 5, priv);
wolfSSL 14:167253f4e170 11167 }
wolfSSL 14:167253f4e170 11168
wolfSSL 14:167253f4e170 11169 for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {
wolfSSL 14:167253f4e170 11170 /* New random point. */
wolfSSL 14:167253f4e170 11171 err = sp_256_ecc_gen_k_5(rng, k);
wolfSSL 14:167253f4e170 11172 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11173 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11174 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11175 err = sp_256_ecc_mulmod_base_avx2_5(point, k, 1, heap);
wolfSSL 14:167253f4e170 11176 else
wolfSSL 14:167253f4e170 11177 #endif
wolfSSL 14:167253f4e170 11178 err = sp_256_ecc_mulmod_base_5(point, k, 1, NULL);
wolfSSL 14:167253f4e170 11179 }
wolfSSL 14:167253f4e170 11180
wolfSSL 14:167253f4e170 11181 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11182 /* r = point->x mod order */
wolfSSL 14:167253f4e170 11183 XMEMCPY(r, point->x, sizeof(sp_digit) * 5);
wolfSSL 14:167253f4e170 11184 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 11185 c = sp_256_cmp_5(r, p256_order);
wolfSSL 14:167253f4e170 11186 sp_256_cond_sub_5(r, r, p256_order, 0 - (c >= 0));
wolfSSL 14:167253f4e170 11187 sp_256_norm_5(r);
wolfSSL 14:167253f4e170 11188
wolfSSL 14:167253f4e170 11189 /* Conv k to Montgomery form (mod order) */
wolfSSL 14:167253f4e170 11190 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11191 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11192 sp_256_mul_avx2_5(k, k, p256_norm_order);
wolfSSL 14:167253f4e170 11193 else
wolfSSL 14:167253f4e170 11194 #endif
wolfSSL 14:167253f4e170 11195 sp_256_mul_5(k, k, p256_norm_order);
wolfSSL 14:167253f4e170 11196 err = sp_256_mod_5(k, k, p256_order);
wolfSSL 14:167253f4e170 11197 }
wolfSSL 14:167253f4e170 11198 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11199 sp_256_norm_5(k);
wolfSSL 14:167253f4e170 11200 /* kInv = 1/k mod order */
wolfSSL 14:167253f4e170 11201 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11202 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11203 sp_256_mont_inv_order_avx2_5(kInv, k, tmp);
wolfSSL 14:167253f4e170 11204 else
wolfSSL 14:167253f4e170 11205 #endif
wolfSSL 14:167253f4e170 11206 sp_256_mont_inv_order_5(kInv, k, tmp);
wolfSSL 14:167253f4e170 11207 sp_256_norm_5(kInv);
wolfSSL 14:167253f4e170 11208
wolfSSL 14:167253f4e170 11209 /* s = r * x + e */
wolfSSL 14:167253f4e170 11210 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11211 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11212 sp_256_mul_avx2_5(x, x, r);
wolfSSL 14:167253f4e170 11213 else
wolfSSL 14:167253f4e170 11214 #endif
wolfSSL 14:167253f4e170 11215 sp_256_mul_5(x, x, r);
wolfSSL 14:167253f4e170 11216 err = sp_256_mod_5(x, x, p256_order);
wolfSSL 14:167253f4e170 11217 }
wolfSSL 14:167253f4e170 11218 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11219 sp_256_norm_5(x);
wolfSSL 14:167253f4e170 11220 carry = sp_256_add_5(s, e, x);
wolfSSL 14:167253f4e170 11221 sp_256_cond_sub_5(s, s, p256_order, 0 - carry);
wolfSSL 14:167253f4e170 11222 sp_256_norm_5(s);
wolfSSL 14:167253f4e170 11223 c = sp_256_cmp_5(s, p256_order);
wolfSSL 14:167253f4e170 11224 sp_256_cond_sub_5(s, s, p256_order, 0 - (c >= 0));
wolfSSL 14:167253f4e170 11225 sp_256_norm_5(s);
wolfSSL 14:167253f4e170 11226
wolfSSL 14:167253f4e170 11227 /* s = s * k^-1 mod order */
wolfSSL 14:167253f4e170 11228 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11229 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11230 sp_256_mont_mul_order_avx2_5(s, s, kInv);
wolfSSL 14:167253f4e170 11231 else
wolfSSL 14:167253f4e170 11232 #endif
wolfSSL 14:167253f4e170 11233 sp_256_mont_mul_order_5(s, s, kInv);
wolfSSL 14:167253f4e170 11234 sp_256_norm_5(s);
wolfSSL 14:167253f4e170 11235
wolfSSL 14:167253f4e170 11236 /* Check that signature is usable. */
wolfSSL 14:167253f4e170 11237 if (!sp_256_iszero_5(s))
wolfSSL 14:167253f4e170 11238 break;
wolfSSL 14:167253f4e170 11239 }
wolfSSL 14:167253f4e170 11240 }
wolfSSL 14:167253f4e170 11241
wolfSSL 14:167253f4e170 11242 if (i == 0)
wolfSSL 14:167253f4e170 11243 err = RNG_FAILURE_E;
wolfSSL 14:167253f4e170 11244
wolfSSL 14:167253f4e170 11245 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11246 err = sp_256_to_mp(r, rm);
wolfSSL 14:167253f4e170 11247 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11248 err = sp_256_to_mp(s, sm);
wolfSSL 14:167253f4e170 11249
wolfSSL 14:167253f4e170 11250 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11251 if (d != NULL) {
wolfSSL 14:167253f4e170 11252 XMEMSET(d, 0, sizeof(sp_digit) * 8 * 5);
wolfSSL 14:167253f4e170 11253 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11254 }
wolfSSL 14:167253f4e170 11255 #else
wolfSSL 14:167253f4e170 11256 XMEMSET(e, 0, sizeof(sp_digit) * 2 * 5);
wolfSSL 14:167253f4e170 11257 XMEMSET(x, 0, sizeof(sp_digit) * 2 * 5);
wolfSSL 14:167253f4e170 11258 XMEMSET(k, 0, sizeof(sp_digit) * 2 * 5);
wolfSSL 14:167253f4e170 11259 XMEMSET(r, 0, sizeof(sp_digit) * 2 * 5);
wolfSSL 14:167253f4e170 11260 XMEMSET(r, 0, sizeof(sp_digit) * 2 * 5);
wolfSSL 14:167253f4e170 11261 XMEMSET(tmp, 0, sizeof(sp_digit) * 3 * 2*5);
wolfSSL 14:167253f4e170 11262 #endif
wolfSSL 14:167253f4e170 11263 sp_ecc_point_free(point, 1, heap);
wolfSSL 14:167253f4e170 11264
wolfSSL 14:167253f4e170 11265 return err;
wolfSSL 14:167253f4e170 11266 }
wolfSSL 14:167253f4e170 11267 #endif /* HAVE_ECC_SIGN */
wolfSSL 14:167253f4e170 11268
wolfSSL 14:167253f4e170 11269 #ifdef HAVE_ECC_VERIFY
wolfSSL 14:167253f4e170 11270 /* Verify the signature values with the hash and public key.
wolfSSL 14:167253f4e170 11271 * e = Truncate(hash, 256)
wolfSSL 14:167253f4e170 11272 * u1 = e/s mod order
wolfSSL 14:167253f4e170 11273 * u2 = r/s mod order
wolfSSL 14:167253f4e170 11274 * r == (u1.G + u2.Q)->x mod order
wolfSSL 14:167253f4e170 11275 * Optimization: Leave point in projective form.
wolfSSL 14:167253f4e170 11276 * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
wolfSSL 14:167253f4e170 11277 * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
wolfSSL 14:167253f4e170 11278 * The hash is truncated to the first 256 bits.
wolfSSL 14:167253f4e170 11279 *
wolfSSL 14:167253f4e170 11280 * hash Hash to sign.
wolfSSL 14:167253f4e170 11281 * hashLen Length of the hash data.
wolfSSL 14:167253f4e170 11282 * rng Random number generator.
wolfSSL 14:167253f4e170 11283 * priv Private part of key - scalar.
wolfSSL 14:167253f4e170 11284 * rm First part of result as an mp_int.
wolfSSL 14:167253f4e170 11285 * sm Sirst part of result as an mp_int.
wolfSSL 14:167253f4e170 11286 * heap Heap to use for allocation.
wolfSSL 14:167253f4e170 11287 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 14:167253f4e170 11288 * MP_OKAY on success.
wolfSSL 14:167253f4e170 11289 */
wolfSSL 14:167253f4e170 11290 int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
wolfSSL 14:167253f4e170 11291 mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)
wolfSSL 14:167253f4e170 11292 {
wolfSSL 14:167253f4e170 11293 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11294 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 11295 #else
wolfSSL 14:167253f4e170 11296 sp_digit u1d[2*5];
wolfSSL 14:167253f4e170 11297 sp_digit u2d[2*5];
wolfSSL 14:167253f4e170 11298 sp_digit sd[2*5];
wolfSSL 14:167253f4e170 11299 sp_digit tmpd[2*5 * 5];
wolfSSL 14:167253f4e170 11300 sp_point p1d;
wolfSSL 14:167253f4e170 11301 sp_point p2d;
wolfSSL 14:167253f4e170 11302 #endif
wolfSSL 14:167253f4e170 11303 sp_digit* u1;
wolfSSL 14:167253f4e170 11304 sp_digit* u2;
wolfSSL 14:167253f4e170 11305 sp_digit* s;
wolfSSL 14:167253f4e170 11306 sp_digit* tmp;
wolfSSL 14:167253f4e170 11307 sp_point* p1;
wolfSSL 14:167253f4e170 11308 sp_point* p2 = NULL;
wolfSSL 14:167253f4e170 11309 sp_digit carry;
wolfSSL 14:167253f4e170 11310 int64_t c;
wolfSSL 14:167253f4e170 11311 int err;
wolfSSL 14:167253f4e170 11312 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11313 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11314 #endif
wolfSSL 14:167253f4e170 11315
wolfSSL 14:167253f4e170 11316 err = sp_ecc_point_new(heap, p1d, p1);
wolfSSL 14:167253f4e170 11317 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11318 err = sp_ecc_point_new(heap, p2d, p2);
wolfSSL 14:167253f4e170 11319 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11320 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11321 d = XMALLOC(sizeof(sp_digit) * 16 * 5, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11322 if (d != NULL) {
wolfSSL 14:167253f4e170 11323 u1 = d + 0 * 5;
wolfSSL 14:167253f4e170 11324 u2 = d + 2 * 5;
wolfSSL 14:167253f4e170 11325 s = d + 4 * 5;
wolfSSL 14:167253f4e170 11326 tmp = d + 6 * 5;
wolfSSL 14:167253f4e170 11327 }
wolfSSL 14:167253f4e170 11328 else
wolfSSL 14:167253f4e170 11329 err = MEMORY_E;
wolfSSL 14:167253f4e170 11330 }
wolfSSL 14:167253f4e170 11331 #else
wolfSSL 14:167253f4e170 11332 u1 = u1d;
wolfSSL 14:167253f4e170 11333 u2 = u2d;
wolfSSL 14:167253f4e170 11334 s = sd;
wolfSSL 14:167253f4e170 11335 tmp = tmpd;
wolfSSL 14:167253f4e170 11336 #endif
wolfSSL 14:167253f4e170 11337
wolfSSL 14:167253f4e170 11338 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11339 if (hashLen > 32)
wolfSSL 14:167253f4e170 11340 hashLen = 32;
wolfSSL 14:167253f4e170 11341
wolfSSL 14:167253f4e170 11342 sp_256_from_bin(u1, 5, hash, hashLen);
wolfSSL 14:167253f4e170 11343 sp_256_from_mp(u2, 5, r);
wolfSSL 14:167253f4e170 11344 sp_256_from_mp(s, 5, sm);
wolfSSL 14:167253f4e170 11345 sp_256_from_mp(p2->x, 5, pX);
wolfSSL 14:167253f4e170 11346 sp_256_from_mp(p2->y, 5, pY);
wolfSSL 14:167253f4e170 11347 sp_256_from_mp(p2->z, 5, pZ);
wolfSSL 14:167253f4e170 11348
wolfSSL 14:167253f4e170 11349 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11350 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11351 sp_256_mul_avx2_5(s, s, p256_norm_order);
wolfSSL 14:167253f4e170 11352 else
wolfSSL 14:167253f4e170 11353 #endif
wolfSSL 14:167253f4e170 11354 sp_256_mul_5(s, s, p256_norm_order);
wolfSSL 14:167253f4e170 11355 err = sp_256_mod_5(s, s, p256_order);
wolfSSL 14:167253f4e170 11356 }
wolfSSL 14:167253f4e170 11357 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11358 sp_256_norm_5(s);
wolfSSL 14:167253f4e170 11359 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11360 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {
wolfSSL 14:167253f4e170 11361 sp_256_mont_inv_order_avx2_5(s, s, tmp);
wolfSSL 14:167253f4e170 11362 sp_256_mont_mul_order_avx2_5(u1, u1, s);
wolfSSL 14:167253f4e170 11363 sp_256_mont_mul_order_avx2_5(u2, u2, s);
wolfSSL 14:167253f4e170 11364 }
wolfSSL 14:167253f4e170 11365 else
wolfSSL 14:167253f4e170 11366 #endif
wolfSSL 14:167253f4e170 11367 {
wolfSSL 14:167253f4e170 11368 sp_256_mont_inv_order_5(s, s, tmp);
wolfSSL 14:167253f4e170 11369 sp_256_mont_mul_order_5(u1, u1, s);
wolfSSL 14:167253f4e170 11370 sp_256_mont_mul_order_5(u2, u2, s);
wolfSSL 14:167253f4e170 11371 }
wolfSSL 14:167253f4e170 11372
wolfSSL 14:167253f4e170 11373 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11374 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11375 err = sp_256_ecc_mulmod_base_avx2_5(p1, u1, 0, heap);
wolfSSL 14:167253f4e170 11376 else
wolfSSL 14:167253f4e170 11377 #endif
wolfSSL 14:167253f4e170 11378 err = sp_256_ecc_mulmod_base_5(p1, u1, 0, heap);
wolfSSL 14:167253f4e170 11379 }
wolfSSL 14:167253f4e170 11380 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11381 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11382 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11383 err = sp_256_ecc_mulmod_avx2_5(p2, p2, u2, 0, heap);
wolfSSL 14:167253f4e170 11384 else
wolfSSL 14:167253f4e170 11385 #endif
wolfSSL 14:167253f4e170 11386 err = sp_256_ecc_mulmod_5(p2, p2, u2, 0, heap);
wolfSSL 14:167253f4e170 11387 }
wolfSSL 14:167253f4e170 11388
wolfSSL 14:167253f4e170 11389 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11390 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11391 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11392 sp_256_proj_point_add_avx2_5(p1, p1, p2, tmp);
wolfSSL 14:167253f4e170 11393 else
wolfSSL 14:167253f4e170 11394 #endif
wolfSSL 14:167253f4e170 11395 sp_256_proj_point_add_5(p1, p1, p2, tmp);
wolfSSL 14:167253f4e170 11396
wolfSSL 14:167253f4e170 11397 /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
wolfSSL 14:167253f4e170 11398 /* Reload r and convert to Montgomery form. */
wolfSSL 14:167253f4e170 11399 sp_256_from_mp(u2, 5, r);
wolfSSL 14:167253f4e170 11400 err = sp_256_mod_mul_norm_5(u2, u2, p256_mod);
wolfSSL 14:167253f4e170 11401 }
wolfSSL 14:167253f4e170 11402
wolfSSL 14:167253f4e170 11403 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11404 /* u1 = r.z'.z' mod prime */
wolfSSL 14:167253f4e170 11405 sp_256_mont_sqr_5(p1->z, p1->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11406 sp_256_mont_mul_5(u1, u2, p1->z, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11407 *res = sp_256_cmp_5(p1->x, u1) == 0;
wolfSSL 14:167253f4e170 11408 if (*res == 0) {
wolfSSL 14:167253f4e170 11409 /* Reload r and add order. */
wolfSSL 14:167253f4e170 11410 sp_256_from_mp(u2, 5, r);
wolfSSL 14:167253f4e170 11411 carry = sp_256_add_5(u2, u2, p256_order);
wolfSSL 14:167253f4e170 11412 /* Carry means result is greater than mod and is not valid. */
wolfSSL 14:167253f4e170 11413 if (!carry) {
wolfSSL 14:167253f4e170 11414 sp_256_norm_5(u2);
wolfSSL 14:167253f4e170 11415
wolfSSL 14:167253f4e170 11416 /* Compare with mod and if greater or equal then not valid. */
wolfSSL 14:167253f4e170 11417 c = sp_256_cmp_5(u2, p256_mod);
wolfSSL 14:167253f4e170 11418 if (c < 0) {
wolfSSL 14:167253f4e170 11419 /* Convert to Montogomery form */
wolfSSL 14:167253f4e170 11420 err = sp_256_mod_mul_norm_5(u2, u2, p256_mod);
wolfSSL 14:167253f4e170 11421 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11422 /* u1 = (r + 1*order).z'.z' mod prime */
wolfSSL 14:167253f4e170 11423 sp_256_mont_mul_5(u1, u2, p1->z, p256_mod,
wolfSSL 14:167253f4e170 11424 p256_mp_mod);
wolfSSL 14:167253f4e170 11425 *res = sp_256_cmp_5(p1->x, u2) == 0;
wolfSSL 14:167253f4e170 11426 }
wolfSSL 14:167253f4e170 11427 }
wolfSSL 14:167253f4e170 11428 }
wolfSSL 14:167253f4e170 11429 }
wolfSSL 14:167253f4e170 11430 }
wolfSSL 14:167253f4e170 11431
wolfSSL 14:167253f4e170 11432 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11433 if (d != NULL)
wolfSSL 14:167253f4e170 11434 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11435 #endif
wolfSSL 14:167253f4e170 11436 sp_ecc_point_free(p1, 0, heap);
wolfSSL 14:167253f4e170 11437 sp_ecc_point_free(p2, 0, heap);
wolfSSL 14:167253f4e170 11438
wolfSSL 14:167253f4e170 11439 return err;
wolfSSL 14:167253f4e170 11440 }
wolfSSL 14:167253f4e170 11441 #endif /* HAVE_ECC_VERIFY */
wolfSSL 14:167253f4e170 11442
wolfSSL 14:167253f4e170 11443 #ifdef HAVE_ECC_CHECK_KEY
wolfSSL 14:167253f4e170 11444 /* Check that the x and y oridinates are a valid point on the curve.
wolfSSL 14:167253f4e170 11445 *
wolfSSL 14:167253f4e170 11446 * point EC point.
wolfSSL 14:167253f4e170 11447 * heap Heap to use if dynamically allocating.
wolfSSL 14:167253f4e170 11448 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 14:167253f4e170 11449 * not on the curve and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11450 */
wolfSSL 14:167253f4e170 11451 static int sp_256_ecc_is_point_5(sp_point* point, void* heap)
wolfSSL 14:167253f4e170 11452 {
wolfSSL 14:167253f4e170 11453 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11454 sp_digit* d = NULL;
wolfSSL 14:167253f4e170 11455 #else
wolfSSL 14:167253f4e170 11456 sp_digit t1d[2*5];
wolfSSL 14:167253f4e170 11457 sp_digit t2d[2*5];
wolfSSL 14:167253f4e170 11458 #endif
wolfSSL 14:167253f4e170 11459 sp_digit* t1;
wolfSSL 14:167253f4e170 11460 sp_digit* t2;
wolfSSL 14:167253f4e170 11461 int err = MP_OKAY;
wolfSSL 14:167253f4e170 11462
wolfSSL 14:167253f4e170 11463 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11464 d = XMALLOC(sizeof(sp_digit) * 5 * 4, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11465 if (d != NULL) {
wolfSSL 14:167253f4e170 11466 t1 = d + 0 * 5;
wolfSSL 14:167253f4e170 11467 t2 = d + 2 * 5;
wolfSSL 14:167253f4e170 11468 }
wolfSSL 14:167253f4e170 11469 else
wolfSSL 14:167253f4e170 11470 err = MEMORY_E;
wolfSSL 14:167253f4e170 11471 #else
wolfSSL 14:167253f4e170 11472 (void)heap;
wolfSSL 14:167253f4e170 11473
wolfSSL 14:167253f4e170 11474 t1 = t1d;
wolfSSL 14:167253f4e170 11475 t2 = t2d;
wolfSSL 14:167253f4e170 11476 #endif
wolfSSL 14:167253f4e170 11477
wolfSSL 14:167253f4e170 11478 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11479 sp_256_sqr_5(t1, point->y);
wolfSSL 14:167253f4e170 11480 sp_256_mod_5(t1, t1, p256_mod);
wolfSSL 14:167253f4e170 11481 sp_256_sqr_5(t2, point->x);
wolfSSL 14:167253f4e170 11482 sp_256_mod_5(t2, t2, p256_mod);
wolfSSL 14:167253f4e170 11483 sp_256_mul_5(t2, t2, point->x);
wolfSSL 14:167253f4e170 11484 sp_256_mod_5(t2, t2, p256_mod);
wolfSSL 14:167253f4e170 11485 sp_256_sub_5(t2, p256_mod, t2);
wolfSSL 14:167253f4e170 11486 sp_256_mont_add_5(t1, t1, t2, p256_mod);
wolfSSL 14:167253f4e170 11487
wolfSSL 14:167253f4e170 11488 sp_256_mont_add_5(t1, t1, point->x, p256_mod);
wolfSSL 14:167253f4e170 11489 sp_256_mont_add_5(t1, t1, point->x, p256_mod);
wolfSSL 14:167253f4e170 11490 sp_256_mont_add_5(t1, t1, point->x, p256_mod);
wolfSSL 14:167253f4e170 11491
wolfSSL 14:167253f4e170 11492 if (sp_256_cmp_5(t1, p256_b) != 0)
wolfSSL 14:167253f4e170 11493 err = MP_VAL;
wolfSSL 14:167253f4e170 11494 }
wolfSSL 14:167253f4e170 11495
wolfSSL 14:167253f4e170 11496 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11497 if (d != NULL)
wolfSSL 14:167253f4e170 11498 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11499 #endif
wolfSSL 14:167253f4e170 11500
wolfSSL 14:167253f4e170 11501 return err;
wolfSSL 14:167253f4e170 11502 }
wolfSSL 14:167253f4e170 11503
wolfSSL 14:167253f4e170 11504 /* Check that the x and y oridinates are a valid point on the curve.
wolfSSL 14:167253f4e170 11505 *
wolfSSL 14:167253f4e170 11506 * pX X ordinate of EC point.
wolfSSL 14:167253f4e170 11507 * pY Y ordinate of EC point.
wolfSSL 14:167253f4e170 11508 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 14:167253f4e170 11509 * not on the curve and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11510 */
wolfSSL 14:167253f4e170 11511 int sp_ecc_is_point_256(mp_int* pX, mp_int* pY)
wolfSSL 14:167253f4e170 11512 {
wolfSSL 14:167253f4e170 11513 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11514 sp_point pubd;
wolfSSL 14:167253f4e170 11515 #endif
wolfSSL 14:167253f4e170 11516 sp_point* pub;
wolfSSL 14:167253f4e170 11517 byte one[1] = { 1 };
wolfSSL 14:167253f4e170 11518 int err;
wolfSSL 14:167253f4e170 11519
wolfSSL 14:167253f4e170 11520 err = sp_ecc_point_new(NULL, pubd, pub);
wolfSSL 14:167253f4e170 11521 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11522 sp_256_from_mp(pub->x, 5, pX);
wolfSSL 14:167253f4e170 11523 sp_256_from_mp(pub->y, 5, pY);
wolfSSL 14:167253f4e170 11524 sp_256_from_bin(pub->z, 5, one, sizeof(one));
wolfSSL 14:167253f4e170 11525
wolfSSL 14:167253f4e170 11526 err = sp_256_ecc_is_point_5(pub, NULL);
wolfSSL 14:167253f4e170 11527 }
wolfSSL 14:167253f4e170 11528
wolfSSL 14:167253f4e170 11529 sp_ecc_point_free(pub, 0, NULL);
wolfSSL 14:167253f4e170 11530
wolfSSL 14:167253f4e170 11531 return err;
wolfSSL 14:167253f4e170 11532 }
wolfSSL 14:167253f4e170 11533
wolfSSL 14:167253f4e170 11534 /* Check that the private scalar generates the EC point (px, py), the point is
wolfSSL 14:167253f4e170 11535 * on the curve and the point has the correct order.
wolfSSL 14:167253f4e170 11536 *
wolfSSL 14:167253f4e170 11537 * pX X ordinate of EC point.
wolfSSL 14:167253f4e170 11538 * pY Y ordinate of EC point.
wolfSSL 14:167253f4e170 11539 * privm Private scalar that generates EC point.
wolfSSL 14:167253f4e170 11540 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 14:167253f4e170 11541 * not on the curve, ECC_INF_E if the point does not have the correct order,
wolfSSL 14:167253f4e170 11542 * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
wolfSSL 14:167253f4e170 11543 * MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11544 */
wolfSSL 14:167253f4e170 11545 int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)
wolfSSL 14:167253f4e170 11546 {
wolfSSL 14:167253f4e170 11547 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11548 sp_digit privd[5];
wolfSSL 14:167253f4e170 11549 sp_point pubd;
wolfSSL 14:167253f4e170 11550 sp_point pd;
wolfSSL 14:167253f4e170 11551 #endif
wolfSSL 14:167253f4e170 11552 sp_digit* priv = NULL;
wolfSSL 14:167253f4e170 11553 sp_point* pub;
wolfSSL 14:167253f4e170 11554 sp_point* p = NULL;
wolfSSL 14:167253f4e170 11555 byte one[1] = { 1 };
wolfSSL 14:167253f4e170 11556 int err;
wolfSSL 14:167253f4e170 11557 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11558 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11559 #endif
wolfSSL 14:167253f4e170 11560
wolfSSL 14:167253f4e170 11561 err = sp_ecc_point_new(heap, pubd, pub);
wolfSSL 14:167253f4e170 11562 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11563 err = sp_ecc_point_new(heap, pd, p);
wolfSSL 14:167253f4e170 11564 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11565 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11566 priv = XMALLOC(sizeof(sp_digit) * 5, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11567 if (priv == NULL)
wolfSSL 14:167253f4e170 11568 err = MEMORY_E;
wolfSSL 14:167253f4e170 11569 }
wolfSSL 14:167253f4e170 11570 #else
wolfSSL 14:167253f4e170 11571 priv = privd;
wolfSSL 14:167253f4e170 11572 #endif
wolfSSL 14:167253f4e170 11573
wolfSSL 14:167253f4e170 11574 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11575 sp_256_from_mp(pub->x, 5, pX);
wolfSSL 14:167253f4e170 11576 sp_256_from_mp(pub->y, 5, pY);
wolfSSL 14:167253f4e170 11577 sp_256_from_bin(pub->z, 5, one, sizeof(one));
wolfSSL 14:167253f4e170 11578 sp_256_from_mp(priv, 5, privm);
wolfSSL 14:167253f4e170 11579
wolfSSL 14:167253f4e170 11580 /* Check point at infinitiy. */
wolfSSL 14:167253f4e170 11581 if (sp_256_iszero_5(pub->x) &&
wolfSSL 14:167253f4e170 11582 sp_256_iszero_5(pub->y))
wolfSSL 14:167253f4e170 11583 err = ECC_INF_E;
wolfSSL 14:167253f4e170 11584 }
wolfSSL 14:167253f4e170 11585
wolfSSL 14:167253f4e170 11586 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11587 /* Check range of X and Y */
wolfSSL 14:167253f4e170 11588 if (sp_256_cmp_5(pub->x, p256_mod) >= 0 ||
wolfSSL 14:167253f4e170 11589 sp_256_cmp_5(pub->y, p256_mod) >= 0)
wolfSSL 14:167253f4e170 11590 err = ECC_OUT_OF_RANGE_E;
wolfSSL 14:167253f4e170 11591 }
wolfSSL 14:167253f4e170 11592
wolfSSL 14:167253f4e170 11593 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11594 /* Check point is on curve */
wolfSSL 14:167253f4e170 11595 err = sp_256_ecc_is_point_5(pub, heap);
wolfSSL 14:167253f4e170 11596 }
wolfSSL 14:167253f4e170 11597
wolfSSL 14:167253f4e170 11598 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11599 /* Point * order = infinity */
wolfSSL 14:167253f4e170 11600 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11601 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11602 err = sp_256_ecc_mulmod_avx2_5(p, pub, p256_order, 1, heap);
wolfSSL 14:167253f4e170 11603 else
wolfSSL 14:167253f4e170 11604 #endif
wolfSSL 14:167253f4e170 11605 err = sp_256_ecc_mulmod_5(p, pub, p256_order, 1, heap);
wolfSSL 14:167253f4e170 11606 }
wolfSSL 14:167253f4e170 11607 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11608 /* Check result is infinity */
wolfSSL 14:167253f4e170 11609 if (!sp_256_iszero_5(p->x) ||
wolfSSL 14:167253f4e170 11610 !sp_256_iszero_5(p->y)) {
wolfSSL 14:167253f4e170 11611 err = ECC_INF_E;
wolfSSL 14:167253f4e170 11612 }
wolfSSL 14:167253f4e170 11613 }
wolfSSL 14:167253f4e170 11614
wolfSSL 14:167253f4e170 11615 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11616 /* Base * private = point */
wolfSSL 14:167253f4e170 11617 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11618 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11619 err = sp_256_ecc_mulmod_base_avx2_5(p, priv, 1, heap);
wolfSSL 14:167253f4e170 11620 else
wolfSSL 14:167253f4e170 11621 #endif
wolfSSL 14:167253f4e170 11622 err = sp_256_ecc_mulmod_base_5(p, priv, 1, heap);
wolfSSL 14:167253f4e170 11623 }
wolfSSL 14:167253f4e170 11624 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11625 /* Check result is public key */
wolfSSL 14:167253f4e170 11626 if (sp_256_cmp_5(p->x, pub->x) != 0 ||
wolfSSL 14:167253f4e170 11627 sp_256_cmp_5(p->y, pub->y) != 0) {
wolfSSL 14:167253f4e170 11628 err = ECC_PRIV_KEY_E;
wolfSSL 14:167253f4e170 11629 }
wolfSSL 14:167253f4e170 11630 }
wolfSSL 14:167253f4e170 11631
wolfSSL 14:167253f4e170 11632 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11633 if (priv != NULL)
wolfSSL 14:167253f4e170 11634 XFREE(priv, heap, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11635 #endif
wolfSSL 14:167253f4e170 11636 sp_ecc_point_free(p, 0, heap);
wolfSSL 14:167253f4e170 11637 sp_ecc_point_free(pub, 0, heap);
wolfSSL 14:167253f4e170 11638
wolfSSL 14:167253f4e170 11639 return err;
wolfSSL 14:167253f4e170 11640 }
wolfSSL 14:167253f4e170 11641 #endif
wolfSSL 14:167253f4e170 11642 #ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
wolfSSL 14:167253f4e170 11643 /* Add two projective EC points together.
wolfSSL 14:167253f4e170 11644 * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)
wolfSSL 14:167253f4e170 11645 *
wolfSSL 14:167253f4e170 11646 * pX First EC point's X ordinate.
wolfSSL 14:167253f4e170 11647 * pY First EC point's Y ordinate.
wolfSSL 14:167253f4e170 11648 * pZ First EC point's Z ordinate.
wolfSSL 14:167253f4e170 11649 * qX Second EC point's X ordinate.
wolfSSL 14:167253f4e170 11650 * qY Second EC point's Y ordinate.
wolfSSL 14:167253f4e170 11651 * qZ Second EC point's Z ordinate.
wolfSSL 14:167253f4e170 11652 * rX Resultant EC point's X ordinate.
wolfSSL 14:167253f4e170 11653 * rY Resultant EC point's Y ordinate.
wolfSSL 14:167253f4e170 11654 * rZ Resultant EC point's Z ordinate.
wolfSSL 14:167253f4e170 11655 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11656 */
wolfSSL 14:167253f4e170 11657 int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
wolfSSL 14:167253f4e170 11658 mp_int* qX, mp_int* qY, mp_int* qZ,
wolfSSL 14:167253f4e170 11659 mp_int* rX, mp_int* rY, mp_int* rZ)
wolfSSL 14:167253f4e170 11660 {
wolfSSL 14:167253f4e170 11661 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11662 sp_digit tmpd[2 * 5 * 5];
wolfSSL 14:167253f4e170 11663 sp_point pd;
wolfSSL 14:167253f4e170 11664 sp_point qd;
wolfSSL 14:167253f4e170 11665 #endif
wolfSSL 14:167253f4e170 11666 sp_digit* tmp;
wolfSSL 14:167253f4e170 11667 sp_point* p;
wolfSSL 14:167253f4e170 11668 sp_point* q = NULL;
wolfSSL 14:167253f4e170 11669 int err;
wolfSSL 14:167253f4e170 11670 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11671 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11672 #endif
wolfSSL 14:167253f4e170 11673
wolfSSL 14:167253f4e170 11674 err = sp_ecc_point_new(NULL, pd, p);
wolfSSL 14:167253f4e170 11675 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11676 err = sp_ecc_point_new(NULL, qd, q);
wolfSSL 14:167253f4e170 11677 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11678 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11679 tmp = XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11680 if (tmp == NULL)
wolfSSL 14:167253f4e170 11681 err = MEMORY_E;
wolfSSL 14:167253f4e170 11682 }
wolfSSL 14:167253f4e170 11683 #else
wolfSSL 14:167253f4e170 11684 tmp = tmpd;
wolfSSL 14:167253f4e170 11685 #endif
wolfSSL 14:167253f4e170 11686
wolfSSL 14:167253f4e170 11687 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11688 sp_256_from_mp(p->x, 5, pX);
wolfSSL 14:167253f4e170 11689 sp_256_from_mp(p->y, 5, pY);
wolfSSL 14:167253f4e170 11690 sp_256_from_mp(p->z, 5, pZ);
wolfSSL 14:167253f4e170 11691 sp_256_from_mp(q->x, 5, qX);
wolfSSL 14:167253f4e170 11692 sp_256_from_mp(q->y, 5, qY);
wolfSSL 14:167253f4e170 11693 sp_256_from_mp(q->z, 5, qZ);
wolfSSL 14:167253f4e170 11694
wolfSSL 14:167253f4e170 11695 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11696 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11697 sp_256_proj_point_add_avx2_5(p, p, q, tmp);
wolfSSL 14:167253f4e170 11698 else
wolfSSL 14:167253f4e170 11699 #endif
wolfSSL 14:167253f4e170 11700 sp_256_proj_point_add_5(p, p, q, tmp);
wolfSSL 14:167253f4e170 11701 }
wolfSSL 14:167253f4e170 11702
wolfSSL 14:167253f4e170 11703 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11704 err = sp_256_to_mp(p->x, rX);
wolfSSL 14:167253f4e170 11705 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11706 err = sp_256_to_mp(p->y, rY);
wolfSSL 14:167253f4e170 11707 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11708 err = sp_256_to_mp(p->z, rZ);
wolfSSL 14:167253f4e170 11709
wolfSSL 14:167253f4e170 11710 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11711 if (tmp != NULL)
wolfSSL 14:167253f4e170 11712 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11713 #endif
wolfSSL 14:167253f4e170 11714 sp_ecc_point_free(q, 0, NULL);
wolfSSL 14:167253f4e170 11715 sp_ecc_point_free(p, 0, NULL);
wolfSSL 14:167253f4e170 11716
wolfSSL 14:167253f4e170 11717 return err;
wolfSSL 14:167253f4e170 11718 }
wolfSSL 14:167253f4e170 11719
wolfSSL 14:167253f4e170 11720 /* Double a projective EC point.
wolfSSL 14:167253f4e170 11721 * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)
wolfSSL 14:167253f4e170 11722 *
wolfSSL 14:167253f4e170 11723 * pX EC point's X ordinate.
wolfSSL 14:167253f4e170 11724 * pY EC point's Y ordinate.
wolfSSL 14:167253f4e170 11725 * pZ EC point's Z ordinate.
wolfSSL 14:167253f4e170 11726 * rX Resultant EC point's X ordinate.
wolfSSL 14:167253f4e170 11727 * rY Resultant EC point's Y ordinate.
wolfSSL 14:167253f4e170 11728 * rZ Resultant EC point's Z ordinate.
wolfSSL 14:167253f4e170 11729 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11730 */
wolfSSL 14:167253f4e170 11731 int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
wolfSSL 14:167253f4e170 11732 mp_int* rX, mp_int* rY, mp_int* rZ)
wolfSSL 14:167253f4e170 11733 {
wolfSSL 14:167253f4e170 11734 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11735 sp_digit tmpd[2 * 5 * 2];
wolfSSL 14:167253f4e170 11736 sp_point pd;
wolfSSL 14:167253f4e170 11737 #endif
wolfSSL 14:167253f4e170 11738 sp_digit* tmp;
wolfSSL 14:167253f4e170 11739 sp_point* p;
wolfSSL 14:167253f4e170 11740 int err;
wolfSSL 14:167253f4e170 11741 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11742 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11743 #endif
wolfSSL 14:167253f4e170 11744
wolfSSL 14:167253f4e170 11745 err = sp_ecc_point_new(NULL, pd, p);
wolfSSL 14:167253f4e170 11746 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11747 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11748 tmp = XMALLOC(sizeof(sp_digit) * 2 * 5 * 2, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11749 if (tmp == NULL)
wolfSSL 14:167253f4e170 11750 err = MEMORY_E;
wolfSSL 14:167253f4e170 11751 }
wolfSSL 14:167253f4e170 11752 #else
wolfSSL 14:167253f4e170 11753 tmp = tmpd;
wolfSSL 14:167253f4e170 11754 #endif
wolfSSL 14:167253f4e170 11755
wolfSSL 14:167253f4e170 11756 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11757 sp_256_from_mp(p->x, 5, pX);
wolfSSL 14:167253f4e170 11758 sp_256_from_mp(p->y, 5, pY);
wolfSSL 14:167253f4e170 11759 sp_256_from_mp(p->z, 5, pZ);
wolfSSL 14:167253f4e170 11760
wolfSSL 14:167253f4e170 11761 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11762 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
wolfSSL 14:167253f4e170 11763 sp_256_proj_point_dbl_avx2_5(p, p, tmp);
wolfSSL 14:167253f4e170 11764 else
wolfSSL 14:167253f4e170 11765 #endif
wolfSSL 14:167253f4e170 11766 sp_256_proj_point_dbl_5(p, p, tmp);
wolfSSL 14:167253f4e170 11767 }
wolfSSL 14:167253f4e170 11768
wolfSSL 14:167253f4e170 11769 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11770 err = sp_256_to_mp(p->x, rX);
wolfSSL 14:167253f4e170 11771 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11772 err = sp_256_to_mp(p->y, rY);
wolfSSL 14:167253f4e170 11773 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11774 err = sp_256_to_mp(p->z, rZ);
wolfSSL 14:167253f4e170 11775
wolfSSL 14:167253f4e170 11776 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11777 if (tmp != NULL)
wolfSSL 14:167253f4e170 11778 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11779 #endif
wolfSSL 14:167253f4e170 11780 sp_ecc_point_free(p, 0, NULL);
wolfSSL 14:167253f4e170 11781
wolfSSL 14:167253f4e170 11782 return err;
wolfSSL 14:167253f4e170 11783 }
wolfSSL 14:167253f4e170 11784
wolfSSL 14:167253f4e170 11785 /* Map a projective EC point to affine in place.
wolfSSL 14:167253f4e170 11786 * pZ will be one.
wolfSSL 14:167253f4e170 11787 *
wolfSSL 14:167253f4e170 11788 * pX EC point's X ordinate.
wolfSSL 14:167253f4e170 11789 * pY EC point's Y ordinate.
wolfSSL 14:167253f4e170 11790 * pZ EC point's Z ordinate.
wolfSSL 14:167253f4e170 11791 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11792 */
wolfSSL 14:167253f4e170 11793 int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)
wolfSSL 14:167253f4e170 11794 {
wolfSSL 14:167253f4e170 11795 #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11796 sp_digit tmpd[2 * 5 * 4];
wolfSSL 14:167253f4e170 11797 sp_point pd;
wolfSSL 14:167253f4e170 11798 #endif
wolfSSL 14:167253f4e170 11799 sp_digit* tmp;
wolfSSL 14:167253f4e170 11800 sp_point* p;
wolfSSL 14:167253f4e170 11801 int err;
wolfSSL 14:167253f4e170 11802
wolfSSL 14:167253f4e170 11803 err = sp_ecc_point_new(NULL, pd, p);
wolfSSL 14:167253f4e170 11804 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11805 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11806 tmp = XMALLOC(sizeof(sp_digit) * 2 * 5 * 4, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11807 if (tmp == NULL)
wolfSSL 14:167253f4e170 11808 err = MEMORY_E;
wolfSSL 14:167253f4e170 11809 }
wolfSSL 14:167253f4e170 11810 #else
wolfSSL 14:167253f4e170 11811 tmp = tmpd;
wolfSSL 14:167253f4e170 11812 #endif
wolfSSL 14:167253f4e170 11813 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11814 sp_256_from_mp(p->x, 5, pX);
wolfSSL 14:167253f4e170 11815 sp_256_from_mp(p->y, 5, pY);
wolfSSL 14:167253f4e170 11816 sp_256_from_mp(p->z, 5, pZ);
wolfSSL 14:167253f4e170 11817
wolfSSL 14:167253f4e170 11818 sp_256_map_5(p, p, tmp);
wolfSSL 14:167253f4e170 11819 }
wolfSSL 14:167253f4e170 11820
wolfSSL 14:167253f4e170 11821 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11822 err = sp_256_to_mp(p->x, pX);
wolfSSL 14:167253f4e170 11823 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11824 err = sp_256_to_mp(p->y, pY);
wolfSSL 14:167253f4e170 11825 if (err == MP_OKAY)
wolfSSL 14:167253f4e170 11826 err = sp_256_to_mp(p->z, pZ);
wolfSSL 14:167253f4e170 11827
wolfSSL 14:167253f4e170 11828 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11829 if (tmp != NULL)
wolfSSL 14:167253f4e170 11830 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11831 #endif
wolfSSL 14:167253f4e170 11832 sp_ecc_point_free(p, 0, NULL);
wolfSSL 14:167253f4e170 11833
wolfSSL 14:167253f4e170 11834 return err;
wolfSSL 14:167253f4e170 11835 }
wolfSSL 14:167253f4e170 11836 #endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */
wolfSSL 14:167253f4e170 11837 #ifdef HAVE_COMP_KEY
wolfSSL 14:167253f4e170 11838 /* Find the square root of a number mod the prime of the curve.
wolfSSL 14:167253f4e170 11839 *
wolfSSL 14:167253f4e170 11840 * y The number to operate on and the result.
wolfSSL 14:167253f4e170 11841 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11842 */
wolfSSL 14:167253f4e170 11843 static int sp_256_mont_sqrt_5(sp_digit* y)
wolfSSL 14:167253f4e170 11844 {
wolfSSL 14:167253f4e170 11845 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11846 sp_digit* d;
wolfSSL 14:167253f4e170 11847 #else
wolfSSL 14:167253f4e170 11848 sp_digit t1d[2 * 5];
wolfSSL 14:167253f4e170 11849 sp_digit t2d[2 * 5];
wolfSSL 14:167253f4e170 11850 #endif
wolfSSL 14:167253f4e170 11851 sp_digit* t1;
wolfSSL 14:167253f4e170 11852 sp_digit* t2;
wolfSSL 14:167253f4e170 11853 int err = MP_OKAY;
wolfSSL 14:167253f4e170 11854 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11855 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11856 #endif
wolfSSL 14:167253f4e170 11857
wolfSSL 14:167253f4e170 11858 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11859 d = XMALLOC(sizeof(sp_digit) * 4 * 5, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11860 if (d != NULL) {
wolfSSL 14:167253f4e170 11861 t1 = d + 0 * 5;
wolfSSL 14:167253f4e170 11862 t2 = d + 2 * 5;
wolfSSL 14:167253f4e170 11863 }
wolfSSL 14:167253f4e170 11864 else
wolfSSL 14:167253f4e170 11865 err = MEMORY_E;
wolfSSL 14:167253f4e170 11866 #else
wolfSSL 14:167253f4e170 11867 t1 = t1d;
wolfSSL 14:167253f4e170 11868 t2 = t2d;
wolfSSL 14:167253f4e170 11869 #endif
wolfSSL 14:167253f4e170 11870
wolfSSL 14:167253f4e170 11871 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11872 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11873 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {
wolfSSL 14:167253f4e170 11874 /* t2 = y ^ 0x2 */
wolfSSL 14:167253f4e170 11875 sp_256_mont_sqr_avx2_5(t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11876 /* t1 = y ^ 0x3 */
wolfSSL 14:167253f4e170 11877 sp_256_mont_mul_avx2_5(t1, t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11878 /* t2 = y ^ 0xc */
wolfSSL 14:167253f4e170 11879 sp_256_mont_sqr_n_avx2_5(t2, t1, 2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11880 /* t1 = y ^ 0xf */
wolfSSL 14:167253f4e170 11881 sp_256_mont_mul_avx2_5(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11882 /* t2 = y ^ 0xf0 */
wolfSSL 14:167253f4e170 11883 sp_256_mont_sqr_n_avx2_5(t2, t1, 4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11884 /* t1 = y ^ 0xff */
wolfSSL 14:167253f4e170 11885 sp_256_mont_mul_avx2_5(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11886 /* t2 = y ^ 0xff00 */
wolfSSL 14:167253f4e170 11887 sp_256_mont_sqr_n_avx2_5(t2, t1, 8, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11888 /* t1 = y ^ 0xffff */
wolfSSL 14:167253f4e170 11889 sp_256_mont_mul_avx2_5(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11890 /* t2 = y ^ 0xffff0000 */
wolfSSL 14:167253f4e170 11891 sp_256_mont_sqr_n_avx2_5(t2, t1, 16, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11892 /* t1 = y ^ 0xffffffff */
wolfSSL 14:167253f4e170 11893 sp_256_mont_mul_avx2_5(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11894 /* t1 = y ^ 0xffffffff00000000 */
wolfSSL 14:167253f4e170 11895 sp_256_mont_sqr_n_avx2_5(t1, t1, 32, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11896 /* t1 = y ^ 0xffffffff00000001 */
wolfSSL 14:167253f4e170 11897 sp_256_mont_mul_avx2_5(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11898 /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */
wolfSSL 14:167253f4e170 11899 sp_256_mont_sqr_n_avx2_5(t1, t1, 96, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11900 /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */
wolfSSL 14:167253f4e170 11901 sp_256_mont_mul_avx2_5(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11902 sp_256_mont_sqr_n_avx2_5(y, t1, 94, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11903 }
wolfSSL 14:167253f4e170 11904 else
wolfSSL 14:167253f4e170 11905 #endif
wolfSSL 14:167253f4e170 11906 {
wolfSSL 14:167253f4e170 11907 /* t2 = y ^ 0x2 */
wolfSSL 14:167253f4e170 11908 sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11909 /* t1 = y ^ 0x3 */
wolfSSL 14:167253f4e170 11910 sp_256_mont_mul_5(t1, t2, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11911 /* t2 = y ^ 0xc */
wolfSSL 14:167253f4e170 11912 sp_256_mont_sqr_n_5(t2, t1, 2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11913 /* t1 = y ^ 0xf */
wolfSSL 14:167253f4e170 11914 sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11915 /* t2 = y ^ 0xf0 */
wolfSSL 14:167253f4e170 11916 sp_256_mont_sqr_n_5(t2, t1, 4, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11917 /* t1 = y ^ 0xff */
wolfSSL 14:167253f4e170 11918 sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11919 /* t2 = y ^ 0xff00 */
wolfSSL 14:167253f4e170 11920 sp_256_mont_sqr_n_5(t2, t1, 8, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11921 /* t1 = y ^ 0xffff */
wolfSSL 14:167253f4e170 11922 sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11923 /* t2 = y ^ 0xffff0000 */
wolfSSL 14:167253f4e170 11924 sp_256_mont_sqr_n_5(t2, t1, 16, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11925 /* t1 = y ^ 0xffffffff */
wolfSSL 14:167253f4e170 11926 sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11927 /* t1 = y ^ 0xffffffff00000000 */
wolfSSL 14:167253f4e170 11928 sp_256_mont_sqr_n_5(t1, t1, 32, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11929 /* t1 = y ^ 0xffffffff00000001 */
wolfSSL 14:167253f4e170 11930 sp_256_mont_mul_5(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11931 /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */
wolfSSL 14:167253f4e170 11932 sp_256_mont_sqr_n_5(t1, t1, 96, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11933 /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */
wolfSSL 14:167253f4e170 11934 sp_256_mont_mul_5(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11935 sp_256_mont_sqr_n_5(y, t1, 94, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11936 }
wolfSSL 14:167253f4e170 11937 }
wolfSSL 14:167253f4e170 11938
wolfSSL 14:167253f4e170 11939 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11940 if (d != NULL)
wolfSSL 14:167253f4e170 11941 XFREE(d, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11942 #endif
wolfSSL 14:167253f4e170 11943
wolfSSL 14:167253f4e170 11944 return err;
wolfSSL 14:167253f4e170 11945 }
wolfSSL 14:167253f4e170 11946
wolfSSL 14:167253f4e170 11947 /* Uncompress the point given the X ordinate.
wolfSSL 14:167253f4e170 11948 *
wolfSSL 14:167253f4e170 11949 * xm X ordinate.
wolfSSL 14:167253f4e170 11950 * odd Whether the Y ordinate is odd.
wolfSSL 14:167253f4e170 11951 * ym Calculated Y ordinate.
wolfSSL 14:167253f4e170 11952 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 14:167253f4e170 11953 */
wolfSSL 14:167253f4e170 11954 int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)
wolfSSL 14:167253f4e170 11955 {
wolfSSL 14:167253f4e170 11956 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11957 sp_digit* d;
wolfSSL 14:167253f4e170 11958 #else
wolfSSL 14:167253f4e170 11959 sp_digit xd[2 * 5];
wolfSSL 14:167253f4e170 11960 sp_digit yd[2 * 5];
wolfSSL 14:167253f4e170 11961 #endif
wolfSSL 14:167253f4e170 11962 sp_digit* x;
wolfSSL 14:167253f4e170 11963 sp_digit* y;
wolfSSL 14:167253f4e170 11964 int err = MP_OKAY;
wolfSSL 14:167253f4e170 11965 #ifdef HAVE_INTEL_AVX2
wolfSSL 14:167253f4e170 11966 word32 cpuid_flags = cpuid_get_flags();
wolfSSL 14:167253f4e170 11967 #endif
wolfSSL 14:167253f4e170 11968
wolfSSL 14:167253f4e170 11969 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 11970 d = XMALLOC(sizeof(sp_digit) * 4 * 5, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 11971 if (d != NULL) {
wolfSSL 14:167253f4e170 11972 x = d + 0 * 5;
wolfSSL 14:167253f4e170 11973 y = d + 2 * 5;
wolfSSL 14:167253f4e170 11974 }
wolfSSL 14:167253f4e170 11975 else
wolfSSL 14:167253f4e170 11976 err = MEMORY_E;
wolfSSL 14:167253f4e170 11977 #else
wolfSSL 14:167253f4e170 11978 x = xd;
wolfSSL 14:167253f4e170 11979 y = yd;
wolfSSL 14:167253f4e170 11980 #endif
wolfSSL 14:167253f4e170 11981
wolfSSL 14:167253f4e170 11982 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11983 sp_256_from_mp(x, 5, xm);
wolfSSL 14:167253f4e170 11984
wolfSSL 14:167253f4e170 11985 err = sp_256_mod_mul_norm_5(x, x, p256_mod);
wolfSSL 14:167253f4e170 11986 }
wolfSSL 14:167253f4e170 11987
wolfSSL 14:167253f4e170 11988 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 11989 /* y = x^3 */
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_sqr_avx2_5(y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11993 sp_256_mont_mul_avx2_5(y, y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11994 }
wolfSSL 14:167253f4e170 11995 else
wolfSSL 14:167253f4e170 11996 #endif
wolfSSL 14:167253f4e170 11997 {
wolfSSL 14:167253f4e170 11998 sp_256_mont_sqr_5(y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 11999 sp_256_mont_mul_5(y, y, x, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12000 }
wolfSSL 14:167253f4e170 12001 /* y = x^3 - 3x */
wolfSSL 14:167253f4e170 12002 sp_256_mont_sub_5(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 12003 sp_256_mont_sub_5(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 12004 sp_256_mont_sub_5(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 12005 /* y = x^3 - 3x + b */
wolfSSL 14:167253f4e170 12006 err = sp_256_mod_mul_norm_5(x, p256_b, p256_mod);
wolfSSL 14:167253f4e170 12007 }
wolfSSL 14:167253f4e170 12008 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12009 sp_256_mont_add_5(y, y, x, p256_mod);
wolfSSL 14:167253f4e170 12010 /* y = sqrt(x^3 - 3x + b) */
wolfSSL 14:167253f4e170 12011 err = sp_256_mont_sqrt_5(y);
wolfSSL 14:167253f4e170 12012 }
wolfSSL 14:167253f4e170 12013 if (err == MP_OKAY) {
wolfSSL 14:167253f4e170 12014 XMEMSET(y + 5, 0, 5 * sizeof(sp_digit));
wolfSSL 14:167253f4e170 12015 sp_256_mont_reduce_5(y, p256_mod, p256_mp_mod);
wolfSSL 14:167253f4e170 12016 if (((y[0] ^ odd) & 1) != 0)
wolfSSL 14:167253f4e170 12017 sp_256_mont_sub_5(y, p256_mod, y, p256_mod);
wolfSSL 14:167253f4e170 12018
wolfSSL 14:167253f4e170 12019 err = sp_256_to_mp(y, ym);
wolfSSL 14:167253f4e170 12020 }
wolfSSL 14:167253f4e170 12021
wolfSSL 14:167253f4e170 12022 #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
wolfSSL 14:167253f4e170 12023 if (d != NULL)
wolfSSL 14:167253f4e170 12024 XFREE(d, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 14:167253f4e170 12025 #endif
wolfSSL 14:167253f4e170 12026
wolfSSL 14:167253f4e170 12027 return err;
wolfSSL 14:167253f4e170 12028 }
wolfSSL 14:167253f4e170 12029 #endif
wolfSSL 14:167253f4e170 12030 #endif /* WOLFSSL_SP_NO_256 */
wolfSSL 14:167253f4e170 12031 #endif /* WOLFSSL_HAVE_SP_ECC */
wolfSSL 14:167253f4e170 12032 #endif /* SP_WORD_SIZE == 64 */
wolfSSL 14:167253f4e170 12033 #endif /* !WOLFSSL_SP_ASM */
wolfSSL 14:167253f4e170 12034 #endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */
wolfSSL 14:167253f4e170 12035