wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Fri Jun 05 00:11:07 2020 +0000
Revision:
17:a5f916481144
Parent:
16:8e0d178b1d1e
wolfSSL 4.4.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 16:8e0d178b1d1e 1 /* sp.c
wolfSSL 16:8e0d178b1d1e 2 *
wolfSSL 16:8e0d178b1d1e 3 * Copyright (C) 2006-2020 wolfSSL Inc.
wolfSSL 16:8e0d178b1d1e 4 *
wolfSSL 16:8e0d178b1d1e 5 * This file is part of wolfSSL.
wolfSSL 16:8e0d178b1d1e 6 *
wolfSSL 16:8e0d178b1d1e 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 16:8e0d178b1d1e 8 * it under the terms of the GNU General Public License as published by
wolfSSL 16:8e0d178b1d1e 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 16:8e0d178b1d1e 10 * (at your option) any later version.
wolfSSL 16:8e0d178b1d1e 11 *
wolfSSL 16:8e0d178b1d1e 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 16:8e0d178b1d1e 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 16:8e0d178b1d1e 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 16:8e0d178b1d1e 15 * GNU General Public License for more details.
wolfSSL 16:8e0d178b1d1e 16 *
wolfSSL 16:8e0d178b1d1e 17 * You should have received a copy of the GNU General Public License
wolfSSL 16:8e0d178b1d1e 18 * along with this program; if not, write to the Free Software
wolfSSL 16:8e0d178b1d1e 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 16:8e0d178b1d1e 20 */
wolfSSL 16:8e0d178b1d1e 21
wolfSSL 16:8e0d178b1d1e 22 /* Implementation by Sean Parkinson. */
wolfSSL 16:8e0d178b1d1e 23
wolfSSL 16:8e0d178b1d1e 24 #ifdef HAVE_CONFIG_H
wolfSSL 16:8e0d178b1d1e 25 #include <config.h>
wolfSSL 16:8e0d178b1d1e 26 #endif
wolfSSL 16:8e0d178b1d1e 27
wolfSSL 16:8e0d178b1d1e 28 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 16:8e0d178b1d1e 29 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 16:8e0d178b1d1e 30 #include <wolfssl/wolfcrypt/cpuid.h>
wolfSSL 16:8e0d178b1d1e 31 #ifdef NO_INLINE
wolfSSL 16:8e0d178b1d1e 32 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 16:8e0d178b1d1e 33 #else
wolfSSL 16:8e0d178b1d1e 34 #define WOLFSSL_MISC_INCLUDED
wolfSSL 16:8e0d178b1d1e 35 #include <wolfcrypt/src/misc.c>
wolfSSL 16:8e0d178b1d1e 36 #endif
wolfSSL 16:8e0d178b1d1e 37
wolfSSL 16:8e0d178b1d1e 38 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \
wolfSSL 16:8e0d178b1d1e 39 defined(WOLFSSL_HAVE_SP_ECC)
wolfSSL 16:8e0d178b1d1e 40
wolfSSL 16:8e0d178b1d1e 41 #ifdef RSA_LOW_MEM
wolfSSL 16:8e0d178b1d1e 42 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 43 #define WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 44 #endif
wolfSSL 16:8e0d178b1d1e 45 #endif
wolfSSL 16:8e0d178b1d1e 46
wolfSSL 16:8e0d178b1d1e 47 #include <wolfssl/wolfcrypt/sp.h>
wolfSSL 16:8e0d178b1d1e 48
wolfSSL 16:8e0d178b1d1e 49 #ifdef __IAR_SYSTEMS_ICC__
wolfSSL 16:8e0d178b1d1e 50 #define __asm__ asm
wolfSSL 16:8e0d178b1d1e 51 #define __volatile__ volatile
wolfSSL 16:8e0d178b1d1e 52 #endif /* __IAR_SYSTEMS_ICC__ */
wolfSSL 16:8e0d178b1d1e 53 #ifdef __KEIL__
wolfSSL 16:8e0d178b1d1e 54 #define __asm__ __asm
wolfSSL 16:8e0d178b1d1e 55 #define __volatile__ volatile
wolfSSL 16:8e0d178b1d1e 56 #endif
wolfSSL 16:8e0d178b1d1e 57
wolfSSL 16:8e0d178b1d1e 58 #ifdef WOLFSSL_SP_ARM_CORTEX_M_ASM
wolfSSL 16:8e0d178b1d1e 59 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 16:8e0d178b1d1e 60 #ifndef WOLFSSL_SP_NO_2048
wolfSSL 16:8e0d178b1d1e 61 /* Read big endian unsigned byte array into r.
wolfSSL 16:8e0d178b1d1e 62 *
wolfSSL 16:8e0d178b1d1e 63 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 64 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 65 * a Byte array.
wolfSSL 16:8e0d178b1d1e 66 * n Number of bytes in array to read.
wolfSSL 16:8e0d178b1d1e 67 */
wolfSSL 16:8e0d178b1d1e 68 static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)
wolfSSL 16:8e0d178b1d1e 69 {
wolfSSL 16:8e0d178b1d1e 70 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 71 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 72
wolfSSL 16:8e0d178b1d1e 73 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 74 for (i = n-1; i >= 0; i--) {
wolfSSL 16:8e0d178b1d1e 75 r[j] |= (((sp_digit)a[i]) << s);
wolfSSL 16:8e0d178b1d1e 76 if (s >= 24U) {
wolfSSL 16:8e0d178b1d1e 77 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 78 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 79 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 80 break;
wolfSSL 16:8e0d178b1d1e 81 }
wolfSSL 16:8e0d178b1d1e 82 r[++j] = (sp_digit)a[i] >> s;
wolfSSL 16:8e0d178b1d1e 83 s = 8U - s;
wolfSSL 16:8e0d178b1d1e 84 }
wolfSSL 16:8e0d178b1d1e 85 else {
wolfSSL 16:8e0d178b1d1e 86 s += 8U;
wolfSSL 16:8e0d178b1d1e 87 }
wolfSSL 16:8e0d178b1d1e 88 }
wolfSSL 16:8e0d178b1d1e 89
wolfSSL 16:8e0d178b1d1e 90 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 91 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 92 }
wolfSSL 16:8e0d178b1d1e 93 }
wolfSSL 16:8e0d178b1d1e 94
wolfSSL 16:8e0d178b1d1e 95 /* Convert an mp_int to an array of sp_digit.
wolfSSL 16:8e0d178b1d1e 96 *
wolfSSL 16:8e0d178b1d1e 97 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 98 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 99 * a A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 100 */
wolfSSL 16:8e0d178b1d1e 101 static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)
wolfSSL 16:8e0d178b1d1e 102 {
wolfSSL 16:8e0d178b1d1e 103 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 104 int j;
wolfSSL 16:8e0d178b1d1e 105
wolfSSL 16:8e0d178b1d1e 106 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 16:8e0d178b1d1e 107
wolfSSL 16:8e0d178b1d1e 108 for (j = a->used; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 109 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 110 }
wolfSSL 16:8e0d178b1d1e 111 #elif DIGIT_BIT > 32
wolfSSL 16:8e0d178b1d1e 112 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 113 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 114
wolfSSL 16:8e0d178b1d1e 115 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 116 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 117 r[j] |= ((sp_digit)a->dp[i] << s);
wolfSSL 16:8e0d178b1d1e 118 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 119 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 120 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 121 break;
wolfSSL 16:8e0d178b1d1e 122 }
wolfSSL 16:8e0d178b1d1e 123 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 124 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 125 while ((s + 32U) <= (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 126 s += 32U;
wolfSSL 16:8e0d178b1d1e 127 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 128 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 129 break;
wolfSSL 16:8e0d178b1d1e 130 }
wolfSSL 16:8e0d178b1d1e 131 if (s < (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 132 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 133 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 134 }
wolfSSL 16:8e0d178b1d1e 135 else {
wolfSSL 16:8e0d178b1d1e 136 r[++j] = 0L;
wolfSSL 16:8e0d178b1d1e 137 }
wolfSSL 16:8e0d178b1d1e 138 }
wolfSSL 16:8e0d178b1d1e 139 s = (word32)DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 140 }
wolfSSL 16:8e0d178b1d1e 141
wolfSSL 16:8e0d178b1d1e 142 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 143 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 144 }
wolfSSL 16:8e0d178b1d1e 145 #else
wolfSSL 16:8e0d178b1d1e 146 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 147
wolfSSL 16:8e0d178b1d1e 148 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 149 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 150 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 16:8e0d178b1d1e 151 if (s + DIGIT_BIT >= 32) {
wolfSSL 16:8e0d178b1d1e 152 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 153 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 154 break;
wolfSSL 16:8e0d178b1d1e 155 }
wolfSSL 16:8e0d178b1d1e 156 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 157 if (s == DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 158 r[++j] = 0;
wolfSSL 16:8e0d178b1d1e 159 s = 0;
wolfSSL 16:8e0d178b1d1e 160 }
wolfSSL 16:8e0d178b1d1e 161 else {
wolfSSL 16:8e0d178b1d1e 162 r[++j] = a->dp[i] >> s;
wolfSSL 16:8e0d178b1d1e 163 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 164 }
wolfSSL 16:8e0d178b1d1e 165 }
wolfSSL 16:8e0d178b1d1e 166 else {
wolfSSL 16:8e0d178b1d1e 167 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 168 }
wolfSSL 16:8e0d178b1d1e 169 }
wolfSSL 16:8e0d178b1d1e 170
wolfSSL 16:8e0d178b1d1e 171 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 172 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 173 }
wolfSSL 16:8e0d178b1d1e 174 #endif
wolfSSL 16:8e0d178b1d1e 175 }
wolfSSL 16:8e0d178b1d1e 176
wolfSSL 16:8e0d178b1d1e 177 /* Write r as big endian to byte array.
wolfSSL 16:8e0d178b1d1e 178 * Fixed length number of bytes written: 256
wolfSSL 16:8e0d178b1d1e 179 *
wolfSSL 16:8e0d178b1d1e 180 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 181 * a Byte array.
wolfSSL 16:8e0d178b1d1e 182 */
wolfSSL 16:8e0d178b1d1e 183 static void sp_2048_to_bin(sp_digit* r, byte* a)
wolfSSL 16:8e0d178b1d1e 184 {
wolfSSL 16:8e0d178b1d1e 185 int i, j, s = 0, b;
wolfSSL 16:8e0d178b1d1e 186
wolfSSL 16:8e0d178b1d1e 187 j = 2048 / 8 - 1;
wolfSSL 16:8e0d178b1d1e 188 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 189 for (i=0; i<64 && j>=0; i++) {
wolfSSL 16:8e0d178b1d1e 190 b = 0;
wolfSSL 16:8e0d178b1d1e 191 /* lint allow cast of mismatch sp_digit and int */
wolfSSL 16:8e0d178b1d1e 192 a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 193 b += 8 - s;
wolfSSL 16:8e0d178b1d1e 194 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 195 break;
wolfSSL 16:8e0d178b1d1e 196 }
wolfSSL 16:8e0d178b1d1e 197 while (b < 32) {
wolfSSL 16:8e0d178b1d1e 198 a[j--] = (byte)(r[i] >> b);
wolfSSL 16:8e0d178b1d1e 199 b += 8;
wolfSSL 16:8e0d178b1d1e 200 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 201 break;
wolfSSL 16:8e0d178b1d1e 202 }
wolfSSL 16:8e0d178b1d1e 203 }
wolfSSL 16:8e0d178b1d1e 204 s = 8 - (b - 32);
wolfSSL 16:8e0d178b1d1e 205 if (j >= 0) {
wolfSSL 16:8e0d178b1d1e 206 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 207 }
wolfSSL 16:8e0d178b1d1e 208 if (s != 0) {
wolfSSL 16:8e0d178b1d1e 209 j++;
wolfSSL 16:8e0d178b1d1e 210 }
wolfSSL 16:8e0d178b1d1e 211 }
wolfSSL 16:8e0d178b1d1e 212 }
wolfSSL 16:8e0d178b1d1e 213
wolfSSL 16:8e0d178b1d1e 214 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 215 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 216 *
wolfSSL 16:8e0d178b1d1e 217 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 218 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 219 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 220 */
wolfSSL 16:8e0d178b1d1e 221 SP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 222 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 223 {
wolfSSL 16:8e0d178b1d1e 224 sp_digit tmp[8];
wolfSSL 16:8e0d178b1d1e 225
wolfSSL 16:8e0d178b1d1e 226 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 227 /* A[0] * B[0] */
wolfSSL 16:8e0d178b1d1e 228 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 229 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 230 "umull r3, r4, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 231 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 232 "str r3, [%[tmp], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 233 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 234 /* A[0] * B[1] */
wolfSSL 16:8e0d178b1d1e 235 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 236 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 237 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 238 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 239 /* A[1] * B[0] */
wolfSSL 16:8e0d178b1d1e 240 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 241 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 242 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 243 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 244 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 245 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 246 "str r4, [%[tmp], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 247 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 248 /* A[0] * B[2] */
wolfSSL 16:8e0d178b1d1e 249 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 250 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 251 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 252 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 253 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 254 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 255 /* A[1] * B[1] */
wolfSSL 16:8e0d178b1d1e 256 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 257 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 258 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 259 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 260 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 261 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 262 /* A[2] * B[0] */
wolfSSL 16:8e0d178b1d1e 263 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 264 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 265 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 266 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 267 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 268 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 269 "str r5, [%[tmp], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 270 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 271 /* A[0] * B[3] */
wolfSSL 16:8e0d178b1d1e 272 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 273 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 274 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 275 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 276 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 277 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 278 /* A[1] * B[2] */
wolfSSL 16:8e0d178b1d1e 279 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 280 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 281 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 282 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 283 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 284 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 285 /* A[2] * B[1] */
wolfSSL 16:8e0d178b1d1e 286 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 287 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 288 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 289 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 290 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 291 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 292 /* A[3] * B[0] */
wolfSSL 16:8e0d178b1d1e 293 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 294 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 295 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 296 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 297 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 298 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 299 "str r3, [%[tmp], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 300 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 301 /* A[0] * B[4] */
wolfSSL 16:8e0d178b1d1e 302 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 303 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 304 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 305 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 306 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 307 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 308 /* A[1] * B[3] */
wolfSSL 16:8e0d178b1d1e 309 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 310 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 311 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 312 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 313 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 314 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 315 /* A[2] * B[2] */
wolfSSL 16:8e0d178b1d1e 316 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 317 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 318 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 319 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 320 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 321 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 322 /* A[3] * B[1] */
wolfSSL 16:8e0d178b1d1e 323 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 324 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 325 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 326 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 327 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 328 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 329 /* A[4] * B[0] */
wolfSSL 16:8e0d178b1d1e 330 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 331 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 332 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 333 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 334 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 335 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 336 "str r4, [%[tmp], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 337 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 338 /* A[0] * B[5] */
wolfSSL 16:8e0d178b1d1e 339 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 340 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 341 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 342 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 343 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 344 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 345 /* A[1] * B[4] */
wolfSSL 16:8e0d178b1d1e 346 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 347 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 348 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 349 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 350 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 351 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 352 /* A[2] * B[3] */
wolfSSL 16:8e0d178b1d1e 353 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 354 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 355 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 356 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 357 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 358 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 359 /* A[3] * B[2] */
wolfSSL 16:8e0d178b1d1e 360 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 361 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 362 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 363 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 364 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 365 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 366 /* A[4] * B[1] */
wolfSSL 16:8e0d178b1d1e 367 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 368 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 369 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 370 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 371 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 372 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 373 /* A[5] * B[0] */
wolfSSL 16:8e0d178b1d1e 374 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 375 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 376 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 377 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 378 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 379 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 380 "str r5, [%[tmp], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 381 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 382 /* A[0] * B[6] */
wolfSSL 16:8e0d178b1d1e 383 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 384 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 385 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 386 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 387 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 388 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 389 /* A[1] * B[5] */
wolfSSL 16:8e0d178b1d1e 390 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 391 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 392 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 393 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 394 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 395 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 396 /* A[2] * B[4] */
wolfSSL 16:8e0d178b1d1e 397 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 398 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 399 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 400 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 401 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 402 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 403 /* A[3] * B[3] */
wolfSSL 16:8e0d178b1d1e 404 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 405 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 406 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 407 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 408 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 409 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 410 /* A[4] * B[2] */
wolfSSL 16:8e0d178b1d1e 411 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 412 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 413 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 414 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 415 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 416 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 417 /* A[5] * B[1] */
wolfSSL 16:8e0d178b1d1e 418 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 419 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 420 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 421 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 422 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 423 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 424 /* A[6] * B[0] */
wolfSSL 16:8e0d178b1d1e 425 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 426 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 427 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 428 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 429 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 430 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 431 "str r3, [%[tmp], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 432 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 433 /* A[0] * B[7] */
wolfSSL 16:8e0d178b1d1e 434 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 435 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 436 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 437 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 438 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 439 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 440 /* A[1] * B[6] */
wolfSSL 16:8e0d178b1d1e 441 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 442 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 443 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 444 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 445 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 446 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 447 /* A[2] * B[5] */
wolfSSL 16:8e0d178b1d1e 448 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 449 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 450 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 451 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 452 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 453 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 454 /* A[3] * B[4] */
wolfSSL 16:8e0d178b1d1e 455 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 456 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 457 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 458 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 459 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 460 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 461 /* A[4] * B[3] */
wolfSSL 16:8e0d178b1d1e 462 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 463 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 464 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 465 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 466 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 467 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 468 /* A[5] * B[2] */
wolfSSL 16:8e0d178b1d1e 469 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 470 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 471 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 472 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 473 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 474 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 475 /* A[6] * B[1] */
wolfSSL 16:8e0d178b1d1e 476 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 477 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 478 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 479 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 480 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 481 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 482 /* A[7] * B[0] */
wolfSSL 16:8e0d178b1d1e 483 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 484 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 485 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 486 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 487 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 488 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 489 "str r4, [%[tmp], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 490 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 491 /* A[1] * B[7] */
wolfSSL 16:8e0d178b1d1e 492 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 493 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 494 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 495 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 496 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 497 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 498 /* A[2] * B[6] */
wolfSSL 16:8e0d178b1d1e 499 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 500 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 501 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 502 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 503 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 504 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 505 /* A[3] * B[5] */
wolfSSL 16:8e0d178b1d1e 506 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 507 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 508 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 509 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 510 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 511 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 512 /* A[4] * B[4] */
wolfSSL 16:8e0d178b1d1e 513 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 514 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 515 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 516 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 517 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 518 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 519 /* A[5] * B[3] */
wolfSSL 16:8e0d178b1d1e 520 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 521 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 522 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 523 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 524 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 525 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 526 /* A[6] * B[2] */
wolfSSL 16:8e0d178b1d1e 527 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 528 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 529 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 530 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 531 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 532 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 533 /* A[7] * B[1] */
wolfSSL 16:8e0d178b1d1e 534 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 535 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 536 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 537 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 538 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 539 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 540 "str r5, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 541 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 542 /* A[2] * B[7] */
wolfSSL 16:8e0d178b1d1e 543 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 544 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 545 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 546 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 547 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 548 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 549 /* A[3] * B[6] */
wolfSSL 16:8e0d178b1d1e 550 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 551 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 552 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 553 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 554 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 555 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 556 /* A[4] * B[5] */
wolfSSL 16:8e0d178b1d1e 557 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 558 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 559 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 560 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 561 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 562 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 563 /* A[5] * B[4] */
wolfSSL 16:8e0d178b1d1e 564 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 565 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 566 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 567 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 568 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 569 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 570 /* A[6] * B[3] */
wolfSSL 16:8e0d178b1d1e 571 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 572 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 573 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 574 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 575 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 576 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 577 /* A[7] * B[2] */
wolfSSL 16:8e0d178b1d1e 578 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 579 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 580 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 581 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 582 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 583 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 584 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 585 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 586 /* A[3] * B[7] */
wolfSSL 16:8e0d178b1d1e 587 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 588 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 589 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 590 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 591 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 592 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 593 /* A[4] * B[6] */
wolfSSL 16:8e0d178b1d1e 594 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 595 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 596 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 597 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 598 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 599 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 600 /* A[5] * B[5] */
wolfSSL 16:8e0d178b1d1e 601 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 602 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 603 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 604 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 605 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 606 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 607 /* A[6] * B[4] */
wolfSSL 16:8e0d178b1d1e 608 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 609 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 610 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 611 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 612 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 613 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 614 /* A[7] * B[3] */
wolfSSL 16:8e0d178b1d1e 615 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 616 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 617 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 618 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 619 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 620 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 621 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 622 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 623 /* A[4] * B[7] */
wolfSSL 16:8e0d178b1d1e 624 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 625 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 626 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 627 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 628 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 629 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 630 /* A[5] * B[6] */
wolfSSL 16:8e0d178b1d1e 631 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 632 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 633 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 634 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 635 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 636 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 637 /* A[6] * B[5] */
wolfSSL 16:8e0d178b1d1e 638 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 639 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 640 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 641 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 642 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 643 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 644 /* A[7] * B[4] */
wolfSSL 16:8e0d178b1d1e 645 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 646 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 647 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 648 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 649 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 650 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 651 "str r5, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 652 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 653 /* A[5] * B[7] */
wolfSSL 16:8e0d178b1d1e 654 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 655 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 656 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 657 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 658 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 659 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 660 /* A[6] * B[6] */
wolfSSL 16:8e0d178b1d1e 661 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 662 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 663 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 664 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 665 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 666 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 667 /* A[7] * B[5] */
wolfSSL 16:8e0d178b1d1e 668 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 669 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 670 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 671 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 672 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 673 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 674 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 675 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 676 /* A[6] * B[7] */
wolfSSL 16:8e0d178b1d1e 677 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 678 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 679 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 680 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 681 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 682 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 683 /* A[7] * B[6] */
wolfSSL 16:8e0d178b1d1e 684 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 685 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 686 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 687 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 688 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 689 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 690 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 691 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 692 /* A[7] * B[7] */
wolfSSL 16:8e0d178b1d1e 693 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 694 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 695 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 696 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 697 "adc r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 698 "str r5, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 699 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 700 /* Transfer tmp to r */
wolfSSL 16:8e0d178b1d1e 701 "ldr r3, [%[tmp], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 702 "ldr r4, [%[tmp], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 703 "ldr r5, [%[tmp], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 704 "ldr r6, [%[tmp], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 705 "str r3, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 706 "str r4, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 707 "str r5, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 708 "str r6, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 709 "ldr r3, [%[tmp], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 710 "ldr r4, [%[tmp], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 711 "ldr r5, [%[tmp], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 712 "ldr r6, [%[tmp], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 713 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 714 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 715 "str r5, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 716 "str r6, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 717 :
wolfSSL 16:8e0d178b1d1e 718 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [tmp] "r" (tmp)
wolfSSL 16:8e0d178b1d1e 719 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 720 );
wolfSSL 16:8e0d178b1d1e 721 }
wolfSSL 16:8e0d178b1d1e 722
wolfSSL 16:8e0d178b1d1e 723 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 724 *
wolfSSL 16:8e0d178b1d1e 725 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 726 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 727 */
wolfSSL 16:8e0d178b1d1e 728 SP_NOINLINE static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 729 {
wolfSSL 16:8e0d178b1d1e 730 sp_digit tmp[8];
wolfSSL 16:8e0d178b1d1e 731 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 732 /* A[0] * A[0] */
wolfSSL 16:8e0d178b1d1e 733 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 734 "umull r3, r4, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 735 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 736 "str r3, [%[tmp], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 737 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 738 /* A[0] * A[1] */
wolfSSL 16:8e0d178b1d1e 739 "ldr r8, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 740 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 741 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 742 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 743 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 744 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 745 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 746 "str r4, [%[tmp], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 747 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 748 /* A[0] * A[2] */
wolfSSL 16:8e0d178b1d1e 749 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 750 "ldr r8, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 751 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 752 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 753 "adc r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 754 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 755 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 756 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 757 /* A[1] * A[1] */
wolfSSL 16:8e0d178b1d1e 758 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 759 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 760 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 761 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 762 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 763 "str r5, [%[tmp], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 764 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 765 /* A[0] * A[3] */
wolfSSL 16:8e0d178b1d1e 766 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 767 "ldr r8, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 768 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 769 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 770 /* A[1] * A[2] */
wolfSSL 16:8e0d178b1d1e 771 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 772 "ldr r8, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 773 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 774 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 775 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 776 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 777 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 778 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 779 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 780 "adds r3, r3, r9\n\t"
wolfSSL 16:8e0d178b1d1e 781 "adcs r4, r4, r10\n\t"
wolfSSL 16:8e0d178b1d1e 782 "adc r5, r5, r11\n\t"
wolfSSL 16:8e0d178b1d1e 783 "str r3, [%[tmp], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 784 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 785 /* A[0] * A[4] */
wolfSSL 16:8e0d178b1d1e 786 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 787 "ldr r8, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 788 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 789 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 790 /* A[1] * A[3] */
wolfSSL 16:8e0d178b1d1e 791 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 792 "ldr r8, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 793 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 794 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 795 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 796 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 797 /* A[2] * A[2] */
wolfSSL 16:8e0d178b1d1e 798 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 799 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 800 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 801 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 802 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 803 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 804 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 805 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 806 "adds r4, r4, r9\n\t"
wolfSSL 16:8e0d178b1d1e 807 "adcs r5, r5, r10\n\t"
wolfSSL 16:8e0d178b1d1e 808 "adc r3, r3, r11\n\t"
wolfSSL 16:8e0d178b1d1e 809 "str r4, [%[tmp], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 810 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 811 /* A[0] * A[5] */
wolfSSL 16:8e0d178b1d1e 812 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 813 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 814 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 815 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 816 /* A[1] * A[4] */
wolfSSL 16:8e0d178b1d1e 817 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 818 "ldr r8, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 819 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 820 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 821 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 822 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 823 /* A[2] * A[3] */
wolfSSL 16:8e0d178b1d1e 824 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 825 "ldr r8, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 826 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 827 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 828 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 829 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 830 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 831 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 832 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 833 "adds r5, r5, r9\n\t"
wolfSSL 16:8e0d178b1d1e 834 "adcs r3, r3, r10\n\t"
wolfSSL 16:8e0d178b1d1e 835 "adc r4, r4, r11\n\t"
wolfSSL 16:8e0d178b1d1e 836 "str r5, [%[tmp], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 837 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 838 /* A[0] * A[6] */
wolfSSL 16:8e0d178b1d1e 839 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 840 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 841 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 842 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 843 /* A[1] * A[5] */
wolfSSL 16:8e0d178b1d1e 844 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 845 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 846 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 847 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 848 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 849 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 850 /* A[2] * A[4] */
wolfSSL 16:8e0d178b1d1e 851 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 852 "ldr r8, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 853 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 854 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 855 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 856 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 857 /* A[3] * A[3] */
wolfSSL 16:8e0d178b1d1e 858 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 859 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 860 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 861 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 862 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 863 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 864 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 865 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 866 "adds r3, r3, r9\n\t"
wolfSSL 16:8e0d178b1d1e 867 "adcs r4, r4, r10\n\t"
wolfSSL 16:8e0d178b1d1e 868 "adc r5, r5, r11\n\t"
wolfSSL 16:8e0d178b1d1e 869 "str r3, [%[tmp], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 870 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 871 /* A[0] * A[7] */
wolfSSL 16:8e0d178b1d1e 872 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 873 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 874 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 875 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 876 /* A[1] * A[6] */
wolfSSL 16:8e0d178b1d1e 877 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 878 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 879 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 880 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 881 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 882 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 883 /* A[2] * A[5] */
wolfSSL 16:8e0d178b1d1e 884 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 885 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 886 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 887 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 888 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 889 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 890 /* A[3] * A[4] */
wolfSSL 16:8e0d178b1d1e 891 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 892 "ldr r8, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 893 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 894 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 895 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 896 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 897 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 898 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 899 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 900 "adds r4, r4, r9\n\t"
wolfSSL 16:8e0d178b1d1e 901 "adcs r5, r5, r10\n\t"
wolfSSL 16:8e0d178b1d1e 902 "adc r3, r3, r11\n\t"
wolfSSL 16:8e0d178b1d1e 903 "str r4, [%[tmp], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 904 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 905 /* A[1] * A[7] */
wolfSSL 16:8e0d178b1d1e 906 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 907 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 908 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 909 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 910 /* A[2] * A[6] */
wolfSSL 16:8e0d178b1d1e 911 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 912 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 913 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 914 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 915 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 916 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 917 /* A[3] * A[5] */
wolfSSL 16:8e0d178b1d1e 918 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 919 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 920 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 921 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 922 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 923 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 924 /* A[4] * A[4] */
wolfSSL 16:8e0d178b1d1e 925 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 926 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 927 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 928 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 929 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 930 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 931 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 932 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 933 "adds r5, r5, r9\n\t"
wolfSSL 16:8e0d178b1d1e 934 "adcs r3, r3, r10\n\t"
wolfSSL 16:8e0d178b1d1e 935 "adc r4, r4, r11\n\t"
wolfSSL 16:8e0d178b1d1e 936 "str r5, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 937 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 938 /* A[2] * A[7] */
wolfSSL 16:8e0d178b1d1e 939 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 940 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 941 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 942 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 943 /* A[3] * A[6] */
wolfSSL 16:8e0d178b1d1e 944 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 945 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 946 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 947 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 948 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 949 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 950 /* A[4] * A[5] */
wolfSSL 16:8e0d178b1d1e 951 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 952 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 953 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 954 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 955 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 956 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 957 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 958 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 959 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 960 "adds r3, r3, r9\n\t"
wolfSSL 16:8e0d178b1d1e 961 "adcs r4, r4, r10\n\t"
wolfSSL 16:8e0d178b1d1e 962 "adc r5, r5, r11\n\t"
wolfSSL 16:8e0d178b1d1e 963 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 964 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 965 /* A[3] * A[7] */
wolfSSL 16:8e0d178b1d1e 966 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 967 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 968 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 969 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 970 /* A[4] * A[6] */
wolfSSL 16:8e0d178b1d1e 971 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 972 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 973 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 974 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 975 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 976 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 977 /* A[5] * A[5] */
wolfSSL 16:8e0d178b1d1e 978 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 979 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 980 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 981 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 982 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 983 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 984 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 985 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 986 "adds r4, r4, r9\n\t"
wolfSSL 16:8e0d178b1d1e 987 "adcs r5, r5, r10\n\t"
wolfSSL 16:8e0d178b1d1e 988 "adc r3, r3, r11\n\t"
wolfSSL 16:8e0d178b1d1e 989 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 990 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 991 /* A[4] * A[7] */
wolfSSL 16:8e0d178b1d1e 992 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 993 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 994 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 995 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 996 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 997 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 998 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 999 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1000 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1001 /* A[5] * A[6] */
wolfSSL 16:8e0d178b1d1e 1002 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 1003 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 1004 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1005 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1006 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1007 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1008 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1009 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1010 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1011 "str r5, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 1012 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1013 /* A[5] * A[7] */
wolfSSL 16:8e0d178b1d1e 1014 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 1015 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 1016 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1017 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1018 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1019 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1020 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1021 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1022 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1023 /* A[6] * A[6] */
wolfSSL 16:8e0d178b1d1e 1024 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 1025 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1026 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1027 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1028 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1029 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 1030 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1031 /* A[6] * A[7] */
wolfSSL 16:8e0d178b1d1e 1032 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 1033 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 1034 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1035 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1036 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1037 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1038 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1039 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1040 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1041 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 1042 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 1043 /* A[7] * A[7] */
wolfSSL 16:8e0d178b1d1e 1044 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 1045 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1046 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1047 "adc r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1048 "str r5, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 1049 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 1050 /* Transfer tmp to r */
wolfSSL 16:8e0d178b1d1e 1051 "ldr r3, [%[tmp], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 1052 "ldr r4, [%[tmp], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 1053 "ldr r5, [%[tmp], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 1054 "ldr r6, [%[tmp], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 1055 "str r3, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 1056 "str r4, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 1057 "str r5, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 1058 "str r6, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 1059 "ldr r3, [%[tmp], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 1060 "ldr r4, [%[tmp], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 1061 "ldr r5, [%[tmp], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 1062 "ldr r6, [%[tmp], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 1063 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 1064 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 1065 "str r5, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 1066 "str r6, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 1067 :
wolfSSL 16:8e0d178b1d1e 1068 : [r] "r" (r), [a] "r" (a), [tmp] "r" (tmp)
wolfSSL 16:8e0d178b1d1e 1069 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11"
wolfSSL 16:8e0d178b1d1e 1070 );
wolfSSL 16:8e0d178b1d1e 1071 }
wolfSSL 16:8e0d178b1d1e 1072
wolfSSL 16:8e0d178b1d1e 1073 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 1074 *
wolfSSL 16:8e0d178b1d1e 1075 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1076 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1077 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 1078 */
wolfSSL 16:8e0d178b1d1e 1079 SP_NOINLINE static sp_digit sp_2048_add_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 1080 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 1081 {
wolfSSL 16:8e0d178b1d1e 1082 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 1083
wolfSSL 16:8e0d178b1d1e 1084 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 1085 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1086 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1087 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1088 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1089 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1090 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1091 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1092 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1093 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1094 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1095 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1096 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1097 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1098 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1099 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1100 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1101 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1102 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1103 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1104 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1105 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 1106 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 1107 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 1108 :
wolfSSL 16:8e0d178b1d1e 1109 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 1110 );
wolfSSL 16:8e0d178b1d1e 1111
wolfSSL 16:8e0d178b1d1e 1112 return c;
wolfSSL 16:8e0d178b1d1e 1113 }
wolfSSL 16:8e0d178b1d1e 1114
wolfSSL 16:8e0d178b1d1e 1115 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 1116 *
wolfSSL 16:8e0d178b1d1e 1117 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1118 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1119 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 1120 */
wolfSSL 16:8e0d178b1d1e 1121 SP_NOINLINE static sp_digit sp_2048_sub_in_place_16(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 1122 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 1123 {
wolfSSL 16:8e0d178b1d1e 1124 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 1125
wolfSSL 16:8e0d178b1d1e 1126 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 1127 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1128 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1129 "subs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1130 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1131 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1132 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1133 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1134 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1135 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1136 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1137 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1138 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1139 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1140 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1141 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1142 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1143 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1144 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1145 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1146 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1147 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1148 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1149 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1150 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1151 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1152 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1153 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1154 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1155 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1156 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1157 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1158 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1159 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1160 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1161 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1162 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1163 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1164 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1165 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1166 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1167 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 1168 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 1169 :
wolfSSL 16:8e0d178b1d1e 1170 : "memory", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 1171 );
wolfSSL 16:8e0d178b1d1e 1172
wolfSSL 16:8e0d178b1d1e 1173 return c;
wolfSSL 16:8e0d178b1d1e 1174 }
wolfSSL 16:8e0d178b1d1e 1175
wolfSSL 16:8e0d178b1d1e 1176 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 1177 *
wolfSSL 16:8e0d178b1d1e 1178 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1179 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1180 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 1181 */
wolfSSL 16:8e0d178b1d1e 1182 SP_NOINLINE static sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 1183 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 1184 {
wolfSSL 16:8e0d178b1d1e 1185 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 1186
wolfSSL 16:8e0d178b1d1e 1187 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 1188 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1189 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1190 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1191 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1192 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1193 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1194 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1195 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1196 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1197 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1198 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1199 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1200 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1201 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1202 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1203 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1204 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1205 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1206 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1207 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1208 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1209 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1210 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1211 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1212 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1213 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1214 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1215 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1216 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1217 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1218 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1219 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1220 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1221 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1222 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1223 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1224 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1225 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1226 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1227 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1228 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 1229 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 1230 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 1231 :
wolfSSL 16:8e0d178b1d1e 1232 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 1233 );
wolfSSL 16:8e0d178b1d1e 1234
wolfSSL 16:8e0d178b1d1e 1235 return c;
wolfSSL 16:8e0d178b1d1e 1236 }
wolfSSL 16:8e0d178b1d1e 1237
wolfSSL 16:8e0d178b1d1e 1238 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 1239 *
wolfSSL 16:8e0d178b1d1e 1240 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1241 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1242 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 1243 */
wolfSSL 16:8e0d178b1d1e 1244 static void sp_2048_mask_8(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 1245 {
wolfSSL 16:8e0d178b1d1e 1246 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 1247 int i;
wolfSSL 16:8e0d178b1d1e 1248
wolfSSL 16:8e0d178b1d1e 1249 for (i=0; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 1250 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 1251 }
wolfSSL 16:8e0d178b1d1e 1252 #else
wolfSSL 16:8e0d178b1d1e 1253 r[0] = a[0] & m;
wolfSSL 16:8e0d178b1d1e 1254 r[1] = a[1] & m;
wolfSSL 16:8e0d178b1d1e 1255 r[2] = a[2] & m;
wolfSSL 16:8e0d178b1d1e 1256 r[3] = a[3] & m;
wolfSSL 16:8e0d178b1d1e 1257 r[4] = a[4] & m;
wolfSSL 16:8e0d178b1d1e 1258 r[5] = a[5] & m;
wolfSSL 16:8e0d178b1d1e 1259 r[6] = a[6] & m;
wolfSSL 16:8e0d178b1d1e 1260 r[7] = a[7] & m;
wolfSSL 16:8e0d178b1d1e 1261 #endif
wolfSSL 16:8e0d178b1d1e 1262 }
wolfSSL 16:8e0d178b1d1e 1263
wolfSSL 16:8e0d178b1d1e 1264 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 1265 *
wolfSSL 16:8e0d178b1d1e 1266 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1267 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1268 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 1269 */
wolfSSL 16:8e0d178b1d1e 1270 SP_NOINLINE static void sp_2048_mul_16(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 1271 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 1272 {
wolfSSL 16:8e0d178b1d1e 1273 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 1274 sp_digit z1[16];
wolfSSL 16:8e0d178b1d1e 1275 sp_digit a1[8];
wolfSSL 16:8e0d178b1d1e 1276 sp_digit b1[8];
wolfSSL 16:8e0d178b1d1e 1277 sp_digit z2[16];
wolfSSL 16:8e0d178b1d1e 1278 sp_digit u, ca, cb;
wolfSSL 16:8e0d178b1d1e 1279
wolfSSL 16:8e0d178b1d1e 1280 ca = sp_2048_add_8(a1, a, &a[8]);
wolfSSL 16:8e0d178b1d1e 1281 cb = sp_2048_add_8(b1, b, &b[8]);
wolfSSL 16:8e0d178b1d1e 1282 u = ca & cb;
wolfSSL 16:8e0d178b1d1e 1283 sp_2048_mul_8(z1, a1, b1);
wolfSSL 16:8e0d178b1d1e 1284 sp_2048_mul_8(z2, &a[8], &b[8]);
wolfSSL 16:8e0d178b1d1e 1285 sp_2048_mul_8(z0, a, b);
wolfSSL 16:8e0d178b1d1e 1286 sp_2048_mask_8(r + 16, a1, 0 - cb);
wolfSSL 16:8e0d178b1d1e 1287 sp_2048_mask_8(b1, b1, 0 - ca);
wolfSSL 16:8e0d178b1d1e 1288 u += sp_2048_add_8(r + 16, r + 16, b1);
wolfSSL 16:8e0d178b1d1e 1289 u += sp_2048_sub_in_place_16(z1, z2);
wolfSSL 16:8e0d178b1d1e 1290 u += sp_2048_sub_in_place_16(z1, z0);
wolfSSL 16:8e0d178b1d1e 1291 u += sp_2048_add_16(r + 8, r + 8, z1);
wolfSSL 16:8e0d178b1d1e 1292 r[24] = u;
wolfSSL 16:8e0d178b1d1e 1293 XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));
wolfSSL 16:8e0d178b1d1e 1294 (void)sp_2048_add_16(r + 16, r + 16, z2);
wolfSSL 16:8e0d178b1d1e 1295 }
wolfSSL 16:8e0d178b1d1e 1296
wolfSSL 16:8e0d178b1d1e 1297 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 1298 *
wolfSSL 16:8e0d178b1d1e 1299 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1300 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1301 */
wolfSSL 16:8e0d178b1d1e 1302 SP_NOINLINE static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 1303 {
wolfSSL 16:8e0d178b1d1e 1304 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 1305 sp_digit z2[16];
wolfSSL 16:8e0d178b1d1e 1306 sp_digit z1[16];
wolfSSL 16:8e0d178b1d1e 1307 sp_digit a1[8];
wolfSSL 16:8e0d178b1d1e 1308 sp_digit u;
wolfSSL 16:8e0d178b1d1e 1309
wolfSSL 16:8e0d178b1d1e 1310 u = sp_2048_add_8(a1, a, &a[8]);
wolfSSL 16:8e0d178b1d1e 1311 sp_2048_sqr_8(z1, a1);
wolfSSL 16:8e0d178b1d1e 1312 sp_2048_sqr_8(z2, &a[8]);
wolfSSL 16:8e0d178b1d1e 1313 sp_2048_sqr_8(z0, a);
wolfSSL 16:8e0d178b1d1e 1314 sp_2048_mask_8(r + 16, a1, 0 - u);
wolfSSL 16:8e0d178b1d1e 1315 u += sp_2048_add_8(r + 16, r + 16, r + 16);
wolfSSL 16:8e0d178b1d1e 1316 u += sp_2048_sub_in_place_16(z1, z2);
wolfSSL 16:8e0d178b1d1e 1317 u += sp_2048_sub_in_place_16(z1, z0);
wolfSSL 16:8e0d178b1d1e 1318 u += sp_2048_add_16(r + 8, r + 8, z1);
wolfSSL 16:8e0d178b1d1e 1319 r[24] = u;
wolfSSL 16:8e0d178b1d1e 1320 XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));
wolfSSL 16:8e0d178b1d1e 1321 (void)sp_2048_add_16(r + 16, r + 16, z2);
wolfSSL 16:8e0d178b1d1e 1322 }
wolfSSL 16:8e0d178b1d1e 1323
wolfSSL 16:8e0d178b1d1e 1324 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 1325 *
wolfSSL 16:8e0d178b1d1e 1326 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1327 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1328 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 1329 */
wolfSSL 16:8e0d178b1d1e 1330 SP_NOINLINE static sp_digit sp_2048_sub_in_place_32(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 1331 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 1332 {
wolfSSL 16:8e0d178b1d1e 1333 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 1334
wolfSSL 16:8e0d178b1d1e 1335 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 1336 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1337 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1338 "subs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1339 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1340 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1341 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1342 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1343 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1344 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1345 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1346 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1347 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1348 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1349 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1350 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1351 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1352 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1353 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1354 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1355 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1356 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1357 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1358 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1359 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1360 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1361 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1362 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1363 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1364 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1365 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1366 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1367 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1368 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1369 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1370 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1371 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1372 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1373 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1374 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1375 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1376 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1377 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1378 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1379 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1380 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1381 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1382 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1383 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1384 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1385 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1386 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1387 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1388 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1389 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1390 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1391 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1392 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1393 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1394 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1395 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1396 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1397 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1398 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1399 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1400 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1401 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1402 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1403 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1404 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1405 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1406 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1407 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1408 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1409 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1410 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1411 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1412 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1413 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1414 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1415 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1416 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 1417 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 1418 :
wolfSSL 16:8e0d178b1d1e 1419 : "memory", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 1420 );
wolfSSL 16:8e0d178b1d1e 1421
wolfSSL 16:8e0d178b1d1e 1422 return c;
wolfSSL 16:8e0d178b1d1e 1423 }
wolfSSL 16:8e0d178b1d1e 1424
wolfSSL 16:8e0d178b1d1e 1425 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 1426 *
wolfSSL 16:8e0d178b1d1e 1427 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1428 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1429 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 1430 */
wolfSSL 16:8e0d178b1d1e 1431 SP_NOINLINE static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 1432 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 1433 {
wolfSSL 16:8e0d178b1d1e 1434 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 1435
wolfSSL 16:8e0d178b1d1e 1436 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 1437 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1438 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1439 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1440 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1441 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1442 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1443 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1444 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1445 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1446 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1447 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1448 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1449 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1450 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1451 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1452 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1453 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1454 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1455 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1456 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1457 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1458 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1459 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1460 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1461 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1462 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1463 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1464 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1465 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1466 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1467 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1468 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1469 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1470 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1471 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1472 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1473 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1474 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1475 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1476 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1477 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1478 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1479 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1480 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1481 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1482 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1483 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1484 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1485 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1486 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1487 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1488 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1489 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1490 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1491 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1492 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1493 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1494 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1495 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1496 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1497 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1498 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1499 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1500 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1501 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1502 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1503 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1504 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1505 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1506 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1507 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1508 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1509 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1510 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1511 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1512 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1513 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1514 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1515 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1516 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1517 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 1518 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 1519 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 1520 :
wolfSSL 16:8e0d178b1d1e 1521 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 1522 );
wolfSSL 16:8e0d178b1d1e 1523
wolfSSL 16:8e0d178b1d1e 1524 return c;
wolfSSL 16:8e0d178b1d1e 1525 }
wolfSSL 16:8e0d178b1d1e 1526
wolfSSL 16:8e0d178b1d1e 1527 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 1528 *
wolfSSL 16:8e0d178b1d1e 1529 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1530 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1531 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 1532 */
wolfSSL 16:8e0d178b1d1e 1533 static void sp_2048_mask_16(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 1534 {
wolfSSL 16:8e0d178b1d1e 1535 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 1536 int i;
wolfSSL 16:8e0d178b1d1e 1537
wolfSSL 16:8e0d178b1d1e 1538 for (i=0; i<16; i++) {
wolfSSL 16:8e0d178b1d1e 1539 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 1540 }
wolfSSL 16:8e0d178b1d1e 1541 #else
wolfSSL 16:8e0d178b1d1e 1542 int i;
wolfSSL 16:8e0d178b1d1e 1543
wolfSSL 16:8e0d178b1d1e 1544 for (i = 0; i < 16; i += 8) {
wolfSSL 16:8e0d178b1d1e 1545 r[i+0] = a[i+0] & m;
wolfSSL 16:8e0d178b1d1e 1546 r[i+1] = a[i+1] & m;
wolfSSL 16:8e0d178b1d1e 1547 r[i+2] = a[i+2] & m;
wolfSSL 16:8e0d178b1d1e 1548 r[i+3] = a[i+3] & m;
wolfSSL 16:8e0d178b1d1e 1549 r[i+4] = a[i+4] & m;
wolfSSL 16:8e0d178b1d1e 1550 r[i+5] = a[i+5] & m;
wolfSSL 16:8e0d178b1d1e 1551 r[i+6] = a[i+6] & m;
wolfSSL 16:8e0d178b1d1e 1552 r[i+7] = a[i+7] & m;
wolfSSL 16:8e0d178b1d1e 1553 }
wolfSSL 16:8e0d178b1d1e 1554 #endif
wolfSSL 16:8e0d178b1d1e 1555 }
wolfSSL 16:8e0d178b1d1e 1556
wolfSSL 16:8e0d178b1d1e 1557 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 1558 *
wolfSSL 16:8e0d178b1d1e 1559 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1560 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1561 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 1562 */
wolfSSL 16:8e0d178b1d1e 1563 SP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 1564 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 1565 {
wolfSSL 16:8e0d178b1d1e 1566 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 1567 sp_digit z1[32];
wolfSSL 16:8e0d178b1d1e 1568 sp_digit a1[16];
wolfSSL 16:8e0d178b1d1e 1569 sp_digit b1[16];
wolfSSL 16:8e0d178b1d1e 1570 sp_digit z2[32];
wolfSSL 16:8e0d178b1d1e 1571 sp_digit u, ca, cb;
wolfSSL 16:8e0d178b1d1e 1572
wolfSSL 16:8e0d178b1d1e 1573 ca = sp_2048_add_16(a1, a, &a[16]);
wolfSSL 16:8e0d178b1d1e 1574 cb = sp_2048_add_16(b1, b, &b[16]);
wolfSSL 16:8e0d178b1d1e 1575 u = ca & cb;
wolfSSL 16:8e0d178b1d1e 1576 sp_2048_mul_16(z1, a1, b1);
wolfSSL 16:8e0d178b1d1e 1577 sp_2048_mul_16(z2, &a[16], &b[16]);
wolfSSL 16:8e0d178b1d1e 1578 sp_2048_mul_16(z0, a, b);
wolfSSL 16:8e0d178b1d1e 1579 sp_2048_mask_16(r + 32, a1, 0 - cb);
wolfSSL 16:8e0d178b1d1e 1580 sp_2048_mask_16(b1, b1, 0 - ca);
wolfSSL 16:8e0d178b1d1e 1581 u += sp_2048_add_16(r + 32, r + 32, b1);
wolfSSL 16:8e0d178b1d1e 1582 u += sp_2048_sub_in_place_32(z1, z2);
wolfSSL 16:8e0d178b1d1e 1583 u += sp_2048_sub_in_place_32(z1, z0);
wolfSSL 16:8e0d178b1d1e 1584 u += sp_2048_add_32(r + 16, r + 16, z1);
wolfSSL 16:8e0d178b1d1e 1585 r[48] = u;
wolfSSL 16:8e0d178b1d1e 1586 XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));
wolfSSL 16:8e0d178b1d1e 1587 (void)sp_2048_add_32(r + 32, r + 32, z2);
wolfSSL 16:8e0d178b1d1e 1588 }
wolfSSL 16:8e0d178b1d1e 1589
wolfSSL 16:8e0d178b1d1e 1590 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 1591 *
wolfSSL 16:8e0d178b1d1e 1592 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1593 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1594 */
wolfSSL 16:8e0d178b1d1e 1595 SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 1596 {
wolfSSL 16:8e0d178b1d1e 1597 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 1598 sp_digit z2[32];
wolfSSL 16:8e0d178b1d1e 1599 sp_digit z1[32];
wolfSSL 16:8e0d178b1d1e 1600 sp_digit a1[16];
wolfSSL 16:8e0d178b1d1e 1601 sp_digit u;
wolfSSL 16:8e0d178b1d1e 1602
wolfSSL 16:8e0d178b1d1e 1603 u = sp_2048_add_16(a1, a, &a[16]);
wolfSSL 16:8e0d178b1d1e 1604 sp_2048_sqr_16(z1, a1);
wolfSSL 16:8e0d178b1d1e 1605 sp_2048_sqr_16(z2, &a[16]);
wolfSSL 16:8e0d178b1d1e 1606 sp_2048_sqr_16(z0, a);
wolfSSL 16:8e0d178b1d1e 1607 sp_2048_mask_16(r + 32, a1, 0 - u);
wolfSSL 16:8e0d178b1d1e 1608 u += sp_2048_add_16(r + 32, r + 32, r + 32);
wolfSSL 16:8e0d178b1d1e 1609 u += sp_2048_sub_in_place_32(z1, z2);
wolfSSL 16:8e0d178b1d1e 1610 u += sp_2048_sub_in_place_32(z1, z0);
wolfSSL 16:8e0d178b1d1e 1611 u += sp_2048_add_32(r + 16, r + 16, z1);
wolfSSL 16:8e0d178b1d1e 1612 r[48] = u;
wolfSSL 16:8e0d178b1d1e 1613 XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));
wolfSSL 16:8e0d178b1d1e 1614 (void)sp_2048_add_32(r + 32, r + 32, z2);
wolfSSL 16:8e0d178b1d1e 1615 }
wolfSSL 16:8e0d178b1d1e 1616
wolfSSL 16:8e0d178b1d1e 1617 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 1618 *
wolfSSL 16:8e0d178b1d1e 1619 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1620 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1621 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 1622 */
wolfSSL 16:8e0d178b1d1e 1623 SP_NOINLINE static sp_digit sp_2048_sub_in_place_64(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 1624 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 1625 {
wolfSSL 16:8e0d178b1d1e 1626 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 1627
wolfSSL 16:8e0d178b1d1e 1628 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 1629 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1630 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1631 "subs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1632 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1633 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1634 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1635 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1636 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1637 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1638 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1639 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1640 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1641 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1642 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1643 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1644 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1645 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1646 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1647 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1648 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1649 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1650 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1651 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1652 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1653 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1654 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1655 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1656 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1657 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1658 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1659 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1660 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1661 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1662 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1663 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1664 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1665 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1666 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1667 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1668 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1669 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1670 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1671 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1672 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1673 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1674 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1675 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1676 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1677 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1678 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1679 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1680 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1681 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1682 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1683 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1684 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1685 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1686 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1687 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1688 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1689 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1690 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1691 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1692 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1693 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1694 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1695 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1696 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1697 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1698 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1699 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1700 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1701 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1702 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1703 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1704 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1705 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1706 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1707 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1708 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1709 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1710 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1711 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1712 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1713 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1714 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1715 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1716 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1717 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1718 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1719 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1720 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1721 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1722 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1723 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1724 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1725 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1726 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1727 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1728 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1729 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1730 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1731 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1732 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1733 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1734 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1735 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1736 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1737 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1738 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1739 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1740 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1741 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1742 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1743 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1744 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1745 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1746 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1747 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1748 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1749 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1750 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1751 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1752 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1753 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1754 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1755 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1756 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1757 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1758 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1759 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1760 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1761 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1762 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1763 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1764 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1765 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1766 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1767 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1768 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1769 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1770 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1771 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1772 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1773 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1774 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1775 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1776 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1777 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1778 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1779 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1780 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1781 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1782 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1783 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1784 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1785 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 1786 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 1787 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1788 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 1789 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 1790 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 1791 :
wolfSSL 16:8e0d178b1d1e 1792 : "memory", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 1793 );
wolfSSL 16:8e0d178b1d1e 1794
wolfSSL 16:8e0d178b1d1e 1795 return c;
wolfSSL 16:8e0d178b1d1e 1796 }
wolfSSL 16:8e0d178b1d1e 1797
wolfSSL 16:8e0d178b1d1e 1798 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 1799 *
wolfSSL 16:8e0d178b1d1e 1800 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1801 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1802 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 1803 */
wolfSSL 16:8e0d178b1d1e 1804 SP_NOINLINE static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 1805 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 1806 {
wolfSSL 16:8e0d178b1d1e 1807 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 1808
wolfSSL 16:8e0d178b1d1e 1809 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 1810 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1811 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1812 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1813 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1814 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1815 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1816 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1817 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1818 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1819 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1820 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1821 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1822 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1823 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1824 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1825 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1826 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1827 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1828 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1829 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1830 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1831 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1832 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1833 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1834 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1835 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1836 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1837 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1838 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1839 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1840 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1841 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1842 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1843 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1844 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1845 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1846 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1847 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1848 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1849 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1850 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1851 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1852 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1853 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1854 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1855 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1856 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1857 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1858 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1859 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1860 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1861 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1862 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1863 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1864 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1865 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1866 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1867 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1868 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1869 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1870 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1871 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1872 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1873 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1874 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1875 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1876 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1877 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1878 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1879 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1880 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1881 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1882 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1883 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1884 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1885 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1886 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1887 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1888 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1889 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1890 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1891 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1892 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1893 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1894 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1895 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1896 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1897 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1898 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1899 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1900 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1901 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1902 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1903 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1904 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1905 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1906 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1907 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1908 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1909 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1910 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1911 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1912 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1913 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1914 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1915 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1916 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1917 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1918 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1919 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1920 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1921 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1922 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1923 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1924 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1925 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1926 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1927 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1928 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1929 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1930 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1931 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1932 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1933 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1934 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1935 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1936 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1937 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1938 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1939 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1940 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1941 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1942 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1943 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1944 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1945 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1946 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1947 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1948 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1949 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1950 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1951 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1952 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1953 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1954 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1955 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1956 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1957 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1958 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1959 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1960 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1961 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1962 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1963 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1964 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1965 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1966 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 1967 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 1968 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 1969 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 1970 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 1971 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 1972 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 1973 :
wolfSSL 16:8e0d178b1d1e 1974 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 1975 );
wolfSSL 16:8e0d178b1d1e 1976
wolfSSL 16:8e0d178b1d1e 1977 return c;
wolfSSL 16:8e0d178b1d1e 1978 }
wolfSSL 16:8e0d178b1d1e 1979
wolfSSL 16:8e0d178b1d1e 1980 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 1981 *
wolfSSL 16:8e0d178b1d1e 1982 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 1983 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 1984 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 1985 */
wolfSSL 16:8e0d178b1d1e 1986 static void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 1987 {
wolfSSL 16:8e0d178b1d1e 1988 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 1989 int i;
wolfSSL 16:8e0d178b1d1e 1990
wolfSSL 16:8e0d178b1d1e 1991 for (i=0; i<32; i++) {
wolfSSL 16:8e0d178b1d1e 1992 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 1993 }
wolfSSL 16:8e0d178b1d1e 1994 #else
wolfSSL 16:8e0d178b1d1e 1995 int i;
wolfSSL 16:8e0d178b1d1e 1996
wolfSSL 16:8e0d178b1d1e 1997 for (i = 0; i < 32; i += 8) {
wolfSSL 16:8e0d178b1d1e 1998 r[i+0] = a[i+0] & m;
wolfSSL 16:8e0d178b1d1e 1999 r[i+1] = a[i+1] & m;
wolfSSL 16:8e0d178b1d1e 2000 r[i+2] = a[i+2] & m;
wolfSSL 16:8e0d178b1d1e 2001 r[i+3] = a[i+3] & m;
wolfSSL 16:8e0d178b1d1e 2002 r[i+4] = a[i+4] & m;
wolfSSL 16:8e0d178b1d1e 2003 r[i+5] = a[i+5] & m;
wolfSSL 16:8e0d178b1d1e 2004 r[i+6] = a[i+6] & m;
wolfSSL 16:8e0d178b1d1e 2005 r[i+7] = a[i+7] & m;
wolfSSL 16:8e0d178b1d1e 2006 }
wolfSSL 16:8e0d178b1d1e 2007 #endif
wolfSSL 16:8e0d178b1d1e 2008 }
wolfSSL 16:8e0d178b1d1e 2009
wolfSSL 16:8e0d178b1d1e 2010 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 2011 *
wolfSSL 16:8e0d178b1d1e 2012 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2013 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2014 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 2015 */
wolfSSL 16:8e0d178b1d1e 2016 SP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2017 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 2018 {
wolfSSL 16:8e0d178b1d1e 2019 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 2020 sp_digit z1[64];
wolfSSL 16:8e0d178b1d1e 2021 sp_digit a1[32];
wolfSSL 16:8e0d178b1d1e 2022 sp_digit b1[32];
wolfSSL 16:8e0d178b1d1e 2023 sp_digit z2[64];
wolfSSL 16:8e0d178b1d1e 2024 sp_digit u, ca, cb;
wolfSSL 16:8e0d178b1d1e 2025
wolfSSL 16:8e0d178b1d1e 2026 ca = sp_2048_add_32(a1, a, &a[32]);
wolfSSL 16:8e0d178b1d1e 2027 cb = sp_2048_add_32(b1, b, &b[32]);
wolfSSL 16:8e0d178b1d1e 2028 u = ca & cb;
wolfSSL 16:8e0d178b1d1e 2029 sp_2048_mul_32(z1, a1, b1);
wolfSSL 16:8e0d178b1d1e 2030 sp_2048_mul_32(z2, &a[32], &b[32]);
wolfSSL 16:8e0d178b1d1e 2031 sp_2048_mul_32(z0, a, b);
wolfSSL 16:8e0d178b1d1e 2032 sp_2048_mask_32(r + 64, a1, 0 - cb);
wolfSSL 16:8e0d178b1d1e 2033 sp_2048_mask_32(b1, b1, 0 - ca);
wolfSSL 16:8e0d178b1d1e 2034 u += sp_2048_add_32(r + 64, r + 64, b1);
wolfSSL 16:8e0d178b1d1e 2035 u += sp_2048_sub_in_place_64(z1, z2);
wolfSSL 16:8e0d178b1d1e 2036 u += sp_2048_sub_in_place_64(z1, z0);
wolfSSL 16:8e0d178b1d1e 2037 u += sp_2048_add_64(r + 32, r + 32, z1);
wolfSSL 16:8e0d178b1d1e 2038 r[96] = u;
wolfSSL 16:8e0d178b1d1e 2039 XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));
wolfSSL 16:8e0d178b1d1e 2040 (void)sp_2048_add_64(r + 64, r + 64, z2);
wolfSSL 16:8e0d178b1d1e 2041 }
wolfSSL 16:8e0d178b1d1e 2042
wolfSSL 16:8e0d178b1d1e 2043 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 2044 *
wolfSSL 16:8e0d178b1d1e 2045 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2046 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2047 */
wolfSSL 16:8e0d178b1d1e 2048 SP_NOINLINE static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 2049 {
wolfSSL 16:8e0d178b1d1e 2050 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 2051 sp_digit z2[64];
wolfSSL 16:8e0d178b1d1e 2052 sp_digit z1[64];
wolfSSL 16:8e0d178b1d1e 2053 sp_digit a1[32];
wolfSSL 16:8e0d178b1d1e 2054 sp_digit u;
wolfSSL 16:8e0d178b1d1e 2055
wolfSSL 16:8e0d178b1d1e 2056 u = sp_2048_add_32(a1, a, &a[32]);
wolfSSL 16:8e0d178b1d1e 2057 sp_2048_sqr_32(z1, a1);
wolfSSL 16:8e0d178b1d1e 2058 sp_2048_sqr_32(z2, &a[32]);
wolfSSL 16:8e0d178b1d1e 2059 sp_2048_sqr_32(z0, a);
wolfSSL 16:8e0d178b1d1e 2060 sp_2048_mask_32(r + 64, a1, 0 - u);
wolfSSL 16:8e0d178b1d1e 2061 u += sp_2048_add_32(r + 64, r + 64, r + 64);
wolfSSL 16:8e0d178b1d1e 2062 u += sp_2048_sub_in_place_64(z1, z2);
wolfSSL 16:8e0d178b1d1e 2063 u += sp_2048_sub_in_place_64(z1, z0);
wolfSSL 16:8e0d178b1d1e 2064 u += sp_2048_add_64(r + 32, r + 32, z1);
wolfSSL 16:8e0d178b1d1e 2065 r[96] = u;
wolfSSL 16:8e0d178b1d1e 2066 XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));
wolfSSL 16:8e0d178b1d1e 2067 (void)sp_2048_add_64(r + 64, r + 64, z2);
wolfSSL 16:8e0d178b1d1e 2068 }
wolfSSL 16:8e0d178b1d1e 2069
wolfSSL 16:8e0d178b1d1e 2070 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 2071 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 2072 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 2073 *
wolfSSL 16:8e0d178b1d1e 2074 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2075 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2076 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 2077 */
wolfSSL 16:8e0d178b1d1e 2078 SP_NOINLINE static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2079 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 2080 {
wolfSSL 16:8e0d178b1d1e 2081 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 2082
wolfSSL 16:8e0d178b1d1e 2083 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2084 "mov r6, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2085 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2086 "add r6, r6, #256\n\t"
wolfSSL 16:8e0d178b1d1e 2087 "sub r8, r8, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2088 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2089 "adds %[c], %[c], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2090 "ldr r4, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2091 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 2092 "adcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2093 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 2094 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 2095 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 2096 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2097 "add %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2098 "add %[r], %[r], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2099 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2100 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2101 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 2102 :
wolfSSL 16:8e0d178b1d1e 2103 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 2104 );
wolfSSL 16:8e0d178b1d1e 2105
wolfSSL 16:8e0d178b1d1e 2106 return c;
wolfSSL 16:8e0d178b1d1e 2107 }
wolfSSL 16:8e0d178b1d1e 2108
wolfSSL 16:8e0d178b1d1e 2109 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 2110 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 2111 /* Sub b from a into a. (a -= b)
wolfSSL 16:8e0d178b1d1e 2112 *
wolfSSL 16:8e0d178b1d1e 2113 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2114 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 2115 */
wolfSSL 16:8e0d178b1d1e 2116 SP_NOINLINE static sp_digit sp_2048_sub_in_place_64(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2117 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 2118 {
wolfSSL 16:8e0d178b1d1e 2119 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 2120 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2121 "mov r8, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2122 "add r8, r8, #256\n\t"
wolfSSL 16:8e0d178b1d1e 2123 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2124 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2125 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 2126 "ldr r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2127 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 2128 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 2129 "ldr r6, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 2130 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2131 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2132 "str r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2133 "str r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 2134 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 2135 "add %[a], %[a], #8\n\t"
wolfSSL 16:8e0d178b1d1e 2136 "add %[b], %[b], #8\n\t"
wolfSSL 16:8e0d178b1d1e 2137 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2138 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2139 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 2140 :
wolfSSL 16:8e0d178b1d1e 2141 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 2142 );
wolfSSL 16:8e0d178b1d1e 2143
wolfSSL 16:8e0d178b1d1e 2144 return c;
wolfSSL 16:8e0d178b1d1e 2145 }
wolfSSL 16:8e0d178b1d1e 2146
wolfSSL 16:8e0d178b1d1e 2147 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 2148 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 2149 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 2150 *
wolfSSL 16:8e0d178b1d1e 2151 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2152 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2153 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 2154 */
wolfSSL 16:8e0d178b1d1e 2155 SP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2156 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 2157 {
wolfSSL 16:8e0d178b1d1e 2158 sp_digit tmp[64 * 2];
wolfSSL 16:8e0d178b1d1e 2159 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2160 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2161 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2162 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 2163 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2164 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2165 "mov r11, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 2166 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2167 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 2168 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2169 "mov r14, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2170 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2171 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 2172 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2173 "mov r6, #252\n\t"
wolfSSL 16:8e0d178b1d1e 2174 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 2175 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2176 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2177 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2178 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2179 "mov %[b], r9\n\t"
wolfSSL 16:8e0d178b1d1e 2180 "sub %[b], %[b], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2181 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 2182 "add %[b], %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 2183 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 2184 /* Multiply Start */
wolfSSL 16:8e0d178b1d1e 2185 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2186 "ldr r8, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 2187 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2188 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2189 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2190 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2191 /* Multiply Done */
wolfSSL 16:8e0d178b1d1e 2192 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2193 "sub %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2194 "cmp %[a], r14\n\t"
wolfSSL 16:8e0d178b1d1e 2195 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 2196 "mov r6, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2197 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2198 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2199 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 2200 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 2201 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 2202 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2203 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2204 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2205 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2206 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2207 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2208 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2209 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 2210 "add r6, r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 2211 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2212 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2213 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2214 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 2215 "mov %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 2216 :
wolfSSL 16:8e0d178b1d1e 2217 : [r] "r" (tmp), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 2218 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 2219 );
wolfSSL 16:8e0d178b1d1e 2220
wolfSSL 16:8e0d178b1d1e 2221 XMEMCPY(r, tmp, sizeof(tmp));
wolfSSL 16:8e0d178b1d1e 2222 }
wolfSSL 16:8e0d178b1d1e 2223
wolfSSL 16:8e0d178b1d1e 2224 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 2225 *
wolfSSL 16:8e0d178b1d1e 2226 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2227 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2228 */
wolfSSL 16:8e0d178b1d1e 2229 SP_NOINLINE static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 2230 {
wolfSSL 16:8e0d178b1d1e 2231 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2232 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2233 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2234 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2235 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 2236 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2237 "mov r6, #2\n\t"
wolfSSL 16:8e0d178b1d1e 2238 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 2239 "neg r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2240 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2241 "mov r11, sp\n\t"
wolfSSL 16:8e0d178b1d1e 2242 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2243 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2244 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 2245 "mov r6, #252\n\t"
wolfSSL 16:8e0d178b1d1e 2246 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 2247 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2248 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2249 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2250 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2251 "mov r2, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2252 "sub r2, r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2253 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 2254 "add r2, r2, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2255 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 2256 "cmp r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2257 "beq 4f\n\t"
wolfSSL 16:8e0d178b1d1e 2258 /* Multiply * 2: Start */
wolfSSL 16:8e0d178b1d1e 2259 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2260 "ldr r8, [r2]\n\t"
wolfSSL 16:8e0d178b1d1e 2261 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2262 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2263 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2264 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2265 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2266 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2267 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2268 /* Multiply * 2: Done */
wolfSSL 16:8e0d178b1d1e 2269 "bal 5f\n\t"
wolfSSL 16:8e0d178b1d1e 2270 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 2271 /* Square: Start */
wolfSSL 16:8e0d178b1d1e 2272 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2273 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2274 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2275 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2276 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2277 /* Square: Done */
wolfSSL 16:8e0d178b1d1e 2278 "\n5:\n\t"
wolfSSL 16:8e0d178b1d1e 2279 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2280 "sub r2, r2, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2281 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2282 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 2283 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2284 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2285 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 2286 "cmp %[a], r2\n\t"
wolfSSL 16:8e0d178b1d1e 2287 "bgt 3f\n\t"
wolfSSL 16:8e0d178b1d1e 2288 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2289 "add r8, r8, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2290 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2291 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 2292 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 2293 "mov %[r], r11\n\t"
wolfSSL 16:8e0d178b1d1e 2294 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2295 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2296 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2297 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2298 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2299 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2300 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2301 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2302 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 2303 "add r6, r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 2304 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2305 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2306 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 2307 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2308 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 2309 "mov %[a], r11\n\t"
wolfSSL 16:8e0d178b1d1e 2310 "mov r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2311 "lsl r3, r3, #8\n\t"
wolfSSL 16:8e0d178b1d1e 2312 "add r3, r3, #252\n\t"
wolfSSL 16:8e0d178b1d1e 2313 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 2314 "ldr r6, [%[a], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 2315 "str r6, [%[r], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 2316 "subs r3, r3, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2317 "bge 4b\n\t"
wolfSSL 16:8e0d178b1d1e 2318 "mov r6, #2\n\t"
wolfSSL 16:8e0d178b1d1e 2319 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 2320 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2321 :
wolfSSL 16:8e0d178b1d1e 2322 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 2323 : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 2324 );
wolfSSL 16:8e0d178b1d1e 2325 }
wolfSSL 16:8e0d178b1d1e 2326
wolfSSL 16:8e0d178b1d1e 2327 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 2328 #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
wolfSSL 16:8e0d178b1d1e 2329 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 2330 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 2331 *
wolfSSL 16:8e0d178b1d1e 2332 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2333 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2334 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 2335 */
wolfSSL 16:8e0d178b1d1e 2336 static void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 2337 {
wolfSSL 16:8e0d178b1d1e 2338 int i;
wolfSSL 16:8e0d178b1d1e 2339
wolfSSL 16:8e0d178b1d1e 2340 for (i=0; i<32; i++) {
wolfSSL 16:8e0d178b1d1e 2341 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 2342 }
wolfSSL 16:8e0d178b1d1e 2343 }
wolfSSL 16:8e0d178b1d1e 2344
wolfSSL 16:8e0d178b1d1e 2345 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 2346 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 2347 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 2348 *
wolfSSL 16:8e0d178b1d1e 2349 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2350 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2351 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 2352 */
wolfSSL 16:8e0d178b1d1e 2353 SP_NOINLINE static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2354 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 2355 {
wolfSSL 16:8e0d178b1d1e 2356 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 2357
wolfSSL 16:8e0d178b1d1e 2358 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2359 "mov r6, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2360 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2361 "add r6, r6, #128\n\t"
wolfSSL 16:8e0d178b1d1e 2362 "sub r8, r8, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2363 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2364 "adds %[c], %[c], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2365 "ldr r4, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2366 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 2367 "adcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2368 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 2369 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 2370 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 2371 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2372 "add %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2373 "add %[r], %[r], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2374 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2375 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2376 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 2377 :
wolfSSL 16:8e0d178b1d1e 2378 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 2379 );
wolfSSL 16:8e0d178b1d1e 2380
wolfSSL 16:8e0d178b1d1e 2381 return c;
wolfSSL 16:8e0d178b1d1e 2382 }
wolfSSL 16:8e0d178b1d1e 2383
wolfSSL 16:8e0d178b1d1e 2384 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 2385 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 2386 /* Sub b from a into a. (a -= b)
wolfSSL 16:8e0d178b1d1e 2387 *
wolfSSL 16:8e0d178b1d1e 2388 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2389 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 2390 */
wolfSSL 16:8e0d178b1d1e 2391 SP_NOINLINE static sp_digit sp_2048_sub_in_place_32(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2392 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 2393 {
wolfSSL 16:8e0d178b1d1e 2394 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 2395 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2396 "mov r8, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2397 "add r8, r8, #128\n\t"
wolfSSL 16:8e0d178b1d1e 2398 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2399 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2400 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 2401 "ldr r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2402 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 2403 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 2404 "ldr r6, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 2405 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2406 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2407 "str r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2408 "str r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 2409 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 2410 "add %[a], %[a], #8\n\t"
wolfSSL 16:8e0d178b1d1e 2411 "add %[b], %[b], #8\n\t"
wolfSSL 16:8e0d178b1d1e 2412 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2413 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2414 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 2415 :
wolfSSL 16:8e0d178b1d1e 2416 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 2417 );
wolfSSL 16:8e0d178b1d1e 2418
wolfSSL 16:8e0d178b1d1e 2419 return c;
wolfSSL 16:8e0d178b1d1e 2420 }
wolfSSL 16:8e0d178b1d1e 2421
wolfSSL 16:8e0d178b1d1e 2422 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 2423 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 2424 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 2425 *
wolfSSL 16:8e0d178b1d1e 2426 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2427 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2428 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 2429 */
wolfSSL 16:8e0d178b1d1e 2430 SP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2431 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 2432 {
wolfSSL 16:8e0d178b1d1e 2433 sp_digit tmp[32 * 2];
wolfSSL 16:8e0d178b1d1e 2434 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2435 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2436 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2437 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 2438 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2439 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2440 "mov r11, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 2441 "mov r6, #128\n\t"
wolfSSL 16:8e0d178b1d1e 2442 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2443 "mov r14, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2444 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2445 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 2446 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2447 "mov r6, #124\n\t"
wolfSSL 16:8e0d178b1d1e 2448 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 2449 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2450 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2451 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2452 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2453 "mov %[b], r9\n\t"
wolfSSL 16:8e0d178b1d1e 2454 "sub %[b], %[b], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2455 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 2456 "add %[b], %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 2457 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 2458 /* Multiply Start */
wolfSSL 16:8e0d178b1d1e 2459 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2460 "ldr r8, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 2461 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2462 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2463 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2464 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2465 /* Multiply Done */
wolfSSL 16:8e0d178b1d1e 2466 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2467 "sub %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2468 "cmp %[a], r14\n\t"
wolfSSL 16:8e0d178b1d1e 2469 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 2470 "mov r6, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2471 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2472 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2473 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 2474 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 2475 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 2476 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2477 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2478 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2479 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2480 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2481 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2482 "mov r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 2483 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2484 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2485 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2486 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 2487 "mov %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 2488 :
wolfSSL 16:8e0d178b1d1e 2489 : [r] "r" (tmp), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 2490 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 2491 );
wolfSSL 16:8e0d178b1d1e 2492
wolfSSL 16:8e0d178b1d1e 2493 XMEMCPY(r, tmp, sizeof(tmp));
wolfSSL 16:8e0d178b1d1e 2494 }
wolfSSL 16:8e0d178b1d1e 2495
wolfSSL 16:8e0d178b1d1e 2496 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 2497 *
wolfSSL 16:8e0d178b1d1e 2498 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2499 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2500 */
wolfSSL 16:8e0d178b1d1e 2501 SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 2502 {
wolfSSL 16:8e0d178b1d1e 2503 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2504 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2505 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2506 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2507 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 2508 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2509 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2510 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 2511 "neg r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2512 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2513 "mov r11, sp\n\t"
wolfSSL 16:8e0d178b1d1e 2514 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2515 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2516 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 2517 "mov r6, #124\n\t"
wolfSSL 16:8e0d178b1d1e 2518 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 2519 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2520 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2521 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2522 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2523 "mov r2, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2524 "sub r2, r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2525 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 2526 "add r2, r2, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2527 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 2528 "cmp r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2529 "beq 4f\n\t"
wolfSSL 16:8e0d178b1d1e 2530 /* Multiply * 2: Start */
wolfSSL 16:8e0d178b1d1e 2531 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2532 "ldr r8, [r2]\n\t"
wolfSSL 16:8e0d178b1d1e 2533 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2534 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2535 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2536 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2537 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2538 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2539 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2540 /* Multiply * 2: Done */
wolfSSL 16:8e0d178b1d1e 2541 "bal 5f\n\t"
wolfSSL 16:8e0d178b1d1e 2542 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 2543 /* Square: Start */
wolfSSL 16:8e0d178b1d1e 2544 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 2545 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2546 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2547 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2548 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 2549 /* Square: Done */
wolfSSL 16:8e0d178b1d1e 2550 "\n5:\n\t"
wolfSSL 16:8e0d178b1d1e 2551 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2552 "sub r2, r2, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2553 "mov r6, #128\n\t"
wolfSSL 16:8e0d178b1d1e 2554 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2555 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2556 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 2557 "cmp %[a], r2\n\t"
wolfSSL 16:8e0d178b1d1e 2558 "bgt 3f\n\t"
wolfSSL 16:8e0d178b1d1e 2559 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2560 "add r8, r8, r10\n\t"
wolfSSL 16:8e0d178b1d1e 2561 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2562 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 2563 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 2564 "mov %[r], r11\n\t"
wolfSSL 16:8e0d178b1d1e 2565 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2566 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2567 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2568 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2569 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2570 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2571 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2572 "mov r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 2573 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2574 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2575 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 2576 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2577 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 2578 "mov %[a], r11\n\t"
wolfSSL 16:8e0d178b1d1e 2579 "mov r3, #252\n\t"
wolfSSL 16:8e0d178b1d1e 2580 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 2581 "ldr r6, [%[a], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 2582 "str r6, [%[r], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 2583 "subs r3, r3, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2584 "bge 4b\n\t"
wolfSSL 16:8e0d178b1d1e 2585 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2586 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 2587 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2588 :
wolfSSL 16:8e0d178b1d1e 2589 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 2590 : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 2591 );
wolfSSL 16:8e0d178b1d1e 2592 }
wolfSSL 16:8e0d178b1d1e 2593
wolfSSL 16:8e0d178b1d1e 2594 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 2595 #endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */
wolfSSL 16:8e0d178b1d1e 2596
wolfSSL 16:8e0d178b1d1e 2597 /* Caclulate the bottom digit of -1/a mod 2^n.
wolfSSL 16:8e0d178b1d1e 2598 *
wolfSSL 16:8e0d178b1d1e 2599 * a A single precision number.
wolfSSL 16:8e0d178b1d1e 2600 * rho Bottom word of inverse.
wolfSSL 16:8e0d178b1d1e 2601 */
wolfSSL 16:8e0d178b1d1e 2602 static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)
wolfSSL 16:8e0d178b1d1e 2603 {
wolfSSL 16:8e0d178b1d1e 2604 sp_digit x, b;
wolfSSL 16:8e0d178b1d1e 2605
wolfSSL 16:8e0d178b1d1e 2606 b = a[0];
wolfSSL 16:8e0d178b1d1e 2607 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
wolfSSL 16:8e0d178b1d1e 2608 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
wolfSSL 16:8e0d178b1d1e 2609 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
wolfSSL 16:8e0d178b1d1e 2610 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
wolfSSL 16:8e0d178b1d1e 2611
wolfSSL 16:8e0d178b1d1e 2612 /* rho = -1/m mod b */
wolfSSL 16:8e0d178b1d1e 2613 *rho = -x;
wolfSSL 16:8e0d178b1d1e 2614 }
wolfSSL 16:8e0d178b1d1e 2615
wolfSSL 16:8e0d178b1d1e 2616 /* Mul a by digit b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 2617 *
wolfSSL 16:8e0d178b1d1e 2618 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2619 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2620 * b A single precision digit.
wolfSSL 16:8e0d178b1d1e 2621 */
wolfSSL 16:8e0d178b1d1e 2622 SP_NOINLINE static void sp_2048_mul_d_64(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2623 sp_digit b)
wolfSSL 16:8e0d178b1d1e 2624 {
wolfSSL 16:8e0d178b1d1e 2625 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2626 "add r9, %[a], #256\n\t"
wolfSSL 16:8e0d178b1d1e 2627 /* A[0] * B */
wolfSSL 16:8e0d178b1d1e 2628 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2629 "umull r5, r3, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 2630 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2631 "str r5, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2632 /* A[0] * B - Done */
wolfSSL 16:8e0d178b1d1e 2633 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2634 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2635 /* A[] * B */
wolfSSL 16:8e0d178b1d1e 2636 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2637 "umull r6, r8, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 2638 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2639 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2640 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2641 /* A[] * B - Done */
wolfSSL 16:8e0d178b1d1e 2642 "str r3, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2643 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2644 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2645 "cmp %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 2646 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2647 "str r3, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 2648 : [r] "+r" (r), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 2649 : [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 2650 : "memory", "r3", "r4", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 2651 );
wolfSSL 16:8e0d178b1d1e 2652 }
wolfSSL 16:8e0d178b1d1e 2653
wolfSSL 16:8e0d178b1d1e 2654 #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
wolfSSL 16:8e0d178b1d1e 2655 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 16:8e0d178b1d1e 2656 * Given m must be 2048 bits, just need to subtract.
wolfSSL 16:8e0d178b1d1e 2657 *
wolfSSL 16:8e0d178b1d1e 2658 * r A single precision number.
wolfSSL 16:8e0d178b1d1e 2659 * m A single precision number.
wolfSSL 16:8e0d178b1d1e 2660 */
wolfSSL 16:8e0d178b1d1e 2661 static void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 2662 {
wolfSSL 16:8e0d178b1d1e 2663 XMEMSET(r, 0, sizeof(sp_digit) * 32);
wolfSSL 16:8e0d178b1d1e 2664
wolfSSL 16:8e0d178b1d1e 2665 /* r = 2^n mod m */
wolfSSL 16:8e0d178b1d1e 2666 sp_2048_sub_in_place_32(r, m);
wolfSSL 16:8e0d178b1d1e 2667 }
wolfSSL 16:8e0d178b1d1e 2668
wolfSSL 16:8e0d178b1d1e 2669 /* Conditionally subtract b from a using the mask m.
wolfSSL 16:8e0d178b1d1e 2670 * m is -1 to subtract and 0 when not copying.
wolfSSL 16:8e0d178b1d1e 2671 *
wolfSSL 16:8e0d178b1d1e 2672 * r A single precision number representing condition subtract result.
wolfSSL 16:8e0d178b1d1e 2673 * a A single precision number to subtract from.
wolfSSL 16:8e0d178b1d1e 2674 * b A single precision number to subtract.
wolfSSL 16:8e0d178b1d1e 2675 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 2676 */
wolfSSL 16:8e0d178b1d1e 2677 SP_NOINLINE static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2678 const sp_digit* b, sp_digit m)
wolfSSL 16:8e0d178b1d1e 2679 {
wolfSSL 16:8e0d178b1d1e 2680 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 2681
wolfSSL 16:8e0d178b1d1e 2682 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2683 "mov r5, #128\n\t"
wolfSSL 16:8e0d178b1d1e 2684 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2685 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2686 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2687 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2688 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 2689 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2690 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 2691 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2692 "sbcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2693 "sbcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 2694 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 2695 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2696 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 2697 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2698 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 2699 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 2700 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 2701 );
wolfSSL 16:8e0d178b1d1e 2702
wolfSSL 16:8e0d178b1d1e 2703 return c;
wolfSSL 16:8e0d178b1d1e 2704 }
wolfSSL 16:8e0d178b1d1e 2705
wolfSSL 16:8e0d178b1d1e 2706 /* Reduce the number back to 2048 bits using Montgomery reduction.
wolfSSL 16:8e0d178b1d1e 2707 *
wolfSSL 16:8e0d178b1d1e 2708 * a A single precision number to reduce in place.
wolfSSL 16:8e0d178b1d1e 2709 * m The single precision number representing the modulus.
wolfSSL 16:8e0d178b1d1e 2710 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 16:8e0d178b1d1e 2711 */
wolfSSL 16:8e0d178b1d1e 2712 SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 2713 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 2714 {
wolfSSL 16:8e0d178b1d1e 2715 sp_digit ca = 0;
wolfSSL 16:8e0d178b1d1e 2716
wolfSSL 16:8e0d178b1d1e 2717 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2718 "mov r9, %[mp]\n\t"
wolfSSL 16:8e0d178b1d1e 2719 "mov r12, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 2720 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2721 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2722 "add r11, r10, #128\n\t"
wolfSSL 16:8e0d178b1d1e 2723 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2724 /* mu = a[i] * mp */
wolfSSL 16:8e0d178b1d1e 2725 "mov %[mp], r9\n\t"
wolfSSL 16:8e0d178b1d1e 2726 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 2727 "mul %[mp], %[mp], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2728 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 2729 "add r14, r10, #120\n\t"
wolfSSL 16:8e0d178b1d1e 2730 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 2731 /* a[i+j] += m[j] * mu */
wolfSSL 16:8e0d178b1d1e 2732 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 2733 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2734 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 2735 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2736 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2737 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2738 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2739 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 2740 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2741 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2742 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2743 /* a[i+j+1] += m[j+1] * mu */
wolfSSL 16:8e0d178b1d1e 2744 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 2745 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2746 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 2747 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2748 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2749 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2750 "adc r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2751 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 2752 "adds r5, r5, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2753 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2754 "str r5, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2755 "cmp r10, r14\n\t"
wolfSSL 16:8e0d178b1d1e 2756 "blt 2b\n\t"
wolfSSL 16:8e0d178b1d1e 2757 /* a[i+30] += m[30] * mu */
wolfSSL 16:8e0d178b1d1e 2758 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 2759 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2760 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 2761 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2762 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2763 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2764 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2765 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 2766 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 2767 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2768 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2769 /* a[i+31] += m[31] * mu */
wolfSSL 16:8e0d178b1d1e 2770 "mov r4, %[ca]\n\t"
wolfSSL 16:8e0d178b1d1e 2771 "mov %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 2772 /* Multiply m[31] and mu - Start */
wolfSSL 16:8e0d178b1d1e 2773 "ldr r8, [%[m]]\n\t"
wolfSSL 16:8e0d178b1d1e 2774 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2775 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2776 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2777 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 2778 /* Multiply m[31] and mu - Done */
wolfSSL 16:8e0d178b1d1e 2779 "ldr r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 2780 "ldr r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 2781 "adds r6, r6, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2782 "adcs r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2783 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 2784 "str r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 2785 "str r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 2786 /* Next word in a */
wolfSSL 16:8e0d178b1d1e 2787 "sub r10, r10, #120\n\t"
wolfSSL 16:8e0d178b1d1e 2788 "cmp r10, r11\n\t"
wolfSSL 16:8e0d178b1d1e 2789 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2790 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 2791 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 2792 : [ca] "+r" (ca), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 2793 : [m] "r" (m), [mp] "r" (mp)
wolfSSL 16:8e0d178b1d1e 2794 : "memory", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 2795 );
wolfSSL 16:8e0d178b1d1e 2796
wolfSSL 16:8e0d178b1d1e 2797 sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - ca);
wolfSSL 16:8e0d178b1d1e 2798 }
wolfSSL 16:8e0d178b1d1e 2799
wolfSSL 16:8e0d178b1d1e 2800 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 16:8e0d178b1d1e 2801 * (r = a * b mod m)
wolfSSL 16:8e0d178b1d1e 2802 *
wolfSSL 16:8e0d178b1d1e 2803 * r Result of multiplication.
wolfSSL 16:8e0d178b1d1e 2804 * a First number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 2805 * b Second number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 2806 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 2807 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 2808 */
wolfSSL 16:8e0d178b1d1e 2809 static void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 2810 const sp_digit* m, sp_digit mp)
wolfSSL 16:8e0d178b1d1e 2811 {
wolfSSL 16:8e0d178b1d1e 2812 sp_2048_mul_32(r, a, b);
wolfSSL 16:8e0d178b1d1e 2813 sp_2048_mont_reduce_32(r, m, mp);
wolfSSL 16:8e0d178b1d1e 2814 }
wolfSSL 16:8e0d178b1d1e 2815
wolfSSL 16:8e0d178b1d1e 2816 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 16:8e0d178b1d1e 2817 *
wolfSSL 16:8e0d178b1d1e 2818 * r Result of squaring.
wolfSSL 16:8e0d178b1d1e 2819 * a Number to square in Montogmery form.
wolfSSL 16:8e0d178b1d1e 2820 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 2821 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 2822 */
wolfSSL 16:8e0d178b1d1e 2823 static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 2824 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 2825 {
wolfSSL 16:8e0d178b1d1e 2826 sp_2048_sqr_32(r, a);
wolfSSL 16:8e0d178b1d1e 2827 sp_2048_mont_reduce_32(r, m, mp);
wolfSSL 16:8e0d178b1d1e 2828 }
wolfSSL 16:8e0d178b1d1e 2829
wolfSSL 16:8e0d178b1d1e 2830 /* Mul a by digit b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 2831 *
wolfSSL 16:8e0d178b1d1e 2832 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 2833 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2834 * b A single precision digit.
wolfSSL 16:8e0d178b1d1e 2835 */
wolfSSL 16:8e0d178b1d1e 2836 SP_NOINLINE static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 2837 sp_digit b)
wolfSSL 16:8e0d178b1d1e 2838 {
wolfSSL 16:8e0d178b1d1e 2839 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2840 "add r9, %[a], #128\n\t"
wolfSSL 16:8e0d178b1d1e 2841 /* A[0] * B */
wolfSSL 16:8e0d178b1d1e 2842 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2843 "umull r5, r3, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 2844 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2845 "str r5, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2846 /* A[0] * B - Done */
wolfSSL 16:8e0d178b1d1e 2847 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2848 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2849 /* A[] * B */
wolfSSL 16:8e0d178b1d1e 2850 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2851 "umull r6, r8, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 2852 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2853 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2854 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2855 /* A[] * B - Done */
wolfSSL 16:8e0d178b1d1e 2856 "str r3, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 2857 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2858 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2859 "cmp %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 2860 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2861 "str r3, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 2862 : [r] "+r" (r), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 2863 : [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 2864 : "memory", "r3", "r4", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 2865 );
wolfSSL 16:8e0d178b1d1e 2866 }
wolfSSL 16:8e0d178b1d1e 2867
wolfSSL 16:8e0d178b1d1e 2868 /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)
wolfSSL 16:8e0d178b1d1e 2869 *
wolfSSL 16:8e0d178b1d1e 2870 * d1 The high order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 2871 * d0 The low order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 2872 * div The dividend.
wolfSSL 16:8e0d178b1d1e 2873 * returns the result of the division.
wolfSSL 16:8e0d178b1d1e 2874 *
wolfSSL 16:8e0d178b1d1e 2875 * Note that this is an approximate div. It may give an answer 1 larger.
wolfSSL 16:8e0d178b1d1e 2876 */
wolfSSL 16:8e0d178b1d1e 2877 SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0,
wolfSSL 16:8e0d178b1d1e 2878 sp_digit div)
wolfSSL 16:8e0d178b1d1e 2879 {
wolfSSL 16:8e0d178b1d1e 2880 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 2881
wolfSSL 16:8e0d178b1d1e 2882 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2883 "lsr r6, %[div], #16\n\t"
wolfSSL 16:8e0d178b1d1e 2884 "add r6, r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 2885 "udiv r4, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2886 "lsl r8, r4, #16\n\t"
wolfSSL 16:8e0d178b1d1e 2887 "umull r4, r5, %[div], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2888 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 2889 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 2890 "udiv r5, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 2891 "lsl r4, r5, #16\n\t"
wolfSSL 16:8e0d178b1d1e 2892 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2893 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 2894 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 2895 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 2896 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 2897 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 2898 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2899 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2900 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 2901 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 2902 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 2903 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 2904 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 2905 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 2906 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2907 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 2908 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 2909 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 2910 "udiv r4, %[d0], %[div]\n\t"
wolfSSL 16:8e0d178b1d1e 2911 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2912 "mov %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2913 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 2914 : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div)
wolfSSL 16:8e0d178b1d1e 2915 : "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 2916 );
wolfSSL 16:8e0d178b1d1e 2917 return r;
wolfSSL 16:8e0d178b1d1e 2918 }
wolfSSL 16:8e0d178b1d1e 2919
wolfSSL 16:8e0d178b1d1e 2920 /* Compare a with b in constant time.
wolfSSL 16:8e0d178b1d1e 2921 *
wolfSSL 16:8e0d178b1d1e 2922 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 2923 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 2924 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 16:8e0d178b1d1e 2925 * respectively.
wolfSSL 16:8e0d178b1d1e 2926 */
wolfSSL 16:8e0d178b1d1e 2927 SP_NOINLINE static int32_t sp_2048_cmp_32(const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 2928 {
wolfSSL 16:8e0d178b1d1e 2929 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 2930
wolfSSL 16:8e0d178b1d1e 2931
wolfSSL 16:8e0d178b1d1e 2932 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 2933 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2934 "mvn r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 2935 "mov r6, #124\n\t"
wolfSSL 16:8e0d178b1d1e 2936 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 2937 "ldr r8, [%[a], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 2938 "ldr r5, [%[b], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 2939 "and r8, r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 2940 "and r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 2941 "mov r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2942 "subs r8, r8, r5\n\t"
wolfSSL 16:8e0d178b1d1e 2943 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2944 "add %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2945 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2946 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2947 "subs r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 2948 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2949 "sub %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 2950 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2951 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 2952 "sub r6, r6, #4\n\t"
wolfSSL 16:8e0d178b1d1e 2953 "cmp r6, #0\n\t"
wolfSSL 16:8e0d178b1d1e 2954 "bge 1b\n\t"
wolfSSL 16:8e0d178b1d1e 2955 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 2956 : [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 2957 : "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 2958 );
wolfSSL 16:8e0d178b1d1e 2959
wolfSSL 16:8e0d178b1d1e 2960 return r;
wolfSSL 16:8e0d178b1d1e 2961 }
wolfSSL 16:8e0d178b1d1e 2962
wolfSSL 16:8e0d178b1d1e 2963 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 2964 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 2965 *
wolfSSL 16:8e0d178b1d1e 2966 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 2967 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 2968 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 2969 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 2970 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 2971 */
wolfSSL 16:8e0d178b1d1e 2972 static WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 2973 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 2974 {
wolfSSL 16:8e0d178b1d1e 2975 sp_digit t1[64], t2[33];
wolfSSL 16:8e0d178b1d1e 2976 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 2977 int i;
wolfSSL 16:8e0d178b1d1e 2978
wolfSSL 16:8e0d178b1d1e 2979 (void)m;
wolfSSL 16:8e0d178b1d1e 2980
wolfSSL 16:8e0d178b1d1e 2981 div = d[31];
wolfSSL 16:8e0d178b1d1e 2982 XMEMCPY(t1, a, sizeof(*t1) * 2 * 32);
wolfSSL 16:8e0d178b1d1e 2983 for (i=31; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 2984 r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 2985
wolfSSL 16:8e0d178b1d1e 2986 sp_2048_mul_d_32(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 2987 t1[32 + i] += sp_2048_sub_in_place_32(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 2988 t1[32 + i] -= t2[32];
wolfSSL 16:8e0d178b1d1e 2989 sp_2048_mask_32(t2, d, t1[32 + i]);
wolfSSL 16:8e0d178b1d1e 2990 t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 2991 sp_2048_mask_32(t2, d, t1[32 + i]);
wolfSSL 16:8e0d178b1d1e 2992 t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 2993 }
wolfSSL 16:8e0d178b1d1e 2994
wolfSSL 16:8e0d178b1d1e 2995 r1 = sp_2048_cmp_32(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 2996 sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 2997
wolfSSL 16:8e0d178b1d1e 2998 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 2999 }
wolfSSL 16:8e0d178b1d1e 3000
wolfSSL 16:8e0d178b1d1e 3001 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 3002 *
wolfSSL 16:8e0d178b1d1e 3003 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 3004 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 3005 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 3006 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 3007 */
wolfSSL 16:8e0d178b1d1e 3008 static WC_INLINE int sp_2048_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 3009 {
wolfSSL 16:8e0d178b1d1e 3010 return sp_2048_div_32(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 3011 }
wolfSSL 16:8e0d178b1d1e 3012
wolfSSL 16:8e0d178b1d1e 3013 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 3014 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 3015 *
wolfSSL 16:8e0d178b1d1e 3016 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 3017 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 3018 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 3019 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 3020 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 3021 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 3022 */
wolfSSL 16:8e0d178b1d1e 3023 static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 3024 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 3025 {
wolfSSL 16:8e0d178b1d1e 3026 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3027 sp_digit t[16][64];
wolfSSL 16:8e0d178b1d1e 3028 #else
wolfSSL 16:8e0d178b1d1e 3029 sp_digit* t[16];
wolfSSL 16:8e0d178b1d1e 3030 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 3031 #endif
wolfSSL 16:8e0d178b1d1e 3032 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 3033 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 3034 sp_digit n;
wolfSSL 16:8e0d178b1d1e 3035 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 3036 int i;
wolfSSL 16:8e0d178b1d1e 3037 int c, y;
wolfSSL 16:8e0d178b1d1e 3038 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 3039
wolfSSL 16:8e0d178b1d1e 3040 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3041 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 64, NULL,
wolfSSL 16:8e0d178b1d1e 3042 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3043 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 3044 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3045 }
wolfSSL 16:8e0d178b1d1e 3046 #endif
wolfSSL 16:8e0d178b1d1e 3047
wolfSSL 16:8e0d178b1d1e 3048 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3049 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3050 for (i=0; i<16; i++) {
wolfSSL 16:8e0d178b1d1e 3051 t[i] = td + i * 64;
wolfSSL 16:8e0d178b1d1e 3052 }
wolfSSL 16:8e0d178b1d1e 3053 #endif
wolfSSL 16:8e0d178b1d1e 3054 norm = t[0];
wolfSSL 16:8e0d178b1d1e 3055
wolfSSL 16:8e0d178b1d1e 3056 sp_2048_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 3057 sp_2048_mont_norm_32(norm, m);
wolfSSL 16:8e0d178b1d1e 3058
wolfSSL 16:8e0d178b1d1e 3059 XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);
wolfSSL 16:8e0d178b1d1e 3060 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 3061 err = sp_2048_mod_32(t[1] + 32, a, m);
wolfSSL 16:8e0d178b1d1e 3062 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3063 err = sp_2048_mod_32(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 3064 }
wolfSSL 16:8e0d178b1d1e 3065 }
wolfSSL 16:8e0d178b1d1e 3066 else {
wolfSSL 16:8e0d178b1d1e 3067 XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);
wolfSSL 16:8e0d178b1d1e 3068 err = sp_2048_mod_32(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 3069 }
wolfSSL 16:8e0d178b1d1e 3070 }
wolfSSL 16:8e0d178b1d1e 3071
wolfSSL 16:8e0d178b1d1e 3072 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3073 sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 3074 sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 3075 sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 3076 sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 3077 sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 3078 sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 3079 sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 3080 sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 3081 sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 3082 sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 3083 sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 3084 sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 3085 sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 3086 sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 3087
wolfSSL 16:8e0d178b1d1e 3088 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 3089 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3090 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 3091 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 3092 c = 32;
wolfSSL 16:8e0d178b1d1e 3093 }
wolfSSL 16:8e0d178b1d1e 3094 c -= bits % 4;
wolfSSL 16:8e0d178b1d1e 3095 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 3096 c = 28;
wolfSSL 16:8e0d178b1d1e 3097 }
wolfSSL 16:8e0d178b1d1e 3098 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 3099 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 3100 XMEMCPY(r, t[y], sizeof(sp_digit) * 32);
wolfSSL 16:8e0d178b1d1e 3101 for (; i>=0 || c>=4; ) {
wolfSSL 16:8e0d178b1d1e 3102 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 3103 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3104 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 3105 n <<= 4;
wolfSSL 16:8e0d178b1d1e 3106 c = 28;
wolfSSL 16:8e0d178b1d1e 3107 }
wolfSSL 16:8e0d178b1d1e 3108 else if (c < 4) {
wolfSSL 16:8e0d178b1d1e 3109 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 3110 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3111 c = 4 - c;
wolfSSL 16:8e0d178b1d1e 3112 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 3113 n <<= c;
wolfSSL 16:8e0d178b1d1e 3114 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 3115 }
wolfSSL 16:8e0d178b1d1e 3116 else {
wolfSSL 16:8e0d178b1d1e 3117 y = (n >> 28) & 0xf;
wolfSSL 16:8e0d178b1d1e 3118 n <<= 4;
wolfSSL 16:8e0d178b1d1e 3119 c -= 4;
wolfSSL 16:8e0d178b1d1e 3120 }
wolfSSL 16:8e0d178b1d1e 3121
wolfSSL 16:8e0d178b1d1e 3122 sp_2048_mont_sqr_32(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3123 sp_2048_mont_sqr_32(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3124 sp_2048_mont_sqr_32(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3125 sp_2048_mont_sqr_32(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3126
wolfSSL 16:8e0d178b1d1e 3127 sp_2048_mont_mul_32(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 3128 }
wolfSSL 16:8e0d178b1d1e 3129
wolfSSL 16:8e0d178b1d1e 3130 XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);
wolfSSL 16:8e0d178b1d1e 3131 sp_2048_mont_reduce_32(r, m, mp);
wolfSSL 16:8e0d178b1d1e 3132
wolfSSL 16:8e0d178b1d1e 3133 mask = 0 - (sp_2048_cmp_32(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 3134 sp_2048_cond_sub_32(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 3135 }
wolfSSL 16:8e0d178b1d1e 3136
wolfSSL 16:8e0d178b1d1e 3137 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3138 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 3139 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3140 }
wolfSSL 16:8e0d178b1d1e 3141 #endif
wolfSSL 16:8e0d178b1d1e 3142
wolfSSL 16:8e0d178b1d1e 3143 return err;
wolfSSL 16:8e0d178b1d1e 3144 }
wolfSSL 16:8e0d178b1d1e 3145 #else
wolfSSL 16:8e0d178b1d1e 3146 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 3147 *
wolfSSL 16:8e0d178b1d1e 3148 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 3149 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 3150 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 3151 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 3152 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 3153 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 3154 */
wolfSSL 16:8e0d178b1d1e 3155 static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 3156 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 3157 {
wolfSSL 16:8e0d178b1d1e 3158 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3159 sp_digit t[32][64];
wolfSSL 16:8e0d178b1d1e 3160 #else
wolfSSL 16:8e0d178b1d1e 3161 sp_digit* t[32];
wolfSSL 16:8e0d178b1d1e 3162 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 3163 #endif
wolfSSL 16:8e0d178b1d1e 3164 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 3165 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 3166 sp_digit n;
wolfSSL 16:8e0d178b1d1e 3167 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 3168 int i;
wolfSSL 16:8e0d178b1d1e 3169 int c, y;
wolfSSL 16:8e0d178b1d1e 3170 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 3171
wolfSSL 16:8e0d178b1d1e 3172 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3173 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 64, NULL,
wolfSSL 16:8e0d178b1d1e 3174 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3175 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 3176 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3177 }
wolfSSL 16:8e0d178b1d1e 3178 #endif
wolfSSL 16:8e0d178b1d1e 3179
wolfSSL 16:8e0d178b1d1e 3180 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3181 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3182 for (i=0; i<32; i++) {
wolfSSL 16:8e0d178b1d1e 3183 t[i] = td + i * 64;
wolfSSL 16:8e0d178b1d1e 3184 }
wolfSSL 16:8e0d178b1d1e 3185 #endif
wolfSSL 16:8e0d178b1d1e 3186 norm = t[0];
wolfSSL 16:8e0d178b1d1e 3187
wolfSSL 16:8e0d178b1d1e 3188 sp_2048_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 3189 sp_2048_mont_norm_32(norm, m);
wolfSSL 16:8e0d178b1d1e 3190
wolfSSL 16:8e0d178b1d1e 3191 XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);
wolfSSL 16:8e0d178b1d1e 3192 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 3193 err = sp_2048_mod_32(t[1] + 32, a, m);
wolfSSL 16:8e0d178b1d1e 3194 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3195 err = sp_2048_mod_32(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 3196 }
wolfSSL 16:8e0d178b1d1e 3197 }
wolfSSL 16:8e0d178b1d1e 3198 else {
wolfSSL 16:8e0d178b1d1e 3199 XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);
wolfSSL 16:8e0d178b1d1e 3200 err = sp_2048_mod_32(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 3201 }
wolfSSL 16:8e0d178b1d1e 3202 }
wolfSSL 16:8e0d178b1d1e 3203
wolfSSL 16:8e0d178b1d1e 3204 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3205 sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 3206 sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 3207 sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 3208 sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 3209 sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 3210 sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 3211 sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 3212 sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 3213 sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 3214 sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 3215 sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 3216 sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 3217 sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 3218 sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 3219 sp_2048_mont_sqr_32(t[16], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 3220 sp_2048_mont_mul_32(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 3221 sp_2048_mont_sqr_32(t[18], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 3222 sp_2048_mont_mul_32(t[19], t[10], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 3223 sp_2048_mont_sqr_32(t[20], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 3224 sp_2048_mont_mul_32(t[21], t[11], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 3225 sp_2048_mont_sqr_32(t[22], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 3226 sp_2048_mont_mul_32(t[23], t[12], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 3227 sp_2048_mont_sqr_32(t[24], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 3228 sp_2048_mont_mul_32(t[25], t[13], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 3229 sp_2048_mont_sqr_32(t[26], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 3230 sp_2048_mont_mul_32(t[27], t[14], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 3231 sp_2048_mont_sqr_32(t[28], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 3232 sp_2048_mont_mul_32(t[29], t[15], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 3233 sp_2048_mont_sqr_32(t[30], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 3234 sp_2048_mont_mul_32(t[31], t[16], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 3235
wolfSSL 16:8e0d178b1d1e 3236 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 3237 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3238 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 3239 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 3240 c = 32;
wolfSSL 16:8e0d178b1d1e 3241 }
wolfSSL 16:8e0d178b1d1e 3242 c -= bits % 5;
wolfSSL 16:8e0d178b1d1e 3243 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 3244 c = 27;
wolfSSL 16:8e0d178b1d1e 3245 }
wolfSSL 16:8e0d178b1d1e 3246 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 3247 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 3248 XMEMCPY(r, t[y], sizeof(sp_digit) * 32);
wolfSSL 16:8e0d178b1d1e 3249 for (; i>=0 || c>=5; ) {
wolfSSL 16:8e0d178b1d1e 3250 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 3251 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3252 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 3253 n <<= 5;
wolfSSL 16:8e0d178b1d1e 3254 c = 27;
wolfSSL 16:8e0d178b1d1e 3255 }
wolfSSL 16:8e0d178b1d1e 3256 else if (c < 5) {
wolfSSL 16:8e0d178b1d1e 3257 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 3258 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3259 c = 5 - c;
wolfSSL 16:8e0d178b1d1e 3260 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 3261 n <<= c;
wolfSSL 16:8e0d178b1d1e 3262 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 3263 }
wolfSSL 16:8e0d178b1d1e 3264 else {
wolfSSL 16:8e0d178b1d1e 3265 y = (n >> 27) & 0x1f;
wolfSSL 16:8e0d178b1d1e 3266 n <<= 5;
wolfSSL 16:8e0d178b1d1e 3267 c -= 5;
wolfSSL 16:8e0d178b1d1e 3268 }
wolfSSL 16:8e0d178b1d1e 3269
wolfSSL 16:8e0d178b1d1e 3270 sp_2048_mont_sqr_32(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3271 sp_2048_mont_sqr_32(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3272 sp_2048_mont_sqr_32(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3273 sp_2048_mont_sqr_32(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3274 sp_2048_mont_sqr_32(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3275
wolfSSL 16:8e0d178b1d1e 3276 sp_2048_mont_mul_32(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 3277 }
wolfSSL 16:8e0d178b1d1e 3278
wolfSSL 16:8e0d178b1d1e 3279 XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);
wolfSSL 16:8e0d178b1d1e 3280 sp_2048_mont_reduce_32(r, m, mp);
wolfSSL 16:8e0d178b1d1e 3281
wolfSSL 16:8e0d178b1d1e 3282 mask = 0 - (sp_2048_cmp_32(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 3283 sp_2048_cond_sub_32(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 3284 }
wolfSSL 16:8e0d178b1d1e 3285
wolfSSL 16:8e0d178b1d1e 3286 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3287 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 3288 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3289 }
wolfSSL 16:8e0d178b1d1e 3290 #endif
wolfSSL 16:8e0d178b1d1e 3291
wolfSSL 16:8e0d178b1d1e 3292 return err;
wolfSSL 16:8e0d178b1d1e 3293 }
wolfSSL 16:8e0d178b1d1e 3294 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 3295
wolfSSL 16:8e0d178b1d1e 3296 #endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */
wolfSSL 16:8e0d178b1d1e 3297
wolfSSL 16:8e0d178b1d1e 3298 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 16:8e0d178b1d1e 3299 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 16:8e0d178b1d1e 3300 * Given m must be 2048 bits, just need to subtract.
wolfSSL 16:8e0d178b1d1e 3301 *
wolfSSL 16:8e0d178b1d1e 3302 * r A single precision number.
wolfSSL 16:8e0d178b1d1e 3303 * m A single precision number.
wolfSSL 16:8e0d178b1d1e 3304 */
wolfSSL 16:8e0d178b1d1e 3305 static void sp_2048_mont_norm_64(sp_digit* r, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 3306 {
wolfSSL 16:8e0d178b1d1e 3307 XMEMSET(r, 0, sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 3308
wolfSSL 16:8e0d178b1d1e 3309 /* r = 2^n mod m */
wolfSSL 16:8e0d178b1d1e 3310 sp_2048_sub_in_place_64(r, m);
wolfSSL 16:8e0d178b1d1e 3311 }
wolfSSL 16:8e0d178b1d1e 3312
wolfSSL 16:8e0d178b1d1e 3313 #endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 3314 /* Conditionally subtract b from a using the mask m.
wolfSSL 16:8e0d178b1d1e 3315 * m is -1 to subtract and 0 when not copying.
wolfSSL 16:8e0d178b1d1e 3316 *
wolfSSL 16:8e0d178b1d1e 3317 * r A single precision number representing condition subtract result.
wolfSSL 16:8e0d178b1d1e 3318 * a A single precision number to subtract from.
wolfSSL 16:8e0d178b1d1e 3319 * b A single precision number to subtract.
wolfSSL 16:8e0d178b1d1e 3320 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 3321 */
wolfSSL 16:8e0d178b1d1e 3322 SP_NOINLINE static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 3323 const sp_digit* b, sp_digit m)
wolfSSL 16:8e0d178b1d1e 3324 {
wolfSSL 16:8e0d178b1d1e 3325 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 3326
wolfSSL 16:8e0d178b1d1e 3327 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 3328 "mov r5, #1\n\t"
wolfSSL 16:8e0d178b1d1e 3329 "lsl r5, r5, #8\n\t"
wolfSSL 16:8e0d178b1d1e 3330 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 3331 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3332 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 3333 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 3334 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 3335 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3336 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 3337 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 3338 "sbcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 3339 "sbcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 3340 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 3341 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 3342 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 3343 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 3344 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 3345 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 3346 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 3347 );
wolfSSL 16:8e0d178b1d1e 3348
wolfSSL 16:8e0d178b1d1e 3349 return c;
wolfSSL 16:8e0d178b1d1e 3350 }
wolfSSL 16:8e0d178b1d1e 3351
wolfSSL 16:8e0d178b1d1e 3352 /* Reduce the number back to 2048 bits using Montgomery reduction.
wolfSSL 16:8e0d178b1d1e 3353 *
wolfSSL 16:8e0d178b1d1e 3354 * a A single precision number to reduce in place.
wolfSSL 16:8e0d178b1d1e 3355 * m The single precision number representing the modulus.
wolfSSL 16:8e0d178b1d1e 3356 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 16:8e0d178b1d1e 3357 */
wolfSSL 16:8e0d178b1d1e 3358 SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 3359 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 3360 {
wolfSSL 16:8e0d178b1d1e 3361 sp_digit ca = 0;
wolfSSL 16:8e0d178b1d1e 3362
wolfSSL 16:8e0d178b1d1e 3363 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 3364 "mov r9, %[mp]\n\t"
wolfSSL 16:8e0d178b1d1e 3365 "mov r12, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 3366 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 3367 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3368 "add r11, r10, #256\n\t"
wolfSSL 16:8e0d178b1d1e 3369 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 3370 /* mu = a[i] * mp */
wolfSSL 16:8e0d178b1d1e 3371 "mov %[mp], r9\n\t"
wolfSSL 16:8e0d178b1d1e 3372 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 3373 "mul %[mp], %[mp], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 3374 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 3375 "add r14, r10, #248\n\t"
wolfSSL 16:8e0d178b1d1e 3376 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 3377 /* a[i+j] += m[j] * mu */
wolfSSL 16:8e0d178b1d1e 3378 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 3379 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3380 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 3381 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 3382 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 3383 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 3384 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3385 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 3386 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 3387 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3388 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 3389 /* a[i+j+1] += m[j+1] * mu */
wolfSSL 16:8e0d178b1d1e 3390 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 3391 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3392 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 3393 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 3394 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 3395 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 3396 "adc r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3397 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 3398 "adds r5, r5, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 3399 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3400 "str r5, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 3401 "cmp r10, r14\n\t"
wolfSSL 16:8e0d178b1d1e 3402 "blt 2b\n\t"
wolfSSL 16:8e0d178b1d1e 3403 /* a[i+62] += m[62] * mu */
wolfSSL 16:8e0d178b1d1e 3404 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 3405 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3406 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 3407 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 3408 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 3409 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 3410 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3411 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 3412 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 3413 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3414 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 3415 /* a[i+63] += m[63] * mu */
wolfSSL 16:8e0d178b1d1e 3416 "mov r4, %[ca]\n\t"
wolfSSL 16:8e0d178b1d1e 3417 "mov %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 3418 /* Multiply m[63] and mu - Start */
wolfSSL 16:8e0d178b1d1e 3419 "ldr r8, [%[m]]\n\t"
wolfSSL 16:8e0d178b1d1e 3420 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 3421 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 3422 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3423 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 3424 /* Multiply m[63] and mu - Done */
wolfSSL 16:8e0d178b1d1e 3425 "ldr r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 3426 "ldr r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 3427 "adds r6, r6, r5\n\t"
wolfSSL 16:8e0d178b1d1e 3428 "adcs r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 3429 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 3430 "str r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 3431 "str r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 3432 /* Next word in a */
wolfSSL 16:8e0d178b1d1e 3433 "sub r10, r10, #248\n\t"
wolfSSL 16:8e0d178b1d1e 3434 "cmp r10, r11\n\t"
wolfSSL 16:8e0d178b1d1e 3435 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 3436 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 3437 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 3438 : [ca] "+r" (ca), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 3439 : [m] "r" (m), [mp] "r" (mp)
wolfSSL 16:8e0d178b1d1e 3440 : "memory", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 3441 );
wolfSSL 16:8e0d178b1d1e 3442
wolfSSL 16:8e0d178b1d1e 3443 sp_2048_cond_sub_64(a - 64, a, m, (sp_digit)0 - ca);
wolfSSL 16:8e0d178b1d1e 3444 }
wolfSSL 16:8e0d178b1d1e 3445
wolfSSL 16:8e0d178b1d1e 3446 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 16:8e0d178b1d1e 3447 * (r = a * b mod m)
wolfSSL 16:8e0d178b1d1e 3448 *
wolfSSL 16:8e0d178b1d1e 3449 * r Result of multiplication.
wolfSSL 16:8e0d178b1d1e 3450 * a First number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 3451 * b Second number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 3452 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 3453 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 3454 */
wolfSSL 16:8e0d178b1d1e 3455 static void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 3456 const sp_digit* m, sp_digit mp)
wolfSSL 16:8e0d178b1d1e 3457 {
wolfSSL 16:8e0d178b1d1e 3458 sp_2048_mul_64(r, a, b);
wolfSSL 16:8e0d178b1d1e 3459 sp_2048_mont_reduce_64(r, m, mp);
wolfSSL 16:8e0d178b1d1e 3460 }
wolfSSL 16:8e0d178b1d1e 3461
wolfSSL 16:8e0d178b1d1e 3462 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 16:8e0d178b1d1e 3463 *
wolfSSL 16:8e0d178b1d1e 3464 * r Result of squaring.
wolfSSL 16:8e0d178b1d1e 3465 * a Number to square in Montogmery form.
wolfSSL 16:8e0d178b1d1e 3466 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 3467 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 3468 */
wolfSSL 16:8e0d178b1d1e 3469 static void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 3470 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 3471 {
wolfSSL 16:8e0d178b1d1e 3472 sp_2048_sqr_64(r, a);
wolfSSL 16:8e0d178b1d1e 3473 sp_2048_mont_reduce_64(r, m, mp);
wolfSSL 16:8e0d178b1d1e 3474 }
wolfSSL 16:8e0d178b1d1e 3475
wolfSSL 16:8e0d178b1d1e 3476 /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)
wolfSSL 16:8e0d178b1d1e 3477 *
wolfSSL 16:8e0d178b1d1e 3478 * d1 The high order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 3479 * d0 The low order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 3480 * div The dividend.
wolfSSL 16:8e0d178b1d1e 3481 * returns the result of the division.
wolfSSL 16:8e0d178b1d1e 3482 *
wolfSSL 16:8e0d178b1d1e 3483 * Note that this is an approximate div. It may give an answer 1 larger.
wolfSSL 16:8e0d178b1d1e 3484 */
wolfSSL 16:8e0d178b1d1e 3485 SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0,
wolfSSL 16:8e0d178b1d1e 3486 sp_digit div)
wolfSSL 16:8e0d178b1d1e 3487 {
wolfSSL 16:8e0d178b1d1e 3488 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 3489
wolfSSL 16:8e0d178b1d1e 3490 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 3491 "lsr r6, %[div], #16\n\t"
wolfSSL 16:8e0d178b1d1e 3492 "add r6, r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 3493 "udiv r4, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 3494 "lsl r8, r4, #16\n\t"
wolfSSL 16:8e0d178b1d1e 3495 "umull r4, r5, %[div], r8\n\t"
wolfSSL 16:8e0d178b1d1e 3496 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 3497 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 3498 "udiv r5, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 3499 "lsl r4, r5, #16\n\t"
wolfSSL 16:8e0d178b1d1e 3500 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 3501 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 3502 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 3503 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 3504 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 3505 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 3506 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 3507 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 3508 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 3509 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 3510 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 3511 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 3512 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 3513 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 3514 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 3515 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 3516 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 3517 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 3518 "udiv r4, %[d0], %[div]\n\t"
wolfSSL 16:8e0d178b1d1e 3519 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 3520 "mov %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 3521 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 3522 : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div)
wolfSSL 16:8e0d178b1d1e 3523 : "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 3524 );
wolfSSL 16:8e0d178b1d1e 3525 return r;
wolfSSL 16:8e0d178b1d1e 3526 }
wolfSSL 16:8e0d178b1d1e 3527
wolfSSL 16:8e0d178b1d1e 3528 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 3529 *
wolfSSL 16:8e0d178b1d1e 3530 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 3531 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 3532 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 3533 */
wolfSSL 16:8e0d178b1d1e 3534 static void sp_2048_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 3535 {
wolfSSL 16:8e0d178b1d1e 3536 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 3537 int i;
wolfSSL 16:8e0d178b1d1e 3538
wolfSSL 16:8e0d178b1d1e 3539 for (i=0; i<64; i++) {
wolfSSL 16:8e0d178b1d1e 3540 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 3541 }
wolfSSL 16:8e0d178b1d1e 3542 #else
wolfSSL 16:8e0d178b1d1e 3543 int i;
wolfSSL 16:8e0d178b1d1e 3544
wolfSSL 16:8e0d178b1d1e 3545 for (i = 0; i < 64; i += 8) {
wolfSSL 16:8e0d178b1d1e 3546 r[i+0] = a[i+0] & m;
wolfSSL 16:8e0d178b1d1e 3547 r[i+1] = a[i+1] & m;
wolfSSL 16:8e0d178b1d1e 3548 r[i+2] = a[i+2] & m;
wolfSSL 16:8e0d178b1d1e 3549 r[i+3] = a[i+3] & m;
wolfSSL 16:8e0d178b1d1e 3550 r[i+4] = a[i+4] & m;
wolfSSL 16:8e0d178b1d1e 3551 r[i+5] = a[i+5] & m;
wolfSSL 16:8e0d178b1d1e 3552 r[i+6] = a[i+6] & m;
wolfSSL 16:8e0d178b1d1e 3553 r[i+7] = a[i+7] & m;
wolfSSL 16:8e0d178b1d1e 3554 }
wolfSSL 16:8e0d178b1d1e 3555 #endif
wolfSSL 16:8e0d178b1d1e 3556 }
wolfSSL 16:8e0d178b1d1e 3557
wolfSSL 16:8e0d178b1d1e 3558 /* Compare a with b in constant time.
wolfSSL 16:8e0d178b1d1e 3559 *
wolfSSL 16:8e0d178b1d1e 3560 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 3561 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 3562 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 16:8e0d178b1d1e 3563 * respectively.
wolfSSL 16:8e0d178b1d1e 3564 */
wolfSSL 16:8e0d178b1d1e 3565 SP_NOINLINE static int32_t sp_2048_cmp_64(const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 3566 {
wolfSSL 16:8e0d178b1d1e 3567 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 3568
wolfSSL 16:8e0d178b1d1e 3569
wolfSSL 16:8e0d178b1d1e 3570 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 3571 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3572 "mvn r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 3573 "mov r6, #252\n\t"
wolfSSL 16:8e0d178b1d1e 3574 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 3575 "ldr r8, [%[a], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 3576 "ldr r5, [%[b], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 3577 "and r8, r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 3578 "and r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 3579 "mov r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3580 "subs r8, r8, r5\n\t"
wolfSSL 16:8e0d178b1d1e 3581 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3582 "add %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 3583 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3584 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3585 "subs r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 3586 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3587 "sub %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 3588 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3589 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 3590 "sub r6, r6, #4\n\t"
wolfSSL 16:8e0d178b1d1e 3591 "cmp r6, #0\n\t"
wolfSSL 16:8e0d178b1d1e 3592 "bge 1b\n\t"
wolfSSL 16:8e0d178b1d1e 3593 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 3594 : [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 3595 : "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 3596 );
wolfSSL 16:8e0d178b1d1e 3597
wolfSSL 16:8e0d178b1d1e 3598 return r;
wolfSSL 16:8e0d178b1d1e 3599 }
wolfSSL 16:8e0d178b1d1e 3600
wolfSSL 16:8e0d178b1d1e 3601 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 3602 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 3603 *
wolfSSL 16:8e0d178b1d1e 3604 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 3605 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 3606 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 3607 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 3608 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 3609 */
wolfSSL 16:8e0d178b1d1e 3610 static WC_INLINE int sp_2048_div_64(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 3611 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 3612 {
wolfSSL 16:8e0d178b1d1e 3613 sp_digit t1[128], t2[65];
wolfSSL 16:8e0d178b1d1e 3614 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 3615 int i;
wolfSSL 16:8e0d178b1d1e 3616
wolfSSL 16:8e0d178b1d1e 3617 (void)m;
wolfSSL 16:8e0d178b1d1e 3618
wolfSSL 16:8e0d178b1d1e 3619 div = d[63];
wolfSSL 16:8e0d178b1d1e 3620 XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);
wolfSSL 16:8e0d178b1d1e 3621 for (i=63; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 3622 r1 = div_2048_word_64(t1[64 + i], t1[64 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 3623
wolfSSL 16:8e0d178b1d1e 3624 sp_2048_mul_d_64(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 3625 t1[64 + i] += sp_2048_sub_in_place_64(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 3626 t1[64 + i] -= t2[64];
wolfSSL 16:8e0d178b1d1e 3627 sp_2048_mask_64(t2, d, t1[64 + i]);
wolfSSL 16:8e0d178b1d1e 3628 t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 3629 sp_2048_mask_64(t2, d, t1[64 + i]);
wolfSSL 16:8e0d178b1d1e 3630 t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 3631 }
wolfSSL 16:8e0d178b1d1e 3632
wolfSSL 16:8e0d178b1d1e 3633 r1 = sp_2048_cmp_64(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 3634 sp_2048_cond_sub_64(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 3635
wolfSSL 16:8e0d178b1d1e 3636 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 3637 }
wolfSSL 16:8e0d178b1d1e 3638
wolfSSL 16:8e0d178b1d1e 3639 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 3640 *
wolfSSL 16:8e0d178b1d1e 3641 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 3642 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 3643 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 3644 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 3645 */
wolfSSL 16:8e0d178b1d1e 3646 static WC_INLINE int sp_2048_mod_64(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 3647 {
wolfSSL 16:8e0d178b1d1e 3648 return sp_2048_div_64(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 3649 }
wolfSSL 16:8e0d178b1d1e 3650
wolfSSL 16:8e0d178b1d1e 3651 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 3652 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 3653 *
wolfSSL 16:8e0d178b1d1e 3654 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 3655 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 3656 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 3657 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 3658 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 3659 */
wolfSSL 16:8e0d178b1d1e 3660 static WC_INLINE int sp_2048_div_64_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 3661 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 3662 {
wolfSSL 16:8e0d178b1d1e 3663 sp_digit t1[128], t2[65];
wolfSSL 16:8e0d178b1d1e 3664 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 3665 int i;
wolfSSL 16:8e0d178b1d1e 3666
wolfSSL 16:8e0d178b1d1e 3667 (void)m;
wolfSSL 16:8e0d178b1d1e 3668
wolfSSL 16:8e0d178b1d1e 3669 div = d[63];
wolfSSL 16:8e0d178b1d1e 3670 XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);
wolfSSL 16:8e0d178b1d1e 3671 for (i=63; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 3672 r1 = div_2048_word_64(t1[64 + i], t1[64 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 3673
wolfSSL 16:8e0d178b1d1e 3674 sp_2048_mul_d_64(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 3675 t1[64 + i] += sp_2048_sub_in_place_64(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 3676 t1[64 + i] -= t2[64];
wolfSSL 16:8e0d178b1d1e 3677 if (t1[64 + i] != 0) {
wolfSSL 16:8e0d178b1d1e 3678 t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], d);
wolfSSL 16:8e0d178b1d1e 3679 if (t1[64 + i] != 0)
wolfSSL 16:8e0d178b1d1e 3680 t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], d);
wolfSSL 16:8e0d178b1d1e 3681 }
wolfSSL 16:8e0d178b1d1e 3682 }
wolfSSL 16:8e0d178b1d1e 3683
wolfSSL 16:8e0d178b1d1e 3684 r1 = sp_2048_cmp_64(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 3685 sp_2048_cond_sub_64(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 3686
wolfSSL 16:8e0d178b1d1e 3687 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 3688 }
wolfSSL 16:8e0d178b1d1e 3689
wolfSSL 16:8e0d178b1d1e 3690 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 3691 *
wolfSSL 16:8e0d178b1d1e 3692 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 3693 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 3694 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 3695 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 3696 */
wolfSSL 16:8e0d178b1d1e 3697 static WC_INLINE int sp_2048_mod_64_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 3698 {
wolfSSL 16:8e0d178b1d1e 3699 return sp_2048_div_64_cond(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 3700 }
wolfSSL 16:8e0d178b1d1e 3701
wolfSSL 16:8e0d178b1d1e 3702 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
wolfSSL 16:8e0d178b1d1e 3703 defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 16:8e0d178b1d1e 3704 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 3705 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 3706 *
wolfSSL 16:8e0d178b1d1e 3707 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 3708 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 3709 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 3710 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 3711 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 3712 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 3713 */
wolfSSL 16:8e0d178b1d1e 3714 static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 3715 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 3716 {
wolfSSL 16:8e0d178b1d1e 3717 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3718 sp_digit t[16][128];
wolfSSL 16:8e0d178b1d1e 3719 #else
wolfSSL 16:8e0d178b1d1e 3720 sp_digit* t[16];
wolfSSL 16:8e0d178b1d1e 3721 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 3722 #endif
wolfSSL 16:8e0d178b1d1e 3723 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 3724 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 3725 sp_digit n;
wolfSSL 16:8e0d178b1d1e 3726 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 3727 int i;
wolfSSL 16:8e0d178b1d1e 3728 int c, y;
wolfSSL 16:8e0d178b1d1e 3729 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 3730
wolfSSL 16:8e0d178b1d1e 3731 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3732 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 128, NULL,
wolfSSL 16:8e0d178b1d1e 3733 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3734 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 3735 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3736 }
wolfSSL 16:8e0d178b1d1e 3737 #endif
wolfSSL 16:8e0d178b1d1e 3738
wolfSSL 16:8e0d178b1d1e 3739 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3740 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3741 for (i=0; i<16; i++) {
wolfSSL 16:8e0d178b1d1e 3742 t[i] = td + i * 128;
wolfSSL 16:8e0d178b1d1e 3743 }
wolfSSL 16:8e0d178b1d1e 3744 #endif
wolfSSL 16:8e0d178b1d1e 3745 norm = t[0];
wolfSSL 16:8e0d178b1d1e 3746
wolfSSL 16:8e0d178b1d1e 3747 sp_2048_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 3748 sp_2048_mont_norm_64(norm, m);
wolfSSL 16:8e0d178b1d1e 3749
wolfSSL 16:8e0d178b1d1e 3750 XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);
wolfSSL 16:8e0d178b1d1e 3751 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 3752 err = sp_2048_mod_64(t[1] + 64, a, m);
wolfSSL 16:8e0d178b1d1e 3753 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3754 err = sp_2048_mod_64(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 3755 }
wolfSSL 16:8e0d178b1d1e 3756 }
wolfSSL 16:8e0d178b1d1e 3757 else {
wolfSSL 16:8e0d178b1d1e 3758 XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 3759 err = sp_2048_mod_64(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 3760 }
wolfSSL 16:8e0d178b1d1e 3761 }
wolfSSL 16:8e0d178b1d1e 3762
wolfSSL 16:8e0d178b1d1e 3763 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3764 sp_2048_mont_sqr_64(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 3765 sp_2048_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 3766 sp_2048_mont_sqr_64(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 3767 sp_2048_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 3768 sp_2048_mont_sqr_64(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 3769 sp_2048_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 3770 sp_2048_mont_sqr_64(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 3771 sp_2048_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 3772 sp_2048_mont_sqr_64(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 3773 sp_2048_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 3774 sp_2048_mont_sqr_64(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 3775 sp_2048_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 3776 sp_2048_mont_sqr_64(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 3777 sp_2048_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 3778
wolfSSL 16:8e0d178b1d1e 3779 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 3780 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3781 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 3782 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 3783 c = 32;
wolfSSL 16:8e0d178b1d1e 3784 }
wolfSSL 16:8e0d178b1d1e 3785 c -= bits % 4;
wolfSSL 16:8e0d178b1d1e 3786 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 3787 c = 28;
wolfSSL 16:8e0d178b1d1e 3788 }
wolfSSL 16:8e0d178b1d1e 3789 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 3790 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 3791 XMEMCPY(r, t[y], sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 3792 for (; i>=0 || c>=4; ) {
wolfSSL 16:8e0d178b1d1e 3793 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 3794 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3795 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 3796 n <<= 4;
wolfSSL 16:8e0d178b1d1e 3797 c = 28;
wolfSSL 16:8e0d178b1d1e 3798 }
wolfSSL 16:8e0d178b1d1e 3799 else if (c < 4) {
wolfSSL 16:8e0d178b1d1e 3800 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 3801 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3802 c = 4 - c;
wolfSSL 16:8e0d178b1d1e 3803 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 3804 n <<= c;
wolfSSL 16:8e0d178b1d1e 3805 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 3806 }
wolfSSL 16:8e0d178b1d1e 3807 else {
wolfSSL 16:8e0d178b1d1e 3808 y = (n >> 28) & 0xf;
wolfSSL 16:8e0d178b1d1e 3809 n <<= 4;
wolfSSL 16:8e0d178b1d1e 3810 c -= 4;
wolfSSL 16:8e0d178b1d1e 3811 }
wolfSSL 16:8e0d178b1d1e 3812
wolfSSL 16:8e0d178b1d1e 3813 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3814 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3815 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3816 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3817
wolfSSL 16:8e0d178b1d1e 3818 sp_2048_mont_mul_64(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 3819 }
wolfSSL 16:8e0d178b1d1e 3820
wolfSSL 16:8e0d178b1d1e 3821 XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);
wolfSSL 16:8e0d178b1d1e 3822 sp_2048_mont_reduce_64(r, m, mp);
wolfSSL 16:8e0d178b1d1e 3823
wolfSSL 16:8e0d178b1d1e 3824 mask = 0 - (sp_2048_cmp_64(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 3825 sp_2048_cond_sub_64(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 3826 }
wolfSSL 16:8e0d178b1d1e 3827
wolfSSL 16:8e0d178b1d1e 3828 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3829 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 3830 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3831 }
wolfSSL 16:8e0d178b1d1e 3832 #endif
wolfSSL 16:8e0d178b1d1e 3833
wolfSSL 16:8e0d178b1d1e 3834 return err;
wolfSSL 16:8e0d178b1d1e 3835 }
wolfSSL 16:8e0d178b1d1e 3836 #else
wolfSSL 16:8e0d178b1d1e 3837 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 3838 *
wolfSSL 16:8e0d178b1d1e 3839 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 3840 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 3841 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 3842 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 3843 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 3844 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 3845 */
wolfSSL 16:8e0d178b1d1e 3846 static int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 3847 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 3848 {
wolfSSL 16:8e0d178b1d1e 3849 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3850 sp_digit t[32][128];
wolfSSL 16:8e0d178b1d1e 3851 #else
wolfSSL 16:8e0d178b1d1e 3852 sp_digit* t[32];
wolfSSL 16:8e0d178b1d1e 3853 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 3854 #endif
wolfSSL 16:8e0d178b1d1e 3855 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 3856 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 3857 sp_digit n;
wolfSSL 16:8e0d178b1d1e 3858 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 3859 int i;
wolfSSL 16:8e0d178b1d1e 3860 int c, y;
wolfSSL 16:8e0d178b1d1e 3861 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 3862
wolfSSL 16:8e0d178b1d1e 3863 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3864 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 128, NULL,
wolfSSL 16:8e0d178b1d1e 3865 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3866 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 3867 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3868 }
wolfSSL 16:8e0d178b1d1e 3869 #endif
wolfSSL 16:8e0d178b1d1e 3870
wolfSSL 16:8e0d178b1d1e 3871 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3872 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3873 for (i=0; i<32; i++) {
wolfSSL 16:8e0d178b1d1e 3874 t[i] = td + i * 128;
wolfSSL 16:8e0d178b1d1e 3875 }
wolfSSL 16:8e0d178b1d1e 3876 #endif
wolfSSL 16:8e0d178b1d1e 3877 norm = t[0];
wolfSSL 16:8e0d178b1d1e 3878
wolfSSL 16:8e0d178b1d1e 3879 sp_2048_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 3880 sp_2048_mont_norm_64(norm, m);
wolfSSL 16:8e0d178b1d1e 3881
wolfSSL 16:8e0d178b1d1e 3882 XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);
wolfSSL 16:8e0d178b1d1e 3883 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 3884 err = sp_2048_mod_64(t[1] + 64, a, m);
wolfSSL 16:8e0d178b1d1e 3885 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3886 err = sp_2048_mod_64(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 3887 }
wolfSSL 16:8e0d178b1d1e 3888 }
wolfSSL 16:8e0d178b1d1e 3889 else {
wolfSSL 16:8e0d178b1d1e 3890 XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 3891 err = sp_2048_mod_64(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 3892 }
wolfSSL 16:8e0d178b1d1e 3893 }
wolfSSL 16:8e0d178b1d1e 3894
wolfSSL 16:8e0d178b1d1e 3895 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 3896 sp_2048_mont_sqr_64(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 3897 sp_2048_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 3898 sp_2048_mont_sqr_64(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 3899 sp_2048_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 3900 sp_2048_mont_sqr_64(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 3901 sp_2048_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 3902 sp_2048_mont_sqr_64(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 3903 sp_2048_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 3904 sp_2048_mont_sqr_64(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 3905 sp_2048_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 3906 sp_2048_mont_sqr_64(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 3907 sp_2048_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 3908 sp_2048_mont_sqr_64(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 3909 sp_2048_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 3910 sp_2048_mont_sqr_64(t[16], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 3911 sp_2048_mont_mul_64(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 3912 sp_2048_mont_sqr_64(t[18], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 3913 sp_2048_mont_mul_64(t[19], t[10], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 3914 sp_2048_mont_sqr_64(t[20], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 3915 sp_2048_mont_mul_64(t[21], t[11], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 3916 sp_2048_mont_sqr_64(t[22], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 3917 sp_2048_mont_mul_64(t[23], t[12], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 3918 sp_2048_mont_sqr_64(t[24], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 3919 sp_2048_mont_mul_64(t[25], t[13], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 3920 sp_2048_mont_sqr_64(t[26], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 3921 sp_2048_mont_mul_64(t[27], t[14], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 3922 sp_2048_mont_sqr_64(t[28], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 3923 sp_2048_mont_mul_64(t[29], t[15], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 3924 sp_2048_mont_sqr_64(t[30], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 3925 sp_2048_mont_mul_64(t[31], t[16], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 3926
wolfSSL 16:8e0d178b1d1e 3927 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 3928 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3929 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 3930 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 3931 c = 32;
wolfSSL 16:8e0d178b1d1e 3932 }
wolfSSL 16:8e0d178b1d1e 3933 c -= bits % 5;
wolfSSL 16:8e0d178b1d1e 3934 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 3935 c = 27;
wolfSSL 16:8e0d178b1d1e 3936 }
wolfSSL 16:8e0d178b1d1e 3937 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 3938 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 3939 XMEMCPY(r, t[y], sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 3940 for (; i>=0 || c>=5; ) {
wolfSSL 16:8e0d178b1d1e 3941 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 3942 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3943 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 3944 n <<= 5;
wolfSSL 16:8e0d178b1d1e 3945 c = 27;
wolfSSL 16:8e0d178b1d1e 3946 }
wolfSSL 16:8e0d178b1d1e 3947 else if (c < 5) {
wolfSSL 16:8e0d178b1d1e 3948 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 3949 n = e[i--];
wolfSSL 16:8e0d178b1d1e 3950 c = 5 - c;
wolfSSL 16:8e0d178b1d1e 3951 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 3952 n <<= c;
wolfSSL 16:8e0d178b1d1e 3953 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 3954 }
wolfSSL 16:8e0d178b1d1e 3955 else {
wolfSSL 16:8e0d178b1d1e 3956 y = (n >> 27) & 0x1f;
wolfSSL 16:8e0d178b1d1e 3957 n <<= 5;
wolfSSL 16:8e0d178b1d1e 3958 c -= 5;
wolfSSL 16:8e0d178b1d1e 3959 }
wolfSSL 16:8e0d178b1d1e 3960
wolfSSL 16:8e0d178b1d1e 3961 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3962 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3963 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3964 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3965 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 3966
wolfSSL 16:8e0d178b1d1e 3967 sp_2048_mont_mul_64(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 3968 }
wolfSSL 16:8e0d178b1d1e 3969
wolfSSL 16:8e0d178b1d1e 3970 XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);
wolfSSL 16:8e0d178b1d1e 3971 sp_2048_mont_reduce_64(r, m, mp);
wolfSSL 16:8e0d178b1d1e 3972
wolfSSL 16:8e0d178b1d1e 3973 mask = 0 - (sp_2048_cmp_64(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 3974 sp_2048_cond_sub_64(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 3975 }
wolfSSL 16:8e0d178b1d1e 3976
wolfSSL 16:8e0d178b1d1e 3977 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3978 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 3979 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3980 }
wolfSSL 16:8e0d178b1d1e 3981 #endif
wolfSSL 16:8e0d178b1d1e 3982
wolfSSL 16:8e0d178b1d1e 3983 return err;
wolfSSL 16:8e0d178b1d1e 3984 }
wolfSSL 16:8e0d178b1d1e 3985 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 3986 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 3987
wolfSSL 16:8e0d178b1d1e 3988 #ifdef WOLFSSL_HAVE_SP_RSA
wolfSSL 16:8e0d178b1d1e 3989 /* RSA public key operation.
wolfSSL 16:8e0d178b1d1e 3990 *
wolfSSL 16:8e0d178b1d1e 3991 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 16:8e0d178b1d1e 3992 * inLen Number of bytes in base.
wolfSSL 16:8e0d178b1d1e 3993 * em Public exponent.
wolfSSL 16:8e0d178b1d1e 3994 * mm Modulus.
wolfSSL 16:8e0d178b1d1e 3995 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 16:8e0d178b1d1e 3996 * Must be at least 256 bytes long.
wolfSSL 16:8e0d178b1d1e 3997 * outLen Number of bytes in result.
wolfSSL 16:8e0d178b1d1e 3998 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 16:8e0d178b1d1e 3999 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 16:8e0d178b1d1e 4000 */
wolfSSL 16:8e0d178b1d1e 4001 int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,
wolfSSL 16:8e0d178b1d1e 4002 byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 4003 {
wolfSSL 16:8e0d178b1d1e 4004 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 4005 sp_digit a[128], m[64], r[128];
wolfSSL 16:8e0d178b1d1e 4006 #else
wolfSSL 16:8e0d178b1d1e 4007 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 4008 sp_digit* a;
wolfSSL 16:8e0d178b1d1e 4009 sp_digit* m;
wolfSSL 16:8e0d178b1d1e 4010 sp_digit* r;
wolfSSL 16:8e0d178b1d1e 4011 #endif
wolfSSL 16:8e0d178b1d1e 4012 sp_digit *ah;
wolfSSL 16:8e0d178b1d1e 4013 sp_digit e[1];
wolfSSL 16:8e0d178b1d1e 4014 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 4015
wolfSSL 16:8e0d178b1d1e 4016 if (*outLen < 256)
wolfSSL 16:8e0d178b1d1e 4017 err = MP_TO_E;
wolfSSL 16:8e0d178b1d1e 4018 if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 256 ||
wolfSSL 16:8e0d178b1d1e 4019 mp_count_bits(mm) != 2048))
wolfSSL 16:8e0d178b1d1e 4020 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4021
wolfSSL 16:8e0d178b1d1e 4022 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 4023 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4024 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 5, NULL,
wolfSSL 16:8e0d178b1d1e 4025 DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 4026 if (d == NULL)
wolfSSL 16:8e0d178b1d1e 4027 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4028 }
wolfSSL 16:8e0d178b1d1e 4029
wolfSSL 16:8e0d178b1d1e 4030 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4031 a = d;
wolfSSL 16:8e0d178b1d1e 4032 r = a + 64 * 2;
wolfSSL 16:8e0d178b1d1e 4033 m = r + 64 * 2;
wolfSSL 16:8e0d178b1d1e 4034 }
wolfSSL 16:8e0d178b1d1e 4035 #endif
wolfSSL 16:8e0d178b1d1e 4036
wolfSSL 16:8e0d178b1d1e 4037 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4038 ah = a + 64;
wolfSSL 16:8e0d178b1d1e 4039
wolfSSL 16:8e0d178b1d1e 4040 sp_2048_from_bin(ah, 64, in, inLen);
wolfSSL 16:8e0d178b1d1e 4041 #if DIGIT_BIT >= 32
wolfSSL 16:8e0d178b1d1e 4042 e[0] = em->dp[0];
wolfSSL 16:8e0d178b1d1e 4043 #else
wolfSSL 16:8e0d178b1d1e 4044 e[0] = em->dp[0];
wolfSSL 16:8e0d178b1d1e 4045 if (em->used > 1) {
wolfSSL 16:8e0d178b1d1e 4046 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 4047 }
wolfSSL 16:8e0d178b1d1e 4048 #endif
wolfSSL 16:8e0d178b1d1e 4049 if (e[0] == 0) {
wolfSSL 16:8e0d178b1d1e 4050 err = MP_EXPTMOD_E;
wolfSSL 16:8e0d178b1d1e 4051 }
wolfSSL 16:8e0d178b1d1e 4052 }
wolfSSL 16:8e0d178b1d1e 4053 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4054 sp_2048_from_mp(m, 64, mm);
wolfSSL 16:8e0d178b1d1e 4055
wolfSSL 16:8e0d178b1d1e 4056 if (e[0] == 0x3) {
wolfSSL 16:8e0d178b1d1e 4057 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4058 sp_2048_sqr_64(r, ah);
wolfSSL 16:8e0d178b1d1e 4059 err = sp_2048_mod_64_cond(r, r, m);
wolfSSL 16:8e0d178b1d1e 4060 }
wolfSSL 16:8e0d178b1d1e 4061 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4062 sp_2048_mul_64(r, ah, r);
wolfSSL 16:8e0d178b1d1e 4063 err = sp_2048_mod_64_cond(r, r, m);
wolfSSL 16:8e0d178b1d1e 4064 }
wolfSSL 16:8e0d178b1d1e 4065 }
wolfSSL 16:8e0d178b1d1e 4066 else {
wolfSSL 16:8e0d178b1d1e 4067 int i;
wolfSSL 16:8e0d178b1d1e 4068 sp_digit mp;
wolfSSL 16:8e0d178b1d1e 4069
wolfSSL 16:8e0d178b1d1e 4070 sp_2048_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 4071
wolfSSL 16:8e0d178b1d1e 4072 /* Convert to Montgomery form. */
wolfSSL 16:8e0d178b1d1e 4073 XMEMSET(a, 0, sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 4074 err = sp_2048_mod_64_cond(a, a, m);
wolfSSL 16:8e0d178b1d1e 4075
wolfSSL 16:8e0d178b1d1e 4076 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4077 for (i = 31; i >= 0; i--) {
wolfSSL 16:8e0d178b1d1e 4078 if (e[0] >> i) {
wolfSSL 16:8e0d178b1d1e 4079 break;
wolfSSL 16:8e0d178b1d1e 4080 }
wolfSSL 16:8e0d178b1d1e 4081 }
wolfSSL 16:8e0d178b1d1e 4082
wolfSSL 16:8e0d178b1d1e 4083 XMEMCPY(r, a, sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 4084 for (i--; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 4085 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 4086 if (((e[0] >> i) & 1) == 1) {
wolfSSL 16:8e0d178b1d1e 4087 sp_2048_mont_mul_64(r, r, a, m, mp);
wolfSSL 16:8e0d178b1d1e 4088 }
wolfSSL 16:8e0d178b1d1e 4089 }
wolfSSL 16:8e0d178b1d1e 4090 XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 4091 sp_2048_mont_reduce_64(r, m, mp);
wolfSSL 16:8e0d178b1d1e 4092
wolfSSL 16:8e0d178b1d1e 4093 for (i = 63; i > 0; i--) {
wolfSSL 16:8e0d178b1d1e 4094 if (r[i] != m[i]) {
wolfSSL 16:8e0d178b1d1e 4095 break;
wolfSSL 16:8e0d178b1d1e 4096 }
wolfSSL 16:8e0d178b1d1e 4097 }
wolfSSL 16:8e0d178b1d1e 4098 if (r[i] >= m[i]) {
wolfSSL 16:8e0d178b1d1e 4099 sp_2048_sub_in_place_64(r, m);
wolfSSL 16:8e0d178b1d1e 4100 }
wolfSSL 16:8e0d178b1d1e 4101 }
wolfSSL 16:8e0d178b1d1e 4102 }
wolfSSL 16:8e0d178b1d1e 4103 }
wolfSSL 16:8e0d178b1d1e 4104
wolfSSL 16:8e0d178b1d1e 4105 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4106 sp_2048_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 4107 *outLen = 256;
wolfSSL 16:8e0d178b1d1e 4108 }
wolfSSL 16:8e0d178b1d1e 4109
wolfSSL 16:8e0d178b1d1e 4110 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 4111 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 4112 XFREE(d, NULL, DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 4113 }
wolfSSL 16:8e0d178b1d1e 4114 #endif
wolfSSL 16:8e0d178b1d1e 4115
wolfSSL 16:8e0d178b1d1e 4116 return err;
wolfSSL 16:8e0d178b1d1e 4117 }
wolfSSL 16:8e0d178b1d1e 4118
wolfSSL 16:8e0d178b1d1e 4119 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
wolfSSL 16:8e0d178b1d1e 4120 sp_digit* a;
wolfSSL 16:8e0d178b1d1e 4121 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 4122 sp_digit* m;
wolfSSL 16:8e0d178b1d1e 4123 sp_digit* r;
wolfSSL 16:8e0d178b1d1e 4124 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 4125
wolfSSL 16:8e0d178b1d1e 4126 (void)pm;
wolfSSL 16:8e0d178b1d1e 4127 (void)qm;
wolfSSL 16:8e0d178b1d1e 4128 (void)dpm;
wolfSSL 16:8e0d178b1d1e 4129 (void)dqm;
wolfSSL 16:8e0d178b1d1e 4130 (void)qim;
wolfSSL 16:8e0d178b1d1e 4131
wolfSSL 16:8e0d178b1d1e 4132 if (*outLen < 256U) {
wolfSSL 16:8e0d178b1d1e 4133 err = MP_TO_E;
wolfSSL 16:8e0d178b1d1e 4134 }
wolfSSL 16:8e0d178b1d1e 4135 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4136 if (mp_count_bits(dm) > 2048) {
wolfSSL 16:8e0d178b1d1e 4137 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4138 }
wolfSSL 16:8e0d178b1d1e 4139 if (inLen > 256) {
wolfSSL 16:8e0d178b1d1e 4140 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4141 }
wolfSSL 16:8e0d178b1d1e 4142 if (mp_count_bits(mm) != 2048) {
wolfSSL 16:8e0d178b1d1e 4143 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4144 }
wolfSSL 16:8e0d178b1d1e 4145 }
wolfSSL 16:8e0d178b1d1e 4146
wolfSSL 16:8e0d178b1d1e 4147 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4148 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 4, NULL,
wolfSSL 16:8e0d178b1d1e 4149 DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 4150 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 4151 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4152 }
wolfSSL 16:8e0d178b1d1e 4153 }
wolfSSL 16:8e0d178b1d1e 4154 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4155 a = d + 64;
wolfSSL 16:8e0d178b1d1e 4156 m = a + 128;
wolfSSL 16:8e0d178b1d1e 4157 r = a;
wolfSSL 16:8e0d178b1d1e 4158
wolfSSL 16:8e0d178b1d1e 4159 sp_2048_from_bin(a, 64, in, inLen);
wolfSSL 16:8e0d178b1d1e 4160 sp_2048_from_mp(d, 64, dm);
wolfSSL 16:8e0d178b1d1e 4161 sp_2048_from_mp(m, 64, mm);
wolfSSL 16:8e0d178b1d1e 4162 err = sp_2048_mod_exp_64(r, a, d, 2048, m, 0);
wolfSSL 16:8e0d178b1d1e 4163 }
wolfSSL 16:8e0d178b1d1e 4164 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4165 sp_2048_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 4166 *outLen = 256;
wolfSSL 16:8e0d178b1d1e 4167 }
wolfSSL 16:8e0d178b1d1e 4168
wolfSSL 16:8e0d178b1d1e 4169 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 4170 XMEMSET(d, 0, sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 4171 XFREE(d, NULL, DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 4172 }
wolfSSL 16:8e0d178b1d1e 4173
wolfSSL 16:8e0d178b1d1e 4174 return err;
wolfSSL 16:8e0d178b1d1e 4175 #else
wolfSSL 16:8e0d178b1d1e 4176 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
wolfSSL 16:8e0d178b1d1e 4177 /* Conditionally add a and b using the mask m.
wolfSSL 16:8e0d178b1d1e 4178 * m is -1 to add and 0 when not.
wolfSSL 16:8e0d178b1d1e 4179 *
wolfSSL 16:8e0d178b1d1e 4180 * r A single precision number representing conditional add result.
wolfSSL 16:8e0d178b1d1e 4181 * a A single precision number to add with.
wolfSSL 16:8e0d178b1d1e 4182 * b A single precision number to add.
wolfSSL 16:8e0d178b1d1e 4183 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 4184 */
wolfSSL 16:8e0d178b1d1e 4185 SP_NOINLINE static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 4186 sp_digit m)
wolfSSL 16:8e0d178b1d1e 4187 {
wolfSSL 16:8e0d178b1d1e 4188 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 4189
wolfSSL 16:8e0d178b1d1e 4190 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 4191 "mov r5, #128\n\t"
wolfSSL 16:8e0d178b1d1e 4192 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4193 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 4194 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 4195 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 4196 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 4197 "adds r5, %[c], #-1\n\t"
wolfSSL 16:8e0d178b1d1e 4198 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 4199 "adcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4200 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 4201 "adcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 4202 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 4203 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 4204 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 4205 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 4206 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 4207 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 4208 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 4209 );
wolfSSL 16:8e0d178b1d1e 4210
wolfSSL 16:8e0d178b1d1e 4211 return c;
wolfSSL 16:8e0d178b1d1e 4212 }
wolfSSL 16:8e0d178b1d1e 4213
wolfSSL 16:8e0d178b1d1e 4214 /* RSA private key operation.
wolfSSL 16:8e0d178b1d1e 4215 *
wolfSSL 16:8e0d178b1d1e 4216 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 16:8e0d178b1d1e 4217 * inLen Number of bytes in base.
wolfSSL 16:8e0d178b1d1e 4218 * dm Private exponent.
wolfSSL 16:8e0d178b1d1e 4219 * pm First prime.
wolfSSL 16:8e0d178b1d1e 4220 * qm Second prime.
wolfSSL 16:8e0d178b1d1e 4221 * dpm First prime's CRT exponent.
wolfSSL 16:8e0d178b1d1e 4222 * dqm Second prime's CRT exponent.
wolfSSL 16:8e0d178b1d1e 4223 * qim Inverse of second prime mod p.
wolfSSL 16:8e0d178b1d1e 4224 * mm Modulus.
wolfSSL 16:8e0d178b1d1e 4225 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 16:8e0d178b1d1e 4226 * Must be at least 256 bytes long.
wolfSSL 16:8e0d178b1d1e 4227 * outLen Number of bytes in result.
wolfSSL 16:8e0d178b1d1e 4228 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 16:8e0d178b1d1e 4229 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 16:8e0d178b1d1e 4230 */
wolfSSL 16:8e0d178b1d1e 4231 int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,
wolfSSL 16:8e0d178b1d1e 4232 mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,
wolfSSL 16:8e0d178b1d1e 4233 byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 4234 {
wolfSSL 16:8e0d178b1d1e 4235 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 4236 sp_digit a[64 * 2];
wolfSSL 16:8e0d178b1d1e 4237 sp_digit p[32], q[32], dp[32];
wolfSSL 16:8e0d178b1d1e 4238 sp_digit tmpa[64], tmpb[64];
wolfSSL 16:8e0d178b1d1e 4239 #else
wolfSSL 16:8e0d178b1d1e 4240 sp_digit* t = NULL;
wolfSSL 16:8e0d178b1d1e 4241 sp_digit* a;
wolfSSL 16:8e0d178b1d1e 4242 sp_digit* p;
wolfSSL 16:8e0d178b1d1e 4243 sp_digit* q;
wolfSSL 16:8e0d178b1d1e 4244 sp_digit* dp;
wolfSSL 16:8e0d178b1d1e 4245 sp_digit* tmpa;
wolfSSL 16:8e0d178b1d1e 4246 sp_digit* tmpb;
wolfSSL 16:8e0d178b1d1e 4247 #endif
wolfSSL 16:8e0d178b1d1e 4248 sp_digit* r;
wolfSSL 16:8e0d178b1d1e 4249 sp_digit* qi;
wolfSSL 16:8e0d178b1d1e 4250 sp_digit* dq;
wolfSSL 16:8e0d178b1d1e 4251 sp_digit c;
wolfSSL 16:8e0d178b1d1e 4252 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 4253
wolfSSL 16:8e0d178b1d1e 4254 (void)dm;
wolfSSL 16:8e0d178b1d1e 4255 (void)mm;
wolfSSL 16:8e0d178b1d1e 4256
wolfSSL 16:8e0d178b1d1e 4257 if (*outLen < 256)
wolfSSL 16:8e0d178b1d1e 4258 err = MP_TO_E;
wolfSSL 16:8e0d178b1d1e 4259 if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))
wolfSSL 16:8e0d178b1d1e 4260 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4261
wolfSSL 16:8e0d178b1d1e 4262 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 4263 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4264 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 11, NULL,
wolfSSL 16:8e0d178b1d1e 4265 DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 4266 if (t == NULL)
wolfSSL 16:8e0d178b1d1e 4267 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4268 }
wolfSSL 16:8e0d178b1d1e 4269 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4270 a = t;
wolfSSL 16:8e0d178b1d1e 4271 p = a + 64 * 2;
wolfSSL 16:8e0d178b1d1e 4272 q = p + 32;
wolfSSL 16:8e0d178b1d1e 4273 qi = dq = dp = q + 32;
wolfSSL 16:8e0d178b1d1e 4274 tmpa = qi + 32;
wolfSSL 16:8e0d178b1d1e 4275 tmpb = tmpa + 64;
wolfSSL 16:8e0d178b1d1e 4276
wolfSSL 16:8e0d178b1d1e 4277 r = t + 64;
wolfSSL 16:8e0d178b1d1e 4278 }
wolfSSL 16:8e0d178b1d1e 4279 #else
wolfSSL 16:8e0d178b1d1e 4280 #endif
wolfSSL 16:8e0d178b1d1e 4281
wolfSSL 16:8e0d178b1d1e 4282 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4283 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 4284 r = a;
wolfSSL 16:8e0d178b1d1e 4285 qi = dq = dp;
wolfSSL 16:8e0d178b1d1e 4286 #endif
wolfSSL 16:8e0d178b1d1e 4287 sp_2048_from_bin(a, 64, in, inLen);
wolfSSL 16:8e0d178b1d1e 4288 sp_2048_from_mp(p, 32, pm);
wolfSSL 16:8e0d178b1d1e 4289 sp_2048_from_mp(q, 32, qm);
wolfSSL 16:8e0d178b1d1e 4290 sp_2048_from_mp(dp, 32, dpm);
wolfSSL 16:8e0d178b1d1e 4291
wolfSSL 16:8e0d178b1d1e 4292 err = sp_2048_mod_exp_32(tmpa, a, dp, 1024, p, 1);
wolfSSL 16:8e0d178b1d1e 4293 }
wolfSSL 16:8e0d178b1d1e 4294 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4295 sp_2048_from_mp(dq, 32, dqm);
wolfSSL 16:8e0d178b1d1e 4296 err = sp_2048_mod_exp_32(tmpb, a, dq, 1024, q, 1);
wolfSSL 16:8e0d178b1d1e 4297 }
wolfSSL 16:8e0d178b1d1e 4298
wolfSSL 16:8e0d178b1d1e 4299 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4300 c = sp_2048_sub_in_place_32(tmpa, tmpb);
wolfSSL 16:8e0d178b1d1e 4301 c += sp_2048_cond_add_32(tmpa, tmpa, p, c);
wolfSSL 16:8e0d178b1d1e 4302 sp_2048_cond_add_32(tmpa, tmpa, p, c);
wolfSSL 16:8e0d178b1d1e 4303
wolfSSL 16:8e0d178b1d1e 4304 sp_2048_from_mp(qi, 32, qim);
wolfSSL 16:8e0d178b1d1e 4305 sp_2048_mul_32(tmpa, tmpa, qi);
wolfSSL 16:8e0d178b1d1e 4306 err = sp_2048_mod_32(tmpa, tmpa, p);
wolfSSL 16:8e0d178b1d1e 4307 }
wolfSSL 16:8e0d178b1d1e 4308
wolfSSL 16:8e0d178b1d1e 4309 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4310 sp_2048_mul_32(tmpa, q, tmpa);
wolfSSL 16:8e0d178b1d1e 4311 XMEMSET(&tmpb[32], 0, sizeof(sp_digit) * 32);
wolfSSL 16:8e0d178b1d1e 4312 sp_2048_add_64(r, tmpb, tmpa);
wolfSSL 16:8e0d178b1d1e 4313
wolfSSL 16:8e0d178b1d1e 4314 sp_2048_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 4315 *outLen = 256;
wolfSSL 16:8e0d178b1d1e 4316 }
wolfSSL 16:8e0d178b1d1e 4317
wolfSSL 16:8e0d178b1d1e 4318 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 4319 if (t != NULL) {
wolfSSL 16:8e0d178b1d1e 4320 XMEMSET(t, 0, sizeof(sp_digit) * 32 * 11);
wolfSSL 16:8e0d178b1d1e 4321 XFREE(t, NULL, DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 4322 }
wolfSSL 16:8e0d178b1d1e 4323 #else
wolfSSL 16:8e0d178b1d1e 4324 XMEMSET(tmpa, 0, sizeof(tmpa));
wolfSSL 16:8e0d178b1d1e 4325 XMEMSET(tmpb, 0, sizeof(tmpb));
wolfSSL 16:8e0d178b1d1e 4326 XMEMSET(p, 0, sizeof(p));
wolfSSL 16:8e0d178b1d1e 4327 XMEMSET(q, 0, sizeof(q));
wolfSSL 16:8e0d178b1d1e 4328 XMEMSET(dp, 0, sizeof(dp));
wolfSSL 16:8e0d178b1d1e 4329 #endif
wolfSSL 16:8e0d178b1d1e 4330
wolfSSL 16:8e0d178b1d1e 4331 return err;
wolfSSL 16:8e0d178b1d1e 4332 }
wolfSSL 16:8e0d178b1d1e 4333 #endif /* WOLFSSL_RSA_PUBLIC_ONLY */
wolfSSL 16:8e0d178b1d1e 4334 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
wolfSSL 16:8e0d178b1d1e 4335 #endif /* WOLFSSL_HAVE_SP_RSA */
wolfSSL 16:8e0d178b1d1e 4336 #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
wolfSSL 16:8e0d178b1d1e 4337 !defined(WOLFSSL_RSA_PUBLIC_ONLY))
wolfSSL 16:8e0d178b1d1e 4338 /* Convert an array of sp_digit to an mp_int.
wolfSSL 16:8e0d178b1d1e 4339 *
wolfSSL 16:8e0d178b1d1e 4340 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 4341 * r A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 4342 */
wolfSSL 16:8e0d178b1d1e 4343 static int sp_2048_to_mp(const sp_digit* a, mp_int* r)
wolfSSL 16:8e0d178b1d1e 4344 {
wolfSSL 16:8e0d178b1d1e 4345 int err;
wolfSSL 16:8e0d178b1d1e 4346
wolfSSL 16:8e0d178b1d1e 4347 err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 16:8e0d178b1d1e 4348 if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
wolfSSL 16:8e0d178b1d1e 4349 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 4350 XMEMCPY(r->dp, a, sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 4351 r->used = 64;
wolfSSL 16:8e0d178b1d1e 4352 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 4353 #elif DIGIT_BIT < 32
wolfSSL 16:8e0d178b1d1e 4354 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 4355
wolfSSL 16:8e0d178b1d1e 4356 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 4357 for (i = 0; i < 64; i++) {
wolfSSL 16:8e0d178b1d1e 4358 r->dp[j] |= (mp_digit)(a[i] << s);
wolfSSL 16:8e0d178b1d1e 4359 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 4360 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 4361 r->dp[++j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 4362 while (s + DIGIT_BIT <= 32) {
wolfSSL 16:8e0d178b1d1e 4363 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 4364 r->dp[j++] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 4365 if (s == SP_WORD_SIZE) {
wolfSSL 16:8e0d178b1d1e 4366 r->dp[j] = 0;
wolfSSL 16:8e0d178b1d1e 4367 }
wolfSSL 16:8e0d178b1d1e 4368 else {
wolfSSL 16:8e0d178b1d1e 4369 r->dp[j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 4370 }
wolfSSL 16:8e0d178b1d1e 4371 }
wolfSSL 16:8e0d178b1d1e 4372 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 4373 }
wolfSSL 16:8e0d178b1d1e 4374 r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 4375 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 4376 #else
wolfSSL 16:8e0d178b1d1e 4377 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 4378
wolfSSL 16:8e0d178b1d1e 4379 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 4380 for (i = 0; i < 64; i++) {
wolfSSL 16:8e0d178b1d1e 4381 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 16:8e0d178b1d1e 4382 if (s + 32 >= DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 4383 #if DIGIT_BIT != 32 && DIGIT_BIT != 64
wolfSSL 16:8e0d178b1d1e 4384 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 4385 #endif
wolfSSL 16:8e0d178b1d1e 4386 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 4387 r->dp[++j] = a[i] >> s;
wolfSSL 16:8e0d178b1d1e 4388 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 4389 }
wolfSSL 16:8e0d178b1d1e 4390 else {
wolfSSL 16:8e0d178b1d1e 4391 s += 32;
wolfSSL 16:8e0d178b1d1e 4392 }
wolfSSL 16:8e0d178b1d1e 4393 }
wolfSSL 16:8e0d178b1d1e 4394 r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 4395 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 4396 #endif
wolfSSL 16:8e0d178b1d1e 4397 }
wolfSSL 16:8e0d178b1d1e 4398
wolfSSL 16:8e0d178b1d1e 4399 return err;
wolfSSL 16:8e0d178b1d1e 4400 }
wolfSSL 16:8e0d178b1d1e 4401
wolfSSL 16:8e0d178b1d1e 4402 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 16:8e0d178b1d1e 4403 *
wolfSSL 16:8e0d178b1d1e 4404 * base Base. MP integer.
wolfSSL 16:8e0d178b1d1e 4405 * exp Exponent. MP integer.
wolfSSL 16:8e0d178b1d1e 4406 * mod Modulus. MP integer.
wolfSSL 16:8e0d178b1d1e 4407 * res Result. MP integer.
wolfSSL 16:8e0d178b1d1e 4408 * returns 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 16:8e0d178b1d1e 4409 * and MEMORY_E if memory allocation fails.
wolfSSL 16:8e0d178b1d1e 4410 */
wolfSSL 16:8e0d178b1d1e 4411 int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)
wolfSSL 16:8e0d178b1d1e 4412 {
wolfSSL 16:8e0d178b1d1e 4413 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 4414 sp_digit b[128], e[64], m[64];
wolfSSL 16:8e0d178b1d1e 4415 sp_digit* r = b;
wolfSSL 16:8e0d178b1d1e 4416 int expBits = mp_count_bits(exp);
wolfSSL 16:8e0d178b1d1e 4417
wolfSSL 16:8e0d178b1d1e 4418 if (mp_count_bits(base) > 2048) {
wolfSSL 16:8e0d178b1d1e 4419 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4420 }
wolfSSL 16:8e0d178b1d1e 4421
wolfSSL 16:8e0d178b1d1e 4422 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4423 if (expBits > 2048) {
wolfSSL 16:8e0d178b1d1e 4424 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4425 }
wolfSSL 16:8e0d178b1d1e 4426 }
wolfSSL 16:8e0d178b1d1e 4427
wolfSSL 16:8e0d178b1d1e 4428 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4429 if (mp_count_bits(mod) != 2048) {
wolfSSL 16:8e0d178b1d1e 4430 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4431 }
wolfSSL 16:8e0d178b1d1e 4432 }
wolfSSL 16:8e0d178b1d1e 4433
wolfSSL 16:8e0d178b1d1e 4434 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4435 sp_2048_from_mp(b, 64, base);
wolfSSL 16:8e0d178b1d1e 4436 sp_2048_from_mp(e, 64, exp);
wolfSSL 16:8e0d178b1d1e 4437 sp_2048_from_mp(m, 64, mod);
wolfSSL 16:8e0d178b1d1e 4438
wolfSSL 16:8e0d178b1d1e 4439 err = sp_2048_mod_exp_64(r, b, e, expBits, m, 0);
wolfSSL 16:8e0d178b1d1e 4440 }
wolfSSL 16:8e0d178b1d1e 4441
wolfSSL 16:8e0d178b1d1e 4442 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4443 err = sp_2048_to_mp(r, res);
wolfSSL 16:8e0d178b1d1e 4444 }
wolfSSL 16:8e0d178b1d1e 4445
wolfSSL 16:8e0d178b1d1e 4446 XMEMSET(e, 0, sizeof(e));
wolfSSL 16:8e0d178b1d1e 4447
wolfSSL 16:8e0d178b1d1e 4448 return err;
wolfSSL 16:8e0d178b1d1e 4449 }
wolfSSL 16:8e0d178b1d1e 4450
wolfSSL 16:8e0d178b1d1e 4451 #ifdef WOLFSSL_HAVE_SP_DH
wolfSSL 16:8e0d178b1d1e 4452
wolfSSL 16:8e0d178b1d1e 4453 #ifdef HAVE_FFDHE_2048
wolfSSL 16:8e0d178b1d1e 4454 static void sp_2048_lshift_64(sp_digit* r, sp_digit* a, byte n)
wolfSSL 16:8e0d178b1d1e 4455 {
wolfSSL 16:8e0d178b1d1e 4456 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 4457 "mov r6, #31\n\t"
wolfSSL 16:8e0d178b1d1e 4458 "sub r6, r6, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4459 "add %[a], %[a], #192\n\t"
wolfSSL 16:8e0d178b1d1e 4460 "add %[r], %[r], #192\n\t"
wolfSSL 16:8e0d178b1d1e 4461 "ldr r3, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 4462 "lsr r4, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4463 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4464 "lsr r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4465 "ldr r2, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 4466 "str r4, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 4467 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4468 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4469 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4470 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4471 "ldr r4, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 4472 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 4473 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4474 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4475 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4476 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4477 "ldr r3, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 4478 "str r2, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 4479 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4480 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4481 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4482 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4483 "ldr r2, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 4484 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 4485 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4486 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4487 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4488 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4489 "ldr r4, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 4490 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 4491 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4492 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4493 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4494 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4495 "ldr r3, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 4496 "str r2, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 4497 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4498 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4499 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4500 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4501 "ldr r2, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 4502 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 4503 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4504 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4505 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4506 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4507 "ldr r4, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 4508 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 4509 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4510 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4511 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4512 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4513 "ldr r3, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 4514 "str r2, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 4515 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4516 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4517 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4518 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4519 "ldr r2, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 4520 "str r4, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 4521 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4522 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4523 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4524 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4525 "ldr r4, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 4526 "str r3, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 4527 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4528 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4529 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4530 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4531 "ldr r3, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 4532 "str r2, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 4533 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4534 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4535 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4536 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4537 "ldr r2, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 4538 "str r4, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 4539 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4540 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4541 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4542 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4543 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 4544 "str r3, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 4545 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4546 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4547 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4548 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4549 "ldr r3, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 4550 "str r2, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 4551 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4552 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4553 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4554 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4555 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 4556 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 4557 "ldr r2, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 4558 "str r4, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 4559 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4560 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4561 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4562 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4563 "ldr r4, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 4564 "str r3, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 4565 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4566 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4567 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4568 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4569 "ldr r3, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 4570 "str r2, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 4571 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4572 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4573 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4574 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4575 "ldr r2, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 4576 "str r4, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 4577 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4578 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4579 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4580 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4581 "ldr r4, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 4582 "str r3, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 4583 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4584 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4585 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4586 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4587 "ldr r3, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 4588 "str r2, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 4589 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4590 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4591 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4592 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4593 "ldr r2, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 4594 "str r4, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 4595 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4596 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4597 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4598 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4599 "ldr r4, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 4600 "str r3, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 4601 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4602 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4603 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4604 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4605 "ldr r3, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 4606 "str r2, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 4607 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4608 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4609 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4610 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4611 "ldr r2, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 4612 "str r4, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 4613 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4614 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4615 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4616 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4617 "ldr r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 4618 "str r3, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 4619 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4620 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4621 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4622 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4623 "ldr r3, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 4624 "str r2, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 4625 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4626 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4627 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4628 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4629 "ldr r2, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 4630 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 4631 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4632 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4633 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4634 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4635 "ldr r4, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 4636 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 4637 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4638 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4639 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4640 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4641 "ldr r3, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 4642 "str r2, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 4643 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4644 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4645 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4646 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4647 "ldr r2, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 4648 "str r4, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 4649 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4650 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4651 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4652 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4653 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 4654 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 4655 "ldr r4, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 4656 "str r3, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 4657 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4658 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4659 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4660 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4661 "ldr r3, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 4662 "str r2, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 4663 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4664 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4665 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4666 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4667 "ldr r2, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 4668 "str r4, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 4669 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4670 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4671 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4672 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4673 "ldr r4, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 4674 "str r3, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 4675 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4676 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4677 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4678 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4679 "ldr r3, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 4680 "str r2, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 4681 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4682 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4683 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4684 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4685 "ldr r2, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 4686 "str r4, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 4687 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4688 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4689 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4690 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4691 "ldr r4, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 4692 "str r3, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 4693 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4694 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4695 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4696 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4697 "ldr r3, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 4698 "str r2, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 4699 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4700 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4701 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4702 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4703 "ldr r2, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 4704 "str r4, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 4705 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4706 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4707 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4708 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4709 "ldr r4, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 4710 "str r3, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 4711 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4712 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4713 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4714 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4715 "ldr r3, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 4716 "str r2, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 4717 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4718 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4719 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4720 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4721 "ldr r2, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 4722 "str r4, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 4723 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4724 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4725 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4726 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4727 "ldr r4, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 4728 "str r3, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 4729 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4730 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4731 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4732 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4733 "ldr r3, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 4734 "str r2, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 4735 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4736 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4737 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4738 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4739 "ldr r2, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 4740 "str r4, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 4741 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4742 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4743 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4744 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4745 "ldr r4, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 4746 "str r3, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 4747 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4748 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4749 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4750 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4751 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 4752 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 4753 "ldr r3, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 4754 "str r2, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 4755 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4756 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4757 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4758 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4759 "ldr r2, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 4760 "str r4, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 4761 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4762 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4763 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4764 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4765 "ldr r4, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 4766 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 4767 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4768 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4769 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4770 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4771 "ldr r3, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 4772 "str r2, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 4773 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4774 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4775 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4776 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4777 "ldr r2, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 4778 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 4779 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4780 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4781 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4782 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4783 "ldr r4, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 4784 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 4785 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4786 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4787 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4788 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4789 "ldr r3, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 4790 "str r2, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 4791 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4792 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4793 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4794 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4795 "ldr r2, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 4796 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 4797 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4798 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4799 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4800 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4801 "ldr r4, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 4802 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 4803 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4804 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4805 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4806 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4807 "ldr r3, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 4808 "str r2, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 4809 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4810 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4811 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4812 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4813 "ldr r2, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 4814 "str r4, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 4815 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4816 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4817 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4818 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4819 "ldr r4, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 4820 "str r3, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 4821 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4822 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4823 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4824 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4825 "ldr r3, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 4826 "str r2, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 4827 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4828 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4829 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4830 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4831 "ldr r2, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 4832 "str r4, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 4833 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4834 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4835 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4836 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4837 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 4838 "str r3, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 4839 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4840 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4841 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4842 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4843 "ldr r3, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 4844 "str r2, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 4845 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 4846 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 4847 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 4848 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 4849 "str r3, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 4850 "str r4, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 4851 :
wolfSSL 16:8e0d178b1d1e 4852 : [r] "r" (r), [a] "r" (a), [n] "r" (n)
wolfSSL 16:8e0d178b1d1e 4853 : "memory", "r2", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 4854 );
wolfSSL 16:8e0d178b1d1e 4855 }
wolfSSL 16:8e0d178b1d1e 4856
wolfSSL 16:8e0d178b1d1e 4857 /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
wolfSSL 16:8e0d178b1d1e 4858 *
wolfSSL 16:8e0d178b1d1e 4859 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 4860 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 4861 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 4862 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 4863 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 4864 */
wolfSSL 16:8e0d178b1d1e 4865 static int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits,
wolfSSL 16:8e0d178b1d1e 4866 const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 4867 {
wolfSSL 16:8e0d178b1d1e 4868 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 4869 sp_digit nd[128];
wolfSSL 16:8e0d178b1d1e 4870 sp_digit td[65];
wolfSSL 16:8e0d178b1d1e 4871 #else
wolfSSL 16:8e0d178b1d1e 4872 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 4873 #endif
wolfSSL 16:8e0d178b1d1e 4874 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 4875 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 4876 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 4877 sp_digit n, o;
wolfSSL 16:8e0d178b1d1e 4878 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 4879 int i;
wolfSSL 16:8e0d178b1d1e 4880 int c, y;
wolfSSL 16:8e0d178b1d1e 4881 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 4882
wolfSSL 16:8e0d178b1d1e 4883 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 4884 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 193, NULL,
wolfSSL 16:8e0d178b1d1e 4885 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 4886 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 4887 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4888 }
wolfSSL 16:8e0d178b1d1e 4889 #endif
wolfSSL 16:8e0d178b1d1e 4890
wolfSSL 16:8e0d178b1d1e 4891 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4892 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 4893 norm = td;
wolfSSL 16:8e0d178b1d1e 4894 tmp = td + 128;
wolfSSL 16:8e0d178b1d1e 4895 #else
wolfSSL 16:8e0d178b1d1e 4896 norm = nd;
wolfSSL 16:8e0d178b1d1e 4897 tmp = td;
wolfSSL 16:8e0d178b1d1e 4898 #endif
wolfSSL 16:8e0d178b1d1e 4899
wolfSSL 16:8e0d178b1d1e 4900 sp_2048_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 4901 sp_2048_mont_norm_64(norm, m);
wolfSSL 16:8e0d178b1d1e 4902
wolfSSL 16:8e0d178b1d1e 4903 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 4904 n = e[i--];
wolfSSL 16:8e0d178b1d1e 4905 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 4906 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 4907 c = 32;
wolfSSL 16:8e0d178b1d1e 4908 }
wolfSSL 16:8e0d178b1d1e 4909 c -= bits % 5;
wolfSSL 16:8e0d178b1d1e 4910 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 4911 c = 27;
wolfSSL 16:8e0d178b1d1e 4912 }
wolfSSL 16:8e0d178b1d1e 4913 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 4914 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 4915 sp_2048_lshift_64(r, norm, y);
wolfSSL 16:8e0d178b1d1e 4916 for (; i>=0 || c>=5; ) {
wolfSSL 16:8e0d178b1d1e 4917 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 4918 n = e[i--];
wolfSSL 16:8e0d178b1d1e 4919 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 4920 n <<= 5;
wolfSSL 16:8e0d178b1d1e 4921 c = 27;
wolfSSL 16:8e0d178b1d1e 4922 }
wolfSSL 16:8e0d178b1d1e 4923 else if (c < 5) {
wolfSSL 16:8e0d178b1d1e 4924 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 4925 n = e[i--];
wolfSSL 16:8e0d178b1d1e 4926 c = 5 - c;
wolfSSL 16:8e0d178b1d1e 4927 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 4928 n <<= c;
wolfSSL 16:8e0d178b1d1e 4929 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 4930 }
wolfSSL 16:8e0d178b1d1e 4931 else {
wolfSSL 16:8e0d178b1d1e 4932 y = (n >> 27) & 0x1f;
wolfSSL 16:8e0d178b1d1e 4933 n <<= 5;
wolfSSL 16:8e0d178b1d1e 4934 c -= 5;
wolfSSL 16:8e0d178b1d1e 4935 }
wolfSSL 16:8e0d178b1d1e 4936
wolfSSL 16:8e0d178b1d1e 4937 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 4938 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 4939 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 4940 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 4941 sp_2048_mont_sqr_64(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 4942
wolfSSL 16:8e0d178b1d1e 4943 sp_2048_lshift_64(r, r, y);
wolfSSL 16:8e0d178b1d1e 4944 sp_2048_mul_d_64(tmp, norm, r[64]);
wolfSSL 16:8e0d178b1d1e 4945 r[64] = 0;
wolfSSL 16:8e0d178b1d1e 4946 o = sp_2048_add_64(r, r, tmp);
wolfSSL 16:8e0d178b1d1e 4947 sp_2048_cond_sub_64(r, r, m, (sp_digit)0 - o);
wolfSSL 16:8e0d178b1d1e 4948 }
wolfSSL 16:8e0d178b1d1e 4949
wolfSSL 16:8e0d178b1d1e 4950 XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);
wolfSSL 16:8e0d178b1d1e 4951 sp_2048_mont_reduce_64(r, m, mp);
wolfSSL 16:8e0d178b1d1e 4952
wolfSSL 16:8e0d178b1d1e 4953 mask = 0 - (sp_2048_cmp_64(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 4954 sp_2048_cond_sub_64(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 4955 }
wolfSSL 16:8e0d178b1d1e 4956
wolfSSL 16:8e0d178b1d1e 4957 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 4958 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 4959 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 4960 }
wolfSSL 16:8e0d178b1d1e 4961 #endif
wolfSSL 16:8e0d178b1d1e 4962
wolfSSL 16:8e0d178b1d1e 4963 return err;
wolfSSL 16:8e0d178b1d1e 4964 }
wolfSSL 16:8e0d178b1d1e 4965 #endif /* HAVE_FFDHE_2048 */
wolfSSL 16:8e0d178b1d1e 4966
wolfSSL 16:8e0d178b1d1e 4967 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 16:8e0d178b1d1e 4968 *
wolfSSL 16:8e0d178b1d1e 4969 * base Base.
wolfSSL 16:8e0d178b1d1e 4970 * exp Array of bytes that is the exponent.
wolfSSL 16:8e0d178b1d1e 4971 * expLen Length of data, in bytes, in exponent.
wolfSSL 16:8e0d178b1d1e 4972 * mod Modulus.
wolfSSL 16:8e0d178b1d1e 4973 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 16:8e0d178b1d1e 4974 * Must be at least 256 bytes long.
wolfSSL 16:8e0d178b1d1e 4975 * outLen Length, in bytes, of exponentiation result.
wolfSSL 16:8e0d178b1d1e 4976 * returns 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 16:8e0d178b1d1e 4977 * and MEMORY_E if memory allocation fails.
wolfSSL 16:8e0d178b1d1e 4978 */
wolfSSL 16:8e0d178b1d1e 4979 int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,
wolfSSL 16:8e0d178b1d1e 4980 mp_int* mod, byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 4981 {
wolfSSL 16:8e0d178b1d1e 4982 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 4983 sp_digit b[128], e[64], m[64];
wolfSSL 16:8e0d178b1d1e 4984 sp_digit* r = b;
wolfSSL 16:8e0d178b1d1e 4985 word32 i;
wolfSSL 16:8e0d178b1d1e 4986
wolfSSL 16:8e0d178b1d1e 4987 if (mp_count_bits(base) > 2048) {
wolfSSL 16:8e0d178b1d1e 4988 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4989 }
wolfSSL 16:8e0d178b1d1e 4990
wolfSSL 16:8e0d178b1d1e 4991 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4992 if (expLen > 256) {
wolfSSL 16:8e0d178b1d1e 4993 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 4994 }
wolfSSL 16:8e0d178b1d1e 4995 }
wolfSSL 16:8e0d178b1d1e 4996
wolfSSL 16:8e0d178b1d1e 4997 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 4998 if (mp_count_bits(mod) != 2048) {
wolfSSL 16:8e0d178b1d1e 4999 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 5000 }
wolfSSL 16:8e0d178b1d1e 5001 }
wolfSSL 16:8e0d178b1d1e 5002
wolfSSL 16:8e0d178b1d1e 5003 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 5004 sp_2048_from_mp(b, 64, base);
wolfSSL 16:8e0d178b1d1e 5005 sp_2048_from_bin(e, 64, exp, expLen);
wolfSSL 16:8e0d178b1d1e 5006 sp_2048_from_mp(m, 64, mod);
wolfSSL 16:8e0d178b1d1e 5007
wolfSSL 16:8e0d178b1d1e 5008 #ifdef HAVE_FFDHE_2048
wolfSSL 16:8e0d178b1d1e 5009 if (base->used == 1 && base->dp[0] == 2 && m[63] == (sp_digit)-1)
wolfSSL 16:8e0d178b1d1e 5010 err = sp_2048_mod_exp_2_64(r, e, expLen * 8, m);
wolfSSL 16:8e0d178b1d1e 5011 else
wolfSSL 16:8e0d178b1d1e 5012 #endif
wolfSSL 16:8e0d178b1d1e 5013 err = sp_2048_mod_exp_64(r, b, e, expLen * 8, m, 0);
wolfSSL 16:8e0d178b1d1e 5014
wolfSSL 16:8e0d178b1d1e 5015 }
wolfSSL 16:8e0d178b1d1e 5016
wolfSSL 16:8e0d178b1d1e 5017 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 5018 sp_2048_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 5019 *outLen = 256;
wolfSSL 16:8e0d178b1d1e 5020 for (i=0; i<256 && out[i] == 0; i++) {
wolfSSL 16:8e0d178b1d1e 5021 }
wolfSSL 16:8e0d178b1d1e 5022 *outLen -= i;
wolfSSL 16:8e0d178b1d1e 5023 XMEMMOVE(out, out + i, *outLen);
wolfSSL 16:8e0d178b1d1e 5024
wolfSSL 16:8e0d178b1d1e 5025 }
wolfSSL 16:8e0d178b1d1e 5026
wolfSSL 16:8e0d178b1d1e 5027 XMEMSET(e, 0, sizeof(e));
wolfSSL 16:8e0d178b1d1e 5028
wolfSSL 16:8e0d178b1d1e 5029 return err;
wolfSSL 16:8e0d178b1d1e 5030 }
wolfSSL 16:8e0d178b1d1e 5031 #endif /* WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 5032
wolfSSL 16:8e0d178b1d1e 5033 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 16:8e0d178b1d1e 5034 *
wolfSSL 16:8e0d178b1d1e 5035 * base Base. MP integer.
wolfSSL 16:8e0d178b1d1e 5036 * exp Exponent. MP integer.
wolfSSL 16:8e0d178b1d1e 5037 * mod Modulus. MP integer.
wolfSSL 16:8e0d178b1d1e 5038 * res Result. MP integer.
wolfSSL 16:8e0d178b1d1e 5039 * returns 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 16:8e0d178b1d1e 5040 * and MEMORY_E if memory allocation fails.
wolfSSL 16:8e0d178b1d1e 5041 */
wolfSSL 16:8e0d178b1d1e 5042 int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)
wolfSSL 16:8e0d178b1d1e 5043 {
wolfSSL 16:8e0d178b1d1e 5044 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 5045 sp_digit b[64], e[32], m[32];
wolfSSL 16:8e0d178b1d1e 5046 sp_digit* r = b;
wolfSSL 16:8e0d178b1d1e 5047 int expBits = mp_count_bits(exp);
wolfSSL 16:8e0d178b1d1e 5048
wolfSSL 16:8e0d178b1d1e 5049 if (mp_count_bits(base) > 1024) {
wolfSSL 16:8e0d178b1d1e 5050 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 5051 }
wolfSSL 16:8e0d178b1d1e 5052
wolfSSL 16:8e0d178b1d1e 5053 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 5054 if (expBits > 1024) {
wolfSSL 16:8e0d178b1d1e 5055 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 5056 }
wolfSSL 16:8e0d178b1d1e 5057 }
wolfSSL 16:8e0d178b1d1e 5058
wolfSSL 16:8e0d178b1d1e 5059 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 5060 if (mp_count_bits(mod) != 1024) {
wolfSSL 16:8e0d178b1d1e 5061 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 5062 }
wolfSSL 16:8e0d178b1d1e 5063 }
wolfSSL 16:8e0d178b1d1e 5064
wolfSSL 16:8e0d178b1d1e 5065 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 5066 sp_2048_from_mp(b, 32, base);
wolfSSL 16:8e0d178b1d1e 5067 sp_2048_from_mp(e, 32, exp);
wolfSSL 16:8e0d178b1d1e 5068 sp_2048_from_mp(m, 32, mod);
wolfSSL 16:8e0d178b1d1e 5069
wolfSSL 16:8e0d178b1d1e 5070 err = sp_2048_mod_exp_32(r, b, e, expBits, m, 0);
wolfSSL 16:8e0d178b1d1e 5071 }
wolfSSL 16:8e0d178b1d1e 5072
wolfSSL 16:8e0d178b1d1e 5073 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 5074 XMEMSET(r + 32, 0, sizeof(*r) * 32U);
wolfSSL 16:8e0d178b1d1e 5075 err = sp_2048_to_mp(r, res);
wolfSSL 16:8e0d178b1d1e 5076 res->used = mod->used;
wolfSSL 16:8e0d178b1d1e 5077 mp_clamp(res);
wolfSSL 16:8e0d178b1d1e 5078 }
wolfSSL 16:8e0d178b1d1e 5079
wolfSSL 16:8e0d178b1d1e 5080 XMEMSET(e, 0, sizeof(e));
wolfSSL 16:8e0d178b1d1e 5081
wolfSSL 16:8e0d178b1d1e 5082 return err;
wolfSSL 16:8e0d178b1d1e 5083 }
wolfSSL 16:8e0d178b1d1e 5084
wolfSSL 16:8e0d178b1d1e 5085 #endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */
wolfSSL 16:8e0d178b1d1e 5086
wolfSSL 16:8e0d178b1d1e 5087 #endif /* !WOLFSSL_SP_NO_2048 */
wolfSSL 16:8e0d178b1d1e 5088
wolfSSL 16:8e0d178b1d1e 5089 #ifndef WOLFSSL_SP_NO_3072
wolfSSL 16:8e0d178b1d1e 5090 /* Read big endian unsigned byte array into r.
wolfSSL 16:8e0d178b1d1e 5091 *
wolfSSL 16:8e0d178b1d1e 5092 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5093 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 5094 * a Byte array.
wolfSSL 16:8e0d178b1d1e 5095 * n Number of bytes in array to read.
wolfSSL 16:8e0d178b1d1e 5096 */
wolfSSL 16:8e0d178b1d1e 5097 static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)
wolfSSL 16:8e0d178b1d1e 5098 {
wolfSSL 16:8e0d178b1d1e 5099 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 5100 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 5101
wolfSSL 16:8e0d178b1d1e 5102 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 5103 for (i = n-1; i >= 0; i--) {
wolfSSL 16:8e0d178b1d1e 5104 r[j] |= (((sp_digit)a[i]) << s);
wolfSSL 16:8e0d178b1d1e 5105 if (s >= 24U) {
wolfSSL 16:8e0d178b1d1e 5106 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 5107 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 5108 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 5109 break;
wolfSSL 16:8e0d178b1d1e 5110 }
wolfSSL 16:8e0d178b1d1e 5111 r[++j] = (sp_digit)a[i] >> s;
wolfSSL 16:8e0d178b1d1e 5112 s = 8U - s;
wolfSSL 16:8e0d178b1d1e 5113 }
wolfSSL 16:8e0d178b1d1e 5114 else {
wolfSSL 16:8e0d178b1d1e 5115 s += 8U;
wolfSSL 16:8e0d178b1d1e 5116 }
wolfSSL 16:8e0d178b1d1e 5117 }
wolfSSL 16:8e0d178b1d1e 5118
wolfSSL 16:8e0d178b1d1e 5119 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 5120 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 5121 }
wolfSSL 16:8e0d178b1d1e 5122 }
wolfSSL 16:8e0d178b1d1e 5123
wolfSSL 16:8e0d178b1d1e 5124 /* Convert an mp_int to an array of sp_digit.
wolfSSL 16:8e0d178b1d1e 5125 *
wolfSSL 16:8e0d178b1d1e 5126 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5127 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 5128 * a A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 5129 */
wolfSSL 16:8e0d178b1d1e 5130 static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)
wolfSSL 16:8e0d178b1d1e 5131 {
wolfSSL 16:8e0d178b1d1e 5132 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 5133 int j;
wolfSSL 16:8e0d178b1d1e 5134
wolfSSL 16:8e0d178b1d1e 5135 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 16:8e0d178b1d1e 5136
wolfSSL 16:8e0d178b1d1e 5137 for (j = a->used; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 5138 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 5139 }
wolfSSL 16:8e0d178b1d1e 5140 #elif DIGIT_BIT > 32
wolfSSL 16:8e0d178b1d1e 5141 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 5142 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 5143
wolfSSL 16:8e0d178b1d1e 5144 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 5145 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 5146 r[j] |= ((sp_digit)a->dp[i] << s);
wolfSSL 16:8e0d178b1d1e 5147 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 5148 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 5149 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 5150 break;
wolfSSL 16:8e0d178b1d1e 5151 }
wolfSSL 16:8e0d178b1d1e 5152 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 5153 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 5154 while ((s + 32U) <= (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 5155 s += 32U;
wolfSSL 16:8e0d178b1d1e 5156 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 5157 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 5158 break;
wolfSSL 16:8e0d178b1d1e 5159 }
wolfSSL 16:8e0d178b1d1e 5160 if (s < (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 5161 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 5162 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 5163 }
wolfSSL 16:8e0d178b1d1e 5164 else {
wolfSSL 16:8e0d178b1d1e 5165 r[++j] = 0L;
wolfSSL 16:8e0d178b1d1e 5166 }
wolfSSL 16:8e0d178b1d1e 5167 }
wolfSSL 16:8e0d178b1d1e 5168 s = (word32)DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 5169 }
wolfSSL 16:8e0d178b1d1e 5170
wolfSSL 16:8e0d178b1d1e 5171 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 5172 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 5173 }
wolfSSL 16:8e0d178b1d1e 5174 #else
wolfSSL 16:8e0d178b1d1e 5175 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 5176
wolfSSL 16:8e0d178b1d1e 5177 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 5178 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 5179 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 16:8e0d178b1d1e 5180 if (s + DIGIT_BIT >= 32) {
wolfSSL 16:8e0d178b1d1e 5181 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 5182 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 5183 break;
wolfSSL 16:8e0d178b1d1e 5184 }
wolfSSL 16:8e0d178b1d1e 5185 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 5186 if (s == DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 5187 r[++j] = 0;
wolfSSL 16:8e0d178b1d1e 5188 s = 0;
wolfSSL 16:8e0d178b1d1e 5189 }
wolfSSL 16:8e0d178b1d1e 5190 else {
wolfSSL 16:8e0d178b1d1e 5191 r[++j] = a->dp[i] >> s;
wolfSSL 16:8e0d178b1d1e 5192 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 5193 }
wolfSSL 16:8e0d178b1d1e 5194 }
wolfSSL 16:8e0d178b1d1e 5195 else {
wolfSSL 16:8e0d178b1d1e 5196 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 5197 }
wolfSSL 16:8e0d178b1d1e 5198 }
wolfSSL 16:8e0d178b1d1e 5199
wolfSSL 16:8e0d178b1d1e 5200 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 5201 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 5202 }
wolfSSL 16:8e0d178b1d1e 5203 #endif
wolfSSL 16:8e0d178b1d1e 5204 }
wolfSSL 16:8e0d178b1d1e 5205
wolfSSL 16:8e0d178b1d1e 5206 /* Write r as big endian to byte array.
wolfSSL 16:8e0d178b1d1e 5207 * Fixed length number of bytes written: 384
wolfSSL 16:8e0d178b1d1e 5208 *
wolfSSL 16:8e0d178b1d1e 5209 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5210 * a Byte array.
wolfSSL 16:8e0d178b1d1e 5211 */
wolfSSL 16:8e0d178b1d1e 5212 static void sp_3072_to_bin(sp_digit* r, byte* a)
wolfSSL 16:8e0d178b1d1e 5213 {
wolfSSL 16:8e0d178b1d1e 5214 int i, j, s = 0, b;
wolfSSL 16:8e0d178b1d1e 5215
wolfSSL 16:8e0d178b1d1e 5216 j = 3072 / 8 - 1;
wolfSSL 16:8e0d178b1d1e 5217 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 5218 for (i=0; i<96 && j>=0; i++) {
wolfSSL 16:8e0d178b1d1e 5219 b = 0;
wolfSSL 16:8e0d178b1d1e 5220 /* lint allow cast of mismatch sp_digit and int */
wolfSSL 16:8e0d178b1d1e 5221 a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 5222 b += 8 - s;
wolfSSL 16:8e0d178b1d1e 5223 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 5224 break;
wolfSSL 16:8e0d178b1d1e 5225 }
wolfSSL 16:8e0d178b1d1e 5226 while (b < 32) {
wolfSSL 16:8e0d178b1d1e 5227 a[j--] = (byte)(r[i] >> b);
wolfSSL 16:8e0d178b1d1e 5228 b += 8;
wolfSSL 16:8e0d178b1d1e 5229 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 5230 break;
wolfSSL 16:8e0d178b1d1e 5231 }
wolfSSL 16:8e0d178b1d1e 5232 }
wolfSSL 16:8e0d178b1d1e 5233 s = 8 - (b - 32);
wolfSSL 16:8e0d178b1d1e 5234 if (j >= 0) {
wolfSSL 16:8e0d178b1d1e 5235 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 5236 }
wolfSSL 16:8e0d178b1d1e 5237 if (s != 0) {
wolfSSL 16:8e0d178b1d1e 5238 j++;
wolfSSL 16:8e0d178b1d1e 5239 }
wolfSSL 16:8e0d178b1d1e 5240 }
wolfSSL 16:8e0d178b1d1e 5241 }
wolfSSL 16:8e0d178b1d1e 5242
wolfSSL 16:8e0d178b1d1e 5243 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 5244 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 5245 *
wolfSSL 16:8e0d178b1d1e 5246 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5247 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5248 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 5249 */
wolfSSL 16:8e0d178b1d1e 5250 SP_NOINLINE static void sp_3072_mul_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 5251 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 5252 {
wolfSSL 16:8e0d178b1d1e 5253 sp_digit tmp[12 * 2];
wolfSSL 16:8e0d178b1d1e 5254 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 5255 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 5256 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 5257 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 5258 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 5259 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 5260 "mov r11, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 5261 "mov r6, #48\n\t"
wolfSSL 16:8e0d178b1d1e 5262 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 5263 "mov r14, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5264 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 5265 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 5266 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 5267 "mov r6, #44\n\t"
wolfSSL 16:8e0d178b1d1e 5268 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 5269 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 5270 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5271 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5272 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 5273 "mov %[b], r9\n\t"
wolfSSL 16:8e0d178b1d1e 5274 "sub %[b], %[b], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 5275 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 5276 "add %[b], %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 5277 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 5278 /* Multiply Start */
wolfSSL 16:8e0d178b1d1e 5279 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 5280 "ldr r8, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 5281 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5282 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5283 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5284 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 5285 /* Multiply Done */
wolfSSL 16:8e0d178b1d1e 5286 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 5287 "sub %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 5288 "cmp %[a], r14\n\t"
wolfSSL 16:8e0d178b1d1e 5289 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 5290 "mov r6, r9\n\t"
wolfSSL 16:8e0d178b1d1e 5291 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 5292 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 5293 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 5294 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 5295 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 5296 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 5297 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 5298 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 5299 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5300 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 5301 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5302 "mov r6, #88\n\t"
wolfSSL 16:8e0d178b1d1e 5303 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5304 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 5305 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 5306 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 5307 "mov %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 5308 :
wolfSSL 16:8e0d178b1d1e 5309 : [r] "r" (tmp), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 5310 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 5311 );
wolfSSL 16:8e0d178b1d1e 5312
wolfSSL 16:8e0d178b1d1e 5313 XMEMCPY(r, tmp, sizeof(tmp));
wolfSSL 16:8e0d178b1d1e 5314 }
wolfSSL 16:8e0d178b1d1e 5315
wolfSSL 16:8e0d178b1d1e 5316 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 5317 *
wolfSSL 16:8e0d178b1d1e 5318 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5319 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5320 */
wolfSSL 16:8e0d178b1d1e 5321 SP_NOINLINE static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 5322 {
wolfSSL 16:8e0d178b1d1e 5323 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 5324 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 5325 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 5326 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 5327 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 5328 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 5329 "mov r6, #96\n\t"
wolfSSL 16:8e0d178b1d1e 5330 "neg r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5331 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5332 "mov r11, sp\n\t"
wolfSSL 16:8e0d178b1d1e 5333 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 5334 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 5335 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 5336 "mov r6, #44\n\t"
wolfSSL 16:8e0d178b1d1e 5337 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 5338 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 5339 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5340 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5341 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 5342 "mov r2, r9\n\t"
wolfSSL 16:8e0d178b1d1e 5343 "sub r2, r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 5344 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 5345 "add r2, r2, r10\n\t"
wolfSSL 16:8e0d178b1d1e 5346 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 5347 "cmp r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 5348 "beq 4f\n\t"
wolfSSL 16:8e0d178b1d1e 5349 /* Multiply * 2: Start */
wolfSSL 16:8e0d178b1d1e 5350 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 5351 "ldr r8, [r2]\n\t"
wolfSSL 16:8e0d178b1d1e 5352 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5353 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5354 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5355 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 5356 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5357 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5358 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 5359 /* Multiply * 2: Done */
wolfSSL 16:8e0d178b1d1e 5360 "bal 5f\n\t"
wolfSSL 16:8e0d178b1d1e 5361 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 5362 /* Square: Start */
wolfSSL 16:8e0d178b1d1e 5363 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 5364 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5365 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5366 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5367 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 5368 /* Square: Done */
wolfSSL 16:8e0d178b1d1e 5369 "\n5:\n\t"
wolfSSL 16:8e0d178b1d1e 5370 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 5371 "sub r2, r2, #4\n\t"
wolfSSL 16:8e0d178b1d1e 5372 "mov r6, #48\n\t"
wolfSSL 16:8e0d178b1d1e 5373 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 5374 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 5375 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 5376 "cmp %[a], r2\n\t"
wolfSSL 16:8e0d178b1d1e 5377 "bgt 3f\n\t"
wolfSSL 16:8e0d178b1d1e 5378 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 5379 "add r8, r8, r10\n\t"
wolfSSL 16:8e0d178b1d1e 5380 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 5381 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 5382 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 5383 "mov %[r], r11\n\t"
wolfSSL 16:8e0d178b1d1e 5384 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 5385 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 5386 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 5387 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5388 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 5389 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 5390 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5391 "mov r6, #88\n\t"
wolfSSL 16:8e0d178b1d1e 5392 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5393 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 5394 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 5395 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 5396 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 5397 "mov %[a], r11\n\t"
wolfSSL 16:8e0d178b1d1e 5398 "mov r3, #92\n\t"
wolfSSL 16:8e0d178b1d1e 5399 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 5400 "ldr r6, [%[a], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 5401 "str r6, [%[r], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 5402 "subs r3, r3, #4\n\t"
wolfSSL 16:8e0d178b1d1e 5403 "bge 4b\n\t"
wolfSSL 16:8e0d178b1d1e 5404 "mov r6, #96\n\t"
wolfSSL 16:8e0d178b1d1e 5405 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5406 :
wolfSSL 16:8e0d178b1d1e 5407 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 5408 : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 5409 );
wolfSSL 16:8e0d178b1d1e 5410 }
wolfSSL 16:8e0d178b1d1e 5411
wolfSSL 16:8e0d178b1d1e 5412 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 5413 *
wolfSSL 16:8e0d178b1d1e 5414 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5415 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5416 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 5417 */
wolfSSL 16:8e0d178b1d1e 5418 SP_NOINLINE static sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 5419 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 5420 {
wolfSSL 16:8e0d178b1d1e 5421 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 5422
wolfSSL 16:8e0d178b1d1e 5423 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 5424 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5425 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5426 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5427 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5428 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5429 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5430 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5431 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5432 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5433 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5434 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5435 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5436 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5437 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5438 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5439 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5440 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5441 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5442 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5443 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5444 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5445 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5446 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5447 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5448 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5449 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5450 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5451 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5452 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5453 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5454 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 5455 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 5456 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 5457 :
wolfSSL 16:8e0d178b1d1e 5458 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 5459 );
wolfSSL 16:8e0d178b1d1e 5460
wolfSSL 16:8e0d178b1d1e 5461 return c;
wolfSSL 16:8e0d178b1d1e 5462 }
wolfSSL 16:8e0d178b1d1e 5463
wolfSSL 16:8e0d178b1d1e 5464 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 5465 *
wolfSSL 16:8e0d178b1d1e 5466 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5467 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5468 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 5469 */
wolfSSL 16:8e0d178b1d1e 5470 SP_NOINLINE static sp_digit sp_3072_sub_in_place_24(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 5471 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 5472 {
wolfSSL 16:8e0d178b1d1e 5473 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 5474
wolfSSL 16:8e0d178b1d1e 5475 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 5476 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5477 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5478 "subs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5479 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5480 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5481 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5482 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5483 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5484 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5485 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5486 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5487 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5488 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5489 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5490 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5491 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5492 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5493 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5494 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5495 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5496 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5497 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5498 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5499 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5500 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5501 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5502 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5503 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5504 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5505 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5506 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5507 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5508 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5509 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5510 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5511 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5512 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5513 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5514 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5515 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5516 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5517 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5518 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5519 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5520 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5521 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5522 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5523 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5524 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5525 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5526 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5527 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5528 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5529 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5530 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5531 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5532 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5533 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5534 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5535 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5536 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 5537 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 5538 :
wolfSSL 16:8e0d178b1d1e 5539 : "memory", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 5540 );
wolfSSL 16:8e0d178b1d1e 5541
wolfSSL 16:8e0d178b1d1e 5542 return c;
wolfSSL 16:8e0d178b1d1e 5543 }
wolfSSL 16:8e0d178b1d1e 5544
wolfSSL 16:8e0d178b1d1e 5545 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 5546 *
wolfSSL 16:8e0d178b1d1e 5547 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5548 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5549 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 5550 */
wolfSSL 16:8e0d178b1d1e 5551 SP_NOINLINE static sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 5552 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 5553 {
wolfSSL 16:8e0d178b1d1e 5554 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 5555
wolfSSL 16:8e0d178b1d1e 5556 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 5557 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5558 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5559 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5560 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5561 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5562 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5563 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5564 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5565 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5566 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5567 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5568 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5569 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5570 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5571 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5572 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5573 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5574 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5575 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5576 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5577 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5578 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5579 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5580 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5581 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5582 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5583 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5584 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5585 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5586 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5587 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5588 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5589 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5590 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5591 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5592 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5593 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5594 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5595 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5596 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5597 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5598 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5599 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5600 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5601 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5602 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5603 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5604 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5605 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5606 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5607 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5608 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5609 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5610 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5611 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5612 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5613 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5614 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5615 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5616 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5617 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 5618 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 5619 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 5620 :
wolfSSL 16:8e0d178b1d1e 5621 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 5622 );
wolfSSL 16:8e0d178b1d1e 5623
wolfSSL 16:8e0d178b1d1e 5624 return c;
wolfSSL 16:8e0d178b1d1e 5625 }
wolfSSL 16:8e0d178b1d1e 5626
wolfSSL 16:8e0d178b1d1e 5627 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 5628 *
wolfSSL 16:8e0d178b1d1e 5629 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5630 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5631 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 5632 */
wolfSSL 16:8e0d178b1d1e 5633 static void sp_3072_mask_12(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 5634 {
wolfSSL 16:8e0d178b1d1e 5635 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 5636 int i;
wolfSSL 16:8e0d178b1d1e 5637
wolfSSL 16:8e0d178b1d1e 5638 for (i=0; i<12; i++) {
wolfSSL 16:8e0d178b1d1e 5639 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 5640 }
wolfSSL 16:8e0d178b1d1e 5641 #else
wolfSSL 16:8e0d178b1d1e 5642 r[0] = a[0] & m;
wolfSSL 16:8e0d178b1d1e 5643 r[1] = a[1] & m;
wolfSSL 16:8e0d178b1d1e 5644 r[2] = a[2] & m;
wolfSSL 16:8e0d178b1d1e 5645 r[3] = a[3] & m;
wolfSSL 16:8e0d178b1d1e 5646 r[4] = a[4] & m;
wolfSSL 16:8e0d178b1d1e 5647 r[5] = a[5] & m;
wolfSSL 16:8e0d178b1d1e 5648 r[6] = a[6] & m;
wolfSSL 16:8e0d178b1d1e 5649 r[7] = a[7] & m;
wolfSSL 16:8e0d178b1d1e 5650 r[8] = a[8] & m;
wolfSSL 16:8e0d178b1d1e 5651 r[9] = a[9] & m;
wolfSSL 16:8e0d178b1d1e 5652 r[10] = a[10] & m;
wolfSSL 16:8e0d178b1d1e 5653 r[11] = a[11] & m;
wolfSSL 16:8e0d178b1d1e 5654 #endif
wolfSSL 16:8e0d178b1d1e 5655 }
wolfSSL 16:8e0d178b1d1e 5656
wolfSSL 16:8e0d178b1d1e 5657 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 5658 *
wolfSSL 16:8e0d178b1d1e 5659 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5660 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5661 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 5662 */
wolfSSL 16:8e0d178b1d1e 5663 SP_NOINLINE static void sp_3072_mul_24(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 5664 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 5665 {
wolfSSL 16:8e0d178b1d1e 5666 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 5667 sp_digit z1[24];
wolfSSL 16:8e0d178b1d1e 5668 sp_digit a1[12];
wolfSSL 16:8e0d178b1d1e 5669 sp_digit b1[12];
wolfSSL 16:8e0d178b1d1e 5670 sp_digit z2[24];
wolfSSL 16:8e0d178b1d1e 5671 sp_digit u, ca, cb;
wolfSSL 16:8e0d178b1d1e 5672
wolfSSL 16:8e0d178b1d1e 5673 ca = sp_3072_add_12(a1, a, &a[12]);
wolfSSL 16:8e0d178b1d1e 5674 cb = sp_3072_add_12(b1, b, &b[12]);
wolfSSL 16:8e0d178b1d1e 5675 u = ca & cb;
wolfSSL 16:8e0d178b1d1e 5676 sp_3072_mul_12(z1, a1, b1);
wolfSSL 16:8e0d178b1d1e 5677 sp_3072_mul_12(z2, &a[12], &b[12]);
wolfSSL 16:8e0d178b1d1e 5678 sp_3072_mul_12(z0, a, b);
wolfSSL 16:8e0d178b1d1e 5679 sp_3072_mask_12(r + 24, a1, 0 - cb);
wolfSSL 16:8e0d178b1d1e 5680 sp_3072_mask_12(b1, b1, 0 - ca);
wolfSSL 16:8e0d178b1d1e 5681 u += sp_3072_add_12(r + 24, r + 24, b1);
wolfSSL 16:8e0d178b1d1e 5682 u += sp_3072_sub_in_place_24(z1, z2);
wolfSSL 16:8e0d178b1d1e 5683 u += sp_3072_sub_in_place_24(z1, z0);
wolfSSL 16:8e0d178b1d1e 5684 u += sp_3072_add_24(r + 12, r + 12, z1);
wolfSSL 16:8e0d178b1d1e 5685 r[36] = u;
wolfSSL 16:8e0d178b1d1e 5686 XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));
wolfSSL 16:8e0d178b1d1e 5687 (void)sp_3072_add_24(r + 24, r + 24, z2);
wolfSSL 16:8e0d178b1d1e 5688 }
wolfSSL 16:8e0d178b1d1e 5689
wolfSSL 16:8e0d178b1d1e 5690 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 5691 *
wolfSSL 16:8e0d178b1d1e 5692 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5693 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5694 */
wolfSSL 16:8e0d178b1d1e 5695 SP_NOINLINE static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 5696 {
wolfSSL 16:8e0d178b1d1e 5697 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 5698 sp_digit z2[24];
wolfSSL 16:8e0d178b1d1e 5699 sp_digit z1[24];
wolfSSL 16:8e0d178b1d1e 5700 sp_digit a1[12];
wolfSSL 16:8e0d178b1d1e 5701 sp_digit u;
wolfSSL 16:8e0d178b1d1e 5702
wolfSSL 16:8e0d178b1d1e 5703 u = sp_3072_add_12(a1, a, &a[12]);
wolfSSL 16:8e0d178b1d1e 5704 sp_3072_sqr_12(z1, a1);
wolfSSL 16:8e0d178b1d1e 5705 sp_3072_sqr_12(z2, &a[12]);
wolfSSL 16:8e0d178b1d1e 5706 sp_3072_sqr_12(z0, a);
wolfSSL 16:8e0d178b1d1e 5707 sp_3072_mask_12(r + 24, a1, 0 - u);
wolfSSL 16:8e0d178b1d1e 5708 u += sp_3072_add_12(r + 24, r + 24, r + 24);
wolfSSL 16:8e0d178b1d1e 5709 u += sp_3072_sub_in_place_24(z1, z2);
wolfSSL 16:8e0d178b1d1e 5710 u += sp_3072_sub_in_place_24(z1, z0);
wolfSSL 16:8e0d178b1d1e 5711 u += sp_3072_add_24(r + 12, r + 12, z1);
wolfSSL 16:8e0d178b1d1e 5712 r[36] = u;
wolfSSL 16:8e0d178b1d1e 5713 XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));
wolfSSL 16:8e0d178b1d1e 5714 (void)sp_3072_add_24(r + 24, r + 24, z2);
wolfSSL 16:8e0d178b1d1e 5715 }
wolfSSL 16:8e0d178b1d1e 5716
wolfSSL 16:8e0d178b1d1e 5717 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 5718 *
wolfSSL 16:8e0d178b1d1e 5719 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5720 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5721 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 5722 */
wolfSSL 16:8e0d178b1d1e 5723 SP_NOINLINE static sp_digit sp_3072_sub_in_place_48(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 5724 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 5725 {
wolfSSL 16:8e0d178b1d1e 5726 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 5727
wolfSSL 16:8e0d178b1d1e 5728 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 5729 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5730 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5731 "subs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5732 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5733 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5734 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5735 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5736 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5737 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5738 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5739 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5740 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5741 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5742 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5743 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5744 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5745 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5746 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5747 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5748 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5749 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5750 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5751 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5752 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5753 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5754 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5755 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5756 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5757 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5758 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5759 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5760 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5761 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5762 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5763 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5764 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5765 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5766 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5767 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5768 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5769 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5770 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5771 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5772 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5773 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5774 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5775 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5776 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5777 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5778 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5779 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5780 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5781 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5782 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5783 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5784 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5785 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5786 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5787 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5788 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5789 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5790 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5791 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5792 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5793 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5794 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5795 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5796 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5797 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5798 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5799 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5800 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5801 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5802 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5803 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5804 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5805 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5806 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5807 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5808 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5809 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5810 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5811 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5812 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5813 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5814 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5815 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5816 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5817 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5818 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5819 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5820 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5821 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5822 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5823 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5824 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5825 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5826 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5827 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5828 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5829 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5830 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5831 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5832 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5833 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5834 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5835 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5836 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5837 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5838 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5839 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5840 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5841 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5842 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5843 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5844 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5845 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 5846 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 5847 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5848 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 5849 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 5850 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 5851 :
wolfSSL 16:8e0d178b1d1e 5852 : "memory", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 5853 );
wolfSSL 16:8e0d178b1d1e 5854
wolfSSL 16:8e0d178b1d1e 5855 return c;
wolfSSL 16:8e0d178b1d1e 5856 }
wolfSSL 16:8e0d178b1d1e 5857
wolfSSL 16:8e0d178b1d1e 5858 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 5859 *
wolfSSL 16:8e0d178b1d1e 5860 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 5861 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 5862 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 5863 */
wolfSSL 16:8e0d178b1d1e 5864 SP_NOINLINE static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 5865 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 5866 {
wolfSSL 16:8e0d178b1d1e 5867 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 5868
wolfSSL 16:8e0d178b1d1e 5869 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 5870 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5871 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5872 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5873 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5874 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5875 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5876 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5877 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5878 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5879 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5880 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5881 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5882 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5883 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5884 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5885 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5886 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5887 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5888 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5889 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5890 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5891 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5892 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5893 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5894 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5895 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5896 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5897 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5898 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5899 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5900 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5901 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5902 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5903 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5904 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5905 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5906 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5907 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5908 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5909 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5910 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5911 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5912 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5913 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5914 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5915 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5916 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5917 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5918 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5919 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5920 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5921 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5922 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5923 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5924 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5925 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5926 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5927 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5928 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5929 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5930 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5931 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5932 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5933 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5934 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5935 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5936 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5937 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5938 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5939 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5940 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5941 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5942 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5943 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5944 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5945 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5946 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5947 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5948 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5949 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5950 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5951 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5952 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5953 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5954 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5955 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5956 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5957 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5958 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5959 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5960 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5961 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5962 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5963 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5964 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5965 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5966 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5967 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5968 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5969 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5970 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5971 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5972 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5973 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5974 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5975 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5976 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5977 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5978 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5979 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5980 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5981 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5982 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5983 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5984 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5985 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5986 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 5987 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 5988 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 5989 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 5990 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 5991 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 5992 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 5993 :
wolfSSL 16:8e0d178b1d1e 5994 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 5995 );
wolfSSL 16:8e0d178b1d1e 5996
wolfSSL 16:8e0d178b1d1e 5997 return c;
wolfSSL 16:8e0d178b1d1e 5998 }
wolfSSL 16:8e0d178b1d1e 5999
wolfSSL 16:8e0d178b1d1e 6000 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 6001 *
wolfSSL 16:8e0d178b1d1e 6002 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6003 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6004 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 6005 */
wolfSSL 16:8e0d178b1d1e 6006 static void sp_3072_mask_24(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 6007 {
wolfSSL 16:8e0d178b1d1e 6008 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 6009 int i;
wolfSSL 16:8e0d178b1d1e 6010
wolfSSL 16:8e0d178b1d1e 6011 for (i=0; i<24; i++) {
wolfSSL 16:8e0d178b1d1e 6012 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 6013 }
wolfSSL 16:8e0d178b1d1e 6014 #else
wolfSSL 16:8e0d178b1d1e 6015 int i;
wolfSSL 16:8e0d178b1d1e 6016
wolfSSL 16:8e0d178b1d1e 6017 for (i = 0; i < 24; i += 8) {
wolfSSL 16:8e0d178b1d1e 6018 r[i+0] = a[i+0] & m;
wolfSSL 16:8e0d178b1d1e 6019 r[i+1] = a[i+1] & m;
wolfSSL 16:8e0d178b1d1e 6020 r[i+2] = a[i+2] & m;
wolfSSL 16:8e0d178b1d1e 6021 r[i+3] = a[i+3] & m;
wolfSSL 16:8e0d178b1d1e 6022 r[i+4] = a[i+4] & m;
wolfSSL 16:8e0d178b1d1e 6023 r[i+5] = a[i+5] & m;
wolfSSL 16:8e0d178b1d1e 6024 r[i+6] = a[i+6] & m;
wolfSSL 16:8e0d178b1d1e 6025 r[i+7] = a[i+7] & m;
wolfSSL 16:8e0d178b1d1e 6026 }
wolfSSL 16:8e0d178b1d1e 6027 #endif
wolfSSL 16:8e0d178b1d1e 6028 }
wolfSSL 16:8e0d178b1d1e 6029
wolfSSL 16:8e0d178b1d1e 6030 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 6031 *
wolfSSL 16:8e0d178b1d1e 6032 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6033 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6034 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 6035 */
wolfSSL 16:8e0d178b1d1e 6036 SP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 6037 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 6038 {
wolfSSL 16:8e0d178b1d1e 6039 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 6040 sp_digit z1[48];
wolfSSL 16:8e0d178b1d1e 6041 sp_digit a1[24];
wolfSSL 16:8e0d178b1d1e 6042 sp_digit b1[24];
wolfSSL 16:8e0d178b1d1e 6043 sp_digit z2[48];
wolfSSL 16:8e0d178b1d1e 6044 sp_digit u, ca, cb;
wolfSSL 16:8e0d178b1d1e 6045
wolfSSL 16:8e0d178b1d1e 6046 ca = sp_3072_add_24(a1, a, &a[24]);
wolfSSL 16:8e0d178b1d1e 6047 cb = sp_3072_add_24(b1, b, &b[24]);
wolfSSL 16:8e0d178b1d1e 6048 u = ca & cb;
wolfSSL 16:8e0d178b1d1e 6049 sp_3072_mul_24(z1, a1, b1);
wolfSSL 16:8e0d178b1d1e 6050 sp_3072_mul_24(z2, &a[24], &b[24]);
wolfSSL 16:8e0d178b1d1e 6051 sp_3072_mul_24(z0, a, b);
wolfSSL 16:8e0d178b1d1e 6052 sp_3072_mask_24(r + 48, a1, 0 - cb);
wolfSSL 16:8e0d178b1d1e 6053 sp_3072_mask_24(b1, b1, 0 - ca);
wolfSSL 16:8e0d178b1d1e 6054 u += sp_3072_add_24(r + 48, r + 48, b1);
wolfSSL 16:8e0d178b1d1e 6055 u += sp_3072_sub_in_place_48(z1, z2);
wolfSSL 16:8e0d178b1d1e 6056 u += sp_3072_sub_in_place_48(z1, z0);
wolfSSL 16:8e0d178b1d1e 6057 u += sp_3072_add_48(r + 24, r + 24, z1);
wolfSSL 16:8e0d178b1d1e 6058 r[72] = u;
wolfSSL 16:8e0d178b1d1e 6059 XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));
wolfSSL 16:8e0d178b1d1e 6060 (void)sp_3072_add_48(r + 48, r + 48, z2);
wolfSSL 16:8e0d178b1d1e 6061 }
wolfSSL 16:8e0d178b1d1e 6062
wolfSSL 16:8e0d178b1d1e 6063 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 6064 *
wolfSSL 16:8e0d178b1d1e 6065 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6066 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6067 */
wolfSSL 16:8e0d178b1d1e 6068 SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 6069 {
wolfSSL 16:8e0d178b1d1e 6070 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 6071 sp_digit z2[48];
wolfSSL 16:8e0d178b1d1e 6072 sp_digit z1[48];
wolfSSL 16:8e0d178b1d1e 6073 sp_digit a1[24];
wolfSSL 16:8e0d178b1d1e 6074 sp_digit u;
wolfSSL 16:8e0d178b1d1e 6075
wolfSSL 16:8e0d178b1d1e 6076 u = sp_3072_add_24(a1, a, &a[24]);
wolfSSL 16:8e0d178b1d1e 6077 sp_3072_sqr_24(z1, a1);
wolfSSL 16:8e0d178b1d1e 6078 sp_3072_sqr_24(z2, &a[24]);
wolfSSL 16:8e0d178b1d1e 6079 sp_3072_sqr_24(z0, a);
wolfSSL 16:8e0d178b1d1e 6080 sp_3072_mask_24(r + 48, a1, 0 - u);
wolfSSL 16:8e0d178b1d1e 6081 u += sp_3072_add_24(r + 48, r + 48, r + 48);
wolfSSL 16:8e0d178b1d1e 6082 u += sp_3072_sub_in_place_48(z1, z2);
wolfSSL 16:8e0d178b1d1e 6083 u += sp_3072_sub_in_place_48(z1, z0);
wolfSSL 16:8e0d178b1d1e 6084 u += sp_3072_add_48(r + 24, r + 24, z1);
wolfSSL 16:8e0d178b1d1e 6085 r[72] = u;
wolfSSL 16:8e0d178b1d1e 6086 XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));
wolfSSL 16:8e0d178b1d1e 6087 (void)sp_3072_add_48(r + 48, r + 48, z2);
wolfSSL 16:8e0d178b1d1e 6088 }
wolfSSL 16:8e0d178b1d1e 6089
wolfSSL 16:8e0d178b1d1e 6090 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 6091 *
wolfSSL 16:8e0d178b1d1e 6092 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6093 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6094 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 6095 */
wolfSSL 16:8e0d178b1d1e 6096 SP_NOINLINE static sp_digit sp_3072_sub_in_place_96(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 6097 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 6098 {
wolfSSL 16:8e0d178b1d1e 6099 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 6100
wolfSSL 16:8e0d178b1d1e 6101 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 6102 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6103 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6104 "subs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6105 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6106 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6107 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6108 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6109 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6110 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6111 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6112 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6113 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6114 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6115 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6116 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6117 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6118 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6119 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6120 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6121 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6122 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6123 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6124 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6125 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6126 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6127 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6128 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6129 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6130 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6131 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6132 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6133 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6134 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6135 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6136 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6137 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6138 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6139 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6140 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6141 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6142 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6143 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6144 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6145 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6146 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6147 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6148 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6149 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6150 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6151 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6152 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6153 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6154 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6155 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6156 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6157 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6158 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6159 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6160 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6161 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6162 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6163 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6164 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6165 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6166 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6167 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6168 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6169 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6170 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6171 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6172 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6173 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6174 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6175 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6176 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6177 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6178 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6179 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6180 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6181 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6182 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6183 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6184 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6185 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6186 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6187 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6188 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6189 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6190 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6191 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6192 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6193 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6194 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6195 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6196 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6197 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6198 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6199 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6200 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6201 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6202 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6203 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6204 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6205 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6206 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6207 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6208 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6209 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6210 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6211 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6212 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6213 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6214 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6215 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6216 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6217 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6218 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6219 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6220 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6221 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6222 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6223 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6224 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6225 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6226 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6227 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6228 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6229 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6230 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6231 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6232 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6233 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6234 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6235 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6236 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6237 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6238 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6239 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6240 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6241 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6242 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6243 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6244 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6245 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6246 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6247 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6248 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6249 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6250 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6251 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6252 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6253 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6254 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6255 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6256 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6257 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6258 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6259 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6260 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6261 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6262 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6263 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6264 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6265 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6266 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6267 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6268 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6269 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6270 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6271 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6272 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6273 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6274 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6275 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6276 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6277 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6278 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6279 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6280 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6281 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6282 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6283 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6284 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6285 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6286 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6287 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6288 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6289 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6290 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6291 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6292 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6293 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6294 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6295 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6296 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6297 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6298 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6299 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6300 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6301 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6302 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6303 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6304 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6305 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6306 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6307 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6308 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6309 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6310 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6311 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6312 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6313 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6314 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6315 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6316 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6317 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6318 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6319 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6320 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6321 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6322 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6323 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6324 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6325 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6326 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6327 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6328 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6329 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6330 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6331 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6332 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6333 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6334 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6335 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6336 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6337 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6338 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 6339 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6340 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6341 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 6342 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 6343 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 6344 :
wolfSSL 16:8e0d178b1d1e 6345 : "memory", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 6346 );
wolfSSL 16:8e0d178b1d1e 6347
wolfSSL 16:8e0d178b1d1e 6348 return c;
wolfSSL 16:8e0d178b1d1e 6349 }
wolfSSL 16:8e0d178b1d1e 6350
wolfSSL 16:8e0d178b1d1e 6351 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 6352 *
wolfSSL 16:8e0d178b1d1e 6353 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6354 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6355 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 6356 */
wolfSSL 16:8e0d178b1d1e 6357 SP_NOINLINE static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 6358 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 6359 {
wolfSSL 16:8e0d178b1d1e 6360 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 6361
wolfSSL 16:8e0d178b1d1e 6362 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 6363 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6364 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6365 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6366 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6367 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6368 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6369 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6370 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6371 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6372 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6373 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6374 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6375 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6376 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6377 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6378 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6379 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6380 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6381 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6382 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6383 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6384 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6385 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6386 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6387 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6388 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6389 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6390 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6391 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6392 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6393 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6394 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6395 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6396 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6397 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6398 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6399 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6400 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6401 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6402 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6403 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6404 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6405 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6406 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6407 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6408 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6409 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6410 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6411 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6412 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6413 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6414 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6415 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6416 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6417 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6418 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6419 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6420 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6421 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6422 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6423 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6424 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6425 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6426 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6427 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6428 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6429 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6430 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6431 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6432 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6433 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6434 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6435 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6436 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6437 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6438 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6439 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6440 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6441 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6442 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6443 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6444 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6445 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6446 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6447 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6448 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6449 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6450 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6451 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6452 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6453 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6454 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6455 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6456 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6457 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6458 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6459 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6460 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6461 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6462 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6463 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6464 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6465 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6466 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6467 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6468 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6469 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6470 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6471 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6472 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6473 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6474 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6475 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6476 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6477 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6478 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6479 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6480 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6481 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6482 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6483 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6484 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6485 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6486 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6487 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6488 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6489 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6490 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6491 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6492 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6493 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6494 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6495 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6496 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6497 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6498 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6499 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6500 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6501 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6502 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6503 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6504 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6505 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6506 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6507 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6508 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6509 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6510 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6511 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6512 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6513 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6514 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6515 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6516 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6517 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6518 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6519 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6520 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6521 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6522 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6523 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6524 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6525 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6526 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6527 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6528 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6529 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6530 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6531 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6532 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6533 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6534 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6535 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6536 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6537 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6538 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6539 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6540 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6541 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6542 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6543 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6544 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6545 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6546 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6547 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6548 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6549 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6550 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6551 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6552 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6553 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6554 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6555 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6556 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6557 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6558 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6559 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6560 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6561 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6562 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6563 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6564 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6565 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6566 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6567 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6568 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6569 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6570 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6571 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6572 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6573 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6574 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6575 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6576 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6577 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6578 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6579 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6580 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6581 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6582 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6583 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6584 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6585 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6586 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6587 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6588 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6589 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6590 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6591 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6592 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6593 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6594 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6595 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6596 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6597 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6598 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6599 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 6600 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6601 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6602 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 6603 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 6604 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 6605 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 6606 :
wolfSSL 16:8e0d178b1d1e 6607 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 6608 );
wolfSSL 16:8e0d178b1d1e 6609
wolfSSL 16:8e0d178b1d1e 6610 return c;
wolfSSL 16:8e0d178b1d1e 6611 }
wolfSSL 16:8e0d178b1d1e 6612
wolfSSL 16:8e0d178b1d1e 6613 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 6614 *
wolfSSL 16:8e0d178b1d1e 6615 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6616 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6617 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 6618 */
wolfSSL 16:8e0d178b1d1e 6619 static void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 6620 {
wolfSSL 16:8e0d178b1d1e 6621 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 6622 int i;
wolfSSL 16:8e0d178b1d1e 6623
wolfSSL 16:8e0d178b1d1e 6624 for (i=0; i<48; i++) {
wolfSSL 16:8e0d178b1d1e 6625 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 6626 }
wolfSSL 16:8e0d178b1d1e 6627 #else
wolfSSL 16:8e0d178b1d1e 6628 int i;
wolfSSL 16:8e0d178b1d1e 6629
wolfSSL 16:8e0d178b1d1e 6630 for (i = 0; i < 48; i += 8) {
wolfSSL 16:8e0d178b1d1e 6631 r[i+0] = a[i+0] & m;
wolfSSL 16:8e0d178b1d1e 6632 r[i+1] = a[i+1] & m;
wolfSSL 16:8e0d178b1d1e 6633 r[i+2] = a[i+2] & m;
wolfSSL 16:8e0d178b1d1e 6634 r[i+3] = a[i+3] & m;
wolfSSL 16:8e0d178b1d1e 6635 r[i+4] = a[i+4] & m;
wolfSSL 16:8e0d178b1d1e 6636 r[i+5] = a[i+5] & m;
wolfSSL 16:8e0d178b1d1e 6637 r[i+6] = a[i+6] & m;
wolfSSL 16:8e0d178b1d1e 6638 r[i+7] = a[i+7] & m;
wolfSSL 16:8e0d178b1d1e 6639 }
wolfSSL 16:8e0d178b1d1e 6640 #endif
wolfSSL 16:8e0d178b1d1e 6641 }
wolfSSL 16:8e0d178b1d1e 6642
wolfSSL 16:8e0d178b1d1e 6643 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 6644 *
wolfSSL 16:8e0d178b1d1e 6645 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6646 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6647 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 6648 */
wolfSSL 16:8e0d178b1d1e 6649 SP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 6650 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 6651 {
wolfSSL 16:8e0d178b1d1e 6652 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 6653 sp_digit z1[96];
wolfSSL 16:8e0d178b1d1e 6654 sp_digit a1[48];
wolfSSL 16:8e0d178b1d1e 6655 sp_digit b1[48];
wolfSSL 16:8e0d178b1d1e 6656 sp_digit z2[96];
wolfSSL 16:8e0d178b1d1e 6657 sp_digit u, ca, cb;
wolfSSL 16:8e0d178b1d1e 6658
wolfSSL 16:8e0d178b1d1e 6659 ca = sp_3072_add_48(a1, a, &a[48]);
wolfSSL 16:8e0d178b1d1e 6660 cb = sp_3072_add_48(b1, b, &b[48]);
wolfSSL 16:8e0d178b1d1e 6661 u = ca & cb;
wolfSSL 16:8e0d178b1d1e 6662 sp_3072_mul_48(z1, a1, b1);
wolfSSL 16:8e0d178b1d1e 6663 sp_3072_mul_48(z2, &a[48], &b[48]);
wolfSSL 16:8e0d178b1d1e 6664 sp_3072_mul_48(z0, a, b);
wolfSSL 16:8e0d178b1d1e 6665 sp_3072_mask_48(r + 96, a1, 0 - cb);
wolfSSL 16:8e0d178b1d1e 6666 sp_3072_mask_48(b1, b1, 0 - ca);
wolfSSL 16:8e0d178b1d1e 6667 u += sp_3072_add_48(r + 96, r + 96, b1);
wolfSSL 16:8e0d178b1d1e 6668 u += sp_3072_sub_in_place_96(z1, z2);
wolfSSL 16:8e0d178b1d1e 6669 u += sp_3072_sub_in_place_96(z1, z0);
wolfSSL 16:8e0d178b1d1e 6670 u += sp_3072_add_96(r + 48, r + 48, z1);
wolfSSL 16:8e0d178b1d1e 6671 r[144] = u;
wolfSSL 16:8e0d178b1d1e 6672 XMEMSET(r + 144 + 1, 0, sizeof(sp_digit) * (48 - 1));
wolfSSL 16:8e0d178b1d1e 6673 (void)sp_3072_add_96(r + 96, r + 96, z2);
wolfSSL 16:8e0d178b1d1e 6674 }
wolfSSL 16:8e0d178b1d1e 6675
wolfSSL 16:8e0d178b1d1e 6676 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 6677 *
wolfSSL 16:8e0d178b1d1e 6678 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6679 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6680 */
wolfSSL 16:8e0d178b1d1e 6681 SP_NOINLINE static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 6682 {
wolfSSL 16:8e0d178b1d1e 6683 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 6684 sp_digit z2[96];
wolfSSL 16:8e0d178b1d1e 6685 sp_digit z1[96];
wolfSSL 16:8e0d178b1d1e 6686 sp_digit a1[48];
wolfSSL 16:8e0d178b1d1e 6687 sp_digit u;
wolfSSL 16:8e0d178b1d1e 6688
wolfSSL 16:8e0d178b1d1e 6689 u = sp_3072_add_48(a1, a, &a[48]);
wolfSSL 16:8e0d178b1d1e 6690 sp_3072_sqr_48(z1, a1);
wolfSSL 16:8e0d178b1d1e 6691 sp_3072_sqr_48(z2, &a[48]);
wolfSSL 16:8e0d178b1d1e 6692 sp_3072_sqr_48(z0, a);
wolfSSL 16:8e0d178b1d1e 6693 sp_3072_mask_48(r + 96, a1, 0 - u);
wolfSSL 16:8e0d178b1d1e 6694 u += sp_3072_add_48(r + 96, r + 96, r + 96);
wolfSSL 16:8e0d178b1d1e 6695 u += sp_3072_sub_in_place_96(z1, z2);
wolfSSL 16:8e0d178b1d1e 6696 u += sp_3072_sub_in_place_96(z1, z0);
wolfSSL 16:8e0d178b1d1e 6697 u += sp_3072_add_96(r + 48, r + 48, z1);
wolfSSL 16:8e0d178b1d1e 6698 r[144] = u;
wolfSSL 16:8e0d178b1d1e 6699 XMEMSET(r + 144 + 1, 0, sizeof(sp_digit) * (48 - 1));
wolfSSL 16:8e0d178b1d1e 6700 (void)sp_3072_add_96(r + 96, r + 96, z2);
wolfSSL 16:8e0d178b1d1e 6701 }
wolfSSL 16:8e0d178b1d1e 6702
wolfSSL 16:8e0d178b1d1e 6703 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 6704 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 6705 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 6706 *
wolfSSL 16:8e0d178b1d1e 6707 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6708 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6709 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 6710 */
wolfSSL 16:8e0d178b1d1e 6711 SP_NOINLINE static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 6712 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 6713 {
wolfSSL 16:8e0d178b1d1e 6714 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 6715
wolfSSL 16:8e0d178b1d1e 6716 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 6717 "mov r6, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 6718 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 6719 "add r6, r6, #384\n\t"
wolfSSL 16:8e0d178b1d1e 6720 "sub r8, r8, #1\n\t"
wolfSSL 16:8e0d178b1d1e 6721 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 6722 "adds %[c], %[c], r8\n\t"
wolfSSL 16:8e0d178b1d1e 6723 "ldr r4, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 6724 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 6725 "adcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6726 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 6727 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 6728 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 6729 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 6730 "add %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 6731 "add %[r], %[r], #4\n\t"
wolfSSL 16:8e0d178b1d1e 6732 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 6733 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 6734 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 6735 :
wolfSSL 16:8e0d178b1d1e 6736 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 6737 );
wolfSSL 16:8e0d178b1d1e 6738
wolfSSL 16:8e0d178b1d1e 6739 return c;
wolfSSL 16:8e0d178b1d1e 6740 }
wolfSSL 16:8e0d178b1d1e 6741
wolfSSL 16:8e0d178b1d1e 6742 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 6743 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 6744 /* Sub b from a into a. (a -= b)
wolfSSL 16:8e0d178b1d1e 6745 *
wolfSSL 16:8e0d178b1d1e 6746 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6747 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 6748 */
wolfSSL 16:8e0d178b1d1e 6749 SP_NOINLINE static sp_digit sp_3072_sub_in_place_96(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 6750 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 6751 {
wolfSSL 16:8e0d178b1d1e 6752 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 6753 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 6754 "mov r8, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 6755 "add r8, r8, #384\n\t"
wolfSSL 16:8e0d178b1d1e 6756 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 6757 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 6758 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 6759 "ldr r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 6760 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 6761 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 6762 "ldr r6, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 6763 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6764 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6765 "str r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 6766 "str r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 6767 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 6768 "add %[a], %[a], #8\n\t"
wolfSSL 16:8e0d178b1d1e 6769 "add %[b], %[b], #8\n\t"
wolfSSL 16:8e0d178b1d1e 6770 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 6771 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 6772 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 6773 :
wolfSSL 16:8e0d178b1d1e 6774 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 6775 );
wolfSSL 16:8e0d178b1d1e 6776
wolfSSL 16:8e0d178b1d1e 6777 return c;
wolfSSL 16:8e0d178b1d1e 6778 }
wolfSSL 16:8e0d178b1d1e 6779
wolfSSL 16:8e0d178b1d1e 6780 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 6781 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 6782 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 6783 *
wolfSSL 16:8e0d178b1d1e 6784 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6785 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6786 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 6787 */
wolfSSL 16:8e0d178b1d1e 6788 SP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 6789 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 6790 {
wolfSSL 16:8e0d178b1d1e 6791 sp_digit tmp[96 * 2];
wolfSSL 16:8e0d178b1d1e 6792 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 6793 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 6794 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 6795 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 6796 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 6797 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 6798 "mov r11, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 6799 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 6800 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 6801 "add r6, r6, #128\n\t"
wolfSSL 16:8e0d178b1d1e 6802 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 6803 "mov r14, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6804 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 6805 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 6806 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 6807 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 6808 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 6809 "add r6, r6, #124\n\t"
wolfSSL 16:8e0d178b1d1e 6810 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 6811 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 6812 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6813 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6814 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 6815 "mov %[b], r9\n\t"
wolfSSL 16:8e0d178b1d1e 6816 "sub %[b], %[b], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 6817 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 6818 "add %[b], %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 6819 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 6820 /* Multiply Start */
wolfSSL 16:8e0d178b1d1e 6821 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 6822 "ldr r8, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 6823 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6824 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6825 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6826 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 6827 /* Multiply Done */
wolfSSL 16:8e0d178b1d1e 6828 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 6829 "sub %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 6830 "cmp %[a], r14\n\t"
wolfSSL 16:8e0d178b1d1e 6831 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 6832 "mov r6, r9\n\t"
wolfSSL 16:8e0d178b1d1e 6833 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 6834 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 6835 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 6836 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 6837 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 6838 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 6839 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 6840 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 6841 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6842 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 6843 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6844 "mov r6, #2\n\t"
wolfSSL 16:8e0d178b1d1e 6845 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 6846 "add r6, r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 6847 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6848 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 6849 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 6850 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 6851 "mov %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 6852 :
wolfSSL 16:8e0d178b1d1e 6853 : [r] "r" (tmp), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 6854 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 6855 );
wolfSSL 16:8e0d178b1d1e 6856
wolfSSL 16:8e0d178b1d1e 6857 XMEMCPY(r, tmp, sizeof(tmp));
wolfSSL 16:8e0d178b1d1e 6858 }
wolfSSL 16:8e0d178b1d1e 6859
wolfSSL 16:8e0d178b1d1e 6860 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 6861 *
wolfSSL 16:8e0d178b1d1e 6862 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6863 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6864 */
wolfSSL 16:8e0d178b1d1e 6865 SP_NOINLINE static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 6866 {
wolfSSL 16:8e0d178b1d1e 6867 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 6868 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 6869 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 6870 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 6871 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 6872 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 6873 "mov r6, #3\n\t"
wolfSSL 16:8e0d178b1d1e 6874 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 6875 "neg r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6876 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6877 "mov r11, sp\n\t"
wolfSSL 16:8e0d178b1d1e 6878 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 6879 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 6880 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 6881 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 6882 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 6883 "add r6, r6, #124\n\t"
wolfSSL 16:8e0d178b1d1e 6884 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 6885 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 6886 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6887 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6888 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 6889 "mov r2, r9\n\t"
wolfSSL 16:8e0d178b1d1e 6890 "sub r2, r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 6891 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 6892 "add r2, r2, r10\n\t"
wolfSSL 16:8e0d178b1d1e 6893 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 6894 "cmp r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 6895 "beq 4f\n\t"
wolfSSL 16:8e0d178b1d1e 6896 /* Multiply * 2: Start */
wolfSSL 16:8e0d178b1d1e 6897 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 6898 "ldr r8, [r2]\n\t"
wolfSSL 16:8e0d178b1d1e 6899 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6900 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6901 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6902 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 6903 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6904 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6905 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 6906 /* Multiply * 2: Done */
wolfSSL 16:8e0d178b1d1e 6907 "bal 5f\n\t"
wolfSSL 16:8e0d178b1d1e 6908 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 6909 /* Square: Start */
wolfSSL 16:8e0d178b1d1e 6910 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 6911 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6912 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6913 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6914 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 6915 /* Square: Done */
wolfSSL 16:8e0d178b1d1e 6916 "\n5:\n\t"
wolfSSL 16:8e0d178b1d1e 6917 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 6918 "sub r2, r2, #4\n\t"
wolfSSL 16:8e0d178b1d1e 6919 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 6920 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 6921 "add r6, r6, #128\n\t"
wolfSSL 16:8e0d178b1d1e 6922 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 6923 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 6924 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 6925 "cmp %[a], r2\n\t"
wolfSSL 16:8e0d178b1d1e 6926 "bgt 3f\n\t"
wolfSSL 16:8e0d178b1d1e 6927 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 6928 "add r8, r8, r10\n\t"
wolfSSL 16:8e0d178b1d1e 6929 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 6930 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 6931 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 6932 "mov %[r], r11\n\t"
wolfSSL 16:8e0d178b1d1e 6933 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 6934 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 6935 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 6936 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 6937 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 6938 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 6939 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 6940 "mov r6, #2\n\t"
wolfSSL 16:8e0d178b1d1e 6941 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 6942 "add r6, r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 6943 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6944 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 6945 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 6946 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 6947 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 6948 "mov %[a], r11\n\t"
wolfSSL 16:8e0d178b1d1e 6949 "mov r3, #2\n\t"
wolfSSL 16:8e0d178b1d1e 6950 "lsl r3, r3, #8\n\t"
wolfSSL 16:8e0d178b1d1e 6951 "add r3, r3, #252\n\t"
wolfSSL 16:8e0d178b1d1e 6952 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 6953 "ldr r6, [%[a], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 6954 "str r6, [%[r], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 6955 "subs r3, r3, #4\n\t"
wolfSSL 16:8e0d178b1d1e 6956 "bge 4b\n\t"
wolfSSL 16:8e0d178b1d1e 6957 "mov r6, #3\n\t"
wolfSSL 16:8e0d178b1d1e 6958 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 6959 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 6960 :
wolfSSL 16:8e0d178b1d1e 6961 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 6962 : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 6963 );
wolfSSL 16:8e0d178b1d1e 6964 }
wolfSSL 16:8e0d178b1d1e 6965
wolfSSL 16:8e0d178b1d1e 6966 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 6967 #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
wolfSSL 16:8e0d178b1d1e 6968 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 6969 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 6970 *
wolfSSL 16:8e0d178b1d1e 6971 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6972 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6973 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 6974 */
wolfSSL 16:8e0d178b1d1e 6975 static void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 6976 {
wolfSSL 16:8e0d178b1d1e 6977 int i;
wolfSSL 16:8e0d178b1d1e 6978
wolfSSL 16:8e0d178b1d1e 6979 for (i=0; i<48; i++) {
wolfSSL 16:8e0d178b1d1e 6980 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 6981 }
wolfSSL 16:8e0d178b1d1e 6982 }
wolfSSL 16:8e0d178b1d1e 6983
wolfSSL 16:8e0d178b1d1e 6984 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 6985 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 6986 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 6987 *
wolfSSL 16:8e0d178b1d1e 6988 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 6989 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 6990 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 6991 */
wolfSSL 16:8e0d178b1d1e 6992 SP_NOINLINE static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 6993 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 6994 {
wolfSSL 16:8e0d178b1d1e 6995 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 6996
wolfSSL 16:8e0d178b1d1e 6997 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 6998 "mov r6, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 6999 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7000 "add r6, r6, #192\n\t"
wolfSSL 16:8e0d178b1d1e 7001 "sub r8, r8, #1\n\t"
wolfSSL 16:8e0d178b1d1e 7002 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7003 "adds %[c], %[c], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7004 "ldr r4, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 7005 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 7006 "adcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7007 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 7008 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 7009 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 7010 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7011 "add %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7012 "add %[r], %[r], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7013 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7014 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7015 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 7016 :
wolfSSL 16:8e0d178b1d1e 7017 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 7018 );
wolfSSL 16:8e0d178b1d1e 7019
wolfSSL 16:8e0d178b1d1e 7020 return c;
wolfSSL 16:8e0d178b1d1e 7021 }
wolfSSL 16:8e0d178b1d1e 7022
wolfSSL 16:8e0d178b1d1e 7023 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 7024 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 7025 /* Sub b from a into a. (a -= b)
wolfSSL 16:8e0d178b1d1e 7026 *
wolfSSL 16:8e0d178b1d1e 7027 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 7028 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 7029 */
wolfSSL 16:8e0d178b1d1e 7030 SP_NOINLINE static sp_digit sp_3072_sub_in_place_48(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 7031 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 7032 {
wolfSSL 16:8e0d178b1d1e 7033 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 7034 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7035 "mov r8, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7036 "add r8, r8, #192\n\t"
wolfSSL 16:8e0d178b1d1e 7037 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7038 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7039 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 7040 "ldr r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 7041 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 7042 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 7043 "ldr r6, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 7044 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7045 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7046 "str r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 7047 "str r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 7048 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 7049 "add %[a], %[a], #8\n\t"
wolfSSL 16:8e0d178b1d1e 7050 "add %[b], %[b], #8\n\t"
wolfSSL 16:8e0d178b1d1e 7051 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7052 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7053 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 7054 :
wolfSSL 16:8e0d178b1d1e 7055 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 7056 );
wolfSSL 16:8e0d178b1d1e 7057
wolfSSL 16:8e0d178b1d1e 7058 return c;
wolfSSL 16:8e0d178b1d1e 7059 }
wolfSSL 16:8e0d178b1d1e 7060
wolfSSL 16:8e0d178b1d1e 7061 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 7062 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 7063 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 7064 *
wolfSSL 16:8e0d178b1d1e 7065 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 7066 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 7067 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 7068 */
wolfSSL 16:8e0d178b1d1e 7069 SP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 7070 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 7071 {
wolfSSL 16:8e0d178b1d1e 7072 sp_digit tmp[48 * 2];
wolfSSL 16:8e0d178b1d1e 7073 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7074 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7075 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7076 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 7077 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 7078 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7079 "mov r11, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 7080 "mov r6, #192\n\t"
wolfSSL 16:8e0d178b1d1e 7081 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 7082 "mov r14, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7083 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7084 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 7085 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7086 "mov r6, #188\n\t"
wolfSSL 16:8e0d178b1d1e 7087 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 7088 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7089 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7090 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7091 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7092 "mov %[b], r9\n\t"
wolfSSL 16:8e0d178b1d1e 7093 "sub %[b], %[b], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7094 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 7095 "add %[b], %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 7096 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 7097 /* Multiply Start */
wolfSSL 16:8e0d178b1d1e 7098 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 7099 "ldr r8, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 7100 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7101 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7102 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7103 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 7104 /* Multiply Done */
wolfSSL 16:8e0d178b1d1e 7105 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7106 "sub %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7107 "cmp %[a], r14\n\t"
wolfSSL 16:8e0d178b1d1e 7108 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 7109 "mov r6, r9\n\t"
wolfSSL 16:8e0d178b1d1e 7110 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 7111 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7112 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 7113 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 7114 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 7115 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 7116 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7117 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7118 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7119 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 7120 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7121 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 7122 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 7123 "add r6, r6, #120\n\t"
wolfSSL 16:8e0d178b1d1e 7124 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7125 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7126 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7127 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 7128 "mov %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 7129 :
wolfSSL 16:8e0d178b1d1e 7130 : [r] "r" (tmp), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 7131 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 7132 );
wolfSSL 16:8e0d178b1d1e 7133
wolfSSL 16:8e0d178b1d1e 7134 XMEMCPY(r, tmp, sizeof(tmp));
wolfSSL 16:8e0d178b1d1e 7135 }
wolfSSL 16:8e0d178b1d1e 7136
wolfSSL 16:8e0d178b1d1e 7137 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 7138 *
wolfSSL 16:8e0d178b1d1e 7139 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 7140 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 7141 */
wolfSSL 16:8e0d178b1d1e 7142 SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 7143 {
wolfSSL 16:8e0d178b1d1e 7144 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7145 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7146 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7147 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7148 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 7149 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 7150 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 7151 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 7152 "add r6, r6, #128\n\t"
wolfSSL 16:8e0d178b1d1e 7153 "neg r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7154 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7155 "mov r11, sp\n\t"
wolfSSL 16:8e0d178b1d1e 7156 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7157 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7158 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 7159 "mov r6, #188\n\t"
wolfSSL 16:8e0d178b1d1e 7160 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 7161 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7162 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7163 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7164 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7165 "mov r2, r9\n\t"
wolfSSL 16:8e0d178b1d1e 7166 "sub r2, r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7167 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 7168 "add r2, r2, r10\n\t"
wolfSSL 16:8e0d178b1d1e 7169 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 7170 "cmp r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7171 "beq 4f\n\t"
wolfSSL 16:8e0d178b1d1e 7172 /* Multiply * 2: Start */
wolfSSL 16:8e0d178b1d1e 7173 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 7174 "ldr r8, [r2]\n\t"
wolfSSL 16:8e0d178b1d1e 7175 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7176 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7177 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7178 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 7179 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7180 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7181 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 7182 /* Multiply * 2: Done */
wolfSSL 16:8e0d178b1d1e 7183 "bal 5f\n\t"
wolfSSL 16:8e0d178b1d1e 7184 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 7185 /* Square: Start */
wolfSSL 16:8e0d178b1d1e 7186 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 7187 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7188 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7189 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7190 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 7191 /* Square: Done */
wolfSSL 16:8e0d178b1d1e 7192 "\n5:\n\t"
wolfSSL 16:8e0d178b1d1e 7193 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7194 "sub r2, r2, #4\n\t"
wolfSSL 16:8e0d178b1d1e 7195 "mov r6, #192\n\t"
wolfSSL 16:8e0d178b1d1e 7196 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 7197 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7198 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 7199 "cmp %[a], r2\n\t"
wolfSSL 16:8e0d178b1d1e 7200 "bgt 3f\n\t"
wolfSSL 16:8e0d178b1d1e 7201 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 7202 "add r8, r8, r10\n\t"
wolfSSL 16:8e0d178b1d1e 7203 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7204 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 7205 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 7206 "mov %[r], r11\n\t"
wolfSSL 16:8e0d178b1d1e 7207 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 7208 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7209 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7210 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7211 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7212 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 7213 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7214 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 7215 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 7216 "add r6, r6, #120\n\t"
wolfSSL 16:8e0d178b1d1e 7217 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7218 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7219 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 7220 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7221 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 7222 "mov %[a], r11\n\t"
wolfSSL 16:8e0d178b1d1e 7223 "mov r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 7224 "lsl r3, r3, #8\n\t"
wolfSSL 16:8e0d178b1d1e 7225 "add r3, r3, #124\n\t"
wolfSSL 16:8e0d178b1d1e 7226 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 7227 "ldr r6, [%[a], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 7228 "str r6, [%[r], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 7229 "subs r3, r3, #4\n\t"
wolfSSL 16:8e0d178b1d1e 7230 "bge 4b\n\t"
wolfSSL 16:8e0d178b1d1e 7231 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 7232 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 7233 "add r6, r6, #128\n\t"
wolfSSL 16:8e0d178b1d1e 7234 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7235 :
wolfSSL 16:8e0d178b1d1e 7236 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 7237 : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 7238 );
wolfSSL 16:8e0d178b1d1e 7239 }
wolfSSL 16:8e0d178b1d1e 7240
wolfSSL 16:8e0d178b1d1e 7241 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 7242 #endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */
wolfSSL 16:8e0d178b1d1e 7243
wolfSSL 16:8e0d178b1d1e 7244 /* Caclulate the bottom digit of -1/a mod 2^n.
wolfSSL 16:8e0d178b1d1e 7245 *
wolfSSL 16:8e0d178b1d1e 7246 * a A single precision number.
wolfSSL 16:8e0d178b1d1e 7247 * rho Bottom word of inverse.
wolfSSL 16:8e0d178b1d1e 7248 */
wolfSSL 16:8e0d178b1d1e 7249 static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)
wolfSSL 16:8e0d178b1d1e 7250 {
wolfSSL 16:8e0d178b1d1e 7251 sp_digit x, b;
wolfSSL 16:8e0d178b1d1e 7252
wolfSSL 16:8e0d178b1d1e 7253 b = a[0];
wolfSSL 16:8e0d178b1d1e 7254 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
wolfSSL 16:8e0d178b1d1e 7255 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
wolfSSL 16:8e0d178b1d1e 7256 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
wolfSSL 16:8e0d178b1d1e 7257 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
wolfSSL 16:8e0d178b1d1e 7258
wolfSSL 16:8e0d178b1d1e 7259 /* rho = -1/m mod b */
wolfSSL 16:8e0d178b1d1e 7260 *rho = -x;
wolfSSL 16:8e0d178b1d1e 7261 }
wolfSSL 16:8e0d178b1d1e 7262
wolfSSL 16:8e0d178b1d1e 7263 /* Mul a by digit b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 7264 *
wolfSSL 16:8e0d178b1d1e 7265 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 7266 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 7267 * b A single precision digit.
wolfSSL 16:8e0d178b1d1e 7268 */
wolfSSL 16:8e0d178b1d1e 7269 SP_NOINLINE static void sp_3072_mul_d_96(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 7270 sp_digit b)
wolfSSL 16:8e0d178b1d1e 7271 {
wolfSSL 16:8e0d178b1d1e 7272 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7273 "add r9, %[a], #384\n\t"
wolfSSL 16:8e0d178b1d1e 7274 /* A[0] * B */
wolfSSL 16:8e0d178b1d1e 7275 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7276 "umull r5, r3, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 7277 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7278 "str r5, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7279 /* A[0] * B - Done */
wolfSSL 16:8e0d178b1d1e 7280 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7281 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7282 /* A[] * B */
wolfSSL 16:8e0d178b1d1e 7283 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7284 "umull r6, r8, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 7285 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7286 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7287 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7288 /* A[] * B - Done */
wolfSSL 16:8e0d178b1d1e 7289 "str r3, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7290 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7291 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7292 "cmp %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 7293 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7294 "str r3, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 7295 : [r] "+r" (r), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 7296 : [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 7297 : "memory", "r3", "r4", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 7298 );
wolfSSL 16:8e0d178b1d1e 7299 }
wolfSSL 16:8e0d178b1d1e 7300
wolfSSL 16:8e0d178b1d1e 7301 #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
wolfSSL 16:8e0d178b1d1e 7302 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 16:8e0d178b1d1e 7303 * Given m must be 3072 bits, just need to subtract.
wolfSSL 16:8e0d178b1d1e 7304 *
wolfSSL 16:8e0d178b1d1e 7305 * r A single precision number.
wolfSSL 16:8e0d178b1d1e 7306 * m A single precision number.
wolfSSL 16:8e0d178b1d1e 7307 */
wolfSSL 16:8e0d178b1d1e 7308 static void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 7309 {
wolfSSL 16:8e0d178b1d1e 7310 XMEMSET(r, 0, sizeof(sp_digit) * 48);
wolfSSL 16:8e0d178b1d1e 7311
wolfSSL 16:8e0d178b1d1e 7312 /* r = 2^n mod m */
wolfSSL 16:8e0d178b1d1e 7313 sp_3072_sub_in_place_48(r, m);
wolfSSL 16:8e0d178b1d1e 7314 }
wolfSSL 16:8e0d178b1d1e 7315
wolfSSL 16:8e0d178b1d1e 7316 /* Conditionally subtract b from a using the mask m.
wolfSSL 16:8e0d178b1d1e 7317 * m is -1 to subtract and 0 when not copying.
wolfSSL 16:8e0d178b1d1e 7318 *
wolfSSL 16:8e0d178b1d1e 7319 * r A single precision number representing condition subtract result.
wolfSSL 16:8e0d178b1d1e 7320 * a A single precision number to subtract from.
wolfSSL 16:8e0d178b1d1e 7321 * b A single precision number to subtract.
wolfSSL 16:8e0d178b1d1e 7322 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 7323 */
wolfSSL 16:8e0d178b1d1e 7324 SP_NOINLINE static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 7325 const sp_digit* b, sp_digit m)
wolfSSL 16:8e0d178b1d1e 7326 {
wolfSSL 16:8e0d178b1d1e 7327 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 7328
wolfSSL 16:8e0d178b1d1e 7329 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7330 "mov r5, #192\n\t"
wolfSSL 16:8e0d178b1d1e 7331 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7332 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7333 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7334 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7335 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 7336 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7337 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 7338 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7339 "sbcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7340 "sbcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 7341 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7342 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 7343 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 7344 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7345 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 7346 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 7347 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 7348 );
wolfSSL 16:8e0d178b1d1e 7349
wolfSSL 16:8e0d178b1d1e 7350 return c;
wolfSSL 16:8e0d178b1d1e 7351 }
wolfSSL 16:8e0d178b1d1e 7352
wolfSSL 16:8e0d178b1d1e 7353 /* Reduce the number back to 3072 bits using Montgomery reduction.
wolfSSL 16:8e0d178b1d1e 7354 *
wolfSSL 16:8e0d178b1d1e 7355 * a A single precision number to reduce in place.
wolfSSL 16:8e0d178b1d1e 7356 * m The single precision number representing the modulus.
wolfSSL 16:8e0d178b1d1e 7357 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 16:8e0d178b1d1e 7358 */
wolfSSL 16:8e0d178b1d1e 7359 SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 7360 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 7361 {
wolfSSL 16:8e0d178b1d1e 7362 sp_digit ca = 0;
wolfSSL 16:8e0d178b1d1e 7363
wolfSSL 16:8e0d178b1d1e 7364 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7365 "mov r9, %[mp]\n\t"
wolfSSL 16:8e0d178b1d1e 7366 "mov r12, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 7367 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7368 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7369 "add r11, r10, #192\n\t"
wolfSSL 16:8e0d178b1d1e 7370 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7371 /* mu = a[i] * mp */
wolfSSL 16:8e0d178b1d1e 7372 "mov %[mp], r9\n\t"
wolfSSL 16:8e0d178b1d1e 7373 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 7374 "mul %[mp], %[mp], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7375 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 7376 "add r14, r10, #184\n\t"
wolfSSL 16:8e0d178b1d1e 7377 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 7378 /* a[i+j] += m[j] * mu */
wolfSSL 16:8e0d178b1d1e 7379 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 7380 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7381 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 7382 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7383 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7384 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7385 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7386 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 7387 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7388 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7389 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7390 /* a[i+j+1] += m[j+1] * mu */
wolfSSL 16:8e0d178b1d1e 7391 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 7392 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7393 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 7394 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7395 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7396 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7397 "adc r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7398 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 7399 "adds r5, r5, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7400 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7401 "str r5, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7402 "cmp r10, r14\n\t"
wolfSSL 16:8e0d178b1d1e 7403 "blt 2b\n\t"
wolfSSL 16:8e0d178b1d1e 7404 /* a[i+46] += m[46] * mu */
wolfSSL 16:8e0d178b1d1e 7405 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 7406 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7407 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 7408 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7409 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7410 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7411 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7412 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 7413 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 7414 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7415 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7416 /* a[i+47] += m[47] * mu */
wolfSSL 16:8e0d178b1d1e 7417 "mov r4, %[ca]\n\t"
wolfSSL 16:8e0d178b1d1e 7418 "mov %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 7419 /* Multiply m[47] and mu - Start */
wolfSSL 16:8e0d178b1d1e 7420 "ldr r8, [%[m]]\n\t"
wolfSSL 16:8e0d178b1d1e 7421 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7422 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7423 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7424 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 7425 /* Multiply m[47] and mu - Done */
wolfSSL 16:8e0d178b1d1e 7426 "ldr r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 7427 "ldr r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 7428 "adds r6, r6, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7429 "adcs r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7430 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 7431 "str r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 7432 "str r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 7433 /* Next word in a */
wolfSSL 16:8e0d178b1d1e 7434 "sub r10, r10, #184\n\t"
wolfSSL 16:8e0d178b1d1e 7435 "cmp r10, r11\n\t"
wolfSSL 16:8e0d178b1d1e 7436 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7437 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 7438 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 7439 : [ca] "+r" (ca), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 7440 : [m] "r" (m), [mp] "r" (mp)
wolfSSL 16:8e0d178b1d1e 7441 : "memory", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 7442 );
wolfSSL 16:8e0d178b1d1e 7443
wolfSSL 16:8e0d178b1d1e 7444 sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - ca);
wolfSSL 16:8e0d178b1d1e 7445 }
wolfSSL 16:8e0d178b1d1e 7446
wolfSSL 16:8e0d178b1d1e 7447 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 16:8e0d178b1d1e 7448 * (r = a * b mod m)
wolfSSL 16:8e0d178b1d1e 7449 *
wolfSSL 16:8e0d178b1d1e 7450 * r Result of multiplication.
wolfSSL 16:8e0d178b1d1e 7451 * a First number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 7452 * b Second number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 7453 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 7454 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 7455 */
wolfSSL 16:8e0d178b1d1e 7456 static void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 7457 const sp_digit* m, sp_digit mp)
wolfSSL 16:8e0d178b1d1e 7458 {
wolfSSL 16:8e0d178b1d1e 7459 sp_3072_mul_48(r, a, b);
wolfSSL 16:8e0d178b1d1e 7460 sp_3072_mont_reduce_48(r, m, mp);
wolfSSL 16:8e0d178b1d1e 7461 }
wolfSSL 16:8e0d178b1d1e 7462
wolfSSL 16:8e0d178b1d1e 7463 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 16:8e0d178b1d1e 7464 *
wolfSSL 16:8e0d178b1d1e 7465 * r Result of squaring.
wolfSSL 16:8e0d178b1d1e 7466 * a Number to square in Montogmery form.
wolfSSL 16:8e0d178b1d1e 7467 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 7468 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 7469 */
wolfSSL 16:8e0d178b1d1e 7470 static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 7471 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 7472 {
wolfSSL 16:8e0d178b1d1e 7473 sp_3072_sqr_48(r, a);
wolfSSL 16:8e0d178b1d1e 7474 sp_3072_mont_reduce_48(r, m, mp);
wolfSSL 16:8e0d178b1d1e 7475 }
wolfSSL 16:8e0d178b1d1e 7476
wolfSSL 16:8e0d178b1d1e 7477 /* Mul a by digit b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 7478 *
wolfSSL 16:8e0d178b1d1e 7479 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 7480 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 7481 * b A single precision digit.
wolfSSL 16:8e0d178b1d1e 7482 */
wolfSSL 16:8e0d178b1d1e 7483 SP_NOINLINE static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 7484 sp_digit b)
wolfSSL 16:8e0d178b1d1e 7485 {
wolfSSL 16:8e0d178b1d1e 7486 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7487 "add r9, %[a], #192\n\t"
wolfSSL 16:8e0d178b1d1e 7488 /* A[0] * B */
wolfSSL 16:8e0d178b1d1e 7489 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7490 "umull r5, r3, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 7491 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7492 "str r5, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7493 /* A[0] * B - Done */
wolfSSL 16:8e0d178b1d1e 7494 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7495 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7496 /* A[] * B */
wolfSSL 16:8e0d178b1d1e 7497 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7498 "umull r6, r8, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 7499 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7500 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7501 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7502 /* A[] * B - Done */
wolfSSL 16:8e0d178b1d1e 7503 "str r3, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 7504 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7505 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7506 "cmp %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 7507 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7508 "str r3, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 7509 : [r] "+r" (r), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 7510 : [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 7511 : "memory", "r3", "r4", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 7512 );
wolfSSL 16:8e0d178b1d1e 7513 }
wolfSSL 16:8e0d178b1d1e 7514
wolfSSL 16:8e0d178b1d1e 7515 /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)
wolfSSL 16:8e0d178b1d1e 7516 *
wolfSSL 16:8e0d178b1d1e 7517 * d1 The high order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 7518 * d0 The low order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 7519 * div The dividend.
wolfSSL 16:8e0d178b1d1e 7520 * returns the result of the division.
wolfSSL 16:8e0d178b1d1e 7521 *
wolfSSL 16:8e0d178b1d1e 7522 * Note that this is an approximate div. It may give an answer 1 larger.
wolfSSL 16:8e0d178b1d1e 7523 */
wolfSSL 16:8e0d178b1d1e 7524 SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0,
wolfSSL 16:8e0d178b1d1e 7525 sp_digit div)
wolfSSL 16:8e0d178b1d1e 7526 {
wolfSSL 16:8e0d178b1d1e 7527 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 7528
wolfSSL 16:8e0d178b1d1e 7529 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7530 "lsr r6, %[div], #16\n\t"
wolfSSL 16:8e0d178b1d1e 7531 "add r6, r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 7532 "udiv r4, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7533 "lsl r8, r4, #16\n\t"
wolfSSL 16:8e0d178b1d1e 7534 "umull r4, r5, %[div], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7535 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 7536 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 7537 "udiv r5, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 7538 "lsl r4, r5, #16\n\t"
wolfSSL 16:8e0d178b1d1e 7539 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7540 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 7541 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 7542 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 7543 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 7544 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 7545 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7546 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7547 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 7548 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 7549 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 7550 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 7551 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 7552 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7553 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7554 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 7555 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 7556 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 7557 "udiv r4, %[d0], %[div]\n\t"
wolfSSL 16:8e0d178b1d1e 7558 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7559 "mov %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7560 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 7561 : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div)
wolfSSL 16:8e0d178b1d1e 7562 : "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 7563 );
wolfSSL 16:8e0d178b1d1e 7564 return r;
wolfSSL 16:8e0d178b1d1e 7565 }
wolfSSL 16:8e0d178b1d1e 7566
wolfSSL 16:8e0d178b1d1e 7567 /* Compare a with b in constant time.
wolfSSL 16:8e0d178b1d1e 7568 *
wolfSSL 16:8e0d178b1d1e 7569 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 7570 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 7571 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 16:8e0d178b1d1e 7572 * respectively.
wolfSSL 16:8e0d178b1d1e 7573 */
wolfSSL 16:8e0d178b1d1e 7574 SP_NOINLINE static int32_t sp_3072_cmp_48(const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 7575 {
wolfSSL 16:8e0d178b1d1e 7576 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 7577
wolfSSL 16:8e0d178b1d1e 7578
wolfSSL 16:8e0d178b1d1e 7579 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7580 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7581 "mvn r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 7582 "mov r6, #188\n\t"
wolfSSL 16:8e0d178b1d1e 7583 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7584 "ldr r8, [%[a], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 7585 "ldr r5, [%[b], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 7586 "and r8, r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 7587 "and r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 7588 "mov r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7589 "subs r8, r8, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7590 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7591 "add %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7592 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7593 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7594 "subs r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 7595 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7596 "sub %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 7597 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7598 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 7599 "sub r6, r6, #4\n\t"
wolfSSL 16:8e0d178b1d1e 7600 "cmp r6, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7601 "bge 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7602 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 7603 : [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 7604 : "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 7605 );
wolfSSL 16:8e0d178b1d1e 7606
wolfSSL 16:8e0d178b1d1e 7607 return r;
wolfSSL 16:8e0d178b1d1e 7608 }
wolfSSL 16:8e0d178b1d1e 7609
wolfSSL 16:8e0d178b1d1e 7610 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 7611 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 7612 *
wolfSSL 16:8e0d178b1d1e 7613 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 7614 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 7615 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 7616 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 7617 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 7618 */
wolfSSL 16:8e0d178b1d1e 7619 static WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 7620 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 7621 {
wolfSSL 16:8e0d178b1d1e 7622 sp_digit t1[96], t2[49];
wolfSSL 16:8e0d178b1d1e 7623 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 7624 int i;
wolfSSL 16:8e0d178b1d1e 7625
wolfSSL 16:8e0d178b1d1e 7626 (void)m;
wolfSSL 16:8e0d178b1d1e 7627
wolfSSL 16:8e0d178b1d1e 7628 div = d[47];
wolfSSL 16:8e0d178b1d1e 7629 XMEMCPY(t1, a, sizeof(*t1) * 2 * 48);
wolfSSL 16:8e0d178b1d1e 7630 for (i=47; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 7631 r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 7632
wolfSSL 16:8e0d178b1d1e 7633 sp_3072_mul_d_48(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 7634 t1[48 + i] += sp_3072_sub_in_place_48(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 7635 t1[48 + i] -= t2[48];
wolfSSL 16:8e0d178b1d1e 7636 sp_3072_mask_48(t2, d, t1[48 + i]);
wolfSSL 16:8e0d178b1d1e 7637 t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 7638 sp_3072_mask_48(t2, d, t1[48 + i]);
wolfSSL 16:8e0d178b1d1e 7639 t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 7640 }
wolfSSL 16:8e0d178b1d1e 7641
wolfSSL 16:8e0d178b1d1e 7642 r1 = sp_3072_cmp_48(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 7643 sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 7644
wolfSSL 16:8e0d178b1d1e 7645 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 7646 }
wolfSSL 16:8e0d178b1d1e 7647
wolfSSL 16:8e0d178b1d1e 7648 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 7649 *
wolfSSL 16:8e0d178b1d1e 7650 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 7651 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 7652 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 7653 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 7654 */
wolfSSL 16:8e0d178b1d1e 7655 static WC_INLINE int sp_3072_mod_48(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 7656 {
wolfSSL 16:8e0d178b1d1e 7657 return sp_3072_div_48(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 7658 }
wolfSSL 16:8e0d178b1d1e 7659
wolfSSL 16:8e0d178b1d1e 7660 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 7661 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 7662 *
wolfSSL 16:8e0d178b1d1e 7663 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 7664 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 7665 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 7666 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 7667 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 7668 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 7669 */
wolfSSL 16:8e0d178b1d1e 7670 static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 7671 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 7672 {
wolfSSL 16:8e0d178b1d1e 7673 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7674 sp_digit t[16][96];
wolfSSL 16:8e0d178b1d1e 7675 #else
wolfSSL 16:8e0d178b1d1e 7676 sp_digit* t[16];
wolfSSL 16:8e0d178b1d1e 7677 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 7678 #endif
wolfSSL 16:8e0d178b1d1e 7679 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 7680 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 7681 sp_digit n;
wolfSSL 16:8e0d178b1d1e 7682 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 7683 int i;
wolfSSL 16:8e0d178b1d1e 7684 int c, y;
wolfSSL 16:8e0d178b1d1e 7685 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 7686
wolfSSL 16:8e0d178b1d1e 7687 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7688 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 96, NULL,
wolfSSL 16:8e0d178b1d1e 7689 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7690 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 7691 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 7692 }
wolfSSL 16:8e0d178b1d1e 7693 #endif
wolfSSL 16:8e0d178b1d1e 7694
wolfSSL 16:8e0d178b1d1e 7695 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 7696 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7697 for (i=0; i<16; i++) {
wolfSSL 16:8e0d178b1d1e 7698 t[i] = td + i * 96;
wolfSSL 16:8e0d178b1d1e 7699 }
wolfSSL 16:8e0d178b1d1e 7700 #endif
wolfSSL 16:8e0d178b1d1e 7701 norm = t[0];
wolfSSL 16:8e0d178b1d1e 7702
wolfSSL 16:8e0d178b1d1e 7703 sp_3072_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 7704 sp_3072_mont_norm_48(norm, m);
wolfSSL 16:8e0d178b1d1e 7705
wolfSSL 16:8e0d178b1d1e 7706 XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);
wolfSSL 16:8e0d178b1d1e 7707 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 7708 err = sp_3072_mod_48(t[1] + 48, a, m);
wolfSSL 16:8e0d178b1d1e 7709 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 7710 err = sp_3072_mod_48(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 7711 }
wolfSSL 16:8e0d178b1d1e 7712 }
wolfSSL 16:8e0d178b1d1e 7713 else {
wolfSSL 16:8e0d178b1d1e 7714 XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);
wolfSSL 16:8e0d178b1d1e 7715 err = sp_3072_mod_48(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 7716 }
wolfSSL 16:8e0d178b1d1e 7717 }
wolfSSL 16:8e0d178b1d1e 7718
wolfSSL 16:8e0d178b1d1e 7719 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 7720 sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 7721 sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 7722 sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 7723 sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 7724 sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 7725 sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 7726 sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 7727 sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 7728 sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 7729 sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 7730 sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 7731 sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 7732 sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 7733 sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 7734
wolfSSL 16:8e0d178b1d1e 7735 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 7736 n = e[i--];
wolfSSL 16:8e0d178b1d1e 7737 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 7738 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 7739 c = 32;
wolfSSL 16:8e0d178b1d1e 7740 }
wolfSSL 16:8e0d178b1d1e 7741 c -= bits % 4;
wolfSSL 16:8e0d178b1d1e 7742 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 7743 c = 28;
wolfSSL 16:8e0d178b1d1e 7744 }
wolfSSL 16:8e0d178b1d1e 7745 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 7746 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 7747 XMEMCPY(r, t[y], sizeof(sp_digit) * 48);
wolfSSL 16:8e0d178b1d1e 7748 for (; i>=0 || c>=4; ) {
wolfSSL 16:8e0d178b1d1e 7749 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 7750 n = e[i--];
wolfSSL 16:8e0d178b1d1e 7751 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 7752 n <<= 4;
wolfSSL 16:8e0d178b1d1e 7753 c = 28;
wolfSSL 16:8e0d178b1d1e 7754 }
wolfSSL 16:8e0d178b1d1e 7755 else if (c < 4) {
wolfSSL 16:8e0d178b1d1e 7756 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 7757 n = e[i--];
wolfSSL 16:8e0d178b1d1e 7758 c = 4 - c;
wolfSSL 16:8e0d178b1d1e 7759 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 7760 n <<= c;
wolfSSL 16:8e0d178b1d1e 7761 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 7762 }
wolfSSL 16:8e0d178b1d1e 7763 else {
wolfSSL 16:8e0d178b1d1e 7764 y = (n >> 28) & 0xf;
wolfSSL 16:8e0d178b1d1e 7765 n <<= 4;
wolfSSL 16:8e0d178b1d1e 7766 c -= 4;
wolfSSL 16:8e0d178b1d1e 7767 }
wolfSSL 16:8e0d178b1d1e 7768
wolfSSL 16:8e0d178b1d1e 7769 sp_3072_mont_sqr_48(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 7770 sp_3072_mont_sqr_48(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 7771 sp_3072_mont_sqr_48(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 7772 sp_3072_mont_sqr_48(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 7773
wolfSSL 16:8e0d178b1d1e 7774 sp_3072_mont_mul_48(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 7775 }
wolfSSL 16:8e0d178b1d1e 7776
wolfSSL 16:8e0d178b1d1e 7777 XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);
wolfSSL 16:8e0d178b1d1e 7778 sp_3072_mont_reduce_48(r, m, mp);
wolfSSL 16:8e0d178b1d1e 7779
wolfSSL 16:8e0d178b1d1e 7780 mask = 0 - (sp_3072_cmp_48(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 7781 sp_3072_cond_sub_48(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 7782 }
wolfSSL 16:8e0d178b1d1e 7783
wolfSSL 16:8e0d178b1d1e 7784 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7785 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 7786 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7787 }
wolfSSL 16:8e0d178b1d1e 7788 #endif
wolfSSL 16:8e0d178b1d1e 7789
wolfSSL 16:8e0d178b1d1e 7790 return err;
wolfSSL 16:8e0d178b1d1e 7791 }
wolfSSL 16:8e0d178b1d1e 7792 #else
wolfSSL 16:8e0d178b1d1e 7793 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 7794 *
wolfSSL 16:8e0d178b1d1e 7795 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 7796 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 7797 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 7798 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 7799 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 7800 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 7801 */
wolfSSL 16:8e0d178b1d1e 7802 static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 7803 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 7804 {
wolfSSL 16:8e0d178b1d1e 7805 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7806 sp_digit t[32][96];
wolfSSL 16:8e0d178b1d1e 7807 #else
wolfSSL 16:8e0d178b1d1e 7808 sp_digit* t[32];
wolfSSL 16:8e0d178b1d1e 7809 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 7810 #endif
wolfSSL 16:8e0d178b1d1e 7811 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 7812 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 7813 sp_digit n;
wolfSSL 16:8e0d178b1d1e 7814 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 7815 int i;
wolfSSL 16:8e0d178b1d1e 7816 int c, y;
wolfSSL 16:8e0d178b1d1e 7817 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 7818
wolfSSL 16:8e0d178b1d1e 7819 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7820 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 96, NULL,
wolfSSL 16:8e0d178b1d1e 7821 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7822 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 7823 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 7824 }
wolfSSL 16:8e0d178b1d1e 7825 #endif
wolfSSL 16:8e0d178b1d1e 7826
wolfSSL 16:8e0d178b1d1e 7827 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 7828 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7829 for (i=0; i<32; i++) {
wolfSSL 16:8e0d178b1d1e 7830 t[i] = td + i * 96;
wolfSSL 16:8e0d178b1d1e 7831 }
wolfSSL 16:8e0d178b1d1e 7832 #endif
wolfSSL 16:8e0d178b1d1e 7833 norm = t[0];
wolfSSL 16:8e0d178b1d1e 7834
wolfSSL 16:8e0d178b1d1e 7835 sp_3072_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 7836 sp_3072_mont_norm_48(norm, m);
wolfSSL 16:8e0d178b1d1e 7837
wolfSSL 16:8e0d178b1d1e 7838 XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);
wolfSSL 16:8e0d178b1d1e 7839 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 7840 err = sp_3072_mod_48(t[1] + 48, a, m);
wolfSSL 16:8e0d178b1d1e 7841 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 7842 err = sp_3072_mod_48(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 7843 }
wolfSSL 16:8e0d178b1d1e 7844 }
wolfSSL 16:8e0d178b1d1e 7845 else {
wolfSSL 16:8e0d178b1d1e 7846 XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);
wolfSSL 16:8e0d178b1d1e 7847 err = sp_3072_mod_48(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 7848 }
wolfSSL 16:8e0d178b1d1e 7849 }
wolfSSL 16:8e0d178b1d1e 7850
wolfSSL 16:8e0d178b1d1e 7851 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 7852 sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 7853 sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 7854 sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 7855 sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 7856 sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 7857 sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 7858 sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 7859 sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 7860 sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 7861 sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 7862 sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 7863 sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 7864 sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 7865 sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 7866 sp_3072_mont_sqr_48(t[16], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 7867 sp_3072_mont_mul_48(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 7868 sp_3072_mont_sqr_48(t[18], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 7869 sp_3072_mont_mul_48(t[19], t[10], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 7870 sp_3072_mont_sqr_48(t[20], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 7871 sp_3072_mont_mul_48(t[21], t[11], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 7872 sp_3072_mont_sqr_48(t[22], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 7873 sp_3072_mont_mul_48(t[23], t[12], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 7874 sp_3072_mont_sqr_48(t[24], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 7875 sp_3072_mont_mul_48(t[25], t[13], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 7876 sp_3072_mont_sqr_48(t[26], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 7877 sp_3072_mont_mul_48(t[27], t[14], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 7878 sp_3072_mont_sqr_48(t[28], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 7879 sp_3072_mont_mul_48(t[29], t[15], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 7880 sp_3072_mont_sqr_48(t[30], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 7881 sp_3072_mont_mul_48(t[31], t[16], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 7882
wolfSSL 16:8e0d178b1d1e 7883 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 7884 n = e[i--];
wolfSSL 16:8e0d178b1d1e 7885 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 7886 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 7887 c = 32;
wolfSSL 16:8e0d178b1d1e 7888 }
wolfSSL 16:8e0d178b1d1e 7889 c -= bits % 5;
wolfSSL 16:8e0d178b1d1e 7890 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 7891 c = 27;
wolfSSL 16:8e0d178b1d1e 7892 }
wolfSSL 16:8e0d178b1d1e 7893 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 7894 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 7895 XMEMCPY(r, t[y], sizeof(sp_digit) * 48);
wolfSSL 16:8e0d178b1d1e 7896 for (; i>=0 || c>=5; ) {
wolfSSL 16:8e0d178b1d1e 7897 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 7898 n = e[i--];
wolfSSL 16:8e0d178b1d1e 7899 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 7900 n <<= 5;
wolfSSL 16:8e0d178b1d1e 7901 c = 27;
wolfSSL 16:8e0d178b1d1e 7902 }
wolfSSL 16:8e0d178b1d1e 7903 else if (c < 5) {
wolfSSL 16:8e0d178b1d1e 7904 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 7905 n = e[i--];
wolfSSL 16:8e0d178b1d1e 7906 c = 5 - c;
wolfSSL 16:8e0d178b1d1e 7907 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 7908 n <<= c;
wolfSSL 16:8e0d178b1d1e 7909 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 7910 }
wolfSSL 16:8e0d178b1d1e 7911 else {
wolfSSL 16:8e0d178b1d1e 7912 y = (n >> 27) & 0x1f;
wolfSSL 16:8e0d178b1d1e 7913 n <<= 5;
wolfSSL 16:8e0d178b1d1e 7914 c -= 5;
wolfSSL 16:8e0d178b1d1e 7915 }
wolfSSL 16:8e0d178b1d1e 7916
wolfSSL 16:8e0d178b1d1e 7917 sp_3072_mont_sqr_48(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 7918 sp_3072_mont_sqr_48(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 7919 sp_3072_mont_sqr_48(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 7920 sp_3072_mont_sqr_48(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 7921 sp_3072_mont_sqr_48(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 7922
wolfSSL 16:8e0d178b1d1e 7923 sp_3072_mont_mul_48(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 7924 }
wolfSSL 16:8e0d178b1d1e 7925
wolfSSL 16:8e0d178b1d1e 7926 XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);
wolfSSL 16:8e0d178b1d1e 7927 sp_3072_mont_reduce_48(r, m, mp);
wolfSSL 16:8e0d178b1d1e 7928
wolfSSL 16:8e0d178b1d1e 7929 mask = 0 - (sp_3072_cmp_48(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 7930 sp_3072_cond_sub_48(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 7931 }
wolfSSL 16:8e0d178b1d1e 7932
wolfSSL 16:8e0d178b1d1e 7933 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7934 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 7935 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7936 }
wolfSSL 16:8e0d178b1d1e 7937 #endif
wolfSSL 16:8e0d178b1d1e 7938
wolfSSL 16:8e0d178b1d1e 7939 return err;
wolfSSL 16:8e0d178b1d1e 7940 }
wolfSSL 16:8e0d178b1d1e 7941 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 7942
wolfSSL 16:8e0d178b1d1e 7943 #endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */
wolfSSL 16:8e0d178b1d1e 7944
wolfSSL 16:8e0d178b1d1e 7945 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 16:8e0d178b1d1e 7946 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 16:8e0d178b1d1e 7947 * Given m must be 3072 bits, just need to subtract.
wolfSSL 16:8e0d178b1d1e 7948 *
wolfSSL 16:8e0d178b1d1e 7949 * r A single precision number.
wolfSSL 16:8e0d178b1d1e 7950 * m A single precision number.
wolfSSL 16:8e0d178b1d1e 7951 */
wolfSSL 16:8e0d178b1d1e 7952 static void sp_3072_mont_norm_96(sp_digit* r, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 7953 {
wolfSSL 16:8e0d178b1d1e 7954 XMEMSET(r, 0, sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 7955
wolfSSL 16:8e0d178b1d1e 7956 /* r = 2^n mod m */
wolfSSL 16:8e0d178b1d1e 7957 sp_3072_sub_in_place_96(r, m);
wolfSSL 16:8e0d178b1d1e 7958 }
wolfSSL 16:8e0d178b1d1e 7959
wolfSSL 16:8e0d178b1d1e 7960 #endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 7961 /* Conditionally subtract b from a using the mask m.
wolfSSL 16:8e0d178b1d1e 7962 * m is -1 to subtract and 0 when not copying.
wolfSSL 16:8e0d178b1d1e 7963 *
wolfSSL 16:8e0d178b1d1e 7964 * r A single precision number representing condition subtract result.
wolfSSL 16:8e0d178b1d1e 7965 * a A single precision number to subtract from.
wolfSSL 16:8e0d178b1d1e 7966 * b A single precision number to subtract.
wolfSSL 16:8e0d178b1d1e 7967 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 7968 */
wolfSSL 16:8e0d178b1d1e 7969 SP_NOINLINE static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 7970 const sp_digit* b, sp_digit m)
wolfSSL 16:8e0d178b1d1e 7971 {
wolfSSL 16:8e0d178b1d1e 7972 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 7973
wolfSSL 16:8e0d178b1d1e 7974 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 7975 "mov r5, #1\n\t"
wolfSSL 16:8e0d178b1d1e 7976 "lsl r5, r5, #8\n\t"
wolfSSL 16:8e0d178b1d1e 7977 "add r5, r5, #128\n\t"
wolfSSL 16:8e0d178b1d1e 7978 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 7979 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7980 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 7981 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7982 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 7983 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 7984 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 7985 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7986 "sbcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 7987 "sbcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 7988 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 7989 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 7990 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 7991 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 7992 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 7993 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 7994 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 7995 );
wolfSSL 16:8e0d178b1d1e 7996
wolfSSL 16:8e0d178b1d1e 7997 return c;
wolfSSL 16:8e0d178b1d1e 7998 }
wolfSSL 16:8e0d178b1d1e 7999
wolfSSL 16:8e0d178b1d1e 8000 /* Reduce the number back to 3072 bits using Montgomery reduction.
wolfSSL 16:8e0d178b1d1e 8001 *
wolfSSL 16:8e0d178b1d1e 8002 * a A single precision number to reduce in place.
wolfSSL 16:8e0d178b1d1e 8003 * m The single precision number representing the modulus.
wolfSSL 16:8e0d178b1d1e 8004 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 16:8e0d178b1d1e 8005 */
wolfSSL 16:8e0d178b1d1e 8006 SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 8007 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 8008 {
wolfSSL 16:8e0d178b1d1e 8009 sp_digit ca = 0;
wolfSSL 16:8e0d178b1d1e 8010
wolfSSL 16:8e0d178b1d1e 8011 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 8012 "mov r9, %[mp]\n\t"
wolfSSL 16:8e0d178b1d1e 8013 "mov r12, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 8014 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 8015 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8016 "add r11, r10, #384\n\t"
wolfSSL 16:8e0d178b1d1e 8017 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 8018 /* mu = a[i] * mp */
wolfSSL 16:8e0d178b1d1e 8019 "mov %[mp], r9\n\t"
wolfSSL 16:8e0d178b1d1e 8020 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 8021 "mul %[mp], %[mp], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 8022 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 8023 "add r14, r10, #376\n\t"
wolfSSL 16:8e0d178b1d1e 8024 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 8025 /* a[i+j] += m[j] * mu */
wolfSSL 16:8e0d178b1d1e 8026 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 8027 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8028 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 8029 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 8030 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 8031 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 8032 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8033 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 8034 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 8035 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8036 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 8037 /* a[i+j+1] += m[j+1] * mu */
wolfSSL 16:8e0d178b1d1e 8038 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 8039 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8040 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 8041 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 8042 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 8043 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 8044 "adc r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8045 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 8046 "adds r5, r5, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 8047 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8048 "str r5, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 8049 "cmp r10, r14\n\t"
wolfSSL 16:8e0d178b1d1e 8050 "blt 2b\n\t"
wolfSSL 16:8e0d178b1d1e 8051 /* a[i+94] += m[94] * mu */
wolfSSL 16:8e0d178b1d1e 8052 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 8053 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8054 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 8055 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 8056 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 8057 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 8058 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8059 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 8060 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 8061 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8062 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 8063 /* a[i+95] += m[95] * mu */
wolfSSL 16:8e0d178b1d1e 8064 "mov r4, %[ca]\n\t"
wolfSSL 16:8e0d178b1d1e 8065 "mov %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 8066 /* Multiply m[95] and mu - Start */
wolfSSL 16:8e0d178b1d1e 8067 "ldr r8, [%[m]]\n\t"
wolfSSL 16:8e0d178b1d1e 8068 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 8069 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 8070 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8071 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 8072 /* Multiply m[95] and mu - Done */
wolfSSL 16:8e0d178b1d1e 8073 "ldr r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 8074 "ldr r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 8075 "adds r6, r6, r5\n\t"
wolfSSL 16:8e0d178b1d1e 8076 "adcs r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 8077 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 8078 "str r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 8079 "str r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 8080 /* Next word in a */
wolfSSL 16:8e0d178b1d1e 8081 "sub r10, r10, #376\n\t"
wolfSSL 16:8e0d178b1d1e 8082 "cmp r10, r11\n\t"
wolfSSL 16:8e0d178b1d1e 8083 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 8084 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 8085 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 8086 : [ca] "+r" (ca), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 8087 : [m] "r" (m), [mp] "r" (mp)
wolfSSL 16:8e0d178b1d1e 8088 : "memory", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 8089 );
wolfSSL 16:8e0d178b1d1e 8090
wolfSSL 16:8e0d178b1d1e 8091 sp_3072_cond_sub_96(a - 96, a, m, (sp_digit)0 - ca);
wolfSSL 16:8e0d178b1d1e 8092 }
wolfSSL 16:8e0d178b1d1e 8093
wolfSSL 16:8e0d178b1d1e 8094 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 16:8e0d178b1d1e 8095 * (r = a * b mod m)
wolfSSL 16:8e0d178b1d1e 8096 *
wolfSSL 16:8e0d178b1d1e 8097 * r Result of multiplication.
wolfSSL 16:8e0d178b1d1e 8098 * a First number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 8099 * b Second number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 8100 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 8101 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 8102 */
wolfSSL 16:8e0d178b1d1e 8103 static void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 8104 const sp_digit* m, sp_digit mp)
wolfSSL 16:8e0d178b1d1e 8105 {
wolfSSL 16:8e0d178b1d1e 8106 sp_3072_mul_96(r, a, b);
wolfSSL 16:8e0d178b1d1e 8107 sp_3072_mont_reduce_96(r, m, mp);
wolfSSL 16:8e0d178b1d1e 8108 }
wolfSSL 16:8e0d178b1d1e 8109
wolfSSL 16:8e0d178b1d1e 8110 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 16:8e0d178b1d1e 8111 *
wolfSSL 16:8e0d178b1d1e 8112 * r Result of squaring.
wolfSSL 16:8e0d178b1d1e 8113 * a Number to square in Montogmery form.
wolfSSL 16:8e0d178b1d1e 8114 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 8115 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 8116 */
wolfSSL 16:8e0d178b1d1e 8117 static void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 8118 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 8119 {
wolfSSL 16:8e0d178b1d1e 8120 sp_3072_sqr_96(r, a);
wolfSSL 16:8e0d178b1d1e 8121 sp_3072_mont_reduce_96(r, m, mp);
wolfSSL 16:8e0d178b1d1e 8122 }
wolfSSL 16:8e0d178b1d1e 8123
wolfSSL 16:8e0d178b1d1e 8124 /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)
wolfSSL 16:8e0d178b1d1e 8125 *
wolfSSL 16:8e0d178b1d1e 8126 * d1 The high order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 8127 * d0 The low order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 8128 * div The dividend.
wolfSSL 16:8e0d178b1d1e 8129 * returns the result of the division.
wolfSSL 16:8e0d178b1d1e 8130 *
wolfSSL 16:8e0d178b1d1e 8131 * Note that this is an approximate div. It may give an answer 1 larger.
wolfSSL 16:8e0d178b1d1e 8132 */
wolfSSL 16:8e0d178b1d1e 8133 SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0,
wolfSSL 16:8e0d178b1d1e 8134 sp_digit div)
wolfSSL 16:8e0d178b1d1e 8135 {
wolfSSL 16:8e0d178b1d1e 8136 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 8137
wolfSSL 16:8e0d178b1d1e 8138 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 8139 "lsr r6, %[div], #16\n\t"
wolfSSL 16:8e0d178b1d1e 8140 "add r6, r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 8141 "udiv r4, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 8142 "lsl r8, r4, #16\n\t"
wolfSSL 16:8e0d178b1d1e 8143 "umull r4, r5, %[div], r8\n\t"
wolfSSL 16:8e0d178b1d1e 8144 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 8145 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 8146 "udiv r5, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 8147 "lsl r4, r5, #16\n\t"
wolfSSL 16:8e0d178b1d1e 8148 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 8149 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 8150 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 8151 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 8152 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 8153 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 8154 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 8155 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 8156 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 8157 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 8158 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 8159 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 8160 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 8161 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 8162 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 8163 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 8164 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 8165 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 8166 "udiv r4, %[d0], %[div]\n\t"
wolfSSL 16:8e0d178b1d1e 8167 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 8168 "mov %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 8169 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 8170 : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div)
wolfSSL 16:8e0d178b1d1e 8171 : "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 8172 );
wolfSSL 16:8e0d178b1d1e 8173 return r;
wolfSSL 16:8e0d178b1d1e 8174 }
wolfSSL 16:8e0d178b1d1e 8175
wolfSSL 16:8e0d178b1d1e 8176 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 8177 *
wolfSSL 16:8e0d178b1d1e 8178 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 8179 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 8180 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 8181 */
wolfSSL 16:8e0d178b1d1e 8182 static void sp_3072_mask_96(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 8183 {
wolfSSL 16:8e0d178b1d1e 8184 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 8185 int i;
wolfSSL 16:8e0d178b1d1e 8186
wolfSSL 16:8e0d178b1d1e 8187 for (i=0; i<96; i++) {
wolfSSL 16:8e0d178b1d1e 8188 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 8189 }
wolfSSL 16:8e0d178b1d1e 8190 #else
wolfSSL 16:8e0d178b1d1e 8191 int i;
wolfSSL 16:8e0d178b1d1e 8192
wolfSSL 16:8e0d178b1d1e 8193 for (i = 0; i < 96; i += 8) {
wolfSSL 16:8e0d178b1d1e 8194 r[i+0] = a[i+0] & m;
wolfSSL 16:8e0d178b1d1e 8195 r[i+1] = a[i+1] & m;
wolfSSL 16:8e0d178b1d1e 8196 r[i+2] = a[i+2] & m;
wolfSSL 16:8e0d178b1d1e 8197 r[i+3] = a[i+3] & m;
wolfSSL 16:8e0d178b1d1e 8198 r[i+4] = a[i+4] & m;
wolfSSL 16:8e0d178b1d1e 8199 r[i+5] = a[i+5] & m;
wolfSSL 16:8e0d178b1d1e 8200 r[i+6] = a[i+6] & m;
wolfSSL 16:8e0d178b1d1e 8201 r[i+7] = a[i+7] & m;
wolfSSL 16:8e0d178b1d1e 8202 }
wolfSSL 16:8e0d178b1d1e 8203 #endif
wolfSSL 16:8e0d178b1d1e 8204 }
wolfSSL 16:8e0d178b1d1e 8205
wolfSSL 16:8e0d178b1d1e 8206 /* Compare a with b in constant time.
wolfSSL 16:8e0d178b1d1e 8207 *
wolfSSL 16:8e0d178b1d1e 8208 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 8209 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 8210 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 16:8e0d178b1d1e 8211 * respectively.
wolfSSL 16:8e0d178b1d1e 8212 */
wolfSSL 16:8e0d178b1d1e 8213 SP_NOINLINE static int32_t sp_3072_cmp_96(const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 8214 {
wolfSSL 16:8e0d178b1d1e 8215 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 8216
wolfSSL 16:8e0d178b1d1e 8217
wolfSSL 16:8e0d178b1d1e 8218 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 8219 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8220 "mvn r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 8221 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 8222 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 8223 "add r6, r6, #124\n\t"
wolfSSL 16:8e0d178b1d1e 8224 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 8225 "ldr r8, [%[a], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 8226 "ldr r5, [%[b], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 8227 "and r8, r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 8228 "and r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 8229 "mov r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8230 "subs r8, r8, r5\n\t"
wolfSSL 16:8e0d178b1d1e 8231 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8232 "add %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 8233 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8234 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8235 "subs r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 8236 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8237 "sub %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 8238 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8239 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 8240 "sub r6, r6, #4\n\t"
wolfSSL 16:8e0d178b1d1e 8241 "cmp r6, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8242 "bge 1b\n\t"
wolfSSL 16:8e0d178b1d1e 8243 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 8244 : [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 8245 : "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 8246 );
wolfSSL 16:8e0d178b1d1e 8247
wolfSSL 16:8e0d178b1d1e 8248 return r;
wolfSSL 16:8e0d178b1d1e 8249 }
wolfSSL 16:8e0d178b1d1e 8250
wolfSSL 16:8e0d178b1d1e 8251 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 8252 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 8253 *
wolfSSL 16:8e0d178b1d1e 8254 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 8255 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 8256 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 8257 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 8258 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 8259 */
wolfSSL 16:8e0d178b1d1e 8260 static WC_INLINE int sp_3072_div_96(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 8261 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 8262 {
wolfSSL 16:8e0d178b1d1e 8263 sp_digit t1[192], t2[97];
wolfSSL 16:8e0d178b1d1e 8264 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 8265 int i;
wolfSSL 16:8e0d178b1d1e 8266
wolfSSL 16:8e0d178b1d1e 8267 (void)m;
wolfSSL 16:8e0d178b1d1e 8268
wolfSSL 16:8e0d178b1d1e 8269 div = d[95];
wolfSSL 16:8e0d178b1d1e 8270 XMEMCPY(t1, a, sizeof(*t1) * 2 * 96);
wolfSSL 16:8e0d178b1d1e 8271 for (i=95; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 8272 r1 = div_3072_word_96(t1[96 + i], t1[96 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 8273
wolfSSL 16:8e0d178b1d1e 8274 sp_3072_mul_d_96(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 8275 t1[96 + i] += sp_3072_sub_in_place_96(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 8276 t1[96 + i] -= t2[96];
wolfSSL 16:8e0d178b1d1e 8277 sp_3072_mask_96(t2, d, t1[96 + i]);
wolfSSL 16:8e0d178b1d1e 8278 t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 8279 sp_3072_mask_96(t2, d, t1[96 + i]);
wolfSSL 16:8e0d178b1d1e 8280 t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 8281 }
wolfSSL 16:8e0d178b1d1e 8282
wolfSSL 16:8e0d178b1d1e 8283 r1 = sp_3072_cmp_96(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 8284 sp_3072_cond_sub_96(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 8285
wolfSSL 16:8e0d178b1d1e 8286 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 8287 }
wolfSSL 16:8e0d178b1d1e 8288
wolfSSL 16:8e0d178b1d1e 8289 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 8290 *
wolfSSL 16:8e0d178b1d1e 8291 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 8292 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 8293 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 8294 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 8295 */
wolfSSL 16:8e0d178b1d1e 8296 static WC_INLINE int sp_3072_mod_96(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 8297 {
wolfSSL 16:8e0d178b1d1e 8298 return sp_3072_div_96(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 8299 }
wolfSSL 16:8e0d178b1d1e 8300
wolfSSL 16:8e0d178b1d1e 8301 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 8302 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 8303 *
wolfSSL 16:8e0d178b1d1e 8304 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 8305 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 8306 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 8307 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 8308 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 8309 */
wolfSSL 16:8e0d178b1d1e 8310 static WC_INLINE int sp_3072_div_96_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 8311 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 8312 {
wolfSSL 16:8e0d178b1d1e 8313 sp_digit t1[192], t2[97];
wolfSSL 16:8e0d178b1d1e 8314 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 8315 int i;
wolfSSL 16:8e0d178b1d1e 8316
wolfSSL 16:8e0d178b1d1e 8317 (void)m;
wolfSSL 16:8e0d178b1d1e 8318
wolfSSL 16:8e0d178b1d1e 8319 div = d[95];
wolfSSL 16:8e0d178b1d1e 8320 XMEMCPY(t1, a, sizeof(*t1) * 2 * 96);
wolfSSL 16:8e0d178b1d1e 8321 for (i=95; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 8322 r1 = div_3072_word_96(t1[96 + i], t1[96 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 8323
wolfSSL 16:8e0d178b1d1e 8324 sp_3072_mul_d_96(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 8325 t1[96 + i] += sp_3072_sub_in_place_96(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 8326 t1[96 + i] -= t2[96];
wolfSSL 16:8e0d178b1d1e 8327 if (t1[96 + i] != 0) {
wolfSSL 16:8e0d178b1d1e 8328 t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], d);
wolfSSL 16:8e0d178b1d1e 8329 if (t1[96 + i] != 0)
wolfSSL 16:8e0d178b1d1e 8330 t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], d);
wolfSSL 16:8e0d178b1d1e 8331 }
wolfSSL 16:8e0d178b1d1e 8332 }
wolfSSL 16:8e0d178b1d1e 8333
wolfSSL 16:8e0d178b1d1e 8334 r1 = sp_3072_cmp_96(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 8335 sp_3072_cond_sub_96(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 8336
wolfSSL 16:8e0d178b1d1e 8337 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 8338 }
wolfSSL 16:8e0d178b1d1e 8339
wolfSSL 16:8e0d178b1d1e 8340 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 8341 *
wolfSSL 16:8e0d178b1d1e 8342 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 8343 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 8344 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 8345 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 8346 */
wolfSSL 16:8e0d178b1d1e 8347 static WC_INLINE int sp_3072_mod_96_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 8348 {
wolfSSL 16:8e0d178b1d1e 8349 return sp_3072_div_96_cond(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 8350 }
wolfSSL 16:8e0d178b1d1e 8351
wolfSSL 16:8e0d178b1d1e 8352 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
wolfSSL 16:8e0d178b1d1e 8353 defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 16:8e0d178b1d1e 8354 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 8355 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 8356 *
wolfSSL 16:8e0d178b1d1e 8357 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 8358 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 8359 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 8360 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 8361 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 8362 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 8363 */
wolfSSL 16:8e0d178b1d1e 8364 static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 8365 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 8366 {
wolfSSL 16:8e0d178b1d1e 8367 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8368 sp_digit t[16][192];
wolfSSL 16:8e0d178b1d1e 8369 #else
wolfSSL 16:8e0d178b1d1e 8370 sp_digit* t[16];
wolfSSL 16:8e0d178b1d1e 8371 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 8372 #endif
wolfSSL 16:8e0d178b1d1e 8373 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 8374 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 8375 sp_digit n;
wolfSSL 16:8e0d178b1d1e 8376 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 8377 int i;
wolfSSL 16:8e0d178b1d1e 8378 int c, y;
wolfSSL 16:8e0d178b1d1e 8379 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 8380
wolfSSL 16:8e0d178b1d1e 8381 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8382 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 192, NULL,
wolfSSL 16:8e0d178b1d1e 8383 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8384 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 8385 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8386 }
wolfSSL 16:8e0d178b1d1e 8387 #endif
wolfSSL 16:8e0d178b1d1e 8388
wolfSSL 16:8e0d178b1d1e 8389 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8390 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8391 for (i=0; i<16; i++) {
wolfSSL 16:8e0d178b1d1e 8392 t[i] = td + i * 192;
wolfSSL 16:8e0d178b1d1e 8393 }
wolfSSL 16:8e0d178b1d1e 8394 #endif
wolfSSL 16:8e0d178b1d1e 8395 norm = t[0];
wolfSSL 16:8e0d178b1d1e 8396
wolfSSL 16:8e0d178b1d1e 8397 sp_3072_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 8398 sp_3072_mont_norm_96(norm, m);
wolfSSL 16:8e0d178b1d1e 8399
wolfSSL 16:8e0d178b1d1e 8400 XMEMSET(t[1], 0, sizeof(sp_digit) * 96U);
wolfSSL 16:8e0d178b1d1e 8401 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 8402 err = sp_3072_mod_96(t[1] + 96, a, m);
wolfSSL 16:8e0d178b1d1e 8403 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8404 err = sp_3072_mod_96(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 8405 }
wolfSSL 16:8e0d178b1d1e 8406 }
wolfSSL 16:8e0d178b1d1e 8407 else {
wolfSSL 16:8e0d178b1d1e 8408 XMEMCPY(t[1] + 96, a, sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 8409 err = sp_3072_mod_96(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 8410 }
wolfSSL 16:8e0d178b1d1e 8411 }
wolfSSL 16:8e0d178b1d1e 8412
wolfSSL 16:8e0d178b1d1e 8413 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8414 sp_3072_mont_sqr_96(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 8415 sp_3072_mont_mul_96(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 8416 sp_3072_mont_sqr_96(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 8417 sp_3072_mont_mul_96(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 8418 sp_3072_mont_sqr_96(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 8419 sp_3072_mont_mul_96(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 8420 sp_3072_mont_sqr_96(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 8421 sp_3072_mont_mul_96(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 8422 sp_3072_mont_sqr_96(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 8423 sp_3072_mont_mul_96(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 8424 sp_3072_mont_sqr_96(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 8425 sp_3072_mont_mul_96(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 8426 sp_3072_mont_sqr_96(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 8427 sp_3072_mont_mul_96(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 8428
wolfSSL 16:8e0d178b1d1e 8429 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 8430 n = e[i--];
wolfSSL 16:8e0d178b1d1e 8431 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 8432 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 8433 c = 32;
wolfSSL 16:8e0d178b1d1e 8434 }
wolfSSL 16:8e0d178b1d1e 8435 c -= bits % 4;
wolfSSL 16:8e0d178b1d1e 8436 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 8437 c = 28;
wolfSSL 16:8e0d178b1d1e 8438 }
wolfSSL 16:8e0d178b1d1e 8439 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 8440 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 8441 XMEMCPY(r, t[y], sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 8442 for (; i>=0 || c>=4; ) {
wolfSSL 16:8e0d178b1d1e 8443 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 8444 n = e[i--];
wolfSSL 16:8e0d178b1d1e 8445 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 8446 n <<= 4;
wolfSSL 16:8e0d178b1d1e 8447 c = 28;
wolfSSL 16:8e0d178b1d1e 8448 }
wolfSSL 16:8e0d178b1d1e 8449 else if (c < 4) {
wolfSSL 16:8e0d178b1d1e 8450 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 8451 n = e[i--];
wolfSSL 16:8e0d178b1d1e 8452 c = 4 - c;
wolfSSL 16:8e0d178b1d1e 8453 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 8454 n <<= c;
wolfSSL 16:8e0d178b1d1e 8455 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 8456 }
wolfSSL 16:8e0d178b1d1e 8457 else {
wolfSSL 16:8e0d178b1d1e 8458 y = (n >> 28) & 0xf;
wolfSSL 16:8e0d178b1d1e 8459 n <<= 4;
wolfSSL 16:8e0d178b1d1e 8460 c -= 4;
wolfSSL 16:8e0d178b1d1e 8461 }
wolfSSL 16:8e0d178b1d1e 8462
wolfSSL 16:8e0d178b1d1e 8463 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8464 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8465 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8466 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8467
wolfSSL 16:8e0d178b1d1e 8468 sp_3072_mont_mul_96(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 8469 }
wolfSSL 16:8e0d178b1d1e 8470
wolfSSL 16:8e0d178b1d1e 8471 XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);
wolfSSL 16:8e0d178b1d1e 8472 sp_3072_mont_reduce_96(r, m, mp);
wolfSSL 16:8e0d178b1d1e 8473
wolfSSL 16:8e0d178b1d1e 8474 mask = 0 - (sp_3072_cmp_96(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 8475 sp_3072_cond_sub_96(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 8476 }
wolfSSL 16:8e0d178b1d1e 8477
wolfSSL 16:8e0d178b1d1e 8478 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8479 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 8480 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8481 }
wolfSSL 16:8e0d178b1d1e 8482 #endif
wolfSSL 16:8e0d178b1d1e 8483
wolfSSL 16:8e0d178b1d1e 8484 return err;
wolfSSL 16:8e0d178b1d1e 8485 }
wolfSSL 16:8e0d178b1d1e 8486 #else
wolfSSL 16:8e0d178b1d1e 8487 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 8488 *
wolfSSL 16:8e0d178b1d1e 8489 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 8490 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 8491 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 8492 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 8493 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 8494 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 8495 */
wolfSSL 16:8e0d178b1d1e 8496 static int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 8497 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 8498 {
wolfSSL 16:8e0d178b1d1e 8499 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8500 sp_digit t[32][192];
wolfSSL 16:8e0d178b1d1e 8501 #else
wolfSSL 16:8e0d178b1d1e 8502 sp_digit* t[32];
wolfSSL 16:8e0d178b1d1e 8503 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 8504 #endif
wolfSSL 16:8e0d178b1d1e 8505 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 8506 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 8507 sp_digit n;
wolfSSL 16:8e0d178b1d1e 8508 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 8509 int i;
wolfSSL 16:8e0d178b1d1e 8510 int c, y;
wolfSSL 16:8e0d178b1d1e 8511 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 8512
wolfSSL 16:8e0d178b1d1e 8513 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8514 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 192, NULL,
wolfSSL 16:8e0d178b1d1e 8515 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8516 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 8517 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8518 }
wolfSSL 16:8e0d178b1d1e 8519 #endif
wolfSSL 16:8e0d178b1d1e 8520
wolfSSL 16:8e0d178b1d1e 8521 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8522 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8523 for (i=0; i<32; i++) {
wolfSSL 16:8e0d178b1d1e 8524 t[i] = td + i * 192;
wolfSSL 16:8e0d178b1d1e 8525 }
wolfSSL 16:8e0d178b1d1e 8526 #endif
wolfSSL 16:8e0d178b1d1e 8527 norm = t[0];
wolfSSL 16:8e0d178b1d1e 8528
wolfSSL 16:8e0d178b1d1e 8529 sp_3072_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 8530 sp_3072_mont_norm_96(norm, m);
wolfSSL 16:8e0d178b1d1e 8531
wolfSSL 16:8e0d178b1d1e 8532 XMEMSET(t[1], 0, sizeof(sp_digit) * 96U);
wolfSSL 16:8e0d178b1d1e 8533 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 8534 err = sp_3072_mod_96(t[1] + 96, a, m);
wolfSSL 16:8e0d178b1d1e 8535 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8536 err = sp_3072_mod_96(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 8537 }
wolfSSL 16:8e0d178b1d1e 8538 }
wolfSSL 16:8e0d178b1d1e 8539 else {
wolfSSL 16:8e0d178b1d1e 8540 XMEMCPY(t[1] + 96, a, sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 8541 err = sp_3072_mod_96(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 8542 }
wolfSSL 16:8e0d178b1d1e 8543 }
wolfSSL 16:8e0d178b1d1e 8544
wolfSSL 16:8e0d178b1d1e 8545 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8546 sp_3072_mont_sqr_96(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 8547 sp_3072_mont_mul_96(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 8548 sp_3072_mont_sqr_96(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 8549 sp_3072_mont_mul_96(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 8550 sp_3072_mont_sqr_96(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 8551 sp_3072_mont_mul_96(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 8552 sp_3072_mont_sqr_96(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 8553 sp_3072_mont_mul_96(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 8554 sp_3072_mont_sqr_96(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 8555 sp_3072_mont_mul_96(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 8556 sp_3072_mont_sqr_96(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 8557 sp_3072_mont_mul_96(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 8558 sp_3072_mont_sqr_96(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 8559 sp_3072_mont_mul_96(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 8560 sp_3072_mont_sqr_96(t[16], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 8561 sp_3072_mont_mul_96(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 8562 sp_3072_mont_sqr_96(t[18], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 8563 sp_3072_mont_mul_96(t[19], t[10], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 8564 sp_3072_mont_sqr_96(t[20], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 8565 sp_3072_mont_mul_96(t[21], t[11], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 8566 sp_3072_mont_sqr_96(t[22], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 8567 sp_3072_mont_mul_96(t[23], t[12], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 8568 sp_3072_mont_sqr_96(t[24], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 8569 sp_3072_mont_mul_96(t[25], t[13], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 8570 sp_3072_mont_sqr_96(t[26], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 8571 sp_3072_mont_mul_96(t[27], t[14], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 8572 sp_3072_mont_sqr_96(t[28], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 8573 sp_3072_mont_mul_96(t[29], t[15], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 8574 sp_3072_mont_sqr_96(t[30], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 8575 sp_3072_mont_mul_96(t[31], t[16], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 8576
wolfSSL 16:8e0d178b1d1e 8577 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 8578 n = e[i--];
wolfSSL 16:8e0d178b1d1e 8579 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 8580 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 8581 c = 32;
wolfSSL 16:8e0d178b1d1e 8582 }
wolfSSL 16:8e0d178b1d1e 8583 c -= bits % 5;
wolfSSL 16:8e0d178b1d1e 8584 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 8585 c = 27;
wolfSSL 16:8e0d178b1d1e 8586 }
wolfSSL 16:8e0d178b1d1e 8587 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 8588 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 8589 XMEMCPY(r, t[y], sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 8590 for (; i>=0 || c>=5; ) {
wolfSSL 16:8e0d178b1d1e 8591 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 8592 n = e[i--];
wolfSSL 16:8e0d178b1d1e 8593 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 8594 n <<= 5;
wolfSSL 16:8e0d178b1d1e 8595 c = 27;
wolfSSL 16:8e0d178b1d1e 8596 }
wolfSSL 16:8e0d178b1d1e 8597 else if (c < 5) {
wolfSSL 16:8e0d178b1d1e 8598 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 8599 n = e[i--];
wolfSSL 16:8e0d178b1d1e 8600 c = 5 - c;
wolfSSL 16:8e0d178b1d1e 8601 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 8602 n <<= c;
wolfSSL 16:8e0d178b1d1e 8603 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 8604 }
wolfSSL 16:8e0d178b1d1e 8605 else {
wolfSSL 16:8e0d178b1d1e 8606 y = (n >> 27) & 0x1f;
wolfSSL 16:8e0d178b1d1e 8607 n <<= 5;
wolfSSL 16:8e0d178b1d1e 8608 c -= 5;
wolfSSL 16:8e0d178b1d1e 8609 }
wolfSSL 16:8e0d178b1d1e 8610
wolfSSL 16:8e0d178b1d1e 8611 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8612 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8613 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8614 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8615 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8616
wolfSSL 16:8e0d178b1d1e 8617 sp_3072_mont_mul_96(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 8618 }
wolfSSL 16:8e0d178b1d1e 8619
wolfSSL 16:8e0d178b1d1e 8620 XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);
wolfSSL 16:8e0d178b1d1e 8621 sp_3072_mont_reduce_96(r, m, mp);
wolfSSL 16:8e0d178b1d1e 8622
wolfSSL 16:8e0d178b1d1e 8623 mask = 0 - (sp_3072_cmp_96(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 8624 sp_3072_cond_sub_96(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 8625 }
wolfSSL 16:8e0d178b1d1e 8626
wolfSSL 16:8e0d178b1d1e 8627 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8628 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 8629 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8630 }
wolfSSL 16:8e0d178b1d1e 8631 #endif
wolfSSL 16:8e0d178b1d1e 8632
wolfSSL 16:8e0d178b1d1e 8633 return err;
wolfSSL 16:8e0d178b1d1e 8634 }
wolfSSL 16:8e0d178b1d1e 8635 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 8636 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 8637
wolfSSL 16:8e0d178b1d1e 8638 #ifdef WOLFSSL_HAVE_SP_RSA
wolfSSL 16:8e0d178b1d1e 8639 /* RSA public key operation.
wolfSSL 16:8e0d178b1d1e 8640 *
wolfSSL 16:8e0d178b1d1e 8641 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 16:8e0d178b1d1e 8642 * inLen Number of bytes in base.
wolfSSL 16:8e0d178b1d1e 8643 * em Public exponent.
wolfSSL 16:8e0d178b1d1e 8644 * mm Modulus.
wolfSSL 16:8e0d178b1d1e 8645 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 16:8e0d178b1d1e 8646 * Must be at least 384 bytes long.
wolfSSL 16:8e0d178b1d1e 8647 * outLen Number of bytes in result.
wolfSSL 16:8e0d178b1d1e 8648 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 16:8e0d178b1d1e 8649 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 16:8e0d178b1d1e 8650 */
wolfSSL 16:8e0d178b1d1e 8651 int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,
wolfSSL 16:8e0d178b1d1e 8652 byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 8653 {
wolfSSL 16:8e0d178b1d1e 8654 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 8655 sp_digit a[192], m[96], r[192];
wolfSSL 16:8e0d178b1d1e 8656 #else
wolfSSL 16:8e0d178b1d1e 8657 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 8658 sp_digit* a;
wolfSSL 16:8e0d178b1d1e 8659 sp_digit* m;
wolfSSL 16:8e0d178b1d1e 8660 sp_digit* r;
wolfSSL 16:8e0d178b1d1e 8661 #endif
wolfSSL 16:8e0d178b1d1e 8662 sp_digit *ah;
wolfSSL 16:8e0d178b1d1e 8663 sp_digit e[1];
wolfSSL 16:8e0d178b1d1e 8664 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 8665
wolfSSL 16:8e0d178b1d1e 8666 if (*outLen < 384)
wolfSSL 16:8e0d178b1d1e 8667 err = MP_TO_E;
wolfSSL 16:8e0d178b1d1e 8668 if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 384 ||
wolfSSL 16:8e0d178b1d1e 8669 mp_count_bits(mm) != 3072))
wolfSSL 16:8e0d178b1d1e 8670 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 8671
wolfSSL 16:8e0d178b1d1e 8672 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 8673 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8674 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 96 * 5, NULL,
wolfSSL 16:8e0d178b1d1e 8675 DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 8676 if (d == NULL)
wolfSSL 16:8e0d178b1d1e 8677 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8678 }
wolfSSL 16:8e0d178b1d1e 8679
wolfSSL 16:8e0d178b1d1e 8680 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8681 a = d;
wolfSSL 16:8e0d178b1d1e 8682 r = a + 96 * 2;
wolfSSL 16:8e0d178b1d1e 8683 m = r + 96 * 2;
wolfSSL 16:8e0d178b1d1e 8684 }
wolfSSL 16:8e0d178b1d1e 8685 #endif
wolfSSL 16:8e0d178b1d1e 8686
wolfSSL 16:8e0d178b1d1e 8687 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8688 ah = a + 96;
wolfSSL 16:8e0d178b1d1e 8689
wolfSSL 16:8e0d178b1d1e 8690 sp_3072_from_bin(ah, 96, in, inLen);
wolfSSL 16:8e0d178b1d1e 8691 #if DIGIT_BIT >= 32
wolfSSL 16:8e0d178b1d1e 8692 e[0] = em->dp[0];
wolfSSL 16:8e0d178b1d1e 8693 #else
wolfSSL 16:8e0d178b1d1e 8694 e[0] = em->dp[0];
wolfSSL 16:8e0d178b1d1e 8695 if (em->used > 1) {
wolfSSL 16:8e0d178b1d1e 8696 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 8697 }
wolfSSL 16:8e0d178b1d1e 8698 #endif
wolfSSL 16:8e0d178b1d1e 8699 if (e[0] == 0) {
wolfSSL 16:8e0d178b1d1e 8700 err = MP_EXPTMOD_E;
wolfSSL 16:8e0d178b1d1e 8701 }
wolfSSL 16:8e0d178b1d1e 8702 }
wolfSSL 16:8e0d178b1d1e 8703 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8704 sp_3072_from_mp(m, 96, mm);
wolfSSL 16:8e0d178b1d1e 8705
wolfSSL 16:8e0d178b1d1e 8706 if (e[0] == 0x3) {
wolfSSL 16:8e0d178b1d1e 8707 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8708 sp_3072_sqr_96(r, ah);
wolfSSL 16:8e0d178b1d1e 8709 err = sp_3072_mod_96_cond(r, r, m);
wolfSSL 16:8e0d178b1d1e 8710 }
wolfSSL 16:8e0d178b1d1e 8711 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8712 sp_3072_mul_96(r, ah, r);
wolfSSL 16:8e0d178b1d1e 8713 err = sp_3072_mod_96_cond(r, r, m);
wolfSSL 16:8e0d178b1d1e 8714 }
wolfSSL 16:8e0d178b1d1e 8715 }
wolfSSL 16:8e0d178b1d1e 8716 else {
wolfSSL 16:8e0d178b1d1e 8717 int i;
wolfSSL 16:8e0d178b1d1e 8718 sp_digit mp;
wolfSSL 16:8e0d178b1d1e 8719
wolfSSL 16:8e0d178b1d1e 8720 sp_3072_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 8721
wolfSSL 16:8e0d178b1d1e 8722 /* Convert to Montgomery form. */
wolfSSL 16:8e0d178b1d1e 8723 XMEMSET(a, 0, sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 8724 err = sp_3072_mod_96_cond(a, a, m);
wolfSSL 16:8e0d178b1d1e 8725
wolfSSL 16:8e0d178b1d1e 8726 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8727 for (i = 31; i >= 0; i--) {
wolfSSL 16:8e0d178b1d1e 8728 if (e[0] >> i) {
wolfSSL 16:8e0d178b1d1e 8729 break;
wolfSSL 16:8e0d178b1d1e 8730 }
wolfSSL 16:8e0d178b1d1e 8731 }
wolfSSL 16:8e0d178b1d1e 8732
wolfSSL 16:8e0d178b1d1e 8733 XMEMCPY(r, a, sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 8734 for (i--; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 8735 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 8736 if (((e[0] >> i) & 1) == 1) {
wolfSSL 16:8e0d178b1d1e 8737 sp_3072_mont_mul_96(r, r, a, m, mp);
wolfSSL 16:8e0d178b1d1e 8738 }
wolfSSL 16:8e0d178b1d1e 8739 }
wolfSSL 16:8e0d178b1d1e 8740 XMEMSET(&r[96], 0, sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 8741 sp_3072_mont_reduce_96(r, m, mp);
wolfSSL 16:8e0d178b1d1e 8742
wolfSSL 16:8e0d178b1d1e 8743 for (i = 95; i > 0; i--) {
wolfSSL 16:8e0d178b1d1e 8744 if (r[i] != m[i]) {
wolfSSL 16:8e0d178b1d1e 8745 break;
wolfSSL 16:8e0d178b1d1e 8746 }
wolfSSL 16:8e0d178b1d1e 8747 }
wolfSSL 16:8e0d178b1d1e 8748 if (r[i] >= m[i]) {
wolfSSL 16:8e0d178b1d1e 8749 sp_3072_sub_in_place_96(r, m);
wolfSSL 16:8e0d178b1d1e 8750 }
wolfSSL 16:8e0d178b1d1e 8751 }
wolfSSL 16:8e0d178b1d1e 8752 }
wolfSSL 16:8e0d178b1d1e 8753 }
wolfSSL 16:8e0d178b1d1e 8754
wolfSSL 16:8e0d178b1d1e 8755 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8756 sp_3072_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 8757 *outLen = 384;
wolfSSL 16:8e0d178b1d1e 8758 }
wolfSSL 16:8e0d178b1d1e 8759
wolfSSL 16:8e0d178b1d1e 8760 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 8761 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 8762 XFREE(d, NULL, DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 8763 }
wolfSSL 16:8e0d178b1d1e 8764 #endif
wolfSSL 16:8e0d178b1d1e 8765
wolfSSL 16:8e0d178b1d1e 8766 return err;
wolfSSL 16:8e0d178b1d1e 8767 }
wolfSSL 16:8e0d178b1d1e 8768
wolfSSL 16:8e0d178b1d1e 8769 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
wolfSSL 16:8e0d178b1d1e 8770 sp_digit* a;
wolfSSL 16:8e0d178b1d1e 8771 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 8772 sp_digit* m;
wolfSSL 16:8e0d178b1d1e 8773 sp_digit* r;
wolfSSL 16:8e0d178b1d1e 8774 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 8775
wolfSSL 16:8e0d178b1d1e 8776 (void)pm;
wolfSSL 16:8e0d178b1d1e 8777 (void)qm;
wolfSSL 16:8e0d178b1d1e 8778 (void)dpm;
wolfSSL 16:8e0d178b1d1e 8779 (void)dqm;
wolfSSL 16:8e0d178b1d1e 8780 (void)qim;
wolfSSL 16:8e0d178b1d1e 8781
wolfSSL 16:8e0d178b1d1e 8782 if (*outLen < 384U) {
wolfSSL 16:8e0d178b1d1e 8783 err = MP_TO_E;
wolfSSL 16:8e0d178b1d1e 8784 }
wolfSSL 16:8e0d178b1d1e 8785 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8786 if (mp_count_bits(dm) > 3072) {
wolfSSL 16:8e0d178b1d1e 8787 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 8788 }
wolfSSL 16:8e0d178b1d1e 8789 if (inLen > 384) {
wolfSSL 16:8e0d178b1d1e 8790 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 8791 }
wolfSSL 16:8e0d178b1d1e 8792 if (mp_count_bits(mm) != 3072) {
wolfSSL 16:8e0d178b1d1e 8793 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 8794 }
wolfSSL 16:8e0d178b1d1e 8795 }
wolfSSL 16:8e0d178b1d1e 8796
wolfSSL 16:8e0d178b1d1e 8797 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8798 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 96 * 4, NULL,
wolfSSL 16:8e0d178b1d1e 8799 DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 8800 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 8801 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8802 }
wolfSSL 16:8e0d178b1d1e 8803 }
wolfSSL 16:8e0d178b1d1e 8804 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8805 a = d + 96;
wolfSSL 16:8e0d178b1d1e 8806 m = a + 192;
wolfSSL 16:8e0d178b1d1e 8807 r = a;
wolfSSL 16:8e0d178b1d1e 8808
wolfSSL 16:8e0d178b1d1e 8809 sp_3072_from_bin(a, 96, in, inLen);
wolfSSL 16:8e0d178b1d1e 8810 sp_3072_from_mp(d, 96, dm);
wolfSSL 16:8e0d178b1d1e 8811 sp_3072_from_mp(m, 96, mm);
wolfSSL 16:8e0d178b1d1e 8812 err = sp_3072_mod_exp_96(r, a, d, 3072, m, 0);
wolfSSL 16:8e0d178b1d1e 8813 }
wolfSSL 16:8e0d178b1d1e 8814 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8815 sp_3072_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 8816 *outLen = 384;
wolfSSL 16:8e0d178b1d1e 8817 }
wolfSSL 16:8e0d178b1d1e 8818
wolfSSL 16:8e0d178b1d1e 8819 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 8820 XMEMSET(d, 0, sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 8821 XFREE(d, NULL, DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 8822 }
wolfSSL 16:8e0d178b1d1e 8823
wolfSSL 16:8e0d178b1d1e 8824 return err;
wolfSSL 16:8e0d178b1d1e 8825 #else
wolfSSL 16:8e0d178b1d1e 8826 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
wolfSSL 16:8e0d178b1d1e 8827 /* Conditionally add a and b using the mask m.
wolfSSL 16:8e0d178b1d1e 8828 * m is -1 to add and 0 when not.
wolfSSL 16:8e0d178b1d1e 8829 *
wolfSSL 16:8e0d178b1d1e 8830 * r A single precision number representing conditional add result.
wolfSSL 16:8e0d178b1d1e 8831 * a A single precision number to add with.
wolfSSL 16:8e0d178b1d1e 8832 * b A single precision number to add.
wolfSSL 16:8e0d178b1d1e 8833 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 8834 */
wolfSSL 16:8e0d178b1d1e 8835 SP_NOINLINE static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 8836 sp_digit m)
wolfSSL 16:8e0d178b1d1e 8837 {
wolfSSL 16:8e0d178b1d1e 8838 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 8839
wolfSSL 16:8e0d178b1d1e 8840 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 8841 "mov r5, #192\n\t"
wolfSSL 16:8e0d178b1d1e 8842 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 8843 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 8844 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 8845 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 8846 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 8847 "adds r5, %[c], #-1\n\t"
wolfSSL 16:8e0d178b1d1e 8848 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 8849 "adcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 8850 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 8851 "adcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 8852 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 8853 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 8854 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 8855 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 8856 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 8857 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 8858 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 8859 );
wolfSSL 16:8e0d178b1d1e 8860
wolfSSL 16:8e0d178b1d1e 8861 return c;
wolfSSL 16:8e0d178b1d1e 8862 }
wolfSSL 16:8e0d178b1d1e 8863
wolfSSL 16:8e0d178b1d1e 8864 /* RSA private key operation.
wolfSSL 16:8e0d178b1d1e 8865 *
wolfSSL 16:8e0d178b1d1e 8866 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 16:8e0d178b1d1e 8867 * inLen Number of bytes in base.
wolfSSL 16:8e0d178b1d1e 8868 * dm Private exponent.
wolfSSL 16:8e0d178b1d1e 8869 * pm First prime.
wolfSSL 16:8e0d178b1d1e 8870 * qm Second prime.
wolfSSL 16:8e0d178b1d1e 8871 * dpm First prime's CRT exponent.
wolfSSL 16:8e0d178b1d1e 8872 * dqm Second prime's CRT exponent.
wolfSSL 16:8e0d178b1d1e 8873 * qim Inverse of second prime mod p.
wolfSSL 16:8e0d178b1d1e 8874 * mm Modulus.
wolfSSL 16:8e0d178b1d1e 8875 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 16:8e0d178b1d1e 8876 * Must be at least 384 bytes long.
wolfSSL 16:8e0d178b1d1e 8877 * outLen Number of bytes in result.
wolfSSL 16:8e0d178b1d1e 8878 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 16:8e0d178b1d1e 8879 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 16:8e0d178b1d1e 8880 */
wolfSSL 16:8e0d178b1d1e 8881 int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,
wolfSSL 16:8e0d178b1d1e 8882 mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,
wolfSSL 16:8e0d178b1d1e 8883 byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 8884 {
wolfSSL 16:8e0d178b1d1e 8885 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 8886 sp_digit a[96 * 2];
wolfSSL 16:8e0d178b1d1e 8887 sp_digit p[48], q[48], dp[48];
wolfSSL 16:8e0d178b1d1e 8888 sp_digit tmpa[96], tmpb[96];
wolfSSL 16:8e0d178b1d1e 8889 #else
wolfSSL 16:8e0d178b1d1e 8890 sp_digit* t = NULL;
wolfSSL 16:8e0d178b1d1e 8891 sp_digit* a;
wolfSSL 16:8e0d178b1d1e 8892 sp_digit* p;
wolfSSL 16:8e0d178b1d1e 8893 sp_digit* q;
wolfSSL 16:8e0d178b1d1e 8894 sp_digit* dp;
wolfSSL 16:8e0d178b1d1e 8895 sp_digit* tmpa;
wolfSSL 16:8e0d178b1d1e 8896 sp_digit* tmpb;
wolfSSL 16:8e0d178b1d1e 8897 #endif
wolfSSL 16:8e0d178b1d1e 8898 sp_digit* r;
wolfSSL 16:8e0d178b1d1e 8899 sp_digit* qi;
wolfSSL 16:8e0d178b1d1e 8900 sp_digit* dq;
wolfSSL 16:8e0d178b1d1e 8901 sp_digit c;
wolfSSL 16:8e0d178b1d1e 8902 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 8903
wolfSSL 16:8e0d178b1d1e 8904 (void)dm;
wolfSSL 16:8e0d178b1d1e 8905 (void)mm;
wolfSSL 16:8e0d178b1d1e 8906
wolfSSL 16:8e0d178b1d1e 8907 if (*outLen < 384)
wolfSSL 16:8e0d178b1d1e 8908 err = MP_TO_E;
wolfSSL 16:8e0d178b1d1e 8909 if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))
wolfSSL 16:8e0d178b1d1e 8910 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 8911
wolfSSL 16:8e0d178b1d1e 8912 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 8913 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8914 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 48 * 11, NULL,
wolfSSL 16:8e0d178b1d1e 8915 DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 8916 if (t == NULL)
wolfSSL 16:8e0d178b1d1e 8917 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8918 }
wolfSSL 16:8e0d178b1d1e 8919 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8920 a = t;
wolfSSL 16:8e0d178b1d1e 8921 p = a + 96 * 2;
wolfSSL 16:8e0d178b1d1e 8922 q = p + 48;
wolfSSL 16:8e0d178b1d1e 8923 qi = dq = dp = q + 48;
wolfSSL 16:8e0d178b1d1e 8924 tmpa = qi + 48;
wolfSSL 16:8e0d178b1d1e 8925 tmpb = tmpa + 96;
wolfSSL 16:8e0d178b1d1e 8926
wolfSSL 16:8e0d178b1d1e 8927 r = t + 96;
wolfSSL 16:8e0d178b1d1e 8928 }
wolfSSL 16:8e0d178b1d1e 8929 #else
wolfSSL 16:8e0d178b1d1e 8930 #endif
wolfSSL 16:8e0d178b1d1e 8931
wolfSSL 16:8e0d178b1d1e 8932 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8933 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 8934 r = a;
wolfSSL 16:8e0d178b1d1e 8935 qi = dq = dp;
wolfSSL 16:8e0d178b1d1e 8936 #endif
wolfSSL 16:8e0d178b1d1e 8937 sp_3072_from_bin(a, 96, in, inLen);
wolfSSL 16:8e0d178b1d1e 8938 sp_3072_from_mp(p, 48, pm);
wolfSSL 16:8e0d178b1d1e 8939 sp_3072_from_mp(q, 48, qm);
wolfSSL 16:8e0d178b1d1e 8940 sp_3072_from_mp(dp, 48, dpm);
wolfSSL 16:8e0d178b1d1e 8941
wolfSSL 16:8e0d178b1d1e 8942 err = sp_3072_mod_exp_48(tmpa, a, dp, 1536, p, 1);
wolfSSL 16:8e0d178b1d1e 8943 }
wolfSSL 16:8e0d178b1d1e 8944 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8945 sp_3072_from_mp(dq, 48, dqm);
wolfSSL 16:8e0d178b1d1e 8946 err = sp_3072_mod_exp_48(tmpb, a, dq, 1536, q, 1);
wolfSSL 16:8e0d178b1d1e 8947 }
wolfSSL 16:8e0d178b1d1e 8948
wolfSSL 16:8e0d178b1d1e 8949 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8950 c = sp_3072_sub_in_place_48(tmpa, tmpb);
wolfSSL 16:8e0d178b1d1e 8951 c += sp_3072_cond_add_48(tmpa, tmpa, p, c);
wolfSSL 16:8e0d178b1d1e 8952 sp_3072_cond_add_48(tmpa, tmpa, p, c);
wolfSSL 16:8e0d178b1d1e 8953
wolfSSL 16:8e0d178b1d1e 8954 sp_3072_from_mp(qi, 48, qim);
wolfSSL 16:8e0d178b1d1e 8955 sp_3072_mul_48(tmpa, tmpa, qi);
wolfSSL 16:8e0d178b1d1e 8956 err = sp_3072_mod_48(tmpa, tmpa, p);
wolfSSL 16:8e0d178b1d1e 8957 }
wolfSSL 16:8e0d178b1d1e 8958
wolfSSL 16:8e0d178b1d1e 8959 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 8960 sp_3072_mul_48(tmpa, q, tmpa);
wolfSSL 16:8e0d178b1d1e 8961 XMEMSET(&tmpb[48], 0, sizeof(sp_digit) * 48);
wolfSSL 16:8e0d178b1d1e 8962 sp_3072_add_96(r, tmpb, tmpa);
wolfSSL 16:8e0d178b1d1e 8963
wolfSSL 16:8e0d178b1d1e 8964 sp_3072_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 8965 *outLen = 384;
wolfSSL 16:8e0d178b1d1e 8966 }
wolfSSL 16:8e0d178b1d1e 8967
wolfSSL 16:8e0d178b1d1e 8968 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 8969 if (t != NULL) {
wolfSSL 16:8e0d178b1d1e 8970 XMEMSET(t, 0, sizeof(sp_digit) * 48 * 11);
wolfSSL 16:8e0d178b1d1e 8971 XFREE(t, NULL, DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 8972 }
wolfSSL 16:8e0d178b1d1e 8973 #else
wolfSSL 16:8e0d178b1d1e 8974 XMEMSET(tmpa, 0, sizeof(tmpa));
wolfSSL 16:8e0d178b1d1e 8975 XMEMSET(tmpb, 0, sizeof(tmpb));
wolfSSL 16:8e0d178b1d1e 8976 XMEMSET(p, 0, sizeof(p));
wolfSSL 16:8e0d178b1d1e 8977 XMEMSET(q, 0, sizeof(q));
wolfSSL 16:8e0d178b1d1e 8978 XMEMSET(dp, 0, sizeof(dp));
wolfSSL 16:8e0d178b1d1e 8979 #endif
wolfSSL 16:8e0d178b1d1e 8980
wolfSSL 16:8e0d178b1d1e 8981 return err;
wolfSSL 16:8e0d178b1d1e 8982 }
wolfSSL 16:8e0d178b1d1e 8983 #endif /* WOLFSSL_RSA_PUBLIC_ONLY */
wolfSSL 16:8e0d178b1d1e 8984 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
wolfSSL 16:8e0d178b1d1e 8985 #endif /* WOLFSSL_HAVE_SP_RSA */
wolfSSL 16:8e0d178b1d1e 8986 #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
wolfSSL 16:8e0d178b1d1e 8987 !defined(WOLFSSL_RSA_PUBLIC_ONLY))
wolfSSL 16:8e0d178b1d1e 8988 /* Convert an array of sp_digit to an mp_int.
wolfSSL 16:8e0d178b1d1e 8989 *
wolfSSL 16:8e0d178b1d1e 8990 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 8991 * r A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 8992 */
wolfSSL 16:8e0d178b1d1e 8993 static int sp_3072_to_mp(const sp_digit* a, mp_int* r)
wolfSSL 16:8e0d178b1d1e 8994 {
wolfSSL 16:8e0d178b1d1e 8995 int err;
wolfSSL 16:8e0d178b1d1e 8996
wolfSSL 16:8e0d178b1d1e 8997 err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 16:8e0d178b1d1e 8998 if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
wolfSSL 16:8e0d178b1d1e 8999 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 9000 XMEMCPY(r->dp, a, sizeof(sp_digit) * 96);
wolfSSL 16:8e0d178b1d1e 9001 r->used = 96;
wolfSSL 16:8e0d178b1d1e 9002 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 9003 #elif DIGIT_BIT < 32
wolfSSL 16:8e0d178b1d1e 9004 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 9005
wolfSSL 16:8e0d178b1d1e 9006 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 9007 for (i = 0; i < 96; i++) {
wolfSSL 16:8e0d178b1d1e 9008 r->dp[j] |= (mp_digit)(a[i] << s);
wolfSSL 16:8e0d178b1d1e 9009 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 9010 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 9011 r->dp[++j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 9012 while (s + DIGIT_BIT <= 32) {
wolfSSL 16:8e0d178b1d1e 9013 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 9014 r->dp[j++] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 9015 if (s == SP_WORD_SIZE) {
wolfSSL 16:8e0d178b1d1e 9016 r->dp[j] = 0;
wolfSSL 16:8e0d178b1d1e 9017 }
wolfSSL 16:8e0d178b1d1e 9018 else {
wolfSSL 16:8e0d178b1d1e 9019 r->dp[j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 9020 }
wolfSSL 16:8e0d178b1d1e 9021 }
wolfSSL 16:8e0d178b1d1e 9022 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 9023 }
wolfSSL 16:8e0d178b1d1e 9024 r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 9025 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 9026 #else
wolfSSL 16:8e0d178b1d1e 9027 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 9028
wolfSSL 16:8e0d178b1d1e 9029 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 9030 for (i = 0; i < 96; i++) {
wolfSSL 16:8e0d178b1d1e 9031 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 16:8e0d178b1d1e 9032 if (s + 32 >= DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 9033 #if DIGIT_BIT != 32 && DIGIT_BIT != 64
wolfSSL 16:8e0d178b1d1e 9034 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 9035 #endif
wolfSSL 16:8e0d178b1d1e 9036 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 9037 r->dp[++j] = a[i] >> s;
wolfSSL 16:8e0d178b1d1e 9038 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 9039 }
wolfSSL 16:8e0d178b1d1e 9040 else {
wolfSSL 16:8e0d178b1d1e 9041 s += 32;
wolfSSL 16:8e0d178b1d1e 9042 }
wolfSSL 16:8e0d178b1d1e 9043 }
wolfSSL 16:8e0d178b1d1e 9044 r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 9045 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 9046 #endif
wolfSSL 16:8e0d178b1d1e 9047 }
wolfSSL 16:8e0d178b1d1e 9048
wolfSSL 16:8e0d178b1d1e 9049 return err;
wolfSSL 16:8e0d178b1d1e 9050 }
wolfSSL 16:8e0d178b1d1e 9051
wolfSSL 16:8e0d178b1d1e 9052 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 16:8e0d178b1d1e 9053 *
wolfSSL 16:8e0d178b1d1e 9054 * base Base. MP integer.
wolfSSL 16:8e0d178b1d1e 9055 * exp Exponent. MP integer.
wolfSSL 16:8e0d178b1d1e 9056 * mod Modulus. MP integer.
wolfSSL 16:8e0d178b1d1e 9057 * res Result. MP integer.
wolfSSL 16:8e0d178b1d1e 9058 * returns 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 16:8e0d178b1d1e 9059 * and MEMORY_E if memory allocation fails.
wolfSSL 16:8e0d178b1d1e 9060 */
wolfSSL 16:8e0d178b1d1e 9061 int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)
wolfSSL 16:8e0d178b1d1e 9062 {
wolfSSL 16:8e0d178b1d1e 9063 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 9064 sp_digit b[192], e[96], m[96];
wolfSSL 16:8e0d178b1d1e 9065 sp_digit* r = b;
wolfSSL 16:8e0d178b1d1e 9066 int expBits = mp_count_bits(exp);
wolfSSL 16:8e0d178b1d1e 9067
wolfSSL 16:8e0d178b1d1e 9068 if (mp_count_bits(base) > 3072) {
wolfSSL 16:8e0d178b1d1e 9069 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 9070 }
wolfSSL 16:8e0d178b1d1e 9071
wolfSSL 16:8e0d178b1d1e 9072 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9073 if (expBits > 3072) {
wolfSSL 16:8e0d178b1d1e 9074 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 9075 }
wolfSSL 16:8e0d178b1d1e 9076 }
wolfSSL 16:8e0d178b1d1e 9077
wolfSSL 16:8e0d178b1d1e 9078 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9079 if (mp_count_bits(mod) != 3072) {
wolfSSL 16:8e0d178b1d1e 9080 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 9081 }
wolfSSL 16:8e0d178b1d1e 9082 }
wolfSSL 16:8e0d178b1d1e 9083
wolfSSL 16:8e0d178b1d1e 9084 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9085 sp_3072_from_mp(b, 96, base);
wolfSSL 16:8e0d178b1d1e 9086 sp_3072_from_mp(e, 96, exp);
wolfSSL 16:8e0d178b1d1e 9087 sp_3072_from_mp(m, 96, mod);
wolfSSL 16:8e0d178b1d1e 9088
wolfSSL 16:8e0d178b1d1e 9089 err = sp_3072_mod_exp_96(r, b, e, expBits, m, 0);
wolfSSL 16:8e0d178b1d1e 9090 }
wolfSSL 16:8e0d178b1d1e 9091
wolfSSL 16:8e0d178b1d1e 9092 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9093 err = sp_3072_to_mp(r, res);
wolfSSL 16:8e0d178b1d1e 9094 }
wolfSSL 16:8e0d178b1d1e 9095
wolfSSL 16:8e0d178b1d1e 9096 XMEMSET(e, 0, sizeof(e));
wolfSSL 16:8e0d178b1d1e 9097
wolfSSL 16:8e0d178b1d1e 9098 return err;
wolfSSL 16:8e0d178b1d1e 9099 }
wolfSSL 16:8e0d178b1d1e 9100
wolfSSL 16:8e0d178b1d1e 9101 #ifdef WOLFSSL_HAVE_SP_DH
wolfSSL 16:8e0d178b1d1e 9102
wolfSSL 16:8e0d178b1d1e 9103 #ifdef HAVE_FFDHE_3072
wolfSSL 16:8e0d178b1d1e 9104 static void sp_3072_lshift_96(sp_digit* r, sp_digit* a, byte n)
wolfSSL 16:8e0d178b1d1e 9105 {
wolfSSL 16:8e0d178b1d1e 9106 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 9107 "mov r6, #31\n\t"
wolfSSL 16:8e0d178b1d1e 9108 "sub r6, r6, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9109 "add %[a], %[a], #320\n\t"
wolfSSL 16:8e0d178b1d1e 9110 "add %[r], %[r], #320\n\t"
wolfSSL 16:8e0d178b1d1e 9111 "ldr r3, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9112 "lsr r4, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9113 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9114 "lsr r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9115 "ldr r2, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9116 "str r4, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 9117 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9118 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9119 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9120 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9121 "ldr r4, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9122 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9123 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9124 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9125 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9126 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9127 "ldr r3, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9128 "str r2, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9129 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9130 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9131 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9132 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9133 "ldr r2, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9134 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9135 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9136 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9137 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9138 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9139 "ldr r4, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9140 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9141 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9142 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9143 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9144 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9145 "ldr r3, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9146 "str r2, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9147 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9148 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9149 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9150 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9151 "ldr r2, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9152 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9153 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9154 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9155 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9156 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9157 "ldr r4, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9158 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9159 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9160 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9161 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9162 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9163 "ldr r3, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9164 "str r2, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9165 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9166 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9167 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9168 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9169 "ldr r2, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9170 "str r4, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9171 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9172 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9173 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9174 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9175 "ldr r4, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9176 "str r3, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9177 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9178 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9179 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9180 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9181 "ldr r3, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9182 "str r2, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9183 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9184 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9185 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9186 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9187 "ldr r2, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9188 "str r4, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9189 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9190 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9191 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9192 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9193 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 9194 "str r3, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9195 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9196 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9197 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9198 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9199 "ldr r3, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 9200 "str r2, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9201 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9202 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9203 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9204 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9205 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9206 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9207 "ldr r2, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9208 "str r4, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 9209 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9210 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9211 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9212 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9213 "ldr r4, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9214 "str r3, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 9215 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9216 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9217 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9218 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9219 "ldr r3, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9220 "str r2, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9221 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9222 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9223 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9224 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9225 "ldr r2, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9226 "str r4, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9227 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9228 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9229 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9230 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9231 "ldr r4, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9232 "str r3, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9233 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9234 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9235 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9236 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9237 "ldr r3, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9238 "str r2, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9239 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9240 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9241 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9242 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9243 "ldr r2, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9244 "str r4, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9245 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9246 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9247 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9248 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9249 "ldr r4, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9250 "str r3, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9251 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9252 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9253 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9254 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9255 "ldr r3, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9256 "str r2, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9257 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9258 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9259 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9260 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9261 "ldr r2, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9262 "str r4, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9263 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9264 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9265 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9266 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9267 "ldr r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9268 "str r3, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9269 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9270 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9271 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9272 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9273 "ldr r3, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9274 "str r2, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9275 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9276 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9277 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9278 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9279 "ldr r2, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9280 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9281 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9282 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9283 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9284 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9285 "ldr r4, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9286 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9287 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9288 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9289 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9290 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9291 "ldr r3, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 9292 "str r2, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9293 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9294 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9295 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9296 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9297 "ldr r2, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 9298 "str r4, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9299 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9300 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9301 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9302 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9303 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9304 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9305 "ldr r4, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9306 "str r3, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 9307 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9308 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9309 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9310 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9311 "ldr r3, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9312 "str r2, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 9313 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9314 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9315 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9316 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9317 "ldr r2, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9318 "str r4, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9319 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9320 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9321 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9322 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9323 "ldr r4, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9324 "str r3, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9325 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9326 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9327 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9328 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9329 "ldr r3, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9330 "str r2, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9331 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9332 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9333 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9334 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9335 "ldr r2, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9336 "str r4, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9337 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9338 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9339 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9340 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9341 "ldr r4, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9342 "str r3, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9343 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9344 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9345 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9346 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9347 "ldr r3, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9348 "str r2, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9349 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9350 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9351 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9352 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9353 "ldr r2, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9354 "str r4, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9355 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9356 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9357 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9358 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9359 "ldr r4, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9360 "str r3, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9361 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9362 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9363 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9364 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9365 "ldr r3, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9366 "str r2, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9367 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9368 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9369 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9370 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9371 "ldr r2, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9372 "str r4, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9373 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9374 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9375 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9376 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9377 "ldr r4, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9378 "str r3, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9379 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9380 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9381 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9382 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9383 "ldr r3, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9384 "str r2, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9385 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9386 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9387 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9388 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9389 "ldr r2, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 9390 "str r4, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9391 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9392 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9393 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9394 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9395 "ldr r4, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 9396 "str r3, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9397 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9398 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9399 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9400 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9401 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9402 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9403 "ldr r3, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9404 "str r2, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 9405 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9406 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9407 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9408 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9409 "ldr r2, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9410 "str r4, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 9411 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9412 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9413 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9414 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9415 "ldr r4, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9416 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9417 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9418 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9419 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9420 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9421 "ldr r3, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9422 "str r2, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9423 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9424 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9425 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9426 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9427 "ldr r2, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9428 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9429 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9430 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9431 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9432 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9433 "ldr r4, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9434 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9435 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9436 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9437 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9438 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9439 "ldr r3, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9440 "str r2, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9441 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9442 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9443 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9444 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9445 "ldr r2, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9446 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9447 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9448 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9449 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9450 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9451 "ldr r4, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9452 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9453 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9454 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9455 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9456 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9457 "ldr r3, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9458 "str r2, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9459 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9460 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9461 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9462 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9463 "ldr r2, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9464 "str r4, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9465 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9466 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9467 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9468 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9469 "ldr r4, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9470 "str r3, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9471 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9472 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9473 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9474 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9475 "ldr r3, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9476 "str r2, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9477 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9478 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9479 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9480 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9481 "ldr r2, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9482 "str r4, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9483 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9484 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9485 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9486 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9487 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 9488 "str r3, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9489 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9490 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9491 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9492 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9493 "ldr r3, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 9494 "str r2, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9495 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9496 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9497 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9498 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9499 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9500 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9501 "ldr r2, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9502 "str r4, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 9503 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9504 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9505 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9506 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9507 "ldr r4, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9508 "str r3, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 9509 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9510 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9511 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9512 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9513 "ldr r3, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9514 "str r2, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9515 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9516 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9517 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9518 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9519 "ldr r2, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9520 "str r4, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9521 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9522 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9523 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9524 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9525 "ldr r4, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9526 "str r3, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9527 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9528 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9529 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9530 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9531 "ldr r3, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9532 "str r2, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9533 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9534 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9535 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9536 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9537 "ldr r2, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9538 "str r4, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9539 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9540 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9541 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9542 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9543 "ldr r4, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9544 "str r3, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9545 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9546 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9547 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9548 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9549 "ldr r3, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9550 "str r2, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9551 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9552 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9553 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9554 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9555 "ldr r2, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9556 "str r4, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9557 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9558 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9559 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9560 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9561 "ldr r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9562 "str r3, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9563 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9564 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9565 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9566 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9567 "ldr r3, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9568 "str r2, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9569 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9570 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9571 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9572 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9573 "ldr r2, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9574 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9575 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9576 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9577 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9578 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9579 "ldr r4, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9580 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9581 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9582 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9583 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9584 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9585 "ldr r3, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 9586 "str r2, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9587 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9588 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9589 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9590 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9591 "ldr r2, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 9592 "str r4, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9593 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9594 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9595 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9596 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9597 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9598 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 9599 "ldr r4, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9600 "str r3, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 9601 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9602 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9603 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9604 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9605 "ldr r3, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9606 "str r2, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 9607 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9608 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9609 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9610 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9611 "ldr r2, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9612 "str r4, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 9613 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9614 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9615 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9616 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9617 "ldr r4, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9618 "str r3, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 9619 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9620 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9621 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9622 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9623 "ldr r3, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9624 "str r2, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 9625 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9626 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9627 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9628 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9629 "ldr r2, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9630 "str r4, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 9631 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9632 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9633 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9634 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9635 "ldr r4, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9636 "str r3, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 9637 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9638 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9639 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9640 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9641 "ldr r3, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9642 "str r2, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 9643 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9644 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9645 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9646 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9647 "ldr r2, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9648 "str r4, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 9649 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9650 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9651 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9652 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9653 "ldr r4, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9654 "str r3, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 9655 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9656 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9657 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9658 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9659 "ldr r3, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9660 "str r2, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 9661 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9662 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9663 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9664 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9665 "ldr r2, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9666 "str r4, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 9667 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9668 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9669 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9670 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9671 "ldr r4, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9672 "str r3, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 9673 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9674 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9675 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9676 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9677 "ldr r3, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9678 "str r2, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 9679 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9680 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9681 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9682 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9683 "ldr r2, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 9684 "str r4, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 9685 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9686 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9687 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9688 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9689 "ldr r4, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 9690 "str r3, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 9691 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 9692 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 9693 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 9694 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 9695 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 9696 "str r2, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 9697 :
wolfSSL 16:8e0d178b1d1e 9698 : [r] "r" (r), [a] "r" (a), [n] "r" (n)
wolfSSL 16:8e0d178b1d1e 9699 : "memory", "r2", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 9700 );
wolfSSL 16:8e0d178b1d1e 9701 }
wolfSSL 16:8e0d178b1d1e 9702
wolfSSL 16:8e0d178b1d1e 9703 /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
wolfSSL 16:8e0d178b1d1e 9704 *
wolfSSL 16:8e0d178b1d1e 9705 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 9706 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 9707 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 9708 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 9709 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 9710 */
wolfSSL 16:8e0d178b1d1e 9711 static int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits,
wolfSSL 16:8e0d178b1d1e 9712 const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 9713 {
wolfSSL 16:8e0d178b1d1e 9714 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9715 sp_digit nd[192];
wolfSSL 16:8e0d178b1d1e 9716 sp_digit td[97];
wolfSSL 16:8e0d178b1d1e 9717 #else
wolfSSL 16:8e0d178b1d1e 9718 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 9719 #endif
wolfSSL 16:8e0d178b1d1e 9720 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 9721 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 9722 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 9723 sp_digit n, o;
wolfSSL 16:8e0d178b1d1e 9724 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 9725 int i;
wolfSSL 16:8e0d178b1d1e 9726 int c, y;
wolfSSL 16:8e0d178b1d1e 9727 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 9728
wolfSSL 16:8e0d178b1d1e 9729 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9730 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 289, NULL,
wolfSSL 16:8e0d178b1d1e 9731 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 9732 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 9733 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 9734 }
wolfSSL 16:8e0d178b1d1e 9735 #endif
wolfSSL 16:8e0d178b1d1e 9736
wolfSSL 16:8e0d178b1d1e 9737 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9738 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9739 norm = td;
wolfSSL 16:8e0d178b1d1e 9740 tmp = td + 192;
wolfSSL 16:8e0d178b1d1e 9741 #else
wolfSSL 16:8e0d178b1d1e 9742 norm = nd;
wolfSSL 16:8e0d178b1d1e 9743 tmp = td;
wolfSSL 16:8e0d178b1d1e 9744 #endif
wolfSSL 16:8e0d178b1d1e 9745
wolfSSL 16:8e0d178b1d1e 9746 sp_3072_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 9747 sp_3072_mont_norm_96(norm, m);
wolfSSL 16:8e0d178b1d1e 9748
wolfSSL 16:8e0d178b1d1e 9749 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 9750 n = e[i--];
wolfSSL 16:8e0d178b1d1e 9751 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 9752 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 9753 c = 32;
wolfSSL 16:8e0d178b1d1e 9754 }
wolfSSL 16:8e0d178b1d1e 9755 c -= bits % 5;
wolfSSL 16:8e0d178b1d1e 9756 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 9757 c = 27;
wolfSSL 16:8e0d178b1d1e 9758 }
wolfSSL 16:8e0d178b1d1e 9759 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 9760 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 9761 sp_3072_lshift_96(r, norm, y);
wolfSSL 16:8e0d178b1d1e 9762 for (; i>=0 || c>=5; ) {
wolfSSL 16:8e0d178b1d1e 9763 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 9764 n = e[i--];
wolfSSL 16:8e0d178b1d1e 9765 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 9766 n <<= 5;
wolfSSL 16:8e0d178b1d1e 9767 c = 27;
wolfSSL 16:8e0d178b1d1e 9768 }
wolfSSL 16:8e0d178b1d1e 9769 else if (c < 5) {
wolfSSL 16:8e0d178b1d1e 9770 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 9771 n = e[i--];
wolfSSL 16:8e0d178b1d1e 9772 c = 5 - c;
wolfSSL 16:8e0d178b1d1e 9773 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 9774 n <<= c;
wolfSSL 16:8e0d178b1d1e 9775 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 9776 }
wolfSSL 16:8e0d178b1d1e 9777 else {
wolfSSL 16:8e0d178b1d1e 9778 y = (n >> 27) & 0x1f;
wolfSSL 16:8e0d178b1d1e 9779 n <<= 5;
wolfSSL 16:8e0d178b1d1e 9780 c -= 5;
wolfSSL 16:8e0d178b1d1e 9781 }
wolfSSL 16:8e0d178b1d1e 9782
wolfSSL 16:8e0d178b1d1e 9783 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 9784 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 9785 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 9786 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 9787 sp_3072_mont_sqr_96(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 9788
wolfSSL 16:8e0d178b1d1e 9789 sp_3072_lshift_96(r, r, y);
wolfSSL 16:8e0d178b1d1e 9790 sp_3072_mul_d_96(tmp, norm, r[96]);
wolfSSL 16:8e0d178b1d1e 9791 r[96] = 0;
wolfSSL 16:8e0d178b1d1e 9792 o = sp_3072_add_96(r, r, tmp);
wolfSSL 16:8e0d178b1d1e 9793 sp_3072_cond_sub_96(r, r, m, (sp_digit)0 - o);
wolfSSL 16:8e0d178b1d1e 9794 }
wolfSSL 16:8e0d178b1d1e 9795
wolfSSL 16:8e0d178b1d1e 9796 XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);
wolfSSL 16:8e0d178b1d1e 9797 sp_3072_mont_reduce_96(r, m, mp);
wolfSSL 16:8e0d178b1d1e 9798
wolfSSL 16:8e0d178b1d1e 9799 mask = 0 - (sp_3072_cmp_96(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 9800 sp_3072_cond_sub_96(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 9801 }
wolfSSL 16:8e0d178b1d1e 9802
wolfSSL 16:8e0d178b1d1e 9803 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9804 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 9805 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 9806 }
wolfSSL 16:8e0d178b1d1e 9807 #endif
wolfSSL 16:8e0d178b1d1e 9808
wolfSSL 16:8e0d178b1d1e 9809 return err;
wolfSSL 16:8e0d178b1d1e 9810 }
wolfSSL 16:8e0d178b1d1e 9811 #endif /* HAVE_FFDHE_3072 */
wolfSSL 16:8e0d178b1d1e 9812
wolfSSL 16:8e0d178b1d1e 9813 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 16:8e0d178b1d1e 9814 *
wolfSSL 16:8e0d178b1d1e 9815 * base Base.
wolfSSL 16:8e0d178b1d1e 9816 * exp Array of bytes that is the exponent.
wolfSSL 16:8e0d178b1d1e 9817 * expLen Length of data, in bytes, in exponent.
wolfSSL 16:8e0d178b1d1e 9818 * mod Modulus.
wolfSSL 16:8e0d178b1d1e 9819 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 16:8e0d178b1d1e 9820 * Must be at least 384 bytes long.
wolfSSL 16:8e0d178b1d1e 9821 * outLen Length, in bytes, of exponentiation result.
wolfSSL 16:8e0d178b1d1e 9822 * returns 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 16:8e0d178b1d1e 9823 * and MEMORY_E if memory allocation fails.
wolfSSL 16:8e0d178b1d1e 9824 */
wolfSSL 16:8e0d178b1d1e 9825 int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,
wolfSSL 16:8e0d178b1d1e 9826 mp_int* mod, byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 9827 {
wolfSSL 16:8e0d178b1d1e 9828 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 9829 sp_digit b[192], e[96], m[96];
wolfSSL 16:8e0d178b1d1e 9830 sp_digit* r = b;
wolfSSL 16:8e0d178b1d1e 9831 word32 i;
wolfSSL 16:8e0d178b1d1e 9832
wolfSSL 16:8e0d178b1d1e 9833 if (mp_count_bits(base) > 3072) {
wolfSSL 16:8e0d178b1d1e 9834 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 9835 }
wolfSSL 16:8e0d178b1d1e 9836
wolfSSL 16:8e0d178b1d1e 9837 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9838 if (expLen > 384) {
wolfSSL 16:8e0d178b1d1e 9839 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 9840 }
wolfSSL 16:8e0d178b1d1e 9841 }
wolfSSL 16:8e0d178b1d1e 9842
wolfSSL 16:8e0d178b1d1e 9843 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9844 if (mp_count_bits(mod) != 3072) {
wolfSSL 16:8e0d178b1d1e 9845 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 9846 }
wolfSSL 16:8e0d178b1d1e 9847 }
wolfSSL 16:8e0d178b1d1e 9848
wolfSSL 16:8e0d178b1d1e 9849 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9850 sp_3072_from_mp(b, 96, base);
wolfSSL 16:8e0d178b1d1e 9851 sp_3072_from_bin(e, 96, exp, expLen);
wolfSSL 16:8e0d178b1d1e 9852 sp_3072_from_mp(m, 96, mod);
wolfSSL 16:8e0d178b1d1e 9853
wolfSSL 16:8e0d178b1d1e 9854 #ifdef HAVE_FFDHE_3072
wolfSSL 16:8e0d178b1d1e 9855 if (base->used == 1 && base->dp[0] == 2 && m[95] == (sp_digit)-1)
wolfSSL 16:8e0d178b1d1e 9856 err = sp_3072_mod_exp_2_96(r, e, expLen * 8, m);
wolfSSL 16:8e0d178b1d1e 9857 else
wolfSSL 16:8e0d178b1d1e 9858 #endif
wolfSSL 16:8e0d178b1d1e 9859 err = sp_3072_mod_exp_96(r, b, e, expLen * 8, m, 0);
wolfSSL 16:8e0d178b1d1e 9860
wolfSSL 16:8e0d178b1d1e 9861 }
wolfSSL 16:8e0d178b1d1e 9862
wolfSSL 16:8e0d178b1d1e 9863 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9864 sp_3072_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 9865 *outLen = 384;
wolfSSL 16:8e0d178b1d1e 9866 for (i=0; i<384 && out[i] == 0; i++) {
wolfSSL 16:8e0d178b1d1e 9867 }
wolfSSL 16:8e0d178b1d1e 9868 *outLen -= i;
wolfSSL 16:8e0d178b1d1e 9869 XMEMMOVE(out, out + i, *outLen);
wolfSSL 16:8e0d178b1d1e 9870
wolfSSL 16:8e0d178b1d1e 9871 }
wolfSSL 16:8e0d178b1d1e 9872
wolfSSL 16:8e0d178b1d1e 9873 XMEMSET(e, 0, sizeof(e));
wolfSSL 16:8e0d178b1d1e 9874
wolfSSL 16:8e0d178b1d1e 9875 return err;
wolfSSL 16:8e0d178b1d1e 9876 }
wolfSSL 16:8e0d178b1d1e 9877 #endif /* WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 9878
wolfSSL 16:8e0d178b1d1e 9879 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 16:8e0d178b1d1e 9880 *
wolfSSL 16:8e0d178b1d1e 9881 * base Base. MP integer.
wolfSSL 16:8e0d178b1d1e 9882 * exp Exponent. MP integer.
wolfSSL 16:8e0d178b1d1e 9883 * mod Modulus. MP integer.
wolfSSL 16:8e0d178b1d1e 9884 * res Result. MP integer.
wolfSSL 16:8e0d178b1d1e 9885 * returns 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 16:8e0d178b1d1e 9886 * and MEMORY_E if memory allocation fails.
wolfSSL 16:8e0d178b1d1e 9887 */
wolfSSL 16:8e0d178b1d1e 9888 int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)
wolfSSL 16:8e0d178b1d1e 9889 {
wolfSSL 16:8e0d178b1d1e 9890 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 9891 sp_digit b[96], e[48], m[48];
wolfSSL 16:8e0d178b1d1e 9892 sp_digit* r = b;
wolfSSL 16:8e0d178b1d1e 9893 int expBits = mp_count_bits(exp);
wolfSSL 16:8e0d178b1d1e 9894
wolfSSL 16:8e0d178b1d1e 9895 if (mp_count_bits(base) > 1536) {
wolfSSL 16:8e0d178b1d1e 9896 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 9897 }
wolfSSL 16:8e0d178b1d1e 9898
wolfSSL 16:8e0d178b1d1e 9899 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9900 if (expBits > 1536) {
wolfSSL 16:8e0d178b1d1e 9901 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 9902 }
wolfSSL 16:8e0d178b1d1e 9903 }
wolfSSL 16:8e0d178b1d1e 9904
wolfSSL 16:8e0d178b1d1e 9905 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9906 if (mp_count_bits(mod) != 1536) {
wolfSSL 16:8e0d178b1d1e 9907 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 9908 }
wolfSSL 16:8e0d178b1d1e 9909 }
wolfSSL 16:8e0d178b1d1e 9910
wolfSSL 16:8e0d178b1d1e 9911 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9912 sp_3072_from_mp(b, 48, base);
wolfSSL 16:8e0d178b1d1e 9913 sp_3072_from_mp(e, 48, exp);
wolfSSL 16:8e0d178b1d1e 9914 sp_3072_from_mp(m, 48, mod);
wolfSSL 16:8e0d178b1d1e 9915
wolfSSL 16:8e0d178b1d1e 9916 err = sp_3072_mod_exp_48(r, b, e, expBits, m, 0);
wolfSSL 16:8e0d178b1d1e 9917 }
wolfSSL 16:8e0d178b1d1e 9918
wolfSSL 16:8e0d178b1d1e 9919 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 9920 XMEMSET(r + 48, 0, sizeof(*r) * 48U);
wolfSSL 16:8e0d178b1d1e 9921 err = sp_3072_to_mp(r, res);
wolfSSL 16:8e0d178b1d1e 9922 res->used = mod->used;
wolfSSL 16:8e0d178b1d1e 9923 mp_clamp(res);
wolfSSL 16:8e0d178b1d1e 9924 }
wolfSSL 16:8e0d178b1d1e 9925
wolfSSL 16:8e0d178b1d1e 9926 XMEMSET(e, 0, sizeof(e));
wolfSSL 16:8e0d178b1d1e 9927
wolfSSL 16:8e0d178b1d1e 9928 return err;
wolfSSL 16:8e0d178b1d1e 9929 }
wolfSSL 16:8e0d178b1d1e 9930
wolfSSL 16:8e0d178b1d1e 9931 #endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */
wolfSSL 16:8e0d178b1d1e 9932
wolfSSL 16:8e0d178b1d1e 9933 #endif /* !WOLFSSL_SP_NO_3072 */
wolfSSL 16:8e0d178b1d1e 9934
wolfSSL 16:8e0d178b1d1e 9935 #ifdef WOLFSSL_SP_4096
wolfSSL 16:8e0d178b1d1e 9936 /* Read big endian unsigned byte array into r.
wolfSSL 16:8e0d178b1d1e 9937 *
wolfSSL 16:8e0d178b1d1e 9938 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 9939 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 9940 * a Byte array.
wolfSSL 16:8e0d178b1d1e 9941 * n Number of bytes in array to read.
wolfSSL 16:8e0d178b1d1e 9942 */
wolfSSL 16:8e0d178b1d1e 9943 static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)
wolfSSL 16:8e0d178b1d1e 9944 {
wolfSSL 16:8e0d178b1d1e 9945 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 9946 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 9947
wolfSSL 16:8e0d178b1d1e 9948 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 9949 for (i = n-1; i >= 0; i--) {
wolfSSL 16:8e0d178b1d1e 9950 r[j] |= (((sp_digit)a[i]) << s);
wolfSSL 16:8e0d178b1d1e 9951 if (s >= 24U) {
wolfSSL 16:8e0d178b1d1e 9952 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 9953 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 9954 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 9955 break;
wolfSSL 16:8e0d178b1d1e 9956 }
wolfSSL 16:8e0d178b1d1e 9957 r[++j] = (sp_digit)a[i] >> s;
wolfSSL 16:8e0d178b1d1e 9958 s = 8U - s;
wolfSSL 16:8e0d178b1d1e 9959 }
wolfSSL 16:8e0d178b1d1e 9960 else {
wolfSSL 16:8e0d178b1d1e 9961 s += 8U;
wolfSSL 16:8e0d178b1d1e 9962 }
wolfSSL 16:8e0d178b1d1e 9963 }
wolfSSL 16:8e0d178b1d1e 9964
wolfSSL 16:8e0d178b1d1e 9965 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 9966 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 9967 }
wolfSSL 16:8e0d178b1d1e 9968 }
wolfSSL 16:8e0d178b1d1e 9969
wolfSSL 16:8e0d178b1d1e 9970 /* Convert an mp_int to an array of sp_digit.
wolfSSL 16:8e0d178b1d1e 9971 *
wolfSSL 16:8e0d178b1d1e 9972 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 9973 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 9974 * a A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 9975 */
wolfSSL 16:8e0d178b1d1e 9976 static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)
wolfSSL 16:8e0d178b1d1e 9977 {
wolfSSL 16:8e0d178b1d1e 9978 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 9979 int j;
wolfSSL 16:8e0d178b1d1e 9980
wolfSSL 16:8e0d178b1d1e 9981 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 16:8e0d178b1d1e 9982
wolfSSL 16:8e0d178b1d1e 9983 for (j = a->used; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 9984 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 9985 }
wolfSSL 16:8e0d178b1d1e 9986 #elif DIGIT_BIT > 32
wolfSSL 16:8e0d178b1d1e 9987 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 9988 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 9989
wolfSSL 16:8e0d178b1d1e 9990 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 9991 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 9992 r[j] |= ((sp_digit)a->dp[i] << s);
wolfSSL 16:8e0d178b1d1e 9993 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 9994 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 9995 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 9996 break;
wolfSSL 16:8e0d178b1d1e 9997 }
wolfSSL 16:8e0d178b1d1e 9998 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 9999 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 10000 while ((s + 32U) <= (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 10001 s += 32U;
wolfSSL 16:8e0d178b1d1e 10002 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 10003 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 10004 break;
wolfSSL 16:8e0d178b1d1e 10005 }
wolfSSL 16:8e0d178b1d1e 10006 if (s < (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 10007 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 10008 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 10009 }
wolfSSL 16:8e0d178b1d1e 10010 else {
wolfSSL 16:8e0d178b1d1e 10011 r[++j] = 0L;
wolfSSL 16:8e0d178b1d1e 10012 }
wolfSSL 16:8e0d178b1d1e 10013 }
wolfSSL 16:8e0d178b1d1e 10014 s = (word32)DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 10015 }
wolfSSL 16:8e0d178b1d1e 10016
wolfSSL 16:8e0d178b1d1e 10017 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 10018 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 10019 }
wolfSSL 16:8e0d178b1d1e 10020 #else
wolfSSL 16:8e0d178b1d1e 10021 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 10022
wolfSSL 16:8e0d178b1d1e 10023 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 10024 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 10025 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 16:8e0d178b1d1e 10026 if (s + DIGIT_BIT >= 32) {
wolfSSL 16:8e0d178b1d1e 10027 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 10028 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 10029 break;
wolfSSL 16:8e0d178b1d1e 10030 }
wolfSSL 16:8e0d178b1d1e 10031 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 10032 if (s == DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 10033 r[++j] = 0;
wolfSSL 16:8e0d178b1d1e 10034 s = 0;
wolfSSL 16:8e0d178b1d1e 10035 }
wolfSSL 16:8e0d178b1d1e 10036 else {
wolfSSL 16:8e0d178b1d1e 10037 r[++j] = a->dp[i] >> s;
wolfSSL 16:8e0d178b1d1e 10038 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 10039 }
wolfSSL 16:8e0d178b1d1e 10040 }
wolfSSL 16:8e0d178b1d1e 10041 else {
wolfSSL 16:8e0d178b1d1e 10042 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 10043 }
wolfSSL 16:8e0d178b1d1e 10044 }
wolfSSL 16:8e0d178b1d1e 10045
wolfSSL 16:8e0d178b1d1e 10046 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 10047 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 10048 }
wolfSSL 16:8e0d178b1d1e 10049 #endif
wolfSSL 16:8e0d178b1d1e 10050 }
wolfSSL 16:8e0d178b1d1e 10051
wolfSSL 16:8e0d178b1d1e 10052 /* Write r as big endian to byte array.
wolfSSL 16:8e0d178b1d1e 10053 * Fixed length number of bytes written: 512
wolfSSL 16:8e0d178b1d1e 10054 *
wolfSSL 16:8e0d178b1d1e 10055 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 10056 * a Byte array.
wolfSSL 16:8e0d178b1d1e 10057 */
wolfSSL 16:8e0d178b1d1e 10058 static void sp_4096_to_bin(sp_digit* r, byte* a)
wolfSSL 16:8e0d178b1d1e 10059 {
wolfSSL 16:8e0d178b1d1e 10060 int i, j, s = 0, b;
wolfSSL 16:8e0d178b1d1e 10061
wolfSSL 16:8e0d178b1d1e 10062 j = 4096 / 8 - 1;
wolfSSL 16:8e0d178b1d1e 10063 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 10064 for (i=0; i<128 && j>=0; i++) {
wolfSSL 16:8e0d178b1d1e 10065 b = 0;
wolfSSL 16:8e0d178b1d1e 10066 /* lint allow cast of mismatch sp_digit and int */
wolfSSL 16:8e0d178b1d1e 10067 a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 10068 b += 8 - s;
wolfSSL 16:8e0d178b1d1e 10069 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 10070 break;
wolfSSL 16:8e0d178b1d1e 10071 }
wolfSSL 16:8e0d178b1d1e 10072 while (b < 32) {
wolfSSL 16:8e0d178b1d1e 10073 a[j--] = (byte)(r[i] >> b);
wolfSSL 16:8e0d178b1d1e 10074 b += 8;
wolfSSL 16:8e0d178b1d1e 10075 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 10076 break;
wolfSSL 16:8e0d178b1d1e 10077 }
wolfSSL 16:8e0d178b1d1e 10078 }
wolfSSL 16:8e0d178b1d1e 10079 s = 8 - (b - 32);
wolfSSL 16:8e0d178b1d1e 10080 if (j >= 0) {
wolfSSL 16:8e0d178b1d1e 10081 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 10082 }
wolfSSL 16:8e0d178b1d1e 10083 if (s != 0) {
wolfSSL 16:8e0d178b1d1e 10084 j++;
wolfSSL 16:8e0d178b1d1e 10085 }
wolfSSL 16:8e0d178b1d1e 10086 }
wolfSSL 16:8e0d178b1d1e 10087 }
wolfSSL 16:8e0d178b1d1e 10088
wolfSSL 16:8e0d178b1d1e 10089 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 10090 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 10091 *
wolfSSL 16:8e0d178b1d1e 10092 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 10093 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 10094 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 10095 */
wolfSSL 16:8e0d178b1d1e 10096 SP_NOINLINE static sp_digit sp_4096_add_64(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 10097 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 10098 {
wolfSSL 16:8e0d178b1d1e 10099 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 10100
wolfSSL 16:8e0d178b1d1e 10101 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 10102 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10103 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10104 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10105 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10106 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10107 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10108 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10109 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10110 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10111 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10112 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10113 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10114 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10115 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10116 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10117 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10118 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10119 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10120 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10121 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10122 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10123 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10124 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10125 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10126 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10127 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10128 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10129 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10130 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10131 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10132 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10133 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10134 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10135 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10136 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10137 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10138 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10139 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10140 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10141 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10142 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10143 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10144 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10145 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10146 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10147 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10148 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10149 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10150 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10151 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10152 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10153 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10154 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10155 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10156 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10157 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10158 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10159 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10160 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10161 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10162 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10163 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10164 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10165 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10166 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10167 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10168 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10169 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10170 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10171 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10172 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10173 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10174 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10175 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10176 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10177 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10178 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10179 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10180 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10181 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10182 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10183 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10184 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10185 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10186 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10187 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10188 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10189 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10190 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10191 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10192 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10193 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10194 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10195 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10196 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10197 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10198 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10199 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10200 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10201 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10202 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10203 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10204 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10205 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10206 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10207 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10208 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10209 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10210 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10211 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10212 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10213 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10214 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10215 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10216 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10217 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10218 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10219 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10220 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10221 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10222 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10223 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10224 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10225 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10226 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10227 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10228 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10229 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10230 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10231 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10232 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10233 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10234 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10235 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10236 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10237 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10238 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10239 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10240 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10241 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10242 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10243 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10244 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10245 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10246 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10247 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10248 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10249 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10250 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10251 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10252 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10253 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10254 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10255 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10256 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10257 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10258 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10259 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10260 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10261 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10262 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 10263 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 10264 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 10265 :
wolfSSL 16:8e0d178b1d1e 10266 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 10267 );
wolfSSL 16:8e0d178b1d1e 10268
wolfSSL 16:8e0d178b1d1e 10269 return c;
wolfSSL 16:8e0d178b1d1e 10270 }
wolfSSL 16:8e0d178b1d1e 10271
wolfSSL 16:8e0d178b1d1e 10272 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 10273 *
wolfSSL 16:8e0d178b1d1e 10274 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 10275 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 10276 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 10277 */
wolfSSL 16:8e0d178b1d1e 10278 SP_NOINLINE static sp_digit sp_4096_sub_in_place_128(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 10279 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 10280 {
wolfSSL 16:8e0d178b1d1e 10281 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 10282
wolfSSL 16:8e0d178b1d1e 10283 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 10284 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10285 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10286 "subs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10287 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10288 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10289 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10290 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10291 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10292 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10293 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10294 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10295 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10296 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10297 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10298 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10299 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10300 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10301 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10302 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10303 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10304 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10305 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10306 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10307 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10308 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10309 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10310 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10311 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10312 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10313 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10314 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10315 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10316 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10317 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10318 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10319 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10320 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10321 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10322 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10323 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10324 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10325 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10326 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10327 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10328 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10329 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10330 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10331 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10332 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10333 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10334 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10335 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10336 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10337 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10338 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10339 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10340 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10341 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10342 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10343 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10344 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10345 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10346 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10347 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10348 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10349 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10350 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10351 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10352 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10353 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10354 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10355 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10356 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10357 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10358 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10359 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10360 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10361 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10362 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10363 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10364 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10365 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10366 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10367 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10368 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10369 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10370 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10371 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10372 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10373 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10374 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10375 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10376 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10377 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10378 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10379 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10380 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10381 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10382 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10383 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10384 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10385 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10386 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10387 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10388 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10389 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10390 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10391 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10392 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10393 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10394 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10395 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10396 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10397 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10398 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10399 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10400 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10401 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10402 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10403 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10404 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10405 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10406 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10407 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10408 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10409 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10410 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10411 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10412 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10413 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10414 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10415 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10416 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10417 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10418 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10419 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10420 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10421 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10422 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10423 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10424 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10425 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10426 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10427 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10428 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10429 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10430 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10431 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10432 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10433 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10434 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10435 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10436 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10437 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10438 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10439 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10440 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10441 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10442 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10443 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10444 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10445 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10446 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10447 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10448 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10449 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10450 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10451 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10452 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10453 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10454 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10455 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10456 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10457 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10458 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10459 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10460 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10461 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10462 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10463 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10464 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10465 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10466 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10467 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10468 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10469 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10470 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10471 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10472 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10473 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10474 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10475 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10476 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10477 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10478 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10479 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10480 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10481 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10482 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10483 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10484 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10485 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10486 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10487 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10488 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10489 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10490 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10491 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10492 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10493 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10494 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10495 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10496 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10497 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10498 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10499 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10500 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10501 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10502 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10503 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10504 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10505 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10506 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10507 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10508 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10509 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10510 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10511 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10512 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10513 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10514 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10515 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10516 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10517 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10518 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10519 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10520 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10521 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10522 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10523 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10524 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10525 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10526 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10527 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10528 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10529 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10530 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10531 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10532 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10533 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10534 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10535 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10536 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10537 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10538 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10539 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10540 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10541 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10542 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10543 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10544 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10545 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10546 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10547 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10548 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10549 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10550 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10551 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10552 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10553 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10554 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10555 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10556 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10557 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10558 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10559 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10560 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10561 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10562 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10563 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10564 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10565 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10566 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10567 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10568 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10569 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10570 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10571 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10572 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10573 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10574 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10575 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10576 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10577 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10578 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10579 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10580 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10581 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10582 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10583 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10584 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10585 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10586 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10587 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10588 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10589 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10590 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10591 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10592 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10593 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10594 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10595 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10596 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10597 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10598 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10599 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10600 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 10601 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 10602 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10603 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 10604 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 10605 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 10606 :
wolfSSL 16:8e0d178b1d1e 10607 : "memory", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 10608 );
wolfSSL 16:8e0d178b1d1e 10609
wolfSSL 16:8e0d178b1d1e 10610 return c;
wolfSSL 16:8e0d178b1d1e 10611 }
wolfSSL 16:8e0d178b1d1e 10612
wolfSSL 16:8e0d178b1d1e 10613 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 10614 *
wolfSSL 16:8e0d178b1d1e 10615 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 10616 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 10617 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 10618 */
wolfSSL 16:8e0d178b1d1e 10619 SP_NOINLINE static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 10620 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 10621 {
wolfSSL 16:8e0d178b1d1e 10622 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 10623
wolfSSL 16:8e0d178b1d1e 10624 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 10625 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10626 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10627 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10628 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10629 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10630 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10631 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10632 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10633 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10634 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10635 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10636 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10637 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10638 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10639 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10640 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10641 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10642 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10643 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10644 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10645 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10646 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10647 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10648 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10649 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10650 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10651 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10652 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10653 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10654 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10655 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10656 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10657 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10658 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10659 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10660 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10661 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10662 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10663 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10664 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10665 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10666 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10667 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10668 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10669 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10670 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10671 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10672 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10673 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10674 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10675 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10676 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10677 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10678 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10679 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10680 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10681 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10682 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10683 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10684 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10685 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10686 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10687 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10688 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10689 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10690 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10691 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10692 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10693 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10694 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10695 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10696 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10697 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10698 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10699 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10700 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10701 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10702 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10703 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10704 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10705 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10706 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10707 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10708 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10709 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10710 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10711 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10712 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10713 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10714 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10715 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10716 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10717 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10718 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10719 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10720 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10721 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10722 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10723 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10724 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10725 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10726 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10727 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10728 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10729 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10730 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10731 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10732 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10733 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10734 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10735 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10736 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10737 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10738 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10739 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10740 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10741 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10742 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10743 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10744 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10745 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10746 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10747 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10748 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10749 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10750 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10751 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10752 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10753 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10754 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10755 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10756 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10757 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10758 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10759 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10760 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10761 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10762 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10763 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10764 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10765 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10766 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10767 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10768 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10769 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10770 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10771 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10772 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10773 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10774 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10775 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10776 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10777 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10778 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10779 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10780 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10781 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10782 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10783 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10784 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10785 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10786 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10787 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10788 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10789 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10790 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10791 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10792 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10793 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10794 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10795 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10796 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10797 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10798 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10799 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10800 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10801 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10802 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10803 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10804 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10805 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10806 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10807 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10808 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10809 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10810 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10811 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10812 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10813 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10814 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10815 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10816 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10817 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10818 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10819 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10820 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10821 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10822 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10823 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10824 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10825 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10826 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10827 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10828 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10829 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10830 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10831 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10832 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10833 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10834 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10835 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10836 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10837 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10838 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10839 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10840 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10841 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10842 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10843 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10844 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10845 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10846 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10847 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10848 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10849 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10850 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10851 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10852 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10853 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10854 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10855 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10856 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10857 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10858 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10859 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10860 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10861 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10862 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10863 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10864 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10865 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10866 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10867 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10868 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10869 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10870 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10871 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10872 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10873 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10874 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10875 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10876 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10877 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10878 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10879 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10880 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10881 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10882 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10883 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10884 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10885 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10886 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10887 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10888 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10889 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10890 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10891 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10892 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10893 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10894 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10895 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10896 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10897 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10898 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10899 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10900 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10901 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10902 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10903 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10904 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10905 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10906 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10907 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10908 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10909 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10910 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10911 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10912 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10913 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10914 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10915 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10916 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10917 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10918 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10919 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10920 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10921 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10922 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10923 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10924 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10925 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10926 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10927 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10928 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10929 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10930 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10931 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10932 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10933 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10934 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10935 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10936 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10937 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10938 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10939 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10940 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10941 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 10942 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10943 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10944 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 10945 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 10946 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 10947 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 10948 :
wolfSSL 16:8e0d178b1d1e 10949 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 10950 );
wolfSSL 16:8e0d178b1d1e 10951
wolfSSL 16:8e0d178b1d1e 10952 return c;
wolfSSL 16:8e0d178b1d1e 10953 }
wolfSSL 16:8e0d178b1d1e 10954
wolfSSL 16:8e0d178b1d1e 10955 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 10956 *
wolfSSL 16:8e0d178b1d1e 10957 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 10958 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 10959 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 10960 */
wolfSSL 16:8e0d178b1d1e 10961 SP_NOINLINE static void sp_4096_mul_64(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 10962 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 10963 {
wolfSSL 16:8e0d178b1d1e 10964 sp_digit tmp[64 * 2];
wolfSSL 16:8e0d178b1d1e 10965 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 10966 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 10967 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 10968 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 10969 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 10970 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 10971 "mov r11, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 10972 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 10973 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 10974 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 10975 "mov r14, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10976 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 10977 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 10978 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 10979 "mov r6, #252\n\t"
wolfSSL 16:8e0d178b1d1e 10980 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 10981 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 10982 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10983 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10984 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 10985 "mov %[b], r9\n\t"
wolfSSL 16:8e0d178b1d1e 10986 "sub %[b], %[b], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 10987 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 10988 "add %[b], %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 10989 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 10990 /* Multiply Start */
wolfSSL 16:8e0d178b1d1e 10991 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 10992 "ldr r8, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 10993 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10994 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 10995 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 10996 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 10997 /* Multiply Done */
wolfSSL 16:8e0d178b1d1e 10998 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 10999 "sub %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11000 "cmp %[a], r14\n\t"
wolfSSL 16:8e0d178b1d1e 11001 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 11002 "mov r6, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11003 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 11004 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11005 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 11006 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 11007 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 11008 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11009 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11010 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11011 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11012 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11013 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11014 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 11015 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11016 "add r6, r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 11017 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11018 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11019 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11020 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 11021 "mov %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 11022 :
wolfSSL 16:8e0d178b1d1e 11023 : [r] "r" (tmp), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 11024 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 11025 );
wolfSSL 16:8e0d178b1d1e 11026
wolfSSL 16:8e0d178b1d1e 11027 XMEMCPY(r, tmp, sizeof(tmp));
wolfSSL 16:8e0d178b1d1e 11028 }
wolfSSL 16:8e0d178b1d1e 11029
wolfSSL 16:8e0d178b1d1e 11030 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 11031 *
wolfSSL 16:8e0d178b1d1e 11032 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 11033 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11034 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 11035 */
wolfSSL 16:8e0d178b1d1e 11036 static void sp_4096_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 11037 {
wolfSSL 16:8e0d178b1d1e 11038 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 11039 int i;
wolfSSL 16:8e0d178b1d1e 11040
wolfSSL 16:8e0d178b1d1e 11041 for (i=0; i<64; i++) {
wolfSSL 16:8e0d178b1d1e 11042 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 11043 }
wolfSSL 16:8e0d178b1d1e 11044 #else
wolfSSL 16:8e0d178b1d1e 11045 int i;
wolfSSL 16:8e0d178b1d1e 11046
wolfSSL 16:8e0d178b1d1e 11047 for (i = 0; i < 64; i += 8) {
wolfSSL 16:8e0d178b1d1e 11048 r[i+0] = a[i+0] & m;
wolfSSL 16:8e0d178b1d1e 11049 r[i+1] = a[i+1] & m;
wolfSSL 16:8e0d178b1d1e 11050 r[i+2] = a[i+2] & m;
wolfSSL 16:8e0d178b1d1e 11051 r[i+3] = a[i+3] & m;
wolfSSL 16:8e0d178b1d1e 11052 r[i+4] = a[i+4] & m;
wolfSSL 16:8e0d178b1d1e 11053 r[i+5] = a[i+5] & m;
wolfSSL 16:8e0d178b1d1e 11054 r[i+6] = a[i+6] & m;
wolfSSL 16:8e0d178b1d1e 11055 r[i+7] = a[i+7] & m;
wolfSSL 16:8e0d178b1d1e 11056 }
wolfSSL 16:8e0d178b1d1e 11057 #endif
wolfSSL 16:8e0d178b1d1e 11058 }
wolfSSL 16:8e0d178b1d1e 11059
wolfSSL 16:8e0d178b1d1e 11060 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 11061 *
wolfSSL 16:8e0d178b1d1e 11062 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 11063 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11064 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 11065 */
wolfSSL 16:8e0d178b1d1e 11066 SP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 11067 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 11068 {
wolfSSL 16:8e0d178b1d1e 11069 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 11070 sp_digit z1[128];
wolfSSL 16:8e0d178b1d1e 11071 sp_digit a1[64];
wolfSSL 16:8e0d178b1d1e 11072 sp_digit b1[64];
wolfSSL 16:8e0d178b1d1e 11073 sp_digit z2[128];
wolfSSL 16:8e0d178b1d1e 11074 sp_digit u, ca, cb;
wolfSSL 16:8e0d178b1d1e 11075
wolfSSL 16:8e0d178b1d1e 11076 ca = sp_2048_add_64(a1, a, &a[64]);
wolfSSL 16:8e0d178b1d1e 11077 cb = sp_2048_add_64(b1, b, &b[64]);
wolfSSL 16:8e0d178b1d1e 11078 u = ca & cb;
wolfSSL 16:8e0d178b1d1e 11079 sp_2048_mul_64(z1, a1, b1);
wolfSSL 16:8e0d178b1d1e 11080 sp_2048_mul_64(z2, &a[64], &b[64]);
wolfSSL 16:8e0d178b1d1e 11081 sp_2048_mul_64(z0, a, b);
wolfSSL 16:8e0d178b1d1e 11082 sp_2048_mask_64(r + 128, a1, 0 - cb);
wolfSSL 16:8e0d178b1d1e 11083 sp_2048_mask_64(b1, b1, 0 - ca);
wolfSSL 16:8e0d178b1d1e 11084 u += sp_2048_add_64(r + 128, r + 128, b1);
wolfSSL 16:8e0d178b1d1e 11085 u += sp_4096_sub_in_place_128(z1, z2);
wolfSSL 16:8e0d178b1d1e 11086 u += sp_4096_sub_in_place_128(z1, z0);
wolfSSL 16:8e0d178b1d1e 11087 u += sp_4096_add_128(r + 64, r + 64, z1);
wolfSSL 16:8e0d178b1d1e 11088 r[192] = u;
wolfSSL 16:8e0d178b1d1e 11089 XMEMSET(r + 192 + 1, 0, sizeof(sp_digit) * (64 - 1));
wolfSSL 16:8e0d178b1d1e 11090 (void)sp_4096_add_128(r + 128, r + 128, z2);
wolfSSL 16:8e0d178b1d1e 11091 }
wolfSSL 16:8e0d178b1d1e 11092
wolfSSL 16:8e0d178b1d1e 11093 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 11094 *
wolfSSL 16:8e0d178b1d1e 11095 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 11096 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11097 */
wolfSSL 16:8e0d178b1d1e 11098 SP_NOINLINE static void sp_4096_sqr_64(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 11099 {
wolfSSL 16:8e0d178b1d1e 11100 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11101 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11102 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11103 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11104 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 11105 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11106 "mov r6, #2\n\t"
wolfSSL 16:8e0d178b1d1e 11107 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11108 "neg r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11109 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11110 "mov r11, sp\n\t"
wolfSSL 16:8e0d178b1d1e 11111 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11112 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 11113 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 11114 "mov r6, #252\n\t"
wolfSSL 16:8e0d178b1d1e 11115 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 11116 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11117 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11118 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11119 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11120 "mov r2, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11121 "sub r2, r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11122 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 11123 "add r2, r2, r10\n\t"
wolfSSL 16:8e0d178b1d1e 11124 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 11125 "cmp r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11126 "beq 4f\n\t"
wolfSSL 16:8e0d178b1d1e 11127 /* Multiply * 2: Start */
wolfSSL 16:8e0d178b1d1e 11128 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 11129 "ldr r8, [r2]\n\t"
wolfSSL 16:8e0d178b1d1e 11130 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11131 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11132 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11133 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11134 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11135 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11136 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11137 /* Multiply * 2: Done */
wolfSSL 16:8e0d178b1d1e 11138 "bal 5f\n\t"
wolfSSL 16:8e0d178b1d1e 11139 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 11140 /* Square: Start */
wolfSSL 16:8e0d178b1d1e 11141 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 11142 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11143 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11144 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11145 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11146 /* Square: Done */
wolfSSL 16:8e0d178b1d1e 11147 "\n5:\n\t"
wolfSSL 16:8e0d178b1d1e 11148 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11149 "sub r2, r2, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11150 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 11151 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11152 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 11153 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11154 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 11155 "cmp %[a], r2\n\t"
wolfSSL 16:8e0d178b1d1e 11156 "bgt 3f\n\t"
wolfSSL 16:8e0d178b1d1e 11157 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11158 "add r8, r8, r10\n\t"
wolfSSL 16:8e0d178b1d1e 11159 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11160 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 11161 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 11162 "mov %[r], r11\n\t"
wolfSSL 16:8e0d178b1d1e 11163 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11164 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11165 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11166 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11167 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11168 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11169 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11170 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 11171 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11172 "add r6, r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 11173 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11174 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11175 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 11176 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11177 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 11178 "mov %[a], r11\n\t"
wolfSSL 16:8e0d178b1d1e 11179 "mov r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 11180 "lsl r3, r3, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11181 "add r3, r3, #252\n\t"
wolfSSL 16:8e0d178b1d1e 11182 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 11183 "ldr r6, [%[a], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 11184 "str r6, [%[r], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 11185 "subs r3, r3, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11186 "bge 4b\n\t"
wolfSSL 16:8e0d178b1d1e 11187 "mov r6, #2\n\t"
wolfSSL 16:8e0d178b1d1e 11188 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11189 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11190 :
wolfSSL 16:8e0d178b1d1e 11191 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 11192 : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 11193 );
wolfSSL 16:8e0d178b1d1e 11194 }
wolfSSL 16:8e0d178b1d1e 11195
wolfSSL 16:8e0d178b1d1e 11196 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 11197 *
wolfSSL 16:8e0d178b1d1e 11198 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 11199 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11200 */
wolfSSL 16:8e0d178b1d1e 11201 SP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 11202 {
wolfSSL 16:8e0d178b1d1e 11203 sp_digit* z0 = r;
wolfSSL 16:8e0d178b1d1e 11204 sp_digit z2[128];
wolfSSL 16:8e0d178b1d1e 11205 sp_digit z1[128];
wolfSSL 16:8e0d178b1d1e 11206 sp_digit a1[64];
wolfSSL 16:8e0d178b1d1e 11207 sp_digit u;
wolfSSL 16:8e0d178b1d1e 11208
wolfSSL 16:8e0d178b1d1e 11209 u = sp_2048_add_64(a1, a, &a[64]);
wolfSSL 16:8e0d178b1d1e 11210 sp_2048_sqr_64(z1, a1);
wolfSSL 16:8e0d178b1d1e 11211 sp_2048_sqr_64(z2, &a[64]);
wolfSSL 16:8e0d178b1d1e 11212 sp_2048_sqr_64(z0, a);
wolfSSL 16:8e0d178b1d1e 11213 sp_2048_mask_64(r + 128, a1, 0 - u);
wolfSSL 16:8e0d178b1d1e 11214 u += sp_2048_add_64(r + 128, r + 128, r + 128);
wolfSSL 16:8e0d178b1d1e 11215 u += sp_4096_sub_in_place_128(z1, z2);
wolfSSL 16:8e0d178b1d1e 11216 u += sp_4096_sub_in_place_128(z1, z0);
wolfSSL 16:8e0d178b1d1e 11217 u += sp_4096_add_128(r + 64, r + 64, z1);
wolfSSL 16:8e0d178b1d1e 11218 r[192] = u;
wolfSSL 16:8e0d178b1d1e 11219 XMEMSET(r + 192 + 1, 0, sizeof(sp_digit) * (64 - 1));
wolfSSL 16:8e0d178b1d1e 11220 (void)sp_4096_add_128(r + 128, r + 128, z2);
wolfSSL 16:8e0d178b1d1e 11221 }
wolfSSL 16:8e0d178b1d1e 11222
wolfSSL 16:8e0d178b1d1e 11223 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 11224 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 11225 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 11226 *
wolfSSL 16:8e0d178b1d1e 11227 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 11228 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11229 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 11230 */
wolfSSL 16:8e0d178b1d1e 11231 SP_NOINLINE static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 11232 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 11233 {
wolfSSL 16:8e0d178b1d1e 11234 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 11235
wolfSSL 16:8e0d178b1d1e 11236 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11237 "mov r6, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11238 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11239 "add r6, r6, #512\n\t"
wolfSSL 16:8e0d178b1d1e 11240 "sub r8, r8, #1\n\t"
wolfSSL 16:8e0d178b1d1e 11241 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 11242 "adds %[c], %[c], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11243 "ldr r4, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 11244 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 11245 "adcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11246 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 11247 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 11248 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 11249 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11250 "add %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11251 "add %[r], %[r], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11252 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11253 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11254 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 11255 :
wolfSSL 16:8e0d178b1d1e 11256 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 11257 );
wolfSSL 16:8e0d178b1d1e 11258
wolfSSL 16:8e0d178b1d1e 11259 return c;
wolfSSL 16:8e0d178b1d1e 11260 }
wolfSSL 16:8e0d178b1d1e 11261
wolfSSL 16:8e0d178b1d1e 11262 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 11263 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 11264 /* Sub b from a into a. (a -= b)
wolfSSL 16:8e0d178b1d1e 11265 *
wolfSSL 16:8e0d178b1d1e 11266 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11267 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 11268 */
wolfSSL 16:8e0d178b1d1e 11269 SP_NOINLINE static sp_digit sp_4096_sub_in_place_128(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 11270 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 11271 {
wolfSSL 16:8e0d178b1d1e 11272 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 11273 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11274 "mov r8, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11275 "add r8, r8, #512\n\t"
wolfSSL 16:8e0d178b1d1e 11276 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 11277 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11278 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 11279 "ldr r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 11280 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 11281 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 11282 "ldr r6, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 11283 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11284 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11285 "str r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 11286 "str r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 11287 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 11288 "add %[a], %[a], #8\n\t"
wolfSSL 16:8e0d178b1d1e 11289 "add %[b], %[b], #8\n\t"
wolfSSL 16:8e0d178b1d1e 11290 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11291 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11292 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 11293 :
wolfSSL 16:8e0d178b1d1e 11294 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 11295 );
wolfSSL 16:8e0d178b1d1e 11296
wolfSSL 16:8e0d178b1d1e 11297 return c;
wolfSSL 16:8e0d178b1d1e 11298 }
wolfSSL 16:8e0d178b1d1e 11299
wolfSSL 16:8e0d178b1d1e 11300 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 11301 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 11302 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 11303 *
wolfSSL 16:8e0d178b1d1e 11304 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 11305 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11306 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 11307 */
wolfSSL 16:8e0d178b1d1e 11308 SP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 11309 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 11310 {
wolfSSL 16:8e0d178b1d1e 11311 sp_digit tmp[128 * 2];
wolfSSL 16:8e0d178b1d1e 11312 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11313 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11314 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11315 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 11316 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11317 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11318 "mov r11, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 11319 "mov r6, #2\n\t"
wolfSSL 16:8e0d178b1d1e 11320 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11321 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 11322 "mov r14, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11323 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 11324 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 11325 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11326 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 11327 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11328 "add r6, r6, #252\n\t"
wolfSSL 16:8e0d178b1d1e 11329 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 11330 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11331 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11332 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11333 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11334 "mov %[b], r9\n\t"
wolfSSL 16:8e0d178b1d1e 11335 "sub %[b], %[b], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11336 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 11337 "add %[b], %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 11338 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 11339 /* Multiply Start */
wolfSSL 16:8e0d178b1d1e 11340 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 11341 "ldr r8, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 11342 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11343 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11344 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11345 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11346 /* Multiply Done */
wolfSSL 16:8e0d178b1d1e 11347 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11348 "sub %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11349 "cmp %[a], r14\n\t"
wolfSSL 16:8e0d178b1d1e 11350 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 11351 "mov r6, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11352 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 11353 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11354 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 11355 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 11356 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 11357 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11358 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11359 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11360 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11361 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11362 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11363 "mov r6, #3\n\t"
wolfSSL 16:8e0d178b1d1e 11364 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11365 "add r6, r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 11366 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11367 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11368 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11369 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 11370 "mov %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 11371 :
wolfSSL 16:8e0d178b1d1e 11372 : [r] "r" (tmp), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 11373 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 11374 );
wolfSSL 16:8e0d178b1d1e 11375
wolfSSL 16:8e0d178b1d1e 11376 XMEMCPY(r, tmp, sizeof(tmp));
wolfSSL 16:8e0d178b1d1e 11377 }
wolfSSL 16:8e0d178b1d1e 11378
wolfSSL 16:8e0d178b1d1e 11379 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 11380 *
wolfSSL 16:8e0d178b1d1e 11381 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 11382 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11383 */
wolfSSL 16:8e0d178b1d1e 11384 SP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 11385 {
wolfSSL 16:8e0d178b1d1e 11386 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11387 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11388 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11389 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11390 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 11391 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11392 "mov r6, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11393 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11394 "neg r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11395 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11396 "mov r11, sp\n\t"
wolfSSL 16:8e0d178b1d1e 11397 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11398 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 11399 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 11400 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 11401 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11402 "add r6, r6, #252\n\t"
wolfSSL 16:8e0d178b1d1e 11403 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 11404 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11405 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11406 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11407 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11408 "mov r2, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11409 "sub r2, r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11410 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 11411 "add r2, r2, r10\n\t"
wolfSSL 16:8e0d178b1d1e 11412 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 11413 "cmp r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11414 "beq 4f\n\t"
wolfSSL 16:8e0d178b1d1e 11415 /* Multiply * 2: Start */
wolfSSL 16:8e0d178b1d1e 11416 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 11417 "ldr r8, [r2]\n\t"
wolfSSL 16:8e0d178b1d1e 11418 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11419 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11420 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11421 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11422 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11423 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11424 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11425 /* Multiply * 2: Done */
wolfSSL 16:8e0d178b1d1e 11426 "bal 5f\n\t"
wolfSSL 16:8e0d178b1d1e 11427 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 11428 /* Square: Start */
wolfSSL 16:8e0d178b1d1e 11429 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 11430 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11431 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11432 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11433 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 11434 /* Square: Done */
wolfSSL 16:8e0d178b1d1e 11435 "\n5:\n\t"
wolfSSL 16:8e0d178b1d1e 11436 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11437 "sub r2, r2, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11438 "mov r6, #2\n\t"
wolfSSL 16:8e0d178b1d1e 11439 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11440 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 11441 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11442 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 11443 "cmp %[a], r2\n\t"
wolfSSL 16:8e0d178b1d1e 11444 "bgt 3f\n\t"
wolfSSL 16:8e0d178b1d1e 11445 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11446 "add r8, r8, r10\n\t"
wolfSSL 16:8e0d178b1d1e 11447 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11448 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 11449 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 11450 "mov %[r], r11\n\t"
wolfSSL 16:8e0d178b1d1e 11451 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11452 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11453 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11454 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11455 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11456 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11457 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11458 "mov r6, #3\n\t"
wolfSSL 16:8e0d178b1d1e 11459 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11460 "add r6, r6, #248\n\t"
wolfSSL 16:8e0d178b1d1e 11461 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11462 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11463 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 11464 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11465 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 11466 "mov %[a], r11\n\t"
wolfSSL 16:8e0d178b1d1e 11467 "mov r3, #3\n\t"
wolfSSL 16:8e0d178b1d1e 11468 "lsl r3, r3, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11469 "add r3, r3, #252\n\t"
wolfSSL 16:8e0d178b1d1e 11470 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 11471 "ldr r6, [%[a], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 11472 "str r6, [%[r], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 11473 "subs r3, r3, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11474 "bge 4b\n\t"
wolfSSL 16:8e0d178b1d1e 11475 "mov r6, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11476 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11477 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11478 :
wolfSSL 16:8e0d178b1d1e 11479 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 11480 : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 11481 );
wolfSSL 16:8e0d178b1d1e 11482 }
wolfSSL 16:8e0d178b1d1e 11483
wolfSSL 16:8e0d178b1d1e 11484 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 11485 /* Caclulate the bottom digit of -1/a mod 2^n.
wolfSSL 16:8e0d178b1d1e 11486 *
wolfSSL 16:8e0d178b1d1e 11487 * a A single precision number.
wolfSSL 16:8e0d178b1d1e 11488 * rho Bottom word of inverse.
wolfSSL 16:8e0d178b1d1e 11489 */
wolfSSL 16:8e0d178b1d1e 11490 static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)
wolfSSL 16:8e0d178b1d1e 11491 {
wolfSSL 16:8e0d178b1d1e 11492 sp_digit x, b;
wolfSSL 16:8e0d178b1d1e 11493
wolfSSL 16:8e0d178b1d1e 11494 b = a[0];
wolfSSL 16:8e0d178b1d1e 11495 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
wolfSSL 16:8e0d178b1d1e 11496 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
wolfSSL 16:8e0d178b1d1e 11497 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
wolfSSL 16:8e0d178b1d1e 11498 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
wolfSSL 16:8e0d178b1d1e 11499
wolfSSL 16:8e0d178b1d1e 11500 /* rho = -1/m mod b */
wolfSSL 16:8e0d178b1d1e 11501 *rho = -x;
wolfSSL 16:8e0d178b1d1e 11502 }
wolfSSL 16:8e0d178b1d1e 11503
wolfSSL 16:8e0d178b1d1e 11504 /* Mul a by digit b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 11505 *
wolfSSL 16:8e0d178b1d1e 11506 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 11507 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11508 * b A single precision digit.
wolfSSL 16:8e0d178b1d1e 11509 */
wolfSSL 16:8e0d178b1d1e 11510 SP_NOINLINE static void sp_4096_mul_d_128(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 11511 sp_digit b)
wolfSSL 16:8e0d178b1d1e 11512 {
wolfSSL 16:8e0d178b1d1e 11513 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11514 "add r9, %[a], #512\n\t"
wolfSSL 16:8e0d178b1d1e 11515 /* A[0] * B */
wolfSSL 16:8e0d178b1d1e 11516 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11517 "umull r5, r3, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 11518 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11519 "str r5, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11520 /* A[0] * B - Done */
wolfSSL 16:8e0d178b1d1e 11521 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 11522 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11523 /* A[] * B */
wolfSSL 16:8e0d178b1d1e 11524 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11525 "umull r6, r8, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 11526 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11527 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11528 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11529 /* A[] * B - Done */
wolfSSL 16:8e0d178b1d1e 11530 "str r3, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11531 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11532 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11533 "cmp %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 11534 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11535 "str r3, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 11536 : [r] "+r" (r), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 11537 : [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 11538 : "memory", "r3", "r4", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 11539 );
wolfSSL 16:8e0d178b1d1e 11540 }
wolfSSL 16:8e0d178b1d1e 11541
wolfSSL 16:8e0d178b1d1e 11542 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 16:8e0d178b1d1e 11543 /* r = 2^n mod m where n is the number of bits to reduce by.
wolfSSL 16:8e0d178b1d1e 11544 * Given m must be 4096 bits, just need to subtract.
wolfSSL 16:8e0d178b1d1e 11545 *
wolfSSL 16:8e0d178b1d1e 11546 * r A single precision number.
wolfSSL 16:8e0d178b1d1e 11547 * m A single precision number.
wolfSSL 16:8e0d178b1d1e 11548 */
wolfSSL 16:8e0d178b1d1e 11549 static void sp_4096_mont_norm_128(sp_digit* r, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 11550 {
wolfSSL 16:8e0d178b1d1e 11551 XMEMSET(r, 0, sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 11552
wolfSSL 16:8e0d178b1d1e 11553 /* r = 2^n mod m */
wolfSSL 16:8e0d178b1d1e 11554 sp_4096_sub_in_place_128(r, m);
wolfSSL 16:8e0d178b1d1e 11555 }
wolfSSL 16:8e0d178b1d1e 11556
wolfSSL 16:8e0d178b1d1e 11557 #endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 11558 /* Conditionally subtract b from a using the mask m.
wolfSSL 16:8e0d178b1d1e 11559 * m is -1 to subtract and 0 when not copying.
wolfSSL 16:8e0d178b1d1e 11560 *
wolfSSL 16:8e0d178b1d1e 11561 * r A single precision number representing condition subtract result.
wolfSSL 16:8e0d178b1d1e 11562 * a A single precision number to subtract from.
wolfSSL 16:8e0d178b1d1e 11563 * b A single precision number to subtract.
wolfSSL 16:8e0d178b1d1e 11564 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 11565 */
wolfSSL 16:8e0d178b1d1e 11566 SP_NOINLINE static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 11567 const sp_digit* b, sp_digit m)
wolfSSL 16:8e0d178b1d1e 11568 {
wolfSSL 16:8e0d178b1d1e 11569 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 11570
wolfSSL 16:8e0d178b1d1e 11571 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11572 "mov r5, #2\n\t"
wolfSSL 16:8e0d178b1d1e 11573 "lsl r5, r5, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11574 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11575 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11576 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 11577 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11578 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 11579 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11580 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 11581 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11582 "sbcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11583 "sbcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 11584 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 11585 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11586 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 11587 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11588 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 11589 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 11590 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 11591 );
wolfSSL 16:8e0d178b1d1e 11592
wolfSSL 16:8e0d178b1d1e 11593 return c;
wolfSSL 16:8e0d178b1d1e 11594 }
wolfSSL 16:8e0d178b1d1e 11595
wolfSSL 16:8e0d178b1d1e 11596 /* Reduce the number back to 4096 bits using Montgomery reduction.
wolfSSL 16:8e0d178b1d1e 11597 *
wolfSSL 16:8e0d178b1d1e 11598 * a A single precision number to reduce in place.
wolfSSL 16:8e0d178b1d1e 11599 * m The single precision number representing the modulus.
wolfSSL 16:8e0d178b1d1e 11600 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 16:8e0d178b1d1e 11601 */
wolfSSL 16:8e0d178b1d1e 11602 SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 11603 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 11604 {
wolfSSL 16:8e0d178b1d1e 11605 sp_digit ca = 0;
wolfSSL 16:8e0d178b1d1e 11606
wolfSSL 16:8e0d178b1d1e 11607 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11608 "mov r9, %[mp]\n\t"
wolfSSL 16:8e0d178b1d1e 11609 "mov r12, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 11610 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11611 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11612 "add r11, r10, #512\n\t"
wolfSSL 16:8e0d178b1d1e 11613 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 11614 /* mu = a[i] * mp */
wolfSSL 16:8e0d178b1d1e 11615 "mov %[mp], r9\n\t"
wolfSSL 16:8e0d178b1d1e 11616 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 11617 "mul %[mp], %[mp], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11618 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 11619 "add r14, r10, #504\n\t"
wolfSSL 16:8e0d178b1d1e 11620 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 11621 /* a[i+j] += m[j] * mu */
wolfSSL 16:8e0d178b1d1e 11622 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 11623 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11624 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 11625 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11626 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11627 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11628 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11629 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 11630 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11631 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11632 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11633 /* a[i+j+1] += m[j+1] * mu */
wolfSSL 16:8e0d178b1d1e 11634 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 11635 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11636 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 11637 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11638 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11639 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11640 "adc r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11641 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 11642 "adds r5, r5, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11643 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11644 "str r5, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11645 "cmp r10, r14\n\t"
wolfSSL 16:8e0d178b1d1e 11646 "blt 2b\n\t"
wolfSSL 16:8e0d178b1d1e 11647 /* a[i+126] += m[126] * mu */
wolfSSL 16:8e0d178b1d1e 11648 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 11649 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11650 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 11651 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11652 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11653 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11654 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11655 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 11656 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 11657 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11658 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 11659 /* a[i+127] += m[127] * mu */
wolfSSL 16:8e0d178b1d1e 11660 "mov r4, %[ca]\n\t"
wolfSSL 16:8e0d178b1d1e 11661 "mov %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 11662 /* Multiply m[127] and mu - Start */
wolfSSL 16:8e0d178b1d1e 11663 "ldr r8, [%[m]]\n\t"
wolfSSL 16:8e0d178b1d1e 11664 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11665 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11666 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11667 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 11668 /* Multiply m[127] and mu - Done */
wolfSSL 16:8e0d178b1d1e 11669 "ldr r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 11670 "ldr r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 11671 "adds r6, r6, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11672 "adcs r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11673 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 11674 "str r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 11675 "str r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 11676 /* Next word in a */
wolfSSL 16:8e0d178b1d1e 11677 "sub r10, r10, #504\n\t"
wolfSSL 16:8e0d178b1d1e 11678 "cmp r10, r11\n\t"
wolfSSL 16:8e0d178b1d1e 11679 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11680 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 11681 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 11682 : [ca] "+r" (ca), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 11683 : [m] "r" (m), [mp] "r" (mp)
wolfSSL 16:8e0d178b1d1e 11684 : "memory", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 11685 );
wolfSSL 16:8e0d178b1d1e 11686
wolfSSL 16:8e0d178b1d1e 11687 sp_4096_cond_sub_128(a - 128, a, m, (sp_digit)0 - ca);
wolfSSL 16:8e0d178b1d1e 11688 }
wolfSSL 16:8e0d178b1d1e 11689
wolfSSL 16:8e0d178b1d1e 11690 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 16:8e0d178b1d1e 11691 * (r = a * b mod m)
wolfSSL 16:8e0d178b1d1e 11692 *
wolfSSL 16:8e0d178b1d1e 11693 * r Result of multiplication.
wolfSSL 16:8e0d178b1d1e 11694 * a First number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 11695 * b Second number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 11696 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 11697 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 11698 */
wolfSSL 16:8e0d178b1d1e 11699 static void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 11700 const sp_digit* m, sp_digit mp)
wolfSSL 16:8e0d178b1d1e 11701 {
wolfSSL 16:8e0d178b1d1e 11702 sp_4096_mul_128(r, a, b);
wolfSSL 16:8e0d178b1d1e 11703 sp_4096_mont_reduce_128(r, m, mp);
wolfSSL 16:8e0d178b1d1e 11704 }
wolfSSL 16:8e0d178b1d1e 11705
wolfSSL 16:8e0d178b1d1e 11706 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 16:8e0d178b1d1e 11707 *
wolfSSL 16:8e0d178b1d1e 11708 * r Result of squaring.
wolfSSL 16:8e0d178b1d1e 11709 * a Number to square in Montogmery form.
wolfSSL 16:8e0d178b1d1e 11710 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 11711 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 11712 */
wolfSSL 16:8e0d178b1d1e 11713 static void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 11714 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 11715 {
wolfSSL 16:8e0d178b1d1e 11716 sp_4096_sqr_128(r, a);
wolfSSL 16:8e0d178b1d1e 11717 sp_4096_mont_reduce_128(r, m, mp);
wolfSSL 16:8e0d178b1d1e 11718 }
wolfSSL 16:8e0d178b1d1e 11719
wolfSSL 16:8e0d178b1d1e 11720 /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)
wolfSSL 16:8e0d178b1d1e 11721 *
wolfSSL 16:8e0d178b1d1e 11722 * d1 The high order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 11723 * d0 The low order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 11724 * div The dividend.
wolfSSL 16:8e0d178b1d1e 11725 * returns the result of the division.
wolfSSL 16:8e0d178b1d1e 11726 *
wolfSSL 16:8e0d178b1d1e 11727 * Note that this is an approximate div. It may give an answer 1 larger.
wolfSSL 16:8e0d178b1d1e 11728 */
wolfSSL 16:8e0d178b1d1e 11729 SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0,
wolfSSL 16:8e0d178b1d1e 11730 sp_digit div)
wolfSSL 16:8e0d178b1d1e 11731 {
wolfSSL 16:8e0d178b1d1e 11732 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 11733
wolfSSL 16:8e0d178b1d1e 11734 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11735 "lsr r6, %[div], #16\n\t"
wolfSSL 16:8e0d178b1d1e 11736 "add r6, r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 11737 "udiv r4, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11738 "lsl r8, r4, #16\n\t"
wolfSSL 16:8e0d178b1d1e 11739 "umull r4, r5, %[div], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11740 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 11741 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 11742 "udiv r5, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 11743 "lsl r4, r5, #16\n\t"
wolfSSL 16:8e0d178b1d1e 11744 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11745 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 11746 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 11747 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 11748 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 11749 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 11750 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11751 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11752 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 11753 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 11754 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 11755 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 11756 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 11757 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 11758 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11759 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 11760 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 11761 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 11762 "udiv r4, %[d0], %[div]\n\t"
wolfSSL 16:8e0d178b1d1e 11763 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11764 "mov %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11765 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 11766 : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div)
wolfSSL 16:8e0d178b1d1e 11767 : "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 11768 );
wolfSSL 16:8e0d178b1d1e 11769 return r;
wolfSSL 16:8e0d178b1d1e 11770 }
wolfSSL 16:8e0d178b1d1e 11771
wolfSSL 16:8e0d178b1d1e 11772 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 11773 *
wolfSSL 16:8e0d178b1d1e 11774 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 11775 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11776 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 11777 */
wolfSSL 16:8e0d178b1d1e 11778 static void sp_4096_mask_128(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 11779 {
wolfSSL 16:8e0d178b1d1e 11780 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 11781 int i;
wolfSSL 16:8e0d178b1d1e 11782
wolfSSL 16:8e0d178b1d1e 11783 for (i=0; i<128; i++) {
wolfSSL 16:8e0d178b1d1e 11784 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 11785 }
wolfSSL 16:8e0d178b1d1e 11786 #else
wolfSSL 16:8e0d178b1d1e 11787 int i;
wolfSSL 16:8e0d178b1d1e 11788
wolfSSL 16:8e0d178b1d1e 11789 for (i = 0; i < 128; i += 8) {
wolfSSL 16:8e0d178b1d1e 11790 r[i+0] = a[i+0] & m;
wolfSSL 16:8e0d178b1d1e 11791 r[i+1] = a[i+1] & m;
wolfSSL 16:8e0d178b1d1e 11792 r[i+2] = a[i+2] & m;
wolfSSL 16:8e0d178b1d1e 11793 r[i+3] = a[i+3] & m;
wolfSSL 16:8e0d178b1d1e 11794 r[i+4] = a[i+4] & m;
wolfSSL 16:8e0d178b1d1e 11795 r[i+5] = a[i+5] & m;
wolfSSL 16:8e0d178b1d1e 11796 r[i+6] = a[i+6] & m;
wolfSSL 16:8e0d178b1d1e 11797 r[i+7] = a[i+7] & m;
wolfSSL 16:8e0d178b1d1e 11798 }
wolfSSL 16:8e0d178b1d1e 11799 #endif
wolfSSL 16:8e0d178b1d1e 11800 }
wolfSSL 16:8e0d178b1d1e 11801
wolfSSL 16:8e0d178b1d1e 11802 /* Compare a with b in constant time.
wolfSSL 16:8e0d178b1d1e 11803 *
wolfSSL 16:8e0d178b1d1e 11804 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 11805 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 11806 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 16:8e0d178b1d1e 11807 * respectively.
wolfSSL 16:8e0d178b1d1e 11808 */
wolfSSL 16:8e0d178b1d1e 11809 SP_NOINLINE static int32_t sp_4096_cmp_128(const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 11810 {
wolfSSL 16:8e0d178b1d1e 11811 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 11812
wolfSSL 16:8e0d178b1d1e 11813
wolfSSL 16:8e0d178b1d1e 11814 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 11815 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11816 "mvn r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 11817 "mov r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 11818 "lsl r6, r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 11819 "add r6, r6, #252\n\t"
wolfSSL 16:8e0d178b1d1e 11820 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 11821 "ldr r8, [%[a], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 11822 "ldr r5, [%[b], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 11823 "and r8, r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 11824 "and r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 11825 "mov r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11826 "subs r8, r8, r5\n\t"
wolfSSL 16:8e0d178b1d1e 11827 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11828 "add %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11829 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11830 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11831 "subs r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 11832 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11833 "sub %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 11834 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11835 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 11836 "sub r6, r6, #4\n\t"
wolfSSL 16:8e0d178b1d1e 11837 "cmp r6, #0\n\t"
wolfSSL 16:8e0d178b1d1e 11838 "bge 1b\n\t"
wolfSSL 16:8e0d178b1d1e 11839 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 11840 : [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 11841 : "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 11842 );
wolfSSL 16:8e0d178b1d1e 11843
wolfSSL 16:8e0d178b1d1e 11844 return r;
wolfSSL 16:8e0d178b1d1e 11845 }
wolfSSL 16:8e0d178b1d1e 11846
wolfSSL 16:8e0d178b1d1e 11847 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 11848 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 11849 *
wolfSSL 16:8e0d178b1d1e 11850 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 11851 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 11852 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 11853 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 11854 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 11855 */
wolfSSL 16:8e0d178b1d1e 11856 static WC_INLINE int sp_4096_div_128(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 11857 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 11858 {
wolfSSL 16:8e0d178b1d1e 11859 sp_digit t1[256], t2[129];
wolfSSL 16:8e0d178b1d1e 11860 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 11861 int i;
wolfSSL 16:8e0d178b1d1e 11862
wolfSSL 16:8e0d178b1d1e 11863 (void)m;
wolfSSL 16:8e0d178b1d1e 11864
wolfSSL 16:8e0d178b1d1e 11865 div = d[127];
wolfSSL 16:8e0d178b1d1e 11866 XMEMCPY(t1, a, sizeof(*t1) * 2 * 128);
wolfSSL 16:8e0d178b1d1e 11867 for (i=127; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 11868 r1 = div_4096_word_128(t1[128 + i], t1[128 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 11869
wolfSSL 16:8e0d178b1d1e 11870 sp_4096_mul_d_128(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 11871 t1[128 + i] += sp_4096_sub_in_place_128(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 11872 t1[128 + i] -= t2[128];
wolfSSL 16:8e0d178b1d1e 11873 sp_4096_mask_128(t2, d, t1[128 + i]);
wolfSSL 16:8e0d178b1d1e 11874 t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 11875 sp_4096_mask_128(t2, d, t1[128 + i]);
wolfSSL 16:8e0d178b1d1e 11876 t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 11877 }
wolfSSL 16:8e0d178b1d1e 11878
wolfSSL 16:8e0d178b1d1e 11879 r1 = sp_4096_cmp_128(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 11880 sp_4096_cond_sub_128(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 11881
wolfSSL 16:8e0d178b1d1e 11882 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 11883 }
wolfSSL 16:8e0d178b1d1e 11884
wolfSSL 16:8e0d178b1d1e 11885 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 11886 *
wolfSSL 16:8e0d178b1d1e 11887 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 11888 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 11889 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 11890 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 11891 */
wolfSSL 16:8e0d178b1d1e 11892 static WC_INLINE int sp_4096_mod_128(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 11893 {
wolfSSL 16:8e0d178b1d1e 11894 return sp_4096_div_128(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 11895 }
wolfSSL 16:8e0d178b1d1e 11896
wolfSSL 16:8e0d178b1d1e 11897 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 11898 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 11899 *
wolfSSL 16:8e0d178b1d1e 11900 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 11901 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 11902 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 11903 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 11904 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 11905 */
wolfSSL 16:8e0d178b1d1e 11906 static WC_INLINE int sp_4096_div_128_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 11907 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 11908 {
wolfSSL 16:8e0d178b1d1e 11909 sp_digit t1[256], t2[129];
wolfSSL 16:8e0d178b1d1e 11910 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 11911 int i;
wolfSSL 16:8e0d178b1d1e 11912
wolfSSL 16:8e0d178b1d1e 11913 (void)m;
wolfSSL 16:8e0d178b1d1e 11914
wolfSSL 16:8e0d178b1d1e 11915 div = d[127];
wolfSSL 16:8e0d178b1d1e 11916 XMEMCPY(t1, a, sizeof(*t1) * 2 * 128);
wolfSSL 16:8e0d178b1d1e 11917 for (i=127; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 11918 r1 = div_4096_word_128(t1[128 + i], t1[128 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 11919
wolfSSL 16:8e0d178b1d1e 11920 sp_4096_mul_d_128(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 11921 t1[128 + i] += sp_4096_sub_in_place_128(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 11922 t1[128 + i] -= t2[128];
wolfSSL 16:8e0d178b1d1e 11923 if (t1[128 + i] != 0) {
wolfSSL 16:8e0d178b1d1e 11924 t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], d);
wolfSSL 16:8e0d178b1d1e 11925 if (t1[128 + i] != 0)
wolfSSL 16:8e0d178b1d1e 11926 t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], d);
wolfSSL 16:8e0d178b1d1e 11927 }
wolfSSL 16:8e0d178b1d1e 11928 }
wolfSSL 16:8e0d178b1d1e 11929
wolfSSL 16:8e0d178b1d1e 11930 r1 = sp_4096_cmp_128(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 11931 sp_4096_cond_sub_128(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 11932
wolfSSL 16:8e0d178b1d1e 11933 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 11934 }
wolfSSL 16:8e0d178b1d1e 11935
wolfSSL 16:8e0d178b1d1e 11936 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 11937 *
wolfSSL 16:8e0d178b1d1e 11938 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 11939 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 11940 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 11941 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 11942 */
wolfSSL 16:8e0d178b1d1e 11943 static WC_INLINE int sp_4096_mod_128_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 11944 {
wolfSSL 16:8e0d178b1d1e 11945 return sp_4096_div_128_cond(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 11946 }
wolfSSL 16:8e0d178b1d1e 11947
wolfSSL 16:8e0d178b1d1e 11948 #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
wolfSSL 16:8e0d178b1d1e 11949 defined(WOLFSSL_HAVE_SP_DH)
wolfSSL 16:8e0d178b1d1e 11950 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 11951 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 11952 *
wolfSSL 16:8e0d178b1d1e 11953 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 11954 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 11955 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 11956 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 11957 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 11958 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 11959 */
wolfSSL 16:8e0d178b1d1e 11960 static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 11961 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 11962 {
wolfSSL 16:8e0d178b1d1e 11963 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 11964 sp_digit t[16][256];
wolfSSL 16:8e0d178b1d1e 11965 #else
wolfSSL 16:8e0d178b1d1e 11966 sp_digit* t[16];
wolfSSL 16:8e0d178b1d1e 11967 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 11968 #endif
wolfSSL 16:8e0d178b1d1e 11969 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 11970 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 11971 sp_digit n;
wolfSSL 16:8e0d178b1d1e 11972 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 11973 int i;
wolfSSL 16:8e0d178b1d1e 11974 int c, y;
wolfSSL 16:8e0d178b1d1e 11975 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 11976
wolfSSL 16:8e0d178b1d1e 11977 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 11978 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 256, NULL,
wolfSSL 16:8e0d178b1d1e 11979 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 11980 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 11981 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 11982 }
wolfSSL 16:8e0d178b1d1e 11983 #endif
wolfSSL 16:8e0d178b1d1e 11984
wolfSSL 16:8e0d178b1d1e 11985 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 11986 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 11987 for (i=0; i<16; i++) {
wolfSSL 16:8e0d178b1d1e 11988 t[i] = td + i * 256;
wolfSSL 16:8e0d178b1d1e 11989 }
wolfSSL 16:8e0d178b1d1e 11990 #endif
wolfSSL 16:8e0d178b1d1e 11991 norm = t[0];
wolfSSL 16:8e0d178b1d1e 11992
wolfSSL 16:8e0d178b1d1e 11993 sp_4096_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 11994 sp_4096_mont_norm_128(norm, m);
wolfSSL 16:8e0d178b1d1e 11995
wolfSSL 16:8e0d178b1d1e 11996 XMEMSET(t[1], 0, sizeof(sp_digit) * 128U);
wolfSSL 16:8e0d178b1d1e 11997 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 11998 err = sp_4096_mod_128(t[1] + 128, a, m);
wolfSSL 16:8e0d178b1d1e 11999 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12000 err = sp_4096_mod_128(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 12001 }
wolfSSL 16:8e0d178b1d1e 12002 }
wolfSSL 16:8e0d178b1d1e 12003 else {
wolfSSL 16:8e0d178b1d1e 12004 XMEMCPY(t[1] + 128, a, sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 12005 err = sp_4096_mod_128(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 12006 }
wolfSSL 16:8e0d178b1d1e 12007 }
wolfSSL 16:8e0d178b1d1e 12008
wolfSSL 16:8e0d178b1d1e 12009 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12010 sp_4096_mont_sqr_128(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 12011 sp_4096_mont_mul_128(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 12012 sp_4096_mont_sqr_128(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 12013 sp_4096_mont_mul_128(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 12014 sp_4096_mont_sqr_128(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 12015 sp_4096_mont_mul_128(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 12016 sp_4096_mont_sqr_128(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 12017 sp_4096_mont_mul_128(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 12018 sp_4096_mont_sqr_128(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 12019 sp_4096_mont_mul_128(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 12020 sp_4096_mont_sqr_128(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 12021 sp_4096_mont_mul_128(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 12022 sp_4096_mont_sqr_128(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 12023 sp_4096_mont_mul_128(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 12024
wolfSSL 16:8e0d178b1d1e 12025 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 12026 n = e[i--];
wolfSSL 16:8e0d178b1d1e 12027 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 12028 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 12029 c = 32;
wolfSSL 16:8e0d178b1d1e 12030 }
wolfSSL 16:8e0d178b1d1e 12031 c -= bits % 4;
wolfSSL 16:8e0d178b1d1e 12032 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 12033 c = 28;
wolfSSL 16:8e0d178b1d1e 12034 }
wolfSSL 16:8e0d178b1d1e 12035 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 12036 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 12037 XMEMCPY(r, t[y], sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 12038 for (; i>=0 || c>=4; ) {
wolfSSL 16:8e0d178b1d1e 12039 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 12040 n = e[i--];
wolfSSL 16:8e0d178b1d1e 12041 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 12042 n <<= 4;
wolfSSL 16:8e0d178b1d1e 12043 c = 28;
wolfSSL 16:8e0d178b1d1e 12044 }
wolfSSL 16:8e0d178b1d1e 12045 else if (c < 4) {
wolfSSL 16:8e0d178b1d1e 12046 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 12047 n = e[i--];
wolfSSL 16:8e0d178b1d1e 12048 c = 4 - c;
wolfSSL 16:8e0d178b1d1e 12049 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 12050 n <<= c;
wolfSSL 16:8e0d178b1d1e 12051 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 12052 }
wolfSSL 16:8e0d178b1d1e 12053 else {
wolfSSL 16:8e0d178b1d1e 12054 y = (n >> 28) & 0xf;
wolfSSL 16:8e0d178b1d1e 12055 n <<= 4;
wolfSSL 16:8e0d178b1d1e 12056 c -= 4;
wolfSSL 16:8e0d178b1d1e 12057 }
wolfSSL 16:8e0d178b1d1e 12058
wolfSSL 16:8e0d178b1d1e 12059 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12060 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12061 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12062 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12063
wolfSSL 16:8e0d178b1d1e 12064 sp_4096_mont_mul_128(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 12065 }
wolfSSL 16:8e0d178b1d1e 12066
wolfSSL 16:8e0d178b1d1e 12067 XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);
wolfSSL 16:8e0d178b1d1e 12068 sp_4096_mont_reduce_128(r, m, mp);
wolfSSL 16:8e0d178b1d1e 12069
wolfSSL 16:8e0d178b1d1e 12070 mask = 0 - (sp_4096_cmp_128(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 12071 sp_4096_cond_sub_128(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 12072 }
wolfSSL 16:8e0d178b1d1e 12073
wolfSSL 16:8e0d178b1d1e 12074 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 12075 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 12076 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 12077 }
wolfSSL 16:8e0d178b1d1e 12078 #endif
wolfSSL 16:8e0d178b1d1e 12079
wolfSSL 16:8e0d178b1d1e 12080 return err;
wolfSSL 16:8e0d178b1d1e 12081 }
wolfSSL 16:8e0d178b1d1e 12082 #else
wolfSSL 16:8e0d178b1d1e 12083 /* Modular exponentiate a to the e mod m. (r = a^e mod m)
wolfSSL 16:8e0d178b1d1e 12084 *
wolfSSL 16:8e0d178b1d1e 12085 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 12086 * a A single precision number being exponentiated.
wolfSSL 16:8e0d178b1d1e 12087 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 12088 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 12089 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 12090 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 12091 */
wolfSSL 16:8e0d178b1d1e 12092 static int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e,
wolfSSL 16:8e0d178b1d1e 12093 int bits, const sp_digit* m, int reduceA)
wolfSSL 16:8e0d178b1d1e 12094 {
wolfSSL 16:8e0d178b1d1e 12095 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 12096 sp_digit t[32][256];
wolfSSL 16:8e0d178b1d1e 12097 #else
wolfSSL 16:8e0d178b1d1e 12098 sp_digit* t[32];
wolfSSL 16:8e0d178b1d1e 12099 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 12100 #endif
wolfSSL 16:8e0d178b1d1e 12101 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 12102 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 12103 sp_digit n;
wolfSSL 16:8e0d178b1d1e 12104 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 12105 int i;
wolfSSL 16:8e0d178b1d1e 12106 int c, y;
wolfSSL 16:8e0d178b1d1e 12107 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 12108
wolfSSL 16:8e0d178b1d1e 12109 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 12110 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 256, NULL,
wolfSSL 16:8e0d178b1d1e 12111 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 12112 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 12113 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 12114 }
wolfSSL 16:8e0d178b1d1e 12115 #endif
wolfSSL 16:8e0d178b1d1e 12116
wolfSSL 16:8e0d178b1d1e 12117 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12118 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 12119 for (i=0; i<32; i++) {
wolfSSL 16:8e0d178b1d1e 12120 t[i] = td + i * 256;
wolfSSL 16:8e0d178b1d1e 12121 }
wolfSSL 16:8e0d178b1d1e 12122 #endif
wolfSSL 16:8e0d178b1d1e 12123 norm = t[0];
wolfSSL 16:8e0d178b1d1e 12124
wolfSSL 16:8e0d178b1d1e 12125 sp_4096_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 12126 sp_4096_mont_norm_128(norm, m);
wolfSSL 16:8e0d178b1d1e 12127
wolfSSL 16:8e0d178b1d1e 12128 XMEMSET(t[1], 0, sizeof(sp_digit) * 128U);
wolfSSL 16:8e0d178b1d1e 12129 if (reduceA != 0) {
wolfSSL 16:8e0d178b1d1e 12130 err = sp_4096_mod_128(t[1] + 128, a, m);
wolfSSL 16:8e0d178b1d1e 12131 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12132 err = sp_4096_mod_128(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 12133 }
wolfSSL 16:8e0d178b1d1e 12134 }
wolfSSL 16:8e0d178b1d1e 12135 else {
wolfSSL 16:8e0d178b1d1e 12136 XMEMCPY(t[1] + 128, a, sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 12137 err = sp_4096_mod_128(t[1], t[1], m);
wolfSSL 16:8e0d178b1d1e 12138 }
wolfSSL 16:8e0d178b1d1e 12139 }
wolfSSL 16:8e0d178b1d1e 12140
wolfSSL 16:8e0d178b1d1e 12141 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12142 sp_4096_mont_sqr_128(t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 12143 sp_4096_mont_mul_128(t[ 3], t[ 2], t[ 1], m, mp);
wolfSSL 16:8e0d178b1d1e 12144 sp_4096_mont_sqr_128(t[ 4], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 12145 sp_4096_mont_mul_128(t[ 5], t[ 3], t[ 2], m, mp);
wolfSSL 16:8e0d178b1d1e 12146 sp_4096_mont_sqr_128(t[ 6], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 12147 sp_4096_mont_mul_128(t[ 7], t[ 4], t[ 3], m, mp);
wolfSSL 16:8e0d178b1d1e 12148 sp_4096_mont_sqr_128(t[ 8], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 12149 sp_4096_mont_mul_128(t[ 9], t[ 5], t[ 4], m, mp);
wolfSSL 16:8e0d178b1d1e 12150 sp_4096_mont_sqr_128(t[10], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 12151 sp_4096_mont_mul_128(t[11], t[ 6], t[ 5], m, mp);
wolfSSL 16:8e0d178b1d1e 12152 sp_4096_mont_sqr_128(t[12], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 12153 sp_4096_mont_mul_128(t[13], t[ 7], t[ 6], m, mp);
wolfSSL 16:8e0d178b1d1e 12154 sp_4096_mont_sqr_128(t[14], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 12155 sp_4096_mont_mul_128(t[15], t[ 8], t[ 7], m, mp);
wolfSSL 16:8e0d178b1d1e 12156 sp_4096_mont_sqr_128(t[16], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 12157 sp_4096_mont_mul_128(t[17], t[ 9], t[ 8], m, mp);
wolfSSL 16:8e0d178b1d1e 12158 sp_4096_mont_sqr_128(t[18], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 12159 sp_4096_mont_mul_128(t[19], t[10], t[ 9], m, mp);
wolfSSL 16:8e0d178b1d1e 12160 sp_4096_mont_sqr_128(t[20], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 12161 sp_4096_mont_mul_128(t[21], t[11], t[10], m, mp);
wolfSSL 16:8e0d178b1d1e 12162 sp_4096_mont_sqr_128(t[22], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 12163 sp_4096_mont_mul_128(t[23], t[12], t[11], m, mp);
wolfSSL 16:8e0d178b1d1e 12164 sp_4096_mont_sqr_128(t[24], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 12165 sp_4096_mont_mul_128(t[25], t[13], t[12], m, mp);
wolfSSL 16:8e0d178b1d1e 12166 sp_4096_mont_sqr_128(t[26], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 12167 sp_4096_mont_mul_128(t[27], t[14], t[13], m, mp);
wolfSSL 16:8e0d178b1d1e 12168 sp_4096_mont_sqr_128(t[28], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 12169 sp_4096_mont_mul_128(t[29], t[15], t[14], m, mp);
wolfSSL 16:8e0d178b1d1e 12170 sp_4096_mont_sqr_128(t[30], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 12171 sp_4096_mont_mul_128(t[31], t[16], t[15], m, mp);
wolfSSL 16:8e0d178b1d1e 12172
wolfSSL 16:8e0d178b1d1e 12173 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 12174 n = e[i--];
wolfSSL 16:8e0d178b1d1e 12175 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 12176 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 12177 c = 32;
wolfSSL 16:8e0d178b1d1e 12178 }
wolfSSL 16:8e0d178b1d1e 12179 c -= bits % 5;
wolfSSL 16:8e0d178b1d1e 12180 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 12181 c = 27;
wolfSSL 16:8e0d178b1d1e 12182 }
wolfSSL 16:8e0d178b1d1e 12183 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 12184 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 12185 XMEMCPY(r, t[y], sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 12186 for (; i>=0 || c>=5; ) {
wolfSSL 16:8e0d178b1d1e 12187 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 12188 n = e[i--];
wolfSSL 16:8e0d178b1d1e 12189 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 12190 n <<= 5;
wolfSSL 16:8e0d178b1d1e 12191 c = 27;
wolfSSL 16:8e0d178b1d1e 12192 }
wolfSSL 16:8e0d178b1d1e 12193 else if (c < 5) {
wolfSSL 16:8e0d178b1d1e 12194 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 12195 n = e[i--];
wolfSSL 16:8e0d178b1d1e 12196 c = 5 - c;
wolfSSL 16:8e0d178b1d1e 12197 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 12198 n <<= c;
wolfSSL 16:8e0d178b1d1e 12199 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 12200 }
wolfSSL 16:8e0d178b1d1e 12201 else {
wolfSSL 16:8e0d178b1d1e 12202 y = (n >> 27) & 0x1f;
wolfSSL 16:8e0d178b1d1e 12203 n <<= 5;
wolfSSL 16:8e0d178b1d1e 12204 c -= 5;
wolfSSL 16:8e0d178b1d1e 12205 }
wolfSSL 16:8e0d178b1d1e 12206
wolfSSL 16:8e0d178b1d1e 12207 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12208 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12209 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12210 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12211 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12212
wolfSSL 16:8e0d178b1d1e 12213 sp_4096_mont_mul_128(r, r, t[y], m, mp);
wolfSSL 16:8e0d178b1d1e 12214 }
wolfSSL 16:8e0d178b1d1e 12215
wolfSSL 16:8e0d178b1d1e 12216 XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);
wolfSSL 16:8e0d178b1d1e 12217 sp_4096_mont_reduce_128(r, m, mp);
wolfSSL 16:8e0d178b1d1e 12218
wolfSSL 16:8e0d178b1d1e 12219 mask = 0 - (sp_4096_cmp_128(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 12220 sp_4096_cond_sub_128(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 12221 }
wolfSSL 16:8e0d178b1d1e 12222
wolfSSL 16:8e0d178b1d1e 12223 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 12224 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 12225 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 12226 }
wolfSSL 16:8e0d178b1d1e 12227 #endif
wolfSSL 16:8e0d178b1d1e 12228
wolfSSL 16:8e0d178b1d1e 12229 return err;
wolfSSL 16:8e0d178b1d1e 12230 }
wolfSSL 16:8e0d178b1d1e 12231 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 12232 #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 12233
wolfSSL 16:8e0d178b1d1e 12234 #ifdef WOLFSSL_HAVE_SP_RSA
wolfSSL 16:8e0d178b1d1e 12235 /* RSA public key operation.
wolfSSL 16:8e0d178b1d1e 12236 *
wolfSSL 16:8e0d178b1d1e 12237 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 16:8e0d178b1d1e 12238 * inLen Number of bytes in base.
wolfSSL 16:8e0d178b1d1e 12239 * em Public exponent.
wolfSSL 16:8e0d178b1d1e 12240 * mm Modulus.
wolfSSL 16:8e0d178b1d1e 12241 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 16:8e0d178b1d1e 12242 * Must be at least 512 bytes long.
wolfSSL 16:8e0d178b1d1e 12243 * outLen Number of bytes in result.
wolfSSL 16:8e0d178b1d1e 12244 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 16:8e0d178b1d1e 12245 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 16:8e0d178b1d1e 12246 */
wolfSSL 16:8e0d178b1d1e 12247 int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm,
wolfSSL 16:8e0d178b1d1e 12248 byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 12249 {
wolfSSL 16:8e0d178b1d1e 12250 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 12251 sp_digit a[256], m[128], r[256];
wolfSSL 16:8e0d178b1d1e 12252 #else
wolfSSL 16:8e0d178b1d1e 12253 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 12254 sp_digit* a;
wolfSSL 16:8e0d178b1d1e 12255 sp_digit* m;
wolfSSL 16:8e0d178b1d1e 12256 sp_digit* r;
wolfSSL 16:8e0d178b1d1e 12257 #endif
wolfSSL 16:8e0d178b1d1e 12258 sp_digit *ah;
wolfSSL 16:8e0d178b1d1e 12259 sp_digit e[1];
wolfSSL 16:8e0d178b1d1e 12260 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 12261
wolfSSL 16:8e0d178b1d1e 12262 if (*outLen < 512)
wolfSSL 16:8e0d178b1d1e 12263 err = MP_TO_E;
wolfSSL 16:8e0d178b1d1e 12264 if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 512 ||
wolfSSL 16:8e0d178b1d1e 12265 mp_count_bits(mm) != 4096))
wolfSSL 16:8e0d178b1d1e 12266 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 12267
wolfSSL 16:8e0d178b1d1e 12268 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 12269 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12270 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 128 * 5, NULL,
wolfSSL 16:8e0d178b1d1e 12271 DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 12272 if (d == NULL)
wolfSSL 16:8e0d178b1d1e 12273 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 12274 }
wolfSSL 16:8e0d178b1d1e 12275
wolfSSL 16:8e0d178b1d1e 12276 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12277 a = d;
wolfSSL 16:8e0d178b1d1e 12278 r = a + 128 * 2;
wolfSSL 16:8e0d178b1d1e 12279 m = r + 128 * 2;
wolfSSL 16:8e0d178b1d1e 12280 }
wolfSSL 16:8e0d178b1d1e 12281 #endif
wolfSSL 16:8e0d178b1d1e 12282
wolfSSL 16:8e0d178b1d1e 12283 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12284 ah = a + 128;
wolfSSL 16:8e0d178b1d1e 12285
wolfSSL 16:8e0d178b1d1e 12286 sp_4096_from_bin(ah, 128, in, inLen);
wolfSSL 16:8e0d178b1d1e 12287 #if DIGIT_BIT >= 32
wolfSSL 16:8e0d178b1d1e 12288 e[0] = em->dp[0];
wolfSSL 16:8e0d178b1d1e 12289 #else
wolfSSL 16:8e0d178b1d1e 12290 e[0] = em->dp[0];
wolfSSL 16:8e0d178b1d1e 12291 if (em->used > 1) {
wolfSSL 16:8e0d178b1d1e 12292 e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 12293 }
wolfSSL 16:8e0d178b1d1e 12294 #endif
wolfSSL 16:8e0d178b1d1e 12295 if (e[0] == 0) {
wolfSSL 16:8e0d178b1d1e 12296 err = MP_EXPTMOD_E;
wolfSSL 16:8e0d178b1d1e 12297 }
wolfSSL 16:8e0d178b1d1e 12298 }
wolfSSL 16:8e0d178b1d1e 12299 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12300 sp_4096_from_mp(m, 128, mm);
wolfSSL 16:8e0d178b1d1e 12301
wolfSSL 16:8e0d178b1d1e 12302 if (e[0] == 0x3) {
wolfSSL 16:8e0d178b1d1e 12303 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12304 sp_4096_sqr_128(r, ah);
wolfSSL 16:8e0d178b1d1e 12305 err = sp_4096_mod_128_cond(r, r, m);
wolfSSL 16:8e0d178b1d1e 12306 }
wolfSSL 16:8e0d178b1d1e 12307 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12308 sp_4096_mul_128(r, ah, r);
wolfSSL 16:8e0d178b1d1e 12309 err = sp_4096_mod_128_cond(r, r, m);
wolfSSL 16:8e0d178b1d1e 12310 }
wolfSSL 16:8e0d178b1d1e 12311 }
wolfSSL 16:8e0d178b1d1e 12312 else {
wolfSSL 16:8e0d178b1d1e 12313 int i;
wolfSSL 16:8e0d178b1d1e 12314 sp_digit mp;
wolfSSL 16:8e0d178b1d1e 12315
wolfSSL 16:8e0d178b1d1e 12316 sp_4096_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 12317
wolfSSL 16:8e0d178b1d1e 12318 /* Convert to Montgomery form. */
wolfSSL 16:8e0d178b1d1e 12319 XMEMSET(a, 0, sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 12320 err = sp_4096_mod_128_cond(a, a, m);
wolfSSL 16:8e0d178b1d1e 12321
wolfSSL 16:8e0d178b1d1e 12322 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12323 for (i = 31; i >= 0; i--) {
wolfSSL 16:8e0d178b1d1e 12324 if (e[0] >> i) {
wolfSSL 16:8e0d178b1d1e 12325 break;
wolfSSL 16:8e0d178b1d1e 12326 }
wolfSSL 16:8e0d178b1d1e 12327 }
wolfSSL 16:8e0d178b1d1e 12328
wolfSSL 16:8e0d178b1d1e 12329 XMEMCPY(r, a, sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 12330 for (i--; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 12331 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 12332 if (((e[0] >> i) & 1) == 1) {
wolfSSL 16:8e0d178b1d1e 12333 sp_4096_mont_mul_128(r, r, a, m, mp);
wolfSSL 16:8e0d178b1d1e 12334 }
wolfSSL 16:8e0d178b1d1e 12335 }
wolfSSL 16:8e0d178b1d1e 12336 XMEMSET(&r[128], 0, sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 12337 sp_4096_mont_reduce_128(r, m, mp);
wolfSSL 16:8e0d178b1d1e 12338
wolfSSL 16:8e0d178b1d1e 12339 for (i = 127; i > 0; i--) {
wolfSSL 16:8e0d178b1d1e 12340 if (r[i] != m[i]) {
wolfSSL 16:8e0d178b1d1e 12341 break;
wolfSSL 16:8e0d178b1d1e 12342 }
wolfSSL 16:8e0d178b1d1e 12343 }
wolfSSL 16:8e0d178b1d1e 12344 if (r[i] >= m[i]) {
wolfSSL 16:8e0d178b1d1e 12345 sp_4096_sub_in_place_128(r, m);
wolfSSL 16:8e0d178b1d1e 12346 }
wolfSSL 16:8e0d178b1d1e 12347 }
wolfSSL 16:8e0d178b1d1e 12348 }
wolfSSL 16:8e0d178b1d1e 12349 }
wolfSSL 16:8e0d178b1d1e 12350
wolfSSL 16:8e0d178b1d1e 12351 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12352 sp_4096_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 12353 *outLen = 512;
wolfSSL 16:8e0d178b1d1e 12354 }
wolfSSL 16:8e0d178b1d1e 12355
wolfSSL 16:8e0d178b1d1e 12356 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 12357 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 12358 XFREE(d, NULL, DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 12359 }
wolfSSL 16:8e0d178b1d1e 12360 #endif
wolfSSL 16:8e0d178b1d1e 12361
wolfSSL 16:8e0d178b1d1e 12362 return err;
wolfSSL 16:8e0d178b1d1e 12363 }
wolfSSL 16:8e0d178b1d1e 12364
wolfSSL 16:8e0d178b1d1e 12365 #if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)
wolfSSL 16:8e0d178b1d1e 12366 sp_digit* a;
wolfSSL 16:8e0d178b1d1e 12367 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 12368 sp_digit* m;
wolfSSL 16:8e0d178b1d1e 12369 sp_digit* r;
wolfSSL 16:8e0d178b1d1e 12370 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 12371
wolfSSL 16:8e0d178b1d1e 12372 (void)pm;
wolfSSL 16:8e0d178b1d1e 12373 (void)qm;
wolfSSL 16:8e0d178b1d1e 12374 (void)dpm;
wolfSSL 16:8e0d178b1d1e 12375 (void)dqm;
wolfSSL 16:8e0d178b1d1e 12376 (void)qim;
wolfSSL 16:8e0d178b1d1e 12377
wolfSSL 16:8e0d178b1d1e 12378 if (*outLen < 512U) {
wolfSSL 16:8e0d178b1d1e 12379 err = MP_TO_E;
wolfSSL 16:8e0d178b1d1e 12380 }
wolfSSL 16:8e0d178b1d1e 12381 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12382 if (mp_count_bits(dm) > 4096) {
wolfSSL 16:8e0d178b1d1e 12383 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 12384 }
wolfSSL 16:8e0d178b1d1e 12385 if (inLen > 512) {
wolfSSL 16:8e0d178b1d1e 12386 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 12387 }
wolfSSL 16:8e0d178b1d1e 12388 if (mp_count_bits(mm) != 4096) {
wolfSSL 16:8e0d178b1d1e 12389 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 12390 }
wolfSSL 16:8e0d178b1d1e 12391 }
wolfSSL 16:8e0d178b1d1e 12392
wolfSSL 16:8e0d178b1d1e 12393 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12394 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 128 * 4, NULL,
wolfSSL 16:8e0d178b1d1e 12395 DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 12396 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 12397 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 12398 }
wolfSSL 16:8e0d178b1d1e 12399 }
wolfSSL 16:8e0d178b1d1e 12400 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12401 a = d + 128;
wolfSSL 16:8e0d178b1d1e 12402 m = a + 256;
wolfSSL 16:8e0d178b1d1e 12403 r = a;
wolfSSL 16:8e0d178b1d1e 12404
wolfSSL 16:8e0d178b1d1e 12405 sp_4096_from_bin(a, 128, in, inLen);
wolfSSL 16:8e0d178b1d1e 12406 sp_4096_from_mp(d, 128, dm);
wolfSSL 16:8e0d178b1d1e 12407 sp_4096_from_mp(m, 128, mm);
wolfSSL 16:8e0d178b1d1e 12408 err = sp_4096_mod_exp_128(r, a, d, 4096, m, 0);
wolfSSL 16:8e0d178b1d1e 12409 }
wolfSSL 16:8e0d178b1d1e 12410 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12411 sp_4096_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 12412 *outLen = 512;
wolfSSL 16:8e0d178b1d1e 12413 }
wolfSSL 16:8e0d178b1d1e 12414
wolfSSL 16:8e0d178b1d1e 12415 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 12416 XMEMSET(d, 0, sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 12417 XFREE(d, NULL, DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 12418 }
wolfSSL 16:8e0d178b1d1e 12419
wolfSSL 16:8e0d178b1d1e 12420 return err;
wolfSSL 16:8e0d178b1d1e 12421 #else
wolfSSL 16:8e0d178b1d1e 12422 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
wolfSSL 16:8e0d178b1d1e 12423 /* Conditionally add a and b using the mask m.
wolfSSL 16:8e0d178b1d1e 12424 * m is -1 to add and 0 when not.
wolfSSL 16:8e0d178b1d1e 12425 *
wolfSSL 16:8e0d178b1d1e 12426 * r A single precision number representing conditional add result.
wolfSSL 16:8e0d178b1d1e 12427 * a A single precision number to add with.
wolfSSL 16:8e0d178b1d1e 12428 * b A single precision number to add.
wolfSSL 16:8e0d178b1d1e 12429 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 12430 */
wolfSSL 16:8e0d178b1d1e 12431 SP_NOINLINE static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 12432 sp_digit m)
wolfSSL 16:8e0d178b1d1e 12433 {
wolfSSL 16:8e0d178b1d1e 12434 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 12435
wolfSSL 16:8e0d178b1d1e 12436 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 12437 "mov r5, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12438 "lsl r5, r5, #8\n\t"
wolfSSL 16:8e0d178b1d1e 12439 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12440 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 12441 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 12442 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 12443 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 12444 "adds r5, %[c], #-1\n\t"
wolfSSL 16:8e0d178b1d1e 12445 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 12446 "adcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12447 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 12448 "adcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 12449 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 12450 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 12451 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 12452 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 12453 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 12454 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 12455 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 12456 );
wolfSSL 16:8e0d178b1d1e 12457
wolfSSL 16:8e0d178b1d1e 12458 return c;
wolfSSL 16:8e0d178b1d1e 12459 }
wolfSSL 16:8e0d178b1d1e 12460
wolfSSL 16:8e0d178b1d1e 12461 /* RSA private key operation.
wolfSSL 16:8e0d178b1d1e 12462 *
wolfSSL 16:8e0d178b1d1e 12463 * in Array of bytes representing the number to exponentiate, base.
wolfSSL 16:8e0d178b1d1e 12464 * inLen Number of bytes in base.
wolfSSL 16:8e0d178b1d1e 12465 * dm Private exponent.
wolfSSL 16:8e0d178b1d1e 12466 * pm First prime.
wolfSSL 16:8e0d178b1d1e 12467 * qm Second prime.
wolfSSL 16:8e0d178b1d1e 12468 * dpm First prime's CRT exponent.
wolfSSL 16:8e0d178b1d1e 12469 * dqm Second prime's CRT exponent.
wolfSSL 16:8e0d178b1d1e 12470 * qim Inverse of second prime mod p.
wolfSSL 16:8e0d178b1d1e 12471 * mm Modulus.
wolfSSL 16:8e0d178b1d1e 12472 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 16:8e0d178b1d1e 12473 * Must be at least 512 bytes long.
wolfSSL 16:8e0d178b1d1e 12474 * outLen Number of bytes in result.
wolfSSL 16:8e0d178b1d1e 12475 * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when
wolfSSL 16:8e0d178b1d1e 12476 * an array is too long and MEMORY_E when dynamic memory allocation fails.
wolfSSL 16:8e0d178b1d1e 12477 */
wolfSSL 16:8e0d178b1d1e 12478 int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm,
wolfSSL 16:8e0d178b1d1e 12479 mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,
wolfSSL 16:8e0d178b1d1e 12480 byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 12481 {
wolfSSL 16:8e0d178b1d1e 12482 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 12483 sp_digit a[128 * 2];
wolfSSL 16:8e0d178b1d1e 12484 sp_digit p[64], q[64], dp[64];
wolfSSL 16:8e0d178b1d1e 12485 sp_digit tmpa[128], tmpb[128];
wolfSSL 16:8e0d178b1d1e 12486 #else
wolfSSL 16:8e0d178b1d1e 12487 sp_digit* t = NULL;
wolfSSL 16:8e0d178b1d1e 12488 sp_digit* a;
wolfSSL 16:8e0d178b1d1e 12489 sp_digit* p;
wolfSSL 16:8e0d178b1d1e 12490 sp_digit* q;
wolfSSL 16:8e0d178b1d1e 12491 sp_digit* dp;
wolfSSL 16:8e0d178b1d1e 12492 sp_digit* tmpa;
wolfSSL 16:8e0d178b1d1e 12493 sp_digit* tmpb;
wolfSSL 16:8e0d178b1d1e 12494 #endif
wolfSSL 16:8e0d178b1d1e 12495 sp_digit* r;
wolfSSL 16:8e0d178b1d1e 12496 sp_digit* qi;
wolfSSL 16:8e0d178b1d1e 12497 sp_digit* dq;
wolfSSL 16:8e0d178b1d1e 12498 sp_digit c;
wolfSSL 16:8e0d178b1d1e 12499 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 12500
wolfSSL 16:8e0d178b1d1e 12501 (void)dm;
wolfSSL 16:8e0d178b1d1e 12502 (void)mm;
wolfSSL 16:8e0d178b1d1e 12503
wolfSSL 16:8e0d178b1d1e 12504 if (*outLen < 512)
wolfSSL 16:8e0d178b1d1e 12505 err = MP_TO_E;
wolfSSL 16:8e0d178b1d1e 12506 if (err == MP_OKAY && (inLen > 512 || mp_count_bits(mm) != 4096))
wolfSSL 16:8e0d178b1d1e 12507 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 12508
wolfSSL 16:8e0d178b1d1e 12509 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 12510 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12511 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 11, NULL,
wolfSSL 16:8e0d178b1d1e 12512 DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 12513 if (t == NULL)
wolfSSL 16:8e0d178b1d1e 12514 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 12515 }
wolfSSL 16:8e0d178b1d1e 12516 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12517 a = t;
wolfSSL 16:8e0d178b1d1e 12518 p = a + 128 * 2;
wolfSSL 16:8e0d178b1d1e 12519 q = p + 64;
wolfSSL 16:8e0d178b1d1e 12520 qi = dq = dp = q + 64;
wolfSSL 16:8e0d178b1d1e 12521 tmpa = qi + 64;
wolfSSL 16:8e0d178b1d1e 12522 tmpb = tmpa + 128;
wolfSSL 16:8e0d178b1d1e 12523
wolfSSL 16:8e0d178b1d1e 12524 r = t + 128;
wolfSSL 16:8e0d178b1d1e 12525 }
wolfSSL 16:8e0d178b1d1e 12526 #else
wolfSSL 16:8e0d178b1d1e 12527 #endif
wolfSSL 16:8e0d178b1d1e 12528
wolfSSL 16:8e0d178b1d1e 12529 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12530 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 12531 r = a;
wolfSSL 16:8e0d178b1d1e 12532 qi = dq = dp;
wolfSSL 16:8e0d178b1d1e 12533 #endif
wolfSSL 16:8e0d178b1d1e 12534 sp_4096_from_bin(a, 128, in, inLen);
wolfSSL 16:8e0d178b1d1e 12535 sp_4096_from_mp(p, 64, pm);
wolfSSL 16:8e0d178b1d1e 12536 sp_4096_from_mp(q, 64, qm);
wolfSSL 16:8e0d178b1d1e 12537 sp_4096_from_mp(dp, 64, dpm);
wolfSSL 16:8e0d178b1d1e 12538
wolfSSL 16:8e0d178b1d1e 12539 err = sp_2048_mod_exp_64(tmpa, a, dp, 2048, p, 1);
wolfSSL 16:8e0d178b1d1e 12540 }
wolfSSL 16:8e0d178b1d1e 12541 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12542 sp_4096_from_mp(dq, 64, dqm);
wolfSSL 16:8e0d178b1d1e 12543 err = sp_2048_mod_exp_64(tmpb, a, dq, 2048, q, 1);
wolfSSL 16:8e0d178b1d1e 12544 }
wolfSSL 16:8e0d178b1d1e 12545
wolfSSL 16:8e0d178b1d1e 12546 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12547 c = sp_2048_sub_in_place_64(tmpa, tmpb);
wolfSSL 16:8e0d178b1d1e 12548 c += sp_4096_cond_add_64(tmpa, tmpa, p, c);
wolfSSL 16:8e0d178b1d1e 12549 sp_4096_cond_add_64(tmpa, tmpa, p, c);
wolfSSL 16:8e0d178b1d1e 12550
wolfSSL 16:8e0d178b1d1e 12551 sp_2048_from_mp(qi, 64, qim);
wolfSSL 16:8e0d178b1d1e 12552 sp_2048_mul_64(tmpa, tmpa, qi);
wolfSSL 16:8e0d178b1d1e 12553 err = sp_2048_mod_64(tmpa, tmpa, p);
wolfSSL 16:8e0d178b1d1e 12554 }
wolfSSL 16:8e0d178b1d1e 12555
wolfSSL 16:8e0d178b1d1e 12556 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12557 sp_2048_mul_64(tmpa, q, tmpa);
wolfSSL 16:8e0d178b1d1e 12558 XMEMSET(&tmpb[64], 0, sizeof(sp_digit) * 64);
wolfSSL 16:8e0d178b1d1e 12559 sp_4096_add_128(r, tmpb, tmpa);
wolfSSL 16:8e0d178b1d1e 12560
wolfSSL 16:8e0d178b1d1e 12561 sp_4096_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 12562 *outLen = 512;
wolfSSL 16:8e0d178b1d1e 12563 }
wolfSSL 16:8e0d178b1d1e 12564
wolfSSL 16:8e0d178b1d1e 12565 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 12566 if (t != NULL) {
wolfSSL 16:8e0d178b1d1e 12567 XMEMSET(t, 0, sizeof(sp_digit) * 64 * 11);
wolfSSL 16:8e0d178b1d1e 12568 XFREE(t, NULL, DYNAMIC_TYPE_RSA);
wolfSSL 16:8e0d178b1d1e 12569 }
wolfSSL 16:8e0d178b1d1e 12570 #else
wolfSSL 16:8e0d178b1d1e 12571 XMEMSET(tmpa, 0, sizeof(tmpa));
wolfSSL 16:8e0d178b1d1e 12572 XMEMSET(tmpb, 0, sizeof(tmpb));
wolfSSL 16:8e0d178b1d1e 12573 XMEMSET(p, 0, sizeof(p));
wolfSSL 16:8e0d178b1d1e 12574 XMEMSET(q, 0, sizeof(q));
wolfSSL 16:8e0d178b1d1e 12575 XMEMSET(dp, 0, sizeof(dp));
wolfSSL 16:8e0d178b1d1e 12576 #endif
wolfSSL 16:8e0d178b1d1e 12577
wolfSSL 16:8e0d178b1d1e 12578 return err;
wolfSSL 16:8e0d178b1d1e 12579 }
wolfSSL 16:8e0d178b1d1e 12580 #endif /* WOLFSSL_RSA_PUBLIC_ONLY */
wolfSSL 16:8e0d178b1d1e 12581 #endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */
wolfSSL 16:8e0d178b1d1e 12582 #endif /* WOLFSSL_HAVE_SP_RSA */
wolfSSL 16:8e0d178b1d1e 12583 #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \
wolfSSL 16:8e0d178b1d1e 12584 !defined(WOLFSSL_RSA_PUBLIC_ONLY))
wolfSSL 16:8e0d178b1d1e 12585 /* Convert an array of sp_digit to an mp_int.
wolfSSL 16:8e0d178b1d1e 12586 *
wolfSSL 16:8e0d178b1d1e 12587 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 12588 * r A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 12589 */
wolfSSL 16:8e0d178b1d1e 12590 static int sp_4096_to_mp(const sp_digit* a, mp_int* r)
wolfSSL 16:8e0d178b1d1e 12591 {
wolfSSL 16:8e0d178b1d1e 12592 int err;
wolfSSL 16:8e0d178b1d1e 12593
wolfSSL 16:8e0d178b1d1e 12594 err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 16:8e0d178b1d1e 12595 if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
wolfSSL 16:8e0d178b1d1e 12596 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 12597 XMEMCPY(r->dp, a, sizeof(sp_digit) * 128);
wolfSSL 16:8e0d178b1d1e 12598 r->used = 128;
wolfSSL 16:8e0d178b1d1e 12599 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 12600 #elif DIGIT_BIT < 32
wolfSSL 16:8e0d178b1d1e 12601 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 12602
wolfSSL 16:8e0d178b1d1e 12603 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 12604 for (i = 0; i < 128; i++) {
wolfSSL 16:8e0d178b1d1e 12605 r->dp[j] |= (mp_digit)(a[i] << s);
wolfSSL 16:8e0d178b1d1e 12606 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 12607 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 12608 r->dp[++j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 12609 while (s + DIGIT_BIT <= 32) {
wolfSSL 16:8e0d178b1d1e 12610 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 12611 r->dp[j++] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 12612 if (s == SP_WORD_SIZE) {
wolfSSL 16:8e0d178b1d1e 12613 r->dp[j] = 0;
wolfSSL 16:8e0d178b1d1e 12614 }
wolfSSL 16:8e0d178b1d1e 12615 else {
wolfSSL 16:8e0d178b1d1e 12616 r->dp[j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 12617 }
wolfSSL 16:8e0d178b1d1e 12618 }
wolfSSL 16:8e0d178b1d1e 12619 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 12620 }
wolfSSL 16:8e0d178b1d1e 12621 r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 12622 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 12623 #else
wolfSSL 16:8e0d178b1d1e 12624 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 12625
wolfSSL 16:8e0d178b1d1e 12626 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 12627 for (i = 0; i < 128; i++) {
wolfSSL 16:8e0d178b1d1e 12628 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 16:8e0d178b1d1e 12629 if (s + 32 >= DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 12630 #if DIGIT_BIT != 32 && DIGIT_BIT != 64
wolfSSL 16:8e0d178b1d1e 12631 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 12632 #endif
wolfSSL 16:8e0d178b1d1e 12633 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 12634 r->dp[++j] = a[i] >> s;
wolfSSL 16:8e0d178b1d1e 12635 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 12636 }
wolfSSL 16:8e0d178b1d1e 12637 else {
wolfSSL 16:8e0d178b1d1e 12638 s += 32;
wolfSSL 16:8e0d178b1d1e 12639 }
wolfSSL 16:8e0d178b1d1e 12640 }
wolfSSL 16:8e0d178b1d1e 12641 r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 12642 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 12643 #endif
wolfSSL 16:8e0d178b1d1e 12644 }
wolfSSL 16:8e0d178b1d1e 12645
wolfSSL 16:8e0d178b1d1e 12646 return err;
wolfSSL 16:8e0d178b1d1e 12647 }
wolfSSL 16:8e0d178b1d1e 12648
wolfSSL 16:8e0d178b1d1e 12649 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 16:8e0d178b1d1e 12650 *
wolfSSL 16:8e0d178b1d1e 12651 * base Base. MP integer.
wolfSSL 16:8e0d178b1d1e 12652 * exp Exponent. MP integer.
wolfSSL 16:8e0d178b1d1e 12653 * mod Modulus. MP integer.
wolfSSL 16:8e0d178b1d1e 12654 * res Result. MP integer.
wolfSSL 16:8e0d178b1d1e 12655 * returns 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 16:8e0d178b1d1e 12656 * and MEMORY_E if memory allocation fails.
wolfSSL 16:8e0d178b1d1e 12657 */
wolfSSL 16:8e0d178b1d1e 12658 int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)
wolfSSL 16:8e0d178b1d1e 12659 {
wolfSSL 16:8e0d178b1d1e 12660 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 12661 sp_digit b[256], e[128], m[128];
wolfSSL 16:8e0d178b1d1e 12662 sp_digit* r = b;
wolfSSL 16:8e0d178b1d1e 12663 int expBits = mp_count_bits(exp);
wolfSSL 16:8e0d178b1d1e 12664
wolfSSL 16:8e0d178b1d1e 12665 if (mp_count_bits(base) > 4096) {
wolfSSL 16:8e0d178b1d1e 12666 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 12667 }
wolfSSL 16:8e0d178b1d1e 12668
wolfSSL 16:8e0d178b1d1e 12669 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12670 if (expBits > 4096) {
wolfSSL 16:8e0d178b1d1e 12671 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 12672 }
wolfSSL 16:8e0d178b1d1e 12673 }
wolfSSL 16:8e0d178b1d1e 12674
wolfSSL 16:8e0d178b1d1e 12675 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12676 if (mp_count_bits(mod) != 4096) {
wolfSSL 16:8e0d178b1d1e 12677 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 12678 }
wolfSSL 16:8e0d178b1d1e 12679 }
wolfSSL 16:8e0d178b1d1e 12680
wolfSSL 16:8e0d178b1d1e 12681 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12682 sp_4096_from_mp(b, 128, base);
wolfSSL 16:8e0d178b1d1e 12683 sp_4096_from_mp(e, 128, exp);
wolfSSL 16:8e0d178b1d1e 12684 sp_4096_from_mp(m, 128, mod);
wolfSSL 16:8e0d178b1d1e 12685
wolfSSL 16:8e0d178b1d1e 12686 err = sp_4096_mod_exp_128(r, b, e, expBits, m, 0);
wolfSSL 16:8e0d178b1d1e 12687 }
wolfSSL 16:8e0d178b1d1e 12688
wolfSSL 16:8e0d178b1d1e 12689 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 12690 err = sp_4096_to_mp(r, res);
wolfSSL 16:8e0d178b1d1e 12691 }
wolfSSL 16:8e0d178b1d1e 12692
wolfSSL 16:8e0d178b1d1e 12693 XMEMSET(e, 0, sizeof(e));
wolfSSL 16:8e0d178b1d1e 12694
wolfSSL 16:8e0d178b1d1e 12695 return err;
wolfSSL 16:8e0d178b1d1e 12696 }
wolfSSL 16:8e0d178b1d1e 12697
wolfSSL 16:8e0d178b1d1e 12698 #ifdef WOLFSSL_HAVE_SP_DH
wolfSSL 16:8e0d178b1d1e 12699
wolfSSL 16:8e0d178b1d1e 12700 #ifdef HAVE_FFDHE_4096
wolfSSL 16:8e0d178b1d1e 12701 static void sp_4096_lshift_128(sp_digit* r, sp_digit* a, byte n)
wolfSSL 16:8e0d178b1d1e 12702 {
wolfSSL 16:8e0d178b1d1e 12703 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 12704 "mov r6, #31\n\t"
wolfSSL 16:8e0d178b1d1e 12705 "sub r6, r6, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12706 "add %[a], %[a], #448\n\t"
wolfSSL 16:8e0d178b1d1e 12707 "add %[r], %[r], #448\n\t"
wolfSSL 16:8e0d178b1d1e 12708 "ldr r3, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 12709 "lsr r4, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12710 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12711 "lsr r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12712 "ldr r2, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 12713 "str r4, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 12714 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12715 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12716 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12717 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12718 "ldr r4, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 12719 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 12720 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12721 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12722 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12723 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12724 "ldr r3, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 12725 "str r2, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 12726 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12727 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12728 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12729 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12730 "ldr r2, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 12731 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 12732 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12733 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12734 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12735 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12736 "ldr r4, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 12737 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 12738 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12739 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12740 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12741 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12742 "ldr r3, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 12743 "str r2, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 12744 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12745 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12746 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12747 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12748 "ldr r2, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 12749 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 12750 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12751 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12752 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12753 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12754 "ldr r4, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 12755 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 12756 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12757 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12758 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12759 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12760 "ldr r3, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 12761 "str r2, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 12762 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12763 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12764 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12765 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12766 "ldr r2, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 12767 "str r4, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 12768 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12769 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12770 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12771 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12772 "ldr r4, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 12773 "str r3, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 12774 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12775 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12776 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12777 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12778 "ldr r3, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 12779 "str r2, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 12780 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12781 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12782 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12783 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12784 "ldr r2, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 12785 "str r4, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 12786 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12787 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12788 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12789 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12790 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 12791 "str r3, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 12792 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12793 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12794 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12795 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12796 "ldr r3, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 12797 "str r2, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 12798 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12799 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12800 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12801 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12802 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 12803 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 12804 "ldr r2, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 12805 "str r4, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 12806 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12807 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12808 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12809 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12810 "ldr r4, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 12811 "str r3, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 12812 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12813 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12814 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12815 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12816 "ldr r3, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 12817 "str r2, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 12818 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12819 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12820 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12821 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12822 "ldr r2, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 12823 "str r4, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 12824 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12825 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12826 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12827 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12828 "ldr r4, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 12829 "str r3, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 12830 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12831 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12832 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12833 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12834 "ldr r3, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 12835 "str r2, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 12836 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12837 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12838 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12839 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12840 "ldr r2, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 12841 "str r4, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 12842 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12843 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12844 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12845 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12846 "ldr r4, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 12847 "str r3, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 12848 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12849 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12850 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12851 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12852 "ldr r3, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 12853 "str r2, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 12854 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12855 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12856 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12857 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12858 "ldr r2, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 12859 "str r4, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 12860 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12861 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12862 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12863 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12864 "ldr r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 12865 "str r3, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 12866 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12867 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12868 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12869 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12870 "ldr r3, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 12871 "str r2, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 12872 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12873 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12874 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12875 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12876 "ldr r2, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 12877 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 12878 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12879 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12880 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12881 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12882 "ldr r4, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 12883 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 12884 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12885 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12886 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12887 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12888 "ldr r3, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 12889 "str r2, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 12890 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12891 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12892 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12893 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12894 "ldr r2, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 12895 "str r4, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 12896 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12897 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12898 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12899 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12900 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 12901 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 12902 "ldr r4, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 12903 "str r3, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 12904 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12905 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12906 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12907 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12908 "ldr r3, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 12909 "str r2, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 12910 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12911 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12912 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12913 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12914 "ldr r2, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 12915 "str r4, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 12916 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12917 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12918 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12919 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12920 "ldr r4, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 12921 "str r3, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 12922 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12923 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12924 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12925 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12926 "ldr r3, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 12927 "str r2, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 12928 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12929 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12930 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12931 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12932 "ldr r2, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 12933 "str r4, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 12934 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12935 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12936 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12937 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12938 "ldr r4, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 12939 "str r3, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 12940 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12941 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12942 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12943 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12944 "ldr r3, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 12945 "str r2, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 12946 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12947 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12948 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12949 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12950 "ldr r2, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 12951 "str r4, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 12952 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12953 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12954 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12955 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12956 "ldr r4, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 12957 "str r3, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 12958 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12959 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12960 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12961 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12962 "ldr r3, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 12963 "str r2, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 12964 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12965 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12966 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12967 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12968 "ldr r2, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 12969 "str r4, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 12970 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12971 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12972 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12973 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12974 "ldr r4, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 12975 "str r3, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 12976 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12977 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12978 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12979 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12980 "ldr r3, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 12981 "str r2, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 12982 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12983 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12984 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12985 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12986 "ldr r2, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 12987 "str r4, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 12988 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12989 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12990 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12991 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12992 "ldr r4, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 12993 "str r3, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 12994 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 12995 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 12996 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 12997 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 12998 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 12999 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 13000 "ldr r3, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13001 "str r2, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 13002 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13003 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13004 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13005 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13006 "ldr r2, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13007 "str r4, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 13008 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13009 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13010 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13011 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13012 "ldr r4, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13013 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13014 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13015 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13016 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13017 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13018 "ldr r3, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13019 "str r2, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13020 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13021 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13022 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13023 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13024 "ldr r2, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13025 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13026 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13027 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13028 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13029 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13030 "ldr r4, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13031 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13032 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13033 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13034 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13035 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13036 "ldr r3, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13037 "str r2, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13038 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13039 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13040 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13041 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13042 "ldr r2, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13043 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13044 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13045 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13046 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13047 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13048 "ldr r4, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13049 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13050 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13051 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13052 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13053 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13054 "ldr r3, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13055 "str r2, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13056 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13057 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13058 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13059 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13060 "ldr r2, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13061 "str r4, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13062 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13063 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13064 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13065 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13066 "ldr r4, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13067 "str r3, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13068 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13069 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13070 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13071 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13072 "ldr r3, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13073 "str r2, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13074 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13075 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13076 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13077 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13078 "ldr r2, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13079 "str r4, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13080 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13081 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13082 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13083 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13084 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 13085 "str r3, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13086 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13087 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13088 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13089 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13090 "ldr r3, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 13091 "str r2, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13092 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13093 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13094 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13095 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13096 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 13097 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 13098 "ldr r2, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13099 "str r4, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 13100 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13101 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13102 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13103 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13104 "ldr r4, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13105 "str r3, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 13106 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13107 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13108 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13109 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13110 "ldr r3, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13111 "str r2, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13112 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13113 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13114 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13115 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13116 "ldr r2, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13117 "str r4, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13118 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13119 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13120 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13121 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13122 "ldr r4, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13123 "str r3, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13124 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13125 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13126 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13127 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13128 "ldr r3, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13129 "str r2, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13130 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13131 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13132 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13133 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13134 "ldr r2, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13135 "str r4, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13136 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13137 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13138 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13139 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13140 "ldr r4, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13141 "str r3, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13142 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13143 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13144 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13145 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13146 "ldr r3, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13147 "str r2, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13148 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13149 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13150 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13151 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13152 "ldr r2, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13153 "str r4, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13154 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13155 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13156 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13157 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13158 "ldr r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13159 "str r3, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13160 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13161 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13162 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13163 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13164 "ldr r3, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13165 "str r2, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13166 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13167 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13168 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13169 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13170 "ldr r2, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13171 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13172 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13173 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13174 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13175 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13176 "ldr r4, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13177 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13178 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13179 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13180 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13181 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13182 "ldr r3, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 13183 "str r2, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13184 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13185 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13186 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13187 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13188 "ldr r2, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 13189 "str r4, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13190 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13191 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13192 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13193 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13194 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 13195 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 13196 "ldr r4, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13197 "str r3, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 13198 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13199 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13200 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13201 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13202 "ldr r3, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13203 "str r2, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 13204 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13205 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13206 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13207 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13208 "ldr r2, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13209 "str r4, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13210 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13211 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13212 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13213 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13214 "ldr r4, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13215 "str r3, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13216 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13217 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13218 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13219 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13220 "ldr r3, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13221 "str r2, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13222 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13223 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13224 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13225 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13226 "ldr r2, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13227 "str r4, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13228 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13229 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13230 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13231 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13232 "ldr r4, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13233 "str r3, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13234 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13235 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13236 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13237 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13238 "ldr r3, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13239 "str r2, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13240 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13241 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13242 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13243 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13244 "ldr r2, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13245 "str r4, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13246 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13247 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13248 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13249 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13250 "ldr r4, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13251 "str r3, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13252 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13253 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13254 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13255 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13256 "ldr r3, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13257 "str r2, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13258 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13259 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13260 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13261 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13262 "ldr r2, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13263 "str r4, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13264 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13265 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13266 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13267 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13268 "ldr r4, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13269 "str r3, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13270 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13271 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13272 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13273 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13274 "ldr r3, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13275 "str r2, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13276 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13277 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13278 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13279 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13280 "ldr r2, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 13281 "str r4, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13282 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13283 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13284 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13285 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13286 "ldr r4, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 13287 "str r3, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13288 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13289 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13290 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13291 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13292 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 13293 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 13294 "ldr r3, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13295 "str r2, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 13296 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13297 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13298 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13299 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13300 "ldr r2, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13301 "str r4, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 13302 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13303 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13304 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13305 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13306 "ldr r4, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13307 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13308 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13309 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13310 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13311 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13312 "ldr r3, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13313 "str r2, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13314 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13315 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13316 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13317 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13318 "ldr r2, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13319 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13320 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13321 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13322 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13323 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13324 "ldr r4, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13325 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13326 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13327 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13328 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13329 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13330 "ldr r3, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13331 "str r2, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13332 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13333 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13334 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13335 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13336 "ldr r2, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13337 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13338 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13339 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13340 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13341 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13342 "ldr r4, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13343 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13344 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13345 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13346 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13347 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13348 "ldr r3, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13349 "str r2, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13350 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13351 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13352 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13353 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13354 "ldr r2, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13355 "str r4, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13356 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13357 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13358 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13359 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13360 "ldr r4, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13361 "str r3, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13362 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13363 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13364 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13365 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13366 "ldr r3, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13367 "str r2, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13368 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13369 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13370 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13371 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13372 "ldr r2, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13373 "str r4, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13374 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13375 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13376 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13377 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13378 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 13379 "str r3, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13380 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13381 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13382 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13383 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13384 "ldr r3, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 13385 "str r2, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13386 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13387 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13388 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13389 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13390 "sub %[a], %[a], #64\n\t"
wolfSSL 16:8e0d178b1d1e 13391 "sub %[r], %[r], #64\n\t"
wolfSSL 16:8e0d178b1d1e 13392 "ldr r2, [%[a], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13393 "str r4, [%[r], #68]\n\t"
wolfSSL 16:8e0d178b1d1e 13394 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13395 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13396 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13397 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13398 "ldr r4, [%[a], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13399 "str r3, [%[r], #64]\n\t"
wolfSSL 16:8e0d178b1d1e 13400 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13401 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13402 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13403 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13404 "ldr r3, [%[a], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13405 "str r2, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 13406 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13407 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13408 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13409 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13410 "ldr r2, [%[a], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13411 "str r4, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 13412 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13413 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13414 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13415 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13416 "ldr r4, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13417 "str r3, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 13418 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13419 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13420 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13421 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13422 "ldr r3, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13423 "str r2, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 13424 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13425 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13426 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13427 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13428 "ldr r2, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13429 "str r4, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 13430 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13431 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13432 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13433 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13434 "ldr r4, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13435 "str r3, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 13436 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13437 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13438 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13439 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13440 "ldr r3, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13441 "str r2, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 13442 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13443 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13444 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13445 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13446 "ldr r2, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13447 "str r4, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 13448 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13449 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13450 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13451 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13452 "ldr r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13453 "str r3, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 13454 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13455 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13456 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13457 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13458 "ldr r3, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13459 "str r2, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 13460 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13461 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13462 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13463 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13464 "ldr r2, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13465 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 13466 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13467 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13468 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13469 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13470 "ldr r4, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13471 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 13472 "lsr r5, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13473 "lsl r4, r4, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13474 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13475 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13476 "ldr r3, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 13477 "str r2, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 13478 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13479 "lsl r3, r3, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13480 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13481 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13482 "ldr r2, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 13483 "str r4, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 13484 "lsr r5, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 13485 "lsl r2, r2, %[n]\n\t"
wolfSSL 16:8e0d178b1d1e 13486 "lsr r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 13487 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 13488 "str r2, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 13489 "str r3, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 13490 :
wolfSSL 16:8e0d178b1d1e 13491 : [r] "r" (r), [a] "r" (a), [n] "r" (n)
wolfSSL 16:8e0d178b1d1e 13492 : "memory", "r2", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 13493 );
wolfSSL 16:8e0d178b1d1e 13494 }
wolfSSL 16:8e0d178b1d1e 13495
wolfSSL 16:8e0d178b1d1e 13496 /* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)
wolfSSL 16:8e0d178b1d1e 13497 *
wolfSSL 16:8e0d178b1d1e 13498 * r A single precision number that is the result of the operation.
wolfSSL 16:8e0d178b1d1e 13499 * e A single precision number that is the exponent.
wolfSSL 16:8e0d178b1d1e 13500 * bits The number of bits in the exponent.
wolfSSL 16:8e0d178b1d1e 13501 * m A single precision number that is the modulus.
wolfSSL 16:8e0d178b1d1e 13502 * returns 0 on success and MEMORY_E on dynamic memory allocation failure.
wolfSSL 16:8e0d178b1d1e 13503 */
wolfSSL 16:8e0d178b1d1e 13504 static int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits,
wolfSSL 16:8e0d178b1d1e 13505 const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 13506 {
wolfSSL 16:8e0d178b1d1e 13507 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 13508 sp_digit nd[256];
wolfSSL 16:8e0d178b1d1e 13509 sp_digit td[129];
wolfSSL 16:8e0d178b1d1e 13510 #else
wolfSSL 16:8e0d178b1d1e 13511 sp_digit* td;
wolfSSL 16:8e0d178b1d1e 13512 #endif
wolfSSL 16:8e0d178b1d1e 13513 sp_digit* norm;
wolfSSL 16:8e0d178b1d1e 13514 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 13515 sp_digit mp = 1;
wolfSSL 16:8e0d178b1d1e 13516 sp_digit n, o;
wolfSSL 16:8e0d178b1d1e 13517 sp_digit mask;
wolfSSL 16:8e0d178b1d1e 13518 int i;
wolfSSL 16:8e0d178b1d1e 13519 int c, y;
wolfSSL 16:8e0d178b1d1e 13520 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 13521
wolfSSL 16:8e0d178b1d1e 13522 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 13523 td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 385, NULL,
wolfSSL 16:8e0d178b1d1e 13524 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 13525 if (td == NULL) {
wolfSSL 16:8e0d178b1d1e 13526 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 13527 }
wolfSSL 16:8e0d178b1d1e 13528 #endif
wolfSSL 16:8e0d178b1d1e 13529
wolfSSL 16:8e0d178b1d1e 13530 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 13531 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 13532 norm = td;
wolfSSL 16:8e0d178b1d1e 13533 tmp = td + 256;
wolfSSL 16:8e0d178b1d1e 13534 #else
wolfSSL 16:8e0d178b1d1e 13535 norm = nd;
wolfSSL 16:8e0d178b1d1e 13536 tmp = td;
wolfSSL 16:8e0d178b1d1e 13537 #endif
wolfSSL 16:8e0d178b1d1e 13538
wolfSSL 16:8e0d178b1d1e 13539 sp_4096_mont_setup(m, &mp);
wolfSSL 16:8e0d178b1d1e 13540 sp_4096_mont_norm_128(norm, m);
wolfSSL 16:8e0d178b1d1e 13541
wolfSSL 16:8e0d178b1d1e 13542 i = (bits - 1) / 32;
wolfSSL 16:8e0d178b1d1e 13543 n = e[i--];
wolfSSL 16:8e0d178b1d1e 13544 c = bits & 31;
wolfSSL 16:8e0d178b1d1e 13545 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 13546 c = 32;
wolfSSL 16:8e0d178b1d1e 13547 }
wolfSSL 16:8e0d178b1d1e 13548 c -= bits % 5;
wolfSSL 16:8e0d178b1d1e 13549 if (c == 32) {
wolfSSL 16:8e0d178b1d1e 13550 c = 27;
wolfSSL 16:8e0d178b1d1e 13551 }
wolfSSL 16:8e0d178b1d1e 13552 y = (int)(n >> c);
wolfSSL 16:8e0d178b1d1e 13553 n <<= 32 - c;
wolfSSL 16:8e0d178b1d1e 13554 sp_4096_lshift_128(r, norm, y);
wolfSSL 16:8e0d178b1d1e 13555 for (; i>=0 || c>=5; ) {
wolfSSL 16:8e0d178b1d1e 13556 if (c == 0) {
wolfSSL 16:8e0d178b1d1e 13557 n = e[i--];
wolfSSL 16:8e0d178b1d1e 13558 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 13559 n <<= 5;
wolfSSL 16:8e0d178b1d1e 13560 c = 27;
wolfSSL 16:8e0d178b1d1e 13561 }
wolfSSL 16:8e0d178b1d1e 13562 else if (c < 5) {
wolfSSL 16:8e0d178b1d1e 13563 y = n >> 27;
wolfSSL 16:8e0d178b1d1e 13564 n = e[i--];
wolfSSL 16:8e0d178b1d1e 13565 c = 5 - c;
wolfSSL 16:8e0d178b1d1e 13566 y |= n >> (32 - c);
wolfSSL 16:8e0d178b1d1e 13567 n <<= c;
wolfSSL 16:8e0d178b1d1e 13568 c = 32 - c;
wolfSSL 16:8e0d178b1d1e 13569 }
wolfSSL 16:8e0d178b1d1e 13570 else {
wolfSSL 16:8e0d178b1d1e 13571 y = (n >> 27) & 0x1f;
wolfSSL 16:8e0d178b1d1e 13572 n <<= 5;
wolfSSL 16:8e0d178b1d1e 13573 c -= 5;
wolfSSL 16:8e0d178b1d1e 13574 }
wolfSSL 16:8e0d178b1d1e 13575
wolfSSL 16:8e0d178b1d1e 13576 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 13577 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 13578 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 13579 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 13580 sp_4096_mont_sqr_128(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 13581
wolfSSL 16:8e0d178b1d1e 13582 sp_4096_lshift_128(r, r, y);
wolfSSL 16:8e0d178b1d1e 13583 sp_4096_mul_d_128(tmp, norm, r[128]);
wolfSSL 16:8e0d178b1d1e 13584 r[128] = 0;
wolfSSL 16:8e0d178b1d1e 13585 o = sp_4096_add_128(r, r, tmp);
wolfSSL 16:8e0d178b1d1e 13586 sp_4096_cond_sub_128(r, r, m, (sp_digit)0 - o);
wolfSSL 16:8e0d178b1d1e 13587 }
wolfSSL 16:8e0d178b1d1e 13588
wolfSSL 16:8e0d178b1d1e 13589 XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);
wolfSSL 16:8e0d178b1d1e 13590 sp_4096_mont_reduce_128(r, m, mp);
wolfSSL 16:8e0d178b1d1e 13591
wolfSSL 16:8e0d178b1d1e 13592 mask = 0 - (sp_4096_cmp_128(r, m) >= 0);
wolfSSL 16:8e0d178b1d1e 13593 sp_4096_cond_sub_128(r, r, m, mask);
wolfSSL 16:8e0d178b1d1e 13594 }
wolfSSL 16:8e0d178b1d1e 13595
wolfSSL 16:8e0d178b1d1e 13596 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 13597 if (td != NULL) {
wolfSSL 16:8e0d178b1d1e 13598 XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 13599 }
wolfSSL 16:8e0d178b1d1e 13600 #endif
wolfSSL 16:8e0d178b1d1e 13601
wolfSSL 16:8e0d178b1d1e 13602 return err;
wolfSSL 16:8e0d178b1d1e 13603 }
wolfSSL 16:8e0d178b1d1e 13604 #endif /* HAVE_FFDHE_4096 */
wolfSSL 16:8e0d178b1d1e 13605
wolfSSL 16:8e0d178b1d1e 13606 /* Perform the modular exponentiation for Diffie-Hellman.
wolfSSL 16:8e0d178b1d1e 13607 *
wolfSSL 16:8e0d178b1d1e 13608 * base Base.
wolfSSL 16:8e0d178b1d1e 13609 * exp Array of bytes that is the exponent.
wolfSSL 16:8e0d178b1d1e 13610 * expLen Length of data, in bytes, in exponent.
wolfSSL 16:8e0d178b1d1e 13611 * mod Modulus.
wolfSSL 16:8e0d178b1d1e 13612 * out Buffer to hold big-endian bytes of exponentiation result.
wolfSSL 16:8e0d178b1d1e 13613 * Must be at least 512 bytes long.
wolfSSL 16:8e0d178b1d1e 13614 * outLen Length, in bytes, of exponentiation result.
wolfSSL 16:8e0d178b1d1e 13615 * returns 0 on success, MP_READ_E if there are too many bytes in an array
wolfSSL 16:8e0d178b1d1e 13616 * and MEMORY_E if memory allocation fails.
wolfSSL 16:8e0d178b1d1e 13617 */
wolfSSL 16:8e0d178b1d1e 13618 int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen,
wolfSSL 16:8e0d178b1d1e 13619 mp_int* mod, byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 13620 {
wolfSSL 16:8e0d178b1d1e 13621 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 13622 sp_digit b[256], e[128], m[128];
wolfSSL 16:8e0d178b1d1e 13623 sp_digit* r = b;
wolfSSL 16:8e0d178b1d1e 13624 word32 i;
wolfSSL 16:8e0d178b1d1e 13625
wolfSSL 16:8e0d178b1d1e 13626 if (mp_count_bits(base) > 4096) {
wolfSSL 16:8e0d178b1d1e 13627 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 13628 }
wolfSSL 16:8e0d178b1d1e 13629
wolfSSL 16:8e0d178b1d1e 13630 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 13631 if (expLen > 512) {
wolfSSL 16:8e0d178b1d1e 13632 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 13633 }
wolfSSL 16:8e0d178b1d1e 13634 }
wolfSSL 16:8e0d178b1d1e 13635
wolfSSL 16:8e0d178b1d1e 13636 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 13637 if (mp_count_bits(mod) != 4096) {
wolfSSL 16:8e0d178b1d1e 13638 err = MP_READ_E;
wolfSSL 16:8e0d178b1d1e 13639 }
wolfSSL 16:8e0d178b1d1e 13640 }
wolfSSL 16:8e0d178b1d1e 13641
wolfSSL 16:8e0d178b1d1e 13642 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 13643 sp_4096_from_mp(b, 128, base);
wolfSSL 16:8e0d178b1d1e 13644 sp_4096_from_bin(e, 128, exp, expLen);
wolfSSL 16:8e0d178b1d1e 13645 sp_4096_from_mp(m, 128, mod);
wolfSSL 16:8e0d178b1d1e 13646
wolfSSL 16:8e0d178b1d1e 13647 #ifdef HAVE_FFDHE_4096
wolfSSL 16:8e0d178b1d1e 13648 if (base->used == 1 && base->dp[0] == 2 && m[127] == (sp_digit)-1)
wolfSSL 16:8e0d178b1d1e 13649 err = sp_4096_mod_exp_2_128(r, e, expLen * 8, m);
wolfSSL 16:8e0d178b1d1e 13650 else
wolfSSL 16:8e0d178b1d1e 13651 #endif
wolfSSL 16:8e0d178b1d1e 13652 err = sp_4096_mod_exp_128(r, b, e, expLen * 8, m, 0);
wolfSSL 16:8e0d178b1d1e 13653
wolfSSL 16:8e0d178b1d1e 13654 }
wolfSSL 16:8e0d178b1d1e 13655
wolfSSL 16:8e0d178b1d1e 13656 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 13657 sp_4096_to_bin(r, out);
wolfSSL 16:8e0d178b1d1e 13658 *outLen = 512;
wolfSSL 16:8e0d178b1d1e 13659 for (i=0; i<512 && out[i] == 0; i++) {
wolfSSL 16:8e0d178b1d1e 13660 }
wolfSSL 16:8e0d178b1d1e 13661 *outLen -= i;
wolfSSL 16:8e0d178b1d1e 13662 XMEMMOVE(out, out + i, *outLen);
wolfSSL 16:8e0d178b1d1e 13663
wolfSSL 16:8e0d178b1d1e 13664 }
wolfSSL 16:8e0d178b1d1e 13665
wolfSSL 16:8e0d178b1d1e 13666 XMEMSET(e, 0, sizeof(e));
wolfSSL 16:8e0d178b1d1e 13667
wolfSSL 16:8e0d178b1d1e 13668 return err;
wolfSSL 16:8e0d178b1d1e 13669 }
wolfSSL 16:8e0d178b1d1e 13670 #endif /* WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 13671
wolfSSL 16:8e0d178b1d1e 13672 #endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */
wolfSSL 16:8e0d178b1d1e 13673
wolfSSL 16:8e0d178b1d1e 13674 #endif /* WOLFSSL_SP_4096 */
wolfSSL 16:8e0d178b1d1e 13675
wolfSSL 16:8e0d178b1d1e 13676 #endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */
wolfSSL 16:8e0d178b1d1e 13677 #ifdef WOLFSSL_HAVE_SP_ECC
wolfSSL 16:8e0d178b1d1e 13678 #ifndef WOLFSSL_SP_NO_256
wolfSSL 16:8e0d178b1d1e 13679
wolfSSL 16:8e0d178b1d1e 13680 /* Point structure to use. */
wolfSSL 16:8e0d178b1d1e 13681 typedef struct sp_point_256 {
wolfSSL 16:8e0d178b1d1e 13682 sp_digit x[2 * 8];
wolfSSL 16:8e0d178b1d1e 13683 sp_digit y[2 * 8];
wolfSSL 16:8e0d178b1d1e 13684 sp_digit z[2 * 8];
wolfSSL 16:8e0d178b1d1e 13685 int infinity;
wolfSSL 16:8e0d178b1d1e 13686 } sp_point_256;
wolfSSL 16:8e0d178b1d1e 13687
wolfSSL 16:8e0d178b1d1e 13688 /* The modulus (prime) of the curve P256. */
wolfSSL 16:8e0d178b1d1e 13689 static const sp_digit p256_mod[8] = {
wolfSSL 16:8e0d178b1d1e 13690 0xffffffff,0xffffffff,0xffffffff,0x00000000,0x00000000,0x00000000,
wolfSSL 16:8e0d178b1d1e 13691 0x00000001,0xffffffff
wolfSSL 16:8e0d178b1d1e 13692 };
wolfSSL 16:8e0d178b1d1e 13693 /* The Montogmery normalizer for modulus of the curve P256. */
wolfSSL 16:8e0d178b1d1e 13694 static const sp_digit p256_norm_mod[8] = {
wolfSSL 16:8e0d178b1d1e 13695 0x00000001,0x00000000,0x00000000,0xffffffff,0xffffffff,0xffffffff,
wolfSSL 16:8e0d178b1d1e 13696 0xfffffffe,0x00000000
wolfSSL 16:8e0d178b1d1e 13697 };
wolfSSL 16:8e0d178b1d1e 13698 /* The Montogmery multiplier for modulus of the curve P256. */
wolfSSL 16:8e0d178b1d1e 13699 static const sp_digit p256_mp_mod = 0x00000001;
wolfSSL 16:8e0d178b1d1e 13700 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
wolfSSL 16:8e0d178b1d1e 13701 defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 13702 /* The order of the curve P256. */
wolfSSL 16:8e0d178b1d1e 13703 static const sp_digit p256_order[8] = {
wolfSSL 16:8e0d178b1d1e 13704 0xfc632551,0xf3b9cac2,0xa7179e84,0xbce6faad,0xffffffff,0xffffffff,
wolfSSL 16:8e0d178b1d1e 13705 0x00000000,0xffffffff
wolfSSL 16:8e0d178b1d1e 13706 };
wolfSSL 16:8e0d178b1d1e 13707 #endif
wolfSSL 16:8e0d178b1d1e 13708 /* The order of the curve P256 minus 2. */
wolfSSL 16:8e0d178b1d1e 13709 static const sp_digit p256_order2[8] = {
wolfSSL 16:8e0d178b1d1e 13710 0xfc63254f,0xf3b9cac2,0xa7179e84,0xbce6faad,0xffffffff,0xffffffff,
wolfSSL 16:8e0d178b1d1e 13711 0x00000000,0xffffffff
wolfSSL 16:8e0d178b1d1e 13712 };
wolfSSL 16:8e0d178b1d1e 13713 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 13714 /* The Montogmery normalizer for order of the curve P256. */
wolfSSL 16:8e0d178b1d1e 13715 static const sp_digit p256_norm_order[8] = {
wolfSSL 16:8e0d178b1d1e 13716 0x039cdaaf,0x0c46353d,0x58e8617b,0x43190552,0x00000000,0x00000000,
wolfSSL 16:8e0d178b1d1e 13717 0xffffffff,0x00000000
wolfSSL 16:8e0d178b1d1e 13718 };
wolfSSL 16:8e0d178b1d1e 13719 #endif
wolfSSL 16:8e0d178b1d1e 13720 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 13721 /* The Montogmery multiplier for order of the curve P256. */
wolfSSL 16:8e0d178b1d1e 13722 static const sp_digit p256_mp_order = 0xee00bc4f;
wolfSSL 16:8e0d178b1d1e 13723 #endif
wolfSSL 16:8e0d178b1d1e 13724 /* The base point of curve P256. */
wolfSSL 16:8e0d178b1d1e 13725 static const sp_point_256 p256_base = {
wolfSSL 16:8e0d178b1d1e 13726 /* X ordinate */
wolfSSL 16:8e0d178b1d1e 13727 {
wolfSSL 16:8e0d178b1d1e 13728 0xd898c296,0xf4a13945,0x2deb33a0,0x77037d81,0x63a440f2,0xf8bce6e5,
wolfSSL 16:8e0d178b1d1e 13729 0xe12c4247,0x6b17d1f2,
wolfSSL 16:8e0d178b1d1e 13730 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
wolfSSL 16:8e0d178b1d1e 13731 },
wolfSSL 16:8e0d178b1d1e 13732 /* Y ordinate */
wolfSSL 16:8e0d178b1d1e 13733 {
wolfSSL 16:8e0d178b1d1e 13734 0x37bf51f5,0xcbb64068,0x6b315ece,0x2bce3357,0x7c0f9e16,0x8ee7eb4a,
wolfSSL 16:8e0d178b1d1e 13735 0xfe1a7f9b,0x4fe342e2,
wolfSSL 16:8e0d178b1d1e 13736 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
wolfSSL 16:8e0d178b1d1e 13737 },
wolfSSL 16:8e0d178b1d1e 13738 /* Z ordinate */
wolfSSL 16:8e0d178b1d1e 13739 {
wolfSSL 16:8e0d178b1d1e 13740 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
wolfSSL 16:8e0d178b1d1e 13741 0x00000000,0x00000000,
wolfSSL 16:8e0d178b1d1e 13742 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
wolfSSL 16:8e0d178b1d1e 13743 },
wolfSSL 16:8e0d178b1d1e 13744 /* infinity */
wolfSSL 16:8e0d178b1d1e 13745 0
wolfSSL 16:8e0d178b1d1e 13746 };
wolfSSL 16:8e0d178b1d1e 13747 #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)
wolfSSL 16:8e0d178b1d1e 13748 static const sp_digit p256_b[8] = {
wolfSSL 16:8e0d178b1d1e 13749 0x27d2604b,0x3bce3c3e,0xcc53b0f6,0x651d06b0,0x769886bc,0xb3ebbd55,
wolfSSL 16:8e0d178b1d1e 13750 0xaa3a93e7,0x5ac635d8
wolfSSL 16:8e0d178b1d1e 13751 };
wolfSSL 16:8e0d178b1d1e 13752 #endif
wolfSSL 16:8e0d178b1d1e 13753
wolfSSL 16:8e0d178b1d1e 13754 static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, sp_point_256** p)
wolfSSL 16:8e0d178b1d1e 13755 {
wolfSSL 16:8e0d178b1d1e 13756 int ret = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 13757 (void)heap;
wolfSSL 16:8e0d178b1d1e 13758 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 13759 (void)sp;
wolfSSL 16:8e0d178b1d1e 13760 *p = (sp_point_256*)XMALLOC(sizeof(sp_point_256), heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 13761 #else
wolfSSL 16:8e0d178b1d1e 13762 *p = sp;
wolfSSL 16:8e0d178b1d1e 13763 #endif
wolfSSL 16:8e0d178b1d1e 13764 if (*p == NULL) {
wolfSSL 16:8e0d178b1d1e 13765 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 13766 }
wolfSSL 16:8e0d178b1d1e 13767 return ret;
wolfSSL 16:8e0d178b1d1e 13768 }
wolfSSL 16:8e0d178b1d1e 13769
wolfSSL 16:8e0d178b1d1e 13770 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 13771 /* Allocate memory for point and return error. */
wolfSSL 16:8e0d178b1d1e 13772 #define sp_256_point_new_8(heap, sp, p) sp_256_point_new_ex_8((heap), NULL, &(p))
wolfSSL 16:8e0d178b1d1e 13773 #else
wolfSSL 16:8e0d178b1d1e 13774 /* Set pointer to data and return no error. */
wolfSSL 16:8e0d178b1d1e 13775 #define sp_256_point_new_8(heap, sp, p) sp_256_point_new_ex_8((heap), &(sp), &(p))
wolfSSL 16:8e0d178b1d1e 13776 #endif
wolfSSL 16:8e0d178b1d1e 13777
wolfSSL 16:8e0d178b1d1e 13778
wolfSSL 16:8e0d178b1d1e 13779 static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap)
wolfSSL 16:8e0d178b1d1e 13780 {
wolfSSL 16:8e0d178b1d1e 13781 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 13782 /* If valid pointer then clear point data if requested and free data. */
wolfSSL 16:8e0d178b1d1e 13783 if (p != NULL) {
wolfSSL 16:8e0d178b1d1e 13784 if (clear != 0) {
wolfSSL 16:8e0d178b1d1e 13785 XMEMSET(p, 0, sizeof(*p));
wolfSSL 16:8e0d178b1d1e 13786 }
wolfSSL 16:8e0d178b1d1e 13787 XFREE(p, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 13788 }
wolfSSL 16:8e0d178b1d1e 13789 #else
wolfSSL 16:8e0d178b1d1e 13790 /* Clear point data if requested. */
wolfSSL 16:8e0d178b1d1e 13791 if (clear != 0) {
wolfSSL 16:8e0d178b1d1e 13792 XMEMSET(p, 0, sizeof(*p));
wolfSSL 16:8e0d178b1d1e 13793 }
wolfSSL 16:8e0d178b1d1e 13794 #endif
wolfSSL 16:8e0d178b1d1e 13795 (void)heap;
wolfSSL 16:8e0d178b1d1e 13796 }
wolfSSL 16:8e0d178b1d1e 13797
wolfSSL 16:8e0d178b1d1e 13798 /* Multiply a number by Montogmery normalizer mod modulus (prime).
wolfSSL 16:8e0d178b1d1e 13799 *
wolfSSL 16:8e0d178b1d1e 13800 * r The resulting Montgomery form number.
wolfSSL 16:8e0d178b1d1e 13801 * a The number to convert.
wolfSSL 16:8e0d178b1d1e 13802 * m The modulus (prime).
wolfSSL 16:8e0d178b1d1e 13803 */
wolfSSL 16:8e0d178b1d1e 13804 static int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 13805 {
wolfSSL 16:8e0d178b1d1e 13806 int64_t t[8];
wolfSSL 16:8e0d178b1d1e 13807 int64_t a64[8];
wolfSSL 16:8e0d178b1d1e 13808 int64_t o;
wolfSSL 16:8e0d178b1d1e 13809
wolfSSL 16:8e0d178b1d1e 13810 (void)m;
wolfSSL 16:8e0d178b1d1e 13811
wolfSSL 16:8e0d178b1d1e 13812 a64[0] = a[0];
wolfSSL 16:8e0d178b1d1e 13813 a64[1] = a[1];
wolfSSL 16:8e0d178b1d1e 13814 a64[2] = a[2];
wolfSSL 16:8e0d178b1d1e 13815 a64[3] = a[3];
wolfSSL 16:8e0d178b1d1e 13816 a64[4] = a[4];
wolfSSL 16:8e0d178b1d1e 13817 a64[5] = a[5];
wolfSSL 16:8e0d178b1d1e 13818 a64[6] = a[6];
wolfSSL 16:8e0d178b1d1e 13819 a64[7] = a[7];
wolfSSL 16:8e0d178b1d1e 13820
wolfSSL 16:8e0d178b1d1e 13821 /* 1 1 0 -1 -1 -1 -1 0 */
wolfSSL 16:8e0d178b1d1e 13822 t[0] = 0 + a64[0] + a64[1] - a64[3] - a64[4] - a64[5] - a64[6];
wolfSSL 16:8e0d178b1d1e 13823 /* 0 1 1 0 -1 -1 -1 -1 */
wolfSSL 16:8e0d178b1d1e 13824 t[1] = 0 + a64[1] + a64[2] - a64[4] - a64[5] - a64[6] - a64[7];
wolfSSL 16:8e0d178b1d1e 13825 /* 0 0 1 1 0 -1 -1 -1 */
wolfSSL 16:8e0d178b1d1e 13826 t[2] = 0 + a64[2] + a64[3] - a64[5] - a64[6] - a64[7];
wolfSSL 16:8e0d178b1d1e 13827 /* -1 -1 0 2 2 1 0 -1 */
wolfSSL 16:8e0d178b1d1e 13828 t[3] = 0 - a64[0] - a64[1] + 2 * a64[3] + 2 * a64[4] + a64[5] - a64[7];
wolfSSL 16:8e0d178b1d1e 13829 /* 0 -1 -1 0 2 2 1 0 */
wolfSSL 16:8e0d178b1d1e 13830 t[4] = 0 - a64[1] - a64[2] + 2 * a64[4] + 2 * a64[5] + a64[6];
wolfSSL 16:8e0d178b1d1e 13831 /* 0 0 -1 -1 0 2 2 1 */
wolfSSL 16:8e0d178b1d1e 13832 t[5] = 0 - a64[2] - a64[3] + 2 * a64[5] + 2 * a64[6] + a64[7];
wolfSSL 16:8e0d178b1d1e 13833 /* -1 -1 0 0 0 1 3 2 */
wolfSSL 16:8e0d178b1d1e 13834 t[6] = 0 - a64[0] - a64[1] + a64[5] + 3 * a64[6] + 2 * a64[7];
wolfSSL 16:8e0d178b1d1e 13835 /* 1 0 -1 -1 -1 -1 0 3 */
wolfSSL 16:8e0d178b1d1e 13836 t[7] = 0 + a64[0] - a64[2] - a64[3] - a64[4] - a64[5] + 3 * a64[7];
wolfSSL 16:8e0d178b1d1e 13837
wolfSSL 16:8e0d178b1d1e 13838 t[1] += t[0] >> 32; t[0] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13839 t[2] += t[1] >> 32; t[1] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13840 t[3] += t[2] >> 32; t[2] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13841 t[4] += t[3] >> 32; t[3] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13842 t[5] += t[4] >> 32; t[4] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13843 t[6] += t[5] >> 32; t[5] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13844 t[7] += t[6] >> 32; t[6] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13845 o = t[7] >> 32; t[7] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13846 t[0] += o;
wolfSSL 16:8e0d178b1d1e 13847 t[3] -= o;
wolfSSL 16:8e0d178b1d1e 13848 t[6] -= o;
wolfSSL 16:8e0d178b1d1e 13849 t[7] += o;
wolfSSL 16:8e0d178b1d1e 13850 t[1] += t[0] >> 32; t[0] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13851 t[2] += t[1] >> 32; t[1] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13852 t[3] += t[2] >> 32; t[2] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13853 t[4] += t[3] >> 32; t[3] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13854 t[5] += t[4] >> 32; t[4] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13855 t[6] += t[5] >> 32; t[5] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13856 t[7] += t[6] >> 32; t[6] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13857 r[0] = t[0];
wolfSSL 16:8e0d178b1d1e 13858 r[1] = t[1];
wolfSSL 16:8e0d178b1d1e 13859 r[2] = t[2];
wolfSSL 16:8e0d178b1d1e 13860 r[3] = t[3];
wolfSSL 16:8e0d178b1d1e 13861 r[4] = t[4];
wolfSSL 16:8e0d178b1d1e 13862 r[5] = t[5];
wolfSSL 16:8e0d178b1d1e 13863 r[6] = t[6];
wolfSSL 16:8e0d178b1d1e 13864 r[7] = t[7];
wolfSSL 16:8e0d178b1d1e 13865
wolfSSL 16:8e0d178b1d1e 13866 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 13867 }
wolfSSL 16:8e0d178b1d1e 13868
wolfSSL 16:8e0d178b1d1e 13869 /* Convert an mp_int to an array of sp_digit.
wolfSSL 16:8e0d178b1d1e 13870 *
wolfSSL 16:8e0d178b1d1e 13871 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 13872 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 13873 * a A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 13874 */
wolfSSL 16:8e0d178b1d1e 13875 static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)
wolfSSL 16:8e0d178b1d1e 13876 {
wolfSSL 16:8e0d178b1d1e 13877 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 13878 int j;
wolfSSL 16:8e0d178b1d1e 13879
wolfSSL 16:8e0d178b1d1e 13880 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 16:8e0d178b1d1e 13881
wolfSSL 16:8e0d178b1d1e 13882 for (j = a->used; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 13883 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 13884 }
wolfSSL 16:8e0d178b1d1e 13885 #elif DIGIT_BIT > 32
wolfSSL 16:8e0d178b1d1e 13886 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 13887 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 13888
wolfSSL 16:8e0d178b1d1e 13889 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 13890 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 13891 r[j] |= ((sp_digit)a->dp[i] << s);
wolfSSL 16:8e0d178b1d1e 13892 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13893 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 13894 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 13895 break;
wolfSSL 16:8e0d178b1d1e 13896 }
wolfSSL 16:8e0d178b1d1e 13897 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 13898 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 13899 while ((s + 32U) <= (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 13900 s += 32U;
wolfSSL 16:8e0d178b1d1e 13901 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13902 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 13903 break;
wolfSSL 16:8e0d178b1d1e 13904 }
wolfSSL 16:8e0d178b1d1e 13905 if (s < (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 13906 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 13907 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 13908 }
wolfSSL 16:8e0d178b1d1e 13909 else {
wolfSSL 16:8e0d178b1d1e 13910 r[++j] = 0L;
wolfSSL 16:8e0d178b1d1e 13911 }
wolfSSL 16:8e0d178b1d1e 13912 }
wolfSSL 16:8e0d178b1d1e 13913 s = (word32)DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 13914 }
wolfSSL 16:8e0d178b1d1e 13915
wolfSSL 16:8e0d178b1d1e 13916 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 13917 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 13918 }
wolfSSL 16:8e0d178b1d1e 13919 #else
wolfSSL 16:8e0d178b1d1e 13920 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 13921
wolfSSL 16:8e0d178b1d1e 13922 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 13923 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 13924 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 16:8e0d178b1d1e 13925 if (s + DIGIT_BIT >= 32) {
wolfSSL 16:8e0d178b1d1e 13926 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 13927 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 13928 break;
wolfSSL 16:8e0d178b1d1e 13929 }
wolfSSL 16:8e0d178b1d1e 13930 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 13931 if (s == DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 13932 r[++j] = 0;
wolfSSL 16:8e0d178b1d1e 13933 s = 0;
wolfSSL 16:8e0d178b1d1e 13934 }
wolfSSL 16:8e0d178b1d1e 13935 else {
wolfSSL 16:8e0d178b1d1e 13936 r[++j] = a->dp[i] >> s;
wolfSSL 16:8e0d178b1d1e 13937 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 13938 }
wolfSSL 16:8e0d178b1d1e 13939 }
wolfSSL 16:8e0d178b1d1e 13940 else {
wolfSSL 16:8e0d178b1d1e 13941 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 13942 }
wolfSSL 16:8e0d178b1d1e 13943 }
wolfSSL 16:8e0d178b1d1e 13944
wolfSSL 16:8e0d178b1d1e 13945 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 13946 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 13947 }
wolfSSL 16:8e0d178b1d1e 13948 #endif
wolfSSL 16:8e0d178b1d1e 13949 }
wolfSSL 16:8e0d178b1d1e 13950
wolfSSL 16:8e0d178b1d1e 13951 /* Convert a point of type ecc_point to type sp_point_256.
wolfSSL 16:8e0d178b1d1e 13952 *
wolfSSL 16:8e0d178b1d1e 13953 * p Point of type sp_point_256 (result).
wolfSSL 16:8e0d178b1d1e 13954 * pm Point of type ecc_point.
wolfSSL 16:8e0d178b1d1e 13955 */
wolfSSL 16:8e0d178b1d1e 13956 static void sp_256_point_from_ecc_point_8(sp_point_256* p, const ecc_point* pm)
wolfSSL 16:8e0d178b1d1e 13957 {
wolfSSL 16:8e0d178b1d1e 13958 XMEMSET(p->x, 0, sizeof(p->x));
wolfSSL 16:8e0d178b1d1e 13959 XMEMSET(p->y, 0, sizeof(p->y));
wolfSSL 16:8e0d178b1d1e 13960 XMEMSET(p->z, 0, sizeof(p->z));
wolfSSL 16:8e0d178b1d1e 13961 sp_256_from_mp(p->x, 8, pm->x);
wolfSSL 16:8e0d178b1d1e 13962 sp_256_from_mp(p->y, 8, pm->y);
wolfSSL 16:8e0d178b1d1e 13963 sp_256_from_mp(p->z, 8, pm->z);
wolfSSL 16:8e0d178b1d1e 13964 p->infinity = 0;
wolfSSL 16:8e0d178b1d1e 13965 }
wolfSSL 16:8e0d178b1d1e 13966
wolfSSL 16:8e0d178b1d1e 13967 /* Convert an array of sp_digit to an mp_int.
wolfSSL 16:8e0d178b1d1e 13968 *
wolfSSL 16:8e0d178b1d1e 13969 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 13970 * r A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 13971 */
wolfSSL 16:8e0d178b1d1e 13972 static int sp_256_to_mp(const sp_digit* a, mp_int* r)
wolfSSL 16:8e0d178b1d1e 13973 {
wolfSSL 16:8e0d178b1d1e 13974 int err;
wolfSSL 16:8e0d178b1d1e 13975
wolfSSL 16:8e0d178b1d1e 13976 err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 16:8e0d178b1d1e 13977 if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
wolfSSL 16:8e0d178b1d1e 13978 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 13979 XMEMCPY(r->dp, a, sizeof(sp_digit) * 8);
wolfSSL 16:8e0d178b1d1e 13980 r->used = 8;
wolfSSL 16:8e0d178b1d1e 13981 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 13982 #elif DIGIT_BIT < 32
wolfSSL 16:8e0d178b1d1e 13983 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 13984
wolfSSL 16:8e0d178b1d1e 13985 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 13986 for (i = 0; i < 8; i++) {
wolfSSL 16:8e0d178b1d1e 13987 r->dp[j] |= (mp_digit)(a[i] << s);
wolfSSL 16:8e0d178b1d1e 13988 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 13989 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 13990 r->dp[++j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 13991 while (s + DIGIT_BIT <= 32) {
wolfSSL 16:8e0d178b1d1e 13992 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 13993 r->dp[j++] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 13994 if (s == SP_WORD_SIZE) {
wolfSSL 16:8e0d178b1d1e 13995 r->dp[j] = 0;
wolfSSL 16:8e0d178b1d1e 13996 }
wolfSSL 16:8e0d178b1d1e 13997 else {
wolfSSL 16:8e0d178b1d1e 13998 r->dp[j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 13999 }
wolfSSL 16:8e0d178b1d1e 14000 }
wolfSSL 16:8e0d178b1d1e 14001 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 14002 }
wolfSSL 16:8e0d178b1d1e 14003 r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 14004 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 14005 #else
wolfSSL 16:8e0d178b1d1e 14006 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 14007
wolfSSL 16:8e0d178b1d1e 14008 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 14009 for (i = 0; i < 8; i++) {
wolfSSL 16:8e0d178b1d1e 14010 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 16:8e0d178b1d1e 14011 if (s + 32 >= DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 14012 #if DIGIT_BIT != 32 && DIGIT_BIT != 64
wolfSSL 16:8e0d178b1d1e 14013 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 14014 #endif
wolfSSL 16:8e0d178b1d1e 14015 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 14016 r->dp[++j] = a[i] >> s;
wolfSSL 16:8e0d178b1d1e 14017 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 14018 }
wolfSSL 16:8e0d178b1d1e 14019 else {
wolfSSL 16:8e0d178b1d1e 14020 s += 32;
wolfSSL 16:8e0d178b1d1e 14021 }
wolfSSL 16:8e0d178b1d1e 14022 }
wolfSSL 16:8e0d178b1d1e 14023 r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 14024 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 14025 #endif
wolfSSL 16:8e0d178b1d1e 14026 }
wolfSSL 16:8e0d178b1d1e 14027
wolfSSL 16:8e0d178b1d1e 14028 return err;
wolfSSL 16:8e0d178b1d1e 14029 }
wolfSSL 16:8e0d178b1d1e 14030
wolfSSL 16:8e0d178b1d1e 14031 /* Convert a point of type sp_point_256 to type ecc_point.
wolfSSL 16:8e0d178b1d1e 14032 *
wolfSSL 16:8e0d178b1d1e 14033 * p Point of type sp_point_256.
wolfSSL 16:8e0d178b1d1e 14034 * pm Point of type ecc_point (result).
wolfSSL 16:8e0d178b1d1e 14035 * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
wolfSSL 16:8e0d178b1d1e 14036 * MP_OKAY.
wolfSSL 16:8e0d178b1d1e 14037 */
wolfSSL 16:8e0d178b1d1e 14038 static int sp_256_point_to_ecc_point_8(const sp_point_256* p, ecc_point* pm)
wolfSSL 16:8e0d178b1d1e 14039 {
wolfSSL 16:8e0d178b1d1e 14040 int err;
wolfSSL 16:8e0d178b1d1e 14041
wolfSSL 16:8e0d178b1d1e 14042 err = sp_256_to_mp(p->x, pm->x);
wolfSSL 16:8e0d178b1d1e 14043 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 14044 err = sp_256_to_mp(p->y, pm->y);
wolfSSL 16:8e0d178b1d1e 14045 }
wolfSSL 16:8e0d178b1d1e 14046 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 14047 err = sp_256_to_mp(p->z, pm->z);
wolfSSL 16:8e0d178b1d1e 14048 }
wolfSSL 16:8e0d178b1d1e 14049
wolfSSL 16:8e0d178b1d1e 14050 return err;
wolfSSL 16:8e0d178b1d1e 14051 }
wolfSSL 16:8e0d178b1d1e 14052
wolfSSL 16:8e0d178b1d1e 14053 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 14054 *
wolfSSL 16:8e0d178b1d1e 14055 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 14056 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 14057 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 14058 */
wolfSSL 16:8e0d178b1d1e 14059 SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 14060 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 14061 {
wolfSSL 16:8e0d178b1d1e 14062 sp_digit tmp[8];
wolfSSL 16:8e0d178b1d1e 14063
wolfSSL 16:8e0d178b1d1e 14064 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 14065 /* A[0] * B[0] */
wolfSSL 16:8e0d178b1d1e 14066 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14067 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14068 "umull r3, r4, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14069 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14070 "str r3, [%[tmp], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14071 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14072 /* A[0] * B[1] */
wolfSSL 16:8e0d178b1d1e 14073 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14074 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14075 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14076 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14077 /* A[1] * B[0] */
wolfSSL 16:8e0d178b1d1e 14078 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14079 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14080 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14081 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14082 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14083 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14084 "str r4, [%[tmp], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14085 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14086 /* A[0] * B[2] */
wolfSSL 16:8e0d178b1d1e 14087 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14088 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14089 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14090 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14091 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14092 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14093 /* A[1] * B[1] */
wolfSSL 16:8e0d178b1d1e 14094 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14095 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14096 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14097 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14098 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14099 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14100 /* A[2] * B[0] */
wolfSSL 16:8e0d178b1d1e 14101 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14102 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14103 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14104 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14105 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14106 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14107 "str r5, [%[tmp], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14108 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14109 /* A[0] * B[3] */
wolfSSL 16:8e0d178b1d1e 14110 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14111 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14112 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14113 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14114 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14115 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14116 /* A[1] * B[2] */
wolfSSL 16:8e0d178b1d1e 14117 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14118 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14119 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14120 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14121 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14122 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14123 /* A[2] * B[1] */
wolfSSL 16:8e0d178b1d1e 14124 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14125 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14126 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14127 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14128 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14129 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14130 /* A[3] * B[0] */
wolfSSL 16:8e0d178b1d1e 14131 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14132 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14133 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14134 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14135 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14136 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14137 "str r3, [%[tmp], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14138 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14139 /* A[0] * B[4] */
wolfSSL 16:8e0d178b1d1e 14140 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14141 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14142 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14143 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14144 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14145 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14146 /* A[1] * B[3] */
wolfSSL 16:8e0d178b1d1e 14147 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14148 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14149 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14150 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14151 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14152 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14153 /* A[2] * B[2] */
wolfSSL 16:8e0d178b1d1e 14154 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14155 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14156 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14157 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14158 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14159 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14160 /* A[3] * B[1] */
wolfSSL 16:8e0d178b1d1e 14161 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14162 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14163 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14164 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14165 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14166 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14167 /* A[4] * B[0] */
wolfSSL 16:8e0d178b1d1e 14168 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14169 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14170 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14171 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14172 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14173 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14174 "str r4, [%[tmp], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14175 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14176 /* A[0] * B[5] */
wolfSSL 16:8e0d178b1d1e 14177 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14178 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14179 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14180 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14181 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14182 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14183 /* A[1] * B[4] */
wolfSSL 16:8e0d178b1d1e 14184 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14185 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14186 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14187 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14188 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14189 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14190 /* A[2] * B[3] */
wolfSSL 16:8e0d178b1d1e 14191 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14192 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14193 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14194 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14195 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14196 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14197 /* A[3] * B[2] */
wolfSSL 16:8e0d178b1d1e 14198 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14199 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14200 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14201 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14202 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14203 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14204 /* A[4] * B[1] */
wolfSSL 16:8e0d178b1d1e 14205 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14206 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14207 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14208 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14209 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14210 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14211 /* A[5] * B[0] */
wolfSSL 16:8e0d178b1d1e 14212 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14213 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14214 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14215 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14216 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14217 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14218 "str r5, [%[tmp], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14219 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14220 /* A[0] * B[6] */
wolfSSL 16:8e0d178b1d1e 14221 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14222 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14223 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14224 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14225 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14226 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14227 /* A[1] * B[5] */
wolfSSL 16:8e0d178b1d1e 14228 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14229 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14230 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14231 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14232 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14233 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14234 /* A[2] * B[4] */
wolfSSL 16:8e0d178b1d1e 14235 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14236 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14237 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14238 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14239 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14240 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14241 /* A[3] * B[3] */
wolfSSL 16:8e0d178b1d1e 14242 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14243 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14244 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14245 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14246 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14247 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14248 /* A[4] * B[2] */
wolfSSL 16:8e0d178b1d1e 14249 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14250 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14251 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14252 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14253 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14254 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14255 /* A[5] * B[1] */
wolfSSL 16:8e0d178b1d1e 14256 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14257 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14258 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14259 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14260 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14261 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14262 /* A[6] * B[0] */
wolfSSL 16:8e0d178b1d1e 14263 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14264 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14265 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14266 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14267 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14268 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14269 "str r3, [%[tmp], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14270 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14271 /* A[0] * B[7] */
wolfSSL 16:8e0d178b1d1e 14272 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14273 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14274 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14275 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14276 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14277 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14278 /* A[1] * B[6] */
wolfSSL 16:8e0d178b1d1e 14279 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14280 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14281 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14282 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14283 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14284 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14285 /* A[2] * B[5] */
wolfSSL 16:8e0d178b1d1e 14286 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14287 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14288 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14289 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14290 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14291 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14292 /* A[3] * B[4] */
wolfSSL 16:8e0d178b1d1e 14293 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14294 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14295 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14296 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14297 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14298 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14299 /* A[4] * B[3] */
wolfSSL 16:8e0d178b1d1e 14300 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14301 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14302 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14303 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14304 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14305 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14306 /* A[5] * B[2] */
wolfSSL 16:8e0d178b1d1e 14307 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14308 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14309 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14310 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14311 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14312 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14313 /* A[6] * B[1] */
wolfSSL 16:8e0d178b1d1e 14314 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14315 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14316 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14317 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14318 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14319 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14320 /* A[7] * B[0] */
wolfSSL 16:8e0d178b1d1e 14321 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14322 "ldr r8, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14323 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14324 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14325 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14326 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14327 "str r4, [%[tmp], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14328 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14329 /* A[1] * B[7] */
wolfSSL 16:8e0d178b1d1e 14330 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14331 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14332 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14333 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14334 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14335 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14336 /* A[2] * B[6] */
wolfSSL 16:8e0d178b1d1e 14337 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14338 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14339 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14340 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14341 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14342 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14343 /* A[3] * B[5] */
wolfSSL 16:8e0d178b1d1e 14344 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14345 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14346 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14347 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14348 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14349 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14350 /* A[4] * B[4] */
wolfSSL 16:8e0d178b1d1e 14351 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14352 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14353 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14354 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14355 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14356 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14357 /* A[5] * B[3] */
wolfSSL 16:8e0d178b1d1e 14358 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14359 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14360 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14361 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14362 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14363 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14364 /* A[6] * B[2] */
wolfSSL 16:8e0d178b1d1e 14365 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14366 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14367 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14368 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14369 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14370 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14371 /* A[7] * B[1] */
wolfSSL 16:8e0d178b1d1e 14372 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14373 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14374 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14375 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14376 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14377 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14378 "str r5, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 14379 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14380 /* A[2] * B[7] */
wolfSSL 16:8e0d178b1d1e 14381 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14382 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14383 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14384 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14385 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14386 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14387 /* A[3] * B[6] */
wolfSSL 16:8e0d178b1d1e 14388 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14389 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14390 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14391 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14392 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14393 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14394 /* A[4] * B[5] */
wolfSSL 16:8e0d178b1d1e 14395 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14396 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14397 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14398 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14399 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14400 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14401 /* A[5] * B[4] */
wolfSSL 16:8e0d178b1d1e 14402 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14403 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14404 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14405 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14406 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14407 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14408 /* A[6] * B[3] */
wolfSSL 16:8e0d178b1d1e 14409 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14410 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14411 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14412 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14413 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14414 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14415 /* A[7] * B[2] */
wolfSSL 16:8e0d178b1d1e 14416 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14417 "ldr r8, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14418 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14419 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14420 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14421 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14422 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 14423 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14424 /* A[3] * B[7] */
wolfSSL 16:8e0d178b1d1e 14425 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14426 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14427 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14428 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14429 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14430 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14431 /* A[4] * B[6] */
wolfSSL 16:8e0d178b1d1e 14432 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14433 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14434 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14435 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14436 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14437 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14438 /* A[5] * B[5] */
wolfSSL 16:8e0d178b1d1e 14439 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14440 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14441 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14442 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14443 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14444 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14445 /* A[6] * B[4] */
wolfSSL 16:8e0d178b1d1e 14446 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14447 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14448 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14449 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14450 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14451 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14452 /* A[7] * B[3] */
wolfSSL 16:8e0d178b1d1e 14453 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14454 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14455 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14456 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14457 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14458 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14459 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 14460 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14461 /* A[4] * B[7] */
wolfSSL 16:8e0d178b1d1e 14462 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14463 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14464 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14465 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14466 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14467 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14468 /* A[5] * B[6] */
wolfSSL 16:8e0d178b1d1e 14469 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14470 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14471 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14472 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14473 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14474 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14475 /* A[6] * B[5] */
wolfSSL 16:8e0d178b1d1e 14476 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14477 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14478 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14479 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14480 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14481 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14482 /* A[7] * B[4] */
wolfSSL 16:8e0d178b1d1e 14483 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14484 "ldr r8, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14485 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14486 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14487 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14488 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14489 "str r5, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 14490 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14491 /* A[5] * B[7] */
wolfSSL 16:8e0d178b1d1e 14492 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14493 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14494 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14495 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14496 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14497 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14498 /* A[6] * B[6] */
wolfSSL 16:8e0d178b1d1e 14499 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14500 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14501 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14502 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14503 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14504 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14505 /* A[7] * B[5] */
wolfSSL 16:8e0d178b1d1e 14506 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14507 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14508 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14509 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14510 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14511 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14512 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 14513 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14514 /* A[6] * B[7] */
wolfSSL 16:8e0d178b1d1e 14515 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14516 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14517 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14518 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14519 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14520 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14521 /* A[7] * B[6] */
wolfSSL 16:8e0d178b1d1e 14522 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14523 "ldr r8, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14524 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14525 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14526 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14527 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14528 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 14529 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14530 /* A[7] * B[7] */
wolfSSL 16:8e0d178b1d1e 14531 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14532 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14533 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14534 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14535 "adc r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14536 "str r5, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 14537 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 14538 /* Transfer tmp to r */
wolfSSL 16:8e0d178b1d1e 14539 "ldr r3, [%[tmp], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14540 "ldr r4, [%[tmp], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14541 "ldr r5, [%[tmp], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14542 "ldr r6, [%[tmp], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14543 "str r3, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14544 "str r4, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14545 "str r5, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14546 "str r6, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14547 "ldr r3, [%[tmp], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14548 "ldr r4, [%[tmp], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14549 "ldr r5, [%[tmp], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14550 "ldr r6, [%[tmp], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14551 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14552 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14553 "str r5, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14554 "str r6, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14555 :
wolfSSL 16:8e0d178b1d1e 14556 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [tmp] "r" (tmp)
wolfSSL 16:8e0d178b1d1e 14557 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 14558 );
wolfSSL 16:8e0d178b1d1e 14559 }
wolfSSL 16:8e0d178b1d1e 14560
wolfSSL 16:8e0d178b1d1e 14561 /* Conditionally subtract b from a using the mask m.
wolfSSL 16:8e0d178b1d1e 14562 * m is -1 to subtract and 0 when not copying.
wolfSSL 16:8e0d178b1d1e 14563 *
wolfSSL 16:8e0d178b1d1e 14564 * r A single precision number representing condition subtract result.
wolfSSL 16:8e0d178b1d1e 14565 * a A single precision number to subtract from.
wolfSSL 16:8e0d178b1d1e 14566 * b A single precision number to subtract.
wolfSSL 16:8e0d178b1d1e 14567 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 14568 */
wolfSSL 16:8e0d178b1d1e 14569 SP_NOINLINE static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 14570 const sp_digit* b, sp_digit m)
wolfSSL 16:8e0d178b1d1e 14571 {
wolfSSL 16:8e0d178b1d1e 14572 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 14573
wolfSSL 16:8e0d178b1d1e 14574 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 14575 "mov r5, #32\n\t"
wolfSSL 16:8e0d178b1d1e 14576 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 14577 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14578 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 14579 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 14580 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 14581 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14582 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 14583 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 14584 "sbcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14585 "sbcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 14586 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 14587 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 14588 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 14589 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 14590 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 14591 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 14592 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 14593 );
wolfSSL 16:8e0d178b1d1e 14594
wolfSSL 16:8e0d178b1d1e 14595 return c;
wolfSSL 16:8e0d178b1d1e 14596 }
wolfSSL 16:8e0d178b1d1e 14597
wolfSSL 16:8e0d178b1d1e 14598 /* Reduce the number back to 256 bits using Montgomery reduction.
wolfSSL 16:8e0d178b1d1e 14599 *
wolfSSL 16:8e0d178b1d1e 14600 * a A single precision number to reduce in place.
wolfSSL 16:8e0d178b1d1e 14601 * m The single precision number representing the modulus.
wolfSSL 16:8e0d178b1d1e 14602 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 16:8e0d178b1d1e 14603 */
wolfSSL 16:8e0d178b1d1e 14604 SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 14605 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 14606 {
wolfSSL 16:8e0d178b1d1e 14607 (void)mp;
wolfSSL 16:8e0d178b1d1e 14608 (void)m;
wolfSSL 16:8e0d178b1d1e 14609
wolfSSL 16:8e0d178b1d1e 14610 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 14611 "mov r2, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14612 "mov r1, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14613 /* i = 0 */
wolfSSL 16:8e0d178b1d1e 14614 "mov r9, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14615 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 14616 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14617 /* mu = a[i] * 1 (mp) = a[i] */
wolfSSL 16:8e0d178b1d1e 14618 "ldr r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 14619 /* a[i] += -1 * mu = -1 * a[i] => a[i] = 0 no carry */
wolfSSL 16:8e0d178b1d1e 14620 /* a[i+1] += -1 * mu */
wolfSSL 16:8e0d178b1d1e 14621 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14622 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14623 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14624 "adc r5, r5, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14625 "str r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14626 /* a[i+2] += -1 * mu */
wolfSSL 16:8e0d178b1d1e 14627 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14628 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14629 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14630 "adc r4, r4, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14631 "str r5, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14632 /* a[i+3] += 0 * mu */
wolfSSL 16:8e0d178b1d1e 14633 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14634 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14635 "adds r4, r4, r3\n\t"
wolfSSL 16:8e0d178b1d1e 14636 "adc r5, r5, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14637 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14638 "adc r5, r5, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14639 "str r4, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14640 /* a[i+4] += 0 * mu */
wolfSSL 16:8e0d178b1d1e 14641 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14642 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14643 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14644 "adc r4, r4, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14645 "str r5, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14646 /* a[i+5] += 0 * mu */
wolfSSL 16:8e0d178b1d1e 14647 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14648 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14649 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14650 "adc r5, r5, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14651 "str r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14652 /* a[i+6] += 1 * mu */
wolfSSL 16:8e0d178b1d1e 14653 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14654 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14655 "adds r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 14656 "adc r4, r4, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14657 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14658 "adc r4, r4, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14659 "str r5, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14660 /* a[i+7] += -1 * mu */
wolfSSL 16:8e0d178b1d1e 14661 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14662 "ldr r8, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 14663 "adds r5, r1, r3\n\t"
wolfSSL 16:8e0d178b1d1e 14664 "mov r1, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14665 "adc r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14666 "subs r4, r4, r3\n\t"
wolfSSL 16:8e0d178b1d1e 14667 "sbcs r5, r5, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14668 "sbc r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14669 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14670 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14671 "adc r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14672 "str r4, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14673 "str r5, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 14674 /* i += 1 */
wolfSSL 16:8e0d178b1d1e 14675 "add r9, r9, #1\n\t"
wolfSSL 16:8e0d178b1d1e 14676 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 14677 "mov r6, #8\n\t"
wolfSSL 16:8e0d178b1d1e 14678 "cmp r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14679 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 14680 "sub %[a], %[a], #32\n\t"
wolfSSL 16:8e0d178b1d1e 14681 "mov r3, r1\n\t"
wolfSSL 16:8e0d178b1d1e 14682 "sub r1, r1, #1\n\t"
wolfSSL 16:8e0d178b1d1e 14683 "mvn r1, r1\n\t"
wolfSSL 16:8e0d178b1d1e 14684 "ldr r4, [%[a],#32]\n\t"
wolfSSL 16:8e0d178b1d1e 14685 "ldr r5, [%[a],#36]\n\t"
wolfSSL 16:8e0d178b1d1e 14686 "ldr r6, [%[a],#40]\n\t"
wolfSSL 16:8e0d178b1d1e 14687 "ldr r8, [%[a],#44]\n\t"
wolfSSL 16:8e0d178b1d1e 14688 "subs r4, r4, r1\n\t"
wolfSSL 16:8e0d178b1d1e 14689 "sbcs r5, r5, r1\n\t"
wolfSSL 16:8e0d178b1d1e 14690 "sbcs r6, r6, r1\n\t"
wolfSSL 16:8e0d178b1d1e 14691 "sbcs r8, r8, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14692 "str r4, [%[a],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 14693 "str r5, [%[a],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 14694 "str r6, [%[a],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 14695 "str r8, [%[a],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 14696 "ldr r4, [%[a],#48]\n\t"
wolfSSL 16:8e0d178b1d1e 14697 "ldr r5, [%[a],#52]\n\t"
wolfSSL 16:8e0d178b1d1e 14698 "ldr r6, [%[a],#56]\n\t"
wolfSSL 16:8e0d178b1d1e 14699 "ldr r8, [%[a],#60]\n\t"
wolfSSL 16:8e0d178b1d1e 14700 "sbcs r4, r4, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14701 "sbcs r5, r5, r2\n\t"
wolfSSL 16:8e0d178b1d1e 14702 "sbcs r6, r6, r3\n\t"
wolfSSL 16:8e0d178b1d1e 14703 "sbc r8, r8, r1\n\t"
wolfSSL 16:8e0d178b1d1e 14704 "str r4, [%[a],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 14705 "str r5, [%[a],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 14706 "str r6, [%[a],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 14707 "str r8, [%[a],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 14708 : [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 14709 :
wolfSSL 16:8e0d178b1d1e 14710 : "memory", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 14711 );
wolfSSL 16:8e0d178b1d1e 14712
wolfSSL 16:8e0d178b1d1e 14713
wolfSSL 16:8e0d178b1d1e 14714 (void)m;
wolfSSL 16:8e0d178b1d1e 14715 (void)mp;
wolfSSL 16:8e0d178b1d1e 14716 }
wolfSSL 16:8e0d178b1d1e 14717
wolfSSL 16:8e0d178b1d1e 14718 /* Reduce the number back to 256 bits using Montgomery reduction.
wolfSSL 16:8e0d178b1d1e 14719 *
wolfSSL 16:8e0d178b1d1e 14720 * a A single precision number to reduce in place.
wolfSSL 16:8e0d178b1d1e 14721 * m The single precision number representing the modulus.
wolfSSL 16:8e0d178b1d1e 14722 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 16:8e0d178b1d1e 14723 */
wolfSSL 16:8e0d178b1d1e 14724 SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 14725 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 14726 {
wolfSSL 16:8e0d178b1d1e 14727 sp_digit ca = 0;
wolfSSL 16:8e0d178b1d1e 14728
wolfSSL 16:8e0d178b1d1e 14729 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 14730 "mov r9, %[mp]\n\t"
wolfSSL 16:8e0d178b1d1e 14731 "mov r12, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 14732 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 14733 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14734 "add r11, r10, #32\n\t"
wolfSSL 16:8e0d178b1d1e 14735 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 14736 /* mu = a[i] * mp */
wolfSSL 16:8e0d178b1d1e 14737 "mov %[mp], r9\n\t"
wolfSSL 16:8e0d178b1d1e 14738 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 14739 "mul %[mp], %[mp], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 14740 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 14741 "add r14, r10, #24\n\t"
wolfSSL 16:8e0d178b1d1e 14742 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 14743 /* a[i+j] += m[j] * mu */
wolfSSL 16:8e0d178b1d1e 14744 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 14745 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14746 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 14747 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 14748 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 14749 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 14750 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14751 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 14752 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 14753 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14754 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 14755 /* a[i+j+1] += m[j+1] * mu */
wolfSSL 16:8e0d178b1d1e 14756 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 14757 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14758 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 14759 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 14760 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 14761 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 14762 "adc r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14763 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 14764 "adds r5, r5, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 14765 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14766 "str r5, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 14767 "cmp r10, r14\n\t"
wolfSSL 16:8e0d178b1d1e 14768 "blt 2b\n\t"
wolfSSL 16:8e0d178b1d1e 14769 /* a[i+6] += m[6] * mu */
wolfSSL 16:8e0d178b1d1e 14770 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 14771 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14772 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 14773 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 14774 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 14775 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 14776 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14777 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 14778 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 14779 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14780 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 14781 /* a[i+7] += m[7] * mu */
wolfSSL 16:8e0d178b1d1e 14782 "mov r4, %[ca]\n\t"
wolfSSL 16:8e0d178b1d1e 14783 "mov %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 14784 /* Multiply m[7] and mu - Start */
wolfSSL 16:8e0d178b1d1e 14785 "ldr r8, [%[m]]\n\t"
wolfSSL 16:8e0d178b1d1e 14786 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 14787 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14788 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14789 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 14790 /* Multiply m[7] and mu - Done */
wolfSSL 16:8e0d178b1d1e 14791 "ldr r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 14792 "ldr r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14793 "adds r6, r6, r5\n\t"
wolfSSL 16:8e0d178b1d1e 14794 "adcs r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 14795 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 14796 "str r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 14797 "str r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14798 /* Next word in a */
wolfSSL 16:8e0d178b1d1e 14799 "sub r10, r10, #24\n\t"
wolfSSL 16:8e0d178b1d1e 14800 "cmp r10, r11\n\t"
wolfSSL 16:8e0d178b1d1e 14801 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 14802 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 14803 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 14804 : [ca] "+r" (ca), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 14805 : [m] "r" (m), [mp] "r" (mp)
wolfSSL 16:8e0d178b1d1e 14806 : "memory", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 14807 );
wolfSSL 16:8e0d178b1d1e 14808
wolfSSL 16:8e0d178b1d1e 14809 sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca);
wolfSSL 16:8e0d178b1d1e 14810 }
wolfSSL 16:8e0d178b1d1e 14811
wolfSSL 16:8e0d178b1d1e 14812 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 16:8e0d178b1d1e 14813 * (r = a * b mod m)
wolfSSL 16:8e0d178b1d1e 14814 *
wolfSSL 16:8e0d178b1d1e 14815 * r Result of multiplication.
wolfSSL 16:8e0d178b1d1e 14816 * a First number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 14817 * b Second number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 14818 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 14819 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 14820 */
wolfSSL 16:8e0d178b1d1e 14821 static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 14822 const sp_digit* m, sp_digit mp)
wolfSSL 16:8e0d178b1d1e 14823 {
wolfSSL 16:8e0d178b1d1e 14824 sp_256_mul_8(r, a, b);
wolfSSL 16:8e0d178b1d1e 14825 sp_256_mont_reduce_8(r, m, mp);
wolfSSL 16:8e0d178b1d1e 14826 }
wolfSSL 16:8e0d178b1d1e 14827
wolfSSL 16:8e0d178b1d1e 14828 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 14829 *
wolfSSL 16:8e0d178b1d1e 14830 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 14831 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 14832 */
wolfSSL 16:8e0d178b1d1e 14833 SP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 14834 {
wolfSSL 16:8e0d178b1d1e 14835 sp_digit tmp[8];
wolfSSL 16:8e0d178b1d1e 14836 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 14837 /* A[0] * A[0] */
wolfSSL 16:8e0d178b1d1e 14838 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14839 "umull r3, r4, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14840 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14841 "str r3, [%[tmp], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14842 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14843 /* A[0] * A[1] */
wolfSSL 16:8e0d178b1d1e 14844 "ldr r8, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14845 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14846 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14847 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14848 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14849 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14850 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14851 "str r4, [%[tmp], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14852 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14853 /* A[0] * A[2] */
wolfSSL 16:8e0d178b1d1e 14854 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14855 "ldr r8, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14856 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14857 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14858 "adc r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14859 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14860 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14861 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14862 /* A[1] * A[1] */
wolfSSL 16:8e0d178b1d1e 14863 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14864 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14865 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14866 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14867 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14868 "str r5, [%[tmp], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14869 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14870 /* A[0] * A[3] */
wolfSSL 16:8e0d178b1d1e 14871 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14872 "ldr r8, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14873 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14874 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14875 /* A[1] * A[2] */
wolfSSL 16:8e0d178b1d1e 14876 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14877 "ldr r8, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14878 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14879 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14880 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14881 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14882 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 14883 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 14884 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 14885 "adds r3, r3, r9\n\t"
wolfSSL 16:8e0d178b1d1e 14886 "adcs r4, r4, r10\n\t"
wolfSSL 16:8e0d178b1d1e 14887 "adc r5, r5, r11\n\t"
wolfSSL 16:8e0d178b1d1e 14888 "str r3, [%[tmp], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14889 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14890 /* A[0] * A[4] */
wolfSSL 16:8e0d178b1d1e 14891 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14892 "ldr r8, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14893 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14894 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14895 /* A[1] * A[3] */
wolfSSL 16:8e0d178b1d1e 14896 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14897 "ldr r8, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14898 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14899 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14900 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14901 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14902 /* A[2] * A[2] */
wolfSSL 16:8e0d178b1d1e 14903 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14904 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14905 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14906 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14907 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14908 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 14909 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 14910 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 14911 "adds r4, r4, r9\n\t"
wolfSSL 16:8e0d178b1d1e 14912 "adcs r5, r5, r10\n\t"
wolfSSL 16:8e0d178b1d1e 14913 "adc r3, r3, r11\n\t"
wolfSSL 16:8e0d178b1d1e 14914 "str r4, [%[tmp], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14915 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14916 /* A[0] * A[5] */
wolfSSL 16:8e0d178b1d1e 14917 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14918 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14919 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14920 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14921 /* A[1] * A[4] */
wolfSSL 16:8e0d178b1d1e 14922 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14923 "ldr r8, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14924 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14925 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14926 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14927 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14928 /* A[2] * A[3] */
wolfSSL 16:8e0d178b1d1e 14929 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14930 "ldr r8, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14931 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14932 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14933 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14934 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14935 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 14936 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 14937 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 14938 "adds r5, r5, r9\n\t"
wolfSSL 16:8e0d178b1d1e 14939 "adcs r3, r3, r10\n\t"
wolfSSL 16:8e0d178b1d1e 14940 "adc r4, r4, r11\n\t"
wolfSSL 16:8e0d178b1d1e 14941 "str r5, [%[tmp], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14942 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14943 /* A[0] * A[6] */
wolfSSL 16:8e0d178b1d1e 14944 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14945 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14946 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14947 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14948 /* A[1] * A[5] */
wolfSSL 16:8e0d178b1d1e 14949 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14950 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14951 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14952 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14953 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14954 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14955 /* A[2] * A[4] */
wolfSSL 16:8e0d178b1d1e 14956 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14957 "ldr r8, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14958 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14959 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14960 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14961 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14962 /* A[3] * A[3] */
wolfSSL 16:8e0d178b1d1e 14963 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14964 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14965 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14966 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14967 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14968 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 14969 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 14970 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 14971 "adds r3, r3, r9\n\t"
wolfSSL 16:8e0d178b1d1e 14972 "adcs r4, r4, r10\n\t"
wolfSSL 16:8e0d178b1d1e 14973 "adc r5, r5, r11\n\t"
wolfSSL 16:8e0d178b1d1e 14974 "str r3, [%[tmp], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14975 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14976 /* A[0] * A[7] */
wolfSSL 16:8e0d178b1d1e 14977 "ldr r6, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 14978 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 14979 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14980 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14981 /* A[1] * A[6] */
wolfSSL 16:8e0d178b1d1e 14982 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 14983 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 14984 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14985 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14986 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14987 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14988 /* A[2] * A[5] */
wolfSSL 16:8e0d178b1d1e 14989 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 14990 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 14991 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14992 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 14993 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14994 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 14995 /* A[3] * A[4] */
wolfSSL 16:8e0d178b1d1e 14996 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 14997 "ldr r8, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 14998 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 14999 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15000 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15001 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15002 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15003 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15004 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15005 "adds r4, r4, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15006 "adcs r5, r5, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15007 "adc r3, r3, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15008 "str r4, [%[tmp], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15009 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15010 /* A[1] * A[7] */
wolfSSL 16:8e0d178b1d1e 15011 "ldr r6, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15012 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15013 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15014 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15015 /* A[2] * A[6] */
wolfSSL 16:8e0d178b1d1e 15016 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15017 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15018 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15019 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15020 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15021 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15022 /* A[3] * A[5] */
wolfSSL 16:8e0d178b1d1e 15023 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15024 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15025 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15026 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15027 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15028 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15029 /* A[4] * A[4] */
wolfSSL 16:8e0d178b1d1e 15030 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15031 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15032 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15033 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15034 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15035 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15036 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15037 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15038 "adds r5, r5, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15039 "adcs r3, r3, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15040 "adc r4, r4, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15041 "str r5, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 15042 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15043 /* A[2] * A[7] */
wolfSSL 16:8e0d178b1d1e 15044 "ldr r6, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15045 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15046 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15047 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15048 /* A[3] * A[6] */
wolfSSL 16:8e0d178b1d1e 15049 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15050 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15051 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15052 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15053 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15054 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15055 /* A[4] * A[5] */
wolfSSL 16:8e0d178b1d1e 15056 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15057 "ldr r8, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15058 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15059 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15060 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15061 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15062 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15063 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15064 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15065 "adds r3, r3, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15066 "adcs r4, r4, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15067 "adc r5, r5, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15068 "str r3, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 15069 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15070 /* A[3] * A[7] */
wolfSSL 16:8e0d178b1d1e 15071 "ldr r6, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15072 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15073 "umull r9, r10, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15074 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15075 /* A[4] * A[6] */
wolfSSL 16:8e0d178b1d1e 15076 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15077 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15078 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15079 "adds r9, r9, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15080 "adcs r10, r10, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15081 "adc r11, r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15082 /* A[5] * A[5] */
wolfSSL 16:8e0d178b1d1e 15083 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15084 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15085 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15086 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15087 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15088 "adds r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15089 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15090 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15091 "adds r4, r4, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15092 "adcs r5, r5, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15093 "adc r3, r3, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15094 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 15095 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15096 /* A[4] * A[7] */
wolfSSL 16:8e0d178b1d1e 15097 "ldr r6, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15098 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15099 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15100 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15101 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15102 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15103 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15104 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15105 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15106 /* A[5] * A[6] */
wolfSSL 16:8e0d178b1d1e 15107 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15108 "ldr r8, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15109 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15110 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15111 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15112 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15113 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15114 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15115 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15116 "str r5, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 15117 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15118 /* A[5] * A[7] */
wolfSSL 16:8e0d178b1d1e 15119 "ldr r6, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15120 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15121 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15122 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15123 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15124 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15125 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15126 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15127 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15128 /* A[6] * A[6] */
wolfSSL 16:8e0d178b1d1e 15129 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15130 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15131 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15132 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15133 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15134 "str r3, [%[r], #48]\n\t"
wolfSSL 16:8e0d178b1d1e 15135 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15136 /* A[6] * A[7] */
wolfSSL 16:8e0d178b1d1e 15137 "ldr r6, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15138 "ldr r8, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15139 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15140 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15141 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15142 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15143 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15144 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15145 "adc r3, r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15146 "str r4, [%[r], #52]\n\t"
wolfSSL 16:8e0d178b1d1e 15147 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15148 /* A[7] * A[7] */
wolfSSL 16:8e0d178b1d1e 15149 "ldr r6, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15150 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15151 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15152 "adc r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15153 "str r5, [%[r], #56]\n\t"
wolfSSL 16:8e0d178b1d1e 15154 "str r3, [%[r], #60]\n\t"
wolfSSL 16:8e0d178b1d1e 15155 /* Transfer tmp to r */
wolfSSL 16:8e0d178b1d1e 15156 "ldr r3, [%[tmp], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15157 "ldr r4, [%[tmp], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15158 "ldr r5, [%[tmp], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15159 "ldr r6, [%[tmp], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15160 "str r3, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15161 "str r4, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15162 "str r5, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15163 "str r6, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15164 "ldr r3, [%[tmp], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15165 "ldr r4, [%[tmp], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15166 "ldr r5, [%[tmp], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15167 "ldr r6, [%[tmp], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15168 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15169 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15170 "str r5, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15171 "str r6, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15172 :
wolfSSL 16:8e0d178b1d1e 15173 : [r] "r" (r), [a] "r" (a), [tmp] "r" (tmp)
wolfSSL 16:8e0d178b1d1e 15174 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11"
wolfSSL 16:8e0d178b1d1e 15175 );
wolfSSL 16:8e0d178b1d1e 15176 }
wolfSSL 16:8e0d178b1d1e 15177
wolfSSL 16:8e0d178b1d1e 15178 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 16:8e0d178b1d1e 15179 *
wolfSSL 16:8e0d178b1d1e 15180 * r Result of squaring.
wolfSSL 16:8e0d178b1d1e 15181 * a Number to square in Montogmery form.
wolfSSL 16:8e0d178b1d1e 15182 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 15183 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 15184 */
wolfSSL 16:8e0d178b1d1e 15185 static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 15186 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 15187 {
wolfSSL 16:8e0d178b1d1e 15188 sp_256_sqr_8(r, a);
wolfSSL 16:8e0d178b1d1e 15189 sp_256_mont_reduce_8(r, m, mp);
wolfSSL 16:8e0d178b1d1e 15190 }
wolfSSL 16:8e0d178b1d1e 15191
wolfSSL 16:8e0d178b1d1e 15192 #if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)
wolfSSL 16:8e0d178b1d1e 15193 /* Square the Montgomery form number a number of times. (r = a ^ n mod m)
wolfSSL 16:8e0d178b1d1e 15194 *
wolfSSL 16:8e0d178b1d1e 15195 * r Result of squaring.
wolfSSL 16:8e0d178b1d1e 15196 * a Number to square in Montogmery form.
wolfSSL 16:8e0d178b1d1e 15197 * n Number of times to square.
wolfSSL 16:8e0d178b1d1e 15198 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 15199 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 15200 */
wolfSSL 16:8e0d178b1d1e 15201 static void sp_256_mont_sqr_n_8(sp_digit* r, const sp_digit* a, int n,
wolfSSL 16:8e0d178b1d1e 15202 const sp_digit* m, sp_digit mp)
wolfSSL 16:8e0d178b1d1e 15203 {
wolfSSL 16:8e0d178b1d1e 15204 sp_256_mont_sqr_8(r, a, m, mp);
wolfSSL 16:8e0d178b1d1e 15205 for (; n > 1; n--) {
wolfSSL 16:8e0d178b1d1e 15206 sp_256_mont_sqr_8(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 15207 }
wolfSSL 16:8e0d178b1d1e 15208 }
wolfSSL 16:8e0d178b1d1e 15209
wolfSSL 16:8e0d178b1d1e 15210 #endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */
wolfSSL 16:8e0d178b1d1e 15211 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 15212 /* Mod-2 for the P256 curve. */
wolfSSL 16:8e0d178b1d1e 15213 static const uint32_t p256_mod_minus_2[8] = {
wolfSSL 16:8e0d178b1d1e 15214 0xfffffffdU,0xffffffffU,0xffffffffU,0x00000000U,0x00000000U,0x00000000U,
wolfSSL 16:8e0d178b1d1e 15215 0x00000001U,0xffffffffU
wolfSSL 16:8e0d178b1d1e 15216 };
wolfSSL 16:8e0d178b1d1e 15217 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 15218
wolfSSL 16:8e0d178b1d1e 15219 /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
wolfSSL 16:8e0d178b1d1e 15220 * P256 curve. (r = 1 / a mod m)
wolfSSL 16:8e0d178b1d1e 15221 *
wolfSSL 16:8e0d178b1d1e 15222 * r Inverse result.
wolfSSL 16:8e0d178b1d1e 15223 * a Number to invert.
wolfSSL 16:8e0d178b1d1e 15224 * td Temporary data.
wolfSSL 16:8e0d178b1d1e 15225 */
wolfSSL 16:8e0d178b1d1e 15226 static void sp_256_mont_inv_8(sp_digit* r, const sp_digit* a, sp_digit* td)
wolfSSL 16:8e0d178b1d1e 15227 {
wolfSSL 16:8e0d178b1d1e 15228 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 15229 sp_digit* t = td;
wolfSSL 16:8e0d178b1d1e 15230 int i;
wolfSSL 16:8e0d178b1d1e 15231
wolfSSL 16:8e0d178b1d1e 15232 XMEMCPY(t, a, sizeof(sp_digit) * 8);
wolfSSL 16:8e0d178b1d1e 15233 for (i=254; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 15234 sp_256_mont_sqr_8(t, t, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15235 if (p256_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 16:8e0d178b1d1e 15236 sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15237 }
wolfSSL 16:8e0d178b1d1e 15238 XMEMCPY(r, t, sizeof(sp_digit) * 8);
wolfSSL 16:8e0d178b1d1e 15239 #else
wolfSSL 16:8e0d178b1d1e 15240 sp_digit* t1 = td;
wolfSSL 16:8e0d178b1d1e 15241 sp_digit* t2 = td + 2 * 8;
wolfSSL 16:8e0d178b1d1e 15242 sp_digit* t3 = td + 4 * 8;
wolfSSL 16:8e0d178b1d1e 15243 /* 0x2 */
wolfSSL 16:8e0d178b1d1e 15244 sp_256_mont_sqr_8(t1, a, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15245 /* 0x3 */
wolfSSL 16:8e0d178b1d1e 15246 sp_256_mont_mul_8(t2, t1, a, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15247 /* 0xc */
wolfSSL 16:8e0d178b1d1e 15248 sp_256_mont_sqr_n_8(t1, t2, 2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15249 /* 0xd */
wolfSSL 16:8e0d178b1d1e 15250 sp_256_mont_mul_8(t3, t1, a, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15251 /* 0xf */
wolfSSL 16:8e0d178b1d1e 15252 sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15253 /* 0xf0 */
wolfSSL 16:8e0d178b1d1e 15254 sp_256_mont_sqr_n_8(t1, t2, 4, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15255 /* 0xfd */
wolfSSL 16:8e0d178b1d1e 15256 sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15257 /* 0xff */
wolfSSL 16:8e0d178b1d1e 15258 sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15259 /* 0xff00 */
wolfSSL 16:8e0d178b1d1e 15260 sp_256_mont_sqr_n_8(t1, t2, 8, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15261 /* 0xfffd */
wolfSSL 16:8e0d178b1d1e 15262 sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15263 /* 0xffff */
wolfSSL 16:8e0d178b1d1e 15264 sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15265 /* 0xffff0000 */
wolfSSL 16:8e0d178b1d1e 15266 sp_256_mont_sqr_n_8(t1, t2, 16, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15267 /* 0xfffffffd */
wolfSSL 16:8e0d178b1d1e 15268 sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15269 /* 0xffffffff */
wolfSSL 16:8e0d178b1d1e 15270 sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15271 /* 0xffffffff00000000 */
wolfSSL 16:8e0d178b1d1e 15272 sp_256_mont_sqr_n_8(t1, t2, 32, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15273 /* 0xffffffffffffffff */
wolfSSL 16:8e0d178b1d1e 15274 sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15275 /* 0xffffffff00000001 */
wolfSSL 16:8e0d178b1d1e 15276 sp_256_mont_mul_8(r, t1, a, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15277 /* 0xffffffff000000010000000000000000000000000000000000000000 */
wolfSSL 16:8e0d178b1d1e 15278 sp_256_mont_sqr_n_8(r, r, 160, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15279 /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */
wolfSSL 16:8e0d178b1d1e 15280 sp_256_mont_mul_8(r, r, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15281 /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */
wolfSSL 16:8e0d178b1d1e 15282 sp_256_mont_sqr_n_8(r, r, 32, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15283 /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */
wolfSSL 16:8e0d178b1d1e 15284 sp_256_mont_mul_8(r, r, t3, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15285 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 15286 }
wolfSSL 16:8e0d178b1d1e 15287
wolfSSL 16:8e0d178b1d1e 15288 /* Compare a with b in constant time.
wolfSSL 16:8e0d178b1d1e 15289 *
wolfSSL 16:8e0d178b1d1e 15290 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 15291 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 15292 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 16:8e0d178b1d1e 15293 * respectively.
wolfSSL 16:8e0d178b1d1e 15294 */
wolfSSL 16:8e0d178b1d1e 15295 SP_NOINLINE static int32_t sp_256_cmp_8(const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 15296 {
wolfSSL 16:8e0d178b1d1e 15297 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 15298
wolfSSL 16:8e0d178b1d1e 15299
wolfSSL 16:8e0d178b1d1e 15300 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15301 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15302 "mvn r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15303 "mov r6, #28\n\t"
wolfSSL 16:8e0d178b1d1e 15304 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 15305 "ldr r8, [%[a], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 15306 "ldr r5, [%[b], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 15307 "and r8, r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15308 "and r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15309 "mov r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15310 "subs r8, r8, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15311 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15312 "add %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 15313 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15314 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15315 "subs r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15316 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15317 "sub %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 15318 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15319 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15320 "sub r6, r6, #4\n\t"
wolfSSL 16:8e0d178b1d1e 15321 "cmp r6, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15322 "bge 1b\n\t"
wolfSSL 16:8e0d178b1d1e 15323 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 15324 : [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 15325 : "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 15326 );
wolfSSL 16:8e0d178b1d1e 15327
wolfSSL 16:8e0d178b1d1e 15328 return r;
wolfSSL 16:8e0d178b1d1e 15329 }
wolfSSL 16:8e0d178b1d1e 15330
wolfSSL 16:8e0d178b1d1e 15331 /* Normalize the values in each word to 32.
wolfSSL 16:8e0d178b1d1e 15332 *
wolfSSL 16:8e0d178b1d1e 15333 * a Array of sp_digit to normalize.
wolfSSL 16:8e0d178b1d1e 15334 */
wolfSSL 16:8e0d178b1d1e 15335 #define sp_256_norm_8(a)
wolfSSL 16:8e0d178b1d1e 15336
wolfSSL 16:8e0d178b1d1e 15337 /* Map the Montgomery form projective coordinate point to an affine point.
wolfSSL 16:8e0d178b1d1e 15338 *
wolfSSL 16:8e0d178b1d1e 15339 * r Resulting affine coordinate point.
wolfSSL 16:8e0d178b1d1e 15340 * p Montgomery form projective coordinate point.
wolfSSL 16:8e0d178b1d1e 15341 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 15342 */
wolfSSL 16:8e0d178b1d1e 15343 static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 15344 {
wolfSSL 16:8e0d178b1d1e 15345 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 15346 sp_digit* t2 = t + 2*8;
wolfSSL 16:8e0d178b1d1e 15347 int32_t n;
wolfSSL 16:8e0d178b1d1e 15348
wolfSSL 16:8e0d178b1d1e 15349 sp_256_mont_inv_8(t1, p->z, t + 2*8);
wolfSSL 16:8e0d178b1d1e 15350
wolfSSL 16:8e0d178b1d1e 15351 sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15352 sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15353
wolfSSL 16:8e0d178b1d1e 15354 /* x /= z^2 */
wolfSSL 16:8e0d178b1d1e 15355 sp_256_mont_mul_8(r->x, p->x, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15356 XMEMSET(r->x + 8, 0, sizeof(r->x) / 2U);
wolfSSL 16:8e0d178b1d1e 15357 sp_256_mont_reduce_8(r->x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15358 /* Reduce x to less than modulus */
wolfSSL 16:8e0d178b1d1e 15359 n = sp_256_cmp_8(r->x, p256_mod);
wolfSSL 16:8e0d178b1d1e 15360 sp_256_cond_sub_8(r->x, r->x, p256_mod, 0 - ((n >= 0) ?
wolfSSL 16:8e0d178b1d1e 15361 (sp_digit)1 : (sp_digit)0));
wolfSSL 16:8e0d178b1d1e 15362 sp_256_norm_8(r->x);
wolfSSL 16:8e0d178b1d1e 15363
wolfSSL 16:8e0d178b1d1e 15364 /* y /= z^3 */
wolfSSL 16:8e0d178b1d1e 15365 sp_256_mont_mul_8(r->y, p->y, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15366 XMEMSET(r->y + 8, 0, sizeof(r->y) / 2U);
wolfSSL 16:8e0d178b1d1e 15367 sp_256_mont_reduce_8(r->y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15368 /* Reduce y to less than modulus */
wolfSSL 16:8e0d178b1d1e 15369 n = sp_256_cmp_8(r->y, p256_mod);
wolfSSL 16:8e0d178b1d1e 15370 sp_256_cond_sub_8(r->y, r->y, p256_mod, 0 - ((n >= 0) ?
wolfSSL 16:8e0d178b1d1e 15371 (sp_digit)1 : (sp_digit)0));
wolfSSL 16:8e0d178b1d1e 15372 sp_256_norm_8(r->y);
wolfSSL 16:8e0d178b1d1e 15373
wolfSSL 16:8e0d178b1d1e 15374 XMEMSET(r->z, 0, sizeof(r->z));
wolfSSL 16:8e0d178b1d1e 15375 r->z[0] = 1;
wolfSSL 16:8e0d178b1d1e 15376
wolfSSL 16:8e0d178b1d1e 15377 }
wolfSSL 16:8e0d178b1d1e 15378
wolfSSL 16:8e0d178b1d1e 15379 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 15380 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 15381 *
wolfSSL 16:8e0d178b1d1e 15382 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 15383 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 15384 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 15385 */
wolfSSL 16:8e0d178b1d1e 15386 SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 15387 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 15388 {
wolfSSL 16:8e0d178b1d1e 15389 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 15390
wolfSSL 16:8e0d178b1d1e 15391 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15392 "mov r6, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 15393 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15394 "add r6, r6, #32\n\t"
wolfSSL 16:8e0d178b1d1e 15395 "sub r8, r8, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15396 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 15397 "adds %[c], %[c], r8\n\t"
wolfSSL 16:8e0d178b1d1e 15398 "ldr r4, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 15399 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 15400 "adcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15401 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 15402 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 15403 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 15404 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 15405 "add %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 15406 "add %[r], %[r], #4\n\t"
wolfSSL 16:8e0d178b1d1e 15407 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 15408 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 15409 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 15410 :
wolfSSL 16:8e0d178b1d1e 15411 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 15412 );
wolfSSL 16:8e0d178b1d1e 15413
wolfSSL 16:8e0d178b1d1e 15414 return c;
wolfSSL 16:8e0d178b1d1e 15415 }
wolfSSL 16:8e0d178b1d1e 15416
wolfSSL 16:8e0d178b1d1e 15417 #else
wolfSSL 16:8e0d178b1d1e 15418 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 15419 *
wolfSSL 16:8e0d178b1d1e 15420 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 15421 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 15422 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 15423 */
wolfSSL 16:8e0d178b1d1e 15424 SP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 15425 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 15426 {
wolfSSL 16:8e0d178b1d1e 15427 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 15428
wolfSSL 16:8e0d178b1d1e 15429 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15430 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 15431 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 15432 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15433 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15434 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 15435 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 15436 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 15437 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15438 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15439 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 15440 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 15441 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 15442 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15443 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15444 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 15445 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 15446 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 15447 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15448 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15449 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 15450 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 15451 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 15452 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 15453 :
wolfSSL 16:8e0d178b1d1e 15454 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 15455 );
wolfSSL 16:8e0d178b1d1e 15456
wolfSSL 16:8e0d178b1d1e 15457 return c;
wolfSSL 16:8e0d178b1d1e 15458 }
wolfSSL 16:8e0d178b1d1e 15459
wolfSSL 16:8e0d178b1d1e 15460 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 15461 /* Add two Montgomery form numbers (r = a + b % m).
wolfSSL 16:8e0d178b1d1e 15462 *
wolfSSL 16:8e0d178b1d1e 15463 * r Result of addition.
wolfSSL 16:8e0d178b1d1e 15464 * a First number to add in Montogmery form.
wolfSSL 16:8e0d178b1d1e 15465 * b Second number to add in Montogmery form.
wolfSSL 16:8e0d178b1d1e 15466 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 15467 */
wolfSSL 16:8e0d178b1d1e 15468 SP_NOINLINE static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 15469 const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 15470 {
wolfSSL 16:8e0d178b1d1e 15471 (void)m;
wolfSSL 16:8e0d178b1d1e 15472
wolfSSL 16:8e0d178b1d1e 15473 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15474 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15475 "ldr r4, [%[a],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15476 "ldr r5, [%[a],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15477 "ldr r6, [%[b],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15478 "ldr r8, [%[b],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15479 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15480 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15481 "str r4, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15482 "str r5, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15483 "ldr r4, [%[a],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15484 "ldr r5, [%[a],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15485 "ldr r6, [%[b],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15486 "ldr r8, [%[b],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15487 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15488 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15489 "str r4, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15490 "str r5, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15491 "ldr r4, [%[a],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15492 "ldr r5, [%[a],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15493 "ldr r6, [%[b],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15494 "ldr r8, [%[b],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15495 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15496 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15497 "mov r9, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15498 "mov r10, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15499 "ldr r4, [%[a],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15500 "ldr r5, [%[a],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15501 "ldr r6, [%[b],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15502 "ldr r8, [%[b],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15503 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15504 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15505 "mov r11, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15506 "mov r12, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15507 "adc r3, r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15508 "mov r6, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15509 "sub r3, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15510 "mvn r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15511 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15512 "ldr r4, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15513 "ldr r5, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15514 "subs r4, r4, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15515 "sbcs r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15516 "str r4, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15517 "str r5, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15518 "ldr r4, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15519 "ldr r5, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15520 "sbcs r4, r4, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15521 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15522 "str r4, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15523 "str r5, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15524 "mov r4, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15525 "mov r5, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15526 "sbcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15527 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15528 "str r4, [%[r],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15529 "str r5, [%[r],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15530 "mov r4, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15531 "mov r5, r12\n\t"
wolfSSL 16:8e0d178b1d1e 15532 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15533 "sbc r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15534 "str r4, [%[r],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15535 "str r5, [%[r],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15536 :
wolfSSL 16:8e0d178b1d1e 15537 : [r] "r" (r), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 15538 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 15539 );
wolfSSL 16:8e0d178b1d1e 15540 }
wolfSSL 16:8e0d178b1d1e 15541
wolfSSL 16:8e0d178b1d1e 15542 /* Double a Montgomery form number (r = a + a % m).
wolfSSL 16:8e0d178b1d1e 15543 *
wolfSSL 16:8e0d178b1d1e 15544 * r Result of doubling.
wolfSSL 16:8e0d178b1d1e 15545 * a Number to double in Montogmery form.
wolfSSL 16:8e0d178b1d1e 15546 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 15547 */
wolfSSL 16:8e0d178b1d1e 15548 SP_NOINLINE static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 15549 {
wolfSSL 16:8e0d178b1d1e 15550 (void)m;
wolfSSL 16:8e0d178b1d1e 15551
wolfSSL 16:8e0d178b1d1e 15552 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15553 "ldr r4, [%[a],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15554 "ldr r5, [%[a],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15555 "ldr r6, [%[a],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15556 "ldr r8, [%[a],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15557 "adds r4, r4, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15558 "adcs r5, r5, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15559 "adcs r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15560 "adcs r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15561 "str r4, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15562 "str r5, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15563 "str r6, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15564 "str r8, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15565 "ldr r4, [%[a],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15566 "ldr r5, [%[a],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15567 "ldr r6, [%[a],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15568 "ldr r8, [%[a],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15569 "adcs r4, r4, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15570 "adcs r5, r5, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15571 "adcs r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15572 "adcs r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15573 "mov r9, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15574 "mov r10, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15575 "mov r11, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15576 "mov r12, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15577 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15578 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15579 "adc r3, r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15580 "mov r2, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15581 "sub r3, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15582 "mvn r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15583 "ldr r4, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15584 "ldr r5, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15585 "ldr r6, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15586 "subs r4, r4, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15587 "sbcs r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15588 "sbcs r6, r6, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15589 "str r4, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15590 "str r5, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15591 "str r6, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15592 "ldr r4, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15593 "mov r5, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15594 "mov r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15595 "sbcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15596 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15597 "sbcs r6, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15598 "str r4, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15599 "str r5, [%[r],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15600 "str r6, [%[r],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15601 "mov r4, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15602 "mov r5, r12\n\t"
wolfSSL 16:8e0d178b1d1e 15603 "sbcs r4, r4, r2\n\t"
wolfSSL 16:8e0d178b1d1e 15604 "sbc r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15605 "str r4, [%[r],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15606 "str r5, [%[r],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15607 :
wolfSSL 16:8e0d178b1d1e 15608 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 15609 : "memory", "r3", "r2", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 15610 );
wolfSSL 16:8e0d178b1d1e 15611 }
wolfSSL 16:8e0d178b1d1e 15612
wolfSSL 16:8e0d178b1d1e 15613 /* Triple a Montgomery form number (r = a + a + a % m).
wolfSSL 16:8e0d178b1d1e 15614 *
wolfSSL 16:8e0d178b1d1e 15615 * r Result of Tripling.
wolfSSL 16:8e0d178b1d1e 15616 * a Number to triple in Montogmery form.
wolfSSL 16:8e0d178b1d1e 15617 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 15618 */
wolfSSL 16:8e0d178b1d1e 15619 SP_NOINLINE static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 15620 {
wolfSSL 16:8e0d178b1d1e 15621 (void)m;
wolfSSL 16:8e0d178b1d1e 15622
wolfSSL 16:8e0d178b1d1e 15623 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15624 "ldr r2, [%[a],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15625 "ldr r3, [%[a],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15626 "ldr r4, [%[a],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15627 "ldr r5, [%[a],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15628 "ldr r6, [%[a],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15629 "ldr r8, [%[a],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15630 "ldr r9, [%[a],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15631 "ldr r10, [%[a],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15632 "adds r2, r2, r2\n\t"
wolfSSL 16:8e0d178b1d1e 15633 "adcs r3, r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15634 "adcs r4, r4, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15635 "adcs r5, r5, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15636 "adcs r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15637 "adcs r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15638 "adcs r9, r9, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15639 "adcs r10, r10, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15640 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15641 "mov r14, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15642 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15643 "mov r12, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15644 "sub r11, r11, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15645 "mvn r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15646 "subs r2, r2, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15647 "sbcs r3, r3, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15648 "sbcs r4, r4, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15649 "sbcs r5, r5, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15650 "sbcs r6, r6, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15651 "sbcs r8, r8, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15652 "sbcs r9, r9, r12\n\t"
wolfSSL 16:8e0d178b1d1e 15653 "sbc r10, r10, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15654 "ldr r12, [%[a],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15655 "ldr r14, [%[a],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15656 "adds r2, r2, r12\n\t"
wolfSSL 16:8e0d178b1d1e 15657 "adcs r3, r3, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15658 "ldr r12, [%[a],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15659 "ldr r14, [%[a],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15660 "adcs r4, r4, r12\n\t"
wolfSSL 16:8e0d178b1d1e 15661 "adcs r5, r5, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15662 "ldr r12, [%[a],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15663 "ldr r14, [%[a],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15664 "adcs r6, r6, r12\n\t"
wolfSSL 16:8e0d178b1d1e 15665 "adcs r8, r8, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15666 "ldr r12, [%[a],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15667 "ldr r14, [%[a],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15668 "adcs r9, r9, r12\n\t"
wolfSSL 16:8e0d178b1d1e 15669 "adcs r10, r10, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15670 "mov r11, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15671 "mov r14, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15672 "adc r11, r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15673 "mov r12, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15674 "sub r11, r11, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15675 "mvn r11, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15676 "subs r2, r2, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15677 "str r2, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15678 "sbcs r3, r3, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15679 "str r3, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15680 "sbcs r4, r4, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15681 "str r4, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15682 "sbcs r5, r5, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15683 "str r5, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15684 "sbcs r6, r6, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15685 "str r6, [%[r],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15686 "sbcs r8, r8, r14\n\t"
wolfSSL 16:8e0d178b1d1e 15687 "str r8, [%[r],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15688 "sbcs r9, r9, r12\n\t"
wolfSSL 16:8e0d178b1d1e 15689 "str r9, [%[r],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15690 "sbc r10, r10, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15691 "str r10, [%[r],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15692 :
wolfSSL 16:8e0d178b1d1e 15693 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 15694 : "memory", "r11", "r12", "r14", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10"
wolfSSL 16:8e0d178b1d1e 15695 );
wolfSSL 16:8e0d178b1d1e 15696 }
wolfSSL 16:8e0d178b1d1e 15697
wolfSSL 16:8e0d178b1d1e 15698 /* Subtract two Montgomery form numbers (r = a - b % m).
wolfSSL 16:8e0d178b1d1e 15699 *
wolfSSL 16:8e0d178b1d1e 15700 * r Result of subtration.
wolfSSL 16:8e0d178b1d1e 15701 * a Number to subtract from in Montogmery form.
wolfSSL 16:8e0d178b1d1e 15702 * b Number to subtract with in Montogmery form.
wolfSSL 16:8e0d178b1d1e 15703 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 15704 */
wolfSSL 16:8e0d178b1d1e 15705 SP_NOINLINE static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 15706 const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 15707 {
wolfSSL 16:8e0d178b1d1e 15708 (void)m;
wolfSSL 16:8e0d178b1d1e 15709
wolfSSL 16:8e0d178b1d1e 15710 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15711 "ldr r4, [%[a],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15712 "ldr r5, [%[a],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15713 "ldr r6, [%[b],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15714 "ldr r8, [%[b],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15715 "subs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15716 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15717 "str r4, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15718 "str r5, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15719 "ldr r4, [%[a],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15720 "ldr r5, [%[a],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15721 "ldr r6, [%[b],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15722 "ldr r8, [%[b],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15723 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15724 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15725 "str r4, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15726 "str r5, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15727 "ldr r4, [%[a],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15728 "ldr r5, [%[a],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15729 "ldr r6, [%[b],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15730 "ldr r8, [%[b],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15731 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15732 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15733 "mov r9, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15734 "mov r10, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15735 "ldr r4, [%[a],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15736 "ldr r5, [%[a],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15737 "ldr r6, [%[b],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15738 "ldr r8, [%[b],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15739 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15740 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15741 "mov r11, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15742 "mov r12, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15743 "sbc r3, r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15744 "lsr r8, r3, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15745 "mov r6, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15746 "ldr r4, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15747 "ldr r5, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15748 "adds r4, r4, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15749 "adcs r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15750 "str r4, [%[r],#0]\n\t"
wolfSSL 16:8e0d178b1d1e 15751 "str r5, [%[r],#4]\n\t"
wolfSSL 16:8e0d178b1d1e 15752 "ldr r4, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15753 "ldr r5, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15754 "adcs r4, r4, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15755 "adcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15756 "str r4, [%[r],#8]\n\t"
wolfSSL 16:8e0d178b1d1e 15757 "str r5, [%[r],#12]\n\t"
wolfSSL 16:8e0d178b1d1e 15758 "mov r4, r9\n\t"
wolfSSL 16:8e0d178b1d1e 15759 "mov r5, r10\n\t"
wolfSSL 16:8e0d178b1d1e 15760 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15761 "adcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15762 "str r4, [%[r],#16]\n\t"
wolfSSL 16:8e0d178b1d1e 15763 "str r5, [%[r],#20]\n\t"
wolfSSL 16:8e0d178b1d1e 15764 "mov r4, r11\n\t"
wolfSSL 16:8e0d178b1d1e 15765 "mov r5, r12\n\t"
wolfSSL 16:8e0d178b1d1e 15766 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15767 "adc r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15768 "str r4, [%[r],#24]\n\t"
wolfSSL 16:8e0d178b1d1e 15769 "str r5, [%[r],#28]\n\t"
wolfSSL 16:8e0d178b1d1e 15770 :
wolfSSL 16:8e0d178b1d1e 15771 : [r] "r" (r), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 15772 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 15773 );
wolfSSL 16:8e0d178b1d1e 15774 }
wolfSSL 16:8e0d178b1d1e 15775
wolfSSL 16:8e0d178b1d1e 15776 /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
wolfSSL 16:8e0d178b1d1e 15777 *
wolfSSL 16:8e0d178b1d1e 15778 * r Result of division by 2.
wolfSSL 16:8e0d178b1d1e 15779 * a Number to divide.
wolfSSL 16:8e0d178b1d1e 15780 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 15781 */
wolfSSL 16:8e0d178b1d1e 15782 SP_NOINLINE static void sp_256_div2_8(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 15783 {
wolfSSL 16:8e0d178b1d1e 15784 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15785 "ldr r8, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15786 "lsl r8, r8, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15787 "lsr r8, r8, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15788 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15789 "sub r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15790 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15791 "lsl r6, r5, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15792 "lsr r6, r6, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15793 "ldr r3, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15794 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15795 "adds r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15796 "adcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15797 "str r3, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15798 "str r4, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15799 "ldr r3, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15800 "ldr r4, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15801 "adcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15802 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15803 "str r3, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15804 "str r4, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15805 "ldr r3, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15806 "ldr r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15807 "adcs r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15808 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15809 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15810 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15811 "ldr r3, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15812 "ldr r4, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15813 "adcs r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15814 "adcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15815 "adc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15816 "lsl r8, r8, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15817 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15818 "lsl r3, r3, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15819 "lsr r6, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15820 "lsl r4, r4, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15821 "orr r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15822 "orr r6, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15823 "mov r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15824 "str r5, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15825 "str r6, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15826 "ldr r3, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15827 "ldr r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15828 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15829 "lsl r3, r3, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15830 "lsr r6, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15831 "lsl r4, r4, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15832 "orr r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15833 "orr r6, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15834 "mov r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15835 "str r5, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15836 "str r6, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15837 "ldr r3, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15838 "ldr r4, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15839 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15840 "lsl r3, r3, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15841 "lsr r6, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15842 "lsl r4, r4, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15843 "orr r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15844 "orr r6, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15845 "mov r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 15846 "str r5, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15847 "str r6, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15848 "ldr r3, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15849 "ldr r4, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15850 "lsr r5, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15851 "lsr r6, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 15852 "lsl r4, r4, #31\n\t"
wolfSSL 16:8e0d178b1d1e 15853 "orr r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 15854 "orr r6, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15855 "str r5, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15856 "str r6, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15857 :
wolfSSL 16:8e0d178b1d1e 15858 : [r] "r" (r), [a] "r" (a), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 15859 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 15860 );
wolfSSL 16:8e0d178b1d1e 15861 }
wolfSSL 16:8e0d178b1d1e 15862
wolfSSL 16:8e0d178b1d1e 15863 /* Double the Montgomery form projective point p.
wolfSSL 16:8e0d178b1d1e 15864 *
wolfSSL 16:8e0d178b1d1e 15865 * r Result of doubling point.
wolfSSL 16:8e0d178b1d1e 15866 * p Point to double.
wolfSSL 16:8e0d178b1d1e 15867 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 15868 */
wolfSSL 16:8e0d178b1d1e 15869 static void sp_256_proj_point_dbl_8(sp_point_256* r, const sp_point_256* p, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 15870 {
wolfSSL 16:8e0d178b1d1e 15871 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 15872 sp_digit* t2 = t + 2*8;
wolfSSL 16:8e0d178b1d1e 15873 sp_digit* x;
wolfSSL 16:8e0d178b1d1e 15874 sp_digit* y;
wolfSSL 16:8e0d178b1d1e 15875 sp_digit* z;
wolfSSL 16:8e0d178b1d1e 15876
wolfSSL 16:8e0d178b1d1e 15877 x = r->x;
wolfSSL 16:8e0d178b1d1e 15878 y = r->y;
wolfSSL 16:8e0d178b1d1e 15879 z = r->z;
wolfSSL 16:8e0d178b1d1e 15880 /* Put infinity into result. */
wolfSSL 16:8e0d178b1d1e 15881 if (r != p) {
wolfSSL 16:8e0d178b1d1e 15882 r->infinity = p->infinity;
wolfSSL 16:8e0d178b1d1e 15883 }
wolfSSL 16:8e0d178b1d1e 15884
wolfSSL 16:8e0d178b1d1e 15885 /* T1 = Z * Z */
wolfSSL 16:8e0d178b1d1e 15886 sp_256_mont_sqr_8(t1, p->z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15887 /* Z = Y * Z */
wolfSSL 16:8e0d178b1d1e 15888 sp_256_mont_mul_8(z, p->y, p->z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15889 /* Z = 2Z */
wolfSSL 16:8e0d178b1d1e 15890 sp_256_mont_dbl_8(z, z, p256_mod);
wolfSSL 16:8e0d178b1d1e 15891 /* T2 = X - T1 */
wolfSSL 16:8e0d178b1d1e 15892 sp_256_mont_sub_8(t2, p->x, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 15893 /* T1 = X + T1 */
wolfSSL 16:8e0d178b1d1e 15894 sp_256_mont_add_8(t1, p->x, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 15895 /* T2 = T1 * T2 */
wolfSSL 16:8e0d178b1d1e 15896 sp_256_mont_mul_8(t2, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15897 /* T1 = 3T2 */
wolfSSL 16:8e0d178b1d1e 15898 sp_256_mont_tpl_8(t1, t2, p256_mod);
wolfSSL 16:8e0d178b1d1e 15899 /* Y = 2Y */
wolfSSL 16:8e0d178b1d1e 15900 sp_256_mont_dbl_8(y, p->y, p256_mod);
wolfSSL 16:8e0d178b1d1e 15901 /* Y = Y * Y */
wolfSSL 16:8e0d178b1d1e 15902 sp_256_mont_sqr_8(y, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15903 /* T2 = Y * Y */
wolfSSL 16:8e0d178b1d1e 15904 sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15905 /* T2 = T2/2 */
wolfSSL 16:8e0d178b1d1e 15906 sp_256_div2_8(t2, t2, p256_mod);
wolfSSL 16:8e0d178b1d1e 15907 /* Y = Y * X */
wolfSSL 16:8e0d178b1d1e 15908 sp_256_mont_mul_8(y, y, p->x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15909 /* X = T1 * T1 */
wolfSSL 16:8e0d178b1d1e 15910 sp_256_mont_sqr_8(x, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15911 /* X = X - Y */
wolfSSL 16:8e0d178b1d1e 15912 sp_256_mont_sub_8(x, x, y, p256_mod);
wolfSSL 16:8e0d178b1d1e 15913 /* X = X - Y */
wolfSSL 16:8e0d178b1d1e 15914 sp_256_mont_sub_8(x, x, y, p256_mod);
wolfSSL 16:8e0d178b1d1e 15915 /* Y = Y - X */
wolfSSL 16:8e0d178b1d1e 15916 sp_256_mont_sub_8(y, y, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 15917 /* Y = Y * T1 */
wolfSSL 16:8e0d178b1d1e 15918 sp_256_mont_mul_8(y, y, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 15919 /* Y = Y - T2 */
wolfSSL 16:8e0d178b1d1e 15920 sp_256_mont_sub_8(y, y, t2, p256_mod);
wolfSSL 16:8e0d178b1d1e 15921 }
wolfSSL 16:8e0d178b1d1e 15922
wolfSSL 16:8e0d178b1d1e 15923 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 15924 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 15925 *
wolfSSL 16:8e0d178b1d1e 15926 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 15927 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 15928 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 15929 */
wolfSSL 16:8e0d178b1d1e 15930 SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 15931 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 15932 {
wolfSSL 16:8e0d178b1d1e 15933 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 15934
wolfSSL 16:8e0d178b1d1e 15935 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15936 "mov r6, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 15937 "add r6, r6, #32\n\t"
wolfSSL 16:8e0d178b1d1e 15938 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 15939 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 15940 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 15941 "ldr r4, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 15942 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 15943 "sbcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 15944 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 15945 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 15946 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 15947 "add %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 15948 "add %[r], %[r], #4\n\t"
wolfSSL 16:8e0d178b1d1e 15949 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 15950 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 15951 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 15952 :
wolfSSL 16:8e0d178b1d1e 15953 : "memory", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 15954 );
wolfSSL 16:8e0d178b1d1e 15955
wolfSSL 16:8e0d178b1d1e 15956 return c;
wolfSSL 16:8e0d178b1d1e 15957 }
wolfSSL 16:8e0d178b1d1e 15958
wolfSSL 16:8e0d178b1d1e 15959 #else
wolfSSL 16:8e0d178b1d1e 15960 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 15961 *
wolfSSL 16:8e0d178b1d1e 15962 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 15963 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 15964 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 15965 */
wolfSSL 16:8e0d178b1d1e 15966 SP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 15967 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 15968 {
wolfSSL 16:8e0d178b1d1e 15969 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 15970
wolfSSL 16:8e0d178b1d1e 15971 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 15972 "ldr r4, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15973 "ldr r5, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15974 "ldr r6, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15975 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15976 "subs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15977 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15978 "str r4, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 15979 "str r5, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 15980 "ldr r4, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15981 "ldr r5, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15982 "ldr r6, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15983 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15984 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15985 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15986 "str r4, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 15987 "str r5, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 15988 "ldr r4, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15989 "ldr r5, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15990 "ldr r6, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15991 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15992 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 15993 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 15994 "str r4, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 15995 "str r5, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 15996 "ldr r4, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15997 "ldr r5, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 15998 "ldr r6, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 15999 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 16000 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 16001 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 16002 "str r4, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 16003 "str r5, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 16004 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 16005 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 16006 :
wolfSSL 16:8e0d178b1d1e 16007 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 16008 );
wolfSSL 16:8e0d178b1d1e 16009
wolfSSL 16:8e0d178b1d1e 16010 return c;
wolfSSL 16:8e0d178b1d1e 16011 }
wolfSSL 16:8e0d178b1d1e 16012
wolfSSL 16:8e0d178b1d1e 16013 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 16014 /* Compare two numbers to determine if they are equal.
wolfSSL 16:8e0d178b1d1e 16015 * Constant time implementation.
wolfSSL 16:8e0d178b1d1e 16016 *
wolfSSL 16:8e0d178b1d1e 16017 * a First number to compare.
wolfSSL 16:8e0d178b1d1e 16018 * b Second number to compare.
wolfSSL 16:8e0d178b1d1e 16019 * returns 1 when equal and 0 otherwise.
wolfSSL 16:8e0d178b1d1e 16020 */
wolfSSL 16:8e0d178b1d1e 16021 static int sp_256_cmp_equal_8(const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 16022 {
wolfSSL 16:8e0d178b1d1e 16023 return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |
wolfSSL 16:8e0d178b1d1e 16024 (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7])) == 0;
wolfSSL 16:8e0d178b1d1e 16025 }
wolfSSL 16:8e0d178b1d1e 16026
wolfSSL 16:8e0d178b1d1e 16027 /* Add two Montgomery form projective points.
wolfSSL 16:8e0d178b1d1e 16028 *
wolfSSL 16:8e0d178b1d1e 16029 * r Result of addition.
wolfSSL 16:8e0d178b1d1e 16030 * p First point to add.
wolfSSL 16:8e0d178b1d1e 16031 * q Second point to add.
wolfSSL 16:8e0d178b1d1e 16032 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 16033 */
wolfSSL 16:8e0d178b1d1e 16034 static void sp_256_proj_point_add_8(sp_point_256* r, const sp_point_256* p, const sp_point_256* q,
wolfSSL 16:8e0d178b1d1e 16035 sp_digit* t)
wolfSSL 16:8e0d178b1d1e 16036 {
wolfSSL 16:8e0d178b1d1e 16037 const sp_point_256* ap[2];
wolfSSL 16:8e0d178b1d1e 16038 sp_point_256* rp[2];
wolfSSL 16:8e0d178b1d1e 16039 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 16040 sp_digit* t2 = t + 2*8;
wolfSSL 16:8e0d178b1d1e 16041 sp_digit* t3 = t + 4*8;
wolfSSL 16:8e0d178b1d1e 16042 sp_digit* t4 = t + 6*8;
wolfSSL 16:8e0d178b1d1e 16043 sp_digit* t5 = t + 8*8;
wolfSSL 16:8e0d178b1d1e 16044 sp_digit* x;
wolfSSL 16:8e0d178b1d1e 16045 sp_digit* y;
wolfSSL 16:8e0d178b1d1e 16046 sp_digit* z;
wolfSSL 16:8e0d178b1d1e 16047 int i;
wolfSSL 16:8e0d178b1d1e 16048
wolfSSL 16:8e0d178b1d1e 16049 /* Ensure only the first point is the same as the result. */
wolfSSL 16:8e0d178b1d1e 16050 if (q == r) {
wolfSSL 16:8e0d178b1d1e 16051 const sp_point_256* a = p;
wolfSSL 16:8e0d178b1d1e 16052 p = q;
wolfSSL 16:8e0d178b1d1e 16053 q = a;
wolfSSL 16:8e0d178b1d1e 16054 }
wolfSSL 16:8e0d178b1d1e 16055
wolfSSL 16:8e0d178b1d1e 16056 /* Check double */
wolfSSL 16:8e0d178b1d1e 16057 (void)sp_256_sub_8(t1, p256_mod, q->y);
wolfSSL 16:8e0d178b1d1e 16058 sp_256_norm_8(t1);
wolfSSL 16:8e0d178b1d1e 16059 if ((sp_256_cmp_equal_8(p->x, q->x) & sp_256_cmp_equal_8(p->z, q->z) &
wolfSSL 16:8e0d178b1d1e 16060 (sp_256_cmp_equal_8(p->y, q->y) | sp_256_cmp_equal_8(p->y, t1))) != 0) {
wolfSSL 16:8e0d178b1d1e 16061 sp_256_proj_point_dbl_8(r, p, t);
wolfSSL 16:8e0d178b1d1e 16062 }
wolfSSL 16:8e0d178b1d1e 16063 else {
wolfSSL 16:8e0d178b1d1e 16064 rp[0] = r;
wolfSSL 16:8e0d178b1d1e 16065
wolfSSL 16:8e0d178b1d1e 16066 /*lint allow cast to different type of pointer*/
wolfSSL 16:8e0d178b1d1e 16067 rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/
wolfSSL 16:8e0d178b1d1e 16068 XMEMSET(rp[1], 0, sizeof(sp_point_256));
wolfSSL 16:8e0d178b1d1e 16069 x = rp[p->infinity | q->infinity]->x;
wolfSSL 16:8e0d178b1d1e 16070 y = rp[p->infinity | q->infinity]->y;
wolfSSL 16:8e0d178b1d1e 16071 z = rp[p->infinity | q->infinity]->z;
wolfSSL 16:8e0d178b1d1e 16072
wolfSSL 16:8e0d178b1d1e 16073 ap[0] = p;
wolfSSL 16:8e0d178b1d1e 16074 ap[1] = q;
wolfSSL 16:8e0d178b1d1e 16075 for (i=0; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 16076 r->x[i] = ap[p->infinity]->x[i];
wolfSSL 16:8e0d178b1d1e 16077 }
wolfSSL 16:8e0d178b1d1e 16078 for (i=0; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 16079 r->y[i] = ap[p->infinity]->y[i];
wolfSSL 16:8e0d178b1d1e 16080 }
wolfSSL 16:8e0d178b1d1e 16081 for (i=0; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 16082 r->z[i] = ap[p->infinity]->z[i];
wolfSSL 16:8e0d178b1d1e 16083 }
wolfSSL 16:8e0d178b1d1e 16084 r->infinity = ap[p->infinity]->infinity;
wolfSSL 16:8e0d178b1d1e 16085
wolfSSL 16:8e0d178b1d1e 16086 /* U1 = X1*Z2^2 */
wolfSSL 16:8e0d178b1d1e 16087 sp_256_mont_sqr_8(t1, q->z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16088 sp_256_mont_mul_8(t3, t1, q->z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16089 sp_256_mont_mul_8(t1, t1, x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16090 /* U2 = X2*Z1^2 */
wolfSSL 16:8e0d178b1d1e 16091 sp_256_mont_sqr_8(t2, z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16092 sp_256_mont_mul_8(t4, t2, z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16093 sp_256_mont_mul_8(t2, t2, q->x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16094 /* S1 = Y1*Z2^3 */
wolfSSL 16:8e0d178b1d1e 16095 sp_256_mont_mul_8(t3, t3, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16096 /* S2 = Y2*Z1^3 */
wolfSSL 16:8e0d178b1d1e 16097 sp_256_mont_mul_8(t4, t4, q->y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16098 /* H = U2 - U1 */
wolfSSL 16:8e0d178b1d1e 16099 sp_256_mont_sub_8(t2, t2, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 16100 /* R = S2 - S1 */
wolfSSL 16:8e0d178b1d1e 16101 sp_256_mont_sub_8(t4, t4, t3, p256_mod);
wolfSSL 16:8e0d178b1d1e 16102 /* Z3 = H*Z1*Z2 */
wolfSSL 16:8e0d178b1d1e 16103 sp_256_mont_mul_8(z, z, q->z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16104 sp_256_mont_mul_8(z, z, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16105 /* X3 = R^2 - H^3 - 2*U1*H^2 */
wolfSSL 16:8e0d178b1d1e 16106 sp_256_mont_sqr_8(x, t4, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16107 sp_256_mont_sqr_8(t5, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16108 sp_256_mont_mul_8(y, t1, t5, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16109 sp_256_mont_mul_8(t5, t5, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16110 sp_256_mont_sub_8(x, x, t5, p256_mod);
wolfSSL 16:8e0d178b1d1e 16111 sp_256_mont_dbl_8(t1, y, p256_mod);
wolfSSL 16:8e0d178b1d1e 16112 sp_256_mont_sub_8(x, x, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 16113 /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
wolfSSL 16:8e0d178b1d1e 16114 sp_256_mont_sub_8(y, y, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 16115 sp_256_mont_mul_8(y, y, t4, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16116 sp_256_mont_mul_8(t5, t5, t3, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16117 sp_256_mont_sub_8(y, y, t5, p256_mod);
wolfSSL 16:8e0d178b1d1e 16118 }
wolfSSL 16:8e0d178b1d1e 16119 }
wolfSSL 16:8e0d178b1d1e 16120
wolfSSL 16:8e0d178b1d1e 16121 /* Multiply the point by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 16122 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 16123 *
wolfSSL 16:8e0d178b1d1e 16124 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 16125 * g Point to multiply.
wolfSSL 16:8e0d178b1d1e 16126 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 16127 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 16128 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 16129 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 16130 */
wolfSSL 16:8e0d178b1d1e 16131 static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 16132 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 16133 {
wolfSSL 16:8e0d178b1d1e 16134 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16135 sp_point_256 td[16];
wolfSSL 16:8e0d178b1d1e 16136 sp_point_256 rtd;
wolfSSL 16:8e0d178b1d1e 16137 sp_digit tmpd[2 * 8 * 5];
wolfSSL 16:8e0d178b1d1e 16138 #endif
wolfSSL 16:8e0d178b1d1e 16139 sp_point_256* t;
wolfSSL 16:8e0d178b1d1e 16140 sp_point_256* rt;
wolfSSL 16:8e0d178b1d1e 16141 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 16142 sp_digit n;
wolfSSL 16:8e0d178b1d1e 16143 int i;
wolfSSL 16:8e0d178b1d1e 16144 int c, y;
wolfSSL 16:8e0d178b1d1e 16145 int err;
wolfSSL 16:8e0d178b1d1e 16146
wolfSSL 16:8e0d178b1d1e 16147 (void)heap;
wolfSSL 16:8e0d178b1d1e 16148
wolfSSL 16:8e0d178b1d1e 16149 err = sp_256_point_new_8(heap, rtd, rt);
wolfSSL 16:8e0d178b1d1e 16150 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16151 t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 16, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 16152 if (t == NULL)
wolfSSL 16:8e0d178b1d1e 16153 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 16154 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,
wolfSSL 16:8e0d178b1d1e 16155 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 16156 if (tmp == NULL)
wolfSSL 16:8e0d178b1d1e 16157 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 16158 #else
wolfSSL 16:8e0d178b1d1e 16159 t = td;
wolfSSL 16:8e0d178b1d1e 16160 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 16161 #endif
wolfSSL 16:8e0d178b1d1e 16162
wolfSSL 16:8e0d178b1d1e 16163 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16164 /* t[0] = {0, 0, 1} * norm */
wolfSSL 16:8e0d178b1d1e 16165 XMEMSET(&t[0], 0, sizeof(t[0]));
wolfSSL 16:8e0d178b1d1e 16166 t[0].infinity = 1;
wolfSSL 16:8e0d178b1d1e 16167 /* t[1] = {g->x, g->y, g->z} * norm */
wolfSSL 16:8e0d178b1d1e 16168 (void)sp_256_mod_mul_norm_8(t[1].x, g->x, p256_mod);
wolfSSL 16:8e0d178b1d1e 16169 (void)sp_256_mod_mul_norm_8(t[1].y, g->y, p256_mod);
wolfSSL 16:8e0d178b1d1e 16170 (void)sp_256_mod_mul_norm_8(t[1].z, g->z, p256_mod);
wolfSSL 16:8e0d178b1d1e 16171 t[1].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16172 sp_256_proj_point_dbl_8(&t[ 2], &t[ 1], tmp);
wolfSSL 16:8e0d178b1d1e 16173 t[ 2].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16174 sp_256_proj_point_add_8(&t[ 3], &t[ 2], &t[ 1], tmp);
wolfSSL 16:8e0d178b1d1e 16175 t[ 3].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16176 sp_256_proj_point_dbl_8(&t[ 4], &t[ 2], tmp);
wolfSSL 16:8e0d178b1d1e 16177 t[ 4].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16178 sp_256_proj_point_add_8(&t[ 5], &t[ 3], &t[ 2], tmp);
wolfSSL 16:8e0d178b1d1e 16179 t[ 5].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16180 sp_256_proj_point_dbl_8(&t[ 6], &t[ 3], tmp);
wolfSSL 16:8e0d178b1d1e 16181 t[ 6].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16182 sp_256_proj_point_add_8(&t[ 7], &t[ 4], &t[ 3], tmp);
wolfSSL 16:8e0d178b1d1e 16183 t[ 7].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16184 sp_256_proj_point_dbl_8(&t[ 8], &t[ 4], tmp);
wolfSSL 16:8e0d178b1d1e 16185 t[ 8].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16186 sp_256_proj_point_add_8(&t[ 9], &t[ 5], &t[ 4], tmp);
wolfSSL 16:8e0d178b1d1e 16187 t[ 9].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16188 sp_256_proj_point_dbl_8(&t[10], &t[ 5], tmp);
wolfSSL 16:8e0d178b1d1e 16189 t[10].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16190 sp_256_proj_point_add_8(&t[11], &t[ 6], &t[ 5], tmp);
wolfSSL 16:8e0d178b1d1e 16191 t[11].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16192 sp_256_proj_point_dbl_8(&t[12], &t[ 6], tmp);
wolfSSL 16:8e0d178b1d1e 16193 t[12].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16194 sp_256_proj_point_add_8(&t[13], &t[ 7], &t[ 6], tmp);
wolfSSL 16:8e0d178b1d1e 16195 t[13].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16196 sp_256_proj_point_dbl_8(&t[14], &t[ 7], tmp);
wolfSSL 16:8e0d178b1d1e 16197 t[14].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16198 sp_256_proj_point_add_8(&t[15], &t[ 8], &t[ 7], tmp);
wolfSSL 16:8e0d178b1d1e 16199 t[15].infinity = 0;
wolfSSL 16:8e0d178b1d1e 16200
wolfSSL 16:8e0d178b1d1e 16201 i = 6;
wolfSSL 16:8e0d178b1d1e 16202 n = k[i+1] << 0;
wolfSSL 16:8e0d178b1d1e 16203 c = 28;
wolfSSL 16:8e0d178b1d1e 16204 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 16205 XMEMCPY(rt, &t[y], sizeof(sp_point_256));
wolfSSL 16:8e0d178b1d1e 16206 n <<= 4;
wolfSSL 16:8e0d178b1d1e 16207 for (; i>=0 || c>=4; ) {
wolfSSL 16:8e0d178b1d1e 16208 if (c < 4) {
wolfSSL 16:8e0d178b1d1e 16209 n |= k[i--];
wolfSSL 16:8e0d178b1d1e 16210 c += 32;
wolfSSL 16:8e0d178b1d1e 16211 }
wolfSSL 16:8e0d178b1d1e 16212 y = (n >> 28) & 0xf;
wolfSSL 16:8e0d178b1d1e 16213 n <<= 4;
wolfSSL 16:8e0d178b1d1e 16214 c -= 4;
wolfSSL 16:8e0d178b1d1e 16215
wolfSSL 16:8e0d178b1d1e 16216 sp_256_proj_point_dbl_8(rt, rt, tmp);
wolfSSL 16:8e0d178b1d1e 16217 sp_256_proj_point_dbl_8(rt, rt, tmp);
wolfSSL 16:8e0d178b1d1e 16218 sp_256_proj_point_dbl_8(rt, rt, tmp);
wolfSSL 16:8e0d178b1d1e 16219 sp_256_proj_point_dbl_8(rt, rt, tmp);
wolfSSL 16:8e0d178b1d1e 16220
wolfSSL 16:8e0d178b1d1e 16221 sp_256_proj_point_add_8(rt, rt, &t[y], tmp);
wolfSSL 16:8e0d178b1d1e 16222 }
wolfSSL 16:8e0d178b1d1e 16223
wolfSSL 16:8e0d178b1d1e 16224 if (map != 0) {
wolfSSL 16:8e0d178b1d1e 16225 sp_256_map_8(r, rt, tmp);
wolfSSL 16:8e0d178b1d1e 16226 }
wolfSSL 16:8e0d178b1d1e 16227 else {
wolfSSL 16:8e0d178b1d1e 16228 XMEMCPY(r, rt, sizeof(sp_point_256));
wolfSSL 16:8e0d178b1d1e 16229 }
wolfSSL 16:8e0d178b1d1e 16230 }
wolfSSL 16:8e0d178b1d1e 16231
wolfSSL 16:8e0d178b1d1e 16232 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16233 if (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 16234 XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 8 * 5);
wolfSSL 16:8e0d178b1d1e 16235 XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 16236 }
wolfSSL 16:8e0d178b1d1e 16237 if (t != NULL) {
wolfSSL 16:8e0d178b1d1e 16238 XMEMSET(t, 0, sizeof(sp_point_256) * 16);
wolfSSL 16:8e0d178b1d1e 16239 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 16240 }
wolfSSL 16:8e0d178b1d1e 16241 #else
wolfSSL 16:8e0d178b1d1e 16242 ForceZero(tmpd, sizeof(tmpd));
wolfSSL 16:8e0d178b1d1e 16243 ForceZero(td, sizeof(td));
wolfSSL 16:8e0d178b1d1e 16244 #endif
wolfSSL 16:8e0d178b1d1e 16245 sp_256_point_free_8(rt, 1, heap);
wolfSSL 16:8e0d178b1d1e 16246
wolfSSL 16:8e0d178b1d1e 16247 return err;
wolfSSL 16:8e0d178b1d1e 16248 }
wolfSSL 16:8e0d178b1d1e 16249
wolfSSL 16:8e0d178b1d1e 16250 /* A table entry for pre-computed points. */
wolfSSL 16:8e0d178b1d1e 16251 typedef struct sp_table_entry_256 {
wolfSSL 16:8e0d178b1d1e 16252 sp_digit x[8];
wolfSSL 16:8e0d178b1d1e 16253 sp_digit y[8];
wolfSSL 16:8e0d178b1d1e 16254 } sp_table_entry_256;
wolfSSL 16:8e0d178b1d1e 16255
wolfSSL 16:8e0d178b1d1e 16256 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 16257 /* Double the Montgomery form projective point p a number of times.
wolfSSL 16:8e0d178b1d1e 16258 *
wolfSSL 16:8e0d178b1d1e 16259 * r Result of repeated doubling of point.
wolfSSL 16:8e0d178b1d1e 16260 * p Point to double.
wolfSSL 16:8e0d178b1d1e 16261 * n Number of times to double
wolfSSL 16:8e0d178b1d1e 16262 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 16263 */
wolfSSL 16:8e0d178b1d1e 16264 static void sp_256_proj_point_dbl_n_8(sp_point_256* p, int n, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 16265 {
wolfSSL 16:8e0d178b1d1e 16266 sp_digit* w = t;
wolfSSL 16:8e0d178b1d1e 16267 sp_digit* a = t + 2*8;
wolfSSL 16:8e0d178b1d1e 16268 sp_digit* b = t + 4*8;
wolfSSL 16:8e0d178b1d1e 16269 sp_digit* t1 = t + 6*8;
wolfSSL 16:8e0d178b1d1e 16270 sp_digit* t2 = t + 8*8;
wolfSSL 16:8e0d178b1d1e 16271 sp_digit* x;
wolfSSL 16:8e0d178b1d1e 16272 sp_digit* y;
wolfSSL 16:8e0d178b1d1e 16273 sp_digit* z;
wolfSSL 16:8e0d178b1d1e 16274
wolfSSL 16:8e0d178b1d1e 16275 x = p->x;
wolfSSL 16:8e0d178b1d1e 16276 y = p->y;
wolfSSL 16:8e0d178b1d1e 16277 z = p->z;
wolfSSL 16:8e0d178b1d1e 16278
wolfSSL 16:8e0d178b1d1e 16279 /* Y = 2*Y */
wolfSSL 16:8e0d178b1d1e 16280 sp_256_mont_dbl_8(y, y, p256_mod);
wolfSSL 16:8e0d178b1d1e 16281 /* W = Z^4 */
wolfSSL 16:8e0d178b1d1e 16282 sp_256_mont_sqr_8(w, z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16283 sp_256_mont_sqr_8(w, w, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16284
wolfSSL 16:8e0d178b1d1e 16285 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 16286 while (--n > 0)
wolfSSL 16:8e0d178b1d1e 16287 #else
wolfSSL 16:8e0d178b1d1e 16288 while (--n >= 0)
wolfSSL 16:8e0d178b1d1e 16289 #endif
wolfSSL 16:8e0d178b1d1e 16290 {
wolfSSL 16:8e0d178b1d1e 16291 /* A = 3*(X^2 - W) */
wolfSSL 16:8e0d178b1d1e 16292 sp_256_mont_sqr_8(t1, x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16293 sp_256_mont_sub_8(t1, t1, w, p256_mod);
wolfSSL 16:8e0d178b1d1e 16294 sp_256_mont_tpl_8(a, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 16295 /* B = X*Y^2 */
wolfSSL 16:8e0d178b1d1e 16296 sp_256_mont_sqr_8(t1, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16297 sp_256_mont_mul_8(b, t1, x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16298 /* X = A^2 - 2B */
wolfSSL 16:8e0d178b1d1e 16299 sp_256_mont_sqr_8(x, a, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16300 sp_256_mont_dbl_8(t2, b, p256_mod);
wolfSSL 16:8e0d178b1d1e 16301 sp_256_mont_sub_8(x, x, t2, p256_mod);
wolfSSL 16:8e0d178b1d1e 16302 /* Z = Z*Y */
wolfSSL 16:8e0d178b1d1e 16303 sp_256_mont_mul_8(z, z, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16304 /* t2 = Y^4 */
wolfSSL 16:8e0d178b1d1e 16305 sp_256_mont_sqr_8(t1, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16306 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 16307 if (n != 0)
wolfSSL 16:8e0d178b1d1e 16308 #endif
wolfSSL 16:8e0d178b1d1e 16309 {
wolfSSL 16:8e0d178b1d1e 16310 /* W = W*Y^4 */
wolfSSL 16:8e0d178b1d1e 16311 sp_256_mont_mul_8(w, w, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16312 }
wolfSSL 16:8e0d178b1d1e 16313 /* y = 2*A*(B - X) - Y^4 */
wolfSSL 16:8e0d178b1d1e 16314 sp_256_mont_sub_8(y, b, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 16315 sp_256_mont_mul_8(y, y, a, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16316 sp_256_mont_dbl_8(y, y, p256_mod);
wolfSSL 16:8e0d178b1d1e 16317 sp_256_mont_sub_8(y, y, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 16318 }
wolfSSL 16:8e0d178b1d1e 16319 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 16320 /* A = 3*(X^2 - W) */
wolfSSL 16:8e0d178b1d1e 16321 sp_256_mont_sqr_8(t1, x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16322 sp_256_mont_sub_8(t1, t1, w, p256_mod);
wolfSSL 16:8e0d178b1d1e 16323 sp_256_mont_tpl_8(a, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 16324 /* B = X*Y^2 */
wolfSSL 16:8e0d178b1d1e 16325 sp_256_mont_sqr_8(t1, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16326 sp_256_mont_mul_8(b, t1, x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16327 /* X = A^2 - 2B */
wolfSSL 16:8e0d178b1d1e 16328 sp_256_mont_sqr_8(x, a, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16329 sp_256_mont_dbl_8(t2, b, p256_mod);
wolfSSL 16:8e0d178b1d1e 16330 sp_256_mont_sub_8(x, x, t2, p256_mod);
wolfSSL 16:8e0d178b1d1e 16331 /* Z = Z*Y */
wolfSSL 16:8e0d178b1d1e 16332 sp_256_mont_mul_8(z, z, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16333 /* t2 = Y^4 */
wolfSSL 16:8e0d178b1d1e 16334 sp_256_mont_sqr_8(t1, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16335 /* y = 2*A*(B - X) - Y^4 */
wolfSSL 16:8e0d178b1d1e 16336 sp_256_mont_sub_8(y, b, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 16337 sp_256_mont_mul_8(y, y, a, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16338 sp_256_mont_dbl_8(y, y, p256_mod);
wolfSSL 16:8e0d178b1d1e 16339 sp_256_mont_sub_8(y, y, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 16340 #endif
wolfSSL 16:8e0d178b1d1e 16341 /* Y = Y/2 */
wolfSSL 16:8e0d178b1d1e 16342 sp_256_div2_8(y, y, p256_mod);
wolfSSL 16:8e0d178b1d1e 16343 }
wolfSSL 16:8e0d178b1d1e 16344
wolfSSL 16:8e0d178b1d1e 16345 /* Convert the projective point to affine.
wolfSSL 16:8e0d178b1d1e 16346 * Ordinates are in Montgomery form.
wolfSSL 16:8e0d178b1d1e 16347 *
wolfSSL 16:8e0d178b1d1e 16348 * a Point to convert.
wolfSSL 16:8e0d178b1d1e 16349 * t Temporary data.
wolfSSL 16:8e0d178b1d1e 16350 */
wolfSSL 16:8e0d178b1d1e 16351 static void sp_256_proj_to_affine_8(sp_point_256* a, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 16352 {
wolfSSL 16:8e0d178b1d1e 16353 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 16354 sp_digit* t2 = t + 2 * 8;
wolfSSL 16:8e0d178b1d1e 16355 sp_digit* tmp = t + 4 * 8;
wolfSSL 16:8e0d178b1d1e 16356
wolfSSL 16:8e0d178b1d1e 16357 sp_256_mont_inv_8(t1, a->z, tmp);
wolfSSL 16:8e0d178b1d1e 16358
wolfSSL 16:8e0d178b1d1e 16359 sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16360 sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16361
wolfSSL 16:8e0d178b1d1e 16362 sp_256_mont_mul_8(a->x, a->x, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16363 sp_256_mont_mul_8(a->y, a->y, t1, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16364 XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 16365 }
wolfSSL 16:8e0d178b1d1e 16366
wolfSSL 16:8e0d178b1d1e 16367 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 16368 /* Add two Montgomery form projective points. The second point has a q value of
wolfSSL 16:8e0d178b1d1e 16369 * one.
wolfSSL 16:8e0d178b1d1e 16370 * Only the first point can be the same pointer as the result point.
wolfSSL 16:8e0d178b1d1e 16371 *
wolfSSL 16:8e0d178b1d1e 16372 * r Result of addition.
wolfSSL 16:8e0d178b1d1e 16373 * p First point to add.
wolfSSL 16:8e0d178b1d1e 16374 * q Second point to add.
wolfSSL 16:8e0d178b1d1e 16375 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 16376 */
wolfSSL 16:8e0d178b1d1e 16377 static void sp_256_proj_point_add_qz1_8(sp_point_256* r, const sp_point_256* p,
wolfSSL 16:8e0d178b1d1e 16378 const sp_point_256* q, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 16379 {
wolfSSL 16:8e0d178b1d1e 16380 const sp_point_256* ap[2];
wolfSSL 16:8e0d178b1d1e 16381 sp_point_256* rp[2];
wolfSSL 16:8e0d178b1d1e 16382 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 16383 sp_digit* t2 = t + 2*8;
wolfSSL 16:8e0d178b1d1e 16384 sp_digit* t3 = t + 4*8;
wolfSSL 16:8e0d178b1d1e 16385 sp_digit* t4 = t + 6*8;
wolfSSL 16:8e0d178b1d1e 16386 sp_digit* t5 = t + 8*8;
wolfSSL 16:8e0d178b1d1e 16387 sp_digit* x;
wolfSSL 16:8e0d178b1d1e 16388 sp_digit* y;
wolfSSL 16:8e0d178b1d1e 16389 sp_digit* z;
wolfSSL 16:8e0d178b1d1e 16390 int i;
wolfSSL 16:8e0d178b1d1e 16391
wolfSSL 16:8e0d178b1d1e 16392 /* Check double */
wolfSSL 16:8e0d178b1d1e 16393 (void)sp_256_sub_8(t1, p256_mod, q->y);
wolfSSL 16:8e0d178b1d1e 16394 sp_256_norm_8(t1);
wolfSSL 16:8e0d178b1d1e 16395 if ((sp_256_cmp_equal_8(p->x, q->x) & sp_256_cmp_equal_8(p->z, q->z) &
wolfSSL 16:8e0d178b1d1e 16396 (sp_256_cmp_equal_8(p->y, q->y) | sp_256_cmp_equal_8(p->y, t1))) != 0) {
wolfSSL 16:8e0d178b1d1e 16397 sp_256_proj_point_dbl_8(r, p, t);
wolfSSL 16:8e0d178b1d1e 16398 }
wolfSSL 16:8e0d178b1d1e 16399 else {
wolfSSL 16:8e0d178b1d1e 16400 rp[0] = r;
wolfSSL 16:8e0d178b1d1e 16401
wolfSSL 16:8e0d178b1d1e 16402 /*lint allow cast to different type of pointer*/
wolfSSL 16:8e0d178b1d1e 16403 rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/
wolfSSL 16:8e0d178b1d1e 16404 XMEMSET(rp[1], 0, sizeof(sp_point_256));
wolfSSL 16:8e0d178b1d1e 16405 x = rp[p->infinity | q->infinity]->x;
wolfSSL 16:8e0d178b1d1e 16406 y = rp[p->infinity | q->infinity]->y;
wolfSSL 16:8e0d178b1d1e 16407 z = rp[p->infinity | q->infinity]->z;
wolfSSL 16:8e0d178b1d1e 16408
wolfSSL 16:8e0d178b1d1e 16409 ap[0] = p;
wolfSSL 16:8e0d178b1d1e 16410 ap[1] = q;
wolfSSL 16:8e0d178b1d1e 16411 for (i=0; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 16412 r->x[i] = ap[p->infinity]->x[i];
wolfSSL 16:8e0d178b1d1e 16413 }
wolfSSL 16:8e0d178b1d1e 16414 for (i=0; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 16415 r->y[i] = ap[p->infinity]->y[i];
wolfSSL 16:8e0d178b1d1e 16416 }
wolfSSL 16:8e0d178b1d1e 16417 for (i=0; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 16418 r->z[i] = ap[p->infinity]->z[i];
wolfSSL 16:8e0d178b1d1e 16419 }
wolfSSL 16:8e0d178b1d1e 16420 r->infinity = ap[p->infinity]->infinity;
wolfSSL 16:8e0d178b1d1e 16421
wolfSSL 16:8e0d178b1d1e 16422 /* U2 = X2*Z1^2 */
wolfSSL 16:8e0d178b1d1e 16423 sp_256_mont_sqr_8(t2, z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16424 sp_256_mont_mul_8(t4, t2, z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16425 sp_256_mont_mul_8(t2, t2, q->x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16426 /* S2 = Y2*Z1^3 */
wolfSSL 16:8e0d178b1d1e 16427 sp_256_mont_mul_8(t4, t4, q->y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16428 /* H = U2 - X1 */
wolfSSL 16:8e0d178b1d1e 16429 sp_256_mont_sub_8(t2, t2, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 16430 /* R = S2 - Y1 */
wolfSSL 16:8e0d178b1d1e 16431 sp_256_mont_sub_8(t4, t4, y, p256_mod);
wolfSSL 16:8e0d178b1d1e 16432 /* Z3 = H*Z1 */
wolfSSL 16:8e0d178b1d1e 16433 sp_256_mont_mul_8(z, z, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16434 /* X3 = R^2 - H^3 - 2*X1*H^2 */
wolfSSL 16:8e0d178b1d1e 16435 sp_256_mont_sqr_8(t1, t4, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16436 sp_256_mont_sqr_8(t5, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16437 sp_256_mont_mul_8(t3, x, t5, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16438 sp_256_mont_mul_8(t5, t5, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16439 sp_256_mont_sub_8(x, t1, t5, p256_mod);
wolfSSL 16:8e0d178b1d1e 16440 sp_256_mont_dbl_8(t1, t3, p256_mod);
wolfSSL 16:8e0d178b1d1e 16441 sp_256_mont_sub_8(x, x, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 16442 /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
wolfSSL 16:8e0d178b1d1e 16443 sp_256_mont_sub_8(t3, t3, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 16444 sp_256_mont_mul_8(t3, t3, t4, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16445 sp_256_mont_mul_8(t5, t5, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 16446 sp_256_mont_sub_8(y, t3, t5, p256_mod);
wolfSSL 16:8e0d178b1d1e 16447 }
wolfSSL 16:8e0d178b1d1e 16448 }
wolfSSL 16:8e0d178b1d1e 16449
wolfSSL 16:8e0d178b1d1e 16450 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 16451 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 16452 /* Generate the pre-computed table of points for the base point.
wolfSSL 16:8e0d178b1d1e 16453 *
wolfSSL 16:8e0d178b1d1e 16454 * a The base point.
wolfSSL 16:8e0d178b1d1e 16455 * table Place to store generated point data.
wolfSSL 16:8e0d178b1d1e 16456 * tmp Temporary data.
wolfSSL 16:8e0d178b1d1e 16457 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 16458 */
wolfSSL 16:8e0d178b1d1e 16459 static int sp_256_gen_stripe_table_8(const sp_point_256* a,
wolfSSL 16:8e0d178b1d1e 16460 sp_table_entry_256* table, sp_digit* tmp, void* heap)
wolfSSL 16:8e0d178b1d1e 16461 {
wolfSSL 16:8e0d178b1d1e 16462 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16463 sp_point_256 td, s1d, s2d;
wolfSSL 16:8e0d178b1d1e 16464 #endif
wolfSSL 16:8e0d178b1d1e 16465 sp_point_256* t;
wolfSSL 16:8e0d178b1d1e 16466 sp_point_256* s1 = NULL;
wolfSSL 16:8e0d178b1d1e 16467 sp_point_256* s2 = NULL;
wolfSSL 16:8e0d178b1d1e 16468 int i, j;
wolfSSL 16:8e0d178b1d1e 16469 int err;
wolfSSL 16:8e0d178b1d1e 16470
wolfSSL 16:8e0d178b1d1e 16471 (void)heap;
wolfSSL 16:8e0d178b1d1e 16472
wolfSSL 16:8e0d178b1d1e 16473 err = sp_256_point_new_8(heap, td, t);
wolfSSL 16:8e0d178b1d1e 16474 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16475 err = sp_256_point_new_8(heap, s1d, s1);
wolfSSL 16:8e0d178b1d1e 16476 }
wolfSSL 16:8e0d178b1d1e 16477 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16478 err = sp_256_point_new_8(heap, s2d, s2);
wolfSSL 16:8e0d178b1d1e 16479 }
wolfSSL 16:8e0d178b1d1e 16480
wolfSSL 16:8e0d178b1d1e 16481 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16482 err = sp_256_mod_mul_norm_8(t->x, a->x, p256_mod);
wolfSSL 16:8e0d178b1d1e 16483 }
wolfSSL 16:8e0d178b1d1e 16484 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16485 err = sp_256_mod_mul_norm_8(t->y, a->y, p256_mod);
wolfSSL 16:8e0d178b1d1e 16486 }
wolfSSL 16:8e0d178b1d1e 16487 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16488 err = sp_256_mod_mul_norm_8(t->z, a->z, p256_mod);
wolfSSL 16:8e0d178b1d1e 16489 }
wolfSSL 16:8e0d178b1d1e 16490 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16491 t->infinity = 0;
wolfSSL 16:8e0d178b1d1e 16492 sp_256_proj_to_affine_8(t, tmp);
wolfSSL 16:8e0d178b1d1e 16493
wolfSSL 16:8e0d178b1d1e 16494 XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 16495 s1->infinity = 0;
wolfSSL 16:8e0d178b1d1e 16496 XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 16497 s2->infinity = 0;
wolfSSL 16:8e0d178b1d1e 16498
wolfSSL 16:8e0d178b1d1e 16499 /* table[0] = {0, 0, infinity} */
wolfSSL 16:8e0d178b1d1e 16500 XMEMSET(&table[0], 0, sizeof(sp_table_entry_256));
wolfSSL 16:8e0d178b1d1e 16501 /* table[1] = Affine version of 'a' in Montgomery form */
wolfSSL 16:8e0d178b1d1e 16502 XMEMCPY(table[1].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16503 XMEMCPY(table[1].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16504
wolfSSL 16:8e0d178b1d1e 16505 for (i=1; i<4; i++) {
wolfSSL 16:8e0d178b1d1e 16506 sp_256_proj_point_dbl_n_8(t, 64, tmp);
wolfSSL 16:8e0d178b1d1e 16507 sp_256_proj_to_affine_8(t, tmp);
wolfSSL 16:8e0d178b1d1e 16508 XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16509 XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16510 }
wolfSSL 16:8e0d178b1d1e 16511
wolfSSL 16:8e0d178b1d1e 16512 for (i=1; i<4; i++) {
wolfSSL 16:8e0d178b1d1e 16513 XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16514 XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16515 for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
wolfSSL 16:8e0d178b1d1e 16516 XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16517 XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16518 sp_256_proj_point_add_qz1_8(t, s1, s2, tmp);
wolfSSL 16:8e0d178b1d1e 16519 sp_256_proj_to_affine_8(t, tmp);
wolfSSL 16:8e0d178b1d1e 16520 XMEMCPY(table[j].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16521 XMEMCPY(table[j].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16522 }
wolfSSL 16:8e0d178b1d1e 16523 }
wolfSSL 16:8e0d178b1d1e 16524 }
wolfSSL 16:8e0d178b1d1e 16525
wolfSSL 16:8e0d178b1d1e 16526 sp_256_point_free_8(s2, 0, heap);
wolfSSL 16:8e0d178b1d1e 16527 sp_256_point_free_8(s1, 0, heap);
wolfSSL 16:8e0d178b1d1e 16528 sp_256_point_free_8( t, 0, heap);
wolfSSL 16:8e0d178b1d1e 16529
wolfSSL 16:8e0d178b1d1e 16530 return err;
wolfSSL 16:8e0d178b1d1e 16531 }
wolfSSL 16:8e0d178b1d1e 16532
wolfSSL 16:8e0d178b1d1e 16533 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 16534 /* Multiply the point by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 16535 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 16536 *
wolfSSL 16:8e0d178b1d1e 16537 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 16538 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 16539 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 16540 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 16541 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 16542 */
wolfSSL 16:8e0d178b1d1e 16543 static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g,
wolfSSL 16:8e0d178b1d1e 16544 const sp_table_entry_256* table, const sp_digit* k, int map, void* heap)
wolfSSL 16:8e0d178b1d1e 16545 {
wolfSSL 16:8e0d178b1d1e 16546 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16547 sp_point_256 rtd;
wolfSSL 16:8e0d178b1d1e 16548 sp_point_256 pd;
wolfSSL 16:8e0d178b1d1e 16549 sp_digit td[2 * 8 * 5];
wolfSSL 16:8e0d178b1d1e 16550 #endif
wolfSSL 16:8e0d178b1d1e 16551 sp_point_256* rt;
wolfSSL 16:8e0d178b1d1e 16552 sp_point_256* p = NULL;
wolfSSL 16:8e0d178b1d1e 16553 sp_digit* t;
wolfSSL 16:8e0d178b1d1e 16554 int i, j;
wolfSSL 16:8e0d178b1d1e 16555 int y, x;
wolfSSL 16:8e0d178b1d1e 16556 int err;
wolfSSL 16:8e0d178b1d1e 16557
wolfSSL 16:8e0d178b1d1e 16558 (void)g;
wolfSSL 16:8e0d178b1d1e 16559 (void)heap;
wolfSSL 16:8e0d178b1d1e 16560
wolfSSL 16:8e0d178b1d1e 16561
wolfSSL 16:8e0d178b1d1e 16562 err = sp_256_point_new_8(heap, rtd, rt);
wolfSSL 16:8e0d178b1d1e 16563 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16564 err = sp_256_point_new_8(heap, pd, p);
wolfSSL 16:8e0d178b1d1e 16565 }
wolfSSL 16:8e0d178b1d1e 16566 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16567 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,
wolfSSL 16:8e0d178b1d1e 16568 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 16569 if (t == NULL) {
wolfSSL 16:8e0d178b1d1e 16570 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 16571 }
wolfSSL 16:8e0d178b1d1e 16572 #else
wolfSSL 16:8e0d178b1d1e 16573 t = td;
wolfSSL 16:8e0d178b1d1e 16574 #endif
wolfSSL 16:8e0d178b1d1e 16575
wolfSSL 16:8e0d178b1d1e 16576 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16577 XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 16578 XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 16579
wolfSSL 16:8e0d178b1d1e 16580 y = 0;
wolfSSL 16:8e0d178b1d1e 16581 for (j=0,x=63; j<4; j++,x+=64) {
wolfSSL 16:8e0d178b1d1e 16582 y |= ((k[x / 32] >> (x % 32)) & 1) << j;
wolfSSL 16:8e0d178b1d1e 16583 }
wolfSSL 16:8e0d178b1d1e 16584 XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
wolfSSL 16:8e0d178b1d1e 16585 XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
wolfSSL 16:8e0d178b1d1e 16586 rt->infinity = !y;
wolfSSL 16:8e0d178b1d1e 16587 for (i=62; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 16588 y = 0;
wolfSSL 16:8e0d178b1d1e 16589 for (j=0,x=i; j<4; j++,x+=64) {
wolfSSL 16:8e0d178b1d1e 16590 y |= ((k[x / 32] >> (x % 32)) & 1) << j;
wolfSSL 16:8e0d178b1d1e 16591 }
wolfSSL 16:8e0d178b1d1e 16592
wolfSSL 16:8e0d178b1d1e 16593 sp_256_proj_point_dbl_8(rt, rt, t);
wolfSSL 16:8e0d178b1d1e 16594 XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
wolfSSL 16:8e0d178b1d1e 16595 XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
wolfSSL 16:8e0d178b1d1e 16596 p->infinity = !y;
wolfSSL 16:8e0d178b1d1e 16597 sp_256_proj_point_add_qz1_8(rt, rt, p, t);
wolfSSL 16:8e0d178b1d1e 16598 }
wolfSSL 16:8e0d178b1d1e 16599
wolfSSL 16:8e0d178b1d1e 16600 if (map != 0) {
wolfSSL 16:8e0d178b1d1e 16601 sp_256_map_8(r, rt, t);
wolfSSL 16:8e0d178b1d1e 16602 }
wolfSSL 16:8e0d178b1d1e 16603 else {
wolfSSL 16:8e0d178b1d1e 16604 XMEMCPY(r, rt, sizeof(sp_point_256));
wolfSSL 16:8e0d178b1d1e 16605 }
wolfSSL 16:8e0d178b1d1e 16606 }
wolfSSL 16:8e0d178b1d1e 16607
wolfSSL 16:8e0d178b1d1e 16608 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16609 if (t != NULL) {
wolfSSL 16:8e0d178b1d1e 16610 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 16611 }
wolfSSL 16:8e0d178b1d1e 16612 #endif
wolfSSL 16:8e0d178b1d1e 16613 sp_256_point_free_8(p, 0, heap);
wolfSSL 16:8e0d178b1d1e 16614 sp_256_point_free_8(rt, 0, heap);
wolfSSL 16:8e0d178b1d1e 16615
wolfSSL 16:8e0d178b1d1e 16616 return err;
wolfSSL 16:8e0d178b1d1e 16617 }
wolfSSL 16:8e0d178b1d1e 16618
wolfSSL 16:8e0d178b1d1e 16619 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 16620 #ifndef FP_ENTRIES
wolfSSL 16:8e0d178b1d1e 16621 #define FP_ENTRIES 16
wolfSSL 16:8e0d178b1d1e 16622 #endif
wolfSSL 16:8e0d178b1d1e 16623
wolfSSL 16:8e0d178b1d1e 16624 typedef struct sp_cache_256_t {
wolfSSL 16:8e0d178b1d1e 16625 sp_digit x[8];
wolfSSL 16:8e0d178b1d1e 16626 sp_digit y[8];
wolfSSL 16:8e0d178b1d1e 16627 sp_table_entry_256 table[16];
wolfSSL 16:8e0d178b1d1e 16628 uint32_t cnt;
wolfSSL 16:8e0d178b1d1e 16629 int set;
wolfSSL 16:8e0d178b1d1e 16630 } sp_cache_256_t;
wolfSSL 16:8e0d178b1d1e 16631
wolfSSL 16:8e0d178b1d1e 16632 static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES];
wolfSSL 16:8e0d178b1d1e 16633 static THREAD_LS_T int sp_cache_256_last = -1;
wolfSSL 16:8e0d178b1d1e 16634 static THREAD_LS_T int sp_cache_256_inited = 0;
wolfSSL 16:8e0d178b1d1e 16635
wolfSSL 16:8e0d178b1d1e 16636 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 16637 static volatile int initCacheMutex_256 = 0;
wolfSSL 16:8e0d178b1d1e 16638 static wolfSSL_Mutex sp_cache_256_lock;
wolfSSL 16:8e0d178b1d1e 16639 #endif
wolfSSL 16:8e0d178b1d1e 16640
wolfSSL 16:8e0d178b1d1e 16641 static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache)
wolfSSL 16:8e0d178b1d1e 16642 {
wolfSSL 16:8e0d178b1d1e 16643 int i, j;
wolfSSL 16:8e0d178b1d1e 16644 uint32_t least;
wolfSSL 16:8e0d178b1d1e 16645
wolfSSL 16:8e0d178b1d1e 16646 if (sp_cache_256_inited == 0) {
wolfSSL 16:8e0d178b1d1e 16647 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 16:8e0d178b1d1e 16648 sp_cache_256[i].set = 0;
wolfSSL 16:8e0d178b1d1e 16649 }
wolfSSL 16:8e0d178b1d1e 16650 sp_cache_256_inited = 1;
wolfSSL 16:8e0d178b1d1e 16651 }
wolfSSL 16:8e0d178b1d1e 16652
wolfSSL 16:8e0d178b1d1e 16653 /* Compare point with those in cache. */
wolfSSL 16:8e0d178b1d1e 16654 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 16:8e0d178b1d1e 16655 if (!sp_cache_256[i].set)
wolfSSL 16:8e0d178b1d1e 16656 continue;
wolfSSL 16:8e0d178b1d1e 16657
wolfSSL 16:8e0d178b1d1e 16658 if (sp_256_cmp_equal_8(g->x, sp_cache_256[i].x) &
wolfSSL 16:8e0d178b1d1e 16659 sp_256_cmp_equal_8(g->y, sp_cache_256[i].y)) {
wolfSSL 16:8e0d178b1d1e 16660 sp_cache_256[i].cnt++;
wolfSSL 16:8e0d178b1d1e 16661 break;
wolfSSL 16:8e0d178b1d1e 16662 }
wolfSSL 16:8e0d178b1d1e 16663 }
wolfSSL 16:8e0d178b1d1e 16664
wolfSSL 16:8e0d178b1d1e 16665 /* No match. */
wolfSSL 16:8e0d178b1d1e 16666 if (i == FP_ENTRIES) {
wolfSSL 16:8e0d178b1d1e 16667 /* Find empty entry. */
wolfSSL 16:8e0d178b1d1e 16668 i = (sp_cache_256_last + 1) % FP_ENTRIES;
wolfSSL 16:8e0d178b1d1e 16669 for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) {
wolfSSL 16:8e0d178b1d1e 16670 if (!sp_cache_256[i].set) {
wolfSSL 16:8e0d178b1d1e 16671 break;
wolfSSL 16:8e0d178b1d1e 16672 }
wolfSSL 16:8e0d178b1d1e 16673 }
wolfSSL 16:8e0d178b1d1e 16674
wolfSSL 16:8e0d178b1d1e 16675 /* Evict least used. */
wolfSSL 16:8e0d178b1d1e 16676 if (i == sp_cache_256_last) {
wolfSSL 16:8e0d178b1d1e 16677 least = sp_cache_256[0].cnt;
wolfSSL 16:8e0d178b1d1e 16678 for (j=1; j<FP_ENTRIES; j++) {
wolfSSL 16:8e0d178b1d1e 16679 if (sp_cache_256[j].cnt < least) {
wolfSSL 16:8e0d178b1d1e 16680 i = j;
wolfSSL 16:8e0d178b1d1e 16681 least = sp_cache_256[i].cnt;
wolfSSL 16:8e0d178b1d1e 16682 }
wolfSSL 16:8e0d178b1d1e 16683 }
wolfSSL 16:8e0d178b1d1e 16684 }
wolfSSL 16:8e0d178b1d1e 16685
wolfSSL 16:8e0d178b1d1e 16686 XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x));
wolfSSL 16:8e0d178b1d1e 16687 XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y));
wolfSSL 16:8e0d178b1d1e 16688 sp_cache_256[i].set = 1;
wolfSSL 16:8e0d178b1d1e 16689 sp_cache_256[i].cnt = 1;
wolfSSL 16:8e0d178b1d1e 16690 }
wolfSSL 16:8e0d178b1d1e 16691
wolfSSL 16:8e0d178b1d1e 16692 *cache = &sp_cache_256[i];
wolfSSL 16:8e0d178b1d1e 16693 sp_cache_256_last = i;
wolfSSL 16:8e0d178b1d1e 16694 }
wolfSSL 16:8e0d178b1d1e 16695 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 16696
wolfSSL 16:8e0d178b1d1e 16697 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 16698 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 16699 *
wolfSSL 16:8e0d178b1d1e 16700 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 16701 * g Point to multiply.
wolfSSL 16:8e0d178b1d1e 16702 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 16703 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 16704 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 16705 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 16706 */
wolfSSL 16:8e0d178b1d1e 16707 static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 16708 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 16709 {
wolfSSL 16:8e0d178b1d1e 16710 #ifndef FP_ECC
wolfSSL 16:8e0d178b1d1e 16711 return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);
wolfSSL 16:8e0d178b1d1e 16712 #else
wolfSSL 16:8e0d178b1d1e 16713 sp_digit tmp[2 * 8 * 5];
wolfSSL 16:8e0d178b1d1e 16714 sp_cache_256_t* cache;
wolfSSL 16:8e0d178b1d1e 16715 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 16716
wolfSSL 16:8e0d178b1d1e 16717 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 16718 if (initCacheMutex_256 == 0) {
wolfSSL 16:8e0d178b1d1e 16719 wc_InitMutex(&sp_cache_256_lock);
wolfSSL 16:8e0d178b1d1e 16720 initCacheMutex_256 = 1;
wolfSSL 16:8e0d178b1d1e 16721 }
wolfSSL 16:8e0d178b1d1e 16722 if (wc_LockMutex(&sp_cache_256_lock) != 0)
wolfSSL 16:8e0d178b1d1e 16723 err = BAD_MUTEX_E;
wolfSSL 16:8e0d178b1d1e 16724 #endif /* HAVE_THREAD_LS */
wolfSSL 16:8e0d178b1d1e 16725
wolfSSL 16:8e0d178b1d1e 16726 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16727 sp_ecc_get_cache_256(g, &cache);
wolfSSL 16:8e0d178b1d1e 16728 if (cache->cnt == 2)
wolfSSL 16:8e0d178b1d1e 16729 sp_256_gen_stripe_table_8(g, cache->table, tmp, heap);
wolfSSL 16:8e0d178b1d1e 16730
wolfSSL 16:8e0d178b1d1e 16731 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 16732 wc_UnLockMutex(&sp_cache_256_lock);
wolfSSL 16:8e0d178b1d1e 16733 #endif /* HAVE_THREAD_LS */
wolfSSL 16:8e0d178b1d1e 16734
wolfSSL 16:8e0d178b1d1e 16735 if (cache->cnt < 2) {
wolfSSL 16:8e0d178b1d1e 16736 err = sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);
wolfSSL 16:8e0d178b1d1e 16737 }
wolfSSL 16:8e0d178b1d1e 16738 else {
wolfSSL 16:8e0d178b1d1e 16739 err = sp_256_ecc_mulmod_stripe_8(r, g, cache->table, k,
wolfSSL 16:8e0d178b1d1e 16740 map, heap);
wolfSSL 16:8e0d178b1d1e 16741 }
wolfSSL 16:8e0d178b1d1e 16742 }
wolfSSL 16:8e0d178b1d1e 16743
wolfSSL 16:8e0d178b1d1e 16744 return err;
wolfSSL 16:8e0d178b1d1e 16745 #endif
wolfSSL 16:8e0d178b1d1e 16746 }
wolfSSL 16:8e0d178b1d1e 16747
wolfSSL 16:8e0d178b1d1e 16748 #else
wolfSSL 16:8e0d178b1d1e 16749 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 16750 /* Generate the pre-computed table of points for the base point.
wolfSSL 16:8e0d178b1d1e 16751 *
wolfSSL 16:8e0d178b1d1e 16752 * a The base point.
wolfSSL 16:8e0d178b1d1e 16753 * table Place to store generated point data.
wolfSSL 16:8e0d178b1d1e 16754 * tmp Temporary data.
wolfSSL 16:8e0d178b1d1e 16755 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 16756 */
wolfSSL 16:8e0d178b1d1e 16757 static int sp_256_gen_stripe_table_8(const sp_point_256* a,
wolfSSL 16:8e0d178b1d1e 16758 sp_table_entry_256* table, sp_digit* tmp, void* heap)
wolfSSL 16:8e0d178b1d1e 16759 {
wolfSSL 16:8e0d178b1d1e 16760 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16761 sp_point_256 td, s1d, s2d;
wolfSSL 16:8e0d178b1d1e 16762 #endif
wolfSSL 16:8e0d178b1d1e 16763 sp_point_256* t;
wolfSSL 16:8e0d178b1d1e 16764 sp_point_256* s1 = NULL;
wolfSSL 16:8e0d178b1d1e 16765 sp_point_256* s2 = NULL;
wolfSSL 16:8e0d178b1d1e 16766 int i, j;
wolfSSL 16:8e0d178b1d1e 16767 int err;
wolfSSL 16:8e0d178b1d1e 16768
wolfSSL 16:8e0d178b1d1e 16769 (void)heap;
wolfSSL 16:8e0d178b1d1e 16770
wolfSSL 16:8e0d178b1d1e 16771 err = sp_256_point_new_8(heap, td, t);
wolfSSL 16:8e0d178b1d1e 16772 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16773 err = sp_256_point_new_8(heap, s1d, s1);
wolfSSL 16:8e0d178b1d1e 16774 }
wolfSSL 16:8e0d178b1d1e 16775 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16776 err = sp_256_point_new_8(heap, s2d, s2);
wolfSSL 16:8e0d178b1d1e 16777 }
wolfSSL 16:8e0d178b1d1e 16778
wolfSSL 16:8e0d178b1d1e 16779 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16780 err = sp_256_mod_mul_norm_8(t->x, a->x, p256_mod);
wolfSSL 16:8e0d178b1d1e 16781 }
wolfSSL 16:8e0d178b1d1e 16782 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16783 err = sp_256_mod_mul_norm_8(t->y, a->y, p256_mod);
wolfSSL 16:8e0d178b1d1e 16784 }
wolfSSL 16:8e0d178b1d1e 16785 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16786 err = sp_256_mod_mul_norm_8(t->z, a->z, p256_mod);
wolfSSL 16:8e0d178b1d1e 16787 }
wolfSSL 16:8e0d178b1d1e 16788 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16789 t->infinity = 0;
wolfSSL 16:8e0d178b1d1e 16790 sp_256_proj_to_affine_8(t, tmp);
wolfSSL 16:8e0d178b1d1e 16791
wolfSSL 16:8e0d178b1d1e 16792 XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 16793 s1->infinity = 0;
wolfSSL 16:8e0d178b1d1e 16794 XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 16795 s2->infinity = 0;
wolfSSL 16:8e0d178b1d1e 16796
wolfSSL 16:8e0d178b1d1e 16797 /* table[0] = {0, 0, infinity} */
wolfSSL 16:8e0d178b1d1e 16798 XMEMSET(&table[0], 0, sizeof(sp_table_entry_256));
wolfSSL 16:8e0d178b1d1e 16799 /* table[1] = Affine version of 'a' in Montgomery form */
wolfSSL 16:8e0d178b1d1e 16800 XMEMCPY(table[1].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16801 XMEMCPY(table[1].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16802
wolfSSL 16:8e0d178b1d1e 16803 for (i=1; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 16804 sp_256_proj_point_dbl_n_8(t, 32, tmp);
wolfSSL 16:8e0d178b1d1e 16805 sp_256_proj_to_affine_8(t, tmp);
wolfSSL 16:8e0d178b1d1e 16806 XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16807 XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16808 }
wolfSSL 16:8e0d178b1d1e 16809
wolfSSL 16:8e0d178b1d1e 16810 for (i=1; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 16811 XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16812 XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16813 for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
wolfSSL 16:8e0d178b1d1e 16814 XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16815 XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16816 sp_256_proj_point_add_qz1_8(t, s1, s2, tmp);
wolfSSL 16:8e0d178b1d1e 16817 sp_256_proj_to_affine_8(t, tmp);
wolfSSL 16:8e0d178b1d1e 16818 XMEMCPY(table[j].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 16819 XMEMCPY(table[j].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 16820 }
wolfSSL 16:8e0d178b1d1e 16821 }
wolfSSL 16:8e0d178b1d1e 16822 }
wolfSSL 16:8e0d178b1d1e 16823
wolfSSL 16:8e0d178b1d1e 16824 sp_256_point_free_8(s2, 0, heap);
wolfSSL 16:8e0d178b1d1e 16825 sp_256_point_free_8(s1, 0, heap);
wolfSSL 16:8e0d178b1d1e 16826 sp_256_point_free_8( t, 0, heap);
wolfSSL 16:8e0d178b1d1e 16827
wolfSSL 16:8e0d178b1d1e 16828 return err;
wolfSSL 16:8e0d178b1d1e 16829 }
wolfSSL 16:8e0d178b1d1e 16830
wolfSSL 16:8e0d178b1d1e 16831 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 16832 /* Multiply the point by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 16833 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 16834 *
wolfSSL 16:8e0d178b1d1e 16835 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 16836 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 16837 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 16838 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 16839 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 16840 */
wolfSSL 16:8e0d178b1d1e 16841 static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g,
wolfSSL 16:8e0d178b1d1e 16842 const sp_table_entry_256* table, const sp_digit* k, int map, void* heap)
wolfSSL 16:8e0d178b1d1e 16843 {
wolfSSL 16:8e0d178b1d1e 16844 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16845 sp_point_256 rtd;
wolfSSL 16:8e0d178b1d1e 16846 sp_point_256 pd;
wolfSSL 16:8e0d178b1d1e 16847 sp_digit td[2 * 8 * 5];
wolfSSL 16:8e0d178b1d1e 16848 #endif
wolfSSL 16:8e0d178b1d1e 16849 sp_point_256* rt;
wolfSSL 16:8e0d178b1d1e 16850 sp_point_256* p = NULL;
wolfSSL 16:8e0d178b1d1e 16851 sp_digit* t;
wolfSSL 16:8e0d178b1d1e 16852 int i, j;
wolfSSL 16:8e0d178b1d1e 16853 int y, x;
wolfSSL 16:8e0d178b1d1e 16854 int err;
wolfSSL 16:8e0d178b1d1e 16855
wolfSSL 16:8e0d178b1d1e 16856 (void)g;
wolfSSL 16:8e0d178b1d1e 16857 (void)heap;
wolfSSL 16:8e0d178b1d1e 16858
wolfSSL 16:8e0d178b1d1e 16859
wolfSSL 16:8e0d178b1d1e 16860 err = sp_256_point_new_8(heap, rtd, rt);
wolfSSL 16:8e0d178b1d1e 16861 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16862 err = sp_256_point_new_8(heap, pd, p);
wolfSSL 16:8e0d178b1d1e 16863 }
wolfSSL 16:8e0d178b1d1e 16864 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16865 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,
wolfSSL 16:8e0d178b1d1e 16866 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 16867 if (t == NULL) {
wolfSSL 16:8e0d178b1d1e 16868 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 16869 }
wolfSSL 16:8e0d178b1d1e 16870 #else
wolfSSL 16:8e0d178b1d1e 16871 t = td;
wolfSSL 16:8e0d178b1d1e 16872 #endif
wolfSSL 16:8e0d178b1d1e 16873
wolfSSL 16:8e0d178b1d1e 16874 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 16875 XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 16876 XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 16877
wolfSSL 16:8e0d178b1d1e 16878 y = 0;
wolfSSL 16:8e0d178b1d1e 16879 for (j=0,x=31; j<8; j++,x+=32) {
wolfSSL 16:8e0d178b1d1e 16880 y |= ((k[x / 32] >> (x % 32)) & 1) << j;
wolfSSL 16:8e0d178b1d1e 16881 }
wolfSSL 16:8e0d178b1d1e 16882 XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
wolfSSL 16:8e0d178b1d1e 16883 XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
wolfSSL 16:8e0d178b1d1e 16884 rt->infinity = !y;
wolfSSL 16:8e0d178b1d1e 16885 for (i=30; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 16886 y = 0;
wolfSSL 16:8e0d178b1d1e 16887 for (j=0,x=i; j<8; j++,x+=32) {
wolfSSL 16:8e0d178b1d1e 16888 y |= ((k[x / 32] >> (x % 32)) & 1) << j;
wolfSSL 16:8e0d178b1d1e 16889 }
wolfSSL 16:8e0d178b1d1e 16890
wolfSSL 16:8e0d178b1d1e 16891 sp_256_proj_point_dbl_8(rt, rt, t);
wolfSSL 16:8e0d178b1d1e 16892 XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
wolfSSL 16:8e0d178b1d1e 16893 XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
wolfSSL 16:8e0d178b1d1e 16894 p->infinity = !y;
wolfSSL 16:8e0d178b1d1e 16895 sp_256_proj_point_add_qz1_8(rt, rt, p, t);
wolfSSL 16:8e0d178b1d1e 16896 }
wolfSSL 16:8e0d178b1d1e 16897
wolfSSL 16:8e0d178b1d1e 16898 if (map != 0) {
wolfSSL 16:8e0d178b1d1e 16899 sp_256_map_8(r, rt, t);
wolfSSL 16:8e0d178b1d1e 16900 }
wolfSSL 16:8e0d178b1d1e 16901 else {
wolfSSL 16:8e0d178b1d1e 16902 XMEMCPY(r, rt, sizeof(sp_point_256));
wolfSSL 16:8e0d178b1d1e 16903 }
wolfSSL 16:8e0d178b1d1e 16904 }
wolfSSL 16:8e0d178b1d1e 16905
wolfSSL 16:8e0d178b1d1e 16906 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 16907 if (t != NULL) {
wolfSSL 16:8e0d178b1d1e 16908 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 16909 }
wolfSSL 16:8e0d178b1d1e 16910 #endif
wolfSSL 16:8e0d178b1d1e 16911 sp_256_point_free_8(p, 0, heap);
wolfSSL 16:8e0d178b1d1e 16912 sp_256_point_free_8(rt, 0, heap);
wolfSSL 16:8e0d178b1d1e 16913
wolfSSL 16:8e0d178b1d1e 16914 return err;
wolfSSL 16:8e0d178b1d1e 16915 }
wolfSSL 16:8e0d178b1d1e 16916
wolfSSL 16:8e0d178b1d1e 16917 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 16918 #ifndef FP_ENTRIES
wolfSSL 16:8e0d178b1d1e 16919 #define FP_ENTRIES 16
wolfSSL 16:8e0d178b1d1e 16920 #endif
wolfSSL 16:8e0d178b1d1e 16921
wolfSSL 16:8e0d178b1d1e 16922 typedef struct sp_cache_256_t {
wolfSSL 16:8e0d178b1d1e 16923 sp_digit x[8];
wolfSSL 16:8e0d178b1d1e 16924 sp_digit y[8];
wolfSSL 16:8e0d178b1d1e 16925 sp_table_entry_256 table[256];
wolfSSL 16:8e0d178b1d1e 16926 uint32_t cnt;
wolfSSL 16:8e0d178b1d1e 16927 int set;
wolfSSL 16:8e0d178b1d1e 16928 } sp_cache_256_t;
wolfSSL 16:8e0d178b1d1e 16929
wolfSSL 16:8e0d178b1d1e 16930 static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES];
wolfSSL 16:8e0d178b1d1e 16931 static THREAD_LS_T int sp_cache_256_last = -1;
wolfSSL 16:8e0d178b1d1e 16932 static THREAD_LS_T int sp_cache_256_inited = 0;
wolfSSL 16:8e0d178b1d1e 16933
wolfSSL 16:8e0d178b1d1e 16934 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 16935 static volatile int initCacheMutex_256 = 0;
wolfSSL 16:8e0d178b1d1e 16936 static wolfSSL_Mutex sp_cache_256_lock;
wolfSSL 16:8e0d178b1d1e 16937 #endif
wolfSSL 16:8e0d178b1d1e 16938
wolfSSL 16:8e0d178b1d1e 16939 static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache)
wolfSSL 16:8e0d178b1d1e 16940 {
wolfSSL 16:8e0d178b1d1e 16941 int i, j;
wolfSSL 16:8e0d178b1d1e 16942 uint32_t least;
wolfSSL 16:8e0d178b1d1e 16943
wolfSSL 16:8e0d178b1d1e 16944 if (sp_cache_256_inited == 0) {
wolfSSL 16:8e0d178b1d1e 16945 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 16:8e0d178b1d1e 16946 sp_cache_256[i].set = 0;
wolfSSL 16:8e0d178b1d1e 16947 }
wolfSSL 16:8e0d178b1d1e 16948 sp_cache_256_inited = 1;
wolfSSL 16:8e0d178b1d1e 16949 }
wolfSSL 16:8e0d178b1d1e 16950
wolfSSL 16:8e0d178b1d1e 16951 /* Compare point with those in cache. */
wolfSSL 16:8e0d178b1d1e 16952 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 16:8e0d178b1d1e 16953 if (!sp_cache_256[i].set)
wolfSSL 16:8e0d178b1d1e 16954 continue;
wolfSSL 16:8e0d178b1d1e 16955
wolfSSL 16:8e0d178b1d1e 16956 if (sp_256_cmp_equal_8(g->x, sp_cache_256[i].x) &
wolfSSL 16:8e0d178b1d1e 16957 sp_256_cmp_equal_8(g->y, sp_cache_256[i].y)) {
wolfSSL 16:8e0d178b1d1e 16958 sp_cache_256[i].cnt++;
wolfSSL 16:8e0d178b1d1e 16959 break;
wolfSSL 16:8e0d178b1d1e 16960 }
wolfSSL 16:8e0d178b1d1e 16961 }
wolfSSL 16:8e0d178b1d1e 16962
wolfSSL 16:8e0d178b1d1e 16963 /* No match. */
wolfSSL 16:8e0d178b1d1e 16964 if (i == FP_ENTRIES) {
wolfSSL 16:8e0d178b1d1e 16965 /* Find empty entry. */
wolfSSL 16:8e0d178b1d1e 16966 i = (sp_cache_256_last + 1) % FP_ENTRIES;
wolfSSL 16:8e0d178b1d1e 16967 for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) {
wolfSSL 16:8e0d178b1d1e 16968 if (!sp_cache_256[i].set) {
wolfSSL 16:8e0d178b1d1e 16969 break;
wolfSSL 16:8e0d178b1d1e 16970 }
wolfSSL 16:8e0d178b1d1e 16971 }
wolfSSL 16:8e0d178b1d1e 16972
wolfSSL 16:8e0d178b1d1e 16973 /* Evict least used. */
wolfSSL 16:8e0d178b1d1e 16974 if (i == sp_cache_256_last) {
wolfSSL 16:8e0d178b1d1e 16975 least = sp_cache_256[0].cnt;
wolfSSL 16:8e0d178b1d1e 16976 for (j=1; j<FP_ENTRIES; j++) {
wolfSSL 16:8e0d178b1d1e 16977 if (sp_cache_256[j].cnt < least) {
wolfSSL 16:8e0d178b1d1e 16978 i = j;
wolfSSL 16:8e0d178b1d1e 16979 least = sp_cache_256[i].cnt;
wolfSSL 16:8e0d178b1d1e 16980 }
wolfSSL 16:8e0d178b1d1e 16981 }
wolfSSL 16:8e0d178b1d1e 16982 }
wolfSSL 16:8e0d178b1d1e 16983
wolfSSL 16:8e0d178b1d1e 16984 XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x));
wolfSSL 16:8e0d178b1d1e 16985 XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y));
wolfSSL 16:8e0d178b1d1e 16986 sp_cache_256[i].set = 1;
wolfSSL 16:8e0d178b1d1e 16987 sp_cache_256[i].cnt = 1;
wolfSSL 16:8e0d178b1d1e 16988 }
wolfSSL 16:8e0d178b1d1e 16989
wolfSSL 16:8e0d178b1d1e 16990 *cache = &sp_cache_256[i];
wolfSSL 16:8e0d178b1d1e 16991 sp_cache_256_last = i;
wolfSSL 16:8e0d178b1d1e 16992 }
wolfSSL 16:8e0d178b1d1e 16993 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 16994
wolfSSL 16:8e0d178b1d1e 16995 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 16996 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 16997 *
wolfSSL 16:8e0d178b1d1e 16998 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 16999 * g Point to multiply.
wolfSSL 16:8e0d178b1d1e 17000 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 17001 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 17002 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 17003 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 17004 */
wolfSSL 16:8e0d178b1d1e 17005 static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 17006 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 17007 {
wolfSSL 16:8e0d178b1d1e 17008 #ifndef FP_ECC
wolfSSL 16:8e0d178b1d1e 17009 return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);
wolfSSL 16:8e0d178b1d1e 17010 #else
wolfSSL 16:8e0d178b1d1e 17011 sp_digit tmp[2 * 8 * 5];
wolfSSL 16:8e0d178b1d1e 17012 sp_cache_256_t* cache;
wolfSSL 16:8e0d178b1d1e 17013 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 17014
wolfSSL 16:8e0d178b1d1e 17015 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 17016 if (initCacheMutex_256 == 0) {
wolfSSL 16:8e0d178b1d1e 17017 wc_InitMutex(&sp_cache_256_lock);
wolfSSL 16:8e0d178b1d1e 17018 initCacheMutex_256 = 1;
wolfSSL 16:8e0d178b1d1e 17019 }
wolfSSL 16:8e0d178b1d1e 17020 if (wc_LockMutex(&sp_cache_256_lock) != 0)
wolfSSL 16:8e0d178b1d1e 17021 err = BAD_MUTEX_E;
wolfSSL 16:8e0d178b1d1e 17022 #endif /* HAVE_THREAD_LS */
wolfSSL 16:8e0d178b1d1e 17023
wolfSSL 16:8e0d178b1d1e 17024 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 17025 sp_ecc_get_cache_256(g, &cache);
wolfSSL 16:8e0d178b1d1e 17026 if (cache->cnt == 2)
wolfSSL 16:8e0d178b1d1e 17027 sp_256_gen_stripe_table_8(g, cache->table, tmp, heap);
wolfSSL 16:8e0d178b1d1e 17028
wolfSSL 16:8e0d178b1d1e 17029 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 17030 wc_UnLockMutex(&sp_cache_256_lock);
wolfSSL 16:8e0d178b1d1e 17031 #endif /* HAVE_THREAD_LS */
wolfSSL 16:8e0d178b1d1e 17032
wolfSSL 16:8e0d178b1d1e 17033 if (cache->cnt < 2) {
wolfSSL 16:8e0d178b1d1e 17034 err = sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);
wolfSSL 16:8e0d178b1d1e 17035 }
wolfSSL 16:8e0d178b1d1e 17036 else {
wolfSSL 16:8e0d178b1d1e 17037 err = sp_256_ecc_mulmod_stripe_8(r, g, cache->table, k,
wolfSSL 16:8e0d178b1d1e 17038 map, heap);
wolfSSL 16:8e0d178b1d1e 17039 }
wolfSSL 16:8e0d178b1d1e 17040 }
wolfSSL 16:8e0d178b1d1e 17041
wolfSSL 16:8e0d178b1d1e 17042 return err;
wolfSSL 16:8e0d178b1d1e 17043 #endif
wolfSSL 16:8e0d178b1d1e 17044 }
wolfSSL 16:8e0d178b1d1e 17045
wolfSSL 16:8e0d178b1d1e 17046 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 17047 /* Multiply the point by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 17048 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 17049 *
wolfSSL 16:8e0d178b1d1e 17050 * km Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 17051 * p Point to multiply.
wolfSSL 16:8e0d178b1d1e 17052 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 17053 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 17054 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 17055 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 17056 */
wolfSSL 16:8e0d178b1d1e 17057 int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,
wolfSSL 16:8e0d178b1d1e 17058 void* heap)
wolfSSL 16:8e0d178b1d1e 17059 {
wolfSSL 16:8e0d178b1d1e 17060 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 17061 sp_point_256 p;
wolfSSL 16:8e0d178b1d1e 17062 sp_digit kd[8];
wolfSSL 16:8e0d178b1d1e 17063 #endif
wolfSSL 16:8e0d178b1d1e 17064 sp_point_256* point;
wolfSSL 16:8e0d178b1d1e 17065 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 17066 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 17067
wolfSSL 16:8e0d178b1d1e 17068 err = sp_256_point_new_8(heap, p, point);
wolfSSL 16:8e0d178b1d1e 17069 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 17070 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 17071 k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,
wolfSSL 16:8e0d178b1d1e 17072 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 17073 if (k == NULL)
wolfSSL 16:8e0d178b1d1e 17074 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 17075 }
wolfSSL 16:8e0d178b1d1e 17076 #else
wolfSSL 16:8e0d178b1d1e 17077 k = kd;
wolfSSL 16:8e0d178b1d1e 17078 #endif
wolfSSL 16:8e0d178b1d1e 17079 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 17080 sp_256_from_mp(k, 8, km);
wolfSSL 16:8e0d178b1d1e 17081 sp_256_point_from_ecc_point_8(point, gm);
wolfSSL 16:8e0d178b1d1e 17082
wolfSSL 16:8e0d178b1d1e 17083 err = sp_256_ecc_mulmod_8(point, point, k, map, heap);
wolfSSL 16:8e0d178b1d1e 17084 }
wolfSSL 16:8e0d178b1d1e 17085 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 17086 err = sp_256_point_to_ecc_point_8(point, r);
wolfSSL 16:8e0d178b1d1e 17087 }
wolfSSL 16:8e0d178b1d1e 17088
wolfSSL 16:8e0d178b1d1e 17089 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 17090 if (k != NULL) {
wolfSSL 16:8e0d178b1d1e 17091 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 17092 }
wolfSSL 16:8e0d178b1d1e 17093 #endif
wolfSSL 16:8e0d178b1d1e 17094 sp_256_point_free_8(point, 0, heap);
wolfSSL 16:8e0d178b1d1e 17095
wolfSSL 16:8e0d178b1d1e 17096 return err;
wolfSSL 16:8e0d178b1d1e 17097 }
wolfSSL 16:8e0d178b1d1e 17098
wolfSSL 16:8e0d178b1d1e 17099 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 17100 static const sp_table_entry_256 p256_table[16] = {
wolfSSL 16:8e0d178b1d1e 17101 /* 0 */
wolfSSL 16:8e0d178b1d1e 17102 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
wolfSSL 16:8e0d178b1d1e 17103 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
wolfSSL 16:8e0d178b1d1e 17104 /* 1 */
wolfSSL 16:8e0d178b1d1e 17105 { { 0x18a9143c,0x79e730d4,0x5fedb601,0x75ba95fc,0x77622510,0x79fb732b,
wolfSSL 16:8e0d178b1d1e 17106 0xa53755c6,0x18905f76 },
wolfSSL 16:8e0d178b1d1e 17107 { 0xce95560a,0xddf25357,0xba19e45c,0x8b4ab8e4,0xdd21f325,0xd2e88688,
wolfSSL 16:8e0d178b1d1e 17108 0x25885d85,0x8571ff18 } },
wolfSSL 16:8e0d178b1d1e 17109 /* 2 */
wolfSSL 16:8e0d178b1d1e 17110 { { 0x16a0d2bb,0x4f922fc5,0x1a623499,0x0d5cc16c,0x57c62c8b,0x9241cf3a,
wolfSSL 16:8e0d178b1d1e 17111 0xfd1b667f,0x2f5e6961 },
wolfSSL 16:8e0d178b1d1e 17112 { 0xf5a01797,0x5c15c70b,0x60956192,0x3d20b44d,0x071fdb52,0x04911b37,
wolfSSL 16:8e0d178b1d1e 17113 0x8d6f0f7b,0xf648f916 } },
wolfSSL 16:8e0d178b1d1e 17114 /* 3 */
wolfSSL 16:8e0d178b1d1e 17115 { { 0xe137bbbc,0x9e566847,0x8a6a0bec,0xe434469e,0x79d73463,0xb1c42761,
wolfSSL 16:8e0d178b1d1e 17116 0x133d0015,0x5abe0285 },
wolfSSL 16:8e0d178b1d1e 17117 { 0xc04c7dab,0x92aa837c,0x43260c07,0x573d9f4c,0x78e6cc37,0x0c931562,
wolfSSL 16:8e0d178b1d1e 17118 0x6b6f7383,0x94bb725b } },
wolfSSL 16:8e0d178b1d1e 17119 /* 4 */
wolfSSL 16:8e0d178b1d1e 17120 { { 0xbfe20925,0x62a8c244,0x8fdce867,0x91c19ac3,0xdd387063,0x5a96a5d5,
wolfSSL 16:8e0d178b1d1e 17121 0x21d324f6,0x61d587d4 },
wolfSSL 16:8e0d178b1d1e 17122 { 0xa37173ea,0xe87673a2,0x53778b65,0x23848008,0x05bab43e,0x10f8441e,
wolfSSL 16:8e0d178b1d1e 17123 0x4621efbe,0xfa11fe12 } },
wolfSSL 16:8e0d178b1d1e 17124 /* 5 */
wolfSSL 16:8e0d178b1d1e 17125 { { 0x2cb19ffd,0x1c891f2b,0xb1923c23,0x01ba8d5b,0x8ac5ca8e,0xb6d03d67,
wolfSSL 16:8e0d178b1d1e 17126 0x1f13bedc,0x586eb04c },
wolfSSL 16:8e0d178b1d1e 17127 { 0x27e8ed09,0x0c35c6e5,0x1819ede2,0x1e81a33c,0x56c652fa,0x278fd6c0,
wolfSSL 16:8e0d178b1d1e 17128 0x70864f11,0x19d5ac08 } },
wolfSSL 16:8e0d178b1d1e 17129 /* 6 */
wolfSSL 16:8e0d178b1d1e 17130 { { 0xd2b533d5,0x62577734,0xa1bdddc0,0x673b8af6,0xa79ec293,0x577e7c9a,
wolfSSL 16:8e0d178b1d1e 17131 0xc3b266b1,0xbb6de651 },
wolfSSL 16:8e0d178b1d1e 17132 { 0xb65259b3,0xe7e9303a,0xd03a7480,0xd6a0afd3,0x9b3cfc27,0xc5ac83d1,
wolfSSL 16:8e0d178b1d1e 17133 0x5d18b99b,0x60b4619a } },
wolfSSL 16:8e0d178b1d1e 17134 /* 7 */
wolfSSL 16:8e0d178b1d1e 17135 { { 0x1ae5aa1c,0xbd6a38e1,0x49e73658,0xb8b7652b,0xee5f87ed,0x0b130014,
wolfSSL 16:8e0d178b1d1e 17136 0xaeebffcd,0x9d0f27b2 },
wolfSSL 16:8e0d178b1d1e 17137 { 0x7a730a55,0xca924631,0xddbbc83a,0x9c955b2f,0xac019a71,0x07c1dfe0,
wolfSSL 16:8e0d178b1d1e 17138 0x356ec48d,0x244a566d } },
wolfSSL 16:8e0d178b1d1e 17139 /* 8 */
wolfSSL 16:8e0d178b1d1e 17140 { { 0xf4f8b16a,0x56f8410e,0xc47b266a,0x97241afe,0x6d9c87c1,0x0a406b8e,
wolfSSL 16:8e0d178b1d1e 17141 0xcd42ab1b,0x803f3e02 },
wolfSSL 16:8e0d178b1d1e 17142 { 0x04dbec69,0x7f0309a8,0x3bbad05f,0xa83b85f7,0xad8e197f,0xc6097273,
wolfSSL 16:8e0d178b1d1e 17143 0x5067adc1,0xc097440e } },
wolfSSL 16:8e0d178b1d1e 17144 /* 9 */
wolfSSL 16:8e0d178b1d1e 17145 { { 0xc379ab34,0x846a56f2,0x841df8d1,0xa8ee068b,0x176c68ef,0x20314459,
wolfSSL 16:8e0d178b1d1e 17146 0x915f1f30,0xf1af32d5 },
wolfSSL 16:8e0d178b1d1e 17147 { 0x5d75bd50,0x99c37531,0xf72f67bc,0x837cffba,0x48d7723f,0x0613a418,
wolfSSL 16:8e0d178b1d1e 17148 0xe2d41c8b,0x23d0f130 } },
wolfSSL 16:8e0d178b1d1e 17149 /* 10 */
wolfSSL 16:8e0d178b1d1e 17150 { { 0xd5be5a2b,0xed93e225,0x5934f3c6,0x6fe79983,0x22626ffc,0x43140926,
wolfSSL 16:8e0d178b1d1e 17151 0x7990216a,0x50bbb4d9 },
wolfSSL 16:8e0d178b1d1e 17152 { 0xe57ec63e,0x378191c6,0x181dcdb2,0x65422c40,0x0236e0f6,0x41a8099b,
wolfSSL 16:8e0d178b1d1e 17153 0x01fe49c3,0x2b100118 } },
wolfSSL 16:8e0d178b1d1e 17154 /* 11 */
wolfSSL 16:8e0d178b1d1e 17155 { { 0x9b391593,0xfc68b5c5,0x598270fc,0xc385f5a2,0xd19adcbb,0x7144f3aa,
wolfSSL 16:8e0d178b1d1e 17156 0x83fbae0c,0xdd558999 },
wolfSSL 16:8e0d178b1d1e 17157 { 0x74b82ff4,0x93b88b8e,0x71e734c9,0xd2e03c40,0x43c0322a,0x9a7a9eaf,
wolfSSL 16:8e0d178b1d1e 17158 0x149d6041,0xe6e4c551 } },
wolfSSL 16:8e0d178b1d1e 17159 /* 12 */
wolfSSL 16:8e0d178b1d1e 17160 { { 0x80ec21fe,0x5fe14bfe,0xc255be82,0xf6ce116a,0x2f4a5d67,0x98bc5a07,
wolfSSL 16:8e0d178b1d1e 17161 0xdb7e63af,0xfad27148 },
wolfSSL 16:8e0d178b1d1e 17162 { 0x29ab05b3,0x90c0b6ac,0x4e251ae6,0x37a9a83c,0xc2aade7d,0x0a7dc875,
wolfSSL 16:8e0d178b1d1e 17163 0x9f0e1a84,0x77387de3 } },
wolfSSL 16:8e0d178b1d1e 17164 /* 13 */
wolfSSL 16:8e0d178b1d1e 17165 { { 0xa56c0dd7,0x1e9ecc49,0x46086c74,0xa5cffcd8,0xf505aece,0x8f7a1408,
wolfSSL 16:8e0d178b1d1e 17166 0xbef0c47e,0xb37b85c0 },
wolfSSL 16:8e0d178b1d1e 17167 { 0xcc0e6a8f,0x3596b6e4,0x6b388f23,0xfd6d4bbf,0xc39cef4e,0xaba453fa,
wolfSSL 16:8e0d178b1d1e 17168 0xf9f628d5,0x9c135ac8 } },
wolfSSL 16:8e0d178b1d1e 17169 /* 14 */
wolfSSL 16:8e0d178b1d1e 17170 { { 0x95c8f8be,0x0a1c7294,0x3bf362bf,0x2961c480,0xdf63d4ac,0x9e418403,
wolfSSL 16:8e0d178b1d1e 17171 0x91ece900,0xc109f9cb },
wolfSSL 16:8e0d178b1d1e 17172 { 0x58945705,0xc2d095d0,0xddeb85c0,0xb9083d96,0x7a40449b,0x84692b8d,
wolfSSL 16:8e0d178b1d1e 17173 0x2eee1ee1,0x9bc3344f } },
wolfSSL 16:8e0d178b1d1e 17174 /* 15 */
wolfSSL 16:8e0d178b1d1e 17175 { { 0x42913074,0x0d5ae356,0x48a542b1,0x55491b27,0xb310732a,0x469ca665,
wolfSSL 16:8e0d178b1d1e 17176 0x5f1a4cc1,0x29591d52 },
wolfSSL 16:8e0d178b1d1e 17177 { 0xb84f983f,0xe76f5b6b,0x9f5f84e1,0xbe7eef41,0x80baa189,0x1200d496,
wolfSSL 16:8e0d178b1d1e 17178 0x18ef332c,0x6376551f } },
wolfSSL 16:8e0d178b1d1e 17179 };
wolfSSL 16:8e0d178b1d1e 17180
wolfSSL 16:8e0d178b1d1e 17181 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 17182 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 17183 *
wolfSSL 16:8e0d178b1d1e 17184 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 17185 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 17186 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 17187 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 17188 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 17189 */
wolfSSL 16:8e0d178b1d1e 17190 static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 17191 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 17192 {
wolfSSL 16:8e0d178b1d1e 17193 return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table,
wolfSSL 16:8e0d178b1d1e 17194 k, map, heap);
wolfSSL 16:8e0d178b1d1e 17195 }
wolfSSL 16:8e0d178b1d1e 17196
wolfSSL 16:8e0d178b1d1e 17197 #else
wolfSSL 16:8e0d178b1d1e 17198 static const sp_table_entry_256 p256_table[256] = {
wolfSSL 16:8e0d178b1d1e 17199 /* 0 */
wolfSSL 16:8e0d178b1d1e 17200 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
wolfSSL 16:8e0d178b1d1e 17201 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
wolfSSL 16:8e0d178b1d1e 17202 /* 1 */
wolfSSL 16:8e0d178b1d1e 17203 { { 0x18a9143c,0x79e730d4,0x5fedb601,0x75ba95fc,0x77622510,0x79fb732b,
wolfSSL 16:8e0d178b1d1e 17204 0xa53755c6,0x18905f76 },
wolfSSL 16:8e0d178b1d1e 17205 { 0xce95560a,0xddf25357,0xba19e45c,0x8b4ab8e4,0xdd21f325,0xd2e88688,
wolfSSL 16:8e0d178b1d1e 17206 0x25885d85,0x8571ff18 } },
wolfSSL 16:8e0d178b1d1e 17207 /* 2 */
wolfSSL 16:8e0d178b1d1e 17208 { { 0x4147519a,0x20288602,0x26b372f0,0xd0981eac,0xa785ebc8,0xa9d4a7ca,
wolfSSL 16:8e0d178b1d1e 17209 0xdbdf58e9,0xd953c50d },
wolfSSL 16:8e0d178b1d1e 17210 { 0xfd590f8f,0x9d6361cc,0x44e6c917,0x72e9626b,0x22eb64cf,0x7fd96110,
wolfSSL 16:8e0d178b1d1e 17211 0x9eb288f3,0x863ebb7e } },
wolfSSL 16:8e0d178b1d1e 17212 /* 3 */
wolfSSL 16:8e0d178b1d1e 17213 { { 0x5cdb6485,0x7856b623,0x2f0a2f97,0x808f0ea2,0x4f7e300b,0x3e68d954,
wolfSSL 16:8e0d178b1d1e 17214 0xb5ff80a0,0x00076055 },
wolfSSL 16:8e0d178b1d1e 17215 { 0x838d2010,0x7634eb9b,0x3243708a,0x54014fbb,0x842a6606,0xe0e47d39,
wolfSSL 16:8e0d178b1d1e 17216 0x34373ee0,0x83087761 } },
wolfSSL 16:8e0d178b1d1e 17217 /* 4 */
wolfSSL 16:8e0d178b1d1e 17218 { { 0x16a0d2bb,0x4f922fc5,0x1a623499,0x0d5cc16c,0x57c62c8b,0x9241cf3a,
wolfSSL 16:8e0d178b1d1e 17219 0xfd1b667f,0x2f5e6961 },
wolfSSL 16:8e0d178b1d1e 17220 { 0xf5a01797,0x5c15c70b,0x60956192,0x3d20b44d,0x071fdb52,0x04911b37,
wolfSSL 16:8e0d178b1d1e 17221 0x8d6f0f7b,0xf648f916 } },
wolfSSL 16:8e0d178b1d1e 17222 /* 5 */
wolfSSL 16:8e0d178b1d1e 17223 { { 0xe137bbbc,0x9e566847,0x8a6a0bec,0xe434469e,0x79d73463,0xb1c42761,
wolfSSL 16:8e0d178b1d1e 17224 0x133d0015,0x5abe0285 },
wolfSSL 16:8e0d178b1d1e 17225 { 0xc04c7dab,0x92aa837c,0x43260c07,0x573d9f4c,0x78e6cc37,0x0c931562,
wolfSSL 16:8e0d178b1d1e 17226 0x6b6f7383,0x94bb725b } },
wolfSSL 16:8e0d178b1d1e 17227 /* 6 */
wolfSSL 16:8e0d178b1d1e 17228 { { 0x720f141c,0xbbf9b48f,0x2df5bc74,0x6199b3cd,0x411045c4,0xdc3f6129,
wolfSSL 16:8e0d178b1d1e 17229 0x2f7dc4ef,0xcdd6bbcb },
wolfSSL 16:8e0d178b1d1e 17230 { 0xeaf436fd,0xcca6700b,0xb99326be,0x6f647f6d,0x014f2522,0x0c0fa792,
wolfSSL 16:8e0d178b1d1e 17231 0x4bdae5f6,0xa361bebd } },
wolfSSL 16:8e0d178b1d1e 17232 /* 7 */
wolfSSL 16:8e0d178b1d1e 17233 { { 0x597c13c7,0x28aa2558,0x50b7c3e1,0xc38d635f,0xf3c09d1d,0x07039aec,
wolfSSL 16:8e0d178b1d1e 17234 0xc4b5292c,0xba12ca09 },
wolfSSL 16:8e0d178b1d1e 17235 { 0x59f91dfd,0x9e408fa4,0xceea07fb,0x3af43b66,0x9d780b29,0x1eceb089,
wolfSSL 16:8e0d178b1d1e 17236 0x701fef4b,0x53ebb99d } },
wolfSSL 16:8e0d178b1d1e 17237 /* 8 */
wolfSSL 16:8e0d178b1d1e 17238 { { 0xb0e63d34,0x4fe7ee31,0xa9e54fab,0xf4600572,0xd5e7b5a4,0xc0493334,
wolfSSL 16:8e0d178b1d1e 17239 0x06d54831,0x8589fb92 },
wolfSSL 16:8e0d178b1d1e 17240 { 0x6583553a,0xaa70f5cc,0xe25649e5,0x0879094a,0x10044652,0xcc904507,
wolfSSL 16:8e0d178b1d1e 17241 0x02541c4f,0xebb0696d } },
wolfSSL 16:8e0d178b1d1e 17242 /* 9 */
wolfSSL 16:8e0d178b1d1e 17243 { { 0xac1647c5,0x4616ca15,0xc4cf5799,0xb8127d47,0x764dfbac,0xdc666aa3,
wolfSSL 16:8e0d178b1d1e 17244 0xd1b27da3,0xeb2820cb },
wolfSSL 16:8e0d178b1d1e 17245 { 0x6a87e008,0x9406f8d8,0x922378f3,0xd87dfa9d,0x80ccecb2,0x56ed2e42,
wolfSSL 16:8e0d178b1d1e 17246 0x55a7da1d,0x1f28289b } },
wolfSSL 16:8e0d178b1d1e 17247 /* 10 */
wolfSSL 16:8e0d178b1d1e 17248 { { 0x3b89da99,0xabbaa0c0,0xb8284022,0xa6f2d79e,0xb81c05e8,0x27847862,
wolfSSL 16:8e0d178b1d1e 17249 0x05e54d63,0x337a4b59 },
wolfSSL 16:8e0d178b1d1e 17250 { 0x21f7794a,0x3c67500d,0x7d6d7f61,0x207005b7,0x04cfd6e8,0x0a5a3781,
wolfSSL 16:8e0d178b1d1e 17251 0xf4c2fbd6,0x0d65e0d5 } },
wolfSSL 16:8e0d178b1d1e 17252 /* 11 */
wolfSSL 16:8e0d178b1d1e 17253 { { 0xb5275d38,0xd9d09bbe,0x0be0a358,0x4268a745,0x973eb265,0xf0762ff4,
wolfSSL 16:8e0d178b1d1e 17254 0x52f4a232,0xc23da242 },
wolfSSL 16:8e0d178b1d1e 17255 { 0x0b94520c,0x5da1b84f,0xb05bd78e,0x09666763,0x94d29ea1,0x3a4dcb86,
wolfSSL 16:8e0d178b1d1e 17256 0xc790cff1,0x19de3b8c } },
wolfSSL 16:8e0d178b1d1e 17257 /* 12 */
wolfSSL 16:8e0d178b1d1e 17258 { { 0x26c5fe04,0x183a716c,0x3bba1bdb,0x3b28de0b,0xa4cb712c,0x7432c586,
wolfSSL 16:8e0d178b1d1e 17259 0x91fccbfd,0xe34dcbd4 },
wolfSSL 16:8e0d178b1d1e 17260 { 0xaaa58403,0xb408d46b,0x82e97a53,0x9a697486,0x36aaa8af,0x9e390127,
wolfSSL 16:8e0d178b1d1e 17261 0x7b4e0f7f,0xe7641f44 } },
wolfSSL 16:8e0d178b1d1e 17262 /* 13 */
wolfSSL 16:8e0d178b1d1e 17263 { { 0xdf64ba59,0x7d753941,0x0b0242fc,0xd33f10ec,0xa1581859,0x4f06dfc6,
wolfSSL 16:8e0d178b1d1e 17264 0x052a57bf,0x4a12df57 },
wolfSSL 16:8e0d178b1d1e 17265 { 0x9439dbd0,0xbfa6338f,0xbde53e1f,0xd3c24bd4,0x21f1b314,0xfd5e4ffa,
wolfSSL 16:8e0d178b1d1e 17266 0xbb5bea46,0x6af5aa93 } },
wolfSSL 16:8e0d178b1d1e 17267 /* 14 */
wolfSSL 16:8e0d178b1d1e 17268 { { 0x10c91999,0xda10b699,0x2a580491,0x0a24b440,0xb8cc2090,0x3e0094b4,
wolfSSL 16:8e0d178b1d1e 17269 0x66a44013,0x5fe3475a },
wolfSSL 16:8e0d178b1d1e 17270 { 0xf93e7b4b,0xb0f8cabd,0x7c23f91a,0x292b501a,0xcd1e6263,0x42e889ae,
wolfSSL 16:8e0d178b1d1e 17271 0xecfea916,0xb544e308 } },
wolfSSL 16:8e0d178b1d1e 17272 /* 15 */
wolfSSL 16:8e0d178b1d1e 17273 { { 0x16ddfdce,0x6478c6e9,0xf89179e6,0x2c329166,0x4d4e67e1,0x4e8d6e76,
wolfSSL 16:8e0d178b1d1e 17274 0xa6b0c20b,0xe0b6b2bd },
wolfSSL 16:8e0d178b1d1e 17275 { 0xbb7efb57,0x0d312df2,0x790c4007,0x1aac0dde,0x679bc944,0xf90336ad,
wolfSSL 16:8e0d178b1d1e 17276 0x25a63774,0x71c023de } },
wolfSSL 16:8e0d178b1d1e 17277 /* 16 */
wolfSSL 16:8e0d178b1d1e 17278 { { 0xbfe20925,0x62a8c244,0x8fdce867,0x91c19ac3,0xdd387063,0x5a96a5d5,
wolfSSL 16:8e0d178b1d1e 17279 0x21d324f6,0x61d587d4 },
wolfSSL 16:8e0d178b1d1e 17280 { 0xa37173ea,0xe87673a2,0x53778b65,0x23848008,0x05bab43e,0x10f8441e,
wolfSSL 16:8e0d178b1d1e 17281 0x4621efbe,0xfa11fe12 } },
wolfSSL 16:8e0d178b1d1e 17282 /* 17 */
wolfSSL 16:8e0d178b1d1e 17283 { { 0x2cb19ffd,0x1c891f2b,0xb1923c23,0x01ba8d5b,0x8ac5ca8e,0xb6d03d67,
wolfSSL 16:8e0d178b1d1e 17284 0x1f13bedc,0x586eb04c },
wolfSSL 16:8e0d178b1d1e 17285 { 0x27e8ed09,0x0c35c6e5,0x1819ede2,0x1e81a33c,0x56c652fa,0x278fd6c0,
wolfSSL 16:8e0d178b1d1e 17286 0x70864f11,0x19d5ac08 } },
wolfSSL 16:8e0d178b1d1e 17287 /* 18 */
wolfSSL 16:8e0d178b1d1e 17288 { { 0x309a4e1f,0x1e99f581,0xe9270074,0xab7de71b,0xefd28d20,0x26a5ef0b,
wolfSSL 16:8e0d178b1d1e 17289 0x7f9c563f,0xe7c0073f },
wolfSSL 16:8e0d178b1d1e 17290 { 0x0ef59f76,0x1f6d663a,0x20fcb050,0x669b3b54,0x7a6602d4,0xc08c1f7a,
wolfSSL 16:8e0d178b1d1e 17291 0xc65b3c0a,0xe08504fe } },
wolfSSL 16:8e0d178b1d1e 17292 /* 19 */
wolfSSL 16:8e0d178b1d1e 17293 { { 0xa031b3ca,0xf098f68d,0xe6da6d66,0x6d1cab9e,0x94f246e8,0x5bfd81fa,
wolfSSL 16:8e0d178b1d1e 17294 0x5b0996b4,0x78f01882 },
wolfSSL 16:8e0d178b1d1e 17295 { 0x3a25787f,0xb7eefde4,0x1dccac9b,0x8016f80d,0xb35bfc36,0x0cea4877,
wolfSSL 16:8e0d178b1d1e 17296 0x7e94747a,0x43a773b8 } },
wolfSSL 16:8e0d178b1d1e 17297 /* 20 */
wolfSSL 16:8e0d178b1d1e 17298 { { 0xd2b533d5,0x62577734,0xa1bdddc0,0x673b8af6,0xa79ec293,0x577e7c9a,
wolfSSL 16:8e0d178b1d1e 17299 0xc3b266b1,0xbb6de651 },
wolfSSL 16:8e0d178b1d1e 17300 { 0xb65259b3,0xe7e9303a,0xd03a7480,0xd6a0afd3,0x9b3cfc27,0xc5ac83d1,
wolfSSL 16:8e0d178b1d1e 17301 0x5d18b99b,0x60b4619a } },
wolfSSL 16:8e0d178b1d1e 17302 /* 21 */
wolfSSL 16:8e0d178b1d1e 17303 { { 0x1ae5aa1c,0xbd6a38e1,0x49e73658,0xb8b7652b,0xee5f87ed,0x0b130014,
wolfSSL 16:8e0d178b1d1e 17304 0xaeebffcd,0x9d0f27b2 },
wolfSSL 16:8e0d178b1d1e 17305 { 0x7a730a55,0xca924631,0xddbbc83a,0x9c955b2f,0xac019a71,0x07c1dfe0,
wolfSSL 16:8e0d178b1d1e 17306 0x356ec48d,0x244a566d } },
wolfSSL 16:8e0d178b1d1e 17307 /* 22 */
wolfSSL 16:8e0d178b1d1e 17308 { { 0xeacf1f96,0x6db0394a,0x024c271c,0x9f2122a9,0x82cbd3b9,0x2626ac1b,
wolfSSL 16:8e0d178b1d1e 17309 0x3581ef69,0x45e58c87 },
wolfSSL 16:8e0d178b1d1e 17310 { 0xa38f9dbc,0xd3ff479d,0xe888a040,0xa8aaf146,0x46e0bed7,0x945adfb2,
wolfSSL 16:8e0d178b1d1e 17311 0xc1e4b7a4,0xc040e21c } },
wolfSSL 16:8e0d178b1d1e 17312 /* 23 */
wolfSSL 16:8e0d178b1d1e 17313 { { 0x6f8117b6,0x847af000,0x73a35433,0x651969ff,0x1d9475eb,0x482b3576,
wolfSSL 16:8e0d178b1d1e 17314 0x682c6ec7,0x1cdf5c97 },
wolfSSL 16:8e0d178b1d1e 17315 { 0x11f04839,0x7db775b4,0x48de1698,0x7dbeacf4,0xb70b3219,0xb2921dd1,
wolfSSL 16:8e0d178b1d1e 17316 0xa92dff3d,0x046755f8 } },
wolfSSL 16:8e0d178b1d1e 17317 /* 24 */
wolfSSL 16:8e0d178b1d1e 17318 { { 0xbce8ffcd,0xcc8ac5d2,0x2fe61a82,0x0d53c48b,0x7202d6c7,0xf6f16172,
wolfSSL 16:8e0d178b1d1e 17319 0x3b83a5f3,0x046e5e11 },
wolfSSL 16:8e0d178b1d1e 17320 { 0xd8007f01,0xe7b8ff64,0x5af43183,0x7fb1ef12,0x35e1a03c,0x045c5ea6,
wolfSSL 16:8e0d178b1d1e 17321 0x303d005b,0x6e0106c3 } },
wolfSSL 16:8e0d178b1d1e 17322 /* 25 */
wolfSSL 16:8e0d178b1d1e 17323 { { 0x88dd73b1,0x48c73584,0x995ed0d9,0x7670708f,0xc56a2ab7,0x38385ea8,
wolfSSL 16:8e0d178b1d1e 17324 0xe901cf1f,0x442594ed },
wolfSSL 16:8e0d178b1d1e 17325 { 0x12d4b65b,0xf8faa2c9,0x96c90c37,0x94c2343b,0x5e978d1f,0xd326e4a1,
wolfSSL 16:8e0d178b1d1e 17326 0x4c2ee68e,0xa796fa51 } },
wolfSSL 16:8e0d178b1d1e 17327 /* 26 */
wolfSSL 16:8e0d178b1d1e 17328 { { 0x823addd7,0x359fb604,0xe56693b3,0x9e2a6183,0x3cbf3c80,0xf885b78e,
wolfSSL 16:8e0d178b1d1e 17329 0xc69766e9,0xe4ad2da9 },
wolfSSL 16:8e0d178b1d1e 17330 { 0x8e048a61,0x357f7f42,0xc092d9a0,0x082d198c,0xc03ed8ef,0xfc3a1af4,
wolfSSL 16:8e0d178b1d1e 17331 0xc37b5143,0xc5e94046 } },
wolfSSL 16:8e0d178b1d1e 17332 /* 27 */
wolfSSL 16:8e0d178b1d1e 17333 { { 0x2be75f9e,0x476a538c,0xcb123a78,0x6fd1a9e8,0xb109c04b,0xd85e4df0,
wolfSSL 16:8e0d178b1d1e 17334 0xdb464747,0x63283daf },
wolfSSL 16:8e0d178b1d1e 17335 { 0xbaf2df15,0xce728cf7,0x0ad9a7f4,0xe592c455,0xe834bcc3,0xfab226ad,
wolfSSL 16:8e0d178b1d1e 17336 0x1981a938,0x68bd19ab } },
wolfSSL 16:8e0d178b1d1e 17337 /* 28 */
wolfSSL 16:8e0d178b1d1e 17338 { { 0x1887d659,0xc08ead51,0xb359305a,0x3374d5f4,0xcfe74fe3,0x96986981,
wolfSSL 16:8e0d178b1d1e 17339 0x3c6fdfd6,0x495292f5 },
wolfSSL 16:8e0d178b1d1e 17340 { 0x1acec896,0x4a878c9e,0xec5b4484,0xd964b210,0x664d60a7,0x6696f7e2,
wolfSSL 16:8e0d178b1d1e 17341 0x26036837,0x0ec7530d } },
wolfSSL 16:8e0d178b1d1e 17342 /* 29 */
wolfSSL 16:8e0d178b1d1e 17343 { { 0xad2687bb,0x2da13a05,0xf32e21fa,0xa1f83b6a,0x1dd4607b,0x390f5ef5,
wolfSSL 16:8e0d178b1d1e 17344 0x64863f0b,0x0f6207a6 },
wolfSSL 16:8e0d178b1d1e 17345 { 0x0f138233,0xbd67e3bb,0x272aa718,0xdd66b96c,0x26ec88ae,0x8ed00407,
wolfSSL 16:8e0d178b1d1e 17346 0x08ed6dcf,0xff0db072 } },
wolfSSL 16:8e0d178b1d1e 17347 /* 30 */
wolfSSL 16:8e0d178b1d1e 17348 { { 0x4c95d553,0x749fa101,0x5d680a8a,0xa44052fd,0xff3b566f,0x183b4317,
wolfSSL 16:8e0d178b1d1e 17349 0x88740ea3,0x313b513c },
wolfSSL 16:8e0d178b1d1e 17350 { 0x08d11549,0xb402e2ac,0xb4dee21c,0x071ee10b,0x47f2320e,0x26b987dd,
wolfSSL 16:8e0d178b1d1e 17351 0x86f19f81,0x2d3abcf9 } },
wolfSSL 16:8e0d178b1d1e 17352 /* 31 */
wolfSSL 16:8e0d178b1d1e 17353 { { 0x815581a2,0x4c288501,0x632211af,0x9a0a6d56,0x0cab2e99,0x19ba7a0f,
wolfSSL 16:8e0d178b1d1e 17354 0xded98cdf,0xc036fa10 },
wolfSSL 16:8e0d178b1d1e 17355 { 0xc1fbd009,0x29ae08ba,0x06d15816,0x0b68b190,0x9b9e0d8f,0xc2eb3277,
wolfSSL 16:8e0d178b1d1e 17356 0xb6d40194,0xa6b2a2c4 } },
wolfSSL 16:8e0d178b1d1e 17357 /* 32 */
wolfSSL 16:8e0d178b1d1e 17358 { { 0x6d3549cf,0xd433e50f,0xfacd665e,0x6f33696f,0xce11fcb4,0x695bfdac,
wolfSSL 16:8e0d178b1d1e 17359 0xaf7c9860,0x810ee252 },
wolfSSL 16:8e0d178b1d1e 17360 { 0x7159bb2c,0x65450fe1,0x758b357b,0xf7dfbebe,0xd69fea72,0x2b057e74,
wolfSSL 16:8e0d178b1d1e 17361 0x92731745,0xd485717a } },
wolfSSL 16:8e0d178b1d1e 17362 /* 33 */
wolfSSL 16:8e0d178b1d1e 17363 { { 0xf0cb5a98,0x11741a8a,0x1f3110bf,0xd3da8f93,0xab382adf,0x1994e2cb,
wolfSSL 16:8e0d178b1d1e 17364 0x2f9a604e,0x6a6045a7 },
wolfSSL 16:8e0d178b1d1e 17365 { 0xa2b2411d,0x170c0d3f,0x510e96e0,0xbe0eb83e,0x8865b3cc,0x3bcc9f73,
wolfSSL 16:8e0d178b1d1e 17366 0xf9e15790,0xd3e45cfa } },
wolfSSL 16:8e0d178b1d1e 17367 /* 34 */
wolfSSL 16:8e0d178b1d1e 17368 { { 0xe83f7669,0xce1f69bb,0x72877d6b,0x09f8ae82,0x3244278d,0x9548ae54,
wolfSSL 16:8e0d178b1d1e 17369 0xe3c2c19c,0x207755de },
wolfSSL 16:8e0d178b1d1e 17370 { 0x6fef1945,0x87bd61d9,0xb12d28c3,0x18813cef,0x72df64aa,0x9fbcd1d6,
wolfSSL 16:8e0d178b1d1e 17371 0x7154b00d,0x48dc5ee5 } },
wolfSSL 16:8e0d178b1d1e 17372 /* 35 */
wolfSSL 16:8e0d178b1d1e 17373 { { 0xf7e5a199,0x123790bf,0x989ccbb7,0xe0efb8cf,0x0a519c79,0xc27a2bfe,
wolfSSL 16:8e0d178b1d1e 17374 0xdff6f445,0xf2fb0aed },
wolfSSL 16:8e0d178b1d1e 17375 { 0xf0b5025f,0x41c09575,0x40fa9f22,0x550543d7,0x380bfbd0,0x8fa3c8ad,
wolfSSL 16:8e0d178b1d1e 17376 0xdb28d525,0xa13e9015 } },
wolfSSL 16:8e0d178b1d1e 17377 /* 36 */
wolfSSL 16:8e0d178b1d1e 17378 { { 0xa2b65cbc,0xf9f7a350,0x2a464226,0x0b04b972,0xe23f07a1,0x265ce241,
wolfSSL 16:8e0d178b1d1e 17379 0x1497526f,0x2bf0d6b0 },
wolfSSL 16:8e0d178b1d1e 17380 { 0x4b216fb7,0xd3d4dd3f,0xfbdda26a,0xf7d7b867,0x6708505c,0xaeb7b83f,
wolfSSL 16:8e0d178b1d1e 17381 0x162fe89f,0x42a94a5a } },
wolfSSL 16:8e0d178b1d1e 17382 /* 37 */
wolfSSL 16:8e0d178b1d1e 17383 { { 0xeaadf191,0x5846ad0b,0x25a268d7,0x0f8a4890,0x494dc1f6,0xe8603050,
wolfSSL 16:8e0d178b1d1e 17384 0xc65ede3d,0x2c2dd969 },
wolfSSL 16:8e0d178b1d1e 17385 { 0x93849c17,0x6d02171d,0x1da250dd,0x460488ba,0x3c3a5485,0x4810c706,
wolfSSL 16:8e0d178b1d1e 17386 0x42c56dbc,0xf437fa1f } },
wolfSSL 16:8e0d178b1d1e 17387 /* 38 */
wolfSSL 16:8e0d178b1d1e 17388 { { 0x4a0f7dab,0x6aa0d714,0x1776e9ac,0x0f049793,0xf5f39786,0x52c0a050,
wolfSSL 16:8e0d178b1d1e 17389 0x54707aa8,0xaaf45b33 },
wolfSSL 16:8e0d178b1d1e 17390 { 0xc18d364a,0x85e37c33,0x3e497165,0xd40b9b06,0x15ec5444,0xf4171681,
wolfSSL 16:8e0d178b1d1e 17391 0xf4f272bc,0xcdf6310d } },
wolfSSL 16:8e0d178b1d1e 17392 /* 39 */
wolfSSL 16:8e0d178b1d1e 17393 { { 0x8ea8b7ef,0x7473c623,0x85bc2287,0x08e93518,0x2bda8e34,0x41956772,
wolfSSL 16:8e0d178b1d1e 17394 0xda9e2ff2,0xf0d008ba },
wolfSSL 16:8e0d178b1d1e 17395 { 0x2414d3b1,0x2912671d,0xb019ea76,0xb3754985,0x453bcbdb,0x5c61b96d,
wolfSSL 16:8e0d178b1d1e 17396 0xca887b8b,0x5bd5c2f5 } },
wolfSSL 16:8e0d178b1d1e 17397 /* 40 */
wolfSSL 16:8e0d178b1d1e 17398 { { 0xf49a3154,0xef0f469e,0x6e2b2e9a,0x3e85a595,0xaa924a9c,0x45aaec1e,
wolfSSL 16:8e0d178b1d1e 17399 0xa09e4719,0xaa12dfc8 },
wolfSSL 16:8e0d178b1d1e 17400 { 0x4df69f1d,0x26f27227,0xa2ff5e73,0xe0e4c82c,0xb7a9dd44,0xb9d8ce73,
wolfSSL 16:8e0d178b1d1e 17401 0xe48ca901,0x6c036e73 } },
wolfSSL 16:8e0d178b1d1e 17402 /* 41 */
wolfSSL 16:8e0d178b1d1e 17403 { { 0x0f6e3138,0x5cfae12a,0x25ad345a,0x6966ef00,0x45672bc5,0x8993c64b,
wolfSSL 16:8e0d178b1d1e 17404 0x96afbe24,0x292ff658 },
wolfSSL 16:8e0d178b1d1e 17405 { 0x5e213402,0xd5250d44,0x4392c9fe,0xf6580e27,0xda1c72e8,0x097b397f,
wolfSSL 16:8e0d178b1d1e 17406 0x311b7276,0x644e0c90 } },
wolfSSL 16:8e0d178b1d1e 17407 /* 42 */
wolfSSL 16:8e0d178b1d1e 17408 { { 0xa47153f0,0xe1e421e1,0x920418c9,0xb86c3b79,0x705d7672,0x93bdce87,
wolfSSL 16:8e0d178b1d1e 17409 0xcab79a77,0xf25ae793 },
wolfSSL 16:8e0d178b1d1e 17410 { 0x6d869d0c,0x1f3194a3,0x4986c264,0x9d55c882,0x096e945e,0x49fb5ea3,
wolfSSL 16:8e0d178b1d1e 17411 0x13db0a3e,0x39b8e653 } },
wolfSSL 16:8e0d178b1d1e 17412 /* 43 */
wolfSSL 16:8e0d178b1d1e 17413 { { 0xb6fd2e59,0x37754200,0x9255c98f,0x35e2c066,0x0e2a5739,0xd9dab21a,
wolfSSL 16:8e0d178b1d1e 17414 0x0f19db06,0x39122f2f },
wolfSSL 16:8e0d178b1d1e 17415 { 0x03cad53c,0xcfbce1e0,0xe65c17e3,0x225b2c0f,0x9aa13877,0x72baf1d2,
wolfSSL 16:8e0d178b1d1e 17416 0xce80ff8d,0x8de80af8 } },
wolfSSL 16:8e0d178b1d1e 17417 /* 44 */
wolfSSL 16:8e0d178b1d1e 17418 { { 0x207bbb76,0xafbea8d9,0x21782758,0x921c7e7c,0x1c0436b1,0xdfa2b74b,
wolfSSL 16:8e0d178b1d1e 17419 0x2e368c04,0x87194906 },
wolfSSL 16:8e0d178b1d1e 17420 { 0xa3993df5,0xb5f928bb,0xf3b3d26a,0x639d75b5,0x85b55050,0x011aa78a,
wolfSSL 16:8e0d178b1d1e 17421 0x5b74fde1,0xfc315e6a } },
wolfSSL 16:8e0d178b1d1e 17422 /* 45 */
wolfSSL 16:8e0d178b1d1e 17423 { { 0xe8d6ecfa,0x561fd41a,0x1aec7f86,0x5f8c44f6,0x4924741d,0x98452a7b,
wolfSSL 16:8e0d178b1d1e 17424 0xee389088,0xe6d4a7ad },
wolfSSL 16:8e0d178b1d1e 17425 { 0x4593c75d,0x60552ed1,0xdd271162,0x70a70da4,0x7ba2c7db,0xd2aede93,
wolfSSL 16:8e0d178b1d1e 17426 0x9be2ae57,0x35dfaf9a } },
wolfSSL 16:8e0d178b1d1e 17427 /* 46 */
wolfSSL 16:8e0d178b1d1e 17428 { { 0xaa736636,0x6b956fcd,0xae2cab7e,0x09f51d97,0x0f349966,0xfb10bf41,
wolfSSL 16:8e0d178b1d1e 17429 0x1c830d2b,0x1da5c7d7 },
wolfSSL 16:8e0d178b1d1e 17430 { 0x3cce6825,0x5c41e483,0xf9573c3b,0x15ad118f,0xf23036b8,0xa28552c7,
wolfSSL 16:8e0d178b1d1e 17431 0xdbf4b9d6,0x7077c0fd } },
wolfSSL 16:8e0d178b1d1e 17432 /* 47 */
wolfSSL 16:8e0d178b1d1e 17433 { { 0x46b9661c,0xbf63ff8d,0x0d2cfd71,0xa1dfd36b,0xa847f8f7,0x0373e140,
wolfSSL 16:8e0d178b1d1e 17434 0xe50efe44,0x53a8632e },
wolfSSL 16:8e0d178b1d1e 17435 { 0x696d8051,0x0976ff68,0xc74f468a,0xdaec0c95,0x5e4e26bd,0x62994dc3,
wolfSSL 16:8e0d178b1d1e 17436 0x34e1fcc1,0x028ca76d } },
wolfSSL 16:8e0d178b1d1e 17437 /* 48 */
wolfSSL 16:8e0d178b1d1e 17438 { { 0xfc9877ee,0xd11d47dc,0x801d0002,0xc8b36210,0x54c260b6,0xd002c117,
wolfSSL 16:8e0d178b1d1e 17439 0x6962f046,0x04c17cd8 },
wolfSSL 16:8e0d178b1d1e 17440 { 0xb0daddf5,0x6d9bd094,0x24ce55c0,0xbea23575,0x72da03b5,0x663356e6,
wolfSSL 16:8e0d178b1d1e 17441 0xfed97474,0xf7ba4de9 } },
wolfSSL 16:8e0d178b1d1e 17442 /* 49 */
wolfSSL 16:8e0d178b1d1e 17443 { { 0xebe1263f,0xd0dbfa34,0x71ae7ce6,0x55763735,0x82a6f523,0xd2440553,
wolfSSL 16:8e0d178b1d1e 17444 0x52131c41,0xe31f9600 },
wolfSSL 16:8e0d178b1d1e 17445 { 0xea6b6ec6,0xd1bb9216,0x73c2fc44,0x37a1d12e,0x89d0a294,0xc10e7eac,
wolfSSL 16:8e0d178b1d1e 17446 0xce34d47b,0xaa3a6259 } },
wolfSSL 16:8e0d178b1d1e 17447 /* 50 */
wolfSSL 16:8e0d178b1d1e 17448 { { 0x36f3dcd3,0xfbcf9df5,0xd2bf7360,0x6ceded50,0xdf504f5b,0x491710fa,
wolfSSL 16:8e0d178b1d1e 17449 0x7e79daee,0x2398dd62 },
wolfSSL 16:8e0d178b1d1e 17450 { 0x6d09569e,0xcf4705a3,0x5149f769,0xea0619bb,0x35f6034c,0xff9c0377,
wolfSSL 16:8e0d178b1d1e 17451 0x1c046210,0x5717f5b2 } },
wolfSSL 16:8e0d178b1d1e 17452 /* 51 */
wolfSSL 16:8e0d178b1d1e 17453 { { 0x21dd895e,0x9fe229c9,0x40c28451,0x8e518500,0x1d637ecd,0xfa13d239,
wolfSSL 16:8e0d178b1d1e 17454 0x0e3c28de,0x660a2c56 },
wolfSSL 16:8e0d178b1d1e 17455 { 0xd67fcbd0,0x9cca88ae,0x0ea9f096,0xc8472478,0x72e92b4d,0x32b2f481,
wolfSSL 16:8e0d178b1d1e 17456 0x4f522453,0x624ee54c } },
wolfSSL 16:8e0d178b1d1e 17457 /* 52 */
wolfSSL 16:8e0d178b1d1e 17458 { { 0xd897eccc,0x09549ce4,0x3f9880aa,0x4d49d1d9,0x043a7c20,0x723c2423,
wolfSSL 16:8e0d178b1d1e 17459 0x92bdfbc0,0x4f392afb },
wolfSSL 16:8e0d178b1d1e 17460 { 0x7de44fd9,0x6969f8fa,0x57b32156,0xb66cfbe4,0x368ebc3c,0xdb2fa803,
wolfSSL 16:8e0d178b1d1e 17461 0xccdb399c,0x8a3e7977 } },
wolfSSL 16:8e0d178b1d1e 17462 /* 53 */
wolfSSL 16:8e0d178b1d1e 17463 { { 0x06c4b125,0xdde1881f,0xf6e3ca8c,0xae34e300,0x5c7a13e9,0xef6999de,
wolfSSL 16:8e0d178b1d1e 17464 0x70c24404,0x3888d023 },
wolfSSL 16:8e0d178b1d1e 17465 { 0x44f91081,0x76280356,0x5f015504,0x3d9fcf61,0x632cd36e,0x1827edc8,
wolfSSL 16:8e0d178b1d1e 17466 0x18102336,0xa5e62e47 } },
wolfSSL 16:8e0d178b1d1e 17467 /* 54 */
wolfSSL 16:8e0d178b1d1e 17468 { { 0x2facd6c8,0x1a825ee3,0x54bcbc66,0x699c6354,0x98df9931,0x0ce3edf7,
wolfSSL 16:8e0d178b1d1e 17469 0x466a5adc,0x2c4768e6 },
wolfSSL 16:8e0d178b1d1e 17470 { 0x90a64bc9,0xb346ff8c,0xe4779f5c,0x630a6020,0xbc05e884,0xd949d064,
wolfSSL 16:8e0d178b1d1e 17471 0xf9e652a0,0x7b5e6441 } },
wolfSSL 16:8e0d178b1d1e 17472 /* 55 */
wolfSSL 16:8e0d178b1d1e 17473 { { 0x1d28444a,0x2169422c,0xbe136a39,0xe996c5d8,0xfb0c7fce,0x2387afe5,
wolfSSL 16:8e0d178b1d1e 17474 0x0c8d744a,0xb8af73cb },
wolfSSL 16:8e0d178b1d1e 17475 { 0x338b86fd,0x5fde83aa,0xa58a5cff,0xfee3f158,0x20ac9433,0xc9ee8f6f,
wolfSSL 16:8e0d178b1d1e 17476 0x7f3f0895,0xa036395f } },
wolfSSL 16:8e0d178b1d1e 17477 /* 56 */
wolfSSL 16:8e0d178b1d1e 17478 { { 0xa10f7770,0x8c73c6bb,0xa12a0e24,0xa6f16d81,0x51bc2b9f,0x100df682,
wolfSSL 16:8e0d178b1d1e 17479 0x875fb533,0x4be36b01 },
wolfSSL 16:8e0d178b1d1e 17480 { 0x9fb56dbb,0x9226086e,0x07e7a4f8,0x306fef8b,0x66d52f20,0xeeaccc05,
wolfSSL 16:8e0d178b1d1e 17481 0x1bdc00c0,0x8cbc9a87 } },
wolfSSL 16:8e0d178b1d1e 17482 /* 57 */
wolfSSL 16:8e0d178b1d1e 17483 { { 0xc0dac4ab,0xe131895c,0x712ff112,0xa874a440,0x6a1cee57,0x6332ae7c,
wolfSSL 16:8e0d178b1d1e 17484 0x0c0835f8,0x44e7553e },
wolfSSL 16:8e0d178b1d1e 17485 { 0x7734002d,0x6d503fff,0x0b34425c,0x9d35cb8b,0x0e8738b5,0x95f70276,
wolfSSL 16:8e0d178b1d1e 17486 0x5eb8fc18,0x470a683a } },
wolfSSL 16:8e0d178b1d1e 17487 /* 58 */
wolfSSL 16:8e0d178b1d1e 17488 { { 0x90513482,0x81b761dc,0x01e9276a,0x0287202a,0x0ce73083,0xcda441ee,
wolfSSL 16:8e0d178b1d1e 17489 0xc63dc6ef,0x16410690 },
wolfSSL 16:8e0d178b1d1e 17490 { 0x6d06a2ed,0xf5034a06,0x189b100b,0xdd4d7745,0xab8218c9,0xd914ae72,
wolfSSL 16:8e0d178b1d1e 17491 0x7abcbb4f,0xd73479fd } },
wolfSSL 16:8e0d178b1d1e 17492 /* 59 */
wolfSSL 16:8e0d178b1d1e 17493 { { 0x5ad4c6e5,0x7edefb16,0x5b06d04d,0x262cf08f,0x8575cb14,0x12ed5bb1,
wolfSSL 16:8e0d178b1d1e 17494 0x0771666b,0x816469e3 },
wolfSSL 16:8e0d178b1d1e 17495 { 0x561e291e,0xd7ab9d79,0xc1de1661,0xeb9daf22,0x135e0513,0xf49827eb,
wolfSSL 16:8e0d178b1d1e 17496 0xf0dd3f9c,0x0a36dd23 } },
wolfSSL 16:8e0d178b1d1e 17497 /* 60 */
wolfSSL 16:8e0d178b1d1e 17498 { { 0x41d5533c,0x098d32c7,0x8684628f,0x7c5f5a9e,0xe349bd11,0x39a228ad,
wolfSSL 16:8e0d178b1d1e 17499 0xfdbab118,0xe331dfd6 },
wolfSSL 16:8e0d178b1d1e 17500 { 0x6bcc6ed8,0x5100ab68,0xef7a260e,0x7160c3bd,0xbce850d7,0x9063d9a7,
wolfSSL 16:8e0d178b1d1e 17501 0x492e3389,0xd3b4782a } },
wolfSSL 16:8e0d178b1d1e 17502 /* 61 */
wolfSSL 16:8e0d178b1d1e 17503 { { 0xf3821f90,0xa149b6e8,0x66eb7aad,0x92edd9ed,0x1a013116,0x0bb66953,
wolfSSL 16:8e0d178b1d1e 17504 0x4c86a5bd,0x7281275a },
wolfSSL 16:8e0d178b1d1e 17505 { 0xd3ff47e5,0x503858f7,0x61016441,0x5e1616bc,0x7dfd9bb1,0x62b0f11a,
wolfSSL 16:8e0d178b1d1e 17506 0xce145059,0x2c062e7e } },
wolfSSL 16:8e0d178b1d1e 17507 /* 62 */
wolfSSL 16:8e0d178b1d1e 17508 { { 0x0159ac2e,0xa76f996f,0xcbdb2713,0x281e7736,0x08e46047,0x2ad6d288,
wolfSSL 16:8e0d178b1d1e 17509 0x2c4e7ef1,0x282a35f9 },
wolfSSL 16:8e0d178b1d1e 17510 { 0xc0ce5cd2,0x9c354b1e,0x1379c229,0xcf99efc9,0x3e82c11e,0x992caf38,
wolfSSL 16:8e0d178b1d1e 17511 0x554d2abd,0xc71cd513 } },
wolfSSL 16:8e0d178b1d1e 17512 /* 63 */
wolfSSL 16:8e0d178b1d1e 17513 { { 0x09b578f4,0x4885de9c,0xe3affa7a,0x1884e258,0x59182f1f,0x8f76b1b7,
wolfSSL 16:8e0d178b1d1e 17514 0xcf47f3a3,0xc50f6740 },
wolfSSL 16:8e0d178b1d1e 17515 { 0x374b68ea,0xa9c4adf3,0x69965fe2,0xa406f323,0x85a53050,0x2f86a222,
wolfSSL 16:8e0d178b1d1e 17516 0x212958dc,0xb9ecb3a7 } },
wolfSSL 16:8e0d178b1d1e 17517 /* 64 */
wolfSSL 16:8e0d178b1d1e 17518 { { 0xf4f8b16a,0x56f8410e,0xc47b266a,0x97241afe,0x6d9c87c1,0x0a406b8e,
wolfSSL 16:8e0d178b1d1e 17519 0xcd42ab1b,0x803f3e02 },
wolfSSL 16:8e0d178b1d1e 17520 { 0x04dbec69,0x7f0309a8,0x3bbad05f,0xa83b85f7,0xad8e197f,0xc6097273,
wolfSSL 16:8e0d178b1d1e 17521 0x5067adc1,0xc097440e } },
wolfSSL 16:8e0d178b1d1e 17522 /* 65 */
wolfSSL 16:8e0d178b1d1e 17523 { { 0xc379ab34,0x846a56f2,0x841df8d1,0xa8ee068b,0x176c68ef,0x20314459,
wolfSSL 16:8e0d178b1d1e 17524 0x915f1f30,0xf1af32d5 },
wolfSSL 16:8e0d178b1d1e 17525 { 0x5d75bd50,0x99c37531,0xf72f67bc,0x837cffba,0x48d7723f,0x0613a418,
wolfSSL 16:8e0d178b1d1e 17526 0xe2d41c8b,0x23d0f130 } },
wolfSSL 16:8e0d178b1d1e 17527 /* 66 */
wolfSSL 16:8e0d178b1d1e 17528 { { 0xf41500d9,0x857ab6ed,0xfcbeada8,0x0d890ae5,0x89725951,0x52fe8648,
wolfSSL 16:8e0d178b1d1e 17529 0xc0a3fadd,0xb0288dd6 },
wolfSSL 16:8e0d178b1d1e 17530 { 0x650bcb08,0x85320f30,0x695d6e16,0x71af6313,0xb989aa76,0x31f520a7,
wolfSSL 16:8e0d178b1d1e 17531 0xf408c8d2,0xffd3724f } },
wolfSSL 16:8e0d178b1d1e 17532 /* 67 */
wolfSSL 16:8e0d178b1d1e 17533 { { 0xb458e6cb,0x53968e64,0x317a5d28,0x992dad20,0x7aa75f56,0x3814ae0b,
wolfSSL 16:8e0d178b1d1e 17534 0xd78c26df,0xf5590f4a },
wolfSSL 16:8e0d178b1d1e 17535 { 0xcf0ba55a,0x0fc24bd3,0x0c778bae,0x0fc4724a,0x683b674a,0x1ce9864f,
wolfSSL 16:8e0d178b1d1e 17536 0xf6f74a20,0x18d6da54 } },
wolfSSL 16:8e0d178b1d1e 17537 /* 68 */
wolfSSL 16:8e0d178b1d1e 17538 { { 0xd5be5a2b,0xed93e225,0x5934f3c6,0x6fe79983,0x22626ffc,0x43140926,
wolfSSL 16:8e0d178b1d1e 17539 0x7990216a,0x50bbb4d9 },
wolfSSL 16:8e0d178b1d1e 17540 { 0xe57ec63e,0x378191c6,0x181dcdb2,0x65422c40,0x0236e0f6,0x41a8099b,
wolfSSL 16:8e0d178b1d1e 17541 0x01fe49c3,0x2b100118 } },
wolfSSL 16:8e0d178b1d1e 17542 /* 69 */
wolfSSL 16:8e0d178b1d1e 17543 { { 0x9b391593,0xfc68b5c5,0x598270fc,0xc385f5a2,0xd19adcbb,0x7144f3aa,
wolfSSL 16:8e0d178b1d1e 17544 0x83fbae0c,0xdd558999 },
wolfSSL 16:8e0d178b1d1e 17545 { 0x74b82ff4,0x93b88b8e,0x71e734c9,0xd2e03c40,0x43c0322a,0x9a7a9eaf,
wolfSSL 16:8e0d178b1d1e 17546 0x149d6041,0xe6e4c551 } },
wolfSSL 16:8e0d178b1d1e 17547 /* 70 */
wolfSSL 16:8e0d178b1d1e 17548 { { 0x1e9af288,0x55f655bb,0xf7ada931,0x647e1a64,0xcb2820e5,0x43697e4b,
wolfSSL 16:8e0d178b1d1e 17549 0x07ed56ff,0x51e00db1 },
wolfSSL 16:8e0d178b1d1e 17550 { 0x771c327e,0x43d169b8,0x4a96c2ad,0x29cdb20b,0x3deb4779,0xc07d51f5,
wolfSSL 16:8e0d178b1d1e 17551 0x49829177,0xe22f4241 } },
wolfSSL 16:8e0d178b1d1e 17552 /* 71 */
wolfSSL 16:8e0d178b1d1e 17553 { { 0x635f1abb,0xcd45e8f4,0x68538874,0x7edc0cb5,0xb5a8034d,0xc9472c1f,
wolfSSL 16:8e0d178b1d1e 17554 0x52dc48c9,0xf709373d },
wolfSSL 16:8e0d178b1d1e 17555 { 0xa8af30d6,0x401966bb,0xf137b69c,0x95bf5f4a,0x9361c47e,0x3966162a,
wolfSSL 16:8e0d178b1d1e 17556 0xe7275b11,0xbd52d288 } },
wolfSSL 16:8e0d178b1d1e 17557 /* 72 */
wolfSSL 16:8e0d178b1d1e 17558 { { 0x9c5fa877,0xab155c7a,0x7d3a3d48,0x17dad672,0x73d189d8,0x43f43f9e,
wolfSSL 16:8e0d178b1d1e 17559 0xc8aa77a6,0xa0d0f8e4 },
wolfSSL 16:8e0d178b1d1e 17560 { 0xcc94f92d,0x0bbeafd8,0x0c4ddb3a,0xd818c8be,0xb82eba14,0x22cc65f8,
wolfSSL 16:8e0d178b1d1e 17561 0x946d6a00,0xa56c78c7 } },
wolfSSL 16:8e0d178b1d1e 17562 /* 73 */
wolfSSL 16:8e0d178b1d1e 17563 { { 0x0dd09529,0x2962391b,0x3daddfcf,0x803e0ea6,0x5b5bf481,0x2c77351f,
wolfSSL 16:8e0d178b1d1e 17564 0x731a367a,0xd8befdf8 },
wolfSSL 16:8e0d178b1d1e 17565 { 0xfc0157f4,0xab919d42,0xfec8e650,0xf51caed7,0x02d48b0a,0xcdf9cb40,
wolfSSL 16:8e0d178b1d1e 17566 0xce9f6478,0x854a68a5 } },
wolfSSL 16:8e0d178b1d1e 17567 /* 74 */
wolfSSL 16:8e0d178b1d1e 17568 { { 0x63506ea5,0xdc35f67b,0xa4fe0d66,0x9286c489,0xfe95cd4d,0x3f101d3b,
wolfSSL 16:8e0d178b1d1e 17569 0x98846a95,0x5cacea0b },
wolfSSL 16:8e0d178b1d1e 17570 { 0x9ceac44d,0xa90df60c,0x354d1c3a,0x3db29af4,0xad5dbabe,0x08dd3de8,
wolfSSL 16:8e0d178b1d1e 17571 0x35e4efa9,0xe4982d12 } },
wolfSSL 16:8e0d178b1d1e 17572 /* 75 */
wolfSSL 16:8e0d178b1d1e 17573 { { 0xc34cd55e,0x23104a22,0x2680d132,0x58695bb3,0x1fa1d943,0xfb345afa,
wolfSSL 16:8e0d178b1d1e 17574 0x16b20499,0x8046b7f6 },
wolfSSL 16:8e0d178b1d1e 17575 { 0x38e7d098,0xb533581e,0xf46f0b70,0xd7f61e8d,0x44cb78c4,0x30dea9ea,
wolfSSL 16:8e0d178b1d1e 17576 0x9082af55,0xeb17ca7b } },
wolfSSL 16:8e0d178b1d1e 17577 /* 76 */
wolfSSL 16:8e0d178b1d1e 17578 { { 0x76a145b9,0x1751b598,0xc1bc71ec,0xa5cf6b0f,0x392715bb,0xd3e03565,
wolfSSL 16:8e0d178b1d1e 17579 0xfab5e131,0x097b00ba },
wolfSSL 16:8e0d178b1d1e 17580 { 0x565f69e1,0xaa66c8e9,0xb5be5199,0x77e8f75a,0xda4fd984,0x6033ba11,
wolfSSL 16:8e0d178b1d1e 17581 0xafdbcc9e,0xf95c747b } },
wolfSSL 16:8e0d178b1d1e 17582 /* 77 */
wolfSSL 16:8e0d178b1d1e 17583 { { 0xbebae45e,0x558f01d3,0xc4bc6955,0xa8ebe9f0,0xdbc64fc6,0xaeb705b1,
wolfSSL 16:8e0d178b1d1e 17584 0x566ed837,0x3512601e },
wolfSSL 16:8e0d178b1d1e 17585 { 0xfa1161cd,0x9336f1e1,0x4c65ef87,0x328ab8d5,0x724f21e5,0x4757eee2,
wolfSSL 16:8e0d178b1d1e 17586 0x6068ab6b,0x0ef97123 } },
wolfSSL 16:8e0d178b1d1e 17587 /* 78 */
wolfSSL 16:8e0d178b1d1e 17588 { { 0x54ca4226,0x02598cf7,0xf8642c8e,0x5eede138,0x468e1790,0x48963f74,
wolfSSL 16:8e0d178b1d1e 17589 0x3b4fbc95,0xfc16d933 },
wolfSSL 16:8e0d178b1d1e 17590 { 0xe7c800ca,0xbe96fb31,0x2678adaa,0x13806331,0x6ff3e8b5,0x3d624497,
wolfSSL 16:8e0d178b1d1e 17591 0xb95d7a17,0x14ca4af1 } },
wolfSSL 16:8e0d178b1d1e 17592 /* 79 */
wolfSSL 16:8e0d178b1d1e 17593 { { 0xbd2f81d5,0x7a4771ba,0x01f7d196,0x1a5f9d69,0xcad9c907,0xd898bef7,
wolfSSL 16:8e0d178b1d1e 17594 0xf59c231d,0x4057b063 },
wolfSSL 16:8e0d178b1d1e 17595 { 0x89c05c0a,0xbffd82fe,0x1dc0df85,0xe4911c6f,0xa35a16db,0x3befccae,
wolfSSL 16:8e0d178b1d1e 17596 0xf1330b13,0x1c3b5d64 } },
wolfSSL 16:8e0d178b1d1e 17597 /* 80 */
wolfSSL 16:8e0d178b1d1e 17598 { { 0x80ec21fe,0x5fe14bfe,0xc255be82,0xf6ce116a,0x2f4a5d67,0x98bc5a07,
wolfSSL 16:8e0d178b1d1e 17599 0xdb7e63af,0xfad27148 },
wolfSSL 16:8e0d178b1d1e 17600 { 0x29ab05b3,0x90c0b6ac,0x4e251ae6,0x37a9a83c,0xc2aade7d,0x0a7dc875,
wolfSSL 16:8e0d178b1d1e 17601 0x9f0e1a84,0x77387de3 } },
wolfSSL 16:8e0d178b1d1e 17602 /* 81 */
wolfSSL 16:8e0d178b1d1e 17603 { { 0xa56c0dd7,0x1e9ecc49,0x46086c74,0xa5cffcd8,0xf505aece,0x8f7a1408,
wolfSSL 16:8e0d178b1d1e 17604 0xbef0c47e,0xb37b85c0 },
wolfSSL 16:8e0d178b1d1e 17605 { 0xcc0e6a8f,0x3596b6e4,0x6b388f23,0xfd6d4bbf,0xc39cef4e,0xaba453fa,
wolfSSL 16:8e0d178b1d1e 17606 0xf9f628d5,0x9c135ac8 } },
wolfSSL 16:8e0d178b1d1e 17607 /* 82 */
wolfSSL 16:8e0d178b1d1e 17608 { { 0x84e35743,0x32aa3202,0x85a3cdef,0x320d6ab1,0x1df19819,0xb821b176,
wolfSSL 16:8e0d178b1d1e 17609 0xc433851f,0x5721361f },
wolfSSL 16:8e0d178b1d1e 17610 { 0x71fc9168,0x1f0db36a,0x5e5c403c,0x5f98ba73,0x37bcd8f5,0xf64ca87e,
wolfSSL 16:8e0d178b1d1e 17611 0xe6bb11bd,0xdcbac3c9 } },
wolfSSL 16:8e0d178b1d1e 17612 /* 83 */
wolfSSL 16:8e0d178b1d1e 17613 { { 0x4518cbe2,0xf01d9968,0x9c9eb04e,0xd242fc18,0xe47feebf,0x727663c7,
wolfSSL 16:8e0d178b1d1e 17614 0x2d626862,0xb8c1c89e },
wolfSSL 16:8e0d178b1d1e 17615 { 0xc8e1d569,0x51a58bdd,0xb7d88cd0,0x563809c8,0xf11f31eb,0x26c27fd9,
wolfSSL 16:8e0d178b1d1e 17616 0x2f9422d4,0x5d23bbda } },
wolfSSL 16:8e0d178b1d1e 17617 /* 84 */
wolfSSL 16:8e0d178b1d1e 17618 { { 0x95c8f8be,0x0a1c7294,0x3bf362bf,0x2961c480,0xdf63d4ac,0x9e418403,
wolfSSL 16:8e0d178b1d1e 17619 0x91ece900,0xc109f9cb },
wolfSSL 16:8e0d178b1d1e 17620 { 0x58945705,0xc2d095d0,0xddeb85c0,0xb9083d96,0x7a40449b,0x84692b8d,
wolfSSL 16:8e0d178b1d1e 17621 0x2eee1ee1,0x9bc3344f } },
wolfSSL 16:8e0d178b1d1e 17622 /* 85 */
wolfSSL 16:8e0d178b1d1e 17623 { { 0x42913074,0x0d5ae356,0x48a542b1,0x55491b27,0xb310732a,0x469ca665,
wolfSSL 16:8e0d178b1d1e 17624 0x5f1a4cc1,0x29591d52 },
wolfSSL 16:8e0d178b1d1e 17625 { 0xb84f983f,0xe76f5b6b,0x9f5f84e1,0xbe7eef41,0x80baa189,0x1200d496,
wolfSSL 16:8e0d178b1d1e 17626 0x18ef332c,0x6376551f } },
wolfSSL 16:8e0d178b1d1e 17627 /* 86 */
wolfSSL 16:8e0d178b1d1e 17628 { { 0x562976cc,0xbda5f14e,0x0ef12c38,0x22bca3e6,0x6cca9852,0xbbfa3064,
wolfSSL 16:8e0d178b1d1e 17629 0x08e2987a,0xbdb79dc8 },
wolfSSL 16:8e0d178b1d1e 17630 { 0xcb06a772,0xfd2cb5c9,0xfe536dce,0x38f475aa,0x7c2b5db8,0xc2a3e022,
wolfSSL 16:8e0d178b1d1e 17631 0xadd3c14a,0x8ee86001 } },
wolfSSL 16:8e0d178b1d1e 17632 /* 87 */
wolfSSL 16:8e0d178b1d1e 17633 { { 0xa4ade873,0xcbe96981,0xc4fba48c,0x7ee9aa4d,0x5a054ba5,0x2cee2899,
wolfSSL 16:8e0d178b1d1e 17634 0x6f77aa4b,0x92e51d7a },
wolfSSL 16:8e0d178b1d1e 17635 { 0x7190a34d,0x948bafa8,0xf6bd1ed1,0xd698f75b,0x0caf1144,0xd00ee6e3,
wolfSSL 16:8e0d178b1d1e 17636 0x0a56aaaa,0x5182f86f } },
wolfSSL 16:8e0d178b1d1e 17637 /* 88 */
wolfSSL 16:8e0d178b1d1e 17638 { { 0x7a4cc99c,0xfba6212c,0x3e6d9ca1,0xff609b68,0x5ac98c5a,0x5dbb27cb,
wolfSSL 16:8e0d178b1d1e 17639 0x4073a6f2,0x91dcab5d },
wolfSSL 16:8e0d178b1d1e 17640 { 0x5f575a70,0x01b6cc3d,0x6f8d87fa,0x0cb36139,0x89981736,0x165d4e8c,
wolfSSL 16:8e0d178b1d1e 17641 0x97974f2b,0x17a0cedb } },
wolfSSL 16:8e0d178b1d1e 17642 /* 89 */
wolfSSL 16:8e0d178b1d1e 17643 { { 0x076c8d3a,0x38861e2a,0x210f924b,0x701aad39,0x13a835d9,0x94d0eae4,
wolfSSL 16:8e0d178b1d1e 17644 0x7f4cdf41,0x2e8ce36c },
wolfSSL 16:8e0d178b1d1e 17645 { 0x037a862b,0x91273dab,0x60e4c8fa,0x01ba9bb7,0x33baf2dd,0xf9645388,
wolfSSL 16:8e0d178b1d1e 17646 0x34f668f3,0xf4ccc6cb } },
wolfSSL 16:8e0d178b1d1e 17647 /* 90 */
wolfSSL 16:8e0d178b1d1e 17648 { { 0xf1f79687,0x44ef525c,0x92efa815,0x7c595495,0xa5c78d29,0xe1231741,
wolfSSL 16:8e0d178b1d1e 17649 0x9a0df3c9,0xac0db488 },
wolfSSL 16:8e0d178b1d1e 17650 { 0xdf01747f,0x86bfc711,0xef17df13,0x592b9358,0x5ccb6bb5,0xe5880e4f,
wolfSSL 16:8e0d178b1d1e 17651 0x94c974a2,0x95a64a61 } },
wolfSSL 16:8e0d178b1d1e 17652 /* 91 */
wolfSSL 16:8e0d178b1d1e 17653 { { 0xc15a4c93,0x72c1efda,0x82585141,0x40269b73,0x16cb0bad,0x6a8dfb1c,
wolfSSL 16:8e0d178b1d1e 17654 0x29210677,0x231e54ba },
wolfSSL 16:8e0d178b1d1e 17655 { 0x8ae6d2dc,0xa70df917,0x39112918,0x4d6aa63f,0x5e5b7223,0xf627726b,
wolfSSL 16:8e0d178b1d1e 17656 0xd8a731e1,0xab0be032 } },
wolfSSL 16:8e0d178b1d1e 17657 /* 92 */
wolfSSL 16:8e0d178b1d1e 17658 { { 0x8d131f2d,0x097ad0e9,0x3b04f101,0x637f09e3,0xd5e9a748,0x1ac86196,
wolfSSL 16:8e0d178b1d1e 17659 0x2cf6a679,0xf1bcc880 },
wolfSSL 16:8e0d178b1d1e 17660 { 0xe8daacb4,0x25c69140,0x60f65009,0x3c4e4055,0x477937a6,0x591cc8fc,
wolfSSL 16:8e0d178b1d1e 17661 0x5aebb271,0x85169469 } },
wolfSSL 16:8e0d178b1d1e 17662 /* 93 */
wolfSSL 16:8e0d178b1d1e 17663 { { 0xf1dcf593,0xde35c143,0xb018be3b,0x78202b29,0x9bdd9d3d,0xe9cdadc2,
wolfSSL 16:8e0d178b1d1e 17664 0xdaad55d8,0x8f67d9d2 },
wolfSSL 16:8e0d178b1d1e 17665 { 0x7481ea5f,0x84111656,0xe34c590c,0xe7d2dde9,0x05053fa8,0xffdd43f4,
wolfSSL 16:8e0d178b1d1e 17666 0xc0728b5d,0xf84572b9 } },
wolfSSL 16:8e0d178b1d1e 17667 /* 94 */
wolfSSL 16:8e0d178b1d1e 17668 { { 0x97af71c9,0x5e1a7a71,0x7a736565,0xa1449444,0x0e1d5063,0xa1b4ae07,
wolfSSL 16:8e0d178b1d1e 17669 0x616b2c19,0xedee2710 },
wolfSSL 16:8e0d178b1d1e 17670 { 0x11734121,0xb2f034f5,0x4a25e9f0,0x1cac6e55,0xa40c2ecf,0x8dc148f3,
wolfSSL 16:8e0d178b1d1e 17671 0x44ebd7f4,0x9fd27e9b } },
wolfSSL 16:8e0d178b1d1e 17672 /* 95 */
wolfSSL 16:8e0d178b1d1e 17673 { { 0xf6e2cb16,0x3cc7658a,0xfe5919b6,0xe3eb7d2c,0x168d5583,0x5a8c5816,
wolfSSL 16:8e0d178b1d1e 17674 0x958ff387,0xa40c2fb6 },
wolfSSL 16:8e0d178b1d1e 17675 { 0xfedcc158,0x8c9ec560,0x55f23056,0x7ad804c6,0x9a307e12,0xd9396704,
wolfSSL 16:8e0d178b1d1e 17676 0x7dc6decf,0x99bc9bb8 } },
wolfSSL 16:8e0d178b1d1e 17677 /* 96 */
wolfSSL 16:8e0d178b1d1e 17678 { { 0x927dafc6,0x84a9521d,0x5c09cd19,0x52c1fb69,0xf9366dde,0x9d9581a0,
wolfSSL 16:8e0d178b1d1e 17679 0xa16d7e64,0x9abe210b },
wolfSSL 16:8e0d178b1d1e 17680 { 0x48915220,0x480af84a,0x4dd816c6,0xfa73176a,0x1681ca5a,0xc7d53987,
wolfSSL 16:8e0d178b1d1e 17681 0x87f344b0,0x7881c257 } },
wolfSSL 16:8e0d178b1d1e 17682 /* 97 */
wolfSSL 16:8e0d178b1d1e 17683 { { 0xe0bcf3ff,0x93399b51,0x127f74f6,0x0d02cbc5,0xdd01d968,0x8fb465a2,
wolfSSL 16:8e0d178b1d1e 17684 0xa30e8940,0x15e6e319 },
wolfSSL 16:8e0d178b1d1e 17685 { 0x3e0e05f4,0x646d6e0d,0x43588404,0xfad7bddc,0xc4f850d3,0xbe61c7d1,
wolfSSL 16:8e0d178b1d1e 17686 0x191172ce,0x0e55facf } },
wolfSSL 16:8e0d178b1d1e 17687 /* 98 */
wolfSSL 16:8e0d178b1d1e 17688 { { 0xf8787564,0x7e9d9806,0x31e85ce6,0x1a331721,0xb819e8d6,0x6b0158ca,
wolfSSL 16:8e0d178b1d1e 17689 0x6fe96577,0xd73d0976 },
wolfSSL 16:8e0d178b1d1e 17690 { 0x1eb7206e,0x42483425,0xc618bb42,0xa519290f,0x5e30a520,0x5dcbb859,
wolfSSL 16:8e0d178b1d1e 17691 0x8f15a50b,0x9250a374 } },
wolfSSL 16:8e0d178b1d1e 17692 /* 99 */
wolfSSL 16:8e0d178b1d1e 17693 { { 0xbe577410,0xcaff08f8,0x5077a8c6,0xfd408a03,0xec0a63a4,0xf1f63289,
wolfSSL 16:8e0d178b1d1e 17694 0xc1cc8c0b,0x77414082 },
wolfSSL 16:8e0d178b1d1e 17695 { 0xeb0991cd,0x05a40fa6,0x49fdc296,0xc1ca0866,0xb324fd40,0x3a68a3c7,
wolfSSL 16:8e0d178b1d1e 17696 0x12eb20b9,0x8cb04f4d } },
wolfSSL 16:8e0d178b1d1e 17697 /* 100 */
wolfSSL 16:8e0d178b1d1e 17698 { { 0x6906171c,0xb1c2d055,0xb0240c3f,0x9073e9cd,0xd8906841,0xdb8e6b4f,
wolfSSL 16:8e0d178b1d1e 17699 0x47123b51,0xe4e429ef },
wolfSSL 16:8e0d178b1d1e 17700 { 0x38ec36f4,0x0b8dd53c,0xff4b6a27,0xf9d2dc01,0x879a9a48,0x5d066e07,
wolfSSL 16:8e0d178b1d1e 17701 0x3c6e6552,0x37bca2ff } },
wolfSSL 16:8e0d178b1d1e 17702 /* 101 */
wolfSSL 16:8e0d178b1d1e 17703 { { 0xdf562470,0x4cd2e3c7,0xc0964ac9,0x44f272a2,0x80c793be,0x7c6d5df9,
wolfSSL 16:8e0d178b1d1e 17704 0x3002b22a,0x59913edc },
wolfSSL 16:8e0d178b1d1e 17705 { 0x5750592a,0x7a139a83,0xe783de02,0x99e01d80,0xea05d64f,0xcf8c0375,
wolfSSL 16:8e0d178b1d1e 17706 0xb013e226,0x43786e4a } },
wolfSSL 16:8e0d178b1d1e 17707 /* 102 */
wolfSSL 16:8e0d178b1d1e 17708 { { 0x9e56b5a6,0xff32b0ed,0xd9fc68f9,0x0750d9a6,0x597846a7,0xec15e845,
wolfSSL 16:8e0d178b1d1e 17709 0xb7e79e7a,0x8638ca98 },
wolfSSL 16:8e0d178b1d1e 17710 { 0x0afc24b2,0x2f5ae096,0x4dace8f2,0x05398eaf,0xaecba78f,0x3b765dd0,
wolfSSL 16:8e0d178b1d1e 17711 0x7b3aa6f0,0x1ecdd36a } },
wolfSSL 16:8e0d178b1d1e 17712 /* 103 */
wolfSSL 16:8e0d178b1d1e 17713 { { 0x6c5ff2f3,0x5d3acd62,0x2873a978,0xa2d516c0,0xd2110d54,0xad94c9fa,
wolfSSL 16:8e0d178b1d1e 17714 0xd459f32d,0xd85d0f85 },
wolfSSL 16:8e0d178b1d1e 17715 { 0x10b11da3,0x9f700b8d,0xa78318c4,0xd2c22c30,0x9208decd,0x556988f4,
wolfSSL 16:8e0d178b1d1e 17716 0xb4ed3c62,0xa04f19c3 } },
wolfSSL 16:8e0d178b1d1e 17717 /* 104 */
wolfSSL 16:8e0d178b1d1e 17718 { { 0xed7f93bd,0x087924c8,0x392f51f6,0xcb64ac5d,0x821b71af,0x7cae330a,
wolfSSL 16:8e0d178b1d1e 17719 0x5c0950b0,0x92b2eeea },
wolfSSL 16:8e0d178b1d1e 17720 { 0x85b6e235,0x85ac4c94,0x2936c0f0,0xab2ca4a9,0xe0508891,0x80faa6b3,
wolfSSL 16:8e0d178b1d1e 17721 0x5834276c,0x1ee78221 } },
wolfSSL 16:8e0d178b1d1e 17722 /* 105 */
wolfSSL 16:8e0d178b1d1e 17723 { { 0xe63e79f7,0xa60a2e00,0xf399d906,0xf590e7b2,0x6607c09d,0x9021054a,
wolfSSL 16:8e0d178b1d1e 17724 0x57a6e150,0xf3f2ced8 },
wolfSSL 16:8e0d178b1d1e 17725 { 0xf10d9b55,0x200510f3,0xd8642648,0x9d2fcfac,0xe8bd0e7c,0xe5631aa7,
wolfSSL 16:8e0d178b1d1e 17726 0x3da3e210,0x0f56a454 } },
wolfSSL 16:8e0d178b1d1e 17727 /* 106 */
wolfSSL 16:8e0d178b1d1e 17728 { { 0x1043e0df,0x5b21bffa,0x9c007e6d,0x6c74b6cc,0xd4a8517a,0x1a656ec0,
wolfSSL 16:8e0d178b1d1e 17729 0x1969e263,0xbd8f1741 },
wolfSSL 16:8e0d178b1d1e 17730 { 0xbeb7494a,0x8a9bbb86,0x45f3b838,0x1567d46f,0xa4e5a79a,0xdf7a12a7,
wolfSSL 16:8e0d178b1d1e 17731 0x30ccfa09,0x2d1a1c35 } },
wolfSSL 16:8e0d178b1d1e 17732 /* 107 */
wolfSSL 16:8e0d178b1d1e 17733 { { 0x506508da,0x192e3813,0xa1d795a7,0x336180c4,0x7a9944b3,0xcddb5949,
wolfSSL 16:8e0d178b1d1e 17734 0xb91fba46,0xa107a65e },
wolfSSL 16:8e0d178b1d1e 17735 { 0x0f94d639,0xe6d1d1c5,0x8a58b7d7,0x8b4af375,0xbd37ca1c,0x1a7c5584,
wolfSSL 16:8e0d178b1d1e 17736 0xf87a9af2,0x183d760a } },
wolfSSL 16:8e0d178b1d1e 17737 /* 108 */
wolfSSL 16:8e0d178b1d1e 17738 { { 0x0dde59a4,0x29d69711,0x0e8bef87,0xf1ad8d07,0x4f2ebe78,0x229b4963,
wolfSSL 16:8e0d178b1d1e 17739 0xc269d754,0x1d44179d },
wolfSSL 16:8e0d178b1d1e 17740 { 0x8390d30e,0xb32dc0cf,0x0de8110c,0x0a3b2753,0x2bc0339a,0x31af1dc5,
wolfSSL 16:8e0d178b1d1e 17741 0x9606d262,0x771f9cc2 } },
wolfSSL 16:8e0d178b1d1e 17742 /* 109 */
wolfSSL 16:8e0d178b1d1e 17743 { { 0x85040739,0x99993e77,0x8026a939,0x44539db9,0xf5f8fc26,0xcf40f6f2,
wolfSSL 16:8e0d178b1d1e 17744 0x0362718e,0x64427a31 },
wolfSSL 16:8e0d178b1d1e 17745 { 0x85428aa8,0x4f4f2d87,0xebfb49a8,0x7b7adc3f,0xf23d01ac,0x201b2c6d,
wolfSSL 16:8e0d178b1d1e 17746 0x6ae90d6d,0x49d9b749 } },
wolfSSL 16:8e0d178b1d1e 17747 /* 110 */
wolfSSL 16:8e0d178b1d1e 17748 { { 0x435d1099,0xcc78d8bc,0x8e8d1a08,0x2adbcd4e,0x2cb68a41,0x02c2e2a0,
wolfSSL 16:8e0d178b1d1e 17749 0x3f605445,0x9037d81b },
wolfSSL 16:8e0d178b1d1e 17750 { 0x074c7b61,0x7cdbac27,0x57bfd72e,0xfe2031ab,0x596d5352,0x61ccec96,
wolfSSL 16:8e0d178b1d1e 17751 0x7cc0639c,0x08c3de6a } },
wolfSSL 16:8e0d178b1d1e 17752 /* 111 */
wolfSSL 16:8e0d178b1d1e 17753 { { 0xf6d552ab,0x20fdd020,0x05cd81f1,0x56baff98,0x91351291,0x06fb7c3e,
wolfSSL 16:8e0d178b1d1e 17754 0x45796b2f,0xc6909442 },
wolfSSL 16:8e0d178b1d1e 17755 { 0x41231bd1,0x17b3ae9c,0x5cc58205,0x1eac6e87,0xf9d6a122,0x208837ab,
wolfSSL 16:8e0d178b1d1e 17756 0xcafe3ac0,0x3fa3db02 } },
wolfSSL 16:8e0d178b1d1e 17757 /* 112 */
wolfSSL 16:8e0d178b1d1e 17758 { { 0x05058880,0xd75a3e65,0x643943f2,0x7da365ef,0xfab24925,0x4147861c,
wolfSSL 16:8e0d178b1d1e 17759 0xfdb808ff,0xc5c4bdb0 },
wolfSSL 16:8e0d178b1d1e 17760 { 0xb272b56b,0x73513e34,0x11b9043a,0xc8327e95,0xf8844969,0xfd8ce37d,
wolfSSL 16:8e0d178b1d1e 17761 0x46c2b6b5,0x2d56db94 } },
wolfSSL 16:8e0d178b1d1e 17762 /* 113 */
wolfSSL 16:8e0d178b1d1e 17763 { { 0xff46ac6b,0x2461782f,0x07a2e425,0xd19f7926,0x09a48de1,0xfafea3c4,
wolfSSL 16:8e0d178b1d1e 17764 0xe503ba42,0x0f56bd9d },
wolfSSL 16:8e0d178b1d1e 17765 { 0x345cda49,0x137d4ed1,0x816f299d,0x821158fc,0xaeb43402,0xe7c6a54a,
wolfSSL 16:8e0d178b1d1e 17766 0x1173b5f1,0x4003bb9d } },
wolfSSL 16:8e0d178b1d1e 17767 /* 114 */
wolfSSL 16:8e0d178b1d1e 17768 { { 0xa0803387,0x3b8e8189,0x39cbd404,0xece115f5,0xd2877f21,0x4297208d,
wolfSSL 16:8e0d178b1d1e 17769 0xa07f2f9e,0x53765522 },
wolfSSL 16:8e0d178b1d1e 17770 { 0xa8a4182d,0xa4980a21,0x3219df79,0xa2bbd07a,0x1a19a2d4,0x674d0a2e,
wolfSSL 16:8e0d178b1d1e 17771 0x6c5d4549,0x7a056f58 } },
wolfSSL 16:8e0d178b1d1e 17772 /* 115 */
wolfSSL 16:8e0d178b1d1e 17773 { { 0x9d8a2a47,0x646b2558,0xc3df2773,0x5b582948,0xabf0d539,0x51ec000e,
wolfSSL 16:8e0d178b1d1e 17774 0x7a1a2675,0x77d482f1 },
wolfSSL 16:8e0d178b1d1e 17775 { 0x87853948,0xb8a1bd95,0x6cfbffee,0xa6f817bd,0x80681e47,0xab6ec057,
wolfSSL 16:8e0d178b1d1e 17776 0x2b38b0e4,0x4115012b } },
wolfSSL 16:8e0d178b1d1e 17777 /* 116 */
wolfSSL 16:8e0d178b1d1e 17778 { { 0x6de28ced,0x3c73f0f4,0x9b13ec47,0x1d5da760,0x6e5c6392,0x61b8ce9e,
wolfSSL 16:8e0d178b1d1e 17779 0xfbea0946,0xcdf04572 },
wolfSSL 16:8e0d178b1d1e 17780 { 0x6c53c3b0,0x1cb3c58b,0x447b843c,0x97fe3c10,0x2cb9780e,0xfb2b8ae1,
wolfSSL 16:8e0d178b1d1e 17781 0x97383109,0xee703dda } },
wolfSSL 16:8e0d178b1d1e 17782 /* 117 */
wolfSSL 16:8e0d178b1d1e 17783 { { 0xff57e43a,0x34515140,0xb1b811b8,0xd44660d3,0x8f42b986,0x2b3b5dff,
wolfSSL 16:8e0d178b1d1e 17784 0xa162ce21,0x2a0ad89d },
wolfSSL 16:8e0d178b1d1e 17785 { 0x6bc277ba,0x64e4a694,0xc141c276,0xc788c954,0xcabf6274,0x141aa64c,
wolfSSL 16:8e0d178b1d1e 17786 0xac2b4659,0xd62d0b67 } },
wolfSSL 16:8e0d178b1d1e 17787 /* 118 */
wolfSSL 16:8e0d178b1d1e 17788 { { 0x2c054ac4,0x39c5d87b,0xf27df788,0x57005859,0xb18128d6,0xedf7cbf3,
wolfSSL 16:8e0d178b1d1e 17789 0x991c2426,0xb39a23f2 },
wolfSSL 16:8e0d178b1d1e 17790 { 0xf0b16ae5,0x95284a15,0xa136f51b,0x0c6a05b1,0xf2700783,0x1d63c137,
wolfSSL 16:8e0d178b1d1e 17791 0xc0674cc5,0x04ed0092 } },
wolfSSL 16:8e0d178b1d1e 17792 /* 119 */
wolfSSL 16:8e0d178b1d1e 17793 { { 0x9ae90393,0x1f4185d1,0x4a3d64e6,0x3047b429,0x9854fc14,0xae0001a6,
wolfSSL 16:8e0d178b1d1e 17794 0x0177c387,0xa0a91fc1 },
wolfSSL 16:8e0d178b1d1e 17795 { 0xae2c831e,0xff0a3f01,0x2b727e16,0xbb76ae82,0x5a3075b4,0x8f12c8a1,
wolfSSL 16:8e0d178b1d1e 17796 0x9ed20c41,0x084cf988 } },
wolfSSL 16:8e0d178b1d1e 17797 /* 120 */
wolfSSL 16:8e0d178b1d1e 17798 { { 0xfca6becf,0xd98509de,0x7dffb328,0x2fceae80,0x4778e8b9,0x5d8a15c4,
wolfSSL 16:8e0d178b1d1e 17799 0x73abf77e,0xd57955b2 },
wolfSSL 16:8e0d178b1d1e 17800 { 0x31b5d4f1,0x210da79e,0x3cfa7a1c,0xaa52f04b,0xdc27c20b,0xd4d12089,
wolfSSL 16:8e0d178b1d1e 17801 0x02d141f1,0x8e14ea42 } },
wolfSSL 16:8e0d178b1d1e 17802 /* 121 */
wolfSSL 16:8e0d178b1d1e 17803 { { 0xf2897042,0xeed50345,0x43402c4a,0x8d05331f,0xc8bdfb21,0xc8d9c194,
wolfSSL 16:8e0d178b1d1e 17804 0x2aa4d158,0x597e1a37 },
wolfSSL 16:8e0d178b1d1e 17805 { 0xcf0bd68c,0x0327ec1a,0xab024945,0x6d4be0dc,0xc9fe3e84,0x5b9c8d7a,
wolfSSL 16:8e0d178b1d1e 17806 0x199b4dea,0xca3f0236 } },
wolfSSL 16:8e0d178b1d1e 17807 /* 122 */
wolfSSL 16:8e0d178b1d1e 17808 { { 0x6170bd20,0x592a10b5,0x6d3f5de7,0x0ea897f1,0x44b2ade2,0xa3363ff1,
wolfSSL 16:8e0d178b1d1e 17809 0x309c07e4,0xbde7fd7e },
wolfSSL 16:8e0d178b1d1e 17810 { 0xb8f5432c,0x516bb6d2,0xe043444b,0x210dc1cb,0xf8f95b5a,0x3db01e6f,
wolfSSL 16:8e0d178b1d1e 17811 0x0a7dd198,0xb623ad0e } },
wolfSSL 16:8e0d178b1d1e 17812 /* 123 */
wolfSSL 16:8e0d178b1d1e 17813 { { 0x60c7b65b,0xa75bd675,0x23a4a289,0xab8c5590,0xd7b26795,0xf8220fd0,
wolfSSL 16:8e0d178b1d1e 17814 0x58ec137b,0xd6aa2e46 },
wolfSSL 16:8e0d178b1d1e 17815 { 0x5138bb85,0x10abc00b,0xd833a95c,0x8c31d121,0x1702a32e,0xb24ff00b,
wolfSSL 16:8e0d178b1d1e 17816 0x2dcc513a,0x111662e0 } },
wolfSSL 16:8e0d178b1d1e 17817 /* 124 */
wolfSSL 16:8e0d178b1d1e 17818 { { 0xefb42b87,0x78114015,0x1b6c4dff,0xbd9f5d70,0xa7d7c129,0x66ecccd7,
wolfSSL 16:8e0d178b1d1e 17819 0x94b750f8,0xdb3ee1cb },
wolfSSL 16:8e0d178b1d1e 17820 { 0xf34837cf,0xb26f3db0,0xb9578d4f,0xe7eed18b,0x7c56657d,0x5d2cdf93,
wolfSSL 16:8e0d178b1d1e 17821 0x52206a59,0x886a6442 } },
wolfSSL 16:8e0d178b1d1e 17822 /* 125 */
wolfSSL 16:8e0d178b1d1e 17823 { { 0x65b569ea,0x3c234cfb,0xf72119c1,0x20011141,0xa15a619e,0x8badc85d,
wolfSSL 16:8e0d178b1d1e 17824 0x018a17bc,0xa70cf4eb },
wolfSSL 16:8e0d178b1d1e 17825 { 0x8c4a6a65,0x224f97ae,0x0134378f,0x36e5cf27,0x4f7e0960,0xbe3a609e,
wolfSSL 16:8e0d178b1d1e 17826 0xd1747b77,0xaa4772ab } },
wolfSSL 16:8e0d178b1d1e 17827 /* 126 */
wolfSSL 16:8e0d178b1d1e 17828 { { 0x7aa60cc0,0x67676131,0x0368115f,0xc7916361,0xbbc1bb5a,0xded98bb4,
wolfSSL 16:8e0d178b1d1e 17829 0x30faf974,0x611a6ddc },
wolfSSL 16:8e0d178b1d1e 17830 { 0xc15ee47a,0x30e78cbc,0x4e0d96a5,0x2e896282,0x3dd9ed88,0x36f35adf,
wolfSSL 16:8e0d178b1d1e 17831 0x16429c88,0x5cfffaf8 } },
wolfSSL 16:8e0d178b1d1e 17832 /* 127 */
wolfSSL 16:8e0d178b1d1e 17833 { { 0x9b7a99cd,0xc0d54cff,0x843c45a1,0x7bf3b99d,0x62c739e1,0x038a908f,
wolfSSL 16:8e0d178b1d1e 17834 0x7dc1994c,0x6e5a6b23 },
wolfSSL 16:8e0d178b1d1e 17835 { 0x0ba5db77,0xef8b454e,0xacf60d63,0xb7b8807f,0x76608378,0xe591c0c6,
wolfSSL 16:8e0d178b1d1e 17836 0x242dabcc,0x481a238d } },
wolfSSL 16:8e0d178b1d1e 17837 /* 128 */
wolfSSL 16:8e0d178b1d1e 17838 { { 0x35d0b34a,0xe3417bc0,0x8327c0a7,0x440b386b,0xac0362d1,0x8fb7262d,
wolfSSL 16:8e0d178b1d1e 17839 0xe0cdf943,0x2c41114c },
wolfSSL 16:8e0d178b1d1e 17840 { 0xad95a0b1,0x2ba5cef1,0x67d54362,0xc09b37a8,0x01e486c9,0x26d6cdd2,
wolfSSL 16:8e0d178b1d1e 17841 0x42ff9297,0x20477abf } },
wolfSSL 16:8e0d178b1d1e 17842 /* 129 */
wolfSSL 16:8e0d178b1d1e 17843 { { 0x18d65dbf,0x2f75173c,0x339edad8,0x77bf940e,0xdcf1001c,0x7022d26b,
wolfSSL 16:8e0d178b1d1e 17844 0xc77396b6,0xac66409a },
wolfSSL 16:8e0d178b1d1e 17845 { 0xc6261cc3,0x8b0bb36f,0x190e7e90,0x213f7bc9,0xa45e6c10,0x6541ceba,
wolfSSL 16:8e0d178b1d1e 17846 0xcc122f85,0xce8e6975 } },
wolfSSL 16:8e0d178b1d1e 17847 /* 130 */
wolfSSL 16:8e0d178b1d1e 17848 { { 0xbc0a67d2,0x0f121b41,0x444d248a,0x62d4760a,0x659b4737,0x0e044f1d,
wolfSSL 16:8e0d178b1d1e 17849 0x250bb4a8,0x08fde365 },
wolfSSL 16:8e0d178b1d1e 17850 { 0x848bf287,0xaceec3da,0xd3369d6e,0xc2a62182,0x92449482,0x3582dfdc,
wolfSSL 16:8e0d178b1d1e 17851 0x565d6cd7,0x2f7e2fd2 } },
wolfSSL 16:8e0d178b1d1e 17852 /* 131 */
wolfSSL 16:8e0d178b1d1e 17853 { { 0xc3770fa7,0xae4b92db,0x379043f9,0x095e8d5c,0x17761171,0x54f34e9d,
wolfSSL 16:8e0d178b1d1e 17854 0x907702ae,0xc65be92e },
wolfSSL 16:8e0d178b1d1e 17855 { 0xf6fd0a40,0x2758a303,0xbcce784b,0xe7d822e3,0x4f9767bf,0x7ae4f585,
wolfSSL 16:8e0d178b1d1e 17856 0xd1193b3a,0x4bff8e47 } },
wolfSSL 16:8e0d178b1d1e 17857 /* 132 */
wolfSSL 16:8e0d178b1d1e 17858 { { 0x00ff1480,0xcd41d21f,0x0754db16,0x2ab8fb7d,0xbbe0f3ea,0xac81d2ef,
wolfSSL 16:8e0d178b1d1e 17859 0x5772967d,0x3e4e4ae6 },
wolfSSL 16:8e0d178b1d1e 17860 { 0x3c5303e6,0x7e18f36d,0x92262397,0x3bd9994b,0x1324c3c0,0x9ed70e26,
wolfSSL 16:8e0d178b1d1e 17861 0x58ec6028,0x5388aefd } },
wolfSSL 16:8e0d178b1d1e 17862 /* 133 */
wolfSSL 16:8e0d178b1d1e 17863 { { 0x5e5d7713,0xad1317eb,0x75de49da,0x09b985ee,0xc74fb261,0x32f5bc4f,
wolfSSL 16:8e0d178b1d1e 17864 0x4f75be0e,0x5cf908d1 },
wolfSSL 16:8e0d178b1d1e 17865 { 0x8e657b12,0x76043510,0xb96ed9e6,0xbfd421a5,0x8970ccc2,0x0e29f51f,
wolfSSL 16:8e0d178b1d1e 17866 0x60f00ce2,0xa698ba40 } },
wolfSSL 16:8e0d178b1d1e 17867 /* 134 */
wolfSSL 16:8e0d178b1d1e 17868 { { 0xef748fec,0x73db1686,0x7e9d2cf9,0xe6e755a2,0xce265eff,0x630b6544,
wolfSSL 16:8e0d178b1d1e 17869 0x7aebad8d,0xb142ef8a },
wolfSSL 16:8e0d178b1d1e 17870 { 0x17d5770a,0xad31af9f,0x2cb3412f,0x66af3b67,0xdf3359de,0x6bd60d1b,
wolfSSL 16:8e0d178b1d1e 17871 0x58515075,0xd1896a96 } },
wolfSSL 16:8e0d178b1d1e 17872 /* 135 */
wolfSSL 16:8e0d178b1d1e 17873 { { 0x33c41c08,0xec5957ab,0x5468e2e1,0x87de94ac,0xac472f6c,0x18816b73,
wolfSSL 16:8e0d178b1d1e 17874 0x7981da39,0x267b0e0b },
wolfSSL 16:8e0d178b1d1e 17875 { 0x8e62b988,0x6e554e5d,0x116d21e7,0xd8ddc755,0x3d2a6f99,0x4610faf0,
wolfSSL 16:8e0d178b1d1e 17876 0xa1119393,0xb54e287a } },
wolfSSL 16:8e0d178b1d1e 17877 /* 136 */
wolfSSL 16:8e0d178b1d1e 17878 { { 0x178a876b,0x0a0122b5,0x085104b4,0x51ff96ff,0x14f29f76,0x050b31ab,
wolfSSL 16:8e0d178b1d1e 17879 0x5f87d4e6,0x84abb28b },
wolfSSL 16:8e0d178b1d1e 17880 { 0x8270790a,0xd5ed439f,0x85e3f46b,0x2d6cb59d,0x6c1e2212,0x75f55c1b,
wolfSSL 16:8e0d178b1d1e 17881 0x17655640,0xe5436f67 } },
wolfSSL 16:8e0d178b1d1e 17882 /* 137 */
wolfSSL 16:8e0d178b1d1e 17883 { { 0x2286e8d5,0x53f9025e,0x864453be,0x353c95b4,0xe408e3a0,0xd832f5bd,
wolfSSL 16:8e0d178b1d1e 17884 0x5b9ce99e,0x0404f68b },
wolfSSL 16:8e0d178b1d1e 17885 { 0xa781e8e5,0xcad33bde,0x163c2f5b,0x3cdf5018,0x0119caa3,0x57576960,
wolfSSL 16:8e0d178b1d1e 17886 0x0ac1c701,0x3a4263df } },
wolfSSL 16:8e0d178b1d1e 17887 /* 138 */
wolfSSL 16:8e0d178b1d1e 17888 { { 0x9aeb596d,0xc2965ecc,0x023c92b4,0x01ea03e7,0x2e013961,0x4704b4b6,
wolfSSL 16:8e0d178b1d1e 17889 0x905ea367,0x0ca8fd3f },
wolfSSL 16:8e0d178b1d1e 17890 { 0x551b2b61,0x92523a42,0x390fcd06,0x1eb7a89c,0x0392a63e,0xe7f1d2be,
wolfSSL 16:8e0d178b1d1e 17891 0x4ddb0c33,0x96dca264 } },
wolfSSL 16:8e0d178b1d1e 17892 /* 139 */
wolfSSL 16:8e0d178b1d1e 17893 { { 0x387510af,0x203bb43a,0xa9a36a01,0x846feaa8,0x2f950378,0xd23a5770,
wolfSSL 16:8e0d178b1d1e 17894 0x3aad59dc,0x4363e212 },
wolfSSL 16:8e0d178b1d1e 17895 { 0x40246a47,0xca43a1c7,0xe55dd24d,0xb362b8d2,0x5d8faf96,0xf9b08604,
wolfSSL 16:8e0d178b1d1e 17896 0xd8bb98c4,0x840e115c } },
wolfSSL 16:8e0d178b1d1e 17897 /* 140 */
wolfSSL 16:8e0d178b1d1e 17898 { { 0x1023e8a7,0xf12205e2,0xd8dc7a0b,0xc808a8cd,0x163a5ddf,0xe292a272,
wolfSSL 16:8e0d178b1d1e 17899 0x30ded6d4,0x5e0d6abd },
wolfSSL 16:8e0d178b1d1e 17900 { 0x7cfc0f64,0x07a721c2,0x0e55ed88,0x42eec01d,0x1d1f9db2,0x26a7bef9,
wolfSSL 16:8e0d178b1d1e 17901 0x2945a25a,0x7dea48f4 } },
wolfSSL 16:8e0d178b1d1e 17902 /* 141 */
wolfSSL 16:8e0d178b1d1e 17903 { { 0xe5060a81,0xabdf6f1c,0xf8f95615,0xe79f9c72,0x06ac268b,0xcfd36c54,
wolfSSL 16:8e0d178b1d1e 17904 0xebfd16d1,0xabc2a2be },
wolfSSL 16:8e0d178b1d1e 17905 { 0xd3e2eac7,0x8ac66f91,0xd2dd0466,0x6f10ba63,0x0282d31b,0x6790e377,
wolfSSL 16:8e0d178b1d1e 17906 0x6c7eefc1,0x4ea35394 } },
wolfSSL 16:8e0d178b1d1e 17907 /* 142 */
wolfSSL 16:8e0d178b1d1e 17908 { { 0x5266309d,0xed8a2f8d,0x81945a3e,0x0a51c6c0,0x578c5dc1,0xcecaf45a,
wolfSSL 16:8e0d178b1d1e 17909 0x1c94ffc3,0x3a76e689 },
wolfSSL 16:8e0d178b1d1e 17910 { 0x7d7b0d0f,0x9aace8a4,0x8f584a5f,0x963ace96,0x4e697fbe,0x51a30c72,
wolfSSL 16:8e0d178b1d1e 17911 0x465e6464,0x8212a10a } },
wolfSSL 16:8e0d178b1d1e 17912 /* 143 */
wolfSSL 16:8e0d178b1d1e 17913 { { 0xcfab8caa,0xef7c61c3,0x0e142390,0x18eb8e84,0x7e9733ca,0xcd1dff67,
wolfSSL 16:8e0d178b1d1e 17914 0x599cb164,0xaa7cab71 },
wolfSSL 16:8e0d178b1d1e 17915 { 0xbc837bd1,0x02fc9273,0xc36af5d7,0xc06407d0,0xf423da49,0x17621292,
wolfSSL 16:8e0d178b1d1e 17916 0xfe0617c3,0x40e38073 } },
wolfSSL 16:8e0d178b1d1e 17917 /* 144 */
wolfSSL 16:8e0d178b1d1e 17918 { { 0xa7bf9b7c,0xf4f80824,0x3fbe30d0,0x365d2320,0x97cf9ce3,0xbfbe5320,
wolfSSL 16:8e0d178b1d1e 17919 0xb3055526,0xe3604700 },
wolfSSL 16:8e0d178b1d1e 17920 { 0x6cc6c2c7,0x4dcb9911,0xba4cbee6,0x72683708,0x637ad9ec,0xdcded434,
wolfSSL 16:8e0d178b1d1e 17921 0xa3dee15f,0x6542d677 } },
wolfSSL 16:8e0d178b1d1e 17922 /* 145 */
wolfSSL 16:8e0d178b1d1e 17923 { { 0x7b6c377a,0x3f32b6d0,0x903448be,0x6cb03847,0x20da8af7,0xd6fdd3a8,
wolfSSL 16:8e0d178b1d1e 17924 0x09bb6f21,0xa6534aee },
wolfSSL 16:8e0d178b1d1e 17925 { 0x1035facf,0x30a1780d,0x9dcb47e6,0x35e55a33,0xc447f393,0x6ea50fe1,
wolfSSL 16:8e0d178b1d1e 17926 0xdc9aef22,0xf3cb672f } },
wolfSSL 16:8e0d178b1d1e 17927 /* 146 */
wolfSSL 16:8e0d178b1d1e 17928 { { 0x3b55fd83,0xeb3719fe,0x875ddd10,0xe0d7a46c,0x05cea784,0x33ac9fa9,
wolfSSL 16:8e0d178b1d1e 17929 0xaae870e7,0x7cafaa2e },
wolfSSL 16:8e0d178b1d1e 17930 { 0x1d53b338,0x9b814d04,0xef87e6c6,0xe0acc0a0,0x11672b0f,0xfb93d108,
wolfSSL 16:8e0d178b1d1e 17931 0xb9bd522e,0x0aab13c1 } },
wolfSSL 16:8e0d178b1d1e 17932 /* 147 */
wolfSSL 16:8e0d178b1d1e 17933 { { 0xd2681297,0xddcce278,0xb509546a,0xcb350eb1,0x7661aaf2,0x2dc43173,
wolfSSL 16:8e0d178b1d1e 17934 0x847012e9,0x4b91a602 },
wolfSSL 16:8e0d178b1d1e 17935 { 0x72f8ddcf,0xdcff1095,0x9a911af4,0x08ebf61e,0xc372430e,0x48f4360a,
wolfSSL 16:8e0d178b1d1e 17936 0x72321cab,0x49534c53 } },
wolfSSL 16:8e0d178b1d1e 17937 /* 148 */
wolfSSL 16:8e0d178b1d1e 17938 { { 0xf07b7e9d,0x83df7d71,0x13cd516f,0xa478efa3,0x6c047ee3,0x78ef264b,
wolfSSL 16:8e0d178b1d1e 17939 0xd65ac5ee,0xcaf46c4f },
wolfSSL 16:8e0d178b1d1e 17940 { 0x92aa8266,0xa04d0c77,0x913684bb,0xedf45466,0xae4b16b0,0x56e65168,
wolfSSL 16:8e0d178b1d1e 17941 0x04c6770f,0x14ce9e57 } },
wolfSSL 16:8e0d178b1d1e 17942 /* 149 */
wolfSSL 16:8e0d178b1d1e 17943 { { 0x965e8f91,0x99445e3e,0xcb0f2492,0xd3aca1ba,0x90c8a0a0,0xd31cc70f,
wolfSSL 16:8e0d178b1d1e 17944 0x3e4c9a71,0x1bb708a5 },
wolfSSL 16:8e0d178b1d1e 17945 { 0x558bdd7a,0xd5ca9e69,0x018a26b1,0x734a0508,0x4c9cf1ec,0xb093aa71,
wolfSSL 16:8e0d178b1d1e 17946 0xda300102,0xf9d126f2 } },
wolfSSL 16:8e0d178b1d1e 17947 /* 150 */
wolfSSL 16:8e0d178b1d1e 17948 { { 0xaff9563e,0x749bca7a,0xb49914a0,0xdd077afe,0xbf5f1671,0xe27a0311,
wolfSSL 16:8e0d178b1d1e 17949 0x729ecc69,0x807afcb9 },
wolfSSL 16:8e0d178b1d1e 17950 { 0xc9b08b77,0x7f8a9337,0x443c7e38,0x86c3a785,0x476fd8ba,0x85fafa59,
wolfSSL 16:8e0d178b1d1e 17951 0x6568cd8c,0x751adcd1 } },
wolfSSL 16:8e0d178b1d1e 17952 /* 151 */
wolfSSL 16:8e0d178b1d1e 17953 { { 0x10715c0d,0x8aea38b4,0x8f7697f7,0xd113ea71,0x93fbf06d,0x665eab14,
wolfSSL 16:8e0d178b1d1e 17954 0x2537743f,0x29ec4468 },
wolfSSL 16:8e0d178b1d1e 17955 { 0xb50bebbc,0x3d94719c,0xe4505422,0x399ee5bf,0x8d2dedb1,0x90cd5b3a,
wolfSSL 16:8e0d178b1d1e 17956 0x92a4077d,0xff9370e3 } },
wolfSSL 16:8e0d178b1d1e 17957 /* 152 */
wolfSSL 16:8e0d178b1d1e 17958 { { 0xc6b75b65,0x59a2d69b,0x266651c5,0x4188f8d5,0x3de9d7d2,0x28a9f33e,
wolfSSL 16:8e0d178b1d1e 17959 0xa2a9d01a,0x9776478b },
wolfSSL 16:8e0d178b1d1e 17960 { 0x929af2c7,0x8852622d,0x4e690923,0x334f5d6d,0xa89a51e9,0xce6cc7e5,
wolfSSL 16:8e0d178b1d1e 17961 0xac2f82fa,0x74a6313f } },
wolfSSL 16:8e0d178b1d1e 17962 /* 153 */
wolfSSL 16:8e0d178b1d1e 17963 { { 0xb75f079c,0xb2f4dfdd,0x18e36fbb,0x85b07c95,0xe7cd36dd,0x1b6cfcf0,
wolfSSL 16:8e0d178b1d1e 17964 0x0ff4863d,0xab75be15 },
wolfSSL 16:8e0d178b1d1e 17965 { 0x173fc9b7,0x81b367c0,0xd2594fd0,0xb90a7420,0xc4091236,0x15fdbf03,
wolfSSL 16:8e0d178b1d1e 17966 0x0b4459f6,0x4ebeac2e } },
wolfSSL 16:8e0d178b1d1e 17967 /* 154 */
wolfSSL 16:8e0d178b1d1e 17968 { { 0x5c9f2c53,0xeb6c5fe7,0x8eae9411,0xd2522011,0xf95ac5d8,0xc8887633,
wolfSSL 16:8e0d178b1d1e 17969 0x2c1baffc,0xdf99887b },
wolfSSL 16:8e0d178b1d1e 17970 { 0x850aaecb,0xbb78eed2,0x01d6a272,0x9d49181b,0xb1cdbcac,0x978dd511,
wolfSSL 16:8e0d178b1d1e 17971 0x779f4058,0x27b040a7 } },
wolfSSL 16:8e0d178b1d1e 17972 /* 155 */
wolfSSL 16:8e0d178b1d1e 17973 { { 0xf73b2eb2,0x90405db7,0x8e1b2118,0xe0df8508,0x5962327e,0x501b7152,
wolfSSL 16:8e0d178b1d1e 17974 0xe4cfa3f5,0xb393dd37 },
wolfSSL 16:8e0d178b1d1e 17975 { 0x3fd75165,0xa1230e7b,0xbcd33554,0xd66344c2,0x0f7b5022,0x6c36f1be,
wolfSSL 16:8e0d178b1d1e 17976 0xd0463419,0x09588c12 } },
wolfSSL 16:8e0d178b1d1e 17977 /* 156 */
wolfSSL 16:8e0d178b1d1e 17978 { { 0x02601c3b,0xe086093f,0xcf5c335f,0xfb0252f8,0x894aff28,0x955cf280,
wolfSSL 16:8e0d178b1d1e 17979 0xdb9f648b,0x81c879a9 },
wolfSSL 16:8e0d178b1d1e 17980 { 0xc6f56c51,0x040e687c,0x3f17618c,0xfed47169,0x9059353b,0x44f88a41,
wolfSSL 16:8e0d178b1d1e 17981 0x5fc11bc4,0xfa0d48f5 } },
wolfSSL 16:8e0d178b1d1e 17982 /* 157 */
wolfSSL 16:8e0d178b1d1e 17983 { { 0xe1608e4d,0xbc6e1c9d,0x3582822c,0x010dda11,0x157ec2d7,0xf6b7ddc1,
wolfSSL 16:8e0d178b1d1e 17984 0xb6a367d6,0x8ea0e156 },
wolfSSL 16:8e0d178b1d1e 17985 { 0x2383b3b4,0xa354e02f,0x3f01f53c,0x69966b94,0x2de03ca5,0x4ff6632b,
wolfSSL 16:8e0d178b1d1e 17986 0xfa00b5ac,0x3f5ab924 } },
wolfSSL 16:8e0d178b1d1e 17987 /* 158 */
wolfSSL 16:8e0d178b1d1e 17988 { { 0x59739efb,0x337bb0d9,0xe7ebec0d,0xc751b0f4,0x411a67d1,0x2da52dd6,
wolfSSL 16:8e0d178b1d1e 17989 0x2b74256e,0x8bc76887 },
wolfSSL 16:8e0d178b1d1e 17990 { 0x82d3d253,0xa5be3b72,0xf58d779f,0xa9f679a1,0xe16767bb,0xa1cac168,
wolfSSL 16:8e0d178b1d1e 17991 0x60fcf34f,0xb386f190 } },
wolfSSL 16:8e0d178b1d1e 17992 /* 159 */
wolfSSL 16:8e0d178b1d1e 17993 { { 0x2fedcfc2,0x31f3c135,0x62f8af0d,0x5396bf62,0xe57288c2,0x9a02b4ea,
wolfSSL 16:8e0d178b1d1e 17994 0x1b069c4d,0x4cb460f7 },
wolfSSL 16:8e0d178b1d1e 17995 { 0x5b8095ea,0xae67b4d3,0x6fc07603,0x92bbf859,0xb614a165,0xe1475f66,
wolfSSL 16:8e0d178b1d1e 17996 0x95ef5223,0x52c0d508 } },
wolfSSL 16:8e0d178b1d1e 17997 /* 160 */
wolfSSL 16:8e0d178b1d1e 17998 { { 0x15339848,0x231c210e,0x70778c8d,0xe87a28e8,0x6956e170,0x9d1de661,
wolfSSL 16:8e0d178b1d1e 17999 0x2bb09c0b,0x4ac3c938 },
wolfSSL 16:8e0d178b1d1e 18000 { 0x6998987d,0x19be0551,0xae09f4d6,0x8b2376c4,0x1a3f933d,0x1de0b765,
wolfSSL 16:8e0d178b1d1e 18001 0xe39705f4,0x380d94c7 } },
wolfSSL 16:8e0d178b1d1e 18002 /* 161 */
wolfSSL 16:8e0d178b1d1e 18003 { { 0x81542e75,0x01a355aa,0xee01b9b7,0x96c724a1,0x624d7087,0x6b3a2977,
wolfSSL 16:8e0d178b1d1e 18004 0xde2637af,0x2ce3e171 },
wolfSSL 16:8e0d178b1d1e 18005 { 0xf5d5bc1a,0xcfefeb49,0x2777e2b5,0xa655607e,0x9513756c,0x4feaac2f,
wolfSSL 16:8e0d178b1d1e 18006 0x0b624e4d,0x2e6cd852 } },
wolfSSL 16:8e0d178b1d1e 18007 /* 162 */
wolfSSL 16:8e0d178b1d1e 18008 { { 0x8c31c31d,0x3685954b,0x5bf21a0c,0x68533d00,0x75c79ec9,0x0bd7626e,
wolfSSL 16:8e0d178b1d1e 18009 0x42c69d54,0xca177547 },
wolfSSL 16:8e0d178b1d1e 18010 { 0xf6d2dbb2,0xcc6edaff,0x174a9d18,0xfd0d8cbd,0xaa4578e8,0x875e8793,
wolfSSL 16:8e0d178b1d1e 18011 0x9cab2ce6,0xa976a713 } },
wolfSSL 16:8e0d178b1d1e 18012 /* 163 */
wolfSSL 16:8e0d178b1d1e 18013 { { 0x93fb353d,0x0a651f1b,0x57fcfa72,0xd75cab8b,0x31b15281,0xaa88cfa7,
wolfSSL 16:8e0d178b1d1e 18014 0x0a1f4999,0x8720a717 },
wolfSSL 16:8e0d178b1d1e 18015 { 0x693e1b90,0x8c3e8d37,0x16f6dfc3,0xd345dc0b,0xb52a8742,0x8ea8d00a,
wolfSSL 16:8e0d178b1d1e 18016 0xc769893c,0x9719ef29 } },
wolfSSL 16:8e0d178b1d1e 18017 /* 164 */
wolfSSL 16:8e0d178b1d1e 18018 { { 0x58e35909,0x820eed8d,0x33ddc116,0x9366d8dc,0x6e205026,0xd7f999d0,
wolfSSL 16:8e0d178b1d1e 18019 0xe15704c1,0xa5072976 },
wolfSSL 16:8e0d178b1d1e 18020 { 0xc4e70b2e,0x002a37ea,0x6890aa8a,0x84dcf657,0x645b2a5c,0xcd71bf18,
wolfSSL 16:8e0d178b1d1e 18021 0xf7b77725,0x99389c9d } },
wolfSSL 16:8e0d178b1d1e 18022 /* 165 */
wolfSSL 16:8e0d178b1d1e 18023 { { 0x7ada7a4b,0x238c08f2,0xfd389366,0x3abe9d03,0x766f512c,0x6b672e89,
wolfSSL 16:8e0d178b1d1e 18024 0x202c82e4,0xa88806aa },
wolfSSL 16:8e0d178b1d1e 18025 { 0xd380184e,0x6602044a,0x126a8b85,0xa8cb78c4,0xad844f17,0x79d670c0,
wolfSSL 16:8e0d178b1d1e 18026 0x4738dcfe,0x0043bffb } },
wolfSSL 16:8e0d178b1d1e 18027 /* 166 */
wolfSSL 16:8e0d178b1d1e 18028 { { 0x36d5192e,0x8d59b5dc,0x4590b2af,0xacf885d3,0x11601781,0x83566d0a,
wolfSSL 16:8e0d178b1d1e 18029 0xba6c4866,0x52f3ef01 },
wolfSSL 16:8e0d178b1d1e 18030 { 0x0edcb64d,0x3986732a,0x8068379f,0x0a482c23,0x7040f309,0x16cbe5fa,
wolfSSL 16:8e0d178b1d1e 18031 0x9ef27e75,0x3296bd89 } },
wolfSSL 16:8e0d178b1d1e 18032 /* 167 */
wolfSSL 16:8e0d178b1d1e 18033 { { 0x454d81d7,0x476aba89,0x51eb9b3c,0x9eade7ef,0x81c57986,0x619a21cd,
wolfSSL 16:8e0d178b1d1e 18034 0xaee571e9,0x3b90febf },
wolfSSL 16:8e0d178b1d1e 18035 { 0x5496f7cb,0x9393023e,0x7fb51bc4,0x55be41d8,0x99beb5ce,0x03f1dd48,
wolfSSL 16:8e0d178b1d1e 18036 0x9f810b18,0x6e88069d } },
wolfSSL 16:8e0d178b1d1e 18037 /* 168 */
wolfSSL 16:8e0d178b1d1e 18038 { { 0xb43ea1db,0xce37ab11,0x5259d292,0x0a7ff1a9,0x8f84f186,0x851b0221,
wolfSSL 16:8e0d178b1d1e 18039 0xdefaad13,0xa7222bea },
wolfSSL 16:8e0d178b1d1e 18040 { 0x2b0a9144,0xa2ac78ec,0xf2fa59c5,0x5a024051,0x6147ce38,0x91d1eca5,
wolfSSL 16:8e0d178b1d1e 18041 0xbc2ac690,0xbe94d523 } },
wolfSSL 16:8e0d178b1d1e 18042 /* 169 */
wolfSSL 16:8e0d178b1d1e 18043 { { 0x0b226ce7,0x72f4945e,0x967e8b70,0xb8afd747,0x85a6c63e,0xedea46f1,
wolfSSL 16:8e0d178b1d1e 18044 0x9be8c766,0x7782defe },
wolfSSL 16:8e0d178b1d1e 18045 { 0x3db38626,0x760d2aa4,0x76f67ad1,0x460ae787,0x54499cdb,0x341b86fc,
wolfSSL 16:8e0d178b1d1e 18046 0xa2892e4b,0x03838567 } },
wolfSSL 16:8e0d178b1d1e 18047 /* 170 */
wolfSSL 16:8e0d178b1d1e 18048 { { 0x79ec1a0f,0x2d8daefd,0xceb39c97,0x3bbcd6fd,0x58f61a95,0xf5575ffc,
wolfSSL 16:8e0d178b1d1e 18049 0xadf7b420,0xdbd986c4 },
wolfSSL 16:8e0d178b1d1e 18050 { 0x15f39eb7,0x81aa8814,0xb98d976c,0x6ee2fcf5,0xcf2f717d,0x5465475d,
wolfSSL 16:8e0d178b1d1e 18051 0x6860bbd0,0x8e24d3c4 } },
wolfSSL 16:8e0d178b1d1e 18052 /* 171 */
wolfSSL 16:8e0d178b1d1e 18053 { { 0x9a587390,0x749d8e54,0x0cbec588,0x12bb194f,0xb25983c6,0x46e07da4,
wolfSSL 16:8e0d178b1d1e 18054 0x407bafc8,0x541a99c4 },
wolfSSL 16:8e0d178b1d1e 18055 { 0x624c8842,0xdb241692,0xd86c05ff,0x6044c12a,0x4f7fcf62,0xc59d14b4,
wolfSSL 16:8e0d178b1d1e 18056 0xf57d35d1,0xc0092c49 } },
wolfSSL 16:8e0d178b1d1e 18057 /* 172 */
wolfSSL 16:8e0d178b1d1e 18058 { { 0xdf2e61ef,0xd3cc75c3,0x2e1b35ca,0x7e8841c8,0x909f29f4,0xc62d30d1,
wolfSSL 16:8e0d178b1d1e 18059 0x7286944d,0x75e40634 },
wolfSSL 16:8e0d178b1d1e 18060 { 0xbbc237d0,0xe7d41fc5,0xec4f01c9,0xc9537bf0,0x282bd534,0x91c51a16,
wolfSSL 16:8e0d178b1d1e 18061 0xc7848586,0x5b7cb658 } },
wolfSSL 16:8e0d178b1d1e 18062 /* 173 */
wolfSSL 16:8e0d178b1d1e 18063 { { 0x8a28ead1,0x964a7084,0xfd3b47f6,0x802dc508,0x767e5b39,0x9ae4bfd1,
wolfSSL 16:8e0d178b1d1e 18064 0x8df097a1,0x7ae13eba },
wolfSSL 16:8e0d178b1d1e 18065 { 0xeadd384e,0xfd216ef8,0xb6b2ff06,0x0361a2d9,0x4bcdb5f3,0x204b9878,
wolfSSL 16:8e0d178b1d1e 18066 0xe2a8e3fd,0x787d8074 } },
wolfSSL 16:8e0d178b1d1e 18067 /* 174 */
wolfSSL 16:8e0d178b1d1e 18068 { { 0x757fbb1c,0xc5e25d6b,0xca201deb,0xe47bddb2,0x6d2233ff,0x4a55e9a3,
wolfSSL 16:8e0d178b1d1e 18069 0x9ef28484,0x5c222819 },
wolfSSL 16:8e0d178b1d1e 18070 { 0x88315250,0x773d4a85,0x827097c1,0x21b21a2b,0xdef5d33f,0xab7c4ea1,
wolfSSL 16:8e0d178b1d1e 18071 0xbaf0f2b0,0xe45d37ab } },
wolfSSL 16:8e0d178b1d1e 18072 /* 175 */
wolfSSL 16:8e0d178b1d1e 18073 { { 0x28511c8a,0xd2df1e34,0xbdca6cd3,0xebb229c8,0x627c39a7,0x578a71a7,
wolfSSL 16:8e0d178b1d1e 18074 0x84dfb9d3,0xed7bc122 },
wolfSSL 16:8e0d178b1d1e 18075 { 0x93dea561,0xcf22a6df,0xd48f0ed1,0x5443f18d,0x5bad23e8,0xd8b86140,
wolfSSL 16:8e0d178b1d1e 18076 0x45ca6d27,0xaac97cc9 } },
wolfSSL 16:8e0d178b1d1e 18077 /* 176 */
wolfSSL 16:8e0d178b1d1e 18078 { { 0xa16bd00a,0xeb54ea74,0xf5c0bcc1,0xd839e9ad,0x1f9bfc06,0x092bb7f1,
wolfSSL 16:8e0d178b1d1e 18079 0x1163dc4e,0x318f97b3 },
wolfSSL 16:8e0d178b1d1e 18080 { 0xc30d7138,0xecc0c5be,0xabc30220,0x44e8df23,0xb0223606,0x2bb7972f,
wolfSSL 16:8e0d178b1d1e 18081 0x9a84ff4d,0xfa41faa1 } },
wolfSSL 16:8e0d178b1d1e 18082 /* 177 */
wolfSSL 16:8e0d178b1d1e 18083 { { 0xa6642269,0x4402d974,0x9bb783bd,0xc81814ce,0x7941e60b,0x398d38e4,
wolfSSL 16:8e0d178b1d1e 18084 0x1d26e9e2,0x38bb6b2c },
wolfSSL 16:8e0d178b1d1e 18085 { 0x6a577f87,0xc64e4a25,0xdc11fe1c,0x8b52d253,0x62280728,0xff336abf,
wolfSSL 16:8e0d178b1d1e 18086 0xce7601a5,0x94dd0905 } },
wolfSSL 16:8e0d178b1d1e 18087 /* 178 */
wolfSSL 16:8e0d178b1d1e 18088 { { 0xde93f92a,0x156cf7dc,0x89b5f315,0xa01333cb,0xc995e750,0x02404df9,
wolfSSL 16:8e0d178b1d1e 18089 0xd25c2ae9,0x92077867 },
wolfSSL 16:8e0d178b1d1e 18090 { 0x0bf39d44,0xe2471e01,0x96bb53d7,0x5f2c9020,0x5c9c3d8f,0x4c44b7b3,
wolfSSL 16:8e0d178b1d1e 18091 0xd29beb51,0x81e8428b } },
wolfSSL 16:8e0d178b1d1e 18092 /* 179 */
wolfSSL 16:8e0d178b1d1e 18093 { { 0xc477199f,0x6dd9c2ba,0x6b5ecdd9,0x8cb8eeee,0xee40fd0e,0x8af7db3f,
wolfSSL 16:8e0d178b1d1e 18094 0xdbbfa4b1,0x1b94ab62 },
wolfSSL 16:8e0d178b1d1e 18095 { 0xce47f143,0x44f0d8b3,0x63f46163,0x51e623fc,0xcc599383,0xf18f270f,
wolfSSL 16:8e0d178b1d1e 18096 0x055590ee,0x06a38e28 } },
wolfSSL 16:8e0d178b1d1e 18097 /* 180 */
wolfSSL 16:8e0d178b1d1e 18098 { { 0xb3355b49,0x2e5b0139,0xb4ebf99b,0x20e26560,0xd269f3dc,0xc08ffa6b,
wolfSSL 16:8e0d178b1d1e 18099 0x83d9d4f8,0xa7b36c20 },
wolfSSL 16:8e0d178b1d1e 18100 { 0x1b3e8830,0x64d15c3a,0xa89f9c0b,0xd5fceae1,0xe2d16930,0xcfeee4a2,
wolfSSL 16:8e0d178b1d1e 18101 0xa2822a20,0xbe54c6b4 } },
wolfSSL 16:8e0d178b1d1e 18102 /* 181 */
wolfSSL 16:8e0d178b1d1e 18103 { { 0x8d91167c,0xd6cdb3df,0xe7a6625e,0x517c3f79,0x346ac7f4,0x7105648f,
wolfSSL 16:8e0d178b1d1e 18104 0xeae022bb,0xbf30a5ab },
wolfSSL 16:8e0d178b1d1e 18105 { 0x93828a68,0x8e7785be,0x7f3ef036,0x5161c332,0x592146b2,0xe11b5feb,
wolfSSL 16:8e0d178b1d1e 18106 0x2732d13a,0xd1c820de } },
wolfSSL 16:8e0d178b1d1e 18107 /* 182 */
wolfSSL 16:8e0d178b1d1e 18108 { { 0x9038b363,0x043e1347,0x6b05e519,0x58c11f54,0x6026cad1,0x4fe57abe,
wolfSSL 16:8e0d178b1d1e 18109 0x68a18da3,0xb7d17bed },
wolfSSL 16:8e0d178b1d1e 18110 { 0xe29c2559,0x44ca5891,0x5bfffd84,0x4f7a0376,0x74e46948,0x498de4af,
wolfSSL 16:8e0d178b1d1e 18111 0x6412cc64,0x3997fd5e } },
wolfSSL 16:8e0d178b1d1e 18112 /* 183 */
wolfSSL 16:8e0d178b1d1e 18113 { { 0x8bd61507,0xf2074682,0x34a64d2a,0x29e132d5,0x8a8a15e3,0xffeddfb0,
wolfSSL 16:8e0d178b1d1e 18114 0x3c6c13e8,0x0eeb8929 },
wolfSSL 16:8e0d178b1d1e 18115 { 0xa7e259f8,0xe9b69a3e,0xd13e7e67,0xce1db7e6,0xad1fa685,0x277318f6,
wolfSSL 16:8e0d178b1d1e 18116 0xc922b6ef,0x228916f8 } },
wolfSSL 16:8e0d178b1d1e 18117 /* 184 */
wolfSSL 16:8e0d178b1d1e 18118 { { 0x0a12ab5b,0x959ae25b,0x957bc136,0xcc11171f,0xd16e2b0c,0x8058429e,
wolfSSL 16:8e0d178b1d1e 18119 0x6e93097e,0xec05ad1d },
wolfSSL 16:8e0d178b1d1e 18120 { 0xac3f3708,0x157ba5be,0x30b59d77,0x31baf935,0x118234e5,0x47b55237,
wolfSSL 16:8e0d178b1d1e 18121 0x7ff11b37,0x7d314156 } },
wolfSSL 16:8e0d178b1d1e 18122 /* 185 */
wolfSSL 16:8e0d178b1d1e 18123 { { 0xf6dfefab,0x7bd9c05c,0xdcb37707,0xbe2f2268,0x3a38bb95,0xe53ead97,
wolfSSL 16:8e0d178b1d1e 18124 0x9bc1d7a3,0xe9ce66fc },
wolfSSL 16:8e0d178b1d1e 18125 { 0x6f6a02a1,0x75aa1576,0x60e600ed,0x38c087df,0x68cdc1b9,0xf8947f34,
wolfSSL 16:8e0d178b1d1e 18126 0x72280651,0xd9650b01 } },
wolfSSL 16:8e0d178b1d1e 18127 /* 186 */
wolfSSL 16:8e0d178b1d1e 18128 { { 0x5a057e60,0x504b4c4a,0x8def25e4,0xcbccc3be,0x17c1ccbd,0xa6353208,
wolfSSL 16:8e0d178b1d1e 18129 0x804eb7a2,0x14d6699a },
wolfSSL 16:8e0d178b1d1e 18130 { 0xdb1f411a,0x2c8a8415,0xf80d769c,0x09fbaf0b,0x1c2f77ad,0xb4deef90,
wolfSSL 16:8e0d178b1d1e 18131 0x0d43598a,0x6f4c6841 } },
wolfSSL 16:8e0d178b1d1e 18132 /* 187 */
wolfSSL 16:8e0d178b1d1e 18133 { { 0x96c24a96,0x8726df4e,0xfcbd99a3,0x534dbc85,0x8b2ae30a,0x3c466ef2,
wolfSSL 16:8e0d178b1d1e 18134 0x61189abb,0x4c4350fd },
wolfSSL 16:8e0d178b1d1e 18135 { 0xf855b8da,0x2967f716,0x463c38a1,0x41a42394,0xeae93343,0xc37e1413,
wolfSSL 16:8e0d178b1d1e 18136 0x5a3118b5,0xa726d242 } },
wolfSSL 16:8e0d178b1d1e 18137 /* 188 */
wolfSSL 16:8e0d178b1d1e 18138 { { 0x948c1086,0xdae6b3ee,0xcbd3a2e1,0xf1de503d,0x03d022f3,0x3f35ed3f,
wolfSSL 16:8e0d178b1d1e 18139 0xcc6cf392,0x13639e82 },
wolfSSL 16:8e0d178b1d1e 18140 { 0xcdafaa86,0x9ac938fb,0x2654a258,0xf45bc5fb,0x45051329,0x1963b26e,
wolfSSL 16:8e0d178b1d1e 18141 0xc1a335a3,0xca9365e1 } },
wolfSSL 16:8e0d178b1d1e 18142 /* 189 */
wolfSSL 16:8e0d178b1d1e 18143 { { 0x4c3b2d20,0x3615ac75,0x904e241b,0x742a5417,0xcc9d071d,0xb08521c4,
wolfSSL 16:8e0d178b1d1e 18144 0x970b72a5,0x9ce29c34 },
wolfSSL 16:8e0d178b1d1e 18145 { 0x6d3e0ad6,0x8cc81f73,0xf2f8434c,0x8060da9e,0x6ce862d9,0x35ed1d1a,
wolfSSL 16:8e0d178b1d1e 18146 0xab42af98,0x48c4abd7 } },
wolfSSL 16:8e0d178b1d1e 18147 /* 190 */
wolfSSL 16:8e0d178b1d1e 18148 { { 0x40c7485a,0xd221b0cc,0xe5274dbf,0xead455bb,0x9263d2e8,0x493c7698,
wolfSSL 16:8e0d178b1d1e 18149 0xf67b33cb,0x78017c32 },
wolfSSL 16:8e0d178b1d1e 18150 { 0x930cb5ee,0xb9d35769,0x0c408ed2,0xc0d14e94,0x272f1a4d,0xf8b7bf55,
wolfSSL 16:8e0d178b1d1e 18151 0xde5c1c04,0x53cd0454 } },
wolfSSL 16:8e0d178b1d1e 18152 /* 191 */
wolfSSL 16:8e0d178b1d1e 18153 { { 0x5d28ccac,0xbcd585fa,0x005b746e,0x5f823e56,0xcd0123aa,0x7c79f0a1,
wolfSSL 16:8e0d178b1d1e 18154 0xd3d7fa8f,0xeea465c1 },
wolfSSL 16:8e0d178b1d1e 18155 { 0x0551803b,0x7810659f,0x7ce6af70,0x6c0b599f,0x29288e70,0x4195a770,
wolfSSL 16:8e0d178b1d1e 18156 0x7ae69193,0x1b6e42a4 } },
wolfSSL 16:8e0d178b1d1e 18157 /* 192 */
wolfSSL 16:8e0d178b1d1e 18158 { { 0xf67d04c3,0x2e80937c,0x89eeb811,0x1e312be2,0x92594d60,0x56b5d887,
wolfSSL 16:8e0d178b1d1e 18159 0x187fbd3d,0x0224da14 },
wolfSSL 16:8e0d178b1d1e 18160 { 0x0c5fe36f,0x87abb863,0x4ef51f5f,0x580f3c60,0xb3b429ec,0x964fb1bf,
wolfSSL 16:8e0d178b1d1e 18161 0x42bfff33,0x60838ef0 } },
wolfSSL 16:8e0d178b1d1e 18162 /* 193 */
wolfSSL 16:8e0d178b1d1e 18163 { { 0x7e0bbe99,0x432cb2f2,0x04aa39ee,0x7bda44f3,0x9fa93903,0x5f497c7a,
wolfSSL 16:8e0d178b1d1e 18164 0x2d331643,0x636eb202 },
wolfSSL 16:8e0d178b1d1e 18165 { 0x93ae00aa,0xfcfd0e61,0x31ae6d2f,0x875a00fe,0x9f93901c,0xf43658a2,
wolfSSL 16:8e0d178b1d1e 18166 0x39218bac,0x8844eeb6 } },
wolfSSL 16:8e0d178b1d1e 18167 /* 194 */
wolfSSL 16:8e0d178b1d1e 18168 { { 0x6b3bae58,0x114171d2,0x17e39f3e,0x7db3df71,0x81a8eada,0xcd37bc7f,
wolfSSL 16:8e0d178b1d1e 18169 0x51fb789e,0x27ba83dc },
wolfSSL 16:8e0d178b1d1e 18170 { 0xfbf54de5,0xa7df439f,0xb5fe1a71,0x7277030b,0xdb297a48,0x42ee8e35,
wolfSSL 16:8e0d178b1d1e 18171 0x87f3a4ab,0xadb62d34 } },
wolfSSL 16:8e0d178b1d1e 18172 /* 195 */
wolfSSL 16:8e0d178b1d1e 18173 { { 0xa175df2a,0x9b1168a2,0x618c32e9,0x082aa04f,0x146b0916,0xc9e4f2e7,
wolfSSL 16:8e0d178b1d1e 18174 0x75e7c8b2,0xb990fd76 },
wolfSSL 16:8e0d178b1d1e 18175 { 0x4df37313,0x0829d96b,0xd0b40789,0x1c205579,0x78087711,0x66c9ae4a,
wolfSSL 16:8e0d178b1d1e 18176 0x4d10d18d,0x81707ef9 } },
wolfSSL 16:8e0d178b1d1e 18177 /* 196 */
wolfSSL 16:8e0d178b1d1e 18178 { { 0x03d6ff96,0x97d7cab2,0x0d843360,0x5b851bfc,0xd042db4b,0x268823c4,
wolfSSL 16:8e0d178b1d1e 18179 0xd5a8aa5c,0x3792daea },
wolfSSL 16:8e0d178b1d1e 18180 { 0x941afa0b,0x52818865,0x42d83671,0xf3e9e741,0x5be4e0a7,0x17c82527,
wolfSSL 16:8e0d178b1d1e 18181 0x94b001ba,0x5abd635e } },
wolfSSL 16:8e0d178b1d1e 18182 /* 197 */
wolfSSL 16:8e0d178b1d1e 18183 { { 0x0ac4927c,0x727fa84e,0xa7c8cf23,0xe3886035,0x4adca0df,0xa4bcd5ea,
wolfSSL 16:8e0d178b1d1e 18184 0x846ab610,0x5995bf21 },
wolfSSL 16:8e0d178b1d1e 18185 { 0x829dfa33,0xe90f860b,0x958fc18b,0xcaafe2ae,0x78630366,0x9b3baf44,
wolfSSL 16:8e0d178b1d1e 18186 0xd483411e,0x44c32ca2 } },
wolfSSL 16:8e0d178b1d1e 18187 /* 198 */
wolfSSL 16:8e0d178b1d1e 18188 { { 0xe40ed80c,0xa74a97f1,0x31d2ca82,0x5f938cb1,0x7c2d6ad9,0x53f2124b,
wolfSSL 16:8e0d178b1d1e 18189 0x8082a54c,0x1f2162fb },
wolfSSL 16:8e0d178b1d1e 18190 { 0x720b173e,0x7e467cc5,0x085f12f9,0x40e8a666,0x4c9d65dc,0x8cebc20e,
wolfSSL 16:8e0d178b1d1e 18191 0xc3e907c9,0x8f1d402b } },
wolfSSL 16:8e0d178b1d1e 18192 /* 199 */
wolfSSL 16:8e0d178b1d1e 18193 { { 0xfbc4058a,0x4f592f9c,0x292f5670,0xb15e14b6,0xbc1d8c57,0xc55cfe37,
wolfSSL 16:8e0d178b1d1e 18194 0x926edbf9,0xb1980f43 },
wolfSSL 16:8e0d178b1d1e 18195 { 0x32c76b09,0x98c33e09,0x33b07f78,0x1df5279d,0x863bb461,0x6f08ead4,
wolfSSL 16:8e0d178b1d1e 18196 0x37448e45,0x2828ad9b } },
wolfSSL 16:8e0d178b1d1e 18197 /* 200 */
wolfSSL 16:8e0d178b1d1e 18198 { { 0xc4cf4ac5,0x696722c4,0xdde64afb,0xf5ac1a3f,0xe0890832,0x0551baa2,
wolfSSL 16:8e0d178b1d1e 18199 0x5a14b390,0x4973f127 },
wolfSSL 16:8e0d178b1d1e 18200 { 0x322eac5d,0xe59d8335,0x0bd9b568,0x5e07eef5,0xa2588393,0xab36720f,
wolfSSL 16:8e0d178b1d1e 18201 0xdb168ac7,0x6dac8ed0 } },
wolfSSL 16:8e0d178b1d1e 18202 /* 201 */
wolfSSL 16:8e0d178b1d1e 18203 { { 0xeda835ef,0xf7b545ae,0x1d10ed51,0x4aa113d2,0x13741b09,0x035a65e0,
wolfSSL 16:8e0d178b1d1e 18204 0x20b9de4c,0x4b23ef59 },
wolfSSL 16:8e0d178b1d1e 18205 { 0x3c4c7341,0xe82bb680,0x3f58bc37,0xd457706d,0xa51e3ee8,0x73527863,
wolfSSL 16:8e0d178b1d1e 18206 0xddf49a4e,0x4dd71534 } },
wolfSSL 16:8e0d178b1d1e 18207 /* 202 */
wolfSSL 16:8e0d178b1d1e 18208 { { 0x95476cd9,0xbf944672,0xe31a725b,0x648d072f,0xfc4b67e0,0x1441c8b8,
wolfSSL 16:8e0d178b1d1e 18209 0x2f4a4dbb,0xfd317000 },
wolfSSL 16:8e0d178b1d1e 18210 { 0x8995d0e1,0x1cb43ff4,0x0ef729aa,0x76e695d1,0x41798982,0xe0d5f976,
wolfSSL 16:8e0d178b1d1e 18211 0x9569f365,0x14fac58c } },
wolfSSL 16:8e0d178b1d1e 18212 /* 203 */
wolfSSL 16:8e0d178b1d1e 18213 { { 0xf312ae18,0xad9a0065,0xfcc93fc9,0x51958dc0,0x8a7d2846,0xd9a14240,
wolfSSL 16:8e0d178b1d1e 18214 0x36abda50,0xed7c7651 },
wolfSSL 16:8e0d178b1d1e 18215 { 0x25d4abbc,0x46270f1a,0xf1a113ea,0x9b5dd8f3,0x5b51952f,0xc609b075,
wolfSSL 16:8e0d178b1d1e 18216 0x4d2e9f53,0xfefcb7f7 } },
wolfSSL 16:8e0d178b1d1e 18217 /* 204 */
wolfSSL 16:8e0d178b1d1e 18218 { { 0xba119185,0xbd09497a,0xaac45ba4,0xd54e8c30,0xaa521179,0x492479de,
wolfSSL 16:8e0d178b1d1e 18219 0x87e0d80b,0x1801a57e },
wolfSSL 16:8e0d178b1d1e 18220 { 0xfcafffb0,0x073d3f8d,0xae255240,0x6cf33c0b,0x5b5fdfbc,0x781d763b,
wolfSSL 16:8e0d178b1d1e 18221 0x1ead1064,0x9f8fc11e } },
wolfSSL 16:8e0d178b1d1e 18222 /* 205 */
wolfSSL 16:8e0d178b1d1e 18223 { { 0x5e69544c,0x1583a171,0xf04b7813,0x0eaf8567,0x278a4c32,0x1e22a8fd,
wolfSSL 16:8e0d178b1d1e 18224 0x3d3a69a9,0xa9d3809d },
wolfSSL 16:8e0d178b1d1e 18225 { 0x59a2da3b,0x936c2c2c,0x1895c847,0x38ccbcf6,0x63d50869,0x5e65244e,
wolfSSL 16:8e0d178b1d1e 18226 0xe1178ef7,0x3006b9ae } },
wolfSSL 16:8e0d178b1d1e 18227 /* 206 */
wolfSSL 16:8e0d178b1d1e 18228 { { 0xc9eead28,0x0bb1f2b0,0x89f4dfbc,0x7eef635d,0xb2ce8939,0x074757fd,
wolfSSL 16:8e0d178b1d1e 18229 0x45f8f761,0x0ab85fd7 },
wolfSSL 16:8e0d178b1d1e 18230 { 0x3e5b4549,0xecda7c93,0x97922f21,0x4be2bb5c,0xb43b8040,0x261a1274,
wolfSSL 16:8e0d178b1d1e 18231 0x11e942c2,0xb122d675 } },
wolfSSL 16:8e0d178b1d1e 18232 /* 207 */
wolfSSL 16:8e0d178b1d1e 18233 { { 0x66a5ae7a,0x3be607be,0x76adcbe3,0x01e703fa,0x4eb6e5c5,0xaf904301,
wolfSSL 16:8e0d178b1d1e 18234 0x097dbaec,0x9f599dc1 },
wolfSSL 16:8e0d178b1d1e 18235 { 0x0ff250ed,0x6d75b718,0x349a20dc,0x8eb91574,0x10b227a3,0x425605a4,
wolfSSL 16:8e0d178b1d1e 18236 0x8a294b78,0x7d5528e0 } },
wolfSSL 16:8e0d178b1d1e 18237 /* 208 */
wolfSSL 16:8e0d178b1d1e 18238 { { 0x20c26def,0xf0f58f66,0x582b2d1e,0x025585ea,0x01ce3881,0xfbe7d79b,
wolfSSL 16:8e0d178b1d1e 18239 0x303f1730,0x28ccea01 },
wolfSSL 16:8e0d178b1d1e 18240 { 0x79644ba5,0xd1dabcd1,0x06fff0b8,0x1fc643e8,0x66b3e17b,0xa60a76fc,
wolfSSL 16:8e0d178b1d1e 18241 0xa1d013bf,0xc18baf48 } },
wolfSSL 16:8e0d178b1d1e 18242 /* 209 */
wolfSSL 16:8e0d178b1d1e 18243 { { 0x5dc4216d,0x34e638c8,0x206142ac,0x00c01067,0x95f5064a,0xd453a171,
wolfSSL 16:8e0d178b1d1e 18244 0xb7a9596b,0x9def809d },
wolfSSL 16:8e0d178b1d1e 18245 { 0x67ab8d2c,0x41e8642e,0x6237a2b6,0xb4240433,0x64c4218b,0x7d506a6d,
wolfSSL 16:8e0d178b1d1e 18246 0x68808ce5,0x0357f8b0 } },
wolfSSL 16:8e0d178b1d1e 18247 /* 210 */
wolfSSL 16:8e0d178b1d1e 18248 { { 0x4cd2cc88,0x8e9dbe64,0xf0b8f39d,0xcc61c28d,0xcd30a0c8,0x4a309874,
wolfSSL 16:8e0d178b1d1e 18249 0x1b489887,0xe4a01add },
wolfSSL 16:8e0d178b1d1e 18250 { 0xf57cd8f9,0x2ed1eeac,0xbd594c48,0x1b767d3e,0x7bd2f787,0xa7295c71,
wolfSSL 16:8e0d178b1d1e 18251 0xce10cc30,0x466d7d79 } },
wolfSSL 16:8e0d178b1d1e 18252 /* 211 */
wolfSSL 16:8e0d178b1d1e 18253 { { 0x9dada2c7,0x47d31892,0x8f9aa27d,0x4fa0a6c3,0x820a59e1,0x90e4fd28,
wolfSSL 16:8e0d178b1d1e 18254 0x451ead1a,0xc672a522 },
wolfSSL 16:8e0d178b1d1e 18255 { 0x5d86b655,0x30607cc8,0xf9ad4af1,0xf0235d3b,0x571172a6,0x99a08680,
wolfSSL 16:8e0d178b1d1e 18256 0xf2a67513,0x5e3d64fa } },
wolfSSL 16:8e0d178b1d1e 18257 /* 212 */
wolfSSL 16:8e0d178b1d1e 18258 { { 0x9b3b4416,0xaa6410c7,0xeab26d99,0xcd8fcf85,0xdb656a74,0x5ebff74a,
wolfSSL 16:8e0d178b1d1e 18259 0xeb8e42fc,0x6c8a7a95 },
wolfSSL 16:8e0d178b1d1e 18260 { 0xb02a63bd,0x10c60ba7,0x8b8f0047,0x6b2f2303,0x312d90b0,0x8c6c3738,
wolfSSL 16:8e0d178b1d1e 18261 0xad82ca91,0x348ae422 } },
wolfSSL 16:8e0d178b1d1e 18262 /* 213 */
wolfSSL 16:8e0d178b1d1e 18263 { { 0x5ccda2fb,0x7f474663,0x8e0726d2,0x22accaa1,0x492b1f20,0x85adf782,
wolfSSL 16:8e0d178b1d1e 18264 0xd9ef2d2e,0xc1074de0 },
wolfSSL 16:8e0d178b1d1e 18265 { 0xae9a65b3,0xfcf3ce44,0x05d7151b,0xfd71e4ac,0xce6a9788,0xd4711f50,
wolfSSL 16:8e0d178b1d1e 18266 0xc9e54ffc,0xfbadfbdb } },
wolfSSL 16:8e0d178b1d1e 18267 /* 214 */
wolfSSL 16:8e0d178b1d1e 18268 { { 0x20a99363,0x1713f1cd,0x6cf22775,0xb915658f,0x24d359b2,0x968175cd,
wolfSSL 16:8e0d178b1d1e 18269 0x83716fcd,0xb7f976b4 },
wolfSSL 16:8e0d178b1d1e 18270 { 0x5d6dbf74,0x5758e24d,0x71c3af36,0x8d23bafd,0x0243dfe3,0x48f47760,
wolfSSL 16:8e0d178b1d1e 18271 0xcafcc805,0xf4d41b2e } },
wolfSSL 16:8e0d178b1d1e 18272 /* 215 */
wolfSSL 16:8e0d178b1d1e 18273 { { 0xfdabd48d,0x51f1cf28,0x32c078a4,0xce81be36,0x117146e9,0x6ace2974,
wolfSSL 16:8e0d178b1d1e 18274 0xe0160f10,0x180824ea },
wolfSSL 16:8e0d178b1d1e 18275 { 0x66e58358,0x0387698b,0xce6ca358,0x63568752,0x5e41e6c5,0x82380e34,
wolfSSL 16:8e0d178b1d1e 18276 0x83cf6d25,0x67e5f639 } },
wolfSSL 16:8e0d178b1d1e 18277 /* 216 */
wolfSSL 16:8e0d178b1d1e 18278 { { 0xcf4899ef,0xf89ccb8d,0x9ebb44c0,0x949015f0,0xb2598ec9,0x546f9276,
wolfSSL 16:8e0d178b1d1e 18279 0x04c11fc6,0x9fef789a },
wolfSSL 16:8e0d178b1d1e 18280 { 0x53d2a071,0x6d367ecf,0xa4519b09,0xb10e1a7f,0x611e2eef,0xca6b3fb0,
wolfSSL 16:8e0d178b1d1e 18281 0xa99c4e20,0xbc80c181 } },
wolfSSL 16:8e0d178b1d1e 18282 /* 217 */
wolfSSL 16:8e0d178b1d1e 18283 { { 0xe5eb82e6,0x972536f8,0xf56cb920,0x1a484fc7,0x50b5da5e,0xc78e2171,
wolfSSL 16:8e0d178b1d1e 18284 0x9f8cdf10,0x49270e62 },
wolfSSL 16:8e0d178b1d1e 18285 { 0xea6b50ad,0x1a39b7bb,0xa2388ffc,0x9a0284c1,0x8107197b,0x5403eb17,
wolfSSL 16:8e0d178b1d1e 18286 0x61372f7f,0xd2ee52f9 } },
wolfSSL 16:8e0d178b1d1e 18287 /* 218 */
wolfSSL 16:8e0d178b1d1e 18288 { { 0x88e0362a,0xd37cd285,0x8fa5d94d,0x442fa8a7,0xa434a526,0xaff836e5,
wolfSSL 16:8e0d178b1d1e 18289 0xe5abb733,0xdfb478be },
wolfSSL 16:8e0d178b1d1e 18290 { 0x673eede6,0xa91f1ce7,0x2b5b2f04,0xa5390ad4,0x5530da2f,0x5e66f7bf,
wolfSSL 16:8e0d178b1d1e 18291 0x08df473a,0xd9a140b4 } },
wolfSSL 16:8e0d178b1d1e 18292 /* 219 */
wolfSSL 16:8e0d178b1d1e 18293 { { 0x6e8ea498,0x0e0221b5,0x3563ee09,0x62347829,0x335d2ade,0xe06b8391,
wolfSSL 16:8e0d178b1d1e 18294 0x623f4b1a,0x760c058d },
wolfSSL 16:8e0d178b1d1e 18295 { 0xc198aa79,0x0b89b58c,0xf07aba7f,0xf74890d2,0xfde2556a,0x4e204110,
wolfSSL 16:8e0d178b1d1e 18296 0x8f190409,0x7141982d } },
wolfSSL 16:8e0d178b1d1e 18297 /* 220 */
wolfSSL 16:8e0d178b1d1e 18298 { { 0x4d4b0f45,0x6f0a0e33,0x392a94e1,0xd9280b38,0xb3c61d5e,0x3af324c6,
wolfSSL 16:8e0d178b1d1e 18299 0x89d54e47,0x3af9d1ce },
wolfSSL 16:8e0d178b1d1e 18300 { 0x20930371,0xfd8f7981,0x21c17097,0xeda2664c,0xdc42309b,0x0e9545dc,
wolfSSL 16:8e0d178b1d1e 18301 0x73957dd6,0xb1f815c3 } },
wolfSSL 16:8e0d178b1d1e 18302 /* 221 */
wolfSSL 16:8e0d178b1d1e 18303 { { 0x89fec44a,0x84faa78e,0x3caa4caf,0xc8c2ae47,0xc1b6a624,0x691c807d,
wolfSSL 16:8e0d178b1d1e 18304 0x1543f052,0xa41aed14 },
wolfSSL 16:8e0d178b1d1e 18305 { 0x7d5ffe04,0x42435399,0x625b6e20,0x8bacb2df,0x87817775,0x85d660be,
wolfSSL 16:8e0d178b1d1e 18306 0x86fb60ef,0xd6e9c1dd } },
wolfSSL 16:8e0d178b1d1e 18307 /* 222 */
wolfSSL 16:8e0d178b1d1e 18308 { { 0xc6853264,0x3aa2e97e,0xe2304a0b,0x771533b7,0xb8eae9be,0x1b912bb7,
wolfSSL 16:8e0d178b1d1e 18309 0xae9bf8c2,0x9c9c6e10 },
wolfSSL 16:8e0d178b1d1e 18310 { 0xe030b74c,0xa2309a59,0x6a631e90,0x4ed7494d,0xa49b79f2,0x89f44b23,
wolfSSL 16:8e0d178b1d1e 18311 0x40fa61b6,0x566bd596 } },
wolfSSL 16:8e0d178b1d1e 18312 /* 223 */
wolfSSL 16:8e0d178b1d1e 18313 { { 0xc18061f3,0x066c0118,0x7c83fc70,0x190b25d3,0x27273245,0xf05fc8e0,
wolfSSL 16:8e0d178b1d1e 18314 0xf525345e,0xcf2c7390 },
wolfSSL 16:8e0d178b1d1e 18315 { 0x10eb30cf,0xa09bceb4,0x0d77703a,0xcfd2ebba,0x150ff255,0xe842c43a,
wolfSSL 16:8e0d178b1d1e 18316 0x8aa20979,0x02f51755 } },
wolfSSL 16:8e0d178b1d1e 18317 /* 224 */
wolfSSL 16:8e0d178b1d1e 18318 { { 0xaddb7d07,0x396ef794,0x24455500,0x0b4fc742,0xc78aa3ce,0xfaff8eac,
wolfSSL 16:8e0d178b1d1e 18319 0xe8d4d97d,0x14e9ada5 },
wolfSSL 16:8e0d178b1d1e 18320 { 0x2f7079e2,0xdaa480a1,0xe4b0800e,0x45baa3cd,0x7838157d,0x01765e2d,
wolfSSL 16:8e0d178b1d1e 18321 0x8e9d9ae8,0xa0ad4fab } },
wolfSSL 16:8e0d178b1d1e 18322 /* 225 */
wolfSSL 16:8e0d178b1d1e 18323 { { 0x4a653618,0x0bfb7621,0x31eaaa5f,0x1872813c,0x44949d5e,0x1553e737,
wolfSSL 16:8e0d178b1d1e 18324 0x6e56ed1e,0xbcd530b8 },
wolfSSL 16:8e0d178b1d1e 18325 { 0x32e9c47b,0x169be853,0xb50059ab,0xdc2776fe,0x192bfbb4,0xcdba9761,
wolfSSL 16:8e0d178b1d1e 18326 0x6979341d,0x909283cf } },
wolfSSL 16:8e0d178b1d1e 18327 /* 226 */
wolfSSL 16:8e0d178b1d1e 18328 { { 0x76e81a13,0x67b00324,0x62171239,0x9bee1a99,0xd32e19d6,0x08ed361b,
wolfSSL 16:8e0d178b1d1e 18329 0xace1549a,0x35eeb7c9 },
wolfSSL 16:8e0d178b1d1e 18330 { 0x7e4e5bdc,0x1280ae5a,0xb6ceec6e,0x2dcd2cd3,0x6e266bc1,0x52e4224c,
wolfSSL 16:8e0d178b1d1e 18331 0x448ae864,0x9a8b2cf4 } },
wolfSSL 16:8e0d178b1d1e 18332 /* 227 */
wolfSSL 16:8e0d178b1d1e 18333 { { 0x09d03b59,0xf6471bf2,0xb65af2ab,0xc90e62a3,0xebd5eec9,0xff7ff168,
wolfSSL 16:8e0d178b1d1e 18334 0xd4491379,0x6bdb60f4 },
wolfSSL 16:8e0d178b1d1e 18335 { 0x8a55bc30,0xdadafebc,0x10097fe0,0xc79ead16,0x4c1e3bdd,0x42e19741,
wolfSSL 16:8e0d178b1d1e 18336 0x94ba08a9,0x01ec3cfd } },
wolfSSL 16:8e0d178b1d1e 18337 /* 228 */
wolfSSL 16:8e0d178b1d1e 18338 { { 0xdc9485c2,0xba6277eb,0x22fb10c7,0x48cc9a79,0x70a28d8a,0x4f61d60f,
wolfSSL 16:8e0d178b1d1e 18339 0x475464f6,0xd1acb1c0 },
wolfSSL 16:8e0d178b1d1e 18340 { 0x26f36612,0xd26902b1,0xe0618d8b,0x59c3a44e,0x308357ee,0x4df8a813,
wolfSSL 16:8e0d178b1d1e 18341 0x405626c2,0x7dcd079d } },
wolfSSL 16:8e0d178b1d1e 18342 /* 229 */
wolfSSL 16:8e0d178b1d1e 18343 { { 0xf05a4b48,0x5ce7d4d3,0x37230772,0xadcd2952,0x812a915a,0xd18f7971,
wolfSSL 16:8e0d178b1d1e 18344 0x377d19b8,0x0bf53589 },
wolfSSL 16:8e0d178b1d1e 18345 { 0x6c68ea73,0x35ecd95a,0x823a584d,0xc7f3bbca,0xf473a723,0x9fb674c6,
wolfSSL 16:8e0d178b1d1e 18346 0xe16686fc,0xd28be4d9 } },
wolfSSL 16:8e0d178b1d1e 18347 /* 230 */
wolfSSL 16:8e0d178b1d1e 18348 { { 0x38fa8e4b,0x5d2b9906,0x893fd8fc,0x559f186e,0x436fb6fc,0x3a6de2aa,
wolfSSL 16:8e0d178b1d1e 18349 0x510f88ce,0xd76007aa },
wolfSSL 16:8e0d178b1d1e 18350 { 0x523a4988,0x2d10aab6,0x74dd0273,0xb455cf44,0xa3407278,0x7f467082,
wolfSSL 16:8e0d178b1d1e 18351 0xb303bb01,0xf2b52f68 } },
wolfSSL 16:8e0d178b1d1e 18352 /* 231 */
wolfSSL 16:8e0d178b1d1e 18353 { { 0x9835b4ca,0x0d57eafa,0xbb669cbc,0x2d2232fc,0xc6643198,0x8eeeb680,
wolfSSL 16:8e0d178b1d1e 18354 0xcc5aed3a,0xd8dbe98e },
wolfSSL 16:8e0d178b1d1e 18355 { 0xc5a02709,0xcba9be3f,0xf5ba1fa8,0x30be68e5,0xf10ea852,0xfebd43cd,
wolfSSL 16:8e0d178b1d1e 18356 0xee559705,0xe01593a3 } },
wolfSSL 16:8e0d178b1d1e 18357 /* 232 */
wolfSSL 16:8e0d178b1d1e 18358 { { 0xea75a0a6,0xd3e5af50,0x57858033,0x512226ac,0xd0176406,0x6fe6d50f,
wolfSSL 16:8e0d178b1d1e 18359 0xaeb8ef06,0xafec07b1 },
wolfSSL 16:8e0d178b1d1e 18360 { 0x80bb0a31,0x7fb99567,0x37309aae,0x6f1af3cc,0x01abf389,0x9153a15a,
wolfSSL 16:8e0d178b1d1e 18361 0x6e2dbfdd,0xa71b9354 } },
wolfSSL 16:8e0d178b1d1e 18362 /* 233 */
wolfSSL 16:8e0d178b1d1e 18363 { { 0x18f593d2,0xbf8e12e0,0xa078122b,0xd1a90428,0x0ba4f2ad,0x150505db,
wolfSSL 16:8e0d178b1d1e 18364 0x628523d9,0x53a2005c },
wolfSSL 16:8e0d178b1d1e 18365 { 0xe7f2b935,0x07c8b639,0xc182961a,0x2bff975a,0x7518ca2c,0x86bceea7,
wolfSSL 16:8e0d178b1d1e 18366 0x3d588e3d,0xbf47d19b } },
wolfSSL 16:8e0d178b1d1e 18367 /* 234 */
wolfSSL 16:8e0d178b1d1e 18368 { { 0xdd7665d5,0x672967a7,0x2f2f4de5,0x4e303057,0x80d4903f,0x144005ae,
wolfSSL 16:8e0d178b1d1e 18369 0x39c9a1b6,0x001c2c7f },
wolfSSL 16:8e0d178b1d1e 18370 { 0x69efc6d6,0x143a8014,0x7bc7a724,0xc810bdaa,0xa78150a4,0x5f65670b,
wolfSSL 16:8e0d178b1d1e 18371 0x86ffb99b,0xfdadf8e7 } },
wolfSSL 16:8e0d178b1d1e 18372 /* 235 */
wolfSSL 16:8e0d178b1d1e 18373 { { 0xffc00785,0xfd38cb88,0x3b48eb67,0x77fa7591,0xbf368fbc,0x0454d055,
wolfSSL 16:8e0d178b1d1e 18374 0x5aa43c94,0x3a838e4d },
wolfSSL 16:8e0d178b1d1e 18375 { 0x3e97bb9a,0x56166329,0x441d94d9,0x9eb93363,0x0adb2a83,0x515591a6,
wolfSSL 16:8e0d178b1d1e 18376 0x873e1da3,0x3cdb8257 } },
wolfSSL 16:8e0d178b1d1e 18377 /* 236 */
wolfSSL 16:8e0d178b1d1e 18378 { { 0x7de77eab,0x137140a9,0x41648109,0xf7e1c50d,0xceb1d0df,0x762dcad2,
wolfSSL 16:8e0d178b1d1e 18379 0xf1f57fba,0x5a60cc89 },
wolfSSL 16:8e0d178b1d1e 18380 { 0x40d45673,0x80b36382,0x5913c655,0x1b82be19,0xdd64b741,0x057284b8,
wolfSSL 16:8e0d178b1d1e 18381 0xdbfd8fc0,0x922ff56f } },
wolfSSL 16:8e0d178b1d1e 18382 /* 237 */
wolfSSL 16:8e0d178b1d1e 18383 { { 0xc9a129a1,0x1b265dee,0xcc284e04,0xa5b1ce57,0xcebfbe3c,0x04380c46,
wolfSSL 16:8e0d178b1d1e 18384 0xf6c5cd62,0x72919a7d },
wolfSSL 16:8e0d178b1d1e 18385 { 0x8fb90f9a,0x298f453a,0x88e4031b,0xd719c00b,0x796f1856,0xe32c0e77,
wolfSSL 16:8e0d178b1d1e 18386 0x3624089a,0x5e791780 } },
wolfSSL 16:8e0d178b1d1e 18387 /* 238 */
wolfSSL 16:8e0d178b1d1e 18388 { { 0x7f63cdfb,0x5c16ec55,0xf1cae4fd,0x8e6a3571,0x560597ca,0xfce26bea,
wolfSSL 16:8e0d178b1d1e 18389 0xe24c2fab,0x4e0a5371 },
wolfSSL 16:8e0d178b1d1e 18390 { 0xa5765357,0x276a40d3,0x0d73a2b4,0x3c89af44,0x41d11a32,0xb8f370ae,
wolfSSL 16:8e0d178b1d1e 18391 0xd56604ee,0xf5ff7818 } },
wolfSSL 16:8e0d178b1d1e 18392 /* 239 */
wolfSSL 16:8e0d178b1d1e 18393 { { 0x1a09df21,0xfbf3e3fe,0xe66e8e47,0x26d5d28e,0x29c89015,0x2096bd0a,
wolfSSL 16:8e0d178b1d1e 18394 0x533f5e64,0xe41df0e9 },
wolfSSL 16:8e0d178b1d1e 18395 { 0xb3ba9e3f,0x305fda40,0x2604d895,0xf2340ceb,0x7f0367c7,0x0866e192,
wolfSSL 16:8e0d178b1d1e 18396 0xac4f155f,0x8edd7d6e } },
wolfSSL 16:8e0d178b1d1e 18397 /* 240 */
wolfSSL 16:8e0d178b1d1e 18398 { { 0x0bfc8ff3,0xc9a1dc0e,0xe936f42f,0x14efd82b,0xcca381ef,0x67016f7c,
wolfSSL 16:8e0d178b1d1e 18399 0xed8aee96,0x1432c1ca },
wolfSSL 16:8e0d178b1d1e 18400 { 0x70b23c26,0xec684829,0x0735b273,0xa64fe873,0xeaef0f5a,0xe389f6e5,
wolfSSL 16:8e0d178b1d1e 18401 0x5ac8d2c6,0xcaef480b } },
wolfSSL 16:8e0d178b1d1e 18402 /* 241 */
wolfSSL 16:8e0d178b1d1e 18403 { { 0x75315922,0x5245c978,0x3063cca5,0xd8295171,0xb64ef2cb,0xf3ce60d0,
wolfSSL 16:8e0d178b1d1e 18404 0x8efae236,0xd0ba177e },
wolfSSL 16:8e0d178b1d1e 18405 { 0xb1b3af60,0x53a9ae8f,0x3d2da20e,0x1a796ae5,0xdf9eef28,0x01d63605,
wolfSSL 16:8e0d178b1d1e 18406 0x1c54ae16,0xf31c957c } },
wolfSSL 16:8e0d178b1d1e 18407 /* 242 */
wolfSSL 16:8e0d178b1d1e 18408 { { 0x49cc4597,0xc0f58d52,0xbae0a028,0xdc5015b0,0x734a814a,0xefc5fc55,
wolfSSL 16:8e0d178b1d1e 18409 0x96e17c3a,0x013404cb },
wolfSSL 16:8e0d178b1d1e 18410 { 0xc9a824bf,0xb29e2585,0x001eaed7,0xd593185e,0x61ef68ac,0x8d6ee682,
wolfSSL 16:8e0d178b1d1e 18411 0x91933e6c,0x6f377c4b } },
wolfSSL 16:8e0d178b1d1e 18412 /* 243 */
wolfSSL 16:8e0d178b1d1e 18413 { { 0xa8333fd2,0x9f93bad1,0x5a2a95b8,0xa8930202,0xeaf75ace,0x211e5037,
wolfSSL 16:8e0d178b1d1e 18414 0xd2d09506,0x6dba3e4e },
wolfSSL 16:8e0d178b1d1e 18415 { 0xd04399cd,0xa48ef98c,0xe6b73ade,0x1811c66e,0xc17ecaf3,0x72f60752,
wolfSSL 16:8e0d178b1d1e 18416 0x3becf4a7,0xf13cf342 } },
wolfSSL 16:8e0d178b1d1e 18417 /* 244 */
wolfSSL 16:8e0d178b1d1e 18418 { { 0xa919e2eb,0xceeb9ec0,0xf62c0f68,0x83a9a195,0x7aba2299,0xcfba3bb6,
wolfSSL 16:8e0d178b1d1e 18419 0x274bbad3,0xc83fa9a9 },
wolfSSL 16:8e0d178b1d1e 18420 { 0x62fa1ce0,0x0d7d1b0b,0x3418efbf,0xe58b60f5,0x52706f04,0xbfa8ef9e,
wolfSSL 16:8e0d178b1d1e 18421 0x5d702683,0xb49d70f4 } },
wolfSSL 16:8e0d178b1d1e 18422 /* 245 */
wolfSSL 16:8e0d178b1d1e 18423 { { 0xfad5513b,0x914c7510,0xb1751e2d,0x05f32eec,0xd9fb9d59,0x6d850418,
wolfSSL 16:8e0d178b1d1e 18424 0x0c30f1cf,0x59cfadbb },
wolfSSL 16:8e0d178b1d1e 18425 { 0x55cb7fd6,0xe167ac23,0x820426a3,0x249367b8,0x90a78864,0xeaeec58c,
wolfSSL 16:8e0d178b1d1e 18426 0x354a4b67,0x5babf362 } },
wolfSSL 16:8e0d178b1d1e 18427 /* 246 */
wolfSSL 16:8e0d178b1d1e 18428 { { 0xee424865,0x37c981d1,0xf2e5577f,0x8b002878,0xb9e0c058,0x702970f1,
wolfSSL 16:8e0d178b1d1e 18429 0x9026c8f0,0x6188c6a7 },
wolfSSL 16:8e0d178b1d1e 18430 { 0xd0f244da,0x06f9a19b,0xfb080873,0x1ecced5c,0x9f213637,0x35470f9b,
wolfSSL 16:8e0d178b1d1e 18431 0xdf50b9d9,0x993fe475 } },
wolfSSL 16:8e0d178b1d1e 18432 /* 247 */
wolfSSL 16:8e0d178b1d1e 18433 { { 0x9b2c3609,0x68e31cdf,0x2c46d4ea,0x84eb19c0,0x9a775101,0x7ac9ec1a,
wolfSSL 16:8e0d178b1d1e 18434 0x4c80616b,0x81f76466 },
wolfSSL 16:8e0d178b1d1e 18435 { 0x75fbe978,0x1d7c2a5a,0xf183b356,0x6743fed3,0x501dd2bf,0x838d1f04,
wolfSSL 16:8e0d178b1d1e 18436 0x5fe9060d,0x564a812a } },
wolfSSL 16:8e0d178b1d1e 18437 /* 248 */
wolfSSL 16:8e0d178b1d1e 18438 { { 0xfa817d1d,0x7a5a64f4,0xbea82e0f,0x55f96844,0xcd57f9aa,0xb5ff5a0f,
wolfSSL 16:8e0d178b1d1e 18439 0x00e51d6c,0x226bf3cf },
wolfSSL 16:8e0d178b1d1e 18440 { 0x2f2833cf,0xd6d1a9f9,0x4f4f89a8,0x20a0a35a,0x8f3f7f77,0x11536c49,
wolfSSL 16:8e0d178b1d1e 18441 0xff257836,0x68779f47 } },
wolfSSL 16:8e0d178b1d1e 18442 /* 249 */
wolfSSL 16:8e0d178b1d1e 18443 { { 0x73043d08,0x79b0c1c1,0x1fc020fa,0xa5446774,0x9a6d26d0,0xd3767e28,
wolfSSL 16:8e0d178b1d1e 18444 0xeb092e0b,0x97bcb0d1 },
wolfSSL 16:8e0d178b1d1e 18445 { 0xf32ed3c3,0x2ab6eaa8,0xb281bc48,0xc8a4f151,0xbfa178f3,0x4d1bf4f3,
wolfSSL 16:8e0d178b1d1e 18446 0x0a784655,0xa872ffe8 } },
wolfSSL 16:8e0d178b1d1e 18447 /* 250 */
wolfSSL 16:8e0d178b1d1e 18448 { { 0xa32b2086,0xb1ab7935,0x8160f486,0xe1eb710e,0x3b6ae6be,0x9bd0cd91,
wolfSSL 16:8e0d178b1d1e 18449 0xb732a36a,0x02812bfc },
wolfSSL 16:8e0d178b1d1e 18450 { 0xcf605318,0xa63fd7ca,0xfdfd6d1d,0x646e5d50,0x2102d619,0xa1d68398,
wolfSSL 16:8e0d178b1d1e 18451 0xfe5396af,0x07391cc9 } },
wolfSSL 16:8e0d178b1d1e 18452 /* 251 */
wolfSSL 16:8e0d178b1d1e 18453 { { 0x8b80d02b,0xc50157f0,0x62877f7f,0x6b8333d1,0x78d542ae,0x7aca1af8,
wolfSSL 16:8e0d178b1d1e 18454 0x7e6d2a08,0x355d2adc },
wolfSSL 16:8e0d178b1d1e 18455 { 0x287386e1,0xb41f335a,0xf8e43275,0xfd272a94,0xe79989ea,0x286ca2cd,
wolfSSL 16:8e0d178b1d1e 18456 0x7c2a3a79,0x3dc2b1e3 } },
wolfSSL 16:8e0d178b1d1e 18457 /* 252 */
wolfSSL 16:8e0d178b1d1e 18458 { { 0x04581352,0xd689d21c,0x376782be,0x0a00c825,0x9fed701f,0x203bd590,
wolfSSL 16:8e0d178b1d1e 18459 0x3ccd846b,0xc4786910 },
wolfSSL 16:8e0d178b1d1e 18460 { 0x24c768ed,0x5dba7708,0x6841f657,0x72feea02,0x6accce0e,0x73313ed5,
wolfSSL 16:8e0d178b1d1e 18461 0xd5bb4d32,0xccc42968 } },
wolfSSL 16:8e0d178b1d1e 18462 /* 253 */
wolfSSL 16:8e0d178b1d1e 18463 { { 0x3d7620b9,0x94e50de1,0x5992a56a,0xd89a5c8a,0x675487c9,0xdc007640,
wolfSSL 16:8e0d178b1d1e 18464 0xaa4871cf,0xe147eb42 },
wolfSSL 16:8e0d178b1d1e 18465 { 0xacf3ae46,0x274ab4ee,0x50350fbe,0xfd4936fb,0x48c840ea,0xdf2afe47,
wolfSSL 16:8e0d178b1d1e 18466 0x080e96e3,0x239ac047 } },
wolfSSL 16:8e0d178b1d1e 18467 /* 254 */
wolfSSL 16:8e0d178b1d1e 18468 { { 0x2bfee8d4,0x481d1f35,0xfa7b0fec,0xce80b5cf,0x2ce9af3c,0x105c4c9e,
wolfSSL 16:8e0d178b1d1e 18469 0xf5f7e59d,0xc55fa1a3 },
wolfSSL 16:8e0d178b1d1e 18470 { 0x8257c227,0x3186f14e,0x342be00b,0xc5b1653f,0xaa904fb2,0x09afc998,
wolfSSL 16:8e0d178b1d1e 18471 0xd4f4b699,0x094cd99c } },
wolfSSL 16:8e0d178b1d1e 18472 /* 255 */
wolfSSL 16:8e0d178b1d1e 18473 { { 0xd703beba,0x8a981c84,0x32ceb291,0x8631d150,0xe3bd49ec,0xa445f2c9,
wolfSSL 16:8e0d178b1d1e 18474 0x42abad33,0xb90a30b6 },
wolfSSL 16:8e0d178b1d1e 18475 { 0xb4a5abf9,0xb465404f,0x75db7603,0x004750c3,0xca35d89f,0x6f9a42cc,
wolfSSL 16:8e0d178b1d1e 18476 0x1b7924f7,0x019f8b9a } },
wolfSSL 16:8e0d178b1d1e 18477 };
wolfSSL 16:8e0d178b1d1e 18478
wolfSSL 16:8e0d178b1d1e 18479 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 18480 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 18481 *
wolfSSL 16:8e0d178b1d1e 18482 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 18483 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 18484 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 18485 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 18486 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 18487 */
wolfSSL 16:8e0d178b1d1e 18488 static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 18489 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 18490 {
wolfSSL 16:8e0d178b1d1e 18491 return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table,
wolfSSL 16:8e0d178b1d1e 18492 k, map, heap);
wolfSSL 16:8e0d178b1d1e 18493 }
wolfSSL 16:8e0d178b1d1e 18494
wolfSSL 16:8e0d178b1d1e 18495 #endif
wolfSSL 16:8e0d178b1d1e 18496
wolfSSL 16:8e0d178b1d1e 18497 /* Multiply the base point of P256 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 18498 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 18499 *
wolfSSL 16:8e0d178b1d1e 18500 * km Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 18501 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 18502 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 18503 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 18504 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 18505 */
wolfSSL 16:8e0d178b1d1e 18506 int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)
wolfSSL 16:8e0d178b1d1e 18507 {
wolfSSL 16:8e0d178b1d1e 18508 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 18509 sp_point_256 p;
wolfSSL 16:8e0d178b1d1e 18510 sp_digit kd[8];
wolfSSL 16:8e0d178b1d1e 18511 #endif
wolfSSL 16:8e0d178b1d1e 18512 sp_point_256* point;
wolfSSL 16:8e0d178b1d1e 18513 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 18514 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 18515
wolfSSL 16:8e0d178b1d1e 18516 err = sp_256_point_new_8(heap, p, point);
wolfSSL 16:8e0d178b1d1e 18517 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 18518 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18519 k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,
wolfSSL 16:8e0d178b1d1e 18520 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 18521 if (k == NULL) {
wolfSSL 16:8e0d178b1d1e 18522 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 18523 }
wolfSSL 16:8e0d178b1d1e 18524 }
wolfSSL 16:8e0d178b1d1e 18525 #else
wolfSSL 16:8e0d178b1d1e 18526 k = kd;
wolfSSL 16:8e0d178b1d1e 18527 #endif
wolfSSL 16:8e0d178b1d1e 18528 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18529 sp_256_from_mp(k, 8, km);
wolfSSL 16:8e0d178b1d1e 18530
wolfSSL 16:8e0d178b1d1e 18531 err = sp_256_ecc_mulmod_base_8(point, k, map, heap);
wolfSSL 16:8e0d178b1d1e 18532 }
wolfSSL 16:8e0d178b1d1e 18533 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18534 err = sp_256_point_to_ecc_point_8(point, r);
wolfSSL 16:8e0d178b1d1e 18535 }
wolfSSL 16:8e0d178b1d1e 18536
wolfSSL 16:8e0d178b1d1e 18537 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 18538 if (k != NULL) {
wolfSSL 16:8e0d178b1d1e 18539 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 18540 }
wolfSSL 16:8e0d178b1d1e 18541 #endif
wolfSSL 16:8e0d178b1d1e 18542 sp_256_point_free_8(point, 0, heap);
wolfSSL 16:8e0d178b1d1e 18543
wolfSSL 16:8e0d178b1d1e 18544 return err;
wolfSSL 16:8e0d178b1d1e 18545 }
wolfSSL 16:8e0d178b1d1e 18546
wolfSSL 16:8e0d178b1d1e 18547 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
wolfSSL 16:8e0d178b1d1e 18548 defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 18549 /* Returns 1 if the number of zero.
wolfSSL 16:8e0d178b1d1e 18550 * Implementation is constant time.
wolfSSL 16:8e0d178b1d1e 18551 *
wolfSSL 16:8e0d178b1d1e 18552 * a Number to check.
wolfSSL 16:8e0d178b1d1e 18553 * returns 1 if the number is zero and 0 otherwise.
wolfSSL 16:8e0d178b1d1e 18554 */
wolfSSL 16:8e0d178b1d1e 18555 static int sp_256_iszero_8(const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 18556 {
wolfSSL 16:8e0d178b1d1e 18557 return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7]) == 0;
wolfSSL 16:8e0d178b1d1e 18558 }
wolfSSL 16:8e0d178b1d1e 18559
wolfSSL 16:8e0d178b1d1e 18560 #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */
wolfSSL 16:8e0d178b1d1e 18561 /* Add 1 to a. (a = a + 1)
wolfSSL 16:8e0d178b1d1e 18562 *
wolfSSL 16:8e0d178b1d1e 18563 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 18564 */
wolfSSL 16:8e0d178b1d1e 18565 SP_NOINLINE static void sp_256_add_one_8(sp_digit* a)
wolfSSL 16:8e0d178b1d1e 18566 {
wolfSSL 16:8e0d178b1d1e 18567 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 18568 "mov r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 18569 "ldr r1, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 18570 "adds r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 18571 "mov r2, #0\n\t"
wolfSSL 16:8e0d178b1d1e 18572 "str r1, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 18573 "ldr r1, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 18574 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 18575 "str r1, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 18576 "ldr r1, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 18577 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 18578 "str r1, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 18579 "ldr r1, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 18580 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 18581 "str r1, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 18582 "ldr r1, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 18583 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 18584 "str r1, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 18585 "ldr r1, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 18586 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 18587 "str r1, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 18588 "ldr r1, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 18589 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 18590 "str r1, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 18591 "ldr r1, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 18592 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 18593 "str r1, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 18594 :
wolfSSL 16:8e0d178b1d1e 18595 : [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 18596 : "memory", "r1", "r2"
wolfSSL 16:8e0d178b1d1e 18597 );
wolfSSL 16:8e0d178b1d1e 18598 }
wolfSSL 16:8e0d178b1d1e 18599
wolfSSL 16:8e0d178b1d1e 18600 /* Read big endian unsigned byte array into r.
wolfSSL 16:8e0d178b1d1e 18601 *
wolfSSL 16:8e0d178b1d1e 18602 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 18603 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 18604 * a Byte array.
wolfSSL 16:8e0d178b1d1e 18605 * n Number of bytes in array to read.
wolfSSL 16:8e0d178b1d1e 18606 */
wolfSSL 16:8e0d178b1d1e 18607 static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)
wolfSSL 16:8e0d178b1d1e 18608 {
wolfSSL 16:8e0d178b1d1e 18609 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 18610 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 18611
wolfSSL 16:8e0d178b1d1e 18612 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 18613 for (i = n-1; i >= 0; i--) {
wolfSSL 16:8e0d178b1d1e 18614 r[j] |= (((sp_digit)a[i]) << s);
wolfSSL 16:8e0d178b1d1e 18615 if (s >= 24U) {
wolfSSL 16:8e0d178b1d1e 18616 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 18617 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 18618 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 18619 break;
wolfSSL 16:8e0d178b1d1e 18620 }
wolfSSL 16:8e0d178b1d1e 18621 r[++j] = (sp_digit)a[i] >> s;
wolfSSL 16:8e0d178b1d1e 18622 s = 8U - s;
wolfSSL 16:8e0d178b1d1e 18623 }
wolfSSL 16:8e0d178b1d1e 18624 else {
wolfSSL 16:8e0d178b1d1e 18625 s += 8U;
wolfSSL 16:8e0d178b1d1e 18626 }
wolfSSL 16:8e0d178b1d1e 18627 }
wolfSSL 16:8e0d178b1d1e 18628
wolfSSL 16:8e0d178b1d1e 18629 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 18630 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 18631 }
wolfSSL 16:8e0d178b1d1e 18632 }
wolfSSL 16:8e0d178b1d1e 18633
wolfSSL 16:8e0d178b1d1e 18634 /* Generates a scalar that is in the range 1..order-1.
wolfSSL 16:8e0d178b1d1e 18635 *
wolfSSL 16:8e0d178b1d1e 18636 * rng Random number generator.
wolfSSL 16:8e0d178b1d1e 18637 * k Scalar value.
wolfSSL 16:8e0d178b1d1e 18638 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 16:8e0d178b1d1e 18639 * MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 18640 */
wolfSSL 16:8e0d178b1d1e 18641 static int sp_256_ecc_gen_k_8(WC_RNG* rng, sp_digit* k)
wolfSSL 16:8e0d178b1d1e 18642 {
wolfSSL 16:8e0d178b1d1e 18643 int err;
wolfSSL 16:8e0d178b1d1e 18644 byte buf[32];
wolfSSL 16:8e0d178b1d1e 18645
wolfSSL 16:8e0d178b1d1e 18646 do {
wolfSSL 16:8e0d178b1d1e 18647 err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));
wolfSSL 16:8e0d178b1d1e 18648 if (err == 0) {
wolfSSL 16:8e0d178b1d1e 18649 sp_256_from_bin(k, 8, buf, (int)sizeof(buf));
wolfSSL 16:8e0d178b1d1e 18650 if (sp_256_cmp_8(k, p256_order2) < 0) {
wolfSSL 16:8e0d178b1d1e 18651 sp_256_add_one_8(k);
wolfSSL 16:8e0d178b1d1e 18652 break;
wolfSSL 16:8e0d178b1d1e 18653 }
wolfSSL 16:8e0d178b1d1e 18654 }
wolfSSL 16:8e0d178b1d1e 18655 }
wolfSSL 16:8e0d178b1d1e 18656 while (err == 0);
wolfSSL 16:8e0d178b1d1e 18657
wolfSSL 16:8e0d178b1d1e 18658 return err;
wolfSSL 16:8e0d178b1d1e 18659 }
wolfSSL 16:8e0d178b1d1e 18660
wolfSSL 16:8e0d178b1d1e 18661 /* Makes a random EC key pair.
wolfSSL 16:8e0d178b1d1e 18662 *
wolfSSL 16:8e0d178b1d1e 18663 * rng Random number generator.
wolfSSL 16:8e0d178b1d1e 18664 * priv Generated private value.
wolfSSL 16:8e0d178b1d1e 18665 * pub Generated public point.
wolfSSL 16:8e0d178b1d1e 18666 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 18667 * returns ECC_INF_E when the point does not have the correct order, RNG
wolfSSL 16:8e0d178b1d1e 18668 * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 18669 */
wolfSSL 16:8e0d178b1d1e 18670 int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)
wolfSSL 16:8e0d178b1d1e 18671 {
wolfSSL 16:8e0d178b1d1e 18672 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 18673 sp_point_256 p;
wolfSSL 16:8e0d178b1d1e 18674 sp_digit kd[8];
wolfSSL 16:8e0d178b1d1e 18675 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 18676 sp_point_256 inf;
wolfSSL 16:8e0d178b1d1e 18677 #endif
wolfSSL 16:8e0d178b1d1e 18678 #endif
wolfSSL 16:8e0d178b1d1e 18679 sp_point_256* point;
wolfSSL 16:8e0d178b1d1e 18680 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 18681 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 18682 sp_point_256* infinity;
wolfSSL 16:8e0d178b1d1e 18683 #endif
wolfSSL 16:8e0d178b1d1e 18684 int err;
wolfSSL 16:8e0d178b1d1e 18685
wolfSSL 16:8e0d178b1d1e 18686 (void)heap;
wolfSSL 16:8e0d178b1d1e 18687
wolfSSL 16:8e0d178b1d1e 18688 err = sp_256_point_new_8(heap, p, point);
wolfSSL 16:8e0d178b1d1e 18689 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 18690 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18691 err = sp_256_point_new_8(heap, inf, infinity);
wolfSSL 16:8e0d178b1d1e 18692 }
wolfSSL 16:8e0d178b1d1e 18693 #endif
wolfSSL 16:8e0d178b1d1e 18694 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 18695 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18696 k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,
wolfSSL 16:8e0d178b1d1e 18697 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 18698 if (k == NULL) {
wolfSSL 16:8e0d178b1d1e 18699 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 18700 }
wolfSSL 16:8e0d178b1d1e 18701 }
wolfSSL 16:8e0d178b1d1e 18702 #else
wolfSSL 16:8e0d178b1d1e 18703 k = kd;
wolfSSL 16:8e0d178b1d1e 18704 #endif
wolfSSL 16:8e0d178b1d1e 18705
wolfSSL 16:8e0d178b1d1e 18706 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18707 err = sp_256_ecc_gen_k_8(rng, k);
wolfSSL 16:8e0d178b1d1e 18708 }
wolfSSL 16:8e0d178b1d1e 18709 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18710 err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);
wolfSSL 16:8e0d178b1d1e 18711 }
wolfSSL 16:8e0d178b1d1e 18712
wolfSSL 16:8e0d178b1d1e 18713 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 18714 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18715 err = sp_256_ecc_mulmod_8(infinity, point, p256_order, 1, NULL);
wolfSSL 16:8e0d178b1d1e 18716 }
wolfSSL 16:8e0d178b1d1e 18717 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18718 if ((sp_256_iszero_8(point->x) == 0) || (sp_256_iszero_8(point->y) == 0)) {
wolfSSL 16:8e0d178b1d1e 18719 err = ECC_INF_E;
wolfSSL 16:8e0d178b1d1e 18720 }
wolfSSL 16:8e0d178b1d1e 18721 }
wolfSSL 16:8e0d178b1d1e 18722 #endif
wolfSSL 16:8e0d178b1d1e 18723
wolfSSL 16:8e0d178b1d1e 18724 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18725 err = sp_256_to_mp(k, priv);
wolfSSL 16:8e0d178b1d1e 18726 }
wolfSSL 16:8e0d178b1d1e 18727 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18728 err = sp_256_point_to_ecc_point_8(point, pub);
wolfSSL 16:8e0d178b1d1e 18729 }
wolfSSL 16:8e0d178b1d1e 18730
wolfSSL 16:8e0d178b1d1e 18731 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 18732 if (k != NULL) {
wolfSSL 16:8e0d178b1d1e 18733 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 18734 }
wolfSSL 16:8e0d178b1d1e 18735 #endif
wolfSSL 16:8e0d178b1d1e 18736 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 18737 sp_256_point_free_8(infinity, 1, heap);
wolfSSL 16:8e0d178b1d1e 18738 #endif
wolfSSL 16:8e0d178b1d1e 18739 sp_256_point_free_8(point, 1, heap);
wolfSSL 16:8e0d178b1d1e 18740
wolfSSL 16:8e0d178b1d1e 18741 return err;
wolfSSL 16:8e0d178b1d1e 18742 }
wolfSSL 16:8e0d178b1d1e 18743
wolfSSL 16:8e0d178b1d1e 18744 #ifdef HAVE_ECC_DHE
wolfSSL 16:8e0d178b1d1e 18745 /* Write r as big endian to byte array.
wolfSSL 16:8e0d178b1d1e 18746 * Fixed length number of bytes written: 32
wolfSSL 16:8e0d178b1d1e 18747 *
wolfSSL 16:8e0d178b1d1e 18748 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 18749 * a Byte array.
wolfSSL 16:8e0d178b1d1e 18750 */
wolfSSL 16:8e0d178b1d1e 18751 static void sp_256_to_bin(sp_digit* r, byte* a)
wolfSSL 16:8e0d178b1d1e 18752 {
wolfSSL 16:8e0d178b1d1e 18753 int i, j, s = 0, b;
wolfSSL 16:8e0d178b1d1e 18754
wolfSSL 16:8e0d178b1d1e 18755 j = 256 / 8 - 1;
wolfSSL 16:8e0d178b1d1e 18756 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 18757 for (i=0; i<8 && j>=0; i++) {
wolfSSL 16:8e0d178b1d1e 18758 b = 0;
wolfSSL 16:8e0d178b1d1e 18759 /* lint allow cast of mismatch sp_digit and int */
wolfSSL 16:8e0d178b1d1e 18760 a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 18761 b += 8 - s;
wolfSSL 16:8e0d178b1d1e 18762 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 18763 break;
wolfSSL 16:8e0d178b1d1e 18764 }
wolfSSL 16:8e0d178b1d1e 18765 while (b < 32) {
wolfSSL 16:8e0d178b1d1e 18766 a[j--] = (byte)(r[i] >> b);
wolfSSL 16:8e0d178b1d1e 18767 b += 8;
wolfSSL 16:8e0d178b1d1e 18768 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 18769 break;
wolfSSL 16:8e0d178b1d1e 18770 }
wolfSSL 16:8e0d178b1d1e 18771 }
wolfSSL 16:8e0d178b1d1e 18772 s = 8 - (b - 32);
wolfSSL 16:8e0d178b1d1e 18773 if (j >= 0) {
wolfSSL 16:8e0d178b1d1e 18774 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 18775 }
wolfSSL 16:8e0d178b1d1e 18776 if (s != 0) {
wolfSSL 16:8e0d178b1d1e 18777 j++;
wolfSSL 16:8e0d178b1d1e 18778 }
wolfSSL 16:8e0d178b1d1e 18779 }
wolfSSL 16:8e0d178b1d1e 18780 }
wolfSSL 16:8e0d178b1d1e 18781
wolfSSL 16:8e0d178b1d1e 18782 /* Multiply the point by the scalar and serialize the X ordinate.
wolfSSL 16:8e0d178b1d1e 18783 * The number is 0 padded to maximum size on output.
wolfSSL 16:8e0d178b1d1e 18784 *
wolfSSL 16:8e0d178b1d1e 18785 * priv Scalar to multiply the point by.
wolfSSL 16:8e0d178b1d1e 18786 * pub Point to multiply.
wolfSSL 16:8e0d178b1d1e 18787 * out Buffer to hold X ordinate.
wolfSSL 16:8e0d178b1d1e 18788 * outLen On entry, size of the buffer in bytes.
wolfSSL 16:8e0d178b1d1e 18789 * On exit, length of data in buffer in bytes.
wolfSSL 16:8e0d178b1d1e 18790 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 18791 * returns BUFFER_E if the buffer is to small for output size,
wolfSSL 16:8e0d178b1d1e 18792 * MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 18793 */
wolfSSL 16:8e0d178b1d1e 18794 int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,
wolfSSL 16:8e0d178b1d1e 18795 word32* outLen, void* heap)
wolfSSL 16:8e0d178b1d1e 18796 {
wolfSSL 16:8e0d178b1d1e 18797 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 18798 sp_point_256 p;
wolfSSL 16:8e0d178b1d1e 18799 sp_digit kd[8];
wolfSSL 16:8e0d178b1d1e 18800 #endif
wolfSSL 16:8e0d178b1d1e 18801 sp_point_256* point = NULL;
wolfSSL 16:8e0d178b1d1e 18802 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 18803 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 18804
wolfSSL 16:8e0d178b1d1e 18805 if (*outLen < 32U) {
wolfSSL 16:8e0d178b1d1e 18806 err = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 18807 }
wolfSSL 16:8e0d178b1d1e 18808
wolfSSL 16:8e0d178b1d1e 18809 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18810 err = sp_256_point_new_8(heap, p, point);
wolfSSL 16:8e0d178b1d1e 18811 }
wolfSSL 16:8e0d178b1d1e 18812 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 18813 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18814 k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,
wolfSSL 16:8e0d178b1d1e 18815 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 18816 if (k == NULL)
wolfSSL 16:8e0d178b1d1e 18817 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 18818 }
wolfSSL 16:8e0d178b1d1e 18819 #else
wolfSSL 16:8e0d178b1d1e 18820 k = kd;
wolfSSL 16:8e0d178b1d1e 18821 #endif
wolfSSL 16:8e0d178b1d1e 18822
wolfSSL 16:8e0d178b1d1e 18823 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18824 sp_256_from_mp(k, 8, priv);
wolfSSL 16:8e0d178b1d1e 18825 sp_256_point_from_ecc_point_8(point, pub);
wolfSSL 16:8e0d178b1d1e 18826 err = sp_256_ecc_mulmod_8(point, point, k, 1, heap);
wolfSSL 16:8e0d178b1d1e 18827 }
wolfSSL 16:8e0d178b1d1e 18828 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 18829 sp_256_to_bin(point->x, out);
wolfSSL 16:8e0d178b1d1e 18830 *outLen = 32;
wolfSSL 16:8e0d178b1d1e 18831 }
wolfSSL 16:8e0d178b1d1e 18832
wolfSSL 16:8e0d178b1d1e 18833 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 18834 if (k != NULL) {
wolfSSL 16:8e0d178b1d1e 18835 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 18836 }
wolfSSL 16:8e0d178b1d1e 18837 #endif
wolfSSL 16:8e0d178b1d1e 18838 sp_256_point_free_8(point, 0, heap);
wolfSSL 16:8e0d178b1d1e 18839
wolfSSL 16:8e0d178b1d1e 18840 return err;
wolfSSL 16:8e0d178b1d1e 18841 }
wolfSSL 16:8e0d178b1d1e 18842 #endif /* HAVE_ECC_DHE */
wolfSSL 16:8e0d178b1d1e 18843
wolfSSL 16:8e0d178b1d1e 18844 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 18845 #endif
wolfSSL 16:8e0d178b1d1e 18846 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 18847 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 18848 /* Sub b from a into a. (a -= b)
wolfSSL 16:8e0d178b1d1e 18849 *
wolfSSL 16:8e0d178b1d1e 18850 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 18851 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 18852 */
wolfSSL 16:8e0d178b1d1e 18853 SP_NOINLINE static sp_digit sp_256_sub_in_place_8(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 18854 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 18855 {
wolfSSL 16:8e0d178b1d1e 18856 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 18857 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 18858 "mov r8, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 18859 "add r8, r8, #32\n\t"
wolfSSL 16:8e0d178b1d1e 18860 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 18861 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 18862 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 18863 "ldr r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 18864 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 18865 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 18866 "ldr r6, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 18867 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 18868 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 18869 "str r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 18870 "str r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 18871 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 18872 "add %[a], %[a], #8\n\t"
wolfSSL 16:8e0d178b1d1e 18873 "add %[b], %[b], #8\n\t"
wolfSSL 16:8e0d178b1d1e 18874 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 18875 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 18876 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 18877 :
wolfSSL 16:8e0d178b1d1e 18878 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 18879 );
wolfSSL 16:8e0d178b1d1e 18880
wolfSSL 16:8e0d178b1d1e 18881 return c;
wolfSSL 16:8e0d178b1d1e 18882 }
wolfSSL 16:8e0d178b1d1e 18883
wolfSSL 16:8e0d178b1d1e 18884 #else
wolfSSL 16:8e0d178b1d1e 18885 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 18886 *
wolfSSL 16:8e0d178b1d1e 18887 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 18888 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 18889 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 18890 */
wolfSSL 16:8e0d178b1d1e 18891 SP_NOINLINE static sp_digit sp_256_sub_in_place_8(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 18892 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 18893 {
wolfSSL 16:8e0d178b1d1e 18894 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 18895
wolfSSL 16:8e0d178b1d1e 18896 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 18897 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 18898 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 18899 "subs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 18900 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 18901 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 18902 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 18903 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 18904 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 18905 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 18906 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 18907 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 18908 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 18909 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 18910 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 18911 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 18912 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 18913 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 18914 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 18915 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 18916 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 18917 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 18918 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 18919 :
wolfSSL 16:8e0d178b1d1e 18920 : "memory", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 18921 );
wolfSSL 16:8e0d178b1d1e 18922
wolfSSL 16:8e0d178b1d1e 18923 return c;
wolfSSL 16:8e0d178b1d1e 18924 }
wolfSSL 16:8e0d178b1d1e 18925
wolfSSL 16:8e0d178b1d1e 18926 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 18927 /* Mul a by digit b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 18928 *
wolfSSL 16:8e0d178b1d1e 18929 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 18930 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 18931 * b A single precision digit.
wolfSSL 16:8e0d178b1d1e 18932 */
wolfSSL 16:8e0d178b1d1e 18933 SP_NOINLINE static void sp_256_mul_d_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 18934 sp_digit b)
wolfSSL 16:8e0d178b1d1e 18935 {
wolfSSL 16:8e0d178b1d1e 18936 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 18937 "add r9, %[a], #32\n\t"
wolfSSL 16:8e0d178b1d1e 18938 /* A[0] * B */
wolfSSL 16:8e0d178b1d1e 18939 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 18940 "umull r5, r3, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 18941 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 18942 "str r5, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 18943 /* A[0] * B - Done */
wolfSSL 16:8e0d178b1d1e 18944 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 18945 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 18946 /* A[] * B */
wolfSSL 16:8e0d178b1d1e 18947 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 18948 "umull r6, r8, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 18949 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 18950 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 18951 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 18952 /* A[] * B - Done */
wolfSSL 16:8e0d178b1d1e 18953 "str r3, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 18954 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 18955 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 18956 "cmp %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 18957 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 18958 "str r3, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 18959 : [r] "+r" (r), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 18960 : [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 18961 : "memory", "r3", "r4", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 18962 );
wolfSSL 16:8e0d178b1d1e 18963 }
wolfSSL 16:8e0d178b1d1e 18964
wolfSSL 16:8e0d178b1d1e 18965 /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)
wolfSSL 16:8e0d178b1d1e 18966 *
wolfSSL 16:8e0d178b1d1e 18967 * d1 The high order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 18968 * d0 The low order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 18969 * div The dividend.
wolfSSL 16:8e0d178b1d1e 18970 * returns the result of the division.
wolfSSL 16:8e0d178b1d1e 18971 *
wolfSSL 16:8e0d178b1d1e 18972 * Note that this is an approximate div. It may give an answer 1 larger.
wolfSSL 16:8e0d178b1d1e 18973 */
wolfSSL 16:8e0d178b1d1e 18974 SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0,
wolfSSL 16:8e0d178b1d1e 18975 sp_digit div)
wolfSSL 16:8e0d178b1d1e 18976 {
wolfSSL 16:8e0d178b1d1e 18977 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 18978
wolfSSL 16:8e0d178b1d1e 18979 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 18980 "lsr r6, %[div], #16\n\t"
wolfSSL 16:8e0d178b1d1e 18981 "add r6, r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 18982 "udiv r4, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 18983 "lsl r8, r4, #16\n\t"
wolfSSL 16:8e0d178b1d1e 18984 "umull r4, r5, %[div], r8\n\t"
wolfSSL 16:8e0d178b1d1e 18985 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 18986 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 18987 "udiv r5, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 18988 "lsl r4, r5, #16\n\t"
wolfSSL 16:8e0d178b1d1e 18989 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 18990 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 18991 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 18992 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 18993 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 18994 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 18995 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 18996 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 18997 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 18998 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 18999 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 19000 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 19001 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 19002 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 19003 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 19004 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 19005 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 19006 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 19007 "udiv r4, %[d0], %[div]\n\t"
wolfSSL 16:8e0d178b1d1e 19008 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 19009 "mov %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 19010 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 19011 : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div)
wolfSSL 16:8e0d178b1d1e 19012 : "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 19013 );
wolfSSL 16:8e0d178b1d1e 19014 return r;
wolfSSL 16:8e0d178b1d1e 19015 }
wolfSSL 16:8e0d178b1d1e 19016
wolfSSL 16:8e0d178b1d1e 19017 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 19018 *
wolfSSL 16:8e0d178b1d1e 19019 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 19020 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 19021 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 19022 */
wolfSSL 16:8e0d178b1d1e 19023 static void sp_256_mask_8(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 19024 {
wolfSSL 16:8e0d178b1d1e 19025 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 19026 int i;
wolfSSL 16:8e0d178b1d1e 19027
wolfSSL 16:8e0d178b1d1e 19028 for (i=0; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 19029 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 19030 }
wolfSSL 16:8e0d178b1d1e 19031 #else
wolfSSL 16:8e0d178b1d1e 19032 r[0] = a[0] & m;
wolfSSL 16:8e0d178b1d1e 19033 r[1] = a[1] & m;
wolfSSL 16:8e0d178b1d1e 19034 r[2] = a[2] & m;
wolfSSL 16:8e0d178b1d1e 19035 r[3] = a[3] & m;
wolfSSL 16:8e0d178b1d1e 19036 r[4] = a[4] & m;
wolfSSL 16:8e0d178b1d1e 19037 r[5] = a[5] & m;
wolfSSL 16:8e0d178b1d1e 19038 r[6] = a[6] & m;
wolfSSL 16:8e0d178b1d1e 19039 r[7] = a[7] & m;
wolfSSL 16:8e0d178b1d1e 19040 #endif
wolfSSL 16:8e0d178b1d1e 19041 }
wolfSSL 16:8e0d178b1d1e 19042
wolfSSL 16:8e0d178b1d1e 19043 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 19044 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 19045 *
wolfSSL 16:8e0d178b1d1e 19046 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 19047 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 19048 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 19049 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 19050 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 19051 */
wolfSSL 16:8e0d178b1d1e 19052 static WC_INLINE int sp_256_div_8(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 19053 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 19054 {
wolfSSL 16:8e0d178b1d1e 19055 sp_digit t1[16], t2[9];
wolfSSL 16:8e0d178b1d1e 19056 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 19057 int i;
wolfSSL 16:8e0d178b1d1e 19058
wolfSSL 16:8e0d178b1d1e 19059 (void)m;
wolfSSL 16:8e0d178b1d1e 19060
wolfSSL 16:8e0d178b1d1e 19061 div = d[7];
wolfSSL 16:8e0d178b1d1e 19062 XMEMCPY(t1, a, sizeof(*t1) * 2 * 8);
wolfSSL 16:8e0d178b1d1e 19063 for (i=7; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 19064 r1 = div_256_word_8(t1[8 + i], t1[8 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 19065
wolfSSL 16:8e0d178b1d1e 19066 sp_256_mul_d_8(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 19067 t1[8 + i] += sp_256_sub_in_place_8(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 19068 t1[8 + i] -= t2[8];
wolfSSL 16:8e0d178b1d1e 19069 sp_256_mask_8(t2, d, t1[8 + i]);
wolfSSL 16:8e0d178b1d1e 19070 t1[8 + i] += sp_256_add_8(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 19071 sp_256_mask_8(t2, d, t1[8 + i]);
wolfSSL 16:8e0d178b1d1e 19072 t1[8 + i] += sp_256_add_8(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 19073 }
wolfSSL 16:8e0d178b1d1e 19074
wolfSSL 16:8e0d178b1d1e 19075 r1 = sp_256_cmp_8(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 19076 sp_256_cond_sub_8(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 19077
wolfSSL 16:8e0d178b1d1e 19078 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 19079 }
wolfSSL 16:8e0d178b1d1e 19080
wolfSSL 16:8e0d178b1d1e 19081 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 19082 *
wolfSSL 16:8e0d178b1d1e 19083 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 19084 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 19085 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 19086 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 19087 */
wolfSSL 16:8e0d178b1d1e 19088 static WC_INLINE int sp_256_mod_8(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 19089 {
wolfSSL 16:8e0d178b1d1e 19090 return sp_256_div_8(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 19091 }
wolfSSL 16:8e0d178b1d1e 19092
wolfSSL 16:8e0d178b1d1e 19093 #endif
wolfSSL 16:8e0d178b1d1e 19094 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 19095 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 19096 /* Order-2 for the P256 curve. */
wolfSSL 16:8e0d178b1d1e 19097 static const uint32_t p256_order_minus_2[8] = {
wolfSSL 16:8e0d178b1d1e 19098 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU,
wolfSSL 16:8e0d178b1d1e 19099 0x00000000U,0xffffffffU
wolfSSL 16:8e0d178b1d1e 19100 };
wolfSSL 16:8e0d178b1d1e 19101 #else
wolfSSL 16:8e0d178b1d1e 19102 /* The low half of the order-2 of the P256 curve. */
wolfSSL 16:8e0d178b1d1e 19103 static const uint32_t p256_order_low[4] = {
wolfSSL 16:8e0d178b1d1e 19104 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU
wolfSSL 16:8e0d178b1d1e 19105 };
wolfSSL 16:8e0d178b1d1e 19106 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 19107
wolfSSL 16:8e0d178b1d1e 19108 /* Multiply two number mod the order of P256 curve. (r = a * b mod order)
wolfSSL 16:8e0d178b1d1e 19109 *
wolfSSL 16:8e0d178b1d1e 19110 * r Result of the multiplication.
wolfSSL 16:8e0d178b1d1e 19111 * a First operand of the multiplication.
wolfSSL 16:8e0d178b1d1e 19112 * b Second operand of the multiplication.
wolfSSL 16:8e0d178b1d1e 19113 */
wolfSSL 16:8e0d178b1d1e 19114 static void sp_256_mont_mul_order_8(sp_digit* r, const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 19115 {
wolfSSL 16:8e0d178b1d1e 19116 sp_256_mul_8(r, a, b);
wolfSSL 16:8e0d178b1d1e 19117 sp_256_mont_reduce_order_8(r, p256_order, p256_mp_order);
wolfSSL 16:8e0d178b1d1e 19118 }
wolfSSL 16:8e0d178b1d1e 19119
wolfSSL 16:8e0d178b1d1e 19120 /* Square number mod the order of P256 curve. (r = a * a mod order)
wolfSSL 16:8e0d178b1d1e 19121 *
wolfSSL 16:8e0d178b1d1e 19122 * r Result of the squaring.
wolfSSL 16:8e0d178b1d1e 19123 * a Number to square.
wolfSSL 16:8e0d178b1d1e 19124 */
wolfSSL 16:8e0d178b1d1e 19125 static void sp_256_mont_sqr_order_8(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 19126 {
wolfSSL 16:8e0d178b1d1e 19127 sp_256_sqr_8(r, a);
wolfSSL 16:8e0d178b1d1e 19128 sp_256_mont_reduce_order_8(r, p256_order, p256_mp_order);
wolfSSL 16:8e0d178b1d1e 19129 }
wolfSSL 16:8e0d178b1d1e 19130
wolfSSL 16:8e0d178b1d1e 19131 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 19132 /* Square number mod the order of P256 curve a number of times.
wolfSSL 16:8e0d178b1d1e 19133 * (r = a ^ n mod order)
wolfSSL 16:8e0d178b1d1e 19134 *
wolfSSL 16:8e0d178b1d1e 19135 * r Result of the squaring.
wolfSSL 16:8e0d178b1d1e 19136 * a Number to square.
wolfSSL 16:8e0d178b1d1e 19137 */
wolfSSL 16:8e0d178b1d1e 19138 static void sp_256_mont_sqr_n_order_8(sp_digit* r, const sp_digit* a, int n)
wolfSSL 16:8e0d178b1d1e 19139 {
wolfSSL 16:8e0d178b1d1e 19140 int i;
wolfSSL 16:8e0d178b1d1e 19141
wolfSSL 16:8e0d178b1d1e 19142 sp_256_mont_sqr_order_8(r, a);
wolfSSL 16:8e0d178b1d1e 19143 for (i=1; i<n; i++) {
wolfSSL 16:8e0d178b1d1e 19144 sp_256_mont_sqr_order_8(r, r);
wolfSSL 16:8e0d178b1d1e 19145 }
wolfSSL 16:8e0d178b1d1e 19146 }
wolfSSL 16:8e0d178b1d1e 19147 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 19148
wolfSSL 16:8e0d178b1d1e 19149 /* Invert the number, in Montgomery form, modulo the order of the P256 curve.
wolfSSL 16:8e0d178b1d1e 19150 * (r = 1 / a mod order)
wolfSSL 16:8e0d178b1d1e 19151 *
wolfSSL 16:8e0d178b1d1e 19152 * r Inverse result.
wolfSSL 16:8e0d178b1d1e 19153 * a Number to invert.
wolfSSL 16:8e0d178b1d1e 19154 * td Temporary data.
wolfSSL 16:8e0d178b1d1e 19155 */
wolfSSL 16:8e0d178b1d1e 19156 static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 19157 sp_digit* td)
wolfSSL 16:8e0d178b1d1e 19158 {
wolfSSL 16:8e0d178b1d1e 19159 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 19160 sp_digit* t = td;
wolfSSL 16:8e0d178b1d1e 19161 int i;
wolfSSL 16:8e0d178b1d1e 19162
wolfSSL 16:8e0d178b1d1e 19163 XMEMCPY(t, a, sizeof(sp_digit) * 8);
wolfSSL 16:8e0d178b1d1e 19164 for (i=254; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 19165 sp_256_mont_sqr_order_8(t, t);
wolfSSL 16:8e0d178b1d1e 19166 if ((p256_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {
wolfSSL 16:8e0d178b1d1e 19167 sp_256_mont_mul_order_8(t, t, a);
wolfSSL 16:8e0d178b1d1e 19168 }
wolfSSL 16:8e0d178b1d1e 19169 }
wolfSSL 16:8e0d178b1d1e 19170 XMEMCPY(r, t, sizeof(sp_digit) * 8U);
wolfSSL 16:8e0d178b1d1e 19171 #else
wolfSSL 16:8e0d178b1d1e 19172 sp_digit* t = td;
wolfSSL 16:8e0d178b1d1e 19173 sp_digit* t2 = td + 2 * 8;
wolfSSL 16:8e0d178b1d1e 19174 sp_digit* t3 = td + 4 * 8;
wolfSSL 16:8e0d178b1d1e 19175 int i;
wolfSSL 16:8e0d178b1d1e 19176
wolfSSL 16:8e0d178b1d1e 19177 /* t = a^2 */
wolfSSL 16:8e0d178b1d1e 19178 sp_256_mont_sqr_order_8(t, a);
wolfSSL 16:8e0d178b1d1e 19179 /* t = a^3 = t * a */
wolfSSL 16:8e0d178b1d1e 19180 sp_256_mont_mul_order_8(t, t, a);
wolfSSL 16:8e0d178b1d1e 19181 /* t2= a^c = t ^ 2 ^ 2 */
wolfSSL 16:8e0d178b1d1e 19182 sp_256_mont_sqr_n_order_8(t2, t, 2);
wolfSSL 16:8e0d178b1d1e 19183 /* t3= a^f = t2 * t */
wolfSSL 16:8e0d178b1d1e 19184 sp_256_mont_mul_order_8(t3, t2, t);
wolfSSL 16:8e0d178b1d1e 19185 /* t2= a^f0 = t3 ^ 2 ^ 4 */
wolfSSL 16:8e0d178b1d1e 19186 sp_256_mont_sqr_n_order_8(t2, t3, 4);
wolfSSL 16:8e0d178b1d1e 19187 /* t = a^ff = t2 * t3 */
wolfSSL 16:8e0d178b1d1e 19188 sp_256_mont_mul_order_8(t, t2, t3);
wolfSSL 16:8e0d178b1d1e 19189 /* t3= a^ff00 = t ^ 2 ^ 8 */
wolfSSL 16:8e0d178b1d1e 19190 sp_256_mont_sqr_n_order_8(t2, t, 8);
wolfSSL 16:8e0d178b1d1e 19191 /* t = a^ffff = t2 * t */
wolfSSL 16:8e0d178b1d1e 19192 sp_256_mont_mul_order_8(t, t2, t);
wolfSSL 16:8e0d178b1d1e 19193 /* t2= a^ffff0000 = t ^ 2 ^ 16 */
wolfSSL 16:8e0d178b1d1e 19194 sp_256_mont_sqr_n_order_8(t2, t, 16);
wolfSSL 16:8e0d178b1d1e 19195 /* t = a^ffffffff = t2 * t */
wolfSSL 16:8e0d178b1d1e 19196 sp_256_mont_mul_order_8(t, t2, t);
wolfSSL 16:8e0d178b1d1e 19197 /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64 */
wolfSSL 16:8e0d178b1d1e 19198 sp_256_mont_sqr_n_order_8(t2, t, 64);
wolfSSL 16:8e0d178b1d1e 19199 /* t2= a^ffffffff00000000ffffffff = t2 * t */
wolfSSL 16:8e0d178b1d1e 19200 sp_256_mont_mul_order_8(t2, t2, t);
wolfSSL 16:8e0d178b1d1e 19201 /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32 */
wolfSSL 16:8e0d178b1d1e 19202 sp_256_mont_sqr_n_order_8(t2, t2, 32);
wolfSSL 16:8e0d178b1d1e 19203 /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */
wolfSSL 16:8e0d178b1d1e 19204 sp_256_mont_mul_order_8(t2, t2, t);
wolfSSL 16:8e0d178b1d1e 19205 /* t2= a^ffffffff00000000ffffffffffffffffbce6 */
wolfSSL 16:8e0d178b1d1e 19206 for (i=127; i>=112; i--) {
wolfSSL 16:8e0d178b1d1e 19207 sp_256_mont_sqr_order_8(t2, t2);
wolfSSL 16:8e0d178b1d1e 19208 if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {
wolfSSL 16:8e0d178b1d1e 19209 sp_256_mont_mul_order_8(t2, t2, a);
wolfSSL 16:8e0d178b1d1e 19210 }
wolfSSL 16:8e0d178b1d1e 19211 }
wolfSSL 16:8e0d178b1d1e 19212 /* t2= a^ffffffff00000000ffffffffffffffffbce6f */
wolfSSL 16:8e0d178b1d1e 19213 sp_256_mont_sqr_n_order_8(t2, t2, 4);
wolfSSL 16:8e0d178b1d1e 19214 sp_256_mont_mul_order_8(t2, t2, t3);
wolfSSL 16:8e0d178b1d1e 19215 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */
wolfSSL 16:8e0d178b1d1e 19216 for (i=107; i>=64; i--) {
wolfSSL 16:8e0d178b1d1e 19217 sp_256_mont_sqr_order_8(t2, t2);
wolfSSL 16:8e0d178b1d1e 19218 if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {
wolfSSL 16:8e0d178b1d1e 19219 sp_256_mont_mul_order_8(t2, t2, a);
wolfSSL 16:8e0d178b1d1e 19220 }
wolfSSL 16:8e0d178b1d1e 19221 }
wolfSSL 16:8e0d178b1d1e 19222 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */
wolfSSL 16:8e0d178b1d1e 19223 sp_256_mont_sqr_n_order_8(t2, t2, 4);
wolfSSL 16:8e0d178b1d1e 19224 sp_256_mont_mul_order_8(t2, t2, t3);
wolfSSL 16:8e0d178b1d1e 19225 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */
wolfSSL 16:8e0d178b1d1e 19226 for (i=59; i>=32; i--) {
wolfSSL 16:8e0d178b1d1e 19227 sp_256_mont_sqr_order_8(t2, t2);
wolfSSL 16:8e0d178b1d1e 19228 if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {
wolfSSL 16:8e0d178b1d1e 19229 sp_256_mont_mul_order_8(t2, t2, a);
wolfSSL 16:8e0d178b1d1e 19230 }
wolfSSL 16:8e0d178b1d1e 19231 }
wolfSSL 16:8e0d178b1d1e 19232 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */
wolfSSL 16:8e0d178b1d1e 19233 sp_256_mont_sqr_n_order_8(t2, t2, 4);
wolfSSL 16:8e0d178b1d1e 19234 sp_256_mont_mul_order_8(t2, t2, t3);
wolfSSL 16:8e0d178b1d1e 19235 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */
wolfSSL 16:8e0d178b1d1e 19236 for (i=27; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 19237 sp_256_mont_sqr_order_8(t2, t2);
wolfSSL 16:8e0d178b1d1e 19238 if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {
wolfSSL 16:8e0d178b1d1e 19239 sp_256_mont_mul_order_8(t2, t2, a);
wolfSSL 16:8e0d178b1d1e 19240 }
wolfSSL 16:8e0d178b1d1e 19241 }
wolfSSL 16:8e0d178b1d1e 19242 /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */
wolfSSL 16:8e0d178b1d1e 19243 sp_256_mont_sqr_n_order_8(t2, t2, 4);
wolfSSL 16:8e0d178b1d1e 19244 /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */
wolfSSL 16:8e0d178b1d1e 19245 sp_256_mont_mul_order_8(r, t2, t3);
wolfSSL 16:8e0d178b1d1e 19246 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 19247 }
wolfSSL 16:8e0d178b1d1e 19248
wolfSSL 16:8e0d178b1d1e 19249 #endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */
wolfSSL 16:8e0d178b1d1e 19250 #ifdef HAVE_ECC_SIGN
wolfSSL 16:8e0d178b1d1e 19251 #ifndef SP_ECC_MAX_SIG_GEN
wolfSSL 16:8e0d178b1d1e 19252 #define SP_ECC_MAX_SIG_GEN 64
wolfSSL 16:8e0d178b1d1e 19253 #endif
wolfSSL 16:8e0d178b1d1e 19254
wolfSSL 16:8e0d178b1d1e 19255 /* Sign the hash using the private key.
wolfSSL 16:8e0d178b1d1e 19256 * e = [hash, 256 bits] from binary
wolfSSL 16:8e0d178b1d1e 19257 * r = (k.G)->x mod order
wolfSSL 16:8e0d178b1d1e 19258 * s = (r * x + e) / k mod order
wolfSSL 16:8e0d178b1d1e 19259 * The hash is truncated to the first 256 bits.
wolfSSL 16:8e0d178b1d1e 19260 *
wolfSSL 16:8e0d178b1d1e 19261 * hash Hash to sign.
wolfSSL 16:8e0d178b1d1e 19262 * hashLen Length of the hash data.
wolfSSL 16:8e0d178b1d1e 19263 * rng Random number generator.
wolfSSL 16:8e0d178b1d1e 19264 * priv Private part of key - scalar.
wolfSSL 16:8e0d178b1d1e 19265 * rm First part of result as an mp_int.
wolfSSL 16:8e0d178b1d1e 19266 * sm Sirst part of result as an mp_int.
wolfSSL 16:8e0d178b1d1e 19267 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 19268 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 16:8e0d178b1d1e 19269 * MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 19270 */
wolfSSL 16:8e0d178b1d1e 19271 int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
wolfSSL 16:8e0d178b1d1e 19272 mp_int* rm, mp_int* sm, mp_int* km, void* heap)
wolfSSL 16:8e0d178b1d1e 19273 {
wolfSSL 16:8e0d178b1d1e 19274 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19275 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 19276 #else
wolfSSL 16:8e0d178b1d1e 19277 sp_digit ed[2*8];
wolfSSL 16:8e0d178b1d1e 19278 sp_digit xd[2*8];
wolfSSL 16:8e0d178b1d1e 19279 sp_digit kd[2*8];
wolfSSL 16:8e0d178b1d1e 19280 sp_digit rd[2*8];
wolfSSL 16:8e0d178b1d1e 19281 sp_digit td[3 * 2*8];
wolfSSL 16:8e0d178b1d1e 19282 sp_point_256 p;
wolfSSL 16:8e0d178b1d1e 19283 #endif
wolfSSL 16:8e0d178b1d1e 19284 sp_digit* e = NULL;
wolfSSL 16:8e0d178b1d1e 19285 sp_digit* x = NULL;
wolfSSL 16:8e0d178b1d1e 19286 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 19287 sp_digit* r = NULL;
wolfSSL 16:8e0d178b1d1e 19288 sp_digit* tmp = NULL;
wolfSSL 16:8e0d178b1d1e 19289 sp_point_256* point = NULL;
wolfSSL 16:8e0d178b1d1e 19290 sp_digit carry;
wolfSSL 16:8e0d178b1d1e 19291 sp_digit* s = NULL;
wolfSSL 16:8e0d178b1d1e 19292 sp_digit* kInv = NULL;
wolfSSL 16:8e0d178b1d1e 19293 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 19294 int32_t c;
wolfSSL 16:8e0d178b1d1e 19295 int i;
wolfSSL 16:8e0d178b1d1e 19296
wolfSSL 16:8e0d178b1d1e 19297 (void)heap;
wolfSSL 16:8e0d178b1d1e 19298
wolfSSL 16:8e0d178b1d1e 19299 err = sp_256_point_new_8(heap, p, point);
wolfSSL 16:8e0d178b1d1e 19300 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19301 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19302 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 8, heap,
wolfSSL 16:8e0d178b1d1e 19303 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19304 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 19305 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 19306 }
wolfSSL 16:8e0d178b1d1e 19307 }
wolfSSL 16:8e0d178b1d1e 19308 #endif
wolfSSL 16:8e0d178b1d1e 19309
wolfSSL 16:8e0d178b1d1e 19310 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19311 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19312 e = d + 0 * 8;
wolfSSL 16:8e0d178b1d1e 19313 x = d + 2 * 8;
wolfSSL 16:8e0d178b1d1e 19314 k = d + 4 * 8;
wolfSSL 16:8e0d178b1d1e 19315 r = d + 6 * 8;
wolfSSL 16:8e0d178b1d1e 19316 tmp = d + 8 * 8;
wolfSSL 16:8e0d178b1d1e 19317 #else
wolfSSL 16:8e0d178b1d1e 19318 e = ed;
wolfSSL 16:8e0d178b1d1e 19319 x = xd;
wolfSSL 16:8e0d178b1d1e 19320 k = kd;
wolfSSL 16:8e0d178b1d1e 19321 r = rd;
wolfSSL 16:8e0d178b1d1e 19322 tmp = td;
wolfSSL 16:8e0d178b1d1e 19323 #endif
wolfSSL 16:8e0d178b1d1e 19324 s = e;
wolfSSL 16:8e0d178b1d1e 19325 kInv = k;
wolfSSL 16:8e0d178b1d1e 19326
wolfSSL 16:8e0d178b1d1e 19327 if (hashLen > 32U) {
wolfSSL 16:8e0d178b1d1e 19328 hashLen = 32U;
wolfSSL 16:8e0d178b1d1e 19329 }
wolfSSL 16:8e0d178b1d1e 19330
wolfSSL 16:8e0d178b1d1e 19331 sp_256_from_bin(e, 8, hash, (int)hashLen);
wolfSSL 16:8e0d178b1d1e 19332 }
wolfSSL 16:8e0d178b1d1e 19333
wolfSSL 16:8e0d178b1d1e 19334 for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {
wolfSSL 16:8e0d178b1d1e 19335 sp_256_from_mp(x, 8, priv);
wolfSSL 16:8e0d178b1d1e 19336
wolfSSL 16:8e0d178b1d1e 19337 /* New random point. */
wolfSSL 16:8e0d178b1d1e 19338 if (km == NULL || mp_iszero(km)) {
wolfSSL 16:8e0d178b1d1e 19339 err = sp_256_ecc_gen_k_8(rng, k);
wolfSSL 16:8e0d178b1d1e 19340 }
wolfSSL 16:8e0d178b1d1e 19341 else {
wolfSSL 16:8e0d178b1d1e 19342 sp_256_from_mp(k, 8, km);
wolfSSL 16:8e0d178b1d1e 19343 mp_zero(km);
wolfSSL 16:8e0d178b1d1e 19344 }
wolfSSL 16:8e0d178b1d1e 19345 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19346 err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);
wolfSSL 16:8e0d178b1d1e 19347 }
wolfSSL 16:8e0d178b1d1e 19348
wolfSSL 16:8e0d178b1d1e 19349 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19350 /* r = point->x mod order */
wolfSSL 16:8e0d178b1d1e 19351 XMEMCPY(r, point->x, sizeof(sp_digit) * 8U);
wolfSSL 16:8e0d178b1d1e 19352 sp_256_norm_8(r);
wolfSSL 16:8e0d178b1d1e 19353 c = sp_256_cmp_8(r, p256_order);
wolfSSL 16:8e0d178b1d1e 19354 sp_256_cond_sub_8(r, r, p256_order, 0L - (sp_digit)(c >= 0));
wolfSSL 16:8e0d178b1d1e 19355 sp_256_norm_8(r);
wolfSSL 16:8e0d178b1d1e 19356
wolfSSL 16:8e0d178b1d1e 19357 /* Conv k to Montgomery form (mod order) */
wolfSSL 16:8e0d178b1d1e 19358 sp_256_mul_8(k, k, p256_norm_order);
wolfSSL 16:8e0d178b1d1e 19359 err = sp_256_mod_8(k, k, p256_order);
wolfSSL 16:8e0d178b1d1e 19360 }
wolfSSL 16:8e0d178b1d1e 19361 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19362 sp_256_norm_8(k);
wolfSSL 16:8e0d178b1d1e 19363 /* kInv = 1/k mod order */
wolfSSL 16:8e0d178b1d1e 19364 sp_256_mont_inv_order_8(kInv, k, tmp);
wolfSSL 16:8e0d178b1d1e 19365 sp_256_norm_8(kInv);
wolfSSL 16:8e0d178b1d1e 19366
wolfSSL 16:8e0d178b1d1e 19367 /* s = r * x + e */
wolfSSL 16:8e0d178b1d1e 19368 sp_256_mul_8(x, x, r);
wolfSSL 16:8e0d178b1d1e 19369 err = sp_256_mod_8(x, x, p256_order);
wolfSSL 16:8e0d178b1d1e 19370 }
wolfSSL 16:8e0d178b1d1e 19371 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19372 sp_256_norm_8(x);
wolfSSL 16:8e0d178b1d1e 19373 carry = sp_256_add_8(s, e, x);
wolfSSL 16:8e0d178b1d1e 19374 sp_256_cond_sub_8(s, s, p256_order, 0 - carry);
wolfSSL 16:8e0d178b1d1e 19375 sp_256_norm_8(s);
wolfSSL 16:8e0d178b1d1e 19376 c = sp_256_cmp_8(s, p256_order);
wolfSSL 16:8e0d178b1d1e 19377 sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0));
wolfSSL 16:8e0d178b1d1e 19378 sp_256_norm_8(s);
wolfSSL 16:8e0d178b1d1e 19379
wolfSSL 16:8e0d178b1d1e 19380 /* s = s * k^-1 mod order */
wolfSSL 16:8e0d178b1d1e 19381 sp_256_mont_mul_order_8(s, s, kInv);
wolfSSL 16:8e0d178b1d1e 19382 sp_256_norm_8(s);
wolfSSL 16:8e0d178b1d1e 19383
wolfSSL 16:8e0d178b1d1e 19384 /* Check that signature is usable. */
wolfSSL 16:8e0d178b1d1e 19385 if (sp_256_iszero_8(s) == 0) {
wolfSSL 16:8e0d178b1d1e 19386 break;
wolfSSL 16:8e0d178b1d1e 19387 }
wolfSSL 16:8e0d178b1d1e 19388 }
wolfSSL 16:8e0d178b1d1e 19389 }
wolfSSL 16:8e0d178b1d1e 19390
wolfSSL 16:8e0d178b1d1e 19391 if (i == 0) {
wolfSSL 16:8e0d178b1d1e 19392 err = RNG_FAILURE_E;
wolfSSL 16:8e0d178b1d1e 19393 }
wolfSSL 16:8e0d178b1d1e 19394
wolfSSL 16:8e0d178b1d1e 19395 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19396 err = sp_256_to_mp(r, rm);
wolfSSL 16:8e0d178b1d1e 19397 }
wolfSSL 16:8e0d178b1d1e 19398 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19399 err = sp_256_to_mp(s, sm);
wolfSSL 16:8e0d178b1d1e 19400 }
wolfSSL 16:8e0d178b1d1e 19401
wolfSSL 16:8e0d178b1d1e 19402 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19403 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 19404 XMEMSET(d, 0, sizeof(sp_digit) * 8 * 8);
wolfSSL 16:8e0d178b1d1e 19405 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19406 }
wolfSSL 16:8e0d178b1d1e 19407 #else
wolfSSL 16:8e0d178b1d1e 19408 XMEMSET(e, 0, sizeof(sp_digit) * 2U * 8U);
wolfSSL 16:8e0d178b1d1e 19409 XMEMSET(x, 0, sizeof(sp_digit) * 2U * 8U);
wolfSSL 16:8e0d178b1d1e 19410 XMEMSET(k, 0, sizeof(sp_digit) * 2U * 8U);
wolfSSL 16:8e0d178b1d1e 19411 XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U);
wolfSSL 16:8e0d178b1d1e 19412 XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U);
wolfSSL 16:8e0d178b1d1e 19413 XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U);
wolfSSL 16:8e0d178b1d1e 19414 #endif
wolfSSL 16:8e0d178b1d1e 19415 sp_256_point_free_8(point, 1, heap);
wolfSSL 16:8e0d178b1d1e 19416
wolfSSL 16:8e0d178b1d1e 19417 return err;
wolfSSL 16:8e0d178b1d1e 19418 }
wolfSSL 16:8e0d178b1d1e 19419 #endif /* HAVE_ECC_SIGN */
wolfSSL 16:8e0d178b1d1e 19420
wolfSSL 16:8e0d178b1d1e 19421 #ifdef HAVE_ECC_VERIFY
wolfSSL 16:8e0d178b1d1e 19422 /* Verify the signature values with the hash and public key.
wolfSSL 16:8e0d178b1d1e 19423 * e = Truncate(hash, 256)
wolfSSL 16:8e0d178b1d1e 19424 * u1 = e/s mod order
wolfSSL 16:8e0d178b1d1e 19425 * u2 = r/s mod order
wolfSSL 16:8e0d178b1d1e 19426 * r == (u1.G + u2.Q)->x mod order
wolfSSL 16:8e0d178b1d1e 19427 * Optimization: Leave point in projective form.
wolfSSL 16:8e0d178b1d1e 19428 * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
wolfSSL 16:8e0d178b1d1e 19429 * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
wolfSSL 16:8e0d178b1d1e 19430 * The hash is truncated to the first 256 bits.
wolfSSL 16:8e0d178b1d1e 19431 *
wolfSSL 16:8e0d178b1d1e 19432 * hash Hash to sign.
wolfSSL 16:8e0d178b1d1e 19433 * hashLen Length of the hash data.
wolfSSL 16:8e0d178b1d1e 19434 * rng Random number generator.
wolfSSL 16:8e0d178b1d1e 19435 * priv Private part of key - scalar.
wolfSSL 16:8e0d178b1d1e 19436 * rm First part of result as an mp_int.
wolfSSL 16:8e0d178b1d1e 19437 * sm Sirst part of result as an mp_int.
wolfSSL 16:8e0d178b1d1e 19438 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 19439 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 16:8e0d178b1d1e 19440 * MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 19441 */
wolfSSL 16:8e0d178b1d1e 19442 int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
wolfSSL 16:8e0d178b1d1e 19443 mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)
wolfSSL 16:8e0d178b1d1e 19444 {
wolfSSL 16:8e0d178b1d1e 19445 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19446 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 19447 #else
wolfSSL 16:8e0d178b1d1e 19448 sp_digit u1d[2*8];
wolfSSL 16:8e0d178b1d1e 19449 sp_digit u2d[2*8];
wolfSSL 16:8e0d178b1d1e 19450 sp_digit sd[2*8];
wolfSSL 16:8e0d178b1d1e 19451 sp_digit tmpd[2*8 * 5];
wolfSSL 16:8e0d178b1d1e 19452 sp_point_256 p1d;
wolfSSL 16:8e0d178b1d1e 19453 sp_point_256 p2d;
wolfSSL 16:8e0d178b1d1e 19454 #endif
wolfSSL 16:8e0d178b1d1e 19455 sp_digit* u1 = NULL;
wolfSSL 16:8e0d178b1d1e 19456 sp_digit* u2 = NULL;
wolfSSL 16:8e0d178b1d1e 19457 sp_digit* s = NULL;
wolfSSL 16:8e0d178b1d1e 19458 sp_digit* tmp = NULL;
wolfSSL 16:8e0d178b1d1e 19459 sp_point_256* p1;
wolfSSL 16:8e0d178b1d1e 19460 sp_point_256* p2 = NULL;
wolfSSL 16:8e0d178b1d1e 19461 sp_digit carry;
wolfSSL 16:8e0d178b1d1e 19462 int32_t c;
wolfSSL 16:8e0d178b1d1e 19463 int err;
wolfSSL 16:8e0d178b1d1e 19464
wolfSSL 16:8e0d178b1d1e 19465 err = sp_256_point_new_8(heap, p1d, p1);
wolfSSL 16:8e0d178b1d1e 19466 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19467 err = sp_256_point_new_8(heap, p2d, p2);
wolfSSL 16:8e0d178b1d1e 19468 }
wolfSSL 16:8e0d178b1d1e 19469 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19470 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19471 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 8, heap,
wolfSSL 16:8e0d178b1d1e 19472 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19473 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 19474 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 19475 }
wolfSSL 16:8e0d178b1d1e 19476 }
wolfSSL 16:8e0d178b1d1e 19477 #endif
wolfSSL 16:8e0d178b1d1e 19478
wolfSSL 16:8e0d178b1d1e 19479 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19480 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19481 u1 = d + 0 * 8;
wolfSSL 16:8e0d178b1d1e 19482 u2 = d + 2 * 8;
wolfSSL 16:8e0d178b1d1e 19483 s = d + 4 * 8;
wolfSSL 16:8e0d178b1d1e 19484 tmp = d + 6 * 8;
wolfSSL 16:8e0d178b1d1e 19485 #else
wolfSSL 16:8e0d178b1d1e 19486 u1 = u1d;
wolfSSL 16:8e0d178b1d1e 19487 u2 = u2d;
wolfSSL 16:8e0d178b1d1e 19488 s = sd;
wolfSSL 16:8e0d178b1d1e 19489 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 19490 #endif
wolfSSL 16:8e0d178b1d1e 19491
wolfSSL 16:8e0d178b1d1e 19492 if (hashLen > 32U) {
wolfSSL 16:8e0d178b1d1e 19493 hashLen = 32U;
wolfSSL 16:8e0d178b1d1e 19494 }
wolfSSL 16:8e0d178b1d1e 19495
wolfSSL 16:8e0d178b1d1e 19496 sp_256_from_bin(u1, 8, hash, (int)hashLen);
wolfSSL 16:8e0d178b1d1e 19497 sp_256_from_mp(u2, 8, r);
wolfSSL 16:8e0d178b1d1e 19498 sp_256_from_mp(s, 8, sm);
wolfSSL 16:8e0d178b1d1e 19499 sp_256_from_mp(p2->x, 8, pX);
wolfSSL 16:8e0d178b1d1e 19500 sp_256_from_mp(p2->y, 8, pY);
wolfSSL 16:8e0d178b1d1e 19501 sp_256_from_mp(p2->z, 8, pZ);
wolfSSL 16:8e0d178b1d1e 19502
wolfSSL 16:8e0d178b1d1e 19503 {
wolfSSL 16:8e0d178b1d1e 19504 sp_256_mul_8(s, s, p256_norm_order);
wolfSSL 16:8e0d178b1d1e 19505 }
wolfSSL 16:8e0d178b1d1e 19506 err = sp_256_mod_8(s, s, p256_order);
wolfSSL 16:8e0d178b1d1e 19507 }
wolfSSL 16:8e0d178b1d1e 19508 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19509 sp_256_norm_8(s);
wolfSSL 16:8e0d178b1d1e 19510 {
wolfSSL 16:8e0d178b1d1e 19511 sp_256_mont_inv_order_8(s, s, tmp);
wolfSSL 16:8e0d178b1d1e 19512 sp_256_mont_mul_order_8(u1, u1, s);
wolfSSL 16:8e0d178b1d1e 19513 sp_256_mont_mul_order_8(u2, u2, s);
wolfSSL 16:8e0d178b1d1e 19514 }
wolfSSL 16:8e0d178b1d1e 19515
wolfSSL 16:8e0d178b1d1e 19516 err = sp_256_ecc_mulmod_base_8(p1, u1, 0, heap);
wolfSSL 16:8e0d178b1d1e 19517 }
wolfSSL 16:8e0d178b1d1e 19518 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19519 err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, heap);
wolfSSL 16:8e0d178b1d1e 19520 }
wolfSSL 16:8e0d178b1d1e 19521
wolfSSL 16:8e0d178b1d1e 19522 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19523 {
wolfSSL 16:8e0d178b1d1e 19524 sp_256_proj_point_add_8(p1, p1, p2, tmp);
wolfSSL 16:8e0d178b1d1e 19525 if (sp_256_iszero_8(p1->z)) {
wolfSSL 16:8e0d178b1d1e 19526 if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) {
wolfSSL 16:8e0d178b1d1e 19527 sp_256_proj_point_dbl_8(p1, p2, tmp);
wolfSSL 16:8e0d178b1d1e 19528 }
wolfSSL 16:8e0d178b1d1e 19529 else {
wolfSSL 16:8e0d178b1d1e 19530 /* Y ordinate is not used from here - don't set. */
wolfSSL 16:8e0d178b1d1e 19531 p1->x[0] = 0;
wolfSSL 16:8e0d178b1d1e 19532 p1->x[1] = 0;
wolfSSL 16:8e0d178b1d1e 19533 p1->x[2] = 0;
wolfSSL 16:8e0d178b1d1e 19534 p1->x[3] = 0;
wolfSSL 16:8e0d178b1d1e 19535 p1->x[4] = 0;
wolfSSL 16:8e0d178b1d1e 19536 p1->x[5] = 0;
wolfSSL 16:8e0d178b1d1e 19537 p1->x[6] = 0;
wolfSSL 16:8e0d178b1d1e 19538 p1->x[7] = 0;
wolfSSL 16:8e0d178b1d1e 19539 XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
wolfSSL 16:8e0d178b1d1e 19540 }
wolfSSL 16:8e0d178b1d1e 19541 }
wolfSSL 16:8e0d178b1d1e 19542 }
wolfSSL 16:8e0d178b1d1e 19543
wolfSSL 16:8e0d178b1d1e 19544 /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
wolfSSL 16:8e0d178b1d1e 19545 /* Reload r and convert to Montgomery form. */
wolfSSL 16:8e0d178b1d1e 19546 sp_256_from_mp(u2, 8, r);
wolfSSL 16:8e0d178b1d1e 19547 err = sp_256_mod_mul_norm_8(u2, u2, p256_mod);
wolfSSL 16:8e0d178b1d1e 19548 }
wolfSSL 16:8e0d178b1d1e 19549
wolfSSL 16:8e0d178b1d1e 19550 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19551 /* u1 = r.z'.z' mod prime */
wolfSSL 16:8e0d178b1d1e 19552 sp_256_mont_sqr_8(p1->z, p1->z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 19553 sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 19554 *res = (int)(sp_256_cmp_8(p1->x, u1) == 0);
wolfSSL 16:8e0d178b1d1e 19555 if (*res == 0) {
wolfSSL 16:8e0d178b1d1e 19556 /* Reload r and add order. */
wolfSSL 16:8e0d178b1d1e 19557 sp_256_from_mp(u2, 8, r);
wolfSSL 16:8e0d178b1d1e 19558 carry = sp_256_add_8(u2, u2, p256_order);
wolfSSL 16:8e0d178b1d1e 19559 /* Carry means result is greater than mod and is not valid. */
wolfSSL 16:8e0d178b1d1e 19560 if (carry == 0) {
wolfSSL 16:8e0d178b1d1e 19561 sp_256_norm_8(u2);
wolfSSL 16:8e0d178b1d1e 19562
wolfSSL 16:8e0d178b1d1e 19563 /* Compare with mod and if greater or equal then not valid. */
wolfSSL 16:8e0d178b1d1e 19564 c = sp_256_cmp_8(u2, p256_mod);
wolfSSL 16:8e0d178b1d1e 19565 if (c < 0) {
wolfSSL 16:8e0d178b1d1e 19566 /* Convert to Montogomery form */
wolfSSL 16:8e0d178b1d1e 19567 err = sp_256_mod_mul_norm_8(u2, u2, p256_mod);
wolfSSL 16:8e0d178b1d1e 19568 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19569 /* u1 = (r + 1*order).z'.z' mod prime */
wolfSSL 16:8e0d178b1d1e 19570 sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,
wolfSSL 16:8e0d178b1d1e 19571 p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 19572 *res = (int)(sp_256_cmp_8(p1->x, u1) == 0);
wolfSSL 16:8e0d178b1d1e 19573 }
wolfSSL 16:8e0d178b1d1e 19574 }
wolfSSL 16:8e0d178b1d1e 19575 }
wolfSSL 16:8e0d178b1d1e 19576 }
wolfSSL 16:8e0d178b1d1e 19577 }
wolfSSL 16:8e0d178b1d1e 19578
wolfSSL 16:8e0d178b1d1e 19579 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19580 if (d != NULL)
wolfSSL 16:8e0d178b1d1e 19581 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19582 #endif
wolfSSL 16:8e0d178b1d1e 19583 sp_256_point_free_8(p1, 0, heap);
wolfSSL 16:8e0d178b1d1e 19584 sp_256_point_free_8(p2, 0, heap);
wolfSSL 16:8e0d178b1d1e 19585
wolfSSL 16:8e0d178b1d1e 19586 return err;
wolfSSL 16:8e0d178b1d1e 19587 }
wolfSSL 16:8e0d178b1d1e 19588 #endif /* HAVE_ECC_VERIFY */
wolfSSL 16:8e0d178b1d1e 19589
wolfSSL 16:8e0d178b1d1e 19590 #ifdef HAVE_ECC_CHECK_KEY
wolfSSL 16:8e0d178b1d1e 19591 /* Check that the x and y oridinates are a valid point on the curve.
wolfSSL 16:8e0d178b1d1e 19592 *
wolfSSL 16:8e0d178b1d1e 19593 * point EC point.
wolfSSL 16:8e0d178b1d1e 19594 * heap Heap to use if dynamically allocating.
wolfSSL 16:8e0d178b1d1e 19595 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 16:8e0d178b1d1e 19596 * not on the curve and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 19597 */
wolfSSL 16:8e0d178b1d1e 19598 static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap)
wolfSSL 16:8e0d178b1d1e 19599 {
wolfSSL 16:8e0d178b1d1e 19600 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19601 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 19602 #else
wolfSSL 16:8e0d178b1d1e 19603 sp_digit t1d[2*8];
wolfSSL 16:8e0d178b1d1e 19604 sp_digit t2d[2*8];
wolfSSL 16:8e0d178b1d1e 19605 #endif
wolfSSL 16:8e0d178b1d1e 19606 sp_digit* t1;
wolfSSL 16:8e0d178b1d1e 19607 sp_digit* t2;
wolfSSL 16:8e0d178b1d1e 19608 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 19609
wolfSSL 16:8e0d178b1d1e 19610 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19611 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 4, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19612 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 19613 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 19614 }
wolfSSL 16:8e0d178b1d1e 19615 #endif
wolfSSL 16:8e0d178b1d1e 19616
wolfSSL 16:8e0d178b1d1e 19617 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19618 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19619 t1 = d + 0 * 8;
wolfSSL 16:8e0d178b1d1e 19620 t2 = d + 2 * 8;
wolfSSL 16:8e0d178b1d1e 19621 #else
wolfSSL 16:8e0d178b1d1e 19622 (void)heap;
wolfSSL 16:8e0d178b1d1e 19623
wolfSSL 16:8e0d178b1d1e 19624 t1 = t1d;
wolfSSL 16:8e0d178b1d1e 19625 t2 = t2d;
wolfSSL 16:8e0d178b1d1e 19626 #endif
wolfSSL 16:8e0d178b1d1e 19627
wolfSSL 16:8e0d178b1d1e 19628 sp_256_sqr_8(t1, point->y);
wolfSSL 16:8e0d178b1d1e 19629 (void)sp_256_mod_8(t1, t1, p256_mod);
wolfSSL 16:8e0d178b1d1e 19630 sp_256_sqr_8(t2, point->x);
wolfSSL 16:8e0d178b1d1e 19631 (void)sp_256_mod_8(t2, t2, p256_mod);
wolfSSL 16:8e0d178b1d1e 19632 sp_256_mul_8(t2, t2, point->x);
wolfSSL 16:8e0d178b1d1e 19633 (void)sp_256_mod_8(t2, t2, p256_mod);
wolfSSL 16:8e0d178b1d1e 19634 (void)sp_256_sub_8(t2, p256_mod, t2);
wolfSSL 16:8e0d178b1d1e 19635 sp_256_mont_add_8(t1, t1, t2, p256_mod);
wolfSSL 16:8e0d178b1d1e 19636
wolfSSL 16:8e0d178b1d1e 19637 sp_256_mont_add_8(t1, t1, point->x, p256_mod);
wolfSSL 16:8e0d178b1d1e 19638 sp_256_mont_add_8(t1, t1, point->x, p256_mod);
wolfSSL 16:8e0d178b1d1e 19639 sp_256_mont_add_8(t1, t1, point->x, p256_mod);
wolfSSL 16:8e0d178b1d1e 19640
wolfSSL 16:8e0d178b1d1e 19641 if (sp_256_cmp_8(t1, p256_b) != 0) {
wolfSSL 16:8e0d178b1d1e 19642 err = MP_VAL;
wolfSSL 16:8e0d178b1d1e 19643 }
wolfSSL 16:8e0d178b1d1e 19644 }
wolfSSL 16:8e0d178b1d1e 19645
wolfSSL 16:8e0d178b1d1e 19646 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19647 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 19648 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19649 }
wolfSSL 16:8e0d178b1d1e 19650 #endif
wolfSSL 16:8e0d178b1d1e 19651
wolfSSL 16:8e0d178b1d1e 19652 return err;
wolfSSL 16:8e0d178b1d1e 19653 }
wolfSSL 16:8e0d178b1d1e 19654
wolfSSL 16:8e0d178b1d1e 19655 /* Check that the x and y oridinates are a valid point on the curve.
wolfSSL 16:8e0d178b1d1e 19656 *
wolfSSL 16:8e0d178b1d1e 19657 * pX X ordinate of EC point.
wolfSSL 16:8e0d178b1d1e 19658 * pY Y ordinate of EC point.
wolfSSL 16:8e0d178b1d1e 19659 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 16:8e0d178b1d1e 19660 * not on the curve and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 19661 */
wolfSSL 16:8e0d178b1d1e 19662 int sp_ecc_is_point_256(mp_int* pX, mp_int* pY)
wolfSSL 16:8e0d178b1d1e 19663 {
wolfSSL 16:8e0d178b1d1e 19664 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19665 sp_point_256 pubd;
wolfSSL 16:8e0d178b1d1e 19666 #endif
wolfSSL 16:8e0d178b1d1e 19667 sp_point_256* pub;
wolfSSL 16:8e0d178b1d1e 19668 byte one[1] = { 1 };
wolfSSL 16:8e0d178b1d1e 19669 int err;
wolfSSL 16:8e0d178b1d1e 19670
wolfSSL 16:8e0d178b1d1e 19671 err = sp_256_point_new_8(NULL, pubd, pub);
wolfSSL 16:8e0d178b1d1e 19672 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19673 sp_256_from_mp(pub->x, 8, pX);
wolfSSL 16:8e0d178b1d1e 19674 sp_256_from_mp(pub->y, 8, pY);
wolfSSL 16:8e0d178b1d1e 19675 sp_256_from_bin(pub->z, 8, one, (int)sizeof(one));
wolfSSL 16:8e0d178b1d1e 19676
wolfSSL 16:8e0d178b1d1e 19677 err = sp_256_ecc_is_point_8(pub, NULL);
wolfSSL 16:8e0d178b1d1e 19678 }
wolfSSL 16:8e0d178b1d1e 19679
wolfSSL 16:8e0d178b1d1e 19680 sp_256_point_free_8(pub, 0, NULL);
wolfSSL 16:8e0d178b1d1e 19681
wolfSSL 16:8e0d178b1d1e 19682 return err;
wolfSSL 16:8e0d178b1d1e 19683 }
wolfSSL 16:8e0d178b1d1e 19684
wolfSSL 16:8e0d178b1d1e 19685 /* Check that the private scalar generates the EC point (px, py), the point is
wolfSSL 16:8e0d178b1d1e 19686 * on the curve and the point has the correct order.
wolfSSL 16:8e0d178b1d1e 19687 *
wolfSSL 16:8e0d178b1d1e 19688 * pX X ordinate of EC point.
wolfSSL 16:8e0d178b1d1e 19689 * pY Y ordinate of EC point.
wolfSSL 16:8e0d178b1d1e 19690 * privm Private scalar that generates EC point.
wolfSSL 16:8e0d178b1d1e 19691 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 16:8e0d178b1d1e 19692 * not on the curve, ECC_INF_E if the point does not have the correct order,
wolfSSL 16:8e0d178b1d1e 19693 * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
wolfSSL 16:8e0d178b1d1e 19694 * MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 19695 */
wolfSSL 16:8e0d178b1d1e 19696 int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)
wolfSSL 16:8e0d178b1d1e 19697 {
wolfSSL 16:8e0d178b1d1e 19698 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19699 sp_digit privd[8];
wolfSSL 16:8e0d178b1d1e 19700 sp_point_256 pubd;
wolfSSL 16:8e0d178b1d1e 19701 sp_point_256 pd;
wolfSSL 16:8e0d178b1d1e 19702 #endif
wolfSSL 16:8e0d178b1d1e 19703 sp_digit* priv = NULL;
wolfSSL 16:8e0d178b1d1e 19704 sp_point_256* pub;
wolfSSL 16:8e0d178b1d1e 19705 sp_point_256* p = NULL;
wolfSSL 16:8e0d178b1d1e 19706 byte one[1] = { 1 };
wolfSSL 16:8e0d178b1d1e 19707 int err;
wolfSSL 16:8e0d178b1d1e 19708
wolfSSL 16:8e0d178b1d1e 19709 err = sp_256_point_new_8(heap, pubd, pub);
wolfSSL 16:8e0d178b1d1e 19710 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19711 err = sp_256_point_new_8(heap, pd, p);
wolfSSL 16:8e0d178b1d1e 19712 }
wolfSSL 16:8e0d178b1d1e 19713 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19714 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19715 priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,
wolfSSL 16:8e0d178b1d1e 19716 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19717 if (priv == NULL) {
wolfSSL 16:8e0d178b1d1e 19718 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 19719 }
wolfSSL 16:8e0d178b1d1e 19720 }
wolfSSL 16:8e0d178b1d1e 19721 #endif
wolfSSL 16:8e0d178b1d1e 19722
wolfSSL 16:8e0d178b1d1e 19723 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19724 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19725 priv = privd;
wolfSSL 16:8e0d178b1d1e 19726 #endif
wolfSSL 16:8e0d178b1d1e 19727
wolfSSL 16:8e0d178b1d1e 19728 sp_256_from_mp(pub->x, 8, pX);
wolfSSL 16:8e0d178b1d1e 19729 sp_256_from_mp(pub->y, 8, pY);
wolfSSL 16:8e0d178b1d1e 19730 sp_256_from_bin(pub->z, 8, one, (int)sizeof(one));
wolfSSL 16:8e0d178b1d1e 19731 sp_256_from_mp(priv, 8, privm);
wolfSSL 16:8e0d178b1d1e 19732
wolfSSL 16:8e0d178b1d1e 19733 /* Check point at infinitiy. */
wolfSSL 16:8e0d178b1d1e 19734 if ((sp_256_iszero_8(pub->x) != 0) &&
wolfSSL 16:8e0d178b1d1e 19735 (sp_256_iszero_8(pub->y) != 0)) {
wolfSSL 16:8e0d178b1d1e 19736 err = ECC_INF_E;
wolfSSL 16:8e0d178b1d1e 19737 }
wolfSSL 16:8e0d178b1d1e 19738 }
wolfSSL 16:8e0d178b1d1e 19739
wolfSSL 16:8e0d178b1d1e 19740 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19741 /* Check range of X and Y */
wolfSSL 16:8e0d178b1d1e 19742 if (sp_256_cmp_8(pub->x, p256_mod) >= 0 ||
wolfSSL 16:8e0d178b1d1e 19743 sp_256_cmp_8(pub->y, p256_mod) >= 0) {
wolfSSL 16:8e0d178b1d1e 19744 err = ECC_OUT_OF_RANGE_E;
wolfSSL 16:8e0d178b1d1e 19745 }
wolfSSL 16:8e0d178b1d1e 19746 }
wolfSSL 16:8e0d178b1d1e 19747
wolfSSL 16:8e0d178b1d1e 19748 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19749 /* Check point is on curve */
wolfSSL 16:8e0d178b1d1e 19750 err = sp_256_ecc_is_point_8(pub, heap);
wolfSSL 16:8e0d178b1d1e 19751 }
wolfSSL 16:8e0d178b1d1e 19752
wolfSSL 16:8e0d178b1d1e 19753 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19754 /* Point * order = infinity */
wolfSSL 16:8e0d178b1d1e 19755 err = sp_256_ecc_mulmod_8(p, pub, p256_order, 1, heap);
wolfSSL 16:8e0d178b1d1e 19756 }
wolfSSL 16:8e0d178b1d1e 19757 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19758 /* Check result is infinity */
wolfSSL 16:8e0d178b1d1e 19759 if ((sp_256_iszero_8(p->x) == 0) ||
wolfSSL 16:8e0d178b1d1e 19760 (sp_256_iszero_8(p->y) == 0)) {
wolfSSL 16:8e0d178b1d1e 19761 err = ECC_INF_E;
wolfSSL 16:8e0d178b1d1e 19762 }
wolfSSL 16:8e0d178b1d1e 19763 }
wolfSSL 16:8e0d178b1d1e 19764
wolfSSL 16:8e0d178b1d1e 19765 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19766 /* Base * private = point */
wolfSSL 16:8e0d178b1d1e 19767 err = sp_256_ecc_mulmod_base_8(p, priv, 1, heap);
wolfSSL 16:8e0d178b1d1e 19768 }
wolfSSL 16:8e0d178b1d1e 19769 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19770 /* Check result is public key */
wolfSSL 16:8e0d178b1d1e 19771 if (sp_256_cmp_8(p->x, pub->x) != 0 ||
wolfSSL 16:8e0d178b1d1e 19772 sp_256_cmp_8(p->y, pub->y) != 0) {
wolfSSL 16:8e0d178b1d1e 19773 err = ECC_PRIV_KEY_E;
wolfSSL 16:8e0d178b1d1e 19774 }
wolfSSL 16:8e0d178b1d1e 19775 }
wolfSSL 16:8e0d178b1d1e 19776
wolfSSL 16:8e0d178b1d1e 19777 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19778 if (priv != NULL) {
wolfSSL 16:8e0d178b1d1e 19779 XFREE(priv, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19780 }
wolfSSL 16:8e0d178b1d1e 19781 #endif
wolfSSL 16:8e0d178b1d1e 19782 sp_256_point_free_8(p, 0, heap);
wolfSSL 16:8e0d178b1d1e 19783 sp_256_point_free_8(pub, 0, heap);
wolfSSL 16:8e0d178b1d1e 19784
wolfSSL 16:8e0d178b1d1e 19785 return err;
wolfSSL 16:8e0d178b1d1e 19786 }
wolfSSL 16:8e0d178b1d1e 19787 #endif
wolfSSL 16:8e0d178b1d1e 19788 #ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
wolfSSL 16:8e0d178b1d1e 19789 /* Add two projective EC points together.
wolfSSL 16:8e0d178b1d1e 19790 * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)
wolfSSL 16:8e0d178b1d1e 19791 *
wolfSSL 16:8e0d178b1d1e 19792 * pX First EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 19793 * pY First EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 19794 * pZ First EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 19795 * qX Second EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 19796 * qY Second EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 19797 * qZ Second EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 19798 * rX Resultant EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 19799 * rY Resultant EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 19800 * rZ Resultant EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 19801 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 19802 */
wolfSSL 16:8e0d178b1d1e 19803 int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
wolfSSL 16:8e0d178b1d1e 19804 mp_int* qX, mp_int* qY, mp_int* qZ,
wolfSSL 16:8e0d178b1d1e 19805 mp_int* rX, mp_int* rY, mp_int* rZ)
wolfSSL 16:8e0d178b1d1e 19806 {
wolfSSL 16:8e0d178b1d1e 19807 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19808 sp_digit tmpd[2 * 8 * 5];
wolfSSL 16:8e0d178b1d1e 19809 sp_point_256 pd;
wolfSSL 16:8e0d178b1d1e 19810 sp_point_256 qd;
wolfSSL 16:8e0d178b1d1e 19811 #endif
wolfSSL 16:8e0d178b1d1e 19812 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 19813 sp_point_256* p;
wolfSSL 16:8e0d178b1d1e 19814 sp_point_256* q = NULL;
wolfSSL 16:8e0d178b1d1e 19815 int err;
wolfSSL 16:8e0d178b1d1e 19816
wolfSSL 16:8e0d178b1d1e 19817 err = sp_256_point_new_8(NULL, pd, p);
wolfSSL 16:8e0d178b1d1e 19818 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19819 err = sp_256_point_new_8(NULL, qd, q);
wolfSSL 16:8e0d178b1d1e 19820 }
wolfSSL 16:8e0d178b1d1e 19821 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19822 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19823 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, NULL,
wolfSSL 16:8e0d178b1d1e 19824 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19825 if (tmp == NULL) {
wolfSSL 16:8e0d178b1d1e 19826 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 19827 }
wolfSSL 16:8e0d178b1d1e 19828 }
wolfSSL 16:8e0d178b1d1e 19829 #else
wolfSSL 16:8e0d178b1d1e 19830 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 19831 #endif
wolfSSL 16:8e0d178b1d1e 19832
wolfSSL 16:8e0d178b1d1e 19833 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19834 sp_256_from_mp(p->x, 8, pX);
wolfSSL 16:8e0d178b1d1e 19835 sp_256_from_mp(p->y, 8, pY);
wolfSSL 16:8e0d178b1d1e 19836 sp_256_from_mp(p->z, 8, pZ);
wolfSSL 16:8e0d178b1d1e 19837 sp_256_from_mp(q->x, 8, qX);
wolfSSL 16:8e0d178b1d1e 19838 sp_256_from_mp(q->y, 8, qY);
wolfSSL 16:8e0d178b1d1e 19839 sp_256_from_mp(q->z, 8, qZ);
wolfSSL 16:8e0d178b1d1e 19840
wolfSSL 16:8e0d178b1d1e 19841 sp_256_proj_point_add_8(p, p, q, tmp);
wolfSSL 16:8e0d178b1d1e 19842 }
wolfSSL 16:8e0d178b1d1e 19843
wolfSSL 16:8e0d178b1d1e 19844 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19845 err = sp_256_to_mp(p->x, rX);
wolfSSL 16:8e0d178b1d1e 19846 }
wolfSSL 16:8e0d178b1d1e 19847 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19848 err = sp_256_to_mp(p->y, rY);
wolfSSL 16:8e0d178b1d1e 19849 }
wolfSSL 16:8e0d178b1d1e 19850 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19851 err = sp_256_to_mp(p->z, rZ);
wolfSSL 16:8e0d178b1d1e 19852 }
wolfSSL 16:8e0d178b1d1e 19853
wolfSSL 16:8e0d178b1d1e 19854 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19855 if (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 19856 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19857 }
wolfSSL 16:8e0d178b1d1e 19858 #endif
wolfSSL 16:8e0d178b1d1e 19859 sp_256_point_free_8(q, 0, NULL);
wolfSSL 16:8e0d178b1d1e 19860 sp_256_point_free_8(p, 0, NULL);
wolfSSL 16:8e0d178b1d1e 19861
wolfSSL 16:8e0d178b1d1e 19862 return err;
wolfSSL 16:8e0d178b1d1e 19863 }
wolfSSL 16:8e0d178b1d1e 19864
wolfSSL 16:8e0d178b1d1e 19865 /* Double a projective EC point.
wolfSSL 16:8e0d178b1d1e 19866 * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)
wolfSSL 16:8e0d178b1d1e 19867 *
wolfSSL 16:8e0d178b1d1e 19868 * pX EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 19869 * pY EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 19870 * pZ EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 19871 * rX Resultant EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 19872 * rY Resultant EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 19873 * rZ Resultant EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 19874 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 19875 */
wolfSSL 16:8e0d178b1d1e 19876 int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
wolfSSL 16:8e0d178b1d1e 19877 mp_int* rX, mp_int* rY, mp_int* rZ)
wolfSSL 16:8e0d178b1d1e 19878 {
wolfSSL 16:8e0d178b1d1e 19879 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19880 sp_digit tmpd[2 * 8 * 2];
wolfSSL 16:8e0d178b1d1e 19881 sp_point_256 pd;
wolfSSL 16:8e0d178b1d1e 19882 #endif
wolfSSL 16:8e0d178b1d1e 19883 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 19884 sp_point_256* p;
wolfSSL 16:8e0d178b1d1e 19885 int err;
wolfSSL 16:8e0d178b1d1e 19886
wolfSSL 16:8e0d178b1d1e 19887 err = sp_256_point_new_8(NULL, pd, p);
wolfSSL 16:8e0d178b1d1e 19888 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19889 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19890 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 2, NULL,
wolfSSL 16:8e0d178b1d1e 19891 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19892 if (tmp == NULL) {
wolfSSL 16:8e0d178b1d1e 19893 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 19894 }
wolfSSL 16:8e0d178b1d1e 19895 }
wolfSSL 16:8e0d178b1d1e 19896 #else
wolfSSL 16:8e0d178b1d1e 19897 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 19898 #endif
wolfSSL 16:8e0d178b1d1e 19899
wolfSSL 16:8e0d178b1d1e 19900 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19901 sp_256_from_mp(p->x, 8, pX);
wolfSSL 16:8e0d178b1d1e 19902 sp_256_from_mp(p->y, 8, pY);
wolfSSL 16:8e0d178b1d1e 19903 sp_256_from_mp(p->z, 8, pZ);
wolfSSL 16:8e0d178b1d1e 19904
wolfSSL 16:8e0d178b1d1e 19905 sp_256_proj_point_dbl_8(p, p, tmp);
wolfSSL 16:8e0d178b1d1e 19906 }
wolfSSL 16:8e0d178b1d1e 19907
wolfSSL 16:8e0d178b1d1e 19908 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19909 err = sp_256_to_mp(p->x, rX);
wolfSSL 16:8e0d178b1d1e 19910 }
wolfSSL 16:8e0d178b1d1e 19911 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19912 err = sp_256_to_mp(p->y, rY);
wolfSSL 16:8e0d178b1d1e 19913 }
wolfSSL 16:8e0d178b1d1e 19914 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19915 err = sp_256_to_mp(p->z, rZ);
wolfSSL 16:8e0d178b1d1e 19916 }
wolfSSL 16:8e0d178b1d1e 19917
wolfSSL 16:8e0d178b1d1e 19918 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19919 if (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 19920 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19921 }
wolfSSL 16:8e0d178b1d1e 19922 #endif
wolfSSL 16:8e0d178b1d1e 19923 sp_256_point_free_8(p, 0, NULL);
wolfSSL 16:8e0d178b1d1e 19924
wolfSSL 16:8e0d178b1d1e 19925 return err;
wolfSSL 16:8e0d178b1d1e 19926 }
wolfSSL 16:8e0d178b1d1e 19927
wolfSSL 16:8e0d178b1d1e 19928 /* Map a projective EC point to affine in place.
wolfSSL 16:8e0d178b1d1e 19929 * pZ will be one.
wolfSSL 16:8e0d178b1d1e 19930 *
wolfSSL 16:8e0d178b1d1e 19931 * pX EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 19932 * pY EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 19933 * pZ EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 19934 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 19935 */
wolfSSL 16:8e0d178b1d1e 19936 int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)
wolfSSL 16:8e0d178b1d1e 19937 {
wolfSSL 16:8e0d178b1d1e 19938 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19939 sp_digit tmpd[2 * 8 * 4];
wolfSSL 16:8e0d178b1d1e 19940 sp_point_256 pd;
wolfSSL 16:8e0d178b1d1e 19941 #endif
wolfSSL 16:8e0d178b1d1e 19942 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 19943 sp_point_256* p;
wolfSSL 16:8e0d178b1d1e 19944 int err;
wolfSSL 16:8e0d178b1d1e 19945
wolfSSL 16:8e0d178b1d1e 19946 err = sp_256_point_new_8(NULL, pd, p);
wolfSSL 16:8e0d178b1d1e 19947 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19948 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19949 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 4, NULL,
wolfSSL 16:8e0d178b1d1e 19950 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19951 if (tmp == NULL) {
wolfSSL 16:8e0d178b1d1e 19952 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 19953 }
wolfSSL 16:8e0d178b1d1e 19954 }
wolfSSL 16:8e0d178b1d1e 19955 #else
wolfSSL 16:8e0d178b1d1e 19956 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 19957 #endif
wolfSSL 16:8e0d178b1d1e 19958 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19959 sp_256_from_mp(p->x, 8, pX);
wolfSSL 16:8e0d178b1d1e 19960 sp_256_from_mp(p->y, 8, pY);
wolfSSL 16:8e0d178b1d1e 19961 sp_256_from_mp(p->z, 8, pZ);
wolfSSL 16:8e0d178b1d1e 19962
wolfSSL 16:8e0d178b1d1e 19963 sp_256_map_8(p, p, tmp);
wolfSSL 16:8e0d178b1d1e 19964 }
wolfSSL 16:8e0d178b1d1e 19965
wolfSSL 16:8e0d178b1d1e 19966 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19967 err = sp_256_to_mp(p->x, pX);
wolfSSL 16:8e0d178b1d1e 19968 }
wolfSSL 16:8e0d178b1d1e 19969 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19970 err = sp_256_to_mp(p->y, pY);
wolfSSL 16:8e0d178b1d1e 19971 }
wolfSSL 16:8e0d178b1d1e 19972 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 19973 err = sp_256_to_mp(p->z, pZ);
wolfSSL 16:8e0d178b1d1e 19974 }
wolfSSL 16:8e0d178b1d1e 19975
wolfSSL 16:8e0d178b1d1e 19976 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19977 if (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 19978 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 19979 }
wolfSSL 16:8e0d178b1d1e 19980 #endif
wolfSSL 16:8e0d178b1d1e 19981 sp_256_point_free_8(p, 0, NULL);
wolfSSL 16:8e0d178b1d1e 19982
wolfSSL 16:8e0d178b1d1e 19983 return err;
wolfSSL 16:8e0d178b1d1e 19984 }
wolfSSL 16:8e0d178b1d1e 19985 #endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */
wolfSSL 16:8e0d178b1d1e 19986 #ifdef HAVE_COMP_KEY
wolfSSL 16:8e0d178b1d1e 19987 /* Find the square root of a number mod the prime of the curve.
wolfSSL 16:8e0d178b1d1e 19988 *
wolfSSL 16:8e0d178b1d1e 19989 * y The number to operate on and the result.
wolfSSL 16:8e0d178b1d1e 19990 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 19991 */
wolfSSL 16:8e0d178b1d1e 19992 static int sp_256_mont_sqrt_8(sp_digit* y)
wolfSSL 16:8e0d178b1d1e 19993 {
wolfSSL 16:8e0d178b1d1e 19994 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 19995 sp_digit* d;
wolfSSL 16:8e0d178b1d1e 19996 #else
wolfSSL 16:8e0d178b1d1e 19997 sp_digit t1d[2 * 8];
wolfSSL 16:8e0d178b1d1e 19998 sp_digit t2d[2 * 8];
wolfSSL 16:8e0d178b1d1e 19999 #endif
wolfSSL 16:8e0d178b1d1e 20000 sp_digit* t1;
wolfSSL 16:8e0d178b1d1e 20001 sp_digit* t2;
wolfSSL 16:8e0d178b1d1e 20002 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 20003
wolfSSL 16:8e0d178b1d1e 20004 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20005 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 8, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 20006 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 20007 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 20008 }
wolfSSL 16:8e0d178b1d1e 20009 #endif
wolfSSL 16:8e0d178b1d1e 20010
wolfSSL 16:8e0d178b1d1e 20011 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 20012 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20013 t1 = d + 0 * 8;
wolfSSL 16:8e0d178b1d1e 20014 t2 = d + 2 * 8;
wolfSSL 16:8e0d178b1d1e 20015 #else
wolfSSL 16:8e0d178b1d1e 20016 t1 = t1d;
wolfSSL 16:8e0d178b1d1e 20017 t2 = t2d;
wolfSSL 16:8e0d178b1d1e 20018 #endif
wolfSSL 16:8e0d178b1d1e 20019
wolfSSL 16:8e0d178b1d1e 20020 {
wolfSSL 16:8e0d178b1d1e 20021 /* t2 = y ^ 0x2 */
wolfSSL 16:8e0d178b1d1e 20022 sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20023 /* t1 = y ^ 0x3 */
wolfSSL 16:8e0d178b1d1e 20024 sp_256_mont_mul_8(t1, t2, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20025 /* t2 = y ^ 0xc */
wolfSSL 16:8e0d178b1d1e 20026 sp_256_mont_sqr_n_8(t2, t1, 2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20027 /* t1 = y ^ 0xf */
wolfSSL 16:8e0d178b1d1e 20028 sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20029 /* t2 = y ^ 0xf0 */
wolfSSL 16:8e0d178b1d1e 20030 sp_256_mont_sqr_n_8(t2, t1, 4, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20031 /* t1 = y ^ 0xff */
wolfSSL 16:8e0d178b1d1e 20032 sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20033 /* t2 = y ^ 0xff00 */
wolfSSL 16:8e0d178b1d1e 20034 sp_256_mont_sqr_n_8(t2, t1, 8, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20035 /* t1 = y ^ 0xffff */
wolfSSL 16:8e0d178b1d1e 20036 sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20037 /* t2 = y ^ 0xffff0000 */
wolfSSL 16:8e0d178b1d1e 20038 sp_256_mont_sqr_n_8(t2, t1, 16, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20039 /* t1 = y ^ 0xffffffff */
wolfSSL 16:8e0d178b1d1e 20040 sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20041 /* t1 = y ^ 0xffffffff00000000 */
wolfSSL 16:8e0d178b1d1e 20042 sp_256_mont_sqr_n_8(t1, t1, 32, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20043 /* t1 = y ^ 0xffffffff00000001 */
wolfSSL 16:8e0d178b1d1e 20044 sp_256_mont_mul_8(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20045 /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */
wolfSSL 16:8e0d178b1d1e 20046 sp_256_mont_sqr_n_8(t1, t1, 96, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20047 /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */
wolfSSL 16:8e0d178b1d1e 20048 sp_256_mont_mul_8(t1, t1, y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20049 sp_256_mont_sqr_n_8(y, t1, 94, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20050 }
wolfSSL 16:8e0d178b1d1e 20051 }
wolfSSL 16:8e0d178b1d1e 20052
wolfSSL 16:8e0d178b1d1e 20053 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20054 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 20055 XFREE(d, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 20056 }
wolfSSL 16:8e0d178b1d1e 20057 #endif
wolfSSL 16:8e0d178b1d1e 20058
wolfSSL 16:8e0d178b1d1e 20059 return err;
wolfSSL 16:8e0d178b1d1e 20060 }
wolfSSL 16:8e0d178b1d1e 20061
wolfSSL 16:8e0d178b1d1e 20062
wolfSSL 16:8e0d178b1d1e 20063 /* Uncompress the point given the X ordinate.
wolfSSL 16:8e0d178b1d1e 20064 *
wolfSSL 16:8e0d178b1d1e 20065 * xm X ordinate.
wolfSSL 16:8e0d178b1d1e 20066 * odd Whether the Y ordinate is odd.
wolfSSL 16:8e0d178b1d1e 20067 * ym Calculated Y ordinate.
wolfSSL 16:8e0d178b1d1e 20068 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 20069 */
wolfSSL 16:8e0d178b1d1e 20070 int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)
wolfSSL 16:8e0d178b1d1e 20071 {
wolfSSL 16:8e0d178b1d1e 20072 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20073 sp_digit* d;
wolfSSL 16:8e0d178b1d1e 20074 #else
wolfSSL 16:8e0d178b1d1e 20075 sp_digit xd[2 * 8];
wolfSSL 16:8e0d178b1d1e 20076 sp_digit yd[2 * 8];
wolfSSL 16:8e0d178b1d1e 20077 #endif
wolfSSL 16:8e0d178b1d1e 20078 sp_digit* x = NULL;
wolfSSL 16:8e0d178b1d1e 20079 sp_digit* y = NULL;
wolfSSL 16:8e0d178b1d1e 20080 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 20081
wolfSSL 16:8e0d178b1d1e 20082 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20083 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 8, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 20084 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 20085 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 20086 }
wolfSSL 16:8e0d178b1d1e 20087 #endif
wolfSSL 16:8e0d178b1d1e 20088
wolfSSL 16:8e0d178b1d1e 20089 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 20090 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20091 x = d + 0 * 8;
wolfSSL 16:8e0d178b1d1e 20092 y = d + 2 * 8;
wolfSSL 16:8e0d178b1d1e 20093 #else
wolfSSL 16:8e0d178b1d1e 20094 x = xd;
wolfSSL 16:8e0d178b1d1e 20095 y = yd;
wolfSSL 16:8e0d178b1d1e 20096 #endif
wolfSSL 16:8e0d178b1d1e 20097
wolfSSL 16:8e0d178b1d1e 20098 sp_256_from_mp(x, 8, xm);
wolfSSL 16:8e0d178b1d1e 20099 err = sp_256_mod_mul_norm_8(x, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 20100 }
wolfSSL 16:8e0d178b1d1e 20101 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 20102 /* y = x^3 */
wolfSSL 16:8e0d178b1d1e 20103 {
wolfSSL 16:8e0d178b1d1e 20104 sp_256_mont_sqr_8(y, x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20105 sp_256_mont_mul_8(y, y, x, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20106 }
wolfSSL 16:8e0d178b1d1e 20107 /* y = x^3 - 3x */
wolfSSL 16:8e0d178b1d1e 20108 sp_256_mont_sub_8(y, y, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 20109 sp_256_mont_sub_8(y, y, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 20110 sp_256_mont_sub_8(y, y, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 20111 /* y = x^3 - 3x + b */
wolfSSL 16:8e0d178b1d1e 20112 err = sp_256_mod_mul_norm_8(x, p256_b, p256_mod);
wolfSSL 16:8e0d178b1d1e 20113 }
wolfSSL 16:8e0d178b1d1e 20114 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 20115 sp_256_mont_add_8(y, y, x, p256_mod);
wolfSSL 16:8e0d178b1d1e 20116 /* y = sqrt(x^3 - 3x + b) */
wolfSSL 16:8e0d178b1d1e 20117 err = sp_256_mont_sqrt_8(y);
wolfSSL 16:8e0d178b1d1e 20118 }
wolfSSL 16:8e0d178b1d1e 20119 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 20120 XMEMSET(y + 8, 0, 8U * sizeof(sp_digit));
wolfSSL 16:8e0d178b1d1e 20121 sp_256_mont_reduce_8(y, p256_mod, p256_mp_mod);
wolfSSL 16:8e0d178b1d1e 20122 if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {
wolfSSL 16:8e0d178b1d1e 20123 sp_256_mont_sub_8(y, p256_mod, y, p256_mod);
wolfSSL 16:8e0d178b1d1e 20124 }
wolfSSL 16:8e0d178b1d1e 20125
wolfSSL 16:8e0d178b1d1e 20126 err = sp_256_to_mp(y, ym);
wolfSSL 16:8e0d178b1d1e 20127 }
wolfSSL 16:8e0d178b1d1e 20128
wolfSSL 16:8e0d178b1d1e 20129 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20130 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 20131 XFREE(d, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 20132 }
wolfSSL 16:8e0d178b1d1e 20133 #endif
wolfSSL 16:8e0d178b1d1e 20134
wolfSSL 16:8e0d178b1d1e 20135 return err;
wolfSSL 16:8e0d178b1d1e 20136 }
wolfSSL 16:8e0d178b1d1e 20137 #endif
wolfSSL 16:8e0d178b1d1e 20138 #endif /* !WOLFSSL_SP_NO_256 */
wolfSSL 16:8e0d178b1d1e 20139 #ifdef WOLFSSL_SP_384
wolfSSL 16:8e0d178b1d1e 20140
wolfSSL 16:8e0d178b1d1e 20141 /* Point structure to use. */
wolfSSL 16:8e0d178b1d1e 20142 typedef struct sp_point_384 {
wolfSSL 16:8e0d178b1d1e 20143 sp_digit x[2 * 12];
wolfSSL 16:8e0d178b1d1e 20144 sp_digit y[2 * 12];
wolfSSL 16:8e0d178b1d1e 20145 sp_digit z[2 * 12];
wolfSSL 16:8e0d178b1d1e 20146 int infinity;
wolfSSL 16:8e0d178b1d1e 20147 } sp_point_384;
wolfSSL 16:8e0d178b1d1e 20148
wolfSSL 16:8e0d178b1d1e 20149 /* The modulus (prime) of the curve P384. */
wolfSSL 16:8e0d178b1d1e 20150 static const sp_digit p384_mod[12] = {
wolfSSL 16:8e0d178b1d1e 20151 0xffffffff,0x00000000,0x00000000,0xffffffff,0xfffffffe,0xffffffff,
wolfSSL 16:8e0d178b1d1e 20152 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
wolfSSL 16:8e0d178b1d1e 20153 };
wolfSSL 16:8e0d178b1d1e 20154 /* The Montogmery normalizer for modulus of the curve P384. */
wolfSSL 16:8e0d178b1d1e 20155 static const sp_digit p384_norm_mod[12] = {
wolfSSL 16:8e0d178b1d1e 20156 0x00000001,0xffffffff,0xffffffff,0x00000000,0x00000001,0x00000000,
wolfSSL 16:8e0d178b1d1e 20157 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000
wolfSSL 16:8e0d178b1d1e 20158 };
wolfSSL 16:8e0d178b1d1e 20159 /* The Montogmery multiplier for modulus of the curve P384. */
wolfSSL 16:8e0d178b1d1e 20160 static sp_digit p384_mp_mod = 0x00000001;
wolfSSL 16:8e0d178b1d1e 20161 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
wolfSSL 16:8e0d178b1d1e 20162 defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 20163 /* The order of the curve P384. */
wolfSSL 16:8e0d178b1d1e 20164 static const sp_digit p384_order[12] = {
wolfSSL 16:8e0d178b1d1e 20165 0xccc52973,0xecec196a,0x48b0a77a,0x581a0db2,0xf4372ddf,0xc7634d81,
wolfSSL 16:8e0d178b1d1e 20166 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
wolfSSL 16:8e0d178b1d1e 20167 };
wolfSSL 16:8e0d178b1d1e 20168 #endif
wolfSSL 16:8e0d178b1d1e 20169 /* The order of the curve P384 minus 2. */
wolfSSL 16:8e0d178b1d1e 20170 static const sp_digit p384_order2[12] = {
wolfSSL 16:8e0d178b1d1e 20171 0xccc52971,0xecec196a,0x48b0a77a,0x581a0db2,0xf4372ddf,0xc7634d81,
wolfSSL 16:8e0d178b1d1e 20172 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
wolfSSL 16:8e0d178b1d1e 20173 };
wolfSSL 16:8e0d178b1d1e 20174 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 20175 /* The Montogmery normalizer for order of the curve P384. */
wolfSSL 16:8e0d178b1d1e 20176 static const sp_digit p384_norm_order[12] = {
wolfSSL 16:8e0d178b1d1e 20177 0x333ad68d,0x1313e695,0xb74f5885,0xa7e5f24d,0x0bc8d220,0x389cb27e,
wolfSSL 16:8e0d178b1d1e 20178 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000
wolfSSL 16:8e0d178b1d1e 20179 };
wolfSSL 16:8e0d178b1d1e 20180 #endif
wolfSSL 16:8e0d178b1d1e 20181 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 20182 /* The Montogmery multiplier for order of the curve P384. */
wolfSSL 16:8e0d178b1d1e 20183 static sp_digit p384_mp_order = 0xe88fdc45;
wolfSSL 16:8e0d178b1d1e 20184 #endif
wolfSSL 16:8e0d178b1d1e 20185 /* The base point of curve P384. */
wolfSSL 16:8e0d178b1d1e 20186 static const sp_point_384 p384_base = {
wolfSSL 16:8e0d178b1d1e 20187 /* X ordinate */
wolfSSL 16:8e0d178b1d1e 20188 {
wolfSSL 16:8e0d178b1d1e 20189 0x72760ab7,0x3a545e38,0xbf55296c,0x5502f25d,0x82542a38,0x59f741e0,
wolfSSL 16:8e0d178b1d1e 20190 0x8ba79b98,0x6e1d3b62,0xf320ad74,0x8eb1c71e,0xbe8b0537,0xaa87ca22,
wolfSSL 16:8e0d178b1d1e 20191 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
wolfSSL 16:8e0d178b1d1e 20192 },
wolfSSL 16:8e0d178b1d1e 20193 /* Y ordinate */
wolfSSL 16:8e0d178b1d1e 20194 {
wolfSSL 16:8e0d178b1d1e 20195 0x90ea0e5f,0x7a431d7c,0x1d7e819d,0x0a60b1ce,0xb5f0b8c0,0xe9da3113,
wolfSSL 16:8e0d178b1d1e 20196 0x289a147c,0xf8f41dbd,0x9292dc29,0x5d9e98bf,0x96262c6f,0x3617de4a,
wolfSSL 16:8e0d178b1d1e 20197 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
wolfSSL 16:8e0d178b1d1e 20198 },
wolfSSL 16:8e0d178b1d1e 20199 /* Z ordinate */
wolfSSL 16:8e0d178b1d1e 20200 {
wolfSSL 16:8e0d178b1d1e 20201 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
wolfSSL 16:8e0d178b1d1e 20202 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
wolfSSL 16:8e0d178b1d1e 20203 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
wolfSSL 16:8e0d178b1d1e 20204 },
wolfSSL 16:8e0d178b1d1e 20205 /* infinity */
wolfSSL 16:8e0d178b1d1e 20206 0
wolfSSL 16:8e0d178b1d1e 20207 };
wolfSSL 16:8e0d178b1d1e 20208 #if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)
wolfSSL 16:8e0d178b1d1e 20209 static const sp_digit p384_b[12] = {
wolfSSL 16:8e0d178b1d1e 20210 0xd3ec2aef,0x2a85c8ed,0x8a2ed19d,0xc656398d,0x5013875a,0x0314088f,
wolfSSL 16:8e0d178b1d1e 20211 0xfe814112,0x181d9c6e,0xe3f82d19,0x988e056b,0xe23ee7e4,0xb3312fa7
wolfSSL 16:8e0d178b1d1e 20212 };
wolfSSL 16:8e0d178b1d1e 20213 #endif
wolfSSL 16:8e0d178b1d1e 20214
wolfSSL 16:8e0d178b1d1e 20215 static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, sp_point_384** p)
wolfSSL 16:8e0d178b1d1e 20216 {
wolfSSL 16:8e0d178b1d1e 20217 int ret = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 20218 (void)heap;
wolfSSL 16:8e0d178b1d1e 20219 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20220 (void)sp;
wolfSSL 16:8e0d178b1d1e 20221 *p = (sp_point_384*)XMALLOC(sizeof(sp_point_384), heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 20222 #else
wolfSSL 16:8e0d178b1d1e 20223 *p = sp;
wolfSSL 16:8e0d178b1d1e 20224 #endif
wolfSSL 16:8e0d178b1d1e 20225 if (*p == NULL) {
wolfSSL 16:8e0d178b1d1e 20226 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 20227 }
wolfSSL 16:8e0d178b1d1e 20228 return ret;
wolfSSL 16:8e0d178b1d1e 20229 }
wolfSSL 16:8e0d178b1d1e 20230
wolfSSL 16:8e0d178b1d1e 20231 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20232 /* Allocate memory for point and return error. */
wolfSSL 16:8e0d178b1d1e 20233 #define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), NULL, &(p))
wolfSSL 16:8e0d178b1d1e 20234 #else
wolfSSL 16:8e0d178b1d1e 20235 /* Set pointer to data and return no error. */
wolfSSL 16:8e0d178b1d1e 20236 #define sp_384_point_new_12(heap, sp, p) sp_384_point_new_ex_12((heap), &(sp), &(p))
wolfSSL 16:8e0d178b1d1e 20237 #endif
wolfSSL 16:8e0d178b1d1e 20238
wolfSSL 16:8e0d178b1d1e 20239
wolfSSL 16:8e0d178b1d1e 20240 static void sp_384_point_free_12(sp_point_384* p, int clear, void* heap)
wolfSSL 16:8e0d178b1d1e 20241 {
wolfSSL 16:8e0d178b1d1e 20242 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20243 /* If valid pointer then clear point data if requested and free data. */
wolfSSL 16:8e0d178b1d1e 20244 if (p != NULL) {
wolfSSL 16:8e0d178b1d1e 20245 if (clear != 0) {
wolfSSL 16:8e0d178b1d1e 20246 XMEMSET(p, 0, sizeof(*p));
wolfSSL 16:8e0d178b1d1e 20247 }
wolfSSL 16:8e0d178b1d1e 20248 XFREE(p, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 20249 }
wolfSSL 16:8e0d178b1d1e 20250 #else
wolfSSL 16:8e0d178b1d1e 20251 /* Clear point data if requested. */
wolfSSL 16:8e0d178b1d1e 20252 if (clear != 0) {
wolfSSL 16:8e0d178b1d1e 20253 XMEMSET(p, 0, sizeof(*p));
wolfSSL 16:8e0d178b1d1e 20254 }
wolfSSL 16:8e0d178b1d1e 20255 #endif
wolfSSL 16:8e0d178b1d1e 20256 (void)heap;
wolfSSL 16:8e0d178b1d1e 20257 }
wolfSSL 16:8e0d178b1d1e 20258
wolfSSL 16:8e0d178b1d1e 20259 /* Multiply a number by Montogmery normalizer mod modulus (prime).
wolfSSL 16:8e0d178b1d1e 20260 *
wolfSSL 16:8e0d178b1d1e 20261 * r The resulting Montgomery form number.
wolfSSL 16:8e0d178b1d1e 20262 * a The number to convert.
wolfSSL 16:8e0d178b1d1e 20263 * m The modulus (prime).
wolfSSL 16:8e0d178b1d1e 20264 * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 20265 */
wolfSSL 16:8e0d178b1d1e 20266 static int sp_384_mod_mul_norm_12(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 20267 {
wolfSSL 16:8e0d178b1d1e 20268 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20269 int64_t* t;
wolfSSL 16:8e0d178b1d1e 20270 #else
wolfSSL 16:8e0d178b1d1e 20271 int64_t t[12];
wolfSSL 16:8e0d178b1d1e 20272 #endif
wolfSSL 16:8e0d178b1d1e 20273 int64_t o;
wolfSSL 16:8e0d178b1d1e 20274 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 20275
wolfSSL 16:8e0d178b1d1e 20276 (void)m;
wolfSSL 16:8e0d178b1d1e 20277
wolfSSL 16:8e0d178b1d1e 20278 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20279 t = (int64_t*)XMALLOC(sizeof(int64_t) * 12, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 20280 if (t == NULL) {
wolfSSL 16:8e0d178b1d1e 20281 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 20282 }
wolfSSL 16:8e0d178b1d1e 20283 #endif
wolfSSL 16:8e0d178b1d1e 20284
wolfSSL 16:8e0d178b1d1e 20285 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 20286 /* 1 0 0 0 0 0 0 0 1 1 0 -1 */
wolfSSL 16:8e0d178b1d1e 20287 t[0] = 0 + (uint64_t)a[0] + (uint64_t)a[8] + (uint64_t)a[9] - (uint64_t)a[11];
wolfSSL 16:8e0d178b1d1e 20288 /* -1 1 0 0 0 0 0 0 -1 0 1 1 */
wolfSSL 16:8e0d178b1d1e 20289 t[1] = 0 - (uint64_t)a[0] + (uint64_t)a[1] - (uint64_t)a[8] + (uint64_t)a[10] + (uint64_t)a[11];
wolfSSL 16:8e0d178b1d1e 20290 /* 0 -1 1 0 0 0 0 0 0 -1 0 1 */
wolfSSL 16:8e0d178b1d1e 20291 t[2] = 0 - (uint64_t)a[1] + (uint64_t)a[2] - (uint64_t)a[9] + (uint64_t)a[11];
wolfSSL 16:8e0d178b1d1e 20292 /* 1 0 -1 1 0 0 0 0 1 1 -1 -1 */
wolfSSL 16:8e0d178b1d1e 20293 t[3] = 0 + (uint64_t)a[0] - (uint64_t)a[2] + (uint64_t)a[3] + (uint64_t)a[8] + (uint64_t)a[9] - (uint64_t)a[10] - (uint64_t)a[11];
wolfSSL 16:8e0d178b1d1e 20294 /* 1 1 0 -1 1 0 0 0 1 2 1 -2 */
wolfSSL 16:8e0d178b1d1e 20295 t[4] = 0 + (uint64_t)a[0] + (uint64_t)a[1] - (uint64_t)a[3] + (uint64_t)a[4] + (uint64_t)a[8] + 2 * (uint64_t)a[9] + (uint64_t)a[10] - 2 * (uint64_t)a[11];
wolfSSL 16:8e0d178b1d1e 20296 /* 0 1 1 0 -1 1 0 0 0 1 2 1 */
wolfSSL 16:8e0d178b1d1e 20297 t[5] = 0 + (uint64_t)a[1] + (uint64_t)a[2] - (uint64_t)a[4] + (uint64_t)a[5] + (uint64_t)a[9] + 2 * (uint64_t)a[10] + (uint64_t)a[11];
wolfSSL 16:8e0d178b1d1e 20298 /* 0 0 1 1 0 -1 1 0 0 0 1 2 */
wolfSSL 16:8e0d178b1d1e 20299 t[6] = 0 + (uint64_t)a[2] + (uint64_t)a[3] - (uint64_t)a[5] + (uint64_t)a[6] + (uint64_t)a[10] + 2 * (uint64_t)a[11];
wolfSSL 16:8e0d178b1d1e 20300 /* 0 0 0 1 1 0 -1 1 0 0 0 1 */
wolfSSL 16:8e0d178b1d1e 20301 t[7] = 0 + (uint64_t)a[3] + (uint64_t)a[4] - (uint64_t)a[6] + (uint64_t)a[7] + (uint64_t)a[11];
wolfSSL 16:8e0d178b1d1e 20302 /* 0 0 0 0 1 1 0 -1 1 0 0 0 */
wolfSSL 16:8e0d178b1d1e 20303 t[8] = 0 + (uint64_t)a[4] + (uint64_t)a[5] - (uint64_t)a[7] + (uint64_t)a[8];
wolfSSL 16:8e0d178b1d1e 20304 /* 0 0 0 0 0 1 1 0 -1 1 0 0 */
wolfSSL 16:8e0d178b1d1e 20305 t[9] = 0 + (uint64_t)a[5] + (uint64_t)a[6] - (uint64_t)a[8] + (uint64_t)a[9];
wolfSSL 16:8e0d178b1d1e 20306 /* 0 0 0 0 0 0 1 1 0 -1 1 0 */
wolfSSL 16:8e0d178b1d1e 20307 t[10] = 0 + (uint64_t)a[6] + (uint64_t)a[7] - (uint64_t)a[9] + (uint64_t)a[10];
wolfSSL 16:8e0d178b1d1e 20308 /* 0 0 0 0 0 0 0 1 1 0 -1 1 */
wolfSSL 16:8e0d178b1d1e 20309 t[11] = 0 + (uint64_t)a[7] + (uint64_t)a[8] - (uint64_t)a[10] + (uint64_t)a[11];
wolfSSL 16:8e0d178b1d1e 20310
wolfSSL 16:8e0d178b1d1e 20311 t[1] += t[0] >> 32; t[0] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20312 t[2] += t[1] >> 32; t[1] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20313 t[3] += t[2] >> 32; t[2] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20314 t[4] += t[3] >> 32; t[3] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20315 t[5] += t[4] >> 32; t[4] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20316 t[6] += t[5] >> 32; t[5] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20317 t[7] += t[6] >> 32; t[6] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20318 t[8] += t[7] >> 32; t[7] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20319 t[9] += t[8] >> 32; t[8] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20320 t[10] += t[9] >> 32; t[9] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20321 t[11] += t[10] >> 32; t[10] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20322 o = t[11] >> 32; t[11] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20323 t[0] += o;
wolfSSL 16:8e0d178b1d1e 20324 t[1] -= o;
wolfSSL 16:8e0d178b1d1e 20325 t[3] += o;
wolfSSL 16:8e0d178b1d1e 20326 t[4] += o;
wolfSSL 16:8e0d178b1d1e 20327 t[1] += t[0] >> 32; t[0] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20328 t[2] += t[1] >> 32; t[1] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20329 t[3] += t[2] >> 32; t[2] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20330 t[4] += t[3] >> 32; t[3] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20331 t[5] += t[4] >> 32; t[4] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20332 t[6] += t[5] >> 32; t[5] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20333 t[7] += t[6] >> 32; t[6] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20334 t[8] += t[7] >> 32; t[7] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20335 t[9] += t[8] >> 32; t[8] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20336 t[10] += t[9] >> 32; t[9] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20337 t[11] += t[10] >> 32; t[10] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20338
wolfSSL 16:8e0d178b1d1e 20339 r[0] = t[0];
wolfSSL 16:8e0d178b1d1e 20340 r[1] = t[1];
wolfSSL 16:8e0d178b1d1e 20341 r[2] = t[2];
wolfSSL 16:8e0d178b1d1e 20342 r[3] = t[3];
wolfSSL 16:8e0d178b1d1e 20343 r[4] = t[4];
wolfSSL 16:8e0d178b1d1e 20344 r[5] = t[5];
wolfSSL 16:8e0d178b1d1e 20345 r[6] = t[6];
wolfSSL 16:8e0d178b1d1e 20346 r[7] = t[7];
wolfSSL 16:8e0d178b1d1e 20347 r[8] = t[8];
wolfSSL 16:8e0d178b1d1e 20348 r[9] = t[9];
wolfSSL 16:8e0d178b1d1e 20349 r[10] = t[10];
wolfSSL 16:8e0d178b1d1e 20350 r[11] = t[11];
wolfSSL 16:8e0d178b1d1e 20351 }
wolfSSL 16:8e0d178b1d1e 20352
wolfSSL 16:8e0d178b1d1e 20353 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 20354 if (t != NULL)
wolfSSL 16:8e0d178b1d1e 20355 XFREE(t, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 20356 #endif
wolfSSL 16:8e0d178b1d1e 20357
wolfSSL 16:8e0d178b1d1e 20358 return err;
wolfSSL 16:8e0d178b1d1e 20359 }
wolfSSL 16:8e0d178b1d1e 20360
wolfSSL 16:8e0d178b1d1e 20361 /* Convert an mp_int to an array of sp_digit.
wolfSSL 16:8e0d178b1d1e 20362 *
wolfSSL 16:8e0d178b1d1e 20363 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 20364 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 20365 * a A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 20366 */
wolfSSL 16:8e0d178b1d1e 20367 static void sp_384_from_mp(sp_digit* r, int size, const mp_int* a)
wolfSSL 16:8e0d178b1d1e 20368 {
wolfSSL 16:8e0d178b1d1e 20369 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 20370 int j;
wolfSSL 16:8e0d178b1d1e 20371
wolfSSL 16:8e0d178b1d1e 20372 XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);
wolfSSL 16:8e0d178b1d1e 20373
wolfSSL 16:8e0d178b1d1e 20374 for (j = a->used; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 20375 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 20376 }
wolfSSL 16:8e0d178b1d1e 20377 #elif DIGIT_BIT > 32
wolfSSL 16:8e0d178b1d1e 20378 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 20379 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 20380
wolfSSL 16:8e0d178b1d1e 20381 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 20382 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 20383 r[j] |= ((sp_digit)a->dp[i] << s);
wolfSSL 16:8e0d178b1d1e 20384 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20385 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 20386 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 20387 break;
wolfSSL 16:8e0d178b1d1e 20388 }
wolfSSL 16:8e0d178b1d1e 20389 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 20390 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 20391 while ((s + 32U) <= (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 20392 s += 32U;
wolfSSL 16:8e0d178b1d1e 20393 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20394 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 20395 break;
wolfSSL 16:8e0d178b1d1e 20396 }
wolfSSL 16:8e0d178b1d1e 20397 if (s < (word32)DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 20398 /* lint allow cast of mismatch word32 and mp_digit */
wolfSSL 16:8e0d178b1d1e 20399 r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 20400 }
wolfSSL 16:8e0d178b1d1e 20401 else {
wolfSSL 16:8e0d178b1d1e 20402 r[++j] = 0L;
wolfSSL 16:8e0d178b1d1e 20403 }
wolfSSL 16:8e0d178b1d1e 20404 }
wolfSSL 16:8e0d178b1d1e 20405 s = (word32)DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 20406 }
wolfSSL 16:8e0d178b1d1e 20407
wolfSSL 16:8e0d178b1d1e 20408 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 20409 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 20410 }
wolfSSL 16:8e0d178b1d1e 20411 #else
wolfSSL 16:8e0d178b1d1e 20412 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 20413
wolfSSL 16:8e0d178b1d1e 20414 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 20415 for (i = 0; i < a->used && j < size; i++) {
wolfSSL 16:8e0d178b1d1e 20416 r[j] |= ((sp_digit)a->dp[i]) << s;
wolfSSL 16:8e0d178b1d1e 20417 if (s + DIGIT_BIT >= 32) {
wolfSSL 16:8e0d178b1d1e 20418 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 20419 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 20420 break;
wolfSSL 16:8e0d178b1d1e 20421 }
wolfSSL 16:8e0d178b1d1e 20422 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 20423 if (s == DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 20424 r[++j] = 0;
wolfSSL 16:8e0d178b1d1e 20425 s = 0;
wolfSSL 16:8e0d178b1d1e 20426 }
wolfSSL 16:8e0d178b1d1e 20427 else {
wolfSSL 16:8e0d178b1d1e 20428 r[++j] = a->dp[i] >> s;
wolfSSL 16:8e0d178b1d1e 20429 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 20430 }
wolfSSL 16:8e0d178b1d1e 20431 }
wolfSSL 16:8e0d178b1d1e 20432 else {
wolfSSL 16:8e0d178b1d1e 20433 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 20434 }
wolfSSL 16:8e0d178b1d1e 20435 }
wolfSSL 16:8e0d178b1d1e 20436
wolfSSL 16:8e0d178b1d1e 20437 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 20438 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 20439 }
wolfSSL 16:8e0d178b1d1e 20440 #endif
wolfSSL 16:8e0d178b1d1e 20441 }
wolfSSL 16:8e0d178b1d1e 20442
wolfSSL 16:8e0d178b1d1e 20443 /* Convert a point of type ecc_point to type sp_point_384.
wolfSSL 16:8e0d178b1d1e 20444 *
wolfSSL 16:8e0d178b1d1e 20445 * p Point of type sp_point_384 (result).
wolfSSL 16:8e0d178b1d1e 20446 * pm Point of type ecc_point.
wolfSSL 16:8e0d178b1d1e 20447 */
wolfSSL 16:8e0d178b1d1e 20448 static void sp_384_point_from_ecc_point_12(sp_point_384* p, const ecc_point* pm)
wolfSSL 16:8e0d178b1d1e 20449 {
wolfSSL 16:8e0d178b1d1e 20450 XMEMSET(p->x, 0, sizeof(p->x));
wolfSSL 16:8e0d178b1d1e 20451 XMEMSET(p->y, 0, sizeof(p->y));
wolfSSL 16:8e0d178b1d1e 20452 XMEMSET(p->z, 0, sizeof(p->z));
wolfSSL 16:8e0d178b1d1e 20453 sp_384_from_mp(p->x, 12, pm->x);
wolfSSL 16:8e0d178b1d1e 20454 sp_384_from_mp(p->y, 12, pm->y);
wolfSSL 16:8e0d178b1d1e 20455 sp_384_from_mp(p->z, 12, pm->z);
wolfSSL 16:8e0d178b1d1e 20456 p->infinity = 0;
wolfSSL 16:8e0d178b1d1e 20457 }
wolfSSL 16:8e0d178b1d1e 20458
wolfSSL 16:8e0d178b1d1e 20459 /* Convert an array of sp_digit to an mp_int.
wolfSSL 16:8e0d178b1d1e 20460 *
wolfSSL 16:8e0d178b1d1e 20461 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 20462 * r A multi-precision integer.
wolfSSL 16:8e0d178b1d1e 20463 */
wolfSSL 16:8e0d178b1d1e 20464 static int sp_384_to_mp(const sp_digit* a, mp_int* r)
wolfSSL 16:8e0d178b1d1e 20465 {
wolfSSL 16:8e0d178b1d1e 20466 int err;
wolfSSL 16:8e0d178b1d1e 20467
wolfSSL 16:8e0d178b1d1e 20468 err = mp_grow(r, (384 + DIGIT_BIT - 1) / DIGIT_BIT);
wolfSSL 16:8e0d178b1d1e 20469 if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/
wolfSSL 16:8e0d178b1d1e 20470 #if DIGIT_BIT == 32
wolfSSL 16:8e0d178b1d1e 20471 XMEMCPY(r->dp, a, sizeof(sp_digit) * 12);
wolfSSL 16:8e0d178b1d1e 20472 r->used = 12;
wolfSSL 16:8e0d178b1d1e 20473 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 20474 #elif DIGIT_BIT < 32
wolfSSL 16:8e0d178b1d1e 20475 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 20476
wolfSSL 16:8e0d178b1d1e 20477 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 20478 for (i = 0; i < 12; i++) {
wolfSSL 16:8e0d178b1d1e 20479 r->dp[j] |= (mp_digit)(a[i] << s);
wolfSSL 16:8e0d178b1d1e 20480 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 20481 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 20482 r->dp[++j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 20483 while (s + DIGIT_BIT <= 32) {
wolfSSL 16:8e0d178b1d1e 20484 s += DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 20485 r->dp[j++] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 20486 if (s == SP_WORD_SIZE) {
wolfSSL 16:8e0d178b1d1e 20487 r->dp[j] = 0;
wolfSSL 16:8e0d178b1d1e 20488 }
wolfSSL 16:8e0d178b1d1e 20489 else {
wolfSSL 16:8e0d178b1d1e 20490 r->dp[j] = (mp_digit)(a[i] >> s);
wolfSSL 16:8e0d178b1d1e 20491 }
wolfSSL 16:8e0d178b1d1e 20492 }
wolfSSL 16:8e0d178b1d1e 20493 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 20494 }
wolfSSL 16:8e0d178b1d1e 20495 r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 20496 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 20497 #else
wolfSSL 16:8e0d178b1d1e 20498 int i, j = 0, s = 0;
wolfSSL 16:8e0d178b1d1e 20499
wolfSSL 16:8e0d178b1d1e 20500 r->dp[0] = 0;
wolfSSL 16:8e0d178b1d1e 20501 for (i = 0; i < 12; i++) {
wolfSSL 16:8e0d178b1d1e 20502 r->dp[j] |= ((mp_digit)a[i]) << s;
wolfSSL 16:8e0d178b1d1e 20503 if (s + 32 >= DIGIT_BIT) {
wolfSSL 16:8e0d178b1d1e 20504 #if DIGIT_BIT != 32 && DIGIT_BIT != 64
wolfSSL 16:8e0d178b1d1e 20505 r->dp[j] &= (1L << DIGIT_BIT) - 1;
wolfSSL 16:8e0d178b1d1e 20506 #endif
wolfSSL 16:8e0d178b1d1e 20507 s = DIGIT_BIT - s;
wolfSSL 16:8e0d178b1d1e 20508 r->dp[++j] = a[i] >> s;
wolfSSL 16:8e0d178b1d1e 20509 s = 32 - s;
wolfSSL 16:8e0d178b1d1e 20510 }
wolfSSL 16:8e0d178b1d1e 20511 else {
wolfSSL 16:8e0d178b1d1e 20512 s += 32;
wolfSSL 16:8e0d178b1d1e 20513 }
wolfSSL 16:8e0d178b1d1e 20514 }
wolfSSL 16:8e0d178b1d1e 20515 r->used = (384 + DIGIT_BIT - 1) / DIGIT_BIT;
wolfSSL 16:8e0d178b1d1e 20516 mp_clamp(r);
wolfSSL 16:8e0d178b1d1e 20517 #endif
wolfSSL 16:8e0d178b1d1e 20518 }
wolfSSL 16:8e0d178b1d1e 20519
wolfSSL 16:8e0d178b1d1e 20520 return err;
wolfSSL 16:8e0d178b1d1e 20521 }
wolfSSL 16:8e0d178b1d1e 20522
wolfSSL 16:8e0d178b1d1e 20523 /* Convert a point of type sp_point_384 to type ecc_point.
wolfSSL 16:8e0d178b1d1e 20524 *
wolfSSL 16:8e0d178b1d1e 20525 * p Point of type sp_point_384.
wolfSSL 16:8e0d178b1d1e 20526 * pm Point of type ecc_point (result).
wolfSSL 16:8e0d178b1d1e 20527 * returns MEMORY_E when allocation of memory in ecc_point fails otherwise
wolfSSL 16:8e0d178b1d1e 20528 * MP_OKAY.
wolfSSL 16:8e0d178b1d1e 20529 */
wolfSSL 16:8e0d178b1d1e 20530 static int sp_384_point_to_ecc_point_12(const sp_point_384* p, ecc_point* pm)
wolfSSL 16:8e0d178b1d1e 20531 {
wolfSSL 16:8e0d178b1d1e 20532 int err;
wolfSSL 16:8e0d178b1d1e 20533
wolfSSL 16:8e0d178b1d1e 20534 err = sp_384_to_mp(p->x, pm->x);
wolfSSL 16:8e0d178b1d1e 20535 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 20536 err = sp_384_to_mp(p->y, pm->y);
wolfSSL 16:8e0d178b1d1e 20537 }
wolfSSL 16:8e0d178b1d1e 20538 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 20539 err = sp_384_to_mp(p->z, pm->z);
wolfSSL 16:8e0d178b1d1e 20540 }
wolfSSL 16:8e0d178b1d1e 20541
wolfSSL 16:8e0d178b1d1e 20542 return err;
wolfSSL 16:8e0d178b1d1e 20543 }
wolfSSL 16:8e0d178b1d1e 20544
wolfSSL 16:8e0d178b1d1e 20545 /* Multiply a and b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 20546 *
wolfSSL 16:8e0d178b1d1e 20547 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 20548 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 20549 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 20550 */
wolfSSL 16:8e0d178b1d1e 20551 SP_NOINLINE static void sp_384_mul_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 20552 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 20553 {
wolfSSL 16:8e0d178b1d1e 20554 sp_digit tmp[12 * 2];
wolfSSL 16:8e0d178b1d1e 20555 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 20556 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20557 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20558 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 20559 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 20560 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20561 "mov r11, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 20562 "mov r6, #48\n\t"
wolfSSL 16:8e0d178b1d1e 20563 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 20564 "mov r14, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20565 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 20566 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 20567 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20568 "mov r6, #44\n\t"
wolfSSL 16:8e0d178b1d1e 20569 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 20570 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 20571 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20572 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20573 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 20574 "mov %[b], r9\n\t"
wolfSSL 16:8e0d178b1d1e 20575 "sub %[b], %[b], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20576 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 20577 "add %[b], %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 20578 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 20579 /* Multiply Start */
wolfSSL 16:8e0d178b1d1e 20580 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 20581 "ldr r8, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 20582 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20583 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20584 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20585 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 20586 /* Multiply Done */
wolfSSL 16:8e0d178b1d1e 20587 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 20588 "sub %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 20589 "cmp %[a], r14\n\t"
wolfSSL 16:8e0d178b1d1e 20590 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 20591 "mov r6, r9\n\t"
wolfSSL 16:8e0d178b1d1e 20592 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 20593 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 20594 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 20595 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 20596 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 20597 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 20598 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 20599 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 20600 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 20601 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 20602 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20603 "mov r6, #88\n\t"
wolfSSL 16:8e0d178b1d1e 20604 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20605 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 20606 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 20607 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 20608 "mov %[b], r11\n\t"
wolfSSL 16:8e0d178b1d1e 20609 :
wolfSSL 16:8e0d178b1d1e 20610 : [r] "r" (tmp), [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 20611 : "memory", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 20612 );
wolfSSL 16:8e0d178b1d1e 20613
wolfSSL 16:8e0d178b1d1e 20614 XMEMCPY(r, tmp, sizeof(tmp));
wolfSSL 16:8e0d178b1d1e 20615 }
wolfSSL 16:8e0d178b1d1e 20616
wolfSSL 16:8e0d178b1d1e 20617 /* Conditionally subtract b from a using the mask m.
wolfSSL 16:8e0d178b1d1e 20618 * m is -1 to subtract and 0 when not copying.
wolfSSL 16:8e0d178b1d1e 20619 *
wolfSSL 16:8e0d178b1d1e 20620 * r A single precision number representing condition subtract result.
wolfSSL 16:8e0d178b1d1e 20621 * a A single precision number to subtract from.
wolfSSL 16:8e0d178b1d1e 20622 * b A single precision number to subtract.
wolfSSL 16:8e0d178b1d1e 20623 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 20624 */
wolfSSL 16:8e0d178b1d1e 20625 SP_NOINLINE static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 20626 const sp_digit* b, sp_digit m)
wolfSSL 16:8e0d178b1d1e 20627 {
wolfSSL 16:8e0d178b1d1e 20628 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 20629
wolfSSL 16:8e0d178b1d1e 20630 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 20631 "mov r5, #48\n\t"
wolfSSL 16:8e0d178b1d1e 20632 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 20633 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20634 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 20635 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 20636 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 20637 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20638 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 20639 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 20640 "sbcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20641 "sbcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 20642 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 20643 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 20644 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 20645 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 20646 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 20647 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 20648 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 20649 );
wolfSSL 16:8e0d178b1d1e 20650
wolfSSL 16:8e0d178b1d1e 20651 return c;
wolfSSL 16:8e0d178b1d1e 20652 }
wolfSSL 16:8e0d178b1d1e 20653
wolfSSL 16:8e0d178b1d1e 20654 #define sp_384_mont_reduce_order_12 sp_384_mont_reduce_12
wolfSSL 16:8e0d178b1d1e 20655
wolfSSL 16:8e0d178b1d1e 20656 /* Reduce the number back to 384 bits using Montgomery reduction.
wolfSSL 16:8e0d178b1d1e 20657 *
wolfSSL 16:8e0d178b1d1e 20658 * a A single precision number to reduce in place.
wolfSSL 16:8e0d178b1d1e 20659 * m The single precision number representing the modulus.
wolfSSL 16:8e0d178b1d1e 20660 * mp The digit representing the negative inverse of m mod 2^n.
wolfSSL 16:8e0d178b1d1e 20661 */
wolfSSL 16:8e0d178b1d1e 20662 SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 20663 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 20664 {
wolfSSL 16:8e0d178b1d1e 20665 sp_digit ca = 0;
wolfSSL 16:8e0d178b1d1e 20666
wolfSSL 16:8e0d178b1d1e 20667 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 20668 "mov r9, %[mp]\n\t"
wolfSSL 16:8e0d178b1d1e 20669 "mov r12, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 20670 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20671 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20672 "add r11, r10, #48\n\t"
wolfSSL 16:8e0d178b1d1e 20673 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 20674 /* mu = a[i] * mp */
wolfSSL 16:8e0d178b1d1e 20675 "mov %[mp], r9\n\t"
wolfSSL 16:8e0d178b1d1e 20676 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 20677 "mul %[mp], %[mp], %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20678 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 20679 "add r14, r10, #40\n\t"
wolfSSL 16:8e0d178b1d1e 20680 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 20681 /* a[i+j] += m[j] * mu */
wolfSSL 16:8e0d178b1d1e 20682 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 20683 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20684 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 20685 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 20686 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 20687 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 20688 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20689 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 20690 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20691 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20692 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 20693 /* a[i+j+1] += m[j+1] * mu */
wolfSSL 16:8e0d178b1d1e 20694 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 20695 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20696 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 20697 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 20698 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 20699 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 20700 "adc r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20701 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 20702 "adds r5, r5, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20703 "adc r4, r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20704 "str r5, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 20705 "cmp r10, r14\n\t"
wolfSSL 16:8e0d178b1d1e 20706 "blt 2b\n\t"
wolfSSL 16:8e0d178b1d1e 20707 /* a[i+10] += m[10] * mu */
wolfSSL 16:8e0d178b1d1e 20708 "ldr %[a], [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 20709 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20710 /* Multiply m[j] and mu - Start */
wolfSSL 16:8e0d178b1d1e 20711 "ldr r8, [%[m]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 20712 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 20713 "adds %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 20714 "adc r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20715 /* Multiply m[j] and mu - Done */
wolfSSL 16:8e0d178b1d1e 20716 "adds r4, r4, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20717 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20718 "str r4, [r10], #4\n\t"
wolfSSL 16:8e0d178b1d1e 20719 /* a[i+11] += m[11] * mu */
wolfSSL 16:8e0d178b1d1e 20720 "mov r4, %[ca]\n\t"
wolfSSL 16:8e0d178b1d1e 20721 "mov %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 20722 /* Multiply m[11] and mu - Start */
wolfSSL 16:8e0d178b1d1e 20723 "ldr r8, [%[m]]\n\t"
wolfSSL 16:8e0d178b1d1e 20724 "umull r6, r8, %[mp], r8\n\t"
wolfSSL 16:8e0d178b1d1e 20725 "adds r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20726 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20727 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 20728 /* Multiply m[11] and mu - Done */
wolfSSL 16:8e0d178b1d1e 20729 "ldr r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 20730 "ldr r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 20731 "adds r6, r6, r5\n\t"
wolfSSL 16:8e0d178b1d1e 20732 "adcs r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 20733 "adc %[ca], %[ca], #0\n\t"
wolfSSL 16:8e0d178b1d1e 20734 "str r6, [r10]\n\t"
wolfSSL 16:8e0d178b1d1e 20735 "str r8, [r10, #4]\n\t"
wolfSSL 16:8e0d178b1d1e 20736 /* Next word in a */
wolfSSL 16:8e0d178b1d1e 20737 "sub r10, r10, #40\n\t"
wolfSSL 16:8e0d178b1d1e 20738 "cmp r10, r11\n\t"
wolfSSL 16:8e0d178b1d1e 20739 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 20740 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 20741 "mov %[m], r12\n\t"
wolfSSL 16:8e0d178b1d1e 20742 : [ca] "+r" (ca), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 20743 : [m] "r" (m), [mp] "r" (mp)
wolfSSL 16:8e0d178b1d1e 20744 : "memory", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12", "r14"
wolfSSL 16:8e0d178b1d1e 20745 );
wolfSSL 16:8e0d178b1d1e 20746
wolfSSL 16:8e0d178b1d1e 20747 sp_384_cond_sub_12(a - 12, a, m, (sp_digit)0 - ca);
wolfSSL 16:8e0d178b1d1e 20748 }
wolfSSL 16:8e0d178b1d1e 20749
wolfSSL 16:8e0d178b1d1e 20750 /* Multiply two Montogmery form numbers mod the modulus (prime).
wolfSSL 16:8e0d178b1d1e 20751 * (r = a * b mod m)
wolfSSL 16:8e0d178b1d1e 20752 *
wolfSSL 16:8e0d178b1d1e 20753 * r Result of multiplication.
wolfSSL 16:8e0d178b1d1e 20754 * a First number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 20755 * b Second number to multiply in Montogmery form.
wolfSSL 16:8e0d178b1d1e 20756 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 20757 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 20758 */
wolfSSL 16:8e0d178b1d1e 20759 static void sp_384_mont_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 20760 const sp_digit* m, sp_digit mp)
wolfSSL 16:8e0d178b1d1e 20761 {
wolfSSL 16:8e0d178b1d1e 20762 sp_384_mul_12(r, a, b);
wolfSSL 16:8e0d178b1d1e 20763 sp_384_mont_reduce_12(r, m, mp);
wolfSSL 16:8e0d178b1d1e 20764 }
wolfSSL 16:8e0d178b1d1e 20765
wolfSSL 16:8e0d178b1d1e 20766 /* Square a and put result in r. (r = a * a)
wolfSSL 16:8e0d178b1d1e 20767 *
wolfSSL 16:8e0d178b1d1e 20768 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 20769 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 20770 */
wolfSSL 16:8e0d178b1d1e 20771 SP_NOINLINE static void sp_384_sqr_12(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 20772 {
wolfSSL 16:8e0d178b1d1e 20773 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 20774 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20775 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20776 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20777 "mov r9, r3\n\t"
wolfSSL 16:8e0d178b1d1e 20778 "mov r12, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 20779 "mov r6, #96\n\t"
wolfSSL 16:8e0d178b1d1e 20780 "neg r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20781 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20782 "mov r11, sp\n\t"
wolfSSL 16:8e0d178b1d1e 20783 "mov r10, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20784 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 20785 "mov %[r], #0\n\t"
wolfSSL 16:8e0d178b1d1e 20786 "mov r6, #44\n\t"
wolfSSL 16:8e0d178b1d1e 20787 "mov %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 20788 "subs %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 20789 "sbc r6, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20790 "mvn r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20791 "and %[a], %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 20792 "mov r2, r9\n\t"
wolfSSL 16:8e0d178b1d1e 20793 "sub r2, r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20794 "add %[a], %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 20795 "add r2, r2, r10\n\t"
wolfSSL 16:8e0d178b1d1e 20796 "\n2:\n\t"
wolfSSL 16:8e0d178b1d1e 20797 "cmp r2, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 20798 "beq 4f\n\t"
wolfSSL 16:8e0d178b1d1e 20799 /* Multiply * 2: Start */
wolfSSL 16:8e0d178b1d1e 20800 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 20801 "ldr r8, [r2]\n\t"
wolfSSL 16:8e0d178b1d1e 20802 "umull r6, r8, r6, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20803 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20804 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20805 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 20806 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20807 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20808 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 20809 /* Multiply * 2: Done */
wolfSSL 16:8e0d178b1d1e 20810 "bal 5f\n\t"
wolfSSL 16:8e0d178b1d1e 20811 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 20812 /* Square: Start */
wolfSSL 16:8e0d178b1d1e 20813 "ldr r6, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 20814 "umull r6, r8, r6, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20815 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20816 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20817 "adc r5, r5, %[r]\n\t"
wolfSSL 16:8e0d178b1d1e 20818 /* Square: Done */
wolfSSL 16:8e0d178b1d1e 20819 "\n5:\n\t"
wolfSSL 16:8e0d178b1d1e 20820 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 20821 "sub r2, r2, #4\n\t"
wolfSSL 16:8e0d178b1d1e 20822 "mov r6, #48\n\t"
wolfSSL 16:8e0d178b1d1e 20823 "add r6, r6, r10\n\t"
wolfSSL 16:8e0d178b1d1e 20824 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 20825 "beq 3f\n\t"
wolfSSL 16:8e0d178b1d1e 20826 "cmp %[a], r2\n\t"
wolfSSL 16:8e0d178b1d1e 20827 "bgt 3f\n\t"
wolfSSL 16:8e0d178b1d1e 20828 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 20829 "add r8, r8, r10\n\t"
wolfSSL 16:8e0d178b1d1e 20830 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 20831 "ble 2b\n\t"
wolfSSL 16:8e0d178b1d1e 20832 "\n3:\n\t"
wolfSSL 16:8e0d178b1d1e 20833 "mov %[r], r11\n\t"
wolfSSL 16:8e0d178b1d1e 20834 "mov r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 20835 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 20836 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 20837 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 20838 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 20839 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 20840 "mov r9, r8\n\t"
wolfSSL 16:8e0d178b1d1e 20841 "mov r6, #88\n\t"
wolfSSL 16:8e0d178b1d1e 20842 "cmp r8, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20843 "ble 1b\n\t"
wolfSSL 16:8e0d178b1d1e 20844 "mov %[a], r10\n\t"
wolfSSL 16:8e0d178b1d1e 20845 "str r3, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 20846 "mov %[r], r12\n\t"
wolfSSL 16:8e0d178b1d1e 20847 "mov %[a], r11\n\t"
wolfSSL 16:8e0d178b1d1e 20848 "mov r3, #92\n\t"
wolfSSL 16:8e0d178b1d1e 20849 "\n4:\n\t"
wolfSSL 16:8e0d178b1d1e 20850 "ldr r6, [%[a], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 20851 "str r6, [%[r], r3]\n\t"
wolfSSL 16:8e0d178b1d1e 20852 "subs r3, r3, #4\n\t"
wolfSSL 16:8e0d178b1d1e 20853 "bge 4b\n\t"
wolfSSL 16:8e0d178b1d1e 20854 "mov r6, #96\n\t"
wolfSSL 16:8e0d178b1d1e 20855 "add sp, sp, r6\n\t"
wolfSSL 16:8e0d178b1d1e 20856 :
wolfSSL 16:8e0d178b1d1e 20857 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 20858 : "memory", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"
wolfSSL 16:8e0d178b1d1e 20859 );
wolfSSL 16:8e0d178b1d1e 20860 }
wolfSSL 16:8e0d178b1d1e 20861
wolfSSL 16:8e0d178b1d1e 20862 /* Square the Montgomery form number. (r = a * a mod m)
wolfSSL 16:8e0d178b1d1e 20863 *
wolfSSL 16:8e0d178b1d1e 20864 * r Result of squaring.
wolfSSL 16:8e0d178b1d1e 20865 * a Number to square in Montogmery form.
wolfSSL 16:8e0d178b1d1e 20866 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 20867 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 20868 */
wolfSSL 16:8e0d178b1d1e 20869 static void sp_384_mont_sqr_12(sp_digit* r, const sp_digit* a, const sp_digit* m,
wolfSSL 16:8e0d178b1d1e 20870 sp_digit mp)
wolfSSL 16:8e0d178b1d1e 20871 {
wolfSSL 16:8e0d178b1d1e 20872 sp_384_sqr_12(r, a);
wolfSSL 16:8e0d178b1d1e 20873 sp_384_mont_reduce_12(r, m, mp);
wolfSSL 16:8e0d178b1d1e 20874 }
wolfSSL 16:8e0d178b1d1e 20875
wolfSSL 16:8e0d178b1d1e 20876 #if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)
wolfSSL 16:8e0d178b1d1e 20877 /* Square the Montgomery form number a number of times. (r = a ^ n mod m)
wolfSSL 16:8e0d178b1d1e 20878 *
wolfSSL 16:8e0d178b1d1e 20879 * r Result of squaring.
wolfSSL 16:8e0d178b1d1e 20880 * a Number to square in Montogmery form.
wolfSSL 16:8e0d178b1d1e 20881 * n Number of times to square.
wolfSSL 16:8e0d178b1d1e 20882 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 20883 * mp Montogmery mulitplier.
wolfSSL 16:8e0d178b1d1e 20884 */
wolfSSL 16:8e0d178b1d1e 20885 static void sp_384_mont_sqr_n_12(sp_digit* r, const sp_digit* a, int n,
wolfSSL 16:8e0d178b1d1e 20886 const sp_digit* m, sp_digit mp)
wolfSSL 16:8e0d178b1d1e 20887 {
wolfSSL 16:8e0d178b1d1e 20888 sp_384_mont_sqr_12(r, a, m, mp);
wolfSSL 16:8e0d178b1d1e 20889 for (; n > 1; n--) {
wolfSSL 16:8e0d178b1d1e 20890 sp_384_mont_sqr_12(r, r, m, mp);
wolfSSL 16:8e0d178b1d1e 20891 }
wolfSSL 16:8e0d178b1d1e 20892 }
wolfSSL 16:8e0d178b1d1e 20893
wolfSSL 16:8e0d178b1d1e 20894 #endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */
wolfSSL 16:8e0d178b1d1e 20895 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 20896 /* Mod-2 for the P384 curve. */
wolfSSL 16:8e0d178b1d1e 20897 static const uint32_t p384_mod_minus_2[12] = {
wolfSSL 16:8e0d178b1d1e 20898 0xfffffffdU,0x00000000U,0x00000000U,0xffffffffU,0xfffffffeU,0xffffffffU,
wolfSSL 16:8e0d178b1d1e 20899 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU
wolfSSL 16:8e0d178b1d1e 20900 };
wolfSSL 16:8e0d178b1d1e 20901 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 20902
wolfSSL 16:8e0d178b1d1e 20903 /* Invert the number, in Montgomery form, modulo the modulus (prime) of the
wolfSSL 16:8e0d178b1d1e 20904 * P384 curve. (r = 1 / a mod m)
wolfSSL 16:8e0d178b1d1e 20905 *
wolfSSL 16:8e0d178b1d1e 20906 * r Inverse result.
wolfSSL 16:8e0d178b1d1e 20907 * a Number to invert.
wolfSSL 16:8e0d178b1d1e 20908 * td Temporary data.
wolfSSL 16:8e0d178b1d1e 20909 */
wolfSSL 16:8e0d178b1d1e 20910 static void sp_384_mont_inv_12(sp_digit* r, const sp_digit* a, sp_digit* td)
wolfSSL 16:8e0d178b1d1e 20911 {
wolfSSL 16:8e0d178b1d1e 20912 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 20913 sp_digit* t = td;
wolfSSL 16:8e0d178b1d1e 20914 int i;
wolfSSL 16:8e0d178b1d1e 20915
wolfSSL 16:8e0d178b1d1e 20916 XMEMCPY(t, a, sizeof(sp_digit) * 12);
wolfSSL 16:8e0d178b1d1e 20917 for (i=382; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 20918 sp_384_mont_sqr_12(t, t, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20919 if (p384_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32)))
wolfSSL 16:8e0d178b1d1e 20920 sp_384_mont_mul_12(t, t, a, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20921 }
wolfSSL 16:8e0d178b1d1e 20922 XMEMCPY(r, t, sizeof(sp_digit) * 12);
wolfSSL 16:8e0d178b1d1e 20923 #else
wolfSSL 16:8e0d178b1d1e 20924 sp_digit* t1 = td;
wolfSSL 16:8e0d178b1d1e 20925 sp_digit* t2 = td + 2 * 12;
wolfSSL 16:8e0d178b1d1e 20926 sp_digit* t3 = td + 4 * 12;
wolfSSL 16:8e0d178b1d1e 20927 sp_digit* t4 = td + 6 * 12;
wolfSSL 16:8e0d178b1d1e 20928 sp_digit* t5 = td + 8 * 12;
wolfSSL 16:8e0d178b1d1e 20929
wolfSSL 16:8e0d178b1d1e 20930 /* 0x2 */
wolfSSL 16:8e0d178b1d1e 20931 sp_384_mont_sqr_12(t1, a, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20932 /* 0x3 */
wolfSSL 16:8e0d178b1d1e 20933 sp_384_mont_mul_12(t5, t1, a, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20934 /* 0xc */
wolfSSL 16:8e0d178b1d1e 20935 sp_384_mont_sqr_n_12(t1, t5, 2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20936 /* 0xf */
wolfSSL 16:8e0d178b1d1e 20937 sp_384_mont_mul_12(t2, t5, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20938 /* 0x1e */
wolfSSL 16:8e0d178b1d1e 20939 sp_384_mont_sqr_12(t1, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20940 /* 0x1f */
wolfSSL 16:8e0d178b1d1e 20941 sp_384_mont_mul_12(t4, t1, a, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20942 /* 0x3e0 */
wolfSSL 16:8e0d178b1d1e 20943 sp_384_mont_sqr_n_12(t1, t4, 5, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20944 /* 0x3ff */
wolfSSL 16:8e0d178b1d1e 20945 sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20946 /* 0x7fe0 */
wolfSSL 16:8e0d178b1d1e 20947 sp_384_mont_sqr_n_12(t1, t2, 5, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20948 /* 0x7fff */
wolfSSL 16:8e0d178b1d1e 20949 sp_384_mont_mul_12(t4, t4, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20950 /* 0x3fff8000 */
wolfSSL 16:8e0d178b1d1e 20951 sp_384_mont_sqr_n_12(t1, t4, 15, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20952 /* 0x3fffffff */
wolfSSL 16:8e0d178b1d1e 20953 sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20954 /* 0xfffffffc */
wolfSSL 16:8e0d178b1d1e 20955 sp_384_mont_sqr_n_12(t3, t2, 2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20956 /* 0xfffffffd */
wolfSSL 16:8e0d178b1d1e 20957 sp_384_mont_mul_12(r, t3, a, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20958 /* 0xffffffff */
wolfSSL 16:8e0d178b1d1e 20959 sp_384_mont_mul_12(t3, t5, t3, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20960 /* 0xfffffffc0000000 */
wolfSSL 16:8e0d178b1d1e 20961 sp_384_mont_sqr_n_12(t1, t2, 30, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20962 /* 0xfffffffffffffff */
wolfSSL 16:8e0d178b1d1e 20963 sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20964 /* 0xfffffffffffffff000000000000000 */
wolfSSL 16:8e0d178b1d1e 20965 sp_384_mont_sqr_n_12(t1, t2, 60, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20966 /* 0xffffffffffffffffffffffffffffff */
wolfSSL 16:8e0d178b1d1e 20967 sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20968 /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */
wolfSSL 16:8e0d178b1d1e 20969 sp_384_mont_sqr_n_12(t1, t2, 120, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20970 /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
wolfSSL 16:8e0d178b1d1e 20971 sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20972 /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */
wolfSSL 16:8e0d178b1d1e 20973 sp_384_mont_sqr_n_12(t1, t2, 15, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20974 /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
wolfSSL 16:8e0d178b1d1e 20975 sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20976 /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */
wolfSSL 16:8e0d178b1d1e 20977 sp_384_mont_sqr_n_12(t1, t2, 33, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20978 /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */
wolfSSL 16:8e0d178b1d1e 20979 sp_384_mont_mul_12(t2, t3, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20980 /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */
wolfSSL 16:8e0d178b1d1e 20981 sp_384_mont_sqr_n_12(t1, t2, 96, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20982 /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */
wolfSSL 16:8e0d178b1d1e 20983 sp_384_mont_mul_12(r, r, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 20984
wolfSSL 16:8e0d178b1d1e 20985 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 20986 }
wolfSSL 16:8e0d178b1d1e 20987
wolfSSL 16:8e0d178b1d1e 20988 /* Compare a with b in constant time.
wolfSSL 16:8e0d178b1d1e 20989 *
wolfSSL 16:8e0d178b1d1e 20990 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 20991 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 20992 * return -ve, 0 or +ve if a is less than, equal to or greater than b
wolfSSL 16:8e0d178b1d1e 20993 * respectively.
wolfSSL 16:8e0d178b1d1e 20994 */
wolfSSL 16:8e0d178b1d1e 20995 SP_NOINLINE static int32_t sp_384_cmp_12(const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 20996 {
wolfSSL 16:8e0d178b1d1e 20997 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 20998
wolfSSL 16:8e0d178b1d1e 20999
wolfSSL 16:8e0d178b1d1e 21000 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 21001 "mov r3, #0\n\t"
wolfSSL 16:8e0d178b1d1e 21002 "mvn r3, r3\n\t"
wolfSSL 16:8e0d178b1d1e 21003 "mov r6, #44\n\t"
wolfSSL 16:8e0d178b1d1e 21004 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 21005 "ldr r8, [%[a], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 21006 "ldr r5, [%[b], r6]\n\t"
wolfSSL 16:8e0d178b1d1e 21007 "and r8, r8, r3\n\t"
wolfSSL 16:8e0d178b1d1e 21008 "and r5, r5, r3\n\t"
wolfSSL 16:8e0d178b1d1e 21009 "mov r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21010 "subs r8, r8, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21011 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21012 "add %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 21013 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21014 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21015 "subs r5, r5, r4\n\t"
wolfSSL 16:8e0d178b1d1e 21016 "sbc r8, r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21017 "sub %[r], %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 21018 "mvn r8, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21019 "and r3, r3, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21020 "sub r6, r6, #4\n\t"
wolfSSL 16:8e0d178b1d1e 21021 "cmp r6, #0\n\t"
wolfSSL 16:8e0d178b1d1e 21022 "bge 1b\n\t"
wolfSSL 16:8e0d178b1d1e 21023 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 21024 : [a] "r" (a), [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 21025 : "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 21026 );
wolfSSL 16:8e0d178b1d1e 21027
wolfSSL 16:8e0d178b1d1e 21028 return r;
wolfSSL 16:8e0d178b1d1e 21029 }
wolfSSL 16:8e0d178b1d1e 21030
wolfSSL 16:8e0d178b1d1e 21031 /* Normalize the values in each word to 32.
wolfSSL 16:8e0d178b1d1e 21032 *
wolfSSL 16:8e0d178b1d1e 21033 * a Array of sp_digit to normalize.
wolfSSL 16:8e0d178b1d1e 21034 */
wolfSSL 16:8e0d178b1d1e 21035 #define sp_384_norm_12(a)
wolfSSL 16:8e0d178b1d1e 21036
wolfSSL 16:8e0d178b1d1e 21037 /* Map the Montgomery form projective coordinate point to an affine point.
wolfSSL 16:8e0d178b1d1e 21038 *
wolfSSL 16:8e0d178b1d1e 21039 * r Resulting affine coordinate point.
wolfSSL 16:8e0d178b1d1e 21040 * p Montgomery form projective coordinate point.
wolfSSL 16:8e0d178b1d1e 21041 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 21042 */
wolfSSL 16:8e0d178b1d1e 21043 static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 21044 {
wolfSSL 16:8e0d178b1d1e 21045 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 21046 sp_digit* t2 = t + 2*12;
wolfSSL 16:8e0d178b1d1e 21047 int32_t n;
wolfSSL 16:8e0d178b1d1e 21048
wolfSSL 16:8e0d178b1d1e 21049 sp_384_mont_inv_12(t1, p->z, t + 2*12);
wolfSSL 16:8e0d178b1d1e 21050
wolfSSL 16:8e0d178b1d1e 21051 sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21052 sp_384_mont_mul_12(t1, t2, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21053
wolfSSL 16:8e0d178b1d1e 21054 /* x /= z^2 */
wolfSSL 16:8e0d178b1d1e 21055 sp_384_mont_mul_12(r->x, p->x, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21056 XMEMSET(r->x + 12, 0, sizeof(r->x) / 2U);
wolfSSL 16:8e0d178b1d1e 21057 sp_384_mont_reduce_12(r->x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21058 /* Reduce x to less than modulus */
wolfSSL 16:8e0d178b1d1e 21059 n = sp_384_cmp_12(r->x, p384_mod);
wolfSSL 16:8e0d178b1d1e 21060 sp_384_cond_sub_12(r->x, r->x, p384_mod, 0 - ((n >= 0) ?
wolfSSL 16:8e0d178b1d1e 21061 (sp_digit)1 : (sp_digit)0));
wolfSSL 16:8e0d178b1d1e 21062 sp_384_norm_12(r->x);
wolfSSL 16:8e0d178b1d1e 21063
wolfSSL 16:8e0d178b1d1e 21064 /* y /= z^3 */
wolfSSL 16:8e0d178b1d1e 21065 sp_384_mont_mul_12(r->y, p->y, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21066 XMEMSET(r->y + 12, 0, sizeof(r->y) / 2U);
wolfSSL 16:8e0d178b1d1e 21067 sp_384_mont_reduce_12(r->y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21068 /* Reduce y to less than modulus */
wolfSSL 16:8e0d178b1d1e 21069 n = sp_384_cmp_12(r->y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21070 sp_384_cond_sub_12(r->y, r->y, p384_mod, 0 - ((n >= 0) ?
wolfSSL 16:8e0d178b1d1e 21071 (sp_digit)1 : (sp_digit)0));
wolfSSL 16:8e0d178b1d1e 21072 sp_384_norm_12(r->y);
wolfSSL 16:8e0d178b1d1e 21073
wolfSSL 16:8e0d178b1d1e 21074 XMEMSET(r->z, 0, sizeof(r->z));
wolfSSL 16:8e0d178b1d1e 21075 r->z[0] = 1;
wolfSSL 16:8e0d178b1d1e 21076
wolfSSL 16:8e0d178b1d1e 21077 }
wolfSSL 16:8e0d178b1d1e 21078
wolfSSL 16:8e0d178b1d1e 21079 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 21080 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 21081 *
wolfSSL 16:8e0d178b1d1e 21082 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 21083 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 21084 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 21085 */
wolfSSL 16:8e0d178b1d1e 21086 SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 21087 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 21088 {
wolfSSL 16:8e0d178b1d1e 21089 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 21090
wolfSSL 16:8e0d178b1d1e 21091 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 21092 "mov r6, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 21093 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 21094 "add r6, r6, #48\n\t"
wolfSSL 16:8e0d178b1d1e 21095 "sub r8, r8, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21096 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 21097 "adds %[c], %[c], r8\n\t"
wolfSSL 16:8e0d178b1d1e 21098 "ldr r4, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 21099 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 21100 "adcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21101 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 21102 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 21103 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 21104 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 21105 "add %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 21106 "add %[r], %[r], #4\n\t"
wolfSSL 16:8e0d178b1d1e 21107 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 21108 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 21109 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 21110 :
wolfSSL 16:8e0d178b1d1e 21111 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 21112 );
wolfSSL 16:8e0d178b1d1e 21113
wolfSSL 16:8e0d178b1d1e 21114 return c;
wolfSSL 16:8e0d178b1d1e 21115 }
wolfSSL 16:8e0d178b1d1e 21116
wolfSSL 16:8e0d178b1d1e 21117 #else
wolfSSL 16:8e0d178b1d1e 21118 /* Add b to a into r. (r = a + b)
wolfSSL 16:8e0d178b1d1e 21119 *
wolfSSL 16:8e0d178b1d1e 21120 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 21121 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 21122 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 21123 */
wolfSSL 16:8e0d178b1d1e 21124 SP_NOINLINE static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 21125 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 21126 {
wolfSSL 16:8e0d178b1d1e 21127 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 21128
wolfSSL 16:8e0d178b1d1e 21129 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 21130 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21131 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 21132 "adds r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21133 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21134 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21135 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21136 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 21137 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21138 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21139 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21140 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21141 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 21142 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21143 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21144 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21145 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21146 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 21147 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21148 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21149 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21150 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21151 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 21152 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21153 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21154 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21155 "ldm %[a]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21156 "ldm %[b]!, {r6, r8}\n\t"
wolfSSL 16:8e0d178b1d1e 21157 "adcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21158 "adcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21159 "stm %[r]!, {r4, r5}\n\t"
wolfSSL 16:8e0d178b1d1e 21160 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 21161 "adc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 21162 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 21163 :
wolfSSL 16:8e0d178b1d1e 21164 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 21165 );
wolfSSL 16:8e0d178b1d1e 21166
wolfSSL 16:8e0d178b1d1e 21167 return c;
wolfSSL 16:8e0d178b1d1e 21168 }
wolfSSL 16:8e0d178b1d1e 21169
wolfSSL 16:8e0d178b1d1e 21170 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 21171 /* Add two Montgomery form numbers (r = a + b % m).
wolfSSL 16:8e0d178b1d1e 21172 *
wolfSSL 16:8e0d178b1d1e 21173 * r Result of addition.
wolfSSL 16:8e0d178b1d1e 21174 * a First number to add in Montogmery form.
wolfSSL 16:8e0d178b1d1e 21175 * b Second number to add in Montogmery form.
wolfSSL 16:8e0d178b1d1e 21176 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 21177 */
wolfSSL 16:8e0d178b1d1e 21178 SP_NOINLINE static void sp_384_mont_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 21179 const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 21180 {
wolfSSL 16:8e0d178b1d1e 21181 sp_digit o;
wolfSSL 16:8e0d178b1d1e 21182
wolfSSL 16:8e0d178b1d1e 21183 o = sp_384_add_12(r, a, b);
wolfSSL 16:8e0d178b1d1e 21184 sp_384_cond_sub_12(r, r, m, 0 - o);
wolfSSL 16:8e0d178b1d1e 21185 }
wolfSSL 16:8e0d178b1d1e 21186
wolfSSL 16:8e0d178b1d1e 21187 /* Double a Montgomery form number (r = a + a % m).
wolfSSL 16:8e0d178b1d1e 21188 *
wolfSSL 16:8e0d178b1d1e 21189 * r Result of doubling.
wolfSSL 16:8e0d178b1d1e 21190 * a Number to double in Montogmery form.
wolfSSL 16:8e0d178b1d1e 21191 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 21192 */
wolfSSL 16:8e0d178b1d1e 21193 SP_NOINLINE static void sp_384_mont_dbl_12(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 21194 {
wolfSSL 16:8e0d178b1d1e 21195 sp_digit o;
wolfSSL 16:8e0d178b1d1e 21196
wolfSSL 16:8e0d178b1d1e 21197 o = sp_384_add_12(r, a, a);
wolfSSL 16:8e0d178b1d1e 21198 sp_384_cond_sub_12(r, r, m, 0 - o);
wolfSSL 16:8e0d178b1d1e 21199 }
wolfSSL 16:8e0d178b1d1e 21200
wolfSSL 16:8e0d178b1d1e 21201 /* Triple a Montgomery form number (r = a + a + a % m).
wolfSSL 16:8e0d178b1d1e 21202 *
wolfSSL 16:8e0d178b1d1e 21203 * r Result of Tripling.
wolfSSL 16:8e0d178b1d1e 21204 * a Number to triple in Montogmery form.
wolfSSL 16:8e0d178b1d1e 21205 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 21206 */
wolfSSL 16:8e0d178b1d1e 21207 SP_NOINLINE static void sp_384_mont_tpl_12(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 21208 {
wolfSSL 16:8e0d178b1d1e 21209 sp_digit o;
wolfSSL 16:8e0d178b1d1e 21210
wolfSSL 16:8e0d178b1d1e 21211 o = sp_384_add_12(r, a, a);
wolfSSL 16:8e0d178b1d1e 21212 sp_384_cond_sub_12(r, r, m, 0 - o);
wolfSSL 16:8e0d178b1d1e 21213 o = sp_384_add_12(r, r, a);
wolfSSL 16:8e0d178b1d1e 21214 sp_384_cond_sub_12(r, r, m, 0 - o);
wolfSSL 16:8e0d178b1d1e 21215 }
wolfSSL 16:8e0d178b1d1e 21216
wolfSSL 16:8e0d178b1d1e 21217 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 21218 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 21219 *
wolfSSL 16:8e0d178b1d1e 21220 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 21221 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 21222 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 21223 */
wolfSSL 16:8e0d178b1d1e 21224 SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 21225 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 21226 {
wolfSSL 16:8e0d178b1d1e 21227 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 21228
wolfSSL 16:8e0d178b1d1e 21229 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 21230 "mov r6, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 21231 "add r6, r6, #48\n\t"
wolfSSL 16:8e0d178b1d1e 21232 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 21233 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 21234 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 21235 "ldr r4, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 21236 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 21237 "sbcs r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21238 "str r4, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 21239 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 21240 "add %[a], %[a], #4\n\t"
wolfSSL 16:8e0d178b1d1e 21241 "add %[b], %[b], #4\n\t"
wolfSSL 16:8e0d178b1d1e 21242 "add %[r], %[r], #4\n\t"
wolfSSL 16:8e0d178b1d1e 21243 "cmp %[a], r6\n\t"
wolfSSL 16:8e0d178b1d1e 21244 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 21245 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 21246 :
wolfSSL 16:8e0d178b1d1e 21247 : "memory", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 21248 );
wolfSSL 16:8e0d178b1d1e 21249
wolfSSL 16:8e0d178b1d1e 21250 return c;
wolfSSL 16:8e0d178b1d1e 21251 }
wolfSSL 16:8e0d178b1d1e 21252
wolfSSL 16:8e0d178b1d1e 21253 #else
wolfSSL 16:8e0d178b1d1e 21254 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 21255 *
wolfSSL 16:8e0d178b1d1e 21256 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 21257 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 21258 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 21259 */
wolfSSL 16:8e0d178b1d1e 21260 SP_NOINLINE static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 21261 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 21262 {
wolfSSL 16:8e0d178b1d1e 21263 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 21264
wolfSSL 16:8e0d178b1d1e 21265 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 21266 "ldr r4, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 21267 "ldr r5, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 21268 "ldr r6, [%[b], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 21269 "ldr r8, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 21270 "subs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21271 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21272 "str r4, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 21273 "str r5, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 21274 "ldr r4, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 21275 "ldr r5, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 21276 "ldr r6, [%[b], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 21277 "ldr r8, [%[b], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 21278 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21279 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21280 "str r4, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 21281 "str r5, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 21282 "ldr r4, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 21283 "ldr r5, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 21284 "ldr r6, [%[b], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 21285 "ldr r8, [%[b], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 21286 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21287 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21288 "str r4, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 21289 "str r5, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 21290 "ldr r4, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 21291 "ldr r5, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 21292 "ldr r6, [%[b], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 21293 "ldr r8, [%[b], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 21294 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21295 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21296 "str r4, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 21297 "str r5, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 21298 "ldr r4, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 21299 "ldr r5, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 21300 "ldr r6, [%[b], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 21301 "ldr r8, [%[b], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 21302 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21303 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21304 "str r4, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 21305 "str r5, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 21306 "ldr r4, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 21307 "ldr r5, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 21308 "ldr r6, [%[b], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 21309 "ldr r8, [%[b], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 21310 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21311 "sbcs r5, r5, r8\n\t"
wolfSSL 16:8e0d178b1d1e 21312 "str r4, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 21313 "str r5, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 21314 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 21315 : [c] "+r" (c), [r] "+r" (r), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 21316 :
wolfSSL 16:8e0d178b1d1e 21317 : "memory", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 21318 );
wolfSSL 16:8e0d178b1d1e 21319
wolfSSL 16:8e0d178b1d1e 21320 return c;
wolfSSL 16:8e0d178b1d1e 21321 }
wolfSSL 16:8e0d178b1d1e 21322
wolfSSL 16:8e0d178b1d1e 21323 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 21324 /* Conditionally add a and b using the mask m.
wolfSSL 16:8e0d178b1d1e 21325 * m is -1 to add and 0 when not.
wolfSSL 16:8e0d178b1d1e 21326 *
wolfSSL 16:8e0d178b1d1e 21327 * r A single precision number representing conditional add result.
wolfSSL 16:8e0d178b1d1e 21328 * a A single precision number to add with.
wolfSSL 16:8e0d178b1d1e 21329 * b A single precision number to add.
wolfSSL 16:8e0d178b1d1e 21330 * m Mask value to apply.
wolfSSL 16:8e0d178b1d1e 21331 */
wolfSSL 16:8e0d178b1d1e 21332 SP_NOINLINE static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 21333 sp_digit m)
wolfSSL 16:8e0d178b1d1e 21334 {
wolfSSL 16:8e0d178b1d1e 21335 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 21336
wolfSSL 16:8e0d178b1d1e 21337 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 21338 "mov r5, #48\n\t"
wolfSSL 16:8e0d178b1d1e 21339 "mov r9, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21340 "mov r8, #0\n\t"
wolfSSL 16:8e0d178b1d1e 21341 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 21342 "ldr r6, [%[b], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 21343 "and r6, r6, %[m]\n\t"
wolfSSL 16:8e0d178b1d1e 21344 "adds r5, %[c], #-1\n\t"
wolfSSL 16:8e0d178b1d1e 21345 "ldr r5, [%[a], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 21346 "adcs r5, r5, r6\n\t"
wolfSSL 16:8e0d178b1d1e 21347 "mov %[c], #0\n\t"
wolfSSL 16:8e0d178b1d1e 21348 "adcs %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 21349 "str r5, [%[r], r8]\n\t"
wolfSSL 16:8e0d178b1d1e 21350 "add r8, r8, #4\n\t"
wolfSSL 16:8e0d178b1d1e 21351 "cmp r8, r9\n\t"
wolfSSL 16:8e0d178b1d1e 21352 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 21353 : [c] "+r" (c)
wolfSSL 16:8e0d178b1d1e 21354 : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m)
wolfSSL 16:8e0d178b1d1e 21355 : "memory", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 21356 );
wolfSSL 16:8e0d178b1d1e 21357
wolfSSL 16:8e0d178b1d1e 21358 return c;
wolfSSL 16:8e0d178b1d1e 21359 }
wolfSSL 16:8e0d178b1d1e 21360
wolfSSL 16:8e0d178b1d1e 21361 /* Subtract two Montgomery form numbers (r = a - b % m).
wolfSSL 16:8e0d178b1d1e 21362 *
wolfSSL 16:8e0d178b1d1e 21363 * r Result of subtration.
wolfSSL 16:8e0d178b1d1e 21364 * a Number to subtract from in Montogmery form.
wolfSSL 16:8e0d178b1d1e 21365 * b Number to subtract with in Montogmery form.
wolfSSL 16:8e0d178b1d1e 21366 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 21367 */
wolfSSL 16:8e0d178b1d1e 21368 SP_NOINLINE static void sp_384_mont_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b,
wolfSSL 16:8e0d178b1d1e 21369 const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 21370 {
wolfSSL 16:8e0d178b1d1e 21371 sp_digit o;
wolfSSL 16:8e0d178b1d1e 21372
wolfSSL 16:8e0d178b1d1e 21373 o = sp_384_sub_12(r, a, b);
wolfSSL 16:8e0d178b1d1e 21374 sp_384_cond_add_12(r, r, m, o);
wolfSSL 16:8e0d178b1d1e 21375 }
wolfSSL 16:8e0d178b1d1e 21376
wolfSSL 16:8e0d178b1d1e 21377 static void sp_384_rshift1_12(sp_digit* r, sp_digit* a)
wolfSSL 16:8e0d178b1d1e 21378 {
wolfSSL 16:8e0d178b1d1e 21379 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 21380 "ldr r2, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 21381 "ldr r3, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 21382 "lsr r2, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21383 "lsl r5, r3, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21384 "lsr r3, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21385 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21386 "ldr r4, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 21387 "str r2, [%[r], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 21388 "lsl r5, r4, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21389 "lsr r4, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21390 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21391 "ldr r2, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 21392 "str r3, [%[r], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 21393 "lsl r5, r2, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21394 "lsr r2, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21395 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21396 "ldr r3, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 21397 "str r4, [%[r], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 21398 "lsl r5, r3, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21399 "lsr r3, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21400 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21401 "ldr r4, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 21402 "str r2, [%[r], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 21403 "lsl r5, r4, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21404 "lsr r4, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21405 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21406 "ldr r2, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 21407 "str r3, [%[r], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 21408 "lsl r5, r2, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21409 "lsr r2, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21410 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21411 "ldr r3, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 21412 "str r4, [%[r], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 21413 "lsl r5, r3, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21414 "lsr r3, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21415 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21416 "ldr r4, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 21417 "str r2, [%[r], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 21418 "lsl r5, r4, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21419 "lsr r4, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21420 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21421 "ldr r2, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 21422 "str r3, [%[r], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 21423 "lsl r5, r2, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21424 "lsr r2, r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21425 "orr r4, r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21426 "ldr r3, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 21427 "str r4, [%[r], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 21428 "lsl r5, r3, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21429 "lsr r3, r3, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21430 "orr r2, r2, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21431 "ldr r4, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 21432 "str r2, [%[r], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 21433 "lsl r5, r4, #31\n\t"
wolfSSL 16:8e0d178b1d1e 21434 "lsr r4, r4, #1\n\t"
wolfSSL 16:8e0d178b1d1e 21435 "orr r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 21436 "str r3, [%[r], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 21437 "str r4, [%[r], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 21438 :
wolfSSL 16:8e0d178b1d1e 21439 : [r] "r" (r), [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 21440 : "memory", "r2", "r3", "r4", "r5"
wolfSSL 16:8e0d178b1d1e 21441 );
wolfSSL 16:8e0d178b1d1e 21442 }
wolfSSL 16:8e0d178b1d1e 21443
wolfSSL 16:8e0d178b1d1e 21444 /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)
wolfSSL 16:8e0d178b1d1e 21445 *
wolfSSL 16:8e0d178b1d1e 21446 * r Result of division by 2.
wolfSSL 16:8e0d178b1d1e 21447 * a Number to divide.
wolfSSL 16:8e0d178b1d1e 21448 * m Modulus (prime).
wolfSSL 16:8e0d178b1d1e 21449 */
wolfSSL 16:8e0d178b1d1e 21450 SP_NOINLINE static void sp_384_div2_12(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 21451 {
wolfSSL 16:8e0d178b1d1e 21452 sp_digit o;
wolfSSL 16:8e0d178b1d1e 21453
wolfSSL 16:8e0d178b1d1e 21454 o = sp_384_cond_add_12(r, a, m, 0 - (a[0] & 1));
wolfSSL 16:8e0d178b1d1e 21455 sp_384_rshift1_12(r, r);
wolfSSL 16:8e0d178b1d1e 21456 r[11] |= o << 31;
wolfSSL 16:8e0d178b1d1e 21457 }
wolfSSL 16:8e0d178b1d1e 21458
wolfSSL 16:8e0d178b1d1e 21459 /* Double the Montgomery form projective point p.
wolfSSL 16:8e0d178b1d1e 21460 *
wolfSSL 16:8e0d178b1d1e 21461 * r Result of doubling point.
wolfSSL 16:8e0d178b1d1e 21462 * p Point to double.
wolfSSL 16:8e0d178b1d1e 21463 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 21464 */
wolfSSL 16:8e0d178b1d1e 21465 static void sp_384_proj_point_dbl_12(sp_point_384* r, const sp_point_384* p, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 21466 {
wolfSSL 16:8e0d178b1d1e 21467 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 21468 sp_digit* t2 = t + 2*12;
wolfSSL 16:8e0d178b1d1e 21469 sp_digit* x;
wolfSSL 16:8e0d178b1d1e 21470 sp_digit* y;
wolfSSL 16:8e0d178b1d1e 21471 sp_digit* z;
wolfSSL 16:8e0d178b1d1e 21472
wolfSSL 16:8e0d178b1d1e 21473 x = r->x;
wolfSSL 16:8e0d178b1d1e 21474 y = r->y;
wolfSSL 16:8e0d178b1d1e 21475 z = r->z;
wolfSSL 16:8e0d178b1d1e 21476 /* Put infinity into result. */
wolfSSL 16:8e0d178b1d1e 21477 if (r != p) {
wolfSSL 16:8e0d178b1d1e 21478 r->infinity = p->infinity;
wolfSSL 16:8e0d178b1d1e 21479 }
wolfSSL 16:8e0d178b1d1e 21480
wolfSSL 16:8e0d178b1d1e 21481 /* T1 = Z * Z */
wolfSSL 16:8e0d178b1d1e 21482 sp_384_mont_sqr_12(t1, p->z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21483 /* Z = Y * Z */
wolfSSL 16:8e0d178b1d1e 21484 sp_384_mont_mul_12(z, p->y, p->z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21485 /* Z = 2Z */
wolfSSL 16:8e0d178b1d1e 21486 sp_384_mont_dbl_12(z, z, p384_mod);
wolfSSL 16:8e0d178b1d1e 21487 /* T2 = X - T1 */
wolfSSL 16:8e0d178b1d1e 21488 sp_384_mont_sub_12(t2, p->x, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 21489 /* T1 = X + T1 */
wolfSSL 16:8e0d178b1d1e 21490 sp_384_mont_add_12(t1, p->x, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 21491 /* T2 = T1 * T2 */
wolfSSL 16:8e0d178b1d1e 21492 sp_384_mont_mul_12(t2, t1, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21493 /* T1 = 3T2 */
wolfSSL 16:8e0d178b1d1e 21494 sp_384_mont_tpl_12(t1, t2, p384_mod);
wolfSSL 16:8e0d178b1d1e 21495 /* Y = 2Y */
wolfSSL 16:8e0d178b1d1e 21496 sp_384_mont_dbl_12(y, p->y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21497 /* Y = Y * Y */
wolfSSL 16:8e0d178b1d1e 21498 sp_384_mont_sqr_12(y, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21499 /* T2 = Y * Y */
wolfSSL 16:8e0d178b1d1e 21500 sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21501 /* T2 = T2/2 */
wolfSSL 16:8e0d178b1d1e 21502 sp_384_div2_12(t2, t2, p384_mod);
wolfSSL 16:8e0d178b1d1e 21503 /* Y = Y * X */
wolfSSL 16:8e0d178b1d1e 21504 sp_384_mont_mul_12(y, y, p->x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21505 /* X = T1 * T1 */
wolfSSL 16:8e0d178b1d1e 21506 sp_384_mont_sqr_12(x, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21507 /* X = X - Y */
wolfSSL 16:8e0d178b1d1e 21508 sp_384_mont_sub_12(x, x, y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21509 /* X = X - Y */
wolfSSL 16:8e0d178b1d1e 21510 sp_384_mont_sub_12(x, x, y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21511 /* Y = Y - X */
wolfSSL 16:8e0d178b1d1e 21512 sp_384_mont_sub_12(y, y, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 21513 /* Y = Y * T1 */
wolfSSL 16:8e0d178b1d1e 21514 sp_384_mont_mul_12(y, y, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21515 /* Y = Y - T2 */
wolfSSL 16:8e0d178b1d1e 21516 sp_384_mont_sub_12(y, y, t2, p384_mod);
wolfSSL 16:8e0d178b1d1e 21517 }
wolfSSL 16:8e0d178b1d1e 21518
wolfSSL 16:8e0d178b1d1e 21519 /* Compare two numbers to determine if they are equal.
wolfSSL 16:8e0d178b1d1e 21520 * Constant time implementation.
wolfSSL 16:8e0d178b1d1e 21521 *
wolfSSL 16:8e0d178b1d1e 21522 * a First number to compare.
wolfSSL 16:8e0d178b1d1e 21523 * b Second number to compare.
wolfSSL 16:8e0d178b1d1e 21524 * returns 1 when equal and 0 otherwise.
wolfSSL 16:8e0d178b1d1e 21525 */
wolfSSL 16:8e0d178b1d1e 21526 static int sp_384_cmp_equal_12(const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 21527 {
wolfSSL 16:8e0d178b1d1e 21528 return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |
wolfSSL 16:8e0d178b1d1e 21529 (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) |
wolfSSL 16:8e0d178b1d1e 21530 (a[8] ^ b[8]) | (a[9] ^ b[9]) | (a[10] ^ b[10]) | (a[11] ^ b[11])) == 0;
wolfSSL 16:8e0d178b1d1e 21531 }
wolfSSL 16:8e0d178b1d1e 21532
wolfSSL 16:8e0d178b1d1e 21533 /* Add two Montgomery form projective points.
wolfSSL 16:8e0d178b1d1e 21534 *
wolfSSL 16:8e0d178b1d1e 21535 * r Result of addition.
wolfSSL 16:8e0d178b1d1e 21536 * p First point to add.
wolfSSL 16:8e0d178b1d1e 21537 * q Second point to add.
wolfSSL 16:8e0d178b1d1e 21538 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 21539 */
wolfSSL 16:8e0d178b1d1e 21540 static void sp_384_proj_point_add_12(sp_point_384* r, const sp_point_384* p, const sp_point_384* q,
wolfSSL 16:8e0d178b1d1e 21541 sp_digit* t)
wolfSSL 16:8e0d178b1d1e 21542 {
wolfSSL 16:8e0d178b1d1e 21543 const sp_point_384* ap[2];
wolfSSL 16:8e0d178b1d1e 21544 sp_point_384* rp[2];
wolfSSL 16:8e0d178b1d1e 21545 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 21546 sp_digit* t2 = t + 2*12;
wolfSSL 16:8e0d178b1d1e 21547 sp_digit* t3 = t + 4*12;
wolfSSL 16:8e0d178b1d1e 21548 sp_digit* t4 = t + 6*12;
wolfSSL 16:8e0d178b1d1e 21549 sp_digit* t5 = t + 8*12;
wolfSSL 16:8e0d178b1d1e 21550 sp_digit* x;
wolfSSL 16:8e0d178b1d1e 21551 sp_digit* y;
wolfSSL 16:8e0d178b1d1e 21552 sp_digit* z;
wolfSSL 16:8e0d178b1d1e 21553 int i;
wolfSSL 16:8e0d178b1d1e 21554
wolfSSL 16:8e0d178b1d1e 21555 /* Ensure only the first point is the same as the result. */
wolfSSL 16:8e0d178b1d1e 21556 if (q == r) {
wolfSSL 16:8e0d178b1d1e 21557 const sp_point_384* a = p;
wolfSSL 16:8e0d178b1d1e 21558 p = q;
wolfSSL 16:8e0d178b1d1e 21559 q = a;
wolfSSL 16:8e0d178b1d1e 21560 }
wolfSSL 16:8e0d178b1d1e 21561
wolfSSL 16:8e0d178b1d1e 21562 /* Check double */
wolfSSL 16:8e0d178b1d1e 21563 (void)sp_384_sub_12(t1, p384_mod, q->y);
wolfSSL 16:8e0d178b1d1e 21564 sp_384_norm_12(t1);
wolfSSL 16:8e0d178b1d1e 21565 if ((sp_384_cmp_equal_12(p->x, q->x) & sp_384_cmp_equal_12(p->z, q->z) &
wolfSSL 16:8e0d178b1d1e 21566 (sp_384_cmp_equal_12(p->y, q->y) | sp_384_cmp_equal_12(p->y, t1))) != 0) {
wolfSSL 16:8e0d178b1d1e 21567 sp_384_proj_point_dbl_12(r, p, t);
wolfSSL 16:8e0d178b1d1e 21568 }
wolfSSL 16:8e0d178b1d1e 21569 else {
wolfSSL 16:8e0d178b1d1e 21570 rp[0] = r;
wolfSSL 16:8e0d178b1d1e 21571
wolfSSL 16:8e0d178b1d1e 21572 /*lint allow cast to different type of pointer*/
wolfSSL 16:8e0d178b1d1e 21573 rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/
wolfSSL 16:8e0d178b1d1e 21574 XMEMSET(rp[1], 0, sizeof(sp_point_384));
wolfSSL 16:8e0d178b1d1e 21575 x = rp[p->infinity | q->infinity]->x;
wolfSSL 16:8e0d178b1d1e 21576 y = rp[p->infinity | q->infinity]->y;
wolfSSL 16:8e0d178b1d1e 21577 z = rp[p->infinity | q->infinity]->z;
wolfSSL 16:8e0d178b1d1e 21578
wolfSSL 16:8e0d178b1d1e 21579 ap[0] = p;
wolfSSL 16:8e0d178b1d1e 21580 ap[1] = q;
wolfSSL 16:8e0d178b1d1e 21581 for (i=0; i<12; i++) {
wolfSSL 16:8e0d178b1d1e 21582 r->x[i] = ap[p->infinity]->x[i];
wolfSSL 16:8e0d178b1d1e 21583 }
wolfSSL 16:8e0d178b1d1e 21584 for (i=0; i<12; i++) {
wolfSSL 16:8e0d178b1d1e 21585 r->y[i] = ap[p->infinity]->y[i];
wolfSSL 16:8e0d178b1d1e 21586 }
wolfSSL 16:8e0d178b1d1e 21587 for (i=0; i<12; i++) {
wolfSSL 16:8e0d178b1d1e 21588 r->z[i] = ap[p->infinity]->z[i];
wolfSSL 16:8e0d178b1d1e 21589 }
wolfSSL 16:8e0d178b1d1e 21590 r->infinity = ap[p->infinity]->infinity;
wolfSSL 16:8e0d178b1d1e 21591
wolfSSL 16:8e0d178b1d1e 21592 /* U1 = X1*Z2^2 */
wolfSSL 16:8e0d178b1d1e 21593 sp_384_mont_sqr_12(t1, q->z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21594 sp_384_mont_mul_12(t3, t1, q->z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21595 sp_384_mont_mul_12(t1, t1, x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21596 /* U2 = X2*Z1^2 */
wolfSSL 16:8e0d178b1d1e 21597 sp_384_mont_sqr_12(t2, z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21598 sp_384_mont_mul_12(t4, t2, z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21599 sp_384_mont_mul_12(t2, t2, q->x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21600 /* S1 = Y1*Z2^3 */
wolfSSL 16:8e0d178b1d1e 21601 sp_384_mont_mul_12(t3, t3, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21602 /* S2 = Y2*Z1^3 */
wolfSSL 16:8e0d178b1d1e 21603 sp_384_mont_mul_12(t4, t4, q->y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21604 /* H = U2 - U1 */
wolfSSL 16:8e0d178b1d1e 21605 sp_384_mont_sub_12(t2, t2, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 21606 /* R = S2 - S1 */
wolfSSL 16:8e0d178b1d1e 21607 sp_384_mont_sub_12(t4, t4, t3, p384_mod);
wolfSSL 16:8e0d178b1d1e 21608 /* Z3 = H*Z1*Z2 */
wolfSSL 16:8e0d178b1d1e 21609 sp_384_mont_mul_12(z, z, q->z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21610 sp_384_mont_mul_12(z, z, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21611 /* X3 = R^2 - H^3 - 2*U1*H^2 */
wolfSSL 16:8e0d178b1d1e 21612 sp_384_mont_sqr_12(x, t4, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21613 sp_384_mont_sqr_12(t5, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21614 sp_384_mont_mul_12(y, t1, t5, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21615 sp_384_mont_mul_12(t5, t5, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21616 sp_384_mont_sub_12(x, x, t5, p384_mod);
wolfSSL 16:8e0d178b1d1e 21617 sp_384_mont_dbl_12(t1, y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21618 sp_384_mont_sub_12(x, x, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 21619 /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
wolfSSL 16:8e0d178b1d1e 21620 sp_384_mont_sub_12(y, y, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 21621 sp_384_mont_mul_12(y, y, t4, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21622 sp_384_mont_mul_12(t5, t5, t3, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21623 sp_384_mont_sub_12(y, y, t5, p384_mod);
wolfSSL 16:8e0d178b1d1e 21624 }
wolfSSL 16:8e0d178b1d1e 21625 }
wolfSSL 16:8e0d178b1d1e 21626
wolfSSL 16:8e0d178b1d1e 21627 /* Multiply the point by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 21628 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 21629 *
wolfSSL 16:8e0d178b1d1e 21630 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 21631 * g Point to multiply.
wolfSSL 16:8e0d178b1d1e 21632 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 21633 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 21634 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 21635 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 21636 */
wolfSSL 16:8e0d178b1d1e 21637 static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 21638 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 21639 {
wolfSSL 16:8e0d178b1d1e 21640 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 21641 sp_point_384 td[16];
wolfSSL 16:8e0d178b1d1e 21642 sp_point_384 rtd;
wolfSSL 16:8e0d178b1d1e 21643 sp_digit tmpd[2 * 12 * 6];
wolfSSL 16:8e0d178b1d1e 21644 #endif
wolfSSL 16:8e0d178b1d1e 21645 sp_point_384* t;
wolfSSL 16:8e0d178b1d1e 21646 sp_point_384* rt;
wolfSSL 16:8e0d178b1d1e 21647 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 21648 sp_digit n;
wolfSSL 16:8e0d178b1d1e 21649 int i;
wolfSSL 16:8e0d178b1d1e 21650 int c, y;
wolfSSL 16:8e0d178b1d1e 21651 int err;
wolfSSL 16:8e0d178b1d1e 21652
wolfSSL 16:8e0d178b1d1e 21653 (void)heap;
wolfSSL 16:8e0d178b1d1e 21654
wolfSSL 16:8e0d178b1d1e 21655 err = sp_384_point_new_12(heap, rtd, rt);
wolfSSL 16:8e0d178b1d1e 21656 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 21657 t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 16, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 21658 if (t == NULL)
wolfSSL 16:8e0d178b1d1e 21659 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 21660 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 6, heap,
wolfSSL 16:8e0d178b1d1e 21661 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 21662 if (tmp == NULL)
wolfSSL 16:8e0d178b1d1e 21663 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 21664 #else
wolfSSL 16:8e0d178b1d1e 21665 t = td;
wolfSSL 16:8e0d178b1d1e 21666 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 21667 #endif
wolfSSL 16:8e0d178b1d1e 21668
wolfSSL 16:8e0d178b1d1e 21669 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 21670 /* t[0] = {0, 0, 1} * norm */
wolfSSL 16:8e0d178b1d1e 21671 XMEMSET(&t[0], 0, sizeof(t[0]));
wolfSSL 16:8e0d178b1d1e 21672 t[0].infinity = 1;
wolfSSL 16:8e0d178b1d1e 21673 /* t[1] = {g->x, g->y, g->z} * norm */
wolfSSL 16:8e0d178b1d1e 21674 (void)sp_384_mod_mul_norm_12(t[1].x, g->x, p384_mod);
wolfSSL 16:8e0d178b1d1e 21675 (void)sp_384_mod_mul_norm_12(t[1].y, g->y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21676 (void)sp_384_mod_mul_norm_12(t[1].z, g->z, p384_mod);
wolfSSL 16:8e0d178b1d1e 21677 t[1].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21678 sp_384_proj_point_dbl_12(&t[ 2], &t[ 1], tmp);
wolfSSL 16:8e0d178b1d1e 21679 t[ 2].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21680 sp_384_proj_point_add_12(&t[ 3], &t[ 2], &t[ 1], tmp);
wolfSSL 16:8e0d178b1d1e 21681 t[ 3].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21682 sp_384_proj_point_dbl_12(&t[ 4], &t[ 2], tmp);
wolfSSL 16:8e0d178b1d1e 21683 t[ 4].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21684 sp_384_proj_point_add_12(&t[ 5], &t[ 3], &t[ 2], tmp);
wolfSSL 16:8e0d178b1d1e 21685 t[ 5].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21686 sp_384_proj_point_dbl_12(&t[ 6], &t[ 3], tmp);
wolfSSL 16:8e0d178b1d1e 21687 t[ 6].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21688 sp_384_proj_point_add_12(&t[ 7], &t[ 4], &t[ 3], tmp);
wolfSSL 16:8e0d178b1d1e 21689 t[ 7].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21690 sp_384_proj_point_dbl_12(&t[ 8], &t[ 4], tmp);
wolfSSL 16:8e0d178b1d1e 21691 t[ 8].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21692 sp_384_proj_point_add_12(&t[ 9], &t[ 5], &t[ 4], tmp);
wolfSSL 16:8e0d178b1d1e 21693 t[ 9].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21694 sp_384_proj_point_dbl_12(&t[10], &t[ 5], tmp);
wolfSSL 16:8e0d178b1d1e 21695 t[10].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21696 sp_384_proj_point_add_12(&t[11], &t[ 6], &t[ 5], tmp);
wolfSSL 16:8e0d178b1d1e 21697 t[11].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21698 sp_384_proj_point_dbl_12(&t[12], &t[ 6], tmp);
wolfSSL 16:8e0d178b1d1e 21699 t[12].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21700 sp_384_proj_point_add_12(&t[13], &t[ 7], &t[ 6], tmp);
wolfSSL 16:8e0d178b1d1e 21701 t[13].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21702 sp_384_proj_point_dbl_12(&t[14], &t[ 7], tmp);
wolfSSL 16:8e0d178b1d1e 21703 t[14].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21704 sp_384_proj_point_add_12(&t[15], &t[ 8], &t[ 7], tmp);
wolfSSL 16:8e0d178b1d1e 21705 t[15].infinity = 0;
wolfSSL 16:8e0d178b1d1e 21706
wolfSSL 16:8e0d178b1d1e 21707 i = 10;
wolfSSL 16:8e0d178b1d1e 21708 n = k[i+1] << 0;
wolfSSL 16:8e0d178b1d1e 21709 c = 28;
wolfSSL 16:8e0d178b1d1e 21710 y = n >> 28;
wolfSSL 16:8e0d178b1d1e 21711 XMEMCPY(rt, &t[y], sizeof(sp_point_384));
wolfSSL 16:8e0d178b1d1e 21712 n <<= 4;
wolfSSL 16:8e0d178b1d1e 21713 for (; i>=0 || c>=4; ) {
wolfSSL 16:8e0d178b1d1e 21714 if (c < 4) {
wolfSSL 16:8e0d178b1d1e 21715 n |= k[i--];
wolfSSL 16:8e0d178b1d1e 21716 c += 32;
wolfSSL 16:8e0d178b1d1e 21717 }
wolfSSL 16:8e0d178b1d1e 21718 y = (n >> 28) & 0xf;
wolfSSL 16:8e0d178b1d1e 21719 n <<= 4;
wolfSSL 16:8e0d178b1d1e 21720 c -= 4;
wolfSSL 16:8e0d178b1d1e 21721
wolfSSL 16:8e0d178b1d1e 21722 sp_384_proj_point_dbl_12(rt, rt, tmp);
wolfSSL 16:8e0d178b1d1e 21723 sp_384_proj_point_dbl_12(rt, rt, tmp);
wolfSSL 16:8e0d178b1d1e 21724 sp_384_proj_point_dbl_12(rt, rt, tmp);
wolfSSL 16:8e0d178b1d1e 21725 sp_384_proj_point_dbl_12(rt, rt, tmp);
wolfSSL 16:8e0d178b1d1e 21726
wolfSSL 16:8e0d178b1d1e 21727 sp_384_proj_point_add_12(rt, rt, &t[y], tmp);
wolfSSL 16:8e0d178b1d1e 21728 }
wolfSSL 16:8e0d178b1d1e 21729
wolfSSL 16:8e0d178b1d1e 21730 if (map != 0) {
wolfSSL 16:8e0d178b1d1e 21731 sp_384_map_12(r, rt, tmp);
wolfSSL 16:8e0d178b1d1e 21732 }
wolfSSL 16:8e0d178b1d1e 21733 else {
wolfSSL 16:8e0d178b1d1e 21734 XMEMCPY(r, rt, sizeof(sp_point_384));
wolfSSL 16:8e0d178b1d1e 21735 }
wolfSSL 16:8e0d178b1d1e 21736 }
wolfSSL 16:8e0d178b1d1e 21737
wolfSSL 16:8e0d178b1d1e 21738 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 21739 if (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 21740 XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 12 * 6);
wolfSSL 16:8e0d178b1d1e 21741 XFREE(tmp, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 21742 }
wolfSSL 16:8e0d178b1d1e 21743 if (t != NULL) {
wolfSSL 16:8e0d178b1d1e 21744 XMEMSET(t, 0, sizeof(sp_point_384) * 16);
wolfSSL 16:8e0d178b1d1e 21745 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 21746 }
wolfSSL 16:8e0d178b1d1e 21747 #else
wolfSSL 16:8e0d178b1d1e 21748 ForceZero(tmpd, sizeof(tmpd));
wolfSSL 16:8e0d178b1d1e 21749 ForceZero(td, sizeof(td));
wolfSSL 16:8e0d178b1d1e 21750 #endif
wolfSSL 16:8e0d178b1d1e 21751 sp_384_point_free_12(rt, 1, heap);
wolfSSL 16:8e0d178b1d1e 21752
wolfSSL 16:8e0d178b1d1e 21753 return err;
wolfSSL 16:8e0d178b1d1e 21754 }
wolfSSL 16:8e0d178b1d1e 21755
wolfSSL 16:8e0d178b1d1e 21756 /* A table entry for pre-computed points. */
wolfSSL 16:8e0d178b1d1e 21757 typedef struct sp_table_entry_384 {
wolfSSL 16:8e0d178b1d1e 21758 sp_digit x[12];
wolfSSL 16:8e0d178b1d1e 21759 sp_digit y[12];
wolfSSL 16:8e0d178b1d1e 21760 } sp_table_entry_384;
wolfSSL 16:8e0d178b1d1e 21761
wolfSSL 16:8e0d178b1d1e 21762 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 21763 /* Double the Montgomery form projective point p a number of times.
wolfSSL 16:8e0d178b1d1e 21764 *
wolfSSL 16:8e0d178b1d1e 21765 * r Result of repeated doubling of point.
wolfSSL 16:8e0d178b1d1e 21766 * p Point to double.
wolfSSL 16:8e0d178b1d1e 21767 * n Number of times to double
wolfSSL 16:8e0d178b1d1e 21768 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 21769 */
wolfSSL 16:8e0d178b1d1e 21770 static void sp_384_proj_point_dbl_n_12(sp_point_384* p, int n, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 21771 {
wolfSSL 16:8e0d178b1d1e 21772 sp_digit* w = t;
wolfSSL 16:8e0d178b1d1e 21773 sp_digit* a = t + 2*12;
wolfSSL 16:8e0d178b1d1e 21774 sp_digit* b = t + 4*12;
wolfSSL 16:8e0d178b1d1e 21775 sp_digit* t1 = t + 6*12;
wolfSSL 16:8e0d178b1d1e 21776 sp_digit* t2 = t + 8*12;
wolfSSL 16:8e0d178b1d1e 21777 sp_digit* x;
wolfSSL 16:8e0d178b1d1e 21778 sp_digit* y;
wolfSSL 16:8e0d178b1d1e 21779 sp_digit* z;
wolfSSL 16:8e0d178b1d1e 21780
wolfSSL 16:8e0d178b1d1e 21781 x = p->x;
wolfSSL 16:8e0d178b1d1e 21782 y = p->y;
wolfSSL 16:8e0d178b1d1e 21783 z = p->z;
wolfSSL 16:8e0d178b1d1e 21784
wolfSSL 16:8e0d178b1d1e 21785 /* Y = 2*Y */
wolfSSL 16:8e0d178b1d1e 21786 sp_384_mont_dbl_12(y, y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21787 /* W = Z^4 */
wolfSSL 16:8e0d178b1d1e 21788 sp_384_mont_sqr_12(w, z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21789 sp_384_mont_sqr_12(w, w, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21790
wolfSSL 16:8e0d178b1d1e 21791 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 21792 while (--n > 0)
wolfSSL 16:8e0d178b1d1e 21793 #else
wolfSSL 16:8e0d178b1d1e 21794 while (--n >= 0)
wolfSSL 16:8e0d178b1d1e 21795 #endif
wolfSSL 16:8e0d178b1d1e 21796 {
wolfSSL 16:8e0d178b1d1e 21797 /* A = 3*(X^2 - W) */
wolfSSL 16:8e0d178b1d1e 21798 sp_384_mont_sqr_12(t1, x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21799 sp_384_mont_sub_12(t1, t1, w, p384_mod);
wolfSSL 16:8e0d178b1d1e 21800 sp_384_mont_tpl_12(a, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 21801 /* B = X*Y^2 */
wolfSSL 16:8e0d178b1d1e 21802 sp_384_mont_sqr_12(t1, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21803 sp_384_mont_mul_12(b, t1, x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21804 /* X = A^2 - 2B */
wolfSSL 16:8e0d178b1d1e 21805 sp_384_mont_sqr_12(x, a, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21806 sp_384_mont_dbl_12(t2, b, p384_mod);
wolfSSL 16:8e0d178b1d1e 21807 sp_384_mont_sub_12(x, x, t2, p384_mod);
wolfSSL 16:8e0d178b1d1e 21808 /* Z = Z*Y */
wolfSSL 16:8e0d178b1d1e 21809 sp_384_mont_mul_12(z, z, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21810 /* t2 = Y^4 */
wolfSSL 16:8e0d178b1d1e 21811 sp_384_mont_sqr_12(t1, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21812 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 21813 if (n != 0)
wolfSSL 16:8e0d178b1d1e 21814 #endif
wolfSSL 16:8e0d178b1d1e 21815 {
wolfSSL 16:8e0d178b1d1e 21816 /* W = W*Y^4 */
wolfSSL 16:8e0d178b1d1e 21817 sp_384_mont_mul_12(w, w, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21818 }
wolfSSL 16:8e0d178b1d1e 21819 /* y = 2*A*(B - X) - Y^4 */
wolfSSL 16:8e0d178b1d1e 21820 sp_384_mont_sub_12(y, b, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 21821 sp_384_mont_mul_12(y, y, a, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21822 sp_384_mont_dbl_12(y, y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21823 sp_384_mont_sub_12(y, y, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 21824 }
wolfSSL 16:8e0d178b1d1e 21825 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 21826 /* A = 3*(X^2 - W) */
wolfSSL 16:8e0d178b1d1e 21827 sp_384_mont_sqr_12(t1, x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21828 sp_384_mont_sub_12(t1, t1, w, p384_mod);
wolfSSL 16:8e0d178b1d1e 21829 sp_384_mont_tpl_12(a, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 21830 /* B = X*Y^2 */
wolfSSL 16:8e0d178b1d1e 21831 sp_384_mont_sqr_12(t1, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21832 sp_384_mont_mul_12(b, t1, x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21833 /* X = A^2 - 2B */
wolfSSL 16:8e0d178b1d1e 21834 sp_384_mont_sqr_12(x, a, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21835 sp_384_mont_dbl_12(t2, b, p384_mod);
wolfSSL 16:8e0d178b1d1e 21836 sp_384_mont_sub_12(x, x, t2, p384_mod);
wolfSSL 16:8e0d178b1d1e 21837 /* Z = Z*Y */
wolfSSL 16:8e0d178b1d1e 21838 sp_384_mont_mul_12(z, z, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21839 /* t2 = Y^4 */
wolfSSL 16:8e0d178b1d1e 21840 sp_384_mont_sqr_12(t1, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21841 /* y = 2*A*(B - X) - Y^4 */
wolfSSL 16:8e0d178b1d1e 21842 sp_384_mont_sub_12(y, b, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 21843 sp_384_mont_mul_12(y, y, a, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21844 sp_384_mont_dbl_12(y, y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21845 sp_384_mont_sub_12(y, y, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 21846 #endif
wolfSSL 16:8e0d178b1d1e 21847 /* Y = Y/2 */
wolfSSL 16:8e0d178b1d1e 21848 sp_384_div2_12(y, y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21849 }
wolfSSL 16:8e0d178b1d1e 21850
wolfSSL 16:8e0d178b1d1e 21851 /* Convert the projective point to affine.
wolfSSL 16:8e0d178b1d1e 21852 * Ordinates are in Montgomery form.
wolfSSL 16:8e0d178b1d1e 21853 *
wolfSSL 16:8e0d178b1d1e 21854 * a Point to convert.
wolfSSL 16:8e0d178b1d1e 21855 * t Temporary data.
wolfSSL 16:8e0d178b1d1e 21856 */
wolfSSL 16:8e0d178b1d1e 21857 static void sp_384_proj_to_affine_12(sp_point_384* a, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 21858 {
wolfSSL 16:8e0d178b1d1e 21859 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 21860 sp_digit* t2 = t + 2 * 12;
wolfSSL 16:8e0d178b1d1e 21861 sp_digit* tmp = t + 4 * 12;
wolfSSL 16:8e0d178b1d1e 21862
wolfSSL 16:8e0d178b1d1e 21863 sp_384_mont_inv_12(t1, a->z, tmp);
wolfSSL 16:8e0d178b1d1e 21864
wolfSSL 16:8e0d178b1d1e 21865 sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21866 sp_384_mont_mul_12(t1, t2, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21867
wolfSSL 16:8e0d178b1d1e 21868 sp_384_mont_mul_12(a->x, a->x, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21869 sp_384_mont_mul_12(a->y, a->y, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21870 XMEMCPY(a->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 21871 }
wolfSSL 16:8e0d178b1d1e 21872
wolfSSL 16:8e0d178b1d1e 21873 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 21874 /* Add two Montgomery form projective points. The second point has a q value of
wolfSSL 16:8e0d178b1d1e 21875 * one.
wolfSSL 16:8e0d178b1d1e 21876 * Only the first point can be the same pointer as the result point.
wolfSSL 16:8e0d178b1d1e 21877 *
wolfSSL 16:8e0d178b1d1e 21878 * r Result of addition.
wolfSSL 16:8e0d178b1d1e 21879 * p First point to add.
wolfSSL 16:8e0d178b1d1e 21880 * q Second point to add.
wolfSSL 16:8e0d178b1d1e 21881 * t Temporary ordinate data.
wolfSSL 16:8e0d178b1d1e 21882 */
wolfSSL 16:8e0d178b1d1e 21883 static void sp_384_proj_point_add_qz1_12(sp_point_384* r, const sp_point_384* p,
wolfSSL 16:8e0d178b1d1e 21884 const sp_point_384* q, sp_digit* t)
wolfSSL 16:8e0d178b1d1e 21885 {
wolfSSL 16:8e0d178b1d1e 21886 const sp_point_384* ap[2];
wolfSSL 16:8e0d178b1d1e 21887 sp_point_384* rp[2];
wolfSSL 16:8e0d178b1d1e 21888 sp_digit* t1 = t;
wolfSSL 16:8e0d178b1d1e 21889 sp_digit* t2 = t + 2*12;
wolfSSL 16:8e0d178b1d1e 21890 sp_digit* t3 = t + 4*12;
wolfSSL 16:8e0d178b1d1e 21891 sp_digit* t4 = t + 6*12;
wolfSSL 16:8e0d178b1d1e 21892 sp_digit* t5 = t + 8*12;
wolfSSL 16:8e0d178b1d1e 21893 sp_digit* x;
wolfSSL 16:8e0d178b1d1e 21894 sp_digit* y;
wolfSSL 16:8e0d178b1d1e 21895 sp_digit* z;
wolfSSL 16:8e0d178b1d1e 21896 int i;
wolfSSL 16:8e0d178b1d1e 21897
wolfSSL 16:8e0d178b1d1e 21898 /* Check double */
wolfSSL 16:8e0d178b1d1e 21899 (void)sp_384_sub_12(t1, p384_mod, q->y);
wolfSSL 16:8e0d178b1d1e 21900 sp_384_norm_12(t1);
wolfSSL 16:8e0d178b1d1e 21901 if ((sp_384_cmp_equal_12(p->x, q->x) & sp_384_cmp_equal_12(p->z, q->z) &
wolfSSL 16:8e0d178b1d1e 21902 (sp_384_cmp_equal_12(p->y, q->y) | sp_384_cmp_equal_12(p->y, t1))) != 0) {
wolfSSL 16:8e0d178b1d1e 21903 sp_384_proj_point_dbl_12(r, p, t);
wolfSSL 16:8e0d178b1d1e 21904 }
wolfSSL 16:8e0d178b1d1e 21905 else {
wolfSSL 16:8e0d178b1d1e 21906 rp[0] = r;
wolfSSL 16:8e0d178b1d1e 21907
wolfSSL 16:8e0d178b1d1e 21908 /*lint allow cast to different type of pointer*/
wolfSSL 16:8e0d178b1d1e 21909 rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/
wolfSSL 16:8e0d178b1d1e 21910 XMEMSET(rp[1], 0, sizeof(sp_point_384));
wolfSSL 16:8e0d178b1d1e 21911 x = rp[p->infinity | q->infinity]->x;
wolfSSL 16:8e0d178b1d1e 21912 y = rp[p->infinity | q->infinity]->y;
wolfSSL 16:8e0d178b1d1e 21913 z = rp[p->infinity | q->infinity]->z;
wolfSSL 16:8e0d178b1d1e 21914
wolfSSL 16:8e0d178b1d1e 21915 ap[0] = p;
wolfSSL 16:8e0d178b1d1e 21916 ap[1] = q;
wolfSSL 16:8e0d178b1d1e 21917 for (i=0; i<12; i++) {
wolfSSL 16:8e0d178b1d1e 21918 r->x[i] = ap[p->infinity]->x[i];
wolfSSL 16:8e0d178b1d1e 21919 }
wolfSSL 16:8e0d178b1d1e 21920 for (i=0; i<12; i++) {
wolfSSL 16:8e0d178b1d1e 21921 r->y[i] = ap[p->infinity]->y[i];
wolfSSL 16:8e0d178b1d1e 21922 }
wolfSSL 16:8e0d178b1d1e 21923 for (i=0; i<12; i++) {
wolfSSL 16:8e0d178b1d1e 21924 r->z[i] = ap[p->infinity]->z[i];
wolfSSL 16:8e0d178b1d1e 21925 }
wolfSSL 16:8e0d178b1d1e 21926 r->infinity = ap[p->infinity]->infinity;
wolfSSL 16:8e0d178b1d1e 21927
wolfSSL 16:8e0d178b1d1e 21928 /* U2 = X2*Z1^2 */
wolfSSL 16:8e0d178b1d1e 21929 sp_384_mont_sqr_12(t2, z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21930 sp_384_mont_mul_12(t4, t2, z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21931 sp_384_mont_mul_12(t2, t2, q->x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21932 /* S2 = Y2*Z1^3 */
wolfSSL 16:8e0d178b1d1e 21933 sp_384_mont_mul_12(t4, t4, q->y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21934 /* H = U2 - X1 */
wolfSSL 16:8e0d178b1d1e 21935 sp_384_mont_sub_12(t2, t2, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 21936 /* R = S2 - Y1 */
wolfSSL 16:8e0d178b1d1e 21937 sp_384_mont_sub_12(t4, t4, y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21938 /* Z3 = H*Z1 */
wolfSSL 16:8e0d178b1d1e 21939 sp_384_mont_mul_12(z, z, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21940 /* X3 = R^2 - H^3 - 2*X1*H^2 */
wolfSSL 16:8e0d178b1d1e 21941 sp_384_mont_sqr_12(t1, t4, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21942 sp_384_mont_sqr_12(t5, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21943 sp_384_mont_mul_12(t3, x, t5, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21944 sp_384_mont_mul_12(t5, t5, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21945 sp_384_mont_sub_12(x, t1, t5, p384_mod);
wolfSSL 16:8e0d178b1d1e 21946 sp_384_mont_dbl_12(t1, t3, p384_mod);
wolfSSL 16:8e0d178b1d1e 21947 sp_384_mont_sub_12(x, x, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 21948 /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */
wolfSSL 16:8e0d178b1d1e 21949 sp_384_mont_sub_12(t3, t3, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 21950 sp_384_mont_mul_12(t3, t3, t4, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21951 sp_384_mont_mul_12(t5, t5, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 21952 sp_384_mont_sub_12(y, t3, t5, p384_mod);
wolfSSL 16:8e0d178b1d1e 21953 }
wolfSSL 16:8e0d178b1d1e 21954 }
wolfSSL 16:8e0d178b1d1e 21955
wolfSSL 16:8e0d178b1d1e 21956 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 21957 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 21958 /* Generate the pre-computed table of points for the base point.
wolfSSL 16:8e0d178b1d1e 21959 *
wolfSSL 16:8e0d178b1d1e 21960 * a The base point.
wolfSSL 16:8e0d178b1d1e 21961 * table Place to store generated point data.
wolfSSL 16:8e0d178b1d1e 21962 * tmp Temporary data.
wolfSSL 16:8e0d178b1d1e 21963 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 21964 */
wolfSSL 16:8e0d178b1d1e 21965 static int sp_384_gen_stripe_table_12(const sp_point_384* a,
wolfSSL 16:8e0d178b1d1e 21966 sp_table_entry_384* table, sp_digit* tmp, void* heap)
wolfSSL 16:8e0d178b1d1e 21967 {
wolfSSL 16:8e0d178b1d1e 21968 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 21969 sp_point_384 td, s1d, s2d;
wolfSSL 16:8e0d178b1d1e 21970 #endif
wolfSSL 16:8e0d178b1d1e 21971 sp_point_384* t;
wolfSSL 16:8e0d178b1d1e 21972 sp_point_384* s1 = NULL;
wolfSSL 16:8e0d178b1d1e 21973 sp_point_384* s2 = NULL;
wolfSSL 16:8e0d178b1d1e 21974 int i, j;
wolfSSL 16:8e0d178b1d1e 21975 int err;
wolfSSL 16:8e0d178b1d1e 21976
wolfSSL 16:8e0d178b1d1e 21977 (void)heap;
wolfSSL 16:8e0d178b1d1e 21978
wolfSSL 16:8e0d178b1d1e 21979 err = sp_384_point_new_12(heap, td, t);
wolfSSL 16:8e0d178b1d1e 21980 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 21981 err = sp_384_point_new_12(heap, s1d, s1);
wolfSSL 16:8e0d178b1d1e 21982 }
wolfSSL 16:8e0d178b1d1e 21983 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 21984 err = sp_384_point_new_12(heap, s2d, s2);
wolfSSL 16:8e0d178b1d1e 21985 }
wolfSSL 16:8e0d178b1d1e 21986
wolfSSL 16:8e0d178b1d1e 21987 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 21988 err = sp_384_mod_mul_norm_12(t->x, a->x, p384_mod);
wolfSSL 16:8e0d178b1d1e 21989 }
wolfSSL 16:8e0d178b1d1e 21990 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 21991 err = sp_384_mod_mul_norm_12(t->y, a->y, p384_mod);
wolfSSL 16:8e0d178b1d1e 21992 }
wolfSSL 16:8e0d178b1d1e 21993 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 21994 err = sp_384_mod_mul_norm_12(t->z, a->z, p384_mod);
wolfSSL 16:8e0d178b1d1e 21995 }
wolfSSL 16:8e0d178b1d1e 21996 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 21997 t->infinity = 0;
wolfSSL 16:8e0d178b1d1e 21998 sp_384_proj_to_affine_12(t, tmp);
wolfSSL 16:8e0d178b1d1e 21999
wolfSSL 16:8e0d178b1d1e 22000 XMEMCPY(s1->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 22001 s1->infinity = 0;
wolfSSL 16:8e0d178b1d1e 22002 XMEMCPY(s2->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 22003 s2->infinity = 0;
wolfSSL 16:8e0d178b1d1e 22004
wolfSSL 16:8e0d178b1d1e 22005 /* table[0] = {0, 0, infinity} */
wolfSSL 16:8e0d178b1d1e 22006 XMEMSET(&table[0], 0, sizeof(sp_table_entry_384));
wolfSSL 16:8e0d178b1d1e 22007 /* table[1] = Affine version of 'a' in Montgomery form */
wolfSSL 16:8e0d178b1d1e 22008 XMEMCPY(table[1].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22009 XMEMCPY(table[1].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22010
wolfSSL 16:8e0d178b1d1e 22011 for (i=1; i<4; i++) {
wolfSSL 16:8e0d178b1d1e 22012 sp_384_proj_point_dbl_n_12(t, 96, tmp);
wolfSSL 16:8e0d178b1d1e 22013 sp_384_proj_to_affine_12(t, tmp);
wolfSSL 16:8e0d178b1d1e 22014 XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22015 XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22016 }
wolfSSL 16:8e0d178b1d1e 22017
wolfSSL 16:8e0d178b1d1e 22018 for (i=1; i<4; i++) {
wolfSSL 16:8e0d178b1d1e 22019 XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22020 XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22021 for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
wolfSSL 16:8e0d178b1d1e 22022 XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22023 XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22024 sp_384_proj_point_add_qz1_12(t, s1, s2, tmp);
wolfSSL 16:8e0d178b1d1e 22025 sp_384_proj_to_affine_12(t, tmp);
wolfSSL 16:8e0d178b1d1e 22026 XMEMCPY(table[j].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22027 XMEMCPY(table[j].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22028 }
wolfSSL 16:8e0d178b1d1e 22029 }
wolfSSL 16:8e0d178b1d1e 22030 }
wolfSSL 16:8e0d178b1d1e 22031
wolfSSL 16:8e0d178b1d1e 22032 sp_384_point_free_12(s2, 0, heap);
wolfSSL 16:8e0d178b1d1e 22033 sp_384_point_free_12(s1, 0, heap);
wolfSSL 16:8e0d178b1d1e 22034 sp_384_point_free_12( t, 0, heap);
wolfSSL 16:8e0d178b1d1e 22035
wolfSSL 16:8e0d178b1d1e 22036 return err;
wolfSSL 16:8e0d178b1d1e 22037 }
wolfSSL 16:8e0d178b1d1e 22038
wolfSSL 16:8e0d178b1d1e 22039 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 22040 /* Multiply the point by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 22041 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 22042 *
wolfSSL 16:8e0d178b1d1e 22043 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 22044 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 22045 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 22046 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 22047 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 22048 */
wolfSSL 16:8e0d178b1d1e 22049 static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g,
wolfSSL 16:8e0d178b1d1e 22050 const sp_table_entry_384* table, const sp_digit* k, int map, void* heap)
wolfSSL 16:8e0d178b1d1e 22051 {
wolfSSL 16:8e0d178b1d1e 22052 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22053 sp_point_384 rtd;
wolfSSL 16:8e0d178b1d1e 22054 sp_point_384 pd;
wolfSSL 16:8e0d178b1d1e 22055 sp_digit td[2 * 12 * 6];
wolfSSL 16:8e0d178b1d1e 22056 #endif
wolfSSL 16:8e0d178b1d1e 22057 sp_point_384* rt;
wolfSSL 16:8e0d178b1d1e 22058 sp_point_384* p = NULL;
wolfSSL 16:8e0d178b1d1e 22059 sp_digit* t;
wolfSSL 16:8e0d178b1d1e 22060 int i, j;
wolfSSL 16:8e0d178b1d1e 22061 int y, x;
wolfSSL 16:8e0d178b1d1e 22062 int err;
wolfSSL 16:8e0d178b1d1e 22063
wolfSSL 16:8e0d178b1d1e 22064 (void)g;
wolfSSL 16:8e0d178b1d1e 22065 (void)heap;
wolfSSL 16:8e0d178b1d1e 22066
wolfSSL 16:8e0d178b1d1e 22067
wolfSSL 16:8e0d178b1d1e 22068 err = sp_384_point_new_12(heap, rtd, rt);
wolfSSL 16:8e0d178b1d1e 22069 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22070 err = sp_384_point_new_12(heap, pd, p);
wolfSSL 16:8e0d178b1d1e 22071 }
wolfSSL 16:8e0d178b1d1e 22072 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22073 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 6, heap,
wolfSSL 16:8e0d178b1d1e 22074 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 22075 if (t == NULL) {
wolfSSL 16:8e0d178b1d1e 22076 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 22077 }
wolfSSL 16:8e0d178b1d1e 22078 #else
wolfSSL 16:8e0d178b1d1e 22079 t = td;
wolfSSL 16:8e0d178b1d1e 22080 #endif
wolfSSL 16:8e0d178b1d1e 22081
wolfSSL 16:8e0d178b1d1e 22082 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22083 XMEMCPY(p->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 22084 XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 22085
wolfSSL 16:8e0d178b1d1e 22086 y = 0;
wolfSSL 16:8e0d178b1d1e 22087 for (j=0,x=95; j<4; j++,x+=96) {
wolfSSL 16:8e0d178b1d1e 22088 y |= ((k[x / 32] >> (x % 32)) & 1) << j;
wolfSSL 16:8e0d178b1d1e 22089 }
wolfSSL 16:8e0d178b1d1e 22090 XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
wolfSSL 16:8e0d178b1d1e 22091 XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
wolfSSL 16:8e0d178b1d1e 22092 rt->infinity = !y;
wolfSSL 16:8e0d178b1d1e 22093 for (i=94; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 22094 y = 0;
wolfSSL 16:8e0d178b1d1e 22095 for (j=0,x=i; j<4; j++,x+=96) {
wolfSSL 16:8e0d178b1d1e 22096 y |= ((k[x / 32] >> (x % 32)) & 1) << j;
wolfSSL 16:8e0d178b1d1e 22097 }
wolfSSL 16:8e0d178b1d1e 22098
wolfSSL 16:8e0d178b1d1e 22099 sp_384_proj_point_dbl_12(rt, rt, t);
wolfSSL 16:8e0d178b1d1e 22100 XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
wolfSSL 16:8e0d178b1d1e 22101 XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
wolfSSL 16:8e0d178b1d1e 22102 p->infinity = !y;
wolfSSL 16:8e0d178b1d1e 22103 sp_384_proj_point_add_qz1_12(rt, rt, p, t);
wolfSSL 16:8e0d178b1d1e 22104 }
wolfSSL 16:8e0d178b1d1e 22105
wolfSSL 16:8e0d178b1d1e 22106 if (map != 0) {
wolfSSL 16:8e0d178b1d1e 22107 sp_384_map_12(r, rt, t);
wolfSSL 16:8e0d178b1d1e 22108 }
wolfSSL 16:8e0d178b1d1e 22109 else {
wolfSSL 16:8e0d178b1d1e 22110 XMEMCPY(r, rt, sizeof(sp_point_384));
wolfSSL 16:8e0d178b1d1e 22111 }
wolfSSL 16:8e0d178b1d1e 22112 }
wolfSSL 16:8e0d178b1d1e 22113
wolfSSL 16:8e0d178b1d1e 22114 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22115 if (t != NULL) {
wolfSSL 16:8e0d178b1d1e 22116 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 22117 }
wolfSSL 16:8e0d178b1d1e 22118 #endif
wolfSSL 16:8e0d178b1d1e 22119 sp_384_point_free_12(p, 0, heap);
wolfSSL 16:8e0d178b1d1e 22120 sp_384_point_free_12(rt, 0, heap);
wolfSSL 16:8e0d178b1d1e 22121
wolfSSL 16:8e0d178b1d1e 22122 return err;
wolfSSL 16:8e0d178b1d1e 22123 }
wolfSSL 16:8e0d178b1d1e 22124
wolfSSL 16:8e0d178b1d1e 22125 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 22126 #ifndef FP_ENTRIES
wolfSSL 16:8e0d178b1d1e 22127 #define FP_ENTRIES 16
wolfSSL 16:8e0d178b1d1e 22128 #endif
wolfSSL 16:8e0d178b1d1e 22129
wolfSSL 16:8e0d178b1d1e 22130 typedef struct sp_cache_384_t {
wolfSSL 16:8e0d178b1d1e 22131 sp_digit x[12];
wolfSSL 16:8e0d178b1d1e 22132 sp_digit y[12];
wolfSSL 16:8e0d178b1d1e 22133 sp_table_entry_384 table[16];
wolfSSL 16:8e0d178b1d1e 22134 uint32_t cnt;
wolfSSL 16:8e0d178b1d1e 22135 int set;
wolfSSL 16:8e0d178b1d1e 22136 } sp_cache_384_t;
wolfSSL 16:8e0d178b1d1e 22137
wolfSSL 16:8e0d178b1d1e 22138 static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES];
wolfSSL 16:8e0d178b1d1e 22139 static THREAD_LS_T int sp_cache_384_last = -1;
wolfSSL 16:8e0d178b1d1e 22140 static THREAD_LS_T int sp_cache_384_inited = 0;
wolfSSL 16:8e0d178b1d1e 22141
wolfSSL 16:8e0d178b1d1e 22142 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 22143 static volatile int initCacheMutex_384 = 0;
wolfSSL 16:8e0d178b1d1e 22144 static wolfSSL_Mutex sp_cache_384_lock;
wolfSSL 16:8e0d178b1d1e 22145 #endif
wolfSSL 16:8e0d178b1d1e 22146
wolfSSL 16:8e0d178b1d1e 22147 static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache)
wolfSSL 16:8e0d178b1d1e 22148 {
wolfSSL 16:8e0d178b1d1e 22149 int i, j;
wolfSSL 16:8e0d178b1d1e 22150 uint32_t least;
wolfSSL 16:8e0d178b1d1e 22151
wolfSSL 16:8e0d178b1d1e 22152 if (sp_cache_384_inited == 0) {
wolfSSL 16:8e0d178b1d1e 22153 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 16:8e0d178b1d1e 22154 sp_cache_384[i].set = 0;
wolfSSL 16:8e0d178b1d1e 22155 }
wolfSSL 16:8e0d178b1d1e 22156 sp_cache_384_inited = 1;
wolfSSL 16:8e0d178b1d1e 22157 }
wolfSSL 16:8e0d178b1d1e 22158
wolfSSL 16:8e0d178b1d1e 22159 /* Compare point with those in cache. */
wolfSSL 16:8e0d178b1d1e 22160 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 16:8e0d178b1d1e 22161 if (!sp_cache_384[i].set)
wolfSSL 16:8e0d178b1d1e 22162 continue;
wolfSSL 16:8e0d178b1d1e 22163
wolfSSL 16:8e0d178b1d1e 22164 if (sp_384_cmp_equal_12(g->x, sp_cache_384[i].x) &
wolfSSL 16:8e0d178b1d1e 22165 sp_384_cmp_equal_12(g->y, sp_cache_384[i].y)) {
wolfSSL 16:8e0d178b1d1e 22166 sp_cache_384[i].cnt++;
wolfSSL 16:8e0d178b1d1e 22167 break;
wolfSSL 16:8e0d178b1d1e 22168 }
wolfSSL 16:8e0d178b1d1e 22169 }
wolfSSL 16:8e0d178b1d1e 22170
wolfSSL 16:8e0d178b1d1e 22171 /* No match. */
wolfSSL 16:8e0d178b1d1e 22172 if (i == FP_ENTRIES) {
wolfSSL 16:8e0d178b1d1e 22173 /* Find empty entry. */
wolfSSL 16:8e0d178b1d1e 22174 i = (sp_cache_384_last + 1) % FP_ENTRIES;
wolfSSL 16:8e0d178b1d1e 22175 for (; i != sp_cache_384_last; i=(i+1)%FP_ENTRIES) {
wolfSSL 16:8e0d178b1d1e 22176 if (!sp_cache_384[i].set) {
wolfSSL 16:8e0d178b1d1e 22177 break;
wolfSSL 16:8e0d178b1d1e 22178 }
wolfSSL 16:8e0d178b1d1e 22179 }
wolfSSL 16:8e0d178b1d1e 22180
wolfSSL 16:8e0d178b1d1e 22181 /* Evict least used. */
wolfSSL 16:8e0d178b1d1e 22182 if (i == sp_cache_384_last) {
wolfSSL 16:8e0d178b1d1e 22183 least = sp_cache_384[0].cnt;
wolfSSL 16:8e0d178b1d1e 22184 for (j=1; j<FP_ENTRIES; j++) {
wolfSSL 16:8e0d178b1d1e 22185 if (sp_cache_384[j].cnt < least) {
wolfSSL 16:8e0d178b1d1e 22186 i = j;
wolfSSL 16:8e0d178b1d1e 22187 least = sp_cache_384[i].cnt;
wolfSSL 16:8e0d178b1d1e 22188 }
wolfSSL 16:8e0d178b1d1e 22189 }
wolfSSL 16:8e0d178b1d1e 22190 }
wolfSSL 16:8e0d178b1d1e 22191
wolfSSL 16:8e0d178b1d1e 22192 XMEMCPY(sp_cache_384[i].x, g->x, sizeof(sp_cache_384[i].x));
wolfSSL 16:8e0d178b1d1e 22193 XMEMCPY(sp_cache_384[i].y, g->y, sizeof(sp_cache_384[i].y));
wolfSSL 16:8e0d178b1d1e 22194 sp_cache_384[i].set = 1;
wolfSSL 16:8e0d178b1d1e 22195 sp_cache_384[i].cnt = 1;
wolfSSL 16:8e0d178b1d1e 22196 }
wolfSSL 16:8e0d178b1d1e 22197
wolfSSL 16:8e0d178b1d1e 22198 *cache = &sp_cache_384[i];
wolfSSL 16:8e0d178b1d1e 22199 sp_cache_384_last = i;
wolfSSL 16:8e0d178b1d1e 22200 }
wolfSSL 16:8e0d178b1d1e 22201 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 22202
wolfSSL 16:8e0d178b1d1e 22203 /* Multiply the base point of P384 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 22204 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 22205 *
wolfSSL 16:8e0d178b1d1e 22206 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 22207 * g Point to multiply.
wolfSSL 16:8e0d178b1d1e 22208 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 22209 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 22210 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 22211 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 22212 */
wolfSSL 16:8e0d178b1d1e 22213 static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 22214 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 22215 {
wolfSSL 16:8e0d178b1d1e 22216 #ifndef FP_ECC
wolfSSL 16:8e0d178b1d1e 22217 return sp_384_ecc_mulmod_fast_12(r, g, k, map, heap);
wolfSSL 16:8e0d178b1d1e 22218 #else
wolfSSL 16:8e0d178b1d1e 22219 sp_digit tmp[2 * 12 * 7];
wolfSSL 16:8e0d178b1d1e 22220 sp_cache_384_t* cache;
wolfSSL 16:8e0d178b1d1e 22221 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 22222
wolfSSL 16:8e0d178b1d1e 22223 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 22224 if (initCacheMutex_384 == 0) {
wolfSSL 16:8e0d178b1d1e 22225 wc_InitMutex(&sp_cache_384_lock);
wolfSSL 16:8e0d178b1d1e 22226 initCacheMutex_384 = 1;
wolfSSL 16:8e0d178b1d1e 22227 }
wolfSSL 16:8e0d178b1d1e 22228 if (wc_LockMutex(&sp_cache_384_lock) != 0)
wolfSSL 16:8e0d178b1d1e 22229 err = BAD_MUTEX_E;
wolfSSL 16:8e0d178b1d1e 22230 #endif /* HAVE_THREAD_LS */
wolfSSL 16:8e0d178b1d1e 22231
wolfSSL 16:8e0d178b1d1e 22232 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22233 sp_ecc_get_cache_384(g, &cache);
wolfSSL 16:8e0d178b1d1e 22234 if (cache->cnt == 2)
wolfSSL 16:8e0d178b1d1e 22235 sp_384_gen_stripe_table_12(g, cache->table, tmp, heap);
wolfSSL 16:8e0d178b1d1e 22236
wolfSSL 16:8e0d178b1d1e 22237 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 22238 wc_UnLockMutex(&sp_cache_384_lock);
wolfSSL 16:8e0d178b1d1e 22239 #endif /* HAVE_THREAD_LS */
wolfSSL 16:8e0d178b1d1e 22240
wolfSSL 16:8e0d178b1d1e 22241 if (cache->cnt < 2) {
wolfSSL 16:8e0d178b1d1e 22242 err = sp_384_ecc_mulmod_fast_12(r, g, k, map, heap);
wolfSSL 16:8e0d178b1d1e 22243 }
wolfSSL 16:8e0d178b1d1e 22244 else {
wolfSSL 16:8e0d178b1d1e 22245 err = sp_384_ecc_mulmod_stripe_12(r, g, cache->table, k,
wolfSSL 16:8e0d178b1d1e 22246 map, heap);
wolfSSL 16:8e0d178b1d1e 22247 }
wolfSSL 16:8e0d178b1d1e 22248 }
wolfSSL 16:8e0d178b1d1e 22249
wolfSSL 16:8e0d178b1d1e 22250 return err;
wolfSSL 16:8e0d178b1d1e 22251 #endif
wolfSSL 16:8e0d178b1d1e 22252 }
wolfSSL 16:8e0d178b1d1e 22253
wolfSSL 16:8e0d178b1d1e 22254 #else
wolfSSL 16:8e0d178b1d1e 22255 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 22256 /* Generate the pre-computed table of points for the base point.
wolfSSL 16:8e0d178b1d1e 22257 *
wolfSSL 16:8e0d178b1d1e 22258 * a The base point.
wolfSSL 16:8e0d178b1d1e 22259 * table Place to store generated point data.
wolfSSL 16:8e0d178b1d1e 22260 * tmp Temporary data.
wolfSSL 16:8e0d178b1d1e 22261 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 22262 */
wolfSSL 16:8e0d178b1d1e 22263 static int sp_384_gen_stripe_table_12(const sp_point_384* a,
wolfSSL 16:8e0d178b1d1e 22264 sp_table_entry_384* table, sp_digit* tmp, void* heap)
wolfSSL 16:8e0d178b1d1e 22265 {
wolfSSL 16:8e0d178b1d1e 22266 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22267 sp_point_384 td, s1d, s2d;
wolfSSL 16:8e0d178b1d1e 22268 #endif
wolfSSL 16:8e0d178b1d1e 22269 sp_point_384* t;
wolfSSL 16:8e0d178b1d1e 22270 sp_point_384* s1 = NULL;
wolfSSL 16:8e0d178b1d1e 22271 sp_point_384* s2 = NULL;
wolfSSL 16:8e0d178b1d1e 22272 int i, j;
wolfSSL 16:8e0d178b1d1e 22273 int err;
wolfSSL 16:8e0d178b1d1e 22274
wolfSSL 16:8e0d178b1d1e 22275 (void)heap;
wolfSSL 16:8e0d178b1d1e 22276
wolfSSL 16:8e0d178b1d1e 22277 err = sp_384_point_new_12(heap, td, t);
wolfSSL 16:8e0d178b1d1e 22278 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22279 err = sp_384_point_new_12(heap, s1d, s1);
wolfSSL 16:8e0d178b1d1e 22280 }
wolfSSL 16:8e0d178b1d1e 22281 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22282 err = sp_384_point_new_12(heap, s2d, s2);
wolfSSL 16:8e0d178b1d1e 22283 }
wolfSSL 16:8e0d178b1d1e 22284
wolfSSL 16:8e0d178b1d1e 22285 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22286 err = sp_384_mod_mul_norm_12(t->x, a->x, p384_mod);
wolfSSL 16:8e0d178b1d1e 22287 }
wolfSSL 16:8e0d178b1d1e 22288 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22289 err = sp_384_mod_mul_norm_12(t->y, a->y, p384_mod);
wolfSSL 16:8e0d178b1d1e 22290 }
wolfSSL 16:8e0d178b1d1e 22291 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22292 err = sp_384_mod_mul_norm_12(t->z, a->z, p384_mod);
wolfSSL 16:8e0d178b1d1e 22293 }
wolfSSL 16:8e0d178b1d1e 22294 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22295 t->infinity = 0;
wolfSSL 16:8e0d178b1d1e 22296 sp_384_proj_to_affine_12(t, tmp);
wolfSSL 16:8e0d178b1d1e 22297
wolfSSL 16:8e0d178b1d1e 22298 XMEMCPY(s1->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 22299 s1->infinity = 0;
wolfSSL 16:8e0d178b1d1e 22300 XMEMCPY(s2->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 22301 s2->infinity = 0;
wolfSSL 16:8e0d178b1d1e 22302
wolfSSL 16:8e0d178b1d1e 22303 /* table[0] = {0, 0, infinity} */
wolfSSL 16:8e0d178b1d1e 22304 XMEMSET(&table[0], 0, sizeof(sp_table_entry_384));
wolfSSL 16:8e0d178b1d1e 22305 /* table[1] = Affine version of 'a' in Montgomery form */
wolfSSL 16:8e0d178b1d1e 22306 XMEMCPY(table[1].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22307 XMEMCPY(table[1].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22308
wolfSSL 16:8e0d178b1d1e 22309 for (i=1; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 22310 sp_384_proj_point_dbl_n_12(t, 48, tmp);
wolfSSL 16:8e0d178b1d1e 22311 sp_384_proj_to_affine_12(t, tmp);
wolfSSL 16:8e0d178b1d1e 22312 XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22313 XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22314 }
wolfSSL 16:8e0d178b1d1e 22315
wolfSSL 16:8e0d178b1d1e 22316 for (i=1; i<8; i++) {
wolfSSL 16:8e0d178b1d1e 22317 XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22318 XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22319 for (j=(1<<i)+1; j<(1<<(i+1)); j++) {
wolfSSL 16:8e0d178b1d1e 22320 XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22321 XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22322 sp_384_proj_point_add_qz1_12(t, s1, s2, tmp);
wolfSSL 16:8e0d178b1d1e 22323 sp_384_proj_to_affine_12(t, tmp);
wolfSSL 16:8e0d178b1d1e 22324 XMEMCPY(table[j].x, t->x, sizeof(table->x));
wolfSSL 16:8e0d178b1d1e 22325 XMEMCPY(table[j].y, t->y, sizeof(table->y));
wolfSSL 16:8e0d178b1d1e 22326 }
wolfSSL 16:8e0d178b1d1e 22327 }
wolfSSL 16:8e0d178b1d1e 22328 }
wolfSSL 16:8e0d178b1d1e 22329
wolfSSL 16:8e0d178b1d1e 22330 sp_384_point_free_12(s2, 0, heap);
wolfSSL 16:8e0d178b1d1e 22331 sp_384_point_free_12(s1, 0, heap);
wolfSSL 16:8e0d178b1d1e 22332 sp_384_point_free_12( t, 0, heap);
wolfSSL 16:8e0d178b1d1e 22333
wolfSSL 16:8e0d178b1d1e 22334 return err;
wolfSSL 16:8e0d178b1d1e 22335 }
wolfSSL 16:8e0d178b1d1e 22336
wolfSSL 16:8e0d178b1d1e 22337 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 22338 /* Multiply the point by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 22339 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 22340 *
wolfSSL 16:8e0d178b1d1e 22341 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 22342 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 22343 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 22344 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 22345 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 22346 */
wolfSSL 16:8e0d178b1d1e 22347 static int sp_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g,
wolfSSL 16:8e0d178b1d1e 22348 const sp_table_entry_384* table, const sp_digit* k, int map, void* heap)
wolfSSL 16:8e0d178b1d1e 22349 {
wolfSSL 16:8e0d178b1d1e 22350 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22351 sp_point_384 rtd;
wolfSSL 16:8e0d178b1d1e 22352 sp_point_384 pd;
wolfSSL 16:8e0d178b1d1e 22353 sp_digit td[2 * 12 * 6];
wolfSSL 16:8e0d178b1d1e 22354 #endif
wolfSSL 16:8e0d178b1d1e 22355 sp_point_384* rt;
wolfSSL 16:8e0d178b1d1e 22356 sp_point_384* p = NULL;
wolfSSL 16:8e0d178b1d1e 22357 sp_digit* t;
wolfSSL 16:8e0d178b1d1e 22358 int i, j;
wolfSSL 16:8e0d178b1d1e 22359 int y, x;
wolfSSL 16:8e0d178b1d1e 22360 int err;
wolfSSL 16:8e0d178b1d1e 22361
wolfSSL 16:8e0d178b1d1e 22362 (void)g;
wolfSSL 16:8e0d178b1d1e 22363 (void)heap;
wolfSSL 16:8e0d178b1d1e 22364
wolfSSL 16:8e0d178b1d1e 22365
wolfSSL 16:8e0d178b1d1e 22366 err = sp_384_point_new_12(heap, rtd, rt);
wolfSSL 16:8e0d178b1d1e 22367 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22368 err = sp_384_point_new_12(heap, pd, p);
wolfSSL 16:8e0d178b1d1e 22369 }
wolfSSL 16:8e0d178b1d1e 22370 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22371 t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 6, heap,
wolfSSL 16:8e0d178b1d1e 22372 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 22373 if (t == NULL) {
wolfSSL 16:8e0d178b1d1e 22374 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 22375 }
wolfSSL 16:8e0d178b1d1e 22376 #else
wolfSSL 16:8e0d178b1d1e 22377 t = td;
wolfSSL 16:8e0d178b1d1e 22378 #endif
wolfSSL 16:8e0d178b1d1e 22379
wolfSSL 16:8e0d178b1d1e 22380 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22381 XMEMCPY(p->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 22382 XMEMCPY(rt->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 22383
wolfSSL 16:8e0d178b1d1e 22384 y = 0;
wolfSSL 16:8e0d178b1d1e 22385 for (j=0,x=47; j<8; j++,x+=48) {
wolfSSL 16:8e0d178b1d1e 22386 y |= ((k[x / 32] >> (x % 32)) & 1) << j;
wolfSSL 16:8e0d178b1d1e 22387 }
wolfSSL 16:8e0d178b1d1e 22388 XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));
wolfSSL 16:8e0d178b1d1e 22389 XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));
wolfSSL 16:8e0d178b1d1e 22390 rt->infinity = !y;
wolfSSL 16:8e0d178b1d1e 22391 for (i=46; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 22392 y = 0;
wolfSSL 16:8e0d178b1d1e 22393 for (j=0,x=i; j<8; j++,x+=48) {
wolfSSL 16:8e0d178b1d1e 22394 y |= ((k[x / 32] >> (x % 32)) & 1) << j;
wolfSSL 16:8e0d178b1d1e 22395 }
wolfSSL 16:8e0d178b1d1e 22396
wolfSSL 16:8e0d178b1d1e 22397 sp_384_proj_point_dbl_12(rt, rt, t);
wolfSSL 16:8e0d178b1d1e 22398 XMEMCPY(p->x, table[y].x, sizeof(table[y].x));
wolfSSL 16:8e0d178b1d1e 22399 XMEMCPY(p->y, table[y].y, sizeof(table[y].y));
wolfSSL 16:8e0d178b1d1e 22400 p->infinity = !y;
wolfSSL 16:8e0d178b1d1e 22401 sp_384_proj_point_add_qz1_12(rt, rt, p, t);
wolfSSL 16:8e0d178b1d1e 22402 }
wolfSSL 16:8e0d178b1d1e 22403
wolfSSL 16:8e0d178b1d1e 22404 if (map != 0) {
wolfSSL 16:8e0d178b1d1e 22405 sp_384_map_12(r, rt, t);
wolfSSL 16:8e0d178b1d1e 22406 }
wolfSSL 16:8e0d178b1d1e 22407 else {
wolfSSL 16:8e0d178b1d1e 22408 XMEMCPY(r, rt, sizeof(sp_point_384));
wolfSSL 16:8e0d178b1d1e 22409 }
wolfSSL 16:8e0d178b1d1e 22410 }
wolfSSL 16:8e0d178b1d1e 22411
wolfSSL 16:8e0d178b1d1e 22412 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22413 if (t != NULL) {
wolfSSL 16:8e0d178b1d1e 22414 XFREE(t, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 22415 }
wolfSSL 16:8e0d178b1d1e 22416 #endif
wolfSSL 16:8e0d178b1d1e 22417 sp_384_point_free_12(p, 0, heap);
wolfSSL 16:8e0d178b1d1e 22418 sp_384_point_free_12(rt, 0, heap);
wolfSSL 16:8e0d178b1d1e 22419
wolfSSL 16:8e0d178b1d1e 22420 return err;
wolfSSL 16:8e0d178b1d1e 22421 }
wolfSSL 16:8e0d178b1d1e 22422
wolfSSL 16:8e0d178b1d1e 22423 #ifdef FP_ECC
wolfSSL 16:8e0d178b1d1e 22424 #ifndef FP_ENTRIES
wolfSSL 16:8e0d178b1d1e 22425 #define FP_ENTRIES 16
wolfSSL 16:8e0d178b1d1e 22426 #endif
wolfSSL 16:8e0d178b1d1e 22427
wolfSSL 16:8e0d178b1d1e 22428 typedef struct sp_cache_384_t {
wolfSSL 16:8e0d178b1d1e 22429 sp_digit x[12];
wolfSSL 16:8e0d178b1d1e 22430 sp_digit y[12];
wolfSSL 16:8e0d178b1d1e 22431 sp_table_entry_384 table[256];
wolfSSL 16:8e0d178b1d1e 22432 uint32_t cnt;
wolfSSL 16:8e0d178b1d1e 22433 int set;
wolfSSL 16:8e0d178b1d1e 22434 } sp_cache_384_t;
wolfSSL 16:8e0d178b1d1e 22435
wolfSSL 16:8e0d178b1d1e 22436 static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES];
wolfSSL 16:8e0d178b1d1e 22437 static THREAD_LS_T int sp_cache_384_last = -1;
wolfSSL 16:8e0d178b1d1e 22438 static THREAD_LS_T int sp_cache_384_inited = 0;
wolfSSL 16:8e0d178b1d1e 22439
wolfSSL 16:8e0d178b1d1e 22440 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 22441 static volatile int initCacheMutex_384 = 0;
wolfSSL 16:8e0d178b1d1e 22442 static wolfSSL_Mutex sp_cache_384_lock;
wolfSSL 16:8e0d178b1d1e 22443 #endif
wolfSSL 16:8e0d178b1d1e 22444
wolfSSL 16:8e0d178b1d1e 22445 static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache)
wolfSSL 16:8e0d178b1d1e 22446 {
wolfSSL 16:8e0d178b1d1e 22447 int i, j;
wolfSSL 16:8e0d178b1d1e 22448 uint32_t least;
wolfSSL 16:8e0d178b1d1e 22449
wolfSSL 16:8e0d178b1d1e 22450 if (sp_cache_384_inited == 0) {
wolfSSL 16:8e0d178b1d1e 22451 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 16:8e0d178b1d1e 22452 sp_cache_384[i].set = 0;
wolfSSL 16:8e0d178b1d1e 22453 }
wolfSSL 16:8e0d178b1d1e 22454 sp_cache_384_inited = 1;
wolfSSL 16:8e0d178b1d1e 22455 }
wolfSSL 16:8e0d178b1d1e 22456
wolfSSL 16:8e0d178b1d1e 22457 /* Compare point with those in cache. */
wolfSSL 16:8e0d178b1d1e 22458 for (i=0; i<FP_ENTRIES; i++) {
wolfSSL 16:8e0d178b1d1e 22459 if (!sp_cache_384[i].set)
wolfSSL 16:8e0d178b1d1e 22460 continue;
wolfSSL 16:8e0d178b1d1e 22461
wolfSSL 16:8e0d178b1d1e 22462 if (sp_384_cmp_equal_12(g->x, sp_cache_384[i].x) &
wolfSSL 16:8e0d178b1d1e 22463 sp_384_cmp_equal_12(g->y, sp_cache_384[i].y)) {
wolfSSL 16:8e0d178b1d1e 22464 sp_cache_384[i].cnt++;
wolfSSL 16:8e0d178b1d1e 22465 break;
wolfSSL 16:8e0d178b1d1e 22466 }
wolfSSL 16:8e0d178b1d1e 22467 }
wolfSSL 16:8e0d178b1d1e 22468
wolfSSL 16:8e0d178b1d1e 22469 /* No match. */
wolfSSL 16:8e0d178b1d1e 22470 if (i == FP_ENTRIES) {
wolfSSL 16:8e0d178b1d1e 22471 /* Find empty entry. */
wolfSSL 16:8e0d178b1d1e 22472 i = (sp_cache_384_last + 1) % FP_ENTRIES;
wolfSSL 16:8e0d178b1d1e 22473 for (; i != sp_cache_384_last; i=(i+1)%FP_ENTRIES) {
wolfSSL 16:8e0d178b1d1e 22474 if (!sp_cache_384[i].set) {
wolfSSL 16:8e0d178b1d1e 22475 break;
wolfSSL 16:8e0d178b1d1e 22476 }
wolfSSL 16:8e0d178b1d1e 22477 }
wolfSSL 16:8e0d178b1d1e 22478
wolfSSL 16:8e0d178b1d1e 22479 /* Evict least used. */
wolfSSL 16:8e0d178b1d1e 22480 if (i == sp_cache_384_last) {
wolfSSL 16:8e0d178b1d1e 22481 least = sp_cache_384[0].cnt;
wolfSSL 16:8e0d178b1d1e 22482 for (j=1; j<FP_ENTRIES; j++) {
wolfSSL 16:8e0d178b1d1e 22483 if (sp_cache_384[j].cnt < least) {
wolfSSL 16:8e0d178b1d1e 22484 i = j;
wolfSSL 16:8e0d178b1d1e 22485 least = sp_cache_384[i].cnt;
wolfSSL 16:8e0d178b1d1e 22486 }
wolfSSL 16:8e0d178b1d1e 22487 }
wolfSSL 16:8e0d178b1d1e 22488 }
wolfSSL 16:8e0d178b1d1e 22489
wolfSSL 16:8e0d178b1d1e 22490 XMEMCPY(sp_cache_384[i].x, g->x, sizeof(sp_cache_384[i].x));
wolfSSL 16:8e0d178b1d1e 22491 XMEMCPY(sp_cache_384[i].y, g->y, sizeof(sp_cache_384[i].y));
wolfSSL 16:8e0d178b1d1e 22492 sp_cache_384[i].set = 1;
wolfSSL 16:8e0d178b1d1e 22493 sp_cache_384[i].cnt = 1;
wolfSSL 16:8e0d178b1d1e 22494 }
wolfSSL 16:8e0d178b1d1e 22495
wolfSSL 16:8e0d178b1d1e 22496 *cache = &sp_cache_384[i];
wolfSSL 16:8e0d178b1d1e 22497 sp_cache_384_last = i;
wolfSSL 16:8e0d178b1d1e 22498 }
wolfSSL 16:8e0d178b1d1e 22499 #endif /* FP_ECC */
wolfSSL 16:8e0d178b1d1e 22500
wolfSSL 16:8e0d178b1d1e 22501 /* Multiply the base point of P384 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 22502 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 22503 *
wolfSSL 16:8e0d178b1d1e 22504 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 22505 * g Point to multiply.
wolfSSL 16:8e0d178b1d1e 22506 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 22507 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 22508 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 22509 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 22510 */
wolfSSL 16:8e0d178b1d1e 22511 static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 22512 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 22513 {
wolfSSL 16:8e0d178b1d1e 22514 #ifndef FP_ECC
wolfSSL 16:8e0d178b1d1e 22515 return sp_384_ecc_mulmod_fast_12(r, g, k, map, heap);
wolfSSL 16:8e0d178b1d1e 22516 #else
wolfSSL 16:8e0d178b1d1e 22517 sp_digit tmp[2 * 12 * 7];
wolfSSL 16:8e0d178b1d1e 22518 sp_cache_384_t* cache;
wolfSSL 16:8e0d178b1d1e 22519 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 22520
wolfSSL 16:8e0d178b1d1e 22521 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 22522 if (initCacheMutex_384 == 0) {
wolfSSL 16:8e0d178b1d1e 22523 wc_InitMutex(&sp_cache_384_lock);
wolfSSL 16:8e0d178b1d1e 22524 initCacheMutex_384 = 1;
wolfSSL 16:8e0d178b1d1e 22525 }
wolfSSL 16:8e0d178b1d1e 22526 if (wc_LockMutex(&sp_cache_384_lock) != 0)
wolfSSL 16:8e0d178b1d1e 22527 err = BAD_MUTEX_E;
wolfSSL 16:8e0d178b1d1e 22528 #endif /* HAVE_THREAD_LS */
wolfSSL 16:8e0d178b1d1e 22529
wolfSSL 16:8e0d178b1d1e 22530 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22531 sp_ecc_get_cache_384(g, &cache);
wolfSSL 16:8e0d178b1d1e 22532 if (cache->cnt == 2)
wolfSSL 16:8e0d178b1d1e 22533 sp_384_gen_stripe_table_12(g, cache->table, tmp, heap);
wolfSSL 16:8e0d178b1d1e 22534
wolfSSL 16:8e0d178b1d1e 22535 #ifndef HAVE_THREAD_LS
wolfSSL 16:8e0d178b1d1e 22536 wc_UnLockMutex(&sp_cache_384_lock);
wolfSSL 16:8e0d178b1d1e 22537 #endif /* HAVE_THREAD_LS */
wolfSSL 16:8e0d178b1d1e 22538
wolfSSL 16:8e0d178b1d1e 22539 if (cache->cnt < 2) {
wolfSSL 16:8e0d178b1d1e 22540 err = sp_384_ecc_mulmod_fast_12(r, g, k, map, heap);
wolfSSL 16:8e0d178b1d1e 22541 }
wolfSSL 16:8e0d178b1d1e 22542 else {
wolfSSL 16:8e0d178b1d1e 22543 err = sp_384_ecc_mulmod_stripe_12(r, g, cache->table, k,
wolfSSL 16:8e0d178b1d1e 22544 map, heap);
wolfSSL 16:8e0d178b1d1e 22545 }
wolfSSL 16:8e0d178b1d1e 22546 }
wolfSSL 16:8e0d178b1d1e 22547
wolfSSL 16:8e0d178b1d1e 22548 return err;
wolfSSL 16:8e0d178b1d1e 22549 #endif
wolfSSL 16:8e0d178b1d1e 22550 }
wolfSSL 16:8e0d178b1d1e 22551
wolfSSL 16:8e0d178b1d1e 22552 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 22553 /* Multiply the point by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 22554 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 22555 *
wolfSSL 16:8e0d178b1d1e 22556 * km Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 22557 * p Point to multiply.
wolfSSL 16:8e0d178b1d1e 22558 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 22559 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 22560 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 22561 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 22562 */
wolfSSL 16:8e0d178b1d1e 22563 int sp_ecc_mulmod_384(mp_int* km, ecc_point* gm, ecc_point* r, int map,
wolfSSL 16:8e0d178b1d1e 22564 void* heap)
wolfSSL 16:8e0d178b1d1e 22565 {
wolfSSL 16:8e0d178b1d1e 22566 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22567 sp_point_384 p;
wolfSSL 16:8e0d178b1d1e 22568 sp_digit kd[12];
wolfSSL 16:8e0d178b1d1e 22569 #endif
wolfSSL 16:8e0d178b1d1e 22570 sp_point_384* point;
wolfSSL 16:8e0d178b1d1e 22571 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 22572 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 22573
wolfSSL 16:8e0d178b1d1e 22574 err = sp_384_point_new_12(heap, p, point);
wolfSSL 16:8e0d178b1d1e 22575 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22576 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22577 k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap,
wolfSSL 16:8e0d178b1d1e 22578 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 22579 if (k == NULL)
wolfSSL 16:8e0d178b1d1e 22580 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 22581 }
wolfSSL 16:8e0d178b1d1e 22582 #else
wolfSSL 16:8e0d178b1d1e 22583 k = kd;
wolfSSL 16:8e0d178b1d1e 22584 #endif
wolfSSL 16:8e0d178b1d1e 22585 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22586 sp_384_from_mp(k, 12, km);
wolfSSL 16:8e0d178b1d1e 22587 sp_384_point_from_ecc_point_12(point, gm);
wolfSSL 16:8e0d178b1d1e 22588
wolfSSL 16:8e0d178b1d1e 22589 err = sp_384_ecc_mulmod_12(point, point, k, map, heap);
wolfSSL 16:8e0d178b1d1e 22590 }
wolfSSL 16:8e0d178b1d1e 22591 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 22592 err = sp_384_point_to_ecc_point_12(point, r);
wolfSSL 16:8e0d178b1d1e 22593 }
wolfSSL 16:8e0d178b1d1e 22594
wolfSSL 16:8e0d178b1d1e 22595 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 22596 if (k != NULL) {
wolfSSL 16:8e0d178b1d1e 22597 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 22598 }
wolfSSL 16:8e0d178b1d1e 22599 #endif
wolfSSL 16:8e0d178b1d1e 22600 sp_384_point_free_12(point, 0, heap);
wolfSSL 16:8e0d178b1d1e 22601
wolfSSL 16:8e0d178b1d1e 22602 return err;
wolfSSL 16:8e0d178b1d1e 22603 }
wolfSSL 16:8e0d178b1d1e 22604
wolfSSL 16:8e0d178b1d1e 22605 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 22606 static const sp_table_entry_384 p384_table[16] = {
wolfSSL 16:8e0d178b1d1e 22607 /* 0 */
wolfSSL 16:8e0d178b1d1e 22608 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
wolfSSL 16:8e0d178b1d1e 22609 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
wolfSSL 16:8e0d178b1d1e 22610 /* 1 */
wolfSSL 16:8e0d178b1d1e 22611 { { 0x49c0b528,0x3dd07566,0xa0d6ce38,0x20e378e2,0x541b4d6e,0x879c3afc,
wolfSSL 16:8e0d178b1d1e 22612 0x59a30eff,0x64548684,0x614ede2b,0x812ff723,0x299e1513,0x4d3aadc2 },
wolfSSL 16:8e0d178b1d1e 22613 { 0x4b03a4fe,0x23043dad,0x7bb4a9ac,0xa1bfa8bf,0x2e83b050,0x8bade756,
wolfSSL 16:8e0d178b1d1e 22614 0x68f4ffd9,0xc6c35219,0x3969a840,0xdd800226,0x5a15c5e9,0x2b78abc2 } },
wolfSSL 16:8e0d178b1d1e 22615 /* 2 */
wolfSSL 16:8e0d178b1d1e 22616 { { 0xf26feef9,0x24480c57,0x3a0e1240,0xc31a2694,0x273e2bc7,0x735002c3,
wolfSSL 16:8e0d178b1d1e 22617 0x3ef1ed4c,0x8c42e9c5,0x7f4948e8,0x028babf6,0x8a978632,0x6a502f43 },
wolfSSL 16:8e0d178b1d1e 22618 { 0xb74536fe,0xf5f13a46,0xd8a9f0eb,0x1d218bab,0x37232768,0x30f36bcc,
wolfSSL 16:8e0d178b1d1e 22619 0x576e8c18,0xc5317b31,0x9bbcb766,0xef1d57a6,0xb3e3d4dc,0x917c4930 } },
wolfSSL 16:8e0d178b1d1e 22620 /* 3 */
wolfSSL 16:8e0d178b1d1e 22621 { { 0xe349ddd0,0x11426e2e,0x9b2fc250,0x9f117ef9,0xec0174a6,0xff36b480,
wolfSSL 16:8e0d178b1d1e 22622 0x18458466,0x4f4bde76,0x05806049,0x2f2edb6d,0x19dfca92,0x8adc75d1 },
wolfSSL 16:8e0d178b1d1e 22623 { 0xb7d5a7ce,0xa619d097,0xa34411e9,0x874275e5,0x0da4b4ef,0x5403e047,
wolfSSL 16:8e0d178b1d1e 22624 0x77901d8f,0x2ebaafd9,0xa747170f,0x5e63ebce,0x7f9d8036,0x12a36944 } },
wolfSSL 16:8e0d178b1d1e 22625 /* 4 */
wolfSSL 16:8e0d178b1d1e 22626 { { 0x2f9fbe67,0x378205de,0x7f728e44,0xc4afcb83,0x682e00f1,0xdbcec06c,
wolfSSL 16:8e0d178b1d1e 22627 0x114d5423,0xf2a145c3,0x7a52463e,0xa01d9874,0x7d717b0a,0xfc0935b1 },
wolfSSL 16:8e0d178b1d1e 22628 { 0xd4d01f95,0x9653bc4f,0x9560ad34,0x9aa83ea8,0xaf8e3f3f,0xf77943dc,
wolfSSL 16:8e0d178b1d1e 22629 0xe86fe16e,0x70774a10,0xbf9ffdcf,0x6b62e6f1,0x588745c9,0x8a72f39e } },
wolfSSL 16:8e0d178b1d1e 22630 /* 5 */
wolfSSL 16:8e0d178b1d1e 22631 { { 0x2341c342,0x73ade4da,0xea704422,0xdd326e54,0x3741cef3,0x336c7d98,
wolfSSL 16:8e0d178b1d1e 22632 0x59e61549,0x1eafa00d,0xbd9a3efd,0xcd3ed892,0xc5c6c7e4,0x03faf26c },
wolfSSL 16:8e0d178b1d1e 22633 { 0x3045f8ac,0x087e2fcf,0x174f1e73,0x14a65532,0xfe0af9a7,0x2cf84f28,
wolfSSL 16:8e0d178b1d1e 22634 0x2cdc935b,0xddfd7a84,0x6929c895,0x4c0f117b,0x4c8bcfcc,0x356572d6 } },
wolfSSL 16:8e0d178b1d1e 22635 /* 6 */
wolfSSL 16:8e0d178b1d1e 22636 { { 0x3f3b236f,0xfab08607,0x81e221da,0x19e9d41d,0x3927b428,0xf3f6571e,
wolfSSL 16:8e0d178b1d1e 22637 0x7550f1f6,0x4348a933,0xa85e62f0,0x7167b996,0x7f5452bf,0x62d43759 },
wolfSSL 16:8e0d178b1d1e 22638 { 0xf2955926,0xd85feb9e,0x6df78353,0x440a561f,0x9ca36b59,0x389668ec,
wolfSSL 16:8e0d178b1d1e 22639 0xa22da016,0x052bf1a1,0xf6093254,0xbdfbff72,0xe22209f3,0x94e50f28 } },
wolfSSL 16:8e0d178b1d1e 22640 /* 7 */
wolfSSL 16:8e0d178b1d1e 22641 { { 0x3062e8af,0x90b2e5b3,0xe8a3d369,0xa8572375,0x201db7b1,0x3fe1b00b,
wolfSSL 16:8e0d178b1d1e 22642 0xee651aa2,0xe926def0,0xb9b10ad7,0x6542c9be,0xa2fcbe74,0x098e309b },
wolfSSL 16:8e0d178b1d1e 22643 { 0xfff1d63f,0x779deeb3,0x20bfd374,0x23d0e80a,0x8768f797,0x8452bb3b,
wolfSSL 16:8e0d178b1d1e 22644 0x1f952856,0xcf75bb4d,0x29ea3faa,0x8fe6b400,0x81373a53,0x12bd3e40 } },
wolfSSL 16:8e0d178b1d1e 22645 /* 8 */
wolfSSL 16:8e0d178b1d1e 22646 { { 0x16973cf4,0x070d34e1,0x7e4f34f7,0x20aee08b,0x5eb8ad29,0x269af9b9,
wolfSSL 16:8e0d178b1d1e 22647 0xa6a45dda,0xdde0a036,0x63df41e0,0xa18b528e,0xa260df2a,0x03cc71b2 },
wolfSSL 16:8e0d178b1d1e 22648 { 0xa06b1dd7,0x24a6770a,0x9d2675d3,0x5bfa9c11,0x96844432,0x73c1e2a1,
wolfSSL 16:8e0d178b1d1e 22649 0x131a6cf0,0x3660558d,0x2ee79454,0xb0289c83,0xc6d8ddcd,0xa6aefb01 } },
wolfSSL 16:8e0d178b1d1e 22650 /* 9 */
wolfSSL 16:8e0d178b1d1e 22651 { { 0x01ab5245,0xba1464b4,0xc48d93ff,0x9b8d0b6d,0x93ad272c,0x939867dc,
wolfSSL 16:8e0d178b1d1e 22652 0xae9fdc77,0xbebe085e,0x894ea8bd,0x73ae5103,0x39ac22e1,0x740fc89a },
wolfSSL 16:8e0d178b1d1e 22653 { 0x28e23b23,0x5e28b0a3,0xe13104d0,0x2352722e,0xb0a2640d,0xf4667a18,
wolfSSL 16:8e0d178b1d1e 22654 0x49bb37c3,0xac74a72e,0xe81e183a,0x79f734f0,0x3fd9c0eb,0xbffe5b6c } },
wolfSSL 16:8e0d178b1d1e 22655 /* 10 */
wolfSSL 16:8e0d178b1d1e 22656 { { 0x00623f3b,0x03cf2922,0x5f29ebff,0x095c7111,0x80aa6823,0x42d72247,
wolfSSL 16:8e0d178b1d1e 22657 0x7458c0b0,0x044c7ba1,0x0959ec20,0xca62f7ef,0xf8ca929f,0x40ae2ab7 },
wolfSSL 16:8e0d178b1d1e 22658 { 0xa927b102,0xb8c5377a,0xdc031771,0x398a86a0,0xc216a406,0x04908f9d,
wolfSSL 16:8e0d178b1d1e 22659 0x918d3300,0xb423a73a,0xe0b94739,0x634b0ff1,0x2d69f697,0xe29de725 } },
wolfSSL 16:8e0d178b1d1e 22660 /* 11 */
wolfSSL 16:8e0d178b1d1e 22661 { { 0x8435af04,0x744d1400,0xfec192da,0x5f255b1d,0x336dc542,0x1f17dc12,
wolfSSL 16:8e0d178b1d1e 22662 0x636a68a8,0x5c90c2a7,0x7704ca1e,0x960c9eb7,0x6fb3d65a,0x9de8cf1e },
wolfSSL 16:8e0d178b1d1e 22663 { 0x511d3d06,0xc60fee0d,0xf9eb52c7,0x466e2313,0x206b0914,0x743c0f5f,
wolfSSL 16:8e0d178b1d1e 22664 0x2191aa4d,0x42f55bac,0xffebdbc2,0xcefc7c8f,0xe6e8ed1c,0xd4fa6081 } },
wolfSSL 16:8e0d178b1d1e 22665 /* 12 */
wolfSSL 16:8e0d178b1d1e 22666 { { 0x98683186,0x867db639,0xddcc4ea9,0xfb5cf424,0xd4f0e7bd,0xcc9a7ffe,
wolfSSL 16:8e0d178b1d1e 22667 0x7a779f7e,0x7c57f71c,0xd6b25ef2,0x90774079,0xb4081680,0x90eae903 },
wolfSSL 16:8e0d178b1d1e 22668 { 0x0ee1fceb,0xdf2aae5e,0xe86c1a1f,0x3ff1da24,0xca193edf,0x80f587d6,
wolfSSL 16:8e0d178b1d1e 22669 0xdc9b9d6a,0xa5695523,0x85920303,0x7b840900,0xba6dbdef,0x1efa4dfc } },
wolfSSL 16:8e0d178b1d1e 22670 /* 13 */
wolfSSL 16:8e0d178b1d1e 22671 { { 0xe0540015,0xfbd838f9,0xc39077dc,0x2c323946,0xad619124,0x8b1fb9e6,
wolfSSL 16:8e0d178b1d1e 22672 0x0ca62ea8,0x9612440c,0x2dbe00ff,0x9ad9b52c,0xae197643,0xf52abaa1 },
wolfSSL 16:8e0d178b1d1e 22673 { 0x2cac32ad,0xd0e89894,0x62a98f91,0xdfb79e42,0x276f55cb,0x65452ecf,
wolfSSL 16:8e0d178b1d1e 22674 0x7ad23e12,0xdb1ac0d2,0xde4986f0,0xf68c5f6a,0x82ce327d,0x389ac37b } },
wolfSSL 16:8e0d178b1d1e 22675 /* 14 */
wolfSSL 16:8e0d178b1d1e 22676 { { 0xb8a9e8c9,0xcd96866d,0x5bb8091e,0xa11963b8,0x045b3cd2,0xc7f90d53,
wolfSSL 16:8e0d178b1d1e 22677 0x80f36504,0x755a72b5,0x21d3751c,0x46f8b399,0x53c193de,0x4bffdc91 },
wolfSSL 16:8e0d178b1d1e 22678 { 0xb89554e7,0xcd15c049,0xf7a26be6,0x353c6754,0xbd41d970,0x79602370,
wolfSSL 16:8e0d178b1d1e 22679 0x12b176c0,0xde16470b,0x40c8809d,0x56ba1175,0xe435fb1e,0xe2db35c3 } },
wolfSSL 16:8e0d178b1d1e 22680 /* 15 */
wolfSSL 16:8e0d178b1d1e 22681 { { 0x6328e33f,0xd71e4aab,0xaf8136d1,0x5486782b,0x86d57231,0x07a4995f,
wolfSSL 16:8e0d178b1d1e 22682 0x1651a968,0xf1f0a5bd,0x76803b6d,0xa5dc5b24,0x42dda935,0x5c587cbc },
wolfSSL 16:8e0d178b1d1e 22683 { 0xbae8b4c0,0x2b6cdb32,0xb1331138,0x66d1598b,0x5d7e9614,0x4a23b2d2,
wolfSSL 16:8e0d178b1d1e 22684 0x74a8c05d,0x93e402a6,0xda7ce82e,0x45ac94e6,0xe463d465,0xeb9f8281 } },
wolfSSL 16:8e0d178b1d1e 22685 };
wolfSSL 16:8e0d178b1d1e 22686
wolfSSL 16:8e0d178b1d1e 22687 /* Multiply the base point of P384 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 22688 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 22689 *
wolfSSL 16:8e0d178b1d1e 22690 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 22691 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 22692 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 22693 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 22694 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 22695 */
wolfSSL 16:8e0d178b1d1e 22696 static int sp_384_ecc_mulmod_base_12(sp_point_384* r, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 22697 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 22698 {
wolfSSL 16:8e0d178b1d1e 22699 return sp_384_ecc_mulmod_stripe_12(r, &p384_base, p384_table,
wolfSSL 16:8e0d178b1d1e 22700 k, map, heap);
wolfSSL 16:8e0d178b1d1e 22701 }
wolfSSL 16:8e0d178b1d1e 22702
wolfSSL 16:8e0d178b1d1e 22703 #else
wolfSSL 16:8e0d178b1d1e 22704 static const sp_table_entry_384 p384_table[256] = {
wolfSSL 16:8e0d178b1d1e 22705 /* 0 */
wolfSSL 16:8e0d178b1d1e 22706 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
wolfSSL 16:8e0d178b1d1e 22707 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
wolfSSL 16:8e0d178b1d1e 22708 /* 1 */
wolfSSL 16:8e0d178b1d1e 22709 { { 0x49c0b528,0x3dd07566,0xa0d6ce38,0x20e378e2,0x541b4d6e,0x879c3afc,
wolfSSL 16:8e0d178b1d1e 22710 0x59a30eff,0x64548684,0x614ede2b,0x812ff723,0x299e1513,0x4d3aadc2 },
wolfSSL 16:8e0d178b1d1e 22711 { 0x4b03a4fe,0x23043dad,0x7bb4a9ac,0xa1bfa8bf,0x2e83b050,0x8bade756,
wolfSSL 16:8e0d178b1d1e 22712 0x68f4ffd9,0xc6c35219,0x3969a840,0xdd800226,0x5a15c5e9,0x2b78abc2 } },
wolfSSL 16:8e0d178b1d1e 22713 /* 2 */
wolfSSL 16:8e0d178b1d1e 22714 { { 0x2b0c535b,0x29864753,0x70506296,0x90dd6953,0x216ab9ac,0x038cd6b4,
wolfSSL 16:8e0d178b1d1e 22715 0xbe12d76a,0x3df9b7b7,0x5f347bdb,0x13f4d978,0x13e94489,0x222c5c9c },
wolfSSL 16:8e0d178b1d1e 22716 { 0x2680dc64,0x5f8e796f,0x58352417,0x120e7cb7,0xd10740b8,0x254b5d8a,
wolfSSL 16:8e0d178b1d1e 22717 0x5337dee6,0xc38b8efb,0x94f02247,0xf688c2e1,0x6c25bc4c,0x7b5c75f3 } },
wolfSSL 16:8e0d178b1d1e 22718 /* 3 */
wolfSSL 16:8e0d178b1d1e 22719 { { 0x9edffea5,0xe26a3cc3,0x37d7e9fc,0x35bbfd1c,0x9bde3ef6,0xf0e7700d,
wolfSSL 16:8e0d178b1d1e 22720 0x1a538f5a,0x0380eb47,0x05bf9eb3,0x2e9da8bb,0x1a460c3e,0xdbb93c73 },
wolfSSL 16:8e0d178b1d1e 22721 { 0xf526b605,0x37dba260,0xfd785537,0x95d4978e,0xed72a04a,0x24ed793a,
wolfSSL 16:8e0d178b1d1e 22722 0x76005b1a,0x26948377,0x9e681f82,0x99f557b9,0xd64954ef,0xae5f9557 } },
wolfSSL 16:8e0d178b1d1e 22723 /* 4 */
wolfSSL 16:8e0d178b1d1e 22724 { { 0xf26feef9,0x24480c57,0x3a0e1240,0xc31a2694,0x273e2bc7,0x735002c3,
wolfSSL 16:8e0d178b1d1e 22725 0x3ef1ed4c,0x8c42e9c5,0x7f4948e8,0x028babf6,0x8a978632,0x6a502f43 },
wolfSSL 16:8e0d178b1d1e 22726 { 0xb74536fe,0xf5f13a46,0xd8a9f0eb,0x1d218bab,0x37232768,0x30f36bcc,
wolfSSL 16:8e0d178b1d1e 22727 0x576e8c18,0xc5317b31,0x9bbcb766,0xef1d57a6,0xb3e3d4dc,0x917c4930 } },
wolfSSL 16:8e0d178b1d1e 22728 /* 5 */
wolfSSL 16:8e0d178b1d1e 22729 { { 0xe349ddd0,0x11426e2e,0x9b2fc250,0x9f117ef9,0xec0174a6,0xff36b480,
wolfSSL 16:8e0d178b1d1e 22730 0x18458466,0x4f4bde76,0x05806049,0x2f2edb6d,0x19dfca92,0x8adc75d1 },
wolfSSL 16:8e0d178b1d1e 22731 { 0xb7d5a7ce,0xa619d097,0xa34411e9,0x874275e5,0x0da4b4ef,0x5403e047,
wolfSSL 16:8e0d178b1d1e 22732 0x77901d8f,0x2ebaafd9,0xa747170f,0x5e63ebce,0x7f9d8036,0x12a36944 } },
wolfSSL 16:8e0d178b1d1e 22733 /* 6 */
wolfSSL 16:8e0d178b1d1e 22734 { { 0x4fc52870,0x28f9c07a,0x1a53a961,0xce0b3748,0x0e1828d9,0xd550fa18,
wolfSSL 16:8e0d178b1d1e 22735 0x6adb225a,0xa24abaf7,0x6e58a348,0xd11ed0a5,0x948acb62,0xf3d811e6 },
wolfSSL 16:8e0d178b1d1e 22736 { 0x4c61ed22,0x8618dd77,0x80b47c9d,0x0bb747f9,0xde6b8559,0x22bf796f,
wolfSSL 16:8e0d178b1d1e 22737 0x680a21e9,0xfdfd1c6d,0x2af2c9dd,0xc0db1577,0xc1e90f3d,0xa09379e6 } },
wolfSSL 16:8e0d178b1d1e 22738 /* 7 */
wolfSSL 16:8e0d178b1d1e 22739 { { 0xe085c629,0x386c66ef,0x095bc89a,0x5fc2a461,0x203f4b41,0x1353d631,
wolfSSL 16:8e0d178b1d1e 22740 0x7e4bd8f5,0x7ca1972b,0xa7df8ce9,0xb077380a,0xee7e4ea3,0xd8a90389 },
wolfSSL 16:8e0d178b1d1e 22741 { 0xe7b14461,0x1bc74dc7,0x0c9c4f78,0xdc2cb014,0x84ef0a10,0x52b4b3a6,
wolfSSL 16:8e0d178b1d1e 22742 0x20327fe2,0xbde6ea5d,0x660f9615,0xb71ec435,0xb8ad8173,0xeede5a04 } },
wolfSSL 16:8e0d178b1d1e 22743 /* 8 */
wolfSSL 16:8e0d178b1d1e 22744 { { 0x893b9a2d,0x5584cbb3,0x00850c5d,0x820c660b,0x7df2d43d,0x4126d826,
wolfSSL 16:8e0d178b1d1e 22745 0x0109e801,0xdd5bbbf0,0x38172f1c,0x85b92ee3,0xf31430d9,0x609d4f93 },
wolfSSL 16:8e0d178b1d1e 22746 { 0xeadaf9d6,0x1e059a07,0x0f125fb0,0x70e6536c,0x560f20e7,0xd6220751,
wolfSSL 16:8e0d178b1d1e 22747 0x7aaf3a9a,0xa59489ae,0x64bae14e,0x7b70e2f6,0x76d08249,0x0dd03701 } },
wolfSSL 16:8e0d178b1d1e 22748 /* 9 */
wolfSSL 16:8e0d178b1d1e 22749 { { 0x8510521f,0x4cc13be8,0xf724cc17,0x87315ba9,0x353dc263,0xb49d83bb,
wolfSSL 16:8e0d178b1d1e 22750 0x0c279257,0x8b677efe,0xc93c9537,0x510a1c1c,0xa4702c99,0x33e30cd8 },
wolfSSL 16:8e0d178b1d1e 22751 { 0x2208353f,0xf0ffc89d,0xced42b2b,0x0170fa8d,0x26e2a5f5,0x090851ed,
wolfSSL 16:8e0d178b1d1e 22752 0xecb52c96,0x81276455,0x7fe1adf4,0x0646c4e1,0xb0868eab,0x513f047e } },
wolfSSL 16:8e0d178b1d1e 22753 /* 10 */
wolfSSL 16:8e0d178b1d1e 22754 { { 0xdf5bdf53,0xc07611f4,0x58b11a6d,0x45d331a7,0x1c4ee394,0x58965daf,
wolfSSL 16:8e0d178b1d1e 22755 0x5a5878d1,0xba8bebe7,0x82dd3025,0xaecc0a18,0xa923eb8b,0xcf2a3899 },
wolfSSL 16:8e0d178b1d1e 22756 { 0xd24fd048,0xf98c9281,0x8bbb025d,0x841bfb59,0xc9ab9d53,0xb8ddf8ce,
wolfSSL 16:8e0d178b1d1e 22757 0x7fef044e,0x538a4cb6,0x23236662,0x092ac21f,0x0b66f065,0xa919d385 } },
wolfSSL 16:8e0d178b1d1e 22758 /* 11 */
wolfSSL 16:8e0d178b1d1e 22759 { { 0x85d480d8,0x3db03b40,0x1b287a7d,0x8cd9f479,0x4a8f3bae,0x8f24dc75,
wolfSSL 16:8e0d178b1d1e 22760 0x3db41892,0x482eb800,0x9c56e0f5,0x38bf9eb3,0x9a91dc6f,0x8b977320 },
wolfSSL 16:8e0d178b1d1e 22761 { 0x7209cfc2,0xa31b05b2,0x05b2db70,0x4c49bf85,0xd619527b,0x56462498,
wolfSSL 16:8e0d178b1d1e 22762 0x1fac51ba,0x3fe51039,0xab4b8342,0xfb04f55e,0x04c6eabf,0xc07c10dc } },
wolfSSL 16:8e0d178b1d1e 22763 /* 12 */
wolfSSL 16:8e0d178b1d1e 22764 { { 0xdb32f048,0xad22fe4c,0x475ed6df,0x5f23bf91,0xaa66b6cb,0xa50ce0c0,
wolfSSL 16:8e0d178b1d1e 22765 0xf03405c0,0xdf627a89,0xf95e2d6a,0x3674837d,0xba42e64e,0x081c95b6 },
wolfSSL 16:8e0d178b1d1e 22766 { 0xe71d6ceb,0xeba3e036,0x6c6b0271,0xb45bcccf,0x0684701d,0x67b47e63,
wolfSSL 16:8e0d178b1d1e 22767 0xe712523f,0x60f8f942,0x5cd47adc,0x82423472,0x87649cbb,0x83027d79 } },
wolfSSL 16:8e0d178b1d1e 22768 /* 13 */
wolfSSL 16:8e0d178b1d1e 22769 { { 0x3615b0b8,0xb3929ea6,0xa54dac41,0xb41441fd,0xb5b6a368,0x8995d556,
wolfSSL 16:8e0d178b1d1e 22770 0x167ef05e,0xa80d4529,0x6d25a27f,0xf6bcb4a1,0x7bd55b68,0x210d6a4c },
wolfSSL 16:8e0d178b1d1e 22771 { 0x25351130,0xf3804abb,0x903e37eb,0x1d2df699,0x084c25c8,0x5f201efc,
wolfSSL 16:8e0d178b1d1e 22772 0xa1c68e91,0x31a28c87,0x563f62a5,0x81dad253,0xd6c415d4,0x5dd6de70 } },
wolfSSL 16:8e0d178b1d1e 22773 /* 14 */
wolfSSL 16:8e0d178b1d1e 22774 { { 0x846612ce,0x29f470fd,0xda18d997,0x986f3eec,0x2f34af86,0x6b84c161,
wolfSSL 16:8e0d178b1d1e 22775 0x46ddaf8b,0x5ef0a408,0xe49e795f,0x14405a00,0xaa2f7a37,0x5f491b16 },
wolfSSL 16:8e0d178b1d1e 22776 { 0xdb41b38d,0xc7f07ae4,0x18fbfcaa,0xef7d119e,0x14443b19,0x3a18e076,
wolfSSL 16:8e0d178b1d1e 22777 0x79a19926,0x4356841a,0xe2226fbe,0x91f4a91c,0x3cc88721,0xdc77248c } },
wolfSSL 16:8e0d178b1d1e 22778 /* 15 */
wolfSSL 16:8e0d178b1d1e 22779 { { 0xe4b1ec9d,0xd570ff1a,0xe7eef706,0x21d23e0e,0xca19e086,0x3cde40f4,
wolfSSL 16:8e0d178b1d1e 22780 0xcd4bb270,0x7d6523c4,0xbf13aa6c,0x16c1f06c,0xd14c4b60,0x5aa7245a },
wolfSSL 16:8e0d178b1d1e 22781 { 0x44b74de8,0x37f81467,0x620a934e,0x839e7a17,0xde8b1aa1,0xf74d14e8,
wolfSSL 16:8e0d178b1d1e 22782 0xf30d75e2,0x8789fa51,0xc81c261e,0x09b24052,0x33c565ee,0x654e2678 } },
wolfSSL 16:8e0d178b1d1e 22783 /* 16 */
wolfSSL 16:8e0d178b1d1e 22784 { { 0x2f9fbe67,0x378205de,0x7f728e44,0xc4afcb83,0x682e00f1,0xdbcec06c,
wolfSSL 16:8e0d178b1d1e 22785 0x114d5423,0xf2a145c3,0x7a52463e,0xa01d9874,0x7d717b0a,0xfc0935b1 },
wolfSSL 16:8e0d178b1d1e 22786 { 0xd4d01f95,0x9653bc4f,0x9560ad34,0x9aa83ea8,0xaf8e3f3f,0xf77943dc,
wolfSSL 16:8e0d178b1d1e 22787 0xe86fe16e,0x70774a10,0xbf9ffdcf,0x6b62e6f1,0x588745c9,0x8a72f39e } },
wolfSSL 16:8e0d178b1d1e 22788 /* 17 */
wolfSSL 16:8e0d178b1d1e 22789 { { 0x2341c342,0x73ade4da,0xea704422,0xdd326e54,0x3741cef3,0x336c7d98,
wolfSSL 16:8e0d178b1d1e 22790 0x59e61549,0x1eafa00d,0xbd9a3efd,0xcd3ed892,0xc5c6c7e4,0x03faf26c },
wolfSSL 16:8e0d178b1d1e 22791 { 0x3045f8ac,0x087e2fcf,0x174f1e73,0x14a65532,0xfe0af9a7,0x2cf84f28,
wolfSSL 16:8e0d178b1d1e 22792 0x2cdc935b,0xddfd7a84,0x6929c895,0x4c0f117b,0x4c8bcfcc,0x356572d6 } },
wolfSSL 16:8e0d178b1d1e 22793 /* 18 */
wolfSSL 16:8e0d178b1d1e 22794 { { 0x7d8c1bba,0x7ecbac01,0x90b0f3d5,0x6058f9c3,0xf6197d0f,0xaee116e3,
wolfSSL 16:8e0d178b1d1e 22795 0x4033b128,0xc4dd7068,0xc209b983,0xf084dba6,0x831dbc4a,0x97c7c2cf },
wolfSSL 16:8e0d178b1d1e 22796 { 0xf96010e8,0x2f4e61dd,0x529faa17,0xd97e4e20,0x69d37f20,0x4ee66660,
wolfSSL 16:8e0d178b1d1e 22797 0x3d366d72,0xccc139ed,0x13488e0f,0x690b6ee2,0xf3a6d533,0x7cad1dc5 } },
wolfSSL 16:8e0d178b1d1e 22798 /* 19 */
wolfSSL 16:8e0d178b1d1e 22799 { { 0xda57a41f,0x660a9a81,0xec0039b6,0xe74a0412,0x5e1dad15,0x42343c6b,
wolfSSL 16:8e0d178b1d1e 22800 0x46681d4c,0x284f3ff5,0x63749e89,0xb51087f1,0x6f9f2f13,0x070f23cc },
wolfSSL 16:8e0d178b1d1e 22801 { 0x5d186e14,0x542211da,0xfddb0dff,0x84748f37,0xdb1f4180,0x41a3aab4,
wolfSSL 16:8e0d178b1d1e 22802 0xa6402d0e,0x25ed667b,0x02f58355,0x2f2924a9,0xfa44a689,0x5844ee7c } },
wolfSSL 16:8e0d178b1d1e 22803 /* 20 */
wolfSSL 16:8e0d178b1d1e 22804 { { 0x3f3b236f,0xfab08607,0x81e221da,0x19e9d41d,0x3927b428,0xf3f6571e,
wolfSSL 16:8e0d178b1d1e 22805 0x7550f1f6,0x4348a933,0xa85e62f0,0x7167b996,0x7f5452bf,0x62d43759 },
wolfSSL 16:8e0d178b1d1e 22806 { 0xf2955926,0xd85feb9e,0x6df78353,0x440a561f,0x9ca36b59,0x389668ec,
wolfSSL 16:8e0d178b1d1e 22807 0xa22da016,0x052bf1a1,0xf6093254,0xbdfbff72,0xe22209f3,0x94e50f28 } },
wolfSSL 16:8e0d178b1d1e 22808 /* 21 */
wolfSSL 16:8e0d178b1d1e 22809 { { 0x3062e8af,0x90b2e5b3,0xe8a3d369,0xa8572375,0x201db7b1,0x3fe1b00b,
wolfSSL 16:8e0d178b1d1e 22810 0xee651aa2,0xe926def0,0xb9b10ad7,0x6542c9be,0xa2fcbe74,0x098e309b },
wolfSSL 16:8e0d178b1d1e 22811 { 0xfff1d63f,0x779deeb3,0x20bfd374,0x23d0e80a,0x8768f797,0x8452bb3b,
wolfSSL 16:8e0d178b1d1e 22812 0x1f952856,0xcf75bb4d,0x29ea3faa,0x8fe6b400,0x81373a53,0x12bd3e40 } },
wolfSSL 16:8e0d178b1d1e 22813 /* 22 */
wolfSSL 16:8e0d178b1d1e 22814 { { 0x104cbba5,0xc023780d,0xfa35dd4c,0x6207e747,0x1ca9b6a3,0x35c23928,
wolfSSL 16:8e0d178b1d1e 22815 0x97987b10,0x4ff19be8,0x8022eee8,0xb8476bbf,0xd3bbe74d,0xaa0a4a14 },
wolfSSL 16:8e0d178b1d1e 22816 { 0x187d4543,0x20f94331,0x79f6e066,0x32153870,0xac7e82e1,0x83b0f74e,
wolfSSL 16:8e0d178b1d1e 22817 0x828f06ab,0xa7748ba2,0xc26ef35f,0xc5f0298a,0x8e9a7dbd,0x0f0c5070 } },
wolfSSL 16:8e0d178b1d1e 22818 /* 23 */
wolfSSL 16:8e0d178b1d1e 22819 { { 0xdef029dd,0x0c5c244c,0x850661b8,0x3dabc687,0xfe11d981,0x9992b865,
wolfSSL 16:8e0d178b1d1e 22820 0x6274dbad,0xe9801b8f,0x098da242,0xe54e6319,0x91a53d08,0x9929a91a },
wolfSSL 16:8e0d178b1d1e 22821 { 0x35285887,0x37bffd72,0xf1418102,0xbc759425,0xfd2e6e20,0x9280cc35,
wolfSSL 16:8e0d178b1d1e 22822 0xfbc42ee5,0x735c600c,0x8837619a,0xb7ad2864,0xa778c57b,0xa3627231 } },
wolfSSL 16:8e0d178b1d1e 22823 /* 24 */
wolfSSL 16:8e0d178b1d1e 22824 { { 0x91361ed8,0xae799b5c,0x6c63366c,0x47d71b75,0x1b265a6a,0x54cdd521,
wolfSSL 16:8e0d178b1d1e 22825 0x98d77b74,0xe0215a59,0xbab29db0,0x4424d9b7,0x7fd9e536,0x8b0ffacc },
wolfSSL 16:8e0d178b1d1e 22826 { 0x37b5d9ef,0x46d85d12,0xbfa91747,0x5b106d62,0x5f99ba2d,0xed0479f8,
wolfSSL 16:8e0d178b1d1e 22827 0x1d104de4,0x0e6f3923,0x25e8983f,0x83a84c84,0xf8105a70,0xa9507e0a } },
wolfSSL 16:8e0d178b1d1e 22828 /* 25 */
wolfSSL 16:8e0d178b1d1e 22829 { { 0x14cf381c,0xf6c68a6e,0xc22e31cc,0xaf9d27bd,0xaa8a5ccb,0x23568d4d,
wolfSSL 16:8e0d178b1d1e 22830 0xe338e4d2,0xe431eec0,0x8f52ad1f,0xf1a828fe,0xe86acd80,0xdb6a0579 },
wolfSSL 16:8e0d178b1d1e 22831 { 0x4507832a,0x2885672e,0x887e5289,0x73fc275f,0x05610d08,0x65f80278,
wolfSSL 16:8e0d178b1d1e 22832 0x075ff5b0,0x8d9b4554,0x09f712b5,0x3a8e8fb1,0x2ebe9cf2,0x39f0ac86 } },
wolfSSL 16:8e0d178b1d1e 22833 /* 26 */
wolfSSL 16:8e0d178b1d1e 22834 { { 0x4c52edf5,0xd8fabf78,0xa589ae53,0xdcd737e5,0xd791ab17,0x94918bf0,
wolfSSL 16:8e0d178b1d1e 22835 0xbcff06c9,0xb5fbd956,0xdca46d45,0xf6d3032e,0x41a3e486,0x2cdff7e1 },
wolfSSL 16:8e0d178b1d1e 22836 { 0x61f47ec8,0x6674b3ba,0xeef84608,0x8a882163,0x4c687f90,0xa257c705,
wolfSSL 16:8e0d178b1d1e 22837 0xf6cdf227,0xe30cb2ed,0x7f6ea846,0x2c4c64ca,0xcc6bcd3c,0x186fa17c } },
wolfSSL 16:8e0d178b1d1e 22838 /* 27 */
wolfSSL 16:8e0d178b1d1e 22839 { { 0x1dfcb91e,0x48a3f536,0x646d358a,0x83595e13,0x91128798,0xbd15827b,
wolfSSL 16:8e0d178b1d1e 22840 0x2187757a,0x3ce612b8,0x61bd7372,0x873150a1,0xb662f568,0xf4684530 },
wolfSSL 16:8e0d178b1d1e 22841 { 0x401896f6,0x8833950b,0x77f3e090,0xe11cb89a,0x48e7f4a5,0xb2f12cac,
wolfSSL 16:8e0d178b1d1e 22842 0xf606677e,0x313dd769,0x16579f93,0xfdcf08b3,0x46b8f22b,0x6429cec9 } },
wolfSSL 16:8e0d178b1d1e 22843 /* 28 */
wolfSSL 16:8e0d178b1d1e 22844 { { 0xbb75f9a4,0x4984dd54,0x29d3b570,0x4aef06b9,0x3d6e4c1e,0xb5f84ca2,
wolfSSL 16:8e0d178b1d1e 22845 0xb083ef35,0x24c61c11,0x392ca9ff,0xce4a7392,0x6730a800,0x865d6517 },
wolfSSL 16:8e0d178b1d1e 22846 { 0x722b4a2b,0xca3dfe76,0x7b083e0e,0x12c04bf9,0x1b86b8a5,0x803ce5b5,
wolfSSL 16:8e0d178b1d1e 22847 0x6a7e3e0c,0x3fc7632d,0xc81adbe4,0xc89970c2,0x120e16b1,0x3cbcd3ad } },
wolfSSL 16:8e0d178b1d1e 22848 /* 29 */
wolfSSL 16:8e0d178b1d1e 22849 { { 0xec30ce93,0xfbfb4cc7,0xb72720a2,0x10ed6c7d,0x47b55500,0xec675bf7,
wolfSSL 16:8e0d178b1d1e 22850 0x333ff7c3,0x90725903,0x5075bfc0,0xc7c3973e,0x07acf31b,0xb049ecb0 },
wolfSSL 16:8e0d178b1d1e 22851 { 0x4f58839c,0xb4076eaf,0xa2b05e4f,0x101896da,0xab40c66e,0x3f6033b0,
wolfSSL 16:8e0d178b1d1e 22852 0xc8d864ba,0x19ee9eeb,0x47bf6d2a,0xeb6cf155,0xf826477d,0x8e5a9663 } },
wolfSSL 16:8e0d178b1d1e 22853 /* 30 */
wolfSSL 16:8e0d178b1d1e 22854 { { 0xf7fbd5e1,0x69e62fdd,0x76912b1d,0x38ecfe54,0xd1da3bfb,0x845a3d56,
wolfSSL 16:8e0d178b1d1e 22855 0x1c86f0d4,0x0494950e,0x3bc36ce8,0x83cadbf9,0x4fccc8d1,0x41fce572 },
wolfSSL 16:8e0d178b1d1e 22856 { 0x8332c144,0x05f939c2,0x0871e46e,0xb17f248b,0x66e8aff6,0x3d8534e2,
wolfSSL 16:8e0d178b1d1e 22857 0x3b85c629,0x1d06f1dc,0xa3131b73,0xdb06a32e,0x8b3f64e5,0xf295184d } },
wolfSSL 16:8e0d178b1d1e 22858 /* 31 */
wolfSSL 16:8e0d178b1d1e 22859 { { 0x36ddc103,0xd9653ff7,0x95ef606f,0x25f43e37,0xfe06dce8,0x09e301fc,
wolfSSL 16:8e0d178b1d1e 22860 0x30b6eebf,0x85af2341,0x0ff56b20,0x79b12b53,0xfe9a3c6b,0x9b4fb499 },
wolfSSL 16:8e0d178b1d1e 22861 { 0x51d27ac2,0x0154f892,0x56ca5389,0xd33167e3,0xafc065a6,0x7828ec1f,
wolfSSL 16:8e0d178b1d1e 22862 0x7f746c9b,0x0959a258,0x0c44f837,0xb18f1be3,0xc4132fdb,0xa7946117 } },
wolfSSL 16:8e0d178b1d1e 22863 /* 32 */
wolfSSL 16:8e0d178b1d1e 22864 { { 0x5e3c647b,0xc0426b77,0x8cf05348,0xbfcbd939,0x172c0d3d,0x31d312e3,
wolfSSL 16:8e0d178b1d1e 22865 0xee754737,0x5f49fde6,0x6da7ee61,0x895530f0,0xe8b3a5fb,0xcf281b0a },
wolfSSL 16:8e0d178b1d1e 22866 { 0x41b8a543,0xfd149735,0x3080dd30,0x41a625a7,0x653908cf,0xe2baae07,
wolfSSL 16:8e0d178b1d1e 22867 0xba02a278,0xc3d01436,0x7b21b8f8,0xa0d0222e,0xd7ec1297,0xfdc270e9 } },
wolfSSL 16:8e0d178b1d1e 22868 /* 33 */
wolfSSL 16:8e0d178b1d1e 22869 { { 0xbc7f41d6,0x00873c0c,0x1b7ad641,0xd976113e,0x238443fb,0x2a536ff4,
wolfSSL 16:8e0d178b1d1e 22870 0x41e62e45,0x030d00e2,0x5f545fc6,0x532e9867,0x8e91208c,0xcd033108 },
wolfSSL 16:8e0d178b1d1e 22871 { 0x9797612c,0xd1a04c99,0xeea674e2,0xd4393e02,0xe19742a1,0xd56fa69e,
wolfSSL 16:8e0d178b1d1e 22872 0x85f0590e,0xdd2ab480,0x48a2243d,0xa5cefc52,0x54383f41,0x48cc67b6 } },
wolfSSL 16:8e0d178b1d1e 22873 /* 34 */
wolfSSL 16:8e0d178b1d1e 22874 { { 0xfc14ab48,0x4e50430e,0x26706a74,0x195b7f4f,0xcc881ff6,0x2fe8a228,
wolfSSL 16:8e0d178b1d1e 22875 0xd945013d,0xb1b968e2,0x4b92162b,0x936aa579,0x364e754a,0x4fb766b7 },
wolfSSL 16:8e0d178b1d1e 22876 { 0x31e1ff7f,0x13f93bca,0xce4f2691,0x696eb5ca,0xa2b09e02,0xff754bf8,
wolfSSL 16:8e0d178b1d1e 22877 0xe58e3ff8,0x58f13c9c,0x1678c0b0,0xb757346f,0xa86692b3,0xd54200db } },
wolfSSL 16:8e0d178b1d1e 22878 /* 35 */
wolfSSL 16:8e0d178b1d1e 22879 { { 0x6dda1265,0x9a030bbd,0xe89718dd,0xf7b4f3fc,0x936065b8,0xa6a4931f,
wolfSSL 16:8e0d178b1d1e 22880 0x5f72241c,0xbce72d87,0x65775857,0x6cbb51cb,0x4e993675,0xc7161815 },
wolfSSL 16:8e0d178b1d1e 22881 { 0x2ee32189,0xe81a0f79,0x277dc0b2,0xef2fab26,0xb71f469f,0x9e64f6fe,
wolfSSL 16:8e0d178b1d1e 22882 0xdfdaf859,0xb448ce33,0xbe6b5df1,0x3f5c1c4c,0x1de45f7b,0xfb8dfb00 } },
wolfSSL 16:8e0d178b1d1e 22883 /* 36 */
wolfSSL 16:8e0d178b1d1e 22884 { { 0x4d5bb921,0xc7345fa7,0x4d2b667e,0x5c7e04be,0x282d7a3e,0x47ed3a80,
wolfSSL 16:8e0d178b1d1e 22885 0x7e47b2a4,0x5c2777f8,0x08488e2e,0x89b3b100,0xb2eb5b45,0x9aad77c2 },
wolfSSL 16:8e0d178b1d1e 22886 { 0xdaac34ae,0xd681bca7,0x26afb326,0x2452e4e5,0x41a1ee14,0x0c887924,
wolfSSL 16:8e0d178b1d1e 22887 0xc2407ade,0x743b04d4,0xfc17a2ac,0xcb5e999b,0x4a701a06,0x4dca2f82 } },
wolfSSL 16:8e0d178b1d1e 22888 /* 37 */
wolfSSL 16:8e0d178b1d1e 22889 { { 0x1127bc1a,0x68e31ca6,0x17ead3be,0xa3edd59b,0xe25f5a15,0x67b6b645,
wolfSSL 16:8e0d178b1d1e 22890 0xa420e15e,0x76221794,0x4b1e872e,0x794fd83b,0xb2dece1b,0x7cab3f03 },
wolfSSL 16:8e0d178b1d1e 22891 { 0xca9b3586,0x7119bf15,0x4d250bd7,0xa5545924,0xcc6bcf24,0x173633ea,
wolfSSL 16:8e0d178b1d1e 22892 0xb1b6f884,0x9bd308c2,0x447d38c3,0x3bae06f5,0xf341fe1c,0x54dcc135 } },
wolfSSL 16:8e0d178b1d1e 22893 /* 38 */
wolfSSL 16:8e0d178b1d1e 22894 { { 0x943caf0d,0x56d3598d,0x225ff133,0xce044ea9,0x563fadea,0x9edf6a7c,
wolfSSL 16:8e0d178b1d1e 22895 0x73e8dc27,0x632eb944,0x3190dcab,0x814b467e,0x6dbb1e31,0x2d4f4f31 },
wolfSSL 16:8e0d178b1d1e 22896 { 0xa143b7ca,0x8d69811c,0xde7cf950,0x4ec1ac32,0x37b5fe82,0x223ab5fd,
wolfSSL 16:8e0d178b1d1e 22897 0x9390f1d9,0xe82616e4,0x75804610,0xabff4b20,0x875b08f0,0x11b9be15 } },
wolfSSL 16:8e0d178b1d1e 22898 /* 39 */
wolfSSL 16:8e0d178b1d1e 22899 { { 0x3bbe682c,0x4ae31a3d,0x74eef2dd,0xbc7c5d26,0x3c47dd40,0x92afd10a,
wolfSSL 16:8e0d178b1d1e 22900 0xc14ab9e1,0xec7e0a3b,0xb2e495e4,0x6a6c3dd1,0x309bcd85,0x085ee5e9 },
wolfSSL 16:8e0d178b1d1e 22901 { 0x8c2e67fd,0xf381a908,0xe261eaf2,0x32083a80,0x96deee15,0x0fcd6a49,
wolfSSL 16:8e0d178b1d1e 22902 0x5e524c79,0xe3b8fb03,0x1d5b08b9,0x8dc360d9,0x7f26719f,0x3a06e2c8 } },
wolfSSL 16:8e0d178b1d1e 22903 /* 40 */
wolfSSL 16:8e0d178b1d1e 22904 { { 0x7237cac0,0x5cd9f5a8,0x43586794,0x93f0b59d,0xe94f6c4e,0x4384a764,
wolfSSL 16:8e0d178b1d1e 22905 0xb62782d3,0x8304ed2b,0xcde06015,0x0b8db8b3,0x5dbe190f,0x4336dd53 },
wolfSSL 16:8e0d178b1d1e 22906 { 0x92ab473a,0x57443553,0xbe5ed046,0x031c7275,0x21909aa4,0x3e78678c,
wolfSSL 16:8e0d178b1d1e 22907 0x99202ddb,0x4ab7e04f,0x6977e635,0x2648d206,0x093198be,0xd427d184 } },
wolfSSL 16:8e0d178b1d1e 22908 /* 41 */
wolfSSL 16:8e0d178b1d1e 22909 { { 0x0f9b5a31,0x822848f5,0xbaadb62a,0xbb003468,0x3357559c,0x233a0472,
wolfSSL 16:8e0d178b1d1e 22910 0x79aee843,0x49ef6880,0xaeb9e1e3,0xa89867a0,0x1f6f9a55,0xc151931b },
wolfSSL 16:8e0d178b1d1e 22911 { 0xad74251e,0xd264eb0b,0x4abf295e,0x37b9b263,0x04960d10,0xb600921b,
wolfSSL 16:8e0d178b1d1e 22912 0x4da77dc0,0x0de53dbc,0xd2b18697,0x01d9bab3,0xf7156ddf,0xad54ec7a } },
wolfSSL 16:8e0d178b1d1e 22913 /* 42 */
wolfSSL 16:8e0d178b1d1e 22914 { { 0x79efdc58,0x8e74dc35,0x4ff68ddb,0x456bd369,0xd32096a5,0x724e74cc,
wolfSSL 16:8e0d178b1d1e 22915 0x386783d0,0xe41cff42,0x7c70d8a4,0xa04c7f21,0xe61a19a2,0x41199d2f },
wolfSSL 16:8e0d178b1d1e 22916 { 0x29c05dd2,0xd389a3e0,0xe7e3fda9,0x535f2a6b,0x7c2b4df8,0x26ecf72d,
wolfSSL 16:8e0d178b1d1e 22917 0xfe745294,0x678275f4,0x9d23f519,0x6319c9cc,0x88048fc4,0x1e05a02d } },
wolfSSL 16:8e0d178b1d1e 22918 /* 43 */
wolfSSL 16:8e0d178b1d1e 22919 { { 0xd4d5ffe8,0x75cc8e2e,0xdbea17f2,0xf8bb4896,0xcee3cb4a,0x35059790,
wolfSSL 16:8e0d178b1d1e 22920 0xa47c6165,0x4c06ee85,0x92935d2f,0xf98fff25,0x32ffd7c7,0x34c4a572 },
wolfSSL 16:8e0d178b1d1e 22921 { 0xea0376a2,0xc4b14806,0x4f115e02,0x2ea5e750,0x1e55d7c0,0x532d76e2,
wolfSSL 16:8e0d178b1d1e 22922 0xf31044da,0x68dc9411,0x71b77993,0x9272e465,0x93a8cfd5,0xadaa38bb } },
wolfSSL 16:8e0d178b1d1e 22923 /* 44 */
wolfSSL 16:8e0d178b1d1e 22924 { { 0x7d4ed72a,0x4bf0c712,0xba1f79a3,0xda0e9264,0xf4c39ea4,0x48c0258b,
wolfSSL 16:8e0d178b1d1e 22925 0x2a715138,0xa5394ed8,0xbf06c660,0x4af511ce,0xec5c37cd,0xfcebceef },
wolfSSL 16:8e0d178b1d1e 22926 { 0x779ae8c1,0xf23b75aa,0xad1e606e,0xdeff59cc,0x22755c82,0xf3f526fd,
wolfSSL 16:8e0d178b1d1e 22927 0xbb32cefd,0x64c5ab44,0x915bdefd,0xa96e11a2,0x1143813e,0xab19746a } },
wolfSSL 16:8e0d178b1d1e 22928 /* 45 */
wolfSSL 16:8e0d178b1d1e 22929 { { 0xec837d7d,0x43c78585,0xb8ee0ba4,0xca5b6fbc,0xd5dbb5ee,0x34e924d9,
wolfSSL 16:8e0d178b1d1e 22930 0xbb4f1ca5,0x3f4fa104,0x398640f7,0x15458b72,0xd7f407ea,0x4231faa9 },
wolfSSL 16:8e0d178b1d1e 22931 { 0xf96e6896,0x53e0661e,0xd03b0f9d,0x554e4c69,0x9c7858d1,0xd4fcb07b,
wolfSSL 16:8e0d178b1d1e 22932 0x52cb04fa,0x7e952793,0x8974e7f7,0x5f5f1574,0x6b6d57c8,0x2e3fa558 } },
wolfSSL 16:8e0d178b1d1e 22933 /* 46 */
wolfSSL 16:8e0d178b1d1e 22934 { { 0x6a9951a8,0x42cd4803,0x42792ad0,0xa8b15b88,0xabb29a73,0x18e8bcf9,
wolfSSL 16:8e0d178b1d1e 22935 0x409933e8,0xbfd9a092,0xefb88dc4,0x760a3594,0x40724458,0x14418863 },
wolfSSL 16:8e0d178b1d1e 22936 { 0x99caedc7,0x162a56ee,0x91d101c9,0x8fb12ecd,0x393202da,0xea671967,
wolfSSL 16:8e0d178b1d1e 22937 0xa4ccd796,0x1aac8c4a,0x1cf185a8,0x7db05036,0x8cfd095a,0x0c9f86cd } },
wolfSSL 16:8e0d178b1d1e 22938 /* 47 */
wolfSSL 16:8e0d178b1d1e 22939 { { 0x10b2a556,0x9a728147,0x327b70b2,0x767ca964,0x5e3799b7,0x04ed9e12,
wolfSSL 16:8e0d178b1d1e 22940 0x22a3eb2a,0x6781d2dc,0x0d9450ac,0x5bd116eb,0xa7ebe08a,0xeccac1fc },
wolfSSL 16:8e0d178b1d1e 22941 { 0xdc2d6e94,0xde68444f,0x35ecf21b,0x3621f429,0x29e03a2c,0x14e2d543,
wolfSSL 16:8e0d178b1d1e 22942 0x7d3e7f0a,0x53e42cd5,0x73ed00b9,0xbba26c09,0xc57d2272,0x00297c39 } },
wolfSSL 16:8e0d178b1d1e 22943 /* 48 */
wolfSSL 16:8e0d178b1d1e 22944 { { 0xb8243a7d,0x3aaaab10,0x8fa58c5b,0x6eeef93e,0x9ae7f764,0xf866fca3,
wolfSSL 16:8e0d178b1d1e 22945 0x61ab04d3,0x64105a26,0x03945d66,0xa3578d8a,0x791b848c,0xb08cd3e4 },
wolfSSL 16:8e0d178b1d1e 22946 { 0x756d2411,0x45edc5f8,0xa755128c,0xd4a790d9,0x49e5f6a0,0xc2cf0963,
wolfSSL 16:8e0d178b1d1e 22947 0xf649beaa,0xc66d267d,0x8467039e,0x3ce6d968,0x42f7816f,0x50046c6b } },
wolfSSL 16:8e0d178b1d1e 22948 /* 49 */
wolfSSL 16:8e0d178b1d1e 22949 { { 0x66425043,0x92ae1602,0xf08db890,0x1ff66afd,0x8f162ce5,0x386f5a7f,
wolfSSL 16:8e0d178b1d1e 22950 0xfcf5598f,0x18d2dea0,0x1a8ca18e,0x78372b3a,0x8cd0e6f7,0xdf0d20eb },
wolfSSL 16:8e0d178b1d1e 22951 { 0x75bb4045,0x7edd5e1d,0xb96d94b7,0x252a47ce,0x2c626776,0xbdb29358,
wolfSSL 16:8e0d178b1d1e 22952 0x40dd1031,0x853c3943,0x7d5f47fd,0x9dc9becf,0xbae4044a,0x27c2302f } },
wolfSSL 16:8e0d178b1d1e 22953 /* 50 */
wolfSSL 16:8e0d178b1d1e 22954 { { 0x8f2d49ce,0x2d1d208a,0x162df0a2,0x0d91aa02,0x09a07f65,0x9c5cce87,
wolfSSL 16:8e0d178b1d1e 22955 0x84339012,0xdf07238b,0x419442cd,0x5028e2c8,0x72062aba,0x2dcbd358 },
wolfSSL 16:8e0d178b1d1e 22956 { 0xe4680967,0xb5fbc3cb,0x9f92d72c,0x2a7bc645,0x116c369d,0x806c76e1,
wolfSSL 16:8e0d178b1d1e 22957 0x3177e8d8,0x5c50677a,0x4569df57,0x753739eb,0x36c3f40b,0x2d481ef6 } },
wolfSSL 16:8e0d178b1d1e 22958 /* 51 */
wolfSSL 16:8e0d178b1d1e 22959 { { 0xfea1103e,0x1a2d39fd,0x95f81b17,0xeaae5592,0xf59b264a,0xdbd0aa18,
wolfSSL 16:8e0d178b1d1e 22960 0xcb592ee0,0x90c39c1a,0x9750cca3,0xdf62f80d,0xdf97cc6c,0xda4d8283 },
wolfSSL 16:8e0d178b1d1e 22961 { 0x1e201067,0x0a6dd346,0x69fb1f6b,0x1531f859,0x1d60121f,0x4895e552,
wolfSSL 16:8e0d178b1d1e 22962 0x4c041c91,0x0b21aab0,0xbcc1ccf8,0x9d896c46,0x3141bde7,0xd24da3b3 } },
wolfSSL 16:8e0d178b1d1e 22963 /* 52 */
wolfSSL 16:8e0d178b1d1e 22964 { { 0x53b0a354,0x575a0537,0x0c6ddcd8,0x392ff2f4,0x56157b94,0x0b8e8cff,
wolfSSL 16:8e0d178b1d1e 22965 0x3b1b80d1,0x073e57bd,0x3fedee15,0x2a75e0f0,0xaa8e6f19,0x752380e4 },
wolfSSL 16:8e0d178b1d1e 22966 { 0x6558ffe9,0x1f4e227c,0x19ec5415,0x3a348618,0xf7997085,0xab382d5e,
wolfSSL 16:8e0d178b1d1e 22967 0xddc46ac2,0x5e6deaff,0xfc8d094c,0xe5144078,0xf60e37c6,0xf674fe51 } },
wolfSSL 16:8e0d178b1d1e 22968 /* 53 */
wolfSSL 16:8e0d178b1d1e 22969 { { 0xaf63408f,0x6fb87ae5,0xcd75a737,0xa39c36a9,0xcf4c618d,0x7833313f,
wolfSSL 16:8e0d178b1d1e 22970 0xf034c88d,0xfbcd4482,0x39b35288,0x4469a761,0x66b5d9c9,0x77a711c5 },
wolfSSL 16:8e0d178b1d1e 22971 { 0x944f8d65,0x4a695dc7,0x161aaba8,0xe6da5f65,0x24601669,0x8654e9c3,
wolfSSL 16:8e0d178b1d1e 22972 0x28ae7491,0xbc8b93f5,0x8f5580d8,0x5f1d1e83,0xcea32cc8,0x8ccf9a1a } },
wolfSSL 16:8e0d178b1d1e 22973 /* 54 */
wolfSSL 16:8e0d178b1d1e 22974 { { 0x7196fee2,0x28ab110c,0x874c8945,0x75799d63,0x29aedadd,0xa2629348,
wolfSSL 16:8e0d178b1d1e 22975 0x2be88ff4,0x9714cc7b,0xd58d60d6,0xf71293cf,0x32a564e9,0xda6b6cb3 },
wolfSSL 16:8e0d178b1d1e 22976 { 0x3dd821c2,0xf43fddb1,0x90dd323d,0xf2f2785f,0x048489f8,0x91246419,
wolfSSL 16:8e0d178b1d1e 22977 0xd24c6749,0x61660f26,0xc803c15c,0x961d9e8c,0xfaadc4c9,0x631c6158 } },
wolfSSL 16:8e0d178b1d1e 22978 /* 55 */
wolfSSL 16:8e0d178b1d1e 22979 { { 0xfd752366,0xacf2ebe0,0x139be88b,0xb93c340e,0x0f20179e,0x98f66485,
wolfSSL 16:8e0d178b1d1e 22980 0xff1da785,0x14820254,0x4f85c16e,0x5278e276,0x7aab1913,0xa246ee45 },
wolfSSL 16:8e0d178b1d1e 22981 { 0x53763b33,0x43861eb4,0x45c0bc0d,0xc49f03fc,0xad6b1ea1,0xafff16bc,
wolfSSL 16:8e0d178b1d1e 22982 0x6fd49c99,0xce33908b,0xf7fde8c3,0x5c51e9bf,0xff142c5e,0x076a7a39 } },
wolfSSL 16:8e0d178b1d1e 22983 /* 56 */
wolfSSL 16:8e0d178b1d1e 22984 { { 0x9e338d10,0x04639dfe,0xf42b411b,0x8ee6996f,0xa875cef2,0x960461d1,
wolfSSL 16:8e0d178b1d1e 22985 0x95b4d0ba,0x1057b6d6,0xa906e0bc,0x27639252,0xe1c20f8a,0x2c19f09a },
wolfSSL 16:8e0d178b1d1e 22986 { 0xeef4c43d,0x5b8fc3f0,0x07a84aa9,0xe2e1b1a8,0x835d2bdb,0x5f455528,
wolfSSL 16:8e0d178b1d1e 22987 0x207132dd,0x0f4aee4d,0x3907f675,0xe9f8338c,0x0e0531f0,0x7a874dc9 } },
wolfSSL 16:8e0d178b1d1e 22988 /* 57 */
wolfSSL 16:8e0d178b1d1e 22989 { { 0x97c27050,0x84b22d45,0x59e70bf8,0xbd0b8df7,0x79738b9b,0xb4d67405,
wolfSSL 16:8e0d178b1d1e 22990 0xcd917c4f,0x47f4d5f5,0x13ce6e33,0x9099c4ce,0x521d0f8b,0x942bfd39 },
wolfSSL 16:8e0d178b1d1e 22991 { 0xa43b566d,0x5028f0f6,0x21bff7de,0xaf6e8669,0xc44232cd,0x83f6f856,
wolfSSL 16:8e0d178b1d1e 22992 0xf915069a,0x65680579,0xecfecb85,0xd12095a2,0xdb01ba16,0xcf7f06ae } },
wolfSSL 16:8e0d178b1d1e 22993 /* 58 */
wolfSSL 16:8e0d178b1d1e 22994 { { 0x8ef96c80,0x0f56e3c4,0x3ddb609c,0xd521f2b3,0x7dc1450d,0x2be94102,
wolfSSL 16:8e0d178b1d1e 22995 0x02a91fe2,0x2d21a071,0x1efa37de,0x2e6f74fa,0x156c28a1,0x9a9a90b8 },
wolfSSL 16:8e0d178b1d1e 22996 { 0x9dc7dfcb,0xc54ea9ea,0x2c2c1d62,0xc74e66fc,0x49d3e067,0x9f23f967,
wolfSSL 16:8e0d178b1d1e 22997 0x54dd38ad,0x1c7c3a46,0x5946cee3,0xc7005884,0x45cc045d,0x89856368 } },
wolfSSL 16:8e0d178b1d1e 22998 /* 59 */
wolfSSL 16:8e0d178b1d1e 22999 { { 0xfce73946,0x29da7cd4,0x23168563,0x8f697db5,0xcba92ec6,0x8e235e9c,
wolfSSL 16:8e0d178b1d1e 23000 0x9f91d3ea,0x55d4655f,0xaa50a6cd,0xf3689f23,0x21e6a1a0,0xdcf21c26 },
wolfSSL 16:8e0d178b1d1e 23001 { 0x61b818bf,0xcffbc82e,0xda47a243,0xc74a2f96,0x8bc1a0cf,0x234e980a,
wolfSSL 16:8e0d178b1d1e 23002 0x7929cb6d,0xf35fd6b5,0xefe17d6c,0x81468e12,0x58b2dafb,0xddea6ae5 } },
wolfSSL 16:8e0d178b1d1e 23003 /* 60 */
wolfSSL 16:8e0d178b1d1e 23004 { { 0x7e787b2e,0x294de887,0x39a9310d,0x258acc1f,0xac14265d,0x92d9714a,
wolfSSL 16:8e0d178b1d1e 23005 0x708b48a0,0x18b5591c,0xe1abbf71,0x27cc6bb0,0x568307b9,0xc0581fa3 },
wolfSSL 16:8e0d178b1d1e 23006 { 0xf24d4d58,0x9e0f58a3,0xe0ce2327,0xfebe9bb8,0x9d1be702,0x91fd6a41,
wolfSSL 16:8e0d178b1d1e 23007 0xfacac993,0x9a7d8a45,0x9e50d66d,0xabc0a08c,0x06498201,0x02c342f7 } },
wolfSSL 16:8e0d178b1d1e 23008 /* 61 */
wolfSSL 16:8e0d178b1d1e 23009 { { 0x157bdbc2,0xccd71407,0xad0e1605,0x72fa89c6,0xb92a015f,0xb1d3da2b,
wolfSSL 16:8e0d178b1d1e 23010 0xa0a3fe56,0x8ad9e7cd,0x24f06737,0x160edcbd,0x61275be6,0x79d4db33 },
wolfSSL 16:8e0d178b1d1e 23011 { 0x5f3497c4,0xd3d31fd9,0x04192fb0,0x8cafeaee,0x13a50af3,0xe13ca745,
wolfSSL 16:8e0d178b1d1e 23012 0x8c85aae5,0x18826167,0x9eb556ff,0xce06cea8,0xbdb549f3,0x2eef1995 } },
wolfSSL 16:8e0d178b1d1e 23013 /* 62 */
wolfSSL 16:8e0d178b1d1e 23014 { { 0x50596edc,0x8ed7d3eb,0x905243a2,0xaa359362,0xa4b6d02b,0xa212c2c2,
wolfSSL 16:8e0d178b1d1e 23015 0xc4fbec68,0x611fd727,0xb84f733d,0x8a0b8ff7,0x5f0daf0e,0xd85a6b90 },
wolfSSL 16:8e0d178b1d1e 23016 { 0xd4091cf7,0x60e899f5,0x2eff2768,0x4fef2b67,0x10c33964,0xc1f195cb,
wolfSSL 16:8e0d178b1d1e 23017 0x93626a8f,0x8275d369,0x0d6c840a,0xc77904f4,0x7a868acd,0x88d8b7fd } },
wolfSSL 16:8e0d178b1d1e 23018 /* 63 */
wolfSSL 16:8e0d178b1d1e 23019 { { 0x7bd98425,0x85f23723,0xc70b154e,0xd4463992,0x96687a2e,0xcbb00ee2,
wolfSSL 16:8e0d178b1d1e 23020 0xc83214fd,0x905fdbf7,0x13593684,0x2019d293,0xef51218e,0x0428c393 },
wolfSSL 16:8e0d178b1d1e 23021 { 0x981e909a,0x40c7623f,0x7be192da,0x92513385,0x4010907e,0x48fe480f,
wolfSSL 16:8e0d178b1d1e 23022 0x3120b459,0xdd7a187c,0xa1fd8f3c,0xc9d7702d,0xe358efc5,0x66e4753b } },
wolfSSL 16:8e0d178b1d1e 23023 /* 64 */
wolfSSL 16:8e0d178b1d1e 23024 { { 0x16973cf4,0x070d34e1,0x7e4f34f7,0x20aee08b,0x5eb8ad29,0x269af9b9,
wolfSSL 16:8e0d178b1d1e 23025 0xa6a45dda,0xdde0a036,0x63df41e0,0xa18b528e,0xa260df2a,0x03cc71b2 },
wolfSSL 16:8e0d178b1d1e 23026 { 0xa06b1dd7,0x24a6770a,0x9d2675d3,0x5bfa9c11,0x96844432,0x73c1e2a1,
wolfSSL 16:8e0d178b1d1e 23027 0x131a6cf0,0x3660558d,0x2ee79454,0xb0289c83,0xc6d8ddcd,0xa6aefb01 } },
wolfSSL 16:8e0d178b1d1e 23028 /* 65 */
wolfSSL 16:8e0d178b1d1e 23029 { { 0x01ab5245,0xba1464b4,0xc48d93ff,0x9b8d0b6d,0x93ad272c,0x939867dc,
wolfSSL 16:8e0d178b1d1e 23030 0xae9fdc77,0xbebe085e,0x894ea8bd,0x73ae5103,0x39ac22e1,0x740fc89a },
wolfSSL 16:8e0d178b1d1e 23031 { 0x28e23b23,0x5e28b0a3,0xe13104d0,0x2352722e,0xb0a2640d,0xf4667a18,
wolfSSL 16:8e0d178b1d1e 23032 0x49bb37c3,0xac74a72e,0xe81e183a,0x79f734f0,0x3fd9c0eb,0xbffe5b6c } },
wolfSSL 16:8e0d178b1d1e 23033 /* 66 */
wolfSSL 16:8e0d178b1d1e 23034 { { 0xc6a2123f,0xb1a358f5,0xfe28df6d,0x927b2d95,0xf199d2f9,0x89702753,
wolfSSL 16:8e0d178b1d1e 23035 0x1a3f82dc,0x0a73754c,0x777affe1,0x063d029d,0xdae6d34d,0x5439817e },
wolfSSL 16:8e0d178b1d1e 23036 { 0x6b8b83c4,0xf7979eef,0x9d945682,0x615cb214,0xc5e57eae,0x8f0e4fac,
wolfSSL 16:8e0d178b1d1e 23037 0x113047dd,0x042b89b8,0x93f36508,0x888356dc,0x5fd1f32f,0xbf008d18 } },
wolfSSL 16:8e0d178b1d1e 23038 /* 67 */
wolfSSL 16:8e0d178b1d1e 23039 { { 0x4e8068db,0x8012aa24,0xa5729a47,0xc72cc641,0x43f0691d,0x3c33df2c,
wolfSSL 16:8e0d178b1d1e 23040 0x1d92145f,0xfa057347,0xb97f7946,0xaefc0f2f,0x2f8121bf,0x813d75cb },
wolfSSL 16:8e0d178b1d1e 23041 { 0x4383bba6,0x05613c72,0xa4224b3f,0xa924ce70,0x5f2179a6,0xe59cecbe,
wolfSSL 16:8e0d178b1d1e 23042 0x79f62b61,0x78e2e8aa,0x53ad8079,0x3ac2cc3b,0xd8f4fa96,0x55518d71 } },
wolfSSL 16:8e0d178b1d1e 23043 /* 68 */
wolfSSL 16:8e0d178b1d1e 23044 { { 0x00623f3b,0x03cf2922,0x5f29ebff,0x095c7111,0x80aa6823,0x42d72247,
wolfSSL 16:8e0d178b1d1e 23045 0x7458c0b0,0x044c7ba1,0x0959ec20,0xca62f7ef,0xf8ca929f,0x40ae2ab7 },
wolfSSL 16:8e0d178b1d1e 23046 { 0xa927b102,0xb8c5377a,0xdc031771,0x398a86a0,0xc216a406,0x04908f9d,
wolfSSL 16:8e0d178b1d1e 23047 0x918d3300,0xb423a73a,0xe0b94739,0x634b0ff1,0x2d69f697,0xe29de725 } },
wolfSSL 16:8e0d178b1d1e 23048 /* 69 */
wolfSSL 16:8e0d178b1d1e 23049 { { 0x8435af04,0x744d1400,0xfec192da,0x5f255b1d,0x336dc542,0x1f17dc12,
wolfSSL 16:8e0d178b1d1e 23050 0x636a68a8,0x5c90c2a7,0x7704ca1e,0x960c9eb7,0x6fb3d65a,0x9de8cf1e },
wolfSSL 16:8e0d178b1d1e 23051 { 0x511d3d06,0xc60fee0d,0xf9eb52c7,0x466e2313,0x206b0914,0x743c0f5f,
wolfSSL 16:8e0d178b1d1e 23052 0x2191aa4d,0x42f55bac,0xffebdbc2,0xcefc7c8f,0xe6e8ed1c,0xd4fa6081 } },
wolfSSL 16:8e0d178b1d1e 23053 /* 70 */
wolfSSL 16:8e0d178b1d1e 23054 { { 0xb0ab9645,0xb5e405d3,0xd5f1f711,0xaeec7f98,0x585c2a6e,0x8ad42311,
wolfSSL 16:8e0d178b1d1e 23055 0x512c6944,0x045acb9e,0xa90db1c6,0xae106c4e,0x898e6563,0xb89f33d5 },
wolfSSL 16:8e0d178b1d1e 23056 { 0x7fed2ce4,0x43b07cd9,0xdd815b20,0xf9934e17,0x0a81a349,0x6778d4d5,
wolfSSL 16:8e0d178b1d1e 23057 0x52918061,0x9e616ade,0xd7e67112,0xfa06db06,0x88488091,0x1da23cf1 } },
wolfSSL 16:8e0d178b1d1e 23058 /* 71 */
wolfSSL 16:8e0d178b1d1e 23059 { { 0x42f2c4b5,0x821c46b3,0x66059e47,0x931513ef,0x66f50cd1,0x7030ae43,
wolfSSL 16:8e0d178b1d1e 23060 0x43e7b127,0x43b536c9,0x5fca5360,0x006258cf,0x6b557abf,0xe4e3ee79 },
wolfSSL 16:8e0d178b1d1e 23061 { 0x24c8b22f,0xbb6b3900,0xfcbf1054,0x2eb5e2c1,0x567492af,0x937b18c9,
wolfSSL 16:8e0d178b1d1e 23062 0xacf53957,0xf09432e4,0x1dbf3a56,0x585f5a9d,0xbe0887cf,0xf86751fd } },
wolfSSL 16:8e0d178b1d1e 23063 /* 72 */
wolfSSL 16:8e0d178b1d1e 23064 { { 0x9d10e0b2,0x157399cb,0x60dc51b7,0x1c0d5956,0x1f583090,0x1d496b8a,
wolfSSL 16:8e0d178b1d1e 23065 0x88590484,0x6658bc26,0x03213f28,0x88c08ab7,0x7ae58de4,0x8d2e0f73 },
wolfSSL 16:8e0d178b1d1e 23066 { 0x486cfee6,0x9b79bc95,0xe9e5bc57,0x036a26c7,0xcd8ae97a,0x1ad03601,
wolfSSL 16:8e0d178b1d1e 23067 0xff3a0494,0x06907f87,0x2c7eb584,0x078f4bbf,0x7e8d0a5a,0xe3731bf5 } },
wolfSSL 16:8e0d178b1d1e 23068 /* 73 */
wolfSSL 16:8e0d178b1d1e 23069 { { 0xe1cd0abe,0x72f2282b,0x87efefa2,0xd4f9015e,0x6c3834bd,0x9d189806,
wolfSSL 16:8e0d178b1d1e 23070 0xb8a29ced,0x9c8cdcc1,0xfee82ebc,0x0601b9f4,0x7206a756,0x371052bc },
wolfSSL 16:8e0d178b1d1e 23071 { 0x46f32562,0x76fa1092,0x17351bb4,0xdaad534c,0xb3636bb5,0xc3d64c37,
wolfSSL 16:8e0d178b1d1e 23072 0x45d54e00,0x038a8c51,0x32c09e7c,0x301e6180,0x95735151,0x9764eae7 } },
wolfSSL 16:8e0d178b1d1e 23073 /* 74 */
wolfSSL 16:8e0d178b1d1e 23074 { { 0xcbd5256a,0x8791b19f,0x6ca13a3b,0x4007e0f2,0x4cf06904,0x03b79460,
wolfSSL 16:8e0d178b1d1e 23075 0xb6c17589,0xb18a9c22,0x81d45908,0xa1cb7d7d,0x21bb68f1,0x6e13fa9d },
wolfSSL 16:8e0d178b1d1e 23076 { 0xa71e6e16,0x47183c62,0xe18749ed,0x5cf0ef8e,0x2e5ed409,0x2c9c7f9b,
wolfSSL 16:8e0d178b1d1e 23077 0xe6e117e1,0x042eeacc,0x13fb5a7f,0xb86d4816,0xc9e5feb1,0xea1cf0ed } },
wolfSSL 16:8e0d178b1d1e 23078 /* 75 */
wolfSSL 16:8e0d178b1d1e 23079 { { 0xcea4cc9b,0x6e6573c9,0xafcec8f3,0x5417961d,0xa438b6f6,0x804bf02a,
wolfSSL 16:8e0d178b1d1e 23080 0xdcd4ea88,0xb894b03c,0x3799571f,0xd0f807e9,0x862156e8,0x3466a7f5 },
wolfSSL 16:8e0d178b1d1e 23081 { 0x56515664,0x51e59acd,0xa3c5eb0b,0x55b0f93c,0x6a4279db,0x84a06b02,
wolfSSL 16:8e0d178b1d1e 23082 0xc5fae08e,0x5c850579,0xa663a1a2,0xcf07b8db,0xf46ffc8d,0x49a36bbc } },
wolfSSL 16:8e0d178b1d1e 23083 /* 76 */
wolfSSL 16:8e0d178b1d1e 23084 { { 0x46d93106,0xe47f5acc,0xaa897c9c,0x65b7ade0,0x12d7e4be,0x37cf4c94,
wolfSSL 16:8e0d178b1d1e 23085 0xd4b2caa9,0xa2ae9b80,0xe60357a3,0x5e7ce09c,0xc8ecd5f9,0x29f77667 },
wolfSSL 16:8e0d178b1d1e 23086 { 0xa8a0b1c5,0xdf6868f5,0x62978ad8,0x240858cf,0xdc0002a1,0x0f7ac101,
wolfSSL 16:8e0d178b1d1e 23087 0xffe9aa05,0x1d28a9d7,0x5b962c97,0x744984d6,0x3d28c8b2,0xa8a7c00b } },
wolfSSL 16:8e0d178b1d1e 23088 /* 77 */
wolfSSL 16:8e0d178b1d1e 23089 { { 0xae11a338,0x7c58a852,0xd1af96e7,0xa78613f1,0x5355cc73,0x7e9767d2,
wolfSSL 16:8e0d178b1d1e 23090 0x792a2de6,0x6ba37009,0x124386b2,0x7d60f618,0x11157674,0xab09b531 },
wolfSSL 16:8e0d178b1d1e 23091 { 0x98eb9dd0,0x95a04841,0x15070328,0xe6c17acc,0x489c6e49,0xafc6da45,
wolfSSL 16:8e0d178b1d1e 23092 0xbb211530,0xab45a60a,0x7d7ea933,0xc58d6592,0x095642c6,0xa3ef3c65 } },
wolfSSL 16:8e0d178b1d1e 23093 /* 78 */
wolfSSL 16:8e0d178b1d1e 23094 { { 0xdf010879,0x89d420e9,0x39576179,0x9d25255d,0xe39513b6,0x9cdefd50,
wolfSSL 16:8e0d178b1d1e 23095 0xd5d1c313,0xe4efe45b,0x3f7af771,0xc0149de7,0x340ab06b,0x55a6b4f4 },
wolfSSL 16:8e0d178b1d1e 23096 { 0xebeaf771,0xf1325251,0x878d4288,0x2ab44128,0x18e05afe,0xfcd5832e,
wolfSSL 16:8e0d178b1d1e 23097 0xcc1fb62b,0xef52a348,0xc1c4792a,0x2bd08274,0x877c6dc7,0x345c5846 } },
wolfSSL 16:8e0d178b1d1e 23098 /* 79 */
wolfSSL 16:8e0d178b1d1e 23099 { { 0xbea65e90,0xde15ceb0,0x2416d99c,0x0987f72b,0xfd863dec,0x44db578d,
wolfSSL 16:8e0d178b1d1e 23100 0xac6a3578,0xf617b74b,0xdb48e999,0x9e62bd7a,0xeab1a1be,0x877cae61 },
wolfSSL 16:8e0d178b1d1e 23101 { 0x3a358610,0x23adddaa,0x325e2b07,0x2fc4d6d1,0x1585754e,0x897198f5,
wolfSSL 16:8e0d178b1d1e 23102 0xb392b584,0xf741852c,0xb55f7de1,0x9927804c,0x1aa8efae,0xe9e6c4ed } },
wolfSSL 16:8e0d178b1d1e 23103 /* 80 */
wolfSSL 16:8e0d178b1d1e 23104 { { 0x98683186,0x867db639,0xddcc4ea9,0xfb5cf424,0xd4f0e7bd,0xcc9a7ffe,
wolfSSL 16:8e0d178b1d1e 23105 0x7a779f7e,0x7c57f71c,0xd6b25ef2,0x90774079,0xb4081680,0x90eae903 },
wolfSSL 16:8e0d178b1d1e 23106 { 0x0ee1fceb,0xdf2aae5e,0xe86c1a1f,0x3ff1da24,0xca193edf,0x80f587d6,
wolfSSL 16:8e0d178b1d1e 23107 0xdc9b9d6a,0xa5695523,0x85920303,0x7b840900,0xba6dbdef,0x1efa4dfc } },
wolfSSL 16:8e0d178b1d1e 23108 /* 81 */
wolfSSL 16:8e0d178b1d1e 23109 { { 0xe0540015,0xfbd838f9,0xc39077dc,0x2c323946,0xad619124,0x8b1fb9e6,
wolfSSL 16:8e0d178b1d1e 23110 0x0ca62ea8,0x9612440c,0x2dbe00ff,0x9ad9b52c,0xae197643,0xf52abaa1 },
wolfSSL 16:8e0d178b1d1e 23111 { 0x2cac32ad,0xd0e89894,0x62a98f91,0xdfb79e42,0x276f55cb,0x65452ecf,
wolfSSL 16:8e0d178b1d1e 23112 0x7ad23e12,0xdb1ac0d2,0xde4986f0,0xf68c5f6a,0x82ce327d,0x389ac37b } },
wolfSSL 16:8e0d178b1d1e 23113 /* 82 */
wolfSSL 16:8e0d178b1d1e 23114 { { 0xf8e60f5b,0x511188b4,0x48aa2ada,0x7fe67015,0x381abca2,0xdb333cb8,
wolfSSL 16:8e0d178b1d1e 23115 0xdaf3fc97,0xb15e6d9d,0x36aabc03,0x4b24f6eb,0x72a748b4,0xc59789df },
wolfSSL 16:8e0d178b1d1e 23116 { 0x29cf5279,0x26fcb8a5,0x01ad9a6c,0x7a3c6bfc,0x4b8bac9b,0x866cf88d,
wolfSSL 16:8e0d178b1d1e 23117 0x9c80d041,0xf4c89989,0x70add148,0xf0a04241,0x45d81a41,0x5a02f479 } },
wolfSSL 16:8e0d178b1d1e 23118 /* 83 */
wolfSSL 16:8e0d178b1d1e 23119 { { 0xc1c90202,0xfa5c877c,0xf8ac7570,0xd099d440,0xd17881f7,0x428a5b1b,
wolfSSL 16:8e0d178b1d1e 23120 0x5b2501d7,0x61e267db,0xf2e4465b,0xf889bf04,0x76aa4cb8,0x4da3ae08 },
wolfSSL 16:8e0d178b1d1e 23121 { 0xe3e66861,0x3ef0fe26,0x3318b86d,0x5e772953,0x747396df,0xc3c35fbc,
wolfSSL 16:8e0d178b1d1e 23122 0x439ffd37,0x5115a29c,0xb2d70374,0xbfc4bd97,0x56246b9d,0x088630ea } },
wolfSSL 16:8e0d178b1d1e 23123 /* 84 */
wolfSSL 16:8e0d178b1d1e 23124 { { 0xb8a9e8c9,0xcd96866d,0x5bb8091e,0xa11963b8,0x045b3cd2,0xc7f90d53,
wolfSSL 16:8e0d178b1d1e 23125 0x80f36504,0x755a72b5,0x21d3751c,0x46f8b399,0x53c193de,0x4bffdc91 },
wolfSSL 16:8e0d178b1d1e 23126 { 0xb89554e7,0xcd15c049,0xf7a26be6,0x353c6754,0xbd41d970,0x79602370,
wolfSSL 16:8e0d178b1d1e 23127 0x12b176c0,0xde16470b,0x40c8809d,0x56ba1175,0xe435fb1e,0xe2db35c3 } },
wolfSSL 16:8e0d178b1d1e 23128 /* 85 */
wolfSSL 16:8e0d178b1d1e 23129 { { 0x6328e33f,0xd71e4aab,0xaf8136d1,0x5486782b,0x86d57231,0x07a4995f,
wolfSSL 16:8e0d178b1d1e 23130 0x1651a968,0xf1f0a5bd,0x76803b6d,0xa5dc5b24,0x42dda935,0x5c587cbc },
wolfSSL 16:8e0d178b1d1e 23131 { 0xbae8b4c0,0x2b6cdb32,0xb1331138,0x66d1598b,0x5d7e9614,0x4a23b2d2,
wolfSSL 16:8e0d178b1d1e 23132 0x74a8c05d,0x93e402a6,0xda7ce82e,0x45ac94e6,0xe463d465,0xeb9f8281 } },
wolfSSL 16:8e0d178b1d1e 23133 /* 86 */
wolfSSL 16:8e0d178b1d1e 23134 { { 0xfecf5b9b,0x34e0f9d1,0xf206966a,0xa115b12b,0x1eaa0534,0x5591cf3b,
wolfSSL 16:8e0d178b1d1e 23135 0xfb1558f9,0x5f0293cb,0x1bc703a5,0x1c8507a4,0x862c1f81,0x92e6b81c },
wolfSSL 16:8e0d178b1d1e 23136 { 0xcdaf24e3,0xcc9ebc66,0x72fcfc70,0x68917ecd,0x8157ba48,0x6dc9a930,
wolfSSL 16:8e0d178b1d1e 23137 0xb06ab2b2,0x5d425c08,0x36e929c4,0x362f8ce7,0x62e89324,0x09f6f57c } },
wolfSSL 16:8e0d178b1d1e 23138 /* 87 */
wolfSSL 16:8e0d178b1d1e 23139 { { 0xd29375fb,0x1c7d6b78,0xe35d1157,0xfabd851e,0x4243ea47,0xf6f62dcd,
wolfSSL 16:8e0d178b1d1e 23140 0x8fe30b0f,0x1dd92460,0xffc6e709,0x08166dfa,0x0881e6a7,0xc6c4c693 },
wolfSSL 16:8e0d178b1d1e 23141 { 0xd6a53fb0,0x20368f87,0x9eb4d1f9,0x38718e9f,0xafd7e790,0x03f08acd,
wolfSSL 16:8e0d178b1d1e 23142 0x72fe2a1c,0x0835eb44,0x88076e5d,0x7e050903,0xa638e731,0x538f765e } },
wolfSSL 16:8e0d178b1d1e 23143 /* 88 */
wolfSSL 16:8e0d178b1d1e 23144 { { 0xc2663b4b,0x0e0249d9,0x47cd38dd,0xe700ab5b,0x2c46559f,0xb192559d,
wolfSSL 16:8e0d178b1d1e 23145 0x4bcde66d,0x8f9f74a8,0x3e2aced5,0xad161523,0x3dd03a5b,0xc155c047 },
wolfSSL 16:8e0d178b1d1e 23146 { 0x3be454eb,0x346a8799,0x83b7dccd,0x66ee94db,0xab9d2abe,0x1f6d8378,
wolfSSL 16:8e0d178b1d1e 23147 0x7733f355,0x4a396dd2,0xf53553c2,0x419bd40a,0x731dd943,0xd0ead98d } },
wolfSSL 16:8e0d178b1d1e 23148 /* 89 */
wolfSSL 16:8e0d178b1d1e 23149 { { 0xec142408,0x908e0b0e,0x4114b310,0x98943cb9,0x1742b1d7,0x03dbf7d8,
wolfSSL 16:8e0d178b1d1e 23150 0x693412f4,0xd270df6b,0x8f69e20c,0xc5065494,0x697e43a1,0xa76a90c3 },
wolfSSL 16:8e0d178b1d1e 23151 { 0x4624825a,0xe0fa3384,0x8acc34c2,0x82e48c0b,0xe9a14f2b,0x7b24bd14,
wolfSSL 16:8e0d178b1d1e 23152 0x4db30803,0x4f5dd5e2,0x932da0a3,0x0c77a9e7,0x74c653dc,0x20db90f2 } },
wolfSSL 16:8e0d178b1d1e 23153 /* 90 */
wolfSSL 16:8e0d178b1d1e 23154 { { 0x0e6c5fd9,0x261179b7,0x6c982eea,0xf8bec123,0xd4957b7e,0x47683338,
wolfSSL 16:8e0d178b1d1e 23155 0x0a72f66a,0xcc47e664,0x1bad9350,0xbd54bf6a,0xf454e95a,0xdfbf4c6a },
wolfSSL 16:8e0d178b1d1e 23156 { 0x6907f4fa,0x3f7a7afa,0x865ca735,0x7311fae0,0x2a496ada,0x24737ab8,
wolfSSL 16:8e0d178b1d1e 23157 0x15feb79b,0x13e425f1,0xa1b93c21,0xe9e97c50,0x4ddd3eb5,0xb26b6eac } },
wolfSSL 16:8e0d178b1d1e 23158 /* 91 */
wolfSSL 16:8e0d178b1d1e 23159 { { 0x2a2e5f2b,0x81cab9f5,0xbf385ac4,0xf93caf29,0xc909963a,0xf4bf35c3,
wolfSSL 16:8e0d178b1d1e 23160 0x74c9143c,0x081e7300,0xc281b4c5,0x3ea57fa8,0x9b340741,0xe497905c },
wolfSSL 16:8e0d178b1d1e 23161 { 0x55ab3cfb,0xf556dd8a,0x518db6ad,0xd444b96b,0x5ef4b955,0x34f5425a,
wolfSSL 16:8e0d178b1d1e 23162 0xecd26aa3,0xdda7a3ac,0xda655e97,0xb57da11b,0xc2024c70,0x02da3eff } },
wolfSSL 16:8e0d178b1d1e 23163 /* 92 */
wolfSSL 16:8e0d178b1d1e 23164 { { 0x6481d0d9,0xe24b0036,0x818fdfe2,0x3740dbe5,0x190fda00,0xc1fc1f45,
wolfSSL 16:8e0d178b1d1e 23165 0x3cf27fde,0x329c9280,0x6934f43e,0x7435cb53,0x7884e8fe,0x2b505a5d },
wolfSSL 16:8e0d178b1d1e 23166 { 0x711adcc9,0x6cfcc6a6,0x531e21e1,0xf034325c,0x9b2a8a99,0xa2f4a967,
wolfSSL 16:8e0d178b1d1e 23167 0x3c21bdff,0x9d5f3842,0x31b57d66,0xb25c7811,0x0b8093b9,0xdb5344d8 } },
wolfSSL 16:8e0d178b1d1e 23168 /* 93 */
wolfSSL 16:8e0d178b1d1e 23169 { { 0xae50a2f5,0x0d72e667,0xe4a861d1,0x9b7f8d8a,0x330df1cb,0xa129f70f,
wolfSSL 16:8e0d178b1d1e 23170 0xe04fefc3,0xe90aa5d7,0xe72c3ae1,0xff561ecb,0xcdb955fa,0x0d8fb428 },
wolfSSL 16:8e0d178b1d1e 23171 { 0xd7663784,0xd2235f73,0x7e2c456a,0xc05baec6,0x2adbfccc,0xe5c292e4,
wolfSSL 16:8e0d178b1d1e 23172 0xefb110d5,0x4fd17988,0xd19d49f3,0x27e57734,0x84f679fe,0x188ac4ce } },
wolfSSL 16:8e0d178b1d1e 23173 /* 94 */
wolfSSL 16:8e0d178b1d1e 23174 { { 0xa796c53e,0x7ee344cf,0x0868009b,0xbbf6074d,0x474a1295,0x1f1594f7,
wolfSSL 16:8e0d178b1d1e 23175 0xac11632d,0x66776edc,0x04e2fa5a,0x1862278b,0xc854a89a,0x52665cf2 },
wolfSSL 16:8e0d178b1d1e 23176 { 0x8104ab58,0x7e376464,0x7204fd6d,0x16775913,0x44ea1199,0x86ca06a5,
wolfSSL 16:8e0d178b1d1e 23177 0x1c9240dd,0xaa3f765b,0x24746149,0x5f8501a9,0xdcd251d7,0x7b982e30 } },
wolfSSL 16:8e0d178b1d1e 23178 /* 95 */
wolfSSL 16:8e0d178b1d1e 23179 { { 0xc15f3060,0xe44e9efc,0xa87ebbe6,0x5ad62f2e,0xc79500d4,0x36499d41,
wolfSSL 16:8e0d178b1d1e 23180 0x336fa9d1,0xa66d6dc0,0x5afd3b1f,0xf8afc495,0xe5c9822b,0x1d8ccb24 },
wolfSSL 16:8e0d178b1d1e 23181 { 0x79d7584b,0x4031422b,0xea3f20dd,0xc54a0580,0x958468c5,0x3f837c8f,
wolfSSL 16:8e0d178b1d1e 23182 0xfbea7735,0x3d82f110,0x7dffe2fc,0x679a8778,0x20704803,0x48eba63b } },
wolfSSL 16:8e0d178b1d1e 23183 /* 96 */
wolfSSL 16:8e0d178b1d1e 23184 { { 0xdf46e2f6,0x89b10d41,0x19514367,0x13ab57f8,0x1d469c87,0x067372b9,
wolfSSL 16:8e0d178b1d1e 23185 0x4f6c5798,0x0c195afa,0x272c9acf,0xea43a12a,0x678abdac,0x9dadd8cb },
wolfSSL 16:8e0d178b1d1e 23186 { 0xe182579a,0xcce56c6b,0x2d26c2d8,0x86febadb,0x2a44745c,0x1c668ee1,
wolfSSL 16:8e0d178b1d1e 23187 0x98dc047a,0x580acd86,0x51b9ec2d,0x5a2b79cc,0x4054f6a0,0x007da608 } },
wolfSSL 16:8e0d178b1d1e 23188 /* 97 */
wolfSSL 16:8e0d178b1d1e 23189 { { 0x17b00dd0,0x9e3ca352,0x0e81a7a6,0x046779cb,0xd482d871,0xb999fef3,
wolfSSL 16:8e0d178b1d1e 23190 0xd9233fbc,0xe6f38134,0xf48cd0e0,0x112c3001,0x3c6c66ae,0x934e7576 },
wolfSSL 16:8e0d178b1d1e 23191 { 0xd73234dc,0xb44d4fc3,0x864eafc1,0xfcae2062,0x26bef21a,0x843afe25,
wolfSSL 16:8e0d178b1d1e 23192 0xf3b75fdf,0x61355107,0x794c2e6b,0x8367a5aa,0x8548a372,0x3d2629b1 } },
wolfSSL 16:8e0d178b1d1e 23193 /* 98 */
wolfSSL 16:8e0d178b1d1e 23194 { { 0x437cfaf8,0x6230618f,0x2032c299,0x5b8742cb,0x2293643a,0x949f7247,
wolfSSL 16:8e0d178b1d1e 23195 0x09464f79,0xb8040f1a,0x4f254143,0x049462d2,0x366c7e76,0xabd6b522 },
wolfSSL 16:8e0d178b1d1e 23196 { 0xd5338f55,0x119b392b,0x01495a0c,0x1a80a9ce,0xf8d7537e,0xf3118ca7,
wolfSSL 16:8e0d178b1d1e 23197 0x6bf4b762,0xb715adc2,0xa8482b6c,0x24506165,0x96a7c84d,0xd958d7c6 } },
wolfSSL 16:8e0d178b1d1e 23198 /* 99 */
wolfSSL 16:8e0d178b1d1e 23199 { { 0xbdc21f31,0x9ad8aa87,0x8063e58c,0xadb3cab4,0xb07dd7b8,0xefd86283,
wolfSSL 16:8e0d178b1d1e 23200 0x1be7c6b4,0xc7b9b762,0x015582de,0x2ef58741,0x299addf3,0xc970c52e },
wolfSSL 16:8e0d178b1d1e 23201 { 0x22f24d66,0x78f02e2a,0x74cc100a,0xefec1d10,0x09316e1a,0xaf2a6a39,
wolfSSL 16:8e0d178b1d1e 23202 0x5849dd49,0xce7c2205,0x96bffc4c,0x9c1fe75c,0x7ba06ec0,0xcad98fd2 } },
wolfSSL 16:8e0d178b1d1e 23203 /* 100 */
wolfSSL 16:8e0d178b1d1e 23204 { { 0xb648b73e,0xed76e2d0,0x1cfd285e,0xa9f92ce5,0x2ed13de1,0xa8c86c06,
wolfSSL 16:8e0d178b1d1e 23205 0xa5191a93,0x1d3a574e,0x1ad1b8bf,0x385cdf8b,0x47d2cfe3,0xbbecc28a },
wolfSSL 16:8e0d178b1d1e 23206 { 0x69cec548,0x98d326c0,0xf240a0b2,0x4f5bc1dd,0x29057236,0x241a7062,
wolfSSL 16:8e0d178b1d1e 23207 0xc68294a4,0x0fc6e9c5,0xa319f17a,0x4d04838b,0x9ffc1c6f,0x8b612cf1 } },
wolfSSL 16:8e0d178b1d1e 23208 /* 101 */
wolfSSL 16:8e0d178b1d1e 23209 { { 0x4c3830eb,0x9bb0b501,0x8ee0d0c5,0x3d08f83c,0x79ba9389,0xa4a62642,
wolfSSL 16:8e0d178b1d1e 23210 0x9cbc2914,0x5d5d4044,0x074c46f0,0xae9eb83e,0x74ead7d6,0x63bb758f },
wolfSSL 16:8e0d178b1d1e 23211 { 0xc6bb29e0,0x1c40d2ea,0x4b02f41e,0x95aa2d87,0x53cb199a,0x92989175,
wolfSSL 16:8e0d178b1d1e 23212 0x51584f6d,0xdd91bafe,0x31a1aaec,0x3715efb9,0x46780f9e,0xc1b6ae5b } },
wolfSSL 16:8e0d178b1d1e 23213 /* 102 */
wolfSSL 16:8e0d178b1d1e 23214 { { 0x42772f41,0xcded3e4b,0x3bcb79d1,0x3a700d5d,0x80feee60,0x4430d50e,
wolfSSL 16:8e0d178b1d1e 23215 0xf5e5d4bb,0x444ef1fc,0xe6e358ff,0xc660194f,0x6a91b43c,0xe68a2f32 },
wolfSSL 16:8e0d178b1d1e 23216 { 0x977fe4d2,0x5842775c,0x7e2a41eb,0x78fdef5c,0xff8df00e,0x5f3bec02,
wolfSSL 16:8e0d178b1d1e 23217 0x5852525d,0xf4b840cd,0x4e6988bd,0x0870483a,0xcc64b837,0x39499e39 } },
wolfSSL 16:8e0d178b1d1e 23218 /* 103 */
wolfSSL 16:8e0d178b1d1e 23219 { { 0xb08df5fe,0xfc05de80,0x63ba0362,0x0c12957c,0xd5cf1428,0xea379414,
wolfSSL 16:8e0d178b1d1e 23220 0x54ef6216,0xc559132a,0xb9e65cf8,0x33d5f12f,0x1695d663,0x09c60278 },
wolfSSL 16:8e0d178b1d1e 23221 { 0x61f7a2fb,0x3ac1ced4,0xd4f5eeb8,0xdd838444,0x8318fcad,0x82a38c6c,
wolfSSL 16:8e0d178b1d1e 23222 0xe9f1a864,0x315be2e5,0x442daf47,0x317b5771,0x95aa5f9e,0x81b5904a } },
wolfSSL 16:8e0d178b1d1e 23223 /* 104 */
wolfSSL 16:8e0d178b1d1e 23224 { { 0x8b21d232,0x6b6b1c50,0x8c2cba75,0x87f3dbc0,0xae9f0faf,0xa7e74b46,
wolfSSL 16:8e0d178b1d1e 23225 0xbb7b8079,0x036a0985,0x8d974a25,0x4f185b90,0xd9af5ec9,0x5aa7cef0 },
wolfSSL 16:8e0d178b1d1e 23226 { 0x57dcfffc,0xe0566a70,0xb8453225,0x6ea311da,0x23368aa9,0x72ea1a8d,
wolfSSL 16:8e0d178b1d1e 23227 0x48cd552d,0xed9b2083,0xc80ea435,0xb987967c,0x6c104173,0xad735c75 } },
wolfSSL 16:8e0d178b1d1e 23228 /* 105 */
wolfSSL 16:8e0d178b1d1e 23229 { { 0xcee76ef4,0xaea85ab3,0xaf1d2b93,0x44997444,0xeacb923f,0x0851929b,
wolfSSL 16:8e0d178b1d1e 23230 0x51e3bc0c,0xb080b590,0x59be68a2,0xc4ee1d86,0x64b26cda,0xf00de219 },
wolfSSL 16:8e0d178b1d1e 23231 { 0xf2e90d4d,0x8d7fb5c0,0x77d9ec64,0x00e219a7,0x5d1c491c,0xc4e6febd,
wolfSSL 16:8e0d178b1d1e 23232 0x1a8f4585,0x080e3754,0x48d2af9c,0x4a9b86c8,0xb6679851,0x2ed70db6 } },
wolfSSL 16:8e0d178b1d1e 23233 /* 106 */
wolfSSL 16:8e0d178b1d1e 23234 { { 0x586f25cb,0xaee44116,0xa0fcf70f,0xf7b6861f,0x18a350e8,0x55d2cd20,
wolfSSL 16:8e0d178b1d1e 23235 0x92dc286f,0x861bf3e5,0x6226aba7,0x9ab18ffa,0xa9857b03,0xd15827be },
wolfSSL 16:8e0d178b1d1e 23236 { 0x92e6acef,0x26c1f547,0xac1fbac3,0x422c63c8,0xfcbfd71d,0xa2d8760d,
wolfSSL 16:8e0d178b1d1e 23237 0xb2511224,0x35f6a539,0x048d1a21,0xbaa88fa1,0xebf999db,0x49f1abe9 } },
wolfSSL 16:8e0d178b1d1e 23238 /* 107 */
wolfSSL 16:8e0d178b1d1e 23239 { { 0xf7492b73,0x16f9f4f4,0xcb392b1a,0xcf28ec1e,0x69ca6ffc,0x45b130d4,
wolfSSL 16:8e0d178b1d1e 23240 0xb72efa58,0x28ba8d40,0x5ca066f5,0xace987c7,0x4ad022eb,0x3e399246 },
wolfSSL 16:8e0d178b1d1e 23241 { 0x752555bb,0x63a2d84e,0x9c2ae394,0xaaa93b4a,0xc89539ca,0xcd80424e,
wolfSSL 16:8e0d178b1d1e 23242 0xaa119a99,0x6d6b5a6d,0x379f2629,0xbd50334c,0xef3cc7d3,0x899e925e } },
wolfSSL 16:8e0d178b1d1e 23243 /* 108 */
wolfSSL 16:8e0d178b1d1e 23244 { { 0xbf825dc4,0xb7ff3651,0x40b9c462,0x0f741cc4,0x5cc4fb5b,0x771ff5a9,
wolfSSL 16:8e0d178b1d1e 23245 0x47fd56fe,0xcb9e9c9b,0x5626c0d3,0xbdf053db,0xf7e14098,0xa97ce675 },
wolfSSL 16:8e0d178b1d1e 23246 { 0x6c934f5e,0x68afe5a3,0xccefc46f,0x6cd5e148,0xd7a88586,0xc7758570,
wolfSSL 16:8e0d178b1d1e 23247 0xdd558d40,0x49978f5e,0x64ae00c1,0xa1d5088a,0xf1d65bb2,0x58f2a720 } },
wolfSSL 16:8e0d178b1d1e 23248 /* 109 */
wolfSSL 16:8e0d178b1d1e 23249 { { 0x3e4daedb,0x66fdda4a,0x65d1b052,0x38318c12,0x4c4bbf5c,0x28d910a2,
wolfSSL 16:8e0d178b1d1e 23250 0x78a9cd14,0x762fe5c4,0xd2cc0aee,0x08e5ebaa,0xca0c654c,0xd2cdf257 },
wolfSSL 16:8e0d178b1d1e 23251 { 0x08b717d2,0x48f7c58b,0x386cd07a,0x3807184a,0xae7d0112,0x3240f626,
wolfSSL 16:8e0d178b1d1e 23252 0xc43917b0,0x03e9361b,0x20aea018,0xf261a876,0x7e1e6372,0x53f556a4 } },
wolfSSL 16:8e0d178b1d1e 23253 /* 110 */
wolfSSL 16:8e0d178b1d1e 23254 { { 0x2f512a90,0xc84cee56,0x1b0ea9f1,0x24b3c004,0xe26cc1ea,0x0ee15d2d,
wolfSSL 16:8e0d178b1d1e 23255 0xf0c9ef7d,0xd848762c,0xd5341435,0x1026e9c5,0xfdb16b31,0x8f5b73dc },
wolfSSL 16:8e0d178b1d1e 23256 { 0xd2c75d95,0x1f69bef2,0xbe064dda,0x8d33d581,0x57ed35e6,0x8c024c12,
wolfSSL 16:8e0d178b1d1e 23257 0xc309c281,0xf8d435f9,0xd6960193,0xfd295061,0xe9e49541,0x66618d78 } },
wolfSSL 16:8e0d178b1d1e 23258 /* 111 */
wolfSSL 16:8e0d178b1d1e 23259 { { 0x8ce382de,0x571cfd45,0xde900dde,0x175806ee,0x34aba3b5,0x61849965,
wolfSSL 16:8e0d178b1d1e 23260 0xde7aec95,0xe899778a,0xff4aa97f,0xe8f00f6e,0x010b0c6d,0xae971cb5 },
wolfSSL 16:8e0d178b1d1e 23261 { 0x3af788f1,0x1827eebc,0xe413fe2d,0xd46229ff,0x4741c9b4,0x8a15455b,
wolfSSL 16:8e0d178b1d1e 23262 0xf8e424eb,0x5f02e690,0xdae87712,0x40a1202e,0x64944f6d,0x49b3bda2 } },
wolfSSL 16:8e0d178b1d1e 23263 /* 112 */
wolfSSL 16:8e0d178b1d1e 23264 { { 0x035b2d69,0xd63c6067,0x6bed91b0,0xb507150d,0x7afb39b2,0x1f35f82f,
wolfSSL 16:8e0d178b1d1e 23265 0x16012b66,0xb9bd9c01,0xed0a5f50,0x00d97960,0x2716f7c9,0xed705451 },
wolfSSL 16:8e0d178b1d1e 23266 { 0x127abdb4,0x1576eff4,0xf01e701c,0x6850d698,0x3fc87e2f,0x9fa7d749,
wolfSSL 16:8e0d178b1d1e 23267 0xb0ce3e48,0x0b6bcc6f,0xf7d8c1c0,0xf4fbe1f5,0x02719cc6,0xcf75230e } },
wolfSSL 16:8e0d178b1d1e 23268 /* 113 */
wolfSSL 16:8e0d178b1d1e 23269 { { 0x722d94ed,0x6761d6c2,0x3718820e,0xd1ec3f21,0x25d0e7c6,0x65a40b70,
wolfSSL 16:8e0d178b1d1e 23270 0xbaf3cf31,0xd67f830e,0xb93ea430,0x633b3807,0x0bc96c69,0x17faa0ea },
wolfSSL 16:8e0d178b1d1e 23271 { 0xdf866b98,0xe6bf3482,0xa9db52d4,0x205c1ee9,0xff9ab869,0x51ef9bbd,
wolfSSL 16:8e0d178b1d1e 23272 0x75eeb985,0x3863dad1,0xd3cf442a,0xef216c3b,0xf9c8e321,0x3fb228e3 } },
wolfSSL 16:8e0d178b1d1e 23273 /* 114 */
wolfSSL 16:8e0d178b1d1e 23274 { { 0x0760ac07,0x94f9b70c,0x9d79bf4d,0xf3c9ccae,0xc5ffc83d,0x73cea084,
wolfSSL 16:8e0d178b1d1e 23275 0xdc49c38e,0xef50f943,0xbc9e7330,0xf467a2ae,0x44ea7fba,0x5ee534b6 },
wolfSSL 16:8e0d178b1d1e 23276 { 0x03609e7f,0x20cb6272,0x62fdc9f0,0x09844355,0x0f1457f7,0xaf5c8e58,
wolfSSL 16:8e0d178b1d1e 23277 0xb4b25941,0xd1f50a6c,0x2ec82395,0x77cb247c,0xda3dca33,0xa5f3e1e5 } },
wolfSSL 16:8e0d178b1d1e 23278 /* 115 */
wolfSSL 16:8e0d178b1d1e 23279 { { 0x7d85fa94,0x023489d6,0x2db9ce47,0x0ba40537,0xaed7aad1,0x0fdf7a1f,
wolfSSL 16:8e0d178b1d1e 23280 0x9a4ccb40,0xa57b0d73,0x5b18967c,0x48fcec99,0xb7274d24,0xf30b5b6e },
wolfSSL 16:8e0d178b1d1e 23281 { 0xc81c5338,0x7ccb4773,0xa3ed6bd0,0xb85639e6,0x1d56eada,0x7d9df95f,
wolfSSL 16:8e0d178b1d1e 23282 0x0a1607ad,0xe256d57f,0x957574d6,0x6da7ffdc,0x01c7a8c4,0x65f84046 } },
wolfSSL 16:8e0d178b1d1e 23283 /* 116 */
wolfSSL 16:8e0d178b1d1e 23284 { { 0xcba1e7f1,0x8d45d0cb,0x02b55f64,0xef0a08c0,0x17e19892,0x771ca31b,
wolfSSL 16:8e0d178b1d1e 23285 0x4885907e,0xe1843ecb,0x364ce16a,0x67797ebc,0x8df4b338,0x816d2b2d },
wolfSSL 16:8e0d178b1d1e 23286 { 0x39aa8671,0xe870b0e5,0xc102b5f5,0x9f0db3e4,0x1720c697,0x34296659,
wolfSSL 16:8e0d178b1d1e 23287 0x613c0d2a,0x0ad4c89e,0x418ddd61,0x1af900b2,0xd336e20e,0xe087ca72 } },
wolfSSL 16:8e0d178b1d1e 23288 /* 117 */
wolfSSL 16:8e0d178b1d1e 23289 { { 0xaba10079,0x222831ff,0x6d64fff2,0x0dc5f87b,0x3e8cb330,0x44547907,
wolfSSL 16:8e0d178b1d1e 23290 0x702a33fb,0xe815aaa2,0x5fba3215,0x338d6b2e,0x79f549c8,0x0f7535cb },
wolfSSL 16:8e0d178b1d1e 23291 { 0x2ee95923,0x471ecd97,0xc6d1c09f,0x1e868b37,0xc666ef4e,0x2bc7b8ec,
wolfSSL 16:8e0d178b1d1e 23292 0x808a4bfc,0xf5416589,0x3fbc4d2e,0xf23e9ee2,0x2d75125b,0x4357236c } },
wolfSSL 16:8e0d178b1d1e 23293 /* 118 */
wolfSSL 16:8e0d178b1d1e 23294 { { 0xba9cdb1b,0xfe176d95,0x2f82791e,0x45a1ca01,0x4de4cca2,0x97654af2,
wolfSSL 16:8e0d178b1d1e 23295 0x5cc4bcb9,0xbdbf9d0e,0xad97ac0a,0xf6a7df50,0x61359fd6,0xc52112b0 },
wolfSSL 16:8e0d178b1d1e 23296 { 0x4f05eae3,0x696d9ce3,0xe943ac2b,0x903adc02,0x0848be17,0xa9075347,
wolfSSL 16:8e0d178b1d1e 23297 0x2a3973e5,0x1e20f170,0x6feb67e9,0xe1aacc1c,0xe16bc6b9,0x2ca0ac32 } },
wolfSSL 16:8e0d178b1d1e 23298 /* 119 */
wolfSSL 16:8e0d178b1d1e 23299 { { 0xef871eb5,0xffea12e4,0xa8bf0a7a,0x94c2f25d,0x78134eaa,0x4d1e4c2a,
wolfSSL 16:8e0d178b1d1e 23300 0x0360fb10,0x11ed16fb,0x85fc11be,0x4029b6db,0xf4d390fa,0x5e9f7ab7 },
wolfSSL 16:8e0d178b1d1e 23301 { 0x30646612,0x5076d72f,0xdda1d0d8,0xa0afed1d,0x85a1d103,0x29022257,
wolfSSL 16:8e0d178b1d1e 23302 0x4e276bcd,0xcb499e17,0x51246c3d,0x16d1da71,0x589a0443,0xc72d56d3 } },
wolfSSL 16:8e0d178b1d1e 23303 /* 120 */
wolfSSL 16:8e0d178b1d1e 23304 { { 0xdae5bb45,0xdf5ffc74,0x261bd6dc,0x99068c4a,0xaa98ec7b,0xdc0afa7a,
wolfSSL 16:8e0d178b1d1e 23305 0xf121e96d,0xedd2ee00,0x1414045c,0x163cc7be,0x335af50e,0xb0b1bbce },
wolfSSL 16:8e0d178b1d1e 23306 { 0x01a06293,0xd440d785,0x6552e644,0xcdebab7c,0x8c757e46,0x48cb8dbc,
wolfSSL 16:8e0d178b1d1e 23307 0x3cabe3cb,0x81f9cf78,0xb123f59a,0xddd02611,0xeeb3784d,0x3dc7b88e } },
wolfSSL 16:8e0d178b1d1e 23308 /* 121 */
wolfSSL 16:8e0d178b1d1e 23309 { { 0xc4741456,0xe1b8d398,0x6032a121,0xa9dfa902,0x1263245b,0x1cbfc86d,
wolfSSL 16:8e0d178b1d1e 23310 0x5244718c,0xf411c762,0x05b0fc54,0x96521d54,0xdbaa4985,0x1afab46e },
wolfSSL 16:8e0d178b1d1e 23311 { 0x8674b4ad,0xa75902ba,0x5ad87d12,0x486b43ad,0x36e0d099,0x72b1c736,
wolfSSL 16:8e0d178b1d1e 23312 0xbb6cd6d6,0x39890e07,0x59bace4e,0x8128999c,0x7b535e33,0xd8da430b } },
wolfSSL 16:8e0d178b1d1e 23313 /* 122 */
wolfSSL 16:8e0d178b1d1e 23314 { { 0xc6b75791,0x39f65642,0x21806bfb,0x050947a6,0x1362ef84,0x0ca3e370,
wolfSSL 16:8e0d178b1d1e 23315 0x8c3d2391,0x9bc60aed,0x732e1ddc,0x9b488671,0xa98ee077,0x12d10d9e },
wolfSSL 16:8e0d178b1d1e 23316 { 0x3651b7dc,0xb6f2822d,0x80abd138,0x6345a5ba,0x472d3c84,0x62033262,
wolfSSL 16:8e0d178b1d1e 23317 0xacc57527,0xd54a1d40,0x424447cb,0x6ea46b3a,0x2fb1a496,0x5bc41057 } },
wolfSSL 16:8e0d178b1d1e 23318 /* 123 */
wolfSSL 16:8e0d178b1d1e 23319 { { 0xa751cd0e,0xe70c57a3,0xeba3c7d6,0x190d8419,0x9d47d55a,0xb1c3bee7,
wolfSSL 16:8e0d178b1d1e 23320 0xf912c6d8,0xda941266,0x407a6ad6,0x12e9aacc,0x6e838911,0xd6ce5f11 },
wolfSSL 16:8e0d178b1d1e 23321 { 0x70e1f2ce,0x063ca97b,0x8213d434,0xa3e47c72,0x84df810a,0xa016e241,
wolfSSL 16:8e0d178b1d1e 23322 0xdfd881a4,0x688ad7b0,0xa89bf0ad,0xa37d99fc,0xa23c2d23,0xd8e3f339 } },
wolfSSL 16:8e0d178b1d1e 23323 /* 124 */
wolfSSL 16:8e0d178b1d1e 23324 { { 0x750bed6f,0xbdf53163,0x83e68b0a,0x808abc32,0x5bb08a33,0x85a36627,
wolfSSL 16:8e0d178b1d1e 23325 0x6b0e4abe,0xf72a3a0f,0xfaf0c6ad,0xf7716d19,0x5379b25f,0x22dcc020 },
wolfSSL 16:8e0d178b1d1e 23326 { 0xf9a56e11,0x7400bf8d,0x56a47f21,0x6cb8bad7,0x7a6eb644,0x7c97176f,
wolfSSL 16:8e0d178b1d1e 23327 0xd1f5b646,0xe8fd84f7,0x44ddb054,0x98320a94,0x1dde86f5,0x07071ba3 } },
wolfSSL 16:8e0d178b1d1e 23328 /* 125 */
wolfSSL 16:8e0d178b1d1e 23329 { { 0x98f8fcb9,0x6fdfa0e5,0x94d0d70c,0x89cec8e0,0x106d20a8,0xa0899397,
wolfSSL 16:8e0d178b1d1e 23330 0xba8acc9c,0x915bfb9a,0x5507e01c,0x1370c94b,0x8a821ffb,0x83246a60 },
wolfSSL 16:8e0d178b1d1e 23331 { 0xbe3c378f,0xa8273a9f,0x35a25be9,0x7e544789,0x4dd929d7,0x6cfa4972,
wolfSSL 16:8e0d178b1d1e 23332 0x365bd878,0x987fed9d,0x5c29a7ae,0x4982ac94,0x5ddd7ec5,0x4589a5d7 } },
wolfSSL 16:8e0d178b1d1e 23333 /* 126 */
wolfSSL 16:8e0d178b1d1e 23334 { { 0xa95540a9,0x9fabb174,0x0162c5b0,0x7cfb886f,0xea3dee18,0x17be766b,
wolfSSL 16:8e0d178b1d1e 23335 0xe88e624c,0xff7da41f,0x8b919c38,0xad0b71eb,0xf31ff9a9,0x86a522e0 },
wolfSSL 16:8e0d178b1d1e 23336 { 0x868bc259,0xbc8e6f72,0x3ccef9e4,0x6130c638,0x9a466555,0x09f1f454,
wolfSSL 16:8e0d178b1d1e 23337 0x19b2bfb4,0x8e6c0f09,0x0ca7bb22,0x945c46c9,0x4dafb67b,0xacd87168 } },
wolfSSL 16:8e0d178b1d1e 23338 /* 127 */
wolfSSL 16:8e0d178b1d1e 23339 { { 0x10c53841,0x090c72ca,0x55a4fced,0xc20ae01b,0xe10234ad,0x03f7ebd5,
wolfSSL 16:8e0d178b1d1e 23340 0x85892064,0xb3f42a6a,0xb4a14722,0xbdbc30c0,0x8ca124cc,0x971bc437 },
wolfSSL 16:8e0d178b1d1e 23341 { 0x517ff2ff,0x6f79f46d,0xecba947b,0x6a9c96e2,0x62925122,0x5e79f2f4,
wolfSSL 16:8e0d178b1d1e 23342 0x6a4e91f1,0x30a96bb1,0x2d4c72da,0x1147c923,0x5811e4df,0x65bc311f } },
wolfSSL 16:8e0d178b1d1e 23343 /* 128 */
wolfSSL 16:8e0d178b1d1e 23344 { { 0x139b3239,0x87c7dd7d,0x4d833bae,0x8b57824e,0x9fff0015,0xbcbc4878,
wolfSSL 16:8e0d178b1d1e 23345 0x909eaf1a,0x8ffcef8b,0xf1443a78,0x9905f4ee,0xe15cbfed,0x020dd4a2 },
wolfSSL 16:8e0d178b1d1e 23346 { 0xa306d695,0xca2969ec,0xb93caf60,0xdf940cad,0x87ea6e39,0x67f7fab7,
wolfSSL 16:8e0d178b1d1e 23347 0xf98c4fe5,0x0d0ee10f,0xc19cb91e,0xc646879a,0x7d1d7ab4,0x4b4ea50c } },
wolfSSL 16:8e0d178b1d1e 23348 /* 129 */
wolfSSL 16:8e0d178b1d1e 23349 { { 0x7a0db57e,0x19e40945,0x9a8c9702,0xe6017cad,0x1be5cff9,0xdbf739e5,
wolfSSL 16:8e0d178b1d1e 23350 0xa7a938a2,0x3646b3cd,0x68350dfc,0x04511085,0x56e098b5,0xad3bd6f3 },
wolfSSL 16:8e0d178b1d1e 23351 { 0xee2e3e3e,0x935ebabf,0x473926cb,0xfbd01702,0x9e9fb5aa,0x7c735b02,
wolfSSL 16:8e0d178b1d1e 23352 0x2e3feff0,0xc52a1b85,0x046b405a,0x9199abd3,0x39039971,0xe306fcec } },
wolfSSL 16:8e0d178b1d1e 23353 /* 130 */
wolfSSL 16:8e0d178b1d1e 23354 { { 0x23e4712c,0xd6d9aec8,0xc3c198ee,0x7ca8376c,0x31bebd8a,0xe6d83187,
wolfSSL 16:8e0d178b1d1e 23355 0xd88bfef3,0xed57aff3,0xcf44edc7,0x72a645ee,0x5cbb1517,0xd4e63d0b },
wolfSSL 16:8e0d178b1d1e 23356 { 0xceee0ecf,0x98ce7a1c,0x5383ee8e,0x8f012633,0xa6b455e8,0x3b879078,
wolfSSL 16:8e0d178b1d1e 23357 0xc7658c06,0xcbcd3d96,0x0783336a,0x721d6fe7,0x5a677136,0xf21a7263 } },
wolfSSL 16:8e0d178b1d1e 23358 /* 131 */
wolfSSL 16:8e0d178b1d1e 23359 { { 0x9586ba11,0x19d8b3cd,0x8a5c0480,0xd9e0aeb2,0x2230ef5c,0xe4261dbf,
wolfSSL 16:8e0d178b1d1e 23360 0x02e6bf09,0x095a9dee,0x80dc7784,0x8963723c,0x145157b1,0x5c97dbaf },
wolfSSL 16:8e0d178b1d1e 23361 { 0x4bc4503e,0x97e74434,0x85a6b370,0x0fb1cb31,0xcd205d4b,0x3e8df2be,
wolfSSL 16:8e0d178b1d1e 23362 0xf8f765da,0x497dd1bc,0x6c988a1a,0x92ef95c7,0x64dc4cfa,0x3f924baa } },
wolfSSL 16:8e0d178b1d1e 23363 /* 132 */
wolfSSL 16:8e0d178b1d1e 23364 { { 0x7268b448,0x6bf1b8dd,0xefd79b94,0xd4c28ba1,0xe4e3551f,0x2fa1f8c8,
wolfSSL 16:8e0d178b1d1e 23365 0x5c9187a9,0x769e3ad4,0x40326c0d,0x28843b4d,0x50d5d669,0xfefc8094 },
wolfSSL 16:8e0d178b1d1e 23366 { 0x90339366,0x30c85bfd,0x5ccf6c3a,0x4eeb56f1,0x28ccd1dc,0x0e72b149,
wolfSSL 16:8e0d178b1d1e 23367 0xf2ce978e,0x73ee85b5,0x3165bb23,0xcdeb2bf3,0x4e410abf,0x8106c923 } },
wolfSSL 16:8e0d178b1d1e 23368 /* 133 */
wolfSSL 16:8e0d178b1d1e 23369 { { 0x7d02f4ee,0xc8df0161,0x18e21225,0x8a781547,0x6acf9e40,0x4ea895eb,
wolfSSL 16:8e0d178b1d1e 23370 0x6e5a633d,0x8b000cb5,0x7e981ffb,0xf31d86d5,0x4475bc32,0xf5c8029c },
wolfSSL 16:8e0d178b1d1e 23371 { 0x1b568973,0x764561ce,0xa62996ec,0x2f809b81,0xda085408,0x9e513d64,
wolfSSL 16:8e0d178b1d1e 23372 0xe61ce309,0xc27d815d,0x272999e0,0x0da6ff99,0xfead73f7,0xbd284779 } },
wolfSSL 16:8e0d178b1d1e 23373 /* 134 */
wolfSSL 16:8e0d178b1d1e 23374 { { 0x9b1cdf2b,0x6033c2f9,0xbc5fa151,0x2a99cf06,0x12177b3b,0x7d27d259,
wolfSSL 16:8e0d178b1d1e 23375 0xc4485483,0xb1f15273,0x102e2297,0x5fd57d81,0xc7f6acb7,0x3d43e017 },
wolfSSL 16:8e0d178b1d1e 23376 { 0x3a70eb28,0x41a8bb0b,0x3e80b06b,0x67de2d8e,0x70c28de5,0x09245a41,
wolfSSL 16:8e0d178b1d1e 23377 0xa7b26023,0xad7dbcb1,0x2cbc6c1e,0x70b08a35,0x9b33041f,0xb504fb66 } },
wolfSSL 16:8e0d178b1d1e 23378 /* 135 */
wolfSSL 16:8e0d178b1d1e 23379 { { 0xf97a27c2,0xa8e85ab5,0xc10a011b,0x6ac5ec8b,0xffbcf161,0x55745533,
wolfSSL 16:8e0d178b1d1e 23380 0x65790a60,0x01780e85,0x99ee75b0,0xe451bf85,0x39c29881,0x8907a63b },
wolfSSL 16:8e0d178b1d1e 23381 { 0x260189ed,0x76d46738,0x47bd35cb,0x284a4436,0x20cab61e,0xd74e8c40,
wolfSSL 16:8e0d178b1d1e 23382 0x416cf20a,0x6264bf8c,0x5fd820ce,0xfa5a6c95,0xf24bb5fc,0xfa7154d0 } },
wolfSSL 16:8e0d178b1d1e 23383 /* 136 */
wolfSSL 16:8e0d178b1d1e 23384 { { 0x9b3f5034,0x18482cec,0xcd9e68fd,0x962d445a,0x95746f23,0x266fb1d6,
wolfSSL 16:8e0d178b1d1e 23385 0x58c94a4b,0xc66ade5a,0xed68a5b6,0xdbbda826,0x7ab0d6ae,0x05664a4d },
wolfSSL 16:8e0d178b1d1e 23386 { 0x025e32fc,0xbcd4fe51,0xa96df252,0x61a5aebf,0x31592a31,0xd88a07e2,
wolfSSL 16:8e0d178b1d1e 23387 0x98905517,0x5d9d94de,0x5fd440e7,0x96bb4010,0xe807db4c,0x1b0c47a2 } },
wolfSSL 16:8e0d178b1d1e 23388 /* 137 */
wolfSSL 16:8e0d178b1d1e 23389 { { 0x08223878,0x5c2a6ac8,0xe65a5558,0xba08c269,0x9bbc27fd,0xd22b1b9b,
wolfSSL 16:8e0d178b1d1e 23390 0x72b9607d,0x919171bf,0xe588dc58,0x9ab455f9,0x23662d93,0x6d54916e },
wolfSSL 16:8e0d178b1d1e 23391 { 0x3b1de0c1,0x8da8e938,0x804f278f,0xa84d186a,0xd3461695,0xbf4988cc,
wolfSSL 16:8e0d178b1d1e 23392 0xe10eb0cb,0xf5eae3be,0xbf2a66ed,0x1ff8b68f,0xc305b570,0xa68daf67 } },
wolfSSL 16:8e0d178b1d1e 23393 /* 138 */
wolfSSL 16:8e0d178b1d1e 23394 { { 0x44b2e045,0xc1004cff,0x4b1c05d4,0x91b5e136,0x88a48a07,0x53ae4090,
wolfSSL 16:8e0d178b1d1e 23395 0xea11bb1a,0x73fb2995,0x3d93a4ea,0x32048570,0x3bfc8a5f,0xcce45de8 },
wolfSSL 16:8e0d178b1d1e 23396 { 0xc2b3106e,0xaff4a97e,0xb6848b4f,0x9069c630,0xed76241c,0xeda837a6,
wolfSSL 16:8e0d178b1d1e 23397 0x6cc3f6cf,0x8a0daf13,0x3da018a8,0x199d049d,0xd9093ba3,0xf867c6b1 } },
wolfSSL 16:8e0d178b1d1e 23398 /* 139 */
wolfSSL 16:8e0d178b1d1e 23399 { { 0x56527296,0xe4d42a56,0xce71178d,0xae26c73d,0x6c251664,0x70a0adac,
wolfSSL 16:8e0d178b1d1e 23400 0x5dc0ae1d,0x813483ae,0xdaab2daf,0x7574eacd,0xc2d55f4f,0xc56b52dc },
wolfSSL 16:8e0d178b1d1e 23401 { 0x95f32923,0x872bc167,0x5bdd2a89,0x4be17581,0xa7699f00,0x9b57f1e7,
wolfSSL 16:8e0d178b1d1e 23402 0x3ac2de02,0x5fcd9c72,0x92377739,0x83af3ba1,0xfc50b97f,0xa64d4e2b } },
wolfSSL 16:8e0d178b1d1e 23403 /* 140 */
wolfSSL 16:8e0d178b1d1e 23404 { { 0x0e552b40,0x2172dae2,0xd34d52e8,0x62f49725,0x07958f98,0x7930ee40,
wolfSSL 16:8e0d178b1d1e 23405 0x751fdd74,0x56da2a90,0xf53e48c3,0xf1192834,0x8e53c343,0x34d2ac26 },
wolfSSL 16:8e0d178b1d1e 23406 { 0x13111286,0x1073c218,0xda9d9827,0x201dac14,0xee95d378,0xec2c29db,
wolfSSL 16:8e0d178b1d1e 23407 0x1f3ee0b1,0x9316f119,0x544ce71c,0x7890c9f0,0x27612127,0xd77138af } },
wolfSSL 16:8e0d178b1d1e 23408 /* 141 */
wolfSSL 16:8e0d178b1d1e 23409 { { 0x3b4ad1cd,0x78045e6d,0x4aa49bc1,0xcd86b94e,0xfd677a16,0x57e51f1d,
wolfSSL 16:8e0d178b1d1e 23410 0xfa613697,0xd9290935,0x34f4d893,0x7a3f9593,0x5d5fcf9b,0x8c9c248b },
wolfSSL 16:8e0d178b1d1e 23411 { 0x6f70d4e9,0x9f23a482,0x63190ae9,0x17273454,0x5b081a48,0x4bdd7c13,
wolfSSL 16:8e0d178b1d1e 23412 0x28d65271,0x1e2de389,0xe5841d1f,0x0bbaaa25,0x746772e5,0xc4c18a79 } },
wolfSSL 16:8e0d178b1d1e 23413 /* 142 */
wolfSSL 16:8e0d178b1d1e 23414 { { 0x593375ac,0x10ee2681,0x7dd5e113,0x4f3288be,0x240f3538,0x9a97b2fb,
wolfSSL 16:8e0d178b1d1e 23415 0x1de6b1e2,0xfa11089f,0x1351bc58,0x516da562,0x2dfa85b5,0x573b6119 },
wolfSSL 16:8e0d178b1d1e 23416 { 0x6cba7df5,0x89e96683,0x8c28ab40,0xf299be15,0xad43fcbf,0xe91c9348,
wolfSSL 16:8e0d178b1d1e 23417 0x9a1cefb3,0xe9bbc7cc,0x738b2775,0xc8add876,0x775eaa01,0x6e3b1f2e } },
wolfSSL 16:8e0d178b1d1e 23418 /* 143 */
wolfSSL 16:8e0d178b1d1e 23419 { { 0xb677788b,0x0365a888,0x3fd6173c,0x634ae8c4,0x9e498dbe,0x30498761,
wolfSSL 16:8e0d178b1d1e 23420 0xc8f779ab,0x08c43e6d,0x4c09aca9,0x068ae384,0x2018d170,0x2380c70b },
wolfSSL 16:8e0d178b1d1e 23421 { 0xa297c5ec,0xcf77fbc3,0xca457948,0xdacbc853,0x336bec7e,0x3690de04,
wolfSSL 16:8e0d178b1d1e 23422 0x14eec461,0x26bbac64,0x1f713abf,0xd1c23c7e,0xe6fd569e,0xf08bbfcd } },
wolfSSL 16:8e0d178b1d1e 23423 /* 144 */
wolfSSL 16:8e0d178b1d1e 23424 { { 0x84770ee3,0x5f8163f4,0x744a1706,0x0e0c7f94,0xe1b2d46d,0x9c8f05f7,
wolfSSL 16:8e0d178b1d1e 23425 0xd01fd99a,0x417eafe7,0x11440e5b,0x2ba15df5,0x91a6fbcf,0xdc5c552a },
wolfSSL 16:8e0d178b1d1e 23426 { 0xa270f721,0x86271d74,0xa004485b,0x32c0a075,0x8defa075,0x9d1a87e3,
wolfSSL 16:8e0d178b1d1e 23427 0xbf0d20fe,0xb590a7ac,0x8feda1f5,0x430c41c2,0x58f6ec24,0x454d2879 } },
wolfSSL 16:8e0d178b1d1e 23428 /* 145 */
wolfSSL 16:8e0d178b1d1e 23429 { { 0x7c525435,0x52b7a635,0x37c4bdbc,0x3d9ef57f,0xdffcc475,0x2bb93e9e,
wolfSSL 16:8e0d178b1d1e 23430 0x7710f3be,0xf7b8ba98,0x21b727de,0x42ee86da,0x2e490d01,0x55ac3f19 },
wolfSSL 16:8e0d178b1d1e 23431 { 0xc0c1c390,0x487e3a6e,0x446cde7b,0x036fb345,0x496ae951,0x089eb276,
wolfSSL 16:8e0d178b1d1e 23432 0x71ed1234,0xedfed4d9,0x900f0b46,0x661b0dd5,0x8582f0d3,0x11bd6f1b } },
wolfSSL 16:8e0d178b1d1e 23433 /* 146 */
wolfSSL 16:8e0d178b1d1e 23434 { { 0x076bc9d1,0x5cf9350f,0xcf3cd2c3,0x15d903be,0x25af031c,0x21cfc8c2,
wolfSSL 16:8e0d178b1d1e 23435 0x8b1cc657,0xe0ad3248,0x70014e87,0xdd9fb963,0x297f1658,0xf0f3a5a1 },
wolfSSL 16:8e0d178b1d1e 23436 { 0xf1f703aa,0xbb908fba,0x2f6760ba,0x2f9cc420,0x66a38b51,0x00ceec66,
wolfSSL 16:8e0d178b1d1e 23437 0x05d645da,0x4deda330,0xf7de3394,0xb9cf5c72,0x1ad4c906,0xaeef6502 } },
wolfSSL 16:8e0d178b1d1e 23438 /* 147 */
wolfSSL 16:8e0d178b1d1e 23439 { { 0x7a19045d,0x0583c8b1,0xd052824c,0xae7c3102,0xff6cfa58,0x2a234979,
wolfSSL 16:8e0d178b1d1e 23440 0x62c733c0,0xfe9dffc9,0x9c0c4b09,0x3a7fa250,0x4fe21805,0x516437bb },
wolfSSL 16:8e0d178b1d1e 23441 { 0xc2a23ddb,0x9454e3d5,0x289c104e,0x0726d887,0x4fd15243,0x8977d918,
wolfSSL 16:8e0d178b1d1e 23442 0x6d7790ba,0xc559e73f,0x465af85f,0x8fd3e87d,0x5feee46b,0xa2615c74 } },
wolfSSL 16:8e0d178b1d1e 23443 /* 148 */
wolfSSL 16:8e0d178b1d1e 23444 { { 0x4335167d,0xc8d607a8,0xe0f5c887,0x8b42d804,0x398d11f9,0x5f9f13df,
wolfSSL 16:8e0d178b1d1e 23445 0x20740c67,0x5aaa5087,0xa3d9234b,0x83da9a6a,0x2a54bad1,0xbd3a5c4e },
wolfSSL 16:8e0d178b1d1e 23446 { 0x2db0f658,0xdd13914c,0x5a3f373a,0x29dcb66e,0x5245a72b,0xbfd62df5,
wolfSSL 16:8e0d178b1d1e 23447 0x91e40847,0x19d18023,0xb136b1ae,0xd9df74db,0x3f93bc5b,0x72a06b6b } },
wolfSSL 16:8e0d178b1d1e 23448 /* 149 */
wolfSSL 16:8e0d178b1d1e 23449 { { 0xad19d96f,0x6da19ec3,0xfb2a4099,0xb342daa4,0x662271ea,0x0e61633a,
wolfSSL 16:8e0d178b1d1e 23450 0xce8c054b,0x3bcece81,0x8bd62dc6,0x7cc8e061,0xee578d8b,0xae189e19 },
wolfSSL 16:8e0d178b1d1e 23451 { 0xdced1eed,0x73e7a25d,0x7875d3ab,0xc1257f0a,0x1cfef026,0x2cb2d5a2,
wolfSSL 16:8e0d178b1d1e 23452 0xb1fdf61c,0xd98ef39b,0x24e83e6c,0xcd8e6f69,0xc7b7088b,0xd71e7076 } },
wolfSSL 16:8e0d178b1d1e 23453 /* 150 */
wolfSSL 16:8e0d178b1d1e 23454 { { 0x9d4245bf,0x33936830,0x2ac2953b,0x22d96217,0x56c3c3cd,0xb3bf5a82,
wolfSSL 16:8e0d178b1d1e 23455 0x0d0699e8,0x50c9be91,0x8f366459,0xec094463,0x513b7c35,0x6c056dba },
wolfSSL 16:8e0d178b1d1e 23456 { 0x045ab0e3,0x687a6a83,0x445c9295,0x8d40b57f,0xa16f5954,0x0f345048,
wolfSSL 16:8e0d178b1d1e 23457 0x3d8f0a87,0x64b5c639,0x9f71c5e2,0x106353a2,0x874f0dd4,0xdd58b475 } },
wolfSSL 16:8e0d178b1d1e 23458 /* 151 */
wolfSSL 16:8e0d178b1d1e 23459 { { 0x62230c72,0x67ec084f,0x481385e3,0xf14f6cca,0x4cda7774,0xf58bb407,
wolfSSL 16:8e0d178b1d1e 23460 0xaa2dbb6b,0xe15011b1,0x0c035ab1,0xd488369d,0x8245f2fd,0xef83c24a },
wolfSSL 16:8e0d178b1d1e 23461 { 0x9fdc2538,0xfb57328f,0x191fe46a,0x79808293,0x32ede548,0xe28f5c44,
wolfSSL 16:8e0d178b1d1e 23462 0xea1a022c,0x1b3cda99,0x3df2ec7f,0x39e639b7,0x760e9a18,0x77b6272b } },
wolfSSL 16:8e0d178b1d1e 23463 /* 152 */
wolfSSL 16:8e0d178b1d1e 23464 { { 0xa65d56d5,0x2b1d51bd,0x7ea696e0,0x3a9b71f9,0x9904f4c4,0x95250ecc,
wolfSSL 16:8e0d178b1d1e 23465 0xe75774b7,0x8bc4d6eb,0xeaeeb9aa,0x0e343f8a,0x930e04cb,0xc473c1d1 },
wolfSSL 16:8e0d178b1d1e 23466 { 0x064cd8ae,0x282321b1,0x5562221c,0xf4b4371e,0xd1bf1221,0xc1cc81ec,
wolfSSL 16:8e0d178b1d1e 23467 0xe2c8082f,0xa52a07a9,0xba64a958,0x350d8e59,0x6fb32c9a,0x29e4f3de } },
wolfSSL 16:8e0d178b1d1e 23468 /* 153 */
wolfSSL 16:8e0d178b1d1e 23469 { { 0xba89aaa5,0x0aa9d56c,0xc4c6059e,0xf0208ac0,0xbd6ddca4,0x7400d9c6,
wolfSSL 16:8e0d178b1d1e 23470 0xf2c2f74a,0xb384e475,0xb1562dd3,0x4c1061fc,0x2e153b8d,0x3924e248 },
wolfSSL 16:8e0d178b1d1e 23471 { 0x849808ab,0xf38b8d98,0xa491aa36,0x29bf3260,0x88220ede,0x85159ada,
wolfSSL 16:8e0d178b1d1e 23472 0xbe5bc422,0x8b47915b,0xd7300967,0xa934d72e,0x2e515d0d,0xc4f30398 } },
wolfSSL 16:8e0d178b1d1e 23473 /* 154 */
wolfSSL 16:8e0d178b1d1e 23474 { { 0x1b1de38b,0xe3e9ee42,0x42636760,0xa124e25a,0x90165b1a,0x90bf73c0,
wolfSSL 16:8e0d178b1d1e 23475 0x146434c5,0x21802a34,0x2e1fa109,0x54aa83f2,0xed9c51e9,0x1d4bd03c },
wolfSSL 16:8e0d178b1d1e 23476 { 0x798751e6,0xc2d96a38,0x8c3507f5,0xed27235f,0xc8c24f88,0xb5fb80e2,
wolfSSL 16:8e0d178b1d1e 23477 0xd37f4f78,0xf873eefa,0xf224ba96,0x7229fd74,0x9edd7149,0x9dcd9199 } },
wolfSSL 16:8e0d178b1d1e 23478 /* 155 */
wolfSSL 16:8e0d178b1d1e 23479 { { 0x4e94f22a,0xee9f81a6,0xf71ec341,0xe5609892,0xa998284e,0x6c818ddd,
wolfSSL 16:8e0d178b1d1e 23480 0x3b54b098,0x9fd47295,0x0e8a7cc9,0x47a6ac03,0xb207a382,0xde684e5e },
wolfSSL 16:8e0d178b1d1e 23481 { 0x2b6b956b,0x4bdd1ecd,0xf01b3583,0x09084414,0x55233b14,0xe2f80b32,
wolfSSL 16:8e0d178b1d1e 23482 0xef5ebc5e,0x5a0fec54,0xbf8b29a2,0x74cf25e6,0x7f29e014,0x1c757fa0 } },
wolfSSL 16:8e0d178b1d1e 23483 /* 156 */
wolfSSL 16:8e0d178b1d1e 23484 { { 0xeb0fdfe4,0x1bcb5c4a,0xf0899367,0xd7c649b3,0x05bc083b,0xaef68e3f,
wolfSSL 16:8e0d178b1d1e 23485 0xa78aa607,0x57a06e46,0x21223a44,0xa2136ecc,0x52f5a50b,0x89bd6484 },
wolfSSL 16:8e0d178b1d1e 23486 { 0x4455f15a,0x724411b9,0x08a9c0fd,0x23dfa970,0x6db63bef,0x7b0da4d1,
wolfSSL 16:8e0d178b1d1e 23487 0xfb162443,0x6f8a7ec1,0xe98284fb,0xc1ac9cee,0x33566022,0x085a582b } },
wolfSSL 16:8e0d178b1d1e 23488 /* 157 */
wolfSSL 16:8e0d178b1d1e 23489 { { 0xec1f138a,0x15cb61f9,0x668f0c28,0x11c9a230,0xdf93f38f,0xac829729,
wolfSSL 16:8e0d178b1d1e 23490 0x4048848d,0xcef25698,0x2bba8fbf,0x3f686da0,0x111c619a,0xed5fea78 },
wolfSSL 16:8e0d178b1d1e 23491 { 0xd6d1c833,0x9b4f73bc,0x86e7bf80,0x50951606,0x042b1d51,0xa2a73508,
wolfSSL 16:8e0d178b1d1e 23492 0x5fb89ec2,0x9ef6ea49,0x5ef8b892,0xf1008ce9,0x9ae8568b,0x78a7e684 } },
wolfSSL 16:8e0d178b1d1e 23493 /* 158 */
wolfSSL 16:8e0d178b1d1e 23494 { { 0x10470cd8,0x3fe83a7c,0xf86df000,0x92734682,0xda9409b5,0xb5dac06b,
wolfSSL 16:8e0d178b1d1e 23495 0x94939c5f,0x1e7a9660,0x5cc116dc,0xdec6c150,0x66bac8cc,0x1a52b408 },
wolfSSL 16:8e0d178b1d1e 23496 { 0x6e864045,0x5303a365,0x9139efc1,0x45eae72a,0x6f31d54f,0x83bec646,
wolfSSL 16:8e0d178b1d1e 23497 0x6e958a6d,0x2fb4a86f,0x4ff44030,0x6760718e,0xe91ae0df,0x008117e3 } },
wolfSSL 16:8e0d178b1d1e 23498 /* 159 */
wolfSSL 16:8e0d178b1d1e 23499 { { 0x384310a2,0x5d5833ba,0x1fd6c9fc,0xbdfb4edc,0x849c4fb8,0xb9a4f102,
wolfSSL 16:8e0d178b1d1e 23500 0x581c1e1f,0xe5fb239a,0xd0a9746d,0xba44b2e7,0x3bd942b9,0x78f7b768 },
wolfSSL 16:8e0d178b1d1e 23501 { 0xc87607ae,0x076c8ca1,0xd5caaa7e,0x82b23c2e,0x2763e461,0x6a581f39,
wolfSSL 16:8e0d178b1d1e 23502 0x3886df11,0xca8a5e4a,0x264e7f22,0xc87e90cf,0x215cfcfc,0x04f74870 } },
wolfSSL 16:8e0d178b1d1e 23503 /* 160 */
wolfSSL 16:8e0d178b1d1e 23504 { { 0x141d161c,0x5285d116,0x93c4ed17,0x67cd2e0e,0x7c36187e,0x12c62a64,
wolfSSL 16:8e0d178b1d1e 23505 0xed2584ca,0xf5329539,0x42fbbd69,0xc4c777c4,0x1bdfc50a,0x107de776 },
wolfSSL 16:8e0d178b1d1e 23506 { 0xe96beebd,0x9976dcc5,0xa865a151,0xbe2aff95,0x9d8872af,0x0e0a9da1,
wolfSSL 16:8e0d178b1d1e 23507 0xa63c17cc,0x5e357a3d,0xe15cc67c,0xd31fdfd8,0x7970c6d8,0xc44bbefd } },
wolfSSL 16:8e0d178b1d1e 23508 /* 161 */
wolfSSL 16:8e0d178b1d1e 23509 { { 0x4c0c62f1,0x703f83e2,0x4e195572,0x9b1e28ee,0xfe26cced,0x6a82858b,
wolfSSL 16:8e0d178b1d1e 23510 0xc43638fa,0xd381c84b,0xa5ba43d8,0x94f72867,0x10b82743,0x3b4a783d },
wolfSSL 16:8e0d178b1d1e 23511 { 0x7576451e,0xee1ad7b5,0x14b6b5c8,0xc3d0b597,0xfcacc1b8,0x3dc30954,
wolfSSL 16:8e0d178b1d1e 23512 0x472c9d7b,0x55df110e,0x02f8a328,0x97c86ed7,0x88dc098f,0xd0433413 } },
wolfSSL 16:8e0d178b1d1e 23513 /* 162 */
wolfSSL 16:8e0d178b1d1e 23514 { { 0x2ca8f2fe,0x1a60d152,0x491bd41f,0x61640948,0x58dfe035,0x6dae29a5,
wolfSSL 16:8e0d178b1d1e 23515 0x278e4863,0x9a615bea,0x9ad7c8e5,0xbbdb4477,0x2ceac2fc,0x1c706630 },
wolfSSL 16:8e0d178b1d1e 23516 { 0x99699b4b,0x5e2b54c6,0x239e17e8,0xb509ca6d,0xea063a82,0x728165fe,
wolfSSL 16:8e0d178b1d1e 23517 0xb6a22e02,0x6b5e609d,0xb26ee1df,0x12813905,0x439491fa,0x07b9f722 } },
wolfSSL 16:8e0d178b1d1e 23518 /* 163 */
wolfSSL 16:8e0d178b1d1e 23519 { { 0x48ff4e49,0x1592ec14,0x6d644129,0x3e4e9f17,0x1156acc0,0x7acf8288,
wolfSSL 16:8e0d178b1d1e 23520 0xbb092b0b,0x5aa34ba8,0x7d38393d,0xcd0f9022,0xea4f8187,0x416724dd },
wolfSSL 16:8e0d178b1d1e 23521 { 0xc0139e73,0x3c4e641c,0x91e4d87d,0xe0fe46cf,0xcab61f8a,0xedb3c792,
wolfSSL 16:8e0d178b1d1e 23522 0xd3868753,0x4cb46de4,0x20f1098a,0xe449c21d,0xf5b8ea6e,0x5e5fd059 } },
wolfSSL 16:8e0d178b1d1e 23523 /* 164 */
wolfSSL 16:8e0d178b1d1e 23524 { { 0x75856031,0x7fcadd46,0xeaf2fbd0,0x89c7a4cd,0x7a87c480,0x1af523ce,
wolfSSL 16:8e0d178b1d1e 23525 0x61d9ae90,0xe5fc1095,0xbcdb95f5,0x3fb5864f,0xbb5b2c7d,0xbeb5188e },
wolfSSL 16:8e0d178b1d1e 23526 { 0x3ae65825,0x3d1563c3,0x0e57d641,0x116854c4,0x1942ebd3,0x11f73d34,
wolfSSL 16:8e0d178b1d1e 23527 0xc06955b3,0x24dc5904,0x995a0a62,0x8a0d4c83,0x5d577b7d,0xfb26b86d } },
wolfSSL 16:8e0d178b1d1e 23528 /* 165 */
wolfSSL 16:8e0d178b1d1e 23529 { { 0xc686ae17,0xc53108e7,0xd1c1da56,0x9090d739,0x9aec50ae,0x4583b013,
wolfSSL 16:8e0d178b1d1e 23530 0xa49a6ab2,0xdd9a088b,0xf382f850,0x28192eea,0xf5fe910e,0xcc8df756 },
wolfSSL 16:8e0d178b1d1e 23531 { 0x9cab7630,0x877823a3,0xfb8e7fc1,0x64984a9a,0x364bfc16,0x5448ef9c,
wolfSSL 16:8e0d178b1d1e 23532 0xc44e2a9a,0xbbb4f871,0x435c95e9,0x901a41ab,0xaaa50a06,0xc6c23e5f } },
wolfSSL 16:8e0d178b1d1e 23533 /* 166 */
wolfSSL 16:8e0d178b1d1e 23534 { { 0x9034d8dd,0xb78016c1,0x0b13e79b,0x856bb44b,0xb3241a05,0x85c6409a,
wolfSSL 16:8e0d178b1d1e 23535 0x2d78ed21,0x8d2fe19a,0x726eddf2,0xdcc7c26d,0x25104f04,0x3ccaff5f },
wolfSSL 16:8e0d178b1d1e 23536 { 0x6b21f843,0x397d7edc,0xe975de4c,0xda88e4dd,0x4f5ab69e,0x5273d396,
wolfSSL 16:8e0d178b1d1e 23537 0x9aae6cc0,0x537680e3,0x3e6f9461,0xf749cce5,0x957bffd3,0x021ddbd9 } },
wolfSSL 16:8e0d178b1d1e 23538 /* 167 */
wolfSSL 16:8e0d178b1d1e 23539 { { 0x777233cf,0x7b64585f,0x0942a6f0,0xfe6771f6,0xdfe6eef0,0x636aba7a,
wolfSSL 16:8e0d178b1d1e 23540 0x86038029,0x63bbeb56,0xde8fcf36,0xacee5842,0xd4a20524,0x48d9aa99 },
wolfSSL 16:8e0d178b1d1e 23541 { 0x0da5e57a,0xcff7a74c,0xe549d6c9,0xc232593c,0xf0f2287b,0x68504bcc,
wolfSSL 16:8e0d178b1d1e 23542 0xbc8360b5,0x6d7d098d,0x5b402f41,0xeac5f149,0xb87d1bf1,0x61936f11 } },
wolfSSL 16:8e0d178b1d1e 23543 /* 168 */
wolfSSL 16:8e0d178b1d1e 23544 { { 0xb8153a9d,0xaa9da167,0x9e83ecf0,0xa49fe3ac,0x1b661384,0x14c18f8e,
wolfSSL 16:8e0d178b1d1e 23545 0x38434de1,0x61c24dab,0x283dae96,0x3d973c3a,0x82754fc9,0xc99baa01 },
wolfSSL 16:8e0d178b1d1e 23546 { 0x4c26b1e3,0x477d198f,0xa7516202,0x12e8e186,0x362addfa,0x386e52f6,
wolfSSL 16:8e0d178b1d1e 23547 0xc3962853,0x31e8f695,0x6aaedb60,0xdec2af13,0x29cf74ac,0xfcfdb4c6 } },
wolfSSL 16:8e0d178b1d1e 23548 /* 169 */
wolfSSL 16:8e0d178b1d1e 23549 { { 0xcca40298,0x6b3ee958,0xf2f5d195,0xc3878153,0xed2eae5b,0x0c565630,
wolfSSL 16:8e0d178b1d1e 23550 0x3a697cf2,0xd089b37e,0xad5029ea,0xc2ed2ac7,0x0f0dda6a,0x7e5cdfad },
wolfSSL 16:8e0d178b1d1e 23551 { 0xd9b86202,0xf98426df,0x4335e054,0xed1960b1,0x3f14639e,0x1fdb0246,
wolfSSL 16:8e0d178b1d1e 23552 0x0db6c670,0x17f709c3,0x773421e1,0xbfc687ae,0x26c1a8ac,0x13fefc4a } },
wolfSSL 16:8e0d178b1d1e 23553 /* 170 */
wolfSSL 16:8e0d178b1d1e 23554 { { 0x7ffa0a5f,0xe361a198,0xc63fe109,0xf4b26102,0x6c74e111,0x264acbc5,
wolfSSL 16:8e0d178b1d1e 23555 0x77abebaf,0x4af445fa,0x24cddb75,0x448c4fdd,0x44506eea,0x0b13157d },
wolfSSL 16:8e0d178b1d1e 23556 { 0x72e9993d,0x22a6b159,0x85e5ecbe,0x2c3c57e4,0xfd83e1a1,0xa673560b,
wolfSSL 16:8e0d178b1d1e 23557 0xc3b8c83b,0x6be23f82,0x40bbe38e,0x40b13a96,0xad17399b,0x66eea033 } },
wolfSSL 16:8e0d178b1d1e 23558 /* 171 */
wolfSSL 16:8e0d178b1d1e 23559 { { 0xb4c6c693,0x49fc6e95,0x36af7d38,0xefc735de,0x35fe42fc,0xe053343d,
wolfSSL 16:8e0d178b1d1e 23560 0x6a9ab7c3,0xf0aa427c,0x4a0fcb24,0xc79f0436,0x93ebbc50,0x16287243 },
wolfSSL 16:8e0d178b1d1e 23561 { 0x16927e1e,0x5c3d6bd0,0x673b984c,0x40158ed2,0x4cd48b9a,0xa7f86fc8,
wolfSSL 16:8e0d178b1d1e 23562 0x60ea282d,0x1643eda6,0xe2a1beed,0x45b393ea,0x19571a94,0x664c839e } },
wolfSSL 16:8e0d178b1d1e 23563 /* 172 */
wolfSSL 16:8e0d178b1d1e 23564 { { 0x27eeaf94,0x57745750,0xea99e1e7,0x2875c925,0x5086adea,0xc127e7ba,
wolfSSL 16:8e0d178b1d1e 23565 0x86fe424f,0x765252a0,0x2b6c0281,0x1143cc6c,0xd671312d,0xc9bb2989 },
wolfSSL 16:8e0d178b1d1e 23566 { 0x51acb0a5,0x880c337c,0xd3c60f78,0xa3710915,0x9262b6ed,0x496113c0,
wolfSSL 16:8e0d178b1d1e 23567 0x9ce48182,0x5d25d9f8,0xb3813586,0x53b6ad72,0x4c0e159c,0x0ea3bebc } },
wolfSSL 16:8e0d178b1d1e 23568 /* 173 */
wolfSSL 16:8e0d178b1d1e 23569 { { 0xc5e49bea,0xcaba450a,0x7c05da59,0x684e5415,0xde7ac36c,0xa2e9cab9,
wolfSSL 16:8e0d178b1d1e 23570 0x2e6f957b,0x4ca79b5f,0x09b817b1,0xef7b0247,0x7d89df0f,0xeb304990 },
wolfSSL 16:8e0d178b1d1e 23571 { 0x46fe5096,0x508f7307,0x2e04eaaf,0x695810e8,0x3512f76c,0x88ef1bd9,
wolfSSL 16:8e0d178b1d1e 23572 0x3ebca06b,0x77661351,0xccf158b7,0xf7d4863a,0x94ee57da,0xb2a81e44 } },
wolfSSL 16:8e0d178b1d1e 23573 /* 174 */
wolfSSL 16:8e0d178b1d1e 23574 { { 0x6d53e6ba,0xff288e5b,0x14484ea2,0xa90de1a9,0xed33c8ec,0x2fadb60c,
wolfSSL 16:8e0d178b1d1e 23575 0x28b66a40,0x579d6ef3,0xec24372d,0x4f2dd6dd,0x1d66ec7d,0xe9e33fc9 },
wolfSSL 16:8e0d178b1d1e 23576 { 0x039eab6e,0x110899d2,0x3e97bb5e,0xa31a667a,0xcfdce68e,0x6200166d,
wolfSSL 16:8e0d178b1d1e 23577 0x5137d54b,0xbe83ebae,0x4800acdf,0x085f7d87,0x0c6f8c86,0xcf4ab133 } },
wolfSSL 16:8e0d178b1d1e 23578 /* 175 */
wolfSSL 16:8e0d178b1d1e 23579 { { 0x931e08fb,0x03f65845,0x1506e2c0,0x6438551e,0x9c36961f,0x5791f0dc,
wolfSSL 16:8e0d178b1d1e 23580 0xe3dcc916,0x68107b29,0xf495d2ca,0x83242374,0x6ee5895b,0xd8cfb663 },
wolfSSL 16:8e0d178b1d1e 23581 { 0xa0349b1b,0x525e0f16,0x4a0fab86,0x33cd2c6c,0x2af8dda9,0x46c12ee8,
wolfSSL 16:8e0d178b1d1e 23582 0x71e97ad3,0x7cc424ba,0x37621eb0,0x69766ddf,0xa5f0d390,0x95565f56 } },
wolfSSL 16:8e0d178b1d1e 23583 /* 176 */
wolfSSL 16:8e0d178b1d1e 23584 { { 0x1a0f5e94,0xe0e7bbf2,0x1d82d327,0xf771e115,0xceb111fa,0x10033e3d,
wolfSSL 16:8e0d178b1d1e 23585 0xd3426638,0xd269744d,0x00d01ef6,0xbdf2d9da,0xa049ceaf,0x1cb80c71 },
wolfSSL 16:8e0d178b1d1e 23586 { 0x9e21c677,0x17f18328,0x19c8f98b,0x6452af05,0x80b67997,0x35b9c5f7,
wolfSSL 16:8e0d178b1d1e 23587 0x40f8f3d4,0x5c2e1cbe,0x66d667ca,0x43f91656,0xcf9d6e79,0x9faaa059 } },
wolfSSL 16:8e0d178b1d1e 23588 /* 177 */
wolfSSL 16:8e0d178b1d1e 23589 { { 0x0a078fe6,0x8ad24618,0x464fd1dd,0xf6cc73e6,0xc3e37448,0x4d2ce34d,
wolfSSL 16:8e0d178b1d1e 23590 0xe3271b5f,0x624950c5,0xefc5af72,0x62910f5e,0xaa132bc6,0x8b585bf8 },
wolfSSL 16:8e0d178b1d1e 23591 { 0xa839327f,0x11723985,0x4aac252f,0x34e2d27d,0x6296cc4e,0x402f59ef,
wolfSSL 16:8e0d178b1d1e 23592 0x47053de9,0x00ae055c,0x28b4f09b,0xfc22a972,0xfa0c180e,0xa9e86264 } },
wolfSSL 16:8e0d178b1d1e 23593 /* 178 */
wolfSSL 16:8e0d178b1d1e 23594 { { 0xbc310ecc,0x0b7b6224,0x67fa14ed,0x8a1a74f1,0x7214395c,0x87dd0960,
wolfSSL 16:8e0d178b1d1e 23595 0xf5c91128,0xdf1b3d09,0x86b264a8,0x39ff23c6,0x3e58d4c5,0xdc2d49d0 },
wolfSSL 16:8e0d178b1d1e 23596 { 0xa9d6f501,0x2152b7d3,0xc04094f7,0xf4c32e24,0xd938990f,0xc6366596,
wolfSSL 16:8e0d178b1d1e 23597 0x94fb207f,0x084d078f,0x328594cb,0xfd99f1d7,0xcb2d96b3,0x36defa64 } },
wolfSSL 16:8e0d178b1d1e 23598 /* 179 */
wolfSSL 16:8e0d178b1d1e 23599 { { 0x13ed7cbe,0x4619b781,0x9784bd0e,0x95e50015,0x2c7705fe,0x2a32251c,
wolfSSL 16:8e0d178b1d1e 23600 0x5f0dd083,0xa376af99,0x0361a45b,0x55425c6c,0x1f291e7b,0x812d2cef },
wolfSSL 16:8e0d178b1d1e 23601 { 0x5fd94972,0xccf581a0,0xe56dc383,0x26e20e39,0x63dbfbf0,0x0093685d,
wolfSSL 16:8e0d178b1d1e 23602 0x36b8c575,0x1fc164cc,0x390ef5e7,0xb9c5ab81,0x26908c66,0x40086beb } },
wolfSSL 16:8e0d178b1d1e 23603 /* 180 */
wolfSSL 16:8e0d178b1d1e 23604 { { 0x37e3c115,0xe5e54f79,0xc1445a8a,0x69b8ee8c,0xb7659709,0x79aedff2,
wolfSSL 16:8e0d178b1d1e 23605 0x1b46fbe6,0xe288e163,0xd18d7bb7,0xdb4844f0,0x48aa6424,0xe0ea23d0 },
wolfSSL 16:8e0d178b1d1e 23606 { 0xf3d80a73,0x714c0e4e,0x3bd64f98,0x87a0aa9e,0x2ec63080,0x8844b8a8,
wolfSSL 16:8e0d178b1d1e 23607 0x255d81a3,0xe0ac9c30,0x455397fc,0x86151237,0x2f820155,0x0b979464 } },
wolfSSL 16:8e0d178b1d1e 23608 /* 181 */
wolfSSL 16:8e0d178b1d1e 23609 { { 0x4ae03080,0x127a255a,0x580a89fb,0x232306b4,0x6416f539,0x04e8cd6a,
wolfSSL 16:8e0d178b1d1e 23610 0x13b02a0e,0xaeb70dee,0x4c09684a,0xa3038cf8,0x28e433ee,0xa710ec3c },
wolfSSL 16:8e0d178b1d1e 23611 { 0x681b1f7d,0x77a72567,0x2fc28170,0x86fbce95,0xf5735ac8,0xd3408683,
wolfSSL 16:8e0d178b1d1e 23612 0x6bd68e93,0x3a324e2a,0xc027d155,0x7ec74353,0xd4427177,0xab60354c } },
wolfSSL 16:8e0d178b1d1e 23613 /* 182 */
wolfSSL 16:8e0d178b1d1e 23614 { { 0xef4c209d,0x32a5342a,0x08d62704,0x2ba75274,0xc825d5fe,0x4bb4af6f,
wolfSSL 16:8e0d178b1d1e 23615 0xd28e7ff1,0x1c3919ce,0xde0340f6,0x1dfc2fdc,0x29f33ba9,0xc6580baf },
wolfSSL 16:8e0d178b1d1e 23616 { 0x41d442cb,0xae121e75,0x3a4724e4,0x4c7727fd,0x524f3474,0xe556d6a4,
wolfSSL 16:8e0d178b1d1e 23617 0x785642a2,0x87e13cc7,0xa17845fd,0x182efbb1,0x4e144857,0xdcec0cf1 } },
wolfSSL 16:8e0d178b1d1e 23618 /* 183 */
wolfSSL 16:8e0d178b1d1e 23619 { { 0xe9539819,0x1cb89541,0x9d94dbf1,0xc8cb3b4f,0x417da578,0x1d353f63,
wolfSSL 16:8e0d178b1d1e 23620 0x8053a09e,0xb7a697fb,0xc35d8b78,0x8d841731,0xb656a7a9,0x85748d6f },
wolfSSL 16:8e0d178b1d1e 23621 { 0xc1859c5d,0x1fd03947,0x535d22a2,0x6ce965c1,0x0ca3aadc,0x1966a13e,
wolfSSL 16:8e0d178b1d1e 23622 0x4fb14eff,0x9802e41d,0x76dd3fcd,0xa9048cbb,0xe9455bba,0x89b182b5 } },
wolfSSL 16:8e0d178b1d1e 23623 /* 184 */
wolfSSL 16:8e0d178b1d1e 23624 { { 0x43360710,0xd777ad6a,0x55e9936b,0x841287ef,0x04a21b24,0xbaf5c670,
wolfSSL 16:8e0d178b1d1e 23625 0x35ad86f1,0xf2c0725f,0xc707e72e,0x338fa650,0xd8883e52,0x2bf8ed2e },
wolfSSL 16:8e0d178b1d1e 23626 { 0xb56e0d6a,0xb0212cf4,0x6843290c,0x50537e12,0x98b3dc6f,0xd8b184a1,
wolfSSL 16:8e0d178b1d1e 23627 0x0210b722,0xd2be9a35,0x559781ee,0x407406db,0x0bc18534,0x5a78d591 } },
wolfSSL 16:8e0d178b1d1e 23628 /* 185 */
wolfSSL 16:8e0d178b1d1e 23629 { { 0xd748b02c,0x4d57aa2a,0xa12b3b95,0xbe5b3451,0x64711258,0xadca7a45,
wolfSSL 16:8e0d178b1d1e 23630 0x322153db,0x597e091a,0x32eb1eab,0xf3271006,0x2873f301,0xbd9adcba },
wolfSSL 16:8e0d178b1d1e 23631 { 0x38543f7f,0xd1dc79d1,0x921b1fef,0x00022092,0x1e5df8ed,0x86db3ef5,
wolfSSL 16:8e0d178b1d1e 23632 0x9e6b944a,0x888cae04,0x791a32b4,0x71bd29ec,0xa6d1c13e,0xd3516206 } },
wolfSSL 16:8e0d178b1d1e 23633 /* 186 */
wolfSSL 16:8e0d178b1d1e 23634 { { 0x55924f43,0x2ef6b952,0x4f9de8d5,0xd2f401ae,0xadc68042,0xfc73e8d7,
wolfSSL 16:8e0d178b1d1e 23635 0x0d9d1bb4,0x627ea70c,0xbbf35679,0xc3bb3e3e,0xd882dee4,0x7e8a254a },
wolfSSL 16:8e0d178b1d1e 23636 { 0xb5924407,0x08906f50,0xa1ad444a,0xf14a0e61,0x65f3738e,0xaa0efa21,
wolfSSL 16:8e0d178b1d1e 23637 0xae71f161,0xd60c7dd6,0xf175894d,0x9e8390fa,0x149f4c00,0xd115cd20 } },
wolfSSL 16:8e0d178b1d1e 23638 /* 187 */
wolfSSL 16:8e0d178b1d1e 23639 { { 0xa52abf77,0x2f2e2c1d,0x54232568,0xc2a0dca5,0x54966dcc,0xed423ea2,
wolfSSL 16:8e0d178b1d1e 23640 0xcd0dd039,0xe48c93c7,0x176405c7,0x1e54a225,0x70d58f2e,0x1efb5b16 },
wolfSSL 16:8e0d178b1d1e 23641 { 0x94fb1471,0xa751f9d9,0x67d2941d,0xfdb31e1f,0x53733698,0xa6c74eb2,
wolfSSL 16:8e0d178b1d1e 23642 0x89a0f64a,0xd3155d11,0xa4b8d2b6,0x4414cfe4,0xf7a8e9e3,0x8d5a4be8 } },
wolfSSL 16:8e0d178b1d1e 23643 /* 188 */
wolfSSL 16:8e0d178b1d1e 23644 { { 0x52669e98,0x5c96b4d4,0x8fd42a03,0x4547f922,0xd285174e,0xcf5c1319,
wolfSSL 16:8e0d178b1d1e 23645 0x064bffa0,0x805cd1ae,0x246d27e7,0x50e8bc4f,0xd5781e11,0xf89ef98f },
wolfSSL 16:8e0d178b1d1e 23646 { 0xdee0b63f,0xb4ff95f6,0x222663a4,0xad850047,0x4d23ce9c,0x02691860,
wolfSSL 16:8e0d178b1d1e 23647 0x50019f59,0x3e5309ce,0x69a508ae,0x27e6f722,0x267ba52c,0xe9376652 } },
wolfSSL 16:8e0d178b1d1e 23648 /* 189 */
wolfSSL 16:8e0d178b1d1e 23649 { { 0xc0368708,0xa04d289c,0x5e306e1d,0xc458872f,0x33112fea,0x76fa23de,
wolfSSL 16:8e0d178b1d1e 23650 0x6efde42e,0x718e3974,0x1d206091,0xf0c98cdc,0x14a71987,0x5fa3ca62 },
wolfSSL 16:8e0d178b1d1e 23651 { 0xdcaa9f2a,0xeee8188b,0x589a860d,0x312cc732,0xc63aeb1f,0xf9808dd6,
wolfSSL 16:8e0d178b1d1e 23652 0x4ea62b53,0x70fd43db,0x890b6e97,0x2c2bfe34,0xfa426aa6,0x105f863c } },
wolfSSL 16:8e0d178b1d1e 23653 /* 190 */
wolfSSL 16:8e0d178b1d1e 23654 { { 0xb38059ad,0x0b29795d,0x90647ea0,0x5686b77e,0xdb473a3e,0xeff0470e,
wolfSSL 16:8e0d178b1d1e 23655 0xf9b6d1e2,0x278d2340,0xbd594ec7,0xebbff95b,0xd3a7f23d,0xf4b72334 },
wolfSSL 16:8e0d178b1d1e 23656 { 0xa5a83f0b,0x2a285980,0x9716a8b3,0x0786c41a,0x22511812,0x138901bd,
wolfSSL 16:8e0d178b1d1e 23657 0xe2fede6e,0xd1b55221,0xdf4eb590,0x0806e264,0x762e462e,0x6c4c897e } },
wolfSSL 16:8e0d178b1d1e 23658 /* 191 */
wolfSSL 16:8e0d178b1d1e 23659 { { 0xb4b41d9d,0xd10b905f,0x4523a65b,0x826ca466,0xb699fa37,0x535bbd13,
wolfSSL 16:8e0d178b1d1e 23660 0x73bc8f90,0x5b9933d7,0xcd2118ad,0x9332d61f,0xd4a65fd0,0x158c693e },
wolfSSL 16:8e0d178b1d1e 23661 { 0xe6806e63,0x4ddfb2a8,0xb5de651b,0xe31ed3ec,0x819bc69a,0xf9460e51,
wolfSSL 16:8e0d178b1d1e 23662 0x2c76b1f8,0x6229c0d6,0x901970a3,0xbb78f231,0x9cee72b8,0x31f3820f } },
wolfSSL 16:8e0d178b1d1e 23663 /* 192 */
wolfSSL 16:8e0d178b1d1e 23664 { { 0xc09e1c72,0xe931caf2,0x12990cf4,0x0715f298,0x943262d8,0x33aad81d,
wolfSSL 16:8e0d178b1d1e 23665 0x73048d3f,0x5d292b7a,0xdc7415f6,0xb152aaa4,0x0fd19587,0xc3d10fd9 },
wolfSSL 16:8e0d178b1d1e 23666 { 0x75ddadd0,0xf76b35c5,0x1e7b694c,0x9f5f4a51,0xc0663025,0x2f1ab7eb,
wolfSSL 16:8e0d178b1d1e 23667 0x920260b0,0x01c9cc87,0x05d39da6,0xc4b1f61a,0xeb4a9c4e,0x6dcd76c4 } },
wolfSSL 16:8e0d178b1d1e 23668 /* 193 */
wolfSSL 16:8e0d178b1d1e 23669 { { 0xfdc83f01,0x0ba0916f,0x9553e4f9,0x354c8b44,0xffc5e622,0xa6cc511a,
wolfSSL 16:8e0d178b1d1e 23670 0xe95be787,0xb954726a,0x75b41a62,0xcb048115,0xebfde989,0xfa2ae6cd },
wolfSSL 16:8e0d178b1d1e 23671 { 0x0f24659a,0x6376bbc7,0x4c289c43,0x13a999fd,0xec9abd8b,0xc7134184,
wolfSSL 16:8e0d178b1d1e 23672 0xa789ab04,0x28c02bf6,0xd3e526ec,0xff841ebc,0x640893a8,0x442b191e } },
wolfSSL 16:8e0d178b1d1e 23673 /* 194 */
wolfSSL 16:8e0d178b1d1e 23674 { { 0xfa2b6e20,0x4cac6c62,0xf6d69861,0x97f29e9b,0xbc96d12d,0x228ab1db,
wolfSSL 16:8e0d178b1d1e 23675 0x5e8e108d,0x6eb91327,0x40771245,0xd4b3d4d1,0xca8a803a,0x61b20623 },
wolfSSL 16:8e0d178b1d1e 23676 { 0xa6a560b1,0x2c2f3b41,0x3859fcf4,0x879e1d40,0x024dbfc3,0x7cdb5145,
wolfSSL 16:8e0d178b1d1e 23677 0x3bfa5315,0x55d08f15,0xaa93823a,0x2f57d773,0xc6a2c9a2,0xa97f259c } },
wolfSSL 16:8e0d178b1d1e 23678 /* 195 */
wolfSSL 16:8e0d178b1d1e 23679 { { 0xe58edbbb,0xc306317b,0x79dfdf13,0x25ade51c,0x16d83dd6,0x6b5beaf1,
wolfSSL 16:8e0d178b1d1e 23680 0x1dd8f925,0xe8038a44,0xb2a87b6b,0x7f00143c,0xf5b438de,0xa885d00d },
wolfSSL 16:8e0d178b1d1e 23681 { 0xcf9e48bd,0xe9f76790,0xa5162768,0xf0bdf9f0,0xad7b57cb,0x0436709f,
wolfSSL 16:8e0d178b1d1e 23682 0xf7c15db7,0x7e151c12,0x5d90ee3b,0x3514f022,0x2c361a8d,0x2e84e803 } },
wolfSSL 16:8e0d178b1d1e 23683 /* 196 */
wolfSSL 16:8e0d178b1d1e 23684 { { 0x563ec8d8,0x2277607d,0xe3934cb7,0xa661811f,0xf58fd5de,0x3ca72e7a,
wolfSSL 16:8e0d178b1d1e 23685 0x62294c6a,0x7989da04,0xf6bbefe9,0x88b3708b,0x53ed7c82,0x0d524cf7 },
wolfSSL 16:8e0d178b1d1e 23686 { 0x2f30c073,0x69f699ca,0x9dc1dcf3,0xf0fa264b,0x05f0aaf6,0x44ca4568,
wolfSSL 16:8e0d178b1d1e 23687 0xd19b9baf,0x0f5b23c7,0xeabd1107,0x39193f41,0x2a7c9b83,0x9e3e10ad } },
wolfSSL 16:8e0d178b1d1e 23688 /* 197 */
wolfSSL 16:8e0d178b1d1e 23689 { { 0xd4ae972f,0xa90824f0,0xc6e846e7,0x43eef02b,0x29d2160a,0x7e460612,
wolfSSL 16:8e0d178b1d1e 23690 0xfe604e91,0x29a178ac,0x4eb184b2,0x23056f04,0xeb54cdf4,0x4fcad55f },
wolfSSL 16:8e0d178b1d1e 23691 { 0xae728d15,0xa0ff96f3,0xc6a00331,0x8a2680c6,0x7ee52556,0x5f84cae0,
wolfSSL 16:8e0d178b1d1e 23692 0xc5a65dad,0x5e462c3a,0xe2d23f4f,0x5d2b81df,0xc5b1eb07,0x6e47301b } },
wolfSSL 16:8e0d178b1d1e 23693 /* 198 */
wolfSSL 16:8e0d178b1d1e 23694 { { 0xaf8219b9,0x77411d68,0x51b1907a,0xcb883ce6,0x101383b5,0x25c87e57,
wolfSSL 16:8e0d178b1d1e 23695 0x982f970d,0x9c7d9859,0x118305d2,0xaa6abca5,0x9013a5db,0x725fed2f },
wolfSSL 16:8e0d178b1d1e 23696 { 0xababd109,0x487cdbaf,0x87586528,0xc0f8cf56,0x8ad58254,0xa02591e6,
wolfSSL 16:8e0d178b1d1e 23697 0xdebbd526,0xc071b1d1,0x961e7e31,0x927dfe8b,0x9263dfe1,0x55f895f9 } },
wolfSSL 16:8e0d178b1d1e 23698 /* 199 */
wolfSSL 16:8e0d178b1d1e 23699 { { 0xb175645b,0xf899b00d,0xb65b4b92,0x51f3a627,0xb67399ef,0xa2f3ac8d,
wolfSSL 16:8e0d178b1d1e 23700 0xe400bc20,0xe717867f,0x1967b952,0x42cc9020,0x3ecd1de1,0x3d596751 },
wolfSSL 16:8e0d178b1d1e 23701 { 0xdb979775,0xd41ebcde,0x6a2e7e88,0x99ba61bc,0x321504f2,0x039149a5,
wolfSSL 16:8e0d178b1d1e 23702 0x27ba2fad,0xe7dc2314,0xb57d8368,0x9f556308,0x57da80a7,0x2b6d16c9 } },
wolfSSL 16:8e0d178b1d1e 23703 /* 200 */
wolfSSL 16:8e0d178b1d1e 23704 { { 0x279ad982,0x84af5e76,0x9c8b81a6,0x9bb4c92d,0x0e698e67,0xd79ad44e,
wolfSSL 16:8e0d178b1d1e 23705 0x265fc167,0xe8be9048,0x0c3a4ccc,0xf135f7e6,0xb8863a33,0xa0a10d38 },
wolfSSL 16:8e0d178b1d1e 23706 { 0xd386efd9,0xe197247c,0xb52346c2,0x0eefd3f9,0x78607bc8,0xc22415f9,
wolfSSL 16:8e0d178b1d1e 23707 0x508674ce,0xa2a8f862,0xc8c9d607,0xa72ad09e,0x50fa764f,0xcd9f0ede } },
wolfSSL 16:8e0d178b1d1e 23708 /* 201 */
wolfSSL 16:8e0d178b1d1e 23709 { { 0xd1a46d4d,0x063391c7,0x9eb01693,0x2df51c11,0x849e83de,0xc5849800,
wolfSSL 16:8e0d178b1d1e 23710 0x8ad08382,0x48fd09aa,0xaa742736,0xa405d873,0xe1f9600c,0xee49e61e },
wolfSSL 16:8e0d178b1d1e 23711 { 0x48c76f73,0xd76676be,0x01274b2a,0xd9c100f6,0x83f8718d,0x110bb67c,
wolfSSL 16:8e0d178b1d1e 23712 0x02fc0d73,0xec85a420,0x744656ad,0xc0449e1e,0x37d9939b,0x28ce7376 } },
wolfSSL 16:8e0d178b1d1e 23713 /* 202 */
wolfSSL 16:8e0d178b1d1e 23714 { { 0x44544ac7,0x97e9af72,0xba010426,0xf2c658d5,0xfb3adfbd,0x732dec39,
wolfSSL 16:8e0d178b1d1e 23715 0xa2df0b07,0xd12faf91,0x2171e208,0x8ac26725,0x5b24fa54,0xf820cdc8 },
wolfSSL 16:8e0d178b1d1e 23716 { 0x94f4cf77,0x307a6eea,0x944a33c6,0x18c783d2,0x0b741ac5,0x4b939d4c,
wolfSSL 16:8e0d178b1d1e 23717 0x3ffbb6e4,0x1d7acd15,0x7a255e44,0x06a24858,0xce336d50,0x14fbc494 } },
wolfSSL 16:8e0d178b1d1e 23718 /* 203 */
wolfSSL 16:8e0d178b1d1e 23719 { { 0x51584e3c,0x9b920c0c,0xf7e54027,0xc7733c59,0x88422bbe,0xe24ce139,
wolfSSL 16:8e0d178b1d1e 23720 0x523bd6ab,0x11ada812,0xb88e6def,0xde068800,0xfe8c582d,0x7b872671 },
wolfSSL 16:8e0d178b1d1e 23721 { 0x7de53510,0x4e746f28,0xf7971968,0x492f8b99,0x7d928ac2,0x1ec80bc7,
wolfSSL 16:8e0d178b1d1e 23722 0x432eb1b5,0xb3913e48,0x32028f6e,0xad084866,0x8fc2f38b,0x122bb835 } },
wolfSSL 16:8e0d178b1d1e 23723 /* 204 */
wolfSSL 16:8e0d178b1d1e 23724 { { 0x3b0b29c3,0x0a9f3b1e,0x4fa44151,0x837b6432,0x17b28ea7,0xb9905c92,
wolfSSL 16:8e0d178b1d1e 23725 0x98451750,0xf39bc937,0xce8b6da1,0xcd383c24,0x010620b2,0x299f57db },
wolfSSL 16:8e0d178b1d1e 23726 { 0x58afdce3,0x7b6ac396,0x3d05ef47,0xa15206b3,0xb9bb02ff,0xa0ae37e2,
wolfSSL 16:8e0d178b1d1e 23727 0x9db3964c,0x107760ab,0x67954bea,0xe29de9a0,0x431c3f82,0x446a1ad8 } },
wolfSSL 16:8e0d178b1d1e 23728 /* 205 */
wolfSSL 16:8e0d178b1d1e 23729 { { 0x5c6b8195,0xc6fecea0,0xf49e71b9,0xd744a7c5,0x177a7ae7,0xa8e96acc,
wolfSSL 16:8e0d178b1d1e 23730 0x358773a7,0x1a05746c,0x37567369,0xa4162146,0x87d1c971,0xaa0217f7 },
wolfSSL 16:8e0d178b1d1e 23731 { 0x77fd3226,0x61e9d158,0xe4f600be,0x0f6f2304,0x7a6dff07,0xa9c4cebc,
wolfSSL 16:8e0d178b1d1e 23732 0x09f12a24,0xd15afa01,0x8c863ee9,0x2bbadb22,0xe5eb8c78,0xa28290e4 } },
wolfSSL 16:8e0d178b1d1e 23733 /* 206 */
wolfSSL 16:8e0d178b1d1e 23734 { { 0x3e9de330,0x55b87fa0,0x195c145b,0x12b26066,0xa920bef0,0xe08536e0,
wolfSSL 16:8e0d178b1d1e 23735 0x4d195adc,0x7bff6f2c,0x945f4187,0x7f319e9d,0xf892ce47,0xf9848863 },
wolfSSL 16:8e0d178b1d1e 23736 { 0x4fe37657,0xd0efc1d3,0x5cf0e45a,0x3c58de82,0x8b0ccbbe,0x626ad21a,
wolfSSL 16:8e0d178b1d1e 23737 0xaf952fc5,0xd2a31208,0xeb437357,0x81791995,0x98e95d4f,0x5f19d30f } },
wolfSSL 16:8e0d178b1d1e 23738 /* 207 */
wolfSSL 16:8e0d178b1d1e 23739 { { 0x0e6865bb,0x72e83d9a,0xf63456a6,0x22f5af3b,0x463c8d9e,0x409e9c73,
wolfSSL 16:8e0d178b1d1e 23740 0xdfe6970e,0x40e9e578,0x711b91ca,0x876b6efa,0x942625a3,0x895512cf },
wolfSSL 16:8e0d178b1d1e 23741 { 0xcb4e462b,0x84c8eda8,0x4412e7c8,0x84c0154a,0xceb7b71f,0x04325db1,
wolfSSL 16:8e0d178b1d1e 23742 0x66f70877,0x1537dde3,0x1992b9ac,0xf3a09399,0xd498ae77,0xa7316606 } },
wolfSSL 16:8e0d178b1d1e 23743 /* 208 */
wolfSSL 16:8e0d178b1d1e 23744 { { 0xcad260f5,0x13990d2f,0xeec0e8c0,0x76c3be29,0x0f7bd7d5,0x7dc5bee0,
wolfSSL 16:8e0d178b1d1e 23745 0xefebda4b,0x9be167d2,0x9122b87e,0xcce3dde6,0x82b5415c,0x75a28b09 },
wolfSSL 16:8e0d178b1d1e 23746 { 0xe84607a6,0xf6810bcd,0x6f4dbf0d,0xc6d58128,0x1b4dafeb,0xfead577d,
wolfSSL 16:8e0d178b1d1e 23747 0x066b28eb,0x9bc440b2,0x8b17e84b,0x53f1da97,0xcda9a575,0x0459504b } },
wolfSSL 16:8e0d178b1d1e 23748 /* 209 */
wolfSSL 16:8e0d178b1d1e 23749 { { 0x329e5836,0x13e39a02,0xf717269d,0x2c9e7d51,0xf26c963b,0xc5ac58d6,
wolfSSL 16:8e0d178b1d1e 23750 0x79967bf5,0x3b0c6c43,0x55908d9d,0x60bbea3f,0xf07c9ad1,0xd84811e7 },
wolfSSL 16:8e0d178b1d1e 23751 { 0x5bd20e4a,0xfe7609a7,0x0a70baa8,0xe4325dd2,0xb3600386,0x3711f370,
wolfSSL 16:8e0d178b1d1e 23752 0xd0924302,0x97f9562f,0x4acc4436,0x040dc0c3,0xde79cdd4,0xfd6d725c } },
wolfSSL 16:8e0d178b1d1e 23753 /* 210 */
wolfSSL 16:8e0d178b1d1e 23754 { { 0xcf13eafb,0xb3efd0e3,0x5aa0ae5f,0x21009cbb,0x79022279,0xe480c553,
wolfSSL 16:8e0d178b1d1e 23755 0xb2fc9a6d,0x755cf334,0x07096ae7,0x8564a5bf,0xbd238139,0xddd649d0 },
wolfSSL 16:8e0d178b1d1e 23756 { 0x8a045041,0xd0de10b1,0xc957d572,0x6e05b413,0x4e0fb25c,0x5c5ff806,
wolfSSL 16:8e0d178b1d1e 23757 0x641162fb,0xd933179b,0xe57439f9,0x42d48485,0x8a8d72aa,0x70c5bd0a } },
wolfSSL 16:8e0d178b1d1e 23758 /* 211 */
wolfSSL 16:8e0d178b1d1e 23759 { { 0x97bdf646,0xa7671738,0xab329f7c,0xaa1485b4,0xf8f25fdf,0xce3e11d6,
wolfSSL 16:8e0d178b1d1e 23760 0xc6221824,0x76a3fc7e,0xf3924740,0x045f281f,0x96d13a9a,0x24557d4e },
wolfSSL 16:8e0d178b1d1e 23761 { 0xdd4c27cd,0x875c804b,0x0f5c7fea,0x11c5f0f4,0xdc55ff7e,0xac8c880b,
wolfSSL 16:8e0d178b1d1e 23762 0x1103f101,0x2acddec5,0xf99faa89,0x38341a21,0xce9d6b57,0xc7b67a2c } },
wolfSSL 16:8e0d178b1d1e 23763 /* 212 */
wolfSSL 16:8e0d178b1d1e 23764 { { 0x8e357586,0x9a0d724f,0xdf648da0,0x1d7f4ff5,0xfdee62a5,0x9c3e6c9b,
wolfSSL 16:8e0d178b1d1e 23765 0x0389b372,0x0499cef0,0x98eab879,0xe904050d,0x6c051617,0xe8eef1b6 },
wolfSSL 16:8e0d178b1d1e 23766 { 0xc37e3ca9,0xebf5bfeb,0xa4e0b91d,0x7c5e946d,0x2c4bea28,0x79097314,
wolfSSL 16:8e0d178b1d1e 23767 0xee67b2b7,0x81f6c109,0xdafc5ede,0xaf237d9b,0x2abb04c7,0xd2e60201 } },
wolfSSL 16:8e0d178b1d1e 23768 /* 213 */
wolfSSL 16:8e0d178b1d1e 23769 { { 0x8a4f57bf,0x6156060c,0xff11182a,0xf9758696,0x6296ef00,0x8336773c,
wolfSSL 16:8e0d178b1d1e 23770 0xff666899,0x9c054bce,0x719cd11c,0xd6a11611,0xdbe1acfa,0x9824a641 },
wolfSSL 16:8e0d178b1d1e 23771 { 0xba89fd01,0x0b7b7a5f,0x889f79d8,0xf8d3b809,0xf578285c,0xc5e1ea08,
wolfSSL 16:8e0d178b1d1e 23772 0xae6d8288,0x7ac74536,0x7521ef5f,0x5d37a200,0xb260a25d,0x5ecc4184 } },
wolfSSL 16:8e0d178b1d1e 23773 /* 214 */
wolfSSL 16:8e0d178b1d1e 23774 { { 0xa708c8d3,0xddcebb19,0xc63f81ec,0xe63ed04f,0x11873f95,0xd045f5a0,
wolfSSL 16:8e0d178b1d1e 23775 0x79f276d5,0x3b5ad544,0x425ae5b3,0x81272a3d,0x10ce1605,0x8bfeb501 },
wolfSSL 16:8e0d178b1d1e 23776 { 0x888228bf,0x4233809c,0xb2aff7df,0x4bd82acf,0x0cbd4a7f,0x9c68f180,
wolfSSL 16:8e0d178b1d1e 23777 0x6b44323d,0xfcd77124,0x891db957,0x60c0fcf6,0x04da8f7f,0xcfbb4d89 } },
wolfSSL 16:8e0d178b1d1e 23778 /* 215 */
wolfSSL 16:8e0d178b1d1e 23779 { { 0x3b26139a,0x9a6a5df9,0xb2cc7eb8,0x3e076a83,0x5a964bcd,0x47a8e82d,
wolfSSL 16:8e0d178b1d1e 23780 0xb9278d6b,0x8a4e2a39,0xe4443549,0x93506c98,0xf1e0d566,0x06497a8f },
wolfSSL 16:8e0d178b1d1e 23781 { 0x2b1efa05,0x3dee8d99,0x45393e33,0x2da63ca8,0xcf0579ad,0xa4af7277,
wolfSSL 16:8e0d178b1d1e 23782 0x3236d8ea,0xaf4b4639,0x32b617f5,0x6ccad95b,0xb88bb124,0xce76d8b8 } },
wolfSSL 16:8e0d178b1d1e 23783 /* 216 */
wolfSSL 16:8e0d178b1d1e 23784 { { 0x083843dc,0x63d2537a,0x1e4153b4,0x89eb3514,0xea9afc94,0x5175ebc4,
wolfSSL 16:8e0d178b1d1e 23785 0x8ed1aed7,0x7a652580,0xd85e8297,0x67295611,0xb584b73d,0x8dd2d68b },
wolfSSL 16:8e0d178b1d1e 23786 { 0x0133c3a4,0x237139e6,0x4bd278ea,0x9de838ab,0xc062fcd9,0xe829b072,
wolfSSL 16:8e0d178b1d1e 23787 0x63ba8706,0x70730d4f,0xd3cd05ec,0x6080483f,0x0c85f84d,0x872ab5b8 } },
wolfSSL 16:8e0d178b1d1e 23788 /* 217 */
wolfSSL 16:8e0d178b1d1e 23789 { { 0x999d4d49,0xfc0776d3,0xec3f45e7,0xa3eb59de,0x0dae1fc1,0xbc990e44,
wolfSSL 16:8e0d178b1d1e 23790 0xa15371ff,0x33596b1e,0x9bc7ab25,0xd447dcb2,0x35979582,0xcd5b63e9 },
wolfSSL 16:8e0d178b1d1e 23791 { 0x77d1ff11,0xae3366fa,0xedee6903,0x59f28f05,0xa4433bf2,0x6f43fed1,
wolfSSL 16:8e0d178b1d1e 23792 0xdf9ce00e,0x15409c9b,0xaca9c5dc,0x21b5cded,0x82d7bdb4,0xf9f33595 } },
wolfSSL 16:8e0d178b1d1e 23793 /* 218 */
wolfSSL 16:8e0d178b1d1e 23794 { { 0x9422c792,0x95944378,0xc958b8bf,0x239ea923,0xdf076541,0x4b61a247,
wolfSSL 16:8e0d178b1d1e 23795 0xbb9fc544,0x4d29ce85,0x0b424559,0x9a692a67,0x0e486900,0x6e0ca5a0 },
wolfSSL 16:8e0d178b1d1e 23796 { 0x85b3bece,0x6b79a782,0xc61f9892,0x41f35e39,0xae747f82,0xff82099a,
wolfSSL 16:8e0d178b1d1e 23797 0xd0ca59d6,0x58c8ae3f,0x99406b5f,0x4ac930e2,0x9df24243,0x2ce04eb9 } },
wolfSSL 16:8e0d178b1d1e 23798 /* 219 */
wolfSSL 16:8e0d178b1d1e 23799 { { 0x1ac37b82,0x4366b994,0x25b04d83,0xff0c728d,0x19c47b7c,0x1f551361,
wolfSSL 16:8e0d178b1d1e 23800 0xbeff13e7,0xdbf2d5ed,0xe12a683d,0xf78efd51,0x989cf9c4,0x82cd85b9 },
wolfSSL 16:8e0d178b1d1e 23801 { 0xe0cb5d37,0xe23c6db6,0x72ee1a15,0x818aeebd,0x28771b14,0x8212aafd,
wolfSSL 16:8e0d178b1d1e 23802 0x1def817d,0x7bc221d9,0x9445c51f,0xdac403a2,0x12c3746b,0x711b0517 } },
wolfSSL 16:8e0d178b1d1e 23803 /* 220 */
wolfSSL 16:8e0d178b1d1e 23804 { { 0x5ea99ecc,0x0ed9ed48,0xb8cab5e1,0xf799500d,0xb570cbdc,0xa8ec87dc,
wolfSSL 16:8e0d178b1d1e 23805 0xd35dfaec,0x52cfb2c2,0x6e4d80a4,0x8d31fae2,0xdcdeabe5,0xe6a37dc9 },
wolfSSL 16:8e0d178b1d1e 23806 { 0x1deca452,0x5d365a34,0x0d68b44e,0x09a5f8a5,0xa60744b1,0x59238ea5,
wolfSSL 16:8e0d178b1d1e 23807 0xbb4249e9,0xf2fedc0d,0xa909b2e3,0xe395c74e,0x39388250,0xe156d1a5 } },
wolfSSL 16:8e0d178b1d1e 23808 /* 221 */
wolfSSL 16:8e0d178b1d1e 23809 { { 0x47181ae9,0xd796b3d0,0x44197808,0xbaf44ba8,0x34cf3fac,0xe6933094,
wolfSSL 16:8e0d178b1d1e 23810 0xc3bd5c46,0x41aa6ade,0xeed947c6,0x4fda75d8,0x9ea5a525,0xacd9d412 },
wolfSSL 16:8e0d178b1d1e 23811 { 0xd430301b,0x65cc55a3,0x7b52ea49,0x3c9a5bcf,0x159507f0,0x22d319cf,
wolfSSL 16:8e0d178b1d1e 23812 0xde74a8dd,0x2ee0b9b5,0x877ac2b6,0x20c26a1e,0x92e7c314,0x387d73da } },
wolfSSL 16:8e0d178b1d1e 23813 /* 222 */
wolfSSL 16:8e0d178b1d1e 23814 { { 0x8cd3fdac,0x13c4833e,0x332e5b8e,0x76fcd473,0xe2fe1fd3,0xff671b4b,
wolfSSL 16:8e0d178b1d1e 23815 0x5d98d8ec,0x4d734e8b,0x514bbc11,0xb1ead3c6,0x7b390494,0xd14ca858 },
wolfSSL 16:8e0d178b1d1e 23816 { 0x5d2d37e9,0x95a443af,0x00464622,0x73c6ea73,0x15755044,0xa44aeb4b,
wolfSSL 16:8e0d178b1d1e 23817 0xfab58fee,0xba3f8575,0xdc680a6f,0x9779dbc9,0x7b37ddfc,0xe1ee5f5a } },
wolfSSL 16:8e0d178b1d1e 23818 /* 223 */
wolfSSL 16:8e0d178b1d1e 23819 { { 0x12d29f46,0xcd0b4648,0x0ed53137,0x93295b0b,0x80bef6c9,0xbfe26094,
wolfSSL 16:8e0d178b1d1e 23820 0x54248b00,0xa6565788,0x80e7f9c4,0x69c43fca,0xbe141ea1,0x2190837b },
wolfSSL 16:8e0d178b1d1e 23821 { 0xa1b26cfb,0x875e159a,0x7affe852,0x90ca9f87,0x92ca598e,0x15e6550d,
wolfSSL 16:8e0d178b1d1e 23822 0x1938ad11,0xe3e0945d,0x366ef937,0xef7636bb,0xb39869e5,0xb6034d0b } },
wolfSSL 16:8e0d178b1d1e 23823 /* 224 */
wolfSSL 16:8e0d178b1d1e 23824 { { 0x26d8356e,0x4d255e30,0xd314626f,0xf83666ed,0xd0c8ed64,0x421ddf61,
wolfSSL 16:8e0d178b1d1e 23825 0x26677b61,0x96e473c5,0x9e9b18b3,0xdad4af7e,0xa9393f75,0xfceffd4a },
wolfSSL 16:8e0d178b1d1e 23826 { 0x11c731d5,0x843138a1,0xb2f141d9,0x05bcb3a1,0x617b7671,0x20e1fa95,
wolfSSL 16:8e0d178b1d1e 23827 0x88ccec7b,0xbefce812,0x90f1b568,0x582073dc,0x1f055cb7,0xf572261a } },
wolfSSL 16:8e0d178b1d1e 23828 /* 225 */
wolfSSL 16:8e0d178b1d1e 23829 { { 0x36973088,0xf3148277,0x86a9f980,0xc008e708,0xe046c261,0x1b795947,
wolfSSL 16:8e0d178b1d1e 23830 0xca76bca0,0xdf1e6a7d,0x71acddf0,0xabafd886,0x1364d8f4,0xff7054d9 },
wolfSSL 16:8e0d178b1d1e 23831 { 0xe2260594,0x2cf63547,0xd73b277e,0x468a5372,0xef9bd35e,0xc7419e24,
wolfSSL 16:8e0d178b1d1e 23832 0x24043cc3,0x2b4a1c20,0x890b39cd,0xa28f047a,0x46f9a2e3,0xdca2cea1 } },
wolfSSL 16:8e0d178b1d1e 23833 /* 226 */
wolfSSL 16:8e0d178b1d1e 23834 { { 0x53277538,0xab788736,0xcf697738,0xa734e225,0x6b22e2c1,0x66ee1d1e,
wolfSSL 16:8e0d178b1d1e 23835 0xebe1d212,0x2c615389,0x02bb0766,0xf36cad40,0x3e64f207,0x120885c3 },
wolfSSL 16:8e0d178b1d1e 23836 { 0x90fbfec2,0x59e77d56,0xd7a574ae,0xf9e781aa,0x5d045e53,0x801410b0,
wolfSSL 16:8e0d178b1d1e 23837 0xa91b5f0e,0xd3b5f0aa,0x7fbb3521,0xb3d1df00,0xc72bee9a,0x11c4b33e } },
wolfSSL 16:8e0d178b1d1e 23838 /* 227 */
wolfSSL 16:8e0d178b1d1e 23839 { { 0x83c3a7f3,0xd32b9832,0x88d8a354,0x8083abcf,0x50f4ec5a,0xdeb16404,
wolfSSL 16:8e0d178b1d1e 23840 0x641e2907,0x18d747f0,0xf1bbf03e,0x4e8978ae,0x88a0cd89,0x932447dc },
wolfSSL 16:8e0d178b1d1e 23841 { 0xcf3d5897,0x561e0feb,0x13600e6d,0xfc3a682f,0xd16a6b73,0xc78b9d73,
wolfSSL 16:8e0d178b1d1e 23842 0xd29bf580,0xe713fede,0x08d69e5c,0x0a225223,0x1ff7fda4,0x3a924a57 } },
wolfSSL 16:8e0d178b1d1e 23843 /* 228 */
wolfSSL 16:8e0d178b1d1e 23844 { { 0xb4093bee,0xfb64554c,0xa58c6ec0,0xa6d65a25,0x43d0ed37,0x4126994d,
wolfSSL 16:8e0d178b1d1e 23845 0x55152d44,0xa5689a51,0x284caa8d,0xb8e5ea8c,0xd1f25538,0x33f05d4f },
wolfSSL 16:8e0d178b1d1e 23846 { 0x1b615d6e,0xe0fdfe09,0x705507da,0x2ded7e8f,0x17bbcc80,0xdd5631e5,
wolfSSL 16:8e0d178b1d1e 23847 0x267fd11f,0x4f87453e,0xff89d62d,0xc6da723f,0xe3cda21d,0x55cbcae2 } },
wolfSSL 16:8e0d178b1d1e 23848 /* 229 */
wolfSSL 16:8e0d178b1d1e 23849 { { 0x6b4e84f3,0x336bc94e,0x4ef72c35,0x72863031,0xeeb57f99,0x6d85fdee,
wolfSSL 16:8e0d178b1d1e 23850 0xa42ece1b,0x7f4e3272,0x36f0320a,0x7f86cbb5,0x923331e6,0xf09b6a2b },
wolfSSL 16:8e0d178b1d1e 23851 { 0x56778435,0x21d3ecf1,0x8323b2d2,0x2977ba99,0x1704bc0f,0x6a1b57fb,
wolfSSL 16:8e0d178b1d1e 23852 0x389f048a,0xd777cf8b,0xac6b42cd,0x9ce2174f,0x09e6c55a,0x404e2bff } },
wolfSSL 16:8e0d178b1d1e 23853 /* 230 */
wolfSSL 16:8e0d178b1d1e 23854 { { 0x204c5ddb,0x9b9b135e,0x3eff550e,0x9dbfe044,0xec3be0f6,0x35eab4bf,
wolfSSL 16:8e0d178b1d1e 23855 0x0a43e56f,0x8b4c3f0d,0x0e73f9b3,0x4c1c6673,0x2c78c905,0x92ed38bd },
wolfSSL 16:8e0d178b1d1e 23856 { 0xa386e27c,0xc7003f6a,0xaced8507,0xb9c4f46f,0x59df5464,0xea024ec8,
wolfSSL 16:8e0d178b1d1e 23857 0x429572ea,0x4af96152,0xe1fc1194,0x279cd5e2,0x281e358c,0xaa376a03 } },
wolfSSL 16:8e0d178b1d1e 23858 /* 231 */
wolfSSL 16:8e0d178b1d1e 23859 { { 0x3cdbc95c,0x07859223,0xef2e337a,0xaae1aa6a,0x472a8544,0xc040108d,
wolfSSL 16:8e0d178b1d1e 23860 0x8d037b7d,0x80c853e6,0x8c7eee24,0xd221315c,0x8ee47752,0x195d3856 },
wolfSSL 16:8e0d178b1d1e 23861 { 0xdacd7fbe,0xd4b1ba03,0xd3e0c52b,0x4b5ac61e,0x6aab7b52,0x68d3c052,
wolfSSL 16:8e0d178b1d1e 23862 0x660e3fea,0xf0d7248c,0x3145efb4,0xafdb3f89,0x8f40936d,0xa73fd9a3 } },
wolfSSL 16:8e0d178b1d1e 23863 /* 232 */
wolfSSL 16:8e0d178b1d1e 23864 { { 0xbb1b17ce,0x891b9ef3,0xc6127f31,0x14023667,0x305521fd,0x12b2e58d,
wolfSSL 16:8e0d178b1d1e 23865 0xe3508088,0x3a47e449,0xff751507,0xe49fc84b,0x5310d16e,0x4023f722 },
wolfSSL 16:8e0d178b1d1e 23866 { 0xb73399fa,0xa608e5ed,0xd532aa3e,0xf12632d8,0x845e8415,0x13a2758e,
wolfSSL 16:8e0d178b1d1e 23867 0x1fc2d861,0xae4b6f85,0x339d02f2,0x3879f5b1,0x80d99ebd,0x446d22a6 } },
wolfSSL 16:8e0d178b1d1e 23868 /* 233 */
wolfSSL 16:8e0d178b1d1e 23869 { { 0x4be164f1,0x0f502302,0x88b81920,0x8d09d2d6,0x984aceff,0x514056f1,
wolfSSL 16:8e0d178b1d1e 23870 0x75e9e80d,0xa5c4ddf0,0xdf496a93,0x38cb47e6,0x38df6bf7,0x899e1d6b },
wolfSSL 16:8e0d178b1d1e 23871 { 0xb59eb2a6,0x69e87e88,0x9b47f38b,0x280d9d63,0x3654e955,0x599411ea,
wolfSSL 16:8e0d178b1d1e 23872 0x969aa581,0xcf8dd4fd,0x530742a7,0xff5c2baf,0x1a373085,0xa4391536 } },
wolfSSL 16:8e0d178b1d1e 23873 /* 234 */
wolfSSL 16:8e0d178b1d1e 23874 { { 0xa8a4bdd2,0x6ace72a3,0xb68ef702,0xc656cdd1,0x90c4dad8,0xd4a33e7e,
wolfSSL 16:8e0d178b1d1e 23875 0x9d951c50,0x4aece08a,0x085d68e6,0xea8005ae,0x6f7502b8,0xfdd7a7d7 },
wolfSSL 16:8e0d178b1d1e 23876 { 0x98d6fa45,0xce6fb0a6,0x1104eb8c,0x228f8672,0xda09d7dc,0xd23d8787,
wolfSSL 16:8e0d178b1d1e 23877 0x2ae93065,0x5521428b,0xea56c366,0x95faba3d,0x0a88aca5,0xedbe5039 } },
wolfSSL 16:8e0d178b1d1e 23878 /* 235 */
wolfSSL 16:8e0d178b1d1e 23879 { { 0xbfb26c82,0xd64da0ad,0x952c2f9c,0xe5d70b3c,0xf7e77f68,0xf5e8f365,
wolfSSL 16:8e0d178b1d1e 23880 0x08f2d695,0x7234e002,0xd12e7be6,0xfaf900ee,0x4acf734e,0x27dc6934 },
wolfSSL 16:8e0d178b1d1e 23881 { 0xc260a46a,0x80e4ff5e,0x2dc31c28,0x7da5ebce,0xca69f552,0x485c5d73,
wolfSSL 16:8e0d178b1d1e 23882 0x69cc84c2,0xcdfb6b29,0xed6d4eca,0x031c5afe,0x22247637,0xc7bbf4c8 } },
wolfSSL 16:8e0d178b1d1e 23883 /* 236 */
wolfSSL 16:8e0d178b1d1e 23884 { { 0x49fe01b2,0x9d5b72c7,0x793a91b8,0x34785186,0xcf460438,0xa3ba3c54,
wolfSSL 16:8e0d178b1d1e 23885 0x3ab21b6f,0x73e8e43d,0xbe57b8ab,0x50cde8e0,0xdd204264,0x6488b3a7 },
wolfSSL 16:8e0d178b1d1e 23886 { 0xdddc4582,0xa9e398b3,0x5bec46fe,0x1698c1a9,0x156d3843,0x7f1446ef,
wolfSSL 16:8e0d178b1d1e 23887 0x770329a2,0x3fd25dd8,0x2c710668,0x05b1221a,0xa72ee6cf,0x65b2dc2a } },
wolfSSL 16:8e0d178b1d1e 23888 /* 237 */
wolfSSL 16:8e0d178b1d1e 23889 { { 0xcd021d63,0x21a885f7,0xfea61f08,0x3f344b15,0xc5cf73e6,0xad5ba6dd,
wolfSSL 16:8e0d178b1d1e 23890 0x227a8b23,0x154d0d8f,0xdc559311,0x9b74373c,0x98620fa1,0x4feab715 },
wolfSSL 16:8e0d178b1d1e 23891 { 0x7d9ec924,0x5098938e,0x6d47e550,0x84d54a5e,0x1b617506,0x1a2d1bdc,
wolfSSL 16:8e0d178b1d1e 23892 0x615868a4,0x99fe1782,0x3005a924,0x171da780,0x7d8f79b6,0xa70bf5ed } },
wolfSSL 16:8e0d178b1d1e 23893 /* 238 */
wolfSSL 16:8e0d178b1d1e 23894 { { 0xfe2216c5,0x0bc1250d,0x7601b351,0x2c37e250,0xd6f06b7e,0xb6300175,
wolfSSL 16:8e0d178b1d1e 23895 0x8bfeb9b7,0x4dde8ca1,0xb82f843d,0x4f210432,0xb1ac0afd,0x8d70e2f9 },
wolfSSL 16:8e0d178b1d1e 23896 { 0xaae91abb,0x25c73b78,0x863028f2,0x0230dca3,0xe5cf30b7,0x8b923ecf,
wolfSSL 16:8e0d178b1d1e 23897 0x5506f265,0xed754ec2,0x729a5e39,0x8e41b88c,0xbabf889b,0xee67cec2 } },
wolfSSL 16:8e0d178b1d1e 23898 /* 239 */
wolfSSL 16:8e0d178b1d1e 23899 { { 0x1be46c65,0xe183acf5,0xe7565d7a,0x9789538f,0xd9627b4e,0x87873391,
wolfSSL 16:8e0d178b1d1e 23900 0x9f1d9187,0xbf4ac4c1,0x4691f5c8,0x5db99f63,0x74a1fb98,0xa68df803 },
wolfSSL 16:8e0d178b1d1e 23901 { 0xbf92b5fa,0x3c448ed1,0x3e0bdc32,0xa098c841,0x79bf016c,0x8e74cd55,
wolfSSL 16:8e0d178b1d1e 23902 0x115e244d,0x5df0d09c,0x3410b66e,0x9418ad01,0x17a02130,0x8b6124cb } },
wolfSSL 16:8e0d178b1d1e 23903 /* 240 */
wolfSSL 16:8e0d178b1d1e 23904 { { 0xc26e3392,0x425ec3af,0xa1722e00,0xc07f8470,0xe2356b43,0xdcc28190,
wolfSSL 16:8e0d178b1d1e 23905 0xb1ef59a6,0x4ed97dff,0xc63028c1,0xc22b3ad1,0x68c18988,0x070723c2 },
wolfSSL 16:8e0d178b1d1e 23906 { 0x4cf49e7d,0x70da302f,0x3f12a522,0xc5e87c93,0x18594148,0x74acdd1d,
wolfSSL 16:8e0d178b1d1e 23907 0xca74124c,0xad5f73ab,0xd69fd478,0xe72e4a3e,0x7b117cc3,0x61593868 } },
wolfSSL 16:8e0d178b1d1e 23908 /* 241 */
wolfSSL 16:8e0d178b1d1e 23909 { { 0xa9aa0486,0x7b7b9577,0xa063d557,0x6e41fb35,0xda9047d7,0xb017d5c7,
wolfSSL 16:8e0d178b1d1e 23910 0x68a87ba9,0x8c748280,0xdf08ad93,0xab45fa5c,0x4c288a28,0xcd9fb217 },
wolfSSL 16:8e0d178b1d1e 23911 { 0x5747843d,0x59544642,0xa56111e3,0x34d64c6c,0x4bfce8d5,0x12e47ea1,
wolfSSL 16:8e0d178b1d1e 23912 0x6169267f,0x17740e05,0xeed03fb5,0x5c49438e,0x4fc3f513,0x9da30add } },
wolfSSL 16:8e0d178b1d1e 23913 /* 242 */
wolfSSL 16:8e0d178b1d1e 23914 { { 0xccfa5200,0xc4e85282,0x6a19b13d,0x2707608f,0xf5726e2f,0xdcb9a53d,
wolfSSL 16:8e0d178b1d1e 23915 0xe9427de5,0x612407c9,0xd54d582a,0x3e5a17e1,0x655ae118,0xb99877de },
wolfSSL 16:8e0d178b1d1e 23916 { 0x015254de,0x6f0e972b,0xf0a6f7c5,0x92a56db1,0xa656f8b2,0xd297e4e1,
wolfSSL 16:8e0d178b1d1e 23917 0xad981983,0x99fe0052,0x07cfed84,0xd3652d2f,0x843c1738,0xc784352e } },
wolfSSL 16:8e0d178b1d1e 23918 /* 243 */
wolfSSL 16:8e0d178b1d1e 23919 { { 0x7e9b2d8a,0x6ee90af0,0x57cf1964,0xac8d7018,0x71f28efc,0xf6ed9031,
wolfSSL 16:8e0d178b1d1e 23920 0x6812b20e,0x7f70d5a9,0xf1c61eee,0x27b557f4,0xc6263758,0xf1c9bd57 },
wolfSSL 16:8e0d178b1d1e 23921 { 0x2a1a6194,0x5cf7d014,0x1890ab84,0xdd614e0b,0x0e93c2a6,0x3ef9de10,
wolfSSL 16:8e0d178b1d1e 23922 0xe0cd91c5,0xf98cf575,0x14befc32,0x504ec0c6,0x6279d68c,0xd0513a66 } },
wolfSSL 16:8e0d178b1d1e 23923 /* 244 */
wolfSSL 16:8e0d178b1d1e 23924 { { 0xa859fb6a,0xa8eadbad,0xdb283666,0xcf8346e7,0x3e22e355,0x7b35e61a,
wolfSSL 16:8e0d178b1d1e 23925 0x99639c6b,0x293ece2c,0x56f241c8,0xfa0162e2,0xbf7a1dda,0xd2e6c7b9 },
wolfSSL 16:8e0d178b1d1e 23926 { 0x40075e63,0xd0de6253,0xf9ec8286,0x2405aa61,0x8fe45494,0x2237830a,
wolfSSL 16:8e0d178b1d1e 23927 0x364e9c8c,0x4fd01ac7,0x904ba750,0x4d9c3d21,0xaf1b520b,0xd589be14 } },
wolfSSL 16:8e0d178b1d1e 23928 /* 245 */
wolfSSL 16:8e0d178b1d1e 23929 { { 0x4662e53b,0x13576a4f,0xf9077676,0x35ec2f51,0x97c0af97,0x66297d13,
wolfSSL 16:8e0d178b1d1e 23930 0x9e598b58,0xed3201fe,0x5e70f604,0x49bc752a,0xbb12d951,0xb54af535 },
wolfSSL 16:8e0d178b1d1e 23931 { 0x212c1c76,0x36ea4c2b,0xeb250dfd,0x18f5bbc7,0x9a0a1a46,0xa0d466cc,
wolfSSL 16:8e0d178b1d1e 23932 0xdac2d917,0x52564da4,0x8e95fab5,0x206559f4,0x9ca67a33,0x7487c190 } },
wolfSSL 16:8e0d178b1d1e 23933 /* 246 */
wolfSSL 16:8e0d178b1d1e 23934 { { 0xdde98e9c,0x75abfe37,0x2a411199,0x99b90b26,0xdcdb1f7c,0x1b410996,
wolfSSL 16:8e0d178b1d1e 23935 0x8b3b5675,0xab346f11,0xf1f8ae1e,0x04852193,0x6b8b98c1,0x1ec4d227 },
wolfSSL 16:8e0d178b1d1e 23936 { 0x45452baa,0xba3bc926,0xacc4a572,0x387d1858,0xe51f171e,0x9478eff6,
wolfSSL 16:8e0d178b1d1e 23937 0x931e1c00,0xf357077d,0xe54c8ca8,0xffee77cd,0x551dc9a4,0xfb4892ff } },
wolfSSL 16:8e0d178b1d1e 23938 /* 247 */
wolfSSL 16:8e0d178b1d1e 23939 { { 0x2db8dff8,0x5b1bdad0,0x5a2285a2,0xd462f4fd,0xda00b461,0x1d6aad8e,
wolfSSL 16:8e0d178b1d1e 23940 0x41306d1b,0x43fbefcf,0x6a13fe19,0x428e86f3,0x17f89404,0xc8b2f118 },
wolfSSL 16:8e0d178b1d1e 23941 { 0xf0d51afb,0x762528aa,0x549b1d06,0xa3e2fea4,0xea3ddf66,0x86fad8f2,
wolfSSL 16:8e0d178b1d1e 23942 0x4fbdd206,0x0d9ccc4b,0xc189ff5a,0xcde97d4c,0x199f19a6,0xc36793d6 } },
wolfSSL 16:8e0d178b1d1e 23943 /* 248 */
wolfSSL 16:8e0d178b1d1e 23944 { { 0x51b85197,0xea38909b,0xb4c92895,0xffb17dd0,0x1ddb3f3f,0x0eb0878b,
wolfSSL 16:8e0d178b1d1e 23945 0xc57cf0f2,0xb05d28ff,0x1abd57e2,0xd8bde2e7,0xc40c1b20,0x7f2be28d },
wolfSSL 16:8e0d178b1d1e 23946 { 0x299a2d48,0x6554dca2,0x8377982d,0x5130ba2e,0x1071971a,0x8863205f,
wolfSSL 16:8e0d178b1d1e 23947 0x7cf2825d,0x15ee6282,0x03748f2b,0xd4b6c57f,0x430385a0,0xa9e3f4da } },
wolfSSL 16:8e0d178b1d1e 23948 /* 249 */
wolfSSL 16:8e0d178b1d1e 23949 { { 0x83fbc9c6,0x33eb7cec,0x4541777e,0x24a311c7,0x4f0767fc,0xc81377f7,
wolfSSL 16:8e0d178b1d1e 23950 0x4ab702da,0x12adae36,0x2a779696,0xb7fcb6db,0x01cea6ad,0x4a6fb284 },
wolfSSL 16:8e0d178b1d1e 23951 { 0xcdfc73de,0x5e8b1d2a,0x1b02fd32,0xd0efae8d,0xd81d8519,0x3f99c190,
wolfSSL 16:8e0d178b1d1e 23952 0xfc808971,0x3c18f7fa,0x51b7ae7b,0x41f713e7,0xf07fc3f8,0x0a4b3435 } },
wolfSSL 16:8e0d178b1d1e 23953 /* 250 */
wolfSSL 16:8e0d178b1d1e 23954 { { 0x019b7d2e,0x7dda3c4c,0xd4dc4b89,0x631c8d1a,0x1cdb313c,0x5489cd6e,
wolfSSL 16:8e0d178b1d1e 23955 0x4c07bb06,0xd44aed10,0x75f000d1,0x8f97e13a,0xdda5df4d,0x0e9ee64f },
wolfSSL 16:8e0d178b1d1e 23956 { 0x3e346910,0xeaa99f3b,0xfa294ad7,0x622f6921,0x0d0b2fe9,0x22aaa20d,
wolfSSL 16:8e0d178b1d1e 23957 0x1e5881ba,0x4fed2f99,0xc1571802,0x9af3b2d6,0xdc7ee17c,0x919e67a8 } },
wolfSSL 16:8e0d178b1d1e 23958 /* 251 */
wolfSSL 16:8e0d178b1d1e 23959 { { 0x76250533,0xc724fe4c,0x7d817ef8,0x8a2080e5,0x172c9751,0xa2afb0f4,
wolfSSL 16:8e0d178b1d1e 23960 0x17c0702e,0x9b10cdeb,0xc9b7e3e9,0xbf3975e3,0x1cd0cdc5,0x206117df },
wolfSSL 16:8e0d178b1d1e 23961 { 0xbe05ebd5,0xfb049e61,0x16c782c0,0xeb0bb55c,0xab7fed09,0x13a331b8,
wolfSSL 16:8e0d178b1d1e 23962 0x632863f0,0xf6c58b1d,0x4d3b6195,0x6264ef6e,0x9a53f116,0x92c51b63 } },
wolfSSL 16:8e0d178b1d1e 23963 /* 252 */
wolfSSL 16:8e0d178b1d1e 23964 { { 0x288b364d,0xa57c7bc8,0x7b41e5c4,0x4a562e08,0x698a9a11,0x699d21c6,
wolfSSL 16:8e0d178b1d1e 23965 0xf3f849b9,0xa4ed9581,0x9eb726ba,0xa223eef3,0xcc2884f9,0x13159c23 },
wolfSSL 16:8e0d178b1d1e 23966 { 0x3a3f4963,0x73931e58,0x0ada6a81,0x96500389,0x5ab2950b,0x3ee8a1c6,
wolfSSL 16:8e0d178b1d1e 23967 0x775fab52,0xeedf4949,0x4f2671b6,0x63d652e1,0x3c4e2f55,0xfed4491c } },
wolfSSL 16:8e0d178b1d1e 23968 /* 253 */
wolfSSL 16:8e0d178b1d1e 23969 { { 0xf4eb453e,0x335eadc3,0xcadd1a5b,0x5ff74b63,0x5d84a91a,0x6933d0d7,
wolfSSL 16:8e0d178b1d1e 23970 0xb49ba337,0x9ca3eeb9,0xc04c15b8,0x1f6facce,0xdc09a7e4,0x4ef19326 },
wolfSSL 16:8e0d178b1d1e 23971 { 0x3dca3233,0x53d2d324,0xa2259d4b,0x0ee40590,0x5546f002,0x18c22edb,
wolfSSL 16:8e0d178b1d1e 23972 0x09ea6b71,0x92429801,0xb0e91e61,0xaada0add,0x99963c50,0x5fe53ef4 } },
wolfSSL 16:8e0d178b1d1e 23973 /* 254 */
wolfSSL 16:8e0d178b1d1e 23974 { { 0x90c28c65,0x372dd06b,0x119ce47d,0x1765242c,0x6b22fc82,0xc041fb80,
wolfSSL 16:8e0d178b1d1e 23975 0xb0a7ccc1,0x667edf07,0x1261bece,0xc79599e7,0x19cff22a,0xbc69d9ba },
wolfSSL 16:8e0d178b1d1e 23976 { 0x13c06819,0x009d77cd,0xe282b79d,0x635a66ae,0x225b1be8,0x4edac4a6,
wolfSSL 16:8e0d178b1d1e 23977 0x524008f9,0x57d4f4e4,0xb056af84,0xee299ac5,0x3a0bc386,0xcc38444c } },
wolfSSL 16:8e0d178b1d1e 23978 /* 255 */
wolfSSL 16:8e0d178b1d1e 23979 { { 0xcd4c2356,0x490643b1,0x750547be,0x740a4851,0xd4944c04,0x643eaf29,
wolfSSL 16:8e0d178b1d1e 23980 0x299a98a0,0xba572479,0xee05fdf9,0x48b29f16,0x089b2d7b,0x33fb4f61 },
wolfSSL 16:8e0d178b1d1e 23981 { 0xa950f955,0x86704902,0xfedc3ddf,0x97e1034d,0x05fbb6a2,0x211320b6,
wolfSSL 16:8e0d178b1d1e 23982 0x432299bb,0x23d7b93f,0x8590e4a3,0x1fe1a057,0xf58c0ce6,0x8e1d0586 } },
wolfSSL 16:8e0d178b1d1e 23983 };
wolfSSL 16:8e0d178b1d1e 23984
wolfSSL 16:8e0d178b1d1e 23985 /* Multiply the base point of P384 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 23986 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 23987 *
wolfSSL 16:8e0d178b1d1e 23988 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 23989 * k Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 23990 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 23991 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 23992 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 23993 */
wolfSSL 16:8e0d178b1d1e 23994 static int sp_384_ecc_mulmod_base_12(sp_point_384* r, const sp_digit* k,
wolfSSL 16:8e0d178b1d1e 23995 int map, void* heap)
wolfSSL 16:8e0d178b1d1e 23996 {
wolfSSL 16:8e0d178b1d1e 23997 return sp_384_ecc_mulmod_stripe_12(r, &p384_base, p384_table,
wolfSSL 16:8e0d178b1d1e 23998 k, map, heap);
wolfSSL 16:8e0d178b1d1e 23999 }
wolfSSL 16:8e0d178b1d1e 24000
wolfSSL 16:8e0d178b1d1e 24001 #endif
wolfSSL 16:8e0d178b1d1e 24002
wolfSSL 16:8e0d178b1d1e 24003 /* Multiply the base point of P384 by the scalar and return the result.
wolfSSL 16:8e0d178b1d1e 24004 * If map is true then convert result to affine coordinates.
wolfSSL 16:8e0d178b1d1e 24005 *
wolfSSL 16:8e0d178b1d1e 24006 * km Scalar to multiply by.
wolfSSL 16:8e0d178b1d1e 24007 * r Resulting point.
wolfSSL 16:8e0d178b1d1e 24008 * map Indicates whether to convert result to affine.
wolfSSL 16:8e0d178b1d1e 24009 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 24010 * returns MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 24011 */
wolfSSL 16:8e0d178b1d1e 24012 int sp_ecc_mulmod_base_384(mp_int* km, ecc_point* r, int map, void* heap)
wolfSSL 16:8e0d178b1d1e 24013 {
wolfSSL 16:8e0d178b1d1e 24014 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24015 sp_point_384 p;
wolfSSL 16:8e0d178b1d1e 24016 sp_digit kd[12];
wolfSSL 16:8e0d178b1d1e 24017 #endif
wolfSSL 16:8e0d178b1d1e 24018 sp_point_384* point;
wolfSSL 16:8e0d178b1d1e 24019 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 24020 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 24021
wolfSSL 16:8e0d178b1d1e 24022 err = sp_384_point_new_12(heap, p, point);
wolfSSL 16:8e0d178b1d1e 24023 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24024 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24025 k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap,
wolfSSL 16:8e0d178b1d1e 24026 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 24027 if (k == NULL) {
wolfSSL 16:8e0d178b1d1e 24028 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 24029 }
wolfSSL 16:8e0d178b1d1e 24030 }
wolfSSL 16:8e0d178b1d1e 24031 #else
wolfSSL 16:8e0d178b1d1e 24032 k = kd;
wolfSSL 16:8e0d178b1d1e 24033 #endif
wolfSSL 16:8e0d178b1d1e 24034 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24035 sp_384_from_mp(k, 12, km);
wolfSSL 16:8e0d178b1d1e 24036
wolfSSL 16:8e0d178b1d1e 24037 err = sp_384_ecc_mulmod_base_12(point, k, map, heap);
wolfSSL 16:8e0d178b1d1e 24038 }
wolfSSL 16:8e0d178b1d1e 24039 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24040 err = sp_384_point_to_ecc_point_12(point, r);
wolfSSL 16:8e0d178b1d1e 24041 }
wolfSSL 16:8e0d178b1d1e 24042
wolfSSL 16:8e0d178b1d1e 24043 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24044 if (k != NULL) {
wolfSSL 16:8e0d178b1d1e 24045 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 24046 }
wolfSSL 16:8e0d178b1d1e 24047 #endif
wolfSSL 16:8e0d178b1d1e 24048 sp_384_point_free_12(point, 0, heap);
wolfSSL 16:8e0d178b1d1e 24049
wolfSSL 16:8e0d178b1d1e 24050 return err;
wolfSSL 16:8e0d178b1d1e 24051 }
wolfSSL 16:8e0d178b1d1e 24052
wolfSSL 16:8e0d178b1d1e 24053 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
wolfSSL 16:8e0d178b1d1e 24054 defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 24055 /* Returns 1 if the number of zero.
wolfSSL 16:8e0d178b1d1e 24056 * Implementation is constant time.
wolfSSL 16:8e0d178b1d1e 24057 *
wolfSSL 16:8e0d178b1d1e 24058 * a Number to check.
wolfSSL 16:8e0d178b1d1e 24059 * returns 1 if the number is zero and 0 otherwise.
wolfSSL 16:8e0d178b1d1e 24060 */
wolfSSL 16:8e0d178b1d1e 24061 static int sp_384_iszero_12(const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 24062 {
wolfSSL 16:8e0d178b1d1e 24063 return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] |
wolfSSL 16:8e0d178b1d1e 24064 a[8] | a[9] | a[10] | a[11]) == 0;
wolfSSL 16:8e0d178b1d1e 24065 }
wolfSSL 16:8e0d178b1d1e 24066
wolfSSL 16:8e0d178b1d1e 24067 #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */
wolfSSL 16:8e0d178b1d1e 24068 /* Add 1 to a. (a = a + 1)
wolfSSL 16:8e0d178b1d1e 24069 *
wolfSSL 16:8e0d178b1d1e 24070 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 24071 */
wolfSSL 16:8e0d178b1d1e 24072 SP_NOINLINE static void sp_384_add_one_12(sp_digit* a)
wolfSSL 16:8e0d178b1d1e 24073 {
wolfSSL 16:8e0d178b1d1e 24074 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 24075 "mov r2, #1\n\t"
wolfSSL 16:8e0d178b1d1e 24076 "ldr r1, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 24077 "adds r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24078 "mov r2, #0\n\t"
wolfSSL 16:8e0d178b1d1e 24079 "str r1, [%[a], #0]\n\t"
wolfSSL 16:8e0d178b1d1e 24080 "ldr r1, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 24081 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24082 "str r1, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 24083 "ldr r1, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 24084 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24085 "str r1, [%[a], #8]\n\t"
wolfSSL 16:8e0d178b1d1e 24086 "ldr r1, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 24087 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24088 "str r1, [%[a], #12]\n\t"
wolfSSL 16:8e0d178b1d1e 24089 "ldr r1, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 24090 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24091 "str r1, [%[a], #16]\n\t"
wolfSSL 16:8e0d178b1d1e 24092 "ldr r1, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 24093 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24094 "str r1, [%[a], #20]\n\t"
wolfSSL 16:8e0d178b1d1e 24095 "ldr r1, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 24096 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24097 "str r1, [%[a], #24]\n\t"
wolfSSL 16:8e0d178b1d1e 24098 "ldr r1, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 24099 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24100 "str r1, [%[a], #28]\n\t"
wolfSSL 16:8e0d178b1d1e 24101 "ldr r1, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 24102 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24103 "str r1, [%[a], #32]\n\t"
wolfSSL 16:8e0d178b1d1e 24104 "ldr r1, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 24105 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24106 "str r1, [%[a], #36]\n\t"
wolfSSL 16:8e0d178b1d1e 24107 "ldr r1, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 24108 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24109 "str r1, [%[a], #40]\n\t"
wolfSSL 16:8e0d178b1d1e 24110 "ldr r1, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 24111 "adcs r1, r1, r2\n\t"
wolfSSL 16:8e0d178b1d1e 24112 "str r1, [%[a], #44]\n\t"
wolfSSL 16:8e0d178b1d1e 24113 :
wolfSSL 16:8e0d178b1d1e 24114 : [a] "r" (a)
wolfSSL 16:8e0d178b1d1e 24115 : "memory", "r1", "r2"
wolfSSL 16:8e0d178b1d1e 24116 );
wolfSSL 16:8e0d178b1d1e 24117 }
wolfSSL 16:8e0d178b1d1e 24118
wolfSSL 16:8e0d178b1d1e 24119 /* Read big endian unsigned byte array into r.
wolfSSL 16:8e0d178b1d1e 24120 *
wolfSSL 16:8e0d178b1d1e 24121 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 24122 * size Maximum number of bytes to convert
wolfSSL 16:8e0d178b1d1e 24123 * a Byte array.
wolfSSL 16:8e0d178b1d1e 24124 * n Number of bytes in array to read.
wolfSSL 16:8e0d178b1d1e 24125 */
wolfSSL 16:8e0d178b1d1e 24126 static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n)
wolfSSL 16:8e0d178b1d1e 24127 {
wolfSSL 16:8e0d178b1d1e 24128 int i, j = 0;
wolfSSL 16:8e0d178b1d1e 24129 word32 s = 0;
wolfSSL 16:8e0d178b1d1e 24130
wolfSSL 16:8e0d178b1d1e 24131 r[0] = 0;
wolfSSL 16:8e0d178b1d1e 24132 for (i = n-1; i >= 0; i--) {
wolfSSL 16:8e0d178b1d1e 24133 r[j] |= (((sp_digit)a[i]) << s);
wolfSSL 16:8e0d178b1d1e 24134 if (s >= 24U) {
wolfSSL 16:8e0d178b1d1e 24135 r[j] &= 0xffffffff;
wolfSSL 16:8e0d178b1d1e 24136 s = 32U - s;
wolfSSL 16:8e0d178b1d1e 24137 if (j + 1 >= size) {
wolfSSL 16:8e0d178b1d1e 24138 break;
wolfSSL 16:8e0d178b1d1e 24139 }
wolfSSL 16:8e0d178b1d1e 24140 r[++j] = (sp_digit)a[i] >> s;
wolfSSL 16:8e0d178b1d1e 24141 s = 8U - s;
wolfSSL 16:8e0d178b1d1e 24142 }
wolfSSL 16:8e0d178b1d1e 24143 else {
wolfSSL 16:8e0d178b1d1e 24144 s += 8U;
wolfSSL 16:8e0d178b1d1e 24145 }
wolfSSL 16:8e0d178b1d1e 24146 }
wolfSSL 16:8e0d178b1d1e 24147
wolfSSL 16:8e0d178b1d1e 24148 for (j++; j < size; j++) {
wolfSSL 16:8e0d178b1d1e 24149 r[j] = 0;
wolfSSL 16:8e0d178b1d1e 24150 }
wolfSSL 16:8e0d178b1d1e 24151 }
wolfSSL 16:8e0d178b1d1e 24152
wolfSSL 16:8e0d178b1d1e 24153 /* Generates a scalar that is in the range 1..order-1.
wolfSSL 16:8e0d178b1d1e 24154 *
wolfSSL 16:8e0d178b1d1e 24155 * rng Random number generator.
wolfSSL 16:8e0d178b1d1e 24156 * k Scalar value.
wolfSSL 16:8e0d178b1d1e 24157 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 16:8e0d178b1d1e 24158 * MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 24159 */
wolfSSL 16:8e0d178b1d1e 24160 static int sp_384_ecc_gen_k_12(WC_RNG* rng, sp_digit* k)
wolfSSL 16:8e0d178b1d1e 24161 {
wolfSSL 16:8e0d178b1d1e 24162 int err;
wolfSSL 16:8e0d178b1d1e 24163 byte buf[48];
wolfSSL 16:8e0d178b1d1e 24164
wolfSSL 16:8e0d178b1d1e 24165 do {
wolfSSL 16:8e0d178b1d1e 24166 err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));
wolfSSL 16:8e0d178b1d1e 24167 if (err == 0) {
wolfSSL 16:8e0d178b1d1e 24168 sp_384_from_bin(k, 12, buf, (int)sizeof(buf));
wolfSSL 16:8e0d178b1d1e 24169 if (sp_384_cmp_12(k, p384_order2) < 0) {
wolfSSL 16:8e0d178b1d1e 24170 sp_384_add_one_12(k);
wolfSSL 16:8e0d178b1d1e 24171 break;
wolfSSL 16:8e0d178b1d1e 24172 }
wolfSSL 16:8e0d178b1d1e 24173 }
wolfSSL 16:8e0d178b1d1e 24174 }
wolfSSL 16:8e0d178b1d1e 24175 while (err == 0);
wolfSSL 16:8e0d178b1d1e 24176
wolfSSL 16:8e0d178b1d1e 24177 return err;
wolfSSL 16:8e0d178b1d1e 24178 }
wolfSSL 16:8e0d178b1d1e 24179
wolfSSL 16:8e0d178b1d1e 24180 /* Makes a random EC key pair.
wolfSSL 16:8e0d178b1d1e 24181 *
wolfSSL 16:8e0d178b1d1e 24182 * rng Random number generator.
wolfSSL 16:8e0d178b1d1e 24183 * priv Generated private value.
wolfSSL 16:8e0d178b1d1e 24184 * pub Generated public point.
wolfSSL 16:8e0d178b1d1e 24185 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 24186 * returns ECC_INF_E when the point does not have the correct order, RNG
wolfSSL 16:8e0d178b1d1e 24187 * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 24188 */
wolfSSL 16:8e0d178b1d1e 24189 int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)
wolfSSL 16:8e0d178b1d1e 24190 {
wolfSSL 16:8e0d178b1d1e 24191 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24192 sp_point_384 p;
wolfSSL 16:8e0d178b1d1e 24193 sp_digit kd[12];
wolfSSL 16:8e0d178b1d1e 24194 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 24195 sp_point_384 inf;
wolfSSL 16:8e0d178b1d1e 24196 #endif
wolfSSL 16:8e0d178b1d1e 24197 #endif
wolfSSL 16:8e0d178b1d1e 24198 sp_point_384* point;
wolfSSL 16:8e0d178b1d1e 24199 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 24200 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 24201 sp_point_384* infinity;
wolfSSL 16:8e0d178b1d1e 24202 #endif
wolfSSL 16:8e0d178b1d1e 24203 int err;
wolfSSL 16:8e0d178b1d1e 24204
wolfSSL 16:8e0d178b1d1e 24205 (void)heap;
wolfSSL 16:8e0d178b1d1e 24206
wolfSSL 16:8e0d178b1d1e 24207 err = sp_384_point_new_12(heap, p, point);
wolfSSL 16:8e0d178b1d1e 24208 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 24209 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24210 err = sp_384_point_new_12(heap, inf, infinity);
wolfSSL 16:8e0d178b1d1e 24211 }
wolfSSL 16:8e0d178b1d1e 24212 #endif
wolfSSL 16:8e0d178b1d1e 24213 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24214 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24215 k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap,
wolfSSL 16:8e0d178b1d1e 24216 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 24217 if (k == NULL) {
wolfSSL 16:8e0d178b1d1e 24218 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 24219 }
wolfSSL 16:8e0d178b1d1e 24220 }
wolfSSL 16:8e0d178b1d1e 24221 #else
wolfSSL 16:8e0d178b1d1e 24222 k = kd;
wolfSSL 16:8e0d178b1d1e 24223 #endif
wolfSSL 16:8e0d178b1d1e 24224
wolfSSL 16:8e0d178b1d1e 24225 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24226 err = sp_384_ecc_gen_k_12(rng, k);
wolfSSL 16:8e0d178b1d1e 24227 }
wolfSSL 16:8e0d178b1d1e 24228 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24229 err = sp_384_ecc_mulmod_base_12(point, k, 1, NULL);
wolfSSL 16:8e0d178b1d1e 24230 }
wolfSSL 16:8e0d178b1d1e 24231
wolfSSL 16:8e0d178b1d1e 24232 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 24233 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24234 err = sp_384_ecc_mulmod_12(infinity, point, p384_order, 1, NULL);
wolfSSL 16:8e0d178b1d1e 24235 }
wolfSSL 16:8e0d178b1d1e 24236 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24237 if ((sp_384_iszero_12(point->x) == 0) || (sp_384_iszero_12(point->y) == 0)) {
wolfSSL 16:8e0d178b1d1e 24238 err = ECC_INF_E;
wolfSSL 16:8e0d178b1d1e 24239 }
wolfSSL 16:8e0d178b1d1e 24240 }
wolfSSL 16:8e0d178b1d1e 24241 #endif
wolfSSL 16:8e0d178b1d1e 24242
wolfSSL 16:8e0d178b1d1e 24243 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24244 err = sp_384_to_mp(k, priv);
wolfSSL 16:8e0d178b1d1e 24245 }
wolfSSL 16:8e0d178b1d1e 24246 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24247 err = sp_384_point_to_ecc_point_12(point, pub);
wolfSSL 16:8e0d178b1d1e 24248 }
wolfSSL 16:8e0d178b1d1e 24249
wolfSSL 16:8e0d178b1d1e 24250 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24251 if (k != NULL) {
wolfSSL 16:8e0d178b1d1e 24252 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 24253 }
wolfSSL 16:8e0d178b1d1e 24254 #endif
wolfSSL 16:8e0d178b1d1e 24255 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 16:8e0d178b1d1e 24256 sp_384_point_free_12(infinity, 1, heap);
wolfSSL 16:8e0d178b1d1e 24257 #endif
wolfSSL 16:8e0d178b1d1e 24258 sp_384_point_free_12(point, 1, heap);
wolfSSL 16:8e0d178b1d1e 24259
wolfSSL 16:8e0d178b1d1e 24260 return err;
wolfSSL 16:8e0d178b1d1e 24261 }
wolfSSL 16:8e0d178b1d1e 24262
wolfSSL 16:8e0d178b1d1e 24263 #ifdef HAVE_ECC_DHE
wolfSSL 16:8e0d178b1d1e 24264 /* Write r as big endian to byte array.
wolfSSL 16:8e0d178b1d1e 24265 * Fixed length number of bytes written: 48
wolfSSL 16:8e0d178b1d1e 24266 *
wolfSSL 16:8e0d178b1d1e 24267 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 24268 * a Byte array.
wolfSSL 16:8e0d178b1d1e 24269 */
wolfSSL 16:8e0d178b1d1e 24270 static void sp_384_to_bin(sp_digit* r, byte* a)
wolfSSL 16:8e0d178b1d1e 24271 {
wolfSSL 16:8e0d178b1d1e 24272 int i, j, s = 0, b;
wolfSSL 16:8e0d178b1d1e 24273
wolfSSL 16:8e0d178b1d1e 24274 j = 384 / 8 - 1;
wolfSSL 16:8e0d178b1d1e 24275 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 24276 for (i=0; i<12 && j>=0; i++) {
wolfSSL 16:8e0d178b1d1e 24277 b = 0;
wolfSSL 16:8e0d178b1d1e 24278 /* lint allow cast of mismatch sp_digit and int */
wolfSSL 16:8e0d178b1d1e 24279 a[j--] |= (byte)(r[i] << s); /*lint !e9033*/
wolfSSL 16:8e0d178b1d1e 24280 b += 8 - s;
wolfSSL 16:8e0d178b1d1e 24281 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 24282 break;
wolfSSL 16:8e0d178b1d1e 24283 }
wolfSSL 16:8e0d178b1d1e 24284 while (b < 32) {
wolfSSL 16:8e0d178b1d1e 24285 a[j--] = (byte)(r[i] >> b);
wolfSSL 16:8e0d178b1d1e 24286 b += 8;
wolfSSL 16:8e0d178b1d1e 24287 if (j < 0) {
wolfSSL 16:8e0d178b1d1e 24288 break;
wolfSSL 16:8e0d178b1d1e 24289 }
wolfSSL 16:8e0d178b1d1e 24290 }
wolfSSL 16:8e0d178b1d1e 24291 s = 8 - (b - 32);
wolfSSL 16:8e0d178b1d1e 24292 if (j >= 0) {
wolfSSL 16:8e0d178b1d1e 24293 a[j] = 0;
wolfSSL 16:8e0d178b1d1e 24294 }
wolfSSL 16:8e0d178b1d1e 24295 if (s != 0) {
wolfSSL 16:8e0d178b1d1e 24296 j++;
wolfSSL 16:8e0d178b1d1e 24297 }
wolfSSL 16:8e0d178b1d1e 24298 }
wolfSSL 16:8e0d178b1d1e 24299 }
wolfSSL 16:8e0d178b1d1e 24300
wolfSSL 16:8e0d178b1d1e 24301 /* Multiply the point by the scalar and serialize the X ordinate.
wolfSSL 16:8e0d178b1d1e 24302 * The number is 0 padded to maximum size on output.
wolfSSL 16:8e0d178b1d1e 24303 *
wolfSSL 16:8e0d178b1d1e 24304 * priv Scalar to multiply the point by.
wolfSSL 16:8e0d178b1d1e 24305 * pub Point to multiply.
wolfSSL 16:8e0d178b1d1e 24306 * out Buffer to hold X ordinate.
wolfSSL 16:8e0d178b1d1e 24307 * outLen On entry, size of the buffer in bytes.
wolfSSL 16:8e0d178b1d1e 24308 * On exit, length of data in buffer in bytes.
wolfSSL 16:8e0d178b1d1e 24309 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 24310 * returns BUFFER_E if the buffer is to small for output size,
wolfSSL 16:8e0d178b1d1e 24311 * MEMORY_E when memory allocation fails and MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 24312 */
wolfSSL 16:8e0d178b1d1e 24313 int sp_ecc_secret_gen_384(mp_int* priv, ecc_point* pub, byte* out,
wolfSSL 16:8e0d178b1d1e 24314 word32* outLen, void* heap)
wolfSSL 16:8e0d178b1d1e 24315 {
wolfSSL 16:8e0d178b1d1e 24316 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24317 sp_point_384 p;
wolfSSL 16:8e0d178b1d1e 24318 sp_digit kd[12];
wolfSSL 16:8e0d178b1d1e 24319 #endif
wolfSSL 16:8e0d178b1d1e 24320 sp_point_384* point = NULL;
wolfSSL 16:8e0d178b1d1e 24321 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 24322 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 24323
wolfSSL 16:8e0d178b1d1e 24324 if (*outLen < 48U) {
wolfSSL 16:8e0d178b1d1e 24325 err = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 24326 }
wolfSSL 16:8e0d178b1d1e 24327
wolfSSL 16:8e0d178b1d1e 24328 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24329 err = sp_384_point_new_12(heap, p, point);
wolfSSL 16:8e0d178b1d1e 24330 }
wolfSSL 16:8e0d178b1d1e 24331 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24332 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24333 k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap,
wolfSSL 16:8e0d178b1d1e 24334 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 24335 if (k == NULL)
wolfSSL 16:8e0d178b1d1e 24336 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 24337 }
wolfSSL 16:8e0d178b1d1e 24338 #else
wolfSSL 16:8e0d178b1d1e 24339 k = kd;
wolfSSL 16:8e0d178b1d1e 24340 #endif
wolfSSL 16:8e0d178b1d1e 24341
wolfSSL 16:8e0d178b1d1e 24342 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24343 sp_384_from_mp(k, 12, priv);
wolfSSL 16:8e0d178b1d1e 24344 sp_384_point_from_ecc_point_12(point, pub);
wolfSSL 16:8e0d178b1d1e 24345 err = sp_384_ecc_mulmod_12(point, point, k, 1, heap);
wolfSSL 16:8e0d178b1d1e 24346 }
wolfSSL 16:8e0d178b1d1e 24347 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24348 sp_384_to_bin(point->x, out);
wolfSSL 16:8e0d178b1d1e 24349 *outLen = 48;
wolfSSL 16:8e0d178b1d1e 24350 }
wolfSSL 16:8e0d178b1d1e 24351
wolfSSL 16:8e0d178b1d1e 24352 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24353 if (k != NULL) {
wolfSSL 16:8e0d178b1d1e 24354 XFREE(k, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 24355 }
wolfSSL 16:8e0d178b1d1e 24356 #endif
wolfSSL 16:8e0d178b1d1e 24357 sp_384_point_free_12(point, 0, heap);
wolfSSL 16:8e0d178b1d1e 24358
wolfSSL 16:8e0d178b1d1e 24359 return err;
wolfSSL 16:8e0d178b1d1e 24360 }
wolfSSL 16:8e0d178b1d1e 24361 #endif /* HAVE_ECC_DHE */
wolfSSL 16:8e0d178b1d1e 24362
wolfSSL 16:8e0d178b1d1e 24363 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 24364 #endif
wolfSSL 16:8e0d178b1d1e 24365 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 24366 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 24367 /* Sub b from a into a. (a -= b)
wolfSSL 16:8e0d178b1d1e 24368 *
wolfSSL 16:8e0d178b1d1e 24369 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 24370 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 24371 */
wolfSSL 16:8e0d178b1d1e 24372 SP_NOINLINE static sp_digit sp_384_sub_in_place_12(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 24373 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 24374 {
wolfSSL 16:8e0d178b1d1e 24375 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 24376 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 24377 "mov r8, %[a]\n\t"
wolfSSL 16:8e0d178b1d1e 24378 "add r8, r8, #48\n\t"
wolfSSL 16:8e0d178b1d1e 24379 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 24380 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 24381 "subs r5, r5, %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 24382 "ldr r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 24383 "ldr r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 24384 "ldr r5, [%[b]]\n\t"
wolfSSL 16:8e0d178b1d1e 24385 "ldr r6, [%[b], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 24386 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 24387 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24388 "str r3, [%[a]]\n\t"
wolfSSL 16:8e0d178b1d1e 24389 "str r4, [%[a], #4]\n\t"
wolfSSL 16:8e0d178b1d1e 24390 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 24391 "add %[a], %[a], #8\n\t"
wolfSSL 16:8e0d178b1d1e 24392 "add %[b], %[b], #8\n\t"
wolfSSL 16:8e0d178b1d1e 24393 "cmp %[a], r8\n\t"
wolfSSL 16:8e0d178b1d1e 24394 "bne 1b\n\t"
wolfSSL 16:8e0d178b1d1e 24395 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 24396 :
wolfSSL 16:8e0d178b1d1e 24397 : "memory", "r3", "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 24398 );
wolfSSL 16:8e0d178b1d1e 24399
wolfSSL 16:8e0d178b1d1e 24400 return c;
wolfSSL 16:8e0d178b1d1e 24401 }
wolfSSL 16:8e0d178b1d1e 24402
wolfSSL 16:8e0d178b1d1e 24403 #else
wolfSSL 16:8e0d178b1d1e 24404 /* Sub b from a into r. (r = a - b)
wolfSSL 16:8e0d178b1d1e 24405 *
wolfSSL 16:8e0d178b1d1e 24406 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 24407 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 24408 * b A single precision integer.
wolfSSL 16:8e0d178b1d1e 24409 */
wolfSSL 16:8e0d178b1d1e 24410 SP_NOINLINE static sp_digit sp_384_sub_in_place_12(sp_digit* a,
wolfSSL 16:8e0d178b1d1e 24411 const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 24412 {
wolfSSL 16:8e0d178b1d1e 24413 sp_digit c = 0;
wolfSSL 16:8e0d178b1d1e 24414
wolfSSL 16:8e0d178b1d1e 24415 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 24416 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24417 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 24418 "subs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 24419 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24420 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24421 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24422 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 24423 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 24424 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24425 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24426 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24427 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 24428 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 24429 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24430 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24431 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24432 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 24433 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 24434 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24435 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24436 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24437 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 24438 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 24439 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24440 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24441 "ldm %[a], {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24442 "ldm %[b]!, {r5, r6}\n\t"
wolfSSL 16:8e0d178b1d1e 24443 "sbcs r3, r3, r5\n\t"
wolfSSL 16:8e0d178b1d1e 24444 "sbcs r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24445 "stm %[a]!, {r3, r4}\n\t"
wolfSSL 16:8e0d178b1d1e 24446 "sbc %[c], %[c], %[c]\n\t"
wolfSSL 16:8e0d178b1d1e 24447 : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b)
wolfSSL 16:8e0d178b1d1e 24448 :
wolfSSL 16:8e0d178b1d1e 24449 : "memory", "r3", "r4", "r5", "r6"
wolfSSL 16:8e0d178b1d1e 24450 );
wolfSSL 16:8e0d178b1d1e 24451
wolfSSL 16:8e0d178b1d1e 24452 return c;
wolfSSL 16:8e0d178b1d1e 24453 }
wolfSSL 16:8e0d178b1d1e 24454
wolfSSL 16:8e0d178b1d1e 24455 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 24456 /* Mul a by digit b into r. (r = a * b)
wolfSSL 16:8e0d178b1d1e 24457 *
wolfSSL 16:8e0d178b1d1e 24458 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 24459 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 24460 * b A single precision digit.
wolfSSL 16:8e0d178b1d1e 24461 */
wolfSSL 16:8e0d178b1d1e 24462 SP_NOINLINE static void sp_384_mul_d_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 24463 sp_digit b)
wolfSSL 16:8e0d178b1d1e 24464 {
wolfSSL 16:8e0d178b1d1e 24465 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 24466 "add r9, %[a], #48\n\t"
wolfSSL 16:8e0d178b1d1e 24467 /* A[0] * B */
wolfSSL 16:8e0d178b1d1e 24468 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 24469 "umull r5, r3, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 24470 "mov r4, #0\n\t"
wolfSSL 16:8e0d178b1d1e 24471 "str r5, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 24472 /* A[0] * B - Done */
wolfSSL 16:8e0d178b1d1e 24473 "\n1:\n\t"
wolfSSL 16:8e0d178b1d1e 24474 "mov r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 24475 /* A[] * B */
wolfSSL 16:8e0d178b1d1e 24476 "ldr r6, [%[a]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 24477 "umull r6, r8, r6, %[b]\n\t"
wolfSSL 16:8e0d178b1d1e 24478 "adds r3, r3, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24479 "adcs r4, r4, r8\n\t"
wolfSSL 16:8e0d178b1d1e 24480 "adc r5, r5, #0\n\t"
wolfSSL 16:8e0d178b1d1e 24481 /* A[] * B - Done */
wolfSSL 16:8e0d178b1d1e 24482 "str r3, [%[r]], #4\n\t"
wolfSSL 16:8e0d178b1d1e 24483 "mov r3, r4\n\t"
wolfSSL 16:8e0d178b1d1e 24484 "mov r4, r5\n\t"
wolfSSL 16:8e0d178b1d1e 24485 "cmp %[a], r9\n\t"
wolfSSL 16:8e0d178b1d1e 24486 "blt 1b\n\t"
wolfSSL 16:8e0d178b1d1e 24487 "str r3, [%[r]]\n\t"
wolfSSL 16:8e0d178b1d1e 24488 : [r] "+r" (r), [a] "+r" (a)
wolfSSL 16:8e0d178b1d1e 24489 : [b] "r" (b)
wolfSSL 16:8e0d178b1d1e 24490 : "memory", "r3", "r4", "r5", "r6", "r8", "r9"
wolfSSL 16:8e0d178b1d1e 24491 );
wolfSSL 16:8e0d178b1d1e 24492 }
wolfSSL 16:8e0d178b1d1e 24493
wolfSSL 16:8e0d178b1d1e 24494 /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)
wolfSSL 16:8e0d178b1d1e 24495 *
wolfSSL 16:8e0d178b1d1e 24496 * d1 The high order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 24497 * d0 The low order half of the number to divide.
wolfSSL 16:8e0d178b1d1e 24498 * div The dividend.
wolfSSL 16:8e0d178b1d1e 24499 * returns the result of the division.
wolfSSL 16:8e0d178b1d1e 24500 *
wolfSSL 16:8e0d178b1d1e 24501 * Note that this is an approximate div. It may give an answer 1 larger.
wolfSSL 16:8e0d178b1d1e 24502 */
wolfSSL 16:8e0d178b1d1e 24503 SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1, sp_digit d0,
wolfSSL 16:8e0d178b1d1e 24504 sp_digit div)
wolfSSL 16:8e0d178b1d1e 24505 {
wolfSSL 16:8e0d178b1d1e 24506 sp_digit r = 0;
wolfSSL 16:8e0d178b1d1e 24507
wolfSSL 16:8e0d178b1d1e 24508 __asm__ __volatile__ (
wolfSSL 16:8e0d178b1d1e 24509 "lsr r6, %[div], #16\n\t"
wolfSSL 16:8e0d178b1d1e 24510 "add r6, r6, #1\n\t"
wolfSSL 16:8e0d178b1d1e 24511 "udiv r4, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 24512 "lsl r8, r4, #16\n\t"
wolfSSL 16:8e0d178b1d1e 24513 "umull r4, r5, %[div], r8\n\t"
wolfSSL 16:8e0d178b1d1e 24514 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 24515 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 24516 "udiv r5, %[d1], r6\n\t"
wolfSSL 16:8e0d178b1d1e 24517 "lsl r4, r5, #16\n\t"
wolfSSL 16:8e0d178b1d1e 24518 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 24519 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 24520 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 24521 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 24522 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 24523 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 24524 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24525 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 24526 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 24527 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 24528 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 24529 "lsl r4, %[d1], #16\n\t"
wolfSSL 16:8e0d178b1d1e 24530 "orr r4, r4, %[d0], lsr #16\n\t"
wolfSSL 16:8e0d178b1d1e 24531 "udiv r4, r4, r6\n\t"
wolfSSL 16:8e0d178b1d1e 24532 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 24533 "umull r4, r5, %[div], r4\n\t"
wolfSSL 16:8e0d178b1d1e 24534 "subs %[d0], %[d0], r4\n\t"
wolfSSL 16:8e0d178b1d1e 24535 "sbc %[d1], %[d1], r5\n\t"
wolfSSL 16:8e0d178b1d1e 24536 "udiv r4, %[d0], %[div]\n\t"
wolfSSL 16:8e0d178b1d1e 24537 "add r8, r8, r4\n\t"
wolfSSL 16:8e0d178b1d1e 24538 "mov %[r], r8\n\t"
wolfSSL 16:8e0d178b1d1e 24539 : [r] "+r" (r)
wolfSSL 16:8e0d178b1d1e 24540 : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div)
wolfSSL 16:8e0d178b1d1e 24541 : "r4", "r5", "r6", "r8"
wolfSSL 16:8e0d178b1d1e 24542 );
wolfSSL 16:8e0d178b1d1e 24543 return r;
wolfSSL 16:8e0d178b1d1e 24544 }
wolfSSL 16:8e0d178b1d1e 24545
wolfSSL 16:8e0d178b1d1e 24546 /* AND m into each word of a and store in r.
wolfSSL 16:8e0d178b1d1e 24547 *
wolfSSL 16:8e0d178b1d1e 24548 * r A single precision integer.
wolfSSL 16:8e0d178b1d1e 24549 * a A single precision integer.
wolfSSL 16:8e0d178b1d1e 24550 * m Mask to AND against each digit.
wolfSSL 16:8e0d178b1d1e 24551 */
wolfSSL 16:8e0d178b1d1e 24552 static void sp_384_mask_12(sp_digit* r, const sp_digit* a, sp_digit m)
wolfSSL 16:8e0d178b1d1e 24553 {
wolfSSL 16:8e0d178b1d1e 24554 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 24555 int i;
wolfSSL 16:8e0d178b1d1e 24556
wolfSSL 16:8e0d178b1d1e 24557 for (i=0; i<12; i++) {
wolfSSL 16:8e0d178b1d1e 24558 r[i] = a[i] & m;
wolfSSL 16:8e0d178b1d1e 24559 }
wolfSSL 16:8e0d178b1d1e 24560 #else
wolfSSL 16:8e0d178b1d1e 24561 r[0] = a[0] & m;
wolfSSL 16:8e0d178b1d1e 24562 r[1] = a[1] & m;
wolfSSL 16:8e0d178b1d1e 24563 r[2] = a[2] & m;
wolfSSL 16:8e0d178b1d1e 24564 r[3] = a[3] & m;
wolfSSL 16:8e0d178b1d1e 24565 r[4] = a[4] & m;
wolfSSL 16:8e0d178b1d1e 24566 r[5] = a[5] & m;
wolfSSL 16:8e0d178b1d1e 24567 r[6] = a[6] & m;
wolfSSL 16:8e0d178b1d1e 24568 r[7] = a[7] & m;
wolfSSL 16:8e0d178b1d1e 24569 r[8] = a[8] & m;
wolfSSL 16:8e0d178b1d1e 24570 r[9] = a[9] & m;
wolfSSL 16:8e0d178b1d1e 24571 r[10] = a[10] & m;
wolfSSL 16:8e0d178b1d1e 24572 r[11] = a[11] & m;
wolfSSL 16:8e0d178b1d1e 24573 #endif
wolfSSL 16:8e0d178b1d1e 24574 }
wolfSSL 16:8e0d178b1d1e 24575
wolfSSL 16:8e0d178b1d1e 24576 /* Divide d in a and put remainder into r (m*d + r = a)
wolfSSL 16:8e0d178b1d1e 24577 * m is not calculated as it is not needed at this time.
wolfSSL 16:8e0d178b1d1e 24578 *
wolfSSL 16:8e0d178b1d1e 24579 * a Nmber to be divided.
wolfSSL 16:8e0d178b1d1e 24580 * d Number to divide with.
wolfSSL 16:8e0d178b1d1e 24581 * m Multiplier result.
wolfSSL 16:8e0d178b1d1e 24582 * r Remainder from the division.
wolfSSL 16:8e0d178b1d1e 24583 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 24584 */
wolfSSL 16:8e0d178b1d1e 24585 static WC_INLINE int sp_384_div_12(const sp_digit* a, const sp_digit* d, sp_digit* m,
wolfSSL 16:8e0d178b1d1e 24586 sp_digit* r)
wolfSSL 16:8e0d178b1d1e 24587 {
wolfSSL 16:8e0d178b1d1e 24588 sp_digit t1[24], t2[13];
wolfSSL 16:8e0d178b1d1e 24589 sp_digit div, r1;
wolfSSL 16:8e0d178b1d1e 24590 int i;
wolfSSL 16:8e0d178b1d1e 24591
wolfSSL 16:8e0d178b1d1e 24592 (void)m;
wolfSSL 16:8e0d178b1d1e 24593
wolfSSL 16:8e0d178b1d1e 24594 div = d[11];
wolfSSL 16:8e0d178b1d1e 24595 XMEMCPY(t1, a, sizeof(*t1) * 2 * 12);
wolfSSL 16:8e0d178b1d1e 24596 for (i=11; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 24597 r1 = div_384_word_12(t1[12 + i], t1[12 + i - 1], div);
wolfSSL 16:8e0d178b1d1e 24598
wolfSSL 16:8e0d178b1d1e 24599 sp_384_mul_d_12(t2, d, r1);
wolfSSL 16:8e0d178b1d1e 24600 t1[12 + i] += sp_384_sub_in_place_12(&t1[i], t2);
wolfSSL 16:8e0d178b1d1e 24601 t1[12 + i] -= t2[12];
wolfSSL 16:8e0d178b1d1e 24602 sp_384_mask_12(t2, d, t1[12 + i]);
wolfSSL 16:8e0d178b1d1e 24603 t1[12 + i] += sp_384_add_12(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 24604 sp_384_mask_12(t2, d, t1[12 + i]);
wolfSSL 16:8e0d178b1d1e 24605 t1[12 + i] += sp_384_add_12(&t1[i], &t1[i], t2);
wolfSSL 16:8e0d178b1d1e 24606 }
wolfSSL 16:8e0d178b1d1e 24607
wolfSSL 16:8e0d178b1d1e 24608 r1 = sp_384_cmp_12(t1, d) >= 0;
wolfSSL 16:8e0d178b1d1e 24609 sp_384_cond_sub_12(r, t1, d, (sp_digit)0 - r1);
wolfSSL 16:8e0d178b1d1e 24610
wolfSSL 16:8e0d178b1d1e 24611 return MP_OKAY;
wolfSSL 16:8e0d178b1d1e 24612 }
wolfSSL 16:8e0d178b1d1e 24613
wolfSSL 16:8e0d178b1d1e 24614 /* Reduce a modulo m into r. (r = a mod m)
wolfSSL 16:8e0d178b1d1e 24615 *
wolfSSL 16:8e0d178b1d1e 24616 * r A single precision number that is the reduced result.
wolfSSL 16:8e0d178b1d1e 24617 * a A single precision number that is to be reduced.
wolfSSL 16:8e0d178b1d1e 24618 * m A single precision number that is the modulus to reduce with.
wolfSSL 16:8e0d178b1d1e 24619 * returns MP_OKAY indicating success.
wolfSSL 16:8e0d178b1d1e 24620 */
wolfSSL 16:8e0d178b1d1e 24621 static WC_INLINE int sp_384_mod_12(sp_digit* r, const sp_digit* a, const sp_digit* m)
wolfSSL 16:8e0d178b1d1e 24622 {
wolfSSL 16:8e0d178b1d1e 24623 return sp_384_div_12(a, m, NULL, r);
wolfSSL 16:8e0d178b1d1e 24624 }
wolfSSL 16:8e0d178b1d1e 24625
wolfSSL 16:8e0d178b1d1e 24626 #endif
wolfSSL 16:8e0d178b1d1e 24627 #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)
wolfSSL 16:8e0d178b1d1e 24628 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 24629 /* Order-2 for the P384 curve. */
wolfSSL 16:8e0d178b1d1e 24630 static const uint32_t p384_order_minus_2[12] = {
wolfSSL 16:8e0d178b1d1e 24631 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U,
wolfSSL 16:8e0d178b1d1e 24632 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU
wolfSSL 16:8e0d178b1d1e 24633 };
wolfSSL 16:8e0d178b1d1e 24634 #else
wolfSSL 16:8e0d178b1d1e 24635 /* The low half of the order-2 of the P384 curve. */
wolfSSL 16:8e0d178b1d1e 24636 static const uint32_t p384_order_low[6] = {
wolfSSL 16:8e0d178b1d1e 24637 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U
wolfSSL 16:8e0d178b1d1e 24638
wolfSSL 16:8e0d178b1d1e 24639 };
wolfSSL 16:8e0d178b1d1e 24640 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 24641
wolfSSL 16:8e0d178b1d1e 24642 /* Multiply two number mod the order of P384 curve. (r = a * b mod order)
wolfSSL 16:8e0d178b1d1e 24643 *
wolfSSL 16:8e0d178b1d1e 24644 * r Result of the multiplication.
wolfSSL 16:8e0d178b1d1e 24645 * a First operand of the multiplication.
wolfSSL 16:8e0d178b1d1e 24646 * b Second operand of the multiplication.
wolfSSL 16:8e0d178b1d1e 24647 */
wolfSSL 16:8e0d178b1d1e 24648 static void sp_384_mont_mul_order_12(sp_digit* r, const sp_digit* a, const sp_digit* b)
wolfSSL 16:8e0d178b1d1e 24649 {
wolfSSL 16:8e0d178b1d1e 24650 sp_384_mul_12(r, a, b);
wolfSSL 16:8e0d178b1d1e 24651 sp_384_mont_reduce_order_12(r, p384_order, p384_mp_order);
wolfSSL 16:8e0d178b1d1e 24652 }
wolfSSL 16:8e0d178b1d1e 24653
wolfSSL 16:8e0d178b1d1e 24654 /* Square number mod the order of P384 curve. (r = a * a mod order)
wolfSSL 16:8e0d178b1d1e 24655 *
wolfSSL 16:8e0d178b1d1e 24656 * r Result of the squaring.
wolfSSL 16:8e0d178b1d1e 24657 * a Number to square.
wolfSSL 16:8e0d178b1d1e 24658 */
wolfSSL 16:8e0d178b1d1e 24659 static void sp_384_mont_sqr_order_12(sp_digit* r, const sp_digit* a)
wolfSSL 16:8e0d178b1d1e 24660 {
wolfSSL 16:8e0d178b1d1e 24661 sp_384_sqr_12(r, a);
wolfSSL 16:8e0d178b1d1e 24662 sp_384_mont_reduce_order_12(r, p384_order, p384_mp_order);
wolfSSL 16:8e0d178b1d1e 24663 }
wolfSSL 16:8e0d178b1d1e 24664
wolfSSL 16:8e0d178b1d1e 24665 #ifndef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 24666 /* Square number mod the order of P384 curve a number of times.
wolfSSL 16:8e0d178b1d1e 24667 * (r = a ^ n mod order)
wolfSSL 16:8e0d178b1d1e 24668 *
wolfSSL 16:8e0d178b1d1e 24669 * r Result of the squaring.
wolfSSL 16:8e0d178b1d1e 24670 * a Number to square.
wolfSSL 16:8e0d178b1d1e 24671 */
wolfSSL 16:8e0d178b1d1e 24672 static void sp_384_mont_sqr_n_order_12(sp_digit* r, const sp_digit* a, int n)
wolfSSL 16:8e0d178b1d1e 24673 {
wolfSSL 16:8e0d178b1d1e 24674 int i;
wolfSSL 16:8e0d178b1d1e 24675
wolfSSL 16:8e0d178b1d1e 24676 sp_384_mont_sqr_order_12(r, a);
wolfSSL 16:8e0d178b1d1e 24677 for (i=1; i<n; i++) {
wolfSSL 16:8e0d178b1d1e 24678 sp_384_mont_sqr_order_12(r, r);
wolfSSL 16:8e0d178b1d1e 24679 }
wolfSSL 16:8e0d178b1d1e 24680 }
wolfSSL 16:8e0d178b1d1e 24681 #endif /* !WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 24682
wolfSSL 16:8e0d178b1d1e 24683 /* Invert the number, in Montgomery form, modulo the order of the P384 curve.
wolfSSL 16:8e0d178b1d1e 24684 * (r = 1 / a mod order)
wolfSSL 16:8e0d178b1d1e 24685 *
wolfSSL 16:8e0d178b1d1e 24686 * r Inverse result.
wolfSSL 16:8e0d178b1d1e 24687 * a Number to invert.
wolfSSL 16:8e0d178b1d1e 24688 * td Temporary data.
wolfSSL 16:8e0d178b1d1e 24689 */
wolfSSL 16:8e0d178b1d1e 24690 static void sp_384_mont_inv_order_12(sp_digit* r, const sp_digit* a,
wolfSSL 16:8e0d178b1d1e 24691 sp_digit* td)
wolfSSL 16:8e0d178b1d1e 24692 {
wolfSSL 16:8e0d178b1d1e 24693 #ifdef WOLFSSL_SP_SMALL
wolfSSL 16:8e0d178b1d1e 24694 sp_digit* t = td;
wolfSSL 16:8e0d178b1d1e 24695 int i;
wolfSSL 16:8e0d178b1d1e 24696
wolfSSL 16:8e0d178b1d1e 24697 XMEMCPY(t, a, sizeof(sp_digit) * 12);
wolfSSL 16:8e0d178b1d1e 24698 for (i=382; i>=0; i--) {
wolfSSL 16:8e0d178b1d1e 24699 sp_384_mont_sqr_order_12(t, t);
wolfSSL 16:8e0d178b1d1e 24700 if ((p384_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {
wolfSSL 16:8e0d178b1d1e 24701 sp_384_mont_mul_order_12(t, t, a);
wolfSSL 16:8e0d178b1d1e 24702 }
wolfSSL 16:8e0d178b1d1e 24703 }
wolfSSL 16:8e0d178b1d1e 24704 XMEMCPY(r, t, sizeof(sp_digit) * 12U);
wolfSSL 16:8e0d178b1d1e 24705 #else
wolfSSL 16:8e0d178b1d1e 24706 sp_digit* t = td;
wolfSSL 16:8e0d178b1d1e 24707 sp_digit* t2 = td + 2 * 12;
wolfSSL 16:8e0d178b1d1e 24708 sp_digit* t3 = td + 4 * 12;
wolfSSL 16:8e0d178b1d1e 24709 int i;
wolfSSL 16:8e0d178b1d1e 24710
wolfSSL 16:8e0d178b1d1e 24711 /* t = a^2 */
wolfSSL 16:8e0d178b1d1e 24712 sp_384_mont_sqr_order_12(t, a);
wolfSSL 16:8e0d178b1d1e 24713 /* t = a^3 = t * a */
wolfSSL 16:8e0d178b1d1e 24714 sp_384_mont_mul_order_12(t, t, a);
wolfSSL 16:8e0d178b1d1e 24715 /* t2= a^c = t ^ 2 ^ 2 */
wolfSSL 16:8e0d178b1d1e 24716 sp_384_mont_sqr_n_order_12(t2, t, 2);
wolfSSL 16:8e0d178b1d1e 24717 /* t = a^f = t2 * t */
wolfSSL 16:8e0d178b1d1e 24718 sp_384_mont_mul_order_12(t, t2, t);
wolfSSL 16:8e0d178b1d1e 24719 /* t2= a^f0 = t ^ 2 ^ 4 */
wolfSSL 16:8e0d178b1d1e 24720 sp_384_mont_sqr_n_order_12(t2, t, 4);
wolfSSL 16:8e0d178b1d1e 24721 /* t = a^ff = t2 * t */
wolfSSL 16:8e0d178b1d1e 24722 sp_384_mont_mul_order_12(t, t2, t);
wolfSSL 16:8e0d178b1d1e 24723 /* t2= a^ff00 = t ^ 2 ^ 8 */
wolfSSL 16:8e0d178b1d1e 24724 sp_384_mont_sqr_n_order_12(t2, t, 8);
wolfSSL 16:8e0d178b1d1e 24725 /* t3= a^ffff = t2 * t */
wolfSSL 16:8e0d178b1d1e 24726 sp_384_mont_mul_order_12(t3, t2, t);
wolfSSL 16:8e0d178b1d1e 24727 /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */
wolfSSL 16:8e0d178b1d1e 24728 sp_384_mont_sqr_n_order_12(t2, t3, 16);
wolfSSL 16:8e0d178b1d1e 24729 /* t = a^ffffffff = t2 * t3 */
wolfSSL 16:8e0d178b1d1e 24730 sp_384_mont_mul_order_12(t, t2, t3);
wolfSSL 16:8e0d178b1d1e 24731 /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */
wolfSSL 16:8e0d178b1d1e 24732 sp_384_mont_sqr_n_order_12(t2, t, 16);
wolfSSL 16:8e0d178b1d1e 24733 /* t = a^ffffffffffff = t2 * t3 */
wolfSSL 16:8e0d178b1d1e 24734 sp_384_mont_mul_order_12(t, t2, t3);
wolfSSL 16:8e0d178b1d1e 24735 /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */
wolfSSL 16:8e0d178b1d1e 24736 sp_384_mont_sqr_n_order_12(t2, t, 48);
wolfSSL 16:8e0d178b1d1e 24737 /* t= a^fffffffffffffffffffffffff = t2 * t */
wolfSSL 16:8e0d178b1d1e 24738 sp_384_mont_mul_order_12(t, t2, t);
wolfSSL 16:8e0d178b1d1e 24739 /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */
wolfSSL 16:8e0d178b1d1e 24740 sp_384_mont_sqr_n_order_12(t2, t, 96);
wolfSSL 16:8e0d178b1d1e 24741 /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */
wolfSSL 16:8e0d178b1d1e 24742 sp_384_mont_mul_order_12(t2, t2, t);
wolfSSL 16:8e0d178b1d1e 24743 for (i=191; i>=1; i--) {
wolfSSL 16:8e0d178b1d1e 24744 sp_384_mont_sqr_order_12(t2, t2);
wolfSSL 16:8e0d178b1d1e 24745 if (((sp_digit)p384_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {
wolfSSL 16:8e0d178b1d1e 24746 sp_384_mont_mul_order_12(t2, t2, a);
wolfSSL 16:8e0d178b1d1e 24747 }
wolfSSL 16:8e0d178b1d1e 24748 }
wolfSSL 16:8e0d178b1d1e 24749 sp_384_mont_sqr_order_12(t2, t2);
wolfSSL 16:8e0d178b1d1e 24750 sp_384_mont_mul_order_12(r, t2, a);
wolfSSL 16:8e0d178b1d1e 24751 #endif /* WOLFSSL_SP_SMALL */
wolfSSL 16:8e0d178b1d1e 24752 }
wolfSSL 16:8e0d178b1d1e 24753
wolfSSL 16:8e0d178b1d1e 24754 #endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */
wolfSSL 16:8e0d178b1d1e 24755 #ifdef HAVE_ECC_SIGN
wolfSSL 16:8e0d178b1d1e 24756 #ifndef SP_ECC_MAX_SIG_GEN
wolfSSL 16:8e0d178b1d1e 24757 #define SP_ECC_MAX_SIG_GEN 64
wolfSSL 16:8e0d178b1d1e 24758 #endif
wolfSSL 16:8e0d178b1d1e 24759
wolfSSL 16:8e0d178b1d1e 24760 /* Sign the hash using the private key.
wolfSSL 16:8e0d178b1d1e 24761 * e = [hash, 384 bits] from binary
wolfSSL 16:8e0d178b1d1e 24762 * r = (k.G)->x mod order
wolfSSL 16:8e0d178b1d1e 24763 * s = (r * x + e) / k mod order
wolfSSL 16:8e0d178b1d1e 24764 * The hash is truncated to the first 384 bits.
wolfSSL 16:8e0d178b1d1e 24765 *
wolfSSL 16:8e0d178b1d1e 24766 * hash Hash to sign.
wolfSSL 16:8e0d178b1d1e 24767 * hashLen Length of the hash data.
wolfSSL 16:8e0d178b1d1e 24768 * rng Random number generator.
wolfSSL 16:8e0d178b1d1e 24769 * priv Private part of key - scalar.
wolfSSL 16:8e0d178b1d1e 24770 * rm First part of result as an mp_int.
wolfSSL 16:8e0d178b1d1e 24771 * sm Sirst part of result as an mp_int.
wolfSSL 16:8e0d178b1d1e 24772 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 24773 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 16:8e0d178b1d1e 24774 * MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 24775 */
wolfSSL 16:8e0d178b1d1e 24776 int sp_ecc_sign_384(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
wolfSSL 16:8e0d178b1d1e 24777 mp_int* rm, mp_int* sm, mp_int* km, void* heap)
wolfSSL 16:8e0d178b1d1e 24778 {
wolfSSL 16:8e0d178b1d1e 24779 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24780 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 24781 #else
wolfSSL 16:8e0d178b1d1e 24782 sp_digit ed[2*12];
wolfSSL 16:8e0d178b1d1e 24783 sp_digit xd[2*12];
wolfSSL 16:8e0d178b1d1e 24784 sp_digit kd[2*12];
wolfSSL 16:8e0d178b1d1e 24785 sp_digit rd[2*12];
wolfSSL 16:8e0d178b1d1e 24786 sp_digit td[3 * 2*12];
wolfSSL 16:8e0d178b1d1e 24787 sp_point_384 p;
wolfSSL 16:8e0d178b1d1e 24788 #endif
wolfSSL 16:8e0d178b1d1e 24789 sp_digit* e = NULL;
wolfSSL 16:8e0d178b1d1e 24790 sp_digit* x = NULL;
wolfSSL 16:8e0d178b1d1e 24791 sp_digit* k = NULL;
wolfSSL 16:8e0d178b1d1e 24792 sp_digit* r = NULL;
wolfSSL 16:8e0d178b1d1e 24793 sp_digit* tmp = NULL;
wolfSSL 16:8e0d178b1d1e 24794 sp_point_384* point = NULL;
wolfSSL 16:8e0d178b1d1e 24795 sp_digit carry;
wolfSSL 16:8e0d178b1d1e 24796 sp_digit* s = NULL;
wolfSSL 16:8e0d178b1d1e 24797 sp_digit* kInv = NULL;
wolfSSL 16:8e0d178b1d1e 24798 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 24799 int32_t c;
wolfSSL 16:8e0d178b1d1e 24800 int i;
wolfSSL 16:8e0d178b1d1e 24801
wolfSSL 16:8e0d178b1d1e 24802 (void)heap;
wolfSSL 16:8e0d178b1d1e 24803
wolfSSL 16:8e0d178b1d1e 24804 err = sp_384_point_new_12(heap, p, point);
wolfSSL 16:8e0d178b1d1e 24805 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24806 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24807 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 12, heap,
wolfSSL 16:8e0d178b1d1e 24808 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 24809 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 24810 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 24811 }
wolfSSL 16:8e0d178b1d1e 24812 }
wolfSSL 16:8e0d178b1d1e 24813 #endif
wolfSSL 16:8e0d178b1d1e 24814
wolfSSL 16:8e0d178b1d1e 24815 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24816 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24817 e = d + 0 * 12;
wolfSSL 16:8e0d178b1d1e 24818 x = d + 2 * 12;
wolfSSL 16:8e0d178b1d1e 24819 k = d + 4 * 12;
wolfSSL 16:8e0d178b1d1e 24820 r = d + 6 * 12;
wolfSSL 16:8e0d178b1d1e 24821 tmp = d + 8 * 12;
wolfSSL 16:8e0d178b1d1e 24822 #else
wolfSSL 16:8e0d178b1d1e 24823 e = ed;
wolfSSL 16:8e0d178b1d1e 24824 x = xd;
wolfSSL 16:8e0d178b1d1e 24825 k = kd;
wolfSSL 16:8e0d178b1d1e 24826 r = rd;
wolfSSL 16:8e0d178b1d1e 24827 tmp = td;
wolfSSL 16:8e0d178b1d1e 24828 #endif
wolfSSL 16:8e0d178b1d1e 24829 s = e;
wolfSSL 16:8e0d178b1d1e 24830 kInv = k;
wolfSSL 16:8e0d178b1d1e 24831
wolfSSL 16:8e0d178b1d1e 24832 if (hashLen > 48U) {
wolfSSL 16:8e0d178b1d1e 24833 hashLen = 48U;
wolfSSL 16:8e0d178b1d1e 24834 }
wolfSSL 16:8e0d178b1d1e 24835
wolfSSL 16:8e0d178b1d1e 24836 sp_384_from_bin(e, 12, hash, (int)hashLen);
wolfSSL 16:8e0d178b1d1e 24837 }
wolfSSL 16:8e0d178b1d1e 24838
wolfSSL 16:8e0d178b1d1e 24839 for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {
wolfSSL 16:8e0d178b1d1e 24840 sp_384_from_mp(x, 12, priv);
wolfSSL 16:8e0d178b1d1e 24841
wolfSSL 16:8e0d178b1d1e 24842 /* New random point. */
wolfSSL 16:8e0d178b1d1e 24843 if (km == NULL || mp_iszero(km)) {
wolfSSL 16:8e0d178b1d1e 24844 err = sp_384_ecc_gen_k_12(rng, k);
wolfSSL 16:8e0d178b1d1e 24845 }
wolfSSL 16:8e0d178b1d1e 24846 else {
wolfSSL 16:8e0d178b1d1e 24847 sp_384_from_mp(k, 12, km);
wolfSSL 16:8e0d178b1d1e 24848 mp_zero(km);
wolfSSL 16:8e0d178b1d1e 24849 }
wolfSSL 16:8e0d178b1d1e 24850 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24851 err = sp_384_ecc_mulmod_base_12(point, k, 1, NULL);
wolfSSL 16:8e0d178b1d1e 24852 }
wolfSSL 16:8e0d178b1d1e 24853
wolfSSL 16:8e0d178b1d1e 24854 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24855 /* r = point->x mod order */
wolfSSL 16:8e0d178b1d1e 24856 XMEMCPY(r, point->x, sizeof(sp_digit) * 12U);
wolfSSL 16:8e0d178b1d1e 24857 sp_384_norm_12(r);
wolfSSL 16:8e0d178b1d1e 24858 c = sp_384_cmp_12(r, p384_order);
wolfSSL 16:8e0d178b1d1e 24859 sp_384_cond_sub_12(r, r, p384_order, 0L - (sp_digit)(c >= 0));
wolfSSL 16:8e0d178b1d1e 24860 sp_384_norm_12(r);
wolfSSL 16:8e0d178b1d1e 24861
wolfSSL 16:8e0d178b1d1e 24862 /* Conv k to Montgomery form (mod order) */
wolfSSL 16:8e0d178b1d1e 24863 sp_384_mul_12(k, k, p384_norm_order);
wolfSSL 16:8e0d178b1d1e 24864 err = sp_384_mod_12(k, k, p384_order);
wolfSSL 16:8e0d178b1d1e 24865 }
wolfSSL 16:8e0d178b1d1e 24866 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24867 sp_384_norm_12(k);
wolfSSL 16:8e0d178b1d1e 24868 /* kInv = 1/k mod order */
wolfSSL 16:8e0d178b1d1e 24869 sp_384_mont_inv_order_12(kInv, k, tmp);
wolfSSL 16:8e0d178b1d1e 24870 sp_384_norm_12(kInv);
wolfSSL 16:8e0d178b1d1e 24871
wolfSSL 16:8e0d178b1d1e 24872 /* s = r * x + e */
wolfSSL 16:8e0d178b1d1e 24873 sp_384_mul_12(x, x, r);
wolfSSL 16:8e0d178b1d1e 24874 err = sp_384_mod_12(x, x, p384_order);
wolfSSL 16:8e0d178b1d1e 24875 }
wolfSSL 16:8e0d178b1d1e 24876 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24877 sp_384_norm_12(x);
wolfSSL 16:8e0d178b1d1e 24878 carry = sp_384_add_12(s, e, x);
wolfSSL 16:8e0d178b1d1e 24879 sp_384_cond_sub_12(s, s, p384_order, 0 - carry);
wolfSSL 16:8e0d178b1d1e 24880 sp_384_norm_12(s);
wolfSSL 16:8e0d178b1d1e 24881 c = sp_384_cmp_12(s, p384_order);
wolfSSL 16:8e0d178b1d1e 24882 sp_384_cond_sub_12(s, s, p384_order, 0L - (sp_digit)(c >= 0));
wolfSSL 16:8e0d178b1d1e 24883 sp_384_norm_12(s);
wolfSSL 16:8e0d178b1d1e 24884
wolfSSL 16:8e0d178b1d1e 24885 /* s = s * k^-1 mod order */
wolfSSL 16:8e0d178b1d1e 24886 sp_384_mont_mul_order_12(s, s, kInv);
wolfSSL 16:8e0d178b1d1e 24887 sp_384_norm_12(s);
wolfSSL 16:8e0d178b1d1e 24888
wolfSSL 16:8e0d178b1d1e 24889 /* Check that signature is usable. */
wolfSSL 16:8e0d178b1d1e 24890 if (sp_384_iszero_12(s) == 0) {
wolfSSL 16:8e0d178b1d1e 24891 break;
wolfSSL 16:8e0d178b1d1e 24892 }
wolfSSL 16:8e0d178b1d1e 24893 }
wolfSSL 16:8e0d178b1d1e 24894 }
wolfSSL 16:8e0d178b1d1e 24895
wolfSSL 16:8e0d178b1d1e 24896 if (i == 0) {
wolfSSL 16:8e0d178b1d1e 24897 err = RNG_FAILURE_E;
wolfSSL 16:8e0d178b1d1e 24898 }
wolfSSL 16:8e0d178b1d1e 24899
wolfSSL 16:8e0d178b1d1e 24900 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24901 err = sp_384_to_mp(r, rm);
wolfSSL 16:8e0d178b1d1e 24902 }
wolfSSL 16:8e0d178b1d1e 24903 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24904 err = sp_384_to_mp(s, sm);
wolfSSL 16:8e0d178b1d1e 24905 }
wolfSSL 16:8e0d178b1d1e 24906
wolfSSL 16:8e0d178b1d1e 24907 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24908 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 24909 XMEMSET(d, 0, sizeof(sp_digit) * 8 * 12);
wolfSSL 16:8e0d178b1d1e 24910 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 24911 }
wolfSSL 16:8e0d178b1d1e 24912 #else
wolfSSL 16:8e0d178b1d1e 24913 XMEMSET(e, 0, sizeof(sp_digit) * 2U * 12U);
wolfSSL 16:8e0d178b1d1e 24914 XMEMSET(x, 0, sizeof(sp_digit) * 2U * 12U);
wolfSSL 16:8e0d178b1d1e 24915 XMEMSET(k, 0, sizeof(sp_digit) * 2U * 12U);
wolfSSL 16:8e0d178b1d1e 24916 XMEMSET(r, 0, sizeof(sp_digit) * 2U * 12U);
wolfSSL 16:8e0d178b1d1e 24917 XMEMSET(r, 0, sizeof(sp_digit) * 2U * 12U);
wolfSSL 16:8e0d178b1d1e 24918 XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 12U);
wolfSSL 16:8e0d178b1d1e 24919 #endif
wolfSSL 16:8e0d178b1d1e 24920 sp_384_point_free_12(point, 1, heap);
wolfSSL 16:8e0d178b1d1e 24921
wolfSSL 16:8e0d178b1d1e 24922 return err;
wolfSSL 16:8e0d178b1d1e 24923 }
wolfSSL 16:8e0d178b1d1e 24924 #endif /* HAVE_ECC_SIGN */
wolfSSL 16:8e0d178b1d1e 24925
wolfSSL 16:8e0d178b1d1e 24926 #ifdef HAVE_ECC_VERIFY
wolfSSL 16:8e0d178b1d1e 24927 /* Verify the signature values with the hash and public key.
wolfSSL 16:8e0d178b1d1e 24928 * e = Truncate(hash, 384)
wolfSSL 16:8e0d178b1d1e 24929 * u1 = e/s mod order
wolfSSL 16:8e0d178b1d1e 24930 * u2 = r/s mod order
wolfSSL 16:8e0d178b1d1e 24931 * r == (u1.G + u2.Q)->x mod order
wolfSSL 16:8e0d178b1d1e 24932 * Optimization: Leave point in projective form.
wolfSSL 16:8e0d178b1d1e 24933 * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')
wolfSSL 16:8e0d178b1d1e 24934 * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'
wolfSSL 16:8e0d178b1d1e 24935 * The hash is truncated to the first 384 bits.
wolfSSL 16:8e0d178b1d1e 24936 *
wolfSSL 16:8e0d178b1d1e 24937 * hash Hash to sign.
wolfSSL 16:8e0d178b1d1e 24938 * hashLen Length of the hash data.
wolfSSL 16:8e0d178b1d1e 24939 * rng Random number generator.
wolfSSL 16:8e0d178b1d1e 24940 * priv Private part of key - scalar.
wolfSSL 16:8e0d178b1d1e 24941 * rm First part of result as an mp_int.
wolfSSL 16:8e0d178b1d1e 24942 * sm Sirst part of result as an mp_int.
wolfSSL 16:8e0d178b1d1e 24943 * heap Heap to use for allocation.
wolfSSL 16:8e0d178b1d1e 24944 * returns RNG failures, MEMORY_E when memory allocation fails and
wolfSSL 16:8e0d178b1d1e 24945 * MP_OKAY on success.
wolfSSL 16:8e0d178b1d1e 24946 */
wolfSSL 16:8e0d178b1d1e 24947 int sp_ecc_verify_384(const byte* hash, word32 hashLen, mp_int* pX,
wolfSSL 16:8e0d178b1d1e 24948 mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)
wolfSSL 16:8e0d178b1d1e 24949 {
wolfSSL 16:8e0d178b1d1e 24950 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24951 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 24952 #else
wolfSSL 16:8e0d178b1d1e 24953 sp_digit u1d[2*12];
wolfSSL 16:8e0d178b1d1e 24954 sp_digit u2d[2*12];
wolfSSL 16:8e0d178b1d1e 24955 sp_digit sd[2*12];
wolfSSL 16:8e0d178b1d1e 24956 sp_digit tmpd[2*12 * 5];
wolfSSL 16:8e0d178b1d1e 24957 sp_point_384 p1d;
wolfSSL 16:8e0d178b1d1e 24958 sp_point_384 p2d;
wolfSSL 16:8e0d178b1d1e 24959 #endif
wolfSSL 16:8e0d178b1d1e 24960 sp_digit* u1 = NULL;
wolfSSL 16:8e0d178b1d1e 24961 sp_digit* u2 = NULL;
wolfSSL 16:8e0d178b1d1e 24962 sp_digit* s = NULL;
wolfSSL 16:8e0d178b1d1e 24963 sp_digit* tmp = NULL;
wolfSSL 16:8e0d178b1d1e 24964 sp_point_384* p1;
wolfSSL 16:8e0d178b1d1e 24965 sp_point_384* p2 = NULL;
wolfSSL 16:8e0d178b1d1e 24966 sp_digit carry;
wolfSSL 16:8e0d178b1d1e 24967 int32_t c;
wolfSSL 16:8e0d178b1d1e 24968 int err;
wolfSSL 16:8e0d178b1d1e 24969
wolfSSL 16:8e0d178b1d1e 24970 err = sp_384_point_new_12(heap, p1d, p1);
wolfSSL 16:8e0d178b1d1e 24971 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24972 err = sp_384_point_new_12(heap, p2d, p2);
wolfSSL 16:8e0d178b1d1e 24973 }
wolfSSL 16:8e0d178b1d1e 24974 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24975 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24976 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 12, heap,
wolfSSL 16:8e0d178b1d1e 24977 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 24978 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 24979 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 24980 }
wolfSSL 16:8e0d178b1d1e 24981 }
wolfSSL 16:8e0d178b1d1e 24982 #endif
wolfSSL 16:8e0d178b1d1e 24983
wolfSSL 16:8e0d178b1d1e 24984 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 24985 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 24986 u1 = d + 0 * 12;
wolfSSL 16:8e0d178b1d1e 24987 u2 = d + 2 * 12;
wolfSSL 16:8e0d178b1d1e 24988 s = d + 4 * 12;
wolfSSL 16:8e0d178b1d1e 24989 tmp = d + 6 * 12;
wolfSSL 16:8e0d178b1d1e 24990 #else
wolfSSL 16:8e0d178b1d1e 24991 u1 = u1d;
wolfSSL 16:8e0d178b1d1e 24992 u2 = u2d;
wolfSSL 16:8e0d178b1d1e 24993 s = sd;
wolfSSL 16:8e0d178b1d1e 24994 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 24995 #endif
wolfSSL 16:8e0d178b1d1e 24996
wolfSSL 16:8e0d178b1d1e 24997 if (hashLen > 48U) {
wolfSSL 16:8e0d178b1d1e 24998 hashLen = 48U;
wolfSSL 16:8e0d178b1d1e 24999 }
wolfSSL 16:8e0d178b1d1e 25000
wolfSSL 16:8e0d178b1d1e 25001 sp_384_from_bin(u1, 12, hash, (int)hashLen);
wolfSSL 16:8e0d178b1d1e 25002 sp_384_from_mp(u2, 12, r);
wolfSSL 16:8e0d178b1d1e 25003 sp_384_from_mp(s, 12, sm);
wolfSSL 16:8e0d178b1d1e 25004 sp_384_from_mp(p2->x, 12, pX);
wolfSSL 16:8e0d178b1d1e 25005 sp_384_from_mp(p2->y, 12, pY);
wolfSSL 16:8e0d178b1d1e 25006 sp_384_from_mp(p2->z, 12, pZ);
wolfSSL 16:8e0d178b1d1e 25007
wolfSSL 16:8e0d178b1d1e 25008 {
wolfSSL 16:8e0d178b1d1e 25009 sp_384_mul_12(s, s, p384_norm_order);
wolfSSL 16:8e0d178b1d1e 25010 }
wolfSSL 16:8e0d178b1d1e 25011 err = sp_384_mod_12(s, s, p384_order);
wolfSSL 16:8e0d178b1d1e 25012 }
wolfSSL 16:8e0d178b1d1e 25013 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25014 sp_384_norm_12(s);
wolfSSL 16:8e0d178b1d1e 25015 {
wolfSSL 16:8e0d178b1d1e 25016 sp_384_mont_inv_order_12(s, s, tmp);
wolfSSL 16:8e0d178b1d1e 25017 sp_384_mont_mul_order_12(u1, u1, s);
wolfSSL 16:8e0d178b1d1e 25018 sp_384_mont_mul_order_12(u2, u2, s);
wolfSSL 16:8e0d178b1d1e 25019 }
wolfSSL 16:8e0d178b1d1e 25020
wolfSSL 16:8e0d178b1d1e 25021 err = sp_384_ecc_mulmod_base_12(p1, u1, 0, heap);
wolfSSL 16:8e0d178b1d1e 25022 }
wolfSSL 16:8e0d178b1d1e 25023 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25024 err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, heap);
wolfSSL 16:8e0d178b1d1e 25025 }
wolfSSL 16:8e0d178b1d1e 25026
wolfSSL 16:8e0d178b1d1e 25027 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25028 {
wolfSSL 16:8e0d178b1d1e 25029 sp_384_proj_point_add_12(p1, p1, p2, tmp);
wolfSSL 16:8e0d178b1d1e 25030 if (sp_384_iszero_12(p1->z)) {
wolfSSL 16:8e0d178b1d1e 25031 if (sp_384_iszero_12(p1->x) && sp_384_iszero_12(p1->y)) {
wolfSSL 16:8e0d178b1d1e 25032 sp_384_proj_point_dbl_12(p1, p2, tmp);
wolfSSL 16:8e0d178b1d1e 25033 }
wolfSSL 16:8e0d178b1d1e 25034 else {
wolfSSL 16:8e0d178b1d1e 25035 /* Y ordinate is not used from here - don't set. */
wolfSSL 16:8e0d178b1d1e 25036 p1->x[0] = 0;
wolfSSL 16:8e0d178b1d1e 25037 p1->x[1] = 0;
wolfSSL 16:8e0d178b1d1e 25038 p1->x[2] = 0;
wolfSSL 16:8e0d178b1d1e 25039 p1->x[3] = 0;
wolfSSL 16:8e0d178b1d1e 25040 p1->x[4] = 0;
wolfSSL 16:8e0d178b1d1e 25041 p1->x[5] = 0;
wolfSSL 16:8e0d178b1d1e 25042 p1->x[6] = 0;
wolfSSL 16:8e0d178b1d1e 25043 p1->x[7] = 0;
wolfSSL 16:8e0d178b1d1e 25044 p1->x[8] = 0;
wolfSSL 16:8e0d178b1d1e 25045 p1->x[9] = 0;
wolfSSL 16:8e0d178b1d1e 25046 p1->x[10] = 0;
wolfSSL 16:8e0d178b1d1e 25047 p1->x[11] = 0;
wolfSSL 16:8e0d178b1d1e 25048 XMEMCPY(p1->z, p384_norm_mod, sizeof(p384_norm_mod));
wolfSSL 16:8e0d178b1d1e 25049 }
wolfSSL 16:8e0d178b1d1e 25050 }
wolfSSL 16:8e0d178b1d1e 25051 }
wolfSSL 16:8e0d178b1d1e 25052
wolfSSL 16:8e0d178b1d1e 25053 /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
wolfSSL 16:8e0d178b1d1e 25054 /* Reload r and convert to Montgomery form. */
wolfSSL 16:8e0d178b1d1e 25055 sp_384_from_mp(u2, 12, r);
wolfSSL 16:8e0d178b1d1e 25056 err = sp_384_mod_mul_norm_12(u2, u2, p384_mod);
wolfSSL 16:8e0d178b1d1e 25057 }
wolfSSL 16:8e0d178b1d1e 25058
wolfSSL 16:8e0d178b1d1e 25059 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25060 /* u1 = r.z'.z' mod prime */
wolfSSL 16:8e0d178b1d1e 25061 sp_384_mont_sqr_12(p1->z, p1->z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25062 sp_384_mont_mul_12(u1, u2, p1->z, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25063 *res = (int)(sp_384_cmp_12(p1->x, u1) == 0);
wolfSSL 16:8e0d178b1d1e 25064 if (*res == 0) {
wolfSSL 16:8e0d178b1d1e 25065 /* Reload r and add order. */
wolfSSL 16:8e0d178b1d1e 25066 sp_384_from_mp(u2, 12, r);
wolfSSL 16:8e0d178b1d1e 25067 carry = sp_384_add_12(u2, u2, p384_order);
wolfSSL 16:8e0d178b1d1e 25068 /* Carry means result is greater than mod and is not valid. */
wolfSSL 16:8e0d178b1d1e 25069 if (carry == 0) {
wolfSSL 16:8e0d178b1d1e 25070 sp_384_norm_12(u2);
wolfSSL 16:8e0d178b1d1e 25071
wolfSSL 16:8e0d178b1d1e 25072 /* Compare with mod and if greater or equal then not valid. */
wolfSSL 16:8e0d178b1d1e 25073 c = sp_384_cmp_12(u2, p384_mod);
wolfSSL 16:8e0d178b1d1e 25074 if (c < 0) {
wolfSSL 16:8e0d178b1d1e 25075 /* Convert to Montogomery form */
wolfSSL 16:8e0d178b1d1e 25076 err = sp_384_mod_mul_norm_12(u2, u2, p384_mod);
wolfSSL 16:8e0d178b1d1e 25077 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25078 /* u1 = (r + 1*order).z'.z' mod prime */
wolfSSL 16:8e0d178b1d1e 25079 sp_384_mont_mul_12(u1, u2, p1->z, p384_mod,
wolfSSL 16:8e0d178b1d1e 25080 p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25081 *res = (int)(sp_384_cmp_12(p1->x, u1) == 0);
wolfSSL 16:8e0d178b1d1e 25082 }
wolfSSL 16:8e0d178b1d1e 25083 }
wolfSSL 16:8e0d178b1d1e 25084 }
wolfSSL 16:8e0d178b1d1e 25085 }
wolfSSL 16:8e0d178b1d1e 25086 }
wolfSSL 16:8e0d178b1d1e 25087
wolfSSL 16:8e0d178b1d1e 25088 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25089 if (d != NULL)
wolfSSL 16:8e0d178b1d1e 25090 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25091 #endif
wolfSSL 16:8e0d178b1d1e 25092 sp_384_point_free_12(p1, 0, heap);
wolfSSL 16:8e0d178b1d1e 25093 sp_384_point_free_12(p2, 0, heap);
wolfSSL 16:8e0d178b1d1e 25094
wolfSSL 16:8e0d178b1d1e 25095 return err;
wolfSSL 16:8e0d178b1d1e 25096 }
wolfSSL 16:8e0d178b1d1e 25097 #endif /* HAVE_ECC_VERIFY */
wolfSSL 16:8e0d178b1d1e 25098
wolfSSL 16:8e0d178b1d1e 25099 #ifdef HAVE_ECC_CHECK_KEY
wolfSSL 16:8e0d178b1d1e 25100 /* Check that the x and y oridinates are a valid point on the curve.
wolfSSL 16:8e0d178b1d1e 25101 *
wolfSSL 16:8e0d178b1d1e 25102 * point EC point.
wolfSSL 16:8e0d178b1d1e 25103 * heap Heap to use if dynamically allocating.
wolfSSL 16:8e0d178b1d1e 25104 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 16:8e0d178b1d1e 25105 * not on the curve and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 25106 */
wolfSSL 16:8e0d178b1d1e 25107 static int sp_384_ecc_is_point_12(sp_point_384* point, void* heap)
wolfSSL 16:8e0d178b1d1e 25108 {
wolfSSL 16:8e0d178b1d1e 25109 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25110 sp_digit* d = NULL;
wolfSSL 16:8e0d178b1d1e 25111 #else
wolfSSL 16:8e0d178b1d1e 25112 sp_digit t1d[2*12];
wolfSSL 16:8e0d178b1d1e 25113 sp_digit t2d[2*12];
wolfSSL 16:8e0d178b1d1e 25114 #endif
wolfSSL 16:8e0d178b1d1e 25115 sp_digit* t1;
wolfSSL 16:8e0d178b1d1e 25116 sp_digit* t2;
wolfSSL 16:8e0d178b1d1e 25117 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 25118
wolfSSL 16:8e0d178b1d1e 25119 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25120 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12 * 4, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25121 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 25122 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 25123 }
wolfSSL 16:8e0d178b1d1e 25124 #endif
wolfSSL 16:8e0d178b1d1e 25125
wolfSSL 16:8e0d178b1d1e 25126 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25127 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25128 t1 = d + 0 * 12;
wolfSSL 16:8e0d178b1d1e 25129 t2 = d + 2 * 12;
wolfSSL 16:8e0d178b1d1e 25130 #else
wolfSSL 16:8e0d178b1d1e 25131 (void)heap;
wolfSSL 16:8e0d178b1d1e 25132
wolfSSL 16:8e0d178b1d1e 25133 t1 = t1d;
wolfSSL 16:8e0d178b1d1e 25134 t2 = t2d;
wolfSSL 16:8e0d178b1d1e 25135 #endif
wolfSSL 16:8e0d178b1d1e 25136
wolfSSL 16:8e0d178b1d1e 25137 sp_384_sqr_12(t1, point->y);
wolfSSL 16:8e0d178b1d1e 25138 (void)sp_384_mod_12(t1, t1, p384_mod);
wolfSSL 16:8e0d178b1d1e 25139 sp_384_sqr_12(t2, point->x);
wolfSSL 16:8e0d178b1d1e 25140 (void)sp_384_mod_12(t2, t2, p384_mod);
wolfSSL 16:8e0d178b1d1e 25141 sp_384_mul_12(t2, t2, point->x);
wolfSSL 16:8e0d178b1d1e 25142 (void)sp_384_mod_12(t2, t2, p384_mod);
wolfSSL 16:8e0d178b1d1e 25143 (void)sp_384_sub_12(t2, p384_mod, t2);
wolfSSL 16:8e0d178b1d1e 25144 sp_384_mont_add_12(t1, t1, t2, p384_mod);
wolfSSL 16:8e0d178b1d1e 25145
wolfSSL 16:8e0d178b1d1e 25146 sp_384_mont_add_12(t1, t1, point->x, p384_mod);
wolfSSL 16:8e0d178b1d1e 25147 sp_384_mont_add_12(t1, t1, point->x, p384_mod);
wolfSSL 16:8e0d178b1d1e 25148 sp_384_mont_add_12(t1, t1, point->x, p384_mod);
wolfSSL 16:8e0d178b1d1e 25149
wolfSSL 16:8e0d178b1d1e 25150 if (sp_384_cmp_12(t1, p384_b) != 0) {
wolfSSL 16:8e0d178b1d1e 25151 err = MP_VAL;
wolfSSL 16:8e0d178b1d1e 25152 }
wolfSSL 16:8e0d178b1d1e 25153 }
wolfSSL 16:8e0d178b1d1e 25154
wolfSSL 16:8e0d178b1d1e 25155 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25156 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 25157 XFREE(d, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25158 }
wolfSSL 16:8e0d178b1d1e 25159 #endif
wolfSSL 16:8e0d178b1d1e 25160
wolfSSL 16:8e0d178b1d1e 25161 return err;
wolfSSL 16:8e0d178b1d1e 25162 }
wolfSSL 16:8e0d178b1d1e 25163
wolfSSL 16:8e0d178b1d1e 25164 /* Check that the x and y oridinates are a valid point on the curve.
wolfSSL 16:8e0d178b1d1e 25165 *
wolfSSL 16:8e0d178b1d1e 25166 * pX X ordinate of EC point.
wolfSSL 16:8e0d178b1d1e 25167 * pY Y ordinate of EC point.
wolfSSL 16:8e0d178b1d1e 25168 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 16:8e0d178b1d1e 25169 * not on the curve and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 25170 */
wolfSSL 16:8e0d178b1d1e 25171 int sp_ecc_is_point_384(mp_int* pX, mp_int* pY)
wolfSSL 16:8e0d178b1d1e 25172 {
wolfSSL 16:8e0d178b1d1e 25173 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25174 sp_point_384 pubd;
wolfSSL 16:8e0d178b1d1e 25175 #endif
wolfSSL 16:8e0d178b1d1e 25176 sp_point_384* pub;
wolfSSL 16:8e0d178b1d1e 25177 byte one[1] = { 1 };
wolfSSL 16:8e0d178b1d1e 25178 int err;
wolfSSL 16:8e0d178b1d1e 25179
wolfSSL 16:8e0d178b1d1e 25180 err = sp_384_point_new_12(NULL, pubd, pub);
wolfSSL 16:8e0d178b1d1e 25181 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25182 sp_384_from_mp(pub->x, 12, pX);
wolfSSL 16:8e0d178b1d1e 25183 sp_384_from_mp(pub->y, 12, pY);
wolfSSL 16:8e0d178b1d1e 25184 sp_384_from_bin(pub->z, 12, one, (int)sizeof(one));
wolfSSL 16:8e0d178b1d1e 25185
wolfSSL 16:8e0d178b1d1e 25186 err = sp_384_ecc_is_point_12(pub, NULL);
wolfSSL 16:8e0d178b1d1e 25187 }
wolfSSL 16:8e0d178b1d1e 25188
wolfSSL 16:8e0d178b1d1e 25189 sp_384_point_free_12(pub, 0, NULL);
wolfSSL 16:8e0d178b1d1e 25190
wolfSSL 16:8e0d178b1d1e 25191 return err;
wolfSSL 16:8e0d178b1d1e 25192 }
wolfSSL 16:8e0d178b1d1e 25193
wolfSSL 16:8e0d178b1d1e 25194 /* Check that the private scalar generates the EC point (px, py), the point is
wolfSSL 16:8e0d178b1d1e 25195 * on the curve and the point has the correct order.
wolfSSL 16:8e0d178b1d1e 25196 *
wolfSSL 16:8e0d178b1d1e 25197 * pX X ordinate of EC point.
wolfSSL 16:8e0d178b1d1e 25198 * pY Y ordinate of EC point.
wolfSSL 16:8e0d178b1d1e 25199 * privm Private scalar that generates EC point.
wolfSSL 16:8e0d178b1d1e 25200 * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is
wolfSSL 16:8e0d178b1d1e 25201 * not on the curve, ECC_INF_E if the point does not have the correct order,
wolfSSL 16:8e0d178b1d1e 25202 * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and
wolfSSL 16:8e0d178b1d1e 25203 * MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 25204 */
wolfSSL 16:8e0d178b1d1e 25205 int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)
wolfSSL 16:8e0d178b1d1e 25206 {
wolfSSL 16:8e0d178b1d1e 25207 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25208 sp_digit privd[12];
wolfSSL 16:8e0d178b1d1e 25209 sp_point_384 pubd;
wolfSSL 16:8e0d178b1d1e 25210 sp_point_384 pd;
wolfSSL 16:8e0d178b1d1e 25211 #endif
wolfSSL 16:8e0d178b1d1e 25212 sp_digit* priv = NULL;
wolfSSL 16:8e0d178b1d1e 25213 sp_point_384* pub;
wolfSSL 16:8e0d178b1d1e 25214 sp_point_384* p = NULL;
wolfSSL 16:8e0d178b1d1e 25215 byte one[1] = { 1 };
wolfSSL 16:8e0d178b1d1e 25216 int err;
wolfSSL 16:8e0d178b1d1e 25217
wolfSSL 16:8e0d178b1d1e 25218 err = sp_384_point_new_12(heap, pubd, pub);
wolfSSL 16:8e0d178b1d1e 25219 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25220 err = sp_384_point_new_12(heap, pd, p);
wolfSSL 16:8e0d178b1d1e 25221 }
wolfSSL 16:8e0d178b1d1e 25222 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25223 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25224 priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap,
wolfSSL 16:8e0d178b1d1e 25225 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25226 if (priv == NULL) {
wolfSSL 16:8e0d178b1d1e 25227 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 25228 }
wolfSSL 16:8e0d178b1d1e 25229 }
wolfSSL 16:8e0d178b1d1e 25230 #endif
wolfSSL 16:8e0d178b1d1e 25231
wolfSSL 16:8e0d178b1d1e 25232 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25233 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25234 priv = privd;
wolfSSL 16:8e0d178b1d1e 25235 #endif
wolfSSL 16:8e0d178b1d1e 25236
wolfSSL 16:8e0d178b1d1e 25237 sp_384_from_mp(pub->x, 12, pX);
wolfSSL 16:8e0d178b1d1e 25238 sp_384_from_mp(pub->y, 12, pY);
wolfSSL 16:8e0d178b1d1e 25239 sp_384_from_bin(pub->z, 12, one, (int)sizeof(one));
wolfSSL 16:8e0d178b1d1e 25240 sp_384_from_mp(priv, 12, privm);
wolfSSL 16:8e0d178b1d1e 25241
wolfSSL 16:8e0d178b1d1e 25242 /* Check point at infinitiy. */
wolfSSL 16:8e0d178b1d1e 25243 if ((sp_384_iszero_12(pub->x) != 0) &&
wolfSSL 16:8e0d178b1d1e 25244 (sp_384_iszero_12(pub->y) != 0)) {
wolfSSL 16:8e0d178b1d1e 25245 err = ECC_INF_E;
wolfSSL 16:8e0d178b1d1e 25246 }
wolfSSL 16:8e0d178b1d1e 25247 }
wolfSSL 16:8e0d178b1d1e 25248
wolfSSL 16:8e0d178b1d1e 25249 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25250 /* Check range of X and Y */
wolfSSL 16:8e0d178b1d1e 25251 if (sp_384_cmp_12(pub->x, p384_mod) >= 0 ||
wolfSSL 16:8e0d178b1d1e 25252 sp_384_cmp_12(pub->y, p384_mod) >= 0) {
wolfSSL 16:8e0d178b1d1e 25253 err = ECC_OUT_OF_RANGE_E;
wolfSSL 16:8e0d178b1d1e 25254 }
wolfSSL 16:8e0d178b1d1e 25255 }
wolfSSL 16:8e0d178b1d1e 25256
wolfSSL 16:8e0d178b1d1e 25257 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25258 /* Check point is on curve */
wolfSSL 16:8e0d178b1d1e 25259 err = sp_384_ecc_is_point_12(pub, heap);
wolfSSL 16:8e0d178b1d1e 25260 }
wolfSSL 16:8e0d178b1d1e 25261
wolfSSL 16:8e0d178b1d1e 25262 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25263 /* Point * order = infinity */
wolfSSL 16:8e0d178b1d1e 25264 err = sp_384_ecc_mulmod_12(p, pub, p384_order, 1, heap);
wolfSSL 16:8e0d178b1d1e 25265 }
wolfSSL 16:8e0d178b1d1e 25266 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25267 /* Check result is infinity */
wolfSSL 16:8e0d178b1d1e 25268 if ((sp_384_iszero_12(p->x) == 0) ||
wolfSSL 16:8e0d178b1d1e 25269 (sp_384_iszero_12(p->y) == 0)) {
wolfSSL 16:8e0d178b1d1e 25270 err = ECC_INF_E;
wolfSSL 16:8e0d178b1d1e 25271 }
wolfSSL 16:8e0d178b1d1e 25272 }
wolfSSL 16:8e0d178b1d1e 25273
wolfSSL 16:8e0d178b1d1e 25274 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25275 /* Base * private = point */
wolfSSL 16:8e0d178b1d1e 25276 err = sp_384_ecc_mulmod_base_12(p, priv, 1, heap);
wolfSSL 16:8e0d178b1d1e 25277 }
wolfSSL 16:8e0d178b1d1e 25278 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25279 /* Check result is public key */
wolfSSL 16:8e0d178b1d1e 25280 if (sp_384_cmp_12(p->x, pub->x) != 0 ||
wolfSSL 16:8e0d178b1d1e 25281 sp_384_cmp_12(p->y, pub->y) != 0) {
wolfSSL 16:8e0d178b1d1e 25282 err = ECC_PRIV_KEY_E;
wolfSSL 16:8e0d178b1d1e 25283 }
wolfSSL 16:8e0d178b1d1e 25284 }
wolfSSL 16:8e0d178b1d1e 25285
wolfSSL 16:8e0d178b1d1e 25286 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25287 if (priv != NULL) {
wolfSSL 16:8e0d178b1d1e 25288 XFREE(priv, heap, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25289 }
wolfSSL 16:8e0d178b1d1e 25290 #endif
wolfSSL 16:8e0d178b1d1e 25291 sp_384_point_free_12(p, 0, heap);
wolfSSL 16:8e0d178b1d1e 25292 sp_384_point_free_12(pub, 0, heap);
wolfSSL 16:8e0d178b1d1e 25293
wolfSSL 16:8e0d178b1d1e 25294 return err;
wolfSSL 16:8e0d178b1d1e 25295 }
wolfSSL 16:8e0d178b1d1e 25296 #endif
wolfSSL 16:8e0d178b1d1e 25297 #ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
wolfSSL 16:8e0d178b1d1e 25298 /* Add two projective EC points together.
wolfSSL 16:8e0d178b1d1e 25299 * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)
wolfSSL 16:8e0d178b1d1e 25300 *
wolfSSL 16:8e0d178b1d1e 25301 * pX First EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 25302 * pY First EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 25303 * pZ First EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 25304 * qX Second EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 25305 * qY Second EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 25306 * qZ Second EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 25307 * rX Resultant EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 25308 * rY Resultant EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 25309 * rZ Resultant EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 25310 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 25311 */
wolfSSL 16:8e0d178b1d1e 25312 int sp_ecc_proj_add_point_384(mp_int* pX, mp_int* pY, mp_int* pZ,
wolfSSL 16:8e0d178b1d1e 25313 mp_int* qX, mp_int* qY, mp_int* qZ,
wolfSSL 16:8e0d178b1d1e 25314 mp_int* rX, mp_int* rY, mp_int* rZ)
wolfSSL 16:8e0d178b1d1e 25315 {
wolfSSL 16:8e0d178b1d1e 25316 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25317 sp_digit tmpd[2 * 12 * 5];
wolfSSL 16:8e0d178b1d1e 25318 sp_point_384 pd;
wolfSSL 16:8e0d178b1d1e 25319 sp_point_384 qd;
wolfSSL 16:8e0d178b1d1e 25320 #endif
wolfSSL 16:8e0d178b1d1e 25321 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 25322 sp_point_384* p;
wolfSSL 16:8e0d178b1d1e 25323 sp_point_384* q = NULL;
wolfSSL 16:8e0d178b1d1e 25324 int err;
wolfSSL 16:8e0d178b1d1e 25325
wolfSSL 16:8e0d178b1d1e 25326 err = sp_384_point_new_12(NULL, pd, p);
wolfSSL 16:8e0d178b1d1e 25327 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25328 err = sp_384_point_new_12(NULL, qd, q);
wolfSSL 16:8e0d178b1d1e 25329 }
wolfSSL 16:8e0d178b1d1e 25330 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25331 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25332 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 5, NULL,
wolfSSL 16:8e0d178b1d1e 25333 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25334 if (tmp == NULL) {
wolfSSL 16:8e0d178b1d1e 25335 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 25336 }
wolfSSL 16:8e0d178b1d1e 25337 }
wolfSSL 16:8e0d178b1d1e 25338 #else
wolfSSL 16:8e0d178b1d1e 25339 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 25340 #endif
wolfSSL 16:8e0d178b1d1e 25341
wolfSSL 16:8e0d178b1d1e 25342 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25343 sp_384_from_mp(p->x, 12, pX);
wolfSSL 16:8e0d178b1d1e 25344 sp_384_from_mp(p->y, 12, pY);
wolfSSL 16:8e0d178b1d1e 25345 sp_384_from_mp(p->z, 12, pZ);
wolfSSL 16:8e0d178b1d1e 25346 sp_384_from_mp(q->x, 12, qX);
wolfSSL 16:8e0d178b1d1e 25347 sp_384_from_mp(q->y, 12, qY);
wolfSSL 16:8e0d178b1d1e 25348 sp_384_from_mp(q->z, 12, qZ);
wolfSSL 16:8e0d178b1d1e 25349
wolfSSL 16:8e0d178b1d1e 25350 sp_384_proj_point_add_12(p, p, q, tmp);
wolfSSL 16:8e0d178b1d1e 25351 }
wolfSSL 16:8e0d178b1d1e 25352
wolfSSL 16:8e0d178b1d1e 25353 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25354 err = sp_384_to_mp(p->x, rX);
wolfSSL 16:8e0d178b1d1e 25355 }
wolfSSL 16:8e0d178b1d1e 25356 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25357 err = sp_384_to_mp(p->y, rY);
wolfSSL 16:8e0d178b1d1e 25358 }
wolfSSL 16:8e0d178b1d1e 25359 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25360 err = sp_384_to_mp(p->z, rZ);
wolfSSL 16:8e0d178b1d1e 25361 }
wolfSSL 16:8e0d178b1d1e 25362
wolfSSL 16:8e0d178b1d1e 25363 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25364 if (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 25365 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25366 }
wolfSSL 16:8e0d178b1d1e 25367 #endif
wolfSSL 16:8e0d178b1d1e 25368 sp_384_point_free_12(q, 0, NULL);
wolfSSL 16:8e0d178b1d1e 25369 sp_384_point_free_12(p, 0, NULL);
wolfSSL 16:8e0d178b1d1e 25370
wolfSSL 16:8e0d178b1d1e 25371 return err;
wolfSSL 16:8e0d178b1d1e 25372 }
wolfSSL 16:8e0d178b1d1e 25373
wolfSSL 16:8e0d178b1d1e 25374 /* Double a projective EC point.
wolfSSL 16:8e0d178b1d1e 25375 * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)
wolfSSL 16:8e0d178b1d1e 25376 *
wolfSSL 16:8e0d178b1d1e 25377 * pX EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 25378 * pY EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 25379 * pZ EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 25380 * rX Resultant EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 25381 * rY Resultant EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 25382 * rZ Resultant EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 25383 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 25384 */
wolfSSL 16:8e0d178b1d1e 25385 int sp_ecc_proj_dbl_point_384(mp_int* pX, mp_int* pY, mp_int* pZ,
wolfSSL 16:8e0d178b1d1e 25386 mp_int* rX, mp_int* rY, mp_int* rZ)
wolfSSL 16:8e0d178b1d1e 25387 {
wolfSSL 16:8e0d178b1d1e 25388 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25389 sp_digit tmpd[2 * 12 * 2];
wolfSSL 16:8e0d178b1d1e 25390 sp_point_384 pd;
wolfSSL 16:8e0d178b1d1e 25391 #endif
wolfSSL 16:8e0d178b1d1e 25392 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 25393 sp_point_384* p;
wolfSSL 16:8e0d178b1d1e 25394 int err;
wolfSSL 16:8e0d178b1d1e 25395
wolfSSL 16:8e0d178b1d1e 25396 err = sp_384_point_new_12(NULL, pd, p);
wolfSSL 16:8e0d178b1d1e 25397 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25398 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25399 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 2, NULL,
wolfSSL 16:8e0d178b1d1e 25400 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25401 if (tmp == NULL) {
wolfSSL 16:8e0d178b1d1e 25402 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 25403 }
wolfSSL 16:8e0d178b1d1e 25404 }
wolfSSL 16:8e0d178b1d1e 25405 #else
wolfSSL 16:8e0d178b1d1e 25406 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 25407 #endif
wolfSSL 16:8e0d178b1d1e 25408
wolfSSL 16:8e0d178b1d1e 25409 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25410 sp_384_from_mp(p->x, 12, pX);
wolfSSL 16:8e0d178b1d1e 25411 sp_384_from_mp(p->y, 12, pY);
wolfSSL 16:8e0d178b1d1e 25412 sp_384_from_mp(p->z, 12, pZ);
wolfSSL 16:8e0d178b1d1e 25413
wolfSSL 16:8e0d178b1d1e 25414 sp_384_proj_point_dbl_12(p, p, tmp);
wolfSSL 16:8e0d178b1d1e 25415 }
wolfSSL 16:8e0d178b1d1e 25416
wolfSSL 16:8e0d178b1d1e 25417 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25418 err = sp_384_to_mp(p->x, rX);
wolfSSL 16:8e0d178b1d1e 25419 }
wolfSSL 16:8e0d178b1d1e 25420 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25421 err = sp_384_to_mp(p->y, rY);
wolfSSL 16:8e0d178b1d1e 25422 }
wolfSSL 16:8e0d178b1d1e 25423 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25424 err = sp_384_to_mp(p->z, rZ);
wolfSSL 16:8e0d178b1d1e 25425 }
wolfSSL 16:8e0d178b1d1e 25426
wolfSSL 16:8e0d178b1d1e 25427 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25428 if (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 25429 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25430 }
wolfSSL 16:8e0d178b1d1e 25431 #endif
wolfSSL 16:8e0d178b1d1e 25432 sp_384_point_free_12(p, 0, NULL);
wolfSSL 16:8e0d178b1d1e 25433
wolfSSL 16:8e0d178b1d1e 25434 return err;
wolfSSL 16:8e0d178b1d1e 25435 }
wolfSSL 16:8e0d178b1d1e 25436
wolfSSL 16:8e0d178b1d1e 25437 /* Map a projective EC point to affine in place.
wolfSSL 16:8e0d178b1d1e 25438 * pZ will be one.
wolfSSL 16:8e0d178b1d1e 25439 *
wolfSSL 16:8e0d178b1d1e 25440 * pX EC point's X ordinate.
wolfSSL 16:8e0d178b1d1e 25441 * pY EC point's Y ordinate.
wolfSSL 16:8e0d178b1d1e 25442 * pZ EC point's Z ordinate.
wolfSSL 16:8e0d178b1d1e 25443 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 25444 */
wolfSSL 16:8e0d178b1d1e 25445 int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ)
wolfSSL 16:8e0d178b1d1e 25446 {
wolfSSL 16:8e0d178b1d1e 25447 #if (!defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)) || defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25448 sp_digit tmpd[2 * 12 * 6];
wolfSSL 16:8e0d178b1d1e 25449 sp_point_384 pd;
wolfSSL 16:8e0d178b1d1e 25450 #endif
wolfSSL 16:8e0d178b1d1e 25451 sp_digit* tmp;
wolfSSL 16:8e0d178b1d1e 25452 sp_point_384* p;
wolfSSL 16:8e0d178b1d1e 25453 int err;
wolfSSL 16:8e0d178b1d1e 25454
wolfSSL 16:8e0d178b1d1e 25455 err = sp_384_point_new_12(NULL, pd, p);
wolfSSL 16:8e0d178b1d1e 25456 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25457 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25458 tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 6, NULL,
wolfSSL 16:8e0d178b1d1e 25459 DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25460 if (tmp == NULL) {
wolfSSL 16:8e0d178b1d1e 25461 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 25462 }
wolfSSL 16:8e0d178b1d1e 25463 }
wolfSSL 16:8e0d178b1d1e 25464 #else
wolfSSL 16:8e0d178b1d1e 25465 tmp = tmpd;
wolfSSL 16:8e0d178b1d1e 25466 #endif
wolfSSL 16:8e0d178b1d1e 25467 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25468 sp_384_from_mp(p->x, 12, pX);
wolfSSL 16:8e0d178b1d1e 25469 sp_384_from_mp(p->y, 12, pY);
wolfSSL 16:8e0d178b1d1e 25470 sp_384_from_mp(p->z, 12, pZ);
wolfSSL 16:8e0d178b1d1e 25471
wolfSSL 16:8e0d178b1d1e 25472 sp_384_map_12(p, p, tmp);
wolfSSL 16:8e0d178b1d1e 25473 }
wolfSSL 16:8e0d178b1d1e 25474
wolfSSL 16:8e0d178b1d1e 25475 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25476 err = sp_384_to_mp(p->x, pX);
wolfSSL 16:8e0d178b1d1e 25477 }
wolfSSL 16:8e0d178b1d1e 25478 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25479 err = sp_384_to_mp(p->y, pY);
wolfSSL 16:8e0d178b1d1e 25480 }
wolfSSL 16:8e0d178b1d1e 25481 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25482 err = sp_384_to_mp(p->z, pZ);
wolfSSL 16:8e0d178b1d1e 25483 }
wolfSSL 16:8e0d178b1d1e 25484
wolfSSL 16:8e0d178b1d1e 25485 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25486 if (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 25487 XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25488 }
wolfSSL 16:8e0d178b1d1e 25489 #endif
wolfSSL 16:8e0d178b1d1e 25490 sp_384_point_free_12(p, 0, NULL);
wolfSSL 16:8e0d178b1d1e 25491
wolfSSL 16:8e0d178b1d1e 25492 return err;
wolfSSL 16:8e0d178b1d1e 25493 }
wolfSSL 16:8e0d178b1d1e 25494 #endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */
wolfSSL 16:8e0d178b1d1e 25495 #ifdef HAVE_COMP_KEY
wolfSSL 16:8e0d178b1d1e 25496 /* Find the square root of a number mod the prime of the curve.
wolfSSL 16:8e0d178b1d1e 25497 *
wolfSSL 16:8e0d178b1d1e 25498 * y The number to operate on and the result.
wolfSSL 16:8e0d178b1d1e 25499 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 25500 */
wolfSSL 16:8e0d178b1d1e 25501 static int sp_384_mont_sqrt_12(sp_digit* y)
wolfSSL 16:8e0d178b1d1e 25502 {
wolfSSL 16:8e0d178b1d1e 25503 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25504 sp_digit* d;
wolfSSL 16:8e0d178b1d1e 25505 #else
wolfSSL 16:8e0d178b1d1e 25506 sp_digit t1d[2 * 12];
wolfSSL 16:8e0d178b1d1e 25507 sp_digit t2d[2 * 12];
wolfSSL 16:8e0d178b1d1e 25508 sp_digit t3d[2 * 12];
wolfSSL 16:8e0d178b1d1e 25509 sp_digit t4d[2 * 12];
wolfSSL 16:8e0d178b1d1e 25510 sp_digit t5d[2 * 12];
wolfSSL 16:8e0d178b1d1e 25511 #endif
wolfSSL 16:8e0d178b1d1e 25512 sp_digit* t1;
wolfSSL 16:8e0d178b1d1e 25513 sp_digit* t2;
wolfSSL 16:8e0d178b1d1e 25514 sp_digit* t3;
wolfSSL 16:8e0d178b1d1e 25515 sp_digit* t4;
wolfSSL 16:8e0d178b1d1e 25516 sp_digit* t5;
wolfSSL 16:8e0d178b1d1e 25517 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 25518
wolfSSL 16:8e0d178b1d1e 25519 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25520 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 12, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25521 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 25522 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 25523 }
wolfSSL 16:8e0d178b1d1e 25524 #endif
wolfSSL 16:8e0d178b1d1e 25525
wolfSSL 16:8e0d178b1d1e 25526 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25527 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25528 t1 = d + 0 * 12;
wolfSSL 16:8e0d178b1d1e 25529 t2 = d + 2 * 12;
wolfSSL 16:8e0d178b1d1e 25530 t3 = d + 4 * 12;
wolfSSL 16:8e0d178b1d1e 25531 t4 = d + 6 * 12;
wolfSSL 16:8e0d178b1d1e 25532 t5 = d + 8 * 12;
wolfSSL 16:8e0d178b1d1e 25533 #else
wolfSSL 16:8e0d178b1d1e 25534 t1 = t1d;
wolfSSL 16:8e0d178b1d1e 25535 t2 = t2d;
wolfSSL 16:8e0d178b1d1e 25536 t3 = t3d;
wolfSSL 16:8e0d178b1d1e 25537 t4 = t4d;
wolfSSL 16:8e0d178b1d1e 25538 t5 = t5d;
wolfSSL 16:8e0d178b1d1e 25539 #endif
wolfSSL 16:8e0d178b1d1e 25540
wolfSSL 16:8e0d178b1d1e 25541 {
wolfSSL 16:8e0d178b1d1e 25542 /* t2 = y ^ 0x2 */
wolfSSL 16:8e0d178b1d1e 25543 sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25544 /* t1 = y ^ 0x3 */
wolfSSL 16:8e0d178b1d1e 25545 sp_384_mont_mul_12(t1, t2, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25546 /* t5 = y ^ 0xc */
wolfSSL 16:8e0d178b1d1e 25547 sp_384_mont_sqr_n_12(t5, t1, 2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25548 /* t1 = y ^ 0xf */
wolfSSL 16:8e0d178b1d1e 25549 sp_384_mont_mul_12(t1, t1, t5, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25550 /* t2 = y ^ 0x1e */
wolfSSL 16:8e0d178b1d1e 25551 sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25552 /* t3 = y ^ 0x1f */
wolfSSL 16:8e0d178b1d1e 25553 sp_384_mont_mul_12(t3, t2, y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25554 /* t2 = y ^ 0x3e0 */
wolfSSL 16:8e0d178b1d1e 25555 sp_384_mont_sqr_n_12(t2, t3, 5, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25556 /* t1 = y ^ 0x3ff */
wolfSSL 16:8e0d178b1d1e 25557 sp_384_mont_mul_12(t1, t3, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25558 /* t2 = y ^ 0x7fe0 */
wolfSSL 16:8e0d178b1d1e 25559 sp_384_mont_sqr_n_12(t2, t1, 5, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25560 /* t3 = y ^ 0x7fff */
wolfSSL 16:8e0d178b1d1e 25561 sp_384_mont_mul_12(t3, t3, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25562 /* t2 = y ^ 0x3fff800 */
wolfSSL 16:8e0d178b1d1e 25563 sp_384_mont_sqr_n_12(t2, t3, 15, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25564 /* t4 = y ^ 0x3ffffff */
wolfSSL 16:8e0d178b1d1e 25565 sp_384_mont_mul_12(t4, t3, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25566 /* t2 = y ^ 0xffffffc000000 */
wolfSSL 16:8e0d178b1d1e 25567 sp_384_mont_sqr_n_12(t2, t4, 30, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25568 /* t1 = y ^ 0xfffffffffffff */
wolfSSL 16:8e0d178b1d1e 25569 sp_384_mont_mul_12(t1, t4, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25570 /* t2 = y ^ 0xfffffffffffffff000000000000000 */
wolfSSL 16:8e0d178b1d1e 25571 sp_384_mont_sqr_n_12(t2, t1, 60, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25572 /* t1 = y ^ 0xffffffffffffffffffffffffffffff */
wolfSSL 16:8e0d178b1d1e 25573 sp_384_mont_mul_12(t1, t1, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25574 /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */
wolfSSL 16:8e0d178b1d1e 25575 sp_384_mont_sqr_n_12(t2, t1, 120, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25576 /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
wolfSSL 16:8e0d178b1d1e 25577 sp_384_mont_mul_12(t1, t1, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25578 /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */
wolfSSL 16:8e0d178b1d1e 25579 sp_384_mont_sqr_n_12(t2, t1, 15, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25580 /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */
wolfSSL 16:8e0d178b1d1e 25581 sp_384_mont_mul_12(t1, t3, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25582 /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */
wolfSSL 16:8e0d178b1d1e 25583 sp_384_mont_sqr_n_12(t2, t1, 31, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25584 /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */
wolfSSL 16:8e0d178b1d1e 25585 sp_384_mont_mul_12(t1, t4, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25586 /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */
wolfSSL 16:8e0d178b1d1e 25587 sp_384_mont_sqr_n_12(t2, t1, 4, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25588 /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */
wolfSSL 16:8e0d178b1d1e 25589 sp_384_mont_mul_12(t1, t5, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25590 /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */
wolfSSL 16:8e0d178b1d1e 25591 sp_384_mont_sqr_n_12(t2, t1, 62, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25592 /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */
wolfSSL 16:8e0d178b1d1e 25593 sp_384_mont_mul_12(t1, y, t2, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25594 /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */
wolfSSL 16:8e0d178b1d1e 25595 sp_384_mont_sqr_n_12(y, t1, 30, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25596 }
wolfSSL 16:8e0d178b1d1e 25597 }
wolfSSL 16:8e0d178b1d1e 25598
wolfSSL 16:8e0d178b1d1e 25599 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25600 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 25601 XFREE(d, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25602 }
wolfSSL 16:8e0d178b1d1e 25603 #endif
wolfSSL 16:8e0d178b1d1e 25604
wolfSSL 16:8e0d178b1d1e 25605 return err;
wolfSSL 16:8e0d178b1d1e 25606 }
wolfSSL 16:8e0d178b1d1e 25607
wolfSSL 16:8e0d178b1d1e 25608
wolfSSL 16:8e0d178b1d1e 25609 /* Uncompress the point given the X ordinate.
wolfSSL 16:8e0d178b1d1e 25610 *
wolfSSL 16:8e0d178b1d1e 25611 * xm X ordinate.
wolfSSL 16:8e0d178b1d1e 25612 * odd Whether the Y ordinate is odd.
wolfSSL 16:8e0d178b1d1e 25613 * ym Calculated Y ordinate.
wolfSSL 16:8e0d178b1d1e 25614 * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.
wolfSSL 16:8e0d178b1d1e 25615 */
wolfSSL 16:8e0d178b1d1e 25616 int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym)
wolfSSL 16:8e0d178b1d1e 25617 {
wolfSSL 16:8e0d178b1d1e 25618 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25619 sp_digit* d;
wolfSSL 16:8e0d178b1d1e 25620 #else
wolfSSL 16:8e0d178b1d1e 25621 sp_digit xd[2 * 12];
wolfSSL 16:8e0d178b1d1e 25622 sp_digit yd[2 * 12];
wolfSSL 16:8e0d178b1d1e 25623 #endif
wolfSSL 16:8e0d178b1d1e 25624 sp_digit* x = NULL;
wolfSSL 16:8e0d178b1d1e 25625 sp_digit* y = NULL;
wolfSSL 16:8e0d178b1d1e 25626 int err = MP_OKAY;
wolfSSL 16:8e0d178b1d1e 25627
wolfSSL 16:8e0d178b1d1e 25628 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25629 d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 12, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25630 if (d == NULL) {
wolfSSL 16:8e0d178b1d1e 25631 err = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 25632 }
wolfSSL 16:8e0d178b1d1e 25633 #endif
wolfSSL 16:8e0d178b1d1e 25634
wolfSSL 16:8e0d178b1d1e 25635 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25636 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25637 x = d + 0 * 12;
wolfSSL 16:8e0d178b1d1e 25638 y = d + 2 * 12;
wolfSSL 16:8e0d178b1d1e 25639 #else
wolfSSL 16:8e0d178b1d1e 25640 x = xd;
wolfSSL 16:8e0d178b1d1e 25641 y = yd;
wolfSSL 16:8e0d178b1d1e 25642 #endif
wolfSSL 16:8e0d178b1d1e 25643
wolfSSL 16:8e0d178b1d1e 25644 sp_384_from_mp(x, 12, xm);
wolfSSL 16:8e0d178b1d1e 25645 err = sp_384_mod_mul_norm_12(x, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 25646 }
wolfSSL 16:8e0d178b1d1e 25647 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25648 /* y = x^3 */
wolfSSL 16:8e0d178b1d1e 25649 {
wolfSSL 16:8e0d178b1d1e 25650 sp_384_mont_sqr_12(y, x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25651 sp_384_mont_mul_12(y, y, x, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25652 }
wolfSSL 16:8e0d178b1d1e 25653 /* y = x^3 - 3x */
wolfSSL 16:8e0d178b1d1e 25654 sp_384_mont_sub_12(y, y, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 25655 sp_384_mont_sub_12(y, y, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 25656 sp_384_mont_sub_12(y, y, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 25657 /* y = x^3 - 3x + b */
wolfSSL 16:8e0d178b1d1e 25658 err = sp_384_mod_mul_norm_12(x, p384_b, p384_mod);
wolfSSL 16:8e0d178b1d1e 25659 }
wolfSSL 16:8e0d178b1d1e 25660 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25661 sp_384_mont_add_12(y, y, x, p384_mod);
wolfSSL 16:8e0d178b1d1e 25662 /* y = sqrt(x^3 - 3x + b) */
wolfSSL 16:8e0d178b1d1e 25663 err = sp_384_mont_sqrt_12(y);
wolfSSL 16:8e0d178b1d1e 25664 }
wolfSSL 16:8e0d178b1d1e 25665 if (err == MP_OKAY) {
wolfSSL 16:8e0d178b1d1e 25666 XMEMSET(y + 12, 0, 12U * sizeof(sp_digit));
wolfSSL 16:8e0d178b1d1e 25667 sp_384_mont_reduce_12(y, p384_mod, p384_mp_mod);
wolfSSL 16:8e0d178b1d1e 25668 if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {
wolfSSL 16:8e0d178b1d1e 25669 sp_384_mont_sub_12(y, p384_mod, y, p384_mod);
wolfSSL 16:8e0d178b1d1e 25670 }
wolfSSL 16:8e0d178b1d1e 25671
wolfSSL 16:8e0d178b1d1e 25672 err = sp_384_to_mp(y, ym);
wolfSSL 16:8e0d178b1d1e 25673 }
wolfSSL 16:8e0d178b1d1e 25674
wolfSSL 16:8e0d178b1d1e 25675 #if (defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) && !defined(WOLFSSL_SP_NO_MALLOC)
wolfSSL 16:8e0d178b1d1e 25676 if (d != NULL) {
wolfSSL 16:8e0d178b1d1e 25677 XFREE(d, NULL, DYNAMIC_TYPE_ECC);
wolfSSL 16:8e0d178b1d1e 25678 }
wolfSSL 16:8e0d178b1d1e 25679 #endif
wolfSSL 16:8e0d178b1d1e 25680
wolfSSL 16:8e0d178b1d1e 25681 return err;
wolfSSL 16:8e0d178b1d1e 25682 }
wolfSSL 16:8e0d178b1d1e 25683 #endif
wolfSSL 16:8e0d178b1d1e 25684 #endif /* WOLFSSL_SP_384 */
wolfSSL 16:8e0d178b1d1e 25685 #endif /* WOLFSSL_HAVE_SP_ECC */
wolfSSL 16:8e0d178b1d1e 25686 #endif /* WOLFSSL_SP_ARM_CORTEX_M_ASM */
wolfSSL 16:8e0d178b1d1e 25687 #endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */
wolfSSL 16:8e0d178b1d1e 25688